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