8 #include "art/Framework/Core/ModuleMacros.h"
9 #include "messagefacility/MessageLogger/MessageLogger.h"
17 #include "TVirtualFFT.h"
33 mf::LogInfo(
"RawDigitCorrelatedCorrectionAlg") <<
"RawDigitCorrelatedCorrectionAlg configured\n";
54 fFFTHistsWireGroup = pset.get<std::vector<size_t>>(
"FFTHistsWireGroup", std::vector<size_t>() = {1, 33, 34});
55 fFFTNumHists = pset.get<std::vector<size_t>>(
"FFTNumWaveHistograms", std::vector<size_t>() = {10,48,48});
56 fFFTHistsStartTick = pset.get<std::vector<double>>(
"FFTWaveHistsStartTick", std::vector<double>() = {96.,96.,7670.});
57 fFFTMinPowerThreshold = pset.get<std::vector<double>>(
"FFTPowerThreshold", std::vector<double>() = {100.,75.,500.});
58 fNumWiresToGroup = pset.get<std::vector<size_t>>(
"NumWiresToGroup", std::vector<size_t>() = {48, 48, 96});
61 fNumRmsToSmoothVec = pset.get<std::vector<float>> (
"NumRmsToSmooth", std::vector<float>() = {3.6, 3.6, 4.});
74 std::vector<float> localCorValVec = corValVec;
76 std::sort(localCorValVec.begin(),localCorValVec.end());
79 float corValSum = std::accumulate(localCorValVec.begin(),localCorValVec.begin() + nTruncVal,0.);
80 float meanCorVal = corValSum / float(nTruncVal);
82 std::vector<float> diffVec(nTruncVal);
83 std::transform(localCorValVec.begin(),localCorValVec.begin() + nTruncVal, diffVec.begin(), std::bind(std::minus<float>(),std::placeholders::_1,meanCorVal));
85 float rmsValSq = std::inner_product(diffVec.begin(),diffVec.end(),diffVec.begin(),0.);
86 float rmsVal = std::sqrt(rmsValSq /
float(nTruncVal));
89 std::vector<float>::iterator lastGoodItr = corValVec.begin();
91 bool wasOutlier(
false);
93 for(std::vector<float>::iterator corValItr = lastGoodItr+1; corValItr != corValVec.end(); corValItr++)
99 float lastVal = *lastGoodItr;
100 float curVal = *corValItr;
102 float slope = (curVal - lastVal) / numTicks;
104 while(lastGoodItr != corValItr)
106 *lastGoodItr++ = (numTicks -
std::distance(lastGoodItr,corValItr)) * slope + lastVal;
111 lastGoodItr = corValItr;
113 else wasOutlier =
true;
120 unsigned int planeIdx,
121 std::vector<float>& truncMeanWireVec,
122 std::vector<float>& truncRmsWireVec,
123 std::vector<short>& minMaxWireVec,
124 std::vector<short>& meanWireVec,
125 std::vector<float>& skewnessWireVec,
126 std::vector<float>& neighborRatioWireVec,
127 std::vector<float>& pedCorWireVec,
128 unsigned int& fftSize,
unsigned int& halfFFTSize,
129 void* fplan,
void* rplan)
const
137 size_t maxTimeSamples(wireToRawDigitVecMap.begin()->second.size());
138 size_t baseWireIdx(wireToRawDigitVecMap.begin()->first - wireToRawDigitVecMap.begin()->first %
fNumWiresToGroup[planeIdx]);
140 std::vector<float> corValVec(maxTimeSamples);
144 if (wireToAdcIdxMap.size() > 2)
147 std::fill(corValVec.begin(),corValVec.end(),0.);
150 for(
size_t sampleIdx = 0; sampleIdx < maxTimeSamples; sampleIdx++)
155 std::vector<float> adcValuesVec;
157 for(
const auto& wireAdcItr : wireToAdcIdxMap)
161 if (sampleIdx < wireAdcItr.second.first || sampleIdx >= wireAdcItr.second.second)
continue;
163 int wireIdx(wireAdcItr.first - baseWireIdx);
166 adcValuesVec.push_back(
float(wireToRawDigitVecMap.at(wireAdcItr.first)[sampleIdx]) - truncMeanWireVec[wireIdx]);
170 float aveValue = std::accumulate(adcValuesVec.begin(),adcValuesVec.end(),0.) / float(adcValuesVec.size());
173 corValVec[sampleIdx] = aveValue;
181 std::vector<std::complex<double>> fftOutputVec(halfFFTSize);
183 lfftw.
DoFFT(corValVec, fftOutputVec);
185 std::vector<double> powerVec(halfFFTSize);
186 std::transform(fftOutputVec.begin(), fftOutputVec.begin() + halfFFTSize, powerVec.begin(), [](
const auto& val){
return std::abs(val);});
189 std::vector<double> firstDerivVec(powerVec.size(), 0.);
192 for(
size_t idx = 1; idx < firstDerivVec.size() - 1; idx++)
193 firstDerivVec.at(idx) = 0.5 * (powerVec.at(idx + 1) - powerVec.at(idx - 1));
196 std::vector<std::tuple<size_t,size_t,size_t>> peakTupleVec;
200 if (!peakTupleVec.empty())
202 for(
const auto& peakTuple : peakTupleVec)
204 size_t startTick = std::get<0>(peakTuple);
205 size_t stopTick = std::get<2>(peakTuple);
207 if (stopTick > startTick)
209 std::complex<double> slope = (fftOutputVec[stopTick] - fftOutputVec[startTick]) /
double(stopTick - startTick);
213 std::complex<double> interpVal = fftOutputVec[startTick] + double(
tick - startTick) * slope;
215 fftOutputVec[
tick] = interpVal;
221 std::vector<double> tmpVec(corValVec.size());
223 lfftw.
DoInvFFT(fftOutputVec, tmpVec);
225 std::transform(corValVec.begin(),corValVec.end(),tmpVec.begin(),corValVec.begin(),std::minus<double>());
230 for(
size_t sampleIdx = 0; sampleIdx < maxTimeSamples; sampleIdx++)
233 for (
const auto& wireAdcItr : wireToAdcIdxMap)
235 float corVal(corValVec[sampleIdx]);
236 int wireIdx(wireAdcItr.first - baseWireIdx);
241 if (sampleIdx < wireAdcItr.second.first || sampleIdx >= wireAdcItr.second.second)
245 short& rawDataTimeVal = wireToRawDigitVecMap.at(wireAdcItr.first)[sampleIdx];
248 float newAdcValueFloat = float(rawDataTimeVal) - corVal - pedCorWireVec[wireIdx];
249 rawDataTimeVal = std::round(newAdcValueFloat);
258 T medianValue(defaultValue);
260 if (!valuesVec.empty())
262 std::sort(valuesVec.begin(),valuesVec.end());
264 size_t medianIdx = valuesVec.size() / 2;
266 medianValue = valuesVec[medianIdx];
268 if (valuesVec.size() > 1 && medianIdx % 2) medianValue = (medianValue + valuesVec[medianIdx+1]) / 2;
271 return std::max(medianValue,defaultValue);
275 typename std::vector<T>::iterator stopItr,
276 std::vector<std::tuple<size_t,size_t,size_t>>& peakTupleVec,
278 size_t firstTick)
const
284 typename std::vector<T>::iterator firstItr = std::max_element(startItr,stopItr,[](
float left,
float right){
return std::fabs(left) < std::fabs(right);});
287 if (std::fabs(*firstItr) > threshold)
294 typename std::vector<T>::iterator secondItr = firstItr;
299 typename std::vector<T>::iterator tempItr = secondItr;
301 while(tempItr != stopItr)
303 if (*++tempItr < -threshold)
305 if (*tempItr < *secondItr) secondItr = tempItr;
307 else if (secondItr != firstItr)
break;
313 typename std::vector<T>::iterator tempItr = secondItr;
315 while(tempItr != startItr)
317 if (*--tempItr > threshold)
319 if (*tempItr > *secondItr) secondItr = tempItr;
321 else if (secondItr != firstItr)
break;
324 std::swap(firstItr,secondItr);
328 if (firstItr != secondItr)
334 while(firstItr != startItr)
if (*--firstItr < 0.)
break;
335 while(secondItr != stopItr)
if (*++secondItr > 0.)
break;
341 findPeaks(startItr, firstItr, peakTupleVec, threshold, firstTick);
344 peakTupleVec.push_back(std::tuple<size_t,size_t,size_t>(firstBin+firstTick,peakBin+firstTick,lastBin+firstTick));
std::pair< WireToRawDigitVecMap, WireToAdcIdxMap > RawDigitAdcIdxPair
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
double distance(geo::Point_t const &point, CathodeDesc_t const &cathode)
Returns the distance of a point from the cathode.
tick_as<> tick
Tick number, represented by std::ptrdiff_t.
void fill(const art::PtrVector< recob::Hit > &hits, int only_plane)
art::ServiceHandle< art::TFileService > tfs
void DoInvFFT(std::vector< T > &output)
std::map< size_t, RawDigitVector & > WireToRawDigitVecMap
void DoFFT(std::vector< T > &input)
process_name can override from command line with o or output caldata
std::map< size_t, RawDigitVectorIdxPair > WireToAdcIdxMap