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