All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
BaselineStandard_tool.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 /// \file Baseline.cc
3 /// \author T. Usher
4 ////////////////////////////////////////////////////////////////////////
5 
6 #include <cmath>
8 #include "art/Utilities/ToolMacros.h"
9 #include "art/Framework/Principal/Handle.h"
10 #include "art_root_io/TFileService.h"
11 #include "messagefacility/MessageLogger/MessageLogger.h"
12 #include "cetlib_except/exception.h"
14 #include "larcore/CoreUtils/ServiceUtil.h" // lar::providerFrom()
15 
16 #include "TH1D.h"
17 
18 #include <fstream>
19 #include <numeric> // std::accumulate
20 
21 namespace icarus_tool
22 {
23 
25 {
26 public:
27  explicit BaselineStandard(const fhicl::ParameterSet& pset);
28 
30 
31  void configure(const fhicl::ParameterSet& pset) override;
32  void outputHistograms(art::TFileDirectory&) const override;
33 
34  float GetBaseline(std::vector<float> const&, raw::ChannelID_t, size_t, size_t) const override;
35 
36 private:
37  // fhicl parameters
39 
40  art::ServiceHandle<icarusutil::SignalShapingICARUSService> fSignalShaping;
41 };
42 
43 //----------------------------------------------------------------------
44 // Constructor.
45 BaselineStandard::BaselineStandard(const fhicl::ParameterSet& pset)
46 {
47  configure(pset);
48 }
49 
51 {
52 }
53 
54 void BaselineStandard::configure(const fhicl::ParameterSet& pset)
55 {
56  // Start by recovering the parameters
57  fNumBinsToAverage = pset.get<int>("NumBinsToAverage", 20);
58 
59  // Get signal shaping service.
60  fSignalShaping = art::ServiceHandle<icarusutil::SignalShapingICARUSService>();
61 
62  return;
63 }
64 
65 
66 float BaselineStandard::GetBaseline(std::vector<float> const& holder,
67  raw::ChannelID_t channel,
68  size_t roiStart,
69  size_t roiLen) const
70 {
71  float base=0;
72  //1. Check Baseline match?
73  // If not, include next ROI(if none, go to the end of signal)
74  // If yes, proceed
75  size_t nBinsToAve(fNumBinsToAverage);
76  size_t roiStop(roiStart + roiLen);
77  size_t newRoiStart(roiStart);
78  size_t newRoiStop(roiStop);
79  size_t nTries(4);
80 
81  // Calculate baslines from the very front of the deconvolution buffer and from the end
82  float basePre = std::accumulate(holder.begin() + roiStart, holder.begin() + roiStart + nBinsToAve, 0.) / float(nBinsToAve);
83  float basePost = std::accumulate(holder.begin() + roiStop - nBinsToAve, holder.begin() + roiStop, 0.) / float(nBinsToAve);
84 
85  // emulate method for refining baseline from original version of CalWireROI
86  float deconNoise = 1.26491 * fSignalShaping->GetDeconNoise(channel); // 4./sqrt(10) * noise
87 
88  // If the estimated baseline from the front of the roi does not agree well with that from the end
89  // of the roi then we'll extend the roi hoping for good agreement
90  while(!(fabs(basePre - basePost) < deconNoise) && nTries++ < 3)
91  {
92  size_t nBinsToAdd(10);
93 
94  if (newRoiStart < nBinsToAdd) newRoiStart = 0;
95  else newRoiStart -= nBinsToAdd;
96  if (newRoiStop + nBinsToAdd > holder.size()) newRoiStop = holder.size();
97  else newRoiStop += nBinsToAdd;
98 
99  basePre = std::accumulate(holder.begin() + newRoiStart, holder.begin() + newRoiStart + nBinsToAve, 0.) / float(nBinsToAve);
100  basePost = std::accumulate(holder.begin() + newRoiStop - nBinsToAve, holder.begin() + newRoiStop, 0.) / float(nBinsToAve);
101  }
102 
103  // get spread in "pre" baseline
104  float maxPre = *std::max_element(holder.begin() + roiStart, holder.begin() + roiStart + nBinsToAve);
105  float minPre = *std::min_element(holder.begin() + roiStart, holder.begin() + roiStart + nBinsToAve);
106 
107  // Basically, we are hoping for a relatively smooth "front porch" for the waveform
108  if ((maxPre - minPre) < 4.) base = basePre;
109  else
110  {
111  // No success... see if the "back porch" is smooth
112  size_t roiStop = roiStart + roiLen;
113 
114  float maxPost = *std::max_element(holder.begin() + roiStop - nBinsToAve, holder.begin() + roiStop);
115  float minPost = *std::min_element(holder.begin() + roiStop - nBinsToAve, holder.begin() + roiStop);
116 
117  if ((maxPost - minPost) < 4.) base = basePost;
118  // Starting to get desparate...
119  else if ((maxPre - minPre) < 8. && std::fabs(basePre) < std::fabs(basePost)) base = basePre;
120  else if ((maxPost - minPost) < 8. && std::fabs(basePost) < std::fabs(basePre)) base = basePost;
121  // Ok, apply brute force
122  else
123  {
124  float min = *std::min_element(holder.begin()+roiStart,holder.begin()+roiStart+roiLen);
125  float max = *std::max_element(holder.begin()+roiStart,holder.begin()+roiStart+roiLen);
126  int nbin = std::ceil(max - min);
127  if (nbin > 0){
128  TH1F *h1 = new TH1F("h1","h1",nbin,min,max);
129  for (unsigned int bin = roiStart; bin < roiStart+roiLen; bin++){
130  h1->Fill(holder[bin]);
131  }
132  int pedBin = h1->GetMaximumBin();
133  float ped = h1->GetBinCenter(pedBin);
134  float ave=0,ncount = 0;
135  for (unsigned int bin = roiStart; bin < roiStart+roiLen; bin++){
136  if (fabs(holder[bin]-ped)<2){
137  ave +=holder[bin];
138  ncount ++;
139  }
140  }
141  if (ncount==0) ncount=1;
142  ave = ave/ncount;
143  h1->Delete();
144  base = ave;
145  }
146  }
147  }
148 
149  return base;
150 }
151 
152 void BaselineStandard::outputHistograms(art::TFileDirectory& histDir) const
153 {
154  // It is assumed that the input TFileDirectory has been set up to group histograms into a common
155  // folder at the calling routine's level. Here we create one more level of indirection to keep
156  // histograms made by this tool separate.
157 /*
158  std::string dirName = "BaselinePlane_" + std::to_string(fPlane);
159 
160  art::TFileDirectory dir = histDir.mkdir(dirName.c_str());
161 
162  auto const* detprop = lar::providerFrom<detinfo::DetectorPropertiesService>();
163  double samplingRate = detprop->SamplingRate();
164  double numBins = fBaselineVec.size();
165  double maxFreq = 500. / samplingRate;
166  std::string histName = "BaselinePlane_" + std::to_string(fPlane);
167 
168  TH1D* hist = dir.make<TH1D>(histName.c_str(), "Baseline;Frequency(MHz)", numBins, 0., maxFreq);
169 
170  for(int bin = 0; bin < numBins; bin++)
171  {
172  double freq = maxFreq * double(bin + 0.5) / double(numBins);
173 
174  hist->Fill(freq, fBaselineVec.at(bin).Re());
175  }
176 */
177 
178  return;
179 }
180 
181 DEFINE_ART_CLASS_TOOL(BaselineStandard)
182 }
Utilities related to art service access.
void outputHistograms(art::TFileDirectory &) const override
This provides an interface for tools which are tasked with finding the baselines in input waveforms...
constexpr details::BinObj< T > bin(T value)
Returns a wrapper to print the specified data in binary format.
float GetBaseline(std::vector< float > const &, raw::ChannelID_t, size_t, size_t) const override
art::ServiceHandle< icarusutil::SignalShapingICARUSService > fSignalShaping
unsigned int ChannelID_t
Type representing the ID of a readout channel.
Definition: RawTypes.h:28
BaselineStandard(const fhicl::ParameterSet &pset)
void configure(const fhicl::ParameterSet &pset) override