CMS 3D CMS Logo

CSCMotherboard.cc
Go to the documentation of this file.
1 //-----------------------------------------------------------------------------
2 //
3 // Class: CSCMotherboard
4 //
5 // Description:
6 // When the Trigger MotherBoard is instantiated it instantiates an ALCT
7 // and CLCT board. The Motherboard takes up to two LCTs from each anode
8 // and cathode LCT card and combines them into a single Correlated LCT.
9 // The output is up to two Correlated LCTs.
10 //
11 // It can be run in either a test mode, where the arguments are a collection
12 // of wire times and arrays of halfstrip times, or
13 // for general use, with with wire digi and comparator digi collections as
14 // arguments. In the latter mode, the wire & strip info is passed on the
15 // LCTProcessors, where it is decoded and converted into a convenient form.
16 // After running the anode and cathode LCTProcessors, TMB correlates the
17 // anode and cathode LCTs. At present, it simply matches the best CLCT
18 // with the best ALCT; perhaps a better algorithm will be determined in
19 // the future. The MotherBoard then determines a few more numbers (such as
20 // quality and pattern) from the ALCT and CLCT information, and constructs
21 // two correlated LCTs.
22 //
23 // correlateLCTs() may need to be modified to take into account a
24 // possibility of ALCTs and CLCTs arriving at different bx times.
25 //
26 // Author List: Benn Tannenbaum 28 August 1999 benn@physics.ucla.edu
27 // Based on code by Nick Wisniewski (nw@its.caltech.edu)
28 // and a framework by Darin Acosta (acosta@phys.ufl.edu).
29 //
30 //
31 // Modifications: Numerous later improvements by Jason Mumford and
32 // Slava Valuev (see cvs in ORCA).
33 // Porting from ORCA by S. Valuev (Slava.Valuev@cern.ch), May 2006.
34 //
35 //-----------------------------------------------------------------------------
36 
38 #include <iostream>
39 
40 // Default values of configuration parameters.
41 const unsigned int CSCMotherboard::def_mpc_block_me1a = 1;
42 const unsigned int CSCMotherboard::def_alct_trig_enable = 0;
43 const unsigned int CSCMotherboard::def_clct_trig_enable = 0;
44 const unsigned int CSCMotherboard::def_match_trig_enable = 1;
45 const unsigned int CSCMotherboard::def_match_trig_window_size = 7;
46 const unsigned int CSCMotherboard::def_tmb_l1a_window_size = 7;
47 
49  unsigned sector, unsigned subsector,
50  unsigned chamber,
51  const edm::ParameterSet& conf) :
52  theEndcap(endcap), theStation(station), theSector(sector),
53  theSubsector(subsector), theTrigChamber(chamber)
54 {
56 
57  // Normal constructor. -JM
58  // Pass ALCT, CLCT, and common parameters on to ALCT and CLCT processors.
59  static std::atomic<bool> config_dumped{false};
60 
61  // Parameters common for all boards
62  commonParams_ = conf.getParameter<edm::ParameterSet>("commonParam");
63 
64  // is it (non-upgrade algorithm) run along with upgrade one?
65  isSLHC_ = commonParams_.getParameter<bool>("isSLHC");
66 
67  runME11ILT_ = commonParams_.existsAs<bool>("runME11ILT") ?
68  commonParams_.getParameter<bool>("runME11ILT"):false;
69  runME21ILT_ = commonParams_.existsAs<bool>("runME21ILT") ?
70  commonParams_.getParameter<bool>("runME21ILT"):false;
71  runME3141ILT_ = commonParams_.existsAs<bool>("runME3141ILT") ?
72  commonParams_.getParameter<bool>("runME3141ILT"):false;
73 
74  // ALCT and CLCT configs
75  alctParams_ = conf.getParameter<edm::ParameterSet>("alctParam07");
76  clctParams_ = conf.getParameter<edm::ParameterSet>("clctParam07");
77 
78  // Motherboard parameters:
79  tmbParams_ = conf.getParameter<edm::ParameterSet>("tmbParam");
80 
81  // run upgrade TMBs for all MEX/1 stations
82  if (isSLHC_ and theRing == 1){
83  if (theStation == 1) {
84  tmbParams_ = conf.getParameter<edm::ParameterSet>("tmbSLHC");
85  alctParams_ = conf.getParameter<edm::ParameterSet>("alctSLHC");
86  clctParams_ = conf.getParameter<edm::ParameterSet>("clctSLHC");
87  if (runME11ILT_) {
88  tmbParams_ = conf.getParameter<edm::ParameterSet>("me11tmbSLHCGEM");
89  }
90  }
91  else if (theStation == 2 and runME21ILT_) {
92  tmbParams_ = conf.getParameter<edm::ParameterSet>("me21tmbSLHCGEM");
93  alctParams_ = conf.getParameter<edm::ParameterSet>("alctSLHCME21");
94  clctParams_ = conf.getParameter<edm::ParameterSet>("clctSLHCME21");
95  }
96  else if ((theStation == 3 or theStation == 4) and runME3141ILT_) {
97  tmbParams_ = conf.getParameter<edm::ParameterSet>("me3141tmbSLHC");
98  alctParams_ = conf.getParameter<edm::ParameterSet>("alctSLHCME3141");
99  clctParams_ = conf.getParameter<edm::ParameterSet>("clctSLHCME3141");
100  }
101  }
102 
103  mpc_block_me1a = tmbParams_.getParameter<unsigned int>("mpcBlockMe1a");
104  alct_trig_enable = tmbParams_.getParameter<unsigned int>("alctTrigEnable");
105  clct_trig_enable = tmbParams_.getParameter<unsigned int>("clctTrigEnable");
106  match_trig_enable = tmbParams_.getParameter<unsigned int>("matchTrigEnable");
108  tmbParams_.getParameter<unsigned int>("matchTrigWindowSize");
109  tmb_l1a_window_size = // Common to CLCT and TMB
110  tmbParams_.getParameter<unsigned int>("tmbL1aWindowSize");
111 
112  // configuration handle for number of early time bins
113  early_tbins = tmbParams_.getParameter<int>("tmbEarlyTbins");
114 
115  // whether to not reuse ALCTs that were used by previous matching CLCTs
116  drop_used_alcts = tmbParams_.getParameter<bool>("tmbDropUsedAlcts");
117  drop_used_clcts = tmbParams_.getParameter<bool>("tmbDropUsedClcts");
118 
119  clct_to_alct = tmbParams_.getParameter<bool>("clctToAlct");
120 
121  //add alct clct offset in matching
122  alctClctOffset = commonParams_.getParameter<unsigned int>("alctClctOffset");
123 
124  // whether to readout only the earliest two LCTs in readout window
125  readout_earliest_2 = tmbParams_.getParameter<bool>("tmbReadoutEarliest2");
126 
127  infoV = tmbParams_.getParameter<int>("verbosity");
128 
129  alctProc.reset( new CSCAnodeLCTProcessor(endcap, station, sector, subsector, chamber, alctParams_, commonParams_) );
130  clctProc.reset( new CSCCathodeLCTProcessor(endcap, station, sector, subsector, chamber, clctParams_, commonParams_, tmbParams_) );
131 
132  // Check and print configuration parameters.
134  if (infoV > 0 && !config_dumped) {
136  config_dumped = true;
137  }
138 }
139 
141  theEndcap(1), theStation(1), theSector(1),
143  // Constructor used only for testing. -JM
144  static std::atomic<bool> config_dumped{false};
145 
146  early_tbins = 4;
147 
148  alctProc.reset( new CSCAnodeLCTProcessor() );
149  clctProc.reset( new CSCCathodeLCTProcessor() );
156 
157  infoV = 2;
158 
159  // Check and print configuration parameters.
161  if (infoV > 0 && !config_dumped) {
163  config_dumped = true;
164  }
165 }
166 
168 {
169  // clear the processors
170  if (alctProc) alctProc->clear();
171  if (clctProc) clctProc->clear();
172 
173  // clear the ALCT and CLCT containers
174  alctV.clear();
175  clctV.clear();
176 
177  // clear the LCT containers
178  for (int bx = 0; bx < CSCConstants::MAX_LCT_TBINS; bx++) {
179  firstLCT[bx].clear();
180  secondLCT[bx].clear();
181  }
182 }
183 
184 // Set configuration parameters obtained via EventSetup mechanism.
186 {
187  static std::atomic<bool> config_dumped{false};
188 
189  // Config. parameters for the TMB itself.
196 
197  // Config. paramteres for ALCT and CLCT processors.
198  alctProc->setConfigParameters(conf);
199  clctProc->setConfigParameters(conf);
200 
201  // Check and print configuration parameters.
203  if (!config_dumped) {
205  config_dumped = true;
206  }
207 }
208 
209 void
211  const CSCComparatorDigiCollection* compdc)
212 {
213  // clear the ALCT/CLCT/LCT containers. Clear the processors
214  clear();
215 
216  // Check for existing processors
217  if (!( alctProc && clctProc))
218  {
219  if (infoV >= 0) edm::LogError("CSCMotherboard|SetupError")
220  << "+++ run() called for non-existing ALCT/CLCT processor! +++ \n";
221  return;
222  }
223 
224  // set geometry
225  alctProc->setCSCGeometry(csc_g);
226  clctProc->setCSCGeometry(csc_g);
227 
228  alctV = alctProc->run(wiredc); // run anodeLCT
229  clctV = clctProc->run(compdc); // run cathodeLCT
230 
231  // CLCT-centric matching
232  if (clct_to_alct){
233  int used_alct_mask[20];
234  for (int a=0;a<20;++a) used_alct_mask[a]=0;
235 
236  int bx_alct_matched = 0; // bx of last matched ALCT
237  for (int bx_clct = 0; bx_clct < CSCConstants::MAX_CLCT_TBINS;
238  bx_clct++) {
239  // There should be at least one valid ALCT or CLCT for a
240  // correlated LCT to be formed. Decision on whether to reject
241  // non-complete LCTs (and if yes of which type) is made further
242  // upstream.
243  if (clctProc->bestCLCT[bx_clct].isValid()) {
244  // Look for ALCTs within the match-time window. The window is
245  // centered at the CLCT bx; therefore, we make an assumption
246  // that anode and cathode hits are perfectly synchronized. This
247  // is always true for MC, but only an approximation when the
248  // data is analyzed (which works fairly good as long as wide
249  // windows are used). To get rid of this assumption, one would
250  // need to access "full BX" words, which are not readily
251  // available.
252  bool is_matched = false;
253  const int bx_alct_start = bx_clct - match_trig_window_size/2 + alctClctOffset;
254  const int bx_alct_stop = bx_clct + match_trig_window_size/2 + alctClctOffset;
255 
256  for (int bx_alct = bx_alct_start; bx_alct <= bx_alct_stop; bx_alct++) {
257  if (bx_alct < 0 || bx_alct >= CSCConstants::MAX_ALCT_TBINS)
258  continue;
259  // default: do not reuse ALCTs that were used with previous CLCTs
260  if (drop_used_alcts && used_alct_mask[bx_alct]) continue;
261  if (alctProc->bestALCT[bx_alct].isValid()) {
262  if (infoV > 1) LogTrace("CSCMotherboard")
263  << "Successful CLCT-ALCT match: bx_clct = " << bx_clct
264  << "; match window: [" << bx_alct_start << "; " << bx_alct_stop
265  << "]; bx_alct = " << bx_alct;
266  correlateLCTs(alctProc->bestALCT[bx_alct], alctProc->secondALCT[bx_alct],
267  clctProc->bestCLCT[bx_clct], clctProc->secondCLCT[bx_clct],
269  used_alct_mask[bx_alct] += 1;
270  is_matched = true;
271  bx_alct_matched = bx_alct;
272  break;
273  }
274  }
275  // No ALCT within the match time interval found: report CLCT-only LCT
276  // (use dummy ALCTs).
277  if (!is_matched and clct_trig_enable) {
278  if (infoV > 1) LogTrace("CSCMotherboard")
279  << "Unsuccessful CLCT-ALCT match (CLCT only): bx_clct = "
280  << bx_clct << "; match window: [" << bx_alct_start
281  << "; " << bx_alct_stop << "]";
282  correlateLCTs(alctProc->bestALCT[bx_clct], alctProc->secondALCT[bx_clct],
283  clctProc->bestCLCT[bx_clct], clctProc->secondCLCT[bx_clct],
285  }
286  }
287  // No valid CLCTs; attempt to make ALCT-only LCT. Use only ALCTs
288  // which have zeroth chance to be matched at later cathode times.
289  // (I am not entirely sure this perfectly matches the firmware logic.)
290  // Use dummy CLCTs.
291  else {
292  int bx_alct = bx_clct - match_trig_window_size/2;
293  if (bx_alct >= 0 && bx_alct > bx_alct_matched) {
294  if (alctProc->bestALCT[bx_alct].isValid() and alct_trig_enable) {
295  if (infoV > 1) LogTrace("CSCMotherboard")
296  << "Unsuccessful CLCT-ALCT match (ALCT only): bx_alct = "
297  << bx_alct;
298  correlateLCTs(alctProc->bestALCT[bx_alct], alctProc->secondALCT[bx_alct],
299  clctProc->bestCLCT[bx_clct], clctProc->secondCLCT[bx_clct],
301  }
302  }
303  }
304  }
305  }
306  // ALCT-centric matching
307  else {
308  int used_clct_mask[20];
309  for (int a=0;a<20;++a) used_clct_mask[a]=0;
310 
311  int bx_clct_matched = 0; // bx of last matched CLCT
312  for (int bx_alct = 0; bx_alct < CSCConstants::MAX_ALCT_TBINS;
313  bx_alct++) {
314  // There should be at least one valid CLCT or ALCT for a
315  // correlated LCT to be formed. Decision on whether to reject
316  // non-complete LCTs (and if yes of which type) is made further
317  // upstream.
318  if (alctProc->bestALCT[bx_alct].isValid()) {
319  // Look for CLCTs within the match-time window. The window is
320  // centered at the ALCT bx; therefore, we make an assumption
321  // that anode and cathode hits are perfectly synchronized. This
322  // is always true for MC, but only an approximation when the
323  // data is analyzed (which works fairly good as long as wide
324  // windows are used). To get rid of this assumption, one would
325  // need to access "full BX" words, which are not readily
326  // available.
327  bool is_matched = false;
328  const int bx_clct_start = bx_alct - match_trig_window_size/2 - alctClctOffset;
329  const int bx_clct_stop = bx_alct + match_trig_window_size/2 - alctClctOffset;
330 
331  for (int bx_clct = bx_clct_start; bx_clct <= bx_clct_stop; bx_clct++) {
332  if (bx_clct < 0 || bx_clct >= CSCConstants::MAX_CLCT_TBINS)
333  continue;
334  // default: do not reuse CLCTs that were used with previous ALCTs
335  if (drop_used_clcts && used_clct_mask[bx_clct]) continue;
336  if (clctProc->bestCLCT[bx_clct].isValid()) {
337  if (infoV > 1) LogTrace("CSCMotherboard")
338  << "Successful ALCT-CLCT match: bx_alct = " << bx_alct
339  << "; match window: [" << bx_clct_start << "; " << bx_clct_stop
340  << "]; bx_clct = " << bx_clct;
341  correlateLCTs(alctProc->bestALCT[bx_alct], alctProc->secondALCT[bx_alct],
342  clctProc->bestCLCT[bx_clct], clctProc->secondCLCT[bx_clct],
344  used_clct_mask[bx_clct] += 1;
345  is_matched = true;
346  bx_clct_matched = bx_clct;
347  break;
348  }
349  }
350  // No CLCT within the match time interval found: report ALCT-only LCT
351  // (use dummy CLCTs).
352  if (!is_matched and alct_trig_enable) {
353  if (infoV > 1) LogTrace("CSCMotherboard")
354  << "Unsuccessful ALCT-CLCT match (ALCT only): bx_alct = "
355  << bx_alct << "; match window: [" << bx_clct_start
356  << "; " << bx_clct_stop << "]";
357  correlateLCTs(alctProc->bestALCT[bx_alct], alctProc->secondALCT[bx_alct],
358  clctProc->bestCLCT[bx_alct], clctProc->secondCLCT[bx_alct],
360  }
361  }
362  // No valid ALCTs; attempt to make CLCT-only LCT. Use only CLCTs
363  // which have zeroth chance to be matched at later cathode times.
364  // (I am not entirely sure this perfectly matches the firmware logic.)
365  // Use dummy ALCTs.
366  else {
367  int bx_clct = bx_alct - match_trig_window_size/2;
368  if (bx_clct >= 0 && bx_clct > bx_clct_matched) {
369  if (clctProc->bestCLCT[bx_clct].isValid() and clct_trig_enable) {
370  if (infoV > 1) LogTrace("CSCMotherboard")
371  << "Unsuccessful ALCT-CLCT match (CLCT only): bx_clct = "
372  << bx_clct;
373  correlateLCTs(alctProc->bestALCT[bx_alct], alctProc->secondALCT[bx_alct],
374  clctProc->bestCLCT[bx_clct], clctProc->secondCLCT[bx_clct],
376  }
377  }
378  }
379  }
380  }
381 
382  // Debug first and second LCTs
383  if (infoV > 0) {
384  for (int bx = 0; bx < CSCConstants::MAX_LCT_TBINS; bx++) {
385  if (firstLCT[bx].isValid())
386  LogDebug("CSCMotherboard") << firstLCT[bx];
387  if (secondLCT[bx].isValid())
388  LogDebug("CSCMotherboard") << secondLCT[bx];
389  }
390  }
391 }
392 
393 
394 // Returns vector of read-out correlated LCTs, if any. Starts with
395 // the vector of all found LCTs and selects the ones in the read-out
396 // time window.
397 std::vector<CSCCorrelatedLCTDigi> CSCMotherboard::readoutLCTs() const
398 {
399  std::vector<CSCCorrelatedLCTDigi> tmpV;
400 
401  // The start time of the L1A*LCT coincidence window should be related
402  // to the fifo_pretrig parameter, but I am not completely sure how.
403  // Just choose it such that the window is centered at bx=7. This may
404  // need further tweaking if the value of tmb_l1a_window_size changes.
405  //static int early_tbins = 4;
406 
407  // Empirical correction to match 2009 collision data (firmware change?)
408  int lct_bins = tmb_l1a_window_size;
409  int late_tbins = early_tbins + lct_bins;
410 
411  int ifois = 0;
412  if (ifois == 0) {
413  if (infoV >= 0 && early_tbins < 0) {
414  edm::LogWarning("CSCMotherboard|SuspiciousParameters")
415  << "+++ early_tbins = " << early_tbins
416  << "; in-time LCTs are not getting read-out!!! +++" << "\n";
417  }
418 
419  if (late_tbins > CSCConstants::MAX_LCT_TBINS-1) {
420  if (infoV >= 0) edm::LogWarning("CSCMotherboard|SuspiciousParameters")
421  << "+++ Allowed range of time bins, [0-" << late_tbins
422  << "] exceeds max allowed, " << CSCConstants::MAX_LCT_TBINS-1 << " +++\n"
423  << "+++ Set late_tbins to max allowed +++\n";
424  late_tbins = CSCConstants::MAX_LCT_TBINS-1;
425  }
426  ifois = 1;
427  }
428 
429  // Start from the vector of all found correlated LCTs and select
430  // those within the LCT*L1A coincidence window.
431  int bx_readout = -1;
432  const std::vector<CSCCorrelatedLCTDigi>& all_lcts = getLCTs();
433  for (auto plct = all_lcts.begin(); plct != all_lcts.end(); plct++) {
434  if (!plct->isValid()) continue;
435 
436  int bx = (*plct).getBX();
437  // Skip LCTs found too early relative to L1Accept.
438  if (bx <= early_tbins) {
439  if (infoV > 1) LogDebug("CSCMotherboard")
440  << " Do not report correlated LCT on key halfstrip "
441  << plct->getStrip() << " and key wire " << plct->getKeyWG()
442  << ": found at bx " << bx << ", whereas the earliest allowed bx is "
443  << early_tbins+1;
444  continue;
445  }
446 
447  // Skip LCTs found too late relative to L1Accept.
448  if (bx > late_tbins) {
449  if (infoV > 1) LogDebug("CSCMotherboard")
450  << " Do not report correlated LCT on key halfstrip "
451  << plct->getStrip() << " and key wire " << plct->getKeyWG()
452  << ": found at bx " << bx << ", whereas the latest allowed bx is "
453  << late_tbins;
454  continue;
455  }
456 
457  // If (readout_earliest_2) take only LCTs in the earliest bx in the read-out window:
458  // in digi->raw step, LCTs have to be packed into the TMB header, and
459  // currently there is room just for two.
460  if (readout_earliest_2) {
461  if (bx_readout == -1 || bx == bx_readout) {
462  tmpV.push_back(*plct);
463  if (bx_readout == -1) bx_readout = bx;
464  }
465  }
466  // if readout_earliest_2 == false, save all LCTs
467  else tmpV.push_back(*plct);
468  }
469  return tmpV;
470 }
471 
472 // Returns vector of all found correlated LCTs, if any.
473 std::vector<CSCCorrelatedLCTDigi> CSCMotherboard::getLCTs() const {
474  std::vector<CSCCorrelatedLCTDigi> tmpV;
475 
476  bool me11 = (theStation == 1 &&
478  theTrigChamber)==1);
479 
480  // Do not report LCTs found in ME1/A if mpc_block_me1/a is set.
481  for (int bx = 0; bx < CSCConstants::MAX_LCT_TBINS; bx++) {
482  if (firstLCT[bx].isValid())
483  if (!mpc_block_me1a || (!me11 || firstLCT[bx].getStrip() <= 127))
484  tmpV.push_back(firstLCT[bx]);
485  if (secondLCT[bx].isValid())
486  if (!mpc_block_me1a || (!me11 || secondLCT[bx].getStrip() <= 127))
487  tmpV.push_back(secondLCT[bx]);
488  }
489  return tmpV;
490 }
491 
493  const CSCALCTDigi& sALCT,
494  const CSCCLCTDigi& bCLCT,
495  const CSCCLCTDigi& sCLCT,
496  int type)
497 {
498  CSCALCTDigi bestALCT = bALCT;
499  CSCALCTDigi secondALCT = sALCT;
500  CSCCLCTDigi bestCLCT = bCLCT;
501  CSCCLCTDigi secondCLCT = sCLCT;
502 
503  bool anodeBestValid = bestALCT.isValid();
504  bool anodeSecondValid = secondALCT.isValid();
505  bool cathodeBestValid = bestCLCT.isValid();
506  bool cathodeSecondValid = secondCLCT.isValid();
507 
508  if (anodeBestValid && !anodeSecondValid) secondALCT = bestALCT;
509  if (!anodeBestValid && anodeSecondValid) bestALCT = secondALCT;
510  if (cathodeBestValid && !cathodeSecondValid) secondCLCT = bestCLCT;
511  if (!cathodeBestValid && cathodeSecondValid) bestCLCT = secondCLCT;
512 
513  // ALCT-CLCT matching conditions are defined by "trig_enable" configuration
514  // parameters.
515  if ((alct_trig_enable && bestALCT.isValid()) ||
516  (clct_trig_enable && bestCLCT.isValid()) ||
517  (match_trig_enable && bestALCT.isValid() && bestCLCT.isValid())) {
518  const CSCCorrelatedLCTDigi& lct = constructLCTs(bestALCT, bestCLCT, type, 1);
519  int bx = lct.getBX();
520  if (bx >= 0 && bx < CSCConstants::MAX_LCT_TBINS) {
521  firstLCT[bx] = lct;
522  }
523  else {
524  if (infoV > 0) edm::LogWarning("CSCMotherboard|OutOfTimeLCT")
525  << "+++ Bx of first LCT candidate, " << bx
526  << ", is not within the allowed range, [0-" << CSCConstants::MAX_LCT_TBINS-1
527  << "); skipping it... +++\n";
528  }
529  }
530 
531  if (((secondALCT != bestALCT) || (secondCLCT != bestCLCT)) &&
532  ((alct_trig_enable && secondALCT.isValid()) ||
533  (clct_trig_enable && secondCLCT.isValid()) ||
534  (match_trig_enable && secondALCT.isValid() && secondCLCT.isValid()))) {
535  const CSCCorrelatedLCTDigi& lct = constructLCTs(secondALCT, secondCLCT, type, 2);
536  int bx = lct.getBX();
537  if (bx >= 0 && bx < CSCConstants::MAX_LCT_TBINS) {
538  secondLCT[bx] = lct;
539  }
540  else {
541  if (infoV > 0) edm::LogWarning("CSCMotherboard|OutOfTimeLCT")
542  << "+++ Bx of second LCT candidate, " << bx
543  << ", is not within the allowed range, [0-" << CSCConstants::MAX_LCT_TBINS-1
544  << "); skipping it... +++\n";
545  }
546  }
547 }
548 
549 // This method calculates all the TMB words and then passes them to the
550 // constructor of correlated LCTs.
552  const CSCCLCTDigi& cLCT,
553  int type,
554  int trknmb) const {
555  // CLCT pattern number
556  unsigned int pattern = encodePattern(cLCT.getPattern());
557 
558  // LCT quality number
559  unsigned int quality = findQuality(aLCT, cLCT);
560 
561  // Bunch crossing: get it from cathode LCT if anode LCT is not there.
562  int bx = aLCT.isValid() ? aLCT.getBX() : cLCT.getBX();
563 
564  // construct correlated LCT
565  CSCCorrelatedLCTDigi thisLCT(trknmb, 1, quality, aLCT.getKeyWG(),
566  cLCT.getKeyStrip(), pattern, cLCT.getBend(),
567  bx, 0, 0, 0, theTrigChamber);
568  thisLCT.setType(type);
569  // make sure to shift the ALCT BX from 8 to 3!
570  thisLCT.setALCT(getBXShiftedALCT(aLCT));
571  thisLCT.setCLCT(cLCT);
572  return thisLCT;
573 }
574 
575 // CLCT pattern number: encodes the pattern number itself
576 unsigned int CSCMotherboard::encodePattern(const int ptn) const
577 {
578  const int kPatternBitWidth = 4;
579 
580  // In the TMB07 firmware, LCT pattern is just a 4-bit CLCT pattern.
581  unsigned int pattern = (abs(ptn) & ((1<<kPatternBitWidth)-1));
582 
583  return pattern;
584 }
585 
586 // 4-bit LCT quality number.
587 unsigned int CSCMotherboard::findQuality(const CSCALCTDigi& aLCT,
588  const CSCCLCTDigi& cLCT) const
589 {
590  unsigned int quality = 0;
591 
592  // 2008 definition.
593  if (!(aLCT.isValid()) || !(cLCT.isValid())) {
594  if (aLCT.isValid() && !(cLCT.isValid())) quality = 1; // no CLCT
595  else if (!(aLCT.isValid()) && cLCT.isValid()) quality = 2; // no ALCT
596  else quality = 0; // both absent; should never happen.
597  }
598  else {
599  int pattern = cLCT.getPattern();
600  if (pattern == 1) quality = 3; // layer-trigger in CLCT
601  else {
602  // CLCT quality is the number of layers hit minus 3.
603  // CLCT quality is the number of layers hit.
604  bool a4 = (aLCT.getQuality() >= 1);
605  bool c4 = (cLCT.getQuality() >= 4);
606  // quality = 4; "reserved for low-quality muons in future"
607  if (!a4 && !c4) quality = 5; // marginal anode and cathode
608  else if ( a4 && !c4) quality = 6; // HQ anode, but marginal cathode
609  else if (!a4 && c4) quality = 7; // HQ cathode, but marginal anode
610  else if ( a4 && c4) {
611  if (aLCT.getAccelerator()) quality = 8; // HQ muon, but accel ALCT
612  else {
613  // quality = 9; "reserved for HQ muons with future patterns
614  // quality = 10; "reserved for HQ muons with future patterns
615  if (pattern == 2 || pattern == 3) quality = 11;
616  else if (pattern == 4 || pattern == 5) quality = 12;
617  else if (pattern == 6 || pattern == 7) quality = 13;
618  else if (pattern == 8 || pattern == 9) quality = 14;
619  else if (pattern == 10) quality = 15;
620  else {
621  if (infoV >= 0) edm::LogWarning("CSCMotherboard|WrongValues")
622  << "+++ findQuality: Unexpected CLCT pattern id = "
623  << pattern << "+++\n";
624  }
625  }
626  }
627  }
628  }
629  return quality;
630 }
631 
633 {
634  // Make sure that the parameter values are within the allowed range.
635 
636  // Max expected values.
637  static const unsigned int max_mpc_block_me1a = 1 << 1;
638  static const unsigned int max_alct_trig_enable = 1 << 1;
639  static const unsigned int max_clct_trig_enable = 1 << 1;
640  static const unsigned int max_match_trig_enable = 1 << 1;
641  static const unsigned int max_match_trig_window_size = 1 << 4;
642  static const unsigned int max_tmb_l1a_window_size = 1 << 4;
643 
644  // Checks.
645  if (mpc_block_me1a >= max_mpc_block_me1a) {
646  if (infoV >= 0) edm::LogError("CSCMotherboard|ConfigError")
647  << "+++ Value of mpc_block_me1a, " << mpc_block_me1a
648  << ", exceeds max allowed, " << max_mpc_block_me1a-1 << " +++\n"
649  << "+++ Try to proceed with the default value, mpc_block_me1a="
650  << def_mpc_block_me1a << " +++\n";
652  }
653  if (alct_trig_enable >= max_alct_trig_enable) {
654  if (infoV >= 0) edm::LogError("CSCMotherboard|ConfigError")
655  << "+++ Value of alct_trig_enable, " << alct_trig_enable
656  << ", exceeds max allowed, " << max_alct_trig_enable-1 << " +++\n"
657  << "+++ Try to proceed with the default value, alct_trig_enable="
658  << def_alct_trig_enable << " +++\n";
660  }
661  if (clct_trig_enable >= max_clct_trig_enable) {
662  if (infoV >= 0) edm::LogError("CSCMotherboard|ConfigError")
663  << "+++ Value of clct_trig_enable, " << clct_trig_enable
664  << ", exceeds max allowed, " << max_clct_trig_enable-1 << " +++\n"
665  << "+++ Try to proceed with the default value, clct_trig_enable="
666  << def_clct_trig_enable << " +++\n";
668  }
669  if (match_trig_enable >= max_match_trig_enable) {
670  if (infoV >= 0) edm::LogError("CSCMotherboard|ConfigError")
671  << "+++ Value of match_trig_enable, " << match_trig_enable
672  << ", exceeds max allowed, " << max_match_trig_enable-1 << " +++\n"
673  << "+++ Try to proceed with the default value, match_trig_enable="
674  << def_match_trig_enable << " +++\n";
676  }
677  if (match_trig_window_size >= max_match_trig_window_size) {
678  if (infoV >= 0) edm::LogError("CSCMotherboard|ConfigError")
679  << "+++ Value of match_trig_window_size, " << match_trig_window_size
680  << ", exceeds max allowed, " << max_match_trig_window_size-1 << " +++\n"
681  << "+++ Try to proceed with the default value, match_trig_window_size="
682  << def_match_trig_window_size << " +++\n";
684  }
685  if (tmb_l1a_window_size >= max_tmb_l1a_window_size) {
686  if (infoV >= 0) edm::LogError("CSCMotherboard|ConfigError")
687  << "+++ Value of tmb_l1a_window_size, " << tmb_l1a_window_size
688  << ", exceeds max allowed, " << max_tmb_l1a_window_size-1 << " +++\n"
689  << "+++ Try to proceed with the default value, tmb_l1a_window_size="
690  << def_tmb_l1a_window_size << " +++\n";
692  }
693 }
694 
696  std::ostringstream strm;
697  strm << "\n";
698  strm << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
699  strm << "+ TMB configuration parameters: +\n";
700  strm << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
701  strm << " mpc_block_me1a [block/not block triggers which come from ME1/A] = "
702  << mpc_block_me1a << "\n";
703  strm << " alct_trig_enable [allow ALCT-only triggers] = "
704  << alct_trig_enable << "\n";
705  strm << " clct_trig_enable [allow CLCT-only triggers] = "
706  << clct_trig_enable << "\n";
707  strm << " match_trig_enable [allow matched ALCT-CLCT triggers] = "
708  << match_trig_enable << "\n";
709  strm << " match_trig_window_size [ALCT-CLCT match window width, in 25 ns] = "
710  << match_trig_window_size << "\n";
711  strm << " tmb_l1a_window_size [L1Accept window width, in 25 ns bins] = "
712  << tmb_l1a_window_size << "\n";
713  strm << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
714  LogDebug("CSCMotherboard") << strm.str();
715 }
716 
719 {
720  CSCALCTDigi aLCT_shifted = aLCT;
721  aLCT_shifted.setBX(aLCT_shifted.getBX() - (CSCConstants::LCT_CENTRAL_BX - tmb_l1a_window_size/2));
722  return aLCT_shifted;
723 }
#define LogDebug(id)
int getQuality() const
return quality of a pattern (number of layers hit!)
Definition: CSCCLCTDigi.h:36
type
Definition: HCALResponse.h:21
edm::ParameterSet clctParams_
const unsigned theSector
T getParameter(std::string const &) const
edm::ParameterSet alctParams_
std::vector< CSCCLCTDigi > clctV
bool existsAs(std::string const &parameterName, bool trackiness=true) const
checks if a parameter exists as a given type
Definition: ParameterSet.h:185
unsigned int clct_trig_enable
unsigned int match_trig_window_size
CSCALCTDigi getBXShiftedALCT(const CSCALCTDigi &) const
const unsigned theTrigChamber
static const unsigned int def_alct_trig_enable
bool isValid() const
check ALCT validity (1 - valid ALCT)
Definition: CSCALCTDigi.h:30
void correlateLCTs(const CSCALCTDigi &bestALCT, const CSCALCTDigi &secondALCT, const CSCCLCTDigi &bestCLCT, const CSCCLCTDigi &secondCLCT, int type)
const unsigned theEndcap
static const unsigned int def_mpc_block_me1a
unsigned int alctClctOffset
unsigned int tmbClctTrigEnable() const
CSCCorrelatedLCTDigi secondLCT[CSCConstants::MAX_LCT_TBINS]
std::unique_ptr< CSCCathodeLCTProcessor > clctProc
static const unsigned int def_clct_trig_enable
const CSCGeometry * csc_g
static int ringFromTriggerLabels(int station, int triggerCSCID)
edm::ParameterSet tmbParams_
int getBend() const
return bend
Definition: CSCCLCTDigi.h:54
unsigned int mpc_block_me1a
std::vector< CSCCorrelatedLCTDigi > getLCTs() const
unsigned int tmbTmbL1aWindowSize() const
const unsigned theStation
unsigned int tmbMatchTrigWindowSize() const
static const unsigned int def_tmb_l1a_window_size
edm::ParameterSet commonParams_
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
const unsigned theSubsector
int getBX() const
return BX
Definition: CSCCLCTDigi.h:72
unsigned int tmbAlctTrigEnable() const
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
unsigned int encodePattern(const int clctPattern) const
unsigned int tmb_l1a_window_size
void checkConfigParameters()
bool isValid() const
check CLCT validity (1 - valid CLCT)
Definition: CSCCLCTDigi.h:30
unsigned int match_trig_enable
CSCCorrelatedLCTDigi constructLCTs(const CSCALCTDigi &aLCT, const CSCCLCTDigi &cLCT, int type, int trknmb) const
#define LogTrace(id)
int getBX() const
return BX
int getBX() const
return BX - five low bits of BXN counter tagged by the ALCT
Definition: CSCALCTDigi.h:63
unsigned int tmbMpcBlockMe1a() const
int getQuality() const
return quality of a pattern
Definition: CSCALCTDigi.h:36
void run(const CSCWireDigiCollection *wiredc, const CSCComparatorDigiCollection *compdc)
int getAccelerator() const
Definition: CSCALCTDigi.h:43
unsigned int findQuality(const CSCALCTDigi &aLCT, const CSCCLCTDigi &cLCT) const
int getPattern() const
return pattern
Definition: CSCCLCTDigi.h:42
static const unsigned int def_match_trig_window_size
unsigned int alct_trig_enable
std::unique_ptr< CSCAnodeLCTProcessor > alctProc
double a
Definition: hdecay.h:121
void dumpConfigParams() const
int getKeyStrip() const
Definition: CSCCLCTDigi.h:89
void setConfigParameters(const CSCDBL1TPParameters *conf)
int getKeyWG() const
return key wire group
Definition: CSCALCTDigi.h:57
static const unsigned int def_match_trig_enable
std::vector< CSCCorrelatedLCTDigi > readoutLCTs() const
void setBX(const int BX)
set BX
Definition: CSCALCTDigi.h:66
unsigned int tmbMatchTrigEnable() const
CSCCorrelatedLCTDigi firstLCT[CSCConstants::MAX_LCT_TBINS]