All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Public Member Functions | Private Member Functions | Private Attributes | List of all members
caldata::RawDigitCorrelatedCorrectionAlg Class Reference

#include <RawDigitCorrelatedCorrectionAlg.h>

Public Member Functions

 RawDigitCorrelatedCorrectionAlg (fhicl::ParameterSet const &pset)
 
 ~RawDigitCorrelatedCorrectionAlg ()
 Destructor. More...
 
void reconfigure (fhicl::ParameterSet const &pset)
 
void initializeHists (art::ServiceHandle< art::TFileService > &)
 Begin job method. More...
 
void removeCorrelatedNoise (RawDigitAdcIdxPair &digitIdxPair, unsigned int viewIdx, std::vector< float > &truncMeanWireVec, std::vector< float > &truncRmsWireVec, std::vector< short > &minMaxWireVec, std::vector< short > &meanWireVec, std::vector< float > &skewnessWireVec, std::vector< float > &neighborRatioWireVec, std::vector< float > &pedCorWireVec, unsigned int &fftSize, unsigned int &halfFFTSize, void *fplan, void *rplan) const
 

Private Member Functions

void smoothCorrectionVec (std::vector< float > &, unsigned int &) const
 
template<class T >
getMedian (std::vector< T > &, T) const
 
template<typename T >
void findPeaks (typename std::vector< T >::iterator startItr, typename std::vector< T >::iterator stopItr, std::vector< std::tuple< size_t, size_t, size_t >> &peakTupleVec, T threshold, size_t firstTick) const
 

Private Attributes

float fTruncMeanFraction
 Fraction for truncated mean. More...
 
bool fApplyCorSmoothing
 Attempt to smooth the correlated noise correction? More...
 
bool fApplyFFTCorrection
 Use an FFT to get the correlated noise correction. More...
 
bool fFillFFTHistograms
 Fill associated FFT histograms. More...
 
std::vector< size_t > fFFTHistsWireGroup
 Wire Group to pick on. More...
 
std::vector< size_t > fFFTNumHists
 Number of hists total per view. More...
 
std::vector< double > fFFTHistsStartTick
 Starting tick for histograms. More...
 
std::vector< double > fFFTMinPowerThreshold
 Threshold for trimming FFT power spectrum. More...
 
std::vector< size_t > fNumWiresToGroup
 If smoothing, the number of wires to look at. More...
 
bool fFillHistograms
 if true then will fill diagnostic hists More...
 
bool fRunFFTCorrected
 Should we run FFT's on corrected wires? More...
 
std::vector< float > fNumRmsToSmoothVec
 

"sigma" to smooth correlated correction vec

More...
 
std::vector< std::set< size_t > > fBadWiresbyViewAndWire
 
art::ServiceHandle< geo::GeometryfGeometry
 pointer to Geometry service More...
 

Detailed Description

Definition at line 46 of file RawDigitCorrelatedCorrectionAlg.h.

Constructor & Destructor Documentation

caldata::RawDigitCorrelatedCorrectionAlg::RawDigitCorrelatedCorrectionAlg ( fhicl::ParameterSet const &  pset)

Constructor.

Arguments:

pset - Fcl parameters.

Definition at line 28 of file RawDigitCorrelatedCorrectionAlg.cc.

29 {
30  reconfigure(pset);
31 
32  // Report.
33  mf::LogInfo("RawDigitCorrelatedCorrectionAlg") << "RawDigitCorrelatedCorrectionAlg configured\n";
34 }
void reconfigure(fhicl::ParameterSet const &pset)
caldata::RawDigitCorrelatedCorrectionAlg::~RawDigitCorrelatedCorrectionAlg ( )

Destructor.

Definition at line 38 of file RawDigitCorrelatedCorrectionAlg.cc.

39 {}

Member Function Documentation

template<typename T >
void caldata::RawDigitCorrelatedCorrectionAlg::findPeaks ( typename std::vector< T >::iterator  startItr,
typename std::vector< T >::iterator  stopItr,
std::vector< std::tuple< size_t, size_t, size_t >> &  peakTupleVec,
threshold,
size_t  firstTick 
) const
private

