diff --git a/DataFormats/L1TMuon/interface/EMTFHit.h b/DataFormats/L1TMuon/interface/EMTFHit.h index 18f6252c82c73..b0fc9bdca9b97 100644 --- a/DataFormats/L1TMuon/interface/EMTFHit.h +++ b/DataFormats/L1TMuon/interface/EMTFHit.h @@ -49,10 +49,16 @@ namespace l1t { strip(-99), strip_hi(-99), strip_low(-99), + strip_quart(-99), // Run 3 + strip_eighth(-99), // Run 3 + strip_quart_bit(-99), // Run 3 + strip_eighth_bit(-99), // Run 3 track_num(-99), quality(-99), pattern(-99), + pattern_run3(-99), // Run 3 bend(-99), + slope(-99), // Run 3 valid(-99), sync_err(-99), layer(-99), // TODO: verify inclusion for GEM, or better to generalize this class... - JS 06.07.20 @@ -148,10 +154,16 @@ namespace l1t { void set_strip(int bits) { strip = bits; } void set_strip_hi(int bits) { strip_hi = bits; } void set_strip_low(int bits) { strip_low = bits; } + void set_strip_quart(int bits) { strip_quart = bits; } // Run 3 + void set_strip_eighth(int bits) { strip_eighth = bits; } // Run 3 + void set_strip_quart_bit(int bits) { strip_quart_bit = bits; } // Run 3 + void set_strip_eighth_bit(int bits) { strip_eighth_bit = bits; } // Run 3 void set_track_num(int bits) { track_num = bits; } void set_quality(int bits) { quality = bits; } void set_pattern(int bits) { pattern = bits; } + void set_pattern_run3(int bits) { pattern_run3 = bits; } // Run 3 void set_bend(int bits) { bend = bits; } + void set_slope(int bits) { slope = bits; } // Run 3 void set_valid(int bits) { valid = bits; } void set_sync_err(int bits) { sync_err = bits; } // GEM specific aliases @@ -210,10 +222,16 @@ namespace l1t { int Strip() const { return strip; } int Strip_hi() const { return strip_hi; } int Strip_low() const { return strip_low; } + int Strip_quart() const { return strip_quart; } // Run 3 + int Strip_eighth() const { return strip_eighth; } // Run 3 + int Strip_quart_bit() const { return strip_quart_bit; } // Run 3 + int Strip_eighth_bit() const { return strip_eighth_bit; } // Run 3 int Track_num() const { return track_num; } int Quality() const { return quality; } int Pattern() const { return pattern; } + int Pattern_run3() const { return pattern_run3; } // Run 3 int Bend() const { return bend; } + int Slope() const { return slope; } // Run 3 int Valid() const { return valid; } int Sync_err() const { return sync_err; } // GEM specific aliases for member variables that don't match GEM nomenclature @@ -295,20 +313,26 @@ namespace l1t { int roll; ///< 1 - 3. For RPCs only, sub-division of ring. (Range? - AWB 02.03.17) int neighbor; ///< 0 or 1. Filled in EMTFBlock(ME|GEM|RPC).cc int mpc_link; ///< 1 - 3. Filled in EMTFHit.cc from CSCCorrelatedLCTDigi - int pc_sector; ///< 1 - 6. EMTF sector that received the LCT, even those sent from neighbor sectors. - int pc_station; ///< 0 - 5. 0 for ME1 subsector 1, 5 for neighbor hits. - int pc_chamber; ///< 0 - 8. - int pc_segment; ///< 0 - 3. - int wire; ///< 0 - 111 For CSCs only. - int strip; ///< 0 - 158 For CSCs only. - int strip_hi; ///< ? - ?. For RPCs only, highest strip in a cluster. (Range? - AWB 02.03.17) - int strip_low; ///< ? - ?. For RPCs only, lowest strip in a cluster. (Range? - AWB 02.03.17) - int track_num; ///< ? - ?. For CSCs only. (Range? - AWB 02.03.17) - int quality; ///< 0 - 15. For CSCs only. - int pattern; ///< 0 - 10. For CSCs only. - int bend; ///< 0 or 1. For CSCs only. - int valid; ///< 0 or 1. For CSCs only (for now; could use to flag failing clusters? - AWB 02.03.17) - int sync_err; ///< 0 or 1. For CSCs only. + int pc_sector; ///< 1 - 6. EMTF sector that received the LCT, even those sent from neighbor sectors. + int pc_station; ///< 0 - 5. 0 for ME1 subsector 1, 5 for neighbor hits. + int pc_chamber; ///< 0 - 8. + int pc_segment; ///< 0 - 3. + int wire; ///< 0 - 111 For CSCs only. + int strip; ///< 0 - 158 For CSCs only. + int strip_hi; ///< ? - ?. For RPCs only, highest strip in a cluster. (Range? - AWB 02.03.17) + int strip_low; ///< ? - ?. For RPCs only, lowest strip in a cluster. (Range? - AWB 02.03.17) + int strip_quart; ///< Run 3 CSC parameters + int strip_eighth; ///< Run 3 CSC parameters + int strip_quart_bit; ///< Run 3 CSC parameters + int strip_eighth_bit; ///< Run 3 CSC parameters + int track_num; ///< ? - ?. For CSCs only. (Range? - AWB 02.03.17) + int quality; ///< 0 - 15. For CSCs only. + int pattern; ///< 0 - 10. For CSCs only. + int pattern_run3; ///< Run 3 For CSC only. + int bend; ///< 0 or 1. For CSCs only. + int slope; ///< Run 3 For CSC only. + int valid; ///< 0 or 1. For CSCs only (for now; could use to flag failing clusters? - AWB 02.03.17) + int sync_err; ///< 0 or 1. For CSCs only. // GEM specific int layer; ///< 0 - 1. For GEMs only, superchamber detector layer (1 or 2). // END GEM specific diff --git a/DataFormats/L1TMuon/interface/EMTFTrack.h b/DataFormats/L1TMuon/interface/EMTFTrack.h index 299a7d2e74b29..fe2dd799b9dd5 100644 --- a/DataFormats/L1TMuon/interface/EMTFTrack.h +++ b/DataFormats/L1TMuon/interface/EMTFTrack.h @@ -32,6 +32,8 @@ namespace l1t { uint16_t sign_ph[6]; // ^ uint16_t sign_th[6]; // ^ uint16_t cpattern[4]; // index: 0=ME1, 1=ME2, 2=ME3, 3=ME4 + uint16_t csign[4]; // index: 0=ME1, 1=ME2, 2=ME3, 3=ME4 + uint16_t slope[4]; // index: 0=ME1, 1=ME2, 2=ME3, 3=ME4 uint16_t fr[4]; // ^ uint16_t bt_vi[5]; // index: 0=ME1sub1, 1=ME1sub2, 2=ME2, 3=ME3, 4=ME4 uint16_t bt_hi[5]; // ^ diff --git a/L1Trigger/L1TMuon/interface/MuonTriggerPrimitive.h b/L1Trigger/L1TMuon/interface/MuonTriggerPrimitive.h index a8973218ab62e..811d3010c99ac 100644 --- a/L1Trigger/L1TMuon/interface/MuonTriggerPrimitive.h +++ b/L1Trigger/L1TMuon/interface/MuonTriggerPrimitive.h @@ -105,7 +105,14 @@ namespace L1TMuon { syncErr(0), cscID(0), alct_quality(0), - clct_quality(0) {} + clct_quality(0), + // run-3 + pattern_run3(0), + strip_quart_bit(0), + strip_eighth_bit(0), + strip_quart(0), + strip_eighth(0), + slope(0) {} uint16_t trknmb; uint16_t valid; uint16_t quality; @@ -120,6 +127,13 @@ namespace L1TMuon { uint16_t cscID; uint16_t alct_quality; // extra info for ALCT (wires) uint16_t clct_quality; // extra info for CLCT (strips) + // run-3 + uint16_t pattern_run3; + uint16_t strip_quart_bit; + uint16_t strip_eighth_bit; + uint16_t strip_quart; + uint16_t strip_eighth; + uint16_t slope; }; struct DTData { diff --git a/L1Trigger/L1TMuon/src/MuonTriggerPrimitive.cc b/L1Trigger/L1TMuon/src/MuonTriggerPrimitive.cc index 6876aae6c8d93..74eeee069ab7a 100644 --- a/L1Trigger/L1TMuon/src/MuonTriggerPrimitive.cc +++ b/L1Trigger/L1TMuon/src/MuonTriggerPrimitive.cc @@ -132,6 +132,13 @@ TriggerPrimitive::TriggerPrimitive(const CSCDetId& detid, const CSCCorrelatedLCT _csc.cscID = digi.getCSCID(); _csc.alct_quality = digi.getALCT().getQuality(); _csc.clct_quality = digi.getCLCT().getQuality(); + // run-3 + _csc.pattern_run3 = digi.getRun3Pattern(); + _csc.slope = digi.getSlope(); + _csc.strip_quart_bit = digi.getQuartStripBit(); + _csc.strip_eighth_bit = digi.getEighthStripBit(); + _csc.strip_quart = digi.getStrip(4); + _csc.strip_eighth = digi.getStrip(8); // Use ME1/1a --> ring 4 convention const bool is_me11a = (detid.station() == 1 && detid.ring() == 1 && digi.getStrip() >= 128); diff --git a/L1Trigger/L1TMuonEndCap/interface/PrimitiveConversion.h b/L1Trigger/L1TMuonEndCap/interface/PrimitiveConversion.h index 3d573a992e4f4..7f0241707dd40 100644 --- a/L1Trigger/L1TMuonEndCap/interface/PrimitiveConversion.h +++ b/L1Trigger/L1TMuonEndCap/interface/PrimitiveConversion.h @@ -23,7 +23,8 @@ class PrimitiveConversion { bool fixZonePhi, bool useNewZones, bool fixME11Edges, - bool bugME11Dupes); + bool bugME11Dupes, + bool useRun3CCLUT); void process(const std::map& selected_prim_map, EMTFHitCollection& conv_hits) const; @@ -103,6 +104,8 @@ class PrimitiveConversion { int zoneOverlap_; bool duplicateTheta_, fixZonePhi_, useNewZones_, fixME11Edges_; bool bugME11Dupes_; + // Run 3 CCLUT algorithm + bool useRun3CCLUT_; }; #endif diff --git a/L1Trigger/L1TMuonEndCap/interface/VersionControl.h b/L1Trigger/L1TMuonEndCap/interface/VersionControl.h index a782008114ffb..13e7f5491a9f5 100644 --- a/L1Trigger/L1TMuonEndCap/interface/VersionControl.h +++ b/L1Trigger/L1TMuonEndCap/interface/VersionControl.h @@ -36,7 +36,7 @@ class VersionControl { // For primitive conversion std::vector zoneBoundaries_; int zoneOverlap_; - bool includeNeighbor_, duplicateTheta_, fixZonePhi_, useNewZones_, fixME11Edges_; + bool includeNeighbor_, duplicateTheta_, fixZonePhi_, useNewZones_, fixME11Edges_, useRun3CCLUT_; // For pattern recognition std::vector pattDefinitions_, symPattDefinitions_; diff --git a/L1Trigger/L1TMuonEndCap/python/simEmtfDigis_cfi.py b/L1Trigger/L1TMuonEndCap/python/simEmtfDigis_cfi.py index aab3459047547..fae3fdacbe077 100644 --- a/L1Trigger/L1TMuonEndCap/python/simEmtfDigis_cfi.py +++ b/L1Trigger/L1TMuonEndCap/python/simEmtfDigis_cfi.py @@ -19,6 +19,9 @@ # Era (options: 'Run2_2016', 'Run2_2017', 'Run2_2018') Era = cms.string('Run2_2018'), + # New Run 3 CSC TPs using CCLUT algorithm + UseRun3CCLUT = cms.bool(False), + # Input collections # Three options for CSCInput # * 'simCscTriggerPrimitiveDigis','MPCSORTED' : simulated trigger primitives (LCTs) from re-emulating CSC digis @@ -157,3 +160,8 @@ ## Era: Run2_2018 from Configuration.Eras.Modifier_stage2L1Trigger_2018_cff import stage2L1Trigger_2018 stage2L1Trigger_2018.toModify(simEmtfDigis, RPCEnable = cms.bool(True), Era = cms.string('Run2_2018')) + +## 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')) + diff --git a/L1Trigger/L1TMuonEndCap/src/AngleCalculation.cc b/L1Trigger/L1TMuonEndCap/src/AngleCalculation.cc index 454c173417e77..eb49282cf526d 100644 --- a/L1Trigger/L1TMuonEndCap/src/AngleCalculation.cc +++ b/L1Trigger/L1TMuonEndCap/src/AngleCalculation.cc @@ -413,6 +413,8 @@ void AngleCalculation::calculate_angles(EMTFTrack& track, const int izone) const for (int i = 0; i < emtf::NUM_STATIONS; ++i) { const auto& v = st_conv_hits.at(i); ptlut_data.cpattern[i] = v.empty() ? 0 : v.front().Pattern(); // Automatically set to 0 for RPCs + ptlut_data.csign[i] = v.empty() ? 0 : v.front().Bend(); // Automatically set to 0 for RPCs + ptlut_data.slope[i] = v.empty() ? 0 : v.front().Slope(); // Automatically set to 0 for RPCs ptlut_data.fr[i] = v.empty() ? 0 : isFront(v.front().Station(), v.front().Ring(), v.front().Chamber(), v.front().Subsystem()); if (i == 0) diff --git a/L1Trigger/L1TMuonEndCap/src/PrimitiveConversion.cc b/L1Trigger/L1TMuonEndCap/src/PrimitiveConversion.cc index 7a489e52c5e1f..dd6d761b62f69 100644 --- a/L1Trigger/L1TMuonEndCap/src/PrimitiveConversion.cc +++ b/L1Trigger/L1TMuonEndCap/src/PrimitiveConversion.cc @@ -20,7 +20,8 @@ void PrimitiveConversion::configure(const GeometryTranslator* tp_geom, bool fixZonePhi, bool useNewZones, bool fixME11Edges, - bool bugME11Dupes) { + bool bugME11Dupes, + bool useRun3CCLUT) { emtf_assert(tp_geom != nullptr); emtf_assert(pc_lut != nullptr); @@ -44,6 +45,9 @@ void PrimitiveConversion::configure(const GeometryTranslator* tp_geom, useNewZones_ = useNewZones; fixME11Edges_ = fixME11Edges; bugME11Dupes_ = bugME11Dupes; + + // Run 3 CCLUT algorithm + useRun3CCLUT_ = useRun3CCLUT; } void PrimitiveConversion::process(const std::map& selected_prim_map, @@ -158,6 +162,13 @@ void PrimitiveConversion::convert_csc(int pc_sector, conv_hit.set_time(0.); // No fine resolution timing conv_hit.set_alct_quality(tp_data.alct_quality); conv_hit.set_clct_quality(tp_data.clct_quality); + // Run-3 + conv_hit.set_strip_quart(tp_data.strip_quart); + conv_hit.set_strip_eighth(tp_data.strip_eighth); + conv_hit.set_strip_quart_bit(tp_data.strip_quart_bit); + conv_hit.set_strip_eighth_bit(tp_data.strip_eighth_bit); + conv_hit.set_pattern_run3(tp_data.pattern_run3); + conv_hit.set_slope(tp_data.slope); conv_hit.set_neighbor(is_neighbor); conv_hit.set_sector_idx((endcap_ == 1) ? sector_ - 1 : sector_ + 5); @@ -286,10 +297,18 @@ void PrimitiveConversion::convert_csc_details(EMTFHit& conv_hit) const { if (is_10degree) { eighth_strip = fw_strip << 2; // full precision, uses only 2 bits of pattern correction - eighth_strip += clct_pat_corr_sign * (clct_pat_corr >> 1); + 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 - eighth_strip += clct_pat_corr_sign * (clct_pat_corr >> 0); + 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); + } } emtf_assert(bugStrip0BeforeFW48200 == true || eighth_strip >= 0); diff --git a/L1Trigger/L1TMuonEndCap/src/SectorProcessor.cc b/L1Trigger/L1TMuonEndCap/src/SectorProcessor.cc index a06e6e5e3e48a..f8af283c0b949 100644 --- a/L1Trigger/L1TMuonEndCap/src/SectorProcessor.cc +++ b/L1Trigger/L1TMuonEndCap/src/SectorProcessor.cc @@ -105,7 +105,8 @@ void SectorProcessor::process_single_bx(int bx, cfg.fixZonePhi_, cfg.useNewZones_, cfg.fixME11Edges_, - cfg.bugME11Dupes_); + cfg.bugME11Dupes_, + cfg.useRun3CCLUT_); PatternRecognition patt_recog; patt_recog.configure(verbose_, diff --git a/L1Trigger/L1TMuonEndCap/src/VersionControl.cc b/L1Trigger/L1TMuonEndCap/src/VersionControl.cc index 0e902b8d6b8ce..97a6300a385db 100644 --- a/L1Trigger/L1TMuonEndCap/src/VersionControl.cc +++ b/L1Trigger/L1TMuonEndCap/src/VersionControl.cc @@ -5,6 +5,8 @@ VersionControl::VersionControl(const edm::ParameterSet& iConfig) : config_(iConf verbose_ = iConfig.getUntrackedParameter("verbosity"); useO2O_ = iConfig.getParameter("FWConfig"); era_ = iConfig.getParameter("Era"); + // Run 3 CCLUT + useRun3CCLUT_ = iConfig.getParameter("UseRun3CCLUT"); useDT_ = iConfig.getParameter("DTEnable"); useCSC_ = iConfig.getParameter("CSCEnable");