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 
40 #include <iostream>
41 
42 // Default values of configuration parameters.
43 const unsigned int CSCMotherboard::def_mpc_block_me1a = 1;
44 const unsigned int CSCMotherboard::def_alct_trig_enable = 0;
45 const unsigned int CSCMotherboard::def_clct_trig_enable = 0;
46 const unsigned int CSCMotherboard::def_match_trig_enable = 1;
47 const unsigned int CSCMotherboard::def_match_trig_window_size = 7;
48 const unsigned int CSCMotherboard::def_tmb_l1a_window_size = 7;
49 
51  unsigned sector, unsigned subsector,
52  unsigned chamber,
53  const edm::ParameterSet& conf) :
54  theEndcap(endcap), theStation(station), theSector(sector),
55  theSubsector(subsector), theTrigChamber(chamber) {
56 
58 
59  // Normal constructor. -JM
60  // Pass ALCT, CLCT, and common parameters on to ALCT and CLCT processors.
61  static std::atomic<bool> config_dumped{false};
62 
63  // Parameters common for all boards
64  edm::ParameterSet commonParams = conf.getParameter<edm::ParameterSet>("commonParam");
65 
66  // is it (non-upgrade algorithm) run along with upgrade one?
67  isSLHC = commonParams.getParameter<bool>("isSLHC");
68 
69  // ALCT and CLCT configs
70  edm::ParameterSet alctParams = conf.getParameter<edm::ParameterSet>("alctParam07");
71  edm::ParameterSet clctParams = conf.getParameter<edm::ParameterSet>("clctParam07");
72 
73  // Motherboard parameters:
74  edm::ParameterSet tmbParams = conf.getParameter<edm::ParameterSet>("tmbParam");
75  const edm::ParameterSet me11tmbGemParams(conf.existsAs<edm::ParameterSet>("me11tmbSLHCGEM")?
76  conf.getParameter<edm::ParameterSet>("me11tmbSLHCGEM"):edm::ParameterSet());
77  const edm::ParameterSet me21tmbGemParams(conf.existsAs<edm::ParameterSet>("me21tmbSLHCGEM")?
78  conf.getParameter<edm::ParameterSet>("me21tmbSLHCGEM"):edm::ParameterSet());
79  const edm::ParameterSet me3141tmbParams(conf.existsAs<edm::ParameterSet>("me3141tmbSLHC")?
80  conf.getParameter<edm::ParameterSet>("me3141tmbSLHC"):edm::ParameterSet());
81 
82  const bool runME11ILT(commonParams.existsAs<bool>("runME11ILT")?commonParams.getParameter<bool>("runME11ILT"):false);
83  const bool runME21ILT(commonParams.existsAs<bool>("runME21ILT")?commonParams.getParameter<bool>("runME21ILT"):false);
84  const bool runME3141ILT(commonParams.existsAs<bool>("runME3141ILT")?commonParams.getParameter<bool>("runME3141ILT"):false);
85 
86  // run upgrade TMBs for all MEX/1 stations
87  if (isSLHC and theRing == 1){
88  if (theStation == 1) {
89  tmbParams = conf.getParameter<edm::ParameterSet>("tmbSLHC");
90  alctParams = conf.getParameter<edm::ParameterSet>("alctSLHC");
91  clctParams = conf.getParameter<edm::ParameterSet>("clctSLHC");
92  if (runME11ILT) {
93  tmbParams = me11tmbGemParams;
94  }
95  }
96  else if (theStation == 2 and runME21ILT) {
97  tmbParams = me21tmbGemParams;
98  alctParams = conf.getParameter<edm::ParameterSet>("alctSLHCME21");
99  clctParams = conf.getParameter<edm::ParameterSet>("clctSLHCME21");
100  }
101  else if ((theStation == 3 or theStation == 4) and runME3141ILT) {
102  tmbParams = me3141tmbParams;
103  alctParams = conf.getParameter<edm::ParameterSet>("alctSLHCME3141");
104  clctParams = conf.getParameter<edm::ParameterSet>("clctSLHCME3141");
105  }
106  }
107 
108  mpc_block_me1a = tmbParams.getParameter<unsigned int>("mpcBlockMe1a");
109  alct_trig_enable = tmbParams.getParameter<unsigned int>("alctTrigEnable");
110  clct_trig_enable = tmbParams.getParameter<unsigned int>("clctTrigEnable");
111  match_trig_enable = tmbParams.getParameter<unsigned int>("matchTrigEnable");
113  tmbParams.getParameter<unsigned int>("matchTrigWindowSize");
114  tmb_l1a_window_size = // Common to CLCT and TMB
115  tmbParams.getParameter<unsigned int>("tmbL1aWindowSize");
116 
117  // configuration handle for number of early time bins
118  early_tbins = tmbParams.getParameter<int>("tmbEarlyTbins");
119 
120  // whether to not reuse ALCTs that were used by previous matching CLCTs
121  drop_used_alcts = tmbParams.getParameter<bool>("tmbDropUsedAlcts");
122  drop_used_clcts = tmbParams.getParameter<bool>("tmbDropUsedClcts");
123 
124  clct_to_alct = tmbParams.getParameter<bool>("clctToAlct");
125 
126  //add alct clct offset in matching
127  alctClctOffset = commonParams.getParameter<unsigned int>("alctClctOffset");
128 
129  // whether to readout only the earliest two LCTs in readout window
130  readout_earliest_2 = tmbParams.getParameter<bool>("tmbReadoutEarliest2");
131 
132  infoV = tmbParams.getParameter<int>("verbosity");
133 
134  alct.reset( new CSCAnodeLCTProcessor(endcap, station, sector, subsector, chamber, alctParams, commonParams) );
135  clct.reset( new CSCCathodeLCTProcessor(endcap, station, sector, subsector, chamber, clctParams, commonParams, tmbParams) );
136 
137  // Check and print configuration parameters.
139  if (infoV > 0 && !config_dumped) {
141  config_dumped = true;
142  }
143 
144  // test to make sure that what goes into a correlated LCT is also what
145  // comes back out.
146  // testLCT();
147 }
148 
150  theEndcap(1), theStation(1), theSector(1),
152  // Constructor used only for testing. -JM
153  static std::atomic<bool> config_dumped{false};
154 
155  early_tbins = 4;
156 
157  alct.reset( new CSCAnodeLCTProcessor() );
158  clct.reset( new CSCCathodeLCTProcessor() );
165 
166  infoV = 2;
167 
168  // Check and print configuration parameters.
170  if (infoV > 0 && !config_dumped) {
172  config_dumped = true;
173  }
174 }
175 
177  if (alct) alct->clear();
178  if (clct) clct->clear();
179  for (int bx = 0; bx < CSCConstants::MAX_LCT_TBINS; bx++) {
180  firstLCT[bx].clear();
181  secondLCT[bx].clear();
182  }
183 }
184 
185 // Set configuration parameters obtained via EventSetup mechanism.
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  alct->setConfigParameters(conf);
199  clct->setConfigParameters(conf);
200 
201  // Check and print configuration parameters.
203  if (!config_dumped) {
205  config_dumped = true;
206  }
207 }
208 
210  // Make sure that the parameter values are within the allowed range.
211 
212  // Max expected values.
213  static const unsigned int max_mpc_block_me1a = 1 << 1;
214  static const unsigned int max_alct_trig_enable = 1 << 1;
215  static const unsigned int max_clct_trig_enable = 1 << 1;
216  static const unsigned int max_match_trig_enable = 1 << 1;
217  static const unsigned int max_match_trig_window_size = 1 << 4;
218  static const unsigned int max_tmb_l1a_window_size = 1 << 4;
219 
220  // Checks.
221  if (mpc_block_me1a >= max_mpc_block_me1a) {
222  if (infoV >= 0) edm::LogError("L1CSCTPEmulatorConfigError")
223  << "+++ Value of mpc_block_me1a, " << mpc_block_me1a
224  << ", exceeds max allowed, " << max_mpc_block_me1a-1 << " +++\n"
225  << "+++ Try to proceed with the default value, mpc_block_me1a="
226  << def_mpc_block_me1a << " +++\n";
228  }
229  if (alct_trig_enable >= max_alct_trig_enable) {
230  if (infoV >= 0) edm::LogError("L1CSCTPEmulatorConfigError")
231  << "+++ Value of alct_trig_enable, " << alct_trig_enable
232  << ", exceeds max allowed, " << max_alct_trig_enable-1 << " +++\n"
233  << "+++ Try to proceed with the default value, alct_trig_enable="
234  << def_alct_trig_enable << " +++\n";
236  }
237  if (clct_trig_enable >= max_clct_trig_enable) {
238  if (infoV >= 0) edm::LogError("L1CSCTPEmulatorConfigError")
239  << "+++ Value of clct_trig_enable, " << clct_trig_enable
240  << ", exceeds max allowed, " << max_clct_trig_enable-1 << " +++\n"
241  << "+++ Try to proceed with the default value, clct_trig_enable="
242  << def_clct_trig_enable << " +++\n";
244  }
245  if (match_trig_enable >= max_match_trig_enable) {
246  if (infoV >= 0) edm::LogError("L1CSCTPEmulatorConfigError")
247  << "+++ Value of match_trig_enable, " << match_trig_enable
248  << ", exceeds max allowed, " << max_match_trig_enable-1 << " +++\n"
249  << "+++ Try to proceed with the default value, match_trig_enable="
250  << def_match_trig_enable << " +++\n";
252  }
253  if (match_trig_window_size >= max_match_trig_window_size) {
254  if (infoV >= 0) edm::LogError("L1CSCTPEmulatorConfigError")
255  << "+++ Value of match_trig_window_size, " << match_trig_window_size
256  << ", exceeds max allowed, " << max_match_trig_window_size-1 << " +++\n"
257  << "+++ Try to proceed with the default value, match_trig_window_size="
258  << def_match_trig_window_size << " +++\n";
260  }
261  if (tmb_l1a_window_size >= max_tmb_l1a_window_size) {
262  if (infoV >= 0) edm::LogError("L1CSCTPEmulatorConfigError")
263  << "+++ Value of tmb_l1a_window_size, " << tmb_l1a_window_size
264  << ", exceeds max allowed, " << max_tmb_l1a_window_size-1 << " +++\n"
265  << "+++ Try to proceed with the default value, tmb_l1a_window_size="
266  << def_tmb_l1a_window_size << " +++\n";
268  }
269 }
270 
271 void
273  const CSCComparatorDigiCollection* compdc) {
274  clear();
275 
276  // set geometry
277  alct->setCSCGeometry(csc_g);
278  clct->setCSCGeometry(csc_g);
279 
280  if (alct && clct) {
281  {
282  const std::vector<CSCALCTDigi>& alctV = alct->run(wiredc); // run anodeLCT
283  }
284  {
285  const std::vector<CSCCLCTDigi>& clctV = clct->run(compdc); // run cathodeLCT
286  }
287 
288  // CLCT-centric matching
289  if (clct_to_alct){
290  int used_alct_mask[20];
291  for (int a=0;a<20;++a) used_alct_mask[a]=0;
292 
293  int bx_alct_matched = 0; // bx of last matched ALCT
294  for (int bx_clct = 0; bx_clct < CSCConstants::MAX_CLCT_TBINS;
295  bx_clct++) {
296  // There should be at least one valid ALCT or CLCT for a
297  // correlated LCT to be formed. Decision on whether to reject
298  // non-complete LCTs (and if yes of which type) is made further
299  // upstream.
300  if (clct->bestCLCT[bx_clct].isValid()) {
301  // Look for ALCTs within the match-time window. The window is
302  // centered at the CLCT bx; therefore, we make an assumption
303  // that anode and cathode hits are perfectly synchronized. This
304  // is always true for MC, but only an approximation when the
305  // data is analyzed (which works fairly good as long as wide
306  // windows are used). To get rid of this assumption, one would
307  // need to access "full BX" words, which are not readily
308  // available.
309  bool is_matched = false;
310  const int bx_alct_start = bx_clct - match_trig_window_size/2 + alctClctOffset;
311  const int bx_alct_stop = bx_clct + match_trig_window_size/2 + alctClctOffset;
312 
313  for (int bx_alct = bx_alct_start; bx_alct <= bx_alct_stop; bx_alct++) {
314  if (bx_alct < 0 || bx_alct >= CSCConstants::MAX_ALCT_TBINS)
315  continue;
316  // default: do not reuse ALCTs that were used with previous CLCTs
317  if (drop_used_alcts && used_alct_mask[bx_alct]) continue;
318  if (alct->bestALCT[bx_alct].isValid()) {
319  if (infoV > 1) LogTrace("CSCMotherboard")
320  << "Successful ALCT-CLCT match: bx_clct = " << bx_clct
321  << "; match window: [" << bx_alct_start << "; " << bx_alct_stop
322  << "]; bx_alct = " << bx_alct;
323  correlateLCTs(alct->bestALCT[bx_alct], alct->secondALCT[bx_alct],
324  clct->bestCLCT[bx_clct], clct->secondCLCT[bx_clct],
326  used_alct_mask[bx_alct] += 1;
327  is_matched = true;
328  bx_alct_matched = bx_alct;
329  break;
330  }
331  }
332  // No ALCT within the match time interval found: report CLCT-only LCT
333  // (use dummy ALCTs).
334  if (!is_matched and clct_trig_enable) {
335  if (infoV > 1) LogTrace("CSCMotherboard")
336  << "Unsuccessful ALCT-CLCT match (CLCT only): bx_clct = "
337  << bx_clct << "; match window: [" << bx_alct_start
338  << "; " << bx_alct_stop << "]";
339  correlateLCTs(alct->bestALCT[bx_clct], alct->secondALCT[bx_clct],
340  clct->bestCLCT[bx_clct], clct->secondCLCT[bx_clct],
342  }
343  }
344  // No valid CLCTs; attempt to make ALCT-only LCT. Use only ALCTs
345  // which have zeroth chance to be matched at later cathode times.
346  // (I am not entirely sure this perfectly matches the firmware logic.)
347  // Use dummy CLCTs.
348  else {
349  int bx_alct = bx_clct - match_trig_window_size/2;
350  if (bx_alct >= 0 && bx_alct > bx_alct_matched) {
351  if (alct->bestALCT[bx_alct].isValid() and alct_trig_enable) {
352  if (infoV > 1) LogTrace("CSCMotherboard")
353  << "Unsuccessful ALCT-CLCT match (ALCT only): bx_alct = "
354  << bx_alct;
355  correlateLCTs(alct->bestALCT[bx_alct], alct->secondALCT[bx_alct],
356  clct->bestCLCT[bx_clct], clct->secondCLCT[bx_clct],
358  }
359  }
360  }
361  }
362  }
363  // ALCT-centric matching
364  else {
365  int used_clct_mask[20];
366  for (int a=0;a<20;++a) used_clct_mask[a]=0;
367 
368  int bx_clct_matched = 0; // bx of last matched CLCT
369  for (int bx_alct = 0; bx_alct < CSCConstants::MAX_ALCT_TBINS;
370  bx_alct++) {
371  // There should be at least one valid CLCT or ALCT for a
372  // correlated LCT to be formed. Decision on whether to reject
373  // non-complete LCTs (and if yes of which type) is made further
374  // upstream.
375  if (alct->bestALCT[bx_alct].isValid()) {
376  // Look for CLCTs within the match-time window. The window is
377  // centered at the ALCT bx; therefore, we make an assumption
378  // that anode and cathode hits are perfectly synchronized. This
379  // is always true for MC, but only an approximation when the
380  // data is analyzed (which works fairly good as long as wide
381  // windows are used). To get rid of this assumption, one would
382  // need to access "full BX" words, which are not readily
383  // available.
384  bool is_matched = false;
385  const int bx_clct_start = bx_alct - match_trig_window_size/2 - alctClctOffset;
386  const int bx_clct_stop = bx_alct + match_trig_window_size/2 - alctClctOffset;
387 
388  for (int bx_clct = bx_clct_start; bx_clct <= bx_clct_stop; bx_clct++) {
389  if (bx_clct < 0 || bx_clct >= CSCConstants::MAX_CLCT_TBINS)
390  continue;
391  // default: do not reuse CLCTs that were used with previous ALCTs
392  if (drop_used_clcts && used_clct_mask[bx_clct]) continue;
393  if (clct->bestCLCT[bx_clct].isValid()) {
394  if (infoV > 1) LogTrace("CSCMotherboard")
395  << "Successful CLCT-ALCT match: bx_alct = " << bx_alct
396  << "; match window: [" << bx_clct_start << "; " << bx_clct_stop
397  << "]; bx_clct = " << bx_clct;
398  correlateLCTs(alct->bestALCT[bx_alct], alct->secondALCT[bx_alct],
399  clct->bestCLCT[bx_clct], clct->secondCLCT[bx_clct],
401  used_clct_mask[bx_clct] += 1;
402  is_matched = true;
403  bx_clct_matched = bx_clct;
404  break;
405  }
406  }
407  // No CLCT within the match time interval found: report ALCT-only LCT
408  // (use dummy CLCTs).
409  if (!is_matched and alct_trig_enable) {
410  if (infoV > 1) LogTrace("CSCMotherboard")
411  << "Unsuccessful CLCT-ALCT match (ALCT only): bx_alct = "
412  << bx_alct << "; match window: [" << bx_clct_start
413  << "; " << bx_clct_stop << "]";
414  correlateLCTs(alct->bestALCT[bx_alct], alct->secondALCT[bx_alct],
415  clct->bestCLCT[bx_alct], clct->secondCLCT[bx_alct],
417  }
418  }
419  // No valid ALCTs; attempt to make CLCT-only LCT. Use only CLCTs
420  // which have zeroth chance to be matched at later cathode times.
421  // (I am not entirely sure this perfectly matches the firmware logic.)
422  // Use dummy ALCTs.
423  else {
424  int bx_clct = bx_alct - match_trig_window_size/2;
425  if (bx_clct >= 0 && bx_clct > bx_clct_matched) {
426  if (clct->bestCLCT[bx_clct].isValid() and clct_trig_enable) {
427  if (infoV > 1) LogTrace("CSCMotherboard")
428  << "Unsuccessful CLCT-ALCT match (CLCT only): bx_clct = "
429  << bx_clct;
430  correlateLCTs(alct->bestALCT[bx_alct], alct->secondALCT[bx_alct],
431  clct->bestCLCT[bx_clct], clct->secondCLCT[bx_clct],
433  }
434  }
435  }
436  }
437  }
438 
439  // Debug first and second LCTs
440  if (infoV > 0) {
441  for (int bx = 0; bx < CSCConstants::MAX_LCT_TBINS; bx++) {
442  if (firstLCT[bx].isValid())
443  LogDebug("CSCMotherboard") << firstLCT[bx];
444  if (secondLCT[bx].isValid())
445  LogDebug("CSCMotherboard") << secondLCT[bx];
446  }
447  }
448  }
449  // No valid ALCT and/or CLCT processor
450  else {
451  if (infoV >= 0) edm::LogError("L1CSCTPEmulatorSetupError")
452  << "+++ run() called for non-existing ALCT/CLCT processor! +++ \n";
453  }
454 }
455 
456 // Returns vector of read-out correlated LCTs, if any. Starts with
457 // the vector of all found LCTs and selects the ones in the read-out
458 // time window.
459 std::vector<CSCCorrelatedLCTDigi> CSCMotherboard::readoutLCTs() const {
460  std::vector<CSCCorrelatedLCTDigi> tmpV;
461 
462  // The start time of the L1A*LCT coincidence window should be related
463  // to the fifo_pretrig parameter, but I am not completely sure how.
464  // Just choose it such that the window is centered at bx=7. This may
465  // need further tweaking if the value of tmb_l1a_window_size changes.
466  //static int early_tbins = 4;
467 
468  // Empirical correction to match 2009 collision data (firmware change?)
469  int lct_bins = tmb_l1a_window_size;
470  int late_tbins = early_tbins + lct_bins;
471 
472  int ifois = 0;
473  if (ifois == 0) {
474  if (infoV >= 0 && early_tbins < 0) {
475  edm::LogWarning("L1CSCTPEmulatorSuspiciousParameters")
476  << "+++ early_tbins = " << early_tbins
477  << "; in-time LCTs are not getting read-out!!! +++" << "\n";
478  }
479 
480  if (late_tbins > CSCConstants::MAX_LCT_TBINS-1) {
481  if (infoV >= 0) edm::LogWarning("L1CSCTPEmulatorSuspiciousParameters")
482  << "+++ Allowed range of time bins, [0-" << late_tbins
483  << "] exceeds max allowed, " << CSCConstants::MAX_LCT_TBINS-1 << " +++\n"
484  << "+++ Set late_tbins to max allowed +++\n";
485  late_tbins = CSCConstants::MAX_LCT_TBINS-1;
486  }
487  ifois = 1;
488  }
489 
490  // Start from the vector of all found correlated LCTs and select
491  // those within the LCT*L1A coincidence window.
492  int bx_readout = -1;
493  const std::vector<CSCCorrelatedLCTDigi>& all_lcts = getLCTs();
494  for (auto plct = all_lcts.begin(); plct != all_lcts.end(); plct++) {
495  if (!plct->isValid()) continue;
496 
497  int bx = (*plct).getBX();
498  // Skip LCTs found too early relative to L1Accept.
499  if (bx <= early_tbins) {
500  if (infoV > 1) LogDebug("CSCMotherboard")
501  << " Do not report correlated LCT on key halfstrip "
502  << plct->getStrip() << " and key wire " << plct->getKeyWG()
503  << ": found at bx " << bx << ", whereas the earliest allowed bx is "
504  << early_tbins+1;
505  continue;
506  }
507 
508  // Skip LCTs found too late relative to L1Accept.
509  if (bx > late_tbins) {
510  if (infoV > 1) LogDebug("CSCMotherboard")
511  << " Do not report correlated LCT on key halfstrip "
512  << plct->getStrip() << " and key wire " << plct->getKeyWG()
513  << ": found at bx " << bx << ", whereas the latest allowed bx is "
514  << late_tbins;
515  continue;
516  }
517 
518  // If (readout_earliest_2) take only LCTs in the earliest bx in the read-out window:
519  // in digi->raw step, LCTs have to be packed into the TMB header, and
520  // currently there is room just for two.
521  if (readout_earliest_2) {
522  if (bx_readout == -1 || bx == bx_readout) {
523  tmpV.push_back(*plct);
524  if (bx_readout == -1) bx_readout = bx;
525  }
526  }
527  // if readout_earliest_2 == false, save all LCTs
528  else tmpV.push_back(*plct);
529  }
530  return tmpV;
531 }
532 
533 // Returns vector of all found correlated LCTs, if any.
534 std::vector<CSCCorrelatedLCTDigi> CSCMotherboard::getLCTs() const {
535  std::vector<CSCCorrelatedLCTDigi> tmpV;
536 
537  bool me11 = (theStation == 1 &&
539  theTrigChamber)==1);
540 
541  // Do not report LCTs found in ME1/A if mpc_block_me1/a is set.
542  for (int bx = 0; bx < CSCConstants::MAX_LCT_TBINS; bx++) {
543  if (firstLCT[bx].isValid())
544  if (!mpc_block_me1a || (!me11 || firstLCT[bx].getStrip() <= 127))
545  tmpV.push_back(firstLCT[bx]);
546  if (secondLCT[bx].isValid())
547  if (!mpc_block_me1a || (!me11 || secondLCT[bx].getStrip() <= 127))
548  tmpV.push_back(secondLCT[bx]);
549  }
550  return tmpV;
551 }
552 
554  const CSCALCTDigi& sALCT,
555  const CSCCLCTDigi& bCLCT,
556  const CSCCLCTDigi& sCLCT,
557  int type)
558 {
559  CSCALCTDigi bestALCT = bALCT;
560  CSCALCTDigi secondALCT = sALCT;
561  CSCCLCTDigi bestCLCT = bCLCT;
562  CSCCLCTDigi secondCLCT = sCLCT;
563 
564  bool anodeBestValid = bestALCT.isValid();
565  bool anodeSecondValid = secondALCT.isValid();
566  bool cathodeBestValid = bestCLCT.isValid();
567  bool cathodeSecondValid = secondCLCT.isValid();
568 
569  if (anodeBestValid && !anodeSecondValid) secondALCT = bestALCT;
570  if (!anodeBestValid && anodeSecondValid) bestALCT = secondALCT;
571  if (cathodeBestValid && !cathodeSecondValid) secondCLCT = bestCLCT;
572  if (!cathodeBestValid && cathodeSecondValid) bestCLCT = secondCLCT;
573 
574  // ALCT-CLCT matching conditions are defined by "trig_enable" configuration
575  // parameters.
576  if ((alct_trig_enable && bestALCT.isValid()) ||
577  (clct_trig_enable && bestCLCT.isValid()) ||
578  (match_trig_enable && bestALCT.isValid() && bestCLCT.isValid())) {
579  const CSCCorrelatedLCTDigi& lct = constructLCTs(bestALCT, bestCLCT, type, 1);
580  int bx = lct.getBX();
581  if (bx >= 0 && bx < CSCConstants::MAX_LCT_TBINS) {
582  firstLCT[bx] = lct;
583  }
584  else {
585  if (infoV > 0) edm::LogWarning("L1CSCTPEmulatorOutOfTimeLCT")
586  << "+++ Bx of first LCT candidate, " << bx
587  << ", is not within the allowed range, [0-" << CSCConstants::MAX_LCT_TBINS-1
588  << "); skipping it... +++\n";
589  }
590  }
591 
592  if (((secondALCT != bestALCT) || (secondCLCT != bestCLCT)) &&
593  ((alct_trig_enable && secondALCT.isValid()) ||
594  (clct_trig_enable && secondCLCT.isValid()) ||
595  (match_trig_enable && secondALCT.isValid() && secondCLCT.isValid()))) {
596  const CSCCorrelatedLCTDigi& lct = constructLCTs(secondALCT, secondCLCT, type, 2);
597  int bx = lct.getBX();
598  if (bx >= 0 && bx < CSCConstants::MAX_LCT_TBINS) {
599  secondLCT[bx] = lct;
600  }
601  else {
602  if (infoV > 0) edm::LogWarning("L1CSCTPEmulatorOutOfTimeLCT")
603  << "+++ Bx of second LCT candidate, " << bx
604  << ", is not within the allowed range, [0-" << CSCConstants::MAX_LCT_TBINS-1
605  << "); skipping it... +++\n";
606  }
607  }
608 }
609 
610 // This method calculates all the TMB words and then passes them to the
611 // constructor of correlated LCTs.
613  const CSCCLCTDigi& cLCT,
614  int type,
615  int trknmb) const {
616  // CLCT pattern number
617  unsigned int pattern = encodePattern(cLCT.getPattern(), cLCT.getStripType());
618 
619  // LCT quality number
620  unsigned int quality = findQuality(aLCT, cLCT);
621 
622  // Bunch crossing: get it from cathode LCT if anode LCT is not there.
623  int bx = aLCT.isValid() ? aLCT.getBX() : cLCT.getBX();
624 
625  // construct correlated LCT
626  CSCCorrelatedLCTDigi thisLCT(trknmb, 1, quality, aLCT.getKeyWG(),
627  cLCT.getKeyStrip(), pattern, cLCT.getBend(),
628  bx, 0, 0, 0, theTrigChamber);
629  thisLCT.setType(type);
630  // make sure to shift the ALCT BX from 8 to 3!
631  thisLCT.setALCT(getBXShiftedALCT(aLCT));
632  thisLCT.setCLCT(cLCT);
633  return thisLCT;
634 }
635 
636 // CLCT pattern number: encodes the pattern number itself and
637 // whether the pattern consists of half-strips or di-strips.
638 unsigned int CSCMotherboard::encodePattern(const int ptn,
639  const int stripType) const {
640  const int kPatternBitWidth = 4;
641 
642  // In the TMB07 firmware, LCT pattern is just a 4-bit CLCT pattern.
643  unsigned int pattern = (abs(ptn) & ((1<<kPatternBitWidth)-1));
644 
645  return pattern;
646 }
647 
648 // 4-bit LCT quality number.
649 unsigned int CSCMotherboard::findQuality(const CSCALCTDigi& aLCT,
650  const CSCCLCTDigi& cLCT) const
651 {
652  unsigned int quality = 0;
653 
654  // 2008 definition.
655  if (!(aLCT.isValid()) || !(cLCT.isValid())) {
656  if (aLCT.isValid() && !(cLCT.isValid())) quality = 1; // no CLCT
657  else if (!(aLCT.isValid()) && cLCT.isValid()) quality = 2; // no ALCT
658  else quality = 0; // both absent; should never happen.
659  }
660  else {
661  int pattern = cLCT.getPattern();
662  if (pattern == 1) quality = 3; // layer-trigger in CLCT
663  else {
664  // CLCT quality is the number of layers hit minus 3.
665  // CLCT quality is the number of layers hit.
666  bool a4 = (aLCT.getQuality() >= 1);
667  bool c4 = (cLCT.getQuality() >= 4);
668  // quality = 4; "reserved for low-quality muons in future"
669  if (!a4 && !c4) quality = 5; // marginal anode and cathode
670  else if ( a4 && !c4) quality = 6; // HQ anode, but marginal cathode
671  else if (!a4 && c4) quality = 7; // HQ cathode, but marginal anode
672  else if ( a4 && c4) {
673  if (aLCT.getAccelerator()) quality = 8; // HQ muon, but accel ALCT
674  else {
675  // quality = 9; "reserved for HQ muons with future patterns
676  // quality = 10; "reserved for HQ muons with future patterns
677  if (pattern == 2 || pattern == 3) quality = 11;
678  else if (pattern == 4 || pattern == 5) quality = 12;
679  else if (pattern == 6 || pattern == 7) quality = 13;
680  else if (pattern == 8 || pattern == 9) quality = 14;
681  else if (pattern == 10) quality = 15;
682  else {
683  if (infoV >= 0) edm::LogWarning("L1CSCTPEmulatorWrongValues")
684  << "+++ findQuality: Unexpected CLCT pattern id = "
685  << pattern << "+++\n";
686  }
687  }
688  }
689  }
690  }
691  return quality;
692 }
693 
695  unsigned int lctPattern, lctQuality;
696  for (int pattern = 0; pattern < 8; pattern++) {
697  for (int bend = 0; bend < 2; bend++) {
698  for (int cfeb = 0; cfeb < 5; cfeb++) {
699  for (int strip = 0; strip < 32; strip++) {
700  for (int bx = 0; bx < 7; bx++) {
701  for (int stripType = 0; stripType < 2; stripType++) {
702  for (int quality = 3; quality < 7; quality++) {
703  CSCCLCTDigi cLCT(1, quality, pattern, stripType, bend,
704  strip, cfeb, bx);
705  lctPattern = encodePattern(cLCT.getPattern(),
706  cLCT.getStripType());
707  for (int aQuality = 0; aQuality < 4; aQuality++) {
708  for (int wireGroup = 0; wireGroup < 120; wireGroup++) {
709  for (int abx = 0; abx < 7; abx++) {
710  CSCALCTDigi aLCT(1, aQuality, 0, 1, wireGroup, abx);
711  lctQuality = findQuality(aLCT, cLCT);
713  thisLCT(0, 1, lctQuality, aLCT.getKeyWG(),
714  cLCT.getKeyStrip(), lctPattern, cLCT.getBend(),
715  aLCT.getBX());
716  if (lctPattern != static_cast<unsigned int>(thisLCT.getPattern()) )
717  LogTrace("CSCMotherboard")
718  << "pattern mismatch: " << lctPattern
719  << " " << thisLCT.getPattern();
720  if (bend != thisLCT.getBend())
721  LogTrace("CSCMotherboard")
722  << "bend mismatch: " << bend
723  << " " << thisLCT.getBend();
724  int key_strip = 32*cfeb + strip;
725  if (key_strip != thisLCT.getStrip())
726  LogTrace("CSCMotherboard")
727  << "strip mismatch: " << key_strip
728  << " " << thisLCT.getStrip();
729  if (wireGroup != thisLCT.getKeyWG())
730  LogTrace("CSCMotherboard")
731  << "wire group mismatch: " << wireGroup
732  << " " << thisLCT.getKeyWG();
733  if (abx != thisLCT.getBX())
734  LogTrace("CSCMotherboard")
735  << "bx mismatch: " << abx << " " << thisLCT.getBX();
736  if (lctQuality != static_cast<unsigned int>(thisLCT.getQuality()))
737  LogTrace("CSCMotherboard")
738  << "quality mismatch: " << lctQuality
739  << " " << thisLCT.getQuality();
740  }
741  }
742  }
743  }
744  }
745  }
746  }
747  }
748  }
749  }
750 }
751 
753  std::ostringstream strm;
754  strm << "\n";
755  strm << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
756  strm << "+ TMB configuration parameters: +\n";
757  strm << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
758  strm << " mpc_block_me1a [block/not block triggers which come from ME1/A] = "
759  << mpc_block_me1a << "\n";
760  strm << " alct_trig_enable [allow ALCT-only triggers] = "
761  << alct_trig_enable << "\n";
762  strm << " clct_trig_enable [allow CLCT-only triggers] = "
763  << clct_trig_enable << "\n";
764  strm << " match_trig_enable [allow matched ALCT-CLCT triggers] = "
765  << match_trig_enable << "\n";
766  strm << " match_trig_window_size [ALCT-CLCT match window width, in 25 ns] = "
767  << match_trig_window_size << "\n";
768  strm << " tmb_l1a_window_size [L1Accept window width, in 25 ns bins] = "
769  << tmb_l1a_window_size << "\n";
770  strm << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
771  LogDebug("CSCMotherboard") << strm.str();
772 }
773 
776 {
777  CSCALCTDigi aLCT_shifted = aLCT;
778  aLCT_shifted.setBX(aLCT_shifted.getBX() - (CSCConstants::LCT_CENTRAL_BX - tmb_l1a_window_size/2));
779  return aLCT_shifted;
780 }
#define LogDebug(id)
int getQuality() const
return quality of a pattern (number of layers hit!)
Definition: CSCCLCTDigi.h:36
type
Definition: HCALResponse.h:21
const unsigned theSector
T getParameter(std::string const &) const
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]
static const unsigned int def_clct_trig_enable
const CSCGeometry * csc_g
static int ringFromTriggerLabels(int station, int triggerCSCID)
int getStripType() const
return striptype
Definition: CSCCLCTDigi.h:48
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
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
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 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 encodePattern(const int ptn, const int highPt) const
unsigned int alct_trig_enable
std::unique_ptr< CSCAnodeLCTProcessor > alct
double a
Definition: hdecay.h:121
void dumpConfigParams() const
std::unique_ptr< CSCCathodeLCTProcessor > clct
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
unsigned theRing
CSCCorrelatedLCTDigi firstLCT[CSCConstants::MAX_LCT_TBINS]