Definition at line 274 of file RawDigitCorrelatedCorrectionAlg.cc.

279 {
280  // Need a minimum distance or else nothing to do
281  if (std::distance(startItr,stopItr) > 4)
282  {
283  // This is a divide and conquer algorithm, start by finding the maximum element.
284  typename std::vector<T>::iterator firstItr = std::max_element(startItr,stopItr,[](float left, float right){return std::fabs(left) < std::fabs(right);});
285 
286  // Are we over threshold?
287  if (std::fabs(*firstItr) > threshold)
288  {
289  // What am I thinking?
290  // First task is to find the "other" lobe max point
291  // Set one to the "first", the other to the "second"
292  // Search backward from first to find start point, forward from second to find end point
293  // Set mid point between first and second as "peak"?
294  typename std::vector<T>::iterator secondItr = firstItr;
295 
296  // Assume if max bin is positive then second lobe is later
297  if (*firstItr > 0)
298  {
299  typename std::vector<T>::iterator tempItr = secondItr;
300 
301  while(tempItr != stopItr)
302  {
303  if (*++tempItr < -threshold)
304  {
305  if (*tempItr < *secondItr) secondItr = tempItr;
306  }
307  else if (secondItr != firstItr) break;
308  }
309  }
310  // Otherwise it goes the other way
311  else
312  {
313  typename std::vector<T>::iterator tempItr = secondItr;
314 
315  while(tempItr != startItr)
316  {
317  if (*--tempItr > threshold)
318  {
319  if (*tempItr > *secondItr) secondItr = tempItr;
320  }
321  else if (secondItr != firstItr) break;
322  }
323 
324  std::swap(firstItr,secondItr);
325  }
326 
327  // It might that no real pulse was found
328  if (firstItr != secondItr)
329  {
330  // Get the "peak" position
331  size_t peakBin = std::distance(startItr,firstItr) + std::distance(firstItr,secondItr) / 2;
332 
333  // Advance (forward or backward) the first and second iterators to get back to zero crossing
334  while(firstItr != startItr) if (*--firstItr < 0.) break;
335  while(secondItr != stopItr) if (*++secondItr > 0.) break;
336 
337  size_t firstBin = std::distance(startItr,firstItr);
338  size_t lastBin = std::distance(startItr,secondItr);
339 
340  // Find leading peaks
341  findPeaks(startItr, firstItr, peakTupleVec, threshold, firstTick);
342 
343  // Save this peak
344  peakTupleVec.push_back(std::tuple<size_t,size_t,size_t>(firstBin+firstTick,peakBin+firstTick,lastBin+firstTick));
345 
346  // Find downstream peaks
347  findPeaks(secondItr, stopItr, peakTupleVec, threshold, firstTick + std::distance(startItr,secondItr));
348  }
349  }
350  }
351 
352  return;
353 }
walls no right
Definition: selectors.fcl:105
void findPeaks(typename std::vector< T >::iterator startItr, typename std::vector< T >::iterator stopItr, std::vector< std::tuple< size_t, size_t, size_t >> &peakTupleVec, T threshold, size_t firstTick) const
double distance(geo::Point_t const &point, CathodeDesc_t const &cathode)
Returns the distance of a point from the cathode.
walls no left
Definition: selectors.fcl:105
template<class T >
T caldata::RawDigitCorrelatedCorrectionAlg::getMedian ( std::vector< T > &  valuesVec,
defaultValue 
) const
private

Definition at line 256 of file RawDigitCorrelatedCorrectionAlg.cc.

257 {
258  T medianValue(defaultValue);
259 
260  if (!valuesVec.empty())
261  {
262  std::sort(valuesVec.begin(),valuesVec.end());
263 
264  size_t medianIdx = valuesVec.size() / 2;
265 
266  medianValue = valuesVec[medianIdx];
267 
268  if (valuesVec.size() > 1 && medianIdx % 2) medianValue = (medianValue + valuesVec[medianIdx+1]) / 2;
269  }
270 
271  return std::max(medianValue,defaultValue);
272 }
void caldata::RawDigitCorrelatedCorrectionAlg::initializeHists ( art::ServiceHandle< art::TFileService > &  tfs)

