diff --git a/DataFormats/CSCDigi/interface/CSCShowerDigi.h b/DataFormats/CSCDigi/interface/CSCShowerDigi.h index 942bbec739398..f637fd89299e1 100644 --- a/DataFormats/CSCDigi/interface/CSCShowerDigi.h +++ b/DataFormats/CSCDigi/interface/CSCShowerDigi.h @@ -10,9 +10,24 @@ class CSCShowerDigi { public: // Run-3 definitions as provided in DN-20-033 enum Run3Shower { kInvalid = 0, kLoose = 1, kNominal = 2, kTight = 3 }; + // Shower types. and showers from OTMB/TMB are assigned with kLCTShower + enum ShowerType { + kInvalidShower = 0, + kALCTShower = 1, + kCLCTShower = 2, + kLCTShower = 3, + kEMTFShower = 4, + kGMTShower = 5 + }; /// Constructors - CSCShowerDigi(const uint16_t inTimeBits, const uint16_t outTimeBits, const uint16_t cscID); + CSCShowerDigi(const uint16_t inTimeBits, + const uint16_t outTimeBits, + const uint16_t cscID, + const uint16_t bx = 0, + const uint16_t showerType = 4, + const uint16_t wireNHits = 0, + const uint16_t compNHits = 0); /// default CSCShowerDigi(); @@ -28,20 +43,30 @@ class CSCShowerDigi { bool isLooseOutOfTime() const; bool isNominalOutOfTime() const; bool isTightOutOfTime() const; + bool isValidShowerType() const; uint16_t bitsInTime() const { return bitsInTime_; } uint16_t bitsOutOfTime() const { return bitsOutOfTime_; } + uint16_t getBX() const { return bx_; } uint16_t getCSCID() const { return cscID_; } + uint16_t getShowerType() const { return showerType_; } + uint16_t getWireNHits() const { return wireNHits_; } + uint16_t getComparatorNHits() const { return comparatorNHits_; } /// set cscID void setCSCID(const uint16_t c) { cscID_ = c; } + void setBX(const uint16_t bx) { bx_ = bx; } private: uint16_t bitsInTime_; uint16_t bitsOutOfTime_; // 4-bit CSC chamber identifier uint16_t cscID_; + uint16_t bx_; + uint16_t showerType_; + uint16_t wireNHits_; + uint16_t comparatorNHits_; }; std::ostream& operator<<(std::ostream& o, const CSCShowerDigi& digi); diff --git a/DataFormats/CSCDigi/src/CSCShowerDigi.cc b/DataFormats/CSCDigi/src/CSCShowerDigi.cc index 9a50ef75cb39b..e79ab6453bdcc 100644 --- a/DataFormats/CSCDigi/src/CSCShowerDigi.cc +++ b/DataFormats/CSCDigi/src/CSCShowerDigi.cc @@ -6,21 +6,39 @@ using namespace std; /// Constructors -CSCShowerDigi::CSCShowerDigi(const uint16_t bitsInTime, const uint16_t bitsOutOfTime, const uint16_t cscID) - : bitsInTime_(bitsInTime), bitsOutOfTime_(bitsOutOfTime), cscID_(cscID) {} +CSCShowerDigi::CSCShowerDigi(const uint16_t bitsInTime, + const uint16_t bitsOutOfTime, + const uint16_t cscID, + const uint16_t bx, + const uint16_t showerType, + const uint16_t wireNHits, + const uint16_t compNHits) + : bitsInTime_(bitsInTime), + bitsOutOfTime_(bitsOutOfTime), + cscID_(cscID), + bx_(bx), + showerType_(showerType), + wireNHits_(wireNHits), + comparatorNHits_(compNHits) {} /// Default -CSCShowerDigi::CSCShowerDigi() : bitsInTime_(0), bitsOutOfTime_(0), cscID_(0) {} +CSCShowerDigi::CSCShowerDigi() + : bitsInTime_(0), bitsOutOfTime_(0), cscID_(0), bx_(0), showerType_(0), wireNHits_(0), comparatorNHits_(0) {} void CSCShowerDigi::clear() { bitsInTime_ = 0; bitsOutOfTime_ = 0; cscID_ = 0; + bx_ = 0; + showerType_ = 0; + wireNHits_ = 0; + comparatorNHits_ = 0; } bool CSCShowerDigi::isValid() const { // any loose shower is valid - return isLooseInTime() or isLooseOutOfTime(); + // isLooseOutofTime() is removed as out-of-time shower is not used for Run3 + return isLooseInTime() and isValidShowerType(); } bool CSCShowerDigi::isLooseInTime() const { return bitsInTime() >= kLoose; } @@ -35,6 +53,39 @@ bool CSCShowerDigi::isNominalOutOfTime() const { return bitsOutOfTime() >= kNomi bool CSCShowerDigi::isTightOutOfTime() const { return bitsOutOfTime() >= kTight; } +bool CSCShowerDigi::isValidShowerType() const { return showerType_ > kInvalidShower; } + std::ostream& operator<<(std::ostream& o, const CSCShowerDigi& digi) { - return o << "CSC Shower: in-time bits " << digi.bitsInTime() << ", out-of-time bits " << digi.bitsOutOfTime(); + unsigned int showerType = digi.getShowerType(); + std::string compHitsStr(", comparatorHits "); + compHitsStr += std::to_string(digi.getComparatorNHits()); + std::string wireHitsStr(", wireHits "); + wireHitsStr += std::to_string(digi.getWireNHits()); + std::string showerStr; + switch (showerType) { + case 0: + showerStr = "Invalid ShowerType"; + break; + case 1: + showerStr = "AnodeShower"; + break; + case 2: + showerStr = "CathodeShower"; + break; + case 3: + showerStr = "MatchedShower"; + break; + case 4: + showerStr = "EMTFShower"; + break; + case 5: + showerStr = "GMTShower"; + break; + default: + showerStr = "UnknownShowerType"; + } + + return o << showerStr << ": bx " << digi.getBX() << ", in-time bits " << digi.bitsInTime() << ", out-of-time bits " + << digi.bitsOutOfTime() << ((showerType == 1 or showerType == 3) ? wireHitsStr : "") + << ((showerType == 2 or showerType == 3) ? compHitsStr : "") << ";"; } diff --git a/DataFormats/CSCDigi/src/classes_def.xml b/DataFormats/CSCDigi/src/classes_def.xml index 67bc65d4f4b75..28e2a0113e2df 100644 --- a/DataFormats/CSCDigi/src/classes_def.xml +++ b/DataFormats/CSCDigi/src/classes_def.xml @@ -39,7 +39,8 @@ - + + diff --git a/EventFilter/CSCRawToDigi/interface/CSCALCTHeader.h b/EventFilter/CSCRawToDigi/interface/CSCALCTHeader.h index 999bce7197353..d2dc5546e400f 100644 --- a/EventFilter/CSCRawToDigi/interface/CSCALCTHeader.h +++ b/EventFilter/CSCRawToDigi/interface/CSCALCTHeader.h @@ -168,7 +168,10 @@ class CSCALCTHeader { // { if ((!theALCTs.empty()) && (theALCTs.size() == unsigned(header2007.lctBins * 2))) { for (unsigned bx = 0; bx < header2007.lctBins; bx++) { - results.push_back(CSCShowerDigi(theALCTs[bx * 2].reserved & 0x3, 0, bx)); + //CSCID is set to be 0 + //ALCTshower, showerType_= 1, wireNHits and ComparatorNHits are not available in data + results.push_back( + CSCShowerDigi(theALCTs[bx * 2].reserved & 0x3, 0, 0, bx, CSCShowerDigi::ShowerType::kALCTShower, 0, 0)); } return results; } else diff --git a/EventFilter/CSCRawToDigi/interface/CSCTMBHeader.h b/EventFilter/CSCRawToDigi/interface/CSCTMBHeader.h index 1ffa9fdb3ab4a..86f04d6324750 100644 --- a/EventFilter/CSCRawToDigi/interface/CSCTMBHeader.h +++ b/EventFilter/CSCRawToDigi/interface/CSCTMBHeader.h @@ -54,6 +54,7 @@ class CSCTMBHeader { uint16_t sizeInBytes() const { return theHeaderFormat->sizeInWords() * 2; } + uint16_t L1AMatchTime() const { return theHeaderFormat->L1AMatchTime(); } /// will throw if the cast fails CSCTMBHeader2007 tmbHeader2007() const; CSCTMBHeader2007_rev0x50c3 tmbHeader2007_rev0x50c3() const; diff --git a/EventFilter/CSCRawToDigi/interface/CSCTMBHeader2006.h b/EventFilter/CSCRawToDigi/interface/CSCTMBHeader2006.h index f38d8404a95ba..aace95458d019 100644 --- a/EventFilter/CSCRawToDigi/interface/CSCTMBHeader2006.h +++ b/EventFilter/CSCRawToDigi/interface/CSCTMBHeader2006.h @@ -26,6 +26,7 @@ struct CSCTMBHeader2006 : public CSCVTMBHeaderFormat { uint16_t syncErrorCLCT() const override { return (bits.clct0_sync_err | bits.clct1_sync_err); } uint16_t syncErrorMPC0() const override { return bits.MPC_Muon0_SyncErr_; } uint16_t syncErrorMPC1() const override { return bits.MPC_Muon1_SyncErr_; } + uint16_t L1AMatchTime() const override { return bits.pop_l1a_match_win; } /// == Run 3 CSC-GEM Trigger Format uint16_t clct0_ComparatorCode() const override { return 0; } diff --git a/EventFilter/CSCRawToDigi/interface/CSCTMBHeader2007.h b/EventFilter/CSCRawToDigi/interface/CSCTMBHeader2007.h index 64cee063d9ef3..6d851838d3021 100644 --- a/EventFilter/CSCRawToDigi/interface/CSCTMBHeader2007.h +++ b/EventFilter/CSCRawToDigi/interface/CSCTMBHeader2007.h @@ -26,6 +26,7 @@ struct CSCTMBHeader2007 : public CSCVTMBHeaderFormat { uint16_t syncErrorCLCT() const override { return (bits.clct0_sync_err | bits.clct1_sync_err); } uint16_t syncErrorMPC0() const override { return bits.MPC_Muon0_SyncErr_; } uint16_t syncErrorMPC1() const override { return bits.MPC_Muon1_SyncErr_; } + uint16_t L1AMatchTime() const override { return bits.pop_l1a_match_win; } /// == Run 3 CSC-GEM Trigger Format uint16_t clct0_ComparatorCode() const override { return 0; } diff --git a/EventFilter/CSCRawToDigi/interface/CSCTMBHeader2007_rev0x50c3.h b/EventFilter/CSCRawToDigi/interface/CSCTMBHeader2007_rev0x50c3.h index f0f83f065d380..fc2a5b118e816 100644 --- a/EventFilter/CSCRawToDigi/interface/CSCTMBHeader2007_rev0x50c3.h +++ b/EventFilter/CSCRawToDigi/interface/CSCTMBHeader2007_rev0x50c3.h @@ -26,6 +26,7 @@ struct CSCTMBHeader2007_rev0x50c3 : public CSCVTMBHeaderFormat { uint16_t syncErrorCLCT() const override { return bits.clct_sync_err; } uint16_t syncErrorMPC0() const override { return bits.MPC_Muon0_SyncErr_; } uint16_t syncErrorMPC1() const override { return bits.MPC_Muon1_SyncErr_; } + uint16_t L1AMatchTime() const override { return bits.pop_l1a_match_win; } /// == Run 3 CSC-GEM Trigger Format uint16_t clct0_ComparatorCode() const override { return 0; } diff --git a/EventFilter/CSCRawToDigi/interface/CSCTMBHeader2013.h b/EventFilter/CSCRawToDigi/interface/CSCTMBHeader2013.h index 82d00e229b6d0..dba992dd22e6a 100644 --- a/EventFilter/CSCRawToDigi/interface/CSCTMBHeader2013.h +++ b/EventFilter/CSCRawToDigi/interface/CSCTMBHeader2013.h @@ -26,6 +26,7 @@ struct CSCTMBHeader2013 : public CSCVTMBHeaderFormat { uint16_t syncErrorCLCT() const override { return bits.clct_sync_err; } uint16_t syncErrorMPC0() const override { return bits.MPC_Muon0_SyncErr_; } uint16_t syncErrorMPC1() const override { return bits.MPC_Muon1_SyncErr_; } + uint16_t L1AMatchTime() const override { return bits.pop_l1a_match_win; } /// == Run 3 CSC-GEM Trigger Format uint16_t clct0_ComparatorCode() const override { return 0; } diff --git a/EventFilter/CSCRawToDigi/interface/CSCTMBHeader2020_CCLUT.h b/EventFilter/CSCRawToDigi/interface/CSCTMBHeader2020_CCLUT.h index 5a6b4780751e7..f1b3847aa701e 100644 --- a/EventFilter/CSCRawToDigi/interface/CSCTMBHeader2020_CCLUT.h +++ b/EventFilter/CSCRawToDigi/interface/CSCTMBHeader2020_CCLUT.h @@ -26,6 +26,7 @@ struct CSCTMBHeader2020_CCLUT : public CSCVTMBHeaderFormat { uint16_t syncErrorCLCT() const override { return bits.clct_sync_err; } uint16_t syncErrorMPC0() const override { return 0; } uint16_t syncErrorMPC1() const override { return 0; } + uint16_t L1AMatchTime() const override { return bits.pop_l1a_match_win; } // == Run 3 CSC-GEM Trigger Format uint16_t clct0_ComparatorCode() const override { return bits.clct0_comparator_code; } diff --git a/EventFilter/CSCRawToDigi/interface/CSCTMBHeader2020_GEM.h b/EventFilter/CSCRawToDigi/interface/CSCTMBHeader2020_GEM.h index b066bf7f50a97..f95f1a5f02727 100644 --- a/EventFilter/CSCRawToDigi/interface/CSCTMBHeader2020_GEM.h +++ b/EventFilter/CSCRawToDigi/interface/CSCTMBHeader2020_GEM.h @@ -26,6 +26,7 @@ struct CSCTMBHeader2020_GEM : public CSCVTMBHeaderFormat { uint16_t syncErrorCLCT() const override { return bits.clct_sync_err; } uint16_t syncErrorMPC0() const override { return 0; } uint16_t syncErrorMPC1() const override { return 0; } + uint16_t L1AMatchTime() const override { return bits.pop_l1a_match_win; } // == Run 3 CSC-GEM Trigger Format uint16_t clct0_ComparatorCode() const override { return bits.clct0_comparator_code; } diff --git a/EventFilter/CSCRawToDigi/interface/CSCTMBHeader2020_Run2.h b/EventFilter/CSCRawToDigi/interface/CSCTMBHeader2020_Run2.h index 790bc1c89505a..163d5bf01349a 100644 --- a/EventFilter/CSCRawToDigi/interface/CSCTMBHeader2020_Run2.h +++ b/EventFilter/CSCRawToDigi/interface/CSCTMBHeader2020_Run2.h @@ -26,6 +26,7 @@ struct CSCTMBHeader2020_Run2 : public CSCVTMBHeaderFormat { uint16_t syncErrorCLCT() const override { return bits.clct_sync_err; } uint16_t syncErrorMPC0() const override { return bits.MPC_Muon0_SyncErr_; } uint16_t syncErrorMPC1() const override { return bits.MPC_Muon1_SyncErr_; } + uint16_t L1AMatchTime() const override { return bits.pop_l1a_match_win; } // == Run 3 CSC-GEM Trigger Format uint16_t clct0_ComparatorCode() const override { return 0; } diff --git a/EventFilter/CSCRawToDigi/interface/CSCTMBHeader2020_TMB.h b/EventFilter/CSCRawToDigi/interface/CSCTMBHeader2020_TMB.h index 61931dbe428b9..a3d03d1642876 100644 --- a/EventFilter/CSCRawToDigi/interface/CSCTMBHeader2020_TMB.h +++ b/EventFilter/CSCRawToDigi/interface/CSCTMBHeader2020_TMB.h @@ -26,6 +26,7 @@ struct CSCTMBHeader2020_TMB : public CSCVTMBHeaderFormat { uint16_t syncErrorCLCT() const override { return bits.clct_sync_err; } uint16_t syncErrorMPC0() const override { return 0; } uint16_t syncErrorMPC1() const override { return 0; } + uint16_t L1AMatchTime() const override { return bits.pop_l1a_match_win; } // == Run 3 CSC-GEM Trigger Format uint16_t clct0_ComparatorCode() const override { return 0; } diff --git a/EventFilter/CSCRawToDigi/interface/CSCVTMBHeaderFormat.h b/EventFilter/CSCRawToDigi/interface/CSCVTMBHeaderFormat.h index 619d075cac3ca..11ea88b519dd4 100644 --- a/EventFilter/CSCRawToDigi/interface/CSCVTMBHeaderFormat.h +++ b/EventFilter/CSCRawToDigi/interface/CSCVTMBHeaderFormat.h @@ -30,6 +30,7 @@ class CSCVTMBHeaderFormat { virtual uint16_t syncErrorCLCT() const = 0; virtual uint16_t syncErrorMPC0() const = 0; virtual uint16_t syncErrorMPC1() const = 0; + virtual uint16_t L1AMatchTime() const = 0; /// == Run 3 CSC-GEM Trigger Format virtual uint16_t clct0_ComparatorCode() const = 0; diff --git a/EventFilter/CSCRawToDigi/src/CSCALCTHeader.cc b/EventFilter/CSCRawToDigi/src/CSCALCTHeader.cc index 295621b85886a..4c90847f15f03 100644 --- a/EventFilter/CSCRawToDigi/src/CSCALCTHeader.cc +++ b/EventFilter/CSCRawToDigi/src/CSCALCTHeader.cc @@ -229,8 +229,9 @@ void CSCALCTHeader::addShower(const std::vector &digis) { if (bx < (int)header2007.lctBins) { const CSCShowerDigi &digi = digis[bx]; int i = bx * 2; - theALCTs[i].reserved = digi.bitsInTime() & 0x3; - theALCTs[i + 1].reserved = digi.bitsInTime() & 0x3; + unsigned hmt_bits = digi.isValid() ? digi.bitsInTime() : 0; + theALCTs[i].reserved = hmt_bits & 0x3; + theALCTs[i + 1].reserved = hmt_bits & 0x3; } } } diff --git a/EventFilter/CSCRawToDigi/src/CSCTMBHeader2020_CCLUT.cc b/EventFilter/CSCRawToDigi/src/CSCTMBHeader2020_CCLUT.cc index 49711092538e4..a1d539d99b5a7 100644 --- a/EventFilter/CSCRawToDigi/src/CSCTMBHeader2020_CCLUT.cc +++ b/EventFilter/CSCRawToDigi/src/CSCTMBHeader2020_CCLUT.cc @@ -161,20 +161,42 @@ std::vector CSCTMBHeader2020_CCLUT::CorrelatedLCTDigis(uin CSCShowerDigi CSCTMBHeader2020_CCLUT::showerDigi(uint32_t idlayer) const { unsigned hmt_bits = bits.MPC_Muon_HMT_bit0 | (bits.MPC_Muon_HMT_high << 1); // HighMultiplicityTrigger bits - uint16_t cscid = 0; // ??? What is 4-bits CSC Id in CSshowerDigi - CSCShowerDigi result(hmt_bits & 0x3, (hmt_bits >> 2) & 0x3, cscid); // 2-bits intime, 2-bits out of time + uint16_t cscid = bits.cscID; // ??? What is 4-bits CSC Id in CSshowerDigi + //L1A_TMB_WINDOW is not included in below formula + //correct version: CSCConstants::LCT_CENTRAL_BX - bits.pop_l1a_match_win + L1A_TMB_WINDOW/2; + // same for anode HMT and cathode HMT + uint16_t bx = CSCConstants::LCT_CENTRAL_BX - bits.pop_l1a_match_win; + //LCTshower with showerType = 3. comparatorNHits from hmt_nhits() and wireNHit is not available + CSCShowerDigi result(hmt_bits & 0x3, + (hmt_bits >> 2) & 0x3, + cscid, + bx, + CSCShowerDigi::ShowerType::kLCTShower, + 0, + hmt_nhits()); // 2-bits intime, 2-bits out of time return result; } CSCShowerDigi CSCTMBHeader2020_CCLUT::anodeShowerDigi(uint32_t idlayer) const { - uint16_t cscid = 0; - CSCShowerDigi result(bits.anode_hmt & 0x3, 0, cscid); // 2-bits intime, no out of time + uint16_t cscid = bits.cscID; + uint16_t bx = CSCConstants::LCT_CENTRAL_BX - bits.pop_l1a_match_win; + //ALCT shower with showerType = 1. nhits_ is not available from unpack data + CSCShowerDigi result( + bits.anode_hmt & 0x3, 0, cscid, bx, CSCShowerDigi::ShowerType::kALCTShower, 0, 0); // 2-bits intime, no out of time return result; } CSCShowerDigi CSCTMBHeader2020_CCLUT::cathodeShowerDigi(uint32_t idlayer) const { - uint16_t cscid = 0; - CSCShowerDigi result(bits.cathode_hmt & 0x3, 0, cscid); // 2-bits intime, no out of time + uint16_t cscid = bits.cscID; + uint16_t bx = CSCConstants::LCT_CENTRAL_BX - bits.pop_l1a_match_win - bits.hmt_match_win + 3; + //CLCT shower with showerType = 2. + CSCShowerDigi result(bits.cathode_hmt & 0x3, + 0, + cscid, + bx, + CSCShowerDigi::ShowerType::kCLCTShower, + 0, + hmt_nhits()); // 2-bits intime, no out of time return result; } @@ -271,19 +293,47 @@ void CSCTMBHeader2020_CCLUT::addCorrelatedLCT1(const CSCCorrelatedLCTDigi& digi) } void CSCTMBHeader2020_CCLUT::addShower(const CSCShowerDigi& digi) { - uint16_t hmt_bits = (digi.bitsInTime() & 0x3) + ((digi.bitsOutOfTime() & 0x3) << 2); + uint16_t hmt_bits = digi.isValid() ? (digi.bitsInTime() & 0x3) + ((digi.bitsOutOfTime() & 0x3) << 2) + //if not valid LCT shower, then in-time bits must be 0. keep out-of-time HMT: + : ((digi.bitsOutOfTime() & 0x3) << 2); bits.MPC_Muon_HMT_bit0 = hmt_bits & 0x1; bits.MPC_Muon_HMT_high = (hmt_bits >> 1) & 0x7; + //to keep pop_l1a_match_win + if (digi.isValid()) + bits.pop_l1a_match_win = CSCConstants::LCT_CENTRAL_BX - digi.getBX(); + else + bits.pop_l1a_match_win = 3; //default value } void CSCTMBHeader2020_CCLUT::addAnodeShower(const CSCShowerDigi& digi) { uint16_t hmt_bits = digi.bitsInTime() & 0x3; + if (not digi.isValid()) + hmt_bits = 0; bits.anode_hmt = hmt_bits; + if (not(bits.MPC_Muon_HMT_bit0 or bits.MPC_Muon_HMT_high) and digi.isValid()) + bits.pop_l1a_match_win = CSCConstants::LCT_CENTRAL_BX - digi.getBX(); + else if (not(digi.isValid())) + bits.pop_l1a_match_win = 3; //default value } void CSCTMBHeader2020_CCLUT::addCathodeShower(const CSCShowerDigi& digi) { uint16_t hmt_bits = digi.bitsInTime() & 0x3; + if (not digi.isValid()) + hmt_bits = 0; bits.cathode_hmt = hmt_bits; + bits.hmt_nhits_bit0 = digi.getComparatorNHits() & 0x1; + bits.hmt_nhits_bit1 = (digi.getComparatorNHits() >> 1) & 0x1; + bits.hmt_nhits_bits_high = (digi.getComparatorNHits() >> 2) & 0x1F; + if (bits.MPC_Muon_HMT_bit0 or bits.MPC_Muon_HMT_high or bits.anode_hmt) { + //matched HMT is found, then pop_l1a_match_win is assigned + bits.hmt_match_win = CSCConstants::LCT_CENTRAL_BX - bits.pop_l1a_match_win + 3 - digi.getBX(); + } else if (digi.isValid()) { + bits.pop_l1a_match_win = 3; //default value + bits.hmt_match_win = CSCConstants::LCT_CENTRAL_BX - digi.getBX(); + } else { + bits.pop_l1a_match_win = 3; //default value + bits.hmt_match_win = 0; //no HMT case + } } void CSCTMBHeader2020_CCLUT::print(std::ostream& os) const { @@ -298,6 +348,8 @@ void CSCTMBHeader2020_CCLUT::print(std::ostream& os) const { << std::hex << (bits.activeCFEBs | (bits.activeCFEBs_2 << 5)) << ", readCFEBs = 0x" << std::hex << (bits.readCFEBs | (bits.readCFEBs_2 << 5)) << std::dec << "\n"; os << "bxnPreTrigger = " << bits.bxnPreTrigger << "\n"; + os << "ALCT location in CLCT window " << bits.matchWin << " L1A location in TMB window " << bits.pop_l1a_match_win + << " ALCT in cathde HMT window " << bits.hmt_match_win << "\n"; os << "tmbMatch = " << bits.tmbMatch << " alctOnly = " << bits.alctOnly << " clctOnly = " << bits.clctOnly << "\n"; os << "readoutCounter: " << std::dec << bits.readoutCounter << ", buf_q_ovf: " << bits.stackOvf @@ -341,5 +393,5 @@ void CSCTMBHeader2020_CCLUT::print(std::ostream& os) const { os << " clct_5bit_pattern_id = " << (bits.MPC_Muon_clct_pattern_low | (bits.MPC_Muon_clct_pattern_bit5 << 4)) << " HMT = " << (bits.MPC_Muon_HMT_bit0 | (bits.MPC_Muon_HMT_high << 1)) << ", alctHMT = " << bits.anode_hmt - << ", clctHMT = " << bits.cathode_hmt << "\n"; + << ", clctHMT = " << bits.cathode_hmt << " cathode nhits " << hmt_nhits() << "\n"; } diff --git a/EventFilter/CSCRawToDigi/src/CSCTMBHeader2020_GEM.cc b/EventFilter/CSCRawToDigi/src/CSCTMBHeader2020_GEM.cc index 8fb5dfaf66d49..4e393e88601b7 100644 --- a/EventFilter/CSCRawToDigi/src/CSCTMBHeader2020_GEM.cc +++ b/EventFilter/CSCRawToDigi/src/CSCTMBHeader2020_GEM.cc @@ -165,20 +165,42 @@ std::vector CSCTMBHeader2020_GEM::CorrelatedLCTDigis(uint3 CSCShowerDigi CSCTMBHeader2020_GEM::showerDigi(uint32_t idlayer) const { unsigned hmt_bits = bits.MPC_Muon_HMT_bit0 | (bits.MPC_Muon_HMT_high << 1); // HighMultiplicityTrigger bits - uint16_t cscid = 0; // ??? What is 4-bits CSC Id in CSshowerDigi - CSCShowerDigi result(hmt_bits & 0x3, (hmt_bits >> 2) & 0x3, cscid); // 2-bits intime, 2-bits out of time + uint16_t cscid = bits.cscID; // ??? What is 4-bits CSC Id in CSshowerDigi + //L1A_TMB_WINDOW is not included in below formula + //correct version: CSCConstants::LCT_CENTRAL_BX - bits.pop_l1a_match_win + L1A_TMB_WINDOW/2; + // same for anode HMT and cathode HMT. offline analysis would take care of this + uint16_t bx = CSCConstants::LCT_CENTRAL_BX - bits.pop_l1a_match_win; + //LCTshower with showerType = 3. comparatorNHits from hmt_nhits() and wireNHits is not available + CSCShowerDigi result(hmt_bits & 0x3, + (hmt_bits >> 2) & 0x3, + cscid, + bx, + CSCShowerDigi::ShowerType::kLCTShower, + 0, + hmt_nhits()); // 2-bits intime, 2-bits out of time return result; } CSCShowerDigi CSCTMBHeader2020_GEM::anodeShowerDigi(uint32_t idlayer) const { - uint16_t cscid = 0; - CSCShowerDigi result(bits.anode_hmt & 0x3, 0, cscid); // 2-bits intime, no out of time + uint16_t cscid = bits.cscID; + uint16_t bx = CSCConstants::LCT_CENTRAL_BX - bits.pop_l1a_match_win; + //ALCT shower with showerType = 1. wireNHits is not available from unpack data + CSCShowerDigi result( + bits.anode_hmt & 0x3, 0, cscid, bx, CSCShowerDigi::ShowerType::kALCTShower, 0, 0); // 2-bits intime, no out of time return result; } CSCShowerDigi CSCTMBHeader2020_GEM::cathodeShowerDigi(uint32_t idlayer) const { - uint16_t cscid = 0; - CSCShowerDigi result(bits.cathode_hmt & 0x3, 0, cscid); // 2-bits intime, no out of time + uint16_t cscid = bits.cscID; + uint16_t bx = CSCConstants::LCT_CENTRAL_BX - bits.pop_l1a_match_win - bits.hmt_match_win + 3; + //CLCT shower with showerType = 2. comparatorNHits from hmt_nhits() + CSCShowerDigi result(bits.cathode_hmt & 0x3, + 0, + cscid, + bx, + CSCShowerDigi::ShowerType::kCLCTShower, + 0, + hmt_nhits()); // 2-bits intime, no out of time return result; } @@ -276,18 +298,47 @@ void CSCTMBHeader2020_GEM::addCorrelatedLCT1(const CSCCorrelatedLCTDigi& digi) { void CSCTMBHeader2020_GEM::addShower(const CSCShowerDigi& digi) { uint16_t hmt_bits = (digi.bitsInTime() & 0x3) + ((digi.bitsOutOfTime() & 0x3) << 2); + //not valid LCT shower, then in-time bits must be 0 + if (not digi.isValid()) + hmt_bits = ((digi.bitsOutOfTime() & 0x3) << 2); bits.MPC_Muon_HMT_bit0 = hmt_bits & 0x1; bits.MPC_Muon_HMT_high = (hmt_bits >> 1) & 0x7; + //to keep pop_l1a_match_win + if (digi.isValid()) + bits.pop_l1a_match_win = CSCConstants::LCT_CENTRAL_BX - digi.getBX(); + else + bits.pop_l1a_match_win = 3; //default value } void CSCTMBHeader2020_GEM::addAnodeShower(const CSCShowerDigi& digi) { uint16_t hmt_bits = digi.bitsInTime() & 0x3; + if (not digi.isValid()) + hmt_bits = 0; bits.anode_hmt = hmt_bits; + if (not(bits.MPC_Muon_HMT_bit0 or bits.MPC_Muon_HMT_high) and digi.isValid()) + bits.pop_l1a_match_win = CSCConstants::LCT_CENTRAL_BX - digi.getBX(); + else if (not(digi.isValid())) + bits.pop_l1a_match_win = 3; //default value } void CSCTMBHeader2020_GEM::addCathodeShower(const CSCShowerDigi& digi) { uint16_t hmt_bits = digi.bitsInTime() & 0x3; + if (not digi.isValid()) + hmt_bits = 0; bits.cathode_hmt = hmt_bits; + bits.hmt_nhits_bit0 = digi.getComparatorNHits() & 0x1; + bits.hmt_nhits_bit1 = (digi.getComparatorNHits() >> 1) & 0x1; + bits.hmt_nhits_bits_high = (digi.getComparatorNHits() >> 2) & 0x1F; + if (bits.MPC_Muon_HMT_bit0 or bits.MPC_Muon_HMT_high or bits.anode_hmt) { + //pop_l1a_match_win is assigned + bits.hmt_match_win = CSCConstants::LCT_CENTRAL_BX - bits.pop_l1a_match_win + 3 - digi.getBX(); + } else if (digi.isValid()) { + bits.pop_l1a_match_win = 3; //default value + bits.hmt_match_win = CSCConstants::LCT_CENTRAL_BX - digi.getBX(); + } else { + bits.pop_l1a_match_win = 3; //default value + bits.hmt_match_win = 0; //no HMT case + } } void CSCTMBHeader2020_GEM::print(std::ostream& os) const { @@ -303,6 +354,8 @@ void CSCTMBHeader2020_GEM::print(std::ostream& os) const { << ", activeCFEBs = 0x" << std::hex << (bits.activeCFEBs | (bits.activeCFEBs_2 << 5)) << ", readCFEBs = 0x" << std::hex << (bits.readCFEBs | (bits.readCFEBs_2 << 5)) << std::dec << "\n"; os << "bxnPreTrigger = " << bits.bxnPreTrigger << "\n"; + os << "ALCT location in CLCT window " << bits.matchWin << " L1A location in TMB window " << bits.pop_l1a_match_win + << " ALCT in cathde HMT window " << bits.hmt_match_win << "\n"; os << "tmbMatch = " << bits.tmbMatch << " alctOnly = " << bits.alctOnly << " clctOnly = " << bits.clctOnly << "\n"; os << "readoutCounter: " << std::dec << bits.readoutCounter << ", buf_q_ovf: " << bits.stackOvf @@ -347,7 +400,7 @@ void CSCTMBHeader2020_GEM::print(std::ostream& os) const { os << " clct_5bit_pattern_id = " << (bits.MPC_Muon_clct_pattern_low | (bits.MPC_Muon_clct_pattern_bit5 << 4)) << " HMT = " << (bits.MPC_Muon_HMT_bit0 | (bits.MPC_Muon_HMT_high << 1)) << ", alctHMT = " << bits.anode_hmt - << ", clctHMT = " << bits.cathode_hmt << "\n"; + << ", clctHMT = " << bits.cathode_hmt << " cathode nhits " << hmt_nhits() << "\n"; // os << "..................CLCT....................." << "\n"; os << "GEM Data:\n" diff --git a/EventFilter/CSCRawToDigi/src/CSCTMBHeader2020_TMB.cc b/EventFilter/CSCRawToDigi/src/CSCTMBHeader2020_TMB.cc index 3d51c5b76959b..2f6edfc8252fc 100644 --- a/EventFilter/CSCRawToDigi/src/CSCTMBHeader2020_TMB.cc +++ b/EventFilter/CSCRawToDigi/src/CSCTMBHeader2020_TMB.cc @@ -131,20 +131,43 @@ std::vector CSCTMBHeader2020_TMB::CorrelatedLCTDigis(uint3 CSCShowerDigi CSCTMBHeader2020_TMB::showerDigi(uint32_t idlayer) const { unsigned hmt_bits = bits.MPC_Muon_HMT_bit0 | (bits.MPC_Muon_HMT_high << 1); // HighMultiplicityTrigger bits - uint16_t cscid = 0; // ??? What is 4-bits CSC Id in CSshowerDigi - CSCShowerDigi result(hmt_bits & 0x3, (hmt_bits >> 2) & 0x3, cscid); // 2-bits intime, 2-bits out of time + uint16_t cscid = bits.cscID; // ??? What is 4-bits CSC Id in CSshowerDigi + //L1A_TMB_WINDOW is not included in below formula + //correct version: CSCConstants::LCT_CENTRAL_BX - bits.pop_l1a_match_win + L1A_TMB_WINDOW/2; + // same for anode HMT and cathode HMT + uint16_t bx = CSCConstants::LCT_CENTRAL_BX - bits.pop_l1a_match_win; + //LCTshower with showerType = 3. wireNHits is not avaiable + //TMB LCT shower is copied from ALCT shower + CSCShowerDigi result(hmt_bits & 0x3, + (hmt_bits >> 2) & 0x3, + cscid, + bx, + CSCShowerDigi::ShowerType::kLCTShower, + 0, + 0); // 2-bits intime, 2-bits out of time return result; } CSCShowerDigi CSCTMBHeader2020_TMB::anodeShowerDigi(uint32_t idlayer) const { - uint16_t cscid = 0; - CSCShowerDigi result(bits.anode_hmt & 0x3, 0, cscid); // 2-bits intime, no out of time + uint16_t cscid = bits.cscID; + uint16_t bx = CSCConstants::LCT_CENTRAL_BX - bits.pop_l1a_match_win; + //ALCTshower with showerType = 1. wireNHits is not avaiable + CSCShowerDigi result( + bits.anode_hmt & 0x3, 0, cscid, bx, CSCShowerDigi::ShowerType::kALCTShower, 0, 0); // 2-bits intime, no out of time return result; } CSCShowerDigi CSCTMBHeader2020_TMB::cathodeShowerDigi(uint32_t idlayer) const { - uint16_t cscid = 0; - CSCShowerDigi result(bits.cathode_hmt & 0x3, 0, cscid); // 2-bits intime, no out of time + uint16_t cscid = bits.cscID; + uint16_t bx = CSCConstants::LCT_CENTRAL_BX - bits.pop_l1a_match_win; + //CLCTshower with showerType = 2. comparatorNhits is not avaiable for TMB yet + CSCShowerDigi result(bits.cathode_hmt & 0x3, + 0, + cscid, + bx, + CSCShowerDigi::ShowerType::kCLCTShower, + 0, + 0); // 2-bits intime, no out of time return result; } @@ -256,13 +279,26 @@ void CSCTMBHeader2020_TMB::addCorrelatedLCT1(const CSCCorrelatedLCTDigi& digi) { void CSCTMBHeader2020_TMB::addShower(const CSCShowerDigi& digi) { uint16_t hmt_bits = (digi.bitsInTime() & 0x3) + ((digi.bitsOutOfTime() & 0x3) << 2); + //not valid LCT shower, then in-time bits must be 0 + if (not digi.isValid()) + hmt_bits = ((digi.bitsOutOfTime() & 0x3) << 2); bits.MPC_Muon_HMT_bit0 = hmt_bits & 0x1; bits.MPC_Muon_HMT_high = (hmt_bits >> 1) & 0x7; + if (digi.isValid()) + bits.pop_l1a_match_win = CSCConstants::LCT_CENTRAL_BX - digi.getBX(); + else + bits.pop_l1a_match_win = 3; //default value } void CSCTMBHeader2020_TMB::addAnodeShower(const CSCShowerDigi& digi) { uint16_t hmt_bits = digi.bitsInTime() & 0x3; + if (not digi.isValid()) + hmt_bits = 0; bits.anode_hmt = hmt_bits; + if (digi.isValid()) + bits.pop_l1a_match_win = CSCConstants::LCT_CENTRAL_BX - digi.getBX(); + else + bits.pop_l1a_match_win = 3; //default value } void CSCTMBHeader2020_TMB::addCathodeShower(const CSCShowerDigi& digi) { @@ -285,6 +321,8 @@ void CSCTMBHeader2020_TMB::print(std::ostream& os) const { << (bits.activeCFEBs | (bits.activeCFEBs_2 << 5)) << ", readCFEBs = 0x" << std::hex << (bits.readCFEBs | (bits.readCFEBs_2 << 5)) << std::dec << "\n"; os << "bxnPreTrigger = " << bits.bxnPreTrigger << "\n"; + os << "ALCT location in CLCT window " << bits.matchWin << " L1A location in TMB window " << bits.pop_l1a_match_win + << "\n"; os << "tmbMatch = " << bits.tmbMatch << " alctOnly = " << bits.alctOnly << " clctOnly = " << bits.clctOnly << "\n"; os << "CLCT Words:\n" diff --git a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/EMTFBlockME.cc b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/EMTFBlockME.cc index e08a6d8a9f9de..8578d08d502b1 100644 --- a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/EMTFBlockME.cc +++ b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/EMTFBlockME.cc @@ -304,7 +304,9 @@ namespace l1t { // Fill the CSCShowerDigi CSCShowerDigi Shower_(ME_.HMT_inTime() == -99 ? 0 : ME_.HMT_inTime(), ME_.HMT_outOfTime() == -99 ? 0 : ME_.HMT_outOfTime(), - Hit_.CSC_DetId()); + Hit_.CSC_DetId(), + Hit_.BX(), + CSCShowerDigi::ShowerType::kEMTFShower); // Set the stub number for this hit // Each chamber can send up to 2 stubs per BX diff --git a/L1Trigger/CSCTriggerPrimitives/interface/CSCAnodeLCTProcessor.h b/L1Trigger/CSCTriggerPrimitives/interface/CSCAnodeLCTProcessor.h index aa1f26807b8fd..0005946ff8fb8 100644 --- a/L1Trigger/CSCTriggerPrimitives/interface/CSCAnodeLCTProcessor.h +++ b/L1Trigger/CSCTriggerPrimitives/interface/CSCAnodeLCTProcessor.h @@ -87,12 +87,11 @@ class CSCAnodeLCTProcessor : public CSCBaseboard { CSCALCTDigi getBestALCT(int bx) const; CSCALCTDigi getSecondALCT(int bx) const; - /* get special bits for high multiplicity triggers */ - unsigned getInTimeHMT() const { return inTimeHMT_; } - unsigned getOutTimeHMT() const { return outTimeHMT_; } + /* get array of high multiplicity triggers */ + std::vector getAllShower() const; /** Returns shower bits */ - CSCShowerDigi readoutShower() const; + std::vector readoutShower() const; protected: /** Best LCTs in this chamber, as found by the processor. @@ -107,7 +106,7 @@ class CSCAnodeLCTProcessor : public CSCBaseboard { PulseArray pulse_; - CSCShowerDigi shower_; + CSCShowerDigi anode_showers_[CSCConstants::MAX_ALCT_TBINS]; /** Access routines to wire digis. */ bool getDigis(const CSCWireDigiCollection* wiredc); @@ -127,16 +126,12 @@ class CSCAnodeLCTProcessor : public CSCBaseboard { std::vector thePreTriggerDigis; /* data members for high multiplicity triggers */ - void encodeHighMultiplicityBits( - const std::vector wire[CSCConstants::NUM_LAYERS][CSCConstants::MAX_NUM_WIREGROUPS]); - unsigned inTimeHMT_; - unsigned outTimeHMT_; + void encodeHighMultiplicityBits(); std::vector thresholds_; - unsigned showerMinInTBin_; - unsigned showerMaxInTBin_; - unsigned showerMinOutTBin_; - unsigned showerMaxOutTBin_; + unsigned showerNumTBins_; unsigned minLayersCentralTBin_; + unsigned minbx_readout_; + unsigned maxbx_readout_; /** Configuration parameters. */ unsigned int fifo_tbins, fifo_pretrig, drift_delay; diff --git a/L1Trigger/CSCTriggerPrimitives/interface/CSCCathodeLCTProcessor.h b/L1Trigger/CSCTriggerPrimitives/interface/CSCCathodeLCTProcessor.h index d1ab3c2d209c1..5aacd295f25da 100644 --- a/L1Trigger/CSCTriggerPrimitives/interface/CSCCathodeLCTProcessor.h +++ b/L1Trigger/CSCTriggerPrimitives/interface/CSCCathodeLCTProcessor.h @@ -87,11 +87,13 @@ class CSCCathodeLCTProcessor : public CSCBaseboard { std::vector preTriggerDigis() const { return thePreTriggerDigis; } /* get special bits for high multiplicity triggers */ - unsigned getInTimeHMT() const { return inTimeHMT_; } - unsigned getOutTimeHMT() const { return outTimeHMT_; } + //unsigned getInTimeHMT() const { return inTimeHMT_; } + //unsigned getOutTimeHMT() const { return outTimeHMT_; } + /* get array of high multiplicity triggers */ + std::vector getAllShower() const; /** Returns shower bits */ - CSCShowerDigi readoutShower() const; + std::vector readoutShower() const; protected: /** Best LCT in this chamber, as found by the processor. */ @@ -100,7 +102,8 @@ class CSCCathodeLCTProcessor : public CSCBaseboard { /** Second best LCT in this chamber, as found by the processor. */ CSCCLCTDigi secondCLCT[CSCConstants::MAX_CLCT_TBINS]; - CSCShowerDigi shower_; + CSCShowerDigi cathode_showers_[CSCConstants::MAX_CLCT_TBINS]; + //CSCShowerDigi shower_; /** Access routines to comparator digis. */ bool getDigis(const CSCComparatorDigiCollection* compdc); @@ -188,16 +191,14 @@ class CSCCathodeLCTProcessor : public CSCBaseboard { std::vector thePreTriggerDigis; /* data members for high multiplicity triggers */ - void encodeHighMultiplicityBits( - const std::vector halfstrip[CSCConstants::NUM_LAYERS][CSCConstants::MAX_NUM_HALF_STRIPS_RUN2_TRIGGER]); - unsigned inTimeHMT_; - unsigned outTimeHMT_; + void encodeHighMultiplicityBits(); std::vector thresholds_; - unsigned showerMinInTBin_; - unsigned showerMaxInTBin_; - unsigned showerMinOutTBin_; - unsigned showerMaxOutTBin_; + unsigned showerNumTBins_; unsigned minLayersCentralTBin_; + unsigned minbx_readout_; + unsigned maxbx_readout_; + /** check the peak of total hits and single bx hits for cathode HMT */ + bool peakCheck_; /** Configuration parameters. */ unsigned int fifo_tbins, fifo_pretrig; // only for test beam mode. diff --git a/L1Trigger/CSCTriggerPrimitives/interface/CSCMotherboard.h b/L1Trigger/CSCTriggerPrimitives/interface/CSCMotherboard.h index 967023a75fabe..98cbc65872623 100644 --- a/L1Trigger/CSCTriggerPrimitives/interface/CSCMotherboard.h +++ b/L1Trigger/CSCTriggerPrimitives/interface/CSCMotherboard.h @@ -88,7 +88,7 @@ class CSCMotherboard : public CSCBaseboard { void selectLCTs(); /** Returns shower bits */ - CSCShowerDigi readoutShower() const; + std::vector readoutShower() const; /** Clears correlated LCT and passes clear signal on to cathode and anode LCT processors. */ @@ -123,7 +123,7 @@ class CSCMotherboard : public CSCBaseboard { /* Container with sorted and selected LCTs */ std::vector lctV; - CSCShowerDigi shower_; + CSCShowerDigi showers_[CSCConstants::MAX_LCT_TBINS]; // helper function to return ALCT/CLCT with correct central BX CSCALCTDigi getBXShiftedALCT(const CSCALCTDigi&) const; @@ -147,7 +147,10 @@ class CSCMotherboard : public CSCBaseboard { bool match_earliest_clct_only_; // encode special bits for high-multiplicity triggers - unsigned showerSource_; + std::vector showerSource_; + unsigned thisShowerSource_; + unsigned minbx_readout_; + unsigned maxbx_readout_; bool ignoreAlctCrossClct_; @@ -232,6 +235,9 @@ class CSCMotherboard : public CSCBaseboard { /** Dump TMB/MPC configuration parameters. */ void dumpConfigParams() const; + /* match cathode shower and anode shower with and/or logic */ + void matchShowers(CSCShowerDigi* anode_showers, CSCShowerDigi* cathode_showers, bool andlogic); + /* encode high multiplicity bits for Run-3 exotic triggers */ void encodeHighMultiplicityBits(); }; diff --git a/L1Trigger/CSCTriggerPrimitives/interface/CSCTriggerPrimitivesBuilder.h b/L1Trigger/CSCTriggerPrimitives/interface/CSCTriggerPrimitivesBuilder.h index 31432c848b4d1..9add27b0c7c63 100644 --- a/L1Trigger/CSCTriggerPrimitives/interface/CSCTriggerPrimitivesBuilder.h +++ b/L1Trigger/CSCTriggerPrimitives/interface/CSCTriggerPrimitivesBuilder.h @@ -132,6 +132,9 @@ class CSCTriggerPrimitivesBuilder { /** Phase2: special switch for the upgrade ME2/1 TMB */ bool runME21ILT_; + /** Selected chambers to run */ + std::vector selectedChambers_; + /** Pointers to TMB processors for all possible chambers. */ std::unique_ptr tmb_[MAX_ENDCAPS][MAX_STATIONS][MAX_SECTORS][MAX_SUBSECTORS][MAX_CHAMBERS]; diff --git a/L1Trigger/CSCTriggerPrimitives/python/cscTriggerPrimitiveDigis_cfi.py b/L1Trigger/CSCTriggerPrimitives/python/cscTriggerPrimitiveDigis_cfi.py index 44e5948595c22..472b64cabac3c 100644 --- a/L1Trigger/CSCTriggerPrimitives/python/cscTriggerPrimitiveDigis_cfi.py +++ b/L1Trigger/CSCTriggerPrimitives/python/cscTriggerPrimitiveDigis_cfi.py @@ -34,6 +34,8 @@ # If True, output collections will only be built for good chambers checkBadChambers = cms.bool(True), + #selected chamebrs to process + selectedChambers = cms.vstring(), # Anode-DAQ rate determined by pre-CLCTs keepCLCTPreTriggers = cms.bool(True), diff --git a/L1Trigger/CSCTriggerPrimitives/python/params/showerParams.py b/L1Trigger/CSCTriggerPrimitives/python/params/showerParams.py index b7fa3ec6a8885..cf3b766462780 100644 --- a/L1Trigger/CSCTriggerPrimitives/python/params/showerParams.py +++ b/L1Trigger/CSCTriggerPrimitives/python/params/showerParams.py @@ -13,7 +13,26 @@ ## loose -> 'loose anode and loose cathode' ## nominal -> 'nominal anode and nominal cathode' ## tight -> 'tight anode and tight cathode' - source = cms.uint32(3), + source = cms.vuint32( + # ME1/1 + 3, + # ME1/2 + 1, + # ME1/3 + 1, + # ME2/1 + 3, + # ME2/2 + 1, + # ME3/1 + 3, + # ME3/2 + 1, + # ME4/1 + 3, + # ME4/2 + 1 + ), ## settings for cathode showers (counting CSCComparatorDigi) cathodeShower = cms.PSet( @@ -21,31 +40,32 @@ ## loose ~ 0.75 kHz ## nominal ~ 0.5 kHz ## tight ~ 0.25 kHz + ## 10000 means to disable cathode HMT for this chamber type showerThresholds = cms.vuint32( # ME1/1 100, 100, 100, # ME1/2 - 0, 0, 0, + 10000, 10000, 10000, # ME1/3 - 0, 0, 0, + 10000, 10000, 10000, # ME2/1 17, 33, 35, # ME2/2 - 0, 0, 0, + 10000, 10000, 10000, # ME3/1 15, 31, 33, # ME3/2 - 0, 0, 0, + 10000, 10000, 10000, # ME4/1 17, 34, 36, # ME4/2 - 0, 0, 0 + 10000, 10000, 10000 ), - showerMinInTBin = cms.uint32(6), - showerMaxInTBin = cms.uint32(8), - showerMinOutTBin = cms.uint32(2), - showerMaxOutTBin = cms.uint32(5), + showerNumTBins = cms.uint32(3),# 3BX for cathode HMT minLayersCentralTBin = cms.uint32(5), + ## peack check feature is not implemented in firmware + ## plan to upgrade in future + peakCheck = cms.bool(False), ), ## settings for anode showers (counting CSCWireDigi) anodeShower = cms.PSet( @@ -70,10 +90,7 @@ # ME4/2 13, 27, 31 ), - showerMinInTBin = cms.uint32(8), - showerMaxInTBin = cms.uint32(8), - showerMinOutTBin = cms.uint32(4), - showerMaxOutTBin = cms.uint32(7), + showerNumTBins = cms.uint32(1),# 1BX for anode HMT minLayersCentralTBin = cms.uint32(5), ) ) diff --git a/L1Trigger/CSCTriggerPrimitives/src/CSCAnodeLCTProcessor.cc b/L1Trigger/CSCTriggerPrimitives/src/CSCAnodeLCTProcessor.cc index 05166b8607aa9..42d341e25843a 100644 --- a/L1Trigger/CSCTriggerPrimitives/src/CSCAnodeLCTProcessor.cc +++ b/L1Trigger/CSCTriggerPrimitives/src/CSCAnodeLCTProcessor.cc @@ -84,11 +84,11 @@ CSCAnodeLCTProcessor::CSCAnodeLCTProcessor(unsigned endcap, const auto& shower = showerParams_.getParameterSet("anodeShower"); thresholds_ = shower.getParameter>("showerThresholds"); - showerMinInTBin_ = shower.getParameter("showerMinInTBin"); - showerMaxInTBin_ = shower.getParameter("showerMaxInTBin"); - showerMinOutTBin_ = shower.getParameter("showerMinOutTBin"); - showerMaxOutTBin_ = shower.getParameter("showerMaxOutTBin"); + showerNumTBins_ = shower.getParameter("showerNumTBins"); minLayersCentralTBin_ = shower.getParameter("minLayersCentralTBin"); + minbx_readout_ = CSCConstants::LCT_CENTRAL_BX - l1a_window_width / 2; + maxbx_readout_ = CSCConstants::LCT_CENTRAL_BX + l1a_window_width / 2; + assert(l1a_window_width / 2 <= CSCConstants::LCT_CENTRAL_BX); } void CSCAnodeLCTProcessor::loadPatternMask() { @@ -112,6 +112,8 @@ void CSCAnodeLCTProcessor::setDefaultConfigParameters() { trig_mode = def_trig_mode; accel_mode = def_accel_mode; l1a_window_width = def_l1a_window_width; + minbx_readout_ = CSCConstants::LCT_CENTRAL_BX - l1a_window_width / 2; + maxbx_readout_ = CSCConstants::LCT_CENTRAL_BX + l1a_window_width / 2; } // Set configuration parameters obtained via EventSetup mechanism. @@ -135,6 +137,8 @@ void CSCAnodeLCTProcessor::setConfigParameters(const CSCDBL1TPParameters* conf) dumpConfigParams(); config_dumped = true; } + minbx_readout_ = CSCConstants::LCT_CENTRAL_BX - l1a_window_width / 2; + maxbx_readout_ = CSCConstants::LCT_CENTRAL_BX + l1a_window_width / 2; } void CSCAnodeLCTProcessor::checkConfigParameters() { @@ -171,15 +175,17 @@ void CSCAnodeLCTProcessor::checkConfigParameters() { CSCBaseboard::checkConfigParameters(trig_mode, max_trig_mode, def_trig_mode, "trig_mode"); CSCBaseboard::checkConfigParameters(accel_mode, max_accel_mode, def_accel_mode, "accel_mode"); CSCBaseboard::checkConfigParameters(l1a_window_width, max_l1a_window_width, def_l1a_window_width, "l1a_window_width"); + + assert(l1a_window_width / 2 <= CSCConstants::LCT_CENTRAL_BX); } void CSCAnodeLCTProcessor::clear() { for (int bx = 0; bx < CSCConstants::MAX_ALCT_TBINS; bx++) { bestALCT[bx].clear(); secondALCT[bx].clear(); + anode_showers_[bx].clear(); //? } lct_list.clear(); - inTimeHMT_ = 0; } void CSCAnodeLCTProcessor::clear(const int wire, const int pattern) { @@ -259,7 +265,7 @@ std::vector CSCAnodeLCTProcessor::run(const CSCWireDigiCollection* if (layersHit >= min_layers) run(wireGroupTimes); // Get the high multiplicity bits in this chamber - encodeHighMultiplicityBits(wireGroupTimes); + encodeHighMultiplicityBits(); } // Return vector of all found ALCTs. @@ -1276,8 +1282,31 @@ CSCALCTDigi CSCAnodeLCTProcessor::getBestALCT(int bx) const { return bestALCT[bx CSCALCTDigi CSCAnodeLCTProcessor::getSecondALCT(int bx) const { return secondALCT[bx]; } +/** return vector of CSCShower digi **/ +std::vector CSCAnodeLCTProcessor::getAllShower() const { + std::vector vshowers(anode_showers_, anode_showers_ + CSCConstants::MAX_ALCT_TBINS); + return vshowers; +}; + /** Returns shower bits */ -CSCShowerDigi CSCAnodeLCTProcessor::readoutShower() const { return shower_; } +std::vector CSCAnodeLCTProcessor::readoutShower() const { + unsigned minBXdiff = 2 * l1a_window_width; //impossible value + unsigned minBX = 0; + std::vector showerOut; + for (unsigned bx = minbx_readout_; bx < maxbx_readout_; bx++) { + unsigned bx_diff = (bx > bx - CSCConstants::LCT_CENTRAL_BX) ? bx - CSCConstants::LCT_CENTRAL_BX + : CSCConstants::LCT_CENTRAL_BX - bx; + if (anode_showers_[bx].isValid() and bx_diff < minBXdiff) { + minBXdiff = bx_diff; + minBX = bx; + } + } + + for (unsigned bx = minbx_readout_; bx < maxbx_readout_; bx++) + if (bx == minBX) + showerOut.push_back(anode_showers_[bx]); + return showerOut; +} //////////////////////////////////////////////////////////////////////// ////////////////////////////Test Routines/////////////////////////////// @@ -1336,50 +1365,29 @@ void CSCAnodeLCTProcessor::setWireContainer(CSCALCTDigi& alct, CSCALCTDigi::Wire alct.setHits(wireHits); } -void CSCAnodeLCTProcessor::encodeHighMultiplicityBits( - const std::vector wires[CSCConstants::NUM_LAYERS][CSCConstants::MAX_NUM_WIREGROUPS]) { - inTimeHMT_ = 0; - - auto layerTime = [=](unsigned time) { return time == CSCConstants::LCT_CENTRAL_BX; }; - +void CSCAnodeLCTProcessor::encodeHighMultiplicityBits() { + //numer of layer with hits and number of hits for 0-15 BXs + std::set layersWithHits[CSCConstants::MAX_ALCT_TBINS]; + unsigned hitsInTime[CSCConstants::MAX_ALCT_TBINS]; // Calculate layers with hits - unsigned nLayersWithHits = 0; - for (int i_layer = 0; i_layer < CSCConstants::NUM_LAYERS; i_layer++) { - bool atLeastOneWGHit = false; - for (int i_wire = 0; i_wire < CSCConstants::MAX_NUM_WIREGROUPS; i_wire++) { - // there is at least one wiregroup... - if (!wires[i_layer][i_wire].empty()) { - auto times = wires[i_layer][i_wire]; - int nLayerTime = std::count_if(times.begin(), times.end(), layerTime); - // ...for which at least one time bin was on for the central BX - if (nLayerTime > 0) { + for (unsigned bx = 0; bx < CSCConstants::MAX_ALCT_TBINS; bx++) { + hitsInTime[bx] = 0; + for (unsigned i_layer = 0; i_layer < CSCConstants::NUM_LAYERS; i_layer++) { + bool atLeastOneWGHit = false; + for (const auto& wd : digiV[i_layer]) { + std::vector bx_times = wd.getTimeBinsOn(); + // there is at least one wiregroup in this bx + if (std::find(bx_times.begin(), bx_times.end(), bx) != bx_times.end()) { + hitsInTime[bx] += 1; atLeastOneWGHit = true; - break; } } + // add this layer to the number of layers hit + if (atLeastOneWGHit) { + layersWithHits[bx].insert(i_layer); + } } - // add this layer to the number of layers hit - if (atLeastOneWGHit) { - nLayersWithHits++; - } - } - - // require at least nLayersWithHits for the central time bin - // do nothing if there are not enough layers with hits - if (nLayersWithHits < minLayersCentralTBin_) - return; - - // functions for in-time and out-of-time - auto inTime = [=](unsigned time) { return time >= showerMinInTBin_ and time <= showerMaxInTBin_; }; - - // count the wires in-time and out-time - unsigned hitsInTime = 0; - for (int i_layer = 0; i_layer < CSCConstants::NUM_LAYERS; i_layer++) { - for (int i_wire = 0; i_wire < CSCConstants::MAX_NUM_WIREGROUPS; i_wire++) { - auto times = wires[i_layer][i_wire]; - hitsInTime += std::count_if(times.begin(), times.end(), inTime); - } - } + } //end of full bx loop // convert station and ring number to index // index runs from 2 to 10, subtract 2 @@ -1389,13 +1397,31 @@ void CSCAnodeLCTProcessor::encodeHighMultiplicityBits( std::vector station_thresholds = { thresholds_[csc_idx * 3], thresholds_[csc_idx * 3 + 1], thresholds_[csc_idx * 3 + 2]}; - // assign the bits - for (unsigned i = 0; i < station_thresholds.size(); i++) { - if (hitsInTime >= station_thresholds[i]) { - inTimeHMT_ = i + 1; + for (unsigned bx = 0; bx < CSCConstants::MAX_ALCT_TBINS; bx++) { + unsigned minbx = bx >= showerNumTBins_ / 2 ? bx - showerNumTBins_ / 2 : bx; + unsigned maxbx = bx < CSCConstants::MAX_ALCT_TBINS - showerNumTBins_ / 2 ? bx + showerNumTBins_ / 2 + : CSCConstants::MAX_ALCT_TBINS - 1; + unsigned this_hitsInTime = 0; + for (unsigned mbx = minbx; mbx <= maxbx; mbx++) { + this_hitsInTime += hitsInTime[mbx]; } - } - // create a new object - shower_ = CSCShowerDigi(inTimeHMT_, false, theTrigChamber); + unsigned this_inTimeHMT = 0; + // require at least nLayersWithHits for the central time bin + // do nothing if there are not enough layers with hits + if (layersWithHits[bx].size() >= minLayersCentralTBin_) { + // assign the bits + if (!station_thresholds.empty()) { + for (int i = station_thresholds.size() - 1; i >= 0; i--) { + if (this_hitsInTime >= station_thresholds[i]) { + this_inTimeHMT = i + 1; + break; + } + } + } + } + //ALCT shower construction with showerType_=1, comparatorhits_= 0; + anode_showers_[bx] = CSCShowerDigi( + this_inTimeHMT, false, theTrigChamber, bx, CSCShowerDigi::ShowerType::kALCTShower, this_hitsInTime, 0); + } } diff --git a/L1Trigger/CSCTriggerPrimitives/src/CSCCathodeLCTProcessor.cc b/L1Trigger/CSCTriggerPrimitives/src/CSCCathodeLCTProcessor.cc index 3bf4626b1afb1..4432781b6b84b 100644 --- a/L1Trigger/CSCTriggerPrimitives/src/CSCCathodeLCTProcessor.cc +++ b/L1Trigger/CSCTriggerPrimitives/src/CSCCathodeLCTProcessor.cc @@ -95,11 +95,13 @@ CSCCathodeLCTProcessor::CSCCathodeLCTProcessor(unsigned endcap, const auto& shower = showerParams_.getParameterSet("cathodeShower"); thresholds_ = shower.getParameter>("showerThresholds"); - showerMinInTBin_ = shower.getParameter("showerMinInTBin"); - showerMaxInTBin_ = shower.getParameter("showerMaxInTBin"); - showerMinOutTBin_ = shower.getParameter("showerMinOutTBin"); - showerMaxOutTBin_ = shower.getParameter("showerMaxOutTBin"); + showerNumTBins_ = shower.getParameter("showerNumTBins"); minLayersCentralTBin_ = shower.getParameter("minLayersCentralTBin"); + peakCheck_ = shower.getParameter("peakCheck"); + minbx_readout_ = CSCConstants::LCT_CENTRAL_BX - tmb_l1a_window_size / 2; + maxbx_readout_ = CSCConstants::LCT_CENTRAL_BX + tmb_l1a_window_size / 2; + assert(tmb_l1a_window_size / 2 <= CSCConstants::LCT_CENTRAL_BX); + thePreTriggerDigis.clear(); // quality control of stubs @@ -117,6 +119,8 @@ void CSCCathodeLCTProcessor::setDefaultConfigParameters() { pid_thresh_pretrig = def_pid_thresh_pretrig; min_separation = def_min_separation; tmb_l1a_window_size = def_tmb_l1a_window_size; + minbx_readout_ = CSCConstants::LCT_CENTRAL_BX - tmb_l1a_window_size / 2; + maxbx_readout_ = CSCConstants::LCT_CENTRAL_BX + tmb_l1a_window_size / 2; } // Set configuration parameters obtained via EventSetup mechanism. @@ -138,6 +142,8 @@ void CSCCathodeLCTProcessor::setConfigParameters(const CSCDBL1TPParameters* conf dumpConfigParams(); config_dumped = true; } + minbx_readout_ = CSCConstants::LCT_CENTRAL_BX - tmb_l1a_window_size / 2; + maxbx_readout_ = CSCConstants::LCT_CENTRAL_BX + tmb_l1a_window_size / 2; } void CSCCathodeLCTProcessor::setESLookupTables(const CSCL1TPLookupTableCCLUT* conf) { cclut_->setESLookupTables(conf); } @@ -170,6 +176,7 @@ void CSCCathodeLCTProcessor::checkConfigParameters() { CSCBaseboard::checkConfigParameters(min_separation, max_min_separation, def_min_separation, "min_separation"); CSCBaseboard::checkConfigParameters( tmb_l1a_window_size, max_tmb_l1a_window_size, def_tmb_l1a_window_size, "tmb_l1a_window_size"); + assert(tmb_l1a_window_size / 2 <= CSCConstants::LCT_CENTRAL_BX); } void CSCCathodeLCTProcessor::clear() { @@ -178,8 +185,8 @@ void CSCCathodeLCTProcessor::clear() { for (int bx = 0; bx < CSCConstants::MAX_CLCT_TBINS; bx++) { bestCLCT[bx].clear(); secondCLCT[bx].clear(); + cathode_showers_[bx].clear(); } - inTimeHMT_ = 0; } std::vector CSCCathodeLCTProcessor::run(const CSCComparatorDigiCollection* compdc) { @@ -300,7 +307,7 @@ std::vector CSCCathodeLCTProcessor::run(const CSCComparatorDigiColl run(halfStripTimes); // Get the high multiplicity bits in this chamber - encodeHighMultiplicityBits(halfStripTimes); + encodeHighMultiplicityBits(); } // Return vector of CLCTs. @@ -1201,52 +1208,46 @@ CSCCLCTDigi CSCCathodeLCTProcessor::getSecondCLCT(int bx) const { return lct; } +/** return vector of CSCShower digi **/ +std::vector CSCCathodeLCTProcessor::getAllShower() const { + std::vector vshowers(cathode_showers_, cathode_showers_ + CSCConstants::MAX_CLCT_TBINS); + return vshowers; +}; + /** Returns shower bits */ -CSCShowerDigi CSCCathodeLCTProcessor::readoutShower() const { return shower_; } +std::vector CSCCathodeLCTProcessor::readoutShower() const { + std::vector showerOut; + for (unsigned bx = minbx_readout_; bx < maxbx_readout_; bx++) + if (cathode_showers_[bx].isValid()) + showerOut.push_back(cathode_showers_[bx]); + return showerOut; +} -void CSCCathodeLCTProcessor::encodeHighMultiplicityBits( - const std::vector halfstrip[CSCConstants::NUM_LAYERS][CSCConstants::MAX_NUM_HALF_STRIPS_RUN2_TRIGGER]) { - inTimeHMT_ = 0; +void CSCCathodeLCTProcessor::encodeHighMultiplicityBits() { + //inTimeHMT_ = 0; - auto layerTime = [=](unsigned time) { return time == CSCConstants::CLCT_CENTRAL_BX; }; + //numer of layer with hits and number of hits for 0-15 BXs + std::set layersWithHits[CSCConstants::MAX_CLCT_TBINS]; + unsigned hitsInTime[CSCConstants::MAX_CLCT_TBINS]; // Calculate layers with hits - unsigned nLayersWithHits = 0; - for (int i_layer = 0; i_layer < CSCConstants::NUM_LAYERS; i_layer++) { - bool atLeastOneWGHit = false; - for (int i_hstrip = 0; i_hstrip < CSCConstants::MAX_NUM_HALF_STRIPS_RUN2_TRIGGER; i_hstrip++) { - // there is at least one halfstrip... - if (!halfstrip[i_layer][i_hstrip].empty()) { - auto times = halfstrip[i_layer][i_hstrip]; - int nLayerTime = std::count_if(times.begin(), times.end(), layerTime); - // ...for which at least one time bin was on for the central BX - if (nLayerTime > 0) { - atLeastOneWGHit = true; - break; + for (unsigned bx = 0; bx < CSCConstants::MAX_CLCT_TBINS; bx++) { + hitsInTime[bx] = 0; + for (unsigned i_layer = 0; i_layer < CSCConstants::NUM_LAYERS; i_layer++) { + bool atLeastOneCompHit = false; + for (const auto& compdigi : digiV[i_layer]) { + std::vector bx_times = compdigi.getTimeBinsOn(); + // there is at least one comparator digi in this bx + if (std::find(bx_times.begin(), bx_times.end(), bx) != bx_times.end()) { + hitsInTime[bx] += 1; + atLeastOneCompHit = true; } } + // add this layer to the number of layers hit + if (atLeastOneCompHit) { + layersWithHits[bx].insert(i_layer); + } } - // add this layer to the number of layers hit - if (atLeastOneWGHit) { - nLayersWithHits++; - } - } - - // require at least nLayersWithHits for the central time bin - // do nothing if there are not enough layers with hits - if (nLayersWithHits < minLayersCentralTBin_) - return; - - // functions for in-time and out-of-time - auto inTime = [=](unsigned time) { return time >= showerMinInTBin_ and time <= showerMaxInTBin_; }; - - // count the half-strips in-time and out-time - unsigned hitsInTime = 0; - for (int i_layer = 0; i_layer < CSCConstants::NUM_LAYERS; i_layer++) { - for (int i_hstrip = 0; i_hstrip < CSCConstants::MAX_NUM_HALF_STRIPS_RUN2_TRIGGER; i_hstrip++) { - auto times = halfstrip[i_layer][i_hstrip]; - hitsInTime += std::count_if(times.begin(), times.end(), inTime); - } - } + } //end of full bx loop // convert station and ring number to index // index runs from 2 to 10, subtract 2 @@ -1256,13 +1257,51 @@ void CSCCathodeLCTProcessor::encodeHighMultiplicityBits( std::vector station_thresholds = { thresholds_[csc_idx * 3], thresholds_[csc_idx * 3 + 1], thresholds_[csc_idx * 3 + 2]}; - // assign the bits - for (unsigned i = 0; i < station_thresholds.size(); i++) { - if (hitsInTime >= station_thresholds[i]) { - inTimeHMT_ = i + 1; + //hard coded dead time as 2Bx, since showerNumTBins = 3, like firmware + // for example, nhits = 0 at bx7; = 100 at bx8; = 0 at bx9 + //cathode HMT must be triggered at bx8, not bx7 and bx9 + //meanwhile we forced 2BX dead time after active shower trigger + unsigned int deadtime = + showerNumTBins_ - 1; // firmware hard coded dead time as 2Bx, since showerNumTBins = 3 in firmware + unsigned int dead_count = 0; + + for (unsigned bx = 0; bx < CSCConstants::MAX_CLCT_TBINS; bx++) { + unsigned minbx = bx >= showerNumTBins_ / 2 ? bx - showerNumTBins_ / 2 : bx; + unsigned maxbx = bx < CSCConstants::MAX_CLCT_TBINS - showerNumTBins_ / 2 ? bx + showerNumTBins_ / 2 + : CSCConstants::MAX_CLCT_TBINS - 1; + unsigned this_hitsInTime = 0; + bool isPeak = true; //check whether total hits in bx is peak of nhits over time bins + /*following is to count number of hits over [minbx, maxbx], showerNumTBins=3 =>[n-1, n+1]*/ + for (unsigned mbx = minbx; mbx <= maxbx; mbx++) { + this_hitsInTime += hitsInTime[mbx]; } - } - // create a new object - shower_ = CSCShowerDigi(inTimeHMT_, false, theTrigChamber); + if (peakCheck_ and bx < CSCConstants::MAX_CLCT_TBINS - showerNumTBins_ / 2 - 1) { + if (hitsInTime[minbx] < hitsInTime[maxbx + 1] or + (hitsInTime[minbx] == hitsInTime[maxbx + 1] and hitsInTime[bx] < hitsInTime[bx + 1])) + isPeak = false; //next bx would have more hits or in the center + } + bool dead_status = dead_count > 0; + if (dead_status) + dead_count--; + + unsigned this_inTimeHMT = 0; + // require at least nLayersWithHits for the central time bin + // do nothing if there are not enough layers with hits + if (layersWithHits[bx].size() >= minLayersCentralTBin_ and !dead_status and isPeak) { + // assign the bits + if (!station_thresholds.empty()) { + for (int i = station_thresholds.size() - 1; i >= 0; i--) { + if (this_hitsInTime >= station_thresholds[i]) { + this_inTimeHMT = i + 1; + dead_count = deadtime; + break; + } + } + } + } + //CLCTshower constructor with showerType_ = 2, wirehits = 0; + cathode_showers_[bx] = CSCShowerDigi( + this_inTimeHMT, false, theTrigChamber, bx, CSCShowerDigi::ShowerType::kCLCTShower, 0, this_hitsInTime); + } } diff --git a/L1Trigger/CSCTriggerPrimitives/src/CSCMotherboard.cc b/L1Trigger/CSCTriggerPrimitives/src/CSCMotherboard.cc index 7ca47cdf64a68..669d3b6493ea8 100644 --- a/L1Trigger/CSCTriggerPrimitives/src/CSCMotherboard.cc +++ b/L1Trigger/CSCTriggerPrimitives/src/CSCMotherboard.cc @@ -55,7 +55,7 @@ CSCMotherboard::CSCMotherboard(unsigned endcap, allLCTs_.setMatchTrigWindowSize(match_trig_window_size); // get the preferred CLCT BX match array - preferred_bx_match_ = tmbParams_.getParameter >("preferredBxMatch"); + preferred_bx_match_ = tmbParams_.getParameter>("preferredBxMatch"); // quality assignment qualityAssignment_ = std::make_unique(endcap, station, sector, subsector, chamber, conf); @@ -64,7 +64,15 @@ CSCMotherboard::CSCMotherboard(unsigned endcap, qualityControl_ = std::make_unique(endcap, station, sector, subsector, chamber, conf); // shower-trigger source - showerSource_ = showerParams_.getParameter("source"); + showerSource_ = showerParams_.getParameter>("source"); + + unsigned csc_idx = CSCDetId::iChamberType(theStation, theRing) - 2; + thisShowerSource_ = showerSource_[csc_idx]; + + // shower readout window + minbx_readout_ = CSCConstants::LCT_CENTRAL_BX - tmb_l1a_window_size / 2; + maxbx_readout_ = CSCConstants::LCT_CENTRAL_BX + tmb_l1a_window_size / 2; + assert(tmb_l1a_window_size / 2 <= CSCConstants::LCT_CENTRAL_BX); // enable the upgrade processors for ring 1 stations if (runPhase2_ and theRing == 1) { @@ -95,8 +103,9 @@ void CSCMotherboard::clear() { allLCTs_.clear(); - // reset the shower trigger - shower_.clear(); + for (int bx = 0; bx < CSCConstants::MAX_LCT_TBINS; bx++) { + showers_[bx].clear(); + } } // Set configuration parameters obtained via EventSetup mechanism. @@ -121,6 +130,8 @@ void CSCMotherboard::setConfigParameters(const CSCDBL1TPParameters* conf) { dumpConfigParams(); config_dumped = true; } + minbx_readout_ = CSCConstants::LCT_CENTRAL_BX - tmb_l1a_window_size / 2; + maxbx_readout_ = CSCConstants::LCT_CENTRAL_BX + tmb_l1a_window_size / 2; } void CSCMotherboard::setESLookupTables(const CSCL1TPLookupTableCCLUT* conf) { lookupTableCCLUT_ = conf; } @@ -190,9 +201,9 @@ void CSCMotherboard::matchALCTCLCT() { // loop on the preferred "delta BX" array for (unsigned mbx = 0; mbx < match_trig_window_size; mbx++) { // evaluate the preffered CLCT BX, taking into account that there is an offset in the simulation - unsigned bx_clct = bx_alct + preferred_bx_match_[mbx] - CSCConstants::ALCT_CLCT_OFFSET; + int bx_clct = bx_alct + preferred_bx_match_[mbx] - CSCConstants::ALCT_CLCT_OFFSET; // check that the CLCT BX is valid - if (bx_clct >= CSCConstants::MAX_CLCT_TBINS) + if (bx_clct >= CSCConstants::MAX_CLCT_TBINS or bx_clct < 0) continue; // do not consider previously matched CLCTs if (drop_used_clcts && used_clct_mask[bx_clct]) @@ -365,7 +376,24 @@ std::vector CSCMotherboard::readoutLCTs() const { return tmpV; } -CSCShowerDigi CSCMotherboard::readoutShower() const { return shower_; } +std::vector CSCMotherboard::readoutShower() const { + unsigned minBXdiff = 2 * tmb_l1a_window_size; //impossible value + unsigned minBX = 0; + std::vector showerOut; + for (unsigned bx = minbx_readout_; bx < maxbx_readout_; bx++) { + unsigned bx_diff = (bx > bx - CSCConstants::LCT_CENTRAL_BX) ? bx - CSCConstants::LCT_CENTRAL_BX + : CSCConstants::LCT_CENTRAL_BX - bx; + if (showers_[bx].isValid() and bx_diff < minBXdiff) { + minBXdiff = bx_diff; + minBX = bx; + } + } + + for (unsigned bx = minbx_readout_; bx < maxbx_readout_; bx++) + if (bx == minBX) + showerOut.push_back(showers_[bx]); + return showerOut; +} void CSCMotherboard::correlateLCTs(const CSCALCTDigi& bALCT, const CSCALCTDigi& sALCT, @@ -548,6 +576,7 @@ void CSCMotherboard::checkConfigParameters() { match_trig_window_size, max_match_trig_window_size, def_match_trig_window_size, "match_trig_window_size"); CSCBaseboard::checkConfigParameters( tmb_l1a_window_size, max_tmb_l1a_window_size, def_tmb_l1a_window_size, "tmb_l1a_window_size"); + assert(tmb_l1a_window_size / 2 <= CSCConstants::LCT_CENTRAL_BX); } void CSCMotherboard::dumpConfigParams() const { @@ -578,34 +607,82 @@ CSCCLCTDigi CSCMotherboard::getBXShiftedCLCT(const CSCCLCTDigi& cLCT) const { return cLCT_shifted; } +void CSCMotherboard::matchShowers(CSCShowerDigi* anode_showers, CSCShowerDigi* cathode_showers, bool andlogic) { + CSCShowerDigi ashower, cshower; + bool used_cshower_mask[CSCConstants::MAX_CLCT_TBINS] = {false}; + for (unsigned bx = 0; bx < CSCConstants::MAX_ALCT_TBINS; bx++) { + ashower = anode_showers[bx]; + cshower = CSCShowerDigi(); //use empty shower digi to initialize cshower + if (ashower.isValid()) { + for (unsigned mbx = 0; mbx < match_trig_window_size; mbx++) { + int cbx = bx + preferred_bx_match_[mbx] - CSCConstants::ALCT_CLCT_OFFSET; + //check bx range [0, CSCConstants::MAX_LCT_TBINS] + if (cbx < 0 || cbx >= CSCConstants::MAX_CLCT_TBINS) + continue; + if (cathode_showers[cbx].isValid() and not used_cshower_mask[cbx]) { + cshower = cathode_showers[cbx]; + used_cshower_mask[cbx] = true; + break; + } + } + } else + cshower = cathode_showers[bx]; //if anode shower is not valid, use the cshower from this bx + + //matched HMT, with and/or logic + unsigned matchHMT = 0; + if (andlogic) { + if (ashower.isTightInTime() and cshower.isTightInTime()) + matchHMT = 3; + else if (ashower.isNominalInTime() and cshower.isNominalInTime()) + matchHMT = 2; + else if (ashower.isLooseInTime() and cshower.isLooseInTime()) + matchHMT = 1; + } else { + if (ashower.isTightInTime() or cshower.isTightInTime()) + matchHMT = 3; + else if (ashower.isNominalInTime() or cshower.isNominalInTime()) + matchHMT = 2; + else if (ashower.isLooseInTime() or cshower.isLooseInTime()) + matchHMT = 1; + } + //LCTShower with showerType = 3 + showers_[bx] = CSCShowerDigi(matchHMT & 3, + false, + ashower.getCSCID(), + bx, + CSCShowerDigi::ShowerType::kLCTShower, + ashower.getWireNHits(), + cshower.getComparatorNHits()); + } +} + void CSCMotherboard::encodeHighMultiplicityBits() { // get the high multiplicity // for anode this reflects what is already in the anode CSCShowerDigi object - unsigned cathodeInTime = clctProc->getInTimeHMT(); - unsigned anodeInTime = alctProc->getInTimeHMT(); + CSCShowerDigi cathode_showers[CSCConstants::MAX_CLCT_TBINS]; + CSCShowerDigi anode_showers[CSCConstants::MAX_ALCT_TBINS]; + auto cshowers_v = clctProc->getAllShower(); + auto ashowers_v = alctProc->getAllShower(); - // assign the bits - unsigned inTimeHMT_; + std::copy(cshowers_v.begin(), cshowers_v.end(), cathode_showers); + std::copy(ashowers_v.begin(), ashowers_v.end(), anode_showers); // set the value according to source - switch (showerSource_) { + switch (thisShowerSource_) { case 0: - inTimeHMT_ = cathodeInTime; + std::copy(std::begin(cathode_showers), std::end(cathode_showers), std::begin(showers_)); break; case 1: - inTimeHMT_ = anodeInTime; + std::copy(std::begin(anode_showers), std::end(anode_showers), std::begin(showers_)); break; case 2: - inTimeHMT_ = anodeInTime | cathodeInTime; + matchShowers(anode_showers, cathode_showers, false); break; case 3: - inTimeHMT_ = anodeInTime & cathodeInTime; + matchShowers(anode_showers, cathode_showers, true); break; default: - inTimeHMT_ = cathodeInTime; + std::copy(std::begin(anode_showers), std::end(anode_showers), std::begin(showers_)); break; }; - - // create a new object - shower_ = CSCShowerDigi(inTimeHMT_, 0, theTrigChamber); } diff --git a/L1Trigger/CSCTriggerPrimitives/src/CSCTriggerPrimitivesBuilder.cc b/L1Trigger/CSCTriggerPrimitives/src/CSCTriggerPrimitivesBuilder.cc index c0aed699dabc1..e8b54327aec2c 100644 --- a/L1Trigger/CSCTriggerPrimitives/src/CSCTriggerPrimitivesBuilder.cc +++ b/L1Trigger/CSCTriggerPrimitives/src/CSCTriggerPrimitivesBuilder.cc @@ -25,6 +25,7 @@ CSCTriggerPrimitivesBuilder::CSCTriggerPrimitivesBuilder(const edm::ParameterSet disableME42_ = commonParams.getParameter("disableME42"); checkBadChambers_ = conf.getParameter("checkBadChambers"); + selectedChambers_ = conf.getParameter>("selectedChambers"); runME11Up_ = commonParams.getParameter("runME11Up"); runME21Up_ = commonParams.getParameter("runME21Up"); @@ -191,6 +192,13 @@ void CSCTriggerPrimitivesBuilder::build(const CSCBadChambers* badChambers, if (checkBadChambers_ && badChambers->isInBadChamber(detid)) continue; + //only process the selected chambers when selectedChambers is not empty + if (!selectedChambers_.empty()) { + if (std::find(selectedChambers_.begin(), selectedChambers_.end(), detid.chamberName()) == + selectedChambers_.end()) { + continue; + } + } const bool upgrade = runPhase2_ and ring == 1; const bool upgradeGE11 = upgrade and stat == 1 and runME11Up_ and runME11ILT_; const bool upgradeGE21 = upgrade and stat == 2 and runME21Up_ and runME21ILT_; @@ -227,9 +235,9 @@ void CSCTriggerPrimitivesBuilder::build(const CSCBadChambers* badChambers, const std::vector& alctpretriggerV = tmb->alctProc->preTriggerDigis(); // showers - const CSCShowerDigi& shower = tmb->readoutShower(); - const CSCShowerDigi& anodeShower = tmb->alctProc->readoutShower(); - const CSCShowerDigi& cathodeShower = tmb->clctProc->readoutShower(); + const std::vector& shower = tmb->readoutShower(); + const std::vector& anodeShower = tmb->alctProc->readoutShower(); + const std::vector& cathodeShower = tmb->clctProc->readoutShower(); put(alctV, oc_alct, detid, tmb->getCSCName() + " ALCT digi"); put(clctV, oc_clct, detid, tmb->getCSCName() + " CLCT digi"); @@ -239,12 +247,15 @@ void CSCTriggerPrimitivesBuilder::build(const CSCBadChambers* badChambers, put(pretriggerV, oc_pretrigger, detid, tmb->getCSCName() + " CLCT pre-trigger digi"); put(alctpretriggerV, oc_alctpretrigger, detid, tmb->getCSCName() + " ALCT pre-trigger digi"); - if (shower.isValid()) - oc_shower.insertDigi(detid, shower); - if (anodeShower.isValid()) - oc_shower_anode.insertDigi(detid, anodeShower); - if (cathodeShower.isValid()) - oc_shower_cathode.insertDigi(detid, cathodeShower); + put(shower, oc_shower, detid, tmb->getCSCName() + "TMB shower"); + put(anodeShower, oc_shower_anode, detid, tmb->getCSCName() + "Anode shower"); + put(cathodeShower, oc_shower_cathode, detid, tmb->getCSCName() + "Cathode shower"); + //if (shower.isValid()) + // oc_shower.insertDigi(detid, shower); + //if (anodeShower.isValid()) + // oc_shower_anode.insertDigi(detid, anodeShower); + //if (cathodeShower.isValid()) + // oc_shower_cathode.insertDigi(detid, cathodeShower); if (!(alctV.empty() && clctV.empty() && lctV.empty()) and infoV > 1) { LogTrace("L1CSCTrigger") << "CSCTriggerPrimitivesBuilder got results in " << detid;