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 4333a591139b2..335ed9385f139 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;