CMS 3D CMS Logo

CSCUpgradeCathodeLCTProcessor.cc
Go to the documentation of this file.
2 
3 #include <iomanip>
4 #include <iostream>
5 
7  unsigned station,
8  unsigned sector,
9  unsigned subsector,
10  unsigned chamber,
11  const edm::ParameterSet& conf)
12  : CSCCathodeLCTProcessor(endcap, station, sector, subsector, chamber, conf) {
13  if (!isSLHC_)
14  edm::LogError("CSCUpgradeCathodeLCTProcessor|ConfigError")
15  << "+++ Upgrade CSCUpgradeCathodeLCTProcessor constructed while isSLHC_ is not set! +++\n";
16 
17  // use of localized dead-time zones
18  use_dead_time_zoning = clctParams_.getParameter<bool>("useDeadTimeZoning");
19  clct_state_machine_zone = clctParams_.getParameter<unsigned int>("clctStateMachineZone");
20  dynamic_state_machine_zone = clctParams_.getParameter<bool>("useDynamicStateMachineZone");
21 
22  // how far away may trigger happen from pretrigger
23  pretrig_trig_zone = clctParams_.getParameter<unsigned int>("clctPretriggerTriggerZone");
24 
25  // whether to calculate bx as corrected_bx instead of pretrigger one
26  use_corrected_bx = clctParams_.getParameter<bool>("clctUseCorrectedBx");
27 }
28 
30  if (!isSLHC_)
31  edm::LogError("CSCUpgradeCathodeLCTProcessor|ConfigError")
32  << "+++ Upgrade CSCUpgradeCathodeLCTProcessor constructed while isSLHC_ is not set! +++\n";
33 }
34 
35 // --------------------------------------------------------------------------
36 // The code below is for SLHC studies of the CLCT algorithm (half-strips only).
37 // --------------------------------------------------------------------------
38 
39 // SLHC version, add the feature of localized dead time zone for pretrigger
42  const int start_bx,
43  int& first_bx) {
44  if (isSLHC_ and !use_dead_time_zoning) {
45  return CSCCathodeLCTProcessor::preTrigger(pulse, start_bx, first_bx);
46  }
47 
48  if (infoV > 1)
49  LogTrace("CSCUpgradeCathodeLCTProcessor")
50  << "....................PreTrigger, SLHC version with localized dead time zone...........................";
51 
52  // Max. number of half-strips for this chamber.
53  const int nStrips = 2 * numStrips + 1;
54 
55  int nPreTriggers = 0;
56 
57  bool pre_trig = false;
58  int delta_hs = clct_state_machine_zone; //dead time zone
59 
60  // Now do a loop over bx times to see (if/when) track goes over threshold
61  for (unsigned int bx_time = start_bx; bx_time < fifo_tbins; bx_time++) {
62  // For any given bunch-crossing, start at the lowest keystrip and look for
63  // the number of separate layers in the pattern for that keystrip that have
64  // pulses at that bunch-crossing time. Do the same for the next keystrip,
65  // etc. Then do the entire process again for the next bunch-crossing, etc
66  // until you find a pre-trigger.
67  bool hits_in_time = patternFinding(pulse, nStrips, bx_time);
68  if (hits_in_time) {
69  for (int hstrip = stagger[CSCConstants::KEY_CLCT_LAYER - 1]; hstrip < nStrips; hstrip++) {
70  if (infoV > 1) {
71  if (nhits[hstrip] > 0) {
72  LogTrace("CSCUpgradeCathodeLCTProcessor")
73  << " bx = " << std::setw(2) << bx_time << " --->"
74  << " halfstrip = " << std::setw(3) << hstrip << " best pid = " << std::setw(2) << best_pid[hstrip]
75  << " nhits = " << nhits[hstrip];
76  }
77  }
78  //ispretrig[hstrip] = false; it is initialzed in findLCT
79  if (nhits[hstrip] >= nplanes_hit_pretrig && best_pid[hstrip] >= pid_thresh_pretrig &&
80  !busyMap[hstrip][bx_time]) {
81  pre_trig = true;
82  ispretrig[hstrip] = true;
83 
84  // write each pre-trigger to output
85  nPreTriggers++;
87  const int halfstrip = hstrip % CSCConstants::NUM_HALF_STRIPS_PER_CFEB;
88  const int cfeb = hstrip / CSCConstants::NUM_HALF_STRIPS_PER_CFEB;
90  1, nhits[hstrip], best_pid[hstrip], 1, bend, halfstrip, cfeb, bx_time, nPreTriggers, 0));
91 
92  } else if (nhits[hstrip] >= nplanes_hit_pretrig &&
93  best_pid[hstrip] >= pid_thresh_pretrig) { //busy zone, keep pretriggering,ignore this
94  ispretrig[hstrip] = true;
95  if (infoV > 1)
96  LogTrace("CSCUpgradeCathodeLCTProcessor")
97  << " halfstrip " << std::setw(3) << hstrip << " in dead zone and is pretriggerred";
98  } else if (nhits[hstrip] < nplanes_hit_pretrig || best_pid[hstrip] < pid_thresh_pretrig) {
99  // not pretriggered anyone, release dead zone
100  ispretrig[hstrip] = false;
101  }
102  } // find all pretriggers
103 
104  //update dead zone
105  for (int hstrip = stagger[CSCConstants::KEY_CLCT_LAYER - 1]; hstrip < nStrips; hstrip++) {
106  if (ispretrig[hstrip]) {
107  int min_hstrip = hstrip - delta_hs; //only fixed localized dead time zone is implemented
108  int max_hstrip = hstrip + delta_hs;
109  if (min_hstrip < stagger[CSCConstants::KEY_CLCT_LAYER - 1])
110  min_hstrip = stagger[CSCConstants::KEY_CLCT_LAYER - 1];
111  if (max_hstrip >= nStrips)
112  max_hstrip = nStrips - 1;
113  for (int hs = min_hstrip; hs <= max_hstrip; hs++)
114  busyMap[hs][bx_time + 1] = true;
115  if (infoV > 1)
116  LogTrace("CSCUpgradeCathodeLCTProcessor")
117  << " marked zone around pretriggerred halfstrip " << hstrip << " as dead zone for pretriggering at bx"
118  << bx_time + 1 << " halfstrip: [" << min_hstrip << "," << max_hstrip << "]";
119  }
120  }
121  if (pre_trig) {
122  first_bx = bx_time; // bx at time of pretrigger
123  return true;
124  }
125  } else //no pattern found, remove all dead time zone
126  for (int hstrip = stagger[CSCConstants::KEY_CLCT_LAYER - 1]; hstrip < nStrips; hstrip++) {
127  if (ispretrig[hstrip])
128  ispretrig[hstrip] = false; //dead zone is gone by default
129  }
130 
131  } // end loop over bx times
132 
133  if (infoV > 1)
134  LogTrace("CSCUpgradeCathodeLCTProcessor") << "no pretrigger, returning \n";
135  first_bx = fifo_tbins;
136  return false;
137 } // preTrigger -- SLHC version.
138 
139 // SLHC version.
141  const std::vector<int> halfstrip[CSCConstants::NUM_LAYERS][CSCConstants::NUM_HALF_STRIPS_7CFEBS]) {
142  // run the original algorithm in case we do not use dead time zoning
143  if (isSLHC_ and !use_dead_time_zoning) {
144  return CSCCathodeLCTProcessor::findLCTs(halfstrip);
145  }
146 
147  std::vector<CSCCLCTDigi> lctList;
148 
149  // Max. number of half-strips for this chamber.
150  const int maxHalfStrips = 2 * numStrips + 1;
151 
152  // initialize the ispretrig before doing pretriggering
153  for (int hstrip = stagger[CSCConstants::KEY_CLCT_LAYER - 1]; hstrip < maxHalfStrips; hstrip++) {
154  ispretrig[hstrip] = false;
155  }
156 
157  if (infoV > 1)
158  dumpDigis(halfstrip, maxHalfStrips);
159 
160  // keeps dead-time zones around key halfstrips of triggered CLCTs
161  for (int i = 0; i < CSCConstants::NUM_HALF_STRIPS_7CFEBS; i++) {
162  for (int j = 0; j < CSCConstants::MAX_CLCT_TBINS; j++) {
163  busyMap[i][j] = false;
164  }
165  }
166 
167  std::vector<CSCCLCTDigi> lctListBX;
168 
170 
171  // Fire half-strip one-shots for hit_persist bx's (4 bx's by default).
172  pulseExtension(halfstrip, maxHalfStrips, pulse);
173 
174  unsigned int start_bx = start_bx_shift;
175  // Stop drift_delay bx's short of fifo_tbins since at later bx's we will
176  // not have a full set of hits to start pattern search anyway.
177  unsigned int stop_bx = fifo_tbins - drift_delay;
178 
179  // Allow for more than one pass over the hits in the time window.
180  // Do search in every BX
181  while (start_bx < stop_bx) {
182  lctListBX.clear();
183 
184  // All half-strip pattern envelopes are evaluated simultaneously, on every clock cycle.
185  int first_bx = 999;
186  bool pre_trig = CSCUpgradeCathodeLCTProcessor::preTrigger(pulse, start_bx, first_bx);
187 
188  // If any of half-strip envelopes has enough layers hit in it, TMB
189  // will pre-trigger.
190  if (pre_trig) {
191  if (infoV > 1)
192  LogTrace("CSCUpgradeCathodeLCTProcessor")
193  << "..... pretrigger at bx = " << first_bx << "; waiting drift delay .....";
194 
195  // TMB latches LCTs drift_delay clocks after pretrigger.
196  int latch_bx = first_bx + drift_delay;
197  bool hits_in_time = patternFinding(pulse, maxHalfStrips, latch_bx);
198  if (infoV > 1) {
199  if (hits_in_time) {
200  for (int hstrip = stagger[CSCConstants::KEY_CLCT_LAYER - 1]; hstrip < maxHalfStrips; hstrip++) {
201  if (nhits[hstrip] > 0) {
202  LogTrace("CSCUpgradeCathodeLCTProcessor")
203  << " bx = " << std::setw(2) << latch_bx << " --->"
204  << " halfstrip = " << std::setw(3) << hstrip << " best pid = " << std::setw(2) << best_pid[hstrip]
205  << " nhits = " << nhits[hstrip];
206  }
207  }
208  }
209  }
210 
211  // 2 possible LCTs per CSC x 7 LCT quantities per BX
213 
214  // Quality for sorting.
217  for (int ilct = 0; ilct < CSCConstants::MAX_CLCTS_PER_PROCESSOR; ilct++) {
218  best_halfstrip[ilct] = -1;
219  best_quality[ilct] = 0;
220  }
221 
222  bool pretrig_zone[CSCConstants::NUM_HALF_STRIPS_7CFEBS];
223 
224  // Calculate quality from pattern id and number of hits, and
225  // simultaneously select best-quality LCT.
226  if (hits_in_time) {
227  // first, mark half-strip zones around pretriggers
228  // that happened at the current first_bx
229  for (int hstrip = 0; hstrip < CSCConstants::NUM_HALF_STRIPS_7CFEBS; hstrip++)
230  pretrig_zone[hstrip] = false;
231  for (int hstrip = 0; hstrip < CSCConstants::NUM_HALF_STRIPS_7CFEBS; hstrip++) {
232  if (ispretrig[hstrip]) {
233  int min_hs = hstrip - pretrig_trig_zone;
234  int max_hs = hstrip + pretrig_trig_zone;
235  if (min_hs < 0)
236  min_hs = 0;
237  if (max_hs > CSCConstants::NUM_HALF_STRIPS_7CFEBS - 1)
238  max_hs = CSCConstants::NUM_HALF_STRIPS_7CFEBS - 1;
239  for (int hs = min_hs; hs <= max_hs; hs++)
240  pretrig_zone[hs] = true;
241  if (infoV > 1)
242  LogTrace("CSCUpgradeCathodeLCTProcessor")
243  << " marked pretrigger halfstrip zone [" << min_hs << "," << max_hs << "]";
244  }
245  }
246 
247  for (int hstrip = stagger[CSCConstants::KEY_CLCT_LAYER - 1]; hstrip < maxHalfStrips; hstrip++) {
248  // The bend-direction bit pid[0] is ignored (left and right bends have equal quality).
249  quality[hstrip] = (best_pid[hstrip] & 14) | (nhits[hstrip] << 5);
250  // do not consider halfstrips:
251  // - out of pretrigger-trigger zones
252  // - in busy zones from previous trigger
253  if (quality[hstrip] > best_quality[0] && pretrig_zone[hstrip] && !busyMap[hstrip][first_bx])
255  {
256  best_halfstrip[0] = hstrip;
257  best_quality[0] = quality[hstrip];
258  if (infoV > 1) {
259  LogTrace("CSCUpgradeCathodeLCTProcessor")
260  << " 1st CLCT: halfstrip = " << std::setw(3) << hstrip << " quality = " << std::setw(3)
261  << quality[hstrip] << " best halfstrip = " << std::setw(3) << best_halfstrip[0]
262  << " best quality = " << std::setw(3) << best_quality[0];
263  }
264  }
265  }
266  }
267 
268  // If 1st best CLCT is found, look for the 2nd best.
269  if (best_halfstrip[0] >= 0) {
270  // Mark keys near best CLCT as busy by setting their quality to zero, and repeat the search.
271  markBusyKeys(best_halfstrip[0], best_pid[best_halfstrip[0]], quality);
272 
273  for (int hstrip = stagger[CSCConstants::KEY_CLCT_LAYER - 1]; hstrip < maxHalfStrips; hstrip++) {
274  if (quality[hstrip] > best_quality[1] && pretrig_zone[hstrip] && !busyMap[hstrip][first_bx])
276  {
277  best_halfstrip[1] = hstrip;
278  best_quality[1] = quality[hstrip];
279  if (infoV > 1) {
280  LogTrace("CSCUpgradeCathodeLCTProcessor")
281  << " 2nd CLCT: halfstrip = " << std::setw(3) << hstrip << " quality = " << std::setw(3)
282  << quality[hstrip] << " best halfstrip = " << std::setw(3) << best_halfstrip[1]
283  << " best quality = " << std::setw(3) << best_quality[1];
284  }
285  }
286  }
287 
288  // Pattern finder.
289  //bool ptn_trig = false;
290  for (int ilct = 0; ilct < CSCConstants::MAX_CLCTS_PER_PROCESSOR; ilct++) {
291  int best_hs = best_halfstrip[ilct];
292  if (best_hs >= 0 && nhits[best_hs] >= nplanes_hit_pattern) {
293  int bx = first_bx;
294  int fbx = first_bx_corrected[best_hs];
295  if (use_corrected_bx) {
296  bx = fbx;
297  fbx = first_bx;
298  }
299  //ptn_trig = true;
300  keystrip_data[ilct][CLCT_PATTERN] = best_pid[best_hs];
301  keystrip_data[ilct][CLCT_BEND] =
303  // Remove stagger if any.
304  keystrip_data[ilct][CLCT_STRIP] = best_hs - stagger[CSCConstants::KEY_CLCT_LAYER - 1];
305  keystrip_data[ilct][CLCT_BX] = bx;
306  keystrip_data[ilct][CLCT_STRIP_TYPE] = 1; // obsolete
307  keystrip_data[ilct][CLCT_QUALITY] = nhits[best_hs];
308  keystrip_data[ilct][CLCT_CFEB] = keystrip_data[ilct][CLCT_STRIP] / CSCConstants::NUM_HALF_STRIPS_PER_CFEB;
309  int halfstrip_in_cfeb = keystrip_data[ilct][CLCT_STRIP] -
310  CSCConstants::NUM_HALF_STRIPS_PER_CFEB * keystrip_data[ilct][CLCT_CFEB];
311 
312  if (infoV > 1)
313  LogTrace("CSCUpgradeCathodeLCTProcessor")
314  << " Final selection: ilct " << ilct << " key halfstrip " << keystrip_data[ilct][CLCT_STRIP]
315  << " quality " << keystrip_data[ilct][CLCT_QUALITY] << " pattern "
316  << keystrip_data[ilct][CLCT_PATTERN] << " bx " << keystrip_data[ilct][CLCT_BX];
317 
318  CSCCLCTDigi thisLCT(1,
319  keystrip_data[ilct][CLCT_QUALITY],
320  keystrip_data[ilct][CLCT_PATTERN],
321  keystrip_data[ilct][CLCT_STRIP_TYPE],
322  keystrip_data[ilct][CLCT_BEND],
323  halfstrip_in_cfeb,
324  keystrip_data[ilct][CLCT_CFEB],
325  keystrip_data[ilct][CLCT_BX]);
326  thisLCT.setFullBX(fbx);
327  lctList.push_back(thisLCT);
328  lctListBX.push_back(thisLCT);
329  }
330  }
331 
332  } //find CLCT, end of best_halfstrip[0] >= 0
333  } //pre_trig
334  // The pattern finder runs continuously, so another pre-trigger
335  // could occur already at the next bx.
336  start_bx = first_bx + 1;
337  }
338 
339  return lctList;
340 } // findLCTs -- SLHC version.
T getParameter(std::string const &) const
void dumpDigis(const std::vector< int > strip[CSCConstants::NUM_LAYERS][CSCConstants::NUM_HALF_STRIPS_7CFEBS], const int nStrips) const
bool patternFinding(const unsigned int pulse[CSCConstants::NUM_LAYERS][CSCConstants::NUM_HALF_STRIPS_7CFEBS], const int nStrips, const unsigned int bx_time)
bool ispretrig[CSCConstants::NUM_HALF_STRIPS_7CFEBS]
virtual std::vector< CSCCLCTDigi > findLCTs(const std::vector< int > halfstrip[CSCConstants::NUM_LAYERS][CSCConstants::NUM_HALF_STRIPS_7CFEBS])
int first_bx_corrected[CSCConstants::NUM_HALF_STRIPS_7CFEBS]
bool busyMap[CSCConstants::NUM_HALF_STRIPS_7CFEBS][CSCConstants::MAX_CLCT_TBINS]
virtual bool preTrigger(const unsigned int pulse[CSCConstants::NUM_LAYERS][CSCConstants::NUM_HALF_STRIPS_7CFEBS], const int start_bx, int &first_bx)
nStrips
1.2 is to make the matching window safely the two nearest strips 0.35 is the size of an ME0 chamber i...
unsigned int best_pid[CSCConstants::NUM_HALF_STRIPS_7CFEBS]
void markBusyKeys(const int best_hstrip, const int best_patid, int quality[CSCConstants::NUM_HALF_STRIPS_7CFEBS])
std::vector< CSCCLCTDigi > findLCTs(const std::vector< int > halfstrip[CSCConstants::NUM_LAYERS][CSCConstants::NUM_HALF_STRIPS_7CFEBS]) override
edm::ParameterSet clctParams_
Definition: CSCBaseboard.h:71
#define LogTrace(id)
std::vector< CSCCLCTPreTriggerDigi > thePreTriggerDigis
bool preTrigger(const unsigned int pulse[CSCConstants::NUM_LAYERS][CSCConstants::NUM_HALF_STRIPS_7CFEBS], const int start_bx, int &first_bx) override
double pulse(double x, double y, double z, double t)
int stagger[CSCConstants::NUM_LAYERS]
void setFullBX(const uint16_t fullbx)
Set 12-bit full BX.
Definition: CSCCLCTDigi.h:106
unsigned int nhits[CSCConstants::NUM_HALF_STRIPS_7CFEBS]
void pulseExtension(const std::vector< int > time[CSCConstants::NUM_LAYERS][CSCConstants::NUM_HALF_STRIPS_7CFEBS], const int nStrips, unsigned int pulse[CSCConstants::NUM_LAYERS][CSCConstants::NUM_HALF_STRIPS_7CFEBS])
static const int clct_pattern[CSCConstants::NUM_CLCT_PATTERNS][CSCConstants::MAX_HALFSTRIPS_IN_PATTERN+2]