9 #include "art/Utilities/ToolMacros.h"
12 #include "TVirtualFFT.h"
24 void configure(
const fhicl::ParameterSet& pset)
override;
29 void triangleSmooth(
const std::vector<float>&, std::vector<float>&,
size_t = 0)
const override;
30 void triangleSmooth(
const std::vector<double>&, std::vector<double>&,
size_t = 0)
const override;
31 void medianSmooth(
const std::vector<float>&, std::vector<float>&,
size_t = 3)
const override;
32 void medianSmooth(
const std::vector<double>&, std::vector<double>&,
size_t = 3)
const override;
33 void getTruncatedMeanRMS(
const std::vector<double>&,
double&,
double&,
double&,
int&)
const override;
34 void getTruncatedMeanRMS(
const std::vector<float>&,
float&,
float&,
float&,
int&)
const override;
35 void firstDerivative(
const std::vector<float>&, std::vector<float>&)
const override;
36 void firstDerivative(
const std::vector<double>&, std::vector<double>&)
const override;
37 void findPeaks(std::vector<float>::iterator, std::vector<float>::iterator,
PeakTupleVec&,
float,
size_t)
const override;
38 void findPeaks(std::vector<double>::iterator, std::vector<double>::iterator,
PeakTupleVec&,
double,
size_t)
const override;
39 void getFFTPower(
const std::vector<float>& inputVec, std::vector<float>& outputPowerVec)
const override;
40 void getFFTPower(
const std::vector<double>& inputVec, std::vector<double>& outputPowerVec)
const override;
69 template <
typename T>
void triangleSmooth(
const std::vector<T>&, std::vector<T>&,
size_t = 0)
const;
70 template <
typename T>
void medianSmooth(
const std::vector<T>&, std::vector<T>&,
size_t = 3)
const;
71 template <
typename T>
void getTruncatedMeanRMS(
const std::vector<T>&, T&, T&, T&,
int&)
const;
72 template <
typename T>
void firstDerivative(
const std::vector<T>&, std::vector<T>&)
const;
73 template <
typename T>
void findPeaks(
typename std::vector<T>::iterator,
typename std::vector<T>::iterator,
PeakTupleVec&, T,
size_t)
const;
103 triangleSmooth<double>(inputVec, smoothVec, lowestBin);
110 triangleSmooth<float>(inputVec, smoothVec, lowestBin);
117 if (inputVec.size() != smoothVec.size()) smoothVec.resize(inputVec.size());
120 if (inputVec.size() > 4)
122 std::copy(inputVec.begin(), inputVec.begin() + 2 + lowestBin, smoothVec.begin());
123 std::copy(inputVec.end() - 2, inputVec.end(), smoothVec.end() - 2);
125 typename std::vector<T>::iterator curItr = smoothVec.begin() + 2 + lowestBin;
126 typename std::vector<T>::const_iterator curInItr = inputVec.begin() + 1 + lowestBin;
127 typename std::vector<T>::const_iterator stopInItr = inputVec.end() - 3;
129 while(curInItr++ != stopInItr)
132 T newVal = (*(curInItr - 2) + 2. * *(curInItr - 1) + 3. * *curInItr + 2. * *(curInItr + 1) + *(curInItr + 2)) / 9.;
137 else std::copy(inputVec.begin(), inputVec.end(), smoothVec.begin());
144 medianSmooth<float>(inputVec, smoothVec, nBins);
151 medianSmooth<double>(inputVec, smoothVec, nBins);
159 if (nBins % 2 == 0) nBins++;
162 if (inputVec.size() != smoothVec.size()) smoothVec.resize(inputVec.size());
165 typename std::vector<T> medianVec(nBins);
166 typename std::vector<T>::const_iterator startItr = inputVec.begin();
167 typename std::vector<T>::const_iterator stopItr = startItr;
169 std::advance(stopItr, inputVec.size() - nBins);
171 size_t medianBin = nBins/2;
172 size_t smoothBin = medianBin;
175 std::copy(startItr, startItr + medianBin, smoothVec.begin());
179 std::copy(startItr,startItr+nBins,medianVec.begin());
180 std::sort(medianVec.begin(),medianVec.end());
182 T medianVal = medianVec[medianBin];
184 smoothVec[smoothBin++] = medianVal;
190 std::copy(startItr + medianBin, inputVec.end(), smoothVec.begin() + smoothBin);
197 getTruncatedMeanRMS<double>(waveform,
mean, rmsFull, rmsTrunc, nTrunc);
202 getTruncatedMeanRMS<float>(waveform,
mean, rmsFull, rmsTrunc, nTrunc);
211 std::map<int,int> frequencyMap;
215 for(
const auto& val : waveform)
217 int intVal = std::round(4.*val);
219 frequencyMap[intVal]++;
221 if (frequencyMap.at(intVal) > mpCount)
223 mpCount = frequencyMap.at(intVal);
231 int binRange = std::min(16,
int(frequencyMap.size()/2 + 1));
233 for(
int idx = -binRange; idx <= binRange; idx++)
235 std::map<int,int>::iterator neighborItr = frequencyMap.find(mpVal+idx);
237 if (neighborItr != frequencyMap.end() && 5 * neighborItr->second > mpCount)
239 meanSum += neighborItr->first * neighborItr->second;
240 meanCnt += neighborItr->second;
244 mean = 0.25 * T(meanSum) / T(meanCnt);
247 typename std::vector<T> locWaveform = waveform;
249 std::transform(locWaveform.begin(), locWaveform.end(), locWaveform.begin(),std::bind(std::minus<T>(),std::placeholders::_1,mean));
252 std::sort(locWaveform.begin(), locWaveform.end(),[](
const auto&
left,
const auto&
right){
return std::fabs(
left) < std::fabs(
right);});
255 rmsFull = std::inner_product(locWaveform.begin(), locWaveform.end(), locWaveform.begin(), 0.);
256 rmsFull = std::sqrt(std::max(T(0.),rmsFull / T(locWaveform.size())));
259 rmsTrunc = std::inner_product(locWaveform.begin(), locWaveform.begin() + meanCnt, locWaveform.begin(), 0.);
260 rmsTrunc = std::sqrt(std::max(T(0.),rmsTrunc / T(meanCnt)));
268 firstDerivative<double>(inputVec, derivVec);
275 firstDerivative<float>(inputVec, derivVec);
282 derivVec.resize(inputVec.size(), 0.);
284 for(
size_t idx = 1; idx < derivVec.size() - 1; idx++)
285 derivVec.at(idx) = 0.5 * (inputVec.at(idx + 1) - inputVec.at(idx - 1));
292 findPeaks<double>(startItr, stopItr, peakTupleVec, threshold, firstTick);
299 findPeaks<float>(startItr, stopItr, peakTupleVec, threshold, firstTick);
305 typename std::vector<T>::iterator stopItr,
308 size_t firstTick)
const
314 typename std::vector<T>::iterator firstItr = std::max_element(startItr,stopItr,[](
float left,
float right){
return std::fabs(left) < std::fabs(right);});
317 if (std::fabs(*firstItr) > threshold)
324 typename std::vector<T>::iterator secondItr = firstItr;
329 typename std::vector<T>::iterator tempItr = secondItr;
331 while(tempItr != stopItr)
333 if (*++tempItr < -threshold)
335 if (*tempItr < *secondItr) secondItr = tempItr;
337 else if (secondItr != firstItr)
break;
343 typename std::vector<T>::iterator tempItr = secondItr;
345 while(tempItr != startItr)
347 if (*--tempItr > threshold)
349 if (*tempItr > *secondItr) secondItr = tempItr;
351 else if (secondItr != firstItr)
break;
354 std::swap(firstItr,secondItr);
358 if (firstItr != secondItr)
364 while(firstItr != startItr)
if (*--firstItr < 0.)
break;
365 while(secondItr != stopItr)
if (*++secondItr > 0.)
break;
371 findPeaks(startItr, firstItr, peakTupleVec, threshold, firstTick);
374 peakTupleVec.push_back(
PeakTuple(firstBin+firstTick,peakBin+firstTick,lastBin+firstTick));
387 std::vector<double> inputDoubleVec(inputVec.size());
388 std::vector<double> outputDoubleVec(inputVec.size()/2);
390 std::copy(inputVec.begin(),inputVec.end(),inputDoubleVec.begin());
394 if (outputDoubleVec.size() != outputPowerVec.size()) outputPowerVec.resize(outputDoubleVec.size());
396 std::copy(outputDoubleVec.begin(),outputDoubleVec.end(),outputPowerVec.begin());
404 int fftDataSize = inputVec.size();
406 TVirtualFFT* fftr2c = TVirtualFFT::FFT(1, &fftDataSize,
"R2C");
408 fftr2c->SetPoints(inputVec.data());
412 size_t halfFFTDataSize(fftDataSize/2 + 1);
414 std::vector<double> realVals(halfFFTDataSize);
415 std::vector<double> imaginaryVals(halfFFTDataSize);
417 fftr2c->GetPointsComplex(realVals.data(), imaginaryVals.data());
419 if (outputPowerVec.size() != halfFFTDataSize) outputPowerVec.resize(halfFFTDataSize,0.);
421 std::transform(realVals.begin(), realVals.begin() + halfFFTDataSize, imaginaryVals.begin(), outputPowerVec.begin(), [](
const double& real,
const double& imaginary){
return std::sqrt(real*real + imaginary*imaginary);});
427 int structuringElement,
434 getErosionDilationAverageDifference<short>(waveform, structuringElement, histogramMap, erosionVec, dilationVec, averageVec, differenceVec);
440 int structuringElement,
447 getErosionDilationAverageDifference<float>(waveform, structuringElement, histogramMap, erosionVec, dilationVec, averageVec, differenceVec);
453 int structuringElement,
460 getErosionDilationAverageDifference<double>(waveform, structuringElement, histogramMap, erosionVec, dilationVec, averageVec, differenceVec);
466 int structuringElement,
474 int halfWindowSize(structuringElement/2);
478 std::minmax_element(inputWaveform.begin(),inputWaveform.begin()+halfWindowSize);
484 erosionVec.resize(inputWaveform.size());
485 dilationVec.resize(inputWaveform.size());
486 averageVec.resize(inputWaveform.size());
487 differenceVec.resize(inputWaveform.size());
502 if (
std::distance(inputItr,inputWaveform.end()) > halfWindowSize)
505 minElementItr = std::min_element(inputItr - halfWindowSize + 1, inputItr + halfWindowSize + 1);
506 else if (*(inputItr + halfWindowSize) < *minElementItr)
507 minElementItr = inputItr + halfWindowSize;
510 maxElementItr = std::max_element(inputItr - halfWindowSize + 1, inputItr + halfWindowSize + 1);
511 else if (*(inputItr + halfWindowSize) > *maxElementItr)
512 maxElementItr = inputItr + halfWindowSize;
516 *minItr++ = *minElementItr;
517 *maxItr++ = *maxElementItr;
518 *aveItr++ = 0.5 * (*maxElementItr + *minElementItr);
519 *difItr++ = *maxElementItr - *minElementItr;
521 if (!histogramMap.empty())
525 histogramMap.at(
WAVEFORM)->Fill( curBin, *inputItr);
526 histogramMap.at(
EROSION)->Fill( curBin, *minElementItr);
527 histogramMap.at(
DILATION)->Fill( curBin, *maxElementItr);
528 histogramMap.at(
AVERAGE)->Fill( curBin, 0.5*(*maxElementItr + *minElementItr));
529 histogramMap.at(
DIFFERENCE)->Fill( curBin, *maxElementItr - *minElementItr);
539 int structuringElement,
544 getOpeningAndClosing<short>(erosionVec, dilationVec, structuringElement, histogramMap, openingVec, closingVec);
551 int structuringElement,
556 getOpeningAndClosing<float>(erosionVec, dilationVec, structuringElement, histogramMap, openingVec, closingVec);
563 int structuringElement,
568 getOpeningAndClosing<double>(erosionVec, dilationVec, structuringElement, histogramMap, openingVec, closingVec);
575 int structuringElement,
581 int halfWindowSize(structuringElement/2);
587 openingVec.resize(erosionVec.size());
599 if (
std::distance(inputItr,erosionVec.end()) > halfWindowSize)
602 maxElementItr = std::max_element(inputItr - halfWindowSize + 1, inputItr + halfWindowSize + 1);
603 else if (*(inputItr + halfWindowSize) > *maxElementItr)
604 maxElementItr = inputItr + halfWindowSize;
608 *maxItr++ = *maxElementItr;
610 if (!histogramMap.empty())
614 histogramMap.at(
OPENING)->Fill(curBin, *maxElementItr);
622 closingVec.resize(dilationVec.size());
634 if (
std::distance(inputItr,dilationVec.end()) > halfWindowSize)
637 minElementItr = std::min_element(inputItr - halfWindowSize + 1, inputItr + halfWindowSize + 1);
638 else if (*(inputItr + halfWindowSize) < *minElementItr)
639 minElementItr = inputItr + halfWindowSize;
643 *minItr++ = *minElementItr;
645 if (!histogramMap.empty())
649 histogramMap.at(
CLOSING)->Fill(curBin, *minElementItr);
650 histogramMap.at(
DOPENCLOSING)->Fill(curBin, *minElementItr - openingVec.at(curBin));
double distance(geo::Point_t const &point, CathodeDesc_t const &cathode)
Returns the distance of a point from the cathode.
double mean(const std::vector< short > &wf, size_t start, size_t nsample)