All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TPCDecoderFilter1D_tool.cc
Go to the documentation of this file.
1 /**
2  * @file TPCDecoderFilter1D_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 TPCDecoderFilter1D class definiton
43  */
44 class TPCDecoderFilter1D : virtual public IDecoderFilter
45 {
46 public:
47  /**
48  * @brief Constructor
49  *
50  * @param pset
51  */
52  explicit TPCDecoderFilter1D(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  using FloatPairVec = std::vector<std::pair<float,float>>;
142 
143  uint32_t fFragment_id_offset; //< Allow offset for id
144  float fSigmaForTruncation; //< Selection cut for truncated rms calculation
145  size_t fCoherentNoiseGrouping; //< # channels in common for coherent noise
146  size_t fCoherentNoiseOffset; //< Offset for midplane
147  size_t fStructuringElement; //< Structuring element for morphological filter
148  size_t fMorphWindow; //< Window for filter
149  std::vector<float> fThreshold; //< Threshold to apply for saving signal
150  bool fUseFFTFilter; //< Turn on/off the use of the FFT filter
151  bool fDiagnosticOutput; //< If true will spew endless messages to output
152  FloatPairVec fFFTSigmaValsVec; //< Gives the sigmas for the filter function
153  FloatPairVec fFFTCutoffValsVec; //< Gives the cutoffs for the filter function
154 
155  std::vector<std::string> fFilterModeVec; //< Allowed modes for the filter
156 
157  using FragmentIDPair = std::pair<unsigned int, unsigned int>;
158  using FragmentIDVec = std::vector<FragmentIDPair>;
159  using FragmentIDMap = std::map<unsigned int, unsigned int>;
160 
162 
163  // Allocate containers for noise processing
164  icarus_signal_processing::VectorInt fChannelIDVec;
165  icarus_signal_processing::ArrayBool fSelectVals;
166  icarus_signal_processing::ArrayBool fROIVals;
167  icarus_signal_processing::ArrayFloat fRawWaveforms;
168  icarus_signal_processing::ArrayFloat fPedCorWaveforms;
169  icarus_signal_processing::ArrayFloat fIntrinsicRMS;
170  icarus_signal_processing::ArrayFloat fCorrectedMedians;
171  icarus_signal_processing::ArrayFloat fWaveLessCoherent;
172  icarus_signal_processing::ArrayFloat fMorphedWaveforms;
173 
174  icarus_signal_processing::VectorFloat fPedestalVals;
175  icarus_signal_processing::VectorFloat fFullRMSVals;
176  icarus_signal_processing::VectorFloat fTruncRMSVals;
177  icarus_signal_processing::VectorInt fNumTruncBins;
178  icarus_signal_processing::VectorInt fRangeBins;
179 
180  icarus_signal_processing::VectorFloat fThresholdVec;
181 
182  icarus_signal_processing::FilterFunctionVec fFilterFunctionVec;
183 
184  const geo::Geometry* fGeometry; //< pointer to the Geometry service
186 
187  // Keep track of the FFT
188  icarus_signal_processing::FFTFilterFunctionVec fFFTFilterFunctionVec;
189 
190 };
191 
192 TPCDecoderFilter1D::TPCDecoderFilter1D(fhicl::ParameterSet const &pset)
193 {
194  std::cout << "TPCDecoderFilter1D is calling configure method" << std::endl;
195  this->configure(pset);
196 
197  fSelectVals.clear();
198  fROIVals.clear();
199  fRawWaveforms.clear();
200  fPedCorWaveforms.clear();
201  fIntrinsicRMS.clear();
202  fCorrectedMedians.clear();
203  fWaveLessCoherent.clear();
204  fMorphedWaveforms.clear();
205 
206  fPedestalVals.clear();
207  fFullRMSVals.clear();
208  fTruncRMSVals.clear();
209  fNumTruncBins.clear();
210  fRangeBins.clear();
211 
212  return;
213 }
214 
215 //------------------------------------------------------------------------------------------------------------------------------------------
216 
218 {
219 }
220 
221 //------------------------------------------------------------------------------------------------------------------------------------------
222 void TPCDecoderFilter1D::configure(fhicl::ParameterSet const &pset)
223 {
224  fFragment_id_offset = pset.get<uint32_t >("fragment_id_offset" );
225  fSigmaForTruncation = pset.get<float >("NSigmaForTrucation", 3.5);
226  fCoherentNoiseGrouping = pset.get<size_t >("CoherentGrouping", 64);
227  fCoherentNoiseOffset = pset.get<size_t >("CoherentOffset", 0);
228  fStructuringElement = pset.get<size_t >("StructuringElement", 20);
229  fMorphWindow = pset.get<size_t >("FilterWindow", 10);
230  fThreshold = pset.get<std::vector<float> >("Threshold", std::vector<float>()={5.0,3.5,3.5});
231  fUseFFTFilter = pset.get<bool >("UseFFTFilter", true);
232  fDiagnosticOutput = pset.get<bool >("DiagnosticOutput", false);
233  fFilterModeVec = pset.get<std::vector<std::string>>("FilterModeVec", std::vector<std::string>()={"e","g","d"});
234 
235  fFFTSigmaValsVec = pset.get<FloatPairVec >("FFTSigmaVals", FloatPairVec()={{1.5,20.}, {1.5,20.}, {2.0,20.}});
236  fFFTCutoffValsVec = pset.get<FloatPairVec >("FFTCutoffVals", FloatPairVec()={{8.,800.}, {8.,800.}, {0.0,800.}});
237 
238  FragmentIDVec tempIDVec = pset.get< FragmentIDVec >("FragmentIDVec", FragmentIDVec());
239 
240  for(const auto& idPair : tempIDVec) fFragmentIDMap[idPair.first] = idPair.second;
241 
242  fGeometry = art::ServiceHandle<geo::Geometry const>{}.get();
243  fChannelMap = art::ServiceHandle<icarusDB::IICARUSChannelMap const>{}.get();
244 
245  fFFTFilterFunctionVec.clear();
246 
247  if (fUseFFTFilter)
248  {
249  for(int plane = 0; plane < 3; plane++)
250  {
251  if (plane < 3) fFFTFilterFunctionVec.emplace_back(std::make_unique<icarus_signal_processing::WindowFFTFilter>(fFFTSigmaValsVec[plane], fFFTCutoffValsVec[plane]));
252  else fFFTFilterFunctionVec.emplace_back(std::make_unique<icarus_signal_processing::NoFFTFilter>());
253 
254  mf::LogInfo("TPCDecoderFilter1D") << "FFT setup for plane " << plane << ", SigmaVals: " << fFFTSigmaValsVec[plane].first << "/" << fFFTSigmaValsVec[plane].second << ", cutoff: " << fFFTCutoffValsVec[plane].first << "/" << fFFTCutoffValsVec[plane].second << std::endl;
255  }
256  }
257 
258  return;
259 }
260 
262  const artdaq::Fragment &fragment)
263 {
264  cet::cpu_timer theClockTotal;
265 
266  theClockTotal.start();
267 
268  // convert fragment to Nevis fragment
269  icarus::PhysCrateFragment physCrateFragment(fragment);
270 
271  size_t nBoardsPerFragment = physCrateFragment.nBoards();
272  size_t nChannelsPerBoard = physCrateFragment.nChannelsPerBoard();
273  size_t nSamplesPerChannel = physCrateFragment.nSamplesPerChannel();
274 // size_t nChannelsPerFragment = nBoardsPerFragment * nChannelsPerBoard;
275 
276  // Recover the Fragment id:
277  artdaq::detail::RawFragmentHeader::fragment_id_t fragmentID = fragment.fragmentID();
278 
279  if (fDiagnosticOutput) std::cout << "==> Recovered fragmentID: " << std::hex << fragmentID << std::dec << " ";
280 
281  // Look for special case of diagnostic running
282  if (!fChannelMap->hasFragmentID(fragmentID))
283  {
284  if (fFragmentIDMap.find(fragmentID) == fFragmentIDMap.end()) //throw std::runtime_error("You can't save yourself");
285  {
286  theClockTotal.stop();
287  if (fDiagnosticOutput) std::cout << " **** no match found ****" << std::endl;
288 
289  return;
290  }
291 
292  if (fDiagnosticOutput) std::cout << "No match, use fhicl list? Have fragmentID: " << fragmentID << ", make it: " << std::hex << fFragmentIDMap[fragmentID] << std::dec << std::endl;
293 
294  fragmentID = fFragmentIDMap[fragmentID];
295 
296  if (!fChannelMap->hasFragmentID(fragmentID))
297  {
298  if (fDiagnosticOutput) std::cout << "WTF? This really can't happen, right?" << std::endl;
299  return;
300  }
301 
302  }
303 
304  if (fDiagnosticOutput) std::cout << std::endl;
305 
306  // Recover the crate name for this fragment
307  const std::string& crateName = fChannelMap->getCrateName(fragmentID);
308 
309  // Get the board ids for this fragment
310  const icarusDB::ReadoutIDVec& readoutIDVec = fChannelMap->getReadoutBoardVec(fragmentID);
311 
312  icarusDB::ReadoutIDVec boardIDVec(readoutIDVec.size());
313 
314  // Note we want these to be in "slot" order...
315  for(const auto& boardID : readoutIDVec)
316  {
317  // Look up the channels associated to this board
318  if (!fChannelMap->hasBoardID(boardID))
319  {
320  if (fDiagnosticOutput)
321  {
322  std::cout << "*** COULD NOT FIND BOARD ***" << std::endl;
323  std::cout << " - boardID: " << std::hex << boardID << ", board map size: " << readoutIDVec.size() << ", nBoardsPerFragment: " << nBoardsPerFragment << std::endl;
324  }
325 
326  return;
327  }
328 
329  unsigned int boardSlot = fChannelMap->getBoardSlot(boardID);
330 
331  boardIDVec[boardSlot] = boardID;
332  }
333 
334  if (fDiagnosticOutput)
335  {
336  std::cout << " - # boards: " << boardIDVec.size() << ", boards: ";
337  for(const auto& id : boardIDVec) std::cout << id << " ";
338  std::cout << std::endl;
339  }
340 
341  // Make sure these always get defined to be as large as can be
342  const size_t maxChannelsPerFragment(576);
343 
344  if (fSelectVals.empty()) fSelectVals = icarus_signal_processing::ArrayBool(maxChannelsPerFragment, icarus_signal_processing::VectorBool(nSamplesPerChannel));
345  if (fROIVals.empty()) fROIVals = icarus_signal_processing::ArrayBool(maxChannelsPerFragment, icarus_signal_processing::VectorBool(nSamplesPerChannel));
346  if (fRawWaveforms.empty()) fRawWaveforms = icarus_signal_processing::ArrayFloat(maxChannelsPerFragment, icarus_signal_processing::VectorFloat(nSamplesPerChannel));
347  if (fPedCorWaveforms.empty()) fPedCorWaveforms = icarus_signal_processing::ArrayFloat(maxChannelsPerFragment, icarus_signal_processing::VectorFloat(nSamplesPerChannel));
348  if (fIntrinsicRMS.empty()) fIntrinsicRMS = icarus_signal_processing::ArrayFloat(maxChannelsPerFragment, icarus_signal_processing::VectorFloat(nSamplesPerChannel));
349  if (fCorrectedMedians.empty()) fCorrectedMedians = icarus_signal_processing::ArrayFloat(maxChannelsPerFragment, icarus_signal_processing::VectorFloat(nSamplesPerChannel));
350  if (fWaveLessCoherent.empty()) fWaveLessCoherent = icarus_signal_processing::ArrayFloat(maxChannelsPerFragment, icarus_signal_processing::VectorFloat(nSamplesPerChannel));
351  if (fMorphedWaveforms.empty()) fMorphedWaveforms = icarus_signal_processing::ArrayFloat(maxChannelsPerFragment, icarus_signal_processing::VectorFloat(nSamplesPerChannel));
352 
353  if (fChannelIDVec.empty()) fChannelIDVec = icarus_signal_processing::VectorInt(maxChannelsPerFragment);
354  if (fPedestalVals.empty()) fPedestalVals = icarus_signal_processing::VectorFloat(maxChannelsPerFragment);
355  if (fFullRMSVals.empty()) fFullRMSVals = icarus_signal_processing::VectorFloat(maxChannelsPerFragment);
356  if (fTruncRMSVals.empty()) fTruncRMSVals = icarus_signal_processing::VectorFloat(maxChannelsPerFragment);
357  if (fNumTruncBins.empty()) fNumTruncBins = icarus_signal_processing::VectorInt(maxChannelsPerFragment);
358  if (fRangeBins.empty()) fRangeBins = icarus_signal_processing::VectorInt(maxChannelsPerFragment);
359 
360  if (fThresholdVec.empty()) fThresholdVec = icarus_signal_processing::VectorFloat(maxChannelsPerFragment / fCoherentNoiseGrouping);
361 
362  if (fFilterFunctionVec.empty()) fFilterFunctionVec.resize(maxChannelsPerFragment);
363 
364  // Allocate the de-noising object
365  icarus_signal_processing::Denoiser1D denoiser;
366  icarus_signal_processing::WaveformTools<float> waveformTools;
367 
368  cet::cpu_timer theClockPedestal;
369 
370  theClockPedestal.start();
371 
372  // The first task is to recover the data from the board data block, determine and subtract the pedestals
373  // and store into vectors useful for the next steps
374  for(size_t board = 0; board < boardIDVec.size(); board++)
375  {
376  // Some diagnostics test are removing boards so put in check here to watch for this
377  if (board >= nBoardsPerFragment)
378  {
379  mf::LogInfo("TPCDecoderFilter1D") << " Asking for board beyond number in fragment, want board " << board << ", maximum is " << nBoardsPerFragment << std::endl;
380  continue;
381  }
382 
383  const icarusDB::ChannelPlanePairVec& channelPlanePairVec = fChannelMap->getChannelPlanePair(boardIDVec[board]);
384 
385  uint32_t boardSlot = physCrateFragment.DataTileHeader(board)->StatusReg_SlotID();
386 
387  if (fDiagnosticOutput)
388  {
389  std::cout << "********************************************************************************" << std::endl;
390  std::cout << "FragmentID: " << std::hex << fragmentID << ", Crate: " << crateName << std::dec << ", boardID: " << boardIDVec[boardSlot] << ", slot: " << boardSlot << "/" << nBoardsPerFragment << ", size " << channelPlanePairVec.size() << "/" << nChannelsPerBoard << ", ";
391  std::cout << std::endl;
392  }
393 
394  // This is where we would recover the base channel for the board from database/module
395  size_t boardOffset = nChannelsPerBoard * board;
396 
397  // Get the pointer to the start of this board's block of data
398  const icarus::A2795DataBlock::data_t* dataBlock = physCrateFragment.BoardData(board);
399 
400  // Copy to input data array
401  for(size_t chanIdx = 0; chanIdx < nChannelsPerBoard; chanIdx++)
402  {
403  // Get the channel number on the Fragment
404  size_t channelOnBoard = boardOffset + chanIdx;
405 
406  icarus_signal_processing::VectorFloat& rawDataVec = fRawWaveforms[channelOnBoard];
407 
408  for(size_t tick = 0; tick < nSamplesPerChannel; tick++)
409  rawDataVec[tick] = -dataBlock[chanIdx + tick * nChannelsPerBoard];
410 
411  icarus_signal_processing::VectorFloat& pedCorDataVec = fPedCorWaveforms[channelOnBoard];
412 
413  // Keep track of the channel
414  fChannelIDVec[channelOnBoard] = channelPlanePairVec[chanIdx].first;
415 
416  // Handle the filter function to use for this channel
417  unsigned int plane = channelPlanePairVec[chanIdx].second;
418 
419  // Set the threshold which toggles between planes
420  fThresholdVec[channelOnBoard / fCoherentNoiseGrouping] = fThreshold[plane];
421 
422  if (plane > 2)
423  {
424  std::cout << "*** COMPLETELY SCREWUP YOU IMBECILE! plane is " << plane << " for chanIdx " << chanIdx << std::endl;
425  continue;
426  }
427 
428  switch(fFilterModeVec[plane][0])
429  {
430  case 'd' :
431  fFilterFunctionVec[channelOnBoard] = std::make_unique<icarus_signal_processing::Dilation1D>(fStructuringElement);
432  break;
433  case 'e' :
434  fFilterFunctionVec[channelOnBoard] = std::make_unique<icarus_signal_processing::Erosion1D>(fStructuringElement);
435  break;
436  case 'g' :
437  fFilterFunctionVec[channelOnBoard] = std::make_unique<icarus_signal_processing::Gradient1D>(fStructuringElement);
438  break;
439  case 'a' :
440  fFilterFunctionVec[channelOnBoard] = std::make_unique<icarus_signal_processing::Average1D>(fStructuringElement);
441  break;
442  case 'm' :
443  fFilterFunctionVec[channelOnBoard] = std::make_unique<icarus_signal_processing::Median1D>(fStructuringElement);
444  break;
445  default:
446  std::cout << "***** FOUND NO MATCH FOR TYPE: " << fFilterModeVec[plane] << ", plane " << plane << " DURING INITIALIZATION OF FILTER FUNCTIONS IN TPCDecoderFilter1D" << std::endl;
447  break;
448  }
449 
450  // Now determine the pedestal and correct for it
451  waveformTools.getPedestalCorrectedWaveform(rawDataVec,
452  pedCorDataVec,
454  fPedestalVals[channelOnBoard],
455  fFullRMSVals[channelOnBoard],
456  fTruncRMSVals[channelOnBoard],
457  fNumTruncBins[channelOnBoard],
458  fRangeBins[channelOnBoard]);
459 
460  // Convolve with a filter function
461  if (fUseFFTFilter) (*fFFTFilterFunctionVec[plane])(pedCorDataVec);
462 
463  if (fDiagnosticOutput)
464  {
465  std::vector<geo::WireID> widVec = fGeometry->ChannelToWire(channelPlanePairVec[chanIdx].first);
466 
467  if (widVec.empty()) std::cout << channelPlanePairVec[chanIdx].first << "/" << chanIdx << "=" << fFullRMSVals[channelOnBoard] << " * ";
468  else std::cout << fChannelIDVec[channelOnBoard] << "-" << widVec[0].Cryostat << "/" << widVec[0].TPC << "/" << widVec[0].Plane << "/" << widVec[0].Wire << "=" << fFullRMSVals[channelOnBoard] << " * ";
469  }
470  }
471 
472  if (fDiagnosticOutput) std::cout << std::endl;
473 
474  // Run the coherent filter
475 // denoiser.removeCoherentNoise1D_Ave(fWaveLessCoherent.begin() + boardOffset,
476 // fPedCorWaveforms.begin() + boardOffset,
477 // fMorphedWaveforms.begin() + boardOffset,
478 // fIntrinsicRMS.begin() + boardOffset,
479 // fSelectVals.begin() + boardOffset,
480 // fROIVals.begin() + boardOffset,
481 // fCorrectedMedians.begin() + boardOffset,
482 // fFilterFunctionVec.begin() + boardOffset,
483 // fThresholdVec.begin() + boardOffset,
484 // nChannelsPerBoard,
485 // fCoherentNoiseGrouping,
486 // fMorphWindow);
487 
488  denoiser(fWaveLessCoherent.begin() + boardOffset,
489  fPedCorWaveforms.begin() + boardOffset,
490  fMorphedWaveforms.begin() + boardOffset,
491  fIntrinsicRMS.begin() + boardOffset,
492  fSelectVals.begin() + boardOffset,
493  fROIVals.begin() + boardOffset,
494  fCorrectedMedians.begin() + boardOffset,
495  fFilterFunctionVec.begin() + boardOffset,
497  nChannelsPerBoard,
500  fMorphWindow);
501  }
502 
503  // We need to make sure the channelID information is not preserved when less than 9 boards in the fragment
504  if (nBoardsPerFragment < 9)
505  {
506  std::fill(fChannelIDVec.begin() + nBoardsPerFragment * nChannelsPerBoard, fChannelIDVec.end(), -1);
507  }
508 
509  theClockPedestal.stop();
510 
511  double pedestalTime = theClockPedestal.accumulated_real_time();
512 
513  cet::cpu_timer theClockDenoise;
514 
515  theClockDenoise.start();
516 
517  // Let's just try something here...
518 // icarus_signal_processing::ArrayFloat inputWaveforms = fPedCorWaveforms;
519 //
520 // for(size_t groupSize = 64; groupSize > 16; groupSize /= 2)// database::ReadoutIDVec& boardIDVec = fragItr->second;
521 
522 
523 // {
524 // // Run the coherent filter
525 // denoiser.removeCoherentNoise1D(fWaveLessCoherent,inputWaveforms,fMorphedWaveforms,fIntrinsicRMS,fSelectVals,fROIVals,fCorrectedMedians,
526 // fFilterModeVec[0],groupSize,fStructuringElement,fMorphWindow,fThreshold);
527 //
528 // inputWaveforms = fWaveLessCoherent;
529 // }
530 
531 
532 // // Run the coherent filter
533 // denoiser.removeCoherentNoise1D(fWaveLessCoherent.begin(),fPedCorWaveforms.begin(),fMorphedWaveforms.begin(),fIntrinsicRMS.begin(),fSelectVals.begin(),fROIVals.begin(),fCorrectedMedians.begin(),
534 // fFilterFunctionVec.begin(),fPedCorWaveforms.size(),fCoherentNoiseGrouping,fStructuringElement,fMorphWindow,fThreshold);
535 
536  theClockDenoise.stop();
537 
538  double denoiseTime = theClockDenoise.accumulated_real_time();
539 
540  theClockDenoise.start();
541 
542 // // One last task to remove remaining offsets from th coherent corrected waveforms
543 // for(size_t idx = 0; idx < fWaveLessCoherent.size(); idx++)
544 // {
545 // // Final pedestal correction to remove last offsets
546 // float cohPedestal;
547 // int numTrunc;
548 // int range;
549 //
550 // // waveform
551 // icarus_signal_processing::VectorFloat& waveform = fWaveLessCoherent[idx];
552 //
553 // waveformTools.getTruncatedMean(waveform, cohPedestal, numTrunc, range);
554 //
555 // if (fDiagnosticOutput) std::cout << "**> channel: " << fChannelIDVec[idx] << ", numTrunc: " << numTrunc << ", range: " << range << ", orig ped: " << fPedestalVals[idx] << ", new: " << cohPedestal << std::endl;
556 //
557 // // Do the pedestal correction
558 // std::transform(waveform.begin(),waveform.end(),waveform.begin(),std::bind(std::minus<float>(),std::placeholders::_1,cohPedestal));
559 // }
560 
561  theClockDenoise.stop();
562 
563  double cohPedSubTime = theClockDenoise.accumulated_real_time() - denoiseTime;
564 
565 
566  theClockTotal.stop();
567 
568  double totalTime = theClockTotal.accumulated_real_time();
569 
570  mf::LogDebug("TPCDecoderFilter1D") << " *totalTime: " << totalTime << ", pedestal: " << pedestalTime << ", noise: " << denoiseTime << ", ped cor: " << cohPedSubTime << std::endl;
571 
572  return;
573 }
574 
575 
576 DEFINE_ART_CLASS_TOOL(TPCDecoderFilter1D)
577 } // namespace lar_cluster3d
std::vector< FragmentIDPair > FragmentIDVec
virtual void configure(const fhicl::ParameterSet &) override
Interface for configuring the particular algorithm tool.
icarus_signal_processing::ArrayBool fSelectVals
std::vector< ChannelPlanePair > ChannelPlanePairVec
icarus_signal_processing::VectorFloat fPedestalVals
std::vector< std::string > fFilterModeVec
const icarus_signal_processing::ArrayFloat getCorrectedMedians() const override
Recover the correction median values.
const icarus_signal_processing::VectorFloat getTruncRMSVals() const override
Recover the truncated RMS noise.
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 getRawWaveforms() const override
Recover the pedestal subtracted waveforms.
const icarus_signal_processing::VectorInt getChannelIDs() const override
Recover the channels for the processed fragment.
icarus_signal_processing::ArrayBool fROIVals
icarus_signal_processing::FilterFunctionVec fFilterFunctionVec
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.
icarus_signal_processing::ArrayFloat fPedCorWaveforms
icarus_signal_processing::VectorFloat fTruncRMSVals
This provides an art tool interface definition for tools which &quot;decode&quot; artdaq fragments into LArSoft...
icarus_signal_processing::VectorInt fNumTruncBins
virtual void process_fragment(detinfo::DetectorClocksData const &, const artdaq::Fragment &) override
Given a set of recob hits, run DBscan to form 3D clusters.
virtual const std::string & getCrateName(const unsigned int) const =0
const icarus_signal_processing::ArrayBool getROIVals() const override
Recover the ROI values.
const icarus_signal_processing::ArrayFloat getIntrinsicRMS() const override
Recover the &quot;intrinsic&quot; RMS.
virtual bool hasBoardID(const unsigned int) const =0
std::pair< unsigned int, unsigned int > FragmentIDPair
icarus_signal_processing::ArrayFloat fIntrinsicRMS
virtual const ChannelPlanePairVec & getChannelPlanePair(const unsigned int) const =0
icarus_signal_processing::ArrayFloat fWaveLessCoherent
tick_as<> tick
Tick number, represented by std::ptrdiff_t.
Definition: electronics.h:75
const icarus_signal_processing::VectorFloat getFullRMSVals() const override
Recover the full RMS before coherent noise.
virtual bool hasFragmentID(const unsigned int) const =0
void fill(const art::PtrVector< recob::Hit > &hits, int only_plane)
const geo::Geometry * fGeometry
const icarus_signal_processing::VectorFloat getPedestalVals() const override
Recover the pedestals for each channel.
The geometry of one entire detector, as served by art.
Definition: Geometry.h:181
TPCDecoderFilter1D(fhicl::ParameterSet const &pset)
Constructor.
icarus_signal_processing::FFTFilterFunctionVec fFFTFilterFunctionVec
Contains all timing reference information for the detector.
icarus_signal_processing::ArrayFloat fMorphedWaveforms
const icarus_signal_processing::ArrayFloat getPedCorWaveforms() const override
Recover the pedestal subtracted waveforms.
const icarus_signal_processing::ArrayFloat getWaveLessCoherent() const override
Recover the waveforms less coherent noise.
virtual unsigned int getBoardSlot(const unsigned int) const =0
const icarus_signal_processing::ArrayBool getSelectionVals() const override
Recover the selection values.
icarus_signal_processing::ArrayFloat fRawWaveforms
icarus_signal_processing::VectorInt fChannelIDVec
icarus_signal_processing::ArrayFloat fCorrectedMedians
icarus_signal_processing::VectorInt fRangeBins
icarus_signal_processing::VectorFloat fFullRMSVals
art framework interface to geometry description
BEGIN_PROLOG could also be cout
std::vector< std::pair< float, float >> FloatPairVec
TPCDecoderFilter1D class definiton.
std::map< unsigned int, unsigned int > FragmentIDMap
const icarusDB::IICARUSChannelMap * fChannelMap
icarus_signal_processing::VectorFloat fThresholdVec
const icarus_signal_processing::ArrayFloat getMorphedWaveforms() const override
Recover the morphological filter waveforms.