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