diff --git a/L1Trigger/CSCTriggerPrimitives/README.md b/L1Trigger/CSCTriggerPrimitives/README.md index 3cbd301fe56f3..b10d4023df033 100644 --- a/L1Trigger/CSCTriggerPrimitives/README.md +++ b/L1Trigger/CSCTriggerPrimitives/README.md @@ -1,3 +1,8 @@ # L1Trigger/CSCTriggerPrimitives Documentation -Please refer to https://gitlab.cern.ch/tdr/notes/DN-21-019/blob/master/temp/DN-21-019_temp.pdf +Please refer to this important documentation: +* GEM, CSC, GEM-CSC, and HMT dataformat https://gitlab.cern.ch/tdr/notes/DN-20-016/blob/master/temp/DN-20-016_temp.pdf +* GEM, CSC, GEM-CSC, and HMT trigger algorithm https://gitlab.cern.ch/tdr/notes/DN-21-019/blob/master/temp/DN-21-019_temp.pdf +* CCLUT algorithm https://gitlab.cern.ch/tdr/notes/DN-19-059/blob/master/temp/DN-19-059_temp.pdf +* Hadronic shower trigger algorithm: https://gitlab.cern.ch/tdr/notes/DN-20-033/blob/master/temp/DN-20-033_temp.pdf +* Note describing the CSC firmware and CSC DAQ format https://github.com/csc-fw/otmb_fw_docs \ No newline at end of file diff --git a/L1Trigger/CSCTriggerPrimitives/interface/CSCBaseboard.h b/L1Trigger/CSCTriggerPrimitives/interface/CSCBaseboard.h index 76df7a6588439..dad5ad2575e8d 100644 --- a/L1Trigger/CSCTriggerPrimitives/interface/CSCBaseboard.h +++ b/L1Trigger/CSCTriggerPrimitives/interface/CSCBaseboard.h @@ -53,6 +53,11 @@ class CSCBaseboard { bool isME21_; bool isME31_; bool isME41_; + bool isME12_; + bool isME22_; + bool isME32_; + bool isME42_; + bool isME13_; // CSCDetId for this chamber CSCDetId cscId_; @@ -104,5 +109,7 @@ class CSCBaseboard { bool runME41Up_; bool runCCLUT_; + bool runCCLUT_TMB_; + bool runCCLUT_OTMB_; }; #endif diff --git a/L1Trigger/CSCTriggerPrimitives/plugins/CSCTriggerPrimitivesProducer.cc b/L1Trigger/CSCTriggerPrimitives/plugins/CSCTriggerPrimitivesProducer.cc index cd1b0cb18fb28..6133a4b6e8c85 100644 --- a/L1Trigger/CSCTriggerPrimitives/plugins/CSCTriggerPrimitivesProducer.cc +++ b/L1Trigger/CSCTriggerPrimitives/plugins/CSCTriggerPrimitivesProducer.cc @@ -99,8 +99,12 @@ class CSCTriggerPrimitivesProducer : public edm::one::EDProducer<> { // write out showrs bool keepShowers_; - // switch to enable the integrated local triggers in ME11 and ME21 - bool runCCLUT_; + // switches to enable the Run-3 pattern finding + bool runCCLUT_; // 'OR' of the two options below + bool runCCLUT_TMB_; // ME1/2, ME1/3, ME2/2, ME3/2, ME4/2 + bool runCCLUT_OTMB_; // ME1/1, ME2/1, ME3/1, ME4/1 + + bool runILT_; // // 'OR' of the two options below bool runME11ILT_; bool runME21ILT_; }; @@ -126,13 +130,17 @@ CSCTriggerPrimitivesProducer::CSCTriggerPrimitivesProducer(const edm::ParameterS // check whether you need to run the integrated local triggers const edm::ParameterSet commonParam(conf.getParameter("commonParam")); - runCCLUT_ = commonParam.getParameter("runCCLUT"); + runCCLUT_TMB_ = commonParam.getParameter("runCCLUT_TMB"); + runCCLUT_OTMB_ = commonParam.getParameter("runCCLUT_OTMB"); + runCCLUT_ = runCCLUT_TMB_ or runCCLUT_OTMB_; + runME11ILT_ = commonParam.getParameter("runME11ILT"); runME21ILT_ = commonParam.getParameter("runME21ILT"); + runILT_ = runME11ILT_ or runME21ILT_; wire_token_ = consumes(wireDigiProducer_); comp_token_ = consumes(compDigiProducer_); - if (runME11ILT_ or runME21ILT_) + if (runILT_) gem_pad_cluster_token_ = consumes(gemPadDigiClusterProducer_); cscToken_ = esConsumes(); gemToken_ = esConsumes(); @@ -162,7 +170,7 @@ CSCTriggerPrimitivesProducer::CSCTriggerPrimitivesProducer(const edm::ParameterS produces(); produces("Anode"); } - if (runME11ILT_ or runME21ILT_) { + if (runILT_) { produces(); } // temporarily switch to a "one" module with a CSCTriggerPrimitivesBuilder data member @@ -177,7 +185,7 @@ void CSCTriggerPrimitivesProducer::produce(edm::Event& ev, const edm::EventSetup // get the gem geometry if it's there edm::ESHandle h_gem = setup.getHandle(gemToken_); - if (runME11ILT_ or runME21ILT_) { + if (runILT_) { if (h_gem.isValid()) { builder_->setGEMGeometry(&*h_gem); } else { @@ -241,7 +249,7 @@ void CSCTriggerPrimitivesProducer::produce(edm::Event& ev, const edm::EventSetup // input GEM pad cluster collection for upgrade scenarios const GEMPadDigiClusterCollection* gemPadClusters = nullptr; - if (runME11ILT_ or runME21ILT_) { + if (runILT_) { if (!gemPadDigiClusterProducer_.label().empty()) { edm::Handle gemPadDigiClusters; ev.getByToken(gem_pad_cluster_token_, gemPadDigiClusters); @@ -313,7 +321,7 @@ void CSCTriggerPrimitivesProducer::produce(edm::Event& ev, const edm::EventSetup } // only put GEM copad collections in the event when the // integrated local triggers are running - if (runME11ILT_ or runME21ILT_) + if (runILT_) ev.put(std::move(oc_gemcopad)); } diff --git a/L1Trigger/CSCTriggerPrimitives/python/params/auxiliaryParams.py b/L1Trigger/CSCTriggerPrimitives/python/params/auxiliaryParams.py index 16a5ecb29cf07..8dc897d33a94a 100644 --- a/L1Trigger/CSCTriggerPrimitives/python/params/auxiliaryParams.py +++ b/L1Trigger/CSCTriggerPrimitives/python/params/auxiliaryParams.py @@ -30,7 +30,10 @@ # comparator-code algorithm to improve # CLCT position and bending resolution - runCCLUT = cms.bool(False), + # CCLUT for TMB is NOT planned for startup Run-3 + runCCLUT_TMB = cms.bool(False), + # CCLUT for OTMB is planned for startup Run-3 + runCCLUT_OTMB = cms.bool(False), ## Phase-2 version is not needed for Run-3 enableAlctPhase2 = cms.bool(False) diff --git a/L1Trigger/CSCTriggerPrimitives/src/CSCBaseboard.cc b/L1Trigger/CSCTriggerPrimitives/src/CSCBaseboard.cc index bea2dc5550f38..1351fce105ccd 100644 --- a/L1Trigger/CSCTriggerPrimitives/src/CSCBaseboard.cc +++ b/L1Trigger/CSCTriggerPrimitives/src/CSCBaseboard.cc @@ -16,7 +16,14 @@ CSCBaseboard::CSCBaseboard(unsigned endcap, isME21_ = (theStation == 2 && theRing == 1); isME31_ = (theStation == 3 && theRing == 1); isME41_ = (theStation == 4 && theRing == 1); - + isME12_ = (theStation == 1 && theRing == 2); + isME22_ = (theStation == 2 && theRing == 2); + isME32_ = (theStation == 3 && theRing == 2); + isME42_ = (theStation == 4 && theRing == 2); + isME13_ = (theStation == 1 && theRing == 3); + + const bool hasTMB(isME12_ or isME22_ or isME32_ or isME42_ or isME13_); + const bool hasOTMB(isME11_ or isME21_ or isME31_ or isME41_); cscId_ = CSCDetId(theEndcap, theStation, theRing, theChamber, 0); commonParams_ = conf.getParameter("commonParam"); @@ -41,7 +48,10 @@ CSCBaseboard::CSCBaseboard(unsigned endcap, runME11ILT_ = commonParams_.getParameter("runME11ILT"); runME21ILT_ = commonParams_.getParameter("runME21ILT"); - runCCLUT_ = commonParams_.getParameter("runCCLUT"); + runCCLUT_TMB_ = commonParams_.getParameter("runCCLUT_TMB"); + runCCLUT_OTMB_ = commonParams_.getParameter("runCCLUT_OTMB"); + // check if CCLUT should be on in this chamber + runCCLUT_ = (hasTMB and runCCLUT_TMB_) or (hasOTMB and runCCLUT_OTMB_); // general case tmbParams_ = conf.getParameter("tmbPhase1"); diff --git a/L1Trigger/CSCTriggerPrimitives/src/GEMClusterProcessor.cc b/L1Trigger/CSCTriggerPrimitives/src/GEMClusterProcessor.cc index b36fd7cf9d182..215076bb6fe23 100644 --- a/L1Trigger/CSCTriggerPrimitives/src/GEMClusterProcessor.cc +++ b/L1Trigger/CSCTriggerPrimitives/src/GEMClusterProcessor.cc @@ -36,6 +36,11 @@ void GEMClusterProcessor::run(const GEMPadDigiClusterCollection* in_clusters) { // Step 1: clear the GEMInternalCluster vector clear(); + if (in_clusters == nullptr) { + edm::LogWarning("GEMClusterProcessor") << "Attempt to run without valid in_clusters pointer."; + return; + } + // Step 2: put coincidence clusters in GEMInternalCluster vector addCoincidenceClusters(in_clusters); diff --git a/L1Trigger/L1TMuonEndCap/interface/PrimitiveConversion.h b/L1Trigger/L1TMuonEndCap/interface/PrimitiveConversion.h index 7f0241707dd40..0db5c976f2bf1 100644 --- a/L1Trigger/L1TMuonEndCap/interface/PrimitiveConversion.h +++ b/L1Trigger/L1TMuonEndCap/interface/PrimitiveConversion.h @@ -24,7 +24,8 @@ class PrimitiveConversion { bool useNewZones, bool fixME11Edges, bool bugME11Dupes, - bool useRun3CCLUT); + bool useRun3CCLUT_OTMB, + bool useRun3CCLUT_TMB); void process(const std::map& selected_prim_map, EMTFHitCollection& conv_hits) const; @@ -105,7 +106,8 @@ class PrimitiveConversion { bool duplicateTheta_, fixZonePhi_, useNewZones_, fixME11Edges_; bool bugME11Dupes_; // Run 3 CCLUT algorithm - bool useRun3CCLUT_; + bool useRun3CCLUT_OTMB_; + bool useRun3CCLUT_TMB_; }; #endif diff --git a/L1Trigger/L1TMuonEndCap/interface/VersionControl.h b/L1Trigger/L1TMuonEndCap/interface/VersionControl.h index 13e7f5491a9f5..091157433a22f 100644 --- a/L1Trigger/L1TMuonEndCap/interface/VersionControl.h +++ b/L1Trigger/L1TMuonEndCap/interface/VersionControl.h @@ -36,7 +36,8 @@ class VersionControl { // For primitive conversion std::vector zoneBoundaries_; int zoneOverlap_; - bool includeNeighbor_, duplicateTheta_, fixZonePhi_, useNewZones_, fixME11Edges_, useRun3CCLUT_; + bool includeNeighbor_, duplicateTheta_, fixZonePhi_, useNewZones_, fixME11Edges_, useRun3CCLUT_OTMB_, + useRun3CCLUT_TMB_; // For pattern recognition std::vector pattDefinitions_, symPattDefinitions_; diff --git a/L1Trigger/L1TMuonEndCap/python/simEmtfDigis_cfi.py b/L1Trigger/L1TMuonEndCap/python/simEmtfDigis_cfi.py index fae3fdacbe077..3e17e502f63d4 100644 --- a/L1Trigger/L1TMuonEndCap/python/simEmtfDigis_cfi.py +++ b/L1Trigger/L1TMuonEndCap/python/simEmtfDigis_cfi.py @@ -20,7 +20,8 @@ Era = cms.string('Run2_2018'), # New Run 3 CSC TPs using CCLUT algorithm - UseRun3CCLUT = cms.bool(False), + UseRun3CCLUT_OTMB = cms.bool(False), + UseRun3CCLUT_TMB = cms.bool(False), # Input collections # Three options for CSCInput @@ -163,5 +164,4 @@ ## Era: Run3_2021 from Configuration.Eras.Modifier_stage2L1Trigger_2021_cff import stage2L1Trigger_2021 -stage2L1Trigger_2021.toModify(simEmtfDigis, RPCEnable = cms.bool(True), UseRun3CCLUT = cms.bool(False), Era = cms.string('Run3_2021')) - +stage2L1Trigger_2021.toModify(simEmtfDigis, RPCEnable = cms.bool(True), UseRun3CCLUT_OTMB = cms.bool(False), Era = cms.string('Run3_2021')) diff --git a/L1Trigger/L1TMuonEndCap/src/PrimitiveConversion.cc b/L1Trigger/L1TMuonEndCap/src/PrimitiveConversion.cc index dd6d761b62f69..fa13e4e98ea28 100644 --- a/L1Trigger/L1TMuonEndCap/src/PrimitiveConversion.cc +++ b/L1Trigger/L1TMuonEndCap/src/PrimitiveConversion.cc @@ -21,7 +21,8 @@ void PrimitiveConversion::configure(const GeometryTranslator* tp_geom, bool useNewZones, bool fixME11Edges, bool bugME11Dupes, - bool useRun3CCLUT) { + bool useRun3CCLUT_OTMB, + bool useRun3CCLUT_TMB) { emtf_assert(tp_geom != nullptr); emtf_assert(pc_lut != nullptr); @@ -47,7 +48,8 @@ void PrimitiveConversion::configure(const GeometryTranslator* tp_geom, bugME11Dupes_ = bugME11Dupes; // Run 3 CCLUT algorithm - useRun3CCLUT_ = useRun3CCLUT; + useRun3CCLUT_OTMB_ = useRun3CCLUT_OTMB; + useRun3CCLUT_TMB_ = useRun3CCLUT_TMB; } void PrimitiveConversion::process(const std::map& selected_prim_map, @@ -127,6 +129,29 @@ void PrimitiveConversion::convert_csc(int pc_sector, } } + // Calculate Pattern + unsigned pattern = tp_data.pattern; + const auto& detid(conv_hit.CreateCSCDetId()); + const bool isOTMB(detid.isME11() or detid.isME21() or detid.isME31() or detid.isME41()); + const bool isTMB((detid.isME12() or detid.isME22() or detid.isME32() or detid.isME42()) or (detid.isME13())); + + // check if CCLUT is on for this CSC TP + const bool useRun3CCLUT((useRun3CCLUT_OTMB_ and isOTMB) or (useRun3CCLUT_TMB_ and isTMB)); + if (useRun3CCLUT) { + // convert slope to Run-2 pattern for CSC TPs coming from MEX/1 chambers + // where the CCLUT algorithm is enabled + const unsigned slopeList[32] = {10, 10, 10, 8, 8, 8, 6, 6, 6, 4, 4, 4, 2, 2, 2, 2, + 10, 10, 10, 9, 9, 9, 7, 7, 7, 5, 5, 5, 3, 3, 3, 3}; + + // this LUT follows the same convention as in CSCPatternBank.cc + unsigned slope_and_sign(tp_data.slope); + if (tp_data.bend == 0) { + slope_and_sign += 16; + } + unsigned run2_converted_PID = slopeList[slope_and_sign]; + pattern = run2_converted_PID; + } + // Set properties conv_hit.SetCSCDetId(tp_detId); @@ -157,7 +182,7 @@ void PrimitiveConversion::convert_csc(int pc_sector, //conv_hit.set_strip_hi ( tp_data.strip_hi ); conv_hit.set_wire(tp_data.keywire); conv_hit.set_quality(tp_data.quality); - conv_hit.set_pattern(tp_data.pattern); + conv_hit.set_pattern(pattern); conv_hit.set_bend(tp_data.bend); conv_hit.set_time(0.); // No fine resolution timing conv_hit.set_alct_quality(tp_data.alct_quality); @@ -295,16 +320,23 @@ void PrimitiveConversion::convert_csc_details(EMTFHit& conv_hit) const { if (bugStrip0BeforeFW48200 == false && fw_strip == 0 && clct_pat_corr_sign == -1) clct_pat_corr = 0; + // check if the CCLUT algorithm is on in this chamber + const auto& detid(conv_hit.CreateCSCDetId()); + const bool isOTMB(detid.isME11() or detid.isME21() or detid.isME31() or detid.isME41()); + const bool isTMB((detid.isME12() or detid.isME22() or detid.isME32() or detid.isME42()) or (detid.isME13())); + + const bool useRun3CCLUT((useRun3CCLUT_OTMB_ and isOTMB) or (useRun3CCLUT_TMB_ and isTMB)); + if (is_10degree) { eighth_strip = fw_strip << 2; // full precision, uses only 2 bits of pattern correction - if (useRun3CCLUT_) { + if (useRun3CCLUT) { eighth_strip += (conv_hit.Strip_quart_bit() << 1 | conv_hit.Strip_eighth_bit() << 0); // Run 3 CCLUT variables } else { eighth_strip += clct_pat_corr_sign * (clct_pat_corr >> 1); } } else { eighth_strip = fw_strip << 3; // multiply by 2, uses all 3 bits of pattern correction - if (useRun3CCLUT_) { + if (useRun3CCLUT) { eighth_strip += (conv_hit.Strip_quart_bit() << 2 | conv_hit.Strip_eighth_bit() << 1); // Run 3 CCLUT variables } else { eighth_strip += clct_pat_corr_sign * (clct_pat_corr >> 0); diff --git a/L1Trigger/L1TMuonEndCap/src/SectorProcessor.cc b/L1Trigger/L1TMuonEndCap/src/SectorProcessor.cc index f8af283c0b949..8cdb84d1f38ab 100644 --- a/L1Trigger/L1TMuonEndCap/src/SectorProcessor.cc +++ b/L1Trigger/L1TMuonEndCap/src/SectorProcessor.cc @@ -106,7 +106,8 @@ void SectorProcessor::process_single_bx(int bx, cfg.useNewZones_, cfg.fixME11Edges_, cfg.bugME11Dupes_, - cfg.useRun3CCLUT_); + cfg.useRun3CCLUT_OTMB_, + cfg.useRun3CCLUT_TMB_); PatternRecognition patt_recog; patt_recog.configure(verbose_, diff --git a/L1Trigger/L1TMuonEndCap/src/VersionControl.cc b/L1Trigger/L1TMuonEndCap/src/VersionControl.cc index 97a6300a385db..4333e56affb88 100644 --- a/L1Trigger/L1TMuonEndCap/src/VersionControl.cc +++ b/L1Trigger/L1TMuonEndCap/src/VersionControl.cc @@ -6,7 +6,8 @@ VersionControl::VersionControl(const edm::ParameterSet& iConfig) : config_(iConf useO2O_ = iConfig.getParameter("FWConfig"); era_ = iConfig.getParameter("Era"); // Run 3 CCLUT - useRun3CCLUT_ = iConfig.getParameter("UseRun3CCLUT"); + useRun3CCLUT_OTMB_ = iConfig.getParameter("UseRun3CCLUT_OTMB"); + useRun3CCLUT_TMB_ = iConfig.getParameter("UseRun3CCLUT_TMB"); useDT_ = iConfig.getParameter("DTEnable"); useCSC_ = iConfig.getParameter("CSCEnable");