All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
RawDigitSmoother_module.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Class: RawDigitSmoother
4 // Module Type: producer
5 // File: RawDigitSmoother_module.cc
6 //
7 // This module implements a two dimensional morphological filter
8 // to apply to plane by plane images with the intent to enhance the
9 // signal regions. The primary aim is to aid pattern recognition
10 //
11 // Configuration parameters:
12 //
13 // DigitModuleLabel - the source of the RawDigit collection
14 //
15 // Created by Tracy Usher (usher@slac.stanford.edu) on July 29, 2018
16 //
17 ////////////////////////////////////////////////////////////////////////
18 
19 #include <cmath>
20 #include <algorithm>
21 #include <vector>
22 
23 #include "art/Framework/Core/EDProducer.h"
24 #include "art/Framework/Services/Registry/ServiceHandle.h"
25 #include "art_root_io/TFileService.h"
26 #include "art/Framework/Principal/Event.h"
27 #include "art/Framework/Core/ModuleMacros.h"
28 #include "art/Utilities/make_tool.h"
29 #include "canvas/Persistency/Common/Ptr.h"
30 #include "messagefacility/MessageLogger/MessageLogger.h"
31 
35 
37 
39 #include "lardataobj/RawData/raw.h"
40 
41 #include <Eigen/Core>
42 
43 class RawDigitSmoother : public art::EDProducer
44 {
45 public:
46 
47  // Copnstructors, destructor.
48  explicit RawDigitSmoother(fhicl::ParameterSet const & pset);
49  virtual ~RawDigitSmoother();
50 
51  // Overrides.
52  virtual void configure(fhicl::ParameterSet const & pset);
53  virtual void produce(art::Event & e);
54  virtual void beginJob();
55  virtual void endJob();
56 
57 private:
58 
59  // Set up our container for the waveforms
60  // We'll keep things in a tuple so we can also keep track of the pedestal and rms for output
61  using WireTuple = std::tuple<raw::ChannelID_t,float,float,caldata::RawDigitVector>;
62  using WaveformVec = std::vector<WireTuple>;
63  using WaveformList = std::list<WireTuple*>;
64 
65  void saveRawDigits(std::unique_ptr<std::vector<raw::RawDigit> >&, WireTuple&);
66  void saveRawDigits(std::unique_ptr<std::vector<raw::RawDigit> >&, raw::ChannelID_t&, float, float, caldata::RawDigitVector&);
67 
68  // Define the structuring element - currently just a vector of vectors
69  using StructuringElement = std::vector<std::vector<short>>;
70 
71  // Fcl parameters.
72  std::string fDigitModuleLabel; ///< The full collection of hits
73  bool fOutputHistograms; ///< Output histograms?
74  bool fOutputWaveforms; ///< Output waveforms?
75 
76  art::TFileDirectory* fHistDirectory;
77 
78  // Statistics.
79  int fNumEvent; ///< Number of events seen.
80 
81  // Once defined the structuring element will not change
85 
86  // Correction algorithms
88 
89  // Useful services, keep copies for now (we can update during begin run periods)
90  geo::GeometryCore const* fGeometry; ///< pointer to Geometry service
91  const lariov::DetPedestalProvider& fPedestalRetrievalAlg; ///< Keep track of an instance to the pedestal retrieval alg
92 };
93 
94 DEFINE_ART_MODULE(RawDigitSmoother)
95 
96 //----------------------------------------------------------------------------
97 /// Constructor.
98 ///
99 /// Arguments:
100 ///
101 /// pset - Fcl parameters.
102 ///
103 RawDigitSmoother::RawDigitSmoother(fhicl::ParameterSet const & pset) : EDProducer{pset},
104  fNumEvent(0),
105  fCharacterizationAlg(pset.get<fhicl::ParameterSet>("CharacterizationAlg")),
106  fPedestalRetrievalAlg(*lar::providerFrom<lariov::DetPedestalService>())
107 {
108 
109  fGeometry = lar::providerFrom<geo::Geometry>();
110 
111  configure(pset);
112  produces<std::vector<raw::RawDigit>>("erosion");
113  produces<std::vector<raw::RawDigit>>("dilation");
114  produces<std::vector<raw::RawDigit>>("edge");
115  produces<std::vector<raw::RawDigit>>("average");
116  produces<std::vector<raw::RawDigit>>("difference");
117  produces<std::vector<raw::RawDigit>>("median");
118 
119  // Report.
120  mf::LogInfo("RawDigitSmoother") << "RawDigitSmoother configured\n";
121 }
122 
123 //----------------------------------------------------------------------------
124 /// Destructor.
126 {}
127 
128 //----------------------------------------------------------------------------
129 /// Reconfigure method.
130 ///
131 /// Arguments:
132 ///
133 /// pset - Fcl parameter set.
134 ///
135 void RawDigitSmoother::configure(fhicl::ParameterSet const & pset)
136 {
137  fDigitModuleLabel = pset.get<std::string>("DigitModuleLabel", "daq");
138  fStructuringElementWireSize = pset.get<size_t> ("StructuringElementWireSize", 5);
139  fStructuringElementTickSize = pset.get<size_t> ("StructuringElementTickSize", 5);
140  fOutputHistograms = pset.get< bool >("OutputHistograms", false);
141  fOutputWaveforms = pset.get< bool >("OutputWaveforms", false);
142 
143  fStructuringElement.resize(fStructuringElementWireSize);
144 
145  // Create a rectangular structuring element to start with
146  for(auto& row : fStructuringElement) row.resize(fStructuringElementTickSize,1);
147 
148  // If asked, define the global histograms
149  if (fOutputHistograms)
150  {
151  // Access ART's TFileService, which will handle creating and writing
152  // histograms and n-tuples for us.
153  art::ServiceHandle<art::TFileService> tfs;
154 
155  fHistDirectory = tfs.get();
156 
157  // Make a directory for these histograms
158  // art::TFileDirectory dir = fHistDirectory->mkdir(Form("ROIPlane_%1zu",fPlane));
159  }
160 }
161 
162 //----------------------------------------------------------------------------
163 /// Begin job method.
165 {
166  // Access ART's TFileService, which will handle creating and writing
167  // histograms and n-tuples for us.
168  art::ServiceHandle<art::TFileService> tfs;
169 
170 // art::TFileDirectory dir = tfs->mkdir(Form("RawDigitSmoother"));
171 
173 
174  return;
175 }
176 
177 //----------------------------------------------------------------------------
178 /// Produce method.
179 ///
180 /// Arguments:
181 ///
182 /// evt - Art event.
183 ///
184 /// This is the primary method.
185 ///
186 void RawDigitSmoother::produce(art::Event & event)
187 {
188  ++fNumEvent;
189 
190  // Agreed convention is to ALWAYS output to the event store so get a pointer to our collection
191  std::unique_ptr<std::vector<raw::RawDigit> > erosionRawDigit(new std::vector<raw::RawDigit>);
192  std::unique_ptr<std::vector<raw::RawDigit> > dilationRawDigit(new std::vector<raw::RawDigit>);
193  std::unique_ptr<std::vector<raw::RawDigit> > edgeRawDigit(new std::vector<raw::RawDigit>);
194  std::unique_ptr<std::vector<raw::RawDigit> > differenceRawDigit(new std::vector<raw::RawDigit>);
195  std::unique_ptr<std::vector<raw::RawDigit> > averageRawDigit(new std::vector<raw::RawDigit>);
196  std::unique_ptr<std::vector<raw::RawDigit> > medianRawDigit(new std::vector<raw::RawDigit>);
197 
198  erosionRawDigit->clear();
199  dilationRawDigit->clear();
200  edgeRawDigit->clear();
201  differenceRawDigit->clear();
202  averageRawDigit->clear();
203  medianRawDigit->clear();
204 
205  // Read in the digit List object(s).
206  art::Handle< std::vector<raw::RawDigit> > digitVecHandle;
207  event.getByLabel(fDigitModuleLabel, digitVecHandle);
208 
209  // Require a valid handle
210  if (digitVecHandle.isValid() && digitVecHandle->size() > 0)
211  {
212  erosionRawDigit->reserve(digitVecHandle->size());
213  dilationRawDigit->reserve(digitVecHandle->size());
214  edgeRawDigit->reserve(digitVecHandle->size());
215  differenceRawDigit->reserve(digitVecHandle->size());
216  averageRawDigit->reserve(digitVecHandle->size());
217  medianRawDigit->reserve(digitVecHandle->size());
218 
219  unsigned int maxChannels = fGeometry->Nchannels();
220 
221  // Sadly, the RawDigits come to us in an unsorted condition which is not optimal for
222  // what we want to do here. So we make a vector of pointers to the input raw digits and sort them
223  std::vector<const raw::RawDigit*> rawDigitVec;
224 
225  // Ugliness to fill the pointer vector...
226  for(size_t idx = 0; idx < digitVecHandle->size(); idx++) rawDigitVec.push_back(&digitVecHandle->at(idx));
227 
228  // Sort (use a lambda to sort by channel id)
229  std::sort(rawDigitVec.begin(),rawDigitVec.end(),[](const raw::RawDigit* left, const raw::RawDigit* right) {return left->Channel() < right->Channel();});
230 
231  // Get size of input data vectors
232  size_t rawDataSize = rawDigitVec.front()->Samples();
233 
234  // Get an instance of our input waveform list and digit vect
235  WaveformList inputWaveformList;
236  WaveformVec wireTupleVec;
237 
238  // First we create vector which contains the data
239  for(size_t idx = 0; idx < fStructuringElementWireSize; idx++) wireTupleVec.push_back(WireTuple(0,0.,0.,caldata::RawDigitVector(rawDataSize)));
240 
241  // Now set the address of each of these in the list
242  for(size_t idx = 0; idx < fStructuringElementWireSize; idx++) inputWaveformList.push_back(&wireTupleVec[idx]);
243 
244  // ok, make containers for the various things we are going to calculate
245  WireTuple erosionTuple = WireTuple(0,0.,0.,caldata::RawDigitVector(rawDataSize, 0));
246  WireTuple dilationTuple = WireTuple(0,0.,0.,caldata::RawDigitVector(rawDataSize, 0));
247  WireTuple edgeTuple = WireTuple(0,0.,0.,caldata::RawDigitVector(rawDataSize, 0));
248  WireTuple differenceTuple = WireTuple(0,0.,0.,caldata::RawDigitVector(rawDataSize, 0));
249  WireTuple averageTuple = WireTuple(0,0.,0.,caldata::RawDigitVector(rawDataSize, 0));
250  WireTuple medianTuple = WireTuple(0,0.,0.,caldata::RawDigitVector(rawDataSize, 0));
251 
252  caldata::RawDigitVector& erosionVec = std::get<3>(erosionTuple);
253  caldata::RawDigitVector& dilationVec = std::get<3>(dilationTuple);
254  caldata::RawDigitVector& edgeVec = std::get<3>(edgeTuple);
255  caldata::RawDigitVector& differenceVec = std::get<3>(differenceTuple);
256  caldata::RawDigitVector& averageVec = std::get<3>(averageTuple);
257  caldata::RawDigitVector& medianVec = std::get<3>(medianTuple);
258 
259  // Use an index for the last valid waveform...
260  size_t validIndex = 0;
261 
262  // On the very inside loop we are going to keep track of ADC values in a vector... we can speed things up by pre determining some parameters
263  size_t maxAdcBinSize(0);
264 
265  for(const auto& rowVec : fStructuringElement)
266  {
267  for(const auto& structElemVal : rowVec)
268  if (structElemVal) maxAdcBinSize++;
269  }
270 
271  std::vector<short> adcBinValVec(maxAdcBinSize, 0);
272 
273  // Avoid creating and destroying a vector each loop... make a single one here
274  caldata::RawDigitVector inputAdcVector(rawDataSize);
275 
276  geo::WireID lastWireID = fGeometry->ChannelToWire(rawDigitVec.front()->Channel())[0];
277 
278  // Commence looping over raw digits
279  for(const auto& rawDigit : rawDigitVec)
280  {
281  raw::ChannelID_t channel = rawDigit->Channel();
282 
283  if (channel >= maxChannels) continue;
284 
285  // Decode the channel and make sure we have a valid one
286  std::vector<geo::WireID> wids = fGeometry->ChannelToWire(channel);
287 
288  // Look to see if we have crossed to another plane
289  if (lastWireID.asPlaneID().cmp(wids[0].asPlaneID()) != 0)
290  {
291  // Dispose of the end set of RawDigits (in order)
292  WaveformList::iterator inputWaveItr = inputWaveformList.begin();
293 
294  std::advance(inputWaveItr, fStructuringElementWireSize/2);
295 
296  while(++inputWaveItr != inputWaveformList.end())
297  {
298  saveRawDigits(erosionRawDigit, **inputWaveItr);
299  saveRawDigits(dilationRawDigit, **inputWaveItr);
300  saveRawDigits(edgeRawDigit, **inputWaveItr);
301  saveRawDigits(differenceRawDigit, **inputWaveItr);
302  saveRawDigits(averageRawDigit, **inputWaveItr);
303  saveRawDigits(medianRawDigit, **inputWaveItr);
304  }
305 
306  // Reset the valid waveforms index
307  validIndex = 0;
308  }
309 
310  // Update the last wire id before we forget...
311  lastWireID = wids[0];
312 
313  // Recover plane and wire in the plane
314  unsigned int plane = wids[0].Plane;
315  unsigned int wire = wids[0].Wire;
316 
317  if (rawDigit->Samples() < 1)
318  {
319  std::cout << "****>> Found zero length raw digit buffer, channel: " << channel << ", plane: " << plane << ", wire: " << wire << std::endl;
320  continue;
321  }
322 
323  // If the buffer is "full" then we need to rotate the first to the end so we can reuse
324  if (validIndex == inputWaveformList.size())
325  {
326  inputWaveformList.push_back(inputWaveformList.front());
327  inputWaveformList.pop_front();
328  }
329  else validIndex++;
330 
331  // Find the right entry
332  WaveformList::iterator inputWaveItr = inputWaveformList.begin();
333  WaveformList::iterator midWaveItr = inputWaveItr;
334 
335  std::advance(inputWaveItr, validIndex - 1);
336  std::advance(midWaveItr, validIndex / 2);
337 
338  caldata::RawDigitVector& rawadc = std::get<3>(**inputWaveItr);
339 
340  // And now uncompress
341  raw::Uncompress(rawDigit->ADCs(), inputAdcVector, rawDigit->Compression());
342 
343  float truncMean;
344  float rmsVal;
345  float pedCorVal;
346 
347  // Recover the mean and rms for this waveform
348  fCharacterizationAlg.getMeanRmsAndPedCor(inputAdcVector, channel, plane, wire, truncMean, rmsVal, pedCorVal);
349 
350  // Recover the database version of the pedestal
351  float pedestal = fPedestalRetrievalAlg.PedMean(channel);
352 
353  std::transform(inputAdcVector.begin(),inputAdcVector.end(),rawadc.begin(),std::bind(std::minus<short>(),std::placeholders::_1,pedCorVal));
354 
355  std::get<0>(**inputWaveItr) = channel;
356  std::get<1>(**inputWaveItr) = pedestal;
357  std::get<2>(**inputWaveItr) = rmsVal;
358 
359  // Finally, at this point we are prepared to do some work!
360  if (validIndex == inputWaveformList.size())
361  {
362 
363  raw::ChannelID_t midChannel = std::get<0>(**midWaveItr);
364  float midPedestal = std::get<1>(**midWaveItr);
365  float midRmsVal = std::get<2>(**midWaveItr);
366  size_t halfStructuringElementTickSize = fStructuringElementTickSize / 2;
367 
368  caldata::RawDigitVector& currentVec = std::get<3>(**midWaveItr);
369 
370  // Fill the edge bins with the pedestal value
371  for(size_t adcBinIdx = 0; adcBinIdx < halfStructuringElementTickSize; adcBinIdx++)
372  {
373  size_t adcLastBinIdx = rawDataSize - adcBinIdx - 1;
374 
375  erosionVec[adcBinIdx] = midPedestal;
376  erosionVec[adcLastBinIdx] = midPedestal;
377  dilationVec[adcBinIdx] = midPedestal;
378  dilationVec[adcLastBinIdx] = midPedestal;
379  edgeVec[adcBinIdx] = midPedestal;
380  edgeVec[adcLastBinIdx] = midPedestal;
381  differenceVec[adcBinIdx] = midPedestal;
382  differenceVec[adcLastBinIdx] = midPedestal;
383  averageVec[adcBinIdx] = midPedestal;
384  averageVec[adcLastBinIdx] = midPedestal;
385  medianVec[adcBinIdx] = midPedestal;
386  medianVec[adcLastBinIdx] = midPedestal;
387  }
388 
389  // Ok, buckle up!
390  // Loop will run from half the structuring element to size less half the structuring element. Edges will simply be what they were
391  for(size_t adcBinIdx = halfStructuringElementTickSize; adcBinIdx < erosionVec.size() - halfStructuringElementTickSize; adcBinIdx++)
392  {
393  size_t rowIdx(0);
394  size_t adcBinVecIdx(0);
395 
396  // Outside loop over vectors
397  for(const auto& curTuple : inputWaveformList)
398  {
399  const caldata::RawDigitVector& curAdcVec = std::get<3>(*curTuple);
400 
401  for(size_t colIdx = 0; colIdx < fStructuringElementTickSize; colIdx++)
402  {
403  if (fStructuringElement[rowIdx][colIdx]) adcBinValVec[adcBinVecIdx++] = curAdcVec[colIdx + adcBinIdx - halfStructuringElementTickSize];
404  }
405 
406  rowIdx++;
407  }
408 
409  std::sort(adcBinValVec.begin(),adcBinValVec.end());
410 
411  erosionVec[adcBinIdx] = adcBinValVec.front();
412  dilationVec[adcBinIdx] = adcBinValVec.back();
413  edgeVec[adcBinIdx] = (dilationVec[adcBinIdx] - currentVec[adcBinIdx]) + midPedestal;
414  differenceVec[adcBinIdx] = (dilationVec[adcBinIdx] - erosionVec[adcBinIdx]) + midPedestal;
415  averageVec[adcBinIdx] = (dilationVec[adcBinIdx] + erosionVec[adcBinIdx]) / 2;
416  medianVec[adcBinIdx] = adcBinValVec[adcBinValVec.size()/2];
417  }
418 
419  saveRawDigits(erosionRawDigit, midChannel, midPedestal, midRmsVal, std::get<3>(erosionTuple));
420  saveRawDigits(dilationRawDigit, midChannel, midPedestal, midRmsVal, std::get<3>(dilationTuple));
421  saveRawDigits(edgeRawDigit, midChannel, midPedestal, midRmsVal, std::get<3>(edgeTuple));
422  saveRawDigits(differenceRawDigit, midChannel, midPedestal, midRmsVal, std::get<3>(differenceTuple));
423  saveRawDigits(averageRawDigit, midChannel, midPedestal, midRmsVal, std::get<3>(averageTuple));
424  saveRawDigits(medianRawDigit, midChannel, midPedestal, midRmsVal, std::get<3>(medianTuple));
425  }
426  else if (validIndex <= fStructuringElementWireSize / 2)
427  {
428  saveRawDigits(erosionRawDigit, **inputWaveItr);
429  saveRawDigits(dilationRawDigit, **inputWaveItr);
430  saveRawDigits(edgeRawDigit, **inputWaveItr);
431  saveRawDigits(differenceRawDigit, **inputWaveItr);
432  saveRawDigits(averageRawDigit, **inputWaveItr);
433  saveRawDigits(medianRawDigit, **inputWaveItr);
434  }
435  }
436  }
437 /*
438  if (fOutputWaveforms)
439  {
440  // Try to limit to the wire number (since we are already segregated by plane)
441  std::vector<geo::WireID> wids = fGeometry->ChannelToWire(channel);
442  size_t cryo = wids[0].Cryostat;
443  size_t tpc = wids[0].TPC;
444  size_t plane = wids[0].Plane;
445  size_t wire = wids[0].Wire;
446 
447  // Make a directory for these histograms
448  art::TFileDirectory dir = fHistDirectory->mkdir(Form("ROIPlane_%1zu/c%1zu/c%1zut%1zuwire_%05zu",fPlane,cnt,cryo,tpc,wire));
449 
450  // We keep track of four histograms:
451  try
452  {
453  // origWaveHist = dir.make<TProfile>(Form("Inp_%03zu_ctw%01zu/%01zu/%05zu",cnt,cryo,tpc,wire), "Waveform", waveform.size(), 0, waveform.size(), -500., 500.);
454  histogramMap[icarus_tool::WAVEFORM] =
455  dir.make<TProfile>(Form("Wfm_%03zu_ctw%01zu-%01zu-%01zu-%05zu",cnt,cryo,tpc,plane,wire), "Waveform", waveformSize, 0, waveformSize, -500., 500.);
456  histogramMap[icarus_tool::EROSION] =
457  dir.make<TProfile>(Form("Ero_%03zu_ctw%01zu-%01zu-%01zu-%05zu",cnt,cryo,tpc,plane,wire), "Erosion", waveformSize, 0, waveformSize, -500., 500.);
458  histogramMap[icarus_tool::DILATION] =
459  dir.make<TProfile>(Form("Dil_%03zu_ctw%01zu-%01zu-%01zu-%05zu",cnt,cryo,tpc,plane,wire), "Dilation", waveformSize, 0, waveformSize, -500., 500.);
460  histogramMap[icarus_tool::AVERAGE] =
461  dir.make<TProfile>(Form("Ave_%03zu_ctw%01zu-%01zu-%01zu-%05zu",cnt,cryo,tpc,plane,wire), "Average", waveformSize, 0, waveformSize, -500., 500.);
462  histogramMap[icarus_tool::DIFFERENCE] =
463  dir.make<TProfile>(Form("Dif_%03zu_ctw%01zu-%01zu-%01zu-%05zu",cnt,cryo,tpc,plane,wire), "Average", waveformSize, 0, waveformSize, -500., 500.);
464 
465  // This is a kludge so that the ROI histogram ends up in the same diretory as the waveforms
466  histogramMap[ROIHISTOGRAM] =
467  dir.make<TProfile>(Form("ROI_%03zu_ctw%01zu-%01zu-%01zu-%05zu",cnt,cryo,tpc,plane,wire), "ROI", waveformSize, 0, waveformSize, -500., 500.);
468 
469  // Also, if smoothing then we would like to keep track of the original waveform too
470  histogramMap[WAVEFORMHIST] =
471  dir.make<TProfile>(Form("Inp_%03zu_ctw%01zu-%01zu-%01zu-%05zu",cnt,cryo,tpc,plane,wire), "Waveform", waveformSize, 0, waveformSize, -500., 500.);
472  } catch(...)
473  {
474  std::cout << "Caught exception trying to make new hists, tpc,plane,cnt,wire: " << tpc << ", " << fPlane << ", " << cnt << ", " << wire << std::endl;
475  }
476  }
477 */
478  // Add tracks and associations to event.
479  event.put(std::move(erosionRawDigit), "erosion");
480  event.put(std::move(dilationRawDigit), "dilation");
481  event.put(std::move(edgeRawDigit), "edge");
482  event.put(std::move(differenceRawDigit), "difference");
483  event.put(std::move(averageRawDigit), "average");
484  event.put(std::move(medianRawDigit), "median");
485 
486  return;
487 }
488 
489 void RawDigitSmoother::saveRawDigits(std::unique_ptr<std::vector<raw::RawDigit> >& filteredRawDigit,
490  WireTuple& wireTuple)
491 {
492  raw::ChannelID_t& channel = std::get<0>(wireTuple);
493  float pedestal = std::get<1>(wireTuple);
494  float rms = std::get<2>(wireTuple);
495  caldata::RawDigitVector& rawDigitVec = std::get<3>(wireTuple);
496 
497  filteredRawDigit->emplace_back(channel, rawDigitVec.size(), rawDigitVec, raw::kNone);
498  filteredRawDigit->back().SetPedestal(pedestal,rms);
499 
500  return;
501 }
502 
503 void RawDigitSmoother::RawDigitSmoother::saveRawDigits(std::unique_ptr<std::vector<raw::RawDigit> >& filteredRawDigit,
504  raw::ChannelID_t& channel,
505  float pedestal,
506  float rms,
507  caldata::RawDigitVector& rawDigitVec)
508 {
509  filteredRawDigit->emplace_back(channel, rawDigitVec.size(), rawDigitVec, raw::kNone);
510  filteredRawDigit->back().SetPedestal(pedestal,rms);
511 
512  return;
513 }
514 
515 //----------------------------------------------------------------------------
516 /// End job method.
518 {
519  mf::LogInfo("RawDigitSmoother") << "Looked at " << fNumEvent << " events" << std::endl;
520 }
virtual void configure(fhicl::ParameterSet const &pset)
Collection of charge vs time digitized from a single readout channel.
Definition: RawDigit.h:69
virtual ~RawDigitSmoother()
Destructor.
static constexpr Sample_t transform(Sample_t sample)
void getMeanRmsAndPedCor(const RawDigitVector &rawWaveform, unsigned int channel, unsigned int view, unsigned int wire, float &aveVal, float &rmsVal, float &pedCorVal) const
virtual void endJob()
End job method.
geo::GeometryCore const * fGeometry
pointer to Geometry service
virtual void produce(art::Event &e)
walls no right
Definition: selectors.fcl:105
RawDigitSmoother(fhicl::ParameterSet const &pset)
ChannelID_t Channel() const
DAQ channel this raw data was read from.
Definition: RawDigit.h:212
const lariov::DetPedestalProvider & fPedestalRetrievalAlg
Keep track of an instance to the pedestal retrieval alg.
raw::RawDigit::ADCvector_t RawDigitVector
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::vector< std::vector< short >> StructuringElement
art::TFileDirectory * fHistDirectory
no compression
Definition: RawTypes.h:9
void saveRawDigits(std::unique_ptr< std::vector< raw::RawDigit > > &, WireTuple &)
unsigned int Nchannels() const
Returns the number of TPC readout channels in the detector.
Collect all the RawData header files together.
std::list< WireTuple * > WaveformList
virtual void beginJob()
Begin job method.
walls no left
Definition: selectors.fcl:105
constexpr PlaneID const & asPlaneID() const
Conversion to PlaneID (for convenience of notation).
Definition: geo_types.h:534
std::string fDigitModuleLabel
The full collection of hits.
Description of geometry of one entire detector.
virtual float PedMean(raw::ChannelID_t ch) const =0
Retrieve pedestal information.
std::vector< WireTuple > WaveformVec
caldata::RawDigitCharacterizationAlg fCharacterizationAlg
do i e
art::ServiceHandle< art::TFileService > tfs
std::tuple< raw::ChannelID_t, float, float, caldata::RawDigitVector > WireTuple
unsigned int ChannelID_t
Type representing the ID of a readout channel.
Definition: RawTypes.h:28
void Uncompress(const std::vector< short > &adc, std::vector< short > &uncompressed, raw::Compress_t compress)
Uncompresses a raw data buffer.
Definition: raw.cxx:776
int fNumEvent
Number of events seen.
void initializeHists(art::ServiceHandle< art::TFileService > &)
Begin job method.
bool fOutputWaveforms
Output waveforms?
constexpr int cmp(PlaneID const &other) const
Returns &lt; 0 if this is smaller than other, 0 if equal, &gt; 0 if larger.
Definition: geo_types.h:541
bool fOutputHistograms
Output histograms?
art framework interface to geometry description
BEGIN_PROLOG could also be cout
StructuringElement fStructuringElement