CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
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 and distrip 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 
41 // Default values of configuration parameters.
42 const unsigned int CSCMotherboard::def_mpc_block_me1a = 1;
43 const unsigned int CSCMotherboard::def_alct_trig_enable = 0;
44 const unsigned int CSCMotherboard::def_clct_trig_enable = 0;
45 const unsigned int CSCMotherboard::def_match_trig_enable = 1;
46 const unsigned int CSCMotherboard::def_match_trig_window_size = 7;
47 const unsigned int CSCMotherboard::def_tmb_l1a_window_size = 7;
48 
50  unsigned sector, unsigned subsector,
51  unsigned chamber,
52  const edm::ParameterSet& conf) :
53  theEndcap(endcap), theStation(station), theSector(sector),
54  theSubsector(subsector), theTrigChamber(chamber) {
55  // Normal constructor. -JM
56  // Pass ALCT, CLCT, and common parameters on to ALCT and CLCT processors.
57  static bool config_dumped = false;
58 
59  // Some configuration parameters and some details of the emulator
60  // algorithms depend on whether we want to emulate the trigger logic
61  // used in TB/MTCC or its idealized version (the latter was used in MC
62  // studies since early ORCA days until (and including) CMSSW_2_1_X).
63  edm::ParameterSet commonParams =
64  conf.getParameter<edm::ParameterSet>("commonParam");
65  isMTCC = commonParams.getParameter<bool>("isMTCC");
66 
67  // Switch for a new (2007) version of the TMB firmware.
68  isTMB07 = commonParams.getParameter<bool>("isTMB07");
69 
70  // is it (non-upgrade algorithm) run along with upgrade one?
71  isSLHC = commonParams.getUntrackedParameter<bool>("isSLHC");
72 
73  // Choose the appropriate set of configuration parameters depending on
74  // isTMB07 and isMTCC flags.
75  // Starting with CMSSW_3_1_X, these settings are overwritten by the
76  // ones delivered by the EventSetup mechanism.
77  edm::ParameterSet alctParams, clctParams;
78  if (isTMB07) {
79  alctParams = conf.getParameter<edm::ParameterSet>("alctParam07");
80  clctParams = conf.getParameter<edm::ParameterSet>("clctParam07");
81  }
82  else if (isMTCC) {
83  alctParams = conf.getParameter<edm::ParameterSet>("alctParamMTCC");
84  clctParams = conf.getParameter<edm::ParameterSet>("clctParamMTCC");
85  }
86  else {
87  alctParams = conf.getParameter<edm::ParameterSet>("alctParamOldMC");
88  clctParams = conf.getParameter<edm::ParameterSet>("clctParamOldMC");
89  }
90 
91  // Motherboard parameters:
92  edm::ParameterSet tmbParams = conf.getParameter<edm::ParameterSet>("tmbParam");
93 
94  if (isSLHC && theStation == 1 &&
96  alctParams = conf.getParameter<edm::ParameterSet>("alctSLHC");
97  clctParams = conf.getParameter<edm::ParameterSet>("clctSLHC");
98  tmbParams = conf.getParameter<edm::ParameterSet>("tmbSLHC");
99  }
100 
101  mpc_block_me1a = tmbParams.getParameter<unsigned int>("mpcBlockMe1a");
102  alct_trig_enable = tmbParams.getParameter<unsigned int>("alctTrigEnable");
103  clct_trig_enable = tmbParams.getParameter<unsigned int>("clctTrigEnable");
104  match_trig_enable = tmbParams.getParameter<unsigned int>("matchTrigEnable");
106  tmbParams.getParameter<unsigned int>("matchTrigWindowSize");
107  tmb_l1a_window_size = // Common to CLCT and TMB
108  tmbParams.getParameter<unsigned int>("tmbL1aWindowSize");
109 
110  // configuration handle for number of early time bins
111  early_tbins = tmbParams.getUntrackedParameter<int>("tmbEarlyTbins",4);
112 
113  // whether to not reuse ALCTs that were used by previous matching CLCTs
114  drop_used_alcts = tmbParams.getUntrackedParameter<bool>("tmbDropUsedAlcts",true);
115 
116  // whether to readout only the earliest two LCTs in readout window
117  readout_earliest_2 = tmbParams.getUntrackedParameter<bool>("tmbReadoutEarliest2",false);
118 
119  infoV = tmbParams.getUntrackedParameter<int>("verbosity", 0);
120 
121  alct = new CSCAnodeLCTProcessor(endcap, station, sector, subsector, chamber, alctParams, commonParams);
122  clct = new CSCCathodeLCTProcessor(endcap, station, sector, subsector, chamber, clctParams, commonParams, tmbParams);
123 
124  //if (theStation==1 && CSCTriggerNumbering::ringFromTriggerLabels(theStation, theTrigChamber)==2) infoV = 3;
125 
126  // Check and print configuration parameters.
128  if (infoV > 0 && !config_dumped) {
130  config_dumped = true;
131  }
132 
133  // test to make sure that what goes into a correlated LCT is also what
134  // comes back out.
135  // testLCT();
136 }
137 
139  theEndcap(1), theStation(1), theSector(1),
140  theSubsector(1), theTrigChamber(1) {
141  // Constructor used only for testing. -JM
142  static bool config_dumped = false;
143 
144  isMTCC = false;
145  isTMB07 = true;
146 
147  early_tbins = 4;
148 
149  alct = new CSCAnodeLCTProcessor();
157 
158  infoV = 2;
159 
160  // Check and print configuration parameters.
162  if (infoV > 0 && !config_dumped) {
164  config_dumped = true;
165  }
166 }
167 
169  if (alct) delete alct;
170  if (clct) delete clct;
171 }
172 
174  if (alct) alct->clear();
175  if (clct) clct->clear();
176  for (int bx = 0; bx < MAX_LCT_BINS; bx++) {
177  firstLCT[bx].clear();
178  secondLCT[bx].clear();
179  }
180 }
181 
182 // Set configuration parameters obtained via EventSetup mechanism.
184  static bool config_dumped = false;
185 
186  // Config. parameters for the TMB itself.
193 
194  // Config. paramteres for ALCT and CLCT processors.
195  alct->setConfigParameters(conf);
196  clct->setConfigParameters(conf);
197 
198  // Check and print configuration parameters.
200  if (!config_dumped) {
202  config_dumped = true;
203  }
204 }
205 
207  // Make sure that the parameter values are within the allowed range.
208 
209  // Max expected values.
210  static const unsigned int max_mpc_block_me1a = 1 << 1;
211  static const unsigned int max_alct_trig_enable = 1 << 1;
212  static const unsigned int max_clct_trig_enable = 1 << 1;
213  static const unsigned int max_match_trig_enable = 1 << 1;
214  static const unsigned int max_match_trig_window_size = 1 << 4;
215  static const unsigned int max_tmb_l1a_window_size = 1 << 4;
216 
217  // Checks.
218  if (mpc_block_me1a >= max_mpc_block_me1a) {
219  if (infoV >= 0) edm::LogError("L1CSCTPEmulatorConfigError")
220  << "+++ Value of mpc_block_me1a, " << mpc_block_me1a
221  << ", exceeds max allowed, " << max_mpc_block_me1a-1 << " +++\n"
222  << "+++ Try to proceed with the default value, mpc_block_me1a="
223  << def_mpc_block_me1a << " +++\n";
225  }
226  if (alct_trig_enable >= max_alct_trig_enable) {
227  if (infoV >= 0) edm::LogError("L1CSCTPEmulatorConfigError")
228  << "+++ Value of alct_trig_enable, " << alct_trig_enable
229  << ", exceeds max allowed, " << max_alct_trig_enable-1 << " +++\n"
230  << "+++ Try to proceed with the default value, alct_trig_enable="
231  << def_alct_trig_enable << " +++\n";
233  }
234  if (clct_trig_enable >= max_clct_trig_enable) {
235  if (infoV >= 0) edm::LogError("L1CSCTPEmulatorConfigError")
236  << "+++ Value of clct_trig_enable, " << clct_trig_enable
237  << ", exceeds max allowed, " << max_clct_trig_enable-1 << " +++\n"
238  << "+++ Try to proceed with the default value, clct_trig_enable="
239  << def_clct_trig_enable << " +++\n";
241  }
242  if (match_trig_enable >= max_match_trig_enable) {
243  if (infoV >= 0) edm::LogError("L1CSCTPEmulatorConfigError")
244  << "+++ Value of match_trig_enable, " << match_trig_enable
245  << ", exceeds max allowed, " << max_match_trig_enable-1 << " +++\n"
246  << "+++ Try to proceed with the default value, match_trig_enable="
247  << def_match_trig_enable << " +++\n";
249  }
250  if (match_trig_window_size >= max_match_trig_window_size) {
251  if (infoV >= 0) edm::LogError("L1CSCTPEmulatorConfigError")
252  << "+++ Value of match_trig_window_size, " << match_trig_window_size
253  << ", exceeds max allowed, " << max_match_trig_window_size-1 << " +++\n"
254  << "+++ Try to proceed with the default value, match_trig_window_size="
255  << def_match_trig_window_size << " +++\n";
257  }
258  if (tmb_l1a_window_size >= max_tmb_l1a_window_size) {
259  if (infoV >= 0) edm::LogError("L1CSCTPEmulatorConfigError")
260  << "+++ Value of tmb_l1a_window_size, " << tmb_l1a_window_size
261  << ", exceeds max allowed, " << max_tmb_l1a_window_size-1 << " +++\n"
262  << "+++ Try to proceed with the default value, tmb_l1a_window_size="
263  << def_tmb_l1a_window_size << " +++\n";
265  }
266 }
267 
269  const std::vector<int> w_times[CSCConstants::NUM_LAYERS][CSCConstants::MAX_NUM_WIRES],
270  const std::vector<int> hs_times[CSCConstants::NUM_LAYERS][CSCConstants::NUM_HALF_STRIPS],
271  const std::vector<int> ds_times[CSCConstants::NUM_LAYERS][CSCConstants::NUM_HALF_STRIPS]) {
272  // Debug version. -JM
273  clear();
274  alct->run(w_times); // run anode LCT
275  clct->run(hs_times, ds_times); // run cathodeLCT
276 
277  int bx_alct_matched = 0;
278  for (int bx_clct = 0; bx_clct < CSCCathodeLCTProcessor::MAX_CLCT_BINS;
279  bx_clct++) {
280  if (clct->bestCLCT[bx_clct].isValid()) {
281  bool is_matched = false;
282  int bx_alct_start = bx_clct - match_trig_window_size/2;
283  int bx_alct_stop = bx_clct + match_trig_window_size/2;
284  // Empirical correction to match 2009 collision data (firmware change?)
285  if (!isSLHC) bx_alct_stop += match_trig_window_size%2;
286 
287  for (int bx_alct = bx_alct_start; bx_alct <= bx_alct_stop; bx_alct++) {
288  if (bx_alct < 0 || bx_alct >= CSCAnodeLCTProcessor::MAX_ALCT_BINS)
289  continue;
290  if (alct->bestALCT[bx_alct].isValid()) {
291  correlateLCTs(alct->bestALCT[bx_alct], alct->secondALCT[bx_alct],
292  clct->bestCLCT[bx_clct], clct->secondCLCT[bx_clct]);
293  is_matched = true;
294  bx_alct_matched = bx_alct;
295  break;
296  }
297  }
298  // No ALCT within the match time interval found: report CLCT-only LCT
299  // (use dummy ALCTs).
300  if (!is_matched) {
301  correlateLCTs(alct->bestALCT[bx_clct], alct->secondALCT[bx_clct],
302  clct->bestCLCT[bx_clct], clct->secondCLCT[bx_clct]);
303  }
304  }
305  // No valid CLCTs; attempt to make ALCT-only LCT (use dummy CLCTs).
306  else {
307  int bx_alct = bx_clct - match_trig_window_size/2;
308  if (bx_alct >= 0 && bx_alct > bx_alct_matched) {
309  if (alct->bestALCT[bx_alct].isValid()) {
310  correlateLCTs(alct->bestALCT[bx_alct], alct->secondALCT[bx_alct],
311  clct->bestCLCT[bx_clct], clct->secondCLCT[bx_clct]);
312  }
313  }
314  }
315  }
316 }
317 
318 void
320  const CSCComparatorDigiCollection* compdc) {
321  clear();
322  if (alct && clct) {
323  {
324  std::vector<CSCALCTDigi> alctV = alct->run(wiredc); // run anodeLCT
325  }
326  {
327  std::vector<CSCCLCTDigi> clctV = clct->run(compdc); // run cathodeLCT
328  }
329 
330  int used_alct_mask[20];
331  for (int a=0;a<20;++a) used_alct_mask[a]=0;
332 
333  int bx_alct_matched = 0; // bx of last matched ALCT
334  for (int bx_clct = 0; bx_clct < CSCCathodeLCTProcessor::MAX_CLCT_BINS;
335  bx_clct++) {
336  // There should be at least one valid ALCT or CLCT for a
337  // correlated LCT to be formed. Decision on whether to reject
338  // non-complete LCTs (and if yes of which type) is made further
339  // upstream.
340  if (clct->bestCLCT[bx_clct].isValid()) {
341  // Look for ALCTs within the match-time window. The window is
342  // centered at the CLCT bx; therefore, we make an assumption
343  // that anode and cathode hits are perfectly synchronized. This
344  // is always true for MC, but only an approximation when the
345  // data is analyzed (which works fairly good as long as wide
346  // windows are used). To get rid of this assumption, one would
347  // need to access "full BX" words, which are not readily
348  // available.
349  bool is_matched = false;
350  int bx_alct_start = bx_clct - match_trig_window_size/2;
351  int bx_alct_stop = bx_clct + match_trig_window_size/2;
352  // Empirical correction to match 2009 collision data (firmware change?)
353  // (but don't do it for SLHC case, assume it would not be there)
354  if (!isSLHC) bx_alct_stop += match_trig_window_size%2;
355 
356  for (int bx_alct = bx_alct_start; bx_alct <= bx_alct_stop; bx_alct++) {
357  if (bx_alct < 0 || bx_alct >= CSCAnodeLCTProcessor::MAX_ALCT_BINS)
358  continue;
359  // default: do not reuse ALCTs that were used with previous CLCTs
360  if (drop_used_alcts && used_alct_mask[bx_alct]) continue;
361  if (alct->bestALCT[bx_alct].isValid()) {
362  if (infoV > 1) LogTrace("CSCMotherboard")
363  << "Successful ALCT-CLCT match: bx_clct = " << bx_clct
364  << "; match window: [" << bx_alct_start << "; " << bx_alct_stop
365  << "]; bx_alct = " << bx_alct;
366  correlateLCTs(alct->bestALCT[bx_alct], alct->secondALCT[bx_alct],
367  clct->bestCLCT[bx_clct], clct->secondCLCT[bx_clct]);
368  used_alct_mask[bx_alct] += 1;
369  is_matched = true;
370  bx_alct_matched = bx_alct;
371  break;
372  }
373  }
374  // No ALCT within the match time interval found: report CLCT-only LCT
375  // (use dummy ALCTs).
376  if (!is_matched) {
377  if (infoV > 1) LogTrace("CSCMotherboard")
378  << "Unsuccessful ALCT-CLCT match (CLCT only): bx_clct = "
379  << bx_clct << "; match window: [" << bx_alct_start
380  << "; " << bx_alct_stop << "]";
381  correlateLCTs(alct->bestALCT[bx_clct], alct->secondALCT[bx_clct],
382  clct->bestCLCT[bx_clct], clct->secondCLCT[bx_clct]);
383  }
384  }
385  // No valid CLCTs; attempt to make ALCT-only LCT. Use only ALCTs
386  // which have zeroth chance to be matched at later cathode times.
387  // (I am not entirely sure this perfectly matches the firmware logic.)
388  // Use dummy CLCTs.
389  else {
390  int bx_alct = bx_clct - match_trig_window_size/2;
391  if (bx_alct >= 0 && bx_alct > bx_alct_matched) {
392  if (alct->bestALCT[bx_alct].isValid()) {
393  if (infoV > 1) LogTrace("CSCMotherboard")
394  << "Unsuccessful ALCT-CLCT match (ALCT only): bx_alct = "
395  << bx_alct;
396  correlateLCTs(alct->bestALCT[bx_alct], alct->secondALCT[bx_alct],
397  clct->bestCLCT[bx_clct], clct->secondCLCT[bx_clct]);
398  }
399  }
400  }
401  }
402 
403  if (infoV > 0) {
404  for (int bx = 0; bx < MAX_LCT_BINS; bx++) {
405  if (firstLCT[bx].isValid())
406  LogDebug("CSCMotherboard") << firstLCT[bx];
407  if (secondLCT[bx].isValid())
408  LogDebug("CSCMotherboard") << secondLCT[bx];
409  }
410  }
411  }
412  else {
413  if (infoV >= 0) edm::LogError("L1CSCTPEmulatorSetupError")
414  << "+++ run() called for non-existing ALCT/CLCT processor! +++ \n";
415  }
416 }
417 
418 // Returns vector of read-out correlated LCTs, if any. Starts with
419 // the vector of all found LCTs and selects the ones in the read-out
420 // time window.
421 std::vector<CSCCorrelatedLCTDigi> CSCMotherboard::readoutLCTs() {
422  std::vector<CSCCorrelatedLCTDigi> tmpV;
423 
424  // The start time of the L1A*LCT coincidence window should be related
425  // to the fifo_pretrig parameter, but I am not completely sure how.
426  // Just choose it such that the window is centered at bx=7. This may
427  // need further tweaking if the value of tmb_l1a_window_size changes.
428  //static int early_tbins = 4;
429 
430  // Empirical correction to match 2009 collision data (firmware change?)
431  static int lct_bins = tmb_l1a_window_size;
432  static int late_tbins = early_tbins + lct_bins;
433 
434  static int ifois = 0;
435  if (ifois == 0) {
436  if (infoV >= 0 && early_tbins < 0) {
437  edm::LogWarning("L1CSCTPEmulatorSuspiciousParameters")
438  << "+++ early_tbins = " << early_tbins
439  << "; in-time LCTs are not getting read-out!!! +++" << "\n";
440  }
441 
442  if (late_tbins > MAX_LCT_BINS-1) {
443  if (infoV >= 0) edm::LogWarning("L1CSCTPEmulatorSuspiciousParameters")
444  << "+++ Allowed range of time bins, [0-" << late_tbins
445  << "] exceeds max allowed, " << MAX_LCT_BINS-1 << " +++\n"
446  << "+++ Set late_tbins to max allowed +++\n";
447  late_tbins = MAX_LCT_BINS-1;
448  }
449  ifois = 1;
450  }
451 
452  // Start from the vector of all found correlated LCTs and select
453  // those within the LCT*L1A coincidence window.
454  int bx_readout = -1;
455  std::vector<CSCCorrelatedLCTDigi> all_lcts = getLCTs();
456  for (std::vector <CSCCorrelatedLCTDigi>::const_iterator plct =
457  all_lcts.begin(); plct != all_lcts.end(); plct++) {
458  if (!plct->isValid()) continue;
459 
460  int bx = (*plct).getBX();
461  // Skip LCTs found too early relative to L1Accept.
462  if (bx <= early_tbins) {
463  if (infoV > 1) LogDebug("CSCMotherboard")
464  << " Do not report correlated LCT on key halfstrip "
465  << plct->getStrip() << " and key wire " << plct->getKeyWG()
466  << ": found at bx " << bx << ", whereas the earliest allowed bx is "
467  << early_tbins+1;
468  continue;
469  }
470 
471  // Skip LCTs found too late relative to L1Accept.
472  if (bx > late_tbins) {
473  if (infoV > 1) LogDebug("CSCMotherboard")
474  << " Do not report correlated LCT on key halfstrip "
475  << plct->getStrip() << " and key wire " << plct->getKeyWG()
476  << ": found at bx " << bx << ", whereas the latest allowed bx is "
477  << late_tbins;
478  continue;
479  }
480 
481  // If (readout_earliest_2) take only LCTs in the earliest bx in the read-out window:
482  // in digi->raw step, LCTs have to be packed into the TMB header, and
483  // currently there is room just for two.
484  if (readout_earliest_2) {
485  if (bx_readout == -1 || bx == bx_readout) {
486  tmpV.push_back(*plct);
487  if (bx_readout == -1) bx_readout = bx;
488  }
489  }
490  // if readout_earliest_2 == false, save all LCTs
491  else tmpV.push_back(*plct);
492  }
493  return tmpV;
494 }
495 
496 // Returns vector of all found correlated LCTs, if any.
497 std::vector<CSCCorrelatedLCTDigi> CSCMotherboard::getLCTs() {
498  std::vector<CSCCorrelatedLCTDigi> tmpV;
499 
500  bool me11 = (theStation == 1 &&
502  theTrigChamber)==1);
503 
504  // Do not report LCTs found in ME1/A if mpc_block_me1/a is set.
505  for (int bx = 0; bx < MAX_LCT_BINS; bx++) {
506  if (firstLCT[bx].isValid())
507  if (!mpc_block_me1a || (!me11 || firstLCT[bx].getStrip() <= 127))
508  tmpV.push_back(firstLCT[bx]);
509  if (secondLCT[bx].isValid())
510  if (!mpc_block_me1a || (!me11 || secondLCT[bx].getStrip() <= 127))
511  tmpV.push_back(secondLCT[bx]);
512  }
513  return tmpV;
514 }
515 
517  CSCALCTDigi secondALCT,
518  CSCCLCTDigi bestCLCT,
519  CSCCLCTDigi secondCLCT) {
520 
521  bool anodeBestValid = bestALCT.isValid();
522  bool anodeSecondValid = secondALCT.isValid();
523  bool cathodeBestValid = bestCLCT.isValid();
524  bool cathodeSecondValid = secondCLCT.isValid();
525 
526  if (anodeBestValid && !anodeSecondValid) secondALCT = bestALCT;
527  if (!anodeBestValid && anodeSecondValid) bestALCT = secondALCT;
528  if (cathodeBestValid && !cathodeSecondValid) secondCLCT = bestCLCT;
529  if (!cathodeBestValid && cathodeSecondValid) bestCLCT = secondCLCT;
530 
531  // ALCT-CLCT matching conditions are defined by "trig_enable" configuration
532  // parameters.
533  if ((alct_trig_enable && bestALCT.isValid()) ||
534  (clct_trig_enable && bestCLCT.isValid()) ||
535  (match_trig_enable && bestALCT.isValid() && bestCLCT.isValid())) {
536  CSCCorrelatedLCTDigi lct = constructLCTs(bestALCT, bestCLCT);
537  int bx = lct.getBX();
538  if (bx >= 0 && bx < MAX_LCT_BINS) {
539  firstLCT[bx] = lct;
540  firstLCT[bx].setTrknmb(1);
541  }
542  else {
543  if (infoV > 0) edm::LogWarning("L1CSCTPEmulatorOutOfTimeLCT")
544  << "+++ Bx of first LCT candidate, " << bx
545  << ", is not within the allowed range, [0-" << MAX_LCT_BINS-1
546  << "); skipping it... +++\n";
547  }
548  }
549 
550  if (((secondALCT != bestALCT) || (secondCLCT != bestCLCT)) &&
551  ((alct_trig_enable && secondALCT.isValid()) ||
552  (clct_trig_enable && secondCLCT.isValid()) ||
553  (match_trig_enable && secondALCT.isValid() && secondCLCT.isValid()))) {
554  CSCCorrelatedLCTDigi lct = constructLCTs(secondALCT, secondCLCT);
555  int bx = lct.getBX();
556  if (bx >= 0 && bx < MAX_LCT_BINS) {
557  secondLCT[bx] = lct;
558  secondLCT[bx].setTrknmb(2);
559  }
560  else {
561  if (infoV > 0) edm::LogWarning("L1CSCTPEmulatorOutOfTimeLCT")
562  << "+++ Bx of second LCT candidate, " << bx
563  << ", is not within the allowed range, [0-" << MAX_LCT_BINS-1
564  << "); skipping it... +++\n";
565  }
566  }
567 }
568 
569 // This method calculates all the TMB words and then passes them to the
570 // constructor of correlated LCTs.
572  const CSCCLCTDigi& cLCT) {
573  // CLCT pattern number
574  unsigned int pattern = encodePattern(cLCT.getPattern(), cLCT.getStripType());
575 
576  // LCT quality number
577  unsigned int quality = findQuality(aLCT, cLCT);
578 
579  // Bunch crossing: get it from cathode LCT if anode LCT is not there.
580  int bx = aLCT.isValid() ? aLCT.getBX() : cLCT.getBX();
581 
582  // construct correlated LCT; temporarily assign track number of 0.
583  int trknmb = 0;
584  CSCCorrelatedLCTDigi thisLCT(trknmb, 1, quality, aLCT.getKeyWG(),
585  cLCT.getKeyStrip(), pattern, cLCT.getBend(),
586  bx, 0, 0, 0, theTrigChamber);
587  return thisLCT;
588 }
589 
590 // CLCT pattern number: encodes the pattern number itself and
591 // whether the pattern consists of half-strips or di-strips.
592 unsigned int CSCMotherboard::encodePattern(const int ptn,
593  const int stripType) {
594  const int kPatternBitWidth = 4;
595  unsigned int pattern;
596 
597  if (!isTMB07) {
598  // Cathode pattern number is a kPatternBitWidth-1 bit word.
599  pattern = (abs(ptn) & ((1<<(kPatternBitWidth-1))-1));
600 
601  // The pattern has the MSB (4th bit in the default version) set if it
602  // consists of half-strips.
603  if (stripType) {
604  pattern = pattern | (1<<(kPatternBitWidth-1));
605  }
606  }
607  else {
608  // In the TMB07 firmware, LCT pattern is just a 4-bit CLCT pattern.
609  pattern = (abs(ptn) & ((1<<kPatternBitWidth)-1));
610  }
611 
612  return pattern;
613 }
614 
615 // 4-bit LCT quality number. Definition can be found in
616 // http://www.phys.ufl.edu/~acosta/tb/tmb_quality.txt. Made by TMB lookup
617 // tables and used for MPC sorting.
618 unsigned int CSCMotherboard::findQuality(const CSCALCTDigi& aLCT,
619  const CSCCLCTDigi& cLCT) {
620  unsigned int quality = 0;
621 
622  if (!isTMB07) {
623  bool isDistrip = (cLCT.getStripType() == 0);
624 
625  if (aLCT.isValid() && !(cLCT.isValid())) { // no CLCT
626  if (aLCT.getAccelerator()) {quality = 1;}
627  else {quality = 3;}
628  }
629  else if (!(aLCT.isValid()) && cLCT.isValid()) { // no ALCT
630  if (isDistrip) {quality = 4;}
631  else {quality = 5;}
632  }
633  else if (aLCT.isValid() && cLCT.isValid()) { // both ALCT and CLCT
634  if (aLCT.getAccelerator()) {quality = 2;} // accelerator muon
635  else { // collision muon
636  // CLCT quality is, in fact, the number of layers hit, so subtract 3
637  // to get quality analogous to ALCT one.
638  int sumQual = aLCT.getQuality() + (cLCT.getQuality()-3);
639  if (sumQual < 1 || sumQual > 6) {
640  if (infoV >= 0) edm::LogWarning("L1CSCTPEmulatorWrongValues")
641  << "+++ findQuality: sumQual = " << sumQual << "+++ \n";
642  }
643  if (isDistrip) { // distrip pattern
644  if (sumQual == 2) {quality = 6;}
645  else if (sumQual == 3) {quality = 7;}
646  else if (sumQual == 4) {quality = 8;}
647  else if (sumQual == 5) {quality = 9;}
648  else if (sumQual == 6) {quality = 10;}
649  }
650  else { // halfstrip pattern
651  if (sumQual == 2) {quality = 11;}
652  else if (sumQual == 3) {quality = 12;}
653  else if (sumQual == 4) {quality = 13;}
654  else if (sumQual == 5) {quality = 14;}
655  else if (sumQual == 6) {quality = 15;}
656  }
657  }
658  }
659  }
660 #ifdef OLD
661  else {
662  // Temporary definition, used until July 2008.
663  // First if statement is fictitious, just to help the CSC TF emulator
664  // handle such cases (one needs to make sure they will be accounted for
665  // in the new quality definition.
666  if (!(aLCT.isValid()) || !(cLCT.isValid())) {
667  if (aLCT.isValid() && !(cLCT.isValid())) quality = 1; // no CLCT
668  else if (!(aLCT.isValid()) && cLCT.isValid()) quality = 2; // no ALCT
669  else quality = 0; // both absent; should never happen.
670  }
671  else {
672  // Sum of ALCT and CLCT quality bits. CLCT quality is, in fact, the
673  // number of layers hit, so subtract 3 to put it to the same footing as
674  // the ALCT quality.
675  int sumQual = aLCT.getQuality() + (cLCT.getQuality()-3);
676  if (sumQual < 1 || sumQual > 6) {
677  if (infoV >= 0) edm::LogWarning("L1CSCTPEmulatorWrongValues")
678  << "+++ findQuality: Unexpected sumQual = " << sumQual << "+++\n";
679  }
680 
681  // LCT quality is basically the sum of ALCT and CLCT qualities, but split
682  // in two groups depending on the CLCT pattern id (higher quality for
683  // straighter patterns).
684  int offset = 0;
685  if (cLCT.getPattern() <= 7) offset = 4;
686  else offset = 9;
687  quality = offset + sumQual;
688  }
689  }
690 #endif
691  else {
692  // 2008 definition.
693  if (!(aLCT.isValid()) || !(cLCT.isValid())) {
694  if (aLCT.isValid() && !(cLCT.isValid())) quality = 1; // no CLCT
695  else if (!(aLCT.isValid()) && cLCT.isValid()) quality = 2; // no ALCT
696  else quality = 0; // both absent; should never happen.
697  }
698  else {
699  int pattern = cLCT.getPattern();
700  if (pattern == 1) quality = 3; // layer-trigger in CLCT
701  else {
702  // CLCT quality is the number of layers hit minus 3.
703  // CLCT quality is the number of layers hit.
704  bool a4 = (aLCT.getQuality() >= 1);
705  bool c4 = (cLCT.getQuality() >= 4);
706  // quality = 4; "reserved for low-quality muons in future"
707  if (!a4 && !c4) quality = 5; // marginal anode and cathode
708  else if ( a4 && !c4) quality = 6; // HQ anode, but marginal cathode
709  else if (!a4 && c4) quality = 7; // HQ cathode, but marginal anode
710  else if ( a4 && c4) {
711  if (aLCT.getAccelerator()) quality = 8; // HQ muon, but accel ALCT
712  else {
713  // quality = 9; "reserved for HQ muons with future patterns
714  // quality = 10; "reserved for HQ muons with future patterns
715  if (pattern == 2 || pattern == 3) quality = 11;
716  else if (pattern == 4 || pattern == 5) quality = 12;
717  else if (pattern == 6 || pattern == 7) quality = 13;
718  else if (pattern == 8 || pattern == 9) quality = 14;
719  else if (pattern == 10) quality = 15;
720  else {
721  if (infoV >= 0) edm::LogWarning("L1CSCTPEmulatorWrongValues")
722  << "+++ findQuality: Unexpected CLCT pattern id = "
723  << pattern << "+++\n";
724  }
725  }
726  }
727  }
728  }
729  }
730  return quality;
731 }
732 
734  unsigned int lctPattern, lctQuality;
735  for (int pattern = 0; pattern < 8; pattern++) {
736  for (int bend = 0; bend < 2; bend++) {
737  for (int cfeb = 0; cfeb < 5; cfeb++) {
738  for (int strip = 0; strip < 32; strip++) {
739  for (int bx = 0; bx < 7; bx++) {
740  for (int stripType = 0; stripType < 2; stripType++) {
741  for (int quality = 3; quality < 7; quality++) {
742  CSCCLCTDigi cLCT(1, quality, pattern, stripType, bend,
743  strip, cfeb, bx);
744  lctPattern = encodePattern(cLCT.getPattern(),
745  cLCT.getStripType());
746  for (int aQuality = 0; aQuality < 4; aQuality++) {
747  for (int wireGroup = 0; wireGroup < 120; wireGroup++) {
748  for (int abx = 0; abx < 7; abx++) {
749  CSCALCTDigi aLCT(1, aQuality, 0, 1, wireGroup, abx);
750  lctQuality = findQuality(aLCT, cLCT);
752  thisLCT(0, 1, lctQuality, aLCT.getKeyWG(),
753  cLCT.getKeyStrip(), lctPattern, cLCT.getBend(),
754  aLCT.getBX());
755  if (lctPattern != static_cast<unsigned int>(thisLCT.getPattern()) )
756  LogTrace("CSCMotherboard")
757  << "pattern mismatch: " << lctPattern
758  << " " << thisLCT.getPattern();
759  if (bend != thisLCT.getBend())
760  LogTrace("CSCMotherboard")
761  << "bend mismatch: " << bend
762  << " " << thisLCT.getBend();
763  int key_strip = 32*cfeb + strip;
764  if (key_strip != thisLCT.getStrip())
765  LogTrace("CSCMotherboard")
766  << "strip mismatch: " << key_strip
767  << " " << thisLCT.getStrip();
768  if (wireGroup != thisLCT.getKeyWG())
769  LogTrace("CSCMotherboard")
770  << "wire group mismatch: " << wireGroup
771  << " " << thisLCT.getKeyWG();
772  if (abx != thisLCT.getBX())
773  LogTrace("CSCMotherboard")
774  << "bx mismatch: " << abx << " " << thisLCT.getBX();
775  if (lctQuality != static_cast<unsigned int>(thisLCT.getQuality()))
776  LogTrace("CSCMotherboard")
777  << "quality mismatch: " << lctQuality
778  << " " << thisLCT.getQuality();
779  }
780  }
781  }
782  }
783  }
784  }
785  }
786  }
787  }
788  }
789 }
790 
792  std::ostringstream strm;
793  strm << "\n";
794  strm << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
795  strm << "+ TMB configuration parameters: +\n";
796  strm << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
797  strm << " mpc_block_me1a [block/not block triggers which come from ME1/A] = "
798  << mpc_block_me1a << "\n";
799  strm << " alct_trig_enable [allow ALCT-only triggers] = "
800  << alct_trig_enable << "\n";
801  strm << " clct_trig_enable [allow CLCT-only triggers] = "
802  << clct_trig_enable << "\n";
803  strm << " match_trig_enable [allow matched ALCT-CLCT triggers] = "
804  << match_trig_enable << "\n";
805  strm << " match_trig_window_size [ALCT-CLCT match window width, in 25 ns] = "
806  << match_trig_window_size << "\n";
807  strm << " tmb_l1a_window_size [L1Accept window width, in 25 ns bins] = "
808  << tmb_l1a_window_size << "\n";
809  strm << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
810  LogDebug("CSCMotherboard") << strm.str();
811  //std::cerr << strm.str()<<std::endl;
812 }
#define LogDebug(id)
int getQuality() const
return quality of a pattern (number of layers hit!)
Definition: CSCCLCTDigi.h:33
CSCCLCTDigi secondCLCT[MAX_CLCT_BINS]
T getParameter(std::string const &) const
T getUntrackedParameter(std::string const &, T const &) const
CSCCorrelatedLCTDigi constructLCTs(const CSCALCTDigi &aLCT, const CSCCLCTDigi &cLCT)
void run(const std::vector< int > w_time[CSCConstants::NUM_LAYERS][CSCConstants::MAX_NUM_WIRES], const std::vector< int > hs_times[CSCConstants::NUM_LAYERS][CSCConstants::NUM_HALF_STRIPS], const std::vector< int > ds_times[CSCConstants::NUM_LAYERS][CSCConstants::NUM_HALF_STRIPS])
unsigned int clct_trig_enable
std::vector< CSCCorrelatedLCTDigi > getLCTs()
std::vector< CSCCorrelatedLCTDigi > readoutLCTs()
CSCALCTDigi bestALCT[MAX_ALCT_BINS]
unsigned int match_trig_window_size
CSCALCTDigi secondALCT[MAX_ALCT_BINS]
const unsigned theTrigChamber
static const unsigned int def_alct_trig_enable
bool isValid() const
check ALCT validity (1 - valid ALCT)
Definition: CSCALCTDigi.h:30
static const unsigned int def_mpc_block_me1a
unsigned int tmbClctTrigEnable() const
unsigned int findQuality(const CSCALCTDigi &aLCT, const CSCCLCTDigi &cLCT)
list pattern
Definition: chain.py:104
static const unsigned int def_clct_trig_enable
CSCCLCTDigi bestCLCT[MAX_CLCT_BINS]
void setConfigParameters(const CSCDBL1TPParameters *conf)
static int ringFromTriggerLabels(int station, int triggerCSCID)
int getStripType() const
return striptype
Definition: CSCCLCTDigi.h:39
int getBend() const
return bend
Definition: CSCCLCTDigi.h:42
unsigned int mpc_block_me1a
unsigned int tmbTmbL1aWindowSize() const
void correlateLCTs(CSCALCTDigi bestALCT, CSCALCTDigi secondALCT, CSCCLCTDigi bestCLCT, CSCCLCTDigi secondCLCT)
const unsigned theStation
unsigned int tmbMatchTrigWindowSize() const
CSCCorrelatedLCTDigi secondLCT[MAX_LCT_BINS]
static const unsigned int def_tmb_l1a_window_size
int getBX() const
return BX
Definition: CSCCLCTDigi.h:51
unsigned int tmbAlctTrigEnable() const
unsigned int encodePattern(const int ptn, const int highPt)
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
#define LogTrace(id)
int getBX() const
return BX
CSCAnodeLCTProcessor * alct
tuple conf
Definition: dbtoconf.py:185
int getBX() const
return BX - five low bits of BXN counter tagged by the ALCT
Definition: CSCALCTDigi.h:48
CSCCorrelatedLCTDigi firstLCT[MAX_LCT_BINS]
unsigned int tmbMpcBlockMe1a() const
int getQuality() const
return quality of a pattern
Definition: CSCALCTDigi.h:33
int getAccelerator() const
Definition: CSCALCTDigi.h:37
int getPattern() const
return pattern
Definition: CSCCLCTDigi.h:36
static const unsigned int def_match_trig_window_size
unsigned int alct_trig_enable
CSCCathodeLCTProcessor * clct
std::vector< CSCCLCTDigi > run(const CSCComparatorDigiCollection *compdc)
double a
Definition: hdecay.h:121
void dumpConfigParams() const
int getKeyStrip() const
Definition: CSCCLCTDigi.h:65
void setConfigParameters(const CSCDBL1TPParameters *conf)
std::vector< CSCALCTDigi > run(const CSCWireDigiCollection *wiredc)
void setTrknmb(const uint16_t number)
Set track number (1,2) after sorting LCTs.
int getKeyWG() const
return key wire group
Definition: CSCALCTDigi.h:45
static const unsigned int def_match_trig_enable
void setConfigParameters(const CSCDBL1TPParameters *conf)
unsigned int tmbMatchTrigEnable() const