All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
WaveformIntegrity_module.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // WaveformIntegrity class - variant of CalWire that deconvolves in
4 // Regions Of Interest
5 //
6 // baller@fnal.gov
7 //
8 //
9 ////////////////////////////////////////////////////////////////////////
10 
11 // C/C++ standard libraries
12 #include <string>
13 #include <vector>
14 #include <utility> // std::pair<>
15 #include <memory> // std::unique_ptr<>
16 #include <iomanip>
17 #include <fstream>
18 #include <random>
19 
20 // ROOT libraries
21 #include "TH1D.h"
22 #include "TProfile.h"
23 
24 // framework libraries
25 #include "art/Framework/Core/ModuleMacros.h"
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/Utilities/make_tool.h"
31 #include "canvas/Persistency/Common/Ptr.h"
32 #include "canvas/Persistency/Common/PtrVector.h"
33 #include "messagefacility/MessageLogger/MessageLogger.h"
34 #include "cetlib/cpu_timer.h"
35 
36 // LArSoft libraries
37 #include "larcoreobj/SimpleTypesAndConstants/RawTypes.h" // raw::ChannelID_t
39 #include "larcore/CoreUtils/ServiceUtil.h" // lar::providerFrom()
41 #include "lardataobj/RawData/raw.h"
50 
54 #include "icarus_signal_processing/WaveformTools.h"
55 
56 #include "tbb/parallel_for.h"
57 #include "tbb/blocked_range.h"
58 #include "tbb/task_arena.h"
59 #include "tbb/spin_mutex.h"
60 
61 ///creation of calibrated signals on wires
62 namespace caldata {
63 
64 tbb::spin_mutex deconvolutionSpinMutex;
65 
66 class WaveformIntegrity : public art::ReplicatedProducer
67 {
68  public:
69  // create calibrated signals on wires. this class runs
70  // an fft to remove the electronics shaping.
71  explicit WaveformIntegrity(fhicl::ParameterSet const &, art::ProcessingFrame const&);
72 
73  void produce(art::Event& evt, art::ProcessingFrame const&) override;
74  // void beginJob() override;
75  // void endJob() override;
76  void reconfigure(fhicl::ParameterSet const& p);
77 
78  private:
79 
80  // It seems there are pedestal shifts that need correcting
81  float fixTheFreakingWaveform(const std::vector<float>&, raw::ChannelID_t, std::vector<float>&) const;
82 
83  float getTruncatedRMS(const std::vector<float>&) const;
84 
85  std::vector<art::InputTag> fNewRawDigitLabelVec; ///< New Raw Digits
86  std::vector<art::InputTag> fOldRawDigitLabelVec; ///< From previous run
87 
88  icarus_signal_processing::WaveformTools<float> fWaveformTool;
89 
90  const geo::GeometryCore* fGeometry = lar::providerFrom<geo::Geometry>();
91  const lariov::ChannelStatusProvider* fChannelFilter = lar::providerFrom<lariov::ChannelStatusService>();
92  const lariov::DetPedestalProvider* fPedRetrievalAlg = lar::providerFrom<lariov::DetPedestalService>();
93 
94 }; // class WaveformIntegrity
95 
96 DEFINE_ART_MODULE(WaveformIntegrity)
97 
98 //-------------------------------------------------
99 WaveformIntegrity::WaveformIntegrity(fhicl::ParameterSet const & pset, art::ProcessingFrame const& frame) : art::ReplicatedProducer(pset,frame)
100 {
101  this->reconfigure(pset);
102 }
103 
104 //////////////////////////////////////////////////////
105 void WaveformIntegrity::reconfigure(fhicl::ParameterSet const& pset)
106 {
107  // Recover the parameters
108  fNewRawDigitLabelVec = pset.get< std::vector<art::InputTag>> ("NewRawDigitLabelVec", {"daqTPC"});
109  fOldRawDigitLabelVec = pset.get< std::vector<art::InputTag>> ("OldRawDigitLabelVec", {"daqTPC"});
110 
111  return;
112 }
113 
114 //////////////////////////////////////////////////////
115 void WaveformIntegrity::produce(art::Event& evt, art::ProcessingFrame const& frame)
116 {
117  // We loop over the collection of RawDigits in our input list
118  // This is not done multi threaded as a way to cut down on overall job memory usage...
119  if (fNewRawDigitLabelVec.size() != fOldRawDigitLabelVec.size())
120  {
121  std::cout << "WaveformIntegrity not given equal size product label vectors" << std::endl;
122  return;
123  }
124 
125  for(size_t prodIdx = 0; prodIdx < fNewRawDigitLabelVec.size(); prodIdx++)
126  {
127  art::Handle<std::vector<raw::RawDigit>> newRawDigitHandle;
128 
129  evt.getByLabel(fNewRawDigitLabelVec[prodIdx],newRawDigitHandle);
130 
131  art::Handle<std::vector<raw::RawDigit>> oldRawDigitHandle;
132 
133  evt.getByLabel(fOldRawDigitLabelVec[prodIdx],oldRawDigitHandle);
134 
135  if (!newRawDigitHandle->size() || !oldRawDigitHandle->size())
136  {
137  std::cout << "WaveformIntegrity found a zero length buffer" << std::endl;
138  continue;
139  }
140 
141  for(size_t chanIdx = 0; chanIdx < newRawDigitHandle->size(); chanIdx++)
142  {
143  // get the reference to the current raw::RawDigit
144  art::Ptr<raw::RawDigit> newDigitVec(newRawDigitHandle, chanIdx);
145  art::Ptr<raw::RawDigit> oldDigitVec(oldRawDigitHandle, chanIdx);
146 
147  raw::ChannelID_t newChannel = newDigitVec->Channel();
148  raw::ChannelID_t oldChannel = oldDigitVec->Channel();
149 
150  if (newChannel != oldChannel)
151  {
152  std::cout << "WaveformIntegrity finds channel mismatch, idx: " << chanIdx << ", new channel: " << newChannel << ", old channel: " << oldChannel << std::endl;
153 
154  continue;
155  }
156 
157  size_t dataSize = newDigitVec->Samples();
158 
159  std::vector<short> newRawADC(dataSize);
160  std::vector<short> oldRawADC(dataSize);
161 
162  // uncompress the data
163  raw::Uncompress(newDigitVec->ADCs(), newRawADC, newDigitVec->Compression());
164  raw::Uncompress(oldDigitVec->ADCs(), oldRawADC, oldDigitVec->Compression());
165 
166  if (newRawADC != oldRawADC)
167  {
168  std::vector<short> diffVec;
169  std::vector<short> idxVec;
170 
171  for(size_t tickIdx = 0; tickIdx < newRawADC.size(); tickIdx++)
172  {
173  if (newRawADC[tickIdx] != oldRawADC[tickIdx])
174  {
175  diffVec.push_back(newRawADC[tickIdx] - oldRawADC[tickIdx]);
176  idxVec.push_back(tickIdx);
177  }
178  }
179 
180  short maxDiff = *std::max_element(diffVec.begin(),diffVec.end());
181  short minDiff = *std::min_element(diffVec.begin(),diffVec.end());
182 
183  std::vector<geo::WireID> wireIDVec = fGeometry->ChannelToWire(newChannel);
184 
185  std::cout << "==> Channel: " << newChannel << " - " << wireIDVec[0] << " - has " << diffVec.size() << " max/min: " << maxDiff << "/" << minDiff << std::endl;
186 // for(size_t idx = 0; diffVec.size(); idx++) std::cout << idxVec[idx] << "/" << diffVec[idx] << " ";
187 // std::cout << std::endl;
188  }
189 
190  }
191 
192  }
193 
194  return;
195 } // produce
196 
197 float WaveformIntegrity::getTruncatedRMS(const std::vector<float>& waveform) const
198 {
199  // do rms calculation - the old fashioned way and over all adc values
200  std::vector<float> locWaveform = waveform;
201 
202  // sort in ascending order so we can truncate the sume
203  std::sort(locWaveform.begin(), locWaveform.end(),[](const auto& left, const auto& right){return std::fabs(left) < std::fabs(right);});
204 
205  float threshold = 10.; //fTruncRMSThreshold;
206 
207  std::vector<float>::iterator threshItr = std::find_if(locWaveform.begin(),locWaveform.end(),[threshold](const auto& val){return std::fabs(val) > threshold;});
208 
209  //int minNumBins = std::max(int(fTruncRMSMinFraction * locWaveform.size()),int(std::distance(locWaveform.begin(),threshItr)));
210  int minNumBins = std::max(int(0.8 * locWaveform.size()),int(std::distance(locWaveform.begin(),threshItr)));
211 
212  // Get the truncated sum
213  float truncRms = std::inner_product(locWaveform.begin(), locWaveform.begin() + minNumBins, locWaveform.begin(), 0.);
214 
215  truncRms = std::sqrt(std::max(0.,truncRms / double(minNumBins)));
216 
217  return truncRms;
218 }
219 
220 float WaveformIntegrity::fixTheFreakingWaveform(const std::vector<float>& waveform, raw::ChannelID_t channel, std::vector<float>& fixedWaveform) const
221 {
222  // do rms calculation - the old fashioned way and over all adc values
223  std::vector<float> locWaveform = waveform;
224 
225  // sort in ascending order so we can truncate the sume
226  std::sort(locWaveform.begin(), locWaveform.end(),[](const auto& left, const auto& right){return std::fabs(left) < std::fabs(right);});
227 
228  // Get the mean of the waveform we're checking...
229  float sumWaveform = std::accumulate(locWaveform.begin(),locWaveform.begin() + locWaveform.size()/2, 0.);
230  float meanWaveform = sumWaveform / float(locWaveform.size()/2);
231 
232  std::vector<float> locWaveformDiff(locWaveform.size()/2);
233 
234  std::transform(locWaveform.begin(),locWaveform.begin() + locWaveform.size()/2,locWaveformDiff.begin(), std::bind(std::minus<float>(),std::placeholders::_1,meanWaveform));
235 
236  float localRMS = std::inner_product(locWaveformDiff.begin(), locWaveformDiff.end(), locWaveformDiff.begin(), 0.);
237 
238  localRMS = std::sqrt(std::max(float(0.),localRMS / float(locWaveformDiff.size())));
239 
240  float threshold = 6. * localRMS;
241 
242  std::vector<float>::iterator threshItr = std::find_if(locWaveform.begin(),locWaveform.end(),[threshold](const auto& val){return std::fabs(val) > threshold;});
243 
244  //int minNumBins = std::max(int(fTruncRMSMinFraction * locWaveform.size()),int(std::distance(locWaveform.begin(),threshItr)));
245  int minNumBins = std::max(int(0.8 * locWaveform.size()),int(std::distance(locWaveform.begin(),threshItr)));
246 
247  // recalculate the mean
248  float aveSum = std::accumulate(locWaveform.begin(), locWaveform.begin() + minNumBins, 0.);
249  float newPedestal = aveSum / minNumBins;
250 
251  // recalculate the rms
252  locWaveformDiff.resize(minNumBins);
253 
254  std::transform(locWaveform.begin(),locWaveform.begin() + minNumBins,locWaveformDiff.begin(), std::bind(std::minus<float>(),std::placeholders::_1,newPedestal));
255 
256  localRMS = std::inner_product(locWaveform.begin(), locWaveform.begin() + minNumBins, locWaveform.begin(), 0.);
257  localRMS = std::sqrt(std::max(float(0.),localRMS / float(minNumBins)));
258 
259  // Set the waveform to the new baseline
260  std::transform(waveform.begin(), waveform.end(), fixedWaveform.begin(), [newPedestal](const auto& val){return val - newPedestal;});
261 
262  return localRMS;
263 }
264 
265 } // end namespace caldata
void reconfigure(fhicl::ParameterSet const &p)
Utilities related to art service access.
static constexpr Sample_t transform(Sample_t sample)
This provides an interface for tools which are tasked with running the deconvolution algorithm...
const geo::GeometryCore * fGeometry
Helper functions to create a wire.
walls no right
Definition: selectors.fcl:105
pdgs p
Definition: selectors.fcl:22
std::vector< art::InputTag > fOldRawDigitLabelVec
From previous run.
const lariov::ChannelStatusProvider * fChannelFilter
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.
for pfile in ack l reconfigure(.*) override"` do echo "checking $
This provides an interface for tools which are tasked with finding the baselines in input waveforms...
std::vector< art::InputTag > fNewRawDigitLabelVec
New Raw Digits.
float getTruncatedRMS(const std::vector< float > &) const
double distance(geo::Point_t const &point, CathodeDesc_t const &cathode)
Returns the distance of a point from the cathode.
Collect all the RawData header files together.
walls no left
Definition: selectors.fcl:105
Class providing information about the quality of channels.
Description of geometry of one entire detector.
WaveformIntegrity(fhicl::ParameterSet const &, art::ProcessingFrame const &)
const lariov::DetPedestalProvider * fPedRetrievalAlg
icarus_signal_processing::WaveformTools< float > fWaveformTool
Interface for experiment-specific channel quality info provider.
void produce(art::Event &evt, art::ProcessingFrame const &) override
Declaration of basic channel signal object.
TCEvent evt
Definition: DataStructs.cxx:8
unsigned int ChannelID_t
Type representing the ID of a readout channel.
Definition: RawTypes.h:28
Interface for experiment-specific service for channel quality info.
void Uncompress(const std::vector< short > &adc, std::vector< short > &uncompressed, raw::Compress_t compress)
Uncompresses a raw data buffer.
Definition: raw.cxx:776
process_name can override from command line with o or output caldata
Definition: pid.fcl:40
tbb::spin_mutex deconvolutionSpinMutex
art framework interface to geometry description
BEGIN_PROLOG could also be cout
float fixTheFreakingWaveform(const std::vector< float > &, raw::ChannelID_t, std::vector< float > &) const