File indexing completed on 2023-10-25 09:54:12
0001 #include "L1Trigger/CSCTriggerPrimitives/interface/CSCMotherboard.h"
0002 #include <iostream>
0003 #include <memory>
0004
0005
0006 const unsigned int CSCMotherboard::def_mpc_block_me1a = 1;
0007 const unsigned int CSCMotherboard::def_alct_trig_enable = 0;
0008 const unsigned int CSCMotherboard::def_clct_trig_enable = 0;
0009 const unsigned int CSCMotherboard::def_match_trig_enable = 1;
0010 const unsigned int CSCMotherboard::def_match_trig_window_size = 7;
0011 const unsigned int CSCMotherboard::def_tmb_l1a_window_size = 7;
0012
0013 CSCMotherboard::CSCMotherboard(unsigned endcap,
0014 unsigned station,
0015 unsigned sector,
0016 unsigned subsector,
0017 unsigned chamber,
0018 CSCBaseboard::Parameters& conf)
0019 : CSCBaseboard(endcap, station, sector, subsector, chamber, conf) {
0020
0021
0022 static std::atomic<bool> config_dumped{false};
0023
0024 mpc_block_me1a_ = conf.tmbParams().getParameter<unsigned int>("mpcBlockMe1a");
0025 alct_trig_enable_ = conf.tmbParams().getParameter<unsigned int>("alctTrigEnable");
0026 clct_trig_enable_ = conf.tmbParams().getParameter<unsigned int>("clctTrigEnable");
0027 match_trig_enable_ = conf.tmbParams().getParameter<unsigned int>("matchTrigEnable");
0028 match_trig_window_size_ = conf.tmbParams().getParameter<unsigned int>("matchTrigWindowSize");
0029 tmb_l1a_window_size_ =
0030 conf.tmbParams().getParameter<unsigned int>("tmbL1aWindowSize");
0031
0032
0033 early_tbins = conf.tmbParams().getParameter<int>("tmbEarlyTbins");
0034
0035
0036 drop_used_clcts = conf.tmbParams().getParameter<bool>("tmbDropUsedClcts");
0037
0038
0039 readout_earliest_2 = conf.tmbParams().getParameter<bool>("tmbReadoutEarliest2");
0040
0041 match_earliest_clct_only_ = conf.tmbParams().getParameter<bool>("matchEarliestClctOnly");
0042
0043 infoV = conf.tmbParams().getParameter<int>("verbosity");
0044
0045 alctProc = std::make_unique<CSCAnodeLCTProcessor>(endcap, station, sector, subsector, chamber, conf);
0046 clctProc = std::make_unique<CSCCathodeLCTProcessor>(endcap, station, sector, subsector, chamber, conf);
0047
0048
0049 checkConfigParameters();
0050 if (infoV > 0 && !config_dumped) {
0051 dumpConfigParams();
0052 config_dumped = true;
0053 }
0054
0055 allLCTs_.setMatchTrigWindowSize(match_trig_window_size_);
0056
0057
0058 preferred_bx_match_ = conf.tmbParams().getParameter<std::vector<int>>("preferredBxMatch");
0059
0060
0061 sort_clct_bx_ = conf.tmbParams().getParameter<bool>("sortClctBx");
0062
0063
0064 qualityAssignment_ = std::make_unique<LCTQualityAssignment>(endcap, station, sector, subsector, chamber, conf);
0065
0066
0067 qualityControl_ = std::make_unique<LCTQualityControl>(endcap, station, sector, subsector, chamber, conf);
0068
0069
0070 showerSource_ = conf.showerParams().getParameter<std::vector<unsigned>>("source");
0071
0072 unsigned csc_idx = CSCDetId::iChamberType(theStation, theRing) - 2;
0073 thisShowerSource_ = showerSource_[csc_idx];
0074
0075
0076 minbx_readout_ = CSCConstants::LCT_CENTRAL_BX - tmb_l1a_window_size_ / 2;
0077 maxbx_readout_ = CSCConstants::LCT_CENTRAL_BX + tmb_l1a_window_size_ / 2;
0078 assert(tmb_l1a_window_size_ / 2 <= CSCConstants::LCT_CENTRAL_BX);
0079
0080
0081 if (runPhase2_ and theRing == 1) {
0082 clctProc = std::make_unique<CSCUpgradeCathodeLCTProcessor>(endcap, station, sector, subsector, chamber, conf);
0083 if (enableAlctPhase2_) {
0084 alctProc = std::make_unique<CSCUpgradeAnodeLCTProcessor>(endcap, station, sector, subsector, chamber, conf);
0085 }
0086 }
0087
0088
0089 ignoreAlctCrossClct_ = conf.tmbParams().getParameter<bool>("ignoreAlctCrossClct");
0090 if (!ignoreAlctCrossClct_) {
0091 cscOverlap_ = std::make_unique<CSCALCTCrossCLCT>(endcap, station, theRing, ignoreAlctCrossClct_, conf.conf());
0092 }
0093 }
0094
0095 void CSCMotherboard::clear() {
0096
0097 if (alctProc)
0098 alctProc->clear();
0099 if (clctProc)
0100 clctProc->clear();
0101
0102 lctV.clear();
0103
0104 allLCTs_.clear();
0105
0106 for (int bx = 0; bx < CSCConstants::MAX_LCT_TBINS; bx++) {
0107 showers_[bx].clear();
0108 }
0109 }
0110
0111
0112 void CSCMotherboard::setConfigParameters(const CSCDBL1TPParameters* conf) {
0113 if (nullptr == conf) {
0114 return;
0115 }
0116 static std::atomic<bool> config_dumped{false};
0117
0118
0119 mpc_block_me1a_ = conf->tmbMpcBlockMe1a();
0120 alct_trig_enable_ = conf->tmbAlctTrigEnable();
0121 clct_trig_enable_ = conf->tmbClctTrigEnable();
0122 match_trig_enable_ = conf->tmbMatchTrigEnable();
0123 match_trig_window_size_ = conf->tmbMatchTrigWindowSize();
0124 tmb_l1a_window_size_ = conf->tmbTmbL1aWindowSize();
0125
0126
0127 alctProc->setConfigParameters(conf);
0128 clctProc->setConfigParameters(conf);
0129
0130
0131 checkConfigParameters();
0132 if (!config_dumped) {
0133 dumpConfigParams();
0134 config_dumped = true;
0135 }
0136 minbx_readout_ = CSCConstants::LCT_CENTRAL_BX - tmb_l1a_window_size_ / 2;
0137 maxbx_readout_ = CSCConstants::LCT_CENTRAL_BX + tmb_l1a_window_size_ / 2;
0138 }
0139
0140 std::tuple<std::vector<CSCALCTDigi>, std::vector<CSCCLCTDigi>> CSCMotherboard::runCommon(
0141 const CSCWireDigiCollection* wiredc, const CSCComparatorDigiCollection* compdc, const RunContext& context) {
0142
0143 clear();
0144
0145 setConfigParameters(context.parameters_);
0146
0147 std::tuple<std::vector<CSCALCTDigi>, std::vector<CSCCLCTDigi>> retValue;
0148
0149
0150 if (!(alctProc && clctProc)) {
0151 edm::LogError("CSCMotherboard|SetupError") << "+++ run() called for non-existing ALCT/CLCT processor! +++ \n";
0152 return retValue;
0153 }
0154
0155 assert(context.cscGeometry_);
0156 auto chamber = cscChamber(*context.cscGeometry_);
0157
0158
0159 retValue = std::make_tuple(alctProc->run(wiredc, chamber), clctProc->run(compdc, chamber, context.lookupTableCCLUT_));
0160
0161
0162 encodeHighMultiplicityBits();
0163
0164 return retValue;
0165 }
0166
0167 void CSCMotherboard::run(const CSCWireDigiCollection* wiredc,
0168 const CSCComparatorDigiCollection* compdc,
0169 const RunContext& context) {
0170 auto [alctV, clctV] = runCommon(wiredc, compdc, context);
0171
0172 if (alctV.empty() and clctV.empty())
0173 return;
0174
0175
0176 matchALCTCLCT();
0177
0178
0179 selectLCTs();
0180 }
0181
0182 void CSCMotherboard::matchALCTCLCT() {
0183
0184 bool used_clct_mask[CSCConstants::MAX_CLCT_TBINS] = {false};
0185
0186
0187 int bx_clct_matched = 0;
0188 for (int bx_alct = 0; bx_alct < CSCConstants::MAX_ALCT_TBINS; bx_alct++) {
0189
0190
0191
0192
0193 if (alctProc->getBestALCT(bx_alct).isValid()) {
0194
0195
0196
0197
0198
0199
0200
0201
0202 bool is_matched = false;
0203
0204
0205 std::vector<unsigned> clctBx_qualbend_match;
0206 sortCLCTByQualBend(bx_alct, clctBx_qualbend_match);
0207
0208 bool hasLocalShower = false;
0209 for (unsigned ibx = 1; ibx <= match_trig_window_size_ / 2; ibx++)
0210 hasLocalShower =
0211 (hasLocalShower or clctProc->getLocalShowerFlag(bx_alct - CSCConstants::ALCT_CLCT_OFFSET - ibx));
0212
0213
0214 for (unsigned mbx = 0; mbx < match_trig_window_size_; mbx++) {
0215
0216
0217 unsigned bx_clct_run2 = bx_alct + preferred_bx_match_[mbx] - CSCConstants::ALCT_CLCT_OFFSET;
0218 unsigned bx_clct_qualbend = clctBx_qualbend_match[mbx];
0219 unsigned bx_clct = (sort_clct_bx_ or not(hasLocalShower)) ? bx_clct_run2 : bx_clct_qualbend;
0220
0221 if (bx_clct >= CSCConstants::MAX_CLCT_TBINS)
0222 continue;
0223
0224 if (drop_used_clcts && used_clct_mask[bx_clct])
0225 continue;
0226
0227
0228
0229 if (clctProc->getBestCLCT(bx_clct).getQuality() <= 3)
0230 continue;
0231
0232 if (clctProc->getBestCLCT(bx_clct).isValid()) {
0233 if (infoV > 1)
0234 LogTrace("CSCMotherboard") << "Successful ALCT-CLCT match: bx_alct = " << bx_alct
0235 << "; bx_clct = " << bx_clct << "; mbx = " << mbx;
0236
0237
0238 correlateLCTs(alctProc->getBestALCT(bx_alct),
0239 alctProc->getSecondALCT(bx_alct),
0240 clctProc->getBestCLCT(bx_clct),
0241 clctProc->getSecondCLCT(bx_clct),
0242 allLCTs_(bx_alct, mbx, 0),
0243 allLCTs_(bx_alct, mbx, 1),
0244 CSCCorrelatedLCTDigi::ALCTCLCT);
0245
0246
0247 if (allLCTs_(bx_alct, mbx, 0).isValid()) {
0248 is_matched = true;
0249 used_clct_mask[bx_clct] = true;
0250 bx_clct_matched = bx_clct;
0251 if (match_earliest_clct_only_)
0252 break;
0253 }
0254 }
0255 }
0256
0257
0258 if (!is_matched) {
0259 if (infoV > 1)
0260 LogTrace("CSCMotherboard") << "Unsuccessful ALCT-CLCT match (ALCT only): bx_alct = " << bx_alct
0261 << " first ALCT " << alctProc->getBestALCT(bx_alct);
0262 if (alct_trig_enable_)
0263 correlateLCTs(alctProc->getBestALCT(bx_alct),
0264 alctProc->getSecondALCT(bx_alct),
0265 clctProc->getBestCLCT(bx_alct),
0266 clctProc->getSecondCLCT(bx_alct),
0267 allLCTs_(bx_alct, 0, 0),
0268 allLCTs_(bx_alct, 0, 1),
0269 CSCCorrelatedLCTDigi::ALCTONLY);
0270 }
0271 }
0272
0273
0274
0275
0276 else {
0277 int bx_clct = bx_alct - match_trig_window_size_ / 2;
0278 if (bx_clct >= 0 && bx_clct > bx_clct_matched) {
0279 if (clctProc->getBestCLCT(bx_clct).isValid() and clct_trig_enable_) {
0280 if (infoV > 1)
0281 LogTrace("CSCMotherboard") << "Unsuccessful ALCT-CLCT match (CLCT only): bx_clct = " << bx_clct;
0282 correlateLCTs(alctProc->getBestALCT(bx_alct),
0283 alctProc->getSecondALCT(bx_alct),
0284 clctProc->getBestCLCT(bx_clct),
0285 clctProc->getSecondCLCT(bx_clct),
0286 allLCTs_(bx_clct, 0, 0),
0287 allLCTs_(bx_clct, 0, 1),
0288 CSCCorrelatedLCTDigi::CLCTONLY);
0289 }
0290 }
0291 }
0292 }
0293 }
0294
0295
0296
0297
0298 std::vector<CSCCorrelatedLCTDigi> CSCMotherboard::readoutLCTs() const {
0299
0300 std::vector<CSCCorrelatedLCTDigi> tmpV;
0301
0302
0303
0304
0305
0306
0307
0308
0309 const unsigned delta_tbin = tmb_l1a_window_size_ / 2;
0310 int early_tbin = CSCConstants::LCT_CENTRAL_BX - delta_tbin;
0311 int late_tbin = CSCConstants::LCT_CENTRAL_BX + delta_tbin;
0312
0313
0314
0315
0316 if (tmb_l1a_window_size_ % 2 == 0)
0317 late_tbin = CSCConstants::LCT_CENTRAL_BX + delta_tbin - 1;
0318 const int max_late_tbin = CSCConstants::MAX_LCT_TBINS - 1;
0319
0320
0321 if (early_tbin < 0) {
0322 edm::LogWarning("CSCMotherboard|SuspiciousParameters")
0323 << "Early time bin (early_tbin) smaller than minimum allowed, which is 0. set early_tbin to 0.";
0324 early_tbin = 0;
0325 }
0326 if (late_tbin > max_late_tbin) {
0327 edm::LogWarning("CSCMotherboard|SuspiciousParameters")
0328 << "Late time bin (late_tbin) larger than maximum allowed, which is " << max_late_tbin
0329 << ". set early_tbin to max allowed";
0330 late_tbin = CSCConstants::MAX_LCT_TBINS - 1;
0331 }
0332
0333
0334
0335 int bx_readout = -1;
0336 for (const auto& lct : lctV) {
0337
0338 if (!lct.isValid()) {
0339 continue;
0340 }
0341
0342 const int bx = lct.getBX();
0343
0344 if (bx < early_tbin) {
0345 if (infoV > 1)
0346 LogDebug("CSCMotherboard") << " Do not report correlated LCT on key halfstrip " << lct.getStrip()
0347 << " and key wire " << lct.getKeyWG() << ": found at bx " << bx
0348 << ", whereas the earliest allowed bx is " << early_tbin;
0349 continue;
0350 }
0351
0352
0353 if (bx > late_tbin) {
0354 if (infoV > 1)
0355 LogDebug("CSCMotherboard") << " Do not report correlated LCT on key halfstrip " << lct.getStrip()
0356 << " and key wire " << lct.getKeyWG() << ": found at bx " << bx
0357 << ", whereas the latest allowed bx is " << late_tbin;
0358 continue;
0359 }
0360
0361
0362 if (mpc_block_me1a_ and isME11_ and lct.getStrip() > CSCConstants::MAX_HALF_STRIP_ME1B) {
0363 continue;
0364 }
0365
0366
0367
0368
0369 if (readout_earliest_2) {
0370 if (bx_readout == -1 || bx == bx_readout) {
0371 tmpV.push_back(lct);
0372 if (bx_readout == -1)
0373 bx_readout = bx;
0374 }
0375 }
0376
0377 else {
0378 tmpV.push_back(lct);
0379 }
0380 }
0381
0382
0383 qualityControl_->checkMultiplicityBX(tmpV);
0384 for (const auto& lct : tmpV) {
0385 qualityControl_->checkValid(lct);
0386
0387
0388
0389 }
0390
0391 return tmpV;
0392 }
0393
0394 std::vector<CSCShowerDigi> CSCMotherboard::readoutShower() const {
0395 unsigned minBXdiff = 2 * tmb_l1a_window_size_;
0396 unsigned minBX = 0;
0397 std::vector<CSCShowerDigi> showerOut;
0398 for (unsigned bx = minbx_readout_; bx < maxbx_readout_; bx++) {
0399 unsigned bx_diff = (bx > bx - CSCConstants::LCT_CENTRAL_BX) ? bx - CSCConstants::LCT_CENTRAL_BX
0400 : CSCConstants::LCT_CENTRAL_BX - bx;
0401 if (showers_[bx].isValid() and bx_diff < minBXdiff) {
0402 minBXdiff = bx_diff;
0403 minBX = bx;
0404 }
0405 }
0406
0407 for (unsigned bx = minbx_readout_; bx < maxbx_readout_; bx++)
0408 if (bx == minBX)
0409 showerOut.push_back(showers_[bx]);
0410 return showerOut;
0411 }
0412
0413 void CSCMotherboard::correlateLCTs(const CSCALCTDigi& bALCT,
0414 const CSCALCTDigi& sALCT,
0415 const CSCCLCTDigi& bCLCT,
0416 const CSCCLCTDigi& sCLCT,
0417 CSCCorrelatedLCTDigi& bLCT,
0418 CSCCorrelatedLCTDigi& sLCT,
0419 int type) const {
0420 CSCALCTDigi bestALCT = bALCT;
0421 CSCALCTDigi secondALCT = sALCT;
0422 CSCCLCTDigi bestCLCT = bCLCT;
0423 CSCCLCTDigi secondCLCT = sCLCT;
0424
0425
0426
0427
0428
0429 if (bestCLCT.getQuality() <= 3)
0430 bestCLCT.clear();
0431 if (secondCLCT.getQuality() <= 3)
0432 secondCLCT.clear();
0433
0434
0435
0436 copyValidToInValidALCT(bestALCT, secondALCT);
0437 copyValidToInValidCLCT(bestCLCT, secondCLCT);
0438
0439
0440 const bool bestCase1(alct_trig_enable_ and bestALCT.isValid());
0441
0442 const bool bestCase2(clct_trig_enable_ and bestCLCT.isValid());
0443
0444
0445
0446
0447
0448
0449
0450
0451 const bool bestCase3(match_trig_enable_ and bestALCT.isValid() and bestCLCT.isValid() and
0452 doesALCTCrossCLCT(bestALCT, bestCLCT));
0453
0454
0455 if (bestCase1 or bestCase2 or bestCase3) {
0456 constructLCTs(bestALCT, bestCLCT, type, 1, bLCT);
0457 }
0458
0459
0460 const bool secondCase1(alct_trig_enable_ and secondALCT.isValid());
0461
0462 const bool secondCase2(clct_trig_enable_ and secondCLCT.isValid());
0463
0464
0465
0466
0467
0468
0469
0470
0471 const bool secondCase3(match_trig_enable_ and secondALCT.isValid() and secondCLCT.isValid() and
0472 doesALCTCrossCLCT(secondALCT, secondCLCT));
0473
0474
0475 if ((secondALCT != bestALCT) or (secondCLCT != bestCLCT)) {
0476
0477 if (secondCase1 or secondCase2 or secondCase3)
0478 constructLCTs(secondALCT, secondCLCT, type, 2, sLCT);
0479 }
0480 }
0481
0482
0483 void CSCMotherboard::copyValidToInValidALCT(CSCALCTDigi& bestALCT, CSCALCTDigi& secondALCT) const {
0484 if (bestALCT.isValid() and !secondALCT.isValid())
0485 secondALCT = bestALCT;
0486 }
0487
0488
0489 void CSCMotherboard::copyValidToInValidCLCT(CSCCLCTDigi& bestCLCT, CSCCLCTDigi& secondCLCT) const {
0490 if (bestCLCT.isValid() and !secondCLCT.isValid())
0491 secondCLCT = bestCLCT;
0492 }
0493
0494 bool CSCMotherboard::doesALCTCrossCLCT(const CSCALCTDigi& alct, const CSCCLCTDigi& clct) const {
0495 if (ignoreAlctCrossClct_)
0496 return true;
0497 else
0498 return cscOverlap_->doesALCTCrossCLCT(alct, clct);
0499 }
0500
0501
0502
0503 void CSCMotherboard::constructLCTs(
0504 const CSCALCTDigi& aLCT, const CSCCLCTDigi& cLCT, int type, int trknmb, CSCCorrelatedLCTDigi& thisLCT) const {
0505 thisLCT.setValid(true);
0506 thisLCT.setType(type);
0507
0508 thisLCT.setALCT(getBXShiftedALCT(aLCT));
0509 thisLCT.setCLCT(getBXShiftedCLCT(cLCT));
0510 thisLCT.setPattern(encodePattern(cLCT.getPattern()));
0511 thisLCT.setMPCLink(0);
0512 thisLCT.setBX0(0);
0513 thisLCT.setSyncErr(0);
0514 thisLCT.setCSCID(theTrigChamber);
0515 thisLCT.setTrknmb(trknmb);
0516 thisLCT.setWireGroup(aLCT.getKeyWG());
0517 thisLCT.setStrip(cLCT.getKeyStrip());
0518 thisLCT.setBend(cLCT.getBend());
0519
0520 int bx = aLCT.isValid() ? aLCT.getBX() : cLCT.getBX();
0521 thisLCT.setBX(bx);
0522 thisLCT.setQuality(qualityAssignment_->findQuality(aLCT, cLCT));
0523 if (runCCLUT_) {
0524 thisLCT.setRun3(true);
0525
0526 thisLCT.setSlope(cLCT.getSlope());
0527 thisLCT.setQuartStripBit(cLCT.getQuartStripBit());
0528 thisLCT.setEighthStripBit(cLCT.getEighthStripBit());
0529 thisLCT.setRun3Pattern(cLCT.getRun3Pattern());
0530 }
0531 }
0532
0533
0534 unsigned int CSCMotherboard::encodePattern(const int ptn) const {
0535 const int kPatternBitWidth = 4;
0536
0537
0538 unsigned int pattern = (abs(ptn) & ((1 << kPatternBitWidth) - 1));
0539
0540 return pattern;
0541 }
0542
0543 void CSCMotherboard::selectLCTs() {
0544
0545 for (int bx = 0; bx < CSCConstants::MAX_LCT_TBINS; bx++) {
0546 unsigned nLCTs = 0;
0547
0548 std::vector<CSCCorrelatedLCTDigi> tempV;
0549
0550 for (unsigned int mbx = 0; mbx < match_trig_window_size_; mbx++) {
0551
0552 for (int i = 0; i < CSCConstants::MAX_LCTS_PER_CSC; i++) {
0553 if (allLCTs_(bx, mbx, i).isValid() and nLCTs < 2) {
0554 tempV.push_back(allLCTs_(bx, mbx, i));
0555 ++nLCTs;
0556 }
0557 }
0558 }
0559
0560 for (const auto& lct : tempV) {
0561 lctV.push_back(lct);
0562 }
0563 }
0564
0565
0566 if (infoV > 0) {
0567 for (const auto& lct : lctV) {
0568 LogDebug("CSCMotherboard") << "Selected LCT" << lct;
0569 }
0570 }
0571 }
0572
0573 void CSCMotherboard::sortCLCTByQualBend(int bx_alct, std::vector<unsigned>& clctBxVector) {
0574
0575
0576
0577 clctBxVector.clear();
0578 int clctQualBendArray[CSCConstants::MAX_CLCT_TBINS + 1] = {0};
0579 for (unsigned mbx = 0; mbx < match_trig_window_size_; mbx++) {
0580 unsigned bx_clct = bx_alct + preferred_bx_match_[mbx] - CSCConstants::ALCT_CLCT_OFFSET;
0581 int tempQualBend = 0;
0582 if (bx_clct >= CSCConstants::MAX_CLCT_TBINS)
0583 continue;
0584 if (!clctProc->getBestCLCT(bx_clct).isValid()) {
0585 clctQualBendArray[bx_clct] = tempQualBend;
0586 continue;
0587 }
0588 CSCCLCTDigi bestCLCT = clctProc->getBestCLCT(bx_clct);
0589
0590
0591 int clctBend = bestCLCT.isRun3() ? (16 - bestCLCT.getSlope()) : (bestCLCT.getPattern() & 0xe);
0592
0593 int clctQualBend = clctBend | (bestCLCT.getQuality() << 5);
0594 clctQualBendArray[bx_clct] = clctQualBend;
0595 if (clctBxVector.empty())
0596 clctBxVector.push_back(bx_clct);
0597 else {
0598 for (auto it = clctBxVector.begin(); it != clctBxVector.end(); it++)
0599 if (clctQualBend > clctQualBendArray[*it]) {
0600 clctBxVector.insert(it, bx_clct);
0601 break;
0602 }
0603 }
0604 }
0605
0606 for (unsigned bx = clctBxVector.size(); bx < match_trig_window_size_; bx++)
0607 clctBxVector.push_back(CSCConstants::MAX_CLCT_TBINS);
0608 }
0609
0610 void CSCMotherboard::checkConfigParameters() {
0611
0612
0613
0614 static constexpr unsigned int max_mpc_block_me1a = 1 << 1;
0615 static constexpr unsigned int max_alct_trig_enable = 1 << 1;
0616 static constexpr unsigned int max_clct_trig_enable = 1 << 1;
0617 static constexpr unsigned int max_match_trig_enable = 1 << 1;
0618 static constexpr unsigned int max_match_trig_window_size = 1 << 4;
0619 static constexpr unsigned int max_tmb_l1a_window_size = 1 << 4;
0620
0621
0622 CSCBaseboard::checkConfigParameters(mpc_block_me1a_, max_mpc_block_me1a, def_mpc_block_me1a, "mpc_block_me1a");
0623 CSCBaseboard::checkConfigParameters(
0624 alct_trig_enable_, max_alct_trig_enable, def_alct_trig_enable, "alct_trig_enable");
0625 CSCBaseboard::checkConfigParameters(
0626 clct_trig_enable_, max_clct_trig_enable, def_clct_trig_enable, "clct_trig_enable");
0627 CSCBaseboard::checkConfigParameters(
0628 match_trig_enable_, max_match_trig_enable, def_match_trig_enable, "match_trig_enable");
0629 CSCBaseboard::checkConfigParameters(
0630 match_trig_window_size_, max_match_trig_window_size, def_match_trig_window_size, "match_trig_window_size");
0631 CSCBaseboard::checkConfigParameters(
0632 tmb_l1a_window_size_, max_tmb_l1a_window_size, def_tmb_l1a_window_size, "tmb_l1a_window_size");
0633 assert(tmb_l1a_window_size_ / 2 <= CSCConstants::LCT_CENTRAL_BX);
0634 }
0635
0636 void CSCMotherboard::dumpConfigParams() const {
0637 std::ostringstream strm;
0638 strm << "\n";
0639 strm << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
0640 strm << "+ TMB configuration parameters: +\n";
0641 strm << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
0642 strm << " mpc_block_me1a [block/not block triggers which come from ME1/A] = " << mpc_block_me1a_ << "\n";
0643 strm << " alct_trig_enable [allow ALCT-only triggers] = " << alct_trig_enable_ << "\n";
0644 strm << " clct_trig_enable [allow CLCT-only triggers] = " << clct_trig_enable_ << "\n";
0645 strm << " match_trig_enable [allow matched ALCT-CLCT triggers] = " << match_trig_enable_ << "\n";
0646 strm << " match_trig_window_size [ALCT-CLCT match window width, in 25 ns] = " << match_trig_window_size_ << "\n";
0647 strm << " tmb_l1a_window_size [L1Accept window width, in 25 ns bins] = " << tmb_l1a_window_size_ << "\n";
0648 strm << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
0649 LogDebug("CSCMotherboard") << strm.str();
0650 }
0651
0652 CSCALCTDigi CSCMotherboard::getBXShiftedALCT(const CSCALCTDigi& aLCT) const {
0653 CSCALCTDigi aLCT_shifted = aLCT;
0654 aLCT_shifted.setBX(aLCT_shifted.getBX() - (CSCConstants::LCT_CENTRAL_BX - CSCConstants::ALCT_CENTRAL_BX));
0655 return aLCT_shifted;
0656 }
0657
0658 CSCCLCTDigi CSCMotherboard::getBXShiftedCLCT(const CSCCLCTDigi& cLCT) const {
0659 CSCCLCTDigi cLCT_shifted = cLCT;
0660 cLCT_shifted.setBX(cLCT_shifted.getBX() - CSCConstants::ALCT_CLCT_OFFSET);
0661 return cLCT_shifted;
0662 }
0663
0664 void CSCMotherboard::matchShowers(CSCShowerDigi* anode_showers, CSCShowerDigi* cathode_showers, bool andlogic) {
0665 CSCShowerDigi ashower, cshower;
0666 bool used_cshower_mask[CSCConstants::MAX_CLCT_TBINS] = {false};
0667 for (unsigned bx = 0; bx < CSCConstants::MAX_ALCT_TBINS; bx++) {
0668 ashower = anode_showers[bx];
0669 cshower = CSCShowerDigi();
0670 if (ashower.isValid()) {
0671 for (unsigned mbx = 0; mbx < match_trig_window_size_; mbx++) {
0672 int cbx = bx + preferred_bx_match_[mbx] - CSCConstants::ALCT_CLCT_OFFSET;
0673
0674 if (cbx < 0 || cbx >= CSCConstants::MAX_CLCT_TBINS)
0675 continue;
0676 if (cathode_showers[cbx].isValid() and not used_cshower_mask[cbx]) {
0677 cshower = cathode_showers[cbx];
0678 used_cshower_mask[cbx] = true;
0679 break;
0680 }
0681 }
0682 } else
0683 cshower = cathode_showers[bx];
0684
0685
0686 unsigned matchHMT = 0;
0687 if (andlogic) {
0688 if (ashower.isTightInTime() and cshower.isTightInTime())
0689 matchHMT = 3;
0690 else if (ashower.isNominalInTime() and cshower.isNominalInTime())
0691 matchHMT = 2;
0692 else if (ashower.isLooseInTime() and cshower.isLooseInTime())
0693 matchHMT = 1;
0694 } else {
0695 if (ashower.isTightInTime() or cshower.isTightInTime())
0696 matchHMT = 3;
0697 else if (ashower.isNominalInTime() or cshower.isNominalInTime())
0698 matchHMT = 2;
0699 else if (ashower.isLooseInTime() or cshower.isLooseInTime())
0700 matchHMT = 1;
0701 }
0702
0703 showers_[bx] = CSCShowerDigi(matchHMT & 3,
0704 false,
0705 ashower.getCSCID(),
0706 bx,
0707 CSCShowerDigi::ShowerType::kLCTShower,
0708 ashower.getWireNHits(),
0709 cshower.getComparatorNHits());
0710 }
0711 }
0712
0713 void CSCMotherboard::encodeHighMultiplicityBits() {
0714
0715
0716 CSCShowerDigi cathode_showers[CSCConstants::MAX_CLCT_TBINS];
0717 CSCShowerDigi anode_showers[CSCConstants::MAX_ALCT_TBINS];
0718 auto cshowers_v = clctProc->getAllShower();
0719 auto ashowers_v = alctProc->getAllShower();
0720
0721 std::copy(cshowers_v.begin(), cshowers_v.end(), cathode_showers);
0722 std::copy(ashowers_v.begin(), ashowers_v.end(), anode_showers);
0723
0724
0725 switch (thisShowerSource_) {
0726 case 0:
0727 std::copy(std::begin(cathode_showers), std::end(cathode_showers), std::begin(showers_));
0728 break;
0729 case 1:
0730 std::copy(std::begin(anode_showers), std::end(anode_showers), std::begin(showers_));
0731 break;
0732 case 2:
0733 matchShowers(anode_showers, cathode_showers, false);
0734 break;
0735 case 3:
0736 matchShowers(anode_showers, cathode_showers, true);
0737 break;
0738 default:
0739 std::copy(std::begin(anode_showers), std::end(anode_showers), std::begin(showers_));
0740 break;
0741 };
0742 }