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