Begin job method.

Definition at line 66 of file RawDigitCorrelatedCorrectionAlg.cc.

67 {
68 }
void caldata::RawDigitCorrelatedCorrectionAlg::reconfigure ( fhicl::ParameterSet const &  pset)

Reconfigure method.

Arguments:

pset - Fcl parameter set.

Definition at line 48 of file RawDigitCorrelatedCorrectionAlg.cc.

49 {
50  fTruncMeanFraction = pset.get<float> ("TruncMeanFraction", 0.15);
51  fApplyCorSmoothing = pset.get<bool> ("ApplyCorSmoothing", true);
52  fApplyFFTCorrection = pset.get<bool> ("ApplyFFTCorrection", true);
53  fFillFFTHistograms = pset.get<bool> ("FillFFTHistograms", false);
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});
59  fFillHistograms = pset.get<bool> ("FillHistograms", false);
60  fRunFFTCorrected = pset.get<bool> ("RunFFTCorrectedWires", false);
61  fNumRmsToSmoothVec = pset.get<std::vector<float>> ("NumRmsToSmooth", std::vector<float>() = {3.6, 3.6, 4.});
62 }
bool fApplyFFTCorrection
Use an FFT to get the correlated noise correction.
std::vector< double > fFFTHistsStartTick
Starting tick for histograms.
bool fFillFFTHistograms
Fill associated FFT histograms.
bool fApplyCorSmoothing
Attempt to smooth the correlated noise correction?
std::vector< size_t > fFFTHistsWireGroup
Wire Group to pick on.
float fTruncMeanFraction
Fraction for truncated mean.
bool fFillHistograms
if true then will fill diagnostic hists
bool fRunFFTCorrected
Should we run FFT&#39;s on corrected wires?
std::vector< size_t > fFFTNumHists
Number of hists total per view.
std::vector< size_t > fNumWiresToGroup
If smoothing, the number of wires to look at.
std::vector< float > fNumRmsToSmoothVec
&quot;sigma&quot; to smooth correlated correction vec
std::vector< double > fFFTMinPowerThreshold
Threshold for trimming FFT power spectrum.
void caldata::RawDigitCorrelatedCorrectionAlg::removeCorrelatedNoise ( RawDigitAdcIdxPair digitIdxPair,
unsigned int  viewIdx,
std::vector< float > &  truncMeanWireVec,
std::vector< float > &  truncRmsWireVec,
std::vector< short > &  minMaxWireVec,
std::vector< short > &  meanWireVec,
std::vector< float > &  skewnessWireVec,
std::vector< float > &  neighborRatioWireVec,
std::vector< float > &  pedCorWireVec,
unsigned int &  fftSize,
unsigned int &  halfFFTSize,
void *  fplan,
void *  rplan 
) const

Definition at line 119 of file RawDigitCorrelatedCorrectionAlg.cc.

