LArSoft  v07_13_02
Liquid Argon Software toolkit - http://larsoft.org/
PeakFitterGaussian_tool.cc
Go to the documentation of this file.
1 
7 #include "larreco/RecoAlg/GausFitCache.h" // hit::GausFitCache
8 
12 #include "cetlib_except/exception.h"
15 
16 #include <cmath>
17 #include <cassert>
18 #include <fstream>
19 #include "TH1F.h"
20 #include "TF1.h"
21 
22 namespace reco_tool
23 {
24 
29 
30  public:
32  BaselinedGausFitCache(std::string const& new_name="BaselinedGausFitCache")
33  : hit::GausFitCache(new_name)
34  {}
35 
36  protected:
37 
41  virtual TF1* CreateFunction(size_t nFunc) const
42  {
43  // add the Gaussians first
44  std::string formula;
45  std::size_t iGaus = 0;
46  while (iGaus < nFunc)
47  formula += "gaus(" + std::to_string(3 * (iGaus++)) + ") + ";
48  formula += "[" + std::to_string(3 * iGaus) + "]";
49 
50  std::string const func_name = FunctionName(nFunc);
51  auto* pF = new TF1(func_name.c_str(), formula.c_str());
52  pF->SetParName(iGaus * 3, "baseline");
53  return pF;
54  } // CreateFunction()
55 
56 }; // BaselinedGausFitCache
57 
58 
60 {
61 public:
62  explicit PeakFitterGaussian(const fhicl::ParameterSet& pset);
63 
65 
66  void configure(const fhicl::ParameterSet& pset) override;
67 
68  void findPeakParameters(const std::vector<float>&,
71  double&,
72  int&) const override;
73 
74 private:
75  // Member variables from the fhicl file
76  double fMinWidth;
77  double fMaxWidthMult;
78  double fPeakRange;
79  double fAmpRange;
81 
83 
84  mutable TH1F fHistogram;
85 
86  const geo::GeometryCore* fGeometry = lar::providerFrom<geo::Geometry>();
87 };
88 
89 //----------------------------------------------------------------------
90 // Constructor.
92 {
93  configure(pset);
94 }
95 
97 {
98 }
99 
101 {
102  // Start by recovering the parameters
103  fMinWidth = pset.get<double>("MinWidth", 0.5);
104  fMaxWidthMult = pset.get<double>("MaxWidthMult", 3.);
105  fPeakRange = pset.get<double>("PeakRangeFact", 2.);
106  fAmpRange = pset.get<double>("PeakAmpRange", 2.);
107  fFloatBaseline = pset.get< bool >("FloatBaseline", false);
108 
109  fHistogram = TH1F("PeakFitterHitSignal","",500,0.,500.);
110 
111  fHistogram.Sumw2();
112 
113  std::string function = "Gaus(0)";
114 
115  return;
116 }
117 
118 // --------------------------------------------------------------------------------------------
119 void PeakFitterGaussian::findPeakParameters(const std::vector<float>& roiSignalVec,
120  const ICandidateHitFinder::HitCandidateVec& hitCandidateVec,
121  PeakParamsVec& peakParamsVec,
122  double& chi2PerNDF,
123  int& NDF) const
124 {
125  // The following is a translation of the original FitGaussians function in the original
126  // GausHitFinder module originally authored by Jonathan Asaadi
127  //
128  // *** NOTE: this algorithm assumes the reference time for input hit candidates is to
129  // the first tick of the input waveform (ie 0)
130  //
131  if (hitCandidateVec.empty()) return;
132 
133  // in case of a fit failure, set the chi-square to infinity
134  chi2PerNDF = std::numeric_limits<double>::infinity();
135 
136  int startTime = hitCandidateVec.front().startTick;
137  int endTime = hitCandidateVec.back().stopTick;
138  int roiSize = endTime - startTime;
139 
140  // Check to see if we need a bigger histogram for fitting
141  if (roiSize > fHistogram.GetNbinsX())
142  {
143  std::string histName = "PeakFitterHitSignal_" + std::to_string(roiSize);
144  fHistogram = TH1F(histName.c_str(),"",roiSize,0.,roiSize);
145  fHistogram.Sumw2();
146  }
147 
148  for(int idx = 0; idx < roiSize; idx++) fHistogram.SetBinContent(idx+1,roiSignalVec.at(startTime+idx));
149 
150  // Build the string to describe the fit formula
151 #if 0
152  std::string equation = "gaus(0)";
153 
154  for(size_t idx = 1; idx < hitCandidateVec.size(); idx++) equation += "+gaus(" + std::to_string(3*idx) + ")";
155 
156  // Set the baseline if so desired
157  float baseline(0.);
158 
159  if (fFloatBaseline)
160  {
161  baseline = roiSignalVec.at(startTime);
162 
163  equation += "+" + std::to_string(baseline);
164  }
165 
166  // Now define the complete function to fit
167  TF1 Gaus("Gaus",equation.c_str(),0,roiSize,TF1::EAddToList::kNo);
168 #else
169  unsigned int const nGaus = hitCandidateVec.size();
170  assert(fFitCache.Get(nGaus));
171  TF1& Gaus = *(fFitCache.Get(nGaus));
172 
173  // Set the baseline if so desired
174  float const baseline = fFloatBaseline? roiSignalVec.at(startTime): 0.0;
175 
176  Gaus.FixParameter(nGaus * 3, baseline); // last parameter is the baseline
177 
178 #endif // 0
179 
180  // ### Setting the parameters for the Gaussian Fit ###
181  int parIdx{0};
182  for(auto const& candidateHit : hitCandidateVec)
183  {
184  double const peakMean = candidateHit.hitCenter - float(startTime);
185  double const peakWidth = candidateHit.hitSigma;
186  double const amplitude = candidateHit.hitHeight - baseline;
187  double const meanLowLim = std::max(peakMean - fPeakRange * peakWidth, 0.);
188  double const meanHiLim = std::min(peakMean + fPeakRange * peakWidth, double(roiSize));
189 
190  Gaus.SetParameter( parIdx, amplitude);
191  Gaus.SetParameter(1+parIdx, peakMean);
192  Gaus.SetParameter(2+parIdx, peakWidth);
193  Gaus.SetParLimits( parIdx, 0.1 * amplitude, fAmpRange * amplitude);
194  Gaus.SetParLimits(1+parIdx, meanLowLim, meanHiLim);
195  Gaus.SetParLimits(2+parIdx, std::max(fMinWidth, 0.1 * peakWidth), fMaxWidthMult * peakWidth);
196 
197  parIdx += 3;
198  }
199 
200  int fitResult{-1};
201 
202  try
203  { fitResult = fHistogram.Fit(&Gaus,"QNWB","", 0., roiSize);}
204  catch(...)
205  {mf::LogWarning("GausHitFinder") << "Fitter failed finding a hit";}
206 
207  // If the fit result is not zero there was an error
208  if (!fitResult)
209  {
210  // ##################################################
211  // ### Getting the fitted parameters from the fit ###
212  // ##################################################
213  chi2PerNDF = (Gaus.GetChisquare() / Gaus.GetNDF());
214  NDF = Gaus.GetNDF();
215 
216  int parIdx { 0 };
217  for(size_t idx = 0; idx < hitCandidateVec.size(); idx++)
218  {
219  PeakFitParams_t peakParams;
220 
221  peakParams.peakAmplitude = Gaus.GetParameter(parIdx);
222  peakParams.peakAmplitudeError = Gaus.GetParError( parIdx);
223  peakParams.peakCenter = Gaus.GetParameter(parIdx + 1) + float(startTime);
224  peakParams.peakCenterError = Gaus.GetParError( parIdx + 1);
225  peakParams.peakSigma = Gaus.GetParameter(parIdx + 2);
226  peakParams.peakSigmaError = Gaus.GetParError( parIdx + 2);
227 
228  peakParamsVec.emplace_back(peakParams);
229 
230  parIdx += 3;
231  }
232  }
233 #if 0
234  Gaus.Delete();
235 #endif // 0
236  return;
237 }
238 
240 }
bool fFloatBaseline
Allow baseline to "float" away from zero.
double fMaxWidthMult
multiplier for max width for gaussian fit
#define DEFINE_ART_CLASS_TOOL(tool)
Definition: ToolMacros.h:45
void configure(const fhicl::ParameterSet &pset) override
double fAmpRange
set range limit for peak amplitude
std::vector< HitCandidate_t > HitCandidateVec
double fPeakRange
set range limits for peak center
PeakFitterGaussian(const fhicl::ParameterSet &pset)
struct PeakFitParams{float peakCenter PeakFitParams_t
Definition: IPeakFitter.h:31
A set of TF1 linear sum of base functions (Gaussians)
Definition: GausFitCache.h:50
BaselinedGausFitCache fFitCache
Preallocated ROOT functions for the fits.
Int_t max
Definition: plot.C:27
T get(std::string const &key) const
Definition: ParameterSet.h:231
BaselinedGausFitCache(std::string const &new_name="BaselinedGausFitCache")
Constructor (see base class constructor).
Description of geometry of one entire detector.
GausFitCache(std::string new_name="GausFitCache")
Constructor; optionally set the name of the repository.
Definition: GausFitCache.h:53
Detector simulation of raw signals on wires.
virtual TF1 * CreateFunction(size_t nFunc) const
std::vector< PeakFitParams_t > PeakParamsVec
Definition: IPeakFitter.h:39
std::string to_string(Flag_t< Storage > const flag)
Convert a flag into a stream (shows its index).
Definition: BitMask.h:187
This provides an interface for tools which are tasked with fitting peaks on input waveforms...
Int_t min
Definition: plot.C:26
virtual std::string FunctionName(size_t nFunc) const
Returns a name for the function with nFunc base functions.
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
Provide caches for TF1 functions to be used with ROOT fitters.
double fMinWidth
minimum initial width for gaussian fit
void findPeakParameters(const std::vector< float > &, const ICandidateHitFinder::HitCandidateVec &, PeakParamsVec &, double &, int &) const override
art framework interface to geometry description