All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
RecoWireROI_module.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // RecoWireROI class - variant of RecoWire 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 
19 // ROOT libraries
20 #include "TComplex.h"
21 #include "TH1D.h"
22 
23 // framework libraries
24 #include "fhiclcpp/ParameterSet.h"
25 #include "messagefacility/MessageLogger/MessageLogger.h"
26 #include "art/Framework/Core/ModuleMacros.h"
27 #include "art/Framework/Core/EDProducer.h"
28 #include "art/Framework/Principal/Event.h"
29 #include "art/Framework/Principal/Handle.h"
30 #include "canvas/Persistency/Common/Ptr.h"
31 #include "canvas/Persistency/Common/PtrVector.h"
32 #include "art/Framework/Services/Registry/ServiceHandle.h"
33 #include "art/Framework/Services/Registry/ServiceDefinitionMacros.h"
34 #include "art_root_io/TFileService.h"
35 #include "canvas/Utilities/Exception.h"
36 
37 // LArSoft libraries
38 #include "larcoreobj/SimpleTypesAndConstants/RawTypes.h" // raw::ChannelID_t
40 #include "larcore/CoreUtils/ServiceUtil.h" // lar::providerFrom()
42 #include "lardataobj/RawData/raw.h"
49 #include "icarus_signal_processing/Filters/ICARUSFFT.h"
50 
55 
57 
58 
59 ///creation of calibrated signals on wires
60 namespace recowire {
61 
62 class RecoWireROI : public art::EDProducer
63 {
64 public:
65  // create calibrated signals on wires. this class runs
66  // an fft to remove the electronics shaping.
67  explicit RecoWireROI(fhicl::ParameterSet const& pset);
68  virtual ~RecoWireROI();
69 
70  void produce(art::Event& evt);
71  void beginJob();
72  void endJob();
73  void reconfigure(fhicl::ParameterSet const& p);
74 
75 private:
76 
77  std::string fDigitModuleLabel; ///< module that made digits
78  std::string fSpillName; ///< nominal spill is an empty string
79  ///< it is set by the DigitModuleLabel
80  ///< ex.: "daq:preSpill" for prespill data
81  unsigned short fNoiseSource; ///< Used to determine ROI threshold
82  unsigned short fNumBinsHalf; ///< Determines # bins in ROI running sum
83  std::vector<unsigned short> fThreshold; ///< abs(threshold) ADC counts for ROI
84  std::vector<int> fNumSigma; ///< "# sigma" rms noise for ROI threshold
85  std::vector<unsigned short> fPreROIPad; ///< ROI padding
86  std::vector<unsigned short> fPostROIPad; ///< ROI padding
87  bool fDoBaselineSub; ///< Do baseline subtraction after deconvolution?
88  bool fuPlaneRamp; ///< set true for correct U plane wire response
89  int fSaveWireWF; ///< Save recob::wire object waveforms
90  size_t fEventCount; ///< count of event processed
91  int fMinAllowedChanStatus; ///< Don't consider channels with lower status
92  bool fDodQdxCalib; ///< Do we apply wire-by-wire calibration?
93  std::string fdQdxCalibFileName; ///< Text file for constants to do wire-by-wire calibration
94  std::map<unsigned int, float> fdQdxCalib; ///< Map to do wire-by-wire calibration, key is channel number, content is correction factor
95 
96  float fMinROIAverageTickThreshold; // try to remove bad ROIs
97 
98  void doDecon(icarusutil::TimeVec& holder,
99  raw::ChannelID_t channel,
100  unsigned int thePlane,
101  const std::vector<std::pair<size_t, size_t>>& rois,
102  const std::vector<std::pair<size_t, size_t>>& holderInfo,
104 
105  float SubtractBaseline(std::vector<float>& holder,
106  float basePre,
107  float basePost,
108  size_t roiStart,
109  size_t roiLen,
110  size_t dataSize);
111 
112  float SubtractBaseline(const std::vector<float>& holder);
113 
117  std::unique_ptr<icarus_signal_processing::ICARUSFFT<double>> fFFT; ///< Object to handle thread safe FFT
118 }; // class RecoWireROI
119 
120 DEFINE_ART_MODULE(RecoWireROI)
121 
122 //-------------------------------------------------
123 RecoWireROI::RecoWireROI(fhicl::ParameterSet const& pset) : EDProducer{pset},
124  fGeometry(*lar::providerFrom<geo::Geometry>()),
125  fSignalServices(*art::ServiceHandle<icarusutil::SignalShapingICARUSService>()),
126  fChanFilt(art::ServiceHandle<lariov::ChannelStatusService>()->GetProvider())
127 {
128  this->reconfigure(pset);
129 
130  produces< std::vector<recob::Wire> >(fSpillName);
131  produces<art::Assns<raw::RawDigit, recob::Wire>>(fSpillName);
132 }
133 
134 //-------------------------------------------------
136 {
137 }
138 
139 //////////////////////////////////////////////////////
140 void RecoWireROI::reconfigure(fhicl::ParameterSet const& p)
141 {
142  std::vector<unsigned short> uin; std::vector<unsigned short> vin;
143  std::vector<unsigned short> zin;
144 
145  fDigitModuleLabel = p.get< std::string > ("DigitModuleLabel", "daq");
146  fNoiseSource = p.get< unsigned short > ("NoiseSource", 3);
147  fNumBinsHalf = p.get< unsigned short > ("NumBinsHalf", 3);
148  fThreshold = p.get< std::vector<unsigned short> > ("Threshold" );
149  fNumSigma = p.get< std::vector<int> > ("NumSigma" );
150  uin = p.get< std::vector<unsigned short> > ("uPlaneROIPad" );
151  vin = p.get< std::vector<unsigned short> > ("vPlaneROIPad" );
152  zin = p.get< std::vector<unsigned short> > ("zPlaneROIPad" );
153  fDoBaselineSub = p.get< bool > ("DoBaselineSub" );
154  fuPlaneRamp = p.get< bool > ("uPlaneRamp" );
155  fSaveWireWF = p.get< int > ("SaveWireWF" );
156  fMinAllowedChanStatus = p.get< int > ("MinAllowedChannelStatus");
157  fMinROIAverageTickThreshold = p.get<float>("MinROIAverageTickThreshold",-0.5);
158 
159  if(uin.size() != 2 || vin.size() != 2 || zin.size() != 2) {
160  throw art::Exception(art::errors::Configuration)
161  << "u/v/z plane ROI pad size != 2";
162  }
163 
164  fPreROIPad.resize(3);
165  fPostROIPad.resize(3);
166 
167  // put the ROI pad sizes into more convenient vectors
168  fPreROIPad[0] = uin[0];
169  fPostROIPad[0] = uin[1];
170  fPreROIPad[1] = vin[0];
171  fPostROIPad[1] = vin[1];
172  fPreROIPad[2] = zin[0];
173  fPostROIPad[2] = zin[1];
174 
175  fSpillName.clear();
176 
177  size_t pos = fDigitModuleLabel.find(":");
178  if( pos!=std::string::npos ) {
179  fSpillName = fDigitModuleLabel.substr( pos+1 );
180  fDigitModuleLabel = fDigitModuleLabel.substr( 0, pos );
181  }
182 
183  //wire-by-wire calibration
184  fDodQdxCalib = p.get< bool > ("DodQdxCalib", false);
185  if (fDodQdxCalib){
186  fdQdxCalibFileName = p.get< std::string > ("dQdxCalibFileName");
187  std::string fullname;
188  cet::search_path sp("FW_SEARCH_PATH");
189  sp.find_file(fdQdxCalibFileName, fullname);
190 
191  if (fullname.empty()) {
192  std::cout << "Input file " << fdQdxCalibFileName << " not found" << std::endl;
193  throw cet::exception("File not found");
194  }
195  else
196  std::cout << "Applying wire-by-wire calibration using file " << fdQdxCalibFileName << std::endl;
197 
198  std::ifstream inFile(fullname, std::ios::in);
199  std::string line;
200 
201  while (std::getline(inFile,line)) {
202  unsigned int channel;
203  float constant;
204  std::stringstream linestream(line);
205  linestream >> channel >> constant;
206  fdQdxCalib[channel] = constant;
207  if (channel%1000==0) std::cout<<"Channel "<<channel<<" correction factor "<<fdQdxCalib[channel]<<std::endl;
208  }
209  }
210 
211  // Now set up our plans for doing the convolution
212  auto const detProp = art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataForJob();
213  fFFT = std::make_unique<icarus_signal_processing::ICARUSFFT<double>>(detProp.NumberTimeSamples());
214 }
215 
216 //-------------------------------------------------
218 {
219  fEventCount = 0;
220 } // beginJob
221 
222 //////////////////////////////////////////////////////
224 {
225 }
226 
227 //////////////////////////////////////////////////////
228 void RecoWireROI::produce(art::Event& evt)
229 {
230  //get pedestal conditions
231  const lariov::DetPedestalProvider& pedestalRetrievalAlg = art::ServiceHandle<lariov::DetPedestalService>()->GetPedestalProvider();
232 
233  // make a collection of Wires
234  std::unique_ptr<std::vector<recob::Wire> > wirecol(new std::vector<recob::Wire>);
235  // ... and an association set
236  std::unique_ptr<art::Assns<raw::RawDigit,recob::Wire> > WireDigitAssn(new art::Assns<raw::RawDigit,recob::Wire>);
237 
238  // Read in the digit List object(s).
239  art::Handle< std::vector<raw::RawDigit> > digitVecHandle;
240  if(fSpillName.size()>0) evt.getByLabel(fDigitModuleLabel, fSpillName, digitVecHandle);
241  else evt.getByLabel(fDigitModuleLabel, digitVecHandle);
242 
243  if (!digitVecHandle->size())
244  {
245  evt.put(std::move(wirecol), fSpillName);
246  evt.put(std::move(WireDigitAssn), fSpillName);
247  return;
248  }
249 
250  raw::ChannelID_t channel = raw::InvalidChannelID; // channel number
251 
252  auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(evt);
253  double samplingRate = sampling_rate(clockData)/1000.;
254  double deconNorm = fSignalServices.GetDeconNorm();
255 
256  // We'll need to set the transform size once we get the waveform and know its size
257  size_t transformSize = 0;
258 
259  // loop over all wires
260  wirecol->reserve(digitVecHandle->size());
261  for(size_t rdIter = 0; rdIter < digitVecHandle->size(); ++rdIter)
262  {
263  // vector that will be moved into the Wire object
265 
266  // vector of ROI begin and end bins
267  std::vector<std::pair<size_t, size_t>> rois;
268 
269  // get the reference to the current raw::RawDigit
270  art::Ptr<raw::RawDigit> digitVec(digitVecHandle, rdIter);
271  channel = digitVec->Channel();
272 
273  // The following test is meant to be temporary until the "correct" solution is implemented
274  if (!fChanFilt.IsPresent(channel)) continue;
275 
276  // Testing an idea about rejecting channels
277  if (digitVec->GetPedestal() < 0.) continue;
278 
279  // skip bad channels
280  if( fChanFilt.Status(channel) >= fMinAllowedChanStatus)
281  {
282  size_t dataSize = digitVec->Samples();
283 
284  if (!dataSize)
285  {
286  std::cout << "***>> zero length data buffer, channel: " << channel << std::endl;
287  continue;
288  }
289 
290  // vector holding uncompressed adc values
291  std::vector<short> rawadc(dataSize);
292 
293  std::vector<geo::WireID> wids = fGeometry.ChannelToWire(channel);
294  size_t thePlane = wids[0].Plane;
295 
296  // Set up the deconvolution and the vector to deconvolve
297 
298  // Set up the deconvolution and the vector to deconvolve
299  // This is called only once per event, but under the hood nothing happens
300  // unless the FFT vector length changes (which it shouldn't for a run)
301  if (!transformSize)
302  {
303  fSignalServices.SetDecon(samplingRate, dataSize, channel);
304  transformSize = dataSize;
305  }
306 
307  icarusutil::TimeVec rawAdcLessPedVec;
308 
309  rawAdcLessPedVec.resize(transformSize,0.);
310 
311  // uncompress the data
312  raw::Uncompress(digitVec->ADCs(), rawadc, digitVec->Compression());
313 
314  // loop over all adc values and subtract the pedestal
315  // When we have a pedestal database, can provide the digit timestamp as the third argument of GetPedestalMean
316  size_t numBins = 2 * fNumBinsHalf + 1;
317  float pdstl = pedestalRetrievalAlg.PedMean(channel);
318  float rms_noise = digitVec->GetSigma();
319  float raw_noise = fSignalServices.GetRawNoise(channel);
320 
321  if (fNoiseSource == 1) raw_noise = rms_noise;
322  else if (fNoiseSource != 2) raw_noise = std::max(raw_noise,rms_noise);
323 
324  size_t binOffset(0);
325 
326  if (transformSize > dataSize) binOffset = (transformSize - dataSize) / 2;
327 
328  size_t startBin(binOffset);
329  size_t stopBin(binOffset+numBins);
330 
331  //float startThreshold = sqrt(float(numBins)) * (fNumSigma[thePlane] * raw_noise + fThreshold[thePlane]);
332  float startThreshold = float(numBins) * (fNumSigma[thePlane] * raw_noise + fThreshold[thePlane]);
333  float stopThreshold = startThreshold;
334 
335  // Get the pedestal subtracted data, centered in the deconvolution vector
336  std::transform(rawadc.begin(),rawadc.end(),rawAdcLessPedVec.begin()+startBin,[pdstl](const short& adc){return std::round(float(adc) - pdstl);});
337  std::fill(rawAdcLessPedVec.begin(),rawAdcLessPedVec.begin()+startBin,0.); //rawAdcLessPedVec.at(startBin));
338  std::fill(rawAdcLessPedVec.begin()+startBin+dataSize,rawAdcLessPedVec.end(),0.); //rawAdcLessPedVec.at(startBin+dataSize-1));
339 
340  // Try a loose cut to see if there is a potential for activity on this channel
341  icarusutil::TimeVec::iterator overThreshItr = std::find_if(rawAdcLessPedVec.begin(),rawAdcLessPedVec.end(),[raw_noise](const auto& val){return val > 2.5 * raw_noise;});
342 
343  if (overThreshItr == rawAdcLessPedVec.end()) continue;
344 
345  float runningSum = std::accumulate(rawAdcLessPedVec.begin()+startBin,rawAdcLessPedVec.begin()+stopBin, 0.);
346 
347  size_t roiStartBin(0);
348  bool roiCandStart(false);
349 
350  // search for ROIs - follow prescription from Bruce B using a running sum to make faster
351  // Note that we start in the middle of the running sum... if we find an ROI padding will extend
352  // past this to take care of ends of the waveform
353  for(size_t bin = fNumBinsHalf + 1; bin < dataSize - fNumBinsHalf; bin++)
354  {
355  // handle the running sum
356  // Case, we are at start of waveform
357  runningSum -= rawAdcLessPedVec[startBin++];
358 
359  // Case, we are at end of waveform
360  runningSum += rawAdcLessPedVec[stopBin++];
361 
362  // We have already started a candidate ROI
363  if (roiCandStart)
364  {
365  if (fabs(runningSum) < stopThreshold)
366  {
367  if (bin - roiStartBin > 2) rois.push_back(std::make_pair(roiStartBin, bin));
368 
369  roiCandStart = false;
370  }
371  }
372  // Not yet started a candidate ROI
373  else
374  {
375  if (fabs(runningSum) > startThreshold)
376  {
377  roiStartBin = bin;
378  roiCandStart = true;
379  }
380  }
381  } // bin
382  // add the last ROI if existed
383  if (roiCandStart)
384  {
385  //unsigned int roiLen = dataSize -1 - roiStart;
386  // if(roiLen > fMinWid)
387  rois.push_back(std::make_pair(roiStartBin, dataSize-1));
388  }
389 
390  // skip deconvolution if there are no ROIs
391  if(rois.size() == 0) continue;
392 
393  // pad the ROIs
394  for(size_t ii = 0; ii < rois.size(); ++ii)
395  {
396  // low ROI end
397  rois[ii].first = std::max(int(rois[ii].first - fPreROIPad[thePlane]),0);
398  // high ROI end
399  rois[ii].second = std::min(rois[ii].second + fPostROIPad[thePlane],dataSize - 1);
400  }
401 
402  // merge the ROIs?
403  if(rois.size() > 1)
404  {
405  // temporary vector for merged ROIs
406  std::vector<std::pair<size_t,size_t>> trois;
407 
408  // Loop through candidate roi's
409  size_t startRoi = rois.front().first;
410  size_t stopRoi = rois.front().second;
411 
412  for(size_t idx = 1; idx < rois.size(); idx++)
413  {
414  if (rois[idx].first < stopRoi)
415  {
416  stopRoi = rois[idx].second;
417  }
418  else
419  {
420  trois.push_back(std::pair<size_t,size_t>(startRoi,stopRoi));
421 
422  startRoi = rois[idx].first;
423  stopRoi = rois[idx].second;
424  }
425  }
426 
427  // Make sure to get the last one
428  trois.push_back(std::pair<size_t,size_t>(startRoi,stopRoi));
429 
430  rois = trois;
431  }
432 
433  // Strategy is to run deconvolution on the entire channel and then pick out the ROI's we found above
434  // Deconvolute the raw signal using the channel's nominal response
435  fFFT->deconvolute(rawAdcLessPedVec, fSignalServices.GetResponse(channel).getDeconvKernel(), fSignalServices.ResponseTOffset(channel));
436 
437  std::vector<float> holder;
438 
439  for(size_t roiIdx = 0; roiIdx < rois.size(); roiIdx++)
440  {
441  const auto roi = rois[roiIdx];
442 
443  // First up: copy out the relevent ADC bins into the ROI holder
444  size_t roiLen = roi.second - roi.first;
445 
446  holder.resize(roiLen);
447 
448  std::copy(rawAdcLessPedVec.begin()+binOffset+roi.first, rawAdcLessPedVec.begin()+binOffset+roi.second, holder.begin());
449  float dnorm=samplingRate*deconNorm;
450  // std::cout << " dnorm " << dnorm << std::endl;
451  std::transform(holder.begin(),holder.end(),holder.begin(),[dnorm](float& deconVal){return deconVal/dnorm;});
452 
453  // Now we do the baseline determination (and I'm left wondering if there is a better way using the entire waveform?)
454  bool baseSet(false);
455  float base(0.);
456  if(fDoBaselineSub && fPreROIPad[thePlane] > 0 )
457  {
458  //1. Check Baseline match?
459  // If not, include next ROI(if none, go to the end of signal)
460  // If yes, proceed
461  size_t binsToAve(20);
462  float basePre = std::accumulate(holder.begin(),holder.begin()+binsToAve,0.) / float(binsToAve);
463  float basePost = std::accumulate(holder.end()-binsToAve,holder.end(),0.) / float(binsToAve);
464 
465  // emulate method for refining baseline from original version of RecoWireROI
466  float deconNoise = 1.26491 * fSignalServices.GetDeconNoise(channel); // 4./sqrt(10) * noise
467 
468  // If the estimated baseline from the front of the roi does not agree well with that from the end
469  // of the roi then we'll extend the roi hoping for good agreement
470  if (!(fabs(basePre - basePost) < deconNoise))
471  {
472  int nTries(0);
473 
474  // get start of roi and find the maximum we can extend to
475  icarusutil::TimeVec::iterator rawAdcRoiStartItr = rawAdcLessPedVec.begin() + binOffset + roi.first;
476  icarusutil::TimeVec::iterator rawAdcMaxItr = rawAdcLessPedVec.end() - binOffset;
477 
478  // if this is not the last roi then limit max range to start of next roi
479  if (roiIdx < rois.size() - 1)
480  rawAdcMaxItr = rawAdcLessPedVec.begin() + binOffset + rois[roiIdx+1].first;
481 
482  // Basically, allow roi to be extended until we get good agreement unless it seems pointless
483  while (!(fabs(basePre - basePost) < deconNoise) && nTries++ < 3)
484  {
485  size_t nBinsToAdd(100);
486  int nBinsLeft = std::distance(rawAdcRoiStartItr+roiLen,rawAdcMaxItr) > 0
487  ? std::distance(rawAdcRoiStartItr+roiLen,rawAdcMaxItr) : 0;
488  size_t roiLenAddition = std::min(nBinsToAdd, size_t(nBinsLeft));
489 
490  if (roiLenAddition > 0)
491  {
492  std::vector<float> additionVec(roiLenAddition);
493 
494  std::copy(rawAdcRoiStartItr + roiLen, rawAdcRoiStartItr + roiLen + roiLenAddition, additionVec.begin());
495 
496  holder.resize(holder.size() + roiLenAddition);
497  std::transform(additionVec.begin(),additionVec.end(),holder.begin() + roiLen,[deconNorm](float& deconVal){return deconVal/deconNorm;});
498 
499  basePost = std::accumulate(holder.end()-binsToAve,holder.end(),0.) / float(binsToAve);
500 
501  roiLen = holder.size();
502  }
503  else break;
504  }
505  }
506 
507  baseSet = true;
508  base = SubtractBaseline(holder, basePre,basePost,roi.first,roiLen,dataSize);
509  } // fDoBaselineSub ...
510 
511  if (baseSet) std::transform(holder.begin(),holder.end(),holder.begin(),[base](float& adcVal){return adcVal - base;});
512 
513  // apply wire-by-wire calibration
514  if (fDodQdxCalib)
515  {
516  if(fdQdxCalib.find(channel) != fdQdxCalib.end())
517  {
518  float constant = fdQdxCalib[channel];
519  //std::cout<<channel<<" "<<constant<<std::endl;
520  for (size_t iholder = 0; iholder < holder.size(); ++iholder) holder[iholder] *= constant;
521  }
522  }
523 
524  //wes 23.12.2016 --- sum up the roi, and if it's very negative get rid of it
525  float average_val = std::accumulate(holder.begin(),holder.end(),0.0) / holder.size();
526  float min = *std::min_element(holder.begin(),holder.end());
527  float max = *std::max_element(holder.begin(),holder.end());
528  if(average_val>fMinROIAverageTickThreshold || std::abs(min)<std::abs(max)){
529  // add the range into ROIVec
530  ROIVec.add_range(roi.first, std::move(holder));
531  }
532  }
533  } // end if not a bad channel
534 
535  // create the new wire directly in wirecol
536  wirecol->push_back(recob::WireCreator(std::move(ROIVec),*digitVec).move());
537 
538  // add an association between the last object in wirecol
539  // (that we just inserted) and digitVec
540  if (!util::CreateAssn(*this, evt, *wirecol, digitVec, *WireDigitAssn, fSpillName))
541  {
542  throw art::Exception(art::errors::ProductRegistrationFailure)
543  << "Can't associate wire #" << (wirecol->size() - 1)
544  << " with raw digit #" << digitVec.key();
545  } // if failed to add association
546  // DumpWire(wirecol->back()); // for debugging
547  }
548 
549  if(wirecol->size() == 0)
550  mf::LogWarning("RecoWireROI") << "No wires made for this event.";
551 
552  //Make Histogram of recob::wire objects from Signal() vector
553  // get access to the TFile service
554  if ( fSaveWireWF )
555  {
556  art::ServiceHandle<art::TFileService> tfs;
557  for (size_t wireN = 0; wireN < wirecol->size(); wireN++)
558  {
559  std::vector<float> sigTMP = wirecol->at(wireN).Signal();
560  TH1D* fWire = tfs->make<TH1D>(Form("Noise_Evt%04zu_N%04zu",fEventCount,wireN), ";Noise (ADC);", sigTMP.size(),-0.5,sigTMP.size()-0.5);
561  for (size_t tick = 0; tick < sigTMP.size(); tick++) fWire->SetBinContent(tick+1, sigTMP.at(tick) );
562  }
563  }
564 
565  evt.put(std::move(wirecol), fSpillName);
566  evt.put(std::move(WireDigitAssn), fSpillName);
567 
568  fEventCount++;
569 
570  return;
571 } // produce
572 
573 
574 float RecoWireROI::SubtractBaseline(std::vector<float>& holder,
575  float basePre,
576  float basePost,
577  size_t roiStart,
578  size_t roiLen,
579  size_t dataSize)
580 {
581  float base=0;
582 
583  //can not trust the early part
584  if (roiStart < 20 && roiStart + roiLen < dataSize - 20){
585  base = basePost;
586  // can not trust the later part
587  }else if (roiStart >= 20 && roiStart + roiLen >= dataSize - 20){
588  base = basePre;
589  // can trust both
590  }else if (roiStart >= 20 && roiStart + roiLen < dataSize - 20){
591  if (fabs(basePre-basePost)<3){
592  base = (basePre+basePost)/2.;
593  }else{
594  if (basePre < basePost){
595  base = basePre;
596  }else{
597  base = basePost;
598  }
599  }
600  // can not use both
601  }else{
602  float min = 0,max=0;
603  for (unsigned int bin = 0; bin < roiLen; bin++){
604  if (holder[bin] > max) max = holder[bin];
605  if (holder[bin] < min) min = holder[bin];
606  }
607  int nbin = max - min;
608  if (nbin!=0){
609  TH1F *h1 = new TH1F("h1","h1",nbin,min,max);
610  for (unsigned int bin = 0; bin < roiLen; bin++){
611  h1->Fill(holder[bin]);
612  }
613  float ped = h1->GetMaximum();
614  float ave=0,ncount = 0;
615  for (unsigned int bin = 0; bin < roiLen; bin++){
616  if (fabs(holder[bin]-ped)<2){
617  ave +=holder[bin];
618  ncount ++;
619  }
620  }
621  if (ncount==0) ncount=1;
622  ave = ave/ncount;
623  h1->Delete();
624  base = ave;
625  }
626  }
627 
628  return base;
629 }
630 
631 
633  raw::ChannelID_t channel,
634  unsigned int thePlane,
635  const std::vector<std::pair<size_t,size_t>>& rois,
636  const std::vector<std::pair<size_t,size_t>>& holderInfo,
638 {
639  // Deconvolute the raw signal using the channel's nominal response
640  fFFT->deconvolute(holder, fSignalServices.GetResponse(channel).getDeconvKernel(), fSignalServices.ResponseTOffset(channel));
641 
642  // transfer the ROIs and start bins into the vector that will be
643  // put into the event
644  for(size_t jr = 0; jr < holderInfo.size(); ++jr)
645  {
646  std::vector<float> sigTemp;
647  size_t bBegin = holderInfo[jr].first;
648  size_t theROI = holderInfo[jr].second;
649  size_t roiLen = rois[theROI].second - rois[theROI].first;
650  size_t bEnd = bBegin + roiLen;
651  float basePre = 0., basePost = 0.;
652  // Baseline subtraction if requested and the ROIs are padded.
653  // Can't baseline subtract signals when the ROI start is close to 0 either
654  if(fDoBaselineSub && fPreROIPad[thePlane] > 0 &&
655  rois[theROI].first > fPreROIPad[thePlane])
656  {
657  // find the baseline from the first few bins in the leading Pad region
658  unsigned short bbins = fPreROIPad[thePlane];
659  size_t bin;
660  if(bbins > 5) bbins = 5;
661  for(bin = 0; bin < bbins; ++bin) {
662  basePre += holder[bBegin + bin];
663  basePost += holder[bEnd - bin];
664  }
665  basePre /= (float)bbins;
666  basePost /= (float)bbins;
667  float slp = (basePost - basePre) / (float)(roiLen - bbins);
668  float base;
669  for(size_t jj = bBegin; jj < bEnd; ++jj) {
670  base = basePre + slp * (jj - bBegin);
671  sigTemp.push_back(holder[jj] - base);
672  } // jj
673  } // fDoBaselineSub ...
674  else {
675  for(size_t jj = bBegin; jj < bEnd; ++jj) sigTemp.push_back(holder[jj]);
676  } // !fDoBaselineSub ...
677 
678  // add the range into ROIVec
679  ROIVec.add_range(rois[theROI].first, std::move(sigTemp));
680  } // jr
681 } // doDecon
682 
683 
684 } // end namespace recowire
std::string fdQdxCalibFileName
Text file for constants to do wire-by-wire calibration.
std::string fDigitModuleLabel
module that made digits
RecoWireROI(fhicl::ParameterSet const &pset)
Utilities related to art service access.
static constexpr Sample_t transform(Sample_t sample)
float SubtractBaseline(std::vector< float > &holder, float basePre, float basePost, size_t roiStart, size_t roiLen, size_t dataSize)
double GetRawNoise(unsigned int const channel) const
Helper functions to create a wire.
pdgs p
Definition: selectors.fcl:22
std::vector< unsigned short > fThreshold
abs(threshold) ADC counts for ROI
std::vector< int > fNumSigma
&quot;# sigma&quot; rms noise for ROI threshold
std::vector< geo::WireID > ChannelToWire(raw::ChannelID_t const channel) const
Returns a list of wires connected to the specified TPC channel.
const datarange_t & add_range(size_type offset, ITER first, ITER last)
Adds a sequence of elements as a range with specified offset.
Definition of basic raw digits.
for pfile in ack l reconfigure(.*) override"` do echo "checking $
Class managing the creation of a new recob::Wire object.
Definition: WireCreator.h:53
bool fDodQdxCalib
Do we apply wire-by-wire calibration?
constexpr details::BinObj< T > bin(T value)
Returns a wrapper to print the specified data in binary format.
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:265
TString inFile
T abs(T value)
std::unique_ptr< icarus_signal_processing::ICARUSFFT< double > > fFFT
Object to handle thread safe FFT.
bool fDoBaselineSub
Do baseline subtraction after deconvolution?
virtual bool IsPresent(raw::ChannelID_t channel) const =0
Returns whether the specified channel is physical and connected to wire.
int fMinAllowedChanStatus
Don&#39;t consider channels with lower status.
constexpr ChannelID_t InvalidChannelID
ID of an invalid channel.
Definition: RawTypes.h:32
double distance(geo::Point_t const &point, CathodeDesc_t const &cathode)
Returns the distance of a point from the cathode.
void produce(art::Event &evt)
std::vector< unsigned short > fPostROIPad
ROI padding.
Collect all the RawData header files together.
const lariov::ChannelStatusProvider & fChanFilt
std::vector< SigProcPrecision > TimeVec
tick_as<> tick
Tick number, represented by std::ptrdiff_t.
Definition: electronics.h:75
virtual Status_t Status(raw::ChannelID_t channel) const
Returns a status integer with arbitrary meaning.
void fill(const art::PtrVector< recob::Hit > &hits, int only_plane)
std::map< unsigned int, float > fdQdxCalib
Map to do wire-by-wire calibration, key is channel number, content is correction factor.
size_t fEventCount
count of event processed
Class providing information about the quality of channels.
Description of geometry of one entire detector.
double GetDeconNoise(unsigned int const channel) const
virtual float PedMean(raw::ChannelID_t ch) const =0
Retrieve pedestal information.
unsigned short fNoiseSource
Used to determine ROI threshold.
bool CreateAssn(art::Event &evt, std::vector< T > const &a, art::Ptr< U > const &b, art::Assns< U, T > &assn, std::string a_instance, size_t index=UINT_MAX)
Creates a single one-to-one association.
virtual const icarusutil::FrequencyVec & getDeconvKernel() const =0
icarusutil::SignalShapingICARUSService & fSignalServices
if &&[-z"$BASH_VERSION"] then echo Attempting to switch to bash bash shellSwitch exit fi &&["$1"= 'shellSwitch'] shift declare a IncludeDirectives for Dir in
Interface for experiment-specific channel quality info provider.
T copy(T const &v)
const icarus_tool::IResponse & GetResponse(size_t channel) const
void reconfigure(fhicl::ParameterSet const &p)
Declaration of basic channel signal object.
bool fuPlaneRamp
set true for correct U plane wire response
BEGIN_PROLOG recowire
art::ServiceHandle< art::TFileService > tfs
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.
std::vector< unsigned short > fPreROIPad
ROI padding.
void Uncompress(const std::vector< short > &adc, std::vector< short > &uncompressed, raw::Compress_t compress)
Uncompresses a raw data buffer.
Definition: raw.cxx:776
double sampling_rate(DetectorClocksData const &data)
Returns the period of the TPC readout electronics clock.
unsigned short fNumBinsHalf
Determines # bins in ROI running sum.
const geo::GeometryCore & fGeometry
int ResponseTOffset(unsigned int const channel) const
void SetDecon(double samplingRate, size_t fftsize, size_t channel)
art framework interface to geometry description
BEGIN_PROLOG could also be cout
auto const detProp
void doDecon(icarusutil::TimeVec &holder, raw::ChannelID_t channel, unsigned int thePlane, const std::vector< std::pair< size_t, size_t >> &rois, const std::vector< std::pair< size_t, size_t >> &holderInfo, recob::Wire::RegionsOfInterest_t &ROIVec)
int fSaveWireWF
Save recob::wire object waveforms.