From 8d68de5f0cdb8d0e160b6c289e9df7d1c48d652d Mon Sep 17 00:00:00 2001 From: Seungjin Yang Date: Tue, 4 Oct 2022 12:58:52 +0200 Subject: [PATCH] Implement the GE21-ME21 segment reconstruction a backport of slowmoyang:ge21-me21-seg-reco__from-CMSSW_12_6_0_pre2 --- .../python/gemcscSegmentsTesting_cff.py | 4 + DQM/GEM/test/testGEMEffByGEMCSCSegment.py | 2 +- .../clients/gem_dqm_sourceclient-live_cfg.py | 2 +- .../plugins/GEMCSCSegmentBuilder.cc | 22 +- .../plugins/GEMCSCSegmentBuilder.h | 1 + .../plugins/GEMCSCSegmentProducer.cc | 24 ++ .../plugins/GEMCSCSegmentProducer.h | 4 + .../python/gemcscSegments_cff.py | 6 + .../python/gemcscSegments_cfi.py | 29 -- .../GEMCSCSegment/test/BuildFile.xml | 3 + .../test/GEMCSCCoincidenceRateAnalyzer.cc | 356 ++++++++++++++++++ .../test/runGEMCSCSegmentProducer_cfg.py | 2 +- 12 files changed, 410 insertions(+), 45 deletions(-) create mode 100644 Configuration/ProcessModifiers/python/gemcscSegmentsTesting_cff.py create mode 100644 RecoLocalMuon/GEMCSCSegment/python/gemcscSegments_cff.py delete mode 100644 RecoLocalMuon/GEMCSCSegment/python/gemcscSegments_cfi.py create mode 100644 RecoLocalMuon/GEMCSCSegment/test/GEMCSCCoincidenceRateAnalyzer.cc diff --git a/Configuration/ProcessModifiers/python/gemcscSegmentsTesting_cff.py b/Configuration/ProcessModifiers/python/gemcscSegmentsTesting_cff.py new file mode 100644 index 0000000000000..0d6d87ee18b51 --- /dev/null +++ b/Configuration/ProcessModifiers/python/gemcscSegmentsTesting_cff.py @@ -0,0 +1,4 @@ +import FWCore.ParameterSet.Config as cms + +# This modifier enable runnig of GEMCSCSegmentProducer in relval workflows +gemcscSegmentsTesting = cms.Modifier() diff --git a/DQM/GEM/test/testGEMEffByGEMCSCSegment.py b/DQM/GEM/test/testGEMEffByGEMCSCSegment.py index a3f385b2f8236..775f48590d3e7 100644 --- a/DQM/GEM/test/testGEMEffByGEMCSCSegment.py +++ b/DQM/GEM/test/testGEMEffByGEMCSCSegment.py @@ -40,7 +40,7 @@ process.load('RecoLocalMuon.GEMRecHit.gemRecHits_cfi') process.load("Configuration.StandardSequences.RawToDigi_Data_cff") process.load("Configuration.StandardSequences.Reconstruction_cff") -process.load('RecoLocalMuon.GEMCSCSegment.gemcscSegments_cfi') +process.load('RecoLocalMuon.GEMCSCSegment.gemcscSegments_cff') process.load("DQM.GEM.gemEffByGEMCSCSegment_cff") process.muonGEMDigis.useDBEMap = True diff --git a/DQM/Integration/python/clients/gem_dqm_sourceclient-live_cfg.py b/DQM/Integration/python/clients/gem_dqm_sourceclient-live_cfg.py index 463972035c8e3..38c1ddfd69bb4 100644 --- a/DQM/Integration/python/clients/gem_dqm_sourceclient-live_cfg.py +++ b/DQM/Integration/python/clients/gem_dqm_sourceclient-live_cfg.py @@ -29,7 +29,7 @@ process.load("Configuration.StandardSequences.RawToDigi_Data_cff") process.load("Configuration.StandardSequences.Reconstruction_cff") -process.load('RecoLocalMuon.GEMCSCSegment.gemcscSegments_cfi') +process.load('RecoLocalMuon.GEMCSCSegment.gemcscSegments_cff') process.load("DQM.GEM.GEMDQM_cff") process.load("DQM.GEM.gemEffByGEMCSCSegment_cff") diff --git a/RecoLocalMuon/GEMCSCSegment/plugins/GEMCSCSegmentBuilder.cc b/RecoLocalMuon/GEMCSCSegment/plugins/GEMCSCSegmentBuilder.cc index f0d6e44d9f445..06fa670f7c144 100644 --- a/RecoLocalMuon/GEMCSCSegment/plugins/GEMCSCSegmentBuilder.cc +++ b/RecoLocalMuon/GEMCSCSegment/plugins/GEMCSCSegmentBuilder.cc @@ -32,6 +32,7 @@ GEMCSCSegmentBuilder::GEMCSCSegmentBuilder(const edm::ParameterSet& ps) : // Ask factory to build this algorithm, giving it appropriate ParameterSet algo{GEMCSCSegmentBuilderPluginFactory::get()->create(ps.getParameter("algo_name"), ps.getParameter("algo_psets"))}, + enable_me21_ge21_(ps.getParameter("enableME21GE21")), gemgeom_{nullptr}, cscgeom_{nullptr} { edm::LogVerbatim("GEMCSCSegmentBuilder") @@ -120,14 +121,13 @@ void GEMCSCSegmentBuilder::build(const GEMRecHitCollection* recHits, CSCDetId CSCId = segmIt->cscDetId(); // Search for Matches between GEM Roll and CSC Chamber - // - only matches between ME1/1(a&b) and GE1/1 - // - notation: CSC ring 1 = ME1/1b; CSC ring 4 = ME1/1a - // Case A :: ME1/1 Segments can have GEM Rechits associated to them + // Case A :: ME1/1 and ME2/1 Segments can have GE1/1 and GE2/1 Rechits associated to them, respectively // ================================================================ - if (CSCId.station() == 1 && (CSCId.ring() == 1 || CSCId.ring() == 4)) { + if (CSCId.isME11() or (enable_me21_ge21_ and CSCId.isME21())) { edm::LogVerbatim("GEMCSCSegmentBuilder") - << "[GEMCSCSegmentBuilder :: build] Found ME1/1 Segment in " << CSCId.rawId() << " = " << CSCId << std::endl; + << "[GEMCSCSegmentBuilder :: build] Found " << (CSCId.isME11() ? "ME1/1" : "ME2/1") << " Segment in " + << CSCId.rawId() << " = " << CSCId << std::endl; // 1) Save the CSC Segment in CSC segment collection // ------------------------------------------------- @@ -214,13 +214,13 @@ void GEMCSCSegmentBuilder::build(const GEMRecHitCollection* recHits, } } // end Loop over GEM Rolls } // end Loop over GEM RecHits - } // end requirement of CSC segment in ME1/1 + } // end requirement of CSC segment in ME1/1 or ME2/1 // Case B :: all other CSC Chambers have no GEM Chamber associated // =============================================================== - else if (!(CSCId.station() == 1 && (CSCId.ring() == 1 || CSCId.ring() == 4))) { - edm::LogVerbatim("GEMCSCSegmentBuilder") << "[GEMCSCSegmentBuilder :: build] Found non-ME1/1 Segment in " - << CSCId.rawId() << " = " << CSCId << std::endl; + else { + edm::LogVerbatim("GEMCSCSegmentBuilder") + << "[GEMCSCSegmentBuilder :: build] Found a Segment in " << CSCId.rawId() << " = " << CSCId << std::endl; // get CSC segment vector associated to this CSCDetId // if no vector is associated yet to this CSCDetId, create empty vector @@ -230,10 +230,6 @@ void GEMCSCSegmentBuilder::build(const GEMRecHitCollection* recHits, cscsegmentvector_noGEM.push_back(segmIt->clone()); cscSegColl_noGEM[CSCId.rawId()] = cscsegmentvector_noGEM; } - - else { - } // no other option - } // end Loop over csc segments // === Now pass CSC Segments and GEM RecHits to the Segment Algorithm === diff --git a/RecoLocalMuon/GEMCSCSegment/plugins/GEMCSCSegmentBuilder.h b/RecoLocalMuon/GEMCSCSegment/plugins/GEMCSCSegmentBuilder.h index 5bf297b583357..d14e217f34746 100644 --- a/RecoLocalMuon/GEMCSCSegment/plugins/GEMCSCSegmentBuilder.h +++ b/RecoLocalMuon/GEMCSCSegment/plugins/GEMCSCSegmentBuilder.h @@ -80,6 +80,7 @@ class GEMCSCSegmentBuilder { private: std::unique_ptr algo; + const bool enable_me21_ge21_; const GEMGeometry* gemgeom_; const CSCGeometry* cscgeom_; }; diff --git a/RecoLocalMuon/GEMCSCSegment/plugins/GEMCSCSegmentProducer.cc b/RecoLocalMuon/GEMCSCSegment/plugins/GEMCSCSegmentProducer.cc index 43201ba50995e..12cc6107aaf9c 100644 --- a/RecoLocalMuon/GEMCSCSegment/plugins/GEMCSCSegmentProducer.cc +++ b/RecoLocalMuon/GEMCSCSegment/plugins/GEMCSCSegmentProducer.cc @@ -34,6 +34,30 @@ GEMCSCSegmentProducer::~GEMCSCSegmentProducer() { delete segmentBuilder_; } +void GEMCSCSegmentProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + // gemcscSegments + edm::ParameterSetDescription desc; + desc.add("inputObjectsGEM", edm::InputTag("gemRecHits")); + desc.add("inputObjectsCSC", edm::InputTag("cscSegments")); + desc.add("enableME21GE21", false); + desc.add("algo_name", "GEMCSCSegAlgoRR"); + { + edm::ParameterSetDescription psd0; + psd0.addUntracked("GEMCSCDebug", true); + psd0.add("minHitsPerSegment", 2); + psd0.add("preClustering", true); + psd0.add("dXclusBoxMax", 1.0); + psd0.add("dYclusBoxMax", 5.0); + psd0.add("preClusteringUseChaining", true); + psd0.add("dPhiChainBoxMax", 1.0); + psd0.add("dThetaChainBoxMax", 0.02); + psd0.add("dRChainBoxMax", 0.5); + psd0.add("maxRecHitsInCluster", 6); + desc.add("algo_psets", psd0); + } + descriptions.add("gemcscSegments", desc); +} + void GEMCSCSegmentProducer::produce(edm::Event& ev, const edm::EventSetup& setup) { LogDebug("GEMCSCSegment") << "start producing segments for " << ++iev << "th event w/ gem and csc data"; diff --git a/RecoLocalMuon/GEMCSCSegment/plugins/GEMCSCSegmentProducer.h b/RecoLocalMuon/GEMCSCSegment/plugins/GEMCSCSegmentProducer.h index 49ce0c336874d..cdf252d75abd6 100644 --- a/RecoLocalMuon/GEMCSCSegment/plugins/GEMCSCSegmentProducer.h +++ b/RecoLocalMuon/GEMCSCSegment/plugins/GEMCSCSegmentProducer.h @@ -14,6 +14,8 @@ #include "FWCore/Framework/interface/Event.h" #include "FWCore/Framework/interface/ESHandle.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" +#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" #include "FWCore/Utilities/interface/InputTag.h" #include "DataFormats/CSCRecHit/interface/CSCSegmentCollection.h" @@ -31,6 +33,8 @@ class GEMCSCSegmentProducer : public edm::stream::EDProducer<> { explicit GEMCSCSegmentProducer(const edm::ParameterSet&); /// Destructor ~GEMCSCSegmentProducer() override; + /// generate gemcscSegment_cfi + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); /// Produce the GEM-CSCSegment collection void produce(edm::Event&, const edm::EventSetup&) override; diff --git a/RecoLocalMuon/GEMCSCSegment/python/gemcscSegments_cff.py b/RecoLocalMuon/GEMCSCSegment/python/gemcscSegments_cff.py new file mode 100644 index 0000000000000..8d7066dd81dfc --- /dev/null +++ b/RecoLocalMuon/GEMCSCSegment/python/gemcscSegments_cff.py @@ -0,0 +1,6 @@ +import FWCore.ParameterSet.Config as cms + +from RecoLocalMuon.GEMCSCSegment.gemcscSegments_cfi import gemcscSegments + +from Configuration.ProcessModifiers.gemcscSegmentsTesting_cff import gemcscSegmentsTesting +gemcscSegmentsTesting.toModify(gemcscSegments, enableME21GE21=True) diff --git a/RecoLocalMuon/GEMCSCSegment/python/gemcscSegments_cfi.py b/RecoLocalMuon/GEMCSCSegment/python/gemcscSegments_cfi.py deleted file mode 100644 index 1ddb62b1e3b4e..0000000000000 --- a/RecoLocalMuon/GEMCSCSegment/python/gemcscSegments_cfi.py +++ /dev/null @@ -1,29 +0,0 @@ -import FWCore.ParameterSet.Config as cms - -gemcscSegments = cms.EDProducer("GEMCSCSegmentProducer", - # define input - inputObjectsGEM = cms.InputTag("gemRecHits"), - inputObjectsCSC = cms.InputTag("cscSegments"), - # inputObjectsGEM = cms.InputTag("gemRecHits","","RECO"), - # inputObjectsCSC = cms.InputTag("cscSegments","","RECO"), - algo_name = cms.string("GEMCSCSegAlgoRR"), - algo_psets = cms.PSet( - GEMCSCDebug = cms.untracked.bool(True), - minHitsPerSegment = cms.uint32(2), - preClustering = cms.bool(True), - dXclusBoxMax = cms.double(1.), - dYclusBoxMax = cms.double(5.), - preClusteringUseChaining = cms.bool(True), - dPhiChainBoxMax = cms.double(1.0), - # dPhiChainBoxMax = cms.double(0.02), - # dPhiChainBoxMax = cms.double(0.01), - # dPhiChainBoxMax = cms.double(0.005), - # dPhiChainBoxMax = cms.double(0.0025), - # dPhiChainBoxMax = cms.double(0.001), - # dPhiChainBoxMax = cms.double(0.), - # dThetaChainBoxMax = cms.double(1.), - dThetaChainBoxMax = cms.double(0.02), - dRChainBoxMax = cms.double(0.5), - maxRecHitsInCluster = cms.int32(6) - ) -) diff --git a/RecoLocalMuon/GEMCSCSegment/test/BuildFile.xml b/RecoLocalMuon/GEMCSCSegment/test/BuildFile.xml index 4083d98dedcee..fc1b23018b6ea 100644 --- a/RecoLocalMuon/GEMCSCSegment/test/BuildFile.xml +++ b/RecoLocalMuon/GEMCSCSegment/test/BuildFile.xml @@ -9,6 +9,7 @@ + @@ -16,6 +17,8 @@ + + diff --git a/RecoLocalMuon/GEMCSCSegment/test/GEMCSCCoincidenceRateAnalyzer.cc b/RecoLocalMuon/GEMCSCSegment/test/GEMCSCCoincidenceRateAnalyzer.cc new file mode 100644 index 0000000000000..93a00e0a1ee8d --- /dev/null +++ b/RecoLocalMuon/GEMCSCSegment/test/GEMCSCCoincidenceRateAnalyzer.cc @@ -0,0 +1,356 @@ +#ifndef RecoLocalMuon_GEMCSCSegment_GEMCSCCoincidenceRateAnalyzer_h +#define RecoLocalMuon_GEMCSCSegment_GEMCSCCoincidenceRateAnalyzer_h +/** \class GEMCSCCoincidenceRateAnalyzer + * + * \author Seungjin Yang + */ +#include +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/one/EDAnalyzer.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/ESHandle.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" +#include "FWCore/ServiceRegistry/interface/Service.h" +#include "FWCore/Utilities/interface/InputTag.h" +#include "DataFormats/GEMRecHit/interface/GEMCSCSegmentCollection.h" +#include "DataFormats/GEMDigi/interface/GEMVFATStatusCollection.h" +#include "DataFormats/GEMDigi/interface/GEMOHStatusCollection.h" +#include "DataFormats/MuonReco/interface/Muon.h" +#include "DataFormats/MuonReco/interface/MuonFwd.h" +#include "DataFormats/MuonDetId/interface/CSCDetId.h" +#include "DataFormats/MuonDetId/interface/GEMDetId.h" +#include "DataFormats/MuonReco/interface/MuonChamberMatch.h" +#include "Geometry/Records/interface/MuonGeometryRecord.h" + +#include "CommonTools/UtilAlgos/interface/TFileService.h" +#include "FWCore/ServiceRegistry/interface/Service.h" + +#include "TTree.h" + +class GEMCSCCoincidenceRateAnalyzer : public edm::one::EDAnalyzer { +public: + explicit GEMCSCCoincidenceRateAnalyzer(const edm::ParameterSet&); + ~GEMCSCCoincidenceRateAnalyzer() override; + static void fillDescriptions(edm::ConfigurationDescriptions&); + +private: + void analyze(const edm::Event&, const edm::EventSetup&) override; + + void resetBranches(); + bool analyzeGEMCSCSegment(const GEMCSCSegment&, + const GEMOHStatusCollection*, + const GEMVFATStatusCollection*, + const std::vector&); + + bool checkGEMChamberStatus(const GEMDetId& chamber_id, const GEMOHStatusCollection*, const GEMVFATStatusCollection*); + std::vector findMuonSegments(const reco::MuonCollection*); + bool isMuonSegment(const CSCSegment&, const std::vector); + bool checkCSCChamberType(const CSCDetId&); + + const edm::EDGetTokenT gem_csc_segment_collection_token_; + const edm::EDGetTokenT gem_oh_status_collection_token_; + const edm::EDGetTokenT gem_vfat_status_collection_token_; + const edm::EDGetTokenT muon_collection_token_; + const std::string log_category_; + const bool use_gem_daq_status_; + const std::vector csc_whitelist_; + + // + TTree* tree_; + //// GEMCSCSegment + int b_region_; + int b_station_; + int b_ring_; + int b_chamber_; + bool b_gem_chamber_has_error_; + float b_norm_chi2_; + //// CSCSegment + float b_csc_norm_chi2_; + int b_csc_num_hit_; + bool b_csc_is_muon_; + //// GEMRecHit + int b_gem_num_hit; + std::vector b_gem_layer_; + std::vector b_gem_ieta_; + std::vector b_gem_first_strip_; + std::vector b_gem_cls_; +}; + +GEMCSCCoincidenceRateAnalyzer::GEMCSCCoincidenceRateAnalyzer(const edm::ParameterSet& ps) + : gem_csc_segment_collection_token_( + consumes(ps.getUntrackedParameter("gemcscSegmentTag"))), + gem_oh_status_collection_token_( + consumes(ps.getUntrackedParameter("ohStatusTag"))), + gem_vfat_status_collection_token_( + consumes(ps.getUntrackedParameter("vfatStatusTag"))), + muon_collection_token_(consumes(ps.getUntrackedParameter("muonTag"))), + log_category_(ps.getUntrackedParameter("logCategory")), + use_gem_daq_status_(ps.getUntrackedParameter("useGEMDAQStatus")), + csc_whitelist_(ps.getUntrackedParameter >("cscWhitelist")) { + usesResource(TFileService::kSharedResource); + + edm::Service file_service; + tree_ = file_service->make("gemcsc", "gemcsc"); + + tree_->Branch("region", &b_region_); + tree_->Branch("station", &b_station_); + tree_->Branch("ring", &b_ring_); + tree_->Branch("chamber", &b_chamber_); + tree_->Branch("gem_chamber_has_error", &b_gem_chamber_has_error_, "gem_chamber_has_error/O"); + + tree_->Branch("norm_chi2", &b_norm_chi2_); + tree_->Branch("csc_norm_chi2", &b_csc_norm_chi2_); + tree_->Branch("csc_num_hit", &b_csc_num_hit_); + tree_->Branch("csc_is_muon", &b_csc_is_muon_); + + tree_->Branch("gem_num_hit", &b_gem_num_hit); + tree_->Branch("gem_layer", &b_gem_layer_); + tree_->Branch("gem_ieta", &b_gem_ieta_); + tree_->Branch("gem_first_strip", &b_gem_first_strip_); + tree_->Branch("gem_cls", &b_gem_cls_); +} + +GEMCSCCoincidenceRateAnalyzer::~GEMCSCCoincidenceRateAnalyzer() {} + +void GEMCSCCoincidenceRateAnalyzer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + edm::ParameterSetDescription desc; + desc.addUntracked("ohStatusTag", edm::InputTag("muonGEMDigis", "OHStatus")); + desc.addUntracked("vfatStatusTag", edm::InputTag("muonGEMDigis", "VFATStatus")); + desc.addUntracked("logCategory", "GEMCSCCoincidenceRateAnalyzer"); + desc.addUntracked("gemcscSegmentTag", edm::InputTag("gemcscSegments")); + desc.addUntracked("muonTag", edm::InputTag("muons")); + desc.addUntracked("useGEMDAQStatus", false); + desc.addUntracked >("cscWhitelist", + {CSCDetId::iChamberType(1, 1), CSCDetId::iChamberType(2, 1)}); + descriptions.addWithDefaultLabel(desc); +} + +void GEMCSCCoincidenceRateAnalyzer::analyze(const edm::Event& event, const edm::EventSetup&) { + ///////////////////////////////////////////////////////////////////////////// + // get data from edm::Event + ///////////////////////////////////////////////////////////////////////////// + const GEMCSCSegmentCollection* gem_csc_segment_collection = nullptr; + if (const edm::Handle handle = event.getHandle(gem_csc_segment_collection_token_)) { + gem_csc_segment_collection = handle.product(); + + } else { + edm::LogError(log_category_) << "failed to get GEMCSCSegmentCollection"; + return; + } + + const GEMOHStatusCollection* gem_oh_status_collection = nullptr; + const GEMVFATStatusCollection* gem_vfat_status_collection = nullptr; + if (use_gem_daq_status_) { + if (auto handle = event.getHandle(gem_oh_status_collection_token_)) { + gem_oh_status_collection = handle.product(); + + } else { + edm::LogError(log_category_) << "failed to get OHVFATStatusCollection"; + return; + } + + if (auto handle = event.getHandle(gem_vfat_status_collection_token_)) { + gem_vfat_status_collection = handle.product(); + + } else { + edm::LogError(log_category_) << "failed to get GEMVFATStatusCollection"; + return; + } + } + + const reco::MuonCollection* muon_collection = nullptr; + if (const edm::Handle handle = event.getHandle(muon_collection_token_)) { + muon_collection = handle.product(); + + } else { + edm::LogError(log_category_) << "failed to get reco::MuonCollection"; + return; + } + + ///////////////////////////////////////////////////////////////////////////// + // analyze + ///////////////////////////////////////////////////////////////////////////// + const std::vector muon_segment_vec = findMuonSegments(muon_collection); + + for (edm::OwnVector::const_iterator iter = gem_csc_segment_collection->begin(); + iter != gem_csc_segment_collection->end(); + iter++) { + const GEMCSCSegment& gem_csc_segment = *iter; + if (not checkCSCChamberType(gem_csc_segment.cscDetId())) { + continue; + } + resetBranches(); + if (analyzeGEMCSCSegment(gem_csc_segment, gem_oh_status_collection, gem_vfat_status_collection, muon_segment_vec)) { + tree_->Fill(); + } + } // GEMCSCSegment +} + +void GEMCSCCoincidenceRateAnalyzer::resetBranches() { + // detector + b_region_ = 0; + b_station_ = 0; + b_ring_ = 0; + b_chamber_ = 0; + b_gem_chamber_has_error_ = false; + // GEMCSCSegment + b_norm_chi2_ = 0.0f; + // CSCSegment + b_csc_norm_chi2_ = 0.0f; + b_csc_num_hit_ = 0; + b_csc_is_muon_ = false; + // GEMRecHit + b_gem_num_hit = 0; + b_gem_layer_.clear(); + b_gem_ieta_.clear(); + b_gem_first_strip_.clear(); + b_gem_cls_.clear(); +} + +// Main function to analyzer GEMCSCSegment. +// Returns a boolean indicating whether the GEMCSCSegment analysis is successful. +bool GEMCSCCoincidenceRateAnalyzer::analyzeGEMCSCSegment(const GEMCSCSegment& gem_csc_segment, + const GEMOHStatusCollection* gem_oh_status_collection, + const GEMVFATStatusCollection* gem_vfat_status_collection, + const std::vector& muon_segment_vec) { + const CSCDetId csc_id = gem_csc_segment.cscDetId(); + const CSCSegment csc_segment = gem_csc_segment.cscSegment(); + const std::vector& gem_hit_vec = gem_csc_segment.gemRecHits(); + // GEMDetId(int region, int ring, int station, int layer, int chamber, int ieta) + const GEMDetId gem_chamber_id{csc_id.zendcap(), 1, csc_id.station(), 0, csc_id.chamber(), 0}; + + // detector + b_region_ = csc_id.zendcap(); + b_station_ = csc_id.station(); + b_ring_ = csc_id.ring(); + b_chamber_ = csc_id.chamber(); + b_gem_chamber_has_error_ = + use_gem_daq_status_ ? checkGEMChamberStatus(gem_chamber_id, gem_oh_status_collection, gem_vfat_status_collection) + : false; + // GEMCSCSegment + b_norm_chi2_ = static_cast(gem_csc_segment.chi2() / gem_csc_segment.nRecHits()); + // CSCSegment + b_csc_norm_chi2_ = static_cast(csc_segment.chi2() / csc_segment.nRecHits()); + b_csc_num_hit_ = csc_segment.nRecHits(); + b_csc_is_muon_ = isMuonSegment(csc_segment, muon_segment_vec); + // GEMRecHit + b_gem_num_hit = gem_hit_vec.size(); + + b_gem_layer_.reserve(b_gem_num_hit); + b_gem_ieta_.reserve(b_gem_num_hit); + b_gem_first_strip_.reserve(b_gem_num_hit); + b_gem_cls_.reserve(b_gem_num_hit); + + for (const GEMRecHit& gem_hit : gem_hit_vec) { + const GEMDetId gem_id = gem_hit.gemId(); + + b_gem_layer_.push_back(gem_id.layer()); + b_gem_ieta_.push_back(gem_id.ieta()); + b_gem_first_strip_.push_back(gem_hit.firstClusterStrip()); + b_gem_cls_.push_back(gem_hit.clusterSize()); + } // GEMRecHit + + return true; +} + +// Returns a vector of CSCSegments, which are matched with muons. +std::vector GEMCSCCoincidenceRateAnalyzer::findMuonSegments( + const reco::MuonCollection* muon_collection) { + std::vector muon_segment_vec; + + for (const reco::Muon& muon : *muon_collection) { + for (const reco::MuonChamberMatch& chamber_match : muon.matches()) { + if (chamber_match.detector() != MuonSubdetId::CSC) { + continue; + } + + if (checkCSCChamberType(chamber_match.id)) { + for (const reco::MuonSegmentMatch& segment_match : chamber_match.segmentMatches) { + if (segment_match.isMask(reco::MuonSegmentMatch::BestInStationByDR)) { + muon_segment_vec.push_back(segment_match.cscSegmentRef.get()); + break; + } + } // MuonSegmentMatch + } // checkCSCChamberType + } // MuonChamberMatch + } // MuonCollection + + return muon_segment_vec; +} + +// Returns a boolean indicating whether the given CSCSegment is matched with a +// muon. +// TODO better segment comparison +bool GEMCSCCoincidenceRateAnalyzer::isMuonSegment(const CSCSegment& csc_segment, + const std::vector muon_segment_vec) { + bool found = false; + + const CSCDetId csc_id = csc_segment.cscDetId(); + for (const CSCSegment* muon_segment : muon_segment_vec) { + if (csc_id != muon_segment->cscDetId()) + continue; + if (csc_segment.localPosition().x() != muon_segment->localPosition().x()) + continue; + if (csc_segment.localPosition().y() != muon_segment->localPosition().y()) + continue; + if (csc_segment.localPosition().z() != muon_segment->localPosition().z()) + continue; + if (csc_segment.time() != muon_segment->time()) + continue; + + found = true; + } + + return found; +} + +// Returns a boolean indicating whether the GEMChamber has any DAQ error. +bool GEMCSCCoincidenceRateAnalyzer::checkGEMChamberStatus(const GEMDetId& chamber_id, + const GEMOHStatusCollection* oh_status_collection, + const GEMVFATStatusCollection* vfat_status_collection) { + const bool has_error = true; + if (not use_gem_daq_status_) { + edm::LogError(log_category_) + << "useGEMDAQStatus is false but checkGEMChamberStatus is called. gem_chamber_has_error will be set to false"; + return not has_error; + } + + for (auto iter = oh_status_collection->begin(); iter != oh_status_collection->end(); iter++) { + const auto [oh_id, range] = (*iter); + if (chamber_id != oh_id) { + continue; + } + + for (auto oh_status = range.first; oh_status != range.second; oh_status++) { + if (oh_status->isBad()) { + // GEMOHStatus is bad. Mask this chamber. + return has_error; + } // isBad + } // range + } // collection + + for (auto iter = vfat_status_collection->begin(); iter != vfat_status_collection->end(); iter++) { + const auto [vfat_id, range] = (*iter); + if (chamber_id != vfat_id.chamberId()) { + continue; + } + for (auto vfat_status = range.first; vfat_status != range.second; vfat_status++) { + if (vfat_status->isBad()) { + return has_error; + } + } // range + } // collection + + return not has_error; +} + +// Returns a boolean indicating whether to allow a CSCDetId. +bool GEMCSCCoincidenceRateAnalyzer::checkCSCChamberType(const CSCDetId& csc_id) { + const auto csc_chamber_type = static_cast(csc_id.iChamberType()); + return std::find(csc_whitelist_.begin(), csc_whitelist_.end(), csc_chamber_type) != csc_whitelist_.end(); +} + +DEFINE_FWK_MODULE(GEMCSCCoincidenceRateAnalyzer); +#endif // RecoLocalMuon_GEMCSCSegment_GEMCSCCoincidenceRateAnalyzer_h diff --git a/RecoLocalMuon/GEMCSCSegment/test/runGEMCSCSegmentProducer_cfg.py b/RecoLocalMuon/GEMCSCSegment/test/runGEMCSCSegmentProducer_cfg.py index 63fb80a97540c..83b3a31d64564 100644 --- a/RecoLocalMuon/GEMCSCSegment/test/runGEMCSCSegmentProducer_cfg.py +++ b/RecoLocalMuon/GEMCSCSegment/test/runGEMCSCSegmentProducer_cfg.py @@ -94,7 +94,7 @@ process.contentAna = cms.EDAnalyzer("EventContentAnalyzer") -process.load('RecoLocalMuon.GEMCSCSegment.gemcscSegments_cfi') +process.load('RecoLocalMuon.GEMCSCSegment.gemcscSegments_cff') process.source = cms.Source("PoolSource", fileNames = cms.untracked.vstring(