CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
SiStripAPVRestorer.cc
Go to the documentation of this file.
5 
6 #include <cmath>
7 #include <iostream>
8 #include <algorithm>
9 
11  : qualityToken_(iC.esConsumes<SiStripQuality, SiStripQualityRcd>()),
12  noiseToken_(iC.esConsumes<SiStripNoises, SiStripNoisesRcd>()),
14  forceNoRestore_(conf.getParameter<bool>("ForceNoRestore")),
15  inspectAlgo_(conf.getParameter<std::string>("APVInspectMode")),
16  restoreAlgo_(conf.getParameter<std::string>("APVRestoreMode")),
17  // CM map settings
18  useRealMeanCM_(conf.getParameter<bool>("useRealMeanCM")),
19  meanCM_(conf.getParameter<int32_t>("MeanCM")),
20  deltaCMThreshold_(conf.getParameter<uint32_t>("DeltaCMThreshold")),
21  // abnormal baseline inspect
22  fraction_(conf.getParameter<double>("Fraction")),
23  deviation_(conf.getParameter<uint32_t>("Deviation")),
24  // nullInspect
25  restoreThreshold_(conf.getParameter<double>("restoreThreshold")),
26  // baseline and saturation inspect
27  nSaturatedStrip_(conf.getParameter<uint32_t>("nSaturatedStrip")),
28  // FlatRegionsFinder
29  nSigmaNoiseDerTh_(conf.getParameter<uint32_t>("nSigmaNoiseDerTh")),
30  consecThreshold_(conf.getParameter<uint32_t>("consecThreshold")),
31  nSmooth_(conf.getParameter<uint32_t>("nSmooth")),
32  distortionThreshold_(conf.getParameter<uint32_t>("distortionThreshold")),
33  applyBaselineCleaner_(conf.getParameter<bool>("ApplyBaselineCleaner")),
34  cleaningSequence_(conf.getParameter<uint32_t>("CleaningSequence")),
35  // cleaner_localmin
36  slopeX_(conf.getParameter<int32_t>("slopeX")),
37  slopeY_(conf.getParameter<int32_t>("slopeY")),
38  // cleaner_monotony
39  hitStripThreshold_(conf.getParameter<uint32_t>("hitStripThreshold")),
40  // baseline follower (restore)
41  minStripsToFit_(conf.getParameter<uint32_t>("minStripsToFit")),
42  applyBaselineRejection_(conf.getParameter<bool>("ApplyBaselineRejection")),
43  filteredBaselineMax_(conf.getParameter<double>("filteredBaselineMax")),
44  filteredBaselineDerivativeSumSquare_(conf.getParameter<double>("filteredBaselineDerivativeSumSquare")),
45  // derivative follower restorer
46  gradient_threshold_(conf.getParameter<int>("discontinuityThreshold")),
47  last_gradient_(conf.getParameter<int>("lastGradient")),
48  size_window_(conf.getParameter<int>("sizeWindow")),
49  width_cluster_(conf.getParameter<int>("widthCluster")) {
50  if (restoreAlgo_ == "BaselineFollower" && inspectAlgo_ != "BaselineFollower" && inspectAlgo_ != "Hybrid")
51  throw cms::Exception("Incompatible Algorithm")
52  << "The BaselineFollower restore method requires the BaselineFollower (or Hybrid) inspect method";
53 }
54 
56  if (noiseWatcher_.check(es)) {
58  }
59  if (qualityWatcher_.check(es)) {
61  }
62  if (pedestalWatcher_.check(es)) {
64  }
65 }
66 
67 uint16_t SiStripAPVRestorer::inspectAndRestore(uint32_t detId,
68  uint16_t firstAPV,
69  const digivector_t& rawDigisPedSubtracted,
70  digivector_t& processedRawDigi,
71  const medians_t& vmedians) {
72  auto nAPVFlagged = inspect(detId, firstAPV, rawDigisPedSubtracted, vmedians);
73  restore(firstAPV, processedRawDigi);
74  return nAPVFlagged;
75 }
76 
77 uint16_t SiStripAPVRestorer::inspect(uint32_t detId,
78  uint16_t firstAPV,
79  const digivector_t& digis,
80  const medians_t& vmedians) {
81  detId_ = detId;
82 
83  apvFlags_.assign(6, "");
84  apvFlagsBoolOverride_.assign(6, false);
85  apvFlagsBool_.clear();
86  median_.assign(6, -999);
87  badAPVs_.assign(6, false);
88  smoothedMaps_.clear();
89  baselineMap_.clear();
90  for (const auto& med : vmedians) {
91  auto iAPV = med.first;
92  median_[iAPV] = med.second;
93  badAPVs_[iAPV] = qualityHandle->IsApvBad(detId_, iAPV);
94  }
95 
96  uint16_t nAPVFlagged = 0;
97  if (inspectAlgo_ == "Hybrid")
98  nAPVFlagged = hybridFormatInspect(firstAPV, digis);
99  else if (inspectAlgo_ == "HybridEmulation")
100  nAPVFlagged = hybridEmulationInspect(firstAPV, digis);
101  else if (inspectAlgo_ == "BaselineFollower")
102  nAPVFlagged = baselineFollowerInspect(firstAPV, digis);
103  else if (inspectAlgo_ == "AbnormalBaseline")
104  nAPVFlagged = abnormalBaselineInspect(firstAPV, digis);
105  else if (inspectAlgo_ == "Null")
106  nAPVFlagged = nullInspect(firstAPV, digis);
107  else if (inspectAlgo_ == "BaselineAndSaturation")
108  nAPVFlagged = baselineAndSaturationInspect(firstAPV, digis);
109  else if (inspectAlgo_ == "DerivativeFollower")
110  nAPVFlagged = forceRestoreInspect(firstAPV, digis);
111  else
112  throw cms::Exception("Unregistered Inspect Algorithm")
113  << "SiStripAPVRestorer possibilities: (Null), (AbnormalBaseline), (BaselineFollower), (BaselineAndSaturation), "
114  "(DerivativeFollower), (Hybrid), (HybridEmulation)";
115 
116  // update boolean version of APV flags
117  for (size_t i = 0; i < apvFlags_.size(); ++i) {
118  apvFlagsBool_.push_back((!apvFlags_[i].empty()) && (!apvFlagsBoolOverride_[i]));
119  }
120 
121  return nAPVFlagged;
122 }
123 
124 void SiStripAPVRestorer::restore(uint16_t firstAPV, digivector_t& digis) {
125  if (forceNoRestore_)
126  return;
127 
128  for (uint16_t iAPV = firstAPV; iAPV < digis.size() / nTotStripsPerAPV + firstAPV; ++iAPV) {
129  auto algoToUse = apvFlags_[iAPV];
130  if (!algoToUse.empty()) {
131  if (algoToUse == "Flat") {
132  flatRestore(iAPV, firstAPV, digis);
133  } else if (algoToUse == "BaselineFollower") {
134  baselineFollowerRestore(iAPV, firstAPV, median_[iAPV], digis);
135  } else if (algoToUse == "DerivativeFollower") {
136  derivativeFollowerRestore(iAPV, firstAPV, digis);
137  } else {
138  throw cms::Exception("Unregistered Restore Algorithm")
139  << "SiStripAPVRestorer possibilities: (Flat), (BaselineFollower), (DerivativeFollower)";
140  }
141  }
142  }
143 }
144 
145 // Inspect method implementations
146 
147 inline uint16_t SiStripAPVRestorer::hybridFormatInspect(uint16_t firstAPV, const digivector_t& digis) {
148  digivector_t singleAPVdigi;
149  singleAPVdigi.reserve(nTotStripsPerAPV);
150  uint16_t nAPVflagged = 0;
151  for (uint16_t iAPV = firstAPV; iAPV < digis.size() / nTotStripsPerAPV + firstAPV; ++iAPV) {
152  digimap_t smoothedmap;
153  if (!badAPVs_[iAPV]) {
154  uint16_t stripsPerAPV = 0;
155  singleAPVdigi.clear();
156  for (int16_t strip = (iAPV - firstAPV) * nTotStripsPerAPV; strip < (iAPV - firstAPV + 1) * nTotStripsPerAPV;
157  ++strip) {
158  const uint16_t adc = digis[strip];
159  singleAPVdigi.push_back(adc);
160  if (adc > 0)
161  ++stripsPerAPV;
162  }
163 
164  if (stripsPerAPV > 64) {
165  flatRegionsFinder(singleAPVdigi, smoothedmap, iAPV);
166  apvFlags_[iAPV] = restoreAlgo_; //specify any algo to make the restore
167  nAPVflagged++;
168  }
169  }
170  smoothedMaps_.emplace_hint(smoothedMaps_.end(), iAPV, std::move(smoothedmap));
171  }
172  return nAPVflagged;
173 }
174 
175 inline uint16_t SiStripAPVRestorer::baselineFollowerInspect(uint16_t firstAPV, const digivector_t& digis) {
176  digivector_t singleAPVdigi;
177  singleAPVdigi.reserve(nTotStripsPerAPV);
178  uint16_t nAPVflagged = 0;
179 
180  auto itCMMap = std::end(meanCMmap_);
181  if (useRealMeanCM_)
182  itCMMap = meanCMmap_.find(detId_);
183 
184  for (uint16_t iAPV = firstAPV; iAPV < firstAPV + digis.size() / nTotStripsPerAPV; ++iAPV) {
185  digimap_t smoothedmap;
186  if (!badAPVs_[iAPV]) {
187  float MeanAPVCM = meanCM_;
188  if (useRealMeanCM_ && (std::end(meanCMmap_) != itCMMap))
189  MeanAPVCM = itCMMap->second[iAPV];
190 
191  singleAPVdigi.clear();
192  std::copy_n(std::begin(digis) + nTotStripsPerAPV * (iAPV - firstAPV),
194  std::back_inserter(singleAPVdigi));
195 
196  const float DeltaCM = median_[iAPV] - MeanAPVCM;
197  if ((DeltaCM < 0) && (std::abs(DeltaCM) > deltaCMThreshold_)) {
198  if (!flatRegionsFinder(singleAPVdigi, smoothedmap, iAPV)) {
199  apvFlags_[iAPV] = restoreAlgo_; //specify any algo to make the restore
200  ++nAPVflagged;
201  }
202  }
203  }
204  smoothedMaps_.emplace_hint(smoothedMaps_.end(), iAPV, std::move(smoothedmap));
205  }
206  return nAPVflagged;
207 }
208 
209 inline uint16_t SiStripAPVRestorer::forceRestoreInspect(uint16_t firstAPV, const digivector_t& digis) {
210  uint16_t nAPVflagged = 0;
211  for (uint16_t iAPV = firstAPV; iAPV < firstAPV + digis.size() / nTotStripsPerAPV; ++iAPV) {
212  if (!badAPVs_[iAPV]) {
213  apvFlags_[iAPV] = restoreAlgo_; //specify any algo to make the restore
214  nAPVflagged++;
215  }
216  }
217  return nAPVflagged;
218 }
219 
220 inline uint16_t SiStripAPVRestorer::baselineAndSaturationInspect(uint16_t firstAPV, const digivector_t& digis) {
221  digivector_t singleAPVdigi;
222  singleAPVdigi.reserve(nTotStripsPerAPV);
223  uint16_t nAPVflagged = 0;
224 
225  auto itCMMap = std::end(meanCMmap_);
226  if (useRealMeanCM_)
227  itCMMap = meanCMmap_.find(detId_);
228 
229  for (uint16_t iAPV = firstAPV; iAPV < firstAPV + digis.size() / nTotStripsPerAPV; ++iAPV) {
230  if (!badAPVs_[iAPV]) {
231  float MeanAPVCM = meanCM_;
232  if (useRealMeanCM_ && (std::end(meanCMmap_) != itCMMap))
233  MeanAPVCM = itCMMap->second[iAPV];
234 
235  singleAPVdigi.clear();
236  uint16_t nSatStrip = 0;
237  for (int16_t strip = (iAPV - firstAPV) * nTotStripsPerAPV; strip < (iAPV - firstAPV + 1) * nTotStripsPerAPV;
238  ++strip) {
239  const uint16_t digi = digis[strip];
240  singleAPVdigi.push_back(digi);
241  if (digi >= 1023)
242  ++nSatStrip;
243  }
244 
245  const float DeltaCM = median_[iAPV] - MeanAPVCM;
246  if ((DeltaCM < 0) && (std::abs(DeltaCM) > deltaCMThreshold_) && (nSatStrip >= nSaturatedStrip_)) {
247  apvFlags_[iAPV] = restoreAlgo_; //specify any algo to make the restore
248  ++nAPVflagged;
249  }
250  }
251  }
252  return nAPVflagged;
253 }
254 
255 inline uint16_t SiStripAPVRestorer::abnormalBaselineInspect(uint16_t firstAPV, const digivector_t& digis) {
257 
258  uint16_t nAPVflagged = 0;
259 
260  auto itCMMap = std::end(meanCMmap_);
261  if (useRealMeanCM_)
262  itCMMap = meanCMmap_.find(detId_);
263 
264  int devCount = 0, qualityCount = 0, minstrip = 0;
265  for (uint16_t iAPV = firstAPV; iAPV < firstAPV + digis.size() / nTotStripsPerAPV; ++iAPV) {
266  if (!badAPVs_[iAPV]) {
267  float MeanAPVCM = meanCM_;
268  if (useRealMeanCM_ && (std::end(meanCMmap_) != itCMMap))
269  MeanAPVCM = itCMMap->second[iAPV];
270 
271  for (uint16_t istrip = iAPV * nTotStripsPerAPV; istrip < (iAPV + 1) * nTotStripsPerAPV; ++istrip) {
272  const auto fs = static_cast<int>(digis[istrip - firstAPV * nTotStripsPerAPV]);
273  if (!qualityHandle->IsStripBad(detQualityRange, istrip)) {
274  qualityCount++;
275  if (std::abs(fs - MeanAPVCM) > static_cast<int>(deviation_)) {
276  devCount++;
277  minstrip = std::min(fs, minstrip);
278  }
279  }
280  }
281  if (devCount > fraction_ * qualityCount) {
282  apvFlags_[iAPV] = restoreAlgo_; //specify any algo to make the restore
283  nAPVflagged++;
284  }
285  }
286  }
287  return nAPVflagged;
288 }
289 
290 inline uint16_t SiStripAPVRestorer::nullInspect(uint16_t firstAPV, const digivector_t& digis) {
292 
293  uint16_t nAPVflagged = 0;
294  for (uint16_t iAPV = firstAPV; iAPV < firstAPV + digis.size() / nTotStripsPerAPV; ++iAPV) {
295  if (!badAPVs_[iAPV]) {
296  int zeroCount = 0, qualityCount = 0;
297  for (uint16_t istrip = iAPV * nTotStripsPerAPV; istrip < (iAPV + 1) * nTotStripsPerAPV; ++istrip) {
298  const auto fs = static_cast<int>(digis[istrip - firstAPV * nTotStripsPerAPV]);
299  if (!qualityHandle->IsStripBad(detQualityRange, istrip)) {
300  qualityCount++;
301  if (fs < 1)
302  zeroCount++;
303  }
304  }
305  if (zeroCount > restoreThreshold_ * qualityCount) {
306  apvFlags_[iAPV] = restoreAlgo_; //specify any algo to make the restore
307  nAPVflagged++;
308  }
309  }
310  }
311  return nAPVflagged;
312 }
313 
314 inline uint16_t SiStripAPVRestorer::hybridEmulationInspect(uint16_t firstAPV, const digivector_t& digis) {
315  uint16_t nAPVflagged = 0;
316 
317  auto itCMMap = std::end(meanCMmap_);
318  if (useRealMeanCM_)
319  itCMMap = meanCMmap_.find(detId_);
320 
321  for (uint16_t iAPV = firstAPV; iAPV < firstAPV + digis.size() / nTotStripsPerAPV; ++iAPV) {
322  if (!badAPVs_[iAPV]) {
323  float MeanAPVCM = meanCM_;
324  if (useRealMeanCM_ && (std::end(meanCMmap_) != itCMMap))
325  MeanAPVCM = itCMMap->second[iAPV];
326 
327  const float DeltaCM = median_[iAPV] - (MeanAPVCM + 1024) / 2;
328  if ((DeltaCM < 0) && (std::abs(DeltaCM) > deltaCMThreshold_ / 2)) {
329  apvFlags_[iAPV] = "HybridEmulation";
330  ++nAPVflagged;
331  }
332  }
333  }
334  return nAPVflagged;
335 }
336 
337 // Restore method implementations
338 
340  uint16_t firstAPV,
341  float median,
342  digivector_t& digis) {
343  digivector_t baseline(size_t(nTotStripsPerAPV), 0);
344 
345  //============================= Find Flat Regions & Interpolating the baseline & subtracting the baseline =================
346  if (!smoothedMaps_.empty()) {
347  auto itSmootedMap = smoothedMaps_.find(apvN);
348  baselineFollower(itSmootedMap->second, baseline, median);
349  } else {
350  //median=0;
351  digivector_t singleAPVdigi;
352  singleAPVdigi.reserve(nTotStripsPerAPV);
353  std::copy_n(
354  std::begin(digis) + nTotStripsPerAPV * (apvN - firstAPV), nTotStripsPerAPV, std::back_inserter(singleAPVdigi));
355  digimap_t smoothedpoints;
356  flatRegionsFinder(singleAPVdigi, smoothedpoints, apvN);
357  baselineFollower(smoothedpoints, baseline, median);
358  }
359 
361  if (checkBaseline(baseline))
362  apvFlagsBoolOverride_[apvN] = true;
363  }
364 
365  //============================= subtracting the baseline =============================================
366  for (int16_t itStrip = 0; itStrip < nTotStripsPerAPV; ++itStrip) {
367  digis[nTotStripsPerAPV * (apvN - firstAPV) + itStrip] -= baseline[itStrip] - median;
368  }
369 
370  //============================= storing baseline to the map =============================================
371  baselineMap_.emplace_hint(baselineMap_.end(), apvN, std::move(baseline));
372 }
373 
374 inline void SiStripAPVRestorer::flatRestore(uint16_t apvN, uint16_t firstAPV, digivector_t& digis) {
375  digivector_t baseline(size_t(nTotStripsPerAPV), 150);
376  baseline[0] = 0;
377  baseline[nTotStripsPerAPV - 1] = 0;
378 
379  for (int16_t itStrip = 0; itStrip < nTotStripsPerAPV; ++itStrip) {
380  digis[nTotStripsPerAPV * (apvN - firstAPV) + itStrip] = baseline[itStrip];
381  }
382  baselineMap_.emplace_hint(baselineMap_.end(), apvN, std::move(baseline));
383 }
384 
385 // Baseline calculation implementation =========================================
386 bool inline SiStripAPVRestorer::flatRegionsFinder(const digivector_t& adcs, digimap_t& smoothedpoints, uint16_t apvN) {
387  smoothedpoints.clear();
388 
390 
391  //============================= Height above local minimum ===============================
392  std::vector<float> adcsLocalMinSubtracted(size_t(nTotStripsPerAPV), 0);
393  for (uint32_t istrip = 0; istrip < nTotStripsPerAPV; ++istrip) {
394  float localmin = 999.9;
395  for (uint16_t jstrip = std::max(0, static_cast<int>(istrip - nSmooth_ / 2));
396  jstrip < std::min((int)nTotStripsPerAPV, static_cast<int>(istrip + nSmooth_ / 2));
397  ++jstrip) {
398  const float nextvalue = adcs[jstrip];
399  if (nextvalue < localmin)
400  localmin = nextvalue;
401  }
402  adcsLocalMinSubtracted[istrip] = adcs[istrip] - localmin;
403  }
404 
405  //============================= Find regions with stable slopes ========================
406  digimap_t consecpoints;
407  std::vector<uint16_t> nConsStrip;
408  //Creating maps with all the neighborhood strip and putting in a nCosntStip vector how many we have
409  uint16_t consecStrips = 0;
410  for (uint32_t istrip = 0; istrip < nTotStripsPerAPV; ++istrip) {
411  const int16_t adc = adcs[istrip];
412  //if( adcsLocalMinSubtracted[istrip] < nSigmaNoiseDerTh_ * (float)noiseHandle->getNoise(istrip+apvN*128,detNoiseRange) && (adc - median) < hitStripThreshold_){
413  if (adcsLocalMinSubtracted[istrip] <
414  nSigmaNoiseDerTh_ * (float)noiseHandle->getNoiseFast(istrip + apvN * nTotStripsPerAPV, detNoiseRange)) {
415  consecpoints.emplace_hint(consecpoints.end(), istrip, adc);
416  ++consecStrips;
417  } else if (consecStrips > 0) {
418  nConsStrip.push_back(consecStrips);
419  consecStrips = 0;
420  }
421  }
422  //to cope with the last flat region of the APV
423  if (consecStrips > 0)
424  nConsStrip.push_back(consecStrips);
425 
426  //removing from the map the fist and last points in wide flat regions and erasing from the map too small regions
427  auto itConsecpoints = consecpoints.begin();
428  float MinSmoothValue = 20000., MaxSmoothValue = 0.;
429  for (const auto consecStrips : nConsStrip) {
430  if (consecStrips >= consecThreshold_) {
431  ++itConsecpoints; //skipping first point
432  uint16_t nFirstStrip = itConsecpoints->first;
433  uint16_t nLastStrip;
434  float smoothValue = 0.0;
435  float stripCount = 1;
436  for (uint16_t n = 0; n < consecStrips - 2; ++n) {
437  smoothValue += itConsecpoints->second;
438  if (stripCount == consecThreshold_) {
439  smoothValue /= (float)stripCount;
440  nLastStrip = nFirstStrip + stripCount - 1;
441  smoothedpoints.emplace_hint(smoothedpoints.end(), nFirstStrip, smoothValue);
442  smoothedpoints.emplace_hint(smoothedpoints.end(), nLastStrip, smoothValue);
443  if (smoothValue > MaxSmoothValue)
444  MaxSmoothValue = smoothValue;
445  if (smoothValue < MinSmoothValue)
446  MinSmoothValue = smoothValue;
447  nFirstStrip = nLastStrip + 1;
448  smoothValue = 0;
449  stripCount = 0;
450  }
451  ++stripCount;
452  ++itConsecpoints;
453  }
454  ++itConsecpoints; //and putting the pointer to the new seies of point
455 
456  if (stripCount > 1) {
457  //if(smoothValue>0){
458  --stripCount;
459  smoothValue /= static_cast<float>(stripCount);
460  nLastStrip = nFirstStrip + stripCount - 1;
461  smoothedpoints.emplace_hint(smoothedpoints.end(), nFirstStrip, smoothValue);
462  smoothedpoints.emplace_hint(smoothedpoints.end(), nLastStrip, smoothValue);
463  if (smoothValue > MaxSmoothValue)
464  MaxSmoothValue = smoothValue;
465  if (smoothValue < MinSmoothValue)
466  MinSmoothValue = smoothValue;
467  }
468  } else {
469  for (int n = 0; n < consecStrips; ++n)
470  ++itConsecpoints;
471  }
472  }
473 
474  if ((MaxSmoothValue - MinSmoothValue) > distortionThreshold_) {
476  baselineCleaner(adcs, smoothedpoints, apvN);
477  return false;
478  }
479  return true;
480 }
481 
482 void inline SiStripAPVRestorer::baselineCleaner(const digivector_t& adcs, digimap_t& smoothedpoints, uint16_t apvN) {
483  if (cleaningSequence_ == 0) { //default sequence used up to now
484  cleaner_HighSlopeChecker(smoothedpoints);
485  cleaner_LocalMinimumAdder(adcs, smoothedpoints, apvN);
486  } else if (cleaningSequence_ == 1) {
487  cleaner_LocalMinimumAdder(adcs, smoothedpoints, apvN);
488  cleaner_HighSlopeChecker(smoothedpoints);
489  cleaner_MonotonyChecker(smoothedpoints);
490  } else if (cleaningSequence_ == 2) {
491  cleaner_HighSlopeChecker(smoothedpoints);
492  } else if (cleaningSequence_ == 3) {
493  cleaner_LocalMinimumAdder(adcs, smoothedpoints, apvN);
494  cleaner_HighSlopeChecker(smoothedpoints);
495  } else {
496  cleaner_HighSlopeChecker(smoothedpoints);
497  cleaner_LocalMinimumAdder(adcs, smoothedpoints, apvN);
498  }
499 }
500 
502  //Removing points without monotony
503  //--------------------------------------------------------------------------------------------------
504  if (smoothedpoints.size() < 3)
505  return;
506 
507  auto it = smoothedpoints.begin();
508  while (smoothedpoints.size() > 3 && it != --(--smoothedpoints.end())) { //while we are not at the last point
509  // get info about current and next points
510  auto it2 = it;
511  const float adc1 = it2->second;
512  const float adc2 = (++it2)->second;
513  const float adc3 = (++it2)->second;
514 
515  if ((adc2 - adc1) > hitStripThreshold_ && (adc2 - adc3) > hitStripThreshold_) {
516  smoothedpoints.erase(--it2);
517  } else {
518  ++it;
519  }
520  }
521 }
522 
524  digimap_t& smoothedpoints,
525  uint16_t apvN) {
527  //inserting extra point is case of local minimum
528  //--------------------------------------------------------------------------------------------------
529  // these should be reset now for the point-insertion that follows
530 
531  if (smoothedpoints.size() >= 2) {
532  for (auto it = smoothedpoints.begin(); it != --smoothedpoints.end(); ++it) {
533  auto itNext = it;
534  ++itNext;
535  const float strip1 = it->first;
536  const float strip2 = itNext->first;
537  const float adc1 = it->second;
538  const float adc2 = itNext->second;
539  const float m = (adc2 - adc1) / (strip2 - strip1);
540 
541  //2,4
542  if ((strip2 - strip1) > slopeX_ && std::abs(adc1 - adc2) > slopeY_) {
543  float itStrip = 1;
544  float strip = itStrip + strip1;
545  while (strip < strip2) {
546  const float adc = adcs[strip];
547  const auto noise =
548  static_cast<float>(noiseHandle->getNoiseFast(strip + apvN * nTotStripsPerAPV, detNoiseRange));
549  if (adc < (adc1 + m * itStrip - 2 * noise)) {
550  smoothedpoints.emplace_hint(itNext, strip, adc);
551  ++it;
552  }
553  ++itStrip;
554  ++strip;
555  }
556  }
557  }
558  }
559 
560  const uint16_t firstStripFlat = smoothedpoints.begin()->first;
561  const uint16_t lastStripFlat = (--smoothedpoints.end())->first;
562  const int16_t firstStripFlatADC = smoothedpoints.begin()->second;
563  const int16_t lastStripFlatADC = (--smoothedpoints.end())->second;
564  if (firstStripFlat > 3) {
565  auto it = smoothedpoints.begin();
566  float strip = 0;
567  while (strip < firstStripFlat) {
568  const float adc = adcs[strip];
569  const auto noise = static_cast<float>(noiseHandle->getNoiseFast(strip + apvN * nTotStripsPerAPV, detNoiseRange));
570  if (adc < (firstStripFlatADC - 2 * noise)) {
571  smoothedpoints.emplace_hint(it, strip, adc);
572  ++it;
573  }
574  ++strip;
575  }
576  }
577  if (lastStripFlat < (nTotStripsPerAPV - 3)) {
578  float strip = lastStripFlat + 1;
579  while (strip < nTotStripsPerAPV) {
580  const float adc = adcs[strip];
581  const auto noise = static_cast<float>(noiseHandle->getNoiseFast(strip + apvN * nTotStripsPerAPV, detNoiseRange));
582  if (adc < (lastStripFlatADC - 2 * noise)) {
583  smoothedpoints.emplace_hint(smoothedpoints.end(), strip, adc);
584  }
585  ++strip;
586  }
587  }
588 }
589 
591  //Removing points in the slope is too high
592  //----------------------------------------------------------------------------
593  if (smoothedpoints.size() < 4)
594  return;
595 
596  auto it = smoothedpoints.begin();
597  while (smoothedpoints.size() > 2 && it != --smoothedpoints.end()) { //while we are not at the last point
598  //if(smoothedpoints.size() <2) break;
599  // get info about current and next points
600  auto itNext = it;
601  ++itNext;
602  const float strip1 = it->first;
603  const float strip2 = itNext->first;
604  const float adc1 = it->second;
605  const float adc2 = itNext->second;
606  const float m = (adc2 - adc1) / (strip2 - strip1);
607 
608  if (m > 2) { // in case of large positive slope, remove next point and try again from same current point
609  smoothedpoints.erase(itNext);
610  } else if (m < -2) { // in case of large negative slope, remove current point and either...
611  // move to next point if we have reached the beginning (post-increment to avoid invalidating pointer during erase) or...
612  if (it == smoothedpoints.begin())
613  smoothedpoints.erase(it++);
614  // try again from the previous point if we have not reached the beginning
615  else
616  smoothedpoints.erase(it--);
617  } else { // in case of a flat enough slope, continue on to the next point
618  ++it;
619  }
620  }
621 }
622 
623 void inline SiStripAPVRestorer::baselineFollower(const digimap_t& smoothedpoints,
624  digivector_t& baseline,
625  float median) {
626  //if not enough points
627  if (smoothedpoints.size() < minStripsToFit_) {
628  baseline.insert(baseline.begin(), nTotStripsPerAPV, median);
629  } else {
630  baseline.assign(size_t(nTotStripsPerAPV), 0);
631 
632  const auto lastIt = --smoothedpoints.end();
633  const uint16_t firstStripFlat = smoothedpoints.begin()->first;
634  const uint16_t lastStripFlat = lastIt->first;
635  const int16_t firstStripFlatADC = smoothedpoints.begin()->second;
636  const int16_t lastStripFlatADC = lastIt->second;
637 
638  //adding here the costant line at the extremities
639  baseline.erase(baseline.begin(), baseline.begin() + firstStripFlat);
640  baseline.insert(baseline.begin(), firstStripFlat, firstStripFlatADC);
641 
642  baseline.erase(baseline.begin() + lastStripFlat, baseline.end());
643  baseline.insert(baseline.end(), nTotStripsPerAPV - lastStripFlat, lastStripFlatADC);
644 
645  //IMPORTANT: the itSmoothedpointsEnd should be at least smaller than smoothedpoints.end() -1
646  for (auto itSmoothedpoints = smoothedpoints.begin(); itSmoothedpoints != (--smoothedpoints.end());
647  ++itSmoothedpoints) {
648  auto itNextSmoothedpoints = itSmoothedpoints;
649  ++itNextSmoothedpoints;
650  const float strip1 = itSmoothedpoints->first;
651  const float strip2 = itNextSmoothedpoints->first;
652  const float adc1 = itSmoothedpoints->second;
653  const float adc2 = itNextSmoothedpoints->second;
654 
655  baseline[strip1] = adc1;
656  baseline[strip2] = adc2;
657  const float m = (adc2 - adc1) / (strip2 - strip1);
658  uint16_t itStrip = strip1 + 1;
659  float stripadc = adc1 + m;
660  while (itStrip < strip2) {
661  baseline[itStrip] = stripadc;
662  ++itStrip;
663  stripadc += m;
664  }
665  }
666  }
667 }
668 
669 bool SiStripAPVRestorer::checkBaseline(const digivector_t& baseline) const {
670  // The Savitzky-Golay (S-G) filter of any left length nL, right
671  // length nR, and order m, and with an optional opt equals the
672  // derivative order (0 for the magnitude, 1 for the first
673  // derivative, etc.) can be calculated using the following
674  // Mathematica code:
675  //
676  // SavitzkyGolay[m_?IntegerQ, {nL_?IntegerQ, nR_?IntegerQ},
677  // opt___] := Module[
678  // {a, d},
679  // d = If[opt === Null, 0, If[IntegerQ[opt], opt, 0]];
680  // a = Table[
681  // If[i == 0 && j == 0, 1, i^j], {i, -nL, nR}, {j, 0,
682  // m}]; (Inverse[Transpose[a].a].Transpose[a])[[d + 1]]];
683  //
684  // The following coefficients can be then calculated by:
685  //
686  // N[Join[Table[SavitzkyGolay[2, {k, 16}], {k, 0, 16}],
687  // Table[SavitzkyGolay[2, {16, k}], {k, 15, 0, -1}]]]
688 
689  // nLR = max(nL, nR)
690  static const size_t savitzky_golay_n_l_r = 16;
691  static const float savitzky_golay_coefficient[2 * savitzky_golay_n_l_r + 1][2 * savitzky_golay_n_l_r + 1] = {
692  {0.422085,
693  0.325077,
694  0.23839,
695  0.162023,
696  0.0959752,
697  0.0402477,
698  -0.00515996,
699  -0.0402477,
700  -0.0650155,
701  -0.0794634,
702  -0.0835913,
703  -0.0773994,
704  -0.0608875,
705  -0.0340557,
706  0.00309598,
707  0.0505676,
708  0.108359},
709  {0.315789,
710  0.254902,
711  0.19969,
712  0.150155,
713  0.106295,
714  0.0681115,
715  0.0356037,
716  0.00877193,
717  -0.0123839,
718  -0.0278638,
719  -0.0376677,
720  -0.0417957,
721  -0.0402477,
722  -0.0330237,
723  -0.0201238,
724  -0.00154799,
725  0.0227038,
726  0.0526316},
727  {0.234586,
728  0.198496,
729  0.165207,
730  0.134719,
731  0.107032,
732  0.0821465,
733  0.0600619,
734  0.0407784,
735  0.024296,
736  0.0106148,
737  -0.000265369,
738  -0.00834439,
739  -0.0136223,
740  -0.0160991,
741  -0.0157747,
742  -0.0126493,
743  -0.00672269,
744  0.00200501,
745  0.0135338},
746  {0.172078, 0.153076, 0.135099, 0.118148, 0.102221, 0.0873206, 0.073445,
747  0.0605947, 0.0487697, 0.0379699, 0.0281955, 0.0194463, 0.0117225, 0.00502392,
748  -0.000649351, -0.00529733, -0.00892003, -0.0115174, -0.0130895, -0.0136364},
749  {0.123659, 0.116431, 0.109144, 0.101798, 0.0943921, 0.0869268, 0.0794021,
750  0.0718179, 0.0641743, 0.0564712, 0.0487087, 0.0408868, 0.0330054, 0.0250646,
751  0.0170644, 0.00900473, 0.000885613, -0.00729294, -0.0155309, -0.0238283, -0.0321852},
752  {0.0859684, 0.0868154, 0.0869565, 0.0863919, 0.0851214, 0.0831451, 0.080463, 0.0770751,
753  0.0729814, 0.0681818, 0.0626765, 0.0564653, 0.0495483, 0.0419255, 0.0335968, 0.0245624,
754  0.0148221, 0.00437606, -0.00677583, -0.0186335, -0.0311971, -0.0444664},
755  {0.0565217, 0.0628458, 0.0680971, 0.0722756, 0.0753811, 0.0774139, 0.0783738, 0.0782609,
756  0.0770751, 0.0748165, 0.071485, 0.0670807, 0.0616036, 0.0550536, 0.0474308, 0.0387352,
757  0.0289667, 0.0181254, 0.00621118, -0.00677583, -0.0208357, -0.0359684, -0.0521739},
758  {0.0334615, 0.0434281, 0.0521329, 0.0595759, 0.0657571, 0.0706765, 0.0743341, 0.07673,
759  0.0778641, 0.0777364, 0.0763469, 0.0736957, 0.0697826, 0.0646078, 0.0581712, 0.0504728,
760  0.0415126, 0.0312907, 0.0198069, 0.00706142, -0.00694588, -0.022215, -0.0387458, -0.0565385},
761  {0.0153846, 0.0276923, 0.0386622, 0.0482943, 0.0565886, 0.0635452, 0.0691639, 0.0734448, 0.076388,
762  0.0779933, 0.0782609, 0.0771906, 0.0747826, 0.0710368, 0.0659532, 0.0595318, 0.0517726, 0.0426756,
763  0.0322408, 0.0204682, 0.00735786, -0.0070903, -0.0228763, -0.04, -0.0584615},
764  {0.001221, 0.0149451, 0.027326, 0.0383639, 0.0480586, 0.0564103, 0.0634188, 0.0690842, 0.0734066,
765  0.0763858, 0.078022, 0.078315, 0.077265, 0.0748718, 0.0711355, 0.0660562, 0.0596337, 0.0518681,
766  0.0427595, 0.0323077, 0.0205128, 0.00737485, -0.00710623, -0.0229304, -0.0400977, -0.0586081},
767  {-0.00985222, 0.00463138, 0.0178098, 0.029683, 0.0402509, 0.0495137, 0.0574713, 0.0641236, 0.0694708,
768  0.0735127, 0.0762494, 0.0776809, 0.0778073, 0.0766284, 0.0741442, 0.0703549, 0.0652604, 0.0588607,
769  0.0511557, 0.0421456, 0.0318302, 0.0202097, 0.0072839, -0.00694708, -0.0224833, -0.0393247, -0.0574713},
770  {-0.0184729, -0.00369458, 0.00984169, 0.0221359, 0.0331881, 0.0429982, 0.0515662,
771  0.0588923, 0.0649762, 0.0698181, 0.073418, 0.0757758, 0.0768915, 0.0767652,
772  0.0753968, 0.0727864, 0.0689339, 0.0638394, 0.0575028, 0.0499242, 0.0411035,
773  0.0310408, 0.019736, 0.00718917, -0.00659972, -0.0216307, -0.0379037, -0.0554187},
774  {-0.025139, -0.0103925, 0.00318873, 0.0156046, 0.0268552, 0.0369405, 0.0458605, 0.0536151,
775  0.0602045, 0.0656285, 0.0698872, 0.0729806, 0.0749086, 0.0756714, 0.0752688, 0.0737009,
776  0.0709677, 0.0670692, 0.0620054, 0.0557763, 0.0483818, 0.039822, 0.0300969, 0.0192065,
777  0.0071508, -0.00607024, -0.0204566, -0.0360083, -0.0527253},
778  {-0.0302419, -0.0157536, -0.00234785, 0.00997537, 0.021216, 0.0313741, 0.0404497, 0.0484427,
779  0.0553532, 0.0611811, 0.0659264, 0.0695892, 0.0721695, 0.0736672, 0.0740823, 0.0734149,
780  0.0716649, 0.0688324, 0.0649174, 0.0599198, 0.0538396, 0.0466769, 0.0384316, 0.0291038,
781  0.0186934, 0.00720046, -0.00537502, -0.0190331, -0.0337736, -0.0495968},
782  {-0.0340909, -0.0200147, -0.006937, 0.00514208, 0.0162226, 0.0263045, 0.0353878, 0.0434725,
783  0.0505587, 0.0566463, 0.0617353, 0.0658257, 0.0689175, 0.0710107, 0.0721054, 0.0722014,
784  0.0712989, 0.0693978, 0.0664981, 0.0625999, 0.057703, 0.0518076, 0.0449135, 0.0370209,
785  0.0281297, 0.01824, 0.0073516, -0.00453534, -0.0174209, -0.031305, -0.0461877},
786  {-0.0369318, -0.0233688, -0.0107221, 0.00100806, 0.0118218, 0.0217192, 0.0307001, 0.0387647,
787  0.0459128, 0.0521444, 0.0574597, 0.0618585, 0.0653409, 0.0679069, 0.0695565, 0.0702896,
788  0.0701063, 0.0690066, 0.0669905, 0.0640579, 0.0602089, 0.0554435, 0.0497617, 0.0431635,
789  0.0356488, 0.0272177, 0.0178702, 0.0076063, -0.00357405, -0.0156708, -0.028684, -0.0426136},
790  {-0.038961, -0.025974, -0.0138249, -0.00251362, 0.00795978, 0.0175953, 0.026393, 0.0343527, 0.0414747,
791  0.0477587, 0.0532049, 0.0578132, 0.0615836, 0.0645161, 0.0666108, 0.0678676, 0.0682866, 0.0678676,
792  0.0666108, 0.0645161, 0.0615836, 0.0578132, 0.0532049, 0.0477587, 0.0414747, 0.0343527, 0.026393,
793  0.0175953, 0.00795978, -0.00251362, -0.0138249, -0.025974, -0.038961},
794  {-0.0426136, -0.028684, -0.0156708, -0.00357405, 0.0076063, 0.0178702, 0.0272177, 0.0356488,
795  0.0431635, 0.0497617, 0.0554435, 0.0602089, 0.0640579, 0.0669905, 0.0690066, 0.0701063,
796  0.0702896, 0.0695565, 0.0679069, 0.0653409, 0.0618585, 0.0574597, 0.0521444, 0.0459128,
797  0.0387647, 0.0307001, 0.0217192, 0.0118218, 0.00100806, -0.0107221, -0.0233688, -0.0369318},
798  {-0.0461877, -0.031305, -0.0174209, -0.00453534, 0.0073516, 0.01824, 0.0281297, 0.0370209,
799  0.0449135, 0.0518076, 0.057703, 0.0625999, 0.0664981, 0.0693978, 0.0712989, 0.0722014,
800  0.0721054, 0.0710107, 0.0689175, 0.0658257, 0.0617353, 0.0566463, 0.0505587, 0.0434725,
801  0.0353878, 0.0263045, 0.0162226, 0.00514208, -0.006937, -0.0200147, -0.0340909},
802  {-0.0495968, -0.0337736, -0.0190331, -0.00537502, 0.00720046, 0.0186934, 0.0291038, 0.0384316,
803  0.0466769, 0.0538396, 0.0599198, 0.0649174, 0.0688324, 0.0716649, 0.0734149, 0.0740823,
804  0.0736672, 0.0721695, 0.0695892, 0.0659264, 0.0611811, 0.0553532, 0.0484427, 0.0404497,
805  0.0313741, 0.021216, 0.00997537, -0.00234785, -0.0157536, -0.0302419},
806  {-0.0527253, -0.0360083, -0.0204566, -0.00607024, 0.0071508, 0.0192065, 0.0300969, 0.039822,
807  0.0483818, 0.0557763, 0.0620054, 0.0670692, 0.0709677, 0.0737009, 0.0752688, 0.0756714,
808  0.0749086, 0.0729806, 0.0698872, 0.0656285, 0.0602045, 0.0536151, 0.0458605, 0.0369405,
809  0.0268552, 0.0156046, 0.00318873, -0.0103925, -0.025139},
810  {-0.0554187, -0.0379037, -0.0216307, -0.00659972, 0.00718917, 0.019736, 0.0310408,
811  0.0411035, 0.0499242, 0.0575028, 0.0638394, 0.0689339, 0.0727864, 0.0753968,
812  0.0767652, 0.0768915, 0.0757758, 0.073418, 0.0698181, 0.0649762, 0.0588923,
813  0.0515662, 0.0429982, 0.0331881, 0.0221359, 0.00984169, -0.00369458, -0.0184729},
814  {-0.0574713, -0.0393247, -0.0224833, -0.00694708, 0.0072839, 0.0202097, 0.0318302, 0.0421456, 0.0511557,
815  0.0588607, 0.0652604, 0.0703549, 0.0741442, 0.0766284, 0.0778073, 0.0776809, 0.0762494, 0.0735127,
816  0.0694708, 0.0641236, 0.0574713, 0.0495137, 0.0402509, 0.029683, 0.0178098, 0.00463138, -0.00985222},
817  {-0.0586081, -0.0400977, -0.0229304, -0.00710623, 0.00737485, 0.0205128, 0.0323077, 0.0427595, 0.0518681,
818  0.0596337, 0.0660562, 0.0711355, 0.0748718, 0.077265, 0.078315, 0.078022, 0.0763858, 0.0734066,
819  0.0690842, 0.0634188, 0.0564103, 0.0480586, 0.0383639, 0.027326, 0.0149451, 0.001221},
820  {-0.0584615, -0.04, -0.0228763, -0.0070903, 0.00735786, 0.0204682, 0.0322408, 0.0426756, 0.0517726,
821  0.0595318, 0.0659532, 0.0710368, 0.0747826, 0.0771906, 0.0782609, 0.0779933, 0.076388, 0.0734448,
822  0.0691639, 0.0635452, 0.0565886, 0.0482943, 0.0386622, 0.0276923, 0.0153846},
823  {-0.0565385, -0.0387458, -0.022215, -0.00694588, 0.00706142, 0.0198069, 0.0312907, 0.0415126,
824  0.0504728, 0.0581712, 0.0646078, 0.0697826, 0.0736957, 0.0763469, 0.0777364, 0.0778641,
825  0.07673, 0.0743341, 0.0706765, 0.0657571, 0.0595759, 0.0521329, 0.0434281, 0.0334615},
826  {-0.0521739, -0.0359684, -0.0208357, -0.00677583, 0.00621118, 0.0181254, 0.0289667, 0.0387352,
827  0.0474308, 0.0550536, 0.0616036, 0.0670807, 0.071485, 0.0748165, 0.0770751, 0.0782609,
828  0.0783738, 0.0774139, 0.0753811, 0.0722756, 0.0680971, 0.0628458, 0.0565217},
829  {-0.0444664, -0.0311971, -0.0186335, -0.00677583, 0.00437606, 0.0148221, 0.0245624, 0.0335968,
830  0.0419255, 0.0495483, 0.0564653, 0.0626765, 0.0681818, 0.0729814, 0.0770751, 0.080463,
831  0.0831451, 0.0851214, 0.0863919, 0.0869565, 0.0868154, 0.0859684},
832  {-0.0321852, -0.0238283, -0.0155309, -0.00729294, 0.000885613, 0.00900473, 0.0170644,
833  0.0250646, 0.0330054, 0.0408868, 0.0487087, 0.0564712, 0.0641743, 0.0718179,
834  0.0794021, 0.0869268, 0.0943921, 0.101798, 0.109144, 0.116431, 0.123659},
835  {-0.0136364, -0.0130895, -0.0115174, -0.00892003, -0.00529733, -0.000649351, 0.00502392,
836  0.0117225, 0.0194463, 0.0281955, 0.0379699, 0.0487697, 0.0605947, 0.073445,
837  0.0873206, 0.102221, 0.118148, 0.135099, 0.153076, 0.172078},
838  {0.0135338,
839  0.00200501,
840  -0.00672269,
841  -0.0126493,
842  -0.0157747,
843  -0.0160991,
844  -0.0136223,
845  -0.00834439,
846  -0.000265369,
847  0.0106148,
848  0.024296,
849  0.0407784,
850  0.0600619,
851  0.0821465,
852  0.107032,
853  0.134719,
854  0.165207,
855  0.198496,
856  0.234586},
857  {0.0526316,
858  0.0227038,
859  -0.00154799,
860  -0.0201238,
861  -0.0330237,
862  -0.0402477,
863  -0.0417957,
864  -0.0376677,
865  -0.0278638,
866  -0.0123839,
867  0.00877193,
868  0.0356037,
869  0.0681115,
870  0.106295,
871  0.150155,
872  0.19969,
873  0.254902,
874  0.315789},
875  {0.108359,
876  0.0505676,
877  0.00309598,
878  -0.0340557,
879  -0.0608875,
880  -0.0773994,
881  -0.0835913,
882  -0.0794634,
883  -0.0650155,
884  -0.0402477,
885  -0.00515996,
886  0.0402477,
887  0.0959752,
888  0.162023,
889  0.23839,
890  0.325077,
891  0.422085}};
892 
893  float filtered_baseline[nTotStripsPerAPV];
894  float filtered_baseline_derivative[nTotStripsPerAPV - 1];
895 
896  // Zero filtered_baseline
897  memset(filtered_baseline, 0, nTotStripsPerAPV * sizeof(float));
898  // Filter the left edge using (nL, nR) = (0, 16) .. (15, 16) S-G
899  // filters
900  for (size_t i = 0; i < savitzky_golay_n_l_r; i++) {
901  for (size_t j = 0; j < savitzky_golay_n_l_r + 1 + i; j++) {
902  filtered_baseline[i] += savitzky_golay_coefficient[i][j] * baseline[j];
903  }
904  }
905  // Filter the middle section using the (nL, nR) = (16, 16) S-G
906  // filter, while taking advantage of the symmetry to save 16
907  // multiplications.
908  for (size_t i = savitzky_golay_n_l_r; i < nTotStripsPerAPV - savitzky_golay_n_l_r; i++) {
909  filtered_baseline[i] = savitzky_golay_coefficient[savitzky_golay_n_l_r][savitzky_golay_n_l_r] * baseline[i];
910  for (size_t j = 0; j < savitzky_golay_n_l_r; j++) {
911  filtered_baseline[i] += savitzky_golay_coefficient[savitzky_golay_n_l_r][j] *
912  (baseline[i + j - savitzky_golay_n_l_r] + baseline[i - j + savitzky_golay_n_l_r]);
913  }
914 #if 0
915  // Test that the indexing above is correct
916  float test = 0;
917  for (size_t j = 0; j < 2 * savitzky_golay_n_l_r + 1; j++) {
918  test +=
919  savitzky_golay_coefficient[savitzky_golay_n_l_r][j] *
920  baseline[i + j - savitzky_golay_n_l_r];
921  }
922  // test == filtered_baseline[i] should hold now
923 #endif
924  }
925  // Filter the right edge using (nL, nR) = (16, 15) .. (16, 0) S-G
926  // filters
927  for (size_t i = nTotStripsPerAPV - savitzky_golay_n_l_r; i < nTotStripsPerAPV; i++) {
928  for (size_t j = 0; j < nTotStripsPerAPV - i + savitzky_golay_n_l_r; j++) {
929  filtered_baseline[i] += savitzky_golay_coefficient[2 * savitzky_golay_n_l_r + i + 1 - nTotStripsPerAPV][j] *
930  baseline[i + j - savitzky_golay_n_l_r];
931  }
932  }
933  // In lieu of a spearate S-G derivative filter, the finite
934  // difference is used here (since the output is sufficiently
935  // smooth).
936  for (size_t i = 0; i < (nTotStripsPerAPV - 1); i++) {
937  filtered_baseline_derivative[i] = filtered_baseline[i + 1] - filtered_baseline[i];
938  }
939 
940  // Calculate the maximum deviation between filtered and unfiltered
941  // baseline, plus the sum square of the derivative.
942 
943  double filtered_baseline_max = 0;
944  double filtered_baseline_derivative_sum_square = 0;
945 
946  for (size_t i = 0; i < nTotStripsPerAPV; i++) {
947  const double d = filtered_baseline[i] - baseline[i];
948 
949  filtered_baseline_max = std::max(filtered_baseline_max, static_cast<double>(fabs(d)));
950  }
951  for (size_t i = 0; i < (nTotStripsPerAPV - 1); i++) {
952  filtered_baseline_derivative_sum_square += filtered_baseline_derivative[i] * filtered_baseline_derivative[i];
953  }
954 
955 #if 0
956  std::cerr << __FILE__ << ':' << __LINE__ << ": "
957  << filtered_baseline_max << ' '
958  << filtered_baseline_derivative_sum_square << std::endl;
959 #endif
960 
961  // Apply the cut
962  return !(filtered_baseline_max >= filteredBaselineMax_ ||
963  filtered_baseline_derivative_sum_square >= filteredBaselineDerivativeSumSquare_);
964 }
965 
966 //Other methods implementation ==============================================
967 //==========================================================================
968 
970  if (useRealMeanCM_) {
972  iEvent.getByLabel("siStripDigis", "VirginRaw", input);
973  createCMMapRealPed(*input);
974  } else {
976  iEvent.getByLabel("MEANAPVCM", inputCM);
977  createCMMapCMstored(*inputCM);
978  }
979 }
981  meanCMmap_.clear();
982  for (const auto& rawDigis : input) {
983  const auto detPedestalRange = pedestalHandle->getRange(rawDigis.id);
984  const size_t nAPVs = rawDigis.size() / nTotStripsPerAPV;
985  std::vector<float> meanCMDetSet;
986  meanCMDetSet.reserve(nAPVs);
987  for (uint16_t iAPV = 0; iAPV < nAPVs; ++iAPV) {
988  uint16_t minPed = nTotStripsPerAPV;
989  for (uint16_t strip = nTotStripsPerAPV * iAPV; strip < nTotStripsPerAPV * (iAPV + 1); ++strip) {
990  uint16_t ped = static_cast<uint16_t>(pedestalHandle->getPed(strip, detPedestalRange));
991  if (ped < minPed)
992  minPed = ped;
993  }
994  meanCMDetSet.push_back(minPed);
995  }
996  meanCMmap_.emplace(rawDigis.id, std::move(meanCMDetSet));
997  }
998 }
1000  meanCMmap_.clear();
1001  for (const auto& rawDigis : input) {
1002  std::vector<float> meanCMNValue;
1003  meanCMNValue.reserve(rawDigis.size());
1005  std::begin(rawDigis), std::end(rawDigis), std::back_inserter(meanCMNValue), [](SiStripProcessedRawDigi cm) {
1006  return cm.adc();
1007  });
1008  meanCMmap_.emplace(rawDigis.id, std::move(meanCMNValue));
1009  }
1010 }
1011 
1012 //NEW algorithm designed for implementation in FW=============================
1013 //============================================================================
1014 void SiStripAPVRestorer::derivativeFollowerRestore(uint16_t apvN, uint16_t firstAPV, digivector_t& digis) {
1015  digivector_t singleAPVdigi;
1016  singleAPVdigi.clear();
1017  for (int16_t strip = (apvN - firstAPV) * nTotStripsPerAPV; strip < (apvN - firstAPV + 1) * nTotStripsPerAPV; ++strip)
1018  singleAPVdigi.push_back(digis[strip] + 1024);
1019 
1020  digimap_t discontinuities; // it will contain the start and the end of each region in which a greadient is present
1021  discontinuities.clear();
1022 
1023  digimap_t::iterator itdiscontinuities;
1024 
1025  //----Variables of the first part---//
1026 
1027  bool isMinimumAndNoMax = false;
1028  bool isFirstStrip = false;
1029 
1030  //---Variables of the second part---//
1031 
1032  int actualStripADC = 0;
1033  int previousStripADC = 0;
1034 
1035  int greadient = 0;
1036  int maximum_value = 0;
1037  const uint32_t n_high_maximum_cluster = 1025 + 1024;
1038  int high_maximum_cluster = n_high_maximum_cluster;
1039  int number_good_minimum = 0;
1040  int first_gradient = 0;
1041  int strip_first_gradient = 0;
1042  int adc_start_point_cluster_pw = 0;
1043  int auxiliary_end_cluster = 0;
1044  int first_start_cluster_strip = 0;
1045  int first_start_cluster_ADC = 0;
1046  bool isAuxiliary_Minimum = false;
1047  bool isPossible_wrong_minimum = false;
1048  bool isMax = false;
1049 
1050  //----------SECOND PART: CLUSTER FINDING--------//
1051 
1052  for (uint16_t strip = 0; strip < singleAPVdigi.size(); ++strip) {
1053  if (strip == 0) {
1054  actualStripADC = singleAPVdigi[strip];
1055  if (std::abs(singleAPVdigi[strip] - singleAPVdigi[strip + 1]) > gradient_threshold_) {
1056  isFirstStrip = true;
1057  isMinimumAndNoMax = true;
1058  discontinuities.insert(discontinuities.end(), std::pair<int, int>(strip, actualStripADC));
1059  } else if (actualStripADC > (gradient_threshold_ + 1024)) {
1060  discontinuities.insert(discontinuities.end(), std::pair<uint16_t, int16_t>(strip, 0 + 1024));
1061  isMinimumAndNoMax = true;
1062  first_start_cluster_strip = strip;
1063  first_start_cluster_ADC = 1024;
1064  }
1065 
1066  } else {
1067  previousStripADC = actualStripADC;
1068  actualStripADC = singleAPVdigi[strip];
1069  greadient = actualStripADC - previousStripADC;
1070 
1071  if (((greadient > gradient_threshold_) && (!isMax) && (!isMinimumAndNoMax))) {
1072  isMax = false;
1073  if (((std::abs(maximum_value - previousStripADC) < (2 * gradient_threshold_)) &&
1074  discontinuities.size() > 1)) { // add the || with the cluster size
1075  //to verify if the noise do not interfere and is detected fake hits
1076  isPossible_wrong_minimum = true;
1077  itdiscontinuities = --discontinuities.end();
1078  if (discontinuities.size() > 1) {
1079  --itdiscontinuities;
1080  }
1081  strip_first_gradient = itdiscontinuities->first;
1082  adc_start_point_cluster_pw = itdiscontinuities->second;
1083  first_gradient = std::abs(adc_start_point_cluster_pw - singleAPVdigi[strip_first_gradient + 1]);
1084  discontinuities.erase(++itdiscontinuities);
1085  discontinuities.erase(--discontinuities.end());
1086  }
1087 
1088  if ((discontinuities.size() % 2 == 1) && (!discontinuities.empty())) { //&&(no_minimo == 0)
1089  discontinuities.erase(--discontinuities.end());
1090  }
1091 
1092  discontinuities.insert(discontinuities.end(), std::pair<uint16_t, int16_t>(strip - 1, previousStripADC));
1093  isMinimumAndNoMax = true;
1094  maximum_value = 0;
1095  first_start_cluster_strip = strip - 1;
1096  first_start_cluster_ADC = previousStripADC;
1097 
1098  } else if ((!isMax) && ((actualStripADC - previousStripADC < 0) && (isMinimumAndNoMax))) {
1099  isMax = true;
1100  isMinimumAndNoMax = false;
1101  high_maximum_cluster = n_high_maximum_cluster;
1102  if ((previousStripADC > maximum_value) && (discontinuities.size() % 2 == 1))
1103  maximum_value = previousStripADC;
1104  }
1105 
1106  if ((isMax) && (strip < (nTotStripsPerAPV - 2))) {
1107  if (high_maximum_cluster > (std::abs(singleAPVdigi[strip + 1] - actualStripADC))) {
1108  high_maximum_cluster = singleAPVdigi[strip + 1] - actualStripADC;
1109  auxiliary_end_cluster = strip + 2;
1110  } else {
1111  auxiliary_end_cluster = nTotStripsPerAPV - 1;
1112  }
1113  }
1114 
1115  if ((isMax) && ((actualStripADC - previousStripADC) >= 0) && (size_window_ > 0) &&
1116  (strip <= ((nTotStripsPerAPV - 1) - size_window_ - 1))) {
1117  number_good_minimum = 0;
1118  for (uint16_t wintry = 0; wintry <= size_window_; wintry++) {
1119  if (std::abs(singleAPVdigi[strip + wintry] - singleAPVdigi[strip + wintry + 1]) <= last_gradient_)
1120  ++number_good_minimum;
1121  }
1122  --number_good_minimum;
1123 
1124  if (size_window_ != number_good_minimum) {
1125  isMax = false; // not Valid end Point
1126  isMinimumAndNoMax = true;
1127  }
1128 
1129  } else if ((isMax) && (strip > ((nTotStripsPerAPV - 1) - size_window_ - 1))) {
1130  isMax = true;
1131  isAuxiliary_Minimum = true; //for minimums after strip 127-SW-1
1132  }
1133 
1134  if (!discontinuities.empty()) {
1135  itdiscontinuities = --discontinuities.end();
1136  }
1137 
1138  if ((isMax) && (actualStripADC <= first_start_cluster_ADC)) {
1139  if ((std::abs(first_start_cluster_ADC - singleAPVdigi[strip + 2]) > first_gradient) &&
1140  (isPossible_wrong_minimum)) {
1141  discontinuities.erase(itdiscontinuities);
1142  discontinuities.insert(discontinuities.end(),
1143  std::pair<int, int>(strip_first_gradient, adc_start_point_cluster_pw));
1144  discontinuities.insert(discontinuities.end(), std::pair<int, int>(strip, adc_start_point_cluster_pw));
1145  } else {
1146  if ((discontinuities.size() % 2 == 0) && (discontinuities.size() > 1)) {
1147  discontinuities.erase(--discontinuities.end());
1148  }
1149  discontinuities.insert(discontinuities.end(), std::pair<int, int>(strip, actualStripADC));
1150  }
1151  isMax = false;
1152  adc_start_point_cluster_pw = 0;
1153  isPossible_wrong_minimum = false;
1154  strip_first_gradient = 0;
1155  first_start_cluster_strip = 0;
1156  first_start_cluster_ADC = 0;
1157  }
1158 
1159  if ((isMax) && ((actualStripADC - previousStripADC) >= 0) &&
1160  (!isAuxiliary_Minimum)) { //For the end Poit when strip >127-SW-1
1161  if ((std::abs(first_start_cluster_ADC - singleAPVdigi[strip + 1]) > first_gradient) &&
1162  (isPossible_wrong_minimum)) {
1163  discontinuities.erase(itdiscontinuities);
1164  discontinuities.insert(discontinuities.end(),
1165  std::pair<int, int>(strip_first_gradient, adc_start_point_cluster_pw));
1166  }
1167 
1168  if ((discontinuities.size() % 2 == 0) && (discontinuities.size() > 1)) {
1169  discontinuities.erase(--discontinuities.end());
1170  }
1171  discontinuities.insert(discontinuities.end(), std::pair<int, int>(strip - 1, previousStripADC));
1172  isMax = false;
1173  adc_start_point_cluster_pw = 0;
1174  isPossible_wrong_minimum = false;
1175  strip_first_gradient = 0;
1176  first_start_cluster_strip = 0;
1177  first_start_cluster_ADC = 0;
1178  }
1179  }
1180  }
1181 
1182  //----------THIRD PART reconstruction of the event without baseline-------//
1183 
1184  if (!discontinuities.empty()) {
1185  if ((first_start_cluster_strip) == (nTotStripsPerAPV - 1) - 1)
1186  discontinuities.insert(discontinuities.end(),
1187  std::pair<int, int>((nTotStripsPerAPV - 1), first_start_cluster_ADC));
1188  if ((isMax) && (isAuxiliary_Minimum))
1189  discontinuities.insert(discontinuities.end(),
1190  std::pair<int, int>(auxiliary_end_cluster, first_start_cluster_ADC));
1191  }
1192 
1193  if (isFirstStrip) {
1194  itdiscontinuities = discontinuities.begin();
1195  ++itdiscontinuities;
1196  ++itdiscontinuities;
1197  int firstADC = itdiscontinuities->second;
1198  --itdiscontinuities;
1199  itdiscontinuities->second = firstADC;
1200  --itdiscontinuities;
1201  itdiscontinuities->second = firstADC;
1202  }
1203 
1204  if (!discontinuities.empty()) {
1205  itdiscontinuities = discontinuities.begin();
1206  uint16_t firstStrip = itdiscontinuities->first;
1207  int16_t firstADC = itdiscontinuities->second;
1208  ++itdiscontinuities;
1209  uint16_t lastStrip = itdiscontinuities->first;
1210  int16_t secondADC = itdiscontinuities->second;
1211  ++itdiscontinuities;
1212 
1213  for (uint16_t strip = 0; strip < nTotStripsPerAPV; ++strip) {
1214  if (strip > lastStrip && itdiscontinuities != discontinuities.end()) {
1215  firstStrip = itdiscontinuities->first;
1216  firstADC = itdiscontinuities->second;
1217  ++itdiscontinuities;
1218  lastStrip = itdiscontinuities->first;
1219  secondADC = itdiscontinuities->second;
1220  ++itdiscontinuities;
1221  }
1222 
1223  if ((firstStrip <= strip) && (strip <= lastStrip) &&
1224  (0 < (singleAPVdigi[strip] - firstADC -
1225  ((secondADC - firstADC) / (lastStrip - firstStrip)) * (strip - firstStrip) - gradient_threshold_))) {
1226  digis[(apvN - firstAPV) * nTotStripsPerAPV + strip] =
1227  singleAPVdigi[strip] - firstADC -
1228  (((secondADC - firstADC) / (lastStrip - firstStrip)) * (strip - firstStrip));
1229  edm::LogWarning("NoBaseline") << "No baseline " << digis[(apvN - firstAPV) * nTotStripsPerAPV + strip] << "\n";
1230  } else {
1231  digis[(apvN - firstAPV) * nTotStripsPerAPV + strip] = 0;
1232  }
1233  }
1234  }
1235 }
edm::ESWatcher< SiStripQualityRcd > qualityWatcher_
SiStripAPVRestorer(const edm::ParameterSet &conf, edm::ConsumesCollector)
bool IsApvBad(const uint32_t &detid, const short &apvNb) const
bool checkBaseline(const std::vector< int16_t > &baseline) const
void init(const edm::EventSetup &es)
void baselineFollowerRestore(uint16_t apvN, uint16_t firstAPV, float median, digivector_t &digis)
uint16_t baselineAndSaturationInspect(uint16_t firstAPV, const digivector_t &digis)
A signed Digi for the silicon strip detector, containing only adc information, and suitable for stori...
bool IsStripBad(const uint32_t &detid, const short &strip) const
const SiStripPedestals * pedestalHandle
std::map< uint16_t, digimap_t > smoothedMaps_
uint16_t baselineFollowerInspect(uint16_t firstAPV, const digivector_t &digis)
double filteredBaselineDerivativeSumSquare_
void flatRestore(uint16_t apvN, uint16_t firstAPV, digivector_t &digis)
edm::ESGetToken< SiStripQuality, SiStripQualityRcd > qualityToken_
static std::string const input
Definition: EdmProvDump.cc:47
edm::ESWatcher< SiStripNoisesRcd > noiseWatcher_
void baselineFollower(const digimap_t &, digivector_t &baseline, float median)
float getPed(const uint16_t &strip, const Range &range) const
void loadMeanCMMap(const edm::Event &)
bool getData(T &iHolder) const
Definition: EventSetup.h:128
U second(std::pair< T, U > const &p)
tuple d
Definition: ztail.py:151
uint16_t hybridEmulationInspect(uint16_t firstAPV, const digivector_t &digis)
std::vector< std::string > apvFlags_
baselinemap_t baselineMap_
static float getNoiseFast(const uint16_t &strip, const Range &range)
Definition: SiStripNoises.h:68
int iEvent
Definition: GenABIO.cc:224
const SiStripQuality * qualityHandle
void baselineCleaner(const digivector_t &adcs, digimap_t &smoothedpoints, uint16_t apvN)
void cleaner_LocalMinimumAdder(const digivector_t &adcs, digimap_t &smoothedpoints, uint16_t apvN)
std::vector< std::pair< short, float >> medians_t
def move
Definition: eostools.py:511
void cleaner_HighSlopeChecker(digimap_t &smoothedpoints)
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
const SiStripNoises * noiseHandle
T min(T a, T b)
Definition: MathUtil.h:58
bool flatRegionsFinder(const digivector_t &adcs, digimap_t &smoothedpoints, uint16_t apvN)
void cleaner_MonotonyChecker(digimap_t &smoothedpoints)
bool getByLabel(InputTag const &tag, Handle< PROD > &result) const
Definition: Event.h:500
uint16_t inspectAndRestore(uint32_t detId, uint16_t firstAPV, const digivector_t &rawDigisPedSubtracted, digivector_t &processedRawDigi, const medians_t &vmedians)
void derivativeFollowerRestore(uint16_t apvN, uint16_t firstAPV, digivector_t &digis)
void createCMMapCMstored(const edm::DetSetVector< SiStripProcessedRawDigi > &input)
edm::ESGetToken< SiStripPedestals, SiStripPedestalsRcd > pedestalToken_
uint16_t hybridFormatInspect(uint16_t firstAPV, const digivector_t &digis)
for(Iditer=Id.begin();Iditer!=Id.end();Iditer++)
__shared__ int noise
edm::ESWatcher< SiStripPedestalsRcd > pedestalWatcher_
std::vector< bool > apvFlagsBoolOverride_
std::map< uint16_t, digi_t > digimap_t
const float & adc() const
edm::ESGetToken< SiStripNoises, SiStripNoisesRcd > noiseToken_
uint16_t nullInspect(uint16_t firstAPV, const digivector_t &digis)
std::vector< bool > badAPVs_
bool check(const edm::EventSetup &iSetup)
Definition: ESWatcher.h:57
std::vector< bool > apvFlagsBool_
T median(std::vector< T > values)
Definition: median.h:16
const Range getRange(const uint32_t detID) const
uint16_t abnormalBaselineInspect(uint16_t firstAPV, const digivector_t &digis)
const Range getRange(const uint32_t detID) const
std::pair< ContainerIterator, ContainerIterator > Range
std::vector< digi_t > digivector_t
string end
Definition: dataset.py:937
std::vector< float > median_
void restore(uint16_t firstAPV, digivector_t &digis)
uint16_t forceRestoreInspect(uint16_t firstAPV, const digivector_t &digis)
const Range getRange(const uint32_t &detID) const
static constexpr uint16_t nTotStripsPerAPV
Log< level::Warning, false > LogWarning
std::pair< ContainerIterator, ContainerIterator > Range
Definition: SiStripNoises.h:47
ESGetTokenH3DDVariant esConsumes(std::string const &Reccord, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
void createCMMapRealPed(const edm::DetSetVector< SiStripRawDigi > &input)
uint16_t *__restrict__ uint16_t const *__restrict__ adc
uint16_t inspect(uint32_t detId, uint16_t firstAPV, const digivector_t &digis, const medians_t &vmedians)
unsigned transform(const HcalDetId &id, unsigned transformCode)