CMS 3D CMS Logo

SiStripFedZeroSuppression.cc
Go to the documentation of this file.
2 
7 
8 //#define DEBUG_SiStripZeroSuppression_
9 //#define ML_DEBUG
10 using namespace std;
11 
13  if (noiseWatcher_.check(es)) {
14  noise_ = &es.getData(noiseToken_);
15  }
16  if (thresholdWatcher_.check(es)) {
17  threshold_ = &es.getData(thresholdToken_);
18  }
19 }
20 
21 namespace {
22 
23  constexpr uint8_t zeroTh = 0;
24  constexpr uint8_t lowTh = 1;
25  constexpr uint8_t highTh = 2;
26 
27  struct Payload {
28  uint8_t stat;
29  uint8_t statPrev;
30  uint8_t statNext;
31  uint8_t statMaxNeigh;
32  uint8_t statPrev2;
33  uint8_t statNext2;
34  };
35 
36  constexpr bool isDigiValid(Payload const& data, uint16_t FEDalgorithm) {
37  // Decide if this strip should be accepted.
38  bool accept = false;
39  switch (FEDalgorithm) {
40  case 1:
41  accept = (data.stat >= lowTh);
42  break;
43  case 2:
44  accept = (data.stat >= highTh || (data.stat >= lowTh && data.statMaxNeigh >= lowTh));
45  break;
46  case 3:
47  accept = (data.stat >= highTh || (data.stat >= lowTh && data.statMaxNeigh >= highTh));
48  break;
49  case 4:
50  accept = ((data.stat >= highTh) //Test for adc>highThresh (same as algorithm 2)
51  || ((data.stat >= lowTh) //Test for adc>lowThresh, with neighbour adc>lowThresh (same as algorithm 2)
52  && (data.statMaxNeigh >= lowTh)) ||
53  ((data.stat < lowTh) //Test for adc<lowThresh
54  && (((data.statPrev >= highTh) //with both neighbours>highThresh
55  && (data.statNext >= highTh)) ||
56  ((data.statPrev >= highTh) //OR with previous neighbour>highThresh and
57  && (data.statNext >= lowTh) //both the next neighbours>lowThresh
58  && (data.statNext2 >= lowTh)) ||
59  ((data.statNext >= highTh) //OR with next neighbour>highThresh and
60  && (data.statPrev >= lowTh) //both the previous neighbours>lowThresh
61  && (data.statPrev2 >= lowTh)) ||
62  ((data.statNext >= lowTh) //OR with both next neighbours>lowThresh and
63  && (data.statNext2 >= lowTh) //both the previous neighbours>lowThresh
64  && (data.statPrev >= lowTh) && (data.statPrev2 >= lowTh)))));
65  break;
66  case 5:
67  accept = true; // zero removed in conversion
68  break;
69  }
70  return accept;
71  }
72 
73 } // namespace
74 
75 void SiStripFedZeroSuppression::suppress(const std::vector<SiStripDigi>& in,
76  std::vector<SiStripDigi>& selectedSignal,
77  uint32_t detID) {
78  suppress(in, selectedSignal, detID, *noise_, *threshold_);
79 }
80 
81 void SiStripFedZeroSuppression::suppress(const std::vector<SiStripDigi>& in,
82  std::vector<SiStripDigi>& selectedSignal,
83  uint32_t detID,
84  const SiStripNoises& noise,
85  const SiStripThreshold& threshold) {
86  int inSize = in.size();
87  SiStripNoises::Range detNoiseRange = noise.getRange(detID);
88  SiStripThreshold::Range detThRange = threshold.getRange(detID);
89 
90  // reserving more than needed, but quicker than one at a time
91  selectedSignal.clear();
92  selectedSignal.reserve(inSize);
93 
94  // load status
95  uint8_t stat[inSize];
96  for (int i = 0; i < inSize; i++) {
97  auto strip = (uint32_t)in[i].strip();
98 
99  auto ladc = in[i].adc();
100  assert(ladc > 0);
101 
102  auto thresholds = threshold.getData(strip, detThRange);
103 
104  auto highThresh = static_cast<int16_t>(thresholds.getHth() * noise.getNoiseFast(strip, detNoiseRange) + 0.5f);
105  auto lowThresh = static_cast<int16_t>(thresholds.getLth() * noise.getNoiseFast(strip, detNoiseRange) + 0.5f);
106 
107  assert(lowThresh >= 0);
108  assert(lowThresh <= highThresh);
109 
110  stat[i] = zeroTh;
111  if (ladc >= lowThresh)
112  stat[i] = lowTh;
113  if (ladc >= highThresh)
114  stat[i] = highTh;
115  }
116 
117  for (int i = 0; i < inSize; i++) {
118  auto strip = (uint32_t)in[i].strip();
119  Payload ldata;
120 
121  ldata.stat = stat[i];
122  ldata.statPrev = zeroTh;
123  ldata.statNext = zeroTh;
124  ldata.statPrev2 = zeroTh;
125  ldata.statNext2 = zeroTh;
126 
127  if (((strip) % 128) == 127) {
128  ldata.statNext = zeroTh;
129  } else if (i + 1 < inSize && in[i + 1].strip() == strip + 1) {
130  ldata.statNext = stat[i + 1];
131  if (((strip) % 128) == 126) {
132  ldata.statNext2 = zeroTh;
133  } else if (i + 2 < inSize && in[i + 2].strip() == strip + 2) {
134  ldata.statNext2 = stat[i + 2];
135  }
136  }
137 
138  if (((strip) % 128) == 0) {
139  ldata.statPrev = zeroTh;
140  } else if (i - 1 >= 0 && in[i - 1].strip() == strip - 1) {
141  ldata.statPrev = stat[i - 1];
142  if (((strip) % 128) == 1) {
143  ldata.statPrev2 = zeroTh;
144  } else if (i - 2 >= 0 && in[i - 2].strip() == strip - 2) {
145  ldata.statPrev2 = stat[i - 2];
146  }
147  }
148 
149  ldata.statMaxNeigh = std::max(ldata.statPrev, ldata.statNext);
150 
151  if (isDigiValid(ldata, theFEDalgorithm)) {
152  selectedSignal.push_back(SiStripDigi(strip, in[i].adc()));
153  }
154  }
155 }
156 
158  const uint32_t detID = out.id;
159  SiStripNoises::Range detNoiseRange = noise_->getRange(detID);
160  SiStripThreshold::Range detThRange = threshold_->getRange(detID);
161 #ifdef DEBUG_SiStripZeroSuppression_
162  if (edm::isDebugEnabled())
163  LogTrace("SiStripZeroSuppression")
164  << "[SiStripFedZeroSuppression::suppress] Zero suppression on edm::DetSet<SiStripRawDigi>: detID " << detID
165  << " size = " << in.data.size();
166 #endif
167  edm::DetSet<SiStripRawDigi>::const_iterator in_iter = in.data.begin();
168  for (; in_iter != in.data.end(); in_iter++) {
169  const uint32_t strip = (uint32_t)(in_iter - in.data.begin());
170 
171 #ifdef DEBUG_SiStripZeroSuppression_
172  if (edm::isDebugEnabled())
173  LogTrace("SiStripZeroSuppression") << "[SiStripFedZeroSuppression::suppress] detID= " << detID
174  << " strip= " << strip << " adc= " << in_iter->adc();
175 #endif
176  adc = in_iter->adc();
177 
178  SiStripThreshold::Data thresholds = threshold_->getData(strip, detThRange);
179  theFEDlowThresh = static_cast<int16_t>(thresholds.getLth() * noise_->getNoiseFast(strip, detNoiseRange) + 0.5);
180  theFEDhighThresh = static_cast<int16_t>(thresholds.getHth() * noise_->getNoiseFast(strip, detNoiseRange) + 0.5);
181 
182  adcPrev = -9999;
183  adcNext = -9999;
184  /*
185  If a strip is the last one on the chip
186  set its next neighbor's thresholds to infinity
187  because the FED does not merge clusters across
188  chip boundaries right now
189  */
190  if (strip % 128 == 127) {
191  adcNext = 0;
192  theNextFEDlowThresh = 9999;
193  theNextFEDhighThresh = 9999;
194  } else {
195  adcNext = (in_iter + 1)->adc();
196  SiStripThreshold::Data thresholds_1 = threshold_->getData(strip + 1, detThRange);
197  theNextFEDlowThresh =
198  static_cast<int16_t>(thresholds_1.getLth() * noise_->getNoiseFast(strip + 1, detNoiseRange) + 0.5);
199  theNextFEDhighThresh =
200  static_cast<int16_t>(thresholds_1.getHth() * noise_->getNoiseFast(strip + 1, detNoiseRange) + 0.5);
201  }
202  /*
203  Similarily, for the first strip
204  on a chip
205  */
206  if (strip % 128 == 0) {
207  adcPrev = 0;
208  thePrevFEDlowThresh = 9999;
209  thePrevFEDhighThresh = 9999;
210  } else {
211  adcPrev = (in_iter - 1)->adc();
212  SiStripThreshold::Data thresholds_1 = threshold_->getData(strip - 1, detThRange);
213  thePrevFEDlowThresh =
214  static_cast<int16_t>(thresholds_1.getLth() * noise_->getNoiseFast(strip - 1, detNoiseRange) + 0.5);
215  thePrevFEDhighThresh =
216  static_cast<int16_t>(thresholds_1.getHth() * noise_->getNoiseFast(strip - 1, detNoiseRange) + 0.5);
217  }
218  if (adcNext < adcPrev) {
219  adcMaxNeigh = adcPrev;
220  theNeighFEDlowThresh = thePrevFEDlowThresh;
221  theNeighFEDhighThresh = thePrevFEDhighThresh;
222  } else {
223  adcMaxNeigh = adcNext;
224  theNeighFEDlowThresh = theNextFEDlowThresh;
225  theNeighFEDhighThresh = theNextFEDhighThresh;
226  }
227 
228  //Find adc values for next neighbouring strips
229  adcPrev2 = -9999;
230  adcNext2 = -9999;
231  thePrev2FEDlowThresh = 1;
232  theNext2FEDlowThresh = 1;
233  if (strip % 128 >= 126) {
234  adcNext2 = 0;
235  theNext2FEDlowThresh = 9999;
236  } else if (strip % 128 < 126) {
237  adcNext2 = (in_iter + 2)->adc();
238  theNext2FEDlowThresh = static_cast<int16_t>(
239  threshold_->getData(strip + 2, detThRange).getLth() * noise_->getNoiseFast(strip + 2, detNoiseRange) + 0.5);
240  }
241  if (strip % 128 <= 1) {
242  adcPrev2 = 0;
243  thePrev2FEDlowThresh = 9999;
244  } else if (strip % 128 > 1) {
245  adcPrev2 = (in_iter - 2)->adc();
246  thePrev2FEDlowThresh = static_cast<int16_t>(
247  threshold_->getData(strip - 2, detThRange).getLth() * noise_->getNoiseFast(strip - 2, detNoiseRange) + 0.5);
248  }
249  //GB 23/6/08: truncation should be done at the very beginning
250  if (isAValidDigi())
251  out.data.push_back(SiStripDigi(strip, truncate(in_iter->adc())));
252  }
253 }
254 
255 void SiStripFedZeroSuppression::fillThresholds_(const uint32_t detID, size_t size) {
256  SiStripNoises::Range detNoiseRange = noise_->getRange(detID);
257  SiStripThreshold::Range detThRange = threshold_->getRange(detID);
258 
259  if (highThr_.size() != size) {
260  highThr_.resize(size);
261  lowThr_.resize(size);
262  noises_.resize(size);
263  highThrSN_.resize(size);
264  lowThrSN_.resize(size);
265  }
266 
267  noise_->allNoises(noises_, detNoiseRange);
268  threshold_->allThresholds(lowThrSN_, highThrSN_, detThRange); // thresholds as S/N
269  for (size_t strip = 0; strip < size; ++strip) {
270  float noise = noises_[strip];
271  // uncomment line below to check bluk noise decoding
272  //assert( noise == noiseHandle->getNoiseFast(strip,detNoiseRange) );
273  highThr_[strip] = static_cast<int16_t>(highThrSN_[strip] * noise + 0.5 + 1e-6);
274  lowThr_[strip] = static_cast<int16_t>(lowThrSN_[strip] * noise + 0.5 + 1e-6);
275  // Note: it's a bit wierd, but there are some cases for which 'highThrSN_[strip]*noise' is an exact integer
276  // but due to roundoffs it gets rounded to the integer below if.
277  // Apparently the optimized code inlines differently and this changes the roundoff.
278  // The +1e-6 fixes the problem. [GPetruc]
279  }
280 }
281 
282 void SiStripFedZeroSuppression::suppress(const std::vector<int16_t>& in,
283  uint16_t firstAPV,
285  const uint32_t detID = out.id;
286  size_t size = in.size();
287 #ifdef DEBUG_SiStripZeroSuppression_
288  if (edm::isDebugEnabled())
289  LogTrace("SiStripZeroSuppression")
290  << "[SiStripFedZeroSuppression::suppress] Zero suppression on std::vector<int16_t>: detID " << detID
291  << " size = " << in.size();
292 #endif
293 
294  fillThresholds_(detID, size + firstAPV * 128); // want to decouple this from the other cost
295 
296  std::vector<int16_t>::const_iterator in_iter = in.begin();
297  uint16_t strip = firstAPV * 128;
298  for (; strip < size + firstAPV * 128; ++strip, ++in_iter) {
299  size_t strip_mod_128 = strip & 127;
300 #ifdef DEBUG_SiStripZeroSuppression_
301  if (edm::isDebugEnabled())
302  LogTrace("SiStripZeroSuppression") << "[SiStripFedZeroSuppression::suppress] detID= " << detID
303  << " strip= " << strip << " adc= " << *in_iter;
304 #endif
305  adc = *in_iter;
306 
307  theFEDlowThresh = lowThr_[strip];
308  theFEDhighThresh = highThr_[strip];
309 
310  //Find adc values for neighbouring strips
311 
312  /*
313  If a strip is the last one on the chip
314  set its next neighbor's thresholds to infinity
315  because the FED does not merge clusters across
316  chip boundaries right now
317  */
318 
319  //adcPrev = -9999; // useless, they are set
320  //adcNext = -9999; // in the next lines in any case
321  if (strip_mod_128 == 127) {
322  adcNext = 0;
323  theNextFEDlowThresh = 9999;
324  theNextFEDhighThresh = 9999;
325  } else {
326  adcNext = *(in_iter + 1);
327  theNextFEDlowThresh = lowThr_[strip + 1];
328  theNextFEDhighThresh = highThr_[strip + 1];
329  }
330 
331  /*
332  Similarily, for the first strip
333  on a chip
334  */
335  if (strip_mod_128 == 0) {
336  adcPrev = 0;
337  thePrevFEDlowThresh = 9999;
338  thePrevFEDhighThresh = 9999;
339  } else {
340  adcPrev = *(in_iter - 1);
341  thePrevFEDlowThresh = lowThr_[strip - 1];
342  thePrevFEDhighThresh = highThr_[strip - 1];
343  }
344 
345  if (adcNext < adcPrev) {
346  adcMaxNeigh = adcPrev;
347  theNeighFEDlowThresh = thePrevFEDlowThresh;
348  theNeighFEDhighThresh = thePrevFEDhighThresh;
349  } else {
350  adcMaxNeigh = adcNext;
351  theNeighFEDlowThresh = theNextFEDlowThresh;
352  theNeighFEDhighThresh = theNextFEDhighThresh;
353  }
354 
355  //Find adc values for next neighbouring strips
356  //adcPrev2 = -9999; //
357  //adcNext2 = -9999; // useless to set them here
358  //thePrev2FEDlowThresh = 1; // they are overwritten always in the next 8 lines
359  //theNext2FEDlowThresh = 1; //
360  if (strip_mod_128 >= 126) {
361  adcNext2 = 0;
362  theNext2FEDlowThresh = 9999;
363  //} else if ( strip_mod_128 < 126 ) { // if it's not >= then is <, no need to "if" again
364  } else {
365  adcNext2 = *(in_iter + 2);
366  theNext2FEDlowThresh = lowThr_[strip + 2];
367  }
368  if (strip_mod_128 <= 1) {
369  adcPrev2 = 0;
370  thePrev2FEDlowThresh = 9999;
371  //} else if ( strip_mod_128 > 1 ) { // same as above
372  } else {
373  adcPrev2 = *(in_iter - 2);
374  thePrev2FEDlowThresh = lowThr_[strip - 2];
375  ;
376  }
377 
378  if (isAValidDigi()) {
379 #ifdef DEBUG_SiStripZeroSuppression_
380  if (edm::isDebugEnabled())
381  LogTrace("SiStripZeroSuppression")
382  << "[SiStripFedZeroSuppression::suppress] DetId " << out.id << " strip " << strip << " adc " << *in_iter
383  << " digiCollection size " << out.data.size();
384 #endif
385  //GB 23/6/08: truncation should be done at the very beginning
386  out.push_back(SiStripDigi(strip, (*in_iter < 0 ? 0 : truncate(*in_iter))));
387  }
388  }
389 }
390 
392 #ifdef DEBUG_SiStripZeroSuppression_
393 
394  if (edm::isDebugEnabled()) {
395  LogTrace("SiStripZeroSuppression") << "[SiStripFedZeroSuppression::suppress] "
396  << "\n\t adc " << adc << "\n\t adcPrev " << adcPrev << "\n\t adcNext " << adcNext
397  << "\n\t adcMaxNeigh " << adcMaxNeigh << "\n\t adcPrev2 " << adcPrev2
398  << "\n\t adcNext2 " << adcNext2 << std::endl;
399 
400  LogTrace("SiStripZeroSuppression") << "[SiStripFedZeroSuppression::suppress] "
401  << "\n\t theFEDlowThresh " << theFEDlowThresh << "\n\t theFEDhighThresh "
402  << theFEDhighThresh << "\n\t thePrevFEDlowThresh " << thePrevFEDlowThresh
403  << "\n\t thePrevFEDhighThresh " << thePrevFEDhighThresh
404  << "\n\t theNextFEDlowThresh " << theNextFEDlowThresh
405  << "\n\t theNextFEDhighThresh " << theNextFEDhighThresh
406  << "\n\t theNeighFEDlowThresh " << theNeighFEDlowThresh
407  << "\n\t theNeighFEDhighThresh " << theNeighFEDhighThresh
408  << "\n\t thePrev2FEDlowThresh " << thePrev2FEDlowThresh
409  << "\n\t theNext2FEDlowThresh " << theNext2FEDlowThresh << std::endl;
410  }
411 #endif
412  // Decide if this strip should be accepted.
413  bool accept = false;
414  switch (theFEDalgorithm) {
415  case 1:
416  accept = (adc >= theFEDlowThresh);
417  break;
418  case 2:
419  accept = (adc >= theFEDhighThresh || (adc >= theFEDlowThresh && adcMaxNeigh >= theNeighFEDlowThresh));
420  break;
421  case 3:
422  accept = (adc >= theFEDhighThresh || (adc >= theFEDlowThresh && adcMaxNeigh >= theNeighFEDhighThresh));
423  break;
424  case 4:
425  accept =
426  ((adc >= theFEDhighThresh) //Test for adc>highThresh (same as algorithm 2)
427  || ((adc >= theFEDlowThresh) //Test for adc>lowThresh, with neighbour adc>lowThresh (same as algorithm 2)
428  && (adcMaxNeigh >= theNeighFEDlowThresh)) ||
429  ((adc < theFEDlowThresh) //Test for adc<lowThresh
430  && (((adcPrev >= thePrevFEDhighThresh) //with both neighbours>highThresh
431  && (adcNext >= theNextFEDhighThresh)) ||
432  ((adcPrev >= thePrevFEDhighThresh) //OR with previous neighbour>highThresh and
433  && (adcNext >= theNextFEDlowThresh) //both the next neighbours>lowThresh
434  && (adcNext2 >= theNext2FEDlowThresh)) ||
435  ((adcNext >= theNextFEDhighThresh) //OR with next neighbour>highThresh and
436  && (adcPrev >= thePrevFEDlowThresh) //both the previous neighbours>lowThresh
437  && (adcPrev2 >= thePrev2FEDlowThresh)) ||
438  ((adcNext >= theNextFEDlowThresh) //OR with both next neighbours>lowThresh and
439  && (adcNext2 >= theNext2FEDlowThresh) //both the previous neighbours>lowThresh
440  && (adcPrev >= thePrevFEDlowThresh) && (adcPrev2 >= thePrev2FEDlowThresh)))));
441  break;
442  case 5:
443  accept = adc > 0;
444  break;
445  }
446  return accept;
447 }
size
Write out results.
static const char noise_[]
bool isDebugEnabled()
void init(const edm::EventSetup &es)
T const & getData(const ESGetToken< T, R > &iToken) const noexcept(false)
Definition: EventSetup.h:119
assert(be >=bs)
bool accept(const edm::Event &event, const edm::TriggerResults &triggerTable, const std::string &triggerPath)
Definition: TopDQMHelpers.h:31
#define LogTrace(id)
A Digi for the silicon strip detector, containing both strip and adc information, and suitable for st...
Definition: SiStripDigi.h:12
std::pair< ContainerIterator, ContainerIterator > Range
void suppress(const std::vector< SiStripDigi > &in, std::vector< SiStripDigi > &selectedSignal, uint32_t detId, const SiStripNoises &, const SiStripThreshold &)
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:79
std::pair< ContainerIterator, ContainerIterator > Range
Definition: SiStripNoises.h:47
collection_type::const_iterator const_iterator
Definition: DetSet.h:31
void fillThresholds_(const uint32_t detID, size_t size)
uint16_t *__restrict__ uint16_t const *__restrict__ adc