Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-09-11 04:32:30

0001 #include "DQM/GEM/plugins/GEMEffByGEMCSCSegmentSource.h"
0002 
0003 #include "Validation/MuonGEMHits/interface/GEMValidationUtils.h"
0004 
0005 GEMEffByGEMCSCSegmentSource::GEMEffByGEMCSCSegmentSource(const edm::ParameterSet& ps)
0006     : GEMDQMEfficiencySourceBase(ps),
0007       kGEMGeometryTokenBeginRun_(esConsumes<edm::Transition::BeginRun>()),
0008       kGEMCSCSegmentCollectionToken_(
0009           consumes<GEMCSCSegmentCollection>(ps.getUntrackedParameter<edm::InputTag>("gemcscSegmentTag"))),
0010       kMuonCollectionToken_(consumes<reco::MuonCollection>(ps.getUntrackedParameter<edm::InputTag>("muonTag"))),
0011       kMinCSCRecHits_(ps.getUntrackedParameter<int>("minCSCRecHits")),
0012       kModeDev_(ps.getUntrackedParameter<bool>("modeDev")),
0013       kUseMuonSegment_(ps.getUntrackedParameter<bool>("useMuonSegment")),
0014       kFolder_(ps.getUntrackedParameter<std::string>("folder")) {}
0015 
0016 GEMEffByGEMCSCSegmentSource::~GEMEffByGEMCSCSegmentSource() {}
0017 
0018 void GEMEffByGEMCSCSegmentSource::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0019   edm::ParameterSetDescription desc;
0020 
0021   // GEMDQMEfficiencySourceBase
0022   desc.addUntracked<edm::InputTag>("ohStatusTag", edm::InputTag("muonGEMDigis", "OHStatus"));
0023   desc.addUntracked<edm::InputTag>("vfatStatusTag", edm::InputTag("muonGEMDigis", "VFATStatus"));
0024   desc.addUntracked<bool>("monitorGE11", true);
0025   desc.addUntracked<bool>("monitorGE21", false);
0026   desc.addUntracked<bool>("monitorGE0", false);
0027   desc.addUntracked<bool>("maskChamberWithError", false);
0028   desc.addUntracked<std::string>("logCategory", "GEMEffByGEMCSCSegmentSource");
0029 
0030   // GEMEffByGEMCSCSegmentSource
0031   desc.addUntracked<edm::InputTag>("gemcscSegmentTag", edm::InputTag("gemcscSegments"));
0032   desc.addUntracked<edm::InputTag>("muonTag", edm::InputTag("muons"));
0033   desc.addUntracked<int>("minCSCRecHits", 6);
0034   desc.addUntracked<bool>("useMuonSegment", false);
0035   desc.addUntracked<bool>("modeDev", false);
0036   desc.addUntracked<std::string>("folder", "GEM/Efficiency/GEMCSCSegment");
0037 
0038   descriptions.addWithDefaultLabel(desc);
0039 }
0040 
0041 void GEMEffByGEMCSCSegmentSource::bookHistograms(DQMStore::IBooker& ibooker,
0042                                                  edm::Run const& run,
0043                                                  edm::EventSetup const& setup) {
0044   const GEMGeometry* gem = nullptr;
0045   if (auto handle = setup.getHandle(kGEMGeometryTokenBeginRun_)) {
0046     gem = handle.product();
0047   } else {
0048     edm::LogError(kLogCategory_ + "|bookHistograms") << "failed to get GEMGeometry";
0049     return;
0050   }
0051 
0052   ibooker.setCurrentFolder(kFolder_);
0053 
0054   for (const GEMStation* station : gem->stations()) {
0055     const int region_id = station->region();
0056     const int station_id = station->station();
0057 
0058     if (skipGEMStation(station_id))
0059       continue;
0060 
0061     if (station_id == 1) {
0062       ////////////////////////////////////////////////////////////////////////////
0063       // Region - Station - Layer
0064       ////////////////////////////////////////////////////////////////////////////
0065       const std::vector<const GEMSuperChamber*> superchamber_vec = station->superChambers();
0066       if (not checkRefs(superchamber_vec)) {
0067         edm::LogError(kLogCategory_) << "got an invalid ptr from GEMStation::superChambers";
0068         return;
0069       }
0070 
0071       const std::vector<const GEMChamber*> chamber_vec = superchamber_vec.front()->chambers();
0072       if (not checkRefs(chamber_vec)) {
0073         edm::LogError(kLogCategory_) << "got an invalid ptr from GEMSuperChamber::chambers";
0074         return;
0075       }
0076 
0077       // we actually loop over layers
0078       for (const GEMChamber* chamber : chamber_vec) {
0079         const int layer_id = chamber->id().layer();
0080         const GEMDetId key = getReStLaKey(chamber->id());
0081         const TString suffix = GEMUtils::getSuffixName(region_id, station_id, layer_id);
0082         const TString title = GEMUtils::getSuffixTitle(region_id, station_id, layer_id);
0083 
0084         // book MEs for the efficiency vs the GEM chambver id
0085         me_chamber_[key] = bookChamber(ibooker, "chamber" + suffix, title, station);
0086         me_chamber_matched_[key] = bookNumerator1D(ibooker, me_chamber_[key]);
0087 
0088         if (kUseMuonSegment_) {
0089           me_chamber_muon_segment_[key] = bookChamber(ibooker, "muon_chamber" + suffix, title, station);
0090           me_chamber_muon_segment_matched_[key] = bookNumerator1D(ibooker, me_chamber_muon_segment_[key]);
0091         }
0092 
0093         if (kModeDev_) {
0094           // book MEs for the efficiency vs the number of CSC hits in a CSC segment
0095           // CSCSegAlgoRU: min hits = 4, max hits = CSC layers = 6
0096           me_num_csc_hits_[key] = ibooker.book1D("num_csc_hits" + suffix, title, 4, 2.5, 6.5);
0097           me_num_csc_hits_[key]->setAxisTitle("Number of CSC Hits", 1);
0098           me_num_csc_hits_matched_[key] = bookNumerator1D(ibooker, me_num_csc_hits_[key]);
0099 
0100           me_csc_reduced_chi2_[key] = ibooker.book1D("reduced_chi2" + suffix, title, 100, 0.0, 10.0);
0101           me_csc_reduced_chi2_[key]->setAxisTitle("#chi^{2} / N_{dof} of CSC Segment", 1);
0102           me_csc_reduced_chi2_matched_[key] = bookNumerator1D(ibooker, me_csc_reduced_chi2_[key]);
0103 
0104           me_csc_chamber_type_[key] = bookCSCChamberType(ibooker, "csc_chamber_type" + suffix, title);
0105           me_csc_chamber_type_matched_[key] = bookNumerator1D(ibooker, me_csc_chamber_type_[key]);
0106         }
0107       }  // GEMChamber
0108     } else {
0109       edm::LogWarning(kLogCategory_) << "The monitoring for ";  // TODO
0110       continue;
0111     }
0112   }  // GEMStataion
0113 }
0114 
0115 // https://github.com/cms-sw/cmssw/blob/CMSSW_12_3_0_pre5/DataFormats/MuonDetId/interface/CSCDetId.h#L187-L193
0116 dqm::impl::MonitorElement* GEMEffByGEMCSCSegmentSource::bookCSCChamberType(DQMStore::IBooker& ibooker,
0117                                                                            const TString& name,
0118                                                                            const TString& title) {
0119   MonitorElement* monitor_element = ibooker.book1D(name, title, 10, 0.5, 10.5);
0120   monitor_element->setAxisTitle("CSC chamber type", 1);
0121   for (int chamber_type = 1; chamber_type <= 10; chamber_type++) {
0122     const std::string label = CSCDetId::chamberName(chamber_type);
0123     monitor_element->setBinLabel(chamber_type, label, 1);
0124   }
0125   return monitor_element;
0126 }
0127 
0128 void GEMEffByGEMCSCSegmentSource::analyze(const edm::Event& event, const edm::EventSetup& setup) {
0129   //////////////////////////////////////////////////////////////////////////////
0130   // get data from event
0131   //////////////////////////////////////////////////////////////////////////////
0132   const GEMCSCSegmentCollection* gemcsc_segment_collection = nullptr;
0133   if (const edm::Handle<GEMCSCSegmentCollection> handle = event.getHandle(kGEMCSCSegmentCollectionToken_)) {
0134     gemcsc_segment_collection = handle.product();
0135 
0136   } else {
0137     edm::LogError(kLogCategory_) << "invalid GEMCSCSegmentCollection";
0138     return;
0139   }
0140 
0141   const reco::MuonCollection* muon_collection = nullptr;
0142   if (kUseMuonSegment_) {
0143     if (const edm::Handle<reco::MuonCollection> handle = event.getHandle(kMuonCollectionToken_)) {
0144       muon_collection = handle.product();
0145 
0146     } else {
0147       edm::LogError(kLogCategory_) << "invalid reco::MuonCollection";
0148       return;
0149     }
0150   }
0151 
0152   const GEMOHStatusCollection* oh_status_collection = nullptr;
0153   const GEMVFATStatusCollection* vfat_status_collection = nullptr;
0154   if (kMaskChamberWithError_) {
0155     if (auto handle = event.getHandle(kGEMOHStatusCollectionToken_)) {
0156       oh_status_collection = handle.product();
0157     } else {
0158       edm::LogError(kLogCategory_) << "failed to get OHVFATStatusCollection";
0159       return;
0160     }
0161 
0162     if (auto handle = event.getHandle(kGEMVFATStatusCollectionToken_)) {
0163       vfat_status_collection = handle.product();
0164     } else {
0165       edm::LogError(kLogCategory_) << "failed to get GEMVFATStatusCollection";
0166       return;
0167     }
0168   }
0169 
0170   //////////////////////////////////////////////////////////////////////////////
0171   // NOTE
0172   //////////////////////////////////////////////////////////////////////////////
0173   if (gemcsc_segment_collection->size() < 1) {
0174     LogDebug(kLogCategory_) << "empty GEMCSCSegment";
0175     return;
0176   }
0177 
0178   if (kUseMuonSegment_) {
0179     findMatchedME11Segments(muon_collection);
0180   }
0181 
0182   for (edm::OwnVector<GEMCSCSegment>::const_iterator iter = gemcsc_segment_collection->begin();
0183        iter != gemcsc_segment_collection->end();
0184        iter++) {
0185     const GEMCSCSegment& gemcsc_segment = *iter;
0186 
0187     const CSCDetId csc_id = gemcsc_segment.cscDetId();
0188     if (csc_id.isME11()) {
0189       analyzeGE11ME11Segment(gemcsc_segment, oh_status_collection, vfat_status_collection);
0190 
0191     } else {
0192       LogDebug(kLogCategory_) << "skip " << csc_id;
0193       continue;
0194     }
0195   }  // GEMCSCSegment
0196 }
0197 
0198 // TODO doc
0199 void GEMEffByGEMCSCSegmentSource::analyzeGE11ME11Segment(const GEMCSCSegment& gemcsc_segment,
0200                                                          const GEMOHStatusCollection* oh_status_collection,
0201                                                          const GEMVFATStatusCollection* vfat_status_collection) {
0202   const GEMRecHit* ge11_hit_layer1 = nullptr;
0203   const GEMRecHit* ge11_hit_layer2 = nullptr;
0204 
0205   const CSCDetId csc_id = gemcsc_segment.cscDetId();
0206   for (const GEMRecHit& gem_hit : gemcsc_segment.gemRecHits()) {
0207     const GEMDetId gem_id = gem_hit.gemId();
0208 
0209     if (not gem_id.isGE11()) {
0210       edm::LogWarning(kLogCategory_) << "CSCSegment is in " << csc_id << " but GEMRecHit is in " << gem_id
0211                                      << ". skip this GEMCSCSegment."
0212                                      << "check if RecoLocalMuon/GEMCSCSegment/plugins/GEMCSCSegAlgoRR.cc has changed.";
0213       return;
0214     }
0215 
0216     if (kMaskChamberWithError_) {
0217       const bool has_error = maskChamberWithError(gem_id.chamberId(), oh_status_collection, vfat_status_collection);
0218       if (has_error) {
0219         return;
0220       }
0221     }
0222 
0223     const int layer = gem_id.layer();
0224     if (layer == 1) {
0225       ge11_hit_layer1 = &gem_hit;
0226 
0227     } else if (layer == 2) {
0228       ge11_hit_layer2 = &gem_hit;
0229 
0230     } else {
0231       edm::LogError(kLogCategory_) << "isGE11 but got unexpected layer " << gem_id << ". skip this GEMCSCSegment.";
0232       return;
0233     }
0234   }  // GEMRecHit
0235 
0236   checkCoincidenceGE11(ge11_hit_layer1, ge11_hit_layer2, gemcsc_segment);
0237   checkCoincidenceGE11(ge11_hit_layer2, ge11_hit_layer1, gemcsc_segment);
0238 }
0239 
0240 // TODO doc
0241 void GEMEffByGEMCSCSegmentSource::checkCoincidenceGE11(const GEMRecHit* trigger_layer_hit,
0242                                                        const GEMRecHit* detection_layer_hit,
0243                                                        const GEMCSCSegment& gemcsc_segment) {
0244   if (trigger_layer_hit == nullptr) {
0245     LogDebug(kLogCategory_) << "trigger_layer_hit is nullptr";
0246     return;
0247   }
0248 
0249   const GEMDetId trigger_layer_id = trigger_layer_hit->gemId();
0250   const int detection_layer = trigger_layer_id.layer() == 1 ? 2 : 1;
0251   // detection layer key
0252   // GEMDetId(int region, int ring, int station, int layer, int chamber, int ieta)
0253   const GEMDetId key{trigger_layer_id.region(), 1, trigger_layer_id.station(), detection_layer, 0, 0};
0254 
0255   const int chamber = trigger_layer_id.chamber();
0256   const bool is_matched = kUseMuonSegment_ ? isME11SegmentMatched(gemcsc_segment.cscSegment()) : false;
0257 
0258   const int num_csc_hits = static_cast<int>(gemcsc_segment.cscRecHits().size());
0259   const double reduced_chi2 = gemcsc_segment.chi2() / gemcsc_segment.degreesOfFreedom();
0260   const int csc_chamber_type = gemcsc_segment.cscDetId().iChamberType();
0261 
0262   if (kModeDev_) {
0263     fillME(me_num_csc_hits_, key, num_csc_hits);
0264     fillMEWithinLimits(me_csc_reduced_chi2_, key, reduced_chi2);
0265     fillME(me_csc_chamber_type_, key, csc_chamber_type);
0266 
0267     if (detection_layer_hit) {
0268       fillME(me_num_csc_hits_matched_, key, num_csc_hits);
0269       fillMEWithinLimits(me_csc_reduced_chi2_matched_, key, reduced_chi2);
0270       fillME(me_csc_chamber_type_matched_, key, csc_chamber_type);
0271     }
0272   }
0273 
0274   // TODO add a method
0275   const bool is_good = num_csc_hits >= kMinCSCRecHits_;
0276   if (not is_good) {
0277     return;
0278   }
0279 
0280   // twofold coincidence rate
0281   fillME(me_chamber_, key, chamber);
0282   if (is_matched) {
0283     fillME(me_chamber_muon_segment_, key, chamber);
0284   }
0285 
0286   // threefold coincidence rate
0287   if (detection_layer_hit) {
0288     fillME(me_chamber_matched_, key, chamber);
0289     if (is_matched) {
0290       fillME(me_chamber_muon_segment_matched_, key, chamber);
0291     }
0292   }
0293 }
0294 
0295 // TODO docs
0296 void GEMEffByGEMCSCSegmentSource::findMatchedME11Segments(const reco::MuonCollection* muon_collection) {
0297   matched_me11_segment_vector_.clear();
0298 
0299   if (muon_collection == nullptr) {
0300     // TODO log
0301     return;
0302   }
0303 
0304   for (unsigned int idx = 0; idx < muon_collection->size(); idx++) {
0305     const reco::Muon& muon = muon_collection->at(idx);
0306 
0307     for (const reco::MuonChamberMatch& chamber_match : muon.matches()) {
0308       if (chamber_match.detector() != MuonSubdetId::CSC) {
0309         continue;
0310       }
0311 
0312       const CSCDetId csc_id{chamber_match.id};
0313       if (not csc_id.isME11()) {
0314         continue;
0315       }
0316 
0317       for (const reco::MuonSegmentMatch& segment_match : chamber_match.segmentMatches) {
0318         if (not segment_match.isMask(reco::MuonSegmentMatch::BestInStationByDR)) {
0319           continue;
0320         }
0321         matched_me11_segment_vector_.push_back(segment_match.cscSegmentRef.get());
0322       }  // MuonSegmentMatch
0323     }  // MuonChamberMatch
0324   }  // MuonCollection
0325 }
0326 
0327 // TODO
0328 bool GEMEffByGEMCSCSegmentSource::isME11SegmentMatched(const CSCSegment& csc_segment) {
0329   bool found = false;
0330 
0331   const CSCDetId csc_id = csc_segment.cscDetId();
0332   if (not csc_id.isME11()) {
0333     return false;
0334   }
0335 
0336   for (const CSCSegment* matched_segment : matched_me11_segment_vector_) {
0337     if (csc_id != matched_segment->cscDetId())
0338       continue;
0339     if (csc_segment.localPosition().x() != matched_segment->localPosition().x())
0340       continue;
0341     if (csc_segment.localPosition().y() != matched_segment->localPosition().y())
0342       continue;
0343     if (csc_segment.localPosition().z() != matched_segment->localPosition().z())
0344       continue;
0345     if (csc_segment.time() != matched_segment->time())
0346       continue;
0347 
0348     found = true;
0349   }
0350 
0351   return found;
0352 }