All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Fit.h
Go to the documentation of this file.
1 #pragma once
2 
6 
7 #include "Math/Minimizer.h"
8 
9 #include <memory>
10 
11 class TGraph;
12 
13 namespace osc
14 {
15  template<class T> class _IOscCalcAdjustable;
16  typedef _IOscCalcAdjustable<double> IOscCalcAdjustable;
17 }
18 
19 namespace ana
20 {
21  class IExperiment;
22  class IFitVar;
23 
24  /// \brief Figure-of-merit with no systematics, for binned data
25  ///
26  /// \param obs The observed data
27  /// \param unosc A spectrum representing the null hypothesis
28  /// \param pot POT to scale to. Leave at default to adopt POT from \a obs
29  ///
30  /// \returns Sum in quadrature over the bins
31  /// \f[ \sqrt{\sum_i^{\rm bins}\left({s_i\over\sqrt{s_i+b_i}}\right)^2} \f]
32  double SimpleFOM(const Spectrum& obs, const Spectrum& unosc, double pot = 0);
33 
34  namespace{SystShifts junkShifts;}
35 
36  /// Perform MINUIT fits in one or two dimensions
37  class Fitter: public ROOT::Math::IBaseFunctionMultiDim
38  {
39  public:
41 
42  enum Precision{
43  // You must select one of these. The first three codes match the settings
44  // used by migrad. The fourth is a custom minimizer.
45  kFast = 0,
46  kNormal = 1,
47  kCareful = 2,
48  kGradDesc = 3,
49  // Allow bitmask operations to extract these first four options
50  kAlgoMask = 3,
51  // You may optionally specify this (eg kNormal | kIncludeSimplex) to
52  // improve the chances of escaping from invalid minima
54  // You may optionally specify these to improve the final error estimates
57  };
59 
60  Fitter(const IExperiment* expt,
61  std::vector<const IFitVar*> vars,
62  std::vector<const ISyst*> systs = {},
64 
65  /// \param[out] seed Seed parameter and output best-fit point
66  /// \param[out] bestSysts Best systematics result returned here
67  /// \param seedPts Set each var to each of the values. Try all
68  /// combinations. Beware of combinatorical explosion...
69  /// \param systSeedPts If non-empty, try fit starting at each of these
70  /// \param verb If quiet, no printout
71  /// \return -2x the log-likelihood of the best-fit point
73  SystShifts& bestSysts = junkShifts,
74  const std::map<const IFitVar*, std::vector<double>>& seedPts = {},
75  const std::vector<SystShifts>& systSeedPts = {},
76  Verbosity verb = kVerbose) const;
77 
78  /// Variant with no seedPts
80  SystShifts& systSeed,
81  Verbosity verb) const
82  {
83  return Fit(seed, systSeed, {}, std::vector<SystShifts>(1, systSeed), verb);
84  }
85 
86  /// Variant with no seedPts and no systematics result returned
88  Verbosity verb) const
89  {
90  return Fit(seed, junkShifts, {}, {}, verb);
91  }
92 
93  /// Variant with no oscillations - useful for ND fits
94  double Fit(SystShifts& systSeed, Verbosity verb = kVerbose) const
95  {
96  return Fit(0, systSeed, {}, std::vector<SystShifts>(1, systSeed), verb);
97  }
98 
99  /// Return the fit covariance
100  TMatrixDSym* GetCovariance(){ return this->fCovar;}
101 
102  /// covariance matrix status (0 = not valid, 1 approximate, 2, full but made pos def, 3 accurate and not pos def)
103  int GetCovarianceStatus() {return this->fCovarStatus;}
104 
105  /// Return the fit names
106  std::vector<std::string> GetParamNames(){ return this->fParamNames;}
107 
108  /// Return the prefit values
109  std::vector<double> GetPreFitValues(){ return this->fPreFitValues;}
110 
111  /// Return the prefit errors
112  std::vector<double> GetPreFitErrors(){ return this->fPreFitErrors;}
113 
114  /// Return the postfit values
115  std::vector<double> GetPostFitValues(){ return this->fPostFitValues;}
116 
117  /// Return the postfit errors
118  std::vector<double> GetPostFitErrors(){ return this->fPostFitErrors;}
119 
120  /// Return the minos errors
121  std::vector<std::pair<double,double>> GetMinosErrors(){ return this->fMinosErrors;}
122 
123  /// Return number of function calls
124  int GetNFCN(){return this->fNEval;}
125 
126  /// Return edm form the fit
127  double GetEDM(){return this->fEdm;}
128 
129  /// Say whether the fit was good
130  bool GetIsValid(){return this->fIsValid;}
131 
132  SystShifts GetSystShifts() const {return fShifts;}
133 
134  /// Evaluate the log-likelihood, as required by MINUT interface
135  virtual double DoEval(const double* pars) const override;
136 
137  // Part of the fitter interface
138  virtual unsigned int NDim() const override {return fVars.size()+fSysts.size();}
139 
140  Fitter* Clone() const override
141  {
142  std::cout << "Fitter::Clone() not implemented" << std::endl;
143  abort();
144  }
145 
146  protected:
147  struct SeedPt
148  {
149  std::map<const IFitVar*, double> fitvars;
151  };
152  std::vector<SeedPt> ExpandSeeds(const std::map<const IFitVar*,
153  std::vector<double>>& seedPts,
154  std::vector<SystShifts> systSeedPts) const;
155 
156  /// Helper for \ref FitHelper
157  std::unique_ptr<ROOT::Math::Minimizer>
159  SystShifts& systSeed,
160  Verbosity verb) const;
161 
162  /// Helper for \ref Fit
163  double FitHelper(osc::IOscCalcAdjustable* seed,
164  SystShifts& bestSysts,
165  const std::map<const IFitVar*, std::vector<double>>& seedPts,
166  std::vector<SystShifts> systSeedPts,
167  Verbosity verb) const;
168 
169  /// Updates mutable fCalc and fShifts
170  void DecodePars(const double* pars) const;
171 
173  std::vector<const IFitVar*> fVars;
174  std::vector<const ISyst*> fSysts;
178 
179  mutable int fNEval = 0;
180  mutable int fNEvalGrad = 0;
181  mutable int fNEvalFiniteDiff = 0;
182 
183  // Some information for post-fit evaluation if necessary
184  mutable double fEdm = -1;
185  mutable bool fIsValid = false;
186  mutable TMatrixDSym* fCovar;
187  mutable bool fCovarStatus;
188  mutable std::vector<std::string> fParamNames;
189  mutable std::vector<double> fPreFitValues;
190  mutable std::vector<double> fPreFitErrors;
191  mutable std::vector<double> fPostFitValues;
192  mutable std::vector<double> fPostFitErrors;
193  mutable std::vector<std::pair<double, double> > fMinosErrors;
194  mutable std::vector<std::pair<double, double> > fTempMinosErrors; // Bit of a hack
195  };
196 
197  // Modern C++ thinks that enum | enum == int. Make things work like we expect
198  // for this bitmask.
200  {
201  return Fitter::Precision(int(a) | int(b));
202  }
203 
204  // Default values for Profile()
205  static std::map<const IFitVar*, TGraph*> empty_vars_map;
206  static std::map<const ISyst*, TGraph*> empty_syst_map;
207 
208  /// \brief \f$\chi^2\f$ scan in one variable, profiling over all others
209  ///
210  /// \param expt The experiment to retrieve chisq values from
211  /// \param calc Initial values of all oscillation parameters
212  /// \param v Scan over this variable
213  /// \param nbinsx Binning
214  /// \param minx Binning
215  /// \param maxx Binning
216  /// \param minchi Set non-default to force a chisq value to evaluate delta
217  /// chisqs against. Useful for comparing two profiles. If set
218  /// to zero it will not zero-adjust and the axis will be
219  /// labelled without "delta"
220  /// \param profVars Profile over these variables
221  /// \param profSysts Profile over these systematics
222  /// \param seedPts Set each var to each of the values. Try all
223  /// combinations. Beware of combinatorical explosion...
224  /// \param systSeedPts If non-empty, try fit starting at each of these
225  /// \param[out] profVarsMap Pass empty map. Returns best values of each var.
226  /// \param[out] systsMap Pass empty map. Returns best values of each syst.
227  ///
228  /// \return The best fit delta chisq as a function of \a a
229  TH1* Profile(const IExperiment* expt,
231  const IFitVar* v,
232  int nbinsx, double minx, double maxx,
233  double minchi = -1,
234  const std::vector<const IFitVar*>& profVars = {},
235  const std::vector<const ISyst*>& profSysts = {},
236  const std::map<const IFitVar*, std::vector<double>>& seedPts = {},
237  const std::vector<SystShifts>& systsSeedPts = {},
238  std::map<const IFitVar*, TGraph*>& profVarsMap = empty_vars_map,
239  std::map<const ISyst*, TGraph*>& systsMap = empty_syst_map);
240 
241  TH1* Profile(const IExperiment* expt,
243  const ISyst* s,
244  int nbinsx, double minx, double maxx,
245  double minchi = -1,
246  const std::vector<const IFitVar*>& profVars = {},
247  const std::vector<const ISyst*>& profSysts = {},
248  const std::map<const IFitVar*, std::vector<double>>& seedPts = {},
249  const std::vector<SystShifts>& systsSeedPts = {},
250  std::map<const IFitVar*, TGraph*>& profVarsMap = empty_vars_map,
251  std::map<const ISyst*, TGraph*>& systsMap = empty_syst_map);
252 
253  /// Forward to \ref Profile but sqrt the result for a crude significance
254  TH1* SqrtProfile(const IExperiment* expt,
256  const IFitVar* v,
257  int nbinsx, double minx, double maxx,
258  double minchi = -1,
259  std::vector<const IFitVar*> profVars = {},
260  std::vector<const ISyst*> profSysts = {},
261  const std::map<const IFitVar*, std::vector<double>>& seedPts = {},
262  const std::vector<SystShifts>& systsSeedPts = {},
263  std::map<const IFitVar*, TGraph*>& profVarsMap = empty_vars_map,
264  std::map<const ISyst*, TGraph*>& systsMap = empty_syst_map);
265 
266  TH1* SqrtProfile(const IExperiment* expt,
268  const ISyst* s,
269  int nbinsx, double minx, double maxx,
270  double minchi = -1,
271  std::vector<const IFitVar*> profVars = {},
272  std::vector<const ISyst*> profSysts = {},
273  const std::map<const IFitVar*, std::vector<double>>& seedPts = {},
274  const std::vector<SystShifts>& systsSeedPts = {},
275  std::map<const IFitVar*, TGraph*>& profVarsMap = empty_vars_map,
276  std::map<const ISyst*, TGraph*>& systsMap = empty_syst_map);
277 
278  /// \f$\chi^2\f$ scan in one variable, holding all others constant
279  TH1* Slice(const IExperiment* expt,
280  osc::IOscCalcAdjustable* calc, const IFitVar* v,
281  int nbinsx, double minx, double maxx,
282  double minchi = -1);
283 
284  TH1* Slice(const IExperiment* expt,
285  osc::IOscCalcAdjustable* calc, const ISyst* s,
286  int nbinsx, double minx, double maxx,
287  double minchi = -1);
288 
289  /// Forward to \ref Slice but sqrt the result for a crude significance
290  TH1* SqrtSlice(const IExperiment* expt,
291  osc::IOscCalcAdjustable* calc, const IFitVar* v,
292  int nbinsx, double minx, double maxx, double minchi = -1);
293 
294  TH1* SqrtSlice(const IExperiment* expt,
295  osc::IOscCalcAdjustable* calc, const ISyst* s,
296  int nbinsx, double minx, double maxx, double minchi = -1);
297 
298  /// \brief Find the minimum in one variable as a function of another
299  ///
300  /// \param transpose plot \a scanVar on the y axis
301  TGraph* FindValley(const IExperiment* expt,
303  const IFitVar& scanVar,
304  const IFitVar& fitVar,
305  int nbinsx, double xmin, double xmax,
306  const std::vector<const IFitVar*>& profVars = {},
307  const std::vector<const ISyst*>& profSysts = {},
308  const std::map<const IFitVar*, std::vector<double>>& seedPts = {},
309  const std::vector<SystShifts>& systsSeedPts = {},
310  bool transpose = false);
311 
312  /// \brief Intended for use on the output of \ref Profile
313  ///
314  /// Returns a list of all the x-coordinates at which the curve described by
315  /// \a h crosses \a critVal. eg using critVal=1 will find the 1sigma lower
316  /// and upper bounds.
317  std::vector<double> FindCurveCrossings(TH1* h, double critVal);
318 }
std::vector< std::pair< double, double > > fMinosErrors
Definition: Fit.h:193
_IOscCalcAdjustable< double > IOscCalcAdjustable
Definition: Calcs.h:5
std::vector< std::pair< double, double > > fTempMinosErrors
Definition: Fit.h:194
TH1 * SqrtProfile(const IExperiment *expt, osc::IOscCalcAdjustable *calc, const IFitVar *v, int nbinsx, double minx, double maxx, double minchi, std::vector< const IFitVar * > profVars, std::vector< const ISyst * > profSysts, const std::map< const IFitVar *, std::vector< double >> &seedPts, const std::vector< SystShifts > &systSeedPts, std::map< const IFitVar *, TGraph * > &profVarsMap, std::map< const ISyst *, TGraph * > &systsMap)
Forward to Profile but sqrt the result for a crude significance.
Definition: Fit.cxx:565
double FitHelper(osc::IOscCalcAdjustable *seed, SystShifts &bestSysts, const std::map< const IFitVar *, std::vector< double >> &seedPts, std::vector< SystShifts > systSeedPts, Verbosity verb) const
Helper for Fit.
Definition: Fit.cxx:176
Fitter * Clone() const override
Definition: Fit.h:140
TGraph * FindValley(const IExperiment *expt, osc::IOscCalcAdjustable *calc, const IFitVar &scanVar, const IFitVar &fitVar, int nbinsx, double xmin, double xmax, const std::vector< const IFitVar * > &profVars, const std::vector< const ISyst * > &profSysts, const std::map< const IFitVar *, std::vector< double >> &seedPts, const std::vector< SystShifts > &systSeedPts, bool transpose)
Find the minimum in one variable as a function of another.
Definition: Fit.cxx:657
int fNEvalGrad
Definition: Fit.h:180
std::vector< double > GetPostFitValues()
Return the postfit values.
Definition: Fit.h:115
Fitter::Precision operator|(Fitter::Precision a, Fitter::Precision b)
Definition: Fit.h:199
Simple record of shifts applied to systematic parameters.
Definition: SystShifts.h:16
SystShifts shift
Definition: Fit.h:150
int GetCovarianceStatus()
covariance matrix status (0 = not valid, 1 approximate, 2, full but made pos def, 3 accurate and not ...
Definition: Fit.h:103
std::vector< double > GetPreFitValues()
Return the prefit values.
Definition: Fit.h:109
double Fit(osc::IOscCalcAdjustable *seed, SystShifts &bestSysts=junkShifts, const std::map< const IFitVar *, std::vector< double >> &seedPts={}, const std::vector< SystShifts > &systSeedPts={}, Verbosity verb=kVerbose) const
Definition: Fit.cxx:276
double Fit(osc::IOscCalcAdjustable *seed, SystShifts &systSeed, Verbosity verb) const
Variant with no seedPts.
Definition: Fit.h:79
std::vector< SeedPt > ExpandSeeds(const std::map< const IFitVar *, std::vector< double >> &seedPts, std::vector< SystShifts > systSeedPts) const
Definition: Fit.cxx:64
std::vector< double > FindCurveCrossings(TH1 *h, double critVal)
Intended for use on the output of Profile.
Definition: Fit.cxx:691
double fEdm
Definition: Fit.h:184
double Fit(osc::IOscCalcAdjustable *seed, Verbosity verb) const
Variant with no seedPts and no systematics result returned.
Definition: Fit.h:87
void SetPrecision(Precision prec)
Definition: Fit.cxx:270
process_name opflashCryoW ana
int fNEval
Definition: Fit.h:179
double GetEDM()
Return edm form the fit.
Definition: Fit.h:127
static std::map< const ISyst *, TGraph * > empty_syst_map
Definition: Fit.h:206
Perform MINUIT fits in one or two dimensions.
Definition: Fit.h:37
TH1 * Profile(const IExperiment *expt, osc::IOscCalcAdjustable *calc, const IFitVar *v, int nbinsx, double minx, double maxx, double input_minchi, const std::vector< const IFitVar * > &profVars, const std::vector< const ISyst * > &profSysts, const std::map< const IFitVar *, std::vector< double >> &seedPts, const std::vector< SystShifts > &systSeedPts, std::map< const IFitVar *, TGraph * > &profVarsMap, std::map< const ISyst *, TGraph * > &profSystsMap)
scan in one variable, profiling over all others
Definition: Fit.cxx:390
process_name gaushit a
process_name pandoraGausCryo1 vertexChargeCryo1 vertexStubCryo1 xmin
SystShifts GetSystShifts() const
Definition: Fit.h:132
while getopts h
int fNEvalFiniteDiff
Definition: Fit.h:181
Verbosity
Definition: Fit.h:40
std::vector< double > GetPreFitErrors()
Return the prefit errors.
Definition: Fit.h:112
std::vector< double > fPreFitValues
Definition: Fit.h:189
TMatrixDSym * GetCovariance()
Return the fit covariance.
Definition: Fit.h:100
std::vector< const IFitVar * > fVars
Definition: Fit.h:173
Precision fPrec
Definition: Fit.h:175
bool fIsValid
Definition: Fit.h:185
TMatrixDSym * fCovar
Definition: Fit.h:186
static std::map< const IFitVar *, TGraph * > empty_vars_map
Definition: Fit.h:205
unsigned int seed
bool fCovarStatus
Definition: Fit.h:187
std::unique_ptr< ROOT::Math::Minimizer > FitHelperSeeded(osc::IOscCalcAdjustable *seed, SystShifts &systSeed, Verbosity verb) const
Helper for FitHelper.
Definition: Fit.cxx:102
std::vector< double > fPostFitValues
Definition: Fit.h:191
std::vector< double > fPreFitErrors
Definition: Fit.h:190
Fitter(const IExperiment *expt, std::vector< const IFitVar * > vars, std::vector< const ISyst * > systs={}, Precision prec=kNormal)
Definition: Fit.cxx:53
osc::IOscCalcAdjustable * fCalc
Definition: Fit.h:176
SystShifts fShifts
Definition: Fit.h:177
virtual unsigned int NDim() const override
Definition: Fit.h:138
TH1 * SqrtSlice(const IExperiment *expt, osc::IOscCalcAdjustable *calc, const IFitVar *v, int nbinsx, double minx, double maxx, double minchi)
Forward to Slice but sqrt the result for a crude significance.
Definition: Fit.cxx:629
void DecodePars(const double *pars) const
Updates mutable fCalc and fShifts.
Definition: Fit.cxx:338
std::vector< std::string > GetParamNames()
Return the fit names.
Definition: Fit.h:106
std::vector< double > GetPostFitErrors()
Return the postfit errors.
Definition: Fit.h:118
std::vector< const ISyst * > fSysts
Definition: Fit.h:174
int prec
std::vector< std::string > fParamNames
Definition: Fit.h:188
then echo File list $list not found else cat $list while read file do echo $file sed s
Definition: file_to_url.sh:60
std::map< const IFitVar *, double > fitvars
Definition: Fit.h:149
double SimpleFOM(const Spectrum &obs, const Spectrum &unosc, double pot)
Figure-of-merit with no systematics, for binned data.
Definition: Fit.cxx:28
Base class defining interface for experiments.
Definition: IExperiment.h:21
const IExperiment * fExpt
Definition: Fit.h:172
Interface definition for fittable variables.
Definition: IFitVar.h:14
bool GetIsValid()
Say whether the fit was good.
Definition: Fit.h:130
std::vector< double > fPostFitErrors
Definition: Fit.h:192
double Fit(SystShifts &systSeed, Verbosity verb=kVerbose) const
Variant with no oscillations - useful for ND fits.
Definition: Fit.h:94
TH1 * Slice(const IExperiment *expt, osc::IOscCalcAdjustable *calc, const IFitVar *v, int nbinsx, double minx, double maxx, double minchi)
scan in one variable, holding all others constant
Definition: Fit.cxx:611
std::vector< std::pair< double, double > > GetMinosErrors()
Return the minos errors.
Definition: Fit.h:121
virtual double DoEval(const double *pars) const override
Evaluate the log-likelihood, as required by MINUT interface.
Definition: Fit.cxx:365
Precision
Definition: Fit.h:42
int GetNFCN()
Return number of function calls.
Definition: Fit.h:124
BEGIN_PROLOG could also be cout