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