CMS 3D CMS Logo

CSCMotherboard.cc
Go to the documentation of this file.
2 #include <iostream>
3 #include <memory>
4 
5 // Default values of configuration parameters.
6 const unsigned int CSCMotherboard::def_mpc_block_me1a = 1;
7 const unsigned int CSCMotherboard::def_alct_trig_enable = 0;
8 const unsigned int CSCMotherboard::def_clct_trig_enable = 0;
9 const unsigned int CSCMotherboard::def_match_trig_enable = 1;
10 const unsigned int CSCMotherboard::def_match_trig_window_size = 7;
11 const unsigned int CSCMotherboard::def_tmb_l1a_window_size = 7;
12 
14  unsigned station,
15  unsigned sector,
16  unsigned subsector,
17  unsigned chamber,
18  const edm::ParameterSet& conf)
19  : CSCBaseboard(endcap, station, sector, subsector, chamber, conf) {
20  // Normal constructor. -JM
21  // Pass ALCT, CLCT, and common parameters on to ALCT and CLCT processors.
22  static std::atomic<bool> config_dumped{false};
23 
24  mpc_block_me1a = tmbParams_.getParameter<unsigned int>("mpcBlockMe1a");
25  alct_trig_enable = tmbParams_.getParameter<unsigned int>("alctTrigEnable");
26  clct_trig_enable = tmbParams_.getParameter<unsigned int>("clctTrigEnable");
27  match_trig_enable = tmbParams_.getParameter<unsigned int>("matchTrigEnable");
28  match_trig_window_size = tmbParams_.getParameter<unsigned int>("matchTrigWindowSize");
29  tmb_l1a_window_size = // Common to CLCT and TMB
30  tmbParams_.getParameter<unsigned int>("tmbL1aWindowSize");
31 
32  // configuration handle for number of early time bins
33  early_tbins = tmbParams_.getParameter<int>("tmbEarlyTbins");
34 
35  // whether to not reuse CLCTs that were used by previous matching ALCTs
36  drop_used_clcts = tmbParams_.getParameter<bool>("tmbDropUsedClcts");
37 
38  // whether to readout only the earliest two LCTs in readout window
39  readout_earliest_2 = tmbParams_.getParameter<bool>("tmbReadoutEarliest2");
40 
41  match_earliest_clct_only_ = tmbParams_.getParameter<bool>("matchEarliestClctOnly");
42 
43  infoV = tmbParams_.getParameter<int>("verbosity");
44 
45  alctProc = std::make_unique<CSCAnodeLCTProcessor>(endcap, station, sector, subsector, chamber, conf);
46  clctProc = std::make_unique<CSCCathodeLCTProcessor>(endcap, station, sector, subsector, chamber, conf);
47 
48  // Check and print configuration parameters.
50  if (infoV > 0 && !config_dumped) {
52  config_dumped = true;
53  }
54 
56 
57  // get the preferred CLCT BX match array
58  preferred_bx_match_ = tmbParams_.getParameter<std::vector<int>>("preferredBxMatch");
59 
60  // quality assignment
61  qualityAssignment_ = std::make_unique<LCTQualityAssignment>(endcap, station, sector, subsector, chamber, conf);
62 
63  // quality control of stubs
64  qualityControl_ = std::make_unique<LCTQualityControl>(endcap, station, sector, subsector, chamber, conf);
65 
66  // shower-trigger source
67  showerSource_ = showerParams_.getParameter<std::vector<unsigned>>("source");
68 
69  unsigned csc_idx = CSCDetId::iChamberType(theStation, theRing) - 2;
71 
72  // shower readout window
76 
77  // enable the upgrade processors for ring 1 stations
78  if (runPhase2_ and theRing == 1) {
79  clctProc = std::make_unique<CSCUpgradeCathodeLCTProcessor>(endcap, station, sector, subsector, chamber, conf);
80  if (enableAlctPhase2_) {
81  alctProc = std::make_unique<CSCUpgradeAnodeLCTProcessor>(endcap, station, sector, subsector, chamber, conf);
82  }
83  }
84 
85  // set up helper class to check if ALCT and CLCT cross
86  ignoreAlctCrossClct_ = tmbParams_.getParameter<bool>("ignoreAlctCrossClct");
87  if (!ignoreAlctCrossClct_) {
88  cscOverlap_ = std::make_unique<CSCALCTCrossCLCT>(endcap, station, theRing, ignoreAlctCrossClct_, conf);
89  }
90 }
91 
93  // clear the processors
94  if (alctProc)
95  alctProc->clear();
96  if (clctProc)
97  clctProc->clear();
98 
99  // clear the ALCT and CLCT containers
100  alctV.clear();
101  clctV.clear();
102  lctV.clear();
103 
104  allLCTs_.clear();
105 
106  for (int bx = 0; bx < CSCConstants::MAX_LCT_TBINS; bx++) {
107  showers_[bx].clear();
108  }
109 }
110 
111 // Set configuration parameters obtained via EventSetup mechanism.
113  static std::atomic<bool> config_dumped{false};
114 
115  // Config. parameters for the TMB itself.
122 
123  // Config. paramteres for ALCT and CLCT processors.
124  alctProc->setConfigParameters(conf);
125  clctProc->setConfigParameters(conf);
126 
127  // Check and print configuration parameters.
129  if (!config_dumped) {
131  config_dumped = true;
132  }
135 }
136 
138 
140 
142 
144  // Step 1: Setup
145  clear();
146 
147  // Check for existing processors
148  if (!(alctProc && clctProc)) {
149  edm::LogError("CSCMotherboard|SetupError") << "+++ run() called for non-existing ALCT/CLCT processor! +++ \n";
150  return;
151  }
152 
153  // set geometry
154  alctProc->setCSCGeometry(cscGeometry_);
155  clctProc->setCSCGeometry(cscGeometry_);
156 
157  // set CCLUT parameters if necessary
158  if (runCCLUT_) {
159  clctProc->setESLookupTables(lookupTableCCLUT_);
160  }
161 
162  // Step 2: Run the processors
163  alctV = alctProc->run(wiredc); // run anodeLCT
164  clctV = clctProc->run(compdc); // run cathodeLCT
165 
166  // Step 2b: encode high multiplicity bits (independent of LCT construction)
168 
169  // if there are no ALCTs and no CLCTs, it does not make sense to run this TMB
170  if (alctV.empty() and clctV.empty())
171  return;
172 
173  // step 3: match the ALCTs to the CLCTs
174  matchALCTCLCT();
175 
176  // Step 4: Select at most 2 LCTs per BX
177  selectLCTs();
178 }
179 
181  // array to mask CLCTs
182  bool used_clct_mask[CSCConstants::MAX_CLCT_TBINS] = {false};
183 
184  // Step 3: ALCT-centric ALCT-to-CLCT matching
185  int bx_clct_matched = 0; // bx of last matched CLCT
186  for (int bx_alct = 0; bx_alct < CSCConstants::MAX_ALCT_TBINS; bx_alct++) {
187  // There should be at least one valid CLCT or ALCT for a
188  // correlated LCT to be formed. Decision on whether to reject
189  // non-complete LCTs (and if yes of which type) is made further
190  // upstream.
191  if (alctProc->getBestALCT(bx_alct).isValid()) {
192  // Look for CLCTs within the match-time window. The window is
193  // centered at the ALCT bx; therefore, we make an assumption
194  // that anode and cathode hits are perfectly synchronized. This
195  // is always true for MC, but only an approximation when the
196  // data is analyzed (which works fairly good as long as wide
197  // windows are used). To get rid of this assumption, one would
198  // need to access "full BX" words, which are not readily
199  // available.
200  bool is_matched = false;
201  // loop on the preferred "delta BX" array
202  for (unsigned mbx = 0; mbx < match_trig_window_size; mbx++) {
203  // evaluate the preffered CLCT BX, taking into account that there is an offset in the simulation
204  int bx_clct = bx_alct + preferred_bx_match_[mbx] - CSCConstants::ALCT_CLCT_OFFSET;
205  // check that the CLCT BX is valid
206  if (bx_clct >= CSCConstants::MAX_CLCT_TBINS or bx_clct < 0)
207  continue;
208  // do not consider previously matched CLCTs
209  if (drop_used_clcts && used_clct_mask[bx_clct])
210  continue;
211  // only consider >=4 layer CLCTs for ALCT-CLCT type LCTs
212  // this condition is lowered to >=3 layers for CLCTs in the
213  // matchALCTCLCTGEM function
214  if (clctProc->getBestCLCT(bx_clct).getQuality() <= 3)
215  continue;
216  // a valid CLCT with sufficient layers!
217  if (clctProc->getBestCLCT(bx_clct).isValid()) {
218  if (infoV > 1)
219  LogTrace("CSCMotherboard") << "Successful ALCT-CLCT match: bx_alct = " << bx_alct
220  << "; bx_clct = " << bx_clct << "; mbx = " << mbx;
221  // now correlate the ALCT and CLCT into LCT.
222  // smaller mbx means more preferred!
223  correlateLCTs(alctProc->getBestALCT(bx_alct),
224  alctProc->getSecondALCT(bx_alct),
225  clctProc->getBestCLCT(bx_clct),
226  clctProc->getSecondCLCT(bx_clct),
227  allLCTs_(bx_alct, mbx, 0),
228  allLCTs_(bx_alct, mbx, 1),
230  // when the first LCT is valid, you can mask the matched CLCT and/or
231  // move on to the next ALCT if match_earliest_clct_only_ is set to true
232  if (allLCTs_(bx_alct, mbx, 0).isValid()) {
233  is_matched = true;
234  used_clct_mask[bx_clct] = true;
235  bx_clct_matched = bx_clct;
237  break;
238  }
239  }
240  }
241  // No CLCT within the match time interval found: report ALCT-only LCT
242  // (use dummy CLCTs).
243  if (!is_matched) {
244  if (infoV > 1)
245  LogTrace("CSCMotherboard") << "Unsuccessful ALCT-CLCT match (ALCT only): bx_alct = " << bx_alct
246  << " first ALCT " << alctProc->getBestALCT(bx_alct);
247  if (alct_trig_enable)
248  correlateLCTs(alctProc->getBestALCT(bx_alct),
249  alctProc->getSecondALCT(bx_alct),
250  clctProc->getBestCLCT(bx_alct),
251  clctProc->getSecondCLCT(bx_alct),
252  allLCTs_(bx_alct, 0, 0),
253  allLCTs_(bx_alct, 0, 1),
255  }
256  }
257  // No valid ALCTs; attempt to make CLCT-only LCT. Use only CLCTs
258  // which have zeroth chance to be matched at later cathode times.
259  // (I am not entirely sure this perfectly matches the firmware logic.)
260  // Use dummy ALCTs.
261  else {
262  int bx_clct = bx_alct - match_trig_window_size / 2;
263  if (bx_clct >= 0 && bx_clct > bx_clct_matched) {
264  if (clctProc->getBestCLCT(bx_clct).isValid() and clct_trig_enable) {
265  if (infoV > 1)
266  LogTrace("CSCMotherboard") << "Unsuccessful ALCT-CLCT match (CLCT only): bx_clct = " << bx_clct;
267  correlateLCTs(alctProc->getBestALCT(bx_alct),
268  alctProc->getSecondALCT(bx_alct),
269  clctProc->getBestCLCT(bx_clct),
270  clctProc->getSecondCLCT(bx_clct),
271  allLCTs_(bx_clct, 0, 0),
272  allLCTs_(bx_clct, 0, 1),
274  }
275  }
276  }
277  }
278 }
279 
280 // Returns vector of read-out correlated LCTs, if any. Starts with
281 // the vector of all found LCTs and selects the ones in the read-out
282 // time window.
283 std::vector<CSCCorrelatedLCTDigi> CSCMotherboard::readoutLCTs() const {
284  // temporary container for further selection
285  std::vector<CSCCorrelatedLCTDigi> tmpV;
286 
287  /*
288  LCTs in the BX window [early_tbin,...,late_tbin] are considered good for physics
289  The central LCT BX is time bin 8.
290  For tmb_l1a_window_size set to 7 (Run-1, Run-2), the window is [5, 6, 7, 8, 9, 10, 11]
291  For tmb_l1a_window_size set to 5 (Run-3), the window is [6, 7, 8, 9, 10]
292  For tmb_l1a_window_size set to 3 (Run-4?), the window is [ 7, 8, 9]
293  */
294  const unsigned delta_tbin = tmb_l1a_window_size / 2;
295  int early_tbin = CSCConstants::LCT_CENTRAL_BX - delta_tbin;
296  int late_tbin = CSCConstants::LCT_CENTRAL_BX + delta_tbin;
297  /*
298  Special case for an even-numbered time-window,
299  For instance tmb_l1a_window_size set to 6: [5, 6, 7, 8, 9, 10]
300  */
301  if (tmb_l1a_window_size % 2 == 0)
302  late_tbin = CSCConstants::LCT_CENTRAL_BX + delta_tbin - 1;
303  const int max_late_tbin = CSCConstants::MAX_LCT_TBINS - 1;
304 
305  // debugging messages when early_tbin or late_tbin has a suspicious value
306  if (early_tbin < 0) {
307  edm::LogWarning("CSCMotherboard|SuspiciousParameters")
308  << "Early time bin (early_tbin) smaller than minimum allowed, which is 0. set early_tbin to 0.";
309  early_tbin = 0;
310  }
311  if (late_tbin > max_late_tbin) {
312  edm::LogWarning("CSCMotherboard|SuspiciousParameters")
313  << "Late time bin (late_tbin) larger than maximum allowed, which is " << max_late_tbin
314  << ". set early_tbin to max allowed";
315  late_tbin = CSCConstants::MAX_LCT_TBINS - 1;
316  }
317 
318  // Start from the vector of all found correlated LCTs and select
319  // those within the LCT*L1A coincidence window.
320  int bx_readout = -1;
321  for (const auto& lct : lctV) {
322  // extra check on invalid LCTs
323  if (!lct.isValid()) {
324  continue;
325  }
326 
327  const int bx = lct.getBX();
328  // Skip LCTs found too early relative to L1Accept.
329  if (bx < early_tbin) {
330  if (infoV > 1)
331  LogDebug("CSCMotherboard") << " Do not report correlated LCT on key halfstrip " << lct.getStrip()
332  << " and key wire " << lct.getKeyWG() << ": found at bx " << bx
333  << ", whereas the earliest allowed bx is " << early_tbin;
334  continue;
335  }
336 
337  // Skip LCTs found too late relative to L1Accept.
338  if (bx > late_tbin) {
339  if (infoV > 1)
340  LogDebug("CSCMotherboard") << " Do not report correlated LCT on key halfstrip " << lct.getStrip()
341  << " and key wire " << lct.getKeyWG() << ": found at bx " << bx
342  << ", whereas the latest allowed bx is " << late_tbin;
343  continue;
344  }
345 
346  // Do not report LCTs found in ME1/A if mpc_block_me1a is set.
347  if (mpc_block_me1a and isME11_ and lct.getStrip() > CSCConstants::MAX_HALF_STRIP_ME1B) {
348  continue;
349  }
350 
351  // If (readout_earliest_2) take only LCTs in the earliest bx in the read-out window:
352  // in digi->raw step, LCTs have to be packed into the TMB header, and
353  // currently there is room just for two.
354  if (readout_earliest_2) {
355  if (bx_readout == -1 || bx == bx_readout) {
356  tmpV.push_back(lct);
357  if (bx_readout == -1)
358  bx_readout = bx;
359  }
360  }
361  // if readout_earliest_2 == false, save all LCTs
362  else {
363  tmpV.push_back(lct);
364  }
365  }
366 
367  // do a final check on the LCTs in readout
368  qualityControl_->checkMultiplicityBX(tmpV);
369  for (const auto& lct : tmpV) {
370  qualityControl_->checkValid(lct);
371  /*std::cout << "\n########################################## Emu LCT ##########################################\n" << std::endl;
372  std::cout << "Emu LCT: " << lct << std::endl;
373  std::cout << "\n########################################## THE END ##########################################\n" << std::endl;*/
374  }
375 
376  return tmpV;
377 }
378 
379 std::vector<CSCShowerDigi> CSCMotherboard::readoutShower() const {
380  unsigned minBXdiff = 2 * tmb_l1a_window_size; //impossible value
381  unsigned minBX = 0;
382  std::vector<CSCShowerDigi> showerOut;
383  for (unsigned bx = minbx_readout_; bx < maxbx_readout_; bx++) {
386  if (showers_[bx].isValid() and bx_diff < minBXdiff) {
387  minBXdiff = bx_diff;
388  minBX = bx;
389  }
390  }
391 
392  for (unsigned bx = minbx_readout_; bx < maxbx_readout_; bx++)
393  if (bx == minBX)
394  showerOut.push_back(showers_[bx]);
395  return showerOut;
396 }
397 
399  const CSCALCTDigi& sALCT,
400  const CSCCLCTDigi& bCLCT,
401  const CSCCLCTDigi& sCLCT,
402  CSCCorrelatedLCTDigi& bLCT,
403  CSCCorrelatedLCTDigi& sLCT,
404  int type) const {
405  CSCALCTDigi bestALCT = bALCT;
406  CSCALCTDigi secondALCT = sALCT;
407  CSCCLCTDigi bestCLCT = bCLCT;
408  CSCCLCTDigi secondCLCT = sCLCT;
409 
410  // extra check to make sure that both CLCTs have at least 4 layers
411  // for regular ALCT-CLCT type LCTs. A check was already done on the
412  // best CLCT, but not yet on the second best CLCT. The check on best
413  // CLCT is repeated for completeness
414  if (bestCLCT.getQuality() <= 3)
415  bestCLCT.clear();
416  if (secondCLCT.getQuality() <= 3)
417  secondCLCT.clear();
418 
419  // if the best ALCT/CLCT is valid, but the second ALCT/CLCT is not,
420  // the information is copied over
421  copyValidToInValidALCT(bestALCT, secondALCT);
422  copyValidToInValidCLCT(bestCLCT, secondCLCT);
423 
424  // ALCT-only LCTs
425  const bool bestCase1(alct_trig_enable and bestALCT.isValid());
426  // CLCT-only LCTs
427  const bool bestCase2(clct_trig_enable and bestCLCT.isValid());
428  /*
429  Normal case: ALCT-CLCT matched LCTs. We require ALCT and CLCT to be valid.
430  Optionally, we can check if the ALCT cross the CLCT. This check will always return true
431  for a valid ALCT-CLCT pair in non-ME1/1 chambers. For ME1/1 chambers, it returns true,
432  only when the ALCT-CLCT pair crosses and when the parameter "checkAlctCrossClct" is set to True.
433  It is recommended to keep "checkAlctCrossClct" set to False, so that the EMTF receives
434  all information, even if it's unphysical.
435  */
436  const bool bestCase3(match_trig_enable and bestALCT.isValid() and bestCLCT.isValid() and
437  doesALCTCrossCLCT(bestALCT, bestCLCT));
438 
439  // at least one of the cases must be valid
440  if (bestCase1 or bestCase2 or bestCase3) {
441  constructLCTs(bestALCT, bestCLCT, type, 1, bLCT);
442  }
443 
444  // ALCT-only LCTs
445  const bool secondCase1(alct_trig_enable and secondALCT.isValid());
446  // CLCT-only LCTs
447  const bool secondCase2(clct_trig_enable and secondCLCT.isValid());
448  /*
449  Normal case: ALCT-CLCT matched LCTs. We require ALCT and CLCT to be valid.
450  Optionally, we can check if the ALCT cross the CLCT. This check will always return true
451  for a valid ALCT-CLCT pair in non-ME1/1 chambers. For ME1/1 chambers, it returns true,
452  only when the ALCT-CLCT pair crosses and when the parameter "checkAlctCrossClct" is set to True.
453  It is recommended to keep "checkAlctCrossClct" set to False, so that the EMTF receives
454  all information, even if it's unphysical.
455  */
456  const bool secondCase3(match_trig_enable and secondALCT.isValid() and secondCLCT.isValid() and
457  doesALCTCrossCLCT(secondALCT, secondCLCT));
458 
459  // at least one component must be different in order to consider the secondLCT
460  if ((secondALCT != bestALCT) or (secondCLCT != bestCLCT)) {
461  // at least one of the cases must be valid
462  if (secondCase1 or secondCase2 or secondCase3)
463  constructLCTs(secondALCT, secondCLCT, type, 2, sLCT);
464  }
465 }
466 
467 // copy the valid ALCT/CLCT information to the valid ALCT
469  if (bestALCT.isValid() and !secondALCT.isValid())
470  secondALCT = bestALCT;
471 }
472 
473 // copy the valid CLCT information to the valid CLCT
475  if (bestCLCT.isValid() and !secondCLCT.isValid())
476  secondCLCT = bestCLCT;
477 }
478 
479 bool CSCMotherboard::doesALCTCrossCLCT(const CSCALCTDigi& alct, const CSCCLCTDigi& clct) const {
481  return true;
482  else
483  return cscOverlap_->doesALCTCrossCLCT(alct, clct);
484 }
485 
486 // This method calculates all the TMB words and then passes them to the
487 // constructor of correlated LCTs.
489  const CSCALCTDigi& aLCT, const CSCCLCTDigi& cLCT, int type, int trknmb, CSCCorrelatedLCTDigi& thisLCT) const {
490  thisLCT.setValid(true);
491  thisLCT.setType(type);
492  // make sure to shift the ALCT BX from 8 to 3 and the CLCT BX from 8 to 7!
493  thisLCT.setALCT(getBXShiftedALCT(aLCT));
494  thisLCT.setCLCT(getBXShiftedCLCT(cLCT));
495  thisLCT.setPattern(encodePattern(cLCT.getPattern()));
496  thisLCT.setMPCLink(0);
497  thisLCT.setBX0(0);
498  thisLCT.setSyncErr(0);
499  thisLCT.setCSCID(theTrigChamber);
500  thisLCT.setTrknmb(trknmb);
501  thisLCT.setWireGroup(aLCT.getKeyWG());
502  thisLCT.setStrip(cLCT.getKeyStrip());
503  thisLCT.setBend(cLCT.getBend());
504  // Bunch crossing: get it from cathode LCT if anode LCT is not there.
505  int bx = aLCT.isValid() ? aLCT.getBX() : cLCT.getBX();
506  thisLCT.setBX(bx);
507  thisLCT.setQuality(qualityAssignment_->findQuality(aLCT, cLCT));
508  if (runCCLUT_) {
509  thisLCT.setRun3(true);
510  // 4-bit slope value derived with the CCLUT algorithm
511  thisLCT.setSlope(cLCT.getSlope());
512  thisLCT.setQuartStripBit(cLCT.getQuartStripBit());
513  thisLCT.setEighthStripBit(cLCT.getEighthStripBit());
514  thisLCT.setRun3Pattern(cLCT.getRun3Pattern());
515  }
516 }
517 
518 // CLCT pattern number: encodes the pattern number itself
519 unsigned int CSCMotherboard::encodePattern(const int ptn) const {
520  const int kPatternBitWidth = 4;
521 
522  // In the TMB07 firmware, LCT pattern is just a 4-bit CLCT pattern.
523  unsigned int pattern = (abs(ptn) & ((1 << kPatternBitWidth) - 1));
524 
525  return pattern;
526 }
527 
529  // in each of the LCT time bins
530  for (int bx = 0; bx < CSCConstants::MAX_LCT_TBINS; bx++) {
531  unsigned nLCTs = 0;
532 
533  std::vector<CSCCorrelatedLCTDigi> tempV;
534  // check each of the preferred combinations
535  for (unsigned int mbx = 0; mbx < match_trig_window_size; mbx++) {
536  // select at most 2
537  for (int i = 0; i < CSCConstants::MAX_LCTS_PER_CSC; i++) {
538  if (allLCTs_(bx, mbx, i).isValid() and nLCTs < 2) {
539  tempV.push_back(allLCTs_(bx, mbx, i));
540  ++nLCTs;
541  }
542  }
543  }
544  // store the best 2
545  for (const auto& lct : tempV) {
546  lctV.push_back(lct);
547  }
548  }
549 
550  // Show the pre-selected LCTs. They're not final yet. Some selection is done in the readoutLCTs function
551  if (infoV > 0) {
552  for (const auto& lct : lctV) {
553  LogDebug("CSCMotherboard") << "Selected LCT" << lct;
554  }
555  }
556 }
557 
559  // Make sure that the parameter values are within the allowed range.
560 
561  // Max expected values.
562  static const unsigned int max_mpc_block_me1a = 1 << 1;
563  static const unsigned int max_alct_trig_enable = 1 << 1;
564  static const unsigned int max_clct_trig_enable = 1 << 1;
565  static const unsigned int max_match_trig_enable = 1 << 1;
566  static const unsigned int max_match_trig_window_size = 1 << 4;
567  static const unsigned int max_tmb_l1a_window_size = 1 << 4;
568 
569  // Checks.
570  CSCBaseboard::checkConfigParameters(mpc_block_me1a, max_mpc_block_me1a, def_mpc_block_me1a, "mpc_block_me1a");
571  CSCBaseboard::checkConfigParameters(alct_trig_enable, max_alct_trig_enable, def_alct_trig_enable, "alct_trig_enable");
572  CSCBaseboard::checkConfigParameters(clct_trig_enable, max_clct_trig_enable, def_clct_trig_enable, "clct_trig_enable");
574  match_trig_enable, max_match_trig_enable, def_match_trig_enable, "match_trig_enable");
576  match_trig_window_size, max_match_trig_window_size, def_match_trig_window_size, "match_trig_window_size");
578  tmb_l1a_window_size, max_tmb_l1a_window_size, def_tmb_l1a_window_size, "tmb_l1a_window_size");
580 }
581 
583  std::ostringstream strm;
584  strm << "\n";
585  strm << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
586  strm << "+ TMB configuration parameters: +\n";
587  strm << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
588  strm << " mpc_block_me1a [block/not block triggers which come from ME1/A] = " << mpc_block_me1a << "\n";
589  strm << " alct_trig_enable [allow ALCT-only triggers] = " << alct_trig_enable << "\n";
590  strm << " clct_trig_enable [allow CLCT-only triggers] = " << clct_trig_enable << "\n";
591  strm << " match_trig_enable [allow matched ALCT-CLCT triggers] = " << match_trig_enable << "\n";
592  strm << " match_trig_window_size [ALCT-CLCT match window width, in 25 ns] = " << match_trig_window_size << "\n";
593  strm << " tmb_l1a_window_size [L1Accept window width, in 25 ns bins] = " << tmb_l1a_window_size << "\n";
594  strm << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
595  LogDebug("CSCMotherboard") << strm.str();
596 }
597 
599  CSCALCTDigi aLCT_shifted = aLCT;
600  aLCT_shifted.setBX(aLCT_shifted.getBX() - (CSCConstants::LCT_CENTRAL_BX - CSCConstants::ALCT_CENTRAL_BX));
601  return aLCT_shifted;
602 }
603 
605  CSCCLCTDigi cLCT_shifted = cLCT;
606  cLCT_shifted.setBX(cLCT_shifted.getBX() - CSCConstants::ALCT_CLCT_OFFSET);
607  return cLCT_shifted;
608 }
609 
610 void CSCMotherboard::matchShowers(CSCShowerDigi* anode_showers, CSCShowerDigi* cathode_showers, bool andlogic) {
611  CSCShowerDigi ashower, cshower;
612  bool used_cshower_mask[CSCConstants::MAX_CLCT_TBINS] = {false};
613  for (unsigned bx = 0; bx < CSCConstants::MAX_ALCT_TBINS; bx++) {
614  ashower = anode_showers[bx];
615  cshower = CSCShowerDigi(); //use empty shower digi to initialize cshower
616  if (ashower.isValid()) {
617  for (unsigned mbx = 0; mbx < match_trig_window_size; mbx++) {
619  //check bx range [0, CSCConstants::MAX_LCT_TBINS]
620  if (cbx < 0 || cbx >= CSCConstants::MAX_CLCT_TBINS)
621  continue;
622  if (cathode_showers[cbx].isValid() and not used_cshower_mask[cbx]) {
623  cshower = cathode_showers[cbx];
624  used_cshower_mask[cbx] = true;
625  break;
626  }
627  }
628  } else
629  cshower = cathode_showers[bx]; //if anode shower is not valid, use the cshower from this bx
630 
631  //matched HMT, with and/or logic
632  unsigned matchHMT = 0;
633  if (andlogic) {
634  if (ashower.isTightInTime() and cshower.isTightInTime())
635  matchHMT = 3;
636  else if (ashower.isNominalInTime() and cshower.isNominalInTime())
637  matchHMT = 2;
638  else if (ashower.isLooseInTime() and cshower.isLooseInTime())
639  matchHMT = 1;
640  } else {
641  if (ashower.isTightInTime() or cshower.isTightInTime())
642  matchHMT = 3;
643  else if (ashower.isNominalInTime() or cshower.isNominalInTime())
644  matchHMT = 2;
645  else if (ashower.isLooseInTime() or cshower.isLooseInTime())
646  matchHMT = 1;
647  }
648  //LCTShower with showerType = 3
649  showers_[bx] = CSCShowerDigi(matchHMT & 3,
650  false,
651  ashower.getCSCID(),
652  bx,
653  CSCShowerDigi::ShowerType::kLCTShower,
654  ashower.getWireNHits(),
655  cshower.getComparatorNHits());
656  }
657 }
658 
660  // get the high multiplicity
661  // for anode this reflects what is already in the anode CSCShowerDigi object
664  auto cshowers_v = clctProc->getAllShower();
665  auto ashowers_v = alctProc->getAllShower();
666 
667  std::copy(cshowers_v.begin(), cshowers_v.end(), cathode_showers);
668  std::copy(ashowers_v.begin(), ashowers_v.end(), anode_showers);
669 
670  // set the value according to source
671  switch (thisShowerSource_) {
672  case 0:
673  std::copy(std::begin(cathode_showers), std::end(cathode_showers), std::begin(showers_));
674  break;
675  case 1:
676  std::copy(std::begin(anode_showers), std::end(anode_showers), std::begin(showers_));
677  break;
678  case 2:
679  matchShowers(anode_showers, cathode_showers, false);
680  break;
681  case 3:
682  matchShowers(anode_showers, cathode_showers, true);
683  break;
684  default:
685  std::copy(std::begin(anode_showers), std::end(anode_showers), std::begin(showers_));
686  break;
687  };
688 }
bool isValid() const
check ALCT validity (1 - valid ALCT)
Definition: CSCALCTDigi.h:40
LCTContainer allLCTs_
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
unsigned thisShowerSource_
virtual std::vector< CSCCorrelatedLCTDigi > readoutLCTs() const
void setPattern(const uint16_t p)
set pattern
void setALCT(const CSCALCTDigi &alct)
uint16_t getBX() const
return BX - five low bits of BXN counter tagged by the ALCT
Definition: CSCALCTDigi.h:73
const CSCL1TPLookupTableME11ILT * lookupTableME11ILT_
unsigned maxbx_readout_
std::vector< CSCCLCTDigi > clctV
unsigned int clct_trig_enable
void setESLookupTables(const CSCL1TPLookupTableCCLUT *conf)
unsigned int encodePattern(const int clctPattern) const
const bool isValid(const Frame &aFrame, const FrameQuality &aQuality, const uint16_t aExpectedPos)
unsigned int match_trig_window_size
bool enableAlctPhase2_
Definition: CSCBaseboard.h:94
void setSlope(const uint16_t slope)
set the slope
static const unsigned int def_alct_trig_enable
void checkConfigParameters(unsigned int &var, const unsigned int var_max, const unsigned int var_def, const std::string &var_str)
uint16_t getQuality() const
return quality of a pattern (number of layers hit!)
Definition: CSCCLCTDigi.h:56
bool isValid() const
data
unsigned int tmbMpcBlockMe1a() const
uint16_t getComparatorNHits() const
Definition: CSCShowerDigi.h:55
CSCShowerDigi showers_[CSCConstants::MAX_LCT_TBINS]
uint16_t getKeyStrip(const uint16_t n=2) const
Definition: CSCCLCTDigi.cc:107
static const unsigned int def_mpc_block_me1a
void setQuartStripBit(const bool quartStripBit)
set single quart strip bit
bool getEighthStripBit() const
get single eighth strip bit
Definition: CSCCLCTDigi.h:114
void setEighthStripBit(const bool eighthStripBit)
set single eighth strip bit
std::vector< CSCCorrelatedLCTDigi > lctV
void matchShowers(CSCShowerDigi *anode_showers, CSCShowerDigi *cathode_showers, bool andlogic)
void setBend(const uint16_t b)
set bend
std::unique_ptr< CSCCathodeLCTProcessor > clctProc
static const unsigned int def_clct_trig_enable
Log< level::Error, false > LogError
void setValid(const uint16_t v)
set valid
unsigned short iChamberType() const
Definition: CSCDetId.h:96
assert(be >=bs)
unsigned int tmbTmbL1aWindowSize() const
#define LogTrace(id)
bool isLooseInTime() const
void copyValidToInValidALCT(CSCALCTDigi &, CSCALCTDigi &) const
CSCCLCTDigi getBXShiftedCLCT(const CSCCLCTDigi &) const
void setMatchTrigWindowSize(unsigned trig_window_size)
Definition: LCTContainer.h:41
unsigned int mpc_block_me1a
void setMPCLink(const uint16_t &link)
Set mpc link number after MPC sorting.
unsigned minbx_readout_
bool getQuartStripBit() const
get single quart strip bit
Definition: CSCCLCTDigi.h:108
const unsigned theTrigChamber
Definition: CSCBaseboard.h:46
void setWireGroup(const uint16_t wiregroup)
set wiregroup number
void correlateLCTs(const CSCALCTDigi &bestALCT, const CSCALCTDigi &secondALCT, const CSCCLCTDigi &bestCLCT, const CSCCLCTDigi &secondCLCT, CSCCorrelatedLCTDigi &bLCT, CSCCorrelatedLCTDigi &sLCT, int type) const
bool isTightInTime() const
unsigned int tmbMatchTrigWindowSize() const
std::vector< int > preferred_bx_match_
bool match_earliest_clct_only_
CSCMotherboard(unsigned endcap, unsigned station, unsigned sector, unsigned subsector, unsigned chamber, const edm::ParameterSet &conf)
std::unique_ptr< CSCALCTCrossCLCT > cscOverlap_
static const unsigned int def_tmb_l1a_window_size
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventID const &, edm::Timestamp const & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
std::vector< CSCALCTDigi > alctV
void dumpConfigParams() const
uint16_t getKeyWG() const
return key wire group
Definition: CSCALCTDigi.h:67
uint16_t getBend() const
Definition: CSCCLCTDigi.h:93
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
unsigned int tmb_l1a_window_size
void checkConfigParameters()
unsigned int match_trig_enable
void copyValidToInValidCLCT(CSCCLCTDigi &, CSCCLCTDigi &) const
void setRun3Pattern(const uint16_t pattern)
set Run-3 pattern
void setBX0(const uint16_t b)
set bx0
bool isValid() const
check CLCT validity (1 - valid CLCT)
Definition: CSCCLCTDigi.h:50
std::vector< unsigned > showerSource_
bool isNominalInTime() const
void setBX(const uint16_t BX)
set BX
Definition: CSCALCTDigi.h:76
const CSCGeometry * cscGeometry_
Definition: CSCBaseboard.h:71
edm::ParameterSet tmbParams_
Definition: CSCBaseboard.h:78
void setCSCID(const uint16_t c)
set cscID
void run(const CSCWireDigiCollection *wiredc, const CSCComparatorDigiCollection *compdc)
uint16_t getCSCID() const
Definition: CSCShowerDigi.h:52
void setRun3(const bool isRun3)
bool doesALCTCrossCLCT(const CSCALCTDigi &, const CSCCLCTDigi &) const
void setBX(const uint16_t b)
set bx
const unsigned theStation
Definition: CSCBaseboard.h:43
static const unsigned int def_match_trig_window_size
unsigned int tmbMatchTrigEnable() const
uint16_t getBX() const
return BX
Definition: CSCCLCTDigi.h:123
uint16_t getPattern() const
return pattern
Definition: CSCCLCTDigi.h:62
unsigned int alct_trig_enable
const CSCL1TPLookupTableME21ILT * lookupTableME21ILT_
void setBX(const uint16_t bx)
set bx
Definition: CSCCLCTDigi.h:129
std::unique_ptr< CSCAnodeLCTProcessor > alctProc
uint16_t getWireNHits() const
Definition: CSCShowerDigi.h:54
const CSCL1TPLookupTableCCLUT * lookupTableCCLUT_
uint16_t getSlope() const
return the slope
Definition: CSCCLCTDigi.h:74
unsigned int tmbClctTrigEnable() const
void setStrip(const uint16_t s)
set strip
void encodeHighMultiplicityBits()
unsigned int tmbAlctTrigEnable() const
uint16_t getRun3Pattern() const
return pattern
Definition: CSCCLCTDigi.h:68
void clear()
clear this CLCT
Definition: CSCCLCTDigi.cc:73
std::vector< CSCShowerDigi > readoutShower() const
void clear()
clear this Shower
unsigned theRing
Definition: CSCBaseboard.h:48
void setQuality(const uint16_t q)
set quality code
CSCALCTDigi getBXShiftedALCT(const CSCALCTDigi &) const
Log< level::Warning, false > LogWarning
edm::ParameterSet showerParams_
Definition: CSCBaseboard.h:87
void setConfigParameters(const CSCDBL1TPParameters *conf)
std::unique_ptr< LCTQualityControl > qualityControl_
void setTrknmb(const uint16_t number)
Set track number (1,2) after sorting LCTs.
void setCLCT(const CSCCLCTDigi &clct)
static const unsigned int def_match_trig_enable
void setSyncErr(const uint16_t s)
set syncErr
#define LogDebug(id)
std::unique_ptr< LCTQualityAssignment > qualityAssignment_
void constructLCTs(const CSCALCTDigi &aLCT, const CSCCLCTDigi &cLCT, int type, int trknmb, CSCCorrelatedLCTDigi &lct) const