All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TPCDecoderFilter2D_tool.cc
Go to the documentation of this file.
1 /**
2  * @file TPCDecoderFilter2D_tool.cc
3  *
4  * @brief This tool converts from daq to LArSoft format with noise filtering
5  *
6  */
7 
8 // Framework Includes
9 #include "art/Framework/Core/EDProducer.h"
10 #include "art/Framework/Principal/Event.h"
11 #include "art/Framework/Principal/Handle.h"
12 #include "art/Framework/Services/Registry/ServiceHandle.h"
13 #include "art/Persistency/Common/PtrMaker.h"
14 #include "art/Utilities/ToolMacros.h"
15 #include "art/Utilities/make_tool.h"
16 #include "cetlib/cpu_timer.h"
17 #include "fhiclcpp/ParameterSet.h"
18 #include "messagefacility/MessageLogger/MessageLogger.h"
19 
20 // LArSoft includes
22 
23 #include "sbndaq-artdaq-core/Overlays/ICARUS/PhysCrateFragment.hh"
24 
27 
28 #include "icarus_signal_processing/WaveformTools.h"
29 #include "icarus_signal_processing/Denoising.h"
30 #include "icarus_signal_processing/Filters/FFTFilterFunctions.h"
31 
32 // std includes
33 #include <string>
34 #include <iostream>
35 #include <memory>
36 
37 //------------------------------------------------------------------------------------------------------------------------------------------
38 // implementation follows
39 
40 namespace daq {
41 /**
42  * @brief TPCDecoderFilter2D class definiton
43  */
44 class TPCDecoderFilter2D : virtual public IDecoderFilter
45 {
46 public:
47  /**
48  * @brief Constructor
49  *
50  * @param pset
51  */
52  explicit TPCDecoderFilter2D(fhicl::ParameterSet const &pset);
53 
54  /**
55  * @brief Destructor
56  */
58 
59  /**
60  * @brief Interface for configuring the particular algorithm tool
61  *
62  * @param ParameterSet The input set of parameters for configuration
63  */
64  virtual void configure(const fhicl::ParameterSet&) override;
65 
66  /**
67  * @brief Given a set of recob hits, run DBscan to form 3D clusters
68  *
69  * @param fragment The artdaq fragment to process
70  */
72  const artdaq::Fragment&) override;
73 
74  /**
75  * @brief Recover the channels for the processed fragment
76  */
77  const icarus_signal_processing::VectorInt getChannelIDs() const override {return fChannelIDVec;}
78 
79  /**
80  * @brief Recover the selection values
81  */
82  const icarus_signal_processing::ArrayBool getSelectionVals() const override {return fSelectVals;};
83 
84  /**
85  * @brief Recover the ROI values
86  */
87  const icarus_signal_processing::ArrayBool getROIVals() const override {return fROIVals;};
88 
89  /**
90  * @brief Recover the pedestal subtracted waveforms
91  */
92  const icarus_signal_processing::ArrayFloat getRawWaveforms() const override {return fRawWaveforms;};
93 
94  /**
95  * @brief Recover the pedestal subtracted waveforms
96  */
97  const icarus_signal_processing::ArrayFloat getPedCorWaveforms() const override {return fPedCorWaveforms;};
98 
99  /**
100  * @brief Recover the "intrinsic" RMS
101  */
102  const icarus_signal_processing::ArrayFloat getIntrinsicRMS() const override {return fIntrinsicRMS;};
103 
104  /**
105  * @brief Recover the correction median values
106  */
107  const icarus_signal_processing::ArrayFloat getCorrectedMedians() const override {return fCorrectedMedians;};
108 
109  /**
110  * @brief Recover the waveforms less coherent noise
111  */
112  const icarus_signal_processing::ArrayFloat getWaveLessCoherent() const override {return fWaveLessCoherent;};
113 
114  /**
115  * @brief Recover the morphological filter waveforms
116  */
117  const icarus_signal_processing::ArrayFloat getMorphedWaveforms() const override {return fMorphedWaveforms;};
118 
119  /**
120  * @brief Recover the pedestals for each channel
121  */
122  const icarus_signal_processing::VectorFloat getPedestalVals() const override {return fPedestalVals;};
123 
124  /**
125  * @brief Recover the full RMS before coherent noise
126  */
127  const icarus_signal_processing::VectorFloat getFullRMSVals() const override {return fFullRMSVals;};
128 
129  /**
130  * @brief Recover the truncated RMS noise
131  */
132  const icarus_signal_processing::VectorFloat getTruncRMSVals() const override {return fTruncRMSVals;};
133 
134  /**
135  * @brief Recover the number of bins after truncation
136  */
137  const icarus_signal_processing::VectorInt getNumTruncBins() const override {return fNumTruncBins;};
138 
139 private:
140 
141  uint32_t fFragment_id_offset; //< Allow offset for id
142  float fSigmaForTruncation; //< Selection cut for truncated rms calculation
143  size_t fCoherentNoiseGrouping; //< # channels in common for coherent noise
144  size_t fCoherentNoiseOffset; //< offset for midplane
145  std::vector<size_t> fStructuringElement; //< Structuring element for morphological filter
146  size_t fMorphWindow; //< Window for filter
147  std::vector<float> fThreshold; //< Threshold to apply for saving signal
148  bool fDiagnosticOutput; //< If true will spew endless messages to output
149 
150  std::vector<char> fFilterModeVec; //< Allowed modes for the filter
151 
152  using FragmentIDPair = std::pair<unsigned int, unsigned int>;
153  using FragmentIDVec = std::vector<FragmentIDPair>;
154  using FragmentIDMap = std::map<unsigned int, unsigned int>;
155 
157 
158  // Allocate containers for noise processing
159  icarus_signal_processing::VectorInt fChannelIDVec;
160  icarus_signal_processing::ArrayBool fSelectVals;
161  icarus_signal_processing::ArrayBool fROIVals;
162  icarus_signal_processing::ArrayFloat fRawWaveforms;
163  icarus_signal_processing::ArrayFloat fPedCorWaveforms;
164  icarus_signal_processing::ArrayFloat fIntrinsicRMS;
165  icarus_signal_processing::ArrayFloat fCorrectedMedians;
166  icarus_signal_processing::ArrayFloat fWaveLessCoherent;
167  icarus_signal_processing::ArrayFloat fMorphedWaveforms;
168 
169  icarus_signal_processing::VectorFloat fPedestalVals;
170  icarus_signal_processing::VectorFloat fFullRMSVals;
171  icarus_signal_processing::VectorFloat fTruncRMSVals;
172  icarus_signal_processing::VectorInt fNumTruncBins;
173  icarus_signal_processing::VectorInt fRangeBins;
174 
175  icarus_signal_processing::VectorFloat fThresholdVec;
176 
177  std::vector<unsigned int> fPlaneVec;
178 
179  const geo::Geometry* fGeometry; //< pointer to the Geometry service
181 
182  // Keep track of the FFT
183  icarus_signal_processing::FFTFilterFunctionVec fFFTFilterFunctionVec;
184 
185 };
186 
187 TPCDecoderFilter2D::TPCDecoderFilter2D(fhicl::ParameterSet const &pset)
188 {
189  this->configure(pset);
190 
191  fSelectVals.clear();
192  fROIVals.clear();
193  fRawWaveforms.clear();
194  fPedCorWaveforms.clear();
195  fIntrinsicRMS.clear();
196  fCorrectedMedians.clear();
197  fWaveLessCoherent.clear();
198  fMorphedWaveforms.clear();
199 
200  fPedestalVals.clear();
201  fFullRMSVals.clear();
202  fTruncRMSVals.clear();
203  fNumTruncBins.clear();
204  fRangeBins.clear();
205 
206  return;
207 }
208 
209 //------------------------------------------------------------------------------------------------------------------------------------------
210 
212 {
213 }
214 
215 //------------------------------------------------------------------------------------------------------------------------------------------
216 void TPCDecoderFilter2D::configure(fhicl::ParameterSet const &pset)
217 {
218  fFragment_id_offset = pset.get<uint32_t >("fragment_id_offset" );
219  fSigmaForTruncation = pset.get<float >("NSigmaForTrucation", 3.5);
220  fCoherentNoiseGrouping = pset.get<size_t >("CoherentGrouping", 64);
221  fCoherentNoiseOffset = pset.get<size_t >("CoherentOffset", 0);
222  fStructuringElement = pset.get<std::vector<size_t>>("StructuringElement", std::vector<size_t>()={8,16});
223  fMorphWindow = pset.get<size_t >("FilterWindow", 10);
224  fThreshold = pset.get<std::vector<float> >("Threshold", std::vector<float>()={5.0,3.5,3.5});
225  fDiagnosticOutput = pset.get<bool >("DiagnosticOutput", false);
226  fFilterModeVec = pset.get<std::vector<char> >("FilterModeVec", std::vector<char>()={'g','g','d'}); //{'d','e','g'});
227 
228  FragmentIDVec tempIDVec = pset.get< FragmentIDVec >("FragmentIDVec", FragmentIDVec());
229 
230  for(const auto& idPair : tempIDVec) fFragmentIDMap[idPair.first] = idPair.second;
231 
232  fGeometry = art::ServiceHandle<geo::Geometry const>{}.get();
233  fChannelMap = art::ServiceHandle<icarusDB::IICARUSChannelMap const>{}.get();
234 
235 // std::vector<double> highPassSigma = {3.5, 3.5, 0.5};
236 // std::vector<double> highPassCutoff = {12., 12., 2.};
237 // So we build a filter kernel for convolution with the waveform working in "tick" space.
238 // For translation, each "tick" is approximately 0.61 kHz... the frequency response functions all
239 // are essentially zero by 500 kHz which is like 800 "ticks".
240  std::vector<std::pair<double,double>> windowSigma = {{1.5,20.}, {1.5,20.}, {2.0,20.}};
241  std::vector<std::pair<double,double>> windowCutoff = {{8.,800.}, {8.,800.}, {3.0,800.}};
242 
243 
244  for(int plane = 0; plane < 3; plane++)
245  {
246  fFFTFilterFunctionVec.emplace_back(std::make_unique<icarus_signal_processing::WindowFFTFilter>(windowSigma[plane], windowCutoff[plane]));
247  }
248 
249  return;
250 }
251 
253  const artdaq::Fragment &fragment)
254 {
255  cet::cpu_timer theClockTotal;
256 
257  theClockTotal.start();
258 
259  // convert fragment to Nevis fragment
260  icarus::PhysCrateFragment physCrateFragment(fragment);
261 
262  size_t nBoardsPerFragment = physCrateFragment.nBoards();
263  size_t nChannelsPerBoard = physCrateFragment.nChannelsPerBoard();
264  size_t nSamplesPerChannel = physCrateFragment.nSamplesPerChannel();
265 // size_t nChannelsPerFragment = nBoardsPerFragment * nChannelsPerBoard;
266 
267  // Recover the Fragment id:
268  artdaq::detail::RawFragmentHeader::fragment_id_t fragmentID = fragment.fragmentID();
269 
270  if (fDiagnosticOutput) std::cout << "==> Recovered fragmentID: " << std::hex << fragmentID << std::dec << " ";
271 
272  // Look for special case of diagnostic running
273  if (!fChannelMap->hasFragmentID(fragmentID))
274  {
275  if (fFragmentIDMap.find(fragmentID) == fFragmentIDMap.end()) //throw std::runtime_error("You can't save yourself");
276  {
277  theClockTotal.stop();
278  if (fDiagnosticOutput) std::cout << " **** no match found ****" << std::endl;
279 
280  return;
281  }
282 
283  if (fDiagnosticOutput) std::cout << "No match, use fhicl list? Have fragmentID: " << fragmentID << ", make it: " << std::hex << fFragmentIDMap[fragmentID] << std::dec << std::endl;
284 
285  fragmentID = fFragmentIDMap[fragmentID];
286 
287  if (!fChannelMap->hasFragmentID(fragmentID))
288  {
289  if (fDiagnosticOutput) std::cout << "WTF? This really can't happen, right?" << std::endl;
290  return;
291  }
292 
293  }
294 
295  if (fDiagnosticOutput) std::cout << std::endl;
296 
297  // Recover the crate name for this fragment
298  const std::string& crateName = fChannelMap->getCrateName(fragmentID);
299 
300  // Get the board ids for this fragment
301  const icarusDB::ReadoutIDVec& readoutIDVec = fChannelMap->getReadoutBoardVec(fragmentID);
302 
303  icarusDB::ReadoutIDVec boardIDVec(readoutIDVec.size());
304 
305  // Note we want these to be in "slot" order...
306  for(const auto& boardID : readoutIDVec)
307  {
308  // Look up the channels associated to this board
309  if (!fChannelMap->hasBoardID(boardID))
310  {
311  if (fDiagnosticOutput)
312  {
313  std::cout << "*** COULD NOT FIND BOARD ***" << std::endl;
314  std::cout << " - boardID: " << std::hex << boardID << ", board map size: " << readoutIDVec.size() << ", nBoardsPerFragment: " << nBoardsPerFragment << std::endl;
315  }
316 
317  return;
318  }
319 
320  unsigned int boardSlot = fChannelMap->getBoardSlot(boardID);
321 
322  boardIDVec[boardSlot] = boardID;
323  }
324 
325  if (fDiagnosticOutput)
326  {
327  std::cout << " - # boards: " << boardIDVec.size() << ", boards: ";
328  for(const auto& id : boardIDVec) std::cout << id << " ";
329  std::cout << std::endl;
330  }
331 
332  // Make sure these always get defined to be as large as can be
333  const size_t maxChannelsPerFragment(576);
334 
335  if (fSelectVals.empty()) fSelectVals = icarus_signal_processing::ArrayBool(maxChannelsPerFragment, icarus_signal_processing::VectorBool(nSamplesPerChannel));
336  if (fROIVals.empty()) fROIVals = icarus_signal_processing::ArrayBool(maxChannelsPerFragment, icarus_signal_processing::VectorBool(nSamplesPerChannel));
337  if (fRawWaveforms.empty()) fRawWaveforms = icarus_signal_processing::ArrayFloat(maxChannelsPerFragment, icarus_signal_processing::VectorFloat(nSamplesPerChannel));
338  if (fPedCorWaveforms.empty()) fPedCorWaveforms = icarus_signal_processing::ArrayFloat(maxChannelsPerFragment, icarus_signal_processing::VectorFloat(nSamplesPerChannel));
339  if (fIntrinsicRMS.empty()) fIntrinsicRMS = icarus_signal_processing::ArrayFloat(maxChannelsPerFragment, icarus_signal_processing::VectorFloat(nSamplesPerChannel));
340  if (fCorrectedMedians.empty()) fCorrectedMedians = icarus_signal_processing::ArrayFloat(maxChannelsPerFragment, icarus_signal_processing::VectorFloat(nSamplesPerChannel));
341  if (fWaveLessCoherent.empty()) fWaveLessCoherent = icarus_signal_processing::ArrayFloat(maxChannelsPerFragment, icarus_signal_processing::VectorFloat(nSamplesPerChannel));
342  if (fMorphedWaveforms.empty()) fMorphedWaveforms = icarus_signal_processing::ArrayFloat(maxChannelsPerFragment, icarus_signal_processing::VectorFloat(nSamplesPerChannel));
343 
344  if (fChannelIDVec.empty()) fChannelIDVec = icarus_signal_processing::VectorInt(maxChannelsPerFragment);
345  if (fPedestalVals.empty()) fPedestalVals = icarus_signal_processing::VectorFloat(maxChannelsPerFragment);
346  if (fFullRMSVals.empty()) fFullRMSVals = icarus_signal_processing::VectorFloat(maxChannelsPerFragment);
347  if (fTruncRMSVals.empty()) fTruncRMSVals = icarus_signal_processing::VectorFloat(maxChannelsPerFragment);
348  if (fNumTruncBins.empty()) fNumTruncBins = icarus_signal_processing::VectorInt(maxChannelsPerFragment);
349  if (fRangeBins.empty()) fRangeBins = icarus_signal_processing::VectorInt(maxChannelsPerFragment);
350 
351  if (fThresholdVec.empty()) fThresholdVec = icarus_signal_processing::VectorFloat(maxChannelsPerFragment);
352 
353  if (fPlaneVec.empty()) fPlaneVec.resize(nChannelsPerBoard,0);
354 
355  // Allocate the de-noising object
356 // icarus_signal_processing::Denoiser2D_Hough denoiser;
357  icarus_signal_processing::WaveformTools<float> waveformTools;
358 
359  cet::cpu_timer theClockPedestal;
360 
361  theClockPedestal.start();
362 
363  // The first task is to recover the data from the board data block, determine and subtract the pedestals
364  // and store into vectors useful for the next steps
365  for(size_t board = 0; board < boardIDVec.size(); board++)
366  {
367  const icarusDB::ChannelPlanePairVec& channelPlanePairVec = fChannelMap->getChannelPlanePair(boardIDVec[board]);
368 
369  uint32_t boardSlot = physCrateFragment.DataTileHeader(board)->StatusReg_SlotID();
370 
371  if (fDiagnosticOutput)
372  {
373  std::cout << "********************************************************************************" << std::endl;
374  std::cout << "FragmentID: " << std::hex << fragmentID << ", Crate: " << crateName << std::dec << ", boardID: " << boardSlot << "/" << nBoardsPerFragment << ", size " << channelPlanePairVec.size() << "/" << nChannelsPerBoard << ", ";
375  std::cout << std::endl;
376  }
377 
378  // This is where we would recover the base channel for the board from database/module
379  size_t boardOffset = nChannelsPerBoard * board;
380 
381  // Get the pointer to the start of this board's block of data
382  const icarus::A2795DataBlock::data_t* dataBlock = physCrateFragment.BoardData(board);
383 
384  // Copy to input data array
385  for(size_t chanIdx = 0; chanIdx < nChannelsPerBoard; chanIdx++)
386  {
387  // Get the channel number on the Fragment
388  size_t channelOnBoard = boardOffset + chanIdx;
389 
390  icarus_signal_processing::VectorFloat& rawDataVec = fRawWaveforms[channelOnBoard];
391 
392  for(size_t tick = 0; tick < nSamplesPerChannel; tick++)
393  rawDataVec[tick] = -dataBlock[chanIdx + tick * nChannelsPerBoard];
394 
395  icarus_signal_processing::VectorFloat& pedCorDataVec = fPedCorWaveforms[channelOnBoard];
396 
397  // Keep track of the channel
398  fChannelIDVec[channelOnBoard] = channelPlanePairVec[chanIdx].first;
399 
400  // Handle the filter function to use for this channel
401  unsigned int plane = channelPlanePairVec[chanIdx].second;
402 
403  fPlaneVec[chanIdx] = plane;
404 
405  // Set the threshold for this channel
406  fThresholdVec[channelOnBoard] = fThreshold[plane];
407 
408  // Now determine the pedestal and correct for it
409  waveformTools.getPedestalCorrectedWaveform(rawDataVec,
410  pedCorDataVec,
412  fPedestalVals[channelOnBoard],
413  fFullRMSVals[channelOnBoard],
414  fTruncRMSVals[channelOnBoard],
415  fNumTruncBins[channelOnBoard],
416  fRangeBins[channelOnBoard]);
417 
418  // Convolve with a filter function
419  (*fFFTFilterFunctionVec[plane])(pedCorDataVec);
420 
421  if (fDiagnosticOutput)
422  {
423  std::vector<geo::WireID> widVec = fGeometry->ChannelToWire(channelPlanePairVec[chanIdx].first);
424 
425  if (widVec.empty()) std::cout << channelPlanePairVec[chanIdx].first << "/" << chanIdx << "=" << fFullRMSVals[channelOnBoard] << " * ";
426  else std::cout << fChannelIDVec[channelOnBoard] << "-" << widVec[0].Cryostat << "/" << widVec[0].TPC << "/" << widVec[0].Plane << "/" << widVec[0].Wire << "=" << fFullRMSVals[channelOnBoard] << " * ";
427  }
428  }
429 
430  if (fDiagnosticOutput) std::cout << std::endl;
431 
432  // The assumption is that channels map to planes in a continuous manner.
433  // For the first induction all the channels on a board should map to the same plane
434  // For middle induction and collection you map to two planes where one group of 32 will go to one plane, the other group to the other plane.
435  // So we need to go through the planeVec to understand how to break this up...
436  unsigned int startChannel(0);
437 
438  while(startChannel < fPlaneVec.size())
439  {
440  unsigned int stopChannel = startChannel;
441  unsigned int plane = fPlaneVec[startChannel];
442 
443  while(stopChannel < fPlaneVec.size() && fPlaneVec[stopChannel] == plane) stopChannel++;
444 
445  size_t deltaChannels = stopChannel - startChannel;
446 
447  std::cout << "==> Board Offset: " << boardOffset << ", start: " << startChannel << ", stop: " << stopChannel << ", delta: " << deltaChannels << std::endl;
448 
449  if (deltaChannels >= 32) // How can we handle this?
450  {
451  // Filter function
452  std::unique_ptr<icarus_signal_processing::IMorphologicalFunctions2D> filterFunctionPtr;
453 
454  switch(fFilterModeVec[plane])
455  {
456  case 'd' :
457  filterFunctionPtr = std::make_unique<icarus_signal_processing::Dilation2D>(fStructuringElement[0],fStructuringElement[1]);
458  break;
459  case 'e' :
460  filterFunctionPtr = std::make_unique<icarus_signal_processing::Erosion2D>(fStructuringElement[0],fStructuringElement[1]);
461  break;
462  case 'g' :
463  filterFunctionPtr = std::make_unique<icarus_signal_processing::Gradient2D>(fStructuringElement[0],fStructuringElement[1]);
464  break;
465  case 'a' :
466  filterFunctionPtr = std::make_unique<icarus_signal_processing::Average2D>(fStructuringElement[0],fStructuringElement[1]);
467  break;
468  case 'm' :
469  filterFunctionPtr = std::make_unique<icarus_signal_processing::Median2D>(fStructuringElement[0],fStructuringElement[1],0);
470  break;
471  default:
472  std::cout << "***** FOUND NO MATCH FOR TYPE: " << fFilterModeVec[plane] << ", plane " << plane << " DURING INITIALIZATION OF FILTER FUNCTIONS IN TPCDecoderFilter2D" << std::endl;
473  break;
474  }
475 
476  if (boardOffset + startChannel + deltaChannels > fWaveLessCoherent.size())
477  {
478  std::cout << "*** Attempting to write past end of array, boardOffset: " << boardOffset << ", startChannel: " << startChannel << ", deltaChannels: " << deltaChannels << ", array size:" << fWaveLessCoherent.size() << std::endl;
479  startChannel = stopChannel;
480  continue;
481  }
482 
483  icarus_signal_processing::Denoiser2D_Hough denoiser(filterFunctionPtr.get(), fThresholdVec, fCoherentNoiseGrouping, fCoherentNoiseOffset, fMorphWindow);
484 
485  // Run the coherent filter
486  denoiser(fWaveLessCoherent.begin() + boardOffset + startChannel,
487  fPedCorWaveforms.begin() + boardOffset + startChannel,
488  fMorphedWaveforms.begin() + boardOffset + startChannel,
489  fIntrinsicRMS.begin() + boardOffset + startChannel,
490  fSelectVals.begin() + boardOffset + startChannel,
491  fROIVals.begin() + boardOffset + startChannel,
492  fCorrectedMedians.begin() + boardOffset + startChannel,
493  deltaChannels);
494 
495  }
496 
497  startChannel = stopChannel;
498  }
499 
500  }
501 
502  // We need to make sure the channelID information is not preserved when less than 9 boards in the fragment
503  if (boardIDVec.size() < 9)
504  {
505  std::fill(fChannelIDVec.begin() + boardIDVec.size() * nChannelsPerBoard, fChannelIDVec.end(), -1);
506  }
507 
508  theClockPedestal.stop();
509 
510  double pedestalTime = theClockPedestal.accumulated_real_time();
511 
512  cet::cpu_timer theClockDenoise;
513 
514  theClockDenoise.start();
515 
516  theClockDenoise.stop();
517 
518  double denoiseTime = theClockDenoise.accumulated_real_time();
519 
520  theClockDenoise.start();
521 
522  theClockDenoise.stop();
523 
524  double cohPedSubTime = theClockDenoise.accumulated_real_time() - denoiseTime;
525 
526 
527  theClockTotal.stop();
528 
529  double totalTime = theClockTotal.accumulated_real_time();
530 
531  mf::LogInfo("TPCDecoderFilter2D") << " *totalTime: " << totalTime << ", pedestal: " << pedestalTime << ", noise: " << denoiseTime << ", ped cor: " << cohPedSubTime << std::endl;
532 
533  return;
534 }
535 
536 
537 DEFINE_ART_CLASS_TOOL(TPCDecoderFilter2D)
538 } // namespace lar_cluster3d
icarus_signal_processing::ArrayFloat fPedCorWaveforms
icarus_signal_processing::VectorFloat fFullRMSVals
std::vector< ChannelPlanePair > ChannelPlanePairVec
const icarus_signal_processing::ArrayFloat getWaveLessCoherent() const override
Recover the waveforms less coherent noise.
std::vector< unsigned int > fPlaneVec
const geo::Geometry * fGeometry
icarus_signal_processing::VectorFloat fTruncRMSVals
std::vector< unsigned int > ReadoutIDVec
virtual const ReadoutIDVec & getReadoutBoardVec(const unsigned int) const =0
const icarus_signal_processing::VectorInt getNumTruncBins() const override
Recover the number of bins after truncation.
const icarus_signal_processing::ArrayFloat getMorphedWaveforms() const override
Recover the morphological filter waveforms.
const icarus_signal_processing::VectorFloat getTruncRMSVals() const override
Recover the truncated RMS noise.
icarus_signal_processing::VectorInt fChannelIDVec
IDecoderFilter interface class definiton.
std::vector< geo::WireID > ChannelToWire(raw::ChannelID_t const channel) const
Returns a list of wires connected to the specified TPC channel.
const icarus_signal_processing::VectorInt getChannelIDs() const override
Recover the channels for the processed fragment.
icarus_signal_processing::VectorInt fRangeBins
std::vector< char > fFilterModeVec
std::map< unsigned int, unsigned int > FragmentIDMap
This provides an art tool interface definition for tools which &quot;decode&quot; artdaq fragments into LArSoft...
virtual const std::string & getCrateName(const unsigned int) const =0
icarus_signal_processing::VectorInt fNumTruncBins
virtual bool hasBoardID(const unsigned int) const =0
icarus_signal_processing::ArrayFloat fMorphedWaveforms
icarus_signal_processing::ArrayFloat fIntrinsicRMS
const icarus_signal_processing::ArrayFloat getCorrectedMedians() const override
Recover the correction median values.
virtual void process_fragment(detinfo::DetectorClocksData const &, const artdaq::Fragment &) override
Given a set of recob hits, run DBscan to form 3D clusters.
const icarusDB::IICARUSChannelMap * fChannelMap
icarus_signal_processing::FFTFilterFunctionVec fFFTFilterFunctionVec
TPCDecoderFilter2D class definiton.
icarus_signal_processing::VectorFloat fThresholdVec
const icarus_signal_processing::ArrayBool getSelectionVals() const override
Recover the selection values.
virtual const ChannelPlanePairVec & getChannelPlanePair(const unsigned int) const =0
std::vector< FragmentIDPair > FragmentIDVec
tick_as<> tick
Tick number, represented by std::ptrdiff_t.
Definition: electronics.h:75
virtual bool hasFragmentID(const unsigned int) const =0
void fill(const art::PtrVector< recob::Hit > &hits, int only_plane)
icarus_signal_processing::VectorFloat fPedestalVals
const icarus_signal_processing::ArrayBool getROIVals() const override
Recover the ROI values.
The geometry of one entire detector, as served by art.
Definition: Geometry.h:181
const icarus_signal_processing::VectorFloat getPedestalVals() const override
Recover the pedestals for each channel.
icarus_signal_processing::ArrayBool fROIVals
virtual void configure(const fhicl::ParameterSet &) override
Interface for configuring the particular algorithm tool.
const icarus_signal_processing::ArrayFloat getIntrinsicRMS() const override
Recover the &quot;intrinsic&quot; RMS.
std::vector< size_t > fStructuringElement
TPCDecoderFilter2D(fhicl::ParameterSet const &pset)
Constructor.
icarus_signal_processing::ArrayFloat fWaveLessCoherent
Contains all timing reference information for the detector.
const icarus_signal_processing::ArrayFloat getPedCorWaveforms() const override
Recover the pedestal subtracted waveforms.
const icarus_signal_processing::VectorFloat getFullRMSVals() const override
Recover the full RMS before coherent noise.
const icarus_signal_processing::ArrayFloat getRawWaveforms() const override
Recover the pedestal subtracted waveforms.
std::pair< unsigned int, unsigned int > FragmentIDPair
icarus_signal_processing::ArrayFloat fCorrectedMedians
virtual unsigned int getBoardSlot(const unsigned int) const =0
icarus_signal_processing::ArrayFloat fRawWaveforms
icarus_signal_processing::ArrayBool fSelectVals
art framework interface to geometry description
BEGIN_PROLOG could also be cout