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