CMS 3D CMS Logo

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