diff --git a/DataFormats/CSCDigi/src/CSCCorrelatedLCTDigi.cc b/DataFormats/CSCDigi/src/CSCCorrelatedLCTDigi.cc index bd0b2afddadc8..1662d95621e3b 100644 --- a/DataFormats/CSCDigi/src/CSCCorrelatedLCTDigi.cc +++ b/DataFormats/CSCDigi/src/CSCCorrelatedLCTDigi.cc @@ -133,7 +133,8 @@ void CSCCorrelatedLCTDigi::print() const { << " Quality = " << getQuality() << " Key Wire = " << getKeyWG() << " Strip = " << getStrip() << " Pattern = " << getPattern() << " Bend = " << ((getBend() == 0) ? 'L' : 'R') << " BX = " << getBX() - << " MPC Link = " << getMPCLink() << " HMT Bit = " << getHMT(); + << " MPC Link = " << getMPCLink() << " Type (SIM) = " << getType() + << " HMT Bit = " << getHMT(); } else { edm::LogVerbatim("CSCDigi") << "Not a valid correlated LCT."; } @@ -141,9 +142,11 @@ void CSCCorrelatedLCTDigi::print() const { std::ostream& operator<<(std::ostream& o, const CSCCorrelatedLCTDigi& digi) { return o << "CSC LCT #" << digi.getTrknmb() << ": Valid = " << digi.isValid() << " Quality = " << digi.getQuality() - << " MPC Link = " << digi.getMPCLink() << " cscID = " << digi.getCSCID() << "\n" + << " MPC Link = " << digi.getMPCLink() << " cscID = " << digi.getCSCID() + << " syncErr = " << digi.getSyncErr() << " Type (SIM) = " << digi.getType() << " HMT Bit = " << digi.getHMT() + << "\n" << " cathode info: Strip = " << digi.getStrip() << " Pattern = " << digi.getPattern() << " Bend = " << ((digi.getBend() == 0) ? 'L' : 'R') << "\n" - << " anode info: Key wire = " << digi.getKeyWG() << " BX = " << digi.getBX() << " bx0 = " << digi.getBX0() - << " syncErr = " << digi.getSyncErr() << " HMT Bit = " << digi.getHMT() << "\n"; + << " anode info: Key wire = " << digi.getKeyWG() << " BX = " << digi.getBX() + << " bx0 = " << digi.getBX0(); } diff --git a/L1Trigger/CSCTriggerPrimitives/interface/CSCAnodeLCTProcessor.h b/L1Trigger/CSCTriggerPrimitives/interface/CSCAnodeLCTProcessor.h index b7429a588b47d..724efaad0a15b 100644 --- a/L1Trigger/CSCTriggerPrimitives/interface/CSCAnodeLCTProcessor.h +++ b/L1Trigger/CSCTriggerPrimitives/interface/CSCAnodeLCTProcessor.h @@ -75,7 +75,7 @@ class CSCAnodeLCTProcessor : public CSCBaseboard { std::vector readoutALCTs(int nMaxALCTs = CSCConstants::MAX_ALCTS_READOUT) const; /** Returns vector of all found ALCTs, if any. */ - std::vector getALCTs(int nMaxALCTs = CSCConstants::MAX_ALCTS_READOUT) const; + std::vector getALCTs(unsigned nMaxALCTs = CSCConstants::MAX_ALCTS_READOUT) const; /** read out pre-ALCTs */ std::vector preTriggerDigis() const { return thePreTriggerDigis; } @@ -99,7 +99,7 @@ class CSCAnodeLCTProcessor : public CSCBaseboard { CSCALCTDigi secondALCT[CSCConstants::MAX_ALCT_TBINS]; /** LCTs in this chamber, as found by the processor. */ - CSCALCTDigi ALCTContainer_[CSCConstants::MAX_ALCT_TBINS][CSCConstants::MAX_ALCTS_PER_PROCESSOR]; + std::vector > ALCTContainer_; /** Access routines to wire digis. */ bool getDigis(const CSCWireDigiCollection* wiredc); @@ -231,6 +231,10 @@ class CSCAnodeLCTProcessor : public CSCBaseboard { /** Dump digis on wire groups. */ void dumpDigis(const std::vector wire[CSCConstants::NUM_LAYERS][CSCConstants::MAX_NUM_WIRES]) const; + // Check if the ALCT is valid + void checkValidReadout(const CSCALCTDigi& alct) const; + void checkValid(const CSCALCTDigi& alct, unsigned max_stubs = CSCConstants::MAX_ALCTS_PER_PROCESSOR) const; + void showPatterns(const int key_wire); }; diff --git a/L1Trigger/CSCTriggerPrimitives/interface/CSCCathodeLCTProcessor.h b/L1Trigger/CSCTriggerPrimitives/interface/CSCCathodeLCTProcessor.h index 0dba5cd5b0ee5..add8e67ae70b8 100644 --- a/L1Trigger/CSCTriggerPrimitives/interface/CSCCathodeLCTProcessor.h +++ b/L1Trigger/CSCTriggerPrimitives/interface/CSCCathodeLCTProcessor.h @@ -70,7 +70,7 @@ class CSCCathodeLCTProcessor : public CSCBaseboard { std::vector readoutCLCTsME1b(int nMaxCLCTs = CSCConstants::MAX_CLCTS_READOUT) const; /** Returns vector of all found CLCTs, if any. */ - std::vector getCLCTs() const; + std::vector getCLCTs(unsigned nMaxCLCTs = CSCConstants::MAX_CLCTS_PER_PROCESSOR) const; /** get best/second best CLCT * Note: CLCT has BX shifted */ @@ -86,7 +86,7 @@ class CSCCathodeLCTProcessor : public CSCBaseboard { protected: /** LCTs in this chamber, as found by the processor. */ - CSCCLCTDigi CLCTContainer_[CSCConstants::MAX_CLCT_TBINS][CSCConstants::MAX_CLCTS_PER_PROCESSOR]; + std::vector > CLCTContainer_; /** Access routines to comparator digis. */ bool getDigis(const CSCComparatorDigiCollection* compdc); @@ -138,6 +138,9 @@ class CSCCathodeLCTProcessor : public CSCBaseboard { void dumpDigis(const std::vector strip[CSCConstants::NUM_LAYERS][CSCConstants::NUM_HALF_STRIPS_7CFEBS], const int nStrips) const; + // Check if the CLCT is valid + void checkValid(const CSCCLCTDigi& lct, unsigned max_stubs = CSCConstants::MAX_CLCTS_PER_PROCESSOR) const; + //--------------------------- Member variables ----------------------------- /* best pattern Id for a given half-strip */ diff --git a/L1Trigger/CSCTriggerPrimitives/interface/CSCLCTTools.h b/L1Trigger/CSCTriggerPrimitives/interface/CSCLCTTools.h new file mode 100644 index 0000000000000..8fc124d846aef --- /dev/null +++ b/L1Trigger/CSCTriggerPrimitives/interface/CSCLCTTools.h @@ -0,0 +1,30 @@ +#ifndef L1Trigger_CSCTriggerPrimitives_CSCLCTTools_h +#define L1Trigger_CSCTriggerPrimitives_CSCLCTTools_h + +#include "L1Trigger/CSCCommonTrigger/interface/CSCConstants.h" + +#include +#include + +namespace csctp { + + // CSC max strip & max wire + unsigned get_csc_max_wire(int station, int ring); + unsigned get_csc_max_halfstrip(int station, int ring); + unsigned get_csc_max_quartstrip(int station, int ring); + unsigned get_csc_max_eightstrip(int station, int ring); + + // CLCT min, max CFEB numbers + std::pair get_csc_min_max_cfeb(int station, int ring); + + // CSC min, max pattern + std::pair get_csc_min_max_pattern(bool isRun3); + + // CSC max quality + unsigned get_csc_alct_max_quality(int station, int ring, bool isRun3); + unsigned get_csc_clct_max_quality(); + unsigned get_csc_lct_max_quality(); + +} // namespace csctp + +#endif diff --git a/L1Trigger/CSCTriggerPrimitives/interface/CSCMotherboard.h b/L1Trigger/CSCTriggerPrimitives/interface/CSCMotherboard.h index 0c8011ff2774e..d7bfd271b95f9 100644 --- a/L1Trigger/CSCTriggerPrimitives/interface/CSCMotherboard.h +++ b/L1Trigger/CSCTriggerPrimitives/interface/CSCMotherboard.h @@ -118,6 +118,9 @@ class CSCMotherboard : public CSCBaseboard { unsigned int highMultiplicityBits_; bool useHighMultiplicityBits_; + // Use the new patterns according to the comparator code format + bool use_run3_patterns_; + /** Default values of configuration parameters. */ static const unsigned int def_mpc_block_me1a; static const unsigned int def_alct_trig_enable, def_clct_trig_enable; @@ -165,6 +168,9 @@ class CSCMotherboard : public CSCBaseboard { /** Dump TMB/MPC configuration parameters. */ void dumpConfigParams() const; + // Check if the LCT is valid + void checkValid(const CSCCorrelatedLCTDigi& lct) const; + /* encode high multiplicity bits for Run-3 exotic triggers */ void encodeHighMultiplicityBits(unsigned alctBits); }; diff --git a/L1Trigger/CSCTriggerPrimitives/python/cscTriggerPrimitiveDigis_cfi.py b/L1Trigger/CSCTriggerPrimitives/python/cscTriggerPrimitiveDigis_cfi.py index 3b421cb0b0da0..1bfe66150983b 100644 --- a/L1Trigger/CSCTriggerPrimitives/python/cscTriggerPrimitiveDigis_cfi.py +++ b/L1Trigger/CSCTriggerPrimitives/python/cscTriggerPrimitiveDigis_cfi.py @@ -371,7 +371,7 @@ ## matching to pads maxDeltaBXPad = cms.int32(1), - maxDeltaBXCoPad = cms.int32(1), + maxDeltaBXCoPad = cms.int32(0), maxDeltaPadL1Even = cms.int32(12), maxDeltaPadL1Odd = cms.int32(24), maxDeltaPadL2Even = cms.int32(12), @@ -424,7 +424,7 @@ ## matching to pads maxDeltaBXPad = cms.int32(1), - maxDeltaBXCoPad = cms.int32(1), + maxDeltaBXCoPad = cms.int32(0), maxDeltaPadL1Even = cms.int32(12), maxDeltaPadL1Odd = cms.int32(24), maxDeltaPadL2Even = cms.int32(12), @@ -488,7 +488,7 @@ runME11Up = cms.bool(True), runME11ILT = cms.bool(True), useClusters = cms.bool(False), - enableAlctSLHC = cms.bool(True)), + enableAlctSLHC = cms.bool(False)), clctSLHC = dict(clctNplanesHitPattern = 3), me11tmbSLHCGEM = me11tmbSLHCGEM, copadParamGE11 = copadParamGE11 @@ -500,13 +500,14 @@ commonParam = dict(runME21Up = cms.bool(True), runME21ILT = cms.bool(True), runME31Up = cms.bool(True), - runME41Up = cms.bool(True)), + runME41Up = cms.bool(True), + enableAlctSLHC = cms.bool(True)), tmbSLHC = dict(ignoreAlctCrossClct = cms.bool(False)), clctSLHC = dict(useDynamicStateMachineZone = cms.bool(True)), - alctSLHCME21 = cscTriggerPrimitiveDigis.alctSLHC.clone(alctNplanesHitPattern = 3), + alctSLHCME21 = cscTriggerPrimitiveDigis.alctParam07.clone(alctNplanesHitPattern = 3), clctSLHCME21 = cscTriggerPrimitiveDigis.clctSLHC.clone(clctNplanesHitPattern = 3), me21tmbSLHCGEM = me21tmbSLHCGEM, - alctSLHCME3141 = cscTriggerPrimitiveDigis.alctSLHC.clone(alctNplanesHitPattern = 4), + alctSLHCME3141 = cscTriggerPrimitiveDigis.alctParam07.clone(alctNplanesHitPattern = 4), clctSLHCME3141 = cscTriggerPrimitiveDigis.clctSLHC.clone(clctNplanesHitPattern = 4), meX1tmbSLHC = meX1tmbSLHC, copadParamGE11 = copadParamGE11, diff --git a/L1Trigger/CSCTriggerPrimitives/src/CSCAnodeLCTProcessor.cc b/L1Trigger/CSCTriggerPrimitives/src/CSCAnodeLCTProcessor.cc index e5eacc99e2281..1498c19a7d6cb 100644 --- a/L1Trigger/CSCTriggerPrimitives/src/CSCAnodeLCTProcessor.cc +++ b/L1Trigger/CSCTriggerPrimitives/src/CSCAnodeLCTProcessor.cc @@ -1,4 +1,5 @@ #include "L1Trigger/CSCTriggerPrimitives/interface/CSCAnodeLCTProcessor.h" +#include "L1Trigger/CSCTriggerPrimitives/interface/CSCLCTTools.h" #include // Default values of configuration parameters. @@ -192,12 +193,11 @@ void CSCAnodeLCTProcessor::checkConfigParameters() { } void CSCAnodeLCTProcessor::clear() { + ALCTContainer_.clear(); + ALCTContainer_.resize(CSCConstants::MAX_ALCT_TBINS); for (int bx = 0; bx < CSCConstants::MAX_ALCT_TBINS; bx++) { bestALCT[bx].clear(); secondALCT[bx].clear(); - for (int iALCT = 0; iALCT < CSCConstants::MAX_ALCTS_PER_PROCESSOR; iALCT++) { - ALCTContainer_[bx][iALCT].clear(); - } } lct_list.clear(); } @@ -222,35 +222,32 @@ std::vector CSCAnodeLCTProcessor::run(const CSCWireDigiCollection* // Get the number of wire groups for the given chamber. Do it only once // per chamber. - if (numWireGroups == 0) { + if (numWireGroups <= 0 or numWireGroups > CSCConstants::MAX_NUM_WIRES) { if (cscChamber_) { numWireGroups = cscChamber_->layer(1)->geometry()->numberOfWireGroups(); if (numWireGroups > CSCConstants::MAX_NUM_WIRES) { - if (infoV >= 0) - edm::LogError("CSCAnodeLCTProcessor|SetupError") - << "+++ Number of wire groups, " << numWireGroups << " found in " << theCSCName_ << " (sector " - << theSector << " subsector " << theSubsector << " trig id. " << theTrigChamber << ")" - << " exceeds max expected, " << CSCConstants::MAX_NUM_WIRES << " +++\n" - << "+++ CSC geometry looks garbled; no emulation possible +++\n"; + edm::LogError("CSCAnodeLCTProcessor|SetupError") + << "+++ Number of wire groups, " << numWireGroups << " found in " << theCSCName_ << " (sector " << theSector + << " subsector " << theSubsector << " trig id. " << theTrigChamber << ")" + << " exceeds max expected, " << CSCConstants::MAX_NUM_WIRES << " +++\n" + << "+++ CSC geometry looks garbled; no emulation possible +++\n"; numWireGroups = -1; } } else { - if (infoV >= 0) - edm::LogError("CSCAnodeLCTProcessor|SetupError") - << "+++ " << theCSCName_ << " (sector " << theSector << " subsector " << theSubsector << " trig id. " - << theTrigChamber << ")" - << " is not defined in current geometry! +++\n" - << "+++ CSC geometry looks garbled; no emulation possible +++\n"; + edm::LogError("CSCAnodeLCTProcessor|SetupError") + << "+++ " << theCSCName_ << " (sector " << theSector << " subsector " << theSubsector << " trig id. " + << theTrigChamber << ")" + << " is not defined in current geometry! +++\n" + << "+++ CSC geometry looks garbled; no emulation possible +++\n"; numWireGroups = -1; } } - if (numWireGroups < 0) { - if (infoV >= 0) - edm::LogError("CSCAnodeLCTProcessor|SetupError") - << "+++ " << theCSCName_ << " (sector " << theSector << " subsector " << theSubsector << " trig id. " - << theTrigChamber << "):" - << " numWireGroups = " << numWireGroups << "; ALCT emulation skipped! +++"; + if (numWireGroups <= 0 or (unsigned) numWireGroups > csctp::get_csc_max_wire(theStation, theRing)) { + edm::LogError("CSCAnodeLCTProcessor|SetupError") + << "+++ " << theCSCName_ << " (sector " << theSector << " subsector " << theSubsector << " trig id. " + << theTrigChamber << "):" + << " numWireGroups = " << numWireGroups << "; ALCT emulation skipped! +++"; std::vector emptyV; return emptyV; } @@ -294,15 +291,17 @@ void CSCAnodeLCTProcessor::run(const std::vector wire[CSCConstants::NUM_LAY // Check if there are any in-time hits and do the pulse extension. bool chamber_empty = pulseExtension(wire); - // Take the best MAX_CLCTS_PER_PROCESSOR candidates per bx. - int ALCTIndex_[CSCConstants::MAX_ALCT_TBINS] = {}; - // Only do the rest of the processing if chamber is not empty. // Stop drift_delay bx's short of fifo_tbins since at later bx's we will // not have a full set of hits to start pattern search anyway. unsigned int stop_bx = fifo_tbins - drift_delay; if (!chamber_empty) { for (int i_wire = 0; i_wire < numWireGroups; i_wire++) { + // extra check to make sure only valid wires are processed + const unsigned max_wire = csctp::get_csc_max_wire(theStation, theRing); + if (unsigned(i_wire) >= max_wire) + continue; + unsigned int start_bx = 0; // Allow for more than one pass over the hits in the time window. while (start_bx < stop_bx) { @@ -322,10 +321,11 @@ void CSCAnodeLCTProcessor::run(const std::vector wire[CSCConstants::NUM_LAY //acceleration mode if (quality[i_wire][0] > 0 and bx < CSCConstants::MAX_ALCT_TBINS) { int valid = (ghost_cleared[0] == 0) ? 1 : 0; //cancelled, valid=0, otherwise it is 1 - const auto& newALCT(CSCALCTDigi(valid, quality[i_wire][0], 1, 0, i_wire, bx)); - lct_list.push_back(newALCT); - ALCTContainer_[bx][ALCTIndex_[bx]] = newALCT; - ALCTIndex_[bx]++; + CSCALCTDigi newALCT(valid, quality[i_wire][0], 1, 0, i_wire, bx); + + lct_list.emplace_back(newALCT); + if (valid) + ALCTContainer_.at(bx).push_back(newALCT); if (infoV > 1) LogTrace("CSCAnodeLCTProcessor") << "Add one ALCT to list " << lct_list.back(); } @@ -333,10 +333,12 @@ void CSCAnodeLCTProcessor::run(const std::vector wire[CSCConstants::NUM_LAY //collision mode if (quality[i_wire][1] > 0 and bx < CSCConstants::MAX_ALCT_TBINS) { int valid = (ghost_cleared[1] == 0) ? 1 : 0; //cancelled, valid=0, otherwise it is 1 - const auto& newALCT(CSCALCTDigi(valid, quality[i_wire][1], 0, quality[i_wire][2], i_wire, bx)); - lct_list.push_back(newALCT); - ALCTContainer_[bx][ALCTIndex_[bx]] = newALCT; - ALCTIndex_[bx]++; + + CSCALCTDigi newALCT(valid, quality[i_wire][1], 0, quality[i_wire][2], i_wire, bx); + + lct_list.emplace_back(newALCT); + if (valid) + ALCTContainer_.at(bx).push_back(newALCT); if (infoV > 1) LogTrace("CSCAnodeLCTProcessor") << "Add one ALCT to list " << lct_list.back(); } @@ -905,6 +907,10 @@ void CSCAnodeLCTProcessor::lctSearch() { for (int bx = 0; bx < CSCConstants::MAX_ALCT_TBINS; bx++) { if (bestALCT[bx].isValid()) { bestALCT[bx].setTrknmb(1); + + // check if the best ALCT is valid + checkValidReadout(bestALCT[bx]); + if (infoV > 0) { LogDebug("CSCAnodeLCTProcessor") << bestALCT[bx] << " fullBX = " << bestALCT[bx].getFullBX() << " found in " << theCSCName_ << " (sector " << theSector << " subsector " << theSubsector @@ -913,6 +919,10 @@ void CSCAnodeLCTProcessor::lctSearch() { } if (secondALCT[bx].isValid()) { secondALCT[bx].setTrknmb(2); + + // check if the second best ALCT is valid + checkValidReadout(secondALCT[bx]); + if (infoV > 0) { LogDebug("CSCAnodeLCTProcessor") << secondALCT[bx] << " fullBX = " << secondALCT[bx].getFullBX() << " found in " << theCSCName_ @@ -925,9 +935,13 @@ void CSCAnodeLCTProcessor::lctSearch() { // set track number for the other ALCTs for (int bx = 0; bx < CSCConstants::MAX_ALCT_TBINS; bx++) { - for (int iALCT = 0; iALCT < CSCConstants::MAX_ALCTS_PER_PROCESSOR; iALCT++) { - if (ALCTContainer_[bx][iALCT].isValid()) { - ALCTContainer_[bx][iALCT].setTrknmb(iALCT + 1); + for (unsigned iALCT = 0; iALCT < ALCTContainer_.at(bx).size(); iALCT++) { + if (ALCTContainer_.at(bx).at(iALCT).isValid()) { + ALCTContainer_.at(bx).at(iALCT).setTrknmb(iALCT + 1); + + // check if ALCT is valid + checkValid(ALCTContainer_.at(bx).at(iALCT)); + if (infoV > 0) { LogDebug("CSCAnodeLCTProcessor") << ALCTContainer_[bx][iALCT] << " found in " << theCSCName_ << " (sector " << theSector << " subsector " @@ -1217,6 +1231,65 @@ void CSCAnodeLCTProcessor::dumpDigis( LogTrace("CSCAnodeLCTProcessor") << strstrm.str(); } +// Check if the ALCT is valid +void CSCAnodeLCTProcessor::checkValidReadout(const CSCALCTDigi& alct) const { + checkValid(alct, CSCConstants::MAX_ALCTS_READOUT); +} + +// Check if the ALCT is valid +void CSCAnodeLCTProcessor::checkValid(const CSCALCTDigi& alct, unsigned max_stubs) const { + const unsigned max_wire = csctp::get_csc_max_wire(theStation, theRing); + const unsigned max_quality = csctp::get_csc_alct_max_quality(theStation, theRing, runME21ILT_); + + unsigned errors = 0; + + // stub must be valid + if (!alct.isValid()) { + edm::LogError("CSCAnodeLCTProcessor") << "CSCALCTDigi with invalid bit set: " << alct.isValid(); + errors++; + } + + // ALCT number is 1 or 2 + if (alct.getTrknmb() < 1 or alct.getTrknmb() > max_stubs) { + edm::LogError("CSCAnodeLCTProcessor") + << "CSCALCTDigi with invalid track number: " << alct.getTrknmb() << "; allowed [1," << max_stubs << "]"; + errors++; + } + + // ALCT quality must be valid + // number of layers - 3 + if (alct.getQuality() <= 0 or alct.getQuality() > max_quality) { + edm::LogError("CSCAnodeLCTProcessor") + << "CSCALCTDigi with invalid quality: " << alct.getQuality() << "; allowed [0," << max_quality << "]"; + errors++; + } + + // ALCT key wire-group must be within bounds + if (alct.getKeyWG() > max_wire) { + edm::LogError("CSCAnodeLCTProcessor") + << "CSCALCTDigi with invalid wire-group: " << alct.getKeyWG() << "; allowed [0, " << max_wire << "]"; + errors++; + } + + // ALCT with out-of-time BX + if (alct.getBX() > CSCConstants::MAX_ALCT_TBINS - 1) { + edm::LogError("CSCAnodeLCTProcessor") << "CSCALCTDigi with invalid BX: " << alct.getBX() << "; allowed [0, " + << CSCConstants::MAX_LCT_TBINS - 1 << "]"; + errors++; + } + + // ALCT is neither accelerator or collision + if (alct.getCollisionB() > 1) { + edm::LogError("CSCAnodeLCTProcessor") + << "CSCALCTDigi with invalid accel/coll bit: " << alct.getCollisionB() << "; allowed [0,1]"; + errors++; + } + + if (errors > 0) { + edm::LogError("CSCAnodeLCTProcessor") << "Faulty ALCT: " << cscId_ << " " << alct << "\n errors " << errors; + } +} + // Returns vector of read-out ALCTs, if any. Starts with the vector of // all found ALCTs and selects the ones in the read-out time window. std::vector CSCAnodeLCTProcessor::readoutALCTs(int nMaxALCTs) const { @@ -1283,11 +1356,17 @@ std::vector CSCAnodeLCTProcessor::readoutALCTs(int nMaxALCTs) const for (auto& p : tmpV) { p.setBX(p.getBX() - (CSCConstants::LCT_CENTRAL_BX - l1a_window_width / 2)); } + + // do a final check on the ALCTs in readout + for (const auto& alct : tmpV) { + checkValid(alct, nMaxALCTs); + } + return tmpV; } // Returns vector of all found ALCTs, if any. Used in ALCT-CLCT matching. -std::vector CSCAnodeLCTProcessor::getALCTs(int nMaxALCTs) const { +std::vector CSCAnodeLCTProcessor::getALCTs(unsigned nMaxALCTs) const { std::vector tmpV; for (int bx = 0; bx < CSCConstants::MAX_ALCT_TBINS; bx++) { if (nMaxALCTs == CSCConstants::MAX_ALCTS_READOUT) { @@ -1296,9 +1375,9 @@ std::vector CSCAnodeLCTProcessor::getALCTs(int nMaxALCTs) const { if (secondALCT[bx].isValid()) tmpV.push_back(secondALCT[bx]); } else { - for (int iALCT = 0; iALCT < CSCConstants::MAX_ALCTS_PER_PROCESSOR; iALCT++) { - if (ALCTContainer_[bx][iALCT].isValid()) { - tmpV.push_back(ALCTContainer_[bx][iALCT]); + for (unsigned iALCT = 0; iALCT < ALCTContainer_.at(bx).size(); iALCT++) { + if (iALCT < nMaxALCTs and ALCTContainer_.at(bx).at(iALCT).isValid()) { + tmpV.push_back(ALCTContainer_.at(bx).at(iALCT)); } } } diff --git a/L1Trigger/CSCTriggerPrimitives/src/CSCBaseboard.cc b/L1Trigger/CSCTriggerPrimitives/src/CSCBaseboard.cc index 0f64cb196b99f..974d007d01fa0 100644 --- a/L1Trigger/CSCTriggerPrimitives/src/CSCBaseboard.cc +++ b/L1Trigger/CSCTriggerPrimitives/src/CSCBaseboard.cc @@ -91,11 +91,10 @@ void CSCBaseboard::checkConfigParameters(unsigned int& var, const std::string& var_str) { // Make sure that the parameter values are within the allowed range. if (var >= var_max) { - if (infoV >= 0) - edm::LogError("CSCConfigError") << "+++ Value of " + var_str + ", " << var << ", exceeds max allowed, " << var - 1 - << " +++\n" - << "+++ Try to proceed with the default value, " + var_str + "=" << var_def - << " +++\n"; + edm::LogError("CSCConfigError") << "+++ Value of " + var_str + ", " << var << ", exceeds max allowed, " << var - 1 + << " +++\n" + << "+++ Try to proceed with the default value, " + var_str + "=" << var_def + << " +++\n"; var = var_def; } } diff --git a/L1Trigger/CSCTriggerPrimitives/src/CSCCathodeLCTProcessor.cc b/L1Trigger/CSCTriggerPrimitives/src/CSCCathodeLCTProcessor.cc index 5f9d69859199a..4f798b1d12db2 100644 --- a/L1Trigger/CSCTriggerPrimitives/src/CSCCathodeLCTProcessor.cc +++ b/L1Trigger/CSCTriggerPrimitives/src/CSCCathodeLCTProcessor.cc @@ -1,4 +1,5 @@ #include "L1Trigger/CSCTriggerPrimitives/interface/CSCCathodeLCTProcessor.h" +#include "L1Trigger/CSCTriggerPrimitives/interface/CSCLCTTools.h" #include #include @@ -185,11 +186,8 @@ void CSCCathodeLCTProcessor::checkConfigParameters() { void CSCCathodeLCTProcessor::clear() { thePreTriggerDigis.clear(); thePreTriggerBXs.clear(); - for (int bx = 0; bx < CSCConstants::MAX_CLCT_TBINS; bx++) { - for (int iCLCT = 0; iCLCT < CSCConstants::MAX_CLCTS_PER_PROCESSOR; iCLCT++) { - CLCTContainer_[bx][iCLCT].clear(); - } - } + CLCTContainer_.clear(); + CLCTContainer_.resize(CSCConstants::MAX_CLCT_TBINS); } std::vector CSCCathodeLCTProcessor::run(const CSCComparatorDigiCollection* compdc) { @@ -205,7 +203,7 @@ std::vector CSCCathodeLCTProcessor::run(const CSCComparatorDigiColl // Get the number of strips and stagger of layers for the given chamber. // Do it only once per chamber. - if (numStrips == 0) { + if (numStrips <= 0 or numStrips > CSCConstants::MAX_NUM_STRIPS_7CFEBS) { if (cscChamber_) { numStrips = cscChamber_->layer(1)->geometry()->numberOfStrips(); // ME1/a is known to the readout hardware as strips 65-80 of ME1/1. @@ -216,12 +214,10 @@ std::vector CSCCathodeLCTProcessor::run(const CSCComparatorDigiColl // For SLHC ME1/1 is set to have 4 CFEBs in ME1/b and 3 CFEBs in ME1/a if (isME11_) { if (theRing == 4) { - if (infoV >= 0) { - edm::LogError("L1CSCTPEmulatorSetupError") - << "+++ Invalid ring number for this processor " << theRing << " was set in the config." - << " +++\n" - << "+++ CSC geometry looks garbled; no emulation possible +++\n"; - } + edm::LogError("CSCCathodeLCTProcessor|SetupError") + << "+++ Invalid ring number for this processor " << theRing << " was set in the config." + << " +++\n" + << "+++ CSC geometry looks garbled; no emulation possible +++\n"; } if (!disableME1a_ && theRing == 1 && !gangedME1a_) numStrips = CSCConstants::MAX_NUM_STRIPS_7CFEBS; @@ -232,13 +228,11 @@ std::vector CSCCathodeLCTProcessor::run(const CSCComparatorDigiColl } if (numStrips > CSCConstants::MAX_NUM_STRIPS_7CFEBS) { - if (infoV >= 0) - edm::LogError("L1CSCTPEmulatorSetupError") - << "+++ Number of strips, " << numStrips << " found in " - << CSCDetId::chamberName(theEndcap, theStation, theRing, theChamber) << " (sector " << theSector - << " subsector " << theSubsector << " trig id. " << theTrigChamber << ")" - << " exceeds max expected, " << CSCConstants::MAX_NUM_STRIPS_7CFEBS << " +++\n" - << "+++ CSC geometry looks garbled; no emulation possible +++\n"; + edm::LogError("CSCCathodeLCTProcessor|SetupError") + << "+++ Number of strips, " << numStrips << " found in " << theCSCName_ << " (sector " << theSector + << " subsector " << theSubsector << " trig id. " << theTrigChamber << ")" + << " exceeds max expected, " << CSCConstants::MAX_NUM_STRIPS_7CFEBS << " +++\n" + << "+++ CSC geometry looks garbled; no emulation possible +++\n"; numStrips = -1; } // The strips for a given layer may be offset from the adjacent layers. @@ -258,22 +252,20 @@ std::vector CSCCathodeLCTProcessor::run(const CSCComparatorDigiColl stagger[i_layer] = (cscChamber_->layer(i_layer + 1)->geometry()->stagger() + 1) / 2; } } else { - if (infoV >= 0) - edm::LogError("L1CSCTPEmulatorConfigError") - << " " << CSCDetId::chamberName(theEndcap, theStation, theRing, theChamber) << " (sector " << theSector - << " subsector " << theSubsector << " trig id. " << theTrigChamber << ")" - << " is not defined in current geometry! +++\n" - << "+++ CSC geometry looks garbled; no emulation possible +++\n"; + edm::LogError("CSCCathodeLCTProcessor|ConfigError") + << " " << theCSCName_ << " (sector " << theSector << " subsector " << theSubsector << " trig id. " + << theTrigChamber << ")" + << " is not defined in current geometry! +++\n" + << "+++ CSC geometry looks garbled; no emulation possible +++\n"; numStrips = -1; } } - if (numStrips < 0) { - if (infoV >= 0) - edm::LogError("L1CSCTPEmulatorConfigError") - << " " << CSCDetId::chamberName(theEndcap, theStation, theRing, theChamber) << " (sector " << theSector - << " subsector " << theSubsector << " trig id. " << theTrigChamber << "):" - << " numStrips = " << numStrips << "; CLCT emulation skipped! +++"; + if (numStrips <= 0 or 2 * (unsigned)numStrips > csctp::get_csc_max_halfstrip(theStation, theRing)) { + edm::LogError("CSCCathodeLCTProcessor|ConfigError") + << " " << theCSCName_ << " (sector " << theSector << " subsector " << theSubsector << " trig id. " + << theTrigChamber << "):" + << " numStrips = " << numStrips << "; CLCT emulation skipped! +++"; std::vector emptyV; return emptyV; } @@ -338,10 +330,11 @@ void CSCCathodeLCTProcessor::run( if (CLCTlist.size() > 1) sort(CLCTlist.begin(), CLCTlist.end(), std::greater()); - // Take the best MAX_CLCTS_PER_PROCESSOR candidates per bx. - int CLCTIndex_[CSCConstants::MAX_CLCT_TBINS] = {}; - for (const auto& p : CLCTlist) { + // only consider valid CLCTs + if (!p.isValid()) + continue; + const int bx = p.getBX(); if (bx >= CSCConstants::MAX_CLCT_TBINS) { if (infoV > 0) @@ -351,18 +344,21 @@ void CSCCathodeLCTProcessor::run( continue; } - CLCTContainer_[bx][CLCTIndex_[bx]] = p; - CLCTIndex_[bx]++; + CLCTContainer_.at(bx).push_back(p); } for (int bx = 0; bx < CSCConstants::MAX_CLCT_TBINS; bx++) { - for (int iCLCT = 0; iCLCT < CSCConstants::MAX_CLCTS_PER_PROCESSOR; iCLCT++) { - if (CLCTContainer_[bx][iCLCT].isValid()) { - CLCTContainer_[bx][iCLCT].setTrknmb(iCLCT + 1); + for (unsigned iCLCT = 0; iCLCT < CLCTContainer_.at(bx).size(); iCLCT++) { + // only consider valid CLCTs + if (CLCTContainer_.at(bx).at(iCLCT).isValid()) { + CLCTContainer_.at(bx).at(iCLCT).setTrknmb(iCLCT + 1); + + // check if the LCT is valid + checkValid(CLCTContainer_.at(bx).at(iCLCT)); + if (infoV > 0) { LogDebug("CSCCathodeLCTProcessor") - << CLCTContainer_[bx][iCLCT] << " found in " - << CSCDetId::chamberName(theEndcap, theStation, theRing, theChamber) << " (sector " << theSector + << CLCTContainer_.at(bx).at(iCLCT) << " found in " << theCSCName_ << " (sector " << theSector << " subsector " << theSubsector << " trig id. " << theTrigChamber << ")" << "\n"; } @@ -905,7 +901,7 @@ bool CSCCathodeLCTProcessor::patternFinding( hit_layer[this_layer] = true; layers_hit++; // determines number of layers hit // add this strip in this layer to the pattern we are currently considering - hits_single_pattern[this_layer][strip_num] = this_strip; + hits_single_pattern[this_layer][strip_num] = this_strip - stagger[this_layer]; } // find at what bx did pulse on this halsfstrip & layer have started @@ -1023,8 +1019,7 @@ void CSCCathodeLCTProcessor::dumpConfigParams() const { void CSCCathodeLCTProcessor::dumpDigis( const std::vector strip[CSCConstants::NUM_LAYERS][CSCConstants::NUM_HALF_STRIPS_7CFEBS], const int nStrips) const { - LogDebug("CSCCathodeLCTProcessor") << CSCDetId::chamberName(theEndcap, theStation, theRing, theChamber) - << " strip type: half-strip, nStrips " << nStrips; + LogDebug("CSCCathodeLCTProcessor") << theCSCName_ << " strip type: half-strip, nStrips " << nStrips; std::ostringstream strstrm; for (int i_strip = 0; i_strip < nStrips; i_strip++) { @@ -1061,6 +1056,111 @@ void CSCCathodeLCTProcessor::dumpDigis( LogTrace("CSCCathodeLCTProcessor") << strstrm.str(); } +// Check if the CLCT is valid +void CSCCathodeLCTProcessor::checkValid(const CSCCLCTDigi& clct, unsigned max_stubs) const { + const unsigned max_strip = csctp::get_csc_max_halfstrip(theStation, theRing); + const auto& [min_pattern, max_pattern] = csctp::get_csc_min_max_pattern(use_run3_patterns_); + const auto& [min_cfeb, max_cfeb] = csctp::get_csc_min_max_cfeb(theStation, theRing); + const unsigned max_quality = csctp::get_csc_clct_max_quality(); + unsigned errors = 0; + + // CLCT must be valid + if (!clct.isValid()) { + edm::LogError("CSCCathodeLCTProcessor") << "CSCLCTDigi with invalid bit set: " << clct.isValid(); + errors++; + } + + // CLCT number is 1 or max + if (clct.getTrknmb() < 1 or clct.getTrknmb() > max_stubs) { + edm::LogError("CSCCathodeLCTProcessor") + << "CSCLCTDigi with invalid track number: " << clct.getTrknmb() << "; allowed [1," << max_stubs << "]"; + errors++; + } + + // CLCT quality must be valid + // CLCTs require at least 4 layers hit + // Run-3: ME1/1 CLCTs require only 3 layers + // Run-4: ME2/1 CLCTs require only 3 layers + if (clct.getQuality() < nplanes_hit_pattern or clct.getQuality() > max_quality) { + edm::LogError("CSCCathodeLCTProcessor") + << "CSCLCTDigi with invalid quality: " << clct.getQuality() << "; allowed [0," << max_quality << "]"; + ; + errors++; + } + + // CLCT half-strip must be within bounds + if (clct.getStrip() >= CSCConstants::NUM_HALF_STRIPS_PER_CFEB) { + edm::LogError("CSCCathodeLCTProcessor") << "CSCLCTDigi with invalid half-strip: " << clct.getStrip() + << "; allowed [0, " << CSCConstants::NUM_HALF_STRIPS_PER_CFEB - 1 << "]"; + errors++; + } + + // CLCT key half-strip must be within bounds + if (clct.getKeyStrip() >= max_strip) { + edm::LogError("CSCCathodeLCTProcessor") + << "CSCLCTDigi with invalid key half-strip: " << clct.getKeyStrip() << "; allowed [0, " << max_strip - 1 << "]"; + errors++; + } + + // CLCT with out-of-time BX + if (clct.getBX() >= CSCConstants::MAX_CLCT_TBINS) { + edm::LogError("CSCCathodeLCTProcessor") << "CSCLCTDigi with invalid BX: " << clct.getBX() << "; allowed [0, " + << CSCConstants::MAX_CLCT_TBINS - 1 << "]"; + errors++; + } + + // CLCT with neither left nor right bending + if (clct.getBend() > 1) { + edm::LogError("CSCCathodeLCTProcessor") + << "CSCLCTDigi with invalid bending: " << clct.getBend() << "; allowed [0,1]"; + errors++; + } + + // CLCT with an invalid pattern ID + if (clct.getPattern() < min_pattern or clct.getPattern() > max_pattern) { + edm::LogError("CSCCathodeLCTProcessor") << "CSCLCTDigi with invalid pattern ID: " << clct.getPattern() + << "; allowed [" << min_pattern << ", " << max_pattern << "]"; + errors++; + } + + // CLCT with an invalid CFEB ID + if (clct.getCFEB() < min_cfeb or clct.getCFEB() > max_cfeb) { + edm::LogError("CSCCathodeLCTProcessor") << "CSCLCTDigi with invalid CFEB ID: " << clct.getCFEB() << "; allowed [" + << min_cfeb << ", " << max_cfeb << "]"; + errors++; + } + + if (use_run3_patterns_) { + // CLCT comparator code is invalid + if (clct.getCompCode() < 0 or clct.getCompCode() >= std::pow(2, 12)) { + edm::LogError("CSCCathodeLCTProcessor") << "CSCLCTDigi with invalid comparator code: " << clct.getCompCode() + << "; allowed [0, " << std::pow(2, 12) - 1 << "]"; + errors++; + } + + unsigned max_quartstrip = csctp::get_csc_max_quartstrip(theStation, theRing); + unsigned max_eightstrip = csctp::get_csc_max_eightstrip(theStation, theRing); + + // CLCT key half-strip must be within bounds + if (clct.getKeyStrip(4) >= max_quartstrip) { + edm::LogError("CSCCathodeLCTProcessor") << "CSCLCTDigi with invalid key quart-strip: " << clct.getKeyStrip(4) + << "; allowed [0, " << max_quartstrip - 1 << "]"; + errors++; + } + + // CLCT key half-strip must be within bounds + if (clct.getKeyStrip(8) >= max_eightstrip) { + edm::LogError("CSCCathodeLCTProcessor") << "CSCLCTDigi with invalid key eight-strip: " << clct.getKeyStrip(8) + << "; allowed [0, " << max_eightstrip - 1 << "]"; + errors++; + } + } + + if (errors > 0) { + edm::LogError("CSCCathodeLCTProcessor") << "Faulty CLCT: " << cscId_ << " " << clct << "\n errors " << errors; + } +} + // Returns vector of read-out CLCTs, if any. Starts with the vector // of all found CLCTs and selects the ones in the read-out time window. std::vector CSCCathodeLCTProcessor::readoutCLCTs(int nMaxCLCTs) const { @@ -1103,7 +1203,7 @@ std::vector CSCCathodeLCTProcessor::readoutCLCTs(int nMaxCLCTs) con // Start from the vector of all found CLCTs and select those within // the CLCT*L1A coincidence window. int bx_readout = -1; - const std::vector& all_lcts = getCLCTs(); + const std::vector& all_lcts = getCLCTs(nMaxCLCTs); for (const auto& p : all_lcts) { // only consider valid CLCTs if (!p.isValid()) @@ -1146,6 +1246,11 @@ std::vector CSCCathodeLCTProcessor::readoutCLCTs(int nMaxCLCTs) con tmpV.erase(tmpV.begin() + nMaxCLCTs, tmpV.end()); } + // do a final check on the CLCTs in readout + for (const auto& clct : tmpV) { + checkValid(clct, nMaxCLCTs); + } + return tmpV; } @@ -1198,12 +1303,12 @@ std::vector CSCCathodeLCTProcessor::preTriggerDigisME1b() } // Returns vector of all found CLCTs, if any. Used for ALCT-CLCT matching. -std::vector CSCCathodeLCTProcessor::getCLCTs() const { +std::vector CSCCathodeLCTProcessor::getCLCTs(unsigned nMaxCLCTs) const { std::vector tmpV; for (int bx = 0; bx < CSCConstants::MAX_CLCT_TBINS; bx++) { - for (int iCLCT = 0; iCLCT < CSCConstants::MAX_CLCTS_PER_PROCESSOR; iCLCT++) { - if (CLCTContainer_[bx][iCLCT].isValid()) { - tmpV.push_back(CLCTContainer_[bx][iCLCT]); + for (unsigned iCLCT = 0; iCLCT < CLCTContainer_.at(bx).size(); iCLCT++) { + if (iCLCT < nMaxCLCTs and CLCTContainer_.at(bx).at(iCLCT).isValid()) { + tmpV.push_back(CLCTContainer_.at(bx).at(iCLCT)); } } } @@ -1216,13 +1321,21 @@ std::vector CSCCathodeLCTProcessor::getCLCTs() const { // to make a proper comparison with ALCTs we need // CLCT and ALCT to have the central BX in the same bin CSCCLCTDigi CSCCathodeLCTProcessor::getBestCLCT(int bx) const { - CSCCLCTDigi lct = CLCTContainer_[bx][0]; - lct.setBX(lct.getBX() + alctClctOffset_); + CSCCLCTDigi lct; + // check that the container has at least one entry + if (!CLCTContainer_.at(bx).empty()) { + lct = CLCTContainer_.at(bx).at(0); + lct.setBX(lct.getBX() + alctClctOffset_); + } return lct; } CSCCLCTDigi CSCCathodeLCTProcessor::getSecondCLCT(int bx) const { - CSCCLCTDigi lct = CLCTContainer_[bx][1]; - lct.setBX(lct.getBX() + alctClctOffset_); + CSCCLCTDigi lct; + // check that the container has at least two entries + if (CLCTContainer_.at(bx).size() >= 2) { + lct = CLCTContainer_.at(bx).at(1); + lct.setBX(lct.getBX() + alctClctOffset_); + } return lct; } diff --git a/L1Trigger/CSCTriggerPrimitives/src/CSCGEMMotherboard.cc b/L1Trigger/CSCTriggerPrimitives/src/CSCGEMMotherboard.cc index caf16eef9f07f..a4286c9cf3bd1 100644 --- a/L1Trigger/CSCTriggerPrimitives/src/CSCGEMMotherboard.cc +++ b/L1Trigger/CSCTriggerPrimitives/src/CSCGEMMotherboard.cc @@ -1,4 +1,5 @@ #include "L1Trigger/CSCTriggerPrimitives/interface/CSCGEMMotherboard.h" +#include "L1Trigger/CSCTriggerPrimitives/interface/CSCLCTTools.h" CSCGEMMotherboard::CSCGEMMotherboard(unsigned endcap, unsigned station, @@ -44,6 +45,10 @@ void CSCGEMMotherboard::retrieveGEMPads(const GEMPadDigiCollection* gemPads, uns GEMDetId roll_id(roll->id()); auto pads_in_det = gemPads->get(roll_id); for (auto pad = pads_in_det.first; pad != pads_in_det.second; ++pad) { + // ignore invalid pads + if (!pad->isValid()) + continue; + const int bx_shifted(CSCConstants::LCT_CENTRAL_BX + pad->bx()); // consider matches with BX difference +1/0/-1 for (int bx = bx_shifted - maxDeltaBXPad_; bx <= bx_shifted + maxDeltaBXPad_; ++bx) { @@ -98,8 +103,8 @@ CSCCorrelatedLCTDigi CSCGEMMotherboard::constructLCTsGEM(const CSCALCTDigi& alct // make a new LCT CSCCorrelatedLCTDigi thisLCT; - if (not alct.isValid() and not clct.isValid()) { - LogTrace("CSCGEMCMotherboard") << "Warning!!! either ALCT or CLCT not valid, return invalid LCT \n"; + if (!alct.isValid() and !clct.isValid()) { + edm::LogError("CSCGEMCMotherboard") << "Warning!!! neither ALCT nor CLCT valid, return invalid LCT"; return thisLCT; } diff --git a/L1Trigger/CSCTriggerPrimitives/src/CSCGEMMotherboardME11.cc b/L1Trigger/CSCTriggerPrimitives/src/CSCGEMMotherboardME11.cc index 76bdaa12e04a0..539509a06999d 100644 --- a/L1Trigger/CSCTriggerPrimitives/src/CSCGEMMotherboardME11.cc +++ b/L1Trigger/CSCTriggerPrimitives/src/CSCGEMMotherboardME11.cc @@ -19,9 +19,13 @@ CSCGEMMotherboardME11::CSCGEMMotherboardME11(unsigned endcap, buildLCTfromCLCTandGEM_ME1b_(tmbParams_.getParameter("buildLCTfromCLCTandGEM_ME1b")), promoteCLCTGEMquality_ME1a_(tmbParams_.getParameter("promoteCLCTGEMquality_ME1a")), promoteCLCTGEMquality_ME1b_(tmbParams_.getParameter("promoteCLCTGEMquality_ME1b")) { - if (!isSLHC_) - edm::LogError("CSCGEMMotherboardME11|ConfigError") - << "+++ Upgrade CSCGEMMotherboardME11 constructed while isSLHC is not set! +++\n"; + if (!isSLHC_) { + edm::LogError("CSCGEMMotherboardME11|SetupError") << "+++ TMB constructed while isSLHC is not set! +++\n"; + } + + if (!runME11ILT_) { + edm::LogError("CSCGEMMotherboardME11|SetupError") << "+++ TMB constructed while runME11ILT_ is not set! +++\n"; + }; // set LUTs tmbLUT_.reset(new CSCGEMMotherboardLUTME11()); @@ -30,9 +34,13 @@ CSCGEMMotherboardME11::CSCGEMMotherboardME11(unsigned endcap, CSCGEMMotherboardME11::CSCGEMMotherboardME11() : CSCGEMMotherboard() { // Constructor used only for testing. - if (!isSLHC_) - edm::LogError("CSCGEMMotherboardME11|ConfigError") - << "+++ Upgrade CSCGEMMotherboardME11 constructed while isSLHC is not set! +++\n"; + if (!isSLHC_) { + edm::LogError("CSCGEMMotherboardME11|SetupError") << "+++ TMB constructed while isSLHC is not set! +++\n"; + } + + if (!runME11ILT_) { + edm::LogError("CSCGEMMotherboardME11|SetupError") << "+++ TMB constructed while runME11ILT_ is not set! +++\n"; + } } CSCGEMMotherboardME11::~CSCGEMMotherboardME11() {} @@ -71,17 +79,15 @@ void CSCGEMMotherboardME11::run(const CSCWireDigiCollection* wiredc, // check for GEM geometry if (not gemGeometryAvailable) { - if (infoV >= 0) - edm::LogError("CSCGEMMotherboardME11|SetupError") - << "+++ run() called for GEM-CSC integrated trigger without valid GEM geometry! +++ \n"; + edm::LogError("CSCGEMMotherboardME11|SetupError") + << "+++ run() called for GEM-CSC integrated trigger without valid GEM geometry! +++ \n"; return; } gemCoPadV = coPadProcessor->run(gemPads); // run copad processor in GE1/1 - if (!(alctProc and clctProc and isSLHC_)) { - if (infoV >= 0) - edm::LogError("CSCGEMMotherboardME11|SetupError") - << "+++ run() called for non-existing ALCT/CLCT processor! +++ \n"; + if (!(alctProc and clctProc)) { + edm::LogError("CSCGEMMotherboardME11|SetupError") + << "+++ run() called for non-existing ALCT/CLCT processor! +++ \n"; return; } @@ -478,6 +484,12 @@ std::vector CSCGEMMotherboardME11::readoutLCTsME11(enum CS } else tmpV.push_back(lct); } + + // do a final check on the LCTs in readout + for (const auto& lct : tmpV) { + checkValid(lct); + } + return tmpV; } diff --git a/L1Trigger/CSCTriggerPrimitives/src/CSCGEMMotherboardME21.cc b/L1Trigger/CSCTriggerPrimitives/src/CSCGEMMotherboardME21.cc index 45752d32f2f0f..be1572ef4260c 100644 --- a/L1Trigger/CSCTriggerPrimitives/src/CSCGEMMotherboardME21.cc +++ b/L1Trigger/CSCTriggerPrimitives/src/CSCGEMMotherboardME21.cc @@ -11,18 +11,26 @@ CSCGEMMotherboardME21::CSCGEMMotherboardME21(unsigned endcap, dropLowQualityALCTsNoGEMs_(tmbParams_.getParameter("dropLowQualityALCTsNoGEMs")), buildLCTfromALCTandGEM_(tmbParams_.getParameter("buildLCTfromALCTandGEM")), buildLCTfromCLCTandGEM_(tmbParams_.getParameter("buildLCTfromCLCTandGEM")) { - if (!isSLHC_ or !runME21ILT_) - edm::LogError("CSCGEMMotherboardME21|ConfigError") - << "+++ Upgrade CSCGEMMotherboardME21 constructed while isSLHC is not set! +++\n"; + if (!isSLHC_) { + edm::LogError("CSCGEMMotherboardME21|SetupError") << "+++ TMB constructed while isSLHC is not set! +++\n"; + } + + if (!runME21ILT_) { + edm::LogError("CSCGEMMotherboardME21|SetupError") << "+++ TMB constructed while runME21ILT_ is not set! +++\n"; + } // set LUTs tmbLUT_.reset(new CSCGEMMotherboardLUTME21()); } CSCGEMMotherboardME21::CSCGEMMotherboardME21() : CSCGEMMotherboard() { - if (!isSLHC_ or !runME21ILT_) - edm::LogError("CSCGEMMotherboardME21|ConfigError") - << "+++ Upgrade CSCGEMMotherboardME21 constructed while isSLHC is not set! +++\n"; + if (!isSLHC_) { + edm::LogError("CSCGEMMotherboardME21|SetupError") << "+++ TMB constructed while isSLHC is not set! +++\n"; + } + + if (!runME21ILT_) { + edm::LogError("CSCGEMMotherboardME21|SetupError") << "+++ TMB constructed while runME21ILT_ is not set! +++\n"; + } } CSCGEMMotherboardME21::~CSCGEMMotherboardME21() {} @@ -54,17 +62,15 @@ void CSCGEMMotherboardME21::run(const CSCWireDigiCollection* wiredc, // check for GEM geometry if (not gemGeometryAvailable) { - if (infoV >= 0) - edm::LogError("CSCGEMMotherboardME21|SetupError") - << "+++ run() called for GEM-CSC integrated trigger without valid GEM geometry! +++ \n"; + edm::LogError("CSCGEMMotherboardME21|SetupError") + << "+++ run() called for GEM-CSC integrated trigger without valid GEM geometry! +++ \n"; return; } gemCoPadV = coPadProcessor->run(gemPads); // run copad processor in GE1/1 if (!(alctProc and clctProc)) { - if (infoV >= 0) - edm::LogError("CSCGEMMotherboardME21|SetupError") - << "+++ run() called for non-existing ALCT/CLCT processor! +++ \n"; + edm::LogError("CSCGEMMotherboardME21|SetupError") + << "+++ run() called for non-existing ALCT/CLCT processor! +++ \n"; return; } @@ -107,6 +113,8 @@ void CSCGEMMotherboardME21::run(const CSCWireDigiCollection* wiredc, const int bx_copad_start(bx_alct - maxDeltaBXCoPad_); const int bx_copad_stop(bx_alct + maxDeltaBXCoPad_); + const int quality(alctProc->getBestALCT(bx_alct).getQuality()); + if (debug_matching) { LogTrace("CSCGEMMotherboardME21") << "========================================================================" << std::endl @@ -214,7 +222,8 @@ void CSCGEMMotherboardME21::run(const CSCWireDigiCollection* wiredc, // ALCT-to-GEM matching int nGoodGEMMatches = 0; - if (nGoodMatches == 0 and buildLCTfromALCTandGEM_) { + // only use high-quality stubs + if (nGoodMatches == 0 and buildLCTfromALCTandGEM_ and quality >=1) { if (debug_matching) LogTrace("CSCGEMMotherboardME21") << "++No valid ALCT-CLCT matches in ME21" << std::endl; for (int bx_gem = bx_copad_start; bx_gem <= bx_copad_stop; bx_gem++) { @@ -436,6 +445,12 @@ std::vector CSCGEMMotherboardME21::readoutLCTs() const { CSCUpgradeMotherboard::sortLCTs(result, CSCUpgradeMotherboard::sortLCTsByQuality); if (tmb_cross_bx_algo == 3) CSCUpgradeMotherboard::sortLCTs(result, CSCUpgradeMotherboard::sortLCTsByGEMDphi); + + // do a final check on the LCTs in readout + for (const auto& lct : result) { + checkValid(lct); + } + return result; } diff --git a/L1Trigger/CSCTriggerPrimitives/src/CSCLCTTools.cc b/L1Trigger/CSCTriggerPrimitives/src/CSCLCTTools.cc new file mode 100644 index 0000000000000..5eb13047a5e4e --- /dev/null +++ b/L1Trigger/CSCTriggerPrimitives/src/CSCLCTTools.cc @@ -0,0 +1,109 @@ +#include "L1Trigger/CSCTriggerPrimitives/interface/CSCLCTTools.h" + +namespace csctp { + + // Number of halfstrips and wiregroups + // +----------------------------+------------+------------+ + // | Chamber type | Num of | Num of | + // | | halfstrips | wiregroups | + // +----------------------------+------------+------------+ + // | ME1/1a | 96 | 48 | + // | ME1/1b | 128 | 48 | + // | ME1/2 | 160 | 64 | + // | ME1/3 | 128 | 32 | + // | ME2/1 | 160 | 112 | + // | ME3/1, ME4/1 | 160 | 96 | + // | ME2/2, ME3/2, ME4/2 | 160 | 64 | + // +----------------------------+------------+------------+ + + unsigned get_csc_max_wire(int station, int ring) { + unsigned max_wire = 0; // wiregroup + if (station == 1 && ring == 4) { // ME1/1a + max_wire = 48; + } else if (station == 1 && ring == 1) { // ME1/1b + max_wire = 48; + } else if (station == 1 && ring == 2) { // ME1/2 + max_wire = 64; + } else if (station == 1 && ring == 3) { // ME1/3 + max_wire = 32; + } else if (station == 2 && ring == 1) { // ME2/1 + max_wire = 112; + } else if (station >= 3 && ring == 1) { // ME3/1, ME4/1 + max_wire = 96; + } else if (station >= 2 && ring == 2) { // ME2/2, ME3/2, ME4/2 + max_wire = 64; + } + return max_wire; + } + + unsigned get_csc_max_halfstrip(int station, int ring) { + int max_strip = 0; // halfstrip + if (station == 1 && ring == 4) { // ME1/1a + max_strip = 96; + } else if (station == 1 && ring == 1) { // ME1/1b + // In the CSC local trigger + // ME1/a is taken together with ME1/b + max_strip = 128 + 96; + } else if (station == 1 && ring == 2) { // ME1/2 + max_strip = 160; + } else if (station == 1 && ring == 3) { // ME1/3 + max_strip = 128; + } else if (station == 2 && ring == 1) { // ME2/1 + max_strip = 160; + } else if (station >= 3 && ring == 1) { // ME3/1, ME4/1 + max_strip = 160; + } else if (station >= 2 && ring == 2) { // ME2/2, ME3/2, ME4/2 + max_strip = 160; + } + return max_strip; + } + + unsigned get_csc_max_quartstrip(int station, int ring) { return get_csc_max_halfstrip(station, ring) * 2; } + + unsigned get_csc_max_eightstrip(int station, int ring) { return get_csc_max_halfstrip(station, ring) * 4; } + + std::pair get_csc_min_max_cfeb(int station, int ring) { + // 5 CFEBs [0,4] for non-ME1/1 chambers + int min_cfeb = 0; + int max_cfeb = CSCConstants::MAX_CFEBS - 1; // 4 + // 7 CFEBs [0,6] for ME1/1 chambers + if (station == 1 and ring == 1) { + max_cfeb = 6; + } + return std::make_pair(min_cfeb, max_cfeb); + } + + std::pair get_csc_min_max_pattern(bool isRun3) { + int min_pattern, max_pattern; + // Run-1 or Run-2 case + if (!isRun3) { + min_pattern = 2; + max_pattern = 10; + // Run-3 case + } else { + min_pattern = 0; + max_pattern = 4; + } + return std::make_pair(min_pattern, max_pattern); + } + + unsigned get_csc_alct_max_quality(int station, int ring, bool runGEMCSC) { + int max_quality = 3; + // GE2/1-ME2/1 ALCTs are allowed 3-layer ALCTs + if (runGEMCSC and station == 2 and ring == 1) { + max_quality = 4; + } + return max_quality; + } + + unsigned get_csc_clct_max_quality() { + int max_quality = 6; + return max_quality; + } + + unsigned get_csc_lct_max_quality() { + int max_quality = 15; + return max_quality; + } + +} // namespace csctp diff --git a/L1Trigger/CSCTriggerPrimitives/src/CSCMotherboard.cc b/L1Trigger/CSCTriggerPrimitives/src/CSCMotherboard.cc index 0cf847a627286..4ad3b6ee90fef 100644 --- a/L1Trigger/CSCTriggerPrimitives/src/CSCMotherboard.cc +++ b/L1Trigger/CSCTriggerPrimitives/src/CSCMotherboard.cc @@ -1,4 +1,5 @@ #include "L1Trigger/CSCTriggerPrimitives/interface/CSCMotherboard.h" +#include "L1Trigger/CSCTriggerPrimitives/interface/CSCLCTTools.h" #include // Default values of configuration parameters. @@ -37,6 +38,8 @@ CSCMotherboard::CSCMotherboard(unsigned endcap, clct_to_alct = tmbParams_.getParameter("clctToAlct"); + use_run3_patterns_ = clctParams_.getParameter("useRun3Patterns"); + // special tmb bits useHighMultiplicityBits_ = tmbParams_.getParameter("useHighMultiplicityBits"); highMultiplicityBits_ = 0; @@ -130,8 +133,7 @@ void CSCMotherboard::run(const CSCWireDigiCollection* wiredc, const CSCComparato // Check for existing processors if (!(alctProc && clctProc)) { - if (infoV >= 0) - edm::LogError("CSCMotherboard|SetupError") << "+++ run() called for non-existing ALCT/CLCT processor! +++ \n"; + edm::LogError("CSCMotherboard|SetupError") << "+++ run() called for non-existing ALCT/CLCT processor! +++ \n"; return; } @@ -399,6 +401,12 @@ std::vector CSCMotherboard::readoutLCTs() const { else tmpV.push_back(*plct); } + + // do a final check on the LCTs in readout + for (const auto& lct : tmpV) { + checkValid(lct); + } + return tmpV; } @@ -409,10 +417,10 @@ std::vector CSCMotherboard::getLCTs() const { // Do not report LCTs found in ME1/A if mpc_block_me1/a is set. for (int bx = 0; bx < CSCConstants::MAX_LCT_TBINS; bx++) { if (firstLCT[bx].isValid()) - if (!mpc_block_me1a || (!isME11_ || firstLCT[bx].getStrip() <= 127)) + if (!mpc_block_me1a || (!isME11_ || firstLCT[bx].getStrip() <= CSCConstants::MAX_HALF_STRIP_ME1B)) tmpV.push_back(firstLCT[bx]); if (secondLCT[bx].isValid()) - if (!mpc_block_me1a || (!isME11_ || secondLCT[bx].getStrip() <= 127)) + if (!mpc_block_me1a || (!isME11_ || secondLCT[bx].getStrip() <= CSCConstants::MAX_HALF_STRIP_ME1B)) tmpV.push_back(secondLCT[bx]); } return tmpV; @@ -635,3 +643,123 @@ void CSCMotherboard::encodeHighMultiplicityBits(unsigned alctBits) { // this depends on memory constraints in the TMB FPGA highMultiplicityBits_ = alctBits; } + +void CSCMotherboard::checkValid(const CSCCorrelatedLCTDigi& lct) const { + const unsigned max_strip = csctp::get_csc_max_halfstrip(theStation, theRing); + const unsigned max_quartstrip = csctp::get_csc_max_quartstrip(theStation, theRing); + const unsigned max_eightstrip = csctp::get_csc_max_eightstrip(theStation, theRing); + const unsigned max_wire = csctp::get_csc_max_wire(theStation, theRing); + const auto& [min_pattern, max_pattern] = csctp::get_csc_min_max_pattern(use_run3_patterns_); + const unsigned max_quality = csctp::get_csc_lct_max_quality(); + + unsigned errors = 0; + + // LCT must be valid + if (!lct.isValid()) { + edm::LogError("CSCMotherboard") << "CSCCorrelatedLCTDigi with invalid bit set: " << lct.isValid(); + errors++; + } + + // LCT number is 1 or 2 + if (lct.getTrknmb() < 1 or lct.getTrknmb() > 2) { + edm::LogError("CSCMotherboard") << "CSCCorrelatedLCTDigi with invalid track number: " << lct.getTrknmb() + << "; allowed [1,2]"; + errors++; + } + + // LCT quality must be valid + if (lct.getQuality() > max_quality) { + edm::LogError("CSCMotherboard") << "CSCCorrelatedLCTDigi with invalid quality: " << lct.getQuality() + << "; allowed [0,15]"; + errors++; + } + + // LCT key half-strip must be within bounds + if (lct.getStrip() > max_strip) { + edm::LogError("CSCMotherboard") << "CSCCorrelatedLCTDigi with invalid half-strip: " << lct.getStrip() + << "; allowed [0, " << max_strip << "]"; + errors++; + } + + // LCT key half-strip must be within bounds + if (lct.getStrip(4) >= max_quartstrip) { + edm::LogError("CSCMotherboard") << "CSCCorrelatedLCTDigi with invalid key quart-strip: " << lct.getStrip(4) + << "; allowed [0, " << max_quartstrip - 1 << "]"; + errors++; + } + + // LCT key half-strip must be within bounds + if (lct.getStrip(8) >= max_eightstrip) { + edm::LogError("CSCMotherboard") << "CSCCorrelatedLCTDigi with invalid key eight-strip: " << lct.getStrip(8) + << "; allowed [0, " << max_eightstrip - 1 << "]"; + errors++; + } + + // LCT key wire-group must be within bounds + if (lct.getKeyWG() > max_wire) { + edm::LogError("CSCMotherboard") << "CSCCorrelatedLCTDigi with invalid wire-group: " << lct.getKeyWG() + << "; allowed [0, " << max_wire << "]"; + errors++; + } + + // LCT with out-of-time BX + if (lct.getBX() > CSCConstants::MAX_LCT_TBINS - 1) { + edm::LogError("CSCMotherboard") << "CSCCorrelatedLCTDigi with invalid BX: " << lct.getBX() << "; allowed [0, " + << CSCConstants::MAX_LCT_TBINS - 1 << "]"; + errors++; + } + + // LCT with neither left nor right bending + if (lct.getBend() > 1) { + edm::LogError("CSCMotherboard") << "CSCCorrelatedLCTDigi with invalid bending: " << lct.getBend() + << "; allowed [0,1"; + errors++; + } + + // LCT with invalid CSCID + if (lct.getCSCID() < CSCTriggerNumbering::minTriggerCscId() or + lct.getCSCID() > CSCTriggerNumbering::maxTriggerCscId()) { + edm::LogError("CSCMotherboard") << "CSCCorrelatedLCTDigi with invalid CSCID: " << lct.getBend() << "; allowed [" + << CSCTriggerNumbering::minTriggerCscId() << ", " + << CSCTriggerNumbering::maxTriggerCscId() << "]"; + errors++; + } + + // LCT with an invalid pattern ID + if (lct.getPattern() < min_pattern or lct.getPattern() > max_pattern) { + edm::LogError("CSCMotherboard") << "CSCCorrelatedLCTDigi with invalid pattern ID: " << lct.getPattern() + << "; allowed [" << min_pattern << ", " << max_pattern << "]"; + errors++; + } + + // simulated LCT type must be valid + if (lct.getType() == CSCCorrelatedLCTDigi::CLCTALCT or lct.getType() == CSCCorrelatedLCTDigi::CLCTONLY or + lct.getType() == CSCCorrelatedLCTDigi::ALCTONLY) { + edm::LogError("CSCMotherboard") << "CSCCorrelatedLCTDigi with invalid type (SIM): " << lct.getType() + << "; allowed [" << CSCCorrelatedLCTDigi::ALCTCLCT << ", " + << CSCCorrelatedLCTDigi::CLCT2GEM << "]"; + errors++; + } + + // non-GEM-CSC stations ALWAYS send out ALCTCLCT type LCTs + if (!(theRing == 1 and (theStation == 1 or theStation == 2))) { + if (lct.getType() != CSCCorrelatedLCTDigi::ALCTCLCT) { + edm::LogError("CSCMotherboard") << "CSCCorrelatedLCTDigi with invalid type (SIM) in this station: " + << lct.getType() << "; allowed [" << CSCCorrelatedLCTDigi::ALCTCLCT << "]"; + errors++; + } + } + + // GEM-CSC stations can send out GEM-type LCTs ONLY when the ILT is turned on! + if (theRing == 1 and lct.getType() != CSCCorrelatedLCTDigi::ALCTCLCT) { + if ((theStation == 1 and !runME11ILT_) or (theStation == 2 and !runME21ILT_)) { + edm::LogError("CSCMotherboard") << "CSCCorrelatedLCTDigi with invalid type (SIM) with GEM-CSC trigger not on: " + << lct.getType() << "; allowed [" << CSCCorrelatedLCTDigi::ALCTCLCT << "]"; + errors++; + } + } + + if (errors > 0) { + edm::LogError("CSCMotherboard") << "Faulty LCT: " << cscId_ << " " << lct << "\n errors " << errors; + } +} diff --git a/L1Trigger/CSCTriggerPrimitives/src/CSCMotherboardME11.cc b/L1Trigger/CSCTriggerPrimitives/src/CSCMotherboardME11.cc index 657de7f9ba544..4bca564f06900 100644 --- a/L1Trigger/CSCTriggerPrimitives/src/CSCMotherboardME11.cc +++ b/L1Trigger/CSCTriggerPrimitives/src/CSCMotherboardME11.cc @@ -20,8 +20,10 @@ CSCMotherboardME11::CSCMotherboardME11(unsigned endcap, const edm::ParameterSet& conf) : CSCUpgradeMotherboard(endcap, station, sector, subsector, chamber, conf) { if (!isSLHC_) - edm::LogError("CSCMotherboardME11|ConfigError") - << "+++ Upgrade CSCMotherboardME11 constructed while isSLHC_ is not set! +++\n"; + edm::LogError("CSCMotherboardME11|SetupError") << "+++ TMB constructed while isSLHC_ is not set! +++\n"; + + if (!runME11Up_) + edm::LogError("CSCMotherboardME11|SetupError") << "+++ TMB constructed while runME11Up_ is not set! +++\n"; cscTmbLUT_.reset(new CSCMotherboardLUTME11()); @@ -31,8 +33,10 @@ CSCMotherboardME11::CSCMotherboardME11(unsigned endcap, CSCMotherboardME11::CSCMotherboardME11() : CSCUpgradeMotherboard() { if (!isSLHC_) - edm::LogError("CSCMotherboardME11|ConfigError") - << "+++ Upgrade CSCMotherboardME11 constructed while isSLHC_ is not set! +++\n"; + edm::LogError("CSCMotherboardME11|SetupError") << "+++ TMB constructed while isSLHC_ is not set! +++\n"; + + if (!runME11Up_) + edm::LogError("CSCMotherboardME11|SetupError") << "+++ TMB constructed while runME11Up_ is not set! +++\n"; } CSCMotherboardME11::~CSCMotherboardME11() {} @@ -50,9 +54,8 @@ void CSCMotherboardME11::run(const CSCWireDigiCollection* wiredc, const CSCCompa clear(); // Check for existing processors - if (!(alctProc && clctProc && isSLHC_)) { - if (infoV >= 0) - edm::LogError("CSCMotherboardME11|SetupError") << "+++ run() called for non-existing ALCT/CLCT processor! +++ \n"; + if (!(alctProc && clctProc)) { + edm::LogError("CSCMotherboardME11|SetupError") << "+++ run() called for non-existing ALCT/CLCT processor! +++ \n"; return; } @@ -273,6 +276,12 @@ std::vector CSCMotherboardME11::readoutLCTs(int me1ab) con } else tmpV.push_back(*plct); } + + // do a final check on the LCTs in readout + for (const auto& lct : tmpV) { + checkValid(lct); + } + return tmpV; } diff --git a/L1Trigger/CSCTriggerPrimitives/src/CSCTriggerPrimitivesBuilder.cc b/L1Trigger/CSCTriggerPrimitives/src/CSCTriggerPrimitivesBuilder.cc index 33140c4577946..80197156e0490 100644 --- a/L1Trigger/CSCTriggerPrimitives/src/CSCTriggerPrimitivesBuilder.cc +++ b/L1Trigger/CSCTriggerPrimitives/src/CSCTriggerPrimitivesBuilder.cc @@ -59,23 +59,22 @@ CSCTriggerPrimitivesBuilder::CSCTriggerPrimitivesBuilder(const edm::ParameterSet // go through all possible cases if (isSLHC_ and ring == 1 and stat == 1 and runME11Up_ and !runME11ILT_) - tmb_[endc - 1][stat - 1][sect - 1][subs - 1][cham - 1].reset( - new CSCMotherboardME11(endc, stat, sect, subs, cham, conf)); + tmb_[endc - 1][stat - 1][sect - 1][subs - 1][cham - 1] = + std::make_unique(endc, stat, sect, subs, cham, conf); else if (isSLHC_ and ring == 1 and stat == 1 and runME11Up_ and runME11ILT_) - tmb_[endc - 1][stat - 1][sect - 1][subs - 1][cham - 1].reset( - new CSCGEMMotherboardME11(endc, stat, sect, subs, cham, conf)); - else if (isSLHC_ and ring == 1 and stat == 2 and runME21Up_ and !runME21ILT_) - tmb_[endc - 1][stat - 1][sect - 1][subs - 1][cham - 1].reset( - new CSCUpgradeMotherboard(endc, stat, sect, subs, cham, conf)); + tmb_[endc - 1][stat - 1][sect - 1][subs - 1][cham - 1] = + std::make_unique(endc, stat, sect, subs, cham, conf); else if (isSLHC_ and ring == 1 and stat == 2 and runME21Up_ and runME21ILT_) - tmb_[endc - 1][stat - 1][sect - 1][subs - 1][cham - 1].reset( - new CSCGEMMotherboardME21(endc, stat, sect, subs, cham, conf)); - else if (isSLHC_ and ring == 1 and ((stat == 3 and runME31Up_) || (stat == 4 and runME41Up_))) - tmb_[endc - 1][stat - 1][sect - 1][subs - 1][cham - 1].reset( - new CSCUpgradeMotherboard(endc, stat, sect, subs, cham, conf)); + tmb_[endc - 1][stat - 1][sect - 1][subs - 1][cham - 1] = + std::make_unique(endc, stat, sect, subs, cham, conf); + else if (isSLHC_ and ring == 1 and + ((stat == 2 and runME21Up_ and !runME21ILT_) || (stat == 3 and runME31Up_) || + (stat == 4 and runME41Up_))) + tmb_[endc - 1][stat - 1][sect - 1][subs - 1][cham - 1] = + std::make_unique(endc, stat, sect, subs, cham, conf); else - tmb_[endc - 1][stat - 1][sect - 1][subs - 1][cham - 1].reset( - new CSCMotherboard(endc, stat, sect, subs, cham, conf)); + tmb_[endc - 1][stat - 1][sect - 1][subs - 1][cham - 1] = + std::make_unique(endc, stat, sect, subs, cham, conf); } } } @@ -335,7 +334,9 @@ void CSCTriggerPrimitivesBuilder::build(const CSCBadChambers* badChambers, put(alctpretriggerV, oc_alctpretrigger, detid, " ME21 ALCT pre-trigger digi"); } // running upgraded ME2/1-ME3/1-ME4/1 TMBs (without GEMs or RPCs) - else if ((stat == 2 or stat == 3 or stat == 4) && ring == 1 && isSLHC_) { + else if (isSLHC_ and ring == 1 and + ((stat == 2 and runME21Up_ and !runME21ILT_) || (stat == 3 and runME31Up_) || + (stat == 4 and runME41Up_))) { // run the TMB CSCUpgradeMotherboard* utmb = static_cast(tmb); utmb->setCSCGeometry(csc_g); diff --git a/L1Trigger/CSCTriggerPrimitives/src/CSCUpgradeAnodeLCTProcessor.cc b/L1Trigger/CSCTriggerPrimitives/src/CSCUpgradeAnodeLCTProcessor.cc index 699b7aac27cc2..4fdd400c89e21 100644 --- a/L1Trigger/CSCTriggerPrimitives/src/CSCUpgradeAnodeLCTProcessor.cc +++ b/L1Trigger/CSCTriggerPrimitives/src/CSCUpgradeAnodeLCTProcessor.cc @@ -36,7 +36,7 @@ void CSCUpgradeAnodeLCTProcessor::ghostCancellationLogic() { // Non-empty wire group. int qual_this = quality[key_wire][i_pattern]; if (qual_this > 0) { - if (isSLHC_ and (runME21ILT_ or runME31Up_ or runME41Up_)) + if (isSLHC_ and runME21ILT_) qual_this = (qual_this & 0x03); // Previous wire. int dt = -1; @@ -47,7 +47,7 @@ void CSCUpgradeAnodeLCTProcessor::ghostCancellationLogic() { else dt = first_bx[key_wire] - first_bx[key_wire - 1]; // hack to run the Phase-II ME2/1, ME3/1 and ME4/1 ILT - if (isSLHC_ and (runME21ILT_ or runME31Up_ or runME41Up_)) + if (isSLHC_ and runME21ILT_) qual_prev = (qual_prev & 0x03); // Cancel this wire @@ -84,7 +84,7 @@ void CSCUpgradeAnodeLCTProcessor::ghostCancellationLogic() { else dt = first_bx[key_wire] - first_bx[key_wire + 1]; // hack to run the Phase-II ME2/1, ME3/1 and ME4/1 ILT - if (isSLHC_ and (runME21ILT_ or runME31Up_ or runME41Up_)) + if (isSLHC_ and runME21ILT_) qual_next = (qual_next & 0x03); // Same cancellation logic as for the previous wire. if (dt == 0) { @@ -127,7 +127,7 @@ void CSCUpgradeAnodeLCTProcessor::ghostCancellationLogicOneWire(const int key_wi // Non-empty wire group. int qual_this = quality[key_wire][i_pattern]; if (qual_this > 0) { - if (isSLHC_ and (runME21ILT_ or runME31Up_ or runME41Up_)) + if (isSLHC_ and runME21ILT_) qual_this = (qual_this & 0x03); // Previous wire. int dt = -1; @@ -150,7 +150,7 @@ void CSCUpgradeAnodeLCTProcessor::ghostCancellationLogicOneWire(const int key_wi else dt = first_bx[key_wire] - first_bx_prev; // hack to run the Phase-II ME2/1, ME3/1 and ME4/1 ILT - if (isSLHC_ and (runME21ILT_ or runME31Up_ or runME41Up_)) + if (isSLHC_ and runME21ILT_) qual_prev = (qual_prev & 0x03); // Cancel this wire @@ -195,7 +195,7 @@ int CSCUpgradeAnodeLCTProcessor::getTempALCTQuality(int temp_quality) const { // on pattern_thresh. int Q; // hack to run the Phase-II ME2/1, ME3/1 and ME4/1 ILT - if (temp_quality == 3 and isSLHC_ and (runME21ILT_ or runME31Up_ or runME41Up_)) + if (temp_quality == 3 and isSLHC_ and runME21ILT_) Q = 4; else if (temp_quality > 3) Q = temp_quality - 3; diff --git a/L1Trigger/CSCTriggerPrimitives/src/CSCUpgradeMotherboard.cc b/L1Trigger/CSCTriggerPrimitives/src/CSCUpgradeMotherboard.cc index a02c2af86e59e..ca316127e8c7e 100644 --- a/L1Trigger/CSCTriggerPrimitives/src/CSCUpgradeMotherboard.cc +++ b/L1Trigger/CSCTriggerPrimitives/src/CSCUpgradeMotherboard.cc @@ -10,8 +10,18 @@ CSCUpgradeMotherboard::CSCUpgradeMotherboard(unsigned endcap, CSCMotherboard(endcap, station, sector, subsector, chamber, conf), allLCTs(match_trig_window_size) { if (!isSLHC_) - edm::LogError("CSCUpgradeMotherboard|ConfigError") - << "+++ Upgrade CSCUpgradeMotherboard constructed while isSLHC_ is not set! +++\n"; + edm::LogError("CSCUpgradeMotherboard|SetupError") << "+++ TMB constructed while isSLHC_ is not set! +++\n"; + + if (theRing == 1) { + if (theStation == 1 and !runME11Up_) + edm::LogError("CSCUpgradeMotherboard|SetupError") << "+++ TMB constructed while runME11Up_ is not set! +++\n"; + if (theStation == 2 and !runME21Up_) + edm::LogError("CSCUpgradeMotherboard|SetupError") << "+++ TMB constructed while runME21Up_ is not set! +++\n"; + if (theStation == 3 and !runME31Up_) + edm::LogError("CSCUpgradeMotherboard|SetupError") << "+++ TMB constructed while runME31Up_ is not set! +++\n"; + if (theStation == 4 and !runME41Up_) + edm::LogError("CSCUpgradeMotherboard|SetupError") << "+++ TMB constructed while runME41Up_ is not set! +++\n"; + } theParity = theChamber % 2 == 0 ? Parity::Even : Parity::Odd; @@ -40,8 +50,18 @@ CSCUpgradeMotherboard::CSCUpgradeMotherboard(unsigned endcap, CSCUpgradeMotherboard::CSCUpgradeMotherboard() : CSCMotherboard(), allLCTs(match_trig_window_size) { if (!isSLHC_) - edm::LogError("CSCUpgradeMotherboard|ConfigError") - << "+++ Upgrade CSCUpgradeMotherboard constructed while isSLHC_ is not set! +++\n"; + edm::LogError("CSCUpgradeMotherboard|SetupError") << "+++ TMB constructed while isSLHC_ is not set! +++\n"; + + if (theRing == 1) { + if (theStation == 1 and !runME11Up_) + edm::LogError("CSCUpgradeMotherboard|SetupError") << "+++ TMB constructed while runME11Up_ is not set! +++\n"; + if (theStation == 2 and !runME21Up_) + edm::LogError("CSCUpgradeMotherboard|SetupError") << "+++ TMB constructed while runME21Up_ is not set! +++\n"; + if (theStation == 3 and !runME31Up_) + edm::LogError("CSCUpgradeMotherboard|SetupError") << "+++ TMB constructed while runME31Up_ is not set! +++\n"; + if (theStation == 4 and !runME41Up_) + edm::LogError("CSCUpgradeMotherboard|SetupError") << "+++ TMB constructed while runME41Up_ is not set! +++\n"; + } setPrefIndex(); } @@ -50,9 +70,8 @@ void CSCUpgradeMotherboard::run(const CSCWireDigiCollection* wiredc, const CSCCo clear(); if (!(alctProc and clctProc)) { - if (infoV >= 0) - edm::LogError("CSCUpgradeMotherboard|SetupError") - << "+++ run() called for non-existing ALCT/CLCT processor! +++ \n"; + edm::LogError("CSCUpgradeMotherboard|SetupError") + << "+++ run() called for non-existing ALCT/CLCT processor! +++ \n"; return; } @@ -243,6 +262,12 @@ std::vector CSCUpgradeMotherboard::readoutLCTs() const { allLCTs.getMatched(result); if (tmb_cross_bx_algo == 2) CSCUpgradeMotherboard::sortLCTs(result, CSCUpgradeMotherboard::sortLCTsByQuality); + + // do a final check on the LCTs in readout + for (const auto& lct : result) { + checkValid(lct); + } + return result; }