LArSoft  v06_85_00
Liquid Argon Software toolkit - http://larsoft.org/
PeakFitterGaussian_tool.cc
Go to the documentation of this file.
1 
7 
11 #include "cetlib_except/exception.h"
14 
15 #include <cmath>
16 #include <fstream>
17 #include "TH1F.h"
18 #include "TF1.h"
19 
20 namespace reco_tool
21 {
22 
24 {
25 public:
26  explicit PeakFitterGaussian(const fhicl::ParameterSet& pset);
27 
29 
30  void configure(const fhicl::ParameterSet& pset) override;
31 
32  void findPeakParameters(const std::vector<float>&,
35  double&,
36  int&) const override;
37 
38 private:
39  // Member variables from the fhicl file
40  double fMinWidth;
41  double fMaxWidthMult;
42  double fPeakRange;
43  double fAmpRange;
44 
45  mutable TH1F fHistogram;
46 
47  const geo::GeometryCore* fGeometry = lar::providerFrom<geo::Geometry>();
48 };
49 
50 //----------------------------------------------------------------------
51 // Constructor.
53 {
54  configure(pset);
55 }
56 
58 {
59 }
60 
62 {
63  // Start by recovering the parameters
64  fMinWidth = pset.get<double>("MinWidth", 0.5);
65  fMaxWidthMult = pset.get<double>("MaxWidthMult", 3.);
66  fPeakRange = pset.get<double>("PeakRangeFact", 2.);
67  fAmpRange = pset.get<double>("PeakAmpRange", 2.);
68 
69  fHistogram = TH1F("PeakFitterHitSignal","",500,0.,500.);
70 
71  fHistogram.Sumw2();
72 
73  std::string function = "Gaus(0)";
74 
75  return;
76 }
77 
78 // --------------------------------------------------------------------------------------------
79 void PeakFitterGaussian::findPeakParameters(const std::vector<float>& roiSignalVec,
80  const ICandidateHitFinder::HitCandidateVec& hitCandidateVec,
81  PeakParamsVec& peakParamsVec,
82  double& chi2PerNDF,
83  int& NDF) const
84 {
85  // The following is a translation of the original FitGaussians function in the original
86  // GausHitFinder module originally authored by Jonathan Asaadi
87  //
88  // *** NOTE: this algorithm assumes the reference time for input hit candidates is to
89  // the first tick of the input waveform (ie 0)
90  //
91  if (hitCandidateVec.empty()) return;
92 
93  // in case of a fit failure, set the chi-square to infinity
94  chi2PerNDF = std::numeric_limits<double>::infinity();
95 
96  int startTime = hitCandidateVec.front().startTick;
97  int endTime = hitCandidateVec.back().stopTick;
98  int roiSize = endTime - startTime;
99 
100  // Check to see if we need a bigger histogram for fitting
101  if (roiSize > fHistogram.GetNbinsX())
102  {
103  std::string histName = "PeakFitterHitSignal_" + std::to_string(roiSize);
104  fHistogram = TH1F(histName.c_str(),"",roiSize,0.,roiSize);
105  fHistogram.Sumw2();
106  }
107 
108  for(int idx = 0; idx < roiSize; idx++) fHistogram.SetBinContent(idx+1,roiSignalVec.at(startTime+idx));
109 
110  // Build the string to describe the fit formula
111  std::string equation = "gaus(0)";
112 
113  for(size_t idx = 1; idx < hitCandidateVec.size(); idx++) equation += "+gaus(" + std::to_string(3*idx) + ")";
114 
115  // Now define the complete function to fit
116  TF1 Gaus("Gaus",equation.c_str(),0,roiSize);
117 
118  // ### Setting the parameters for the Gaussian Fit ###
119  int parIdx(0);
120  for(auto& candidateHit : hitCandidateVec)
121  {
122  double peakMean = candidateHit.hitCenter - float(startTime);
123  double peakWidth = candidateHit.hitSigma;
124  double amplitude = candidateHit.hitHeight;
125  double meanLowLim = std::max(peakMean - fPeakRange * peakWidth, 0.);
126  double meanHiLim = std::min(peakMean + fPeakRange * peakWidth, double(roiSize));
127 
128  Gaus.SetParameter( parIdx, amplitude);
129  Gaus.SetParameter(1+parIdx, peakMean);
130  Gaus.SetParameter(2+parIdx, peakWidth);
131  Gaus.SetParLimits( parIdx, 0.1 * amplitude, fAmpRange * amplitude);
132  Gaus.SetParLimits(1+parIdx, meanLowLim, meanHiLim);
133  Gaus.SetParLimits(2+parIdx, std::max(fMinWidth, 0.1 * peakWidth), fMaxWidthMult * peakWidth);
134 
135  parIdx += 3;
136  }
137 
138  int fitResult(-1);
139 
140  try
141  { fitResult = fHistogram.Fit(&Gaus,"QNRWB","", 0., roiSize);}
142  catch(...)
143  {mf::LogWarning("GausHitFinder") << "Fitter failed finding a hit";}
144 
145  // If the fit result is not zero there was an error
146  if (!fitResult)
147  {
148  // ##################################################
149  // ### Getting the fitted parameters from the fit ###
150  // ##################################################
151  chi2PerNDF = (Gaus.GetChisquare() / Gaus.GetNDF());
152  NDF = Gaus.GetNDF();
153 
154  parIdx = 0;
155  for(size_t idx = 0; idx < hitCandidateVec.size(); idx++)
156  {
157  PeakFitParams_t peakParams;
158 
159  peakParams.peakAmplitude = Gaus.GetParameter(parIdx);
160  peakParams.peakAmplitudeError = Gaus.GetParError( parIdx);
161  peakParams.peakCenter = Gaus.GetParameter(parIdx + 1) + float(startTime);
162  peakParams.peakCenterError = Gaus.GetParError( parIdx + 1);
163  peakParams.peakSigma = Gaus.GetParameter(parIdx + 2);
164  peakParams.peakSigmaError = Gaus.GetParError( parIdx + 2);
165 
166  peakParamsVec.emplace_back(peakParams);
167 
168  parIdx += 3;
169  }
170  }
171 
172  Gaus.Delete();
173 
174  return;
175 }
176 
178 }
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
Int_t max
Definition: plot.C:27
T get(std::string const &key) const
Definition: ParameterSet.h:231
const geo::GeometryCore * fGeometry
Description of geometry of one entire detector.
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
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
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