10 #include "cetlib_except/exception.h" 20 #include "TVirtualFFT.h" 40 void triangleSmooth(
const std::vector<float>&, std::vector<float>&,
size_t = 0)
const override;
41 void triangleSmooth(
const std::vector<double>&, std::vector<double>&,
size_t = 0)
const override;
42 void medianSmooth(
const std::vector<float>&, std::vector<float>&,
size_t = 3)
const override;
43 void medianSmooth(
const std::vector<double>&, std::vector<double>&,
size_t = 3)
const override;
44 void getTruncatedMeanRMS(
const std::vector<double>&,
double&,
double&,
double&,
int&)
const override;
45 void getTruncatedMeanRMS(
const std::vector<float>&,
float&,
float&,
float&,
int&)
const override;
46 void firstDerivative(
const std::vector<float>&, std::vector<float>&)
const override;
47 void firstDerivative(
const std::vector<double>&, std::vector<double>&)
const override;
50 void getFFTPower(
const std::vector<float>& inputVec, std::vector<float>& outputPowerVec)
const override;
51 void getFFTPower(
const std::vector<double>& inputVec, std::vector<double>& outputPowerVec)
const override;
80 template <
typename T>
void triangleSmooth(
const std::vector<T>&, std::vector<T>&,
size_t = 0)
const;
81 template <
typename T>
void medianSmooth(
const std::vector<T>&, std::vector<T>&,
size_t = 3)
const;
82 template <
typename T>
void getTruncatedMeanRMS(
const std::vector<T>&, T&, T&, T&,
int&)
const;
83 template <
typename T>
void firstDerivative(
const std::vector<T>&, std::vector<T>&)
const;
114 triangleSmooth<double>(inputVec, smoothVec, lowestBin);
121 triangleSmooth<float>(inputVec, smoothVec, lowestBin);
128 if (inputVec.size() != smoothVec.size()) smoothVec.resize(inputVec.size());
130 std::copy(inputVec.begin(), inputVec.begin() + 2 + lowestBin, smoothVec.begin());
131 std::copy(inputVec.end() - 2, inputVec.end(), smoothVec.end() - 2);
137 while(curInItr++ != stopInItr)
140 T newVal = (*(curInItr - 2) + 2. * *(curInItr - 1) + 3. * *curInItr + 2. * *(curInItr + 1) + *(curInItr + 2)) / 9.;
149 medianSmooth<float>(inputVec, smoothVec, nBins);
156 medianSmooth<double>(inputVec, smoothVec, nBins);
164 if (nBins % 2 == 0) nBins++;
167 if (inputVec.size() != smoothVec.size()) smoothVec.resize(inputVec.size());
170 typename std::vector<T> medianVec(nBins);
174 std::advance(stopItr, inputVec.size() - nBins);
176 size_t medianBin = nBins/2;
177 size_t smoothBin = medianBin;
180 std::copy(startItr, startItr + medianBin, smoothVec.begin());
182 while(std::distance(startItr,stopItr) > 0)
184 std::copy(startItr,startItr+nBins,medianVec.begin());
185 std::sort(medianVec.begin(),medianVec.end());
187 T medianVal = medianVec[medianBin];
189 smoothVec[smoothBin++] = medianVal;
195 std::copy(startItr + medianBin, inputVec.end(), smoothVec.begin() + smoothBin);
202 getTruncatedMeanRMS<double>(waveform,
mean, rmsFull, rmsTrunc, nTrunc);
207 getTruncatedMeanRMS<float>(waveform,
mean, rmsFull, rmsTrunc, nTrunc);
216 std::map<int,int> frequencyMap;
220 for(
const auto& val : waveform)
222 int intVal = std::round(4.*val);
224 frequencyMap[intVal]++;
226 if (frequencyMap.at(intVal) > mpCount)
228 mpCount = frequencyMap.at(intVal);
236 int binRange =
std::min(16,
int(frequencyMap.size()/2 + 1));
238 for(
int idx = -binRange; idx <= binRange; idx++)
242 if (neighborItr != frequencyMap.end() && 5 * neighborItr->second > mpCount)
244 meanSum += neighborItr->first * neighborItr->second;
245 meanCnt += neighborItr->second;
249 mean = 0.25 * T(meanSum) / T(meanCnt);
252 typename std::vector<T> locWaveform = waveform;
254 std::transform(locWaveform.begin(), locWaveform.end(), locWaveform.begin(),std::bind(std::minus<T>(),std::placeholders::_1,mean));
257 std::sort(locWaveform.begin(), locWaveform.end(),[](
const auto&
left,
const auto&
right){
return std::fabs(
left) < std::fabs(
right);});
260 rmsFull = std::inner_product(locWaveform.begin(), locWaveform.end(), locWaveform.begin(), 0.);
261 rmsFull = std::sqrt(
std::max(T(0.),rmsFull / T(locWaveform.size())));
264 rmsTrunc = std::inner_product(locWaveform.begin(), locWaveform.begin() + meanCnt, locWaveform.begin(), 0.);
265 rmsTrunc = std::sqrt(
std::max(T(0.),rmsTrunc / T(meanCnt)));
273 firstDerivative<double>(inputVec, derivVec);
280 firstDerivative<float>(inputVec, derivVec);
287 derivVec.resize(inputVec.size(), 0.);
289 for(
size_t idx = 1; idx < derivVec.size() - 1; idx++)
290 derivVec.at(idx) = 0.5 * (inputVec.at(idx + 1) - inputVec.at(idx - 1));
297 findPeaks<double>(startItr, stopItr, peakTupleVec, threshold, firstTick);
304 findPeaks<float>(startItr, stopItr, peakTupleVec, threshold, firstTick);
313 size_t firstTick)
const 316 if (std::distance(startItr,stopItr) > 4)
322 if (std::fabs(*firstItr) > threshold)
336 while(tempItr != stopItr)
338 if (*++tempItr < -threshold)
340 if (*tempItr < *secondItr) secondItr = tempItr;
342 else if (secondItr != firstItr)
break;
350 while(tempItr != startItr)
352 if (*--tempItr > threshold)
354 if (*tempItr > *secondItr) secondItr = tempItr;
356 else if (secondItr != firstItr)
break;
359 std::swap(firstItr,secondItr);
363 if (firstItr != secondItr)
366 size_t peakBin = std::distance(startItr,firstItr) + std::distance(firstItr,secondItr) / 2;
369 while(firstItr != startItr)
if (*--firstItr < 0.)
break;
370 while(secondItr != stopItr)
if (*++secondItr > 0.)
break;
372 size_t firstBin = std::distance(startItr,firstItr);
373 size_t lastBin = std::distance(startItr,secondItr);
376 findPeaks(startItr, firstItr, peakTupleVec, threshold, firstTick);
379 peakTupleVec.push_back(
PeakTuple(firstBin+firstTick,peakBin+firstTick,lastBin+firstTick));
382 findPeaks(secondItr, stopItr, peakTupleVec, threshold, firstTick + std::distance(startItr,secondItr));
392 std::vector<double> inputDoubleVec(inputVec.size());
393 std::vector<double> outputDoubleVec(inputVec.size()/2);
395 std::copy(inputVec.begin(),inputVec.end(),inputDoubleVec.begin());
399 if (outputDoubleVec.size() != outputPowerVec.size()) outputPowerVec.resize(outputDoubleVec.size());
401 std::copy(outputDoubleVec.begin(),outputDoubleVec.end(),outputPowerVec.begin());
409 int fftDataSize = inputVec.size();
411 TVirtualFFT* fftr2c = TVirtualFFT::FFT(1, &fftDataSize,
"R2C");
413 fftr2c->SetPoints(inputVec.data());
417 size_t halfFFTDataSize(fftDataSize/2 + 1);
419 std::vector<double> realVals(halfFFTDataSize);
420 std::vector<double> imaginaryVals(halfFFTDataSize);
422 fftr2c->GetPointsComplex(realVals.data(), imaginaryVals.data());
424 if (outputPowerVec.size() != halfFFTDataSize) outputPowerVec.resize(halfFFTDataSize,0.);
426 std::transform(realVals.begin(), realVals.begin() + halfFFTDataSize, imaginaryVals.begin(), outputPowerVec.begin(), [](
const double& real,
const double& imaginary){
return std::sqrt(real*real + imaginary*imaginary);});
432 int structuringElement,
439 getErosionDilationAverageDifference<short>(waveform, structuringElement, histogramMap, erosionVec, dilationVec, averageVec, differenceVec);
445 int structuringElement,
452 getErosionDilationAverageDifference<float>(waveform, structuringElement, histogramMap, erosionVec, dilationVec, averageVec, differenceVec);
458 int structuringElement,
465 getErosionDilationAverageDifference<double>(waveform, structuringElement, histogramMap, erosionVec, dilationVec, averageVec, differenceVec);
471 int structuringElement,
479 int halfWindowSize(structuringElement/2);
483 std::minmax_element(inputWaveform.begin(),inputWaveform.begin()+halfWindowSize);
489 erosionVec.resize(inputWaveform.size());
490 dilationVec.resize(inputWaveform.size());
491 averageVec.resize(inputWaveform.size());
492 differenceVec.resize(inputWaveform.size());
507 if (std::distance(inputItr,inputWaveform.end()) > halfWindowSize)
509 if (std::distance(minElementItr,inputItr) >= halfWindowSize)
510 minElementItr = std::min_element(inputItr - halfWindowSize + 1, inputItr + halfWindowSize + 1);
511 else if (*(inputItr + halfWindowSize) < *minElementItr)
512 minElementItr = inputItr + halfWindowSize;
514 if (std::distance(maxElementItr,inputItr) >= halfWindowSize)
515 maxElementItr = std::max_element(inputItr - halfWindowSize + 1, inputItr + halfWindowSize + 1);
516 else if (*(inputItr + halfWindowSize) > *maxElementItr)
517 maxElementItr = inputItr + halfWindowSize;
521 *minItr++ = *minElementItr;
522 *maxItr++ = *maxElementItr;
523 *aveItr++ = 0.5 * (*maxElementItr + *minElementItr);
524 *difItr++ = *maxElementItr - *minElementItr;
526 if (!histogramMap.empty())
528 int curBin = std::distance(inputWaveform.begin(),inputItr);
530 histogramMap.at(
WAVEFORM)->Fill( curBin, *inputItr);
531 histogramMap.at(
EROSION)->Fill( curBin, *minElementItr);
532 histogramMap.at(
DILATION)->Fill( curBin, *maxElementItr);
533 histogramMap.at(
AVERAGE)->Fill( curBin, 0.5*(*maxElementItr + *minElementItr));
534 histogramMap.at(
DIFFERENCE)->Fill( curBin, *maxElementItr - *minElementItr);
544 int structuringElement,
549 getOpeningAndClosing<short>(erosionVec, dilationVec, structuringElement, histogramMap, openingVec, closingVec);
556 int structuringElement,
561 getOpeningAndClosing<float>(erosionVec, dilationVec, structuringElement, histogramMap, openingVec, closingVec);
568 int structuringElement,
573 getOpeningAndClosing<double>(erosionVec, dilationVec, structuringElement, histogramMap, openingVec, closingVec);
580 int structuringElement,
586 int halfWindowSize(structuringElement/2);
592 openingVec.resize(erosionVec.size());
604 if (std::distance(inputItr,erosionVec.end()) > halfWindowSize)
606 if (std::distance(maxElementItr,inputItr) >= halfWindowSize)
607 maxElementItr = std::max_element(inputItr - halfWindowSize + 1, inputItr + halfWindowSize + 1);
608 else if (*(inputItr + halfWindowSize) > *maxElementItr)
609 maxElementItr = inputItr + halfWindowSize;
613 *maxItr++ = *maxElementItr;
615 if (!histogramMap.empty())
617 int curBin = std::distance(erosionVec.begin(),inputItr);
619 histogramMap.at(
OPENING)->Fill(curBin, *maxElementItr);
627 closingVec.resize(dilationVec.size());
639 if (std::distance(inputItr,dilationVec.end()) > halfWindowSize)
641 if (std::distance(minElementItr,inputItr) >= halfWindowSize)
642 minElementItr = std::min_element(inputItr - halfWindowSize + 1, inputItr + halfWindowSize + 1);
643 else if (*(inputItr + halfWindowSize) < *minElementItr)
644 minElementItr = inputItr + halfWindowSize;
648 *minItr++ = *minElementItr;
650 if (!histogramMap.empty())
652 int curBin = std::distance(dilationVec.begin(),inputItr);
654 histogramMap.at(
CLOSING)->Fill(curBin, *minElementItr);
655 histogramMap.at(
DOPENCLOSING)->Fill(curBin, *minElementItr - openingVec.at(curBin));
constexpr auto const & right(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
Utilities related to art service access.
Generic class for shaping signals on wires.
Definition of data types for geometry description.
constexpr auto const & left(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
double mean(const std::vector< short > &wf, size_t start, size_t nsample)
art framework interface to geometry description