11 #include "TVirtualFFT.h" 28 void triangleSmooth(
const std::vector<float>&, std::vector<float>&,
size_t = 0)
const override;
29 void triangleSmooth(
const std::vector<double>&, std::vector<double>&,
size_t = 0)
const override;
30 void medianSmooth(
const std::vector<float>&, std::vector<float>&,
size_t = 3)
const override;
31 void medianSmooth(
const std::vector<double>&, std::vector<double>&,
size_t = 3)
const override;
32 void getTruncatedMeanRMS(
const std::vector<double>&,
double&,
double&,
double&,
int&)
const override;
33 void getTruncatedMeanRMS(
const std::vector<float>&,
float&,
float&,
float&,
int&)
const override;
34 void firstDerivative(
const std::vector<float>&, std::vector<float>&)
const override;
35 void firstDerivative(
const std::vector<double>&, std::vector<double>&)
const override;
38 void getFFTPower(
const std::vector<float>& inputVec, std::vector<float>& outputPowerVec)
const override;
39 void getFFTPower(
const std::vector<double>& inputVec, std::vector<double>& outputPowerVec)
const override;
68 template <
typename T>
void triangleSmooth(
const std::vector<T>&, std::vector<T>&,
size_t = 0)
const;
69 template <
typename T>
void medianSmooth(
const std::vector<T>&, std::vector<T>&,
size_t = 3)
const;
71 template <
typename T>
void firstDerivative(
const std::vector<T>&, std::vector<T>&)
const;
102 triangleSmooth<double>(inputVec, smoothVec, lowestBin);
109 triangleSmooth<float>(inputVec, smoothVec, lowestBin);
116 if (inputVec.size() != smoothVec.size()) smoothVec.resize(inputVec.size());
119 if (inputVec.size() > 4)
121 std::copy(inputVec.begin(), inputVec.begin() + 2 + lowestBin, smoothVec.begin());
122 std::copy(inputVec.end() - 2, inputVec.end(), smoothVec.end() - 2);
128 while(curInItr++ != stopInItr)
131 T newVal = (*(curInItr - 2) + 2. * *(curInItr - 1) + 3. * *curInItr + 2. * *(curInItr + 1) + *(curInItr + 2)) / 9.;
136 else std::copy(inputVec.begin(), inputVec.end(), smoothVec.begin());
143 medianSmooth<float>(inputVec, smoothVec,
nBins);
150 medianSmooth<double>(inputVec, smoothVec,
nBins);
158 if (nBins % 2 == 0) nBins++;
161 if (inputVec.size() != smoothVec.size()) smoothVec.resize(inputVec.size());
164 typename std::vector<T> medianVec(nBins);
168 std::advance(stopItr, inputVec.size() -
nBins);
170 size_t medianBin = nBins/2;
171 size_t smoothBin = medianBin;
174 std::copy(startItr, startItr + medianBin, smoothVec.begin());
178 std::copy(startItr,startItr+nBins,medianVec.begin());
179 std::sort(medianVec.begin(),medianVec.end());
181 T medianVal = medianVec[medianBin];
183 smoothVec[smoothBin++] = medianVal;
189 std::copy(startItr + medianBin, inputVec.end(), smoothVec.begin() + smoothBin);
196 getTruncatedMeanRMS<double>(waveform,
mean, rmsFull, rmsTrunc, nTrunc);
201 getTruncatedMeanRMS<float>(waveform,
mean, rmsFull, rmsTrunc, nTrunc);
210 std::map<int,int> frequencyMap;
214 for(
const auto&
val : waveform)
216 int intVal = std::round(4.*
val);
218 frequencyMap[intVal]++;
220 if (frequencyMap.at(intVal) > mpCount)
222 mpCount = frequencyMap.at(intVal);
230 int binRange =
std::min(16,
int(frequencyMap.size()/2 + 1));
232 for(
int idx = -binRange; idx <= binRange; idx++)
236 if (neighborItr != frequencyMap.end() && 5 * neighborItr->second > mpCount)
238 meanSum += neighborItr->first * neighborItr->second;
239 meanCnt += neighborItr->second;
243 mean = 0.25 *
T(meanSum) /
T(meanCnt);
246 typename std::vector<T> locWaveform = waveform;
248 std::transform(locWaveform.begin(), locWaveform.end(), locWaveform.begin(),std::bind(std::minus<T>(),std::placeholders::_1,mean));
251 std::sort(locWaveform.begin(), locWaveform.end(),[](
const auto&
left,
const auto&
right){
return std::fabs(
left) < std::fabs(
right);});
254 rmsFull = std::inner_product(locWaveform.begin(), locWaveform.end(), locWaveform.begin(), 0.);
255 rmsFull = std::sqrt(
std::max(
T(0.),rmsFull /
T(locWaveform.size())));
258 rmsTrunc = std::inner_product(locWaveform.begin(), locWaveform.begin() + meanCnt, locWaveform.begin(), 0.);
259 rmsTrunc = std::sqrt(
std::max(
T(0.),rmsTrunc /
T(meanCnt)));
267 firstDerivative<double>(inputVec, derivVec);
274 firstDerivative<float>(inputVec, derivVec);
281 derivVec.resize(inputVec.size(), 0.);
283 for(
size_t idx = 1; idx < derivVec.size() - 1; idx++)
284 derivVec.at(idx) = 0.5 * (inputVec.at(idx + 1) - inputVec.at(idx - 1));
291 findPeaks<double>(startItr, stopItr, peakTupleVec, threshold, firstTick);
298 findPeaks<float>(startItr, stopItr, peakTupleVec, threshold, firstTick);
307 size_t firstTick)
const 316 if (std::fabs(*firstItr) > threshold)
330 while(tempItr != stopItr)
332 if (*++tempItr < -threshold)
334 if (*tempItr < *secondItr) secondItr = tempItr;
336 else if (secondItr != firstItr)
break;
344 while(tempItr != startItr)
346 if (*--tempItr > threshold)
348 if (*tempItr > *secondItr) secondItr = tempItr;
350 else if (secondItr != firstItr)
break;
357 if (firstItr != secondItr)
363 while(firstItr != startItr)
if (*--firstItr < 0.)
break;
364 while(secondItr != stopItr)
if (*++secondItr > 0.)
break;
370 findPeaks(startItr, firstItr, peakTupleVec, threshold, firstTick);
373 peakTupleVec.push_back(
PeakTuple(firstBin+firstTick,peakBin+firstTick,lastBin+firstTick));
386 std::vector<double> inputDoubleVec(inputVec.size());
387 std::vector<double> outputDoubleVec(inputVec.size()/2);
389 std::copy(inputVec.begin(),inputVec.end(),inputDoubleVec.begin());
393 if (outputDoubleVec.size() != outputPowerVec.size()) outputPowerVec.resize(outputDoubleVec.size());
395 std::copy(outputDoubleVec.begin(),outputDoubleVec.end(),outputPowerVec.begin());
403 int fftDataSize = inputVec.size();
405 TVirtualFFT* fftr2c = TVirtualFFT::FFT(1, &fftDataSize,
"R2C");
407 fftr2c->SetPoints(inputVec.data());
411 size_t halfFFTDataSize(fftDataSize/2 + 1);
413 std::vector<double> realVals(halfFFTDataSize);
414 std::vector<double> imaginaryVals(halfFFTDataSize);
416 fftr2c->GetPointsComplex(realVals.data(), imaginaryVals.data());
418 if (outputPowerVec.size() != halfFFTDataSize) outputPowerVec.resize(halfFFTDataSize,0.);
420 std::transform(realVals.begin(), realVals.begin() + halfFFTDataSize, imaginaryVals.begin(), outputPowerVec.begin(), [](
const double& real,
const double& imaginary){
return std::sqrt(real*real + imaginary*imaginary);});
426 int structuringElement,
433 getErosionDilationAverageDifference<short>(waveform, structuringElement, histogramMap, erosionVec, dilationVec, averageVec, differenceVec);
439 int structuringElement,
446 getErosionDilationAverageDifference<float>(waveform, structuringElement, histogramMap, erosionVec, dilationVec, averageVec, differenceVec);
452 int structuringElement,
459 getErosionDilationAverageDifference<double>(waveform, structuringElement, histogramMap, erosionVec, dilationVec, averageVec, differenceVec);
465 int structuringElement,
473 int halfWindowSize(structuringElement/2);
477 std::minmax_element(inputWaveform.begin(),inputWaveform.begin()+halfWindowSize);
483 erosionVec.resize(inputWaveform.size());
484 dilationVec.resize(inputWaveform.size());
485 averageVec.resize(inputWaveform.size());
486 differenceVec.resize(inputWaveform.size());
501 if (
std::distance(inputItr,inputWaveform.end()) > halfWindowSize)
504 minElementItr = std::min_element(inputItr - halfWindowSize + 1, inputItr + halfWindowSize + 1);
505 else if (*(inputItr + halfWindowSize) < *minElementItr)
506 minElementItr = inputItr + halfWindowSize;
509 maxElementItr = std::max_element(inputItr - halfWindowSize + 1, inputItr + halfWindowSize + 1);
510 else if (*(inputItr + halfWindowSize) > *maxElementItr)
511 maxElementItr = inputItr + halfWindowSize;
515 *minItr++ = *minElementItr;
516 *maxItr++ = *maxElementItr;
517 *aveItr++ = 0.5 * (*maxElementItr + *minElementItr);
518 *difItr++ = *maxElementItr - *minElementItr;
520 if (!histogramMap.empty())
524 histogramMap.at(
WAVEFORM)->Fill( curBin, *inputItr);
525 histogramMap.at(
EROSION)->Fill( curBin, *minElementItr);
526 histogramMap.at(
DILATION)->Fill( curBin, *maxElementItr);
527 histogramMap.at(
AVERAGE)->Fill( curBin, 0.5*(*maxElementItr + *minElementItr));
528 histogramMap.at(
DIFFERENCE)->Fill( curBin, *maxElementItr - *minElementItr);
538 int structuringElement,
543 getOpeningAndClosing<short>(erosionVec, dilationVec, structuringElement, histogramMap, openingVec, closingVec);
550 int structuringElement,
555 getOpeningAndClosing<float>(erosionVec, dilationVec, structuringElement, histogramMap, openingVec, closingVec);
562 int structuringElement,
567 getOpeningAndClosing<double>(erosionVec, dilationVec, structuringElement, histogramMap, openingVec, closingVec);
574 int structuringElement,
580 int halfWindowSize(structuringElement/2);
586 openingVec.resize(erosionVec.size());
598 if (
std::distance(inputItr,erosionVec.end()) > halfWindowSize)
601 maxElementItr = std::max_element(inputItr - halfWindowSize + 1, inputItr + halfWindowSize + 1);
602 else if (*(inputItr + halfWindowSize) > *maxElementItr)
603 maxElementItr = inputItr + halfWindowSize;
607 *maxItr++ = *maxElementItr;
609 if (!histogramMap.empty())
613 histogramMap.at(
OPENING)->Fill(curBin, *maxElementItr);
621 closingVec.resize(dilationVec.size());
633 if (
std::distance(inputItr,dilationVec.end()) > halfWindowSize)
636 minElementItr = std::min_element(inputItr - halfWindowSize + 1, inputItr + halfWindowSize + 1);
637 else if (*(inputItr + halfWindowSize) < *minElementItr)
638 minElementItr = inputItr + halfWindowSize;
642 *minItr++ = *minElementItr;
644 if (!histogramMap.empty())
648 histogramMap.at(
CLOSING)->Fill(curBin, *minElementItr);
649 histogramMap.at(
DOPENCLOSING)->Fill(curBin, *minElementItr - openingVec.at(curBin));
void swap(Handle< T > &a, Handle< T > &b)
double distance(double x1, double y1, double z1, double x2, double y2, double z2)
static int max(int a, int b)
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
double mean(sqlite3 *db, std::string const &table_name, std::string const &column_name)