All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
mtRawDigitFilterICARUS_module.cc
Go to the documentation of this file.
1 #include <cmath>
2 #include <algorithm>
3 #include <vector>
4 #include <numeric> // std::accumulate
5 
6 #include "tbb/parallel_for.h"
7 #include "tbb/blocked_range.h"
8 
9 #include "TComplex.h"
10 
11 #include "art/Framework/Core/ReplicatedProducer.h"
12 #include "art/Framework/Principal/Event.h"
13 #include "art/Framework/Services/Registry/ServiceHandle.h"
14 #include "art_root_io/TFileService.h"
15 #include "art/Framework/Core/ModuleMacros.h"
16 #include "art/Utilities/make_tool.h"
17 #include "canvas/Persistency/Common/Ptr.h"
18 #include "messagefacility/MessageLogger/MessageLogger.h"
19 
25 
33 
35 #include "lardataobj/RawData/raw.h"
36 
37 using std::vector;
38 using std::cout;
39 using std::endl;
40 
41 // raw::ChannelID_t channel;
42 struct WireChar {
43  float truncMean;
44  float truncRms;
45  short mean;
46  short median;
47  short mode;
48  float skewness;
49  float fullRms;
50  short minMax;
52  float pedCor;
53  unsigned int tcka;
54  unsigned int tckb;
55  unsigned int plane;
56  unsigned int wire;
57  unsigned int wireIdx;
59  int irawdig;
60 };
61 
63  int group;
64  int windx;
65  int irawdig;
66  int qgroup;
67  unsigned int qgindx;
68 };
69 
70 class RawDigitFilterICARUS : public art::ReplicatedProducer
71 {
72 public:
73 
74  // Copnstructors, destructor.
75  explicit RawDigitFilterICARUS(fhicl::ParameterSet const & pset, art::ProcessingFrame const& frame);
76  virtual ~RawDigitFilterICARUS();
77 
78  // Overrides.
79  virtual void configure(fhicl::ParameterSet const & pset);
80  virtual void produce(art::Event & e, art::ProcessingFrame const& frame);
81  virtual void beginJob(art::ProcessingFrame const& frame);
82  virtual void endJob(art::ProcessingFrame const& frame);
83  void WaveformChar(unsigned int i, unsigned int& fDataSize, unsigned int& fftsize, void* fplan, void* rplan,
84  vector<GroupWireDigIndx>& igwvec,
85  std::vector<const raw::RawDigit*>& rawDigitVec,
86  vector<vector<caldata::RawDigitVector>>& rawadcgvec,
87  vector<vector<WireChar>>& wgcvec,
88  vector<vector<vector <int>>>& wgqvec,
89  std::unique_ptr<std::vector<raw::RawDigit> >& filteredRawDigit)const;
90  void RemoveCorrelatedNoise(unsigned int igrp, unsigned int& fftSize, unsigned int& halfFFTSize, void* fplan, void* rplan,
91  vector<vector<caldata::RawDigitVector>>& rawadcgvec,
92  vector<vector<WireChar>>& wgcvec,
93  vector<vector<vector <int>>>& wgqvec,
94  std::unique_ptr<std::vector<raw::RawDigit> >& filteredRawDigit)const;
95 
96 private:
97 
98  template <typename T> void findPeaks(typename std::vector<T>::iterator startItr,
99  typename std::vector<T>::iterator stopItr,
100  std::vector<std::tuple<size_t,size_t,size_t>>& peakTupleVec,
101  T threshold,
102  size_t firstTick) const;
103 
104  void saveRawDigits(std::unique_ptr<std::vector<raw::RawDigit> >&, raw::ChannelID_t&, caldata::RawDigitVector&, float, float);
105 
106  // Fcl parameters.
107  std::string fDigitModuleLabel; ///< The full collection of hits
108  bool fTruncateTicks; ///< If true then drop ticks off ends of wires
109  bool fTruncateChannels; ///< If true then we drop channels with "no signal"
110  bool fDoFFTCorrection; ///< Run the FFT noise correction
111  bool fSmoothCorrelatedNoise; ///< Should we smooth the noise?
112  bool fDoCorrelatedNoise; ///< Process the noise
113  bool fApplyCorSmoothing; ///< Attempt to smooth the correlated noise correction?
114  bool fApplyFFTCorrection; ///< Use an FFT to get the correlated noise correction
115  bool fApplyTopHatFilter; ///< Apply the top hat filter
116  unsigned int fWindowSize; ///< # ticks to keep in window
117  unsigned int fNumTicksToDropFront; ///< # ticks to drop from front of waveform
118  float fTruncMeanFraction; ///< Fraction for truncated mean
119  std::vector<size_t> fNumWiresToGroup; ///< If smoothing, the number of wires to look at
120  std::vector<short> fMinMaxSelectionCut; ///< Plane by plane cuts for spread cut
121  std::vector<float> fNRmsChannelReject; ///< # rms to reject channel as no signal
122  std::vector<float> fRmsRejectionCutHi; ///< Maximum rms for input channels, reject if larger
123  std::vector<float> fRmsRejectionCutLow; ///< Minimum rms to consider channel "alive"
124  std::vector<float> fNumRmsToSmoothVec; ///< # "sigma" to smooth correlated correction vec
125  std::vector<double> fFFTMinPowerThreshold; ///< Threshold for trimming FFT power spectrum
126 
127  // Statistics.
128  int fNumEvent; ///< Number of events seen.
129 
130  // Correction algorithms
134 
135  std::unique_ptr<caldata::IRawDigitFilter> fRawDigitFilterTool;
136 
137  std::map<size_t,std::vector<std::complex<double>>> fFilterVec;
138  std::map<size_t,std::unique_ptr<icarus_tool::IFilter>> fFilterToolMap;
139 
140  // Useful services, keep copies for now (we can update during begin run periods)
141  geo::GeometryCore const* fGeometry; ///< pointer to Geometry service
142  const lariov::DetPedestalProvider& fPedestalRetrievalAlg; ///< Keep track of an instance to the pedestal retrieval alg
143 
144  // mwang added
146 };
147 
148 DEFINE_ART_MODULE(RawDigitFilterICARUS)
149 
150 //----------------------------------------------------------------------------
152  public:
154  unsigned int & fdatasize,
155  unsigned int & fftsize,
156  void* fplan, void* rplan,
157  vector<GroupWireDigIndx>& igwv,
158  std::vector<const raw::RawDigit*>& rawdigitvec,
159  vector<vector<caldata::RawDigitVector>>& rawadcgv,
160  vector<vector<WireChar>>& wgcv,
161  vector<vector<vector <int>>>& wgqv,
162  std::unique_ptr<std::vector<raw::RawDigit> >& filteredrawdigit)
163  : prod(prod),
164  fDataSize(fdatasize),
165  fftSize(fftsize),
166  fplan(fplan),
167  rplan(rplan),
168  igwvec(igwv),
169  rawDigitVec(rawdigitvec),
170  rawadcgvec(rawadcgv),
171  wgcvec(wgcv),
172  wgqvec(wgqv),
173  filteredRawDigit(filteredrawdigit){}
174  void operator()(const tbb::blocked_range<size_t>& range) const{
175  //std::cout << " !!!!!!!!!! range.begin(): " << range.begin() << " and range.end(): " << range.end() << std::endl;
176  for (size_t i = range.begin(); i < range.end(); ++i)
177  prod.WaveformChar(i, fDataSize, fftSize, fplan, rplan, igwvec, rawDigitVec, rawadcgvec, wgcvec, wgqvec, filteredRawDigit);
178  }
179  private:
181  unsigned int & fDataSize;
182  unsigned int & fftSize;
183  void* fplan;
184  void* rplan;
185  vector<GroupWireDigIndx>& igwvec;
186  std::vector<const raw::RawDigit*>& rawDigitVec;
187  vector<vector<caldata::RawDigitVector>>& rawadcgvec;
188  vector<vector<WireChar>>& wgcvec;
189  vector<vector<vector <int>>>& wgqvec;
190  std::unique_ptr<std::vector<raw::RawDigit> >& filteredRawDigit;
191 };
192 
193 //----------------------------------------------------------------------------
195  public:
197  unsigned int & fftsize,
198  unsigned int & halffftsize,
199  void* fplan, void* rplan,
200  vector<vector<caldata::RawDigitVector>>& rawadcgv,
201  vector<vector<WireChar>>& wgcv,
202  vector<vector<vector <int>>>& wgqv,
203  std::unique_ptr<std::vector<raw::RawDigit> >& filteredrawdigit)
204  : prod(prod),
205  fftSize(fftsize),
206  halfFFTSize(halffftsize),
207  fplan(fplan),
208  rplan(rplan),
209  rawadcgvec(rawadcgv),
210  wgcvec(wgcv),
211  wgqvec(wgqv),
212  filteredRawDigit(filteredrawdigit){}
213  void operator()(const tbb::blocked_range<size_t>& range) const{
214  for (size_t i = range.begin(); i < range.end(); ++i)
216  }
217  private:
219  unsigned int & fftSize;
220  unsigned int & halfFFTSize;
221  void* fplan;
222  void* rplan;
223  vector<vector<caldata::RawDigitVector>>& rawadcgvec;
224  vector<vector<WireChar>>& wgcvec;
225  vector<vector<vector <int>>>& wgqvec;
226  std::unique_ptr<std::vector<raw::RawDigit> >& filteredRawDigit;
227 };
228 
229 //----------------------------------------------------------------------------
230 RawDigitFilterICARUS::RawDigitFilterICARUS(fhicl::ParameterSet const & pset, art::ProcessingFrame const& frame) :
231  art::ReplicatedProducer(pset, frame),
232  fNumEvent(0),
233  fBinAverageAlg(pset),
234  fCharacterizationAlg(pset.get<fhicl::ParameterSet>("CharacterizationAlg")),
235  fCorCorrectAlg(pset.get<fhicl::ParameterSet>("CorrelatedCorrectionAlg")),
236  fPedestalRetrievalAlg(*lar::providerFrom<lariov::DetPedestalService>()),
237  fChannelGroups(pset)
238 {
239 
240  fGeometry = lar::providerFrom<geo::Geometry>();
241 
242  configure(pset);
243  produces<std::vector<raw::RawDigit> >();
244 
245  // Report.
246  mf::LogInfo("RawDigitFilterICARUS") << "RawDigitFilterICARUS configured\n";
247 }
248 
249 //----------------------------------------------------------------------------
251 {}
252 
253 //----------------------------------------------------------------------------
254 void RawDigitFilterICARUS::configure(fhicl::ParameterSet const & pset)
255 {
256  fDigitModuleLabel = pset.get<std::string> ("DigitModuleLabel", "daq");
257  fWindowSize = pset.get<size_t> ("WindowSize", 6400);
258  fTruncateTicks = pset.get<bool> ("TruncateTicks", false);
259  fNumTicksToDropFront = pset.get<size_t> ("NumTicksToDropFront", 2400);
260  fTruncateChannels = pset.get<bool> ("TruncateChannels", false);
261  fDoFFTCorrection = pset.get<bool> ("FFTNoise", true);
262  fNRmsChannelReject = pset.get<std::vector<float>> ("NRMSChannelReject", std::vector<float>() = {3., 3., 3. });
263  fSmoothCorrelatedNoise = pset.get<bool> ("SmoothCorrelatedNoise", true);
264  // .. waveform characterization
265  fRmsRejectionCutHi = pset.get<std::vector<float>> ("RMSRejectionCutHi", std::vector<float>() = {25.0,25.0,25.0});
266  fRmsRejectionCutLow = pset.get<std::vector<float>> ("RMSRejectionCutLow", std::vector<float>() = {0.70,0.70,0.70});
267  fMinMaxSelectionCut = pset.get<std::vector<short>> ("MinMaxSelectionCut", std::vector<short>() = {13, 13, 11});
268  // .. correlated noise correction
269  fNumWiresToGroup = pset.get<std::vector<size_t>>("NumWiresToGroup", std::vector<size_t>() = {48, 48, 96});
270  fDoCorrelatedNoise = pset.get<bool> ("ProcessNoise", true);
271  fApplyCorSmoothing = pset.get<bool> ("ApplyCorSmoothing", true);
272  fTruncMeanFraction = pset.get<float> ("TruncMeanFraction", 0.15);
273  fNumRmsToSmoothVec = pset.get<std::vector<float>> ("NumRmsToSmooth", std::vector<float>() = {3.6, 3.6, 4.});
274  fApplyFFTCorrection = pset.get<bool> ("ApplyFFTCorrection", true);
275  fFFTMinPowerThreshold = pset.get<std::vector<double>>("FFTPowerThreshold", std::vector<double>() = {100.,75.,500.});
276  fApplyTopHatFilter = pset.get<bool> ("ApplyTopHatFilter", true);
277 
278  fRawDigitFilterTool = art::make_tool<caldata::IRawDigitFilter>(pset.get<fhicl::ParameterSet>("RawDigitFilterTool"));
279 
280  // Implement the tools for handling the responses
281  const fhicl::ParameterSet& filterTools = pset.get<fhicl::ParameterSet>("FilterTools");
282 
283  for(const std::string& filterTool : filterTools.get_pset_names())
284  {
285  const fhicl::ParameterSet& filterToolParamSet = filterTools.get<fhicl::ParameterSet>(filterTool);
286  size_t planeIdx = filterToolParamSet.get<size_t>("Plane");
287 
288  fFilterToolMap.insert(std::pair<size_t,std::unique_ptr<icarus_tool::IFilter>>(planeIdx,art::make_tool<icarus_tool::IFilter>(filterToolParamSet)));
289  }
290 }
291 
292 //----------------------------------------------------------------------------
293 void RawDigitFilterICARUS::beginJob(art::ProcessingFrame const&)
294 {
295  // Access ART's TFileService, which will handle creating and writing
296  // histograms and n-tuples for us.
297  art::ServiceHandle<art::TFileService> tfs;
298 
301 
302  art::TFileDirectory dir = tfs->mkdir(Form("RawDigitFilter"));
303 
304  fRawDigitFilterTool->initializeHistograms(dir);
305 
306  return;
307 }
308 
309 //----------------------------------------------------------------------------
310 void RawDigitFilterICARUS::produce(art::Event & event, art::ProcessingFrame const&)
311 {
312  ++fNumEvent;
313 
314  // Read in the digit List object(s).
315  art::Handle< std::vector<raw::RawDigit> > digitVecHandle;
316  event.getByLabel(fDigitModuleLabel, digitVecHandle);
317 
318  // Agreed convention is to ALWAYS output to the event store so get a pointer to our collection
319  std::unique_ptr<std::vector<raw::RawDigit> > filteredRawDigit(new std::vector<raw::RawDigit>);
320  filteredRawDigit->resize(digitVecHandle->size());
321  //std::cout << " ~~~~~ Initial size of filteredRawDigit: " << filteredRawDigit->size() << std::endl;
322 
323  // ... Require a valid handle
324  if (digitVecHandle.isValid() && digitVecHandle->size()>0 ){
325  unsigned int maxChannels = fGeometry->Nchannels();
326 
327  // .. Let's first sort the rawDigitVec
328  std::vector<const raw::RawDigit*> rawDigitVec;
329  for(size_t idx = 0; idx < digitVecHandle->size(); idx++) rawDigitVec.push_back(&digitVecHandle->at(idx));
330  std::sort(rawDigitVec.begin(),rawDigitVec.end(),
331  [](const raw::RawDigit* left, const raw::RawDigit* right) {return left->Channel() < right->Channel();});
332 
333  // .. Use the handle to get a particular (0th) element of collection.
334  art::Ptr<raw::RawDigit> digitVec0(digitVecHandle, 0);
335  unsigned int fDataSize = digitVec0->Samples(); //size of raw data vectors
336  unsigned int fftSize;
337  if (fTruncateTicks) {
338  fftSize = fWindowSize;
339  } else {
340  fftSize = fDataSize;
341  }
342  vector<short> rawadc;
343  rawadc.resize(fftSize);
344 
345  vector<vector<caldata::RawDigitVector>> rawadcgvec;
346  vector<vector<WireChar>> wgcvec;
347  vector<vector<vector <int>>> wgqvec;
348  vector<GroupWireDigIndx>igwvec;
349 
350  vector<caldata::RawDigitVector> rawadcvec;
351  vector<WireChar> wcvec;
352  vector<vector<int>>wqvec;
353  wqvec.push_back({});
354  wqvec.push_back({});
355  int irawdig=-1;
356 
357  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
358  // ... Do a first loop over all the rawDigits to set up the grouped vectors
359  // for:
360  // wgcvec: wire charactestics
361  // wgqvec: wire quality
362  // rawdcgvec: uncompressed raw adcs
363  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
364  for(const auto& rawDigit : rawDigitVec){
365 
366  irawdig++;
367 
368  raw::ChannelID_t channel = rawDigit->Channel();
369  bool goodChan(true);
370  std::vector<geo::WireID> wids;
371  try {
372  wids = fGeometry->ChannelToWire(channel);
373  }
374  catch(...){
375  goodChan = false;
376  }
377  if (channel >= maxChannels || !goodChan) continue;
378 
379  unsigned int plane = wids[0].Plane;
380  unsigned int wire = wids[0].Wire;
381 
382  // .. Verify that dataSize looks fine
383  unsigned int dataSize = rawDigit->Samples();
384  if (dataSize < 1){
385  std::cout << "****>> Found zero length raw digit buffer, channel: "
386  << channel << ", plane: " << plane << ", wire: " << wire << std::endl;
387  continue;
388  }else if (dataSize!=fDataSize) {
389  std::cout << "****>> DataSize has changed from " << fDataSize << " to " << dataSize
390  << " for channel: " << channel << ", plane: " << plane << ", wire: " << wire << std::endl;
391  continue;
392  }
393  rawadcvec.push_back(rawadc);
394 
395  unsigned int wireIdx = wire % fNumWiresToGroup[plane];
396  //std::cout << "Channel = " << channel << " wire = " << wire
397  // << " plane = " << plane << " wireIdx = " << wireIdx << std::endl;
398 
399  WireChar wc;
400  wc.wire = wire;
401  wc.plane = plane;
402  wc.channel = channel;
403  wc.wireIdx = wireIdx;
404  wc.irawdig = irawdig;
405  wcvec.push_back(wc);
406 
407  GroupWireDigIndx igw;
408  igw.windx=int(wcvec.size()-1);
409  igw.irawdig=irawdig;
410  igw.group=int(wgcvec.size());
411 
412  igw.qgroup=-1;
413  size_t group = fChannelGroups.channelGroup(plane,wire);
414  if (group==0) {
415  wqvec[0].push_back(wcvec.size()-1);
416  igw.qgroup=0;
417  igw.qgindx=wqvec[0].size()-1;
418  } else if (group==1){
419  wqvec[1].push_back(wcvec.size()-1);
420  igw.qgroup=1;
421  igw.qgindx=wqvec[1].size()-1;
422  }
423 
424  igwvec.push_back(igw);
425 
426  // Are we at the correct boundary for dealing with the noise?
427  if (!((wireIdx + 1) % fNumWiresToGroup[plane])){
428  //std::cout << "!!!! Reached boundary to group wires" << std::endl;
429  rawadcgvec.push_back(rawadcvec);
430  wgcvec.push_back(wcvec);
431  wgqvec.push_back(wqvec);
432  rawadcvec.clear();
433  wcvec.clear();
434  wqvec[0].clear();
435  wqvec[1].clear();
436  }
437  }
438 
439  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
440  // ... Now that we have set up the data structures above, we can peform
441  // the FFT correction and determine the waveform parameters for each
442  // individual wire.
443  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
444 
445  // .. First set up the filters
446  unsigned int halfFFTSize(fftSize/2 + 1);
447  for(unsigned int plne = 0; plne < 3; plne++)
448  {
449  fFilterToolMap.at(plne)->setResponse(fftSize,1.,1.);
450  fFilterVec[plne] = fFilterToolMap.at(plne)->getResponseVec();
451  }
452 
453  // .. Now set up the fftw plan
454  util::LArFFTWPlan lfftwp(fftSize,"ES");
455 
456  //int nwavedump = 0;
457 
458  //for (std::size_t i=0; i<igwvec.size(); i++){
459  // WaveformChar(i, fDataSize, igwvec, rawDigitVec, rawadcgvec, wgcvec, filteredRawDigit);
460  //}
461  // ... Launch multiple threads with TBB to do the waveform characterization and fft correction in parallel
462  auto func = lartbb_WaveformChar(*this, fDataSize, fftSize, lfftwp.fPlan, lfftwp.rPlan, igwvec, rawDigitVec,
463  rawadcgvec, wgcvec, wgqvec, filteredRawDigit);
464  tbb::parallel_for(tbb::blocked_range<size_t>(0, igwvec.size()), func);
465 
466  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
467  // ... Next, we can do the correlated noise correction for each wire group
468  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
469 
471 
472  // .. Loop over each group of wires
473  //for (size_t igrp = 0; igrp < wgcvec.size(); igrp++) {
474  // RemoveCorrelatedNoise(igrp, fftSize, halfFFTSize, lfftwp.fPlan, lfftwp.rPlan, rawadcgvec, wgcvec, wgqvec, filteredRawDigit);
475  //} // loop over igrp
476  auto func = lartbb_RemoveCorrelatedNoise(*this, fftSize, halfFFTSize, lfftwp.fPlan, lfftwp.rPlan,
477  rawadcgvec, wgcvec, wgqvec, filteredRawDigit);
478  tbb::parallel_for(tbb::blocked_range<size_t>(0, wgcvec.size()), func);
479  } // if do and smooth correlated noise
480 
481  filteredRawDigit->erase(std::remove_if(filteredRawDigit->begin(),filteredRawDigit->end(),
482  [](const raw::RawDigit & frd){return frd.ADCs().size()==0;}),
483  filteredRawDigit->end());
484 
485  rawadcgvec.clear();
486  wgcvec.clear();
487  wgqvec.clear();
488  igwvec.clear();
489 
490  }
491 
492  //std::cout << " ~~~~~ Final size of filteredRawDigit: " << filteredRawDigit->size() << std::endl;
493 
494  // Add tracks and associations to event.
495  event.put(std::move(filteredRawDigit));
496 }
497 
498 //----------------------------------------------------------------------------
499 void RawDigitFilterICARUS::RemoveCorrelatedNoise(unsigned int igrp, unsigned int& fftSize, unsigned int& halfFFTSize, void* fplan, void* rplan,
500  vector<vector<caldata::RawDigitVector>>& rawadcgvec,
501  vector<vector<WireChar>>& wgcvec,
502  vector<vector<vector <int>>>& wgqvec,
503  std::unique_ptr<std::vector<raw::RawDigit> >& filteredRawDigit)const{
504 
505  for (size_t iq = 0; iq < 2; iq++) {
506 
507  if (wgqvec[igrp][iq].size() == 0) continue;
508 
509  // .. Remove the unclassified wires whose indices have been set to negative
510  wgqvec[igrp][iq].erase(std::remove_if(wgqvec[igrp][iq].begin(),wgqvec[igrp][iq].end(),[](const int& i){return i<0;}),wgqvec[igrp][iq].end());
511 
512  // .. Don't try to do correction if too few wires unless they have gaps
513  size_t nwq = wgqvec[igrp][iq].size();
514  if (nwq <= 2) continue;
515 
516  std::vector<float> corValVec;
517  corValVec.resize(fftSize, 0.);
518 
519  // ----------------------------------------------------
520  // .. Build the vector of corrections for each time bin
521  // ----------------------------------------------------
522  for(size_t itck = 0; itck < fftSize; itck++){
523  std::vector<float> adcValuesVec;
524  // .. Loop over each entry in wgqvec[igrp][iq]
525  for (size_t i = 0; i < nwq; i++) {
526  // .. get index into the wgvec[igrp] array
527  size_t iwdx = wgqvec[igrp][iq][i];
528  // .. Check that we should be doing something in this range
529  // Note that if the wire is not to be considered then the "start" bin will be after the last bin
530  if (itck < wgcvec[igrp][iwdx].tcka || itck >= wgcvec[igrp][iwdx].tckb) continue;
531  // .. Accumulate
532  adcValuesVec.push_back(float(rawadcgvec[igrp][iwdx][itck]) - wgcvec[igrp][iwdx].truncMean);
533  }
534  // ... Get the median for this time tick across all wires in the group
535  float medval(-10000);
536  if (!adcValuesVec.empty()) {
537  std::sort(adcValuesVec.begin(),adcValuesVec.end());
538  size_t medidx = adcValuesVec.size() / 2;
539  medval = adcValuesVec[medidx];
540  if (adcValuesVec.size() > 1 && medidx % 2) medval = (medval + adcValuesVec[medidx+1]) / 2;
541  }
542  corValVec[itck] = std::max(medval,float(-10000.));
543  } // loop over itck
544 
545  // .. get the plane number for first wire in this set, for use below
546  size_t iwdx0 = wgqvec[igrp][iq][0];
547  unsigned int plane = wgcvec[igrp][iwdx0].plane;
548 
549  // --------------------------------------
550  // ... Try to eliminate any real outliers
551  // --------------------------------------
552  if (fApplyCorSmoothing) {
553  std::vector<float> localCorValVec = corValVec;
554  std::sort(localCorValVec.begin(),localCorValVec.end());
555 
556  int nTruncVal = (1. - fTruncMeanFraction) * localCorValVec.size();
557  float corValSum = std::accumulate(localCorValVec.begin(),localCorValVec.begin() + nTruncVal,0.);
558  float meanCorVal = corValSum / float(nTruncVal);
559 
560  std::vector<float> diffVec(nTruncVal);
561  std::transform(localCorValVec.begin(),localCorValVec.begin() + nTruncVal, diffVec.begin(),
562  std::bind(std::minus<float>(),std::placeholders::_1,meanCorVal));
563 
564  float rmsValSq = std::inner_product(diffVec.begin(),diffVec.end(),diffVec.begin(),0.);
565  float rmsVal = std::sqrt(rmsValSq / float(nTruncVal));
566 
567  // .. Now set up to run through and do a "simple" interpolation over outliers
568  std::vector<float>::iterator lastGoodItr = corValVec.begin();
569  bool wasOutlier(false);
570  for(std::vector<float>::iterator corValItr = lastGoodItr+1; corValItr != corValVec.end(); corValItr++){
571  if (fabs(*corValItr - meanCorVal) < fNumRmsToSmoothVec.at(plane)*rmsVal){
572  if (wasOutlier){
573  float lastVal = *lastGoodItr;
574  float curVal = *corValItr;
575  float numTicks = std::distance(lastGoodItr,corValItr);
576  float slope = (curVal - lastVal) / numTicks;
577  while(lastGoodItr != corValItr){
578  *lastGoodItr++ = (numTicks - std::distance(lastGoodItr,corValItr)) * slope + lastVal;
579  }
580  }
581  wasOutlier = false;
582  lastGoodItr = corValItr;
583  } else {
584  wasOutlier = true;
585  }
586  }
587  } // fApplyCorSmoothing
588 
589  // ... Get the FFT correction
590  if (fApplyFFTCorrection) {
591  std::vector<std::complex<double>> fftOutputVec(halfFFTSize);
592  util::LArFFTW lfftw(fftSize, fplan, rplan, 0);
593  lfftw.DoFFT(corValVec, fftOutputVec);
594 
595  std::vector<double> powerVec(halfFFTSize);
596  std::transform(fftOutputVec.begin(), fftOutputVec.begin() + halfFFTSize, powerVec.begin(), [](const auto& val){return std::abs(val);});
597 
598  // Want the first derivative
599  std::vector<double> firstDerivVec(powerVec.size(), 0.);
600 
601  //fWaveformTool->firstDerivative(powerVec, firstDerivVec);
602  for(size_t idx = 1; idx < firstDerivVec.size() - 1; idx++)
603  firstDerivVec.at(idx) = 0.5 * (powerVec.at(idx + 1) - powerVec.at(idx - 1));
604 
605  // Find the peaks
606  std::vector<std::tuple<size_t,size_t,size_t>> peakTupleVec;
607 
608  findPeaks(firstDerivVec.begin(),firstDerivVec.end(),peakTupleVec,fFFTMinPowerThreshold[plane],0);
609 
610  if (!peakTupleVec.empty())
611  {
612  for(const auto& peakTuple : peakTupleVec)
613  {
614  size_t startTick = std::get<0>(peakTuple);
615  size_t stopTick = std::get<2>(peakTuple);
616 
617  if (stopTick > startTick)
618  {
619  std::complex<double> slope = (fftOutputVec[stopTick] - fftOutputVec[startTick]) / double(stopTick - startTick);
620 
621  for(size_t tick = startTick; tick < stopTick; tick++)
622  {
623  std::complex<double> interpVal = fftOutputVec[startTick] + double(tick - startTick) * slope;
624 
625  fftOutputVec[tick] = interpVal;
626  //fftOutputVec[fftDataSize - tick - 1] = interpVal;
627  }
628  }
629  }
630 
631  std::vector<double> tmpVec(corValVec.size());
632 
633  lfftw.DoInvFFT(fftOutputVec, tmpVec);
634 
635  std::transform(corValVec.begin(),corValVec.end(),tmpVec.begin(),corValVec.begin(),std::minus<double>());
636  }
637  } // fApplyFFTCorrection
638 
639  // -------------------------------------------
640  // ... Now go through and apply the correction
641  // -------------------------------------------
642  for(size_t itck = 0; itck < fftSize; itck++){
643  for (size_t i = 0; i < nwq; i++) {
644  float corVal;
645  size_t iwdx = wgqvec[igrp][iq][i];
646  // .. If the "start" bin is after the "stop" bin then we are meant to skip this wire in the averaging process
647  // Or if the sample index is in a chirping section then no correction is applied.
648  // Both cases are handled by looking at the sampleIdx
649  if (itck < wgcvec[igrp][iwdx].tcka || itck >= wgcvec[igrp][iwdx].tckb) {
650  corVal=0.;
651  } else {
652  corVal = corValVec[itck];
653  }
654  // .. Probably doesn't matter, but try to get slightly more accuracy by doing float math and rounding
655  float newAdcValueFloat = float(rawadcgvec[igrp][iwdx][itck]) - corVal - wgcvec[igrp][iwdx].pedCor;
656  rawadcgvec[igrp][iwdx][itck] = std::round(newAdcValueFloat);
657  }
658  }
659  } // loop over iq
660 
661  // ----------------------------------------------------
662  // ... One more pass through to store the good channels
663  // ----------------------------------------------------
664  for (size_t iwdx = 0; iwdx < wgcvec[igrp].size(); iwdx++) {
665 
666  unsigned int plane = wgcvec[igrp][iwdx].plane;
667 
668  // Try baseline correction?
669  if (fApplyTopHatFilter && plane != 2 && wgcvec[igrp][iwdx].skewness > 0.) {
670  fRawDigitFilterTool->FilterWaveform(rawadcgvec[igrp][iwdx], iwdx, plane);
671  }
672 
673  // recalculate rms for the output
674  float rmsVal = 0.;
675  float pedestal = wgcvec[igrp][iwdx].truncMean;
676  float pedCor = wgcvec[igrp][iwdx].pedCor;
677  float deltaPed = pedestal - pedCor;
678 
679  caldata::RawDigitVector& rawDataVec = rawadcgvec[igrp][iwdx];
680  fCharacterizationAlg.getTruncatedRMS(rawDataVec, deltaPed, rmsVal);
681 
682  // The ultra high noise channels are simply zapped
683  raw::ChannelID_t channel = wgcvec[igrp][iwdx].channel;
684  if (rmsVal < fRmsRejectionCutHi[plane]) { // && ImAGoodWire(plane,baseWireIdx + locWireIdx))
685  int irdg = wgcvec[igrp][iwdx].irawdig;
686  //saveRawDigits(filteredRawDigit, channelWireVec[locWireIdx], rawDataVec, pedestal, rmsVal);
687  filteredRawDigit->at(irdg) = raw::RawDigit(channel, rawDataVec.size(), rawDataVec, raw::kNone);
688  filteredRawDigit->at(irdg).SetPedestal(pedestal, rmsVal);
689  } else {
690  mf::LogInfo("RawDigitFilterICARUS") << "--> Rejecting channel for large rms, channel: "
691  << channel << ", rmsVal: " << rmsVal << ", truncMean: " << pedestal
692  << ", pedestal: " << pedCor << std::endl;
693  }
694  } // loop over igrp
695 
696 }
697 
698 //----------------------------------------------------------------------------
699 void RawDigitFilterICARUS::WaveformChar(unsigned int i, unsigned int& fDataSize, unsigned int& fftSize, void* fplan, void* rplan,
700  vector<GroupWireDigIndx>& igwvec,
701  std::vector<const raw::RawDigit*>& rawDigitVec,
702  vector<vector<caldata::RawDigitVector>>& rawadcgvec,
703  vector<vector<WireChar>>& wgcvec,
704  vector<vector<vector <int>>>& wgqvec,
705  std::unique_ptr<std::vector<raw::RawDigit> >& filteredRawDigit)const{
706  int igrp = igwvec[i].group;
707  int iwdx = igwvec[i].windx;
708  int irdg = igwvec[i].irawdig;
709  const raw::RawDigit* rawDigit = rawDigitVec.at(irdg);
710 
711  // .. Uncompress the RawDigit
712  caldata::RawDigitVector& rawADC = rawadcgvec[igrp][iwdx];
713  caldata::RawDigitVector tempVec(fDataSize);
714  if (fTruncateTicks){
715  raw::Uncompress(rawDigit->ADCs(), tempVec, rawDigit->Compression());
716  std::copy(tempVec.begin() + fNumTicksToDropFront, tempVec.begin() + fNumTicksToDropFront + fWindowSize, rawADC.begin());
717  } else {
718  raw::Uncompress(rawDigit->ADCs(), rawADC, rawDigit->Compression());
719  }
720 
721  // .. Do the FFT correction
722 
723  raw::ChannelID_t channel = rawDigit->Channel();
724  unsigned int plane = wgcvec[igrp][iwdx].plane;
725 
726  if (fDoFFTCorrection){
727  // .. Subtract the pedestal
728  float pedestal = fPedestalRetrievalAlg.PedMean(channel);
729  std::vector<float> holder(fftSize);
730  std::transform(rawADC.begin(),rawADC.end(),holder.begin(),[pedestal](const auto& val){return float(float(val) - pedestal);});
731 
732  const icarusutil::FrequencyVec& filterVecPlane = fFilterVec.at(plane);
733 
734  std::vector<std::complex<double>> filterVec(filterVecPlane.size());
735 
736  for(size_t idx = 0; idx < filterVecPlane.size(); idx++)
737  filterVec[idx] = filterVecPlane[idx];
738 
739  // .. Do the correction
740  util::LArFFTW lfftw(fftSize, fplan, rplan, 0);
741  lfftw.Convolute(holder, filterVec);
742 
743  // .. Restore the pedestal
744  std::transform(holder.begin(), holder.end(), rawADC.begin(), [pedestal](const float& adc){return std::round(adc + pedestal);});
745  }
746 
748  channel,
749  plane,
750  wgcvec[igrp][iwdx].wire,
751  wgcvec[igrp][iwdx].truncMean,
752  wgcvec[igrp][iwdx].truncRms,
753  wgcvec[igrp][iwdx].mean,
754  wgcvec[igrp][iwdx].median,
755  wgcvec[igrp][iwdx].mode,
756  wgcvec[igrp][iwdx].skewness,
757  wgcvec[igrp][iwdx].fullRms,
758  wgcvec[igrp][iwdx].minMax,
759  wgcvec[igrp][iwdx].neighborRatio,
760  wgcvec[igrp][iwdx].pedCor);
761 
762  // This allows the module to be used simply to truncate waveforms with no noise processing
763  if (!fDoCorrelatedNoise)
764  {
765  // Is this channel "quiet" and should be rejected?
766  // Note that the "max - min" range is to be compared to twice the rms cut
767  if (fTruncateChannels && wgcvec[igrp][iwdx].minMax < 2. * fNRmsChannelReject[plane] * wgcvec[igrp][iwdx].truncRms) return;
768 
769  caldata::RawDigitVector pedCorrectedVec;
770  pedCorrectedVec.resize(rawADC.size(),0);
771  std::transform(rawADC.begin(),rawADC.end(),pedCorrectedVec.begin(),std::bind(std::minus<short>(),std::placeholders::_1,wgcvec[igrp][iwdx].pedCor));
772 
773  //saveRawDigits(filteredRawDigit, channel, pedCorrectedVec, truncMeanWireVec[wireIdx], truncRmsWireVec[wireIdx]);
774  filteredRawDigit->at(irdg) = raw::RawDigit(channel, pedCorrectedVec.size(), pedCorrectedVec, raw::kNone);
775  filteredRawDigit->at(irdg).SetPedestal(wgcvec[igrp][iwdx].truncMean,wgcvec[igrp][iwdx].truncRms);
776  return;
777  }
778 
779  // If we are not performing noise corrections then we are done with this wire
780  // Store it and move on
782  {
783  // Filter out the very high noise wires
784  if (wgcvec[igrp][iwdx].truncRms < fRmsRejectionCutHi[plane]) {
785  //saveRawDigits(filteredRawDigit, channel, rawadc, truncMeanWireVec[wireIdx], truncRmsWireVec[wireIdx]);
786  filteredRawDigit->at(irdg) = raw::RawDigit(channel, rawADC.size(), rawADC, raw::kNone);
787  filteredRawDigit->at(irdg).SetPedestal(wgcvec[igrp][iwdx].truncMean,wgcvec[igrp][iwdx].truncRms);
788  } else {
789  // Eventually we'll interface to some sort of channel status communication mechanism.
790  // For now use the log file
791  mf::LogInfo("RawDigitFilterICARUS") << "--> Rejecting channel for large rms, channel: " << channel
792  << ", rmsVal: " << wgcvec[igrp][iwdx].truncRms << ", truncMean: " << wgcvec[igrp][iwdx].truncMean
793  << ", pedestal: " << wgcvec[igrp][iwdx].pedCor << std::endl;
794  }
795 
796  return;
797  }
798 
799  // .. Classify the waveform
800  if (wgcvec[igrp][iwdx].minMax > fMinMaxSelectionCut[plane] && wgcvec[igrp][iwdx].truncRms < fRmsRejectionCutHi[plane]){
801  wgcvec[igrp][iwdx].tcka = 0;
802  wgcvec[igrp][iwdx].tckb = rawADC.size();
803  // .. Look for chirping wire sections. Confine this to only the V plane
804  if (plane == 1){
805  // .. Do wire shape corrections to look for chirping wires & other oddities to avoid. Recover our objects...
806  short threshold(6);
807  short mean = wgcvec[igrp][iwdx].mean;
808 
809  // .. If going from quiescent to on again, then the min/max will be large
810  if (wgcvec[igrp][iwdx].skewness > 0. && wgcvec[igrp][iwdx].neighborRatio < 0.7 && wgcvec[igrp][iwdx].minMax > 50){
811  raw::RawDigit::ADCvector_t::iterator stopChirpItr = std::find_if(rawADC.begin(),rawADC.end(),
812  [mean,threshold](const short& elem){return abs(elem - mean) > threshold;});
813  size_t threshIndex = std::distance(rawADC.begin(),stopChirpItr);
814  if (threshIndex > 60) wgcvec[igrp][iwdx].tcka = threshIndex;
815  } else if (wgcvec[igrp][iwdx].minMax > 20 && wgcvec[igrp][iwdx].neighborRatio < 0.7){ // .. Check in the reverse direction?
816  threshold = 3;
817  raw::RawDigit::ADCvector_t::reverse_iterator startChirpItr = std::find_if(rawADC.rbegin(),rawADC.rend(),
818  [mean,threshold](const short& elem){return abs(elem - mean) > threshold;});
819  size_t threshIndex = std::distance(rawADC.rbegin(),startChirpItr);
820  if (threshIndex > 60) wgcvec[igrp][iwdx].tckb = rawADC.size() - threshIndex;
821  }
822  }
823  } else {
824  // .. If unable to classify, then set the wire index in wgqvec to negative to skip coherent noise correction
825  int iqgrp = igwvec[i].qgroup;
826  unsigned int iqdx = igwvec[i].qgindx;
827  if ( iqgrp == 0 || iqgrp == 1 ) {
828  wgqvec[igrp][iqgrp][iqdx]=-1;
829  }
830  // .. and apply the pedestal correction
831  std::transform(rawADC.begin(),rawADC.end(),rawADC.begin(),std::bind(std::minus<short>(),std::placeholders::_1,wgcvec[igrp][iwdx].pedCor));
832  }
833 
834  return;
835 }
836 
837 //----------------------------------------------------------------------------
838 template <typename T> void RawDigitFilterICARUS::findPeaks(typename std::vector<T>::iterator startItr,
839  typename std::vector<T>::iterator stopItr,
840  std::vector<std::tuple<size_t,size_t,size_t>>& peakTupleVec,
841  T threshold,
842  size_t firstTick) const
843 {
844  // Need a minimum distance or else nothing to do
845  if (std::distance(startItr,stopItr) > 4)
846  {
847  // This is a divide and conquer algorithm, start by finding the maximum element.
848  typename std::vector<T>::iterator firstItr = std::max_element(startItr,stopItr,[](float left, float right){return std::fabs(left) < std::fabs(right);});
849 
850  // Are we over threshold?
851  if (std::fabs(*firstItr) > threshold)
852  {
853  // What am I thinking?
854  // First task is to find the "other" lobe max point
855  // Set one to the "first", the other to the "second"
856  // Search backward from first to find start point, forward from second to find end point
857  // Set mid point between first and second as "peak"?
858  typename std::vector<T>::iterator secondItr = firstItr;
859 
860  // Assume if max bin is positive then second lobe is later
861  if (*firstItr > 0)
862  {
863  typename std::vector<T>::iterator tempItr = secondItr;
864 
865  while(tempItr != stopItr)
866  {
867  if (*++tempItr < -threshold)
868  {
869  if (*tempItr < *secondItr) secondItr = tempItr;
870  }
871  else if (secondItr != firstItr) break;
872  }
873  }
874  // Otherwise it goes the other way
875  else
876  {
877  typename std::vector<T>::iterator tempItr = secondItr;
878 
879  while(tempItr != startItr)
880  {
881  if (*--tempItr > threshold)
882  {
883  if (*tempItr > *secondItr) secondItr = tempItr;
884  }
885  else if (secondItr != firstItr) break;
886  }
887 
888  std::swap(firstItr,secondItr);
889  }
890 
891  // It might that no real pulse was found
892  if (firstItr != secondItr)
893  {
894  // Get the "peak" position
895  size_t peakBin = std::distance(startItr,firstItr) + std::distance(firstItr,secondItr) / 2;
896 
897  // Advance (forward or backward) the first and second iterators to get back to zero crossing
898  while(firstItr != startItr) if (*--firstItr < 0.) break;
899  while(secondItr != stopItr) if (*++secondItr > 0.) break;
900 
901  size_t firstBin = std::distance(startItr,firstItr);
902  size_t lastBin = std::distance(startItr,secondItr);
903 
904  // Find leading peaks
905  findPeaks(startItr, firstItr, peakTupleVec, threshold, firstTick);
906 
907  // Save this peak
908  peakTupleVec.push_back(std::tuple<size_t,size_t,size_t>(firstBin+firstTick,peakBin+firstTick,lastBin+firstTick));
909 
910  // Find downstream peaks
911  findPeaks(secondItr, stopItr, peakTupleVec, threshold, firstTick + std::distance(startItr,secondItr));
912  }
913  }
914  }
915 
916  return;
917 }
918 
919 //----------------------------------------------------------------------------
920 void RawDigitFilterICARUS::saveRawDigits(std::unique_ptr<std::vector<raw::RawDigit> >& filteredRawDigit,
921  raw::ChannelID_t& channel,
922  caldata::RawDigitVector& rawDigitVec,
923  float pedestal,
924  float rms)
925 {
926  //filteredRawDigit->emplace_back(raw::RawDigit(channel, rawDigitVec.size(), rawDigitVec, raw::kNone));
927  filteredRawDigit->emplace_back(channel, rawDigitVec.size(), rawDigitVec, raw::kNone);
928  filteredRawDigit->back().SetPedestal(pedestal,rms);
929 
930  return;
931 }
932 
933 //----------------------------------------------------------------------------
934 void RawDigitFilterICARUS::endJob(art::ProcessingFrame const&)
935 {
936  mf::LogInfo("RawDigitFilterICARUS") << "Looked at " << fNumEvent << " events" << std::endl;
937 }
caldata::RawDigitCorrelatedCorrectionAlg fCorCorrectAlg
raw::ChannelID_t channel
bool fTruncateChannels
If true then we drop channels with &quot;no signal&quot;.
bool fApplyFFTCorrection
Use an FFT to get the correlated noise correction.
std::vector< short > fMinMaxSelectionCut
Plane by plane cuts for spread cut.
const ADCvector_t & ADCs() const
Reference to the compressed ADC count vector.
Definition: RawDigit.h:210
vector< vector< WireChar > > & wgcvec
vector< vector< vector< int > > > & wgqvec
Collection of charge vs time digitized from a single readout channel.
Definition: RawDigit.h:69
static constexpr Sample_t transform(Sample_t sample)
void saveRawDigits(std::unique_ptr< std::vector< raw::RawDigit > > &, raw::ChannelID_t &, caldata::RawDigitVector &, float, float)
float fTruncMeanFraction
Fraction for truncated mean.
bool fTruncateTicks
If true then drop ticks off ends of wires.
T::provider_type const * providerFrom()
Returns a constant pointer to the provider of specified service.
Definition: ServiceUtil.h:77
walls no right
Definition: selectors.fcl:105
virtual void produce(art::Event &e, art::ProcessingFrame const &frame)
ChannelID_t Channel() const
DAQ channel this raw data was read from.
Definition: RawDigit.h:212
std::string fDigitModuleLabel
The full collection of hits.
void RemoveCorrelatedNoise(unsigned int igrp, unsigned int &fftSize, unsigned int &halfFFTSize, void *fplan, void *rplan, vector< vector< caldata::RawDigitVector >> &rawadcgvec, vector< vector< WireChar >> &wgcvec, vector< vector< vector< int >>> &wgqvec, std::unique_ptr< std::vector< raw::RawDigit > > &filteredRawDigit) const
unsigned int fWindowSize
ticks to keep in window
raw::RawDigit::ADCvector_t RawDigitVector
bool fDoFFTCorrection
Run the FFT noise correction.
std::vector< geo::WireID > ChannelToWire(raw::ChannelID_t const channel) const
Returns a list of wires connected to the specified TPC channel.
Definition of basic raw digits.
std::size_t size(FixedBins< T, C > const &) noexcept
Definition: FixedBins.h:561
bool fDoCorrelatedNoise
Process the noise.
const lariov::DetPedestalProvider & fPedestalRetrievalAlg
Keep track of an instance to the pedestal retrieval alg.
vector< vector< caldata::RawDigitVector > > & rawadcgvec
std::vector< ComplexVal > FrequencyVec
vector< vector< vector< int > > > & wgqvec
std::vector< float > fRmsRejectionCutHi
Maximum rms for input channels, reject if larger.
caldata::RawDigitCharacterizationAlg fCharacterizationAlg
no compression
Definition: RawTypes.h:9
lartbb_RemoveCorrelatedNoise(RawDigitFilterICARUS const &prod, unsigned int &fftsize, unsigned int &halffftsize, void *fplan, void *rplan, vector< vector< caldata::RawDigitVector >> &rawadcgv, vector< vector< WireChar >> &wgcv, vector< vector< vector< int >>> &wgqv, std::unique_ptr< std::vector< raw::RawDigit > > &filteredrawdigit)
vector< vector< WireChar > > & wgcvec
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
unsigned int Nchannels() const
Returns the number of TPC readout channels in the detector.
void operator()(const tbb::blocked_range< size_t > &range) const
std::vector< const raw::RawDigit * > & rawDigitVec
vector< GroupWireDigIndx > & igwvec
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:265
int fNumEvent
Number of events seen.
T abs(T value)
std::unique_ptr< std::vector< raw::RawDigit > > & filteredRawDigit
double distance(geo::Point_t const &point, CathodeDesc_t const &cathode)
Returns the distance of a point from the cathode.
size_t channelGroup(size_t view, size_t wire) const
bool fApplyCorSmoothing
Attempt to smooth the correlated noise correction?
bool fSmoothCorrelatedNoise
Should we smooth the noise?
const char mode
Definition: noise_ana.cxx:20
Collect all the RawData header files together.
bool fApplyTopHatFilter
Apply the top hat filter.
auto end(FixedBins< T, C > const &) noexcept
Definition: FixedBins.h:585
tick_as<> tick
Tick number, represented by std::ptrdiff_t.
Definition: electronics.h:75
void initializeHists(art::ServiceHandle< art::TFileService > &)
Begin job method.
unsigned int fNumTicksToDropFront
ticks to drop from front of waveform
void Convolute(std::vector< T > &func, const ComplexVector &kern)
Definition: LArFFTW.h:156
walls no left
Definition: selectors.fcl:105
vector< vector< caldata::RawDigitVector > > & rawadcgvec
std::vector< double > fFFTMinPowerThreshold
Threshold for trimming FFT power spectrum.
virtual void beginJob(art::ProcessingFrame const &frame)
Begin job method.
std::unique_ptr< std::vector< raw::RawDigit > > & filteredRawDigit
std::map< size_t, std::vector< std::complex< double > > > fFilterVec
caldata::ChannelGroups fChannelGroups
Description of geometry of one entire detector.
This is the interface class for a tool to handle a filter for the overall response.
virtual float PedMean(raw::ChannelID_t ch) const =0
Retrieve pedestal information.
RawDigitFilterICARUS const & prod
void getTruncatedRMS(const RawDigitVector &rawWaveform, float &pedestal, float &truncRms) const
tuple dir
Definition: dropbox.py:28
std::vector< float > fRmsRejectionCutLow
Minimum rms to consider channel &quot;alive&quot;.
virtual void configure(fhicl::ParameterSet const &pset)
auto begin(FixedBins< T, C > const &) noexcept
Definition: FixedBins.h:573
raw::Compress_t Compression() const
Compression algorithm used to store the ADC counts.
Definition: RawDigit.h:216
virtual ~RawDigitFilterICARUS()
Destructor.
double mean(const std::vector< short > &wf, size_t start, size_t nsample)
Definition: UtilFunc.cxx:13
std::unique_ptr< caldata::IRawDigitFilter > fRawDigitFilterTool
This provides an interface for tools which are tasked with filtering input waveforms.
virtual void endJob(art::ProcessingFrame const &frame)
End job method.
void SetPedestal(float ped, float sigma=1.)
Set pedestal and its RMS (the latter is 0 by default)
Definition: RawDigit.cxx:68
lartbb_WaveformChar(RawDigitFilterICARUS const &prod, unsigned int &fdatasize, unsigned int &fftsize, void *fplan, void *rplan, vector< GroupWireDigIndx > &igwv, std::vector< const raw::RawDigit * > &rawdigitvec, vector< vector< caldata::RawDigitVector >> &rawadcgv, vector< vector< WireChar >> &wgcv, vector< vector< vector< int >>> &wgqv, std::unique_ptr< std::vector< raw::RawDigit > > &filteredrawdigit)
caldata::RawDigitBinAverageAlg fBinAverageAlg
do i e
T copy(T const &v)
std::vector< float > fNumRmsToSmoothVec
&quot;sigma&quot; to smooth correlated correction vec
geo::GeometryCore const * fGeometry
pointer to Geometry service
art::ServiceHandle< art::TFileService > tfs
RawDigitFilterICARUS(fhicl::ParameterSet const &pset, art::ProcessingFrame const &frame)
void DoInvFFT(std::vector< T > &output)
Definition: LArFFTW.h:113
std::map< size_t, std::unique_ptr< icarus_tool::IFilter > > fFilterToolMap
unsigned int ChannelID_t
Type representing the ID of a readout channel.
Definition: RawTypes.h:28
std::vector< size_t > fNumWiresToGroup
If smoothing, the number of wires to look at.
void Uncompress(const std::vector< short > &adc, std::vector< short > &uncompressed, raw::Compress_t compress)
Uncompresses a raw data buffer.
Definition: raw.cxx:776
void initializeHists(art::ServiceHandle< art::TFileService > &)
Begin job method.
void getWaveformParams(const RawDigitVector &rawWaveform, unsigned int channel, unsigned int view, unsigned int wire, float &truncMean, float &truncRms, short &mean, short &median, short &mode, float &skewness, float &rms, short &minMax, float &neighborRatio, float &pedCorVal) const
void DoFFT(std::vector< T > &input)
Definition: LArFFTW.h:76
std::vector< float > fNRmsChannelReject
rms to reject channel as no signal
art framework interface to geometry description
BEGIN_PROLOG could also be cout
void operator()(const tbb::blocked_range< size_t > &range) const
void WaveformChar(unsigned int i, unsigned int &fDataSize, unsigned int &fftsize, void *fplan, void *rplan, vector< GroupWireDigIndx > &igwvec, std::vector< const raw::RawDigit * > &rawDigitVec, vector< vector< caldata::RawDigitVector >> &rawadcgvec, vector< vector< WireChar >> &wgcvec, vector< vector< vector< int >>> &wgqvec, std::unique_ptr< std::vector< raw::RawDigit > > &filteredRawDigit) const