130 {
131  // This method represents and enhanced implementation of "Corey's Algorithm" for correcting the
132  // correlated noise across a group of wires. The primary enhancement involves using a FFT to
133  // "fit" for the underlying noise as a way to reduce the impact on the signal.
134  WireToRawDigitVecMap& wireToRawDigitVecMap = digitIdxPair.first;
135  WireToAdcIdxMap& wireToAdcIdxMap = digitIdxPair.second;
136 
137  size_t maxTimeSamples(wireToRawDigitVecMap.begin()->second.size());
138  size_t baseWireIdx(wireToRawDigitVecMap.begin()->first - wireToRawDigitVecMap.begin()->first % fNumWiresToGroup[planeIdx]);
139 
140  std::vector<float> corValVec(maxTimeSamples);
141 
142  // First step is to get the correction values to apply to this set of input waveforms
143  // Don't try to do correction if too few wires unless they have gaps
144  if (wireToAdcIdxMap.size() > 2) // || largestGapSize > 2)
145  {
146  // Zero? This is probably not necessary
147  std::fill(corValVec.begin(),corValVec.end(),0.);
148 
149  // Build the vector of corrections for each time bin
150  for(size_t sampleIdx = 0; sampleIdx < maxTimeSamples; sampleIdx++)
151  {
152  // Define a vector for accumulating values...
153  // Loop over the wires at this time bin and get their pedestal corrected ADC values
154  // We'll use a simple stl vector for this
155  std::vector<float> adcValuesVec;
156 
157  for(const auto& wireAdcItr : wireToAdcIdxMap)
158  {
159  // Check that we should be doing something in this range
160  // Note that if the wire is not to be considered then the "start" bin will be after the last bin
161  if (sampleIdx < wireAdcItr.second.first || sampleIdx >= wireAdcItr.second.second) continue;
162 
163  int wireIdx(wireAdcItr.first - baseWireIdx);
164 
165  // Accumulate
166  adcValuesVec.push_back(float(wireToRawDigitVecMap.at(wireAdcItr.first)[sampleIdx]) - truncMeanWireVec[wireIdx]);
167  }
168 
169 // float medianValue = getMedian(adcValuesVec, float(-10000.));
170  float aveValue = std::accumulate(adcValuesVec.begin(),adcValuesVec.end(),0.) / float(adcValuesVec.size());
171 
172 // corValVec[sampleIdx] = medianValue;
173  corValVec[sampleIdx] = aveValue;
174  }
175 
176  // Try to eliminate any real outliers
177  if (fApplyCorSmoothing) smoothCorrectionVec(corValVec, planeIdx);
178 
179  // Get the FFT correction
180  if (fApplyFFTCorrection) {
181  std::vector<std::complex<double>> fftOutputVec(halfFFTSize);
182  util::LArFFTW lfftw(fftSize, fplan, rplan, 0);
183  lfftw.DoFFT(corValVec, fftOutputVec);
184 
185  std::vector<double> powerVec(halfFFTSize);
186  std::transform(fftOutputVec.begin(), fftOutputVec.begin() + halfFFTSize, powerVec.begin(), [](const auto& val){return std::abs(val);});
187 
188  // Want the first derivative
189  std::vector<double> firstDerivVec(powerVec.size(), 0.);
190 
191  //fWaveformTool->firstDerivative(powerVec, firstDerivVec);
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));
194 
195  // Find the peaks
196  std::vector<std::tuple<size_t,size_t,size_t>> peakTupleVec;
197 
198  findPeaks(firstDerivVec.begin(),firstDerivVec.end(),peakTupleVec,fFFTMinPowerThreshold[planeIdx],0);
199 
200  if (!peakTupleVec.empty())
201  {
202  for(const auto& peakTuple : peakTupleVec)
203  {
204  size_t startTick = std::get<0>(peakTuple);
205  size_t stopTick = std::get<2>(peakTuple);
206 
207  if (stopTick > startTick)
208  {
209  std::complex<double> slope = (fftOutputVec[stopTick] - fftOutputVec[startTick]) / double(stopTick - startTick);
210 
211  for(size_t tick = startTick; tick < stopTick; tick++)
212  {
213  std::complex<double> interpVal = fftOutputVec[startTick] + double(tick - startTick) * slope;
214 
215  fftOutputVec[tick] = interpVal;
216  //fftOutputVec[fftDataSize - tick - 1] = interpVal;
217  }
218  }
219  }
220 
221  std::vector<double> tmpVec(corValVec.size());
222 
223  lfftw.DoInvFFT(fftOutputVec, tmpVec);
224 
225  std::transform(corValVec.begin(),corValVec.end(),tmpVec.begin(),corValVec.begin(),std::minus<double>());
226  }
227  } // fApplyFFTCorrection
228 
229  // Now go through and apply the correction
230  for(size_t sampleIdx = 0; sampleIdx < maxTimeSamples; sampleIdx++)
231  {
232  // Now run through and apply correction
233  for (const auto& wireAdcItr : wireToAdcIdxMap)
234  {
235  float corVal(corValVec[sampleIdx]);
236  int wireIdx(wireAdcItr.first - baseWireIdx);
237 
238  // If the "start" bin is after the "stop" bin then we are meant to skip this wire in the averaging process
239  // Or if the sample index is in a chirping section then no correction is applied.
240  // Both cases are handled by looking at the sampleIdx
241  if (sampleIdx < wireAdcItr.second.first || sampleIdx >= wireAdcItr.second.second)
242  corVal = 0.;
243 
244  //RawDigitVector& rawDataTimeVec = wireToRawDigitVecMap.at(wireIdx);
245  short& rawDataTimeVal = wireToRawDigitVecMap.at(wireAdcItr.first)[sampleIdx];
246 
247  // Probably doesn't matter, but try to get slightly more accuracy by doing float math and rounding
248  float newAdcValueFloat = float(rawDataTimeVal) - corVal - pedCorWireVec[wireIdx];
249  rawDataTimeVal = std::round(newAdcValueFloat);
250  }
251  }
252  }
253  return;
254 }
bool fApplyFFTCorrection
Use an FFT to get the correlated noise correction.
static constexpr Sample_t transform(Sample_t sample)
bool fApplyCorSmoothing
Attempt to smooth the correlated noise correction?
T abs(T value)
void findPeaks(typename std::vector< T >::iterator startItr, typename std::vector< T >::iterator stopItr, std::vector< std::tuple< size_t, size_t, size_t >> &peakTupleVec, T threshold, size_t firstTick) const
void smoothCorrectionVec(std::vector< float > &, unsigned int &) const
tick_as<> tick
Tick number, represented by std::ptrdiff_t.
Definition: electronics.h:75
void fill(const art::PtrVector< recob::Hit > &hits, int only_plane)
std::vector< size_t > fNumWiresToGroup
If smoothing, the number of wires to look at.
std::map< size_t, RawDigitVector & > WireToRawDigitVecMap
std::vector< double > fFFTMinPowerThreshold
Threshold for trimming FFT power spectrum.
std::map< size_t, RawDigitVectorIdxPair > WireToAdcIdxMap
void caldata::RawDigitCorrelatedCorrectionAlg::smoothCorrectionVec ( std::vector< float > &  corValVec,
unsigned int &  viewIdx 
) const
private

