All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PeakFitterMrqdt_tool.cc
Go to the documentation of this file.
2 #include "larreco/RecoAlg/GausFitCache.h" // hit::GausFitCache
4 #include "larvecutils/MarqFitAlg/MarqFitAlg.h" //marqfit functions
5 
6 #include "art/Utilities/ToolMacros.h"
7 #include "cetlib_except/exception.h"
9 #include "messagefacility/MessageLogger/MessageLogger.h"
10 
11 #include <cassert>
12 #include <cmath>
13 #include <fstream>
14 
16 
17 namespace reco_tool {
18 
20  public:
21  explicit PeakFitterMrqdt(const fhicl::ParameterSet& pset);
22 
23  void findPeakParameters(const std::vector<float>&,
26  double&,
27  int&) const override;
28 
29  private:
30  //Variables from the fhicl file
31  const double fMinWidth;
32  const double fMaxWidthMult;
33  const double fPeakRange;
34  const double fAmpRange;
35 
36  std::unique_ptr<gshf::MarqFitAlg> fMarqFitAlg;
37 
38  const geo::GeometryCore* fGeometry = lar::providerFrom<geo::Geometry>();
39  };
40 
41  //--------------------------
42  //constructor
43 
44  PeakFitterMrqdt::PeakFitterMrqdt(const fhicl::ParameterSet& pset)
45  : fMinWidth(pset.get<double>("MinWidth", 0.5))
46  , fMaxWidthMult(pset.get<double>("MaxWidthMult", 3.))
47  , fPeakRange(pset.get<double>("PeakRangeFact", 2.))
48  , fAmpRange(pset.get<double>("PeakAmpRange", 2.))
49  {}
50 
51  //------------------------
52  //output parameters should be replaced with a returned value
53  void
54  PeakFitterMrqdt::findPeakParameters(const std::vector<float>& signal,
56  PeakParamsVec& mhpp_vec,
57  double& chi2PerNDF,
58  int& NDF) const
59  {
60  if (fhc_vec.empty()) return;
61 
62  const float chiCut = 1e-3;
63  float lambda = 0.001; /* Marquardt damping parameter */
64  float chiSqr = std::numeric_limits<float>::max(), dchiSqr = std::numeric_limits<float>::max();
65  int nParams = 0;
66 
67  int startTime = fhc_vec.front().startTick;
68  int endTime = fhc_vec.back().stopTick;
69 
70  int roiSize = endTime - startTime;
71 
72  // init to a large number in case the fit fails
73  chi2PerNDF = chiSqr;
74 
75  std::vector<float> y(roiSize);
76  std::vector<float> p(3 * fhc_vec.size());
77  std::vector<float> plimmin(3 * fhc_vec.size());
78  std::vector<float> plimmax(3 * fhc_vec.size());
79  std::vector<float> perr(3 * fhc_vec.size());
80 
81  /* choose the fit function and set the parameters */
82  nParams = 0;
83 
84  for (size_t ih = 0; ih < fhc_vec.size(); ih++) {
85  float const peakMean =
86  fhc_vec[ih].hitCenter - 0.5 - (float)startTime; //shift by 0.5 to account for bin width
87  float const peakWidth = fhc_vec[ih].hitSigma;
88  float const amplitude = fhc_vec[ih].hitHeight;
89  float const meanLowLim = fmax(peakMean - fPeakRange * peakWidth, 0.);
90  float const meanHiLim = fmin(peakMean + fPeakRange * peakWidth, (float)roiSize);
91  p[0 + nParams] = amplitude;
92  p[1 + nParams] = peakMean;
93  p[2 + nParams] = peakWidth;
94 
95  plimmin[0 + nParams] = amplitude * 0.1;
96  plimmin[1 + nParams] = meanLowLim;
97  plimmin[2 + nParams] = std::max(fMinWidth, 0.1 * peakWidth);
98 
99  plimmax[0 + nParams] = amplitude * fAmpRange;
100  plimmax[1 + nParams] = meanHiLim;
101  plimmax[2 + nParams] = fMaxWidthMult * peakWidth;
102 
103  nParams += 3;
104  }
105  int fitResult = -1;
106 
107  for (size_t idx = 0; idx < size_t(roiSize); idx++) {
108  y[idx] = signal[startTime + idx];
109  }
110 
111  int trial = 0;
112  lambda = -1.; /* initialize lambda on first call */
113  do {
114  fitResult = fMarqFitAlg->gshf::MarqFitAlg::mrqdtfit(
115  lambda, &p[0], &plimmin[0], &plimmax[0], &y[0], nParams, roiSize, chiSqr, dchiSqr);
116  trial++;
117  if (fitResult || (trial > 100)) break;
118  } while (fabs(dchiSqr) >= chiCut);
119 
120  if (!fitResult) {
121  int fitResult2 =
122  fMarqFitAlg->gshf::MarqFitAlg::cal_perr(&p[0], &y[0], nParams, roiSize, &perr[0]);
123  if (!fitResult2) {
124  NDF = roiSize - nParams;
125  chi2PerNDF = chiSqr / NDF;
126  int parIdx = 0;
127  for (size_t i = 0; i < fhc_vec.size(); i++) {
128 
129  /* stand alone method
130  mhpp_vec[i].peakAmplitude = p[parIdx + 0];
131  mhpp_vec[i].peakAmplitudeError = perr[parIdx + 0];
132  mhpp_vec[i].peakCenter = p[parIdx + 1] + 0.5 + float(startTime);
133  mhpp_vec[i].peakCenterError = perr[parIdx + 1];
134  mhpp_vec[i].peakSigma = p[parIdx + 2];
135  mhpp_vec[i].peakSigmaError = perr[parIdx + 2];
136  */
137 
138  PeakFitParams_t mhpp;
139  mhpp.peakAmplitude = p[parIdx + 0];
140  mhpp.peakAmplitudeError = perr[parIdx + 0];
141  mhpp.peakCenter =
142  p[parIdx + 1] + 0.5 + float(startTime); //shift by 0.5 to account for bin width
143  mhpp.peakCenterError = perr[parIdx + 1];
144  mhpp.peakSigma = std::abs(p[parIdx + 2]);
145  mhpp.peakSigmaError = perr[parIdx + 2];
146 
147  mhpp_vec.emplace_back(mhpp);
148 
149  parIdx += 3;
150  }
151 
152  // fitStat=0;
153  }
154  }
155  return;
156  }
157 
158  DEFINE_ART_CLASS_TOOL(PeakFitterMrqdt)
159 }
Utilities related to art service access.
void findPeakParameters(const std::vector< float > &, const ICandidateHitFinder::HitCandidateVec &, PeakParamsVec &, double &, int &) const override
double lambda(double a, double b, double c)
std::unique_ptr< gshf::MarqFitAlg > fMarqFitAlg
pdgs p
Definition: selectors.fcl:22
T abs(T value)
process_name opflash particleana ie ie y
PeakFitterMrqdt(const fhicl::ParameterSet &pset)
Description of geometry of one entire detector.
do i e
This provides an interface for tools which are tasked with finding candidate hits on input waveforms...
Provide caches for TF1 functions to be used with ROOT fitters.
const geo::GeometryCore * fGeometry
art framework interface to geometry description
std::vector< HitCandidate > HitCandidateVec