9 #include "OscLib/IOscCalc.h"
15 #include "TMatrixDSym.h"
18 #include "Fit/Fitter.h"
19 #include "Math/Factory.h"
20 #include "Math/Functor.h"
30 if(pot == 0) pot = obs.
POT();
32 std::unique_ptr<TH1> oh(obs.
ToTH1(pot));
33 std::unique_ptr<TH1> bh(unosc.
ToTH1(pot));
34 assert(oh->GetNbinsX() == bh->GetNbinsX());
39 for(
int i = 0; i < oh->GetNbinsX(); ++i){
40 const double o = oh->GetBinContent(i);
41 const double b = bh->GetBinContent(i);
54 std::vector<const IFitVar*> vars,
55 std::vector<const ISyst*> systs,
57 : fExpt(expt),
fVars(vars), fSysts(systs), fPrec(prec), fCalc(0),
58 fCovar(0), fCovarStatus(-1)
65 std::vector<double>>& seedPts,
66 std::vector<SystShifts> systSeedPts)
const
68 std::vector<SeedPt> ret;
71 for(
auto it: seedPts){
75 std::vector<SeedPt> newret;
76 for(
double val: it.second){
86 if(!systSeedPts.empty()){
87 std::vector<SeedPt> newret;
101 std::unique_ptr<ROOT::Math::Minimizer>
111 std::cout <<
"GradDesc option specified but not implemented. Abort." << std::endl;
115 std::unique_ptr<ROOT::Math::Minimizer> mnMin(
116 ROOT::Math::Factory::CreateMinimizer(
"Minuit2",
"Combined"));
117 mnMin->SetStrategy(
int(
fPrec & kAlgoMask));
118 mnMin->SetMaxFunctionCalls(1E8);
119 mnMin->SetMaxIterations(1E8);
122 const double val = v->GetValue(seed);
124 mnMin->SetVariable(mnMin->NFree(), v->ShortName(), val, val ? fabs(val/2) : .1);
130 assert(mnMin->NFree() == fVars.size());
134 mnMin->SetVariable(mnMin->NFree(),
s->ShortName(), val, 1);
140 assert(mnMin->NFree() == fVars.size()+fSysts.size());
142 mnMin->SetFunction(*
this);
144 if(verb == Verbosity::kQuiet) mnMin->SetPrintLevel(0);
146 if(!mnMin->Minimize()){
147 std::cout <<
"*** ERROR: minimum is not valid ***" << std::endl;
148 std::cout <<
"*** Precision: " << mnMin->Precision() << std::endl;
151 for(uint i = 0; i < mnMin->NFree(); ++i){
152 std::cout <<
"\t" << mnMin->VariableName(i) <<
" = " << mnMin->X()[i] <<
"\n";
157 std::cout <<
"It's Hesse o'clock" << std::endl;
162 std::cout <<
"It's minos time" << std::endl;
164 for (uint i = 0; i < mnMin->NDim(); ++i){
165 double errLow = 0, errHigh = 0;
166 mnMin->GetMinosError(i, errLow, errHigh);
167 std::cout << i <<
"/" << mnMin->NDim() <<
" " <<
fParamNames[i] <<
": " << errLow <<
", +" << errHigh <<
" (" << mnMin->Errors()[i] <<
")" << std::endl;
178 const std::map<
const IFitVar*, std::vector<double>>& seedPts,
179 std::vector<SystShifts> systSeedPts,
182 const std::vector<SeedPt> pts =
ExpandSeeds(seedPts, systSeedPts);
183 double minchi = 1
e10;
184 std::vector<double> bestFitPars, bestSystPars;
186 for(
const SeedPt& pt: pts){
189 for(
auto it: pt.fitvars) it.first->SetValue(seed, it.second);
199 if(std::find(fit_systs.begin(), fit_systs.end(),
s) == fit_systs.end()) {
204 std::unique_ptr<ROOT::Math::Minimizer> thisMin =
208 if (thisMin->MinValue() < minchi) {
209 minchi = thisMin->MinValue();
223 const double val = v->GetValue(seed);
236 fPostFitValues = std::vector<double>(thisMin->X(), thisMin->X()+thisMin->NDim());
237 fPostFitErrors = std::vector<double>(thisMin->Errors(), thisMin->Errors()+thisMin->NDim());
239 fEdm = thisMin->Edm();
243 fCovar =
new TMatrixDSym(thisMin->NDim());
245 for(
unsigned int row = 0;
row < thisMin->NDim(); ++
row){
246 for(
unsigned int col = 0; col < thisMin->NDim(); ++col){
247 (*fCovar)(
row, col) = thisMin->CovMatrix(row, col);
252 for(
unsigned int i = 0; i < fVars.size(); ++i)
254 for(
unsigned int j = 0; j < fSysts.size(); ++j)
261 for(
unsigned int i = 0; i <
fVars.size(); ++i)
262 fVars[i]->SetValue(initseed, bestFitPars[i]);
263 for(
unsigned int i = 0; i <
fSysts.size(); ++i)
278 const std::map<
const IFitVar*, std::vector<double>>& seedPts,
279 const std::vector<SystShifts>& systSeedPts,
284 assert(seed ||
fVars.empty());
286 for(
const auto& it: seedPts){
288 std::cout <<
"ERROR Fitter::Fit() trying to seed '"
289 << it.first->ShortName()
290 <<
"' which is not part of the fit." << std::endl;
294 for(
const auto& it: systSeedPts){
295 for(
const ISyst*
s: it.ActiveSysts()){
297 std::cout <<
"ERROR Fitter::Fit() trying to seed '"
299 <<
"' which is not part of the fit." << std::endl;
314 const double chi =
FitHelper(seed, bestSysts, seedPts, systSeedPts, verb);
319 std::cout <<
", " << v->ShortName() <<
" = " << v->GetValue(seed);
324 std::cout <<
", LL = " << chi << std::endl;
326 std::cout <<
" found with " <<
fNEval <<
" evaluations of the likelihood";
340 for(
unsigned int i = 0; i <
fVars.size(); ++i){
341 const double val = pars[i];
342 if(isnan(val) || isinf(val)){
343 std::cout <<
"Fitter::DecodePars(). Minuit wants to set " <<
fVars[i]->ShortName() <<
" = " << val <<
". Will ignore it and hope for the best." << std::endl;
351 for(
unsigned int j = 0; j <
fSysts.size(); ++j){
352 const double val = pars[
fVars.size()+j];
353 if(isnan(val) || isinf(val)){
354 std::cout <<
"Fitter::DecodePars(). Minuit wants to set " <<
fSysts[j]->ShortName() <<
" = " << val <<
". Will ignore it and hope for the best." << std::endl;
374 for(
unsigned int i = 0; i <
fVars.size(); ++i){
375 const double x = pars[i];
376 if(isinf(x) || isnan(x))
continue;
379 for(
unsigned int j = 0; j <
fSysts.size(); ++j){
380 const double x = pars[
fVars.size()+j];
381 if(isinf(x) || isnan(x))
continue;
382 penalty +=
fSysts[j]->Penalty(x);
392 int nbinsx,
double minx,
double maxx,
394 const std::vector<const IFitVar*>& profVars,
395 const std::vector<const ISyst*>& profSysts,
396 const std::map<
const IFitVar*, std::vector<double>>& seedPts,
397 const std::vector<SystShifts>& systSeedPts,
398 std::map<const IFitVar*, TGraph*>& profVarsMap,
399 std::map<const ISyst*, TGraph*>& profSystsMap)
404 for(
auto it: profVarsMap)
delete it.second;
405 for(
auto it: profSystsMap)
delete it.second;
407 profSystsMap.clear();
410 for(
const IFitVar* v: profVars) profVarsMap[v] =
new TGraph;
411 for(
const ISyst*
s: profSysts) profSystsMap[
s] =
new TGraph;
414 (
";"+v->
LatexName()+ (input_minchi == 0?
";#chi^{2}" :
";#Delta#chi^{2}") ).c_str(),
419 std::vector<double> seedValues;
420 for(
const IFitVar* v: profVars) seedValues.push_back(v->
GetValue(calc));
423 double minchi = 1
e10;
425 Fitter fit(expt, profVars, profSysts);
427 for(
int n = 0;
n < nbinsx; ++
n){
430 const double x = ret->GetXaxis()->GetBinCenter(
n+1);
434 for(
unsigned int i = 0; i < seedValues.size(); ++i)
435 profVars[i]->SetValue( calc, seedValues[i] );
438 const double chi = fit.
Fit(calc, systshift, seedPts, systSeedPts,
Fitter::kQuiet);
446 for(
const IFitVar* var: profVars){
447 profVarsMap[var]->SetPoint(
n, x, var->GetValue(calc));
449 for(
const ISyst*
s: profSysts){
450 profSystsMap[
s]->SetPoint(
n, x, systshift.
GetShift(
s));
455 if(input_minchi == -1){
456 std::vector<const IFitVar*> allVars = {v};
457 for(
unsigned int i = 0; i < seedValues.size(); ++i) {
458 profVars[i]->
SetValue(calc, seedValues[i]);
459 allVars.push_back(profVars[i]);
461 Fitter fit(expt, allVars, profSysts);
464 minchi = fit.
Fit(calc);
467 minchi = input_minchi;
471 for(
int n = 0;
n < nbinsx; ++
n) ret->AddBinContent(
n+1, -minchi);
479 int nbinsx,
double minx,
double maxx,
481 const std::vector<const IFitVar*>& profVars,
482 const std::vector<const ISyst*>& profSysts,
483 const std::map<
const IFitVar*, std::vector<double>>& seedPts,
484 const std::vector<SystShifts>& systSeedPts,
485 std::map<const IFitVar*, TGraph*>& profVarsMap,
486 std::map<const ISyst*, TGraph*>& profSystsMap)
491 for(
auto it: profVarsMap)
delete it.second;
492 for(
auto it: profSystsMap)
delete it.second;
494 profSystsMap.clear();
497 for(
const IFitVar* v: profVars) profVarsMap[v] =
new TGraph;
498 for(
const ISyst* prof_syst: profSysts) profSystsMap[prof_syst] =
new TGraph;
501 (
";"+s->
LatexName()+ (input_minchi == 0?
";#chi^{2}" :
";#Delta#chi^{2}") ).c_str(),
506 std::vector<double> seedValues;
507 for(
const IFitVar* v: profVars) seedValues.push_back(v->GetValue(calc));
510 double minchi = 1
e10;
512 Fitter fit(expt, profVars, profSysts);
514 for(
int n = 0;
n < nbinsx; ++
n){
517 const double x = ret->GetXaxis()->GetBinCenter(
n+1);
521 for(
unsigned int i = 0; i < seedValues.size(); ++i)
522 profVars[i]->SetValue( calc, seedValues[i] );
524 const double chi = fit.
Fit(calc, systshift, seedPts, systSeedPts,
Fitter::kQuiet);
532 for(
const IFitVar* var: profVars){
533 profVarsMap[var]->SetPoint(
n, x, var->GetValue(calc));
535 for(
const ISyst* s: profSysts){
536 profSystsMap[
s]->SetPoint(
n, x, systshift.
GetShift(s));
541 if(input_minchi == -1){
542 std::vector<const ISyst*>
allSysts = {s};
543 for(
unsigned int i = 0; i < seedValues.size(); ++i) {
544 profVars[i]->SetValue(calc, seedValues[i]);
546 for(
unsigned int i = 0; i < profSysts.size(); ++i) {
547 allSysts.push_back(profSysts[i]);
549 Fitter fit(expt, profVars, allSysts);
552 minchi = fit.
Fit(calc, systshift);
555 minchi = input_minchi;
559 for(
int n = 0;
n < nbinsx; ++
n) ret->AddBinContent(
n+1, -minchi);
567 int nbinsx,
double minx,
double maxx,
double minchi,
568 std::vector<const IFitVar*> profVars,
569 std::vector<const ISyst*> profSysts,
570 const std::map<
const IFitVar*, std::vector<double>>& seedPts,
571 const std::vector<SystShifts>& systSeedPts,
572 std::map<const IFitVar*, TGraph*>& profVarsMap,
573 std::map<const ISyst*, TGraph*>& systsMap)
576 v, nbinsx, minx, maxx,
577 minchi, profVars, profSysts, seedPts, systSeedPts,
578 profVarsMap, systsMap);
579 for(
int n = 0;
n < ret->GetNbinsX()+2; ++
n){
580 const double v = ret->GetBinContent(
n);
581 ret->SetBinContent(
n, v > 0 ? sqrt(v) : 0);
583 ret->GetYaxis()->SetTitle(
"#sigma");
590 int nbinsx,
double minx,
double maxx,
double minchi,
591 std::vector<const IFitVar*> profVars,
592 std::vector<const ISyst*> profSysts,
593 const std::map<
const IFitVar*, std::vector<double>>& seedPts,
594 const std::vector<SystShifts>& systSeedPts,
595 std::map<const IFitVar*, TGraph*>& profVarsMap,
596 std::map<const ISyst*, TGraph*>& systsMap)
599 s, nbinsx, minx, maxx,
600 minchi, profVars, profSysts, seedPts, systSeedPts,
601 profVarsMap, systsMap);
602 for(
int n = 0;
n < ret->GetNbinsX()+2; ++
n){
603 const double v = ret->GetBinContent(
n);
604 ret->SetBinContent(
n, v > 0 ? sqrt(v) : 0);
606 ret->GetYaxis()->SetTitle(
"#sigma");
613 int nbinsx,
double minx,
double maxx,
616 return Profile(expt, calc, v, nbinsx, minx, maxx, minchi);
622 int nbinsx,
double minx,
double maxx,
625 return Profile(expt, calc, s, nbinsx, minx, maxx, minchi);
631 int nbinsx,
double minx,
double maxx,
double minchi)
633 TH1* ret =
Slice(expt, calc, v, nbinsx, minx, maxx, minchi);
634 for(
int n = 0;
n < ret->GetNbinsX()+2; ++
n){
635 const double v = ret->GetBinContent(
n);
636 ret->SetBinContent(
n, v > 0 ? sqrt(v) : 0);
638 ret->GetYaxis()->SetTitle(
"#sigma");
645 int nbinsx,
double minx,
double maxx,
double minchi)
647 TH1* ret =
Slice(expt, calc, s, nbinsx, minx, maxx, minchi);
648 for(
int n = 0;
n < ret->GetNbinsX()+2; ++
n){
649 const double v = ret->GetBinContent(
n);
650 ret->SetBinContent(
n, v > 0 ? sqrt(v) : 0);
652 ret->GetYaxis()->SetTitle(
"#sigma");
661 int nbinsx,
double xmin,
double xmax,
662 const std::vector<const IFitVar*>& profVars,
663 const std::vector<const ISyst*>& profSysts,
664 const std::map<
const IFitVar*, std::vector<double>>& seedPts,
665 const std::vector<SystShifts>& systSeedPts,
668 TGraph*
g =
new TGraph;
671 std::vector<const IFitVar*> vars = profVars;
672 vars.push_back(&fitVar);
674 for(
int i = 0; i <= nbinsx; ++i){
675 const double x = xmin + i*(xmax-
xmin)/nbinsx;
677 Fitter fit(expt, vars, profSysts);
682 g->SetPoint(i, y, x);
684 g->SetPoint(i, x, y);
693 std::vector<double> ret;
698 for(
int i = 1; i < h->GetNbinsX(); ++i){
699 const double x0 = h->GetXaxis()->GetBinCenter(i);
700 const double x1 = h->GetXaxis()->GetBinCenter(i+1);
702 const double y0 = h->GetBinContent(i);
703 const double y1 = h->GetBinContent(i+1);
706 if((y0 < critVal) != (y1 < critVal)){
708 const double x = x0 + (x1-x0)*(critVal-y0)/(y1-y0);
std::vector< std::pair< double, double > > fMinosErrors
std::vector< std::pair< double, double > > fTempMinosErrors
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.
TH1D * ToTH1(double exposure, Color_t col=kBlack, Style_t style=kSolid, EExposureType expotype=kPOT, EBinType bintype=kBinContent) const
Histogram made from this Spectrum, scaled to some exposure.
virtual std::string LatexName() const =0
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.
virtual double GetValue(const osc::IOscCalcAdjustable *osc) const =0
void SetShift(const ISyst *syst, double shift)
Shifts are 0=nominal, -1,+1 = 1 sigma shifts.
process_name opflash particleana ie x
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.
Simple record of shifts applied to systematic parameters.
virtual double ChiSq(osc::IOscCalcAdjustable *osc, const SystShifts &syst=SystShifts::Nominal()) const =0
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
std::vector< SeedPt > ExpandSeeds(const std::map< const IFitVar *, std::vector< double >> &seedPts, std::vector< SystShifts > systSeedPts) const
std::vector< double > FindCurveCrossings(TH1 *h, double critVal)
Intended for use on the output of Profile.
void SetPrecision(Precision prec)
process_name opflashCryoW ana
static SystShifts Nominal()
T sqr(T x)
More efficient square function than pow(x,2)
Encapsulate code to systematically shift a caf::StandardRecord.
Perform MINUIT fits in one or two dimensions.
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
Representation of a spectrum in any variable, with associated POT.
process_name pandoraGausCryo1 vertexChargeCryo1 vertexStubCryo1 xmin
process_name opflash particleana ie ie y
std::vector< double > fPreFitValues
virtual void SetValue(osc::IOscCalcAdjustable *osc, double val) const =0
std::vector< const IFitVar * > fVars
std::unique_ptr< ROOT::Math::Minimizer > FitHelperSeeded(osc::IOscCalcAdjustable *seed, SystShifts &systSeed, Verbosity verb) const
Helper for FitHelper.
std::vector< double > fPostFitValues
std::vector< double > fPreFitErrors
double GetShift(const ISyst *syst) const
std::vector< const ISyst * > allSysts
Fitter(const IExperiment *expt, std::vector< const IFitVar * > vars, std::vector< const ISyst * > systs={}, Precision prec=kNormal)
osc::IOscCalcAdjustable * fCalc
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.
void DecodePars(const double *pars) const
Updates mutable fCalc and fShifts.
std::vector< const ISyst * > fSysts
void SetProgress(double frac)
Update the progress fraction between zero and one.
std::vector< std::string > fParamNames
then echo File list $list not found else cat $list while read file do echo $file sed s
double SimpleFOM(const Spectrum &obs, const Spectrum &unosc, double pot)
Figure-of-merit with no systematics, for binned data.
Base class defining interface for experiments.
const IExperiment * fExpt
A simple ascii-art progress bar.
Interface definition for fittable variables.
then echo ***************************************echo Variable FHICL_FILE_PATH not found echo You porbably haven t set up larsoft echo Try setup uboonecode vXX_XX_XX q e10
std::vector< double > fPostFitErrors
std::vector< const ISyst * > ActiveSysts() const
virtual std::string LatexName() const final
The name used on plots (ROOT's TLatex syntax)
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
void Done()
Call this when action is completed.
virtual double DoEval(const double *pars) const override
Evaluate the log-likelihood, as required by MINUT interface.
std::string UniqueName()
Return a different string each time, for creating histograms.
BEGIN_PROLOG could also be cout