Definition at line 70 of file RawDigitCorrelatedCorrectionAlg.cc.

71 {
72  // First get the truncated mean and rms for the input vector (noting that it is not in same format as raw data)
73  // We need a local copy so we can sort it
74  std::vector<float> localCorValVec = corValVec;
75 
76  std::sort(localCorValVec.begin(),localCorValVec.end());
77 
78  int nTruncVal = (1. - fTruncMeanFraction) * localCorValVec.size();
79  float corValSum = std::accumulate(localCorValVec.begin(),localCorValVec.begin() + nTruncVal,0.);
80  float meanCorVal = corValSum / float(nTruncVal);
81 
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));
84 
85  float rmsValSq = std::inner_product(diffVec.begin(),diffVec.end(),diffVec.begin(),0.);
86  float rmsVal = std::sqrt(rmsValSq / float(nTruncVal));
87 
88  // Now set up to run through and do a "simple" interpolation over outliers
89  std::vector<float>::iterator lastGoodItr = corValVec.begin();
90 
91  bool wasOutlier(false);
92 
93  for(std::vector<float>::iterator corValItr = lastGoodItr+1; corValItr != corValVec.end(); corValItr++)
94  {
95  if (fabs(*corValItr - meanCorVal) < fNumRmsToSmoothVec.at(viewIdx)*rmsVal)
96  {
97  if (wasOutlier)
98  {
99  float lastVal = *lastGoodItr;
100  float curVal = *corValItr;
101  float numTicks = std::distance(lastGoodItr,corValItr);
102  float slope = (curVal - lastVal) / numTicks;
103 
104  while(lastGoodItr != corValItr)
105  {
106  *lastGoodItr++ = (numTicks - std::distance(lastGoodItr,corValItr)) * slope + lastVal;
107  }
108  }
109 
110  wasOutlier = false;
111  lastGoodItr = corValItr;
112  }
113  else wasOutlier = true;
114  }
115 
116  return;
117 }
static constexpr Sample_t transform(Sample_t sample)
float fTruncMeanFraction
Fraction for truncated mean.
double distance(geo::Point_t const &point, CathodeDesc_t const &cathode)
Returns the distance of a point from the cathode.
std::vector< float > fNumRmsToSmoothVec
&quot;sigma&quot; to smooth correlated correction vec

Member Data Documentation

bool caldata::RawDigitCorrelatedCorrectionAlg::fApplyCorSmoothing
private

Attempt to smooth the correlated noise correction?

Definition at line 85 of file RawDigitCorrelatedCorrectionAlg.h.

bool caldata::RawDigitCorrelatedCorrectionAlg::fApplyFFTCorrection
private

Use an FFT to get the correlated noise correction.

Definition at line 86 of file RawDigitCorrelatedCorrectionAlg.h.

std::vector<std::set<size_t> > caldata::RawDigitCorrelatedCorrectionAlg::fBadWiresbyViewAndWire
private

Definition at line 97 of file RawDigitCorrelatedCorrectionAlg.h.

std::vector<double> caldata::RawDigitCorrelatedCorrectionAlg::fFFTHistsStartTick
private

Starting tick for histograms.

Definition at line 90 of file RawDigitCorrelatedCorrectionAlg.h.

std::vector<size_t> caldata::RawDigitCorrelatedCorrectionAlg::fFFTHistsWireGroup
private

Wire Group to pick on.

Definition at line 88 of file RawDigitCorrelatedCorrectionAlg.h.

std::vector<double> caldata::RawDigitCorrelatedCorrectionAlg::fFFTMinPowerThreshold
private

Threshold for trimming FFT power spectrum.

Definition at line 91 of file RawDigitCorrelatedCorrectionAlg.h.

std::vector<size_t> caldata::RawDigitCorrelatedCorrectionAlg::fFFTNumHists
private

Number of hists total per view.

Definition at line 89 of file RawDigitCorrelatedCorrectionAlg.h.

bool caldata::RawDigitCorrelatedCorrectionAlg::fFillFFTHistograms
private

Fill associated FFT histograms.

Definition at line 87 of file RawDigitCorrelatedCorrectionAlg.h.

bool caldata::RawDigitCorrelatedCorrectionAlg::fFillHistograms
private

if true then will fill diagnostic hists

Definition at line 93 of file RawDigitCorrelatedCorrectionAlg.h.

art::ServiceHandle<geo::Geometry> caldata::RawDigitCorrelatedCorrectionAlg::fGeometry
private

pointer to Geometry service

Definition at line 100 of file RawDigitCorrelatedCorrectionAlg.h.

std::vector<float> caldata::RawDigitCorrelatedCorrectionAlg::fNumRmsToSmoothVec
private

"sigma" to smooth correlated correction vec

Definition at line 95 of file RawDigitCorrelatedCorrectionAlg.h.

std::vector<size_t> caldata::RawDigitCorrelatedCorrectionAlg::fNumWiresToGroup
private

If smoothing, the number of wires to look at.

Definition at line 92 of file RawDigitCorrelatedCorrectionAlg.h.

bool caldata::RawDigitCorrelatedCorrectionAlg::fRunFFTCorrected
private

Should we run FFT's on corrected wires?

Definition at line 94 of file RawDigitCorrelatedCorrectionAlg.h.

float caldata::RawDigitCorrelatedCorrectionAlg::fTruncMeanFraction
private

Fraction for truncated mean.

Definition at line 83 of file RawDigitCorrelatedCorrectionAlg.h.


The documentation for this class was generated from the following files: