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