CMS 3D CMS Logo

CSCAnodeLCTProcessor.cc
Go to the documentation of this file.
1 //-----------------------------------------------------------------------------
2 //
3 // Class: CSCAnodeLCTProcessor
4 //
5 // Description:
6 // This is the simulation for the Anode LCT Processor for the Level-1
7 // Trigger. This processor consists of several stages:
8 //
9 // 1. Pulse extension of signals coming from wires.
10 // 2. Pretrigger for each key-wire.
11 // 3. Pattern detector if a pretrigger is found for the given key-wire.
12 // 4. Ghost Cancellation Logic (GCL).
13 // 5. Best track search and promotion.
14 // 6. Second best track search and promotion.
15 //
16 // The inputs to the ALCT Processor are wire digis.
17 // The output is up to two ALCT digi words.
18 //
19 // Author List: Benn Tannenbaum (1999), Jason Mumford (2002), Slava Valuev.
20 // Porting from ORCA by S. Valuev (Slava.Valuev@cern.ch),
21 // May 2006.
22 //
23 //
24 // Modifications:
25 //
26 //-----------------------------------------------------------------------------
27 
30 
33 #include <set>
34 
35 //-----------------
36 // Static variables
37 //-----------------
38 
39 /* This is the pattern envelope, which is used to define the collision
40  patterns A and B.
41  pattern_envelope[0][i]=layer;
42  pattern_envelope[1+MEposition][i]=key_wire offset. */
44  //Layer
45  { 0, 0, 0,
46  1, 1,
47  2,
48  3, 3,
49  4, 4, 4,
50  5, 5, 5},
51 
52  //Keywire offset for ME1 and ME2
53  {-2, -1, 0,
54  -1, 0,
55  0,
56  0, 1,
57  0, 1, 2,
58  0, 1, 2},
59 
60  //Keywire offset for ME3 and ME4
61  {2, 1, 0,
62  1, 0,
63  0,
64  0, -1,
65  0, -1, -2,
66  0, -1, -2}
67 };
68 
69 // time averaging weights for pattern (used for SLHC version)
71  //Layer
72  { 0, 1, 1,
73  1, 2,
74  2,
75  2, 1,
76  2, 1, 0,
77  1, 1, 0};
78 
79 
80 // These mask the pattern envelope to give the desired accelerator pattern
81 // and collision patterns A and B. These masks were meant to be the default
82 // ones in early 200X, but were never implemented because of limited FPGA
83 // resources.
85  // Accelerator pattern
86  {0, 0, 1,
87  0, 1,
88  1,
89  1, 0,
90  1, 0, 0,
91  1, 0, 0},
92 
93  // Collision pattern A
94  {0, 1, 0,
95  1, 1,
96  1,
97  1, 0,
98  0, 1, 0,
99  0, 1, 0},
100 
101  // Collision pattern B
102  {1, 1, 0,
103  1, 1,
104  1,
105  1, 1,
106  0, 1, 1,
107  0, 0, 1}
108 };
109 
110 // Since the test beams in 2003, both collision patterns are "completely
111 // open". This is our current default.
113  // Accelerator pattern
114  {0, 0, 1,
115  0, 1,
116  1,
117  1, 0,
118  1, 0, 0,
119  1, 0, 0},
120 
121  // Collision pattern A
122  {1, 1, 1,
123  1, 1,
124  1,
125  1, 1,
126  1, 1, 1,
127  1, 1, 1},
128 
129  // Collision pattern B
130  {1, 1, 1,
131  1, 1,
132  1,
133  1, 1,
134  1, 1, 1,
135  1, 1, 1}
136 };
137 
138 // Special option for narrow pattern for ring 1 stations
140  // Accelerator pattern
141  {0, 0, 1,
142  0, 1,
143  1,
144  1, 0,
145  1, 0, 0,
146  1, 0, 0},
147 
148  // Collision pattern A
149  {0, 1, 1,
150  1, 1,
151  1,
152  1, 0,
153  1, 1, 0,
154  1, 1, 0},
155 
156  // Collision pattern B
157  {0, 1, 1,
158  1, 1,
159  1,
160  1, 0,
161  1, 1, 0,
162  1, 1, 0}
163 };
164 
165 
166 
167 // Default values of configuration parameters.
168 const unsigned int CSCAnodeLCTProcessor::def_fifo_tbins = 16;
169 const unsigned int CSCAnodeLCTProcessor::def_fifo_pretrig = 10;
170 const unsigned int CSCAnodeLCTProcessor::def_drift_delay = 2;
171 const unsigned int CSCAnodeLCTProcessor::def_nplanes_hit_pretrig = 2;
172 const unsigned int CSCAnodeLCTProcessor::def_nplanes_hit_pattern = 4;
175 const unsigned int CSCAnodeLCTProcessor::def_trig_mode = 2; // 3?
176 const unsigned int CSCAnodeLCTProcessor::def_accel_mode = 0; // 1?
177 const unsigned int CSCAnodeLCTProcessor::def_l1a_window_width = 7; // 5?
178 
179 //----------------
180 // Constructors --
181 //----------------
182 
184  unsigned sector, unsigned subsector,
185  unsigned chamber,
186  const edm::ParameterSet& conf,
187  const edm::ParameterSet& comm) :
188  theEndcap(endcap), theStation(station), theSector(sector),
189  theSubsector(subsector), theTrigChamber(chamber) {
190  static std::atomic<bool> config_dumped{false};
191 
192  // ALCT configuration parameters.
193  fifo_tbins = conf.getParameter<unsigned int>("alctFifoTbins");
194  fifo_pretrig = conf.getParameter<unsigned int>("alctFifoPretrig");
195  drift_delay = conf.getParameter<unsigned int>("alctDriftDelay");
197  conf.getParameter<unsigned int>("alctNplanesHitPretrig");
199  conf.getParameter<unsigned int>("alctNplanesHitPattern");
201  conf.getParameter<unsigned int>("alctNplanesHitAccelPretrig");
203  conf.getParameter<unsigned int>("alctNplanesHitAccelPattern");
204  trig_mode = conf.getParameter<unsigned int>("alctTrigMode");
205  accel_mode = conf.getParameter<unsigned int>("alctAccelMode");
206  l1a_window_width = conf.getParameter<unsigned int>("alctL1aWindowWidth");
207 
208  hit_persist = conf.getParameter<unsigned int>("alctHitPersist");
209 
210  // Verbosity level, set to 0 (no print) by default.
211  infoV = conf.getParameter<int>("verbosity");
212 
213  // Other parameters.
214  // Use open pattern instead of more restrictive (slim) ones.
215  isMTCC = comm.getParameter<bool>("isMTCC");
216  // Use TMB07 flag for DAQ-2006 firmware version (implemented in late 2007).
217  isTMB07 = comm.getParameter<bool>("isTMB07");
218 
219  // Flag for SLHC studies
220  isSLHC = comm.getParameter<bool>("isSLHC");
221 
222  // special configuration parameters for ME11 treatment
223  disableME1a = comm.getParameter<bool>("disableME1a");
224 
225  // separate handle for early time bins
226  early_tbins = conf.getParameter<int>("alctEarlyTbins");
227  if (early_tbins<0) early_tbins = fifo_pretrig - CSCConstants::ALCT_EMUL_TIME_OFFSET;
228 
229  // delta BX time depth for ghostCancellationLogic
230  ghost_cancellation_bx_depth = conf.getParameter<int>("alctGhostCancellationBxDepth");
231 
232  // whether to consider ALCT candidates' qualities while doing ghostCancellationLogic on +-1 wire groups
233  ghost_cancellation_side_quality = conf.getParameter<bool>("alctGhostCancellationSideQuality");
234 
235  // deadtime clocks after pretrigger (extra in addition to drift_delay)
236  pretrig_extra_deadtime = conf.getParameter<unsigned int>("alctPretrigDeadtime");
237 
238  // whether to use narrow pattern mask for the rings close to the beam
239  narrow_mask_r1 = conf.getParameter<bool>("alctNarrowMaskForR1");
240 
241  // Check and print configuration parameters.
243  if ((infoV > 0 || isSLHC) && !config_dumped) {
244  //std::cout<<"**** ALCT constructor parameters dump ****"<<std::endl;
246  config_dumped = true;
247  }
248 
249  numWireGroups = 0; // Will be set later.
250  MESelection = (theStation < 3) ? 0 : 1;
251 
253 
256 
257  // trigger numbering doesn't distinguish between ME1a and ME1b chambers:
258  isME11 = (theStation == 1 && theRing == 1);
259 
260  // whether to calculate bx as corrected_bx instead of pretrigger one
261  use_corrected_bx = false;
262  if (isSLHC && isME11) {
263  use_corrected_bx = conf.getParameter<bool>("alctUseCorrectedBx");
264  }
265 
266  // run the ALCT processor for the Phase-II ME2/1 integrated local trigger
267  runME21ILT_ = comm.existsAs<bool>("runME21ILT")?
268  comm.getParameter<bool>("runME21ILT"):false;
269 
270  // run the ALCT processor for the Phase-II ME3/1-ME4/1 integrated local trigger
271  runME3141ILT_ = comm.existsAs<bool>("runME3141ILT")?
272  comm.getParameter<bool>("runME3141ILT"):false;
273 
274  //if (theStation==1 && theRing==2) infoV = 3;
275 
276  // Load appropriate pattern mask.
277  loadPatternMask();
278 }
279 
281  theEndcap(1), theStation(1), theSector(1),
283  // Used for debugging. -JM
284  static std::atomic<bool> config_dumped{false};
285 
286  // ALCT parameters.
288  infoV = 2;
289  isMTCC = false;
290  isTMB07 = true;
291 
292  isSLHC = false;
293  disableME1a = false;
294 
295  early_tbins = 4;
296 
297  // Check and print configuration parameters.
299  if (!config_dumped) {
300  //std::cout<<"**** ALCT default constructor parameters dump ****"<<std::endl;
302  config_dumped = true;
303  }
304 
306  MESelection = (theStation < 3) ? 0 : 1;
307 
311  isME11 = (theStation == 1 && theRing == 1);
312 
313  // Load pattern mask.
314  loadPatternMask();
315 }
316 
317 
319  // Load appropriate pattern mask.
320  for (int i_patt = 0; i_patt < CSCConstants::NUM_ALCT_PATTERNS; i_patt++) {
321  for (int i_wire = 0; i_wire < CSCConstants::MAX_WIRES_IN_PATTERN; i_wire++) {
322  if (isMTCC || isTMB07) {
323  pattern_mask[i_patt][i_wire] = pattern_mask_open[i_patt][i_wire];
324  if (narrow_mask_r1 && (theRing == 1 || theRing == 4))
325  pattern_mask[i_patt][i_wire] = pattern_mask_r1[i_patt][i_wire];
326  }
327  else {
328  pattern_mask[i_patt][i_wire] = pattern_mask_slim[i_patt][i_wire];
329  }
330  }
331  }
332 }
333 
334 
336  // Set default values for configuration parameters.
347 }
348 
349 // Set configuration parameters obtained via EventSetup mechanism.
351  static std::atomic<bool> config_dumped{false};
352 
353  fifo_tbins = conf->alctFifoTbins();
354  fifo_pretrig = conf->alctFifoPretrig();
355  drift_delay = conf->alctDriftDelay();
360  trig_mode = conf->alctTrigMode();
361  accel_mode = conf->alctAccelMode();
363 
364  // Check and print configuration parameters.
366  if (!config_dumped) {
367  //std::cout<<"**** ALCT setConfigParam parameters dump ****"<<std::endl;
369  config_dumped = true;
370  }
371 }
372 
374  // Make sure that the parameter values are within the allowed range.
375 
376  // Max expected values.
377  static const unsigned int max_fifo_tbins = 1 << 5;
378  static const unsigned int max_fifo_pretrig = 1 << 5;
379  static const unsigned int max_drift_delay = 1 << 2;
380  static const unsigned int max_nplanes_hit_pretrig = 1 << 3;
381  static const unsigned int max_nplanes_hit_pattern = 1 << 3;
382  static const unsigned int max_nplanes_hit_accel_pretrig = 1 << 3;
383  static const unsigned int max_nplanes_hit_accel_pattern = 1 << 3;
384  static const unsigned int max_trig_mode = 1 << 2;
385  static const unsigned int max_accel_mode = 1 << 2;
386  static const unsigned int max_l1a_window_width = CSCConstants::MAX_ALCT_TBINS; // 4 bits
387 
388  // Checks.
389  if (fifo_tbins >= max_fifo_tbins) {
390  if (infoV >= 0) edm::LogError("L1CSCTPEmulatorConfigError")
391  << "+++ Value of fifo_tbins, " << fifo_tbins
392  << ", exceeds max allowed, " << max_fifo_tbins-1 << " +++\n"
393  << "+++ Try to proceed with the default value, fifo_tbins="
394  << def_fifo_tbins << " +++\n";
396  }
397  if (fifo_pretrig >= max_fifo_pretrig) {
398  if (infoV >= 0) edm::LogError("L1CSCTPEmulatorConfigError")
399  << "+++ Value of fifo_pretrig, " << fifo_pretrig
400  << ", exceeds max allowed, " << max_fifo_pretrig-1 << " +++\n"
401  << "+++ Try to proceed with the default value, fifo_pretrig="
402  << def_fifo_pretrig << " +++\n";
404  }
405  if (drift_delay >= max_drift_delay) {
406  if (infoV >= 0) edm::LogError("L1CSCTPEmulatorConfigError")
407  << "+++ Value of drift_delay, " << drift_delay
408  << ", exceeds max allowed, " << max_drift_delay-1 << " +++\n"
409  << "+++ Try to proceed with the default value, drift_delay="
410  << def_drift_delay << " +++\n";
412  }
413  if (nplanes_hit_pretrig >= max_nplanes_hit_pretrig) {
414  if (infoV >= 0) edm::LogError("L1CSCTPEmulatorConfigError")
415  << "+++ Value of nplanes_hit_pretrig, " << nplanes_hit_pretrig
416  << ", exceeds max allowed, " << max_nplanes_hit_pretrig-1 << " +++\n"
417  << "+++ Try to proceed with the default value, nplanes_hit_pretrig="
418  << nplanes_hit_pretrig << " +++\n";
419  nplanes_hit_pretrig = def_nplanes_hit_pretrig;
420  }
421  if (nplanes_hit_pattern >= max_nplanes_hit_pattern) {
422  if (infoV >= 0) edm::LogError("L1CSCTPEmulatorConfigError")
423  << "+++ Value of nplanes_hit_pattern, " << nplanes_hit_pattern
424  << ", exceeds max allowed, " << max_nplanes_hit_pattern-1 << " +++\n"
425  << "+++ Try to proceed with the default value, nplanes_hit_pattern="
426  << nplanes_hit_pattern << " +++\n";
427  nplanes_hit_pattern = def_nplanes_hit_pattern;
428  }
429  if (nplanes_hit_accel_pretrig >= max_nplanes_hit_accel_pretrig) {
430  if (infoV >= 0) edm::LogError("L1CSCTPEmulatorConfigError")
431  << "+++ Value of nplanes_hit_accel_pretrig, "
432  << nplanes_hit_accel_pretrig << ", exceeds max allowed, "
433  << max_nplanes_hit_accel_pretrig-1 << " +++\n"
434  << "+++ Try to proceed with the default value, "
435  << "nplanes_hit_accel_pretrig=" << nplanes_hit_accel_pretrig << " +++\n";
436  nplanes_hit_accel_pretrig = def_nplanes_hit_accel_pretrig;
437  }
438  if (nplanes_hit_accel_pattern >= max_nplanes_hit_accel_pattern) {
439  if (infoV >= 0) edm::LogError("L1CSCTPEmulatorConfigError")
440  << "+++ Value of nplanes_hit_accel_pattern, "
441  << nplanes_hit_accel_pattern << ", exceeds max allowed, "
442  << max_nplanes_hit_accel_pattern-1 << " +++\n"
443  << "+++ Try to proceed with the default value, "
444  << "nplanes_hit_accel_pattern=" << nplanes_hit_accel_pattern << " +++\n";
445  nplanes_hit_accel_pattern = def_nplanes_hit_accel_pattern;
446  }
447  if (trig_mode >= max_trig_mode) {
448  if (infoV >= 0) edm::LogError("L1CSCTPEmulatorConfigError")
449  << "+++ Value of trig_mode, " << trig_mode
450  << ", exceeds max allowed, " << max_trig_mode-1 << " +++\n"
451  << "+++ Try to proceed with the default value, trig_mode="
452  << trig_mode << " +++\n";
453  trig_mode = def_trig_mode;
454  }
455  if (accel_mode >= max_accel_mode) {
456  if (infoV >= 0) edm::LogError("L1CSCTPEmulatorConfigError")
457  << "+++ Value of accel_mode, " << accel_mode
458  << ", exceeds max allowed, " << max_accel_mode-1 << " +++\n"
459  << "+++ Try to proceed with the default value, accel_mode="
460  << accel_mode << " +++\n";
461  accel_mode = def_accel_mode;
462  }
463  if (l1a_window_width >= max_l1a_window_width) {
464  if (infoV >= 0) edm::LogError("L1CSCTPEmulatorConfigError")
465  << "+++ Value of l1a_window_width, " << l1a_window_width
466  << ", exceeds max allowed, " << max_l1a_window_width-1 << " +++\n"
467  << "+++ Try to proceed with the default value, l1a_window_width="
468  << l1a_window_width << " +++\n";
469  l1a_window_width = def_l1a_window_width;
470  }
471 }
472 
474  for (int bx = 0; bx < CSCConstants::MAX_ALCT_TBINS; bx++) {
475  bestALCT[bx].clear();
476  secondALCT[bx].clear();
477  }
478 }
479 
480 void CSCAnodeLCTProcessor::clear(const int wire, const int pattern) {
481  /* Clear the data off of selected pattern */
482  if (pattern == 0) quality[wire][0] = -999;
483  else {
484  quality[wire][1] = -999;
485  quality[wire][2] = -999;
486  }
487 }
488 
489 std::vector<CSCALCTDigi>
491  // This is the main routine for normal running. It gets wire times
492  // from the wire digis and then passes them on to another run() function.
493 
494  static std::atomic<bool> config_dumped{false};
495  if ((infoV > 0 || isSLHC) && !config_dumped) {
496  //std::cout<<"**** ALCT run parameters dump ****"<<std::endl;
498  config_dumped = true;
499  }
500 
501 
502  // Get the number of wire groups for the given chamber. Do it only once
503  // per chamber.
504  if (numWireGroups == 0) {
507  CSCDetId detid(theEndcap, theStation, ring, chid, 0);
508  const auto& chamber = csc_g->chamber(detid);
509  if (chamber) {
510  numWireGroups = chamber->layer(1)->geometry()->numberOfWireGroups();
512  if (infoV >= 0) edm::LogError("L1CSCTPEmulatorSetupError")
513  << "+++ Number of wire groups, " << numWireGroups
514  << " found in ME" << ((theEndcap == 1) ? "+" : "-")
515  << theStation << "/" << theRing << "/" << theChamber
516  << " (sector " << theSector << " subsector " << theSubsector
517  << " trig id. " << theTrigChamber << ")"
518  << " exceeds max expected, " << CSCConstants::MAX_NUM_WIRES
519  << " +++\n"
520  << "+++ CSC geometry looks garbled; no emulation possible +++\n";
521  numWireGroups = -1;
522  }
523  }
524  else {
525  if (infoV >= 0) edm::LogError("L1CSCTPEmulatorSetupError")
526  << "+++ ME" << ((theEndcap == 1) ? "+" : "-")
527  << theStation << "/" << theRing << "/" << theChamber
528  << " (sector " << theSector << " subsector " << theSubsector
529  << " trig id. " << theTrigChamber << ")"
530  << " is not defined in current geometry! +++\n"
531  << "+++ CSC geometry looks garbled; no emulation possible +++\n";
532  numWireGroups = -1;
533  }
534  }
535 
536  if (numWireGroups < 0) {
537  if (infoV >= 0) edm::LogError("L1CSCTPEmulatorSetupError")
538  << "+++ ME" << ((theEndcap == 1) ? "+" : "-")
539  << theStation << "/" << theRing << "/" << theChamber
540  << " (sector " << theSector << " subsector " << theSubsector
541  << " trig id. " << theTrigChamber << "):"
542  << " numWireGroups = " << numWireGroups
543  << "; ALCT emulation skipped! +++";
544  std::vector<CSCALCTDigi> emptyV;
545  return emptyV;
546  }
547 
548  // Get wire digis in this chamber from wire digi collection.
549  bool noDigis = getDigis(wiredc);
550 
551  if (!noDigis) {
552  // First get wire times from the wire digis.
553  std::vector<int>
555  readWireDigis(wire);
556 
557  // Pass an array of wire times on to another run() doing the LCT search.
558  // If the number of layers containing digis is smaller than that
559  // required to trigger, quit right away.
560  const unsigned int min_layers =
566  );
567 
568  unsigned int layersHit = 0;
569  for (int i_layer = 0; i_layer < CSCConstants::NUM_LAYERS; i_layer++) {
570  for (int i_wire = 0; i_wire < numWireGroups; i_wire++) {
571  if (!wire[i_layer][i_wire].empty()) {layersHit++; break;}
572  }
573  }
574  if (layersHit >= min_layers) run(wire);
575  }
576 
577  // Return vector of all found ALCTs.
578  std::vector<CSCALCTDigi> tmpV = getALCTs();
579  return tmpV;
580 }
581 
583  // This version of the run() function can either be called in a standalone
584  // test, being passed the time array, or called by the run() function above.
585  // It gets wire times from an input array and then loops over the keywires.
586  // All found LCT candidates are sorted and the best two are retained.
587 
588  bool trigger = false;
589 
590  // Check if there are any in-time hits and do the pulse extension.
591  bool chamber_empty = pulseExtension(wire);
592 
593  // Only do the rest of the processing if chamber is not empty.
594  // Stop drift_delay bx's short of fifo_tbins since at later bx's we will
595  // not have a full set of hits to start pattern search anyway.
596  unsigned int stop_bx = fifo_tbins - drift_delay;
597  if (!chamber_empty) {
598  for (int i_wire = 0; i_wire < numWireGroups; i_wire++) {
599  unsigned int start_bx = 0;
600  // Allow for more than one pass over the hits in the time window.
601  while (start_bx < stop_bx) {
602  if (preTrigger(i_wire, start_bx)) {
603  if (infoV > 2) showPatterns(i_wire);
604  if (patternDetection(i_wire)) {
605  trigger = true;
606  break;
607  }
608  else {
609  // Assume that the earliest time when another pre-trigger can
610  // occur in case pattern detection failed is bx_pretrigger+4:
611  // this seems to match the data.
612  start_bx = first_bx[i_wire] + drift_delay + pretrig_extra_deadtime;
613  }
614  }
615  else {
616  break;
617  }
618  }
619  }
620  }
621 
622  // Do the rest only if there is at least one trigger candidate.
623  if (trigger) {
625  else ghostCancellationLogic();
626  lctSearch();
627  }
628 }
629 
631  // Routine for getting digis and filling digiV vector.
632  bool noDigis = true;
633 
634  // Loop over layers and save wire digis on each one into digiV[layer].
635  for (int i_layer = 0; i_layer < CSCConstants::NUM_LAYERS; i_layer++) {
636  digiV[i_layer].clear();
637 
638  CSCDetId detid(theEndcap, theStation, theRing, theChamber, i_layer+1);
639  getDigis(wiredc, detid);
640 
641  // If this is ME1/1, fetch digis in corresponding ME1/A (ring=4) as well.
642  if (isME11 && !disableME1a) {
643  CSCDetId detid_me1a(theEndcap, theStation, 4, theChamber, i_layer+1);
644  getDigis(wiredc, detid_me1a);
645  }
646 
647  if (!digiV[i_layer].empty()) {
648  noDigis = false;
649  if (infoV > 1) {
650  LogTrace("CSCAnodeLCTProcessor")
651  << "found " << digiV[i_layer].size()
652  << " wire digi(s) in layer " << i_layer << " of ME"
653  << ((theEndcap == 1) ? "+" : "-") << theStation << "/" << theRing
654  << "/" << theChamber << " (trig. sector " << theSector
655  << " subsector " << theSubsector << " id " << theTrigChamber << ")";
656  for (std::vector<CSCWireDigi>::iterator pld = digiV[i_layer].begin();
657  pld != digiV[i_layer].end(); pld++) {
658  LogTrace("CSCAnodeLCTProcessor") << " " << (*pld);
659  }
660  }
661  }
662  }
663 
664  return noDigis;
665 }
666 
668  const CSCDetId& id) {
669  const CSCWireDigiCollection::Range rwired = wiredc->get(id);
670  for (CSCWireDigiCollection::const_iterator digiIt = rwired.first;
671  digiIt != rwired.second; ++digiIt) {
672  digiV[id.layer()-1].push_back(*digiIt);
673  }
674 }
675 
677  /* Gets wire times from the wire digis and fills wire[][] vector */
678 
679  // Loop over all 6 layers.
680  for (int i_layer = 0; i_layer < CSCConstants::NUM_LAYERS; i_layer++) {
681  // Loop over all digis in the layer and find the wireGroup and bx
682  // time for each.
683  for (std::vector<CSCWireDigi>::iterator pld = digiV[i_layer].begin();
684  pld != digiV[i_layer].end(); pld++) {
685  int i_wire = pld->getWireGroup()-1;
686  std::vector<int> bx_times = pld->getTimeBinsOn();
687 
688  // Check that the wires and times are appropriate.
689  if (i_wire < 0 || i_wire >= numWireGroups) {
690  if (infoV >= 0) edm::LogWarning("L1CSCTPEmulatorWrongInput")
691  << "+++ Found wire digi with wrong wire number = " << i_wire
692  << " (max wires = " << numWireGroups << "); skipping it... +++\n";
693  continue;
694  }
695  // Accept digis in expected time window. Total number of time
696  // bins in DAQ readout is given by fifo_tbins, which thus
697  // determines the maximum length of time interval. Anode raw
698  // hits in DAQ readout start (fifo_pretrig - 6) clocks before
699  // L1Accept. If times earlier than L1Accept were recorded, we
700  // use them since they can modify the ALCTs found later, via
701  // ghost-cancellation logic.
702  int last_time = -999;
703  if (bx_times.size() == fifo_tbins) {
704  wire[i_layer][i_wire].push_back(0);
705  wire[i_layer][i_wire].push_back(6);
706  }
707  else {
708  for (unsigned int i = 0; i < bx_times.size(); i++) {
709  // Find rising edge change
710  if (i > 0 && bx_times[i] == (bx_times[i-1]+1)) continue;
711  if (bx_times[i] < static_cast<int>(fifo_tbins)) {
712  if (infoV > 2) LogTrace("CSCAnodeLCTProcessor")
713  << "Digi on layer " << i_layer << " wire " << i_wire
714  << " at time " << bx_times[i];
715 
716  // Finally save times of hit wires. One shot module will
717  // not restart if a new pulse comes before the expiration
718  // of the 6-bx period.
719  if (last_time < 0 || ((bx_times[i]-last_time) >= 6) ) {
720  wire[i_layer][i_wire].push_back(bx_times[i]);
721  last_time = bx_times[i];
722  }
723  }
724  else {
725  if (infoV > 1) LogTrace("CSCAnodeLCTProcessor")
726  << "+++ Skipping wire digi: wire = " << i_wire
727  << " layer = " << i_layer << ", bx = " << bx_times[i] << " +++";
728  }
729  }
730  }
731  }
732  }
733 }
734 
736  /* A pulse array will be used as a bit representation of hit times.
737  For example: if a keywire has a bx_time of 3, then 1 shifted
738  left 3 will be bit pattern 0000000000001000. Bits are then added to
739  signify the duration of a signal (hit_persist, formerly bx_width). So
740  for the pulse with a hit_persist of 6 will look like 0000000111111000. */
741 
742  bool chamber_empty = true;
743  int i_wire, i_layer, digi_num;
744  const unsigned int bits_in_pulse = 8*sizeof(pulse[0][0]);
745 
746  for (i_wire = 0; i_wire < numWireGroups; i_wire++) {
747  for (i_layer = 0; i_layer < CSCConstants::NUM_LAYERS; i_layer++) {
748  pulse[i_layer][i_wire] = 0;
749  }
750  first_bx[i_wire] = -999;
751  first_bx_corrected[i_wire] = -999;
752  for (int j = 0; j < 3; j++) quality[i_wire][j] = -999;
753  }
754 
755  for (i_layer = 0; i_layer < CSCConstants::NUM_LAYERS; i_layer++){
756  digi_num = 0;
757  for (i_wire = 0; i_wire < numWireGroups; i_wire++) {
758  if (!wire[i_layer][i_wire].empty()) {
759  std::vector<int> bx_times = wire[i_layer][i_wire];
760  for (unsigned int i = 0; i < bx_times.size(); i++) {
761  // Check that min and max times are within the allowed range.
762  if (bx_times[i] < 0 || bx_times[i] + hit_persist >= bits_in_pulse) {
763  if (infoV > 0) edm::LogWarning("L1CSCTPEmulatorOutOfTimeDigi")
764  << "+++ BX time of wire digi (wire = " << i_wire
765  << " layer = " << i_layer << ") bx = " << bx_times[i]
766  << " is not within the range (0-" << bits_in_pulse
767  << "] allowed for pulse extension. Skip this digi! +++\n";
768  continue;
769  }
770 
771  // Found at least one in-time digi; set chamber_empty to false
772  if (chamber_empty) chamber_empty = false;
773 
774  // make the pulse
775  for (unsigned int bx = bx_times[i];
776  bx < (bx_times[i] + hit_persist); bx++)
777  pulse[i_layer][i_wire] = pulse[i_layer][i_wire] | (1 << bx);
778 
779  // Debug information.
780  if (infoV > 1) {
781  LogTrace("CSCAnodeLCTProcessor")
782  << "Wire digi: layer " << i_layer
783  << " digi #" << ++digi_num << " wire group " << i_wire
784  << " time " << bx_times[i];
785  if (infoV > 2) {
786  std::ostringstream strstrm;
787  for (int i = 1; i <= 32; i++) {
788  strstrm << ((pulse[i_layer][i_wire]>>(32-i)) & 1);
789  }
790  LogTrace("CSCAnodeLCTProcessor") << " Pulse: " << strstrm.str();
791  }
792  }
793  }
794  }
795  }
796  }
797 
798  if (infoV > 1 && !chamber_empty) {
799  dumpDigis(wire);
800  }
801 
802  return chamber_empty;
803 }
804 
805 bool CSCAnodeLCTProcessor::preTrigger(const int key_wire, const int start_bx) {
806  /* Check that there are nplanes_hit_pretrig or more layers hit in collision
807  or accelerator patterns for a particular key_wire. If so, return
808  true and the PatternDetection process will start. */
809 
810  unsigned int layers_hit;
811  bool hit_layer[CSCConstants::NUM_LAYERS];
812  int this_layer, this_wire;
813  // If nplanes_hit_accel_pretrig is 0, the firmware uses the value
814  // of nplanes_hit_pretrig instead.
815  const unsigned int nplanes_hit_pretrig_acc =
818  const unsigned int pretrig_thresh[CSCConstants::NUM_ALCT_PATTERNS] = {
819  nplanes_hit_pretrig_acc, nplanes_hit_pretrig, nplanes_hit_pretrig
820  };
821 
822  // Loop over bx times, accelerator and collision patterns to
823  // look for pretrigger.
824  // Stop drift_delay bx's short of fifo_tbins since at later bx's we will
825  // not have a full set of hits to start pattern search anyway.
826  unsigned int stop_bx = fifo_tbins - drift_delay;
827  for (unsigned int bx_time = start_bx; bx_time < stop_bx; bx_time++) {
828  for (int i_pattern = 0; i_pattern < CSCConstants::NUM_ALCT_PATTERNS; i_pattern++) {
829  for (int i_layer = 0; i_layer < CSCConstants::NUM_LAYERS; i_layer++)
830  hit_layer[i_layer] = false;
831  layers_hit = 0;
832 
833  for (int i_wire = 0; i_wire < CSCConstants::MAX_WIRES_IN_PATTERN; i_wire++){
834  if (pattern_mask[i_pattern][i_wire] != 0){
835  this_layer = pattern_envelope[0][i_wire];
836  this_wire = pattern_envelope[1+MESelection][i_wire]+key_wire;
837  if ((this_wire >= 0) && (this_wire < numWireGroups)){
838  // Perform bit operation to see if pulse is 1 at a certain bx_time.
839  if (((pulse[this_layer][this_wire] >> bx_time) & 1) == 1) {
840  // Store number of layers hit.
841  if (hit_layer[this_layer] == false){
842  hit_layer[this_layer] = true;
843  layers_hit++;
844  }
845 
846  // See if number of layers hit is greater than or equal to
847  // pretrig_thresh.
848  if (layers_hit >= pretrig_thresh[i_pattern]) {
849  first_bx[key_wire] = bx_time;
850  if (infoV > 1) {
851  LogTrace("CSCAnodeLCTProcessor")
852  << "Pretrigger was satisfied for wire: " << key_wire
853  << " pattern: " << i_pattern
854  << " bx_time: " << bx_time;
855  }
856  return true;
857  }
858  }
859  }
860  }
861  }
862  }
863  }
864  // If the pretrigger was never satisfied, then return false.
865  return false;
866 }
867 
868 bool CSCAnodeLCTProcessor::patternDetection(const int key_wire) {
869  /* See if there is a pattern that satisfies nplanes_hit_pattern number of
870  layers hit for either the accelerator or collision patterns. Use
871  the pattern with the best quality. */
872 
873  bool trigger = false;
874  bool hit_layer[CSCConstants::NUM_LAYERS];
875  unsigned int temp_quality;
876  int this_layer, this_wire, delta_wire;
877  // If nplanes_hit_accel_pattern is 0, the firmware uses the value
878  // of nplanes_hit_pattern instead.
879  const unsigned int nplanes_hit_pattern_acc =
882  const unsigned int pattern_thresh[CSCConstants::NUM_ALCT_PATTERNS] = {
883  nplanes_hit_pattern_acc, nplanes_hit_pattern, nplanes_hit_pattern
884  };
885  const std::string ptn_label[] = {"Accelerator", "CollisionA", "CollisionB"};
886 
887  for (int i_pattern = 0; i_pattern < CSCConstants::NUM_ALCT_PATTERNS; i_pattern++){
888  temp_quality = 0;
889  for (int i_layer = 0; i_layer < CSCConstants::NUM_LAYERS; i_layer++)
890  hit_layer[i_layer] = false;
891 
892  double num_pattern_hits=0., times_sum=0.;
893  std::multiset<int> mset_for_median;
894  mset_for_median.clear();
895 
896  for (int i_wire = 0; i_wire < CSCConstants::MAX_WIRES_IN_PATTERN; i_wire++){
897  if (pattern_mask[i_pattern][i_wire] != 0){
898  this_layer = pattern_envelope[0][i_wire];
899  delta_wire = pattern_envelope[1+MESelection][i_wire];
900  this_wire = delta_wire + key_wire;
901  if ((this_wire >= 0) && (this_wire < numWireGroups)){
902 
903  // Wait a drift_delay time later and look for layers hit in
904  // the pattern.
905  if ( ( (pulse[this_layer][this_wire] >>
906  (first_bx[key_wire] + drift_delay)) & 1) == 1) {
907 
908  // If layer has never had a hit before, then increment number
909  // of layer hits.
910  if (hit_layer[this_layer] == false){
911  temp_quality++;
912  // keep track of which layers already had hits.
913  hit_layer[this_layer] = true;
914  if (infoV > 1)
915  LogTrace("CSCAnodeLCTProcessor")
916  << "bx_time: " << first_bx[key_wire]
917  << " pattern: " << i_pattern << " keywire: " << key_wire
918  << " layer: " << this_layer
919  << " quality: " << temp_quality;
920  }
921 
922  // for averaged time use only the closest WGs around the key WG
923  if (abs(delta_wire)<2) {
924  // find at what bx did pulse on this wire&layer start
925  // use hit_pesrist constraint on how far back we can go
926  int first_bx_layer = first_bx[key_wire] + drift_delay;
927  for (unsigned int dbx=0; dbx<hit_persist; dbx++) {
928  if (((pulse[this_layer][this_wire] >> (first_bx_layer-1)) & 1) == 1) first_bx_layer--;
929  else break;
930  }
931  times_sum += (double)first_bx_layer;
932  num_pattern_hits += 1.;
933  mset_for_median.insert(first_bx_layer);
934  if (infoV > 2)
935  LogTrace("CSCAnodeLCTProcessor")
936  <<" 1st bx in layer: "<<first_bx_layer
937  <<" sum bx: "<<times_sum
938  <<" #pat. hits: "<<num_pattern_hits;
939  }
940  }
941  }
942  }
943  }
944 
945  // calculate median
946  const int sz = mset_for_median.size();
947  if (sz > 0) {
948  std::multiset<int>::iterator im = mset_for_median.begin();
949  if (sz > 1) std::advance(im,sz/2-1);
950  if (sz == 1) first_bx_corrected[key_wire] = *im;
951  else if ((sz % 2) == 1) first_bx_corrected[key_wire] = *(++im);
952  else first_bx_corrected[key_wire] = ((*im) + (*(++im)))/2;
953 
954  if (infoV > 1) {
955  char bxs[300]="";
956  for (im = mset_for_median.begin(); im != mset_for_median.end(); im++)
957  sprintf(bxs,"%s %d", bxs, *im);
958  LogTrace("CSCAnodeLCTProcessor")
959  <<"bx="<<first_bx[key_wire]<<" bx_cor="<< first_bx_corrected[key_wire]<<" bxset="<<bxs;
960  }
961  }
962 
963  if (temp_quality >= pattern_thresh[i_pattern]) {
964  trigger = true;
965 
966  if (!isTMB07) {
967  // Quality reported by the pattern detector is defined as the number
968  // of the layers hit in a pattern minus (pattern_thresh-1) value.
969  temp_quality -= (pattern_thresh[i_pattern]-1);
970  }
971  else {
972  // Quality definition changed on 22 June 2007: it no longer depends
973  // on pattern_thresh.
974  int Q;
975  // hack to run the Phase-II ME2/1, ME3/1 and ME4/1 ILT
976  if (temp_quality == 3 and (runME21ILT_ or runME3141ILT_)) Q = 4;
977  else if (temp_quality > 3) Q = temp_quality - 3;
978  else Q = 0; // quality code 0 is valid!
979  temp_quality = Q;
980  }
981 
982  if (i_pattern == 0) {
983  // Accelerator pattern
984  quality[key_wire][0] = temp_quality;
985  }
986  else {
987  // Only one collision pattern (of the best quality) is reported
988  if (static_cast<int>(temp_quality) > quality[key_wire][1]) {
989  quality[key_wire][1] = temp_quality;
990  quality[key_wire][2] = i_pattern-1;
991  }
992  }
993  if (infoV > 1) {
994  LogTrace("CSCAnodeLCTProcessor")
995  << "Pattern found; keywire: " << key_wire
996  << " type: " << ptn_label[i_pattern]
997  << " quality: " << temp_quality << "\n";
998  }
999  }
1000  }
1001  if (infoV > 1 && quality[key_wire][1] > 0) {
1002  if (quality[key_wire][2] == 0)
1003  LogTrace("CSCAnodeLCTProcessor")
1004  << "Collision Pattern A is chosen" << "\n";
1005  else if (quality[key_wire][2] == 1)
1006  LogTrace("CSCAnodeLCTProcessor")
1007  << "Collision Pattern B is chosen" << "\n";
1008  }
1009  return trigger;
1010 }
1011 
1013  /* This function looks for LCTs on the previous and next wires. If one
1014  exists and it has a better quality and a bx_time up to 4 clocks earlier
1015  than the present, then the present LCT is cancelled. The present LCT
1016  also gets cancelled if it has the same quality as the one on the
1017  previous wire (this has not been done in 2003 test beam). The
1018  cancellation is done separately for collision and accelerator patterns. */
1019 
1020  int ghost_cleared[CSCConstants::MAX_NUM_WIRES][2];
1021 
1022  for (int key_wire = 0; key_wire < numWireGroups; key_wire++) {
1023  for (int i_pattern = 0; i_pattern < 2; i_pattern++) {
1024  ghost_cleared[key_wire][i_pattern] = 0;
1025 
1026  // Non-empty wire group.
1027  int qual_this = quality[key_wire][i_pattern];
1028  if (qual_this > 0) {
1029 
1030  // Previous wire.
1031  int qual_prev = (key_wire > 0) ? quality[key_wire-1][i_pattern] : 0;
1032  if (qual_prev > 0) {
1033  int dt = first_bx[key_wire] - first_bx[key_wire-1];
1034  // Cancel this wire
1035  // 1) If the candidate at the previous wire is at the same bx
1036  // clock and has better quality (or equal quality - this has
1037  // been implemented only in 2004).
1038  // 2) If the candidate at the previous wire is up to 4 clocks
1039  // earlier, regardless of quality.
1040  if (dt == 0) {
1041  if (qual_prev >= qual_this) ghost_cleared[key_wire][i_pattern] = 1;
1042  }
1043  else if (dt > 0 && dt <= ghost_cancellation_bx_depth ) {
1044  // Next "if" check accounts for firmware bug and should be
1045  // removed once the next firmware version is used.
1046  // The bug is fixed in 5/5/2008 version of ALCT firmware,
1047  // which is used in all chambers starting with 26/05/2008.
1050  (qual_prev > qual_this) )
1051  ghost_cleared[key_wire][i_pattern] = 1;
1052  }
1053  }
1054 
1055  // Next wire.
1056  // Skip this step if this wire is already declared "ghost".
1057  if (ghost_cleared[key_wire][i_pattern] == 1) {
1058  if (infoV > 1) LogTrace("CSCAnodeLCTProcessor")
1059  << ((i_pattern == 0) ? "Accelerator" : "Collision")
1060  << " pattern ghost cancelled on key_wire " << key_wire <<" q="<<qual_this
1061  << " by wire " << key_wire-1<<" q="<<qual_prev;
1062  continue;
1063  }
1064 
1065  int qual_next =
1066  (key_wire < numWireGroups-1) ? quality[key_wire+1][i_pattern] : 0;
1067  if (qual_next > 0) {
1068  int dt = first_bx[key_wire] - first_bx[key_wire+1];
1069  // Same cancellation logic as for the previous wire.
1070  if (dt == 0) {
1071  if (qual_next > qual_this) ghost_cleared[key_wire][i_pattern] = 1;
1072  }
1073  else if (dt > 0 && dt <= ghost_cancellation_bx_depth ) {
1074  // Next "if" check accounts for firmware bug and should be
1075  // removed once the next firmware version is used.
1076  // The bug is fixed in 5/5/2008 version of ALCT firmware,
1077  // which is used in all chambers starting with 26/05/2008.
1080  (qual_next >= qual_this) )
1081  ghost_cleared[key_wire][i_pattern] = 1;
1082  }
1083  }
1084  if (ghost_cleared[key_wire][i_pattern] == 1) {
1085  if (infoV > 1) LogTrace("CSCAnodeLCTProcessor")
1086  << ((i_pattern == 0) ? "Accelerator" : "Collision")
1087  << " pattern ghost cancelled on key_wire " << key_wire <<" q="<<qual_this
1088  << " by wire " << key_wire+1<<" q="<<qual_next;
1089  continue;
1090  }
1091  }
1092  }
1093  }
1094 
1095  // All cancellation is done in parallel, so wiregroups do not know what
1096  // their neighbors are cancelling.
1097  for (int key_wire = 0; key_wire < numWireGroups; key_wire++) {
1098  for (int i_pattern = 0; i_pattern < 2; i_pattern++) {
1099  if (ghost_cleared[key_wire][i_pattern] > 0) {
1100  clear(key_wire, i_pattern);
1101  }
1102  }
1103  }
1104 }
1105 
1106 
1108  /* This function looks for LCTs on the previous and next wires. If one
1109  exists and it has a better quality and a bx_time up to
1110  ghost_cancellation_bx_depth clocks earlier than the present,
1111  then the present LCT is cancelled. The present LCT
1112  also gets cancelled if it has the same quality as the one on the
1113  previous wire (this has not been done in 2003 test beam). The
1114  cancellation is done separately for collision and accelerator patterns. */
1115 
1116  int ghost_cleared[CSCConstants::MAX_NUM_WIRES][2];
1117 
1118  for (int key_wire = 0; key_wire < numWireGroups; key_wire++) {
1119  for (int i_pattern = 0; i_pattern < 2; i_pattern++) {
1120  ghost_cleared[key_wire][i_pattern] = 0;
1121 
1122  // Non-empty wire group.
1123  int qual_this = quality[key_wire][i_pattern];
1124  if (qual_this > 0) {
1125 
1126  if (runME21ILT_ or runME3141ILT_) qual_this = (qual_this & 0x03);
1127  // Previous wire.
1128  int dt = -1;
1129  int qual_prev = (key_wire > 0) ? quality[key_wire-1][i_pattern] : 0;
1130  if (qual_prev > 0) {
1131  if (use_corrected_bx)
1132  dt = first_bx_corrected[key_wire] - first_bx_corrected[key_wire-1];
1133  else
1134  dt = first_bx[key_wire] - first_bx[key_wire-1];
1135  // hack to run the Phase-II ME2/1, ME3/1 and ME4/1 ILT
1136  if (runME21ILT_ or runME3141ILT_) qual_prev = (qual_prev & 0x03);
1137 
1138  // Cancel this wire
1139  // 1) If the candidate at the previous wire is at the same bx
1140  // clock and has better quality (or equal? quality - this has
1141  // been implemented only in 2004).
1142  // 2) If the candidate at the previous wire is up to 4 clocks
1143  // earlier, regardless of quality.
1144  if (dt == 0) {
1145  if (qual_prev > qual_this) ghost_cleared[key_wire][i_pattern] = 1;
1146  }
1147  else if (dt > 0 && dt <= ghost_cancellation_bx_depth ) {
1148  // Next "if" check accounts for firmware bug and should be
1149  // removed once the next firmware version is used.
1150  // The bug is fixed in 5/5/2008 version of ALCT firmware,
1151  // which is used in all chambers starting with 26/05/2008.
1154  (qual_prev > qual_this) )
1155  ghost_cleared[key_wire][i_pattern] = 1;
1156  }
1157  }
1158 
1159  // Next wire.
1160  // Skip this step if this wire is already declared "ghost".
1161  if (ghost_cleared[key_wire][i_pattern] == 1) {
1162  if (infoV > 1) LogTrace("CSCAnodeLCTProcessor")
1163  << ((i_pattern == 0) ? "Accelerator" : "Collision")
1164  << " pattern ghost cancelled on key_wire " << key_wire <<" q="<<qual_this
1165  << " by wire " << key_wire-1<<" q="<<qual_prev<<" dt="<<dt;
1166  continue;
1167  }
1168 
1169  dt = -1;
1170  int qual_next =
1171  (key_wire < numWireGroups-1) ? quality[key_wire+1][i_pattern] : 0;
1172  if (qual_next > 0) {
1173  if (use_corrected_bx)
1174  dt = first_bx_corrected[key_wire] - first_bx_corrected[key_wire+1];
1175  else
1176  dt = first_bx[key_wire] - first_bx[key_wire+1];
1177  // hack to run the Phase-II ME2/1, ME3/1 and ME4/1 ILT
1178  if (runME21ILT_ or runME3141ILT_)
1179  qual_next = (qual_next & 0x03);
1180  // Same cancellation logic as for the previous wire.
1181  if (dt == 0) {
1182  if (qual_next >= qual_this) ghost_cleared[key_wire][i_pattern] = 1;
1183  }
1184  else if (dt > 0 && dt <= ghost_cancellation_bx_depth ) {
1185  // Next "if" check accounts for firmware bug and should be
1186  // removed once the next firmware version is used.
1187  // The bug is fixed in 5/5/2008 version of ALCT firmware,
1188  // which is used in all chambers starting with 26/05/2008.
1191  (qual_next >= qual_this) )
1192  ghost_cleared[key_wire][i_pattern] = 1;
1193  }
1194  }
1195  if (ghost_cleared[key_wire][i_pattern] == 1) {
1196  if (infoV > 1) LogTrace("CSCAnodeLCTProcessor")
1197  << ((i_pattern == 0) ? "Accelerator" : "Collision")
1198  << " pattern ghost cancelled on key_wire " << key_wire <<" q="<<qual_this
1199  << " by wire " << key_wire+1<<" q="<<qual_next<<" dt="<<dt;
1200  continue;
1201  }
1202  }
1203  }
1204  }
1205 
1206  // All cancellation is done in parallel, so wiregroups do not know what
1207  // their neighbors are cancelling.
1208  for (int key_wire = 0; key_wire < numWireGroups; key_wire++) {
1209  for (int i_pattern = 0; i_pattern < 2; i_pattern++) {
1210  if (ghost_cleared[key_wire][i_pattern] > 0) {
1211  clear(key_wire, i_pattern);
1212  }
1213  }
1214  }
1215 }
1216 
1217 
1219  // First modify the quality according accel_mode, then store all
1220  // of the valid LCTs in an array.
1221  std::vector<CSCALCTDigi> lct_list;
1222 
1223  for (int i_wire = 0; i_wire < numWireGroups; i_wire++) {
1224  // If there is either accelerator or collision, perform trigMode
1225  // function before storing and sorting.
1226  if (quality[i_wire][0] > 0 || quality[i_wire][1] > 0) {
1227  trigMode(i_wire);
1228 
1229  int bx = first_bx[i_wire];
1230  int fbx = first_bx_corrected[i_wire];
1231  if (infoV>1) LogTrace("CSCAnodeLCTProcessor")<<" bx="<<bx<<" fbx="<<fbx;
1232  if (use_corrected_bx) {
1233  bx = fbx;
1234  fbx = first_bx[i_wire];
1235  }
1236  if (infoV>1) LogTrace("CSCAnodeLCTProcessor")<<" bx="<<bx<<" fbx="<<fbx;
1237  // Store any valid accelerator pattern LCTs.
1238  if (quality[i_wire][0] > 0) {
1239  int qual = (quality[i_wire][0] & 0x03); // 2 LSBs
1240  CSCALCTDigi lct_info(1, qual, 1, 0, i_wire, bx);
1241  lct_info.setFullBX(fbx);
1242  lct_list.push_back(lct_info);
1243  }
1244 
1245  // Store any valid collision pattern LCTs.
1246  if (quality[i_wire][1] > 0) {
1247  int qual = (quality[i_wire][1] & 0x03); // 2 LSBs
1248  CSCALCTDigi lct_info(1, qual, 0, quality[i_wire][2], i_wire, bx);
1249  //lct_info.setFullBX(fbx); // uncomment if one wants, e.g., to keep corrected time here
1250  lct_list.push_back(lct_info);
1251  if (infoV>1) LogTrace("CSCAnodeLCTProcessor")<<" got lct_info: "<<lct_info;
1252  }
1253 
1254  // Modify qualities according to accel_mode parameter.
1255  accelMode(i_wire);
1256  }
1257  }
1258 
1259  // Best track selector selects two collision and two accelerator ALCTs
1260  // with the best quality per time bin.
1261  std::vector<CSCALCTDigi> fourBest = bestTrackSelector(lct_list);
1262 
1263  if (infoV > 0) {
1264  int n_alct_all=0, n_alct=0;
1265  for (std::vector <CSCALCTDigi>::const_iterator plct = lct_list.begin(); plct != lct_list.end(); plct++)
1266  if (plct->isValid() && plct->getBX()==6) n_alct_all++;
1267  for (std::vector <CSCALCTDigi>::const_iterator plct = fourBest.begin(); plct != fourBest.end(); plct++)
1268  if (plct->isValid() && plct->getBX()==6) n_alct++;
1269 
1270  LogTrace("CSCAnodeLCTProcessor")<<"alct_count E:"<<theEndcap<<"S:"<<theStation<<"R:"<<theRing<<"C:"<<theChamber
1271  <<" all "<<n_alct_all<<" found "<<n_alct;
1272  }
1273 
1274  // Select two best of four per time bin, based on quality and
1275  // accel_mode parameter.
1276  for (std::vector<CSCALCTDigi>::const_iterator plct = fourBest.begin();
1277  plct != fourBest.end(); plct++) {
1278 
1279  int bx = plct->getBX();
1280  if (bx >= CSCConstants::MAX_ALCT_TBINS) {
1281  if (infoV > 0) edm::LogWarning("L1CSCTPEmulatorOutOfTimeALCT")
1282  << "+++ Bx of ALCT candidate, " << bx << ", exceeds max allowed, "
1283  << CSCConstants::MAX_ALCT_TBINS-1 << "; skipping it... +++\n";
1284  continue;
1285  }
1286 
1287  if (isBetterALCT(*plct, bestALCT[bx])) {
1288  if (isBetterALCT(bestALCT[bx], secondALCT[bx])) {
1289  secondALCT[bx] = bestALCT[bx];
1290  }
1291  bestALCT[bx] = *plct;
1292  }
1293  else if (isBetterALCT(*plct, secondALCT[bx])) {
1294  secondALCT[bx] = *plct;
1295  }
1296  }
1297 
1298  if (!isTMB07) {
1299  // Prior to DAQ-2006 format, only ALCTs at the earliest bx were reported.
1301  for (int bx = 0; bx < CSCConstants::MAX_ALCT_TBINS; bx++) {
1302  if (bestALCT[bx].isValid()) {
1303  first_bx = bx;
1304  break;
1305  }
1306  }
1307  if (first_bx < CSCConstants::MAX_ALCT_TBINS) {
1308  for (int bx = first_bx + 1; bx < CSCConstants::MAX_ALCT_TBINS; bx++) {
1309  if (bestALCT[bx].isValid()) bestALCT[bx].clear();
1310  if (secondALCT[bx].isValid()) secondALCT[bx].clear();
1311  }
1312  }
1313  }
1314 
1315  for (int bx = 0; bx < CSCConstants::MAX_ALCT_TBINS; bx++) {
1316  if (bestALCT[bx].isValid()) {
1317  bestALCT[bx].setTrknmb(1);
1318  if (infoV > 0) {
1319  LogDebug("CSCAnodeLCTProcessor")
1320  << "\n" << bestALCT[bx] << " fullBX = "<<bestALCT[bx].getFullBX()
1321  << " found in ME"
1322  << ((theEndcap == 1) ? "+" : "-")
1323  << theStation << "/" << theRing << "/" << theChamber
1324  << " (sector " << theSector << " subsector " << theSubsector
1325  << " trig id. " << theTrigChamber << ")" << "\n";
1326  }
1327  if (secondALCT[bx].isValid()) {
1328  secondALCT[bx].setTrknmb(2);
1329  if (infoV > 0) {
1330  LogDebug("CSCAnodeLCTProcessor")
1331  << secondALCT[bx] << " fullBX = "<<secondALCT[bx].getFullBX()
1332  << " found in ME"
1333  << ((theEndcap == 1) ? "+" : "-")
1334  << theStation << "/" << theRing << "/" << theChamber
1335  << " (sector " << theSector << " subsector " << theSubsector
1336  << " trig id. " << theTrigChamber << ")" << "\n";
1337  }
1338  }
1339  }
1340  }
1341 }
1342 
1344  const std::vector<CSCALCTDigi>& all_alcts) {
1345  /* Selects two collision and two accelerator ALCTs per time bin with
1346  the best quality. */
1348 
1349  if (infoV > 1) {
1350  LogTrace("CSCAnodeLCTProcessor") << all_alcts.size() <<
1351  " ALCTs at the input of best-track selector: ";
1352  for (std::vector <CSCALCTDigi>::const_iterator plct = all_alcts.begin();
1353  plct != all_alcts.end(); plct++) {
1354  if (!plct->isValid()) continue;
1355  LogTrace("CSCAnodeLCTProcessor") << (*plct);
1356  }
1357  }
1358 
1360  for (std::vector <CSCALCTDigi>::const_iterator plct = all_alcts.begin();
1361  plct != all_alcts.end(); plct++) {
1362  if (!plct->isValid()) continue;
1363 
1364  // Select two collision and two accelerator ALCTs with the highest
1365  // quality at every bx. The search for best ALCTs is done in parallel
1366  // for collision and accelerator patterns, and simultaneously for
1367  // two ALCTs, tA and tB. If two or more ALCTs have equal qualities,
1368  // the priority is given to the ALCT with larger wiregroup number
1369  // in the search for tA (collision and accelerator), and to the ALCT
1370  // with smaller wiregroup number in the search for tB.
1371  int bx = (*plct).getBX();
1372  int accel = (*plct).getAccelerator();
1373  int qual = (*plct).getQuality();
1374  int wire = (*plct).getKeyWG();
1375  bool vA = tA[bx][accel].isValid();
1376  bool vB = tB[bx][accel].isValid();
1377  int qA = tA[bx][accel].getQuality();
1378  int qB = tB[bx][accel].getQuality();
1379  int wA = tA[bx][accel].getKeyWG();
1380  int wB = tB[bx][accel].getKeyWG();
1381  if (!vA || qual > qA || (qual == qA && wire > wA)) {
1382  tA[bx][accel] = *plct;
1383  }
1384  if (!vB || qual > qB || (qual == qB && wire < wB)) {
1385  tB[bx][accel] = *plct;
1386  }
1387  }
1388 
1389  for (int bx = 0; bx < CSCConstants::MAX_ALCT_TBINS; bx++) {
1390  for (int accel = 0; accel <= 1; accel++) {
1391  // Best ALCT is always tA.
1392  if (tA[bx][accel].isValid()) {
1393  if (infoV > 2) {
1394  LogTrace("CSCAnodeLCTProcessor") << "tA: " << tA[bx][accel];
1395  LogTrace("CSCAnodeLCTProcessor") << "tB: " << tB[bx][accel];
1396  }
1397  bestALCTs[bx][accel] = tA[bx][accel];
1398 
1399  // If tA exists, tB exists too.
1400  if (tA[bx][accel] != tB[bx][accel] &&
1401  tA[bx][accel].getQuality() == tB[bx][accel].getQuality()) {
1402  secondALCTs[bx][accel] = tB[bx][accel];
1403  }
1404  else {
1405  // Funny part: if tA and tB are the same, or the quality of tB
1406  // is inferior to the quality of tA, the second best ALCT is
1407  // not tB. Instead it is the largest-wiregroup ALCT among those
1408  // ALCT whose qualities are lower than the quality of the best one.
1409  for (std::vector <CSCALCTDigi>::const_iterator plct =
1410  all_alcts.begin(); plct != all_alcts.end(); plct++) {
1411  if ((*plct).isValid() &&
1412  (*plct).getAccelerator() == accel && (*plct).getBX() == bx &&
1413  (*plct).getQuality() < bestALCTs[bx][accel].getQuality() &&
1414  (*plct).getQuality() >= secondALCTs[bx][accel].getQuality() &&
1415  (*plct).getKeyWG() >= secondALCTs[bx][accel].getKeyWG()) {
1416  secondALCTs[bx][accel] = *plct;
1417  }
1418  }
1419  }
1420  }
1421  }
1422  }
1423 
1424  // Fill the vector with up to four best ALCTs per bx and return it.
1425  std::vector<CSCALCTDigi> fourBest;
1426  for (int bx = 0; bx < CSCConstants::MAX_ALCT_TBINS; bx++) {
1427  for (int i = 0; i < 2; i++) {
1428  if (bestALCTs[bx][i].isValid()) fourBest.push_back(bestALCTs[bx][i]);
1429  }
1430  for (int i = 0; i < 2; i++) {
1431  if (secondALCTs[bx][i].isValid()) fourBest.push_back(secondALCTs[bx][i]);
1432  }
1433  }
1434 
1435  if (infoV > 1) {
1436  LogTrace("CSCAnodeLCTProcessor") << fourBest.size() << " ALCTs selected: ";
1437  for (std::vector<CSCALCTDigi>::const_iterator plct = fourBest.begin();
1438  plct != fourBest.end(); plct++) {
1439  LogTrace("CSCAnodeLCTProcessor") << (*plct);
1440  }
1441  }
1442 
1443  return fourBest;
1444 }
1445 
1447  const CSCALCTDigi& rhsALCT) {
1448  /* This method should have been an overloaded > operator, but we
1449  have to keep it here since need to check values in quality[][]
1450  array modified according to accel_mode parameter. */
1451  bool returnValue = false;
1452 
1453  if (lhsALCT.isValid() && !rhsALCT.isValid()) {return true;}
1454 
1455  // ALCTs found at earlier bx times are ranked higher than ALCTs found at
1456  // later bx times regardless of the quality.
1457  if (lhsALCT.getBX() < rhsALCT.getBX()) {returnValue = true;}
1458  if (lhsALCT.getBX() != rhsALCT.getBX()) {return returnValue;}
1459 
1460  // First check the quality of ALCTs.
1461  int qual1 = lhsALCT.getQuality();
1462  int qual2 = rhsALCT.getQuality();
1463  if (qual1 > qual2) {returnValue = true;}
1464  // If qualities are the same, check accelerator bits of both ALCTs.
1465  // If they are not the same, rank according to accel_mode value.
1466  // If they are the same, keep the track selector assignment.
1467  else if (qual1 == qual2 &&
1468  lhsALCT.getAccelerator() != rhsALCT.getAccelerator() &&
1469  quality[lhsALCT.getKeyWG()][1-lhsALCT.getAccelerator()] >
1470  quality[rhsALCT.getKeyWG()][1-rhsALCT.getAccelerator()])
1471  {returnValue = true;}
1472 
1473  return returnValue;
1474 }
1475 
1476 void CSCAnodeLCTProcessor::trigMode(const int key_wire) {
1477  /* Function which enables/disables either collision or accelerator tracks.
1478  The function uses the trig_mode parameter to decide. */
1479 
1480  switch(trig_mode) {
1481  default:
1482  case 0:
1483  // Enables both collision and accelerator tracks
1484  break;
1485  case 1:
1486  // Disables collision tracks
1487  if (quality[key_wire][1] > 0) {
1488  quality[key_wire][1] = 0;
1489  if (infoV > 1) LogTrace("CSCAnodeLCTProcessor")
1490  << "trigMode(): collision track " << key_wire << " disabled" << "\n";
1491  }
1492  break;
1493  case 2:
1494  // Disables accelerator tracks
1495  if (quality[key_wire][0] > 0) {
1496  quality[key_wire][0] = 0;
1497  if (infoV > 1) LogTrace("CSCAnodeLCTProcessor")
1498  << "trigMode(): accelerator track " << key_wire << " disabled" << "\n";
1499  }
1500  break;
1501  case 3:
1502  // Disables collision track if there is an accelerator track found
1503  // in the same wire group at the same time
1504  if (quality[key_wire][0] > 0 && quality[key_wire][1] > 0) {
1505  quality[key_wire][1] = 0;
1506  if (infoV > 1) LogTrace("CSCAnodeLCTProcessor")
1507  << "trigMode(): collision track " << key_wire << " disabled" << "\n";
1508  }
1509  break;
1510  }
1511 }
1512 
1513 void CSCAnodeLCTProcessor::accelMode(const int key_wire) {
1514  /* Function which gives a preference either to the collision patterns
1515  or accelerator patterns. The function uses the accel_mode parameter
1516  to decide. */
1517  int promotionBit = 1 << 2;
1518 
1519  switch(accel_mode) {
1520  default:
1521  case 0:
1522  // Ignore accelerator muons.
1523  if (quality[key_wire][0] > 0) {
1524  quality[key_wire][0] = 0;
1525  if (infoV > 1) LogTrace("CSCAnodeLCTProcessor")
1526  << "alctMode(): accelerator track " << key_wire << " ignored" << "\n";
1527  }
1528  break;
1529  case 1:
1530  // Prefer collision muons by adding promotion bit.
1531  if (quality[key_wire][1] > 0) {
1532  quality[key_wire][1] += promotionBit;
1533  if (infoV > 1) LogTrace("CSCAnodeLCTProcessor")
1534  << "alctMode(): collision track " << key_wire << " promoted" << "\n";
1535  }
1536  break;
1537  case 2:
1538  // Prefer accelerator muons by adding promotion bit.
1539  if (quality[key_wire][0] > 0) {
1540  quality[key_wire][0] += promotionBit;
1541  if (infoV > 1) LogTrace("CSCAnodeLCTProcessor")
1542  << "alctMode(): accelerator track " << key_wire << " promoted"<< "\n";
1543  }
1544  break;
1545  case 3:
1546  // Ignore collision muons.
1547  if (quality[key_wire][1] > 0) {
1548  quality[key_wire][1] = 0;
1549  if (infoV > 1) LogTrace("CSCAnodeLCTProcessor")
1550  << "alctMode(): collision track " << key_wire << " ignored" << "\n";
1551  }
1552  break;
1553  }
1554 }
1555 
1556 // Dump of configuration parameters.
1558  std::ostringstream strm;
1559  strm << "\n";
1560  strm << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
1561  strm << "+ ALCT configuration parameters: +\n";
1562  strm << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
1563  strm << " fifo_tbins [total number of time bins in DAQ readout] = "
1564  << fifo_tbins << "\n";
1565  strm << " fifo_pretrig [start time of anode raw hits in DAQ readout] = "
1566  << fifo_pretrig << "\n";
1567  strm << " drift_delay [drift delay after pre-trigger, in 25 ns bins] = "
1568  << drift_delay << "\n";
1569  strm << " nplanes_hit_pretrig [min. number of layers hit for pre-trigger] = "
1570  << nplanes_hit_pretrig << "\n";
1571  strm << " nplanes_hit_pattern [min. number of layers hit for trigger] = "
1572  << nplanes_hit_pattern << "\n";
1573  strm << " nplanes_hit_accel_pretrig [min. number of layers hit for accel."
1574  << " pre-trig.] = " << nplanes_hit_accel_pretrig << "\n";
1575  strm << " nplanes_hit_accel_pattern [min. number of layers hit for accel."
1576  << " trigger] = " << nplanes_hit_accel_pattern << "\n";
1577  strm << " trig_mode [enabling/disabling collision/accelerator tracks] = "
1578  << trig_mode << "\n";
1579  strm << " accel_mode [preference to collision/accelerator tracks] = "
1580  << accel_mode << "\n";
1581  strm << " l1a_window_width [L1Accept window width, in 25 ns bins] = "
1582  << l1a_window_width << "\n";
1583  strm << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
1584  LogDebug("CSCAnodeLCTProcessor") << strm.str();
1585  //std::cout<<strm.str()<<std::endl;
1586 }
1587 
1588 // Dump of digis on wire groups.
1590  LogDebug("CSCAnodeLCTProcessor")
1591  << "ME" << ((theEndcap == 1) ? "+" : "-")
1592  << theStation << "/" << theRing << "/" << theChamber
1593  << " nWiregroups " << numWireGroups;
1594 
1595  std::ostringstream strstrm;
1596  for (int i_wire = 0; i_wire < numWireGroups; i_wire++) {
1597  if (i_wire%10 == 0) {
1598  if (i_wire < 100) strstrm << i_wire/10;
1599  else strstrm << (i_wire-100)/10;
1600  }
1601  else strstrm << " ";
1602  }
1603  strstrm << "\n";
1604  for (int i_wire = 0; i_wire < numWireGroups; i_wire++) {
1605  strstrm << i_wire%10;
1606  }
1607  for (int i_layer = 0; i_layer < CSCConstants::NUM_LAYERS; i_layer++) {
1608  strstrm << "\n";
1609  for (int i_wire = 0; i_wire < numWireGroups; i_wire++) {
1610  if (!wire[i_layer][i_wire].empty()) {
1611  std::vector<int> bx_times = wire[i_layer][i_wire];
1612  strstrm << std::hex << bx_times[0] << std::dec;
1613  }
1614  else {
1615  strstrm << ".";
1616  }
1617  }
1618  }
1619  LogTrace("CSCAnodeLCTProcessor") << strstrm.str();
1620 }
1621 
1622 // Returns vector of read-out ALCTs, if any. Starts with the vector of
1623 // all found ALCTs and selects the ones in the read-out time window.
1624 std::vector<CSCALCTDigi> CSCAnodeLCTProcessor::readoutALCTs() {
1625  std::vector<CSCALCTDigi> tmpV;
1626 
1627  // The number of LCT bins in the read-out is given by the
1628  // l1a_window_width parameter, but made even by setting the LSB of
1629  // l1a_window_width to 0.
1630  const int lct_bins =
1631  // (l1a_window_width%2 == 0) ? l1a_window_width : l1a_window_width-1;
1633  static std::atomic<int> late_tbins{early_tbins + lct_bins};
1634 
1635  static std::atomic<int> ifois{0};
1636  if (ifois == 0) {
1637 
1638  //std::cout<<"ALCT early_tbins="<<early_tbins<<" lct_bins="<<lct_bins<<" l1a_window_width="<<l1a_window_width<<" late_tbins="<<late_tbins<<std::endl;
1639  //std::cout<<"**** ALCT readoutALCTs config dump ****"<<std::endl;
1640  //dumpConfigParams();
1641 
1642  if (infoV >= 0 && early_tbins < 0) {
1643  edm::LogWarning("L1CSCTPEmulatorSuspiciousParameters")
1644  << "+++ fifo_pretrig = " << fifo_pretrig
1645  << "; in-time ALCTs are not getting read-out!!! +++" << "\n";
1646  }
1647 
1648  if (late_tbins > CSCConstants::MAX_ALCT_TBINS-1) {
1649  if (infoV >= 0) edm::LogWarning("L1CSCTPEmulatorSuspiciousParameters")
1650  << "+++ Allowed range of time bins, [0-" << late_tbins
1651  << "] exceeds max allowed, " << CSCConstants::MAX_ALCT_TBINS-1 << " +++\n"
1652  << "+++ Set late_tbins to max allowed +++\n";
1653  late_tbins = CSCConstants::MAX_ALCT_TBINS-1;
1654  }
1655  ifois = 1;
1656  }
1657 
1658  // Start from the vector of all found ALCTs and select those within
1659  // the ALCT*L1A coincidence window.
1660  std::vector<CSCALCTDigi> all_alcts = getALCTs();
1661  for (std::vector <CSCALCTDigi>::const_iterator plct = all_alcts.begin();
1662  plct != all_alcts.end(); plct++) {
1663  if (!plct->isValid()) continue;
1664 
1665  int bx = (*plct).getBX();
1666  // Skip ALCTs found too early relative to L1Accept.
1667  if (bx <= early_tbins) {
1668  if (infoV > 1) LogDebug("CSCAnodeLCTProcessor")
1669  << " Do not report ALCT on keywire " << plct->getKeyWG()
1670  << ": found at bx " << bx << ", whereas the earliest allowed bx is "
1671  << early_tbins+1;
1672  continue;
1673  }
1674 
1675  // Skip ALCTs found too late relative to L1Accept.
1676  if (bx > late_tbins) {
1677  if (infoV > 1) LogDebug("CSCAnodeLCTProcessor")
1678  << " Do not report ALCT on keywire " << plct->getKeyWG()
1679  << ": found at bx " << bx << ", whereas the latest allowed bx is "
1680  << late_tbins;
1681  continue;
1682  }
1683 
1684  tmpV.push_back(*plct);
1685  }
1686  return tmpV;
1687 }
1688 
1689 // Returns vector of all found ALCTs, if any. Used in ALCT-CLCT matching.
1690 std::vector<CSCALCTDigi> CSCAnodeLCTProcessor::getALCTs() {
1691  std::vector<CSCALCTDigi> tmpV;
1692  for (int bx = 0; bx < CSCConstants::MAX_ALCT_TBINS; bx++) {
1693  if (bestALCT[bx].isValid()) tmpV.push_back(bestALCT[bx]);
1694  if (secondALCT[bx].isValid()) tmpV.push_back(secondALCT[bx]);
1695  }
1696  return tmpV;
1697 }
1698 
1701 
1702 void CSCAnodeLCTProcessor::showPatterns(const int key_wire) {
1703  /* Method to test the pretrigger */
1704  for (int i_pattern = 0; i_pattern < CSCConstants::NUM_ALCT_PATTERNS;
1705  i_pattern++) {
1706  std::ostringstream strstrm_header;
1707  LogTrace("CSCAnodeLCTProcessor")
1708  << "\n" << "Pattern: " << i_pattern << " Key wire: " << key_wire;
1709  for (int i = 1; i <= 32; i++) {
1710  strstrm_header << ((32-i)%10);
1711  }
1712  LogTrace("CSCAnodeLCTProcessor") << strstrm_header.str();
1713  for (int i_wire = 0; i_wire < CSCConstants::MAX_WIRES_IN_PATTERN; i_wire++) {
1714  if (pattern_mask[i_pattern][i_wire] != 0) {
1715  std::ostringstream strstrm_pulse;
1716  int this_layer = pattern_envelope[0][i_wire];
1717  int this_wire = pattern_envelope[1+MESelection][i_wire]+key_wire;
1718  if (this_wire >= 0 && this_wire < numWireGroups) {
1719  for (int i = 1; i <= 32; i++) {
1720  strstrm_pulse << ((pulse[this_layer][this_wire]>>(32-i)) & 1);
1721  }
1722  LogTrace("CSCAnodeLCTProcessor")
1723  << strstrm_pulse.str() << " on layer " << this_layer;
1724  }
1725  }
1726  }
1727  LogTrace("CSCAnodeLCTProcessor")
1728  << "-------------------------------------------";
1729  }
1730 }
#define LogDebug(id)
static const int time_weights[CSCConstants::MAX_WIRES_IN_PATTERN]
T getParameter(std::string const &) const
float dt
Definition: AMPTWrapper.h:126
void showPatterns(const int key_wire)
void readWireDigis(std::vector< int > wire[CSCConstants::NUM_LAYERS][CSCConstants::MAX_NUM_WIRES])
bool existsAs(std::string const &parameterName, bool trackiness=true) const
checks if a parameter exists as a given type
Definition: ParameterSet.h:186
int quality[CSCConstants::MAX_NUM_WIRES][3]
unsigned int alctDriftDelay() const
int first_bx_corrected[CSCConstants::MAX_NUM_WIRES]
static const unsigned int def_drift_delay
static const unsigned int def_fifo_tbins
bool getDigis(const CSCWireDigiCollection *wiredc)
bool isValid() const
check ALCT validity (1 - valid ALCT)
Definition: CSCALCTDigi.h:30
void clear()
clear this ALCT
Definition: CSCALCTDigi.cc:35
unsigned int alctNplanesHitPretrig() const
void setConfigParameters(const CSCDBL1TPParameters *conf)
void trigMode(const int key_wire)
static int ringFromTriggerLabels(int station, int triggerCSCID)
static const unsigned int def_accel_mode
unsigned int alctL1aWindowWidth() const
int getFullBX() const
return 12-bit full BX.
Definition: CSCALCTDigi.h:57
static const int pattern_envelope[CSCConstants::NUM_ALCT_PATTERNS][CSCConstants::MAX_WIRES_IN_PATTERN]
static const unsigned int def_nplanes_hit_accel_pretrig
static const unsigned int def_fifo_pretrig
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
void accelMode(const int key_wire)
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
int pattern_mask[CSCConstants::NUM_ALCT_PATTERNS][CSCConstants::MAX_WIRES_IN_PATTERN]
static const unsigned int def_nplanes_hit_pattern
unsigned int alctTrigMode() const
#define LogTrace(id)
bool preTrigger(const int key_wire, const int start_bx)
bool pulseExtension(const std::vector< int > wire[CSCConstants::NUM_LAYERS][CSCConstants::MAX_NUM_WIRES])
int getBX() const
return BX - five low bits of BXN counter tagged by the ALCT
Definition: CSCALCTDigi.h:48
CSCALCTDigi secondALCT[CSCConstants::MAX_ALCT_TBINS]
static const unsigned int def_l1a_window_width
static const int pattern_mask_open[CSCConstants::NUM_ALCT_PATTERNS][CSCConstants::MAX_WIRES_IN_PATTERN]
int getQuality() const
return quality of a pattern
Definition: CSCALCTDigi.h:33
bool isBetterALCT(const CSCALCTDigi &lhsALCT, const CSCALCTDigi &rhsALCT)
unsigned int alctAccelMode() const
static const unsigned int def_trig_mode
int getAccelerator() const
Definition: CSCALCTDigi.h:37
static const unsigned int def_nplanes_hit_accel_pattern
unsigned int alctFifoPretrig() const
std::vector< CSCALCTDigi > readoutALCTs()
const CSCGeometry * csc_g
unsigned int alctNplanesHitAccelPretrig() const
const CSCChamber * chamber(CSCDetId id) const
Return the chamber corresponding to given DetId.
Definition: CSCGeometry.cc:118
std::vector< CSCWireDigi >::const_iterator const_iterator
unsigned int alctNplanesHitAccelPattern() const
std::vector< CSCALCTDigi > bestTrackSelector(const std::vector< CSCALCTDigi > &all_alcts)
#define begin
Definition: vmac.h:32
CSCALCTDigi bestALCT[CSCConstants::MAX_ALCT_TBINS]
int first_bx[CSCConstants::MAX_NUM_WIRES]
std::pair< const_iterator, const_iterator > Range
void dumpDigis(const std::vector< int > wire[CSCConstants::NUM_LAYERS][CSCConstants::MAX_NUM_WIRES]) const
void setTrknmb(const uint16_t number)
Set track number (1,2) after sorting ALCTs.
Definition: CSCALCTDigi.h:54
void setFullBX(const uint16_t fullbx)
Set 12-bit full BX.
Definition: CSCALCTDigi.h:60
unsigned int pulse[CSCConstants::NUM_LAYERS][CSCConstants::MAX_NUM_WIRES]
unsigned int alctNplanesHitPattern() const
bool patternDetection(const int key_wire)
static const int pattern_mask_r1[CSCConstants::NUM_ALCT_PATTERNS][CSCConstants::MAX_WIRES_IN_PATTERN]
unsigned int nplanes_hit_accel_pattern
std::vector< CSCALCTDigi > run(const CSCWireDigiCollection *wiredc)
unsigned int pretrig_extra_deadtime
int getKeyWG() const
return key wire group
Definition: CSCALCTDigi.h:45
std::vector< CSCWireDigi > digiV[CSCConstants::NUM_LAYERS]
static int chamberFromTriggerLabels(int TriggerSector, int TriggerSubSector, int station, int TriggerCSCID)
static const int pattern_mask_slim[CSCConstants::NUM_ALCT_PATTERNS][CSCConstants::MAX_WIRES_IN_PATTERN]
std::vector< CSCALCTDigi > getALCTs()
static const unsigned int def_nplanes_hit_pretrig
unsigned int nplanes_hit_accel_pretrig
unsigned int alctFifoTbins() const