CMS 3D CMS Logo

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