All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DaqDecoderICARUSTPC_module.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Class: DaqDecoderICARUSTPC
4 // Module Type: producer
5 // File: DaqDecoderICARUSTPC_module.cc
6 //
7 // The intent of this module is to both "decode" artdaq fragments
8 // and convert to RawDigits and also to do the initial noise
9 // filtering, specifically the coherent noise.
10 //
11 // Configuration parameters:
12 //
13 // DigitModuleLabel - the source of the RawDigit collection
14 //
15 //
16 // Modeled after example from Mike Wang (mwang@fnal.gov)
17 // Copied/Modified by Tracy Usher (usher@slac.stanford.edu) on January 27, 2020
18 //
19 ////////////////////////////////////////////////////////////////////////
20 
21 #include <cmath>
22 #include <algorithm>
23 #include <vector>
24 #include <iterator>
25 
26 #include "art/Framework/Core/ReplicatedProducer.h"
27 #include "art/Framework/Principal/Event.h"
28 #include "art/Framework/Services/Registry/ServiceHandle.h"
29 #include "art_root_io/TFileService.h"
30 #include "art/Framework/Core/ModuleMacros.h"
31 #include "art/Utilities/make_tool.h"
32 #include "canvas/Persistency/Common/Ptr.h"
33 #include "messagefacility/MessageLogger/MessageLogger.h"
34 #include "cetlib/cpu_timer.h"
35 
36 #include "tbb/parallel_for.h"
37 #include "tbb/blocked_range.h"
38 #include "tbb/task_arena.h"
39 #include "tbb/spin_mutex.h"
40 #include "tbb/concurrent_vector.h"
41 
43 #include "larcore/CoreUtils/ServiceUtil.h" // lar::providerFrom()
46 
47 #include "sbndaq-artdaq-core/Overlays/ICARUS/PhysCrateFragment.hh"
48 
50 
51 #include "icarus_signal_processing/ICARUSSigProcDefs.h"
52 #include "icarus_signal_processing/WaveformTools.h"
53 
54 namespace daq
55 {
56 
57 class DaqDecoderICARUSTPC : public art::ReplicatedProducer
58 {
59 public:
60 
61  // Copnstructors, destructor.
62  explicit DaqDecoderICARUSTPC(fhicl::ParameterSet const & pset, art::ProcessingFrame const& frame);
63  virtual ~DaqDecoderICARUSTPC();
64 
65  // Overrides.
66  virtual void configure(fhicl::ParameterSet const & pset);
67  virtual void produce(art::Event & e, art::ProcessingFrame const& frame);
68  virtual void beginJob(art::ProcessingFrame const& frame);
69  virtual void endJob(art::ProcessingFrame const& frame);
70 
71  // Define the RawDigit collection
72  using RawDigitCollection = std::vector<raw::RawDigit>;
73  using RawDigitCollectionPtr = std::unique_ptr<RawDigitCollection>;
74  using ConcurrentRawDigitCol = tbb::concurrent_vector<raw::RawDigit>;
75 
76  // Function to do the work
77  void processSingleFragment(size_t,
78  detinfo::DetectorClocksData const& clockData,
79  art::Handle<artdaq::Fragments>, ConcurrentRawDigitCol&, ConcurrentRawDigitCol&, ConcurrentRawDigitCol&) const;
80 
81 private:
82 
84  {
85  public:
87  detinfo::DetectorClocksData const& clockData,
88  art::Handle<artdaq::Fragments>& fragmentsHandle,
89  ConcurrentRawDigitCol& rawDigitCollection,
90  ConcurrentRawDigitCol& rawRawDigitCollection,
91  ConcurrentRawDigitCol& coherentCollection)
92  : fDaqDecoderICARUSTPC(parent),
93  fClockData{clockData},
94  fFragmentsHandle(fragmentsHandle),
95  fRawDigitCollection(rawDigitCollection),
96  fRawRawDigitCollection(rawRawDigitCollection),
97  fCoherentCollection(coherentCollection)
98  {}
99 
100  void operator()(const tbb::blocked_range<size_t>& range) const
101  {
102  for (size_t idx = range.begin(); idx < range.end(); idx++)
104  }
105  private:
108  art::Handle<artdaq::Fragments>& fFragmentsHandle;
112  };
113 
114  // Function to save our RawDigits
115  void saveRawDigits(const icarus_signal_processing::ArrayFloat&,
116  const icarus_signal_processing::VectorFloat&,
117  const icarus_signal_processing::VectorFloat&,
118  const icarus_signal_processing::VectorInt&,
119  ConcurrentRawDigitCol&) const;
120 
121  // Tools for decoding fragments depending on type
122  std::vector<std::unique_ptr<IDecoderFilter>> fDecoderToolVec; ///< Decoder tools
123 
124  // Fcl parameters.
125  std::vector<art::InputTag> fFragmentsLabelVec; ///< The input artdaq fragment label vector (for more than one)
126  bool fOutputRawWaveform; ///< Should we output pedestal corrected (not noise filtered)?
127  bool fOutputCorrection; ///< Should we output the coherent noise correction vectors?
128  std::string fOutputRawWavePath; ///< Path to assign to the output if asked for
129  std::string fOutputCoherentPath; ///< Path to assign to the output if asked for
130  unsigned int fPlaneToSimulate; ///< Use to get fragment offset
131  float fSigmaForTruncation; ///< This determines the point at which we truncate bins for the RMS calc
132 
133  // Statistics.
134  int fNumEvent; ///< Number of events seen.
135 
136  size_t fFragmentOffset; ///< The fragment offset to set channel numbering
137 
138  // Useful services, keep copies for now (we can update during begin run periods)
139  geo::GeometryCore const* fGeometry; ///< pointer to Geometry service
140 };
141 
142 DEFINE_ART_MODULE(DaqDecoderICARUSTPC)
143 
144 //----------------------------------------------------------------------------
145 /// Constructor.
146 ///
147 /// Arguments:
148 ///
149 /// pset - Fcl parameters.
150 ///
151 DaqDecoderICARUSTPC::DaqDecoderICARUSTPC(fhicl::ParameterSet const & pset, art::ProcessingFrame const& frame) :
152  art::ReplicatedProducer(pset, frame),
153  fNumEvent(0)
154 {
155  fGeometry = lar::providerFrom<geo::Geometry>();
156 
157  configure(pset);
158 
159  // Check the concurrency
160  int max_concurrency = tbb::this_task_arena::max_concurrency();
161 
162  mf::LogDebug("DaqDecoderICARUSTPC") << " ==> concurrency: " << max_concurrency << std::endl;
163 
164  // Recover the vector of fhicl parameters for the ROI tools
165  const fhicl::ParameterSet& decoderToolParams = pset.get<fhicl::ParameterSet>("DecoderTool");
166 
167  fDecoderToolVec.resize(max_concurrency);
168 
169  for(auto& decoderTool : fDecoderToolVec)
170  {
171  // Get instance of tool
172  decoderTool = art::make_tool<IDecoderFilter>(decoderToolParams);
173  }
174 
175  // Compute the fragment offset from the channel number for the desired plane
176  // Get a base channel number for the plane we want
177  mf::LogDebug("DaqDecoderICARUSTPC") << "ICARUS has " << fGeometry->Nchannels() << " in total with " << fGeometry->Views().size() << " views" << std::endl;
178 
179  geo::WireID wireID(0, 0, fPlaneToSimulate, 0);
180 
181  mf::LogDebug("DaqDecoderICARUSTPC") << "WireID: " << wireID << std::endl;
182 
183  geo::WireID firstWireID = fGeometry->GetBeginWireID(geo::PlaneID(0,0,fPlaneToSimulate));
184 
185  mf::LogDebug("DaqDecoderICARUSTPC") << "From geo, first WireID: " << firstWireID << std::endl;
186 
187  raw::ChannelID_t channel = fGeometry->PlaneWireToChannel(wireID);
188 
189  mf::LogDebug("DaqDecoderICARUSTPC") << "Channel: " << channel << std::endl;
190 
191  for(size_t thePlane = 0; thePlane < 3; thePlane++)
192  {
193  geo::WireID tempWireID(0, 0, thePlane, 0);
194  geo::PlaneID tempPlaneID = tempWireID.planeID();
195 
196  mf::LogDebug("DaqDecoderICARUSTPC") << "thePlane: " << thePlane << ", WireID: " << tempWireID << ", channel: " <<
197  fGeometry->PlaneWireToChannel(tempWireID) << ", view: " << fGeometry->View(tempPlaneID) << std::endl;
198  }
199 
200  fFragmentOffset = channel / 576;
201 
202  // Set up our "produces"
203  // Note that we can have multiple instances input to the module
204  // Our convention will be to create a similar number of outputs with the same instance names
205  for(const auto& fragmentLabel : fFragmentsLabelVec)
206  {
207  produces<std::vector<raw::RawDigit>>(fragmentLabel.instance());
208 
209  if (fOutputRawWaveform)
210  produces<std::vector<raw::RawDigit>>(fragmentLabel.instance() + fOutputRawWavePath);
211 
212  if (fOutputCorrection)
213  produces<std::vector<raw::RawDigit>>(fragmentLabel.instance() + fOutputCoherentPath);
214  }
215 
216  // Report.
217  mf::LogInfo("DaqDecoderICARUSTPC") << "DaqDecoderICARUSTPC configured\n";
218 }
219 
220 //----------------------------------------------------------------------------
221 /// Destructor.
223 {}
224 
225 //----------------------------------------------------------------------------
226 /// Reconfigure method.
227 ///
228 /// Arguments:
229 ///
230 /// pset - Fcl parameter set.
231 ///
232 void DaqDecoderICARUSTPC::configure(fhicl::ParameterSet const & pset)
233 {
234  fFragmentsLabelVec = pset.get<std::vector<art::InputTag>>("FragmentsLabelVec", std::vector<art::InputTag>()={"daq:PHYSCRATEDATA"});
235  fOutputRawWaveform = pset.get<bool >("OutputRawWaveform", false);
236  fOutputCorrection = pset.get<bool >("OutputCorrection", false);
237  fOutputRawWavePath = pset.get<std::string >("OutputRawWavePath", "raw");
238  fOutputCoherentPath = pset.get<std::string >("OutputCoherentPath", "Cor");
239  fPlaneToSimulate = pset.get<unsigned int >("PlaneToSimulate", 2);
240  fSigmaForTruncation = pset.get<float >("NSigmaForTrucation", 3.5);
241 }
242 
243 //----------------------------------------------------------------------------
244 /// Begin job method.
245 void DaqDecoderICARUSTPC::beginJob(art::ProcessingFrame const&)
246 {
247  return;
248 }
249 
250 //----------------------------------------------------------------------------
251 /// Produce method.
252 ///
253 /// Arguments:
254 ///
255 /// evt - Art event.
256 ///
257 /// This is the primary method.
258 ///
259 void DaqDecoderICARUSTPC::produce(art::Event & event, art::ProcessingFrame const&)
260 {
261  ++fNumEvent;
262 
263  mf::LogDebug("DaqDecoderICARUSTPC") << "**** Processing raw data fragments ****" << std::endl;
264 
265  // Check the concurrency
266  int max_concurrency = tbb::this_task_arena::max_concurrency();
267 
268  mf::LogDebug("DaqDecoderICARUSTPC") << " ==> concurrency: " << max_concurrency << std::endl;
269 
270 
271  std::cout << "------------------------------------------------------------------------------------------" << std::endl;
272  std::cout << "===> Run: " << event.id().run() << ", subrn: " << event.id().subRun() << ", event: " << event.id().event() << std::endl;
273 
274  cet::cpu_timer theClockTotal;
275 
276  theClockTotal.start();
277 
278  // Loop through the list of input daq fragment collections one by one
279  // We are not trying to multi thread at this stage because we are trying to control
280  // overall memory usage at this level. We'll multi thread internally...
281  for(const auto& fragmentLabel : fFragmentsLabelVec)
282  {
283  art::Handle<artdaq::Fragments> daq_handle;
284  event.getByLabel(fragmentLabel, daq_handle);
285 
286  ConcurrentRawDigitCol concurrentRawDigits;
287  ConcurrentRawDigitCol concurrentRawRawDigits;
288  ConcurrentRawDigitCol coherentRawDigits;
289 
290  // ... Launch multiple threads with TBB to do the deconvolution and find ROIs in parallel
291  auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService>()->DataFor(event);
292  multiThreadFragmentProcessing fragmentProcessing(*this,
293  clockData,
294  daq_handle,
295  concurrentRawDigits,
296  concurrentRawRawDigits,
297  coherentRawDigits);
298 
299  tbb::parallel_for(tbb::blocked_range<size_t>(0, daq_handle->size()), fragmentProcessing);
300 
301  // Copy the raw digits from the concurrent vector to our output vector
302  RawDigitCollectionPtr rawDigitCollection = std::make_unique<std::vector<raw::RawDigit>>(std::move_iterator(concurrentRawDigits.begin()),
303  std::move_iterator(concurrentRawDigits.end()));
304 
305  // Want the RawDigits to be sorted in channel order... has to be done somewhere so why not now?
306  std::sort(rawDigitCollection->begin(),rawDigitCollection->end(),[](const auto& left,const auto&right){return left.Channel() < right.Channel();});
307 
308  // Now transfer ownership to the event store
309  event.put(std::move(rawDigitCollection), fragmentLabel.instance());
310 
311  if (fOutputRawWaveform)
312  {
313  // Copy the raw digits from the concurrent vector to our output vector
314  RawDigitCollectionPtr rawRawDigitCollection = std::make_unique<std::vector<raw::RawDigit>>(std::move_iterator(concurrentRawRawDigits.begin()),
315  std::move_iterator(concurrentRawRawDigits.end()));
316 
317  // Want the RawDigits to be sorted in channel order... has to be done somewhere so why not now?
318  std::sort(rawRawDigitCollection->begin(),rawRawDigitCollection->end(),[](const auto& left,const auto&right){return left.Channel() < right.Channel();});
319 
320  // Now transfer ownership to the event store
321  event.put(std::move(rawRawDigitCollection),fragmentLabel.instance() + fOutputRawWavePath);
322  }
323 
324  if (fOutputCorrection)
325  {
326  // Copy the raw digits from the concurrent vector to our output vector
327  RawDigitCollectionPtr coherentCollection = std::make_unique<std::vector<raw::RawDigit>>(std::move_iterator(coherentRawDigits.begin()),
328  std::move_iterator(coherentRawDigits.end()));
329 
330  // Want the RawDigits to be sorted in channel order... has to be done somewhere so why not now?
331  std::sort(coherentCollection->begin(),coherentCollection->end(),[](const auto& left,const auto&right){return left.Channel() < right.Channel();});
332 
333  // Now transfer ownership to the event store
334  event.put(std::move(coherentCollection),fragmentLabel.instance() + fOutputCoherentPath);
335  }
336  }
337 
338  theClockTotal.stop();
339 
340  double totalTime = theClockTotal.accumulated_real_time();
341 
342  mf::LogInfo("DaqDecoderICARUSTPC") << "==> DaqDecoderICARUSTPC total time: " << totalTime << std::endl;
343 
344  return;
345 }
346 
348  detinfo::DetectorClocksData const& clockData,
349  art::Handle<artdaq::Fragments> fragmentHandle,
350  ConcurrentRawDigitCol& rawDigitCollection,
351  ConcurrentRawDigitCol& rawRawDigitCollection,
352  ConcurrentRawDigitCol& coherentCollection) const
353 {
354  cet::cpu_timer theClockProcess;
355 
356  theClockProcess.start();
357 
358  art::Ptr<artdaq::Fragment> fragmentPtr(fragmentHandle, idx);
359 
360  mf::LogDebug("DaqDecoderICARUSTPC") << "--> Processing fragment ID: " << fragmentPtr->fragmentID() << std::endl;
361  mf::LogDebug("DaqDecoderICARUSTPC") << " ==> Current thread index: " << tbb::this_task_arena::current_thread_index() << std::endl;
362 
363  // Recover pointer to the decoder needed here
364  IDecoderFilter* decoderTool = fDecoderToolVec[tbb::this_task_arena::current_thread_index()].get();
365 
366  //process_fragment(event, rawfrag, product_collection, header_collection);
367  decoderTool->process_fragment(clockData, *fragmentPtr);
368 
369  // Useful numerology
370  // convert fragment to Nevis fragment
371  icarus::PhysCrateFragment physCrateFragment(*fragmentPtr);
372 
373 // size_t nBoardsPerFragment = physCrateFragment.nBoards();
374 // size_t nChannelsPerBoard = physCrateFragment.nChannelsPerBoard();
375 
376  // Set base channel for both the board and the board/fragment
377 // size_t boardFragOffset = nChannelsPerBoard * nBoardsPerFragment * (fragmentPtr->fragmentID() + fFragmentOffset);
378 
379  theClockProcess.stop();
380 
381  double totalTime = theClockProcess.accumulated_real_time();
382 
383  // We need to recalculate pedestals for the noise corrected waveforms
384  icarus_signal_processing::WaveformTools<float> waveformTools;
385 
386  // Save the filtered RawDigitsactive but for corrected raw digits pedestal is zero
387  icarus_signal_processing::VectorFloat locPedsVec(decoderTool->getWaveLessCoherent().size(),0.);
388  icarus_signal_processing::VectorFloat locFullRMSVec(locPedsVec.size(),0.);
389  icarus_signal_processing::VectorFloat locTruncRMSVec(locPedsVec.size(),0.);
390  icarus_signal_processing::VectorInt locNumTruncBins(locPedsVec.size(),0);
391  icarus_signal_processing::VectorInt locRangeBins(locPedsVec.size(),0);
392 
393  const icarus_signal_processing::VectorInt& channelVec = decoderTool->getChannelIDs();
394  const icarus_signal_processing::ArrayFloat& corWaveforms = decoderTool->getWaveLessCoherent();
395 
396  icarus_signal_processing::ArrayFloat pedCorWaveforms(corWaveforms.size(),icarus_signal_processing::VectorFloat(corWaveforms[0].size()));
397 
398  for(size_t idx = 0; idx < corWaveforms.size(); idx++)
399  {
400  // Now determine the pedestal and correct for it
401  waveformTools.getPedestalCorrectedWaveform(corWaveforms[idx],
402  pedCorWaveforms[idx],
404  locPedsVec[idx],
405  locFullRMSVec[idx],
406  locTruncRMSVec[idx],
407  locNumTruncBins[idx],
408  locRangeBins[idx]);
409  }
410 
411  saveRawDigits(pedCorWaveforms, locPedsVec, locTruncRMSVec, channelVec, rawDigitCollection);
412 
413  // Optionally, save the raw RawDigits
414  if (fOutputRawWaveform)
415  saveRawDigits(decoderTool->getRawWaveforms(),decoderTool->getPedestalVals(),decoderTool->getFullRMSVals(),channelVec, rawRawDigitCollection);
416 
417  // Also optional is to output the coherent corrections (note there will be many fewer of these! )
418  if (fOutputCorrection)
419 // saveRawDigits(decoderTool->getCorrectedMedians(),decoderTool->getPedestalVals(),decoderTool->getFullRMSVals(),channelVec,coherentCollection);
420  saveRawDigits(decoderTool->getCorrectedMedians(),locPedsVec,decoderTool->getFullRMSVals(),channelVec,coherentCollection);
421 
422  mf::LogDebug("DaqDecoderICARUSTPC") << "--> Exiting fragment processing for thread: " << tbb::this_task_arena::current_thread_index() << ", time: " << totalTime << std::endl;
423  return;
424 }
425 
426 void DaqDecoderICARUSTPC::saveRawDigits(const icarus_signal_processing::ArrayFloat& dataArray,
427  const icarus_signal_processing::VectorFloat& pedestalVec,
428  const icarus_signal_processing::VectorFloat& rmsVec,
429  const icarus_signal_processing::VectorInt& channelVec,
430  ConcurrentRawDigitCol& rawDigitCol) const
431 {
432  if (!dataArray.empty())
433  {
434  cet::cpu_timer theClockSave;
435 
436  theClockSave.start();
437 
438  raw::RawDigit::ADCvector_t wvfm(dataArray[0].size());
439 
440  mf::LogDebug("DaqDecoderICARUSTPC") << " --> saving rawdigits for " << dataArray.size() << " channels" << std::endl;
441 
442  // Loop over the channels to recover the RawDigits after filtering
443  for(size_t chanIdx = 0; chanIdx != dataArray.size(); chanIdx++)
444  {
445  // Protect against case where there was no readout
446  if (channelVec[chanIdx] < 0) continue;
447 
448  const icarus_signal_processing::VectorFloat& dataVec = dataArray[chanIdx];
449 
450  // Need to convert from float to short int
451  std::transform(dataVec.begin(),dataVec.end(),wvfm.begin(),[](const auto& val){return short(std::round(val));});
452 
453  ConcurrentRawDigitCol::iterator newObjItr = rawDigitCol.emplace_back(channelVec[chanIdx],wvfm.size(),wvfm);
454  newObjItr->SetPedestal(pedestalVec[chanIdx],rmsVec[chanIdx]);
455  }//loop over channel indices
456 
457  theClockSave.stop();
458 
459  double totalTime = theClockSave.accumulated_real_time();
460 
461  mf::LogDebug("DaqDecoderICARUSTPC") << " --> done with save, time: " << totalTime << std::endl;
462  }
463 
464  return;
465 }
466 
467 //----------------------------------------------------------------------------
468 /// End job method.
469 void DaqDecoderICARUSTPC::endJob(art::ProcessingFrame const&)
470 {
471  mf::LogInfo("DaqDecoderICARUSTPC") << "Looked at " << fNumEvent << " events" << std::endl;
472 }
473 
474 } // end of namespace
DaqDecoderICARUSTPC(fhicl::ParameterSet const &pset, art::ProcessingFrame const &frame)
virtual void configure(fhicl::ParameterSet const &pset)
Utilities related to art service access.
tbb::concurrent_vector< raw::RawDigit > ConcurrentRawDigitCol
static constexpr Sample_t transform(Sample_t sample)
virtual const icarus_signal_processing::VectorInt getChannelIDs() const =0
Recover the channels for the processed fragment.
std::vector< std::unique_ptr< IDecoderFilter > > fDecoderToolVec
Decoder tools.
float fSigmaForTruncation
This determines the point at which we truncate bins for the RMS calc.
bool fOutputCorrection
Should we output the coherent noise correction vectors?
walls no right
Definition: selectors.fcl:105
void processSingleFragment(size_t, detinfo::DetectorClocksData const &clockData, art::Handle< artdaq::Fragments >, ConcurrentRawDigitCol &, ConcurrentRawDigitCol &, ConcurrentRawDigitCol &) const
The data type to uniquely identify a Plane.
Definition: geo_types.h:472
std::string fOutputCoherentPath
Path to assign to the output if asked for.
std::vector< short > ADCvector_t
Type representing a (compressed) vector of ADC counts.
Definition: RawDigit.h:73
IDecoderFilter interface class definiton.
Definition of basic raw digits.
std::size_t size(FixedBins< T, C > const &) noexcept
Definition: FixedBins.h:561
int fNumEvent
Number of events seen.
virtual ~DaqDecoderICARUSTPC()
Destructor.
bool fOutputRawWaveform
Should we output pedestal corrected (not noise filtered)?
multiThreadFragmentProcessing(DaqDecoderICARUSTPC const &parent, detinfo::DetectorClocksData const &clockData, art::Handle< artdaq::Fragments > &fragmentsHandle, ConcurrentRawDigitCol &rawDigitCollection, ConcurrentRawDigitCol &rawRawDigitCollection, ConcurrentRawDigitCol &coherentCollection)
unsigned int fPlaneToSimulate
Use to get fragment offset.
virtual const icarus_signal_processing::ArrayFloat getWaveLessCoherent() const =0
Recover the waveforms less coherent noise.
virtual void beginJob(art::ProcessingFrame const &frame)
Begin job method.
This provides an art tool interface definition for tools which &quot;decode&quot; artdaq fragments into LArSoft...
std::vector< raw::RawDigit > RawDigitCollection
virtual void process_fragment(detinfo::DetectorClocksData const &clockData, const artdaq::Fragment &fragment)=0
Given a set of recob hits, run DBscan to form 3D clusters.
std::unique_ptr< RawDigitCollection > RawDigitCollectionPtr
geo::GeometryCore const * fGeometry
pointer to Geometry service
virtual const icarus_signal_processing::ArrayFloat getCorrectedMedians() const =0
Recover the correction median values.
size_t fFragmentOffset
The fragment offset to set channel numbering.
void operator()(const tbb::blocked_range< size_t > &range) const
walls no left
Definition: selectors.fcl:105
Description of geometry of one entire detector.
virtual void endJob(art::ProcessingFrame const &frame)
End job method.
virtual void produce(art::Event &e, art::ProcessingFrame const &frame)
void saveRawDigits(const icarus_signal_processing::ArrayFloat &, const icarus_signal_processing::VectorFloat &, const icarus_signal_processing::VectorFloat &, const icarus_signal_processing::VectorInt &, ConcurrentRawDigitCol &) const
std::vector< art::InputTag > fFragmentsLabelVec
The input artdaq fragment label vector (for more than one)
Contains all timing reference information for the detector.
virtual const icarus_signal_processing::VectorFloat getFullRMSVals() const =0
Recover the full RMS before coherent noise.
do i e
virtual const icarus_signal_processing::VectorFloat getPedestalVals() const =0
Recover the pedestals for each channel.
virtual const icarus_signal_processing::ArrayFloat getRawWaveforms() const =0
Recover the original raw waveforms.
constexpr PlaneID const & planeID() const
Definition: geo_types.h:638
unsigned int ChannelID_t
Type representing the ID of a readout channel.
Definition: RawTypes.h:28
std::string fOutputRawWavePath
Path to assign to the output if asked for.
art framework interface to geometry description
BEGIN_PROLOG could also be cout