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 
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),
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  if (alct) alct->clear();
200  if (clct) clct->clear();
201  for (int bx = 0; bx < MAX_LCT_BINS; bx++) {
202  firstLCT[bx].clear();
203  secondLCT[bx].clear();
204  }
205 }
206 
207 // Set configuration parameters obtained via EventSetup mechanism.
209  static 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  alct->run(w_times); // run anode LCT
300  clct->run(hs_times, ds_times); // run cathodeLCT
301 
302  int bx_alct_matched = 0;
303  for (int bx_clct = 0; bx_clct < CSCCathodeLCTProcessor::MAX_CLCT_BINS;
304  bx_clct++) {
305  if (clct->bestCLCT[bx_clct].isValid()) {
306  bool is_matched = false;
307  int bx_alct_start = bx_clct - match_trig_window_size/2;
308  int bx_alct_stop = bx_clct + match_trig_window_size/2;
309  // Empirical correction to match 2009 collision data (firmware change?)
310  if (!isSLHC) bx_alct_stop += match_trig_window_size%2;
311 
312  for (int bx_alct = bx_alct_start; bx_alct <= bx_alct_stop; bx_alct++) {
313  if (bx_alct < 0 || bx_alct >= CSCAnodeLCTProcessor::MAX_ALCT_BINS)
314  continue;
315  if (alct->bestALCT[bx_alct].isValid()) {
316  correlateLCTs(alct->bestALCT[bx_alct], alct->secondALCT[bx_alct],
317  clct->bestCLCT[bx_clct], clct->secondCLCT[bx_clct]);
318  is_matched = true;
319  bx_alct_matched = bx_alct;
320  break;
321  }
322  }
323  // No ALCT within the match time interval found: report CLCT-only LCT
324  // (use dummy ALCTs).
325  if (!is_matched) {
326  correlateLCTs(alct->bestALCT[bx_clct], alct->secondALCT[bx_clct],
327  clct->bestCLCT[bx_clct], clct->secondCLCT[bx_clct]);
328  }
329  }
330  // No valid CLCTs; attempt to make ALCT-only LCT (use dummy CLCTs).
331  else {
332  int bx_alct = bx_clct - match_trig_window_size/2;
333  if (bx_alct >= 0 && bx_alct > bx_alct_matched) {
334  if (alct->bestALCT[bx_alct].isValid()) {
335  correlateLCTs(alct->bestALCT[bx_alct], alct->secondALCT[bx_alct],
336  clct->bestCLCT[bx_clct], clct->secondCLCT[bx_clct]);
337  }
338  }
339  }
340  }
341 }
342 
343 void
345  const CSCComparatorDigiCollection* compdc) {
346  clear();
347  if (alct && clct) {
348  {
349  std::vector<CSCALCTDigi> alctV = alct->run(wiredc); // run anodeLCT
350  }
351  {
352  std::vector<CSCCLCTDigi> clctV = clct->run(compdc); // run cathodeLCT
353  }
354 
355  int used_alct_mask[20];
356  for (int a=0;a<20;++a) used_alct_mask[a]=0;
357 
358  int bx_alct_matched = 0; // bx of last matched ALCT
359  for (int bx_clct = 0; bx_clct < CSCCathodeLCTProcessor::MAX_CLCT_BINS;
360  bx_clct++) {
361  // There should be at least one valid ALCT or CLCT for a
362  // correlated LCT to be formed. Decision on whether to reject
363  // non-complete LCTs (and if yes of which type) is made further
364  // upstream.
365  if (clct->bestCLCT[bx_clct].isValid()) {
366  // Look for ALCTs within the match-time window. The window is
367  // centered at the CLCT bx; therefore, we make an assumption
368  // that anode and cathode hits are perfectly synchronized. This
369  // is always true for MC, but only an approximation when the
370  // data is analyzed (which works fairly good as long as wide
371  // windows are used). To get rid of this assumption, one would
372  // need to access "full BX" words, which are not readily
373  // available.
374  bool is_matched = false;
375  int bx_alct_start = bx_clct - match_trig_window_size/2;
376  int bx_alct_stop = bx_clct + match_trig_window_size/2;
377  // Empirical correction to match 2009 collision data (firmware change?)
378  // (but don't do it for SLHC case, assume it would not be there)
379  if (!isSLHC) bx_alct_stop += match_trig_window_size%2;
380 
381  for (int bx_alct = bx_alct_start; bx_alct <= bx_alct_stop; bx_alct++) {
382  if (bx_alct < 0 || bx_alct >= CSCAnodeLCTProcessor::MAX_ALCT_BINS)
383  continue;
384  // default: do not reuse ALCTs that were used with previous CLCTs
385  if (drop_used_alcts && used_alct_mask[bx_alct]) continue;
386  if (alct->bestALCT[bx_alct].isValid()) {
387  if (infoV > 1) LogTrace("CSCMotherboard")
388  << "Successful ALCT-CLCT match: bx_clct = " << bx_clct
389  << "; match window: [" << bx_alct_start << "; " << bx_alct_stop
390  << "]; bx_alct = " << bx_alct;
391  correlateLCTs(alct->bestALCT[bx_alct], alct->secondALCT[bx_alct],
392  clct->bestCLCT[bx_clct], clct->secondCLCT[bx_clct]);
393  used_alct_mask[bx_alct] += 1;
394  is_matched = true;
395  bx_alct_matched = bx_alct;
396  break;
397  }
398  }
399  // No ALCT within the match time interval found: report CLCT-only LCT
400  // (use dummy ALCTs).
401  if (!is_matched) {
402  if (infoV > 1) LogTrace("CSCMotherboard")
403  << "Unsuccessful ALCT-CLCT match (CLCT only): bx_clct = "
404  << bx_clct << "; match window: [" << bx_alct_start
405  << "; " << bx_alct_stop << "]";
406  correlateLCTs(alct->bestALCT[bx_clct], alct->secondALCT[bx_clct],
407  clct->bestCLCT[bx_clct], clct->secondCLCT[bx_clct]);
408  }
409  }
410  // No valid CLCTs; attempt to make ALCT-only LCT. Use only ALCTs
411  // which have zeroth chance to be matched at later cathode times.
412  // (I am not entirely sure this perfectly matches the firmware logic.)
413  // Use dummy CLCTs.
414  else {
415  int bx_alct = bx_clct - match_trig_window_size/2;
416  if (bx_alct >= 0 && bx_alct > bx_alct_matched) {
417  if (alct->bestALCT[bx_alct].isValid()) {
418  if (infoV > 1) LogTrace("CSCMotherboard")
419  << "Unsuccessful ALCT-CLCT match (ALCT only): bx_alct = "
420  << bx_alct;
421  correlateLCTs(alct->bestALCT[bx_alct], alct->secondALCT[bx_alct],
422  clct->bestCLCT[bx_clct], clct->secondCLCT[bx_clct]);
423  }
424  }
425  }
426  }
427 
428  if (infoV > 0) {
429  for (int bx = 0; bx < MAX_LCT_BINS; bx++) {
430  if (firstLCT[bx].isValid())
431  LogDebug("CSCMotherboard") << firstLCT[bx];
432  if (secondLCT[bx].isValid())
433  LogDebug("CSCMotherboard") << secondLCT[bx];
434  }
435  }
436  }
437  else {
438  if (infoV >= 0) edm::LogError("L1CSCTPEmulatorSetupError")
439  << "+++ run() called for non-existing ALCT/CLCT processor! +++ \n";
440  }
441 }
442 
443 // Returns vector of read-out correlated LCTs, if any. Starts with
444 // the vector of all found LCTs and selects the ones in the read-out
445 // time window.
446 std::vector<CSCCorrelatedLCTDigi> CSCMotherboard::readoutLCTs() {
447  std::vector<CSCCorrelatedLCTDigi> tmpV;
448 
449  // The start time of the L1A*LCT coincidence window should be related
450  // to the fifo_pretrig parameter, but I am not completely sure how.
451  // Just choose it such that the window is centered at bx=7. This may
452  // need further tweaking if the value of tmb_l1a_window_size changes.
453  //static int early_tbins = 4;
454 
455  // Empirical correction to match 2009 collision data (firmware change?)
456  static int lct_bins = tmb_l1a_window_size;
457  static int late_tbins = early_tbins + lct_bins;
458 
459  static int ifois = 0;
460  if (ifois == 0) {
461  if (infoV >= 0 && early_tbins < 0) {
462  edm::LogWarning("L1CSCTPEmulatorSuspiciousParameters")
463  << "+++ early_tbins = " << early_tbins
464  << "; in-time LCTs are not getting read-out!!! +++" << "\n";
465  }
466 
467  if (late_tbins > MAX_LCT_BINS-1) {
468  if (infoV >= 0) edm::LogWarning("L1CSCTPEmulatorSuspiciousParameters")
469  << "+++ Allowed range of time bins, [0-" << late_tbins
470  << "] exceeds max allowed, " << MAX_LCT_BINS-1 << " +++\n"
471  << "+++ Set late_tbins to max allowed +++\n";
472  late_tbins = MAX_LCT_BINS-1;
473  }
474  ifois = 1;
475  }
476 
477  // Start from the vector of all found correlated LCTs and select
478  // those within the LCT*L1A coincidence window.
479  int bx_readout = -1;
480  std::vector<CSCCorrelatedLCTDigi> all_lcts = getLCTs();
481  for (std::vector <CSCCorrelatedLCTDigi>::const_iterator plct =
482  all_lcts.begin(); plct != all_lcts.end(); plct++) {
483  if (!plct->isValid()) continue;
484 
485  int bx = (*plct).getBX();
486  // Skip LCTs found too early relative to L1Accept.
487  if (bx <= early_tbins) {
488  if (infoV > 1) LogDebug("CSCMotherboard")
489  << " Do not report correlated LCT on key halfstrip "
490  << plct->getStrip() << " and key wire " << plct->getKeyWG()
491  << ": found at bx " << bx << ", whereas the earliest allowed bx is "
492  << early_tbins+1;
493  continue;
494  }
495 
496  // Skip LCTs found too late relative to L1Accept.
497  if (bx > late_tbins) {
498  if (infoV > 1) LogDebug("CSCMotherboard")
499  << " Do not report correlated LCT on key halfstrip "
500  << plct->getStrip() << " and key wire " << plct->getKeyWG()
501  << ": found at bx " << bx << ", whereas the latest allowed bx is "
502  << late_tbins;
503  continue;
504  }
505 
506  // If (readout_earliest_2) take only LCTs in the earliest bx in the read-out window:
507  // in digi->raw step, LCTs have to be packed into the TMB header, and
508  // currently there is room just for two.
509  if (readout_earliest_2) {
510  if (bx_readout == -1 || bx == bx_readout) {
511  tmpV.push_back(*plct);
512  if (bx_readout == -1) bx_readout = bx;
513  }
514  }
515  // if readout_earliest_2 == false, save all LCTs
516  else tmpV.push_back(*plct);
517  }
518  return tmpV;
519 }
520 
521 // Returns vector of all found correlated LCTs, if any.
522 std::vector<CSCCorrelatedLCTDigi> CSCMotherboard::getLCTs() {
523  std::vector<CSCCorrelatedLCTDigi> tmpV;
524 
525  bool me11 = (theStation == 1 &&
527  theTrigChamber)==1);
528 
529  // Do not report LCTs found in ME1/A if mpc_block_me1/a is set.
530  for (int bx = 0; bx < MAX_LCT_BINS; bx++) {
531  if (firstLCT[bx].isValid())
532  if (!mpc_block_me1a || (!me11 || firstLCT[bx].getStrip() <= 127))
533  tmpV.push_back(firstLCT[bx]);
534  if (secondLCT[bx].isValid())
535  if (!mpc_block_me1a || (!me11 || secondLCT[bx].getStrip() <= 127))
536  tmpV.push_back(secondLCT[bx]);
537  }
538  return tmpV;
539 }
540 
542  CSCALCTDigi secondALCT,
543  CSCCLCTDigi bestCLCT,
544  CSCCLCTDigi secondCLCT) {
545 
546  bool anodeBestValid = bestALCT.isValid();
547  bool anodeSecondValid = secondALCT.isValid();
548  bool cathodeBestValid = bestCLCT.isValid();
549  bool cathodeSecondValid = secondCLCT.isValid();
550 
551  if (anodeBestValid && !anodeSecondValid) secondALCT = bestALCT;
552  if (!anodeBestValid && anodeSecondValid) bestALCT = secondALCT;
553  if (cathodeBestValid && !cathodeSecondValid) secondCLCT = bestCLCT;
554  if (!cathodeBestValid && cathodeSecondValid) bestCLCT = secondCLCT;
555 
556  // ALCT-CLCT matching conditions are defined by "trig_enable" configuration
557  // parameters.
558  if ((alct_trig_enable && bestALCT.isValid()) ||
559  (clct_trig_enable && bestCLCT.isValid()) ||
560  (match_trig_enable && bestALCT.isValid() && bestCLCT.isValid())) {
561  CSCCorrelatedLCTDigi lct = constructLCTs(bestALCT, bestCLCT);
562  int bx = lct.getBX();
563  if (bx >= 0 && bx < MAX_LCT_BINS) {
564  firstLCT[bx] = lct;
565  firstLCT[bx].setTrknmb(1);
566  }
567  else {
568  if (infoV > 0) edm::LogWarning("L1CSCTPEmulatorOutOfTimeLCT")
569  << "+++ Bx of first LCT candidate, " << bx
570  << ", is not within the allowed range, [0-" << MAX_LCT_BINS-1
571  << "); skipping it... +++\n";
572  }
573  }
574 
575  if (((secondALCT != bestALCT) || (secondCLCT != bestCLCT)) &&
576  ((alct_trig_enable && secondALCT.isValid()) ||
577  (clct_trig_enable && secondCLCT.isValid()) ||
578  (match_trig_enable && secondALCT.isValid() && secondCLCT.isValid()))) {
579  CSCCorrelatedLCTDigi lct = constructLCTs(secondALCT, secondCLCT);
580  int bx = lct.getBX();
581  if (bx >= 0 && bx < MAX_LCT_BINS) {
582  secondLCT[bx] = lct;
583  secondLCT[bx].setTrknmb(2);
584  }
585  else {
586  if (infoV > 0) edm::LogWarning("L1CSCTPEmulatorOutOfTimeLCT")
587  << "+++ Bx of second LCT candidate, " << bx
588  << ", is not within the allowed range, [0-" << MAX_LCT_BINS-1
589  << "); skipping it... +++\n";
590  }
591  }
592 }
593 
594 // This method calculates all the TMB words and then passes them to the
595 // constructor of correlated LCTs.
597  const CSCCLCTDigi& cLCT) {
598  // CLCT pattern number
599  unsigned int pattern = encodePattern(cLCT.getPattern(), cLCT.getStripType());
600 
601  // LCT quality number
602  unsigned int quality = findQuality(aLCT, cLCT);
603 
604  // Bunch crossing: get it from cathode LCT if anode LCT is not there.
605  int bx = aLCT.isValid() ? aLCT.getBX() : cLCT.getBX();
606 
607  // construct correlated LCT; temporarily assign track number of 0.
608  int trknmb = 0;
609  CSCCorrelatedLCTDigi thisLCT(trknmb, 1, quality, aLCT.getKeyWG(),
610  cLCT.getKeyStrip(), pattern, cLCT.getBend(),
611  bx, 0, 0, 0, theTrigChamber);
612  return thisLCT;
613 }
614 
615 // CLCT pattern number: encodes the pattern number itself and
616 // whether the pattern consists of half-strips or di-strips.
617 unsigned int CSCMotherboard::encodePattern(const int ptn,
618  const int stripType) {
619  const int kPatternBitWidth = 4;
620  unsigned int pattern;
621 
622  if (!isTMB07) {
623  // Cathode pattern number is a kPatternBitWidth-1 bit word.
624  pattern = (abs(ptn) & ((1<<(kPatternBitWidth-1))-1));
625 
626  // The pattern has the MSB (4th bit in the default version) set if it
627  // consists of half-strips.
628  if (stripType) {
629  pattern = pattern | (1<<(kPatternBitWidth-1));
630  }
631  }
632  else {
633  // In the TMB07 firmware, LCT pattern is just a 4-bit CLCT pattern.
634  pattern = (abs(ptn) & ((1<<kPatternBitWidth)-1));
635  }
636 
637  return pattern;
638 }
639 
640 // 4-bit LCT quality number. Definition can be found in
641 // http://www.phys.ufl.edu/~acosta/tb/tmb_quality.txt. Made by TMB lookup
642 // tables and used for MPC sorting.
643 unsigned int CSCMotherboard::findQuality(const CSCALCTDigi& aLCT,
644  const CSCCLCTDigi& cLCT) {
645  unsigned int quality = 0;
646 
647  if (!isTMB07) {
648  bool isDistrip = (cLCT.getStripType() == 0);
649 
650  if (aLCT.isValid() && !(cLCT.isValid())) { // no CLCT
651  if (aLCT.getAccelerator()) {quality = 1;}
652  else {quality = 3;}
653  }
654  else if (!(aLCT.isValid()) && cLCT.isValid()) { // no ALCT
655  if (isDistrip) {quality = 4;}
656  else {quality = 5;}
657  }
658  else if (aLCT.isValid() && cLCT.isValid()) { // both ALCT and CLCT
659  if (aLCT.getAccelerator()) {quality = 2;} // accelerator muon
660  else { // collision muon
661  // CLCT quality is, in fact, the number of layers hit, so subtract 3
662  // to get quality analogous to ALCT one.
663  int sumQual = aLCT.getQuality() + (cLCT.getQuality()-3);
664  if (sumQual < 1 || sumQual > 6) {
665  if (infoV >= 0) edm::LogWarning("L1CSCTPEmulatorWrongValues")
666  << "+++ findQuality: sumQual = " << sumQual << "+++ \n";
667  }
668  if (isDistrip) { // distrip pattern
669  if (sumQual == 2) {quality = 6;}
670  else if (sumQual == 3) {quality = 7;}
671  else if (sumQual == 4) {quality = 8;}
672  else if (sumQual == 5) {quality = 9;}
673  else if (sumQual == 6) {quality = 10;}
674  }
675  else { // halfstrip pattern
676  if (sumQual == 2) {quality = 11;}
677  else if (sumQual == 3) {quality = 12;}
678  else if (sumQual == 4) {quality = 13;}
679  else if (sumQual == 5) {quality = 14;}
680  else if (sumQual == 6) {quality = 15;}
681  }
682  }
683  }
684  }
685 #ifdef OLD
686  else {
687  // Temporary definition, used until July 2008.
688  // First if statement is fictitious, just to help the CSC TF emulator
689  // handle such cases (one needs to make sure they will be accounted for
690  // in the new quality definition.
691  if (!(aLCT.isValid()) || !(cLCT.isValid())) {
692  if (aLCT.isValid() && !(cLCT.isValid())) quality = 1; // no CLCT
693  else if (!(aLCT.isValid()) && cLCT.isValid()) quality = 2; // no ALCT
694  else quality = 0; // both absent; should never happen.
695  }
696  else {
697  // Sum of ALCT and CLCT quality bits. CLCT quality is, in fact, the
698  // number of layers hit, so subtract 3 to put it to the same footing as
699  // the ALCT quality.
700  int sumQual = aLCT.getQuality() + (cLCT.getQuality()-3);
701  if (sumQual < 1 || sumQual > 6) {
702  if (infoV >= 0) edm::LogWarning("L1CSCTPEmulatorWrongValues")
703  << "+++ findQuality: Unexpected sumQual = " << sumQual << "+++\n";
704  }
705 
706  // LCT quality is basically the sum of ALCT and CLCT qualities, but split
707  // in two groups depending on the CLCT pattern id (higher quality for
708  // straighter patterns).
709  int offset = 0;
710  if (cLCT.getPattern() <= 7) offset = 4;
711  else offset = 9;
712  quality = offset + sumQual;
713  }
714  }
715 #endif
716  else {
717  // 2008 definition.
718  if (!(aLCT.isValid()) || !(cLCT.isValid())) {
719  if (aLCT.isValid() && !(cLCT.isValid())) quality = 1; // no CLCT
720  else if (!(aLCT.isValid()) && cLCT.isValid()) quality = 2; // no ALCT
721  else quality = 0; // both absent; should never happen.
722  }
723  else {
724  int pattern = cLCT.getPattern();
725  if (pattern == 1) quality = 3; // layer-trigger in CLCT
726  else {
727  // CLCT quality is the number of layers hit minus 3.
728  // CLCT quality is the number of layers hit.
729  bool a4 = (aLCT.getQuality() >= 1);
730  bool c4 = (cLCT.getQuality() >= 4);
731  // quality = 4; "reserved for low-quality muons in future"
732  if (!a4 && !c4) quality = 5; // marginal anode and cathode
733  else if ( a4 && !c4) quality = 6; // HQ anode, but marginal cathode
734  else if (!a4 && c4) quality = 7; // HQ cathode, but marginal anode
735  else if ( a4 && c4) {
736  if (aLCT.getAccelerator()) quality = 8; // HQ muon, but accel ALCT
737  else {
738  // quality = 9; "reserved for HQ muons with future patterns
739  // quality = 10; "reserved for HQ muons with future patterns
740  if (pattern == 2 || pattern == 3) quality = 11;
741  else if (pattern == 4 || pattern == 5) quality = 12;
742  else if (pattern == 6 || pattern == 7) quality = 13;
743  else if (pattern == 8 || pattern == 9) quality = 14;
744  else if (pattern == 10) quality = 15;
745  else {
746  if (infoV >= 0) edm::LogWarning("L1CSCTPEmulatorWrongValues")
747  << "+++ findQuality: Unexpected CLCT pattern id = "
748  << pattern << "+++\n";
749  }
750  }
751  }
752  }
753  }
754  }
755  return quality;
756 }
757 
759  unsigned int lctPattern, lctQuality;
760  for (int pattern = 0; pattern < 8; pattern++) {
761  for (int bend = 0; bend < 2; bend++) {
762  for (int cfeb = 0; cfeb < 5; cfeb++) {
763  for (int strip = 0; strip < 32; strip++) {
764  for (int bx = 0; bx < 7; bx++) {
765  for (int stripType = 0; stripType < 2; stripType++) {
766  for (int quality = 3; quality < 7; quality++) {
767  CSCCLCTDigi cLCT(1, quality, pattern, stripType, bend,
768  strip, cfeb, bx);
769  lctPattern = encodePattern(cLCT.getPattern(),
770  cLCT.getStripType());
771  for (int aQuality = 0; aQuality < 4; aQuality++) {
772  for (int wireGroup = 0; wireGroup < 120; wireGroup++) {
773  for (int abx = 0; abx < 7; abx++) {
774  CSCALCTDigi aLCT(1, aQuality, 0, 1, wireGroup, abx);
775  lctQuality = findQuality(aLCT, cLCT);
777  thisLCT(0, 1, lctQuality, aLCT.getKeyWG(),
778  cLCT.getKeyStrip(), lctPattern, cLCT.getBend(),
779  aLCT.getBX());
780  if (lctPattern != static_cast<unsigned int>(thisLCT.getPattern()) )
781  LogTrace("CSCMotherboard")
782  << "pattern mismatch: " << lctPattern
783  << " " << thisLCT.getPattern();
784  if (bend != thisLCT.getBend())
785  LogTrace("CSCMotherboard")
786  << "bend mismatch: " << bend
787  << " " << thisLCT.getBend();
788  int key_strip = 32*cfeb + strip;
789  if (key_strip != thisLCT.getStrip())
790  LogTrace("CSCMotherboard")
791  << "strip mismatch: " << key_strip
792  << " " << thisLCT.getStrip();
793  if (wireGroup != thisLCT.getKeyWG())
794  LogTrace("CSCMotherboard")
795  << "wire group mismatch: " << wireGroup
796  << " " << thisLCT.getKeyWG();
797  if (abx != thisLCT.getBX())
798  LogTrace("CSCMotherboard")
799  << "bx mismatch: " << abx << " " << thisLCT.getBX();
800  if (lctQuality != static_cast<unsigned int>(thisLCT.getQuality()))
801  LogTrace("CSCMotherboard")
802  << "quality mismatch: " << lctQuality
803  << " " << thisLCT.getQuality();
804  }
805  }
806  }
807  }
808  }
809  }
810  }
811  }
812  }
813  }
814 }
815 
817  std::ostringstream strm;
818  strm << "\n";
819  strm << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
820  strm << "+ TMB configuration parameters: +\n";
821  strm << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
822  strm << " mpc_block_me1a [block/not block triggers which come from ME1/A] = "
823  << mpc_block_me1a << "\n";
824  strm << " alct_trig_enable [allow ALCT-only triggers] = "
825  << alct_trig_enable << "\n";
826  strm << " clct_trig_enable [allow CLCT-only triggers] = "
827  << clct_trig_enable << "\n";
828  strm << " match_trig_enable [allow matched ALCT-CLCT triggers] = "
829  << match_trig_enable << "\n";
830  strm << " match_trig_window_size [ALCT-CLCT match window width, in 25 ns] = "
831  << match_trig_window_size << "\n";
832  strm << " tmb_l1a_window_size [L1Accept window width, in 25 ns bins] = "
833  << tmb_l1a_window_size << "\n";
834  strm << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
835  LogDebug("CSCMotherboard") << strm.str();
836 }
837 
838 
839 // compare LCTs by quality
841 {
842  return lct1.getQuality() > lct2.getQuality();
843 }
844 
845 // compare LCTs by GEM bending angle
847 {
848  // return lct1.getGEMDPhi() < lct2.getGEMDPhi();
849  return true;
850 }
#define LogDebug(id)
int getQuality() const
return quality of a pattern (number of layers hit!)
Definition: CSCCLCTDigi.h:33
const unsigned theSector
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()
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
const unsigned theEndcap
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
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: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