CovarianceFitHelper.cxx
Go to the documentation of this file.
1 //
2 // Created by Brian Rebel on 12/15/18.
3 //
4 
5 //#include <sstream>
6 #include <cmath>
7 
8 #include "cetlib_except/exception.h"
9 
18 
19 // ROOT includes
20 #include "TCanvas.h"
21 #include "TFile.h"
22 #include "TGraph.h"
23 #include "TH1.h"
24 #include "TH2.h"
25 #include "TLegend.h"
26 //#include "TStopwatch.h"
27 #include "Math/Minimizer.h"
28 #include "Math/Factory.h"
29 #include "Math/Functor.h"
30 #include "Fit/ParameterSettings.h"
31 
32 namespace cmf {
33 
34  static CovarianceFitHelper *gCovFitHelp = nullptr;
35 
36  // Must be outside of the class for ROOT factory functor ctor to be happy
37  std::unique_ptr<cmf::EventListColl> gMCEventLists;
38  std::unique_ptr<cmf::ExposureMap> gExposureMap;
39  std::unique_ptr<cmf::Location> gLoc;
40  std::unique_ptr<std::vector<double>> gFFVals;
41  std::unique_ptr<std::vector<std::string>> gFFNames;
42  ROOT::Math::Minimizer *gFFMin;
44  double gMinChiSqr;
46  static const double gPI = 3.141592653589793238462643383279502884;
47 
48  //----------------------------------------------------------------------------
49  // Ideally this function does all the heavy lifting of the fit.
50  double FitFunction_ForROOT(const double* params)
51  {
52  // debug
53  MF_LOG_VERBATIM("CovarianceFit") << "Processing guess: ";
54 
55  for(size_t i = 0; i < gFFVals->size(); ++i){
56  (*gFFVals)[i] = params[i];
57 
59  MF_LOG_VERBATIM("CovarianceFit")
60  << "\t"
61  << (*gFFNames)[i]
62  << " : "
63  << params[i]
64  << "; sin^2("
65  << (*gFFNames)[i]
66  << "): "
67  << std::pow(std::sin(params[i]), 2.);
68  else if ((*gFFNames)[i] == "dCP")
69  MF_LOG_VERBATIM("CovarianceFit")
70  << "\t"
71  << (*gFFNames)[i]
72  << " : "
73  << params[i]
74  << " = "
75  << params[i] / gPI
76  << " (pi)";
77  else
78  MF_LOG_VERBATIM("CovarianceFit")
79  << "\t"
80  << (*gFFNames)[i]
81  << " : "
82  << params[i];
83  }
84 
85  // Now update the ShifterAndWeighter to check the goodness of fit
87  gFFVals->data());
88 
89  MF_LOG_DEBUG("CovarianceMatrixFitter")
90  << "fill the MC spectrum with the new values";
91 
92  // fill the MC spectrum
94 
95  MF_LOG_DEBUG("CovarianceMatrixFitter")
96  << "get the new chi^2";
97 
98 
99  // Get Chisq
100  double chisq = cmf::ChiSqrCalculator::Instance()->ChiSqr(gChiSqrCalc,
101  *gFFNames,
102  gFFVals->data());
103 
104  MF_LOG_DEBUG("CovarianceMatrixFitter")
105  << "add to the iterations";
106 
107  // store this iteration of the fitter
109  *gFFNames,
110  *gFFVals,
111  gChiSqrCalc);
112 
113  MF_LOG_VERBATIM("CovarianceFit")
114  << "\t"
115  << "FitValue = "
116  << chisq;
117 
118  // Return the fit value; that's what we're looking to minimize
119  return chisq;
120  }
121 
122  //----------------------------------------------------------------------------
124  {
125  if(gCovFitHelp == nullptr) gCovFitHelp = new CovarianceFitHelper();
126 
127  return gCovFitHelp;
128  }
129 
130  //----------------------------------------------------------------------------
132  {
133  fDataSpectrum.resize(cmf::CovarianceBinUtility::Instance()->TotalBins(), 0.);
134  fMCSpectrum .resize(cmf::CovarianceBinUtility::Instance()->TotalBins(), 0.);
135  fDataCount .resize(cmf::CovarianceBinUtility::Instance()->TotalBins(), 0.);
136  fMCCount .resize(cmf::CovarianceBinUtility::Instance()->TotalBins(), 0.);
137  }
138 
139  //----------------------------------------------------------------------------
141  {
142  // fIterations .clear();
143  // fDataSpectrum.clear();
144  // fMCSpectrum .clear();
145  // fDataCount .clear();
146  // fMCCount .clear();
147  // fDataPOT .clear();
148 
149  // gLoc->FDLoc .clear();
150  // gLoc->NDLoc .clear();
151  // gLoc .reset();
152  // gExposureMap.reset();
153  // gFFVals .reset();
154  // gFFNames .reset();
155  }
156 
157  //----------------------------------------------------------------------------
159  fhicl::ParameterSet const& chiSqrCalcPars,
160  fhicl::ParameterSet const& manipulatorPars,
161  fhicl::ParameterSet const& minimizerPars,
162  fhicl::ParameterSet const& sawPars)
163  {
165 
166  this->InitializeGlobalVars();
167  this->InitializeFitHelper(helperPars);
168  this->InitializeShifterAndWeighter(sawPars);
169  this->InitializeEventLists(manipulatorPars,
170  cmf::Spectrum());
171  this->InitializeMinimizer(minimizerPars);
172  this->InitializeFit();
173  }
174 
175  //----------------------------------------------------------------------------
177  fhicl::ParameterSet const& sawPars)
178  {
180  this->InitializeGlobalVars();
181  this->InitializeShifterAndWeighter(sawPars);
182  }
183 
184  //----------------------------------------------------------------------------
186  fhicl::ParameterSet const& chiSqrCalcPars,
187  fhicl::ParameterSet const& manipulatorPars,
188  fhicl::ParameterSet const& minimizerPars,
189  fhicl::ParameterSet const& sawPars,
190  cmf::Spectrum const& dataSpectrum)
191  {
193 
194  this->InitializeGlobalVars();
195  this->InitializeFitHelper(helperPars);
196  this->InitializeShifterAndWeighter(sawPars);
197  this->InitializeEventLists(manipulatorPars,
198  dataSpectrum);
199  this->InitializeMinimizer(minimizerPars);
200  this->InitializeFit();
201  }
202 
203  //----------------------------------------------------------------------------
205  {
207 
209  sawPars);
210 
212  //cmf::ShifterAndWeighter::Instance()->ReportCurrentVals();
213  }
214 
215  //----------------------------------------------------------------------------
217  cmf::Spectrum const& dataSpectrum)
218  {
219 
220  if( !dataSpectrum.empty() ){
221  this->FillDataSpectrum(dataSpectrum);
222  }
223 
224  // get the manipulator to deserialize the data and MC
225  // we'll keep the MC lists around, but will drop the data lists as
226  // soon as we leave this method
227  cmf::EventListManipulator elm(manipulatorPars);
228  gExposureMap = std::make_unique<cmf::ExposureMap>(elm.ExposureMap());
229  gMCEventLists = std::make_unique<cmf::EventListColl>();
230 
231  MF_LOG_DEBUG("CovarianceFitHelper")
232  << "Exposure map has "
233  << gExposureMap->size()
234  << " entries";
235 
236  for(auto const& itr : *gExposureMap){
237  MF_LOG_DEBUG("CovarianceFitHelper")
238  << itr.first.ToString()
239  << " has "
240  << itr.second
241  << " POT";
242 
243  fDataPOT[itr.first.DetectorBeamSelectionKey() + itr.first.PeriodKey()] = itr.second.goodPOT;
244  }
245 
246  // deserialize the ND and FD
247  elm.Deserialize(*gMCEventLists, cmf::kMC);
248  }
249 
250  //----------------------------------------------------------------------------
252  {
253  // initial fill of the MC spectrum
254  this->FillMCSpectrum(*gMCEventLists);
255 
256  // for(size_t b = 0; b< fMCSpectrum.size(); ++b)
257  // MF_LOG_VERBATIM("CovarianceFitHelper")
258  // << "Initial MC Spectrum "
259  // << b
260  // << " "
261  // << fMCSpectrum[b];
262 
263  }
264 
265  //----------------------------------------------------------------------------
267  {
268  MF_LOG_DEBUG("CovarianceFitHelper")
269  << helperPars.to_indented_string();
270 
271  fNumCPRanges = helperPars.get<int >("NumCPRanges", 3);
272  }
273 
274  //----------------------------------------------------------------------------
276  {
277  gFFVals = std::make_unique<std::vector<double> >();
278  gFFNames = std::make_unique<std::vector<std::string>>();
279  gMinChiSqr = cmf::kGarbageDouble;
280  gMinStatus = std::numeric_limits<int>::max();
281  gLoc = std::make_unique<cmf::Location>(cmf::ParameterUtility::Instance()->ParametersAsLocation());
282 
283  // Add all FD entry keys to the psl_key_list
284  // Add ND entry keys only if they don't show up on FD list
285  // E.g., FD entry will override ND entry if common
286  // Don't add fixed parameters or systematic uncertainties because
287  // those are never fit
288  std::list<std::string> psl_key_list_fd;
289 
290  for(auto const& detItr : cmf::SelectionUtility::Instance()->DetectorsToUse()){
291  for(auto const& psl : gLoc->DetectorLocation(detItr).Parameters()){
292  if(psl.IsFixed() ||
293  !psl.IsOscPar() ||
294  std::count(psl_key_list_fd.begin(), psl_key_list_fd.end(), psl.Name()) > 0) continue;
295 
296  MF_LOG_DEBUG("ROOTFactoryFit")
297  << cmf::cDetType_Strings[detItr]
298  << " Adding "
299  << psl;
300  gFFVals->emplace_back(psl.Value());
301  gFFNames->emplace_back(psl.Name());
302 
303  psl_key_list_fd.emplace_back(psl.Name());
304  }
305  } // end loop over detectors
306 
307  }
308 
309  //----------------------------------------------------------------------------
311  {
312  fMinimizerPars = minimizerPars;
313 
314  // Look for minName and algoName (following ROOT factory nomenclature,
315  // see NumericalMinimization.C in ROOT fit documentation,
316  // root.cern.ch/root/html/tutorials/fit/NumericalMinimization.C.html
317  // Default here is set to Minuit2 && Migrad
318  auto minName = fMinimizerPars.get<std::string >("MinName", "Minuit2");
319  auto algoName = fMinimizerPars.get<std::string >("AlgoName", "Migrad" );
320  auto maxFunctionCalls = fMinimizerPars.get<unsigned int >("MaxFunctionCalls", 1000);
321  auto maxIterations = fMinimizerPars.get<unsigned int >("MaxIterations", 1000);
322  auto tolerance = fMinimizerPars.get<double >("Tolerance", 0);
323  auto precision = fMinimizerPars.get<double >("Precision", 0);
324  auto strategyCode = fMinimizerPars.get<int >("StrategyCode", 0);
325  auto printLevel = fMinimizerPars.get<int >("MINUITPrintLevel", 3);
326 
327  // make the ROOT minimizer
328  gFFMin = ROOT::Math::Factory::CreateMinimizer(minName,
329  algoName);
330 
331  // Set up the minimizer particulars
332  gFFMin->SetMaxFunctionCalls(maxFunctionCalls);
333  gFFMin->SetMaxIterations(maxIterations);
334  gFFMin->SetStrategy(strategyCode);
335  gFFMin->SetPrintLevel(printLevel);
336  if(tolerance > 0) gFFMin->SetTolerance(tolerance);
337  if(precision > 0) gFFMin->SetPrecision(precision);
338 
339  for(size_t ipar = 0; ipar < gFFNames->size(); ++ipar){
340  if(cmf::ParameterUtility::Instance()->ParameterInfo((*gFFNames)[ipar]).IsConstrained()){
341 
342  gFFMin->SetLimitedVariable(ipar,
343  (*gFFNames)[ipar],
344  (*gFFVals)[ipar],
345  0.01,
346  cmf::ParameterUtility::Instance()->ParameterInfo((*gFFNames)[ipar]).LowerBound(),
347  cmf::ParameterUtility::Instance()->ParameterInfo((*gFFNames)[ipar]).UpperBound());
348  }
349  else{
350  gFFMin->SetVariable(ipar,
351  (*gFFNames)[ipar],
352  (*gFFVals)[ipar],
353  0.01);
354  } // end if unconstrained parameter
355  } // end loop to set the initial parameters
356 
357  MF_LOG_VERBATIM("CovarianceMatrixFit")
358  << "\nNum floatables: "
359  << gFFNames->size()
360  << "\nMax function calls: "
361  << maxFunctionCalls
362  << "\nMax iterations: "
363  << maxIterations
364  << "\nTolerance: "
365  << tolerance
366  << "\nInitial guess: ";
367 
368  ROOT::Fit::ParameterSettings parSet;
369  for(size_t i = 0; i < gFFNames->size(); ++i){
370  gFFMin->GetVariableSettings(i, parSet);
371  MF_LOG_VERBATIM("CovarianceMatrixFit")
372  << parSet.Name()
373  << " : "
374  << parSet.Value()
375  << " lower limit ("
376  << parSet.HasLowerLimit()
377  << ") "
378  << parSet.LowerLimit()
379  << " upper limit ("
380  << parSet.HasUpperLimit()
381  << ") "
382  << parSet.UpperLimit();
383  }
384 
385  // Link in the function to be minimized
386  auto *f = new ROOT::Math::Functor(&FitFunction_ForROOT, gFFNames->size());
387  gFFMin->SetFunction(*f);
388  }
389 
390  //......................................................................
392  {
393  fDataSpectrum = dataSpectrum;
394 
396  // for(auto const& itr : *fDataSpectrum)
397  // MF_LOG_VERBATIM("CovarianceFitHelper")
398  // << itr;
399  }
400 
401  //......................................................................
403  {
404  // now fill the data spectrum - set the values to 0
405  // for all the elements as cmf::FillSpectrum does not reset the vectors
406  for(size_t i = 0; i < fDataSpectrum.size(); ++i){
407  fDataSpectrum[i] = 0;
408  fDataCount[i] = 0.;
409  }
410 
411  cmf::FillSpectrum(eventLists,
412  *gExposureMap,
414  fDataCount);
415 
417  // for(auto const& itr : *fDataSpectrum)
418  // MF_LOG_VERBATIM("CovarianceFitHelper")
419  // << itr;
420  }
421 
422  //......................................................................
424  {
425  // now fill the MC spectrum with the current point - set the values to 0
426  // for all the elements as cmf::FillSpectrum does not reset the vectors
427  for(size_t i = 0; i < fMCSpectrum.size(); ++i){
428  fMCSpectrum[i] = 0;
429  fMCCount[i] = 0.;
430  }
431 
432  cmf::FillSpectrum(eventLists,
433  *gExposureMap,
434  fMCSpectrum,
435  fMCCount);
436 
438 
439  }
440 
441  //----------------------------------------------------------------------------
442  void CovarianceFitHelper::FindInitialGuess(std::vector<cmf::OscParamPoint> const& library)
443  {
444  // loop over the points in the library to get the initial guess
445  gMinChiSqr = cmf::kGarbageDouble;
446  double chiSqr;
447  cmf::OscillationParameterMap minOscPars;
448 
449  // TStopwatch ts;
450  // ts.Start();
451 
452  for(auto const& itr : library.front().OscPoint())
453  minOscPars.emplace(itr.first, itr.second);
454 
455  cmf::OscillationParameterMap oscPars = minOscPars;
456 
457  // The data spectrum was set when the CovarianceFitHelper was initialized
458  // so now for each point in space set the MC spectrum for the ChiSqrCalculator
459  for(auto const& prediction : library){
460 
461  for(auto const& oscItr : prediction.OscPoint())
462  oscPars[oscItr.first] = oscItr.second;
463 
464  cmf::ChiSqrCalculator::Instance()->SetSpectrum(prediction.PredictedSpectrum(),
465  false);
466  chiSqr = cmf::ChiSqrCalculator::Instance()->ChiSqr(gChiSqrCalc, oscPars);
467  if(chiSqr < gMinChiSqr){
468  gMinChiSqr = chiSqr;
469  minOscPars.swap(oscPars);
470  fMCSpectrum = cmf::Spectrum(prediction.PredictedSpectrum());
471  } // end if the minimum chiSqr
472  } // end loop over the predictions
473 
474  // now set the initial guess to the parameters at the minimum
475  // we only care about the oscillation parameters here
476  std::string initialGuess("initial guess from grid search - ");
477  cmf::OscParm_t oscPar;
478  for(size_t p = 0; p < gFFNames->size(); ++p){
479 
480  if(!cmf::IsOscillationParameter((*gFFNames)[p])) continue;
481 
482  oscPar = cmf::StringToOscParmType((*gFFNames)[p]);
483 
484  if(minOscPars.count(oscPar) > 0)
485  (*gFFVals)[p] = minOscPars.find(oscPar)->second;
486 
487  initialGuess += (*gFFNames)[p] + ": " + std::to_string((*gFFVals)[p]) + "\t";
488  }
489 
490  // Now update the ShifterAndWeighter to check the goodness of fit
492  gFFVals->data());
493 
494  // store this iteration of the fitter
496  *gFFNames,
497  *gFFVals,
498  gChiSqrCalc);
499 
500  MF_LOG_VERBATIM("CovarianceFitHelper")
501  << initialGuess
502  << " with chi^2: "
503  << gMinChiSqr;
504 // << " took "
505 // << ts.RealTime()
506 // << " to go through "
507 // << library.size()
508 // << " library spectra";
509  }
510 
511  //......................................................................
513  std::string const& uniqueID,
514  bool fillFromLists)
515  {
516 
517  auto tfd = fTFS->mkdir(dirBaseName + uniqueID);
518 
519  this->MakeIterationGraphs(tfd, uniqueID);
520  this->MakeCovarianceMatrixHistogram(tfd, uniqueID);
521  if(fillFromLists) this->Make1DSpectra(tfd, *gMCEventLists, uniqueID);
522 
523  std::map<long, TH1D*> totMCSpectra;
524  std::map<long, TH1D*> dataSpectra;
525 
526  cmf::PlotUtilities::Instance()->MakeEnergySpectraFromBins(fDataSpectrum, fDataCount, dataSpectra, "DataEnergySpectrum", tfd, uniqueID);
527  cmf::PlotUtilities::Instance()->MakeEnergySpectraFromBins(fMCSpectrum, fMCCount, totMCSpectra, "TotMCEnergySpectrum", tfd, uniqueID);
528 
529  // make the chi^2 histograms
530  auto binByBin = tfd.make<TH1D>("binByBinChiSqr",
531  ";Logical Bin;#chi^{2} per Bin;",
533  0,
535 
536  auto cumulativeChiSqr = tfd.make<TH1D>("cumulativeChiSqr",
537  ";Logical Bin;Cumulative #chi^{2}",
539  0,
541 
544  fMCSpectrum,
545  binByBin,
546  cumulativeChiSqr);
547 
548 
549  // make 1 canvas each for the general selections, numu, nue and NC data/MC comparison
550  // The spectra maps have what we want and we can use the keys
551  // to determine how to make the canvases
552 
553  // if a desired selection type is not available from the SelectionUtility,
554  // the call to MakeDataMCCanv is a no-op
555  std::set<std::pair<cmf::SelectionType_t, std::string>> selToString({ {cmf::kNuMuSelection, "NuMuResultsCanv"},
556  {cmf::kNuESelection, "NuEResultsCanv" },
557  {cmf::kNCSelection, "NCResultsCanv" },
558  });
559 
560  for(auto const& itr : selToString){
562  totMCSpectra,
563  itr.first,
564  itr.second,
565  tfd,
566  uniqueID);
567  }
568 
569  // Finally create a TTree with the output of the oscillation parameters at
570  // the best fit
571 
572  auto *fitResTree = tfd.make<TTree>("FitResultTree", "Best Fit Values");
573 
574  std::vector<double> parVals (cmf::kNumOscParams, 0.);
575  std::vector<int> parFixed(cmf::kNumOscParams, 1);
576 
577  // now fill the tree
578  fitResTree->Branch("ChiSqr", &gMinChiSqr);
579 
580  // put the final fit values into the location for the FD
581  for(size_t p = 0; p < gFFNames->size(); ++p){
582  gLoc->SetParameterValue((*gFFNames)[p],
583  (*gFFVals)[p],
584  cmf::kFARDET);
585  }
586 
587  for(auto const& itr : gLoc->OscillationParameters()){
588  parVals [itr.Key()] = itr.Value();
589  parFixed[itr.Key()] = itr.IsFixed();
590 
591  fitResTree->Branch((itr.Name() + "Val").c_str(), &parVals [itr.Key()]);
592  fitResTree->Branch((itr.Name() + "Fix").c_str(), &parFixed[itr.Key()]);
593 
594  MF_LOG_DEBUG("CovarianceFitHelper")
595  << "added branches "
596  << itr.Name() + "Val"
597  << " "
598  << parVals[itr.Key()]
599  << " "
600  << itr.Name() + "Fix"
601  << " "
602  << parFixed[itr.Key()]
603  << " to tree";
604  }
605 
606  fitResTree->Fill();
607  }
608 
609  // Function to make TH1D from the data and MC 1D spectra vectors
610  // Ideally this function is called after the fit is finished
611  //......................................................................
612  void CovarianceFitHelper::Make1DSpectra(art::TFileDirectory & tfd,
613  cmf::EventListColl const& mcLists,
614  std::string const& uniqueID)
615  {
616  size_t numBins = fDataSpectrum.size();
617 
618  if(numBins != fMCSpectrum.size())
619  throw cet::exception("CovarianceFitHelper")
620  << "data and MC spectra sizes are different: data - "
621  << numBins
622  << " mc - "
623  << fMCSpectrum.size();
624 
625  auto data1DHist = cmf::PlotUtilities::Instance()->MakeSpectrumHistogram(tfd,
626  ("dataSpectrumBins" + uniqueID).c_str(),
627  ";Logical Bin;Events",
628  fDataSpectrum);
629 
631  ("mcSpectrumBins" + uniqueID).c_str(),
632  ";Logical Bin;Events",
633  fMCSpectrum);
634 
635  // for(size_t b = 0; b < numBins; ++b){
636  // data1DHist->SetBinContent(b + 1, fDataSpectrum[b]);
637  // mc1DHist ->SetBinContent(b + 1, fMCSpectrum[b] );
638  // }
639 
640  // fill the energy spectra for each event selection, file type, beam and detector
641  // data and MC. The MC can be made from the event lists. We dropped the data
642  // from the event lists to save memory, so use the bin vector to make the data
643  // plots
644 
646  std::string histTitle;
647  std::map<std::string, TH1F*> nameToSpectrum;
649  double norm;
650  TH1F *spectrum;
651 
652  for(auto const& itr : mcLists){
653  auto const& md = itr.ListMetaData();
654 
655  bins.clear();
657 
658  histName = ("SpectraEnergy" +
659  uniqueID +
660  cmf::cBeamType_Strings[md.BeamType()] +
661  md.DetectorString() +
662  cmf::cFileTypeStrings[md.fileType] +
663  cmf::cSelectionType_Strings[md.selectionType]);
664 
665  histTitle = (cmf::cBeamType_LatexStrings[md.BeamType()] + " " +
666  md.DetectorString() + " " +
667  cmf::cSelectionType_LatexStrings[md.selectionType] +
668  ";Energy (GeV);Events / 0.1 GeV");
669 
670 // MF_LOG_DEBUG("CovarianceFitHelper")
671 // << "1D spectrum hist is "
672 // << histName;
673 
674 // for(auto const& binitr : bins)
675 // MF_LOG_VERBATIM("CovarianceFitHelper")
676 // << "bin edge: "
677 // << binitr;
678 
679  if(nameToSpectrum.count(histName) < 1)
680  spectrum = nameToSpectrum.emplace(histName,
682  histName,
683  histTitle,
684  bins)
685  ).first->second;
686  else
687  spectrum = nameToSpectrum.find(histName)->second;
688  // get the normalization to use
689 
690  norm = 1.;
691  if(md.isMC){
692  norm = fDataPOT[md.DetectorBeamSelectionKey() + md.PeriodKey()] / itr.ListSpillSummary().goodPOT;
693  }
694 
695  // fill the histogram with the proper weight and normalization
696  for(auto const& evt : itr){
697  spectrum->Fill(evt->DataVals().val_at(cmf::kCMF_RecoE, md),
699  } // end loop over events
700 
701  // now normalize the bin contents if desired to the desired width
702  if(md.IsNuESelected())
704  else if(md.IsNuMuSelected())
706 
707  } // end loop over event lists
708 
709  }
710 
711  //......................................................................
713  std::string const& uniqueID)
714  {
715  // we need to fill the covariance matrix so that we have the correct
716  // output histogram for it. This method is called after the minimizations
717  // finish and we have the final fit values.
718  // Set the MC spectra in the ChiSqrCalculator to be sure it is at the best fit,
719  // ie final iteration
720  // then find the chi^2 to ensure the matrix is properly loaded
721  // just pass an empty nuisance parametermap, we aren't really trying to
722  // find the chi^2 anyway here
725  *gFFNames,
726  gFFVals->data());
727 
728 
729  auto matrixHistStat = tfd.make<TH2D>(("FitHelperStatCovarianceMatrix" + uniqueID).c_str(),
730  ";Logical Bin;Logical Bin",
731  fDataSpectrum.size(),
732  0,
733  fDataSpectrum.size(),
734  fDataSpectrum.size(),
735  0,
736  fDataSpectrum.size());
737 
738  auto matrixHistSyst = tfd.make<TH2D>(("FitHelperSystCovarianceMatrix" + uniqueID).c_str(),
739  ";Logical Bin;Logical Bin",
740  fDataSpectrum.size(),
741  0,
742  fDataSpectrum.size(),
743  fDataSpectrum.size(),
744  0,
745  fDataSpectrum.size());
746 
747  auto matrixHistTot = tfd.make<TH2D>(("FitHelperTotCovarianceMatrix" + uniqueID).c_str(),
748  ";Logical Bin;Logical Bin",
749  fDataSpectrum.size(),
750  0,
751  fDataSpectrum.size(),
752  fDataSpectrum.size(),
753  0,
754  fDataSpectrum.size());
755 
756  for(size_t r = 0; r < fDataSpectrum.size(); ++r){
757  for(size_t c = 0; c < fDataSpectrum.size(); ++c){
758  //if(this->ValidVectPosition(fCovarianceMatrixTot.size(), r * fDataSpectrum.size() + c))
759  matrixHistTot ->SetBinContent(r + 1, c + 1, cmf::ChiSqrCalculator::Instance()->CovarianceMatrixEntry(r * fDataSpectrum.size() + c, cmf::kStatMatrix) );
760  matrixHistSyst->SetBinContent(r + 1, c + 1, cmf::ChiSqrCalculator::Instance()->CovarianceMatrixEntry(r * fDataSpectrum.size() + c, cmf::kSystMatrix) );
761  matrixHistStat->SetBinContent(r + 1, c + 1, cmf::ChiSqrCalculator::Instance()->CovarianceMatrixEntry(r * fDataSpectrum.size() + c, cmf::kTotalMatrix));
762  }
763  }
764  }
765 
766  //......................................................................
767  // it is assumed that selVec contains only selections for either numu, nue or NC
768  // not a mixture of the different categories
769  void CovarianceFitHelper::MakeDataMCCanv(std::map<long, TH1D*> & dataSpecMap,
770  std::map<long, TH1D*> & mcSpecMap,
771  cmf::SelectionType_t const& selType,
772  std::string const& canvName,
773  art::TFileDirectory & tfd,
774  std::string const& uniqueID)
775  {
776 
778  cmf::SelectionUtility::Instance()->SelectionsUsedOfType(selType, subsetOfSels);
779 
780  // make sure we have selections of the type we want
781  if(subsetOfSels.empty()) return;
782 
783  // figure out how many selection types we have and how many beams
784  size_t numSels = 0;
785  int cnt;
786  std::map<cmf::SelectionType_t, int> selToNum;
787  std::set<cmf::BeamType_t> beams;
788  for(auto const& itr : subsetOfSels){
789  beams.insert(itr.BeamType());
790  if(itr.Selections().size() > numSels){
791  numSels = itr.Selections().size();
792  cnt = 0;
793  for(auto const& selItr : itr.Selections()){
794  selToNum.emplace(selItr, cnt);
795  ++cnt;
796  }
797  }
798  }
799 
800  size_t numBeams = beams.size();
801 
802  // make 1 canvas each for the general selections, numu, nue and NC data/MC comparison
803  // The spectra maps have what we want and we can use the keys
804  // to determine how to make the canvases
805 
806  // for now we need pads for the ND and FD, FHC and RHC
807  // arrange them ND above FD, FHC grouped above RHC
808 
809  // We need a pad for each selection in each detector for each beam type.
810  // Arrange them ND above FD, FHC grouped above RHC.
811  // The total number of canvases is then 2 * 2 * selVec.size()
812  // We want selVec.size() columns of divisions and 2 * 2 rows
813  // Since we want an even number of divisions, the TCanvas::Divide function
814  // works for us here
815  auto canv = tfd.make<TCanvas>((canvName + uniqueID).c_str(),
816  canvName.c_str(),
817  1200,
818  1200);
819  canv->Divide(numSels, 2 * numBeams);
820 
822  TH1D *dataHist = nullptr;
823  TH1D *mcHist = nullptr;
824  long canvDiv;
825  long key;
826  std::vector<double> bins;
827  TVirtualPad *curPad = nullptr;
828  TLegend *curLeg = nullptr;
829 
830  for(auto const& dbsItr : subsetOfSels){
831  for(auto const& selItr : dbsItr.Selections()){
832 
833  md.selectionType = selItr;
834  md.detector = dbsItr.Detector();
835 
836  // make vectors of the bin boundaries for the new histogram
837  bins.clear();
838  bins.push_back(0.);
839  for(auto const& itr : cmf::CovarianceBinUtility::Instance()->SelectionHighEdges(md)){
840  bins.push_back(itr.first);
841  MF_LOG_DEBUG("CovarianceFitHelper")
842  << md.ToString()
843  << " bins for total MC and ratios "
844  << bins.back()
845  << " "
846  << bins.size();
847  }
848 
849  canvDiv = (1 + selToNum.find(selItr)->second) + (numBeams * dbsItr.BeamType() * numSels) + (dbsItr.Detector() - 1) * numSels;
850 
851  curPad = canv->cd(canvDiv);
852 
853  key = cmf::DetectorBeamSelectionTypesToKey(dbsItr.Detector(), dbsItr.BeamType(), selItr);
854 
855  // grab the data and MC spectra for this key
856  dataHist = dataSpecMap.find(key)->second;
857  mcHist = mcSpecMap.find(key)->second;
858 
859  double max = std::max(dataHist->GetMaximum(), mcHist->GetMaximum());
860  mcHist->SetMaximum(1.2 * (max + std::sqrt(max)));
861 
862  mcHist->SetLineColor(kRed);
863 
864  mcHist->Draw("hist");
865  dataHist->Draw("psame");
866 
867  if(selItr == *(dbsItr.Selections().rbegin())){
868  curLeg = curPad->BuildLegend();
869  curLeg->SetBorderSize(0);
870  curLeg->SetFillStyle(0);
871  }
872 
873  canv->Update();
874 
875  } // end loop over selections
876  } // end loop over DetBeamSelSet
877 
878  // write out the canvas
879  canv->Write();
880 
881  delete curLeg;
882  }
883 
884  //......................................................................
885  void CovarianceFitHelper::MakeIterationGraphs(art::TFileDirectory & tfd,
886  std::string const& uniqueID)
887  {
888  // loop over the different possible chi^2 calculators
889  std::string calcName;
890  for(auto const& itr : fIterations){
891 
892  calcName = cmf::cChiSqrCalcType_Strings[itr.first];
893  std::vector<cmf::CovFitIteration> const& cfiVec = itr.second;
894 
895  // create histograms for the fit parameters and the chi^2 to see
896  // how they changed during the minimization
897 
898  // make a collection of TGraphs for the fit parameters
899  std::map<std::string, TGraph*> grMap;
900  for(auto const& itr : cfiVec[0].parNames){
901 
902  if(!cmf::IsOscillationParameter(itr)) continue;
903 
904  grMap[itr] = tfd.make<TGraph>(cfiVec.size());
905  grMap[itr]->SetName((itr + calcName + "IterGraph" + uniqueID).c_str());
906  grMap[itr]->SetTitle(itr.c_str());
907  grMap[itr]->SetMarkerStyle(20);
908  }
909 
910  // Make the TGraph for the chi^2 values
911  auto chisq_graph = tfd.make<TGraph>(cfiVec.size());
912  chisq_graph->SetName((calcName + "IterGraphChiSqr" + uniqueID).c_str());
913  chisq_graph->SetTitle("#chi^{2}");
914  chisq_graph->SetMarkerStyle(20);
915 
916  //loop over the iterations to fill the graphs
917  // the last value in fIterations is not the minimum, it is
918  // the value that Minuit used to confirm it had found a minimum,
919  // so don't use it in the graphs
920  double parVal;
921  int ctr = 0;
922  for(auto const& itr : cfiVec){
923 
924  // get the value for each parameter we care about and put it into its
925  // graph
926  for(size_t p = 0; p < itr.parNames.size(); ++p){
927  parVal = itr.parVals[p];
928 
929  grMap.find(itr.parNames[p])->second->SetPoint(ctr, ctr * 1., parVal);
930  }
931 
932  // fill the chi^2 graph
933  chisq_graph->SetPoint(ctr, ctr * 1., itr.chiSqr);
934  ++ctr;
935  } // end loop over iterations
936 
937  // now loop over the graphs and create a canvas for each
938  std::string canvasname = calcName + uniqueID + "_ParameterIterationCanv";
939  TCanvas *can = tfd.make<TCanvas>(canvasname.data(), canvasname.data(), 800, 800);
940  can->Divide((grMap.size() / 2) + 1, (grMap.size() / 2) + 1);
941 
942  size_t pad = 1;
943  for(auto mapItr : grMap){
944 
945  can->cd(pad);
946  mapItr.second->Draw("ACP");
947  ++pad;
948  }//end of loop over parameter graphs
949 
950  // now do the chi^2 values for the iterations
951  can->cd(pad);
952  chisq_graph->Draw("ACP");
953 
954  // Save the canvas to file
955  can->Update();
956  can->Write();
957 
958  } // end loop over the different chi^2 calculators
959  }
960 
961  //......................................................................
963  {
964  gChiSqrCalc = chiSqrCalc;
965 
966  // get the initial chi^2
967  if(gMinChiSqr == cmf::kGarbageDouble)
968  gMinChiSqr = cmf::ChiSqrCalculator::Instance()->ChiSqr(gChiSqrCalc,
969  *gFFNames,
970  gFFVals->data());
971 
972  MF_LOG_VERBATIM("CovarianceMatrixFitter")
973  << "initial chi^2: "
974  << gMinChiSqr;
975 
976  // store this iteration of the fitter
977  this->AddIteration(gMinChiSqr,
978  *gFFNames,
979  *gFFVals,
980  gChiSqrCalc);
981 
982  // if we are minimizing d_CP we have just minimized allowing the
983  // value of d_CP to vary between 0 < d_CP < pi, now try it
984  // with pi < d_CP < 2pi
985  // the value of dCP should be the same for all detectors, so just get it from the
986  // NOvA FD location
987  if( !(gLoc->DetectorLocation(cmf::kFARDET).Parameter(std::string("dCP")).IsFixed()) ){
988 
989  double dCPRange = 2. * gPI / (1. * fNumCPRanges);
990 
991  for(int i = 0; i < fNumCPRanges; ++i){
992  this->MinimizeCP(i * dCPRange,
993  (i + 1) * dCPRange);
994  }
995  } // end if we have to minimize over ranges of d_CP
996  else{
997  // the minimizer returns true if we converge
998  if( !gFFMin->Minimize() ){
999  MF_LOG_WARNING("CovarianceMatrixFit")
1000  << "Fit failed to converge with the "
1001  << gFFMin->Options().MinimizerAlgorithm()
1002  << " algorithm";
1003  }
1004 
1005  // grab the results of the minimization
1006  gMinChiSqr = gFFMin->MinValue();
1007  gMinStatus = gFFMin->Status();
1008  for(size_t v = 0; v < gFFVals->size(); ++v) (*gFFVals)[v] = gFFMin->X()[v];
1009  } // end if dCP is fixed
1010 
1011  // Now update the ShifterAndWeighter to check the goodness of fit
1012  cmf::ShifterAndWeighter::Instance()->SetCurrentVals(*gFFNames, gFFVals->data());
1013 
1014  MF_LOG_VERBATIM("CovarianceMatrixFitter")
1015  << "fill the MC spectrum with the final fit values\n";
1016  for(size_t i = 0; i < gFFNames->size(); ++i){
1017  MF_LOG_VERBATIM("CovarianceMatrixFitter")
1018  << (*gFFNames)[i]
1019  << " "
1020  << (*gFFVals)[i];
1021  }
1022 
1023  // fill the MC spectrum
1024  this->FillMCSpectrum(*gMCEventLists);
1025  }
1026 
1027  //......................................................................
1028  // Method to minimize delta_CP given a number of trials for minimization
1029  // The idea here is that maybe we are finding a local minimum if we try
1030  // to minimize over the full range, so break it up into multiple ranges
1031  void CovarianceFitHelper::MinimizeCP(double const& dCPLow,
1032  double const& dCPHigh)
1033  {
1034 
1035  // Set initial values for all parameterSpaceLocations and
1036  // tell the minimizer what it is fitting
1037  double lowCon;
1038  double highCon;
1039 
1040  ROOT::Fit::ParameterSettings parSet;
1041 
1042  for(size_t ipar = 0; ipar < gFFNames->size(); ++ipar){
1043 
1044  if((*gFFNames)[ipar] == "dCP") (*gFFVals)[ipar] = 0.25 * dCPHigh + 0.75 * dCPLow;
1045 
1046  auto const& par = cmf::ParameterUtility::Instance()->ParameterInfo((*gFFNames)[ipar]);
1047 
1048  if(par.IsConstrained()){
1049  lowCon = par.LowerBound();
1050  highCon = par.UpperBound();
1051 
1052  if((*gFFNames)[ipar] == "dCP"){
1053  lowCon = dCPLow;
1054  highCon = dCPHigh;
1055  }
1056 
1057  gFFMin->SetLimitedVariable(ipar,
1058  (*gFFNames)[ipar],
1059  (*gFFVals)[ipar],
1060  0.01,
1061  lowCon,
1062  highCon);
1063  }
1064  else{
1065  gFFMin->SetVariable(ipar,
1066  (*gFFNames)[ipar],
1067  (*gFFVals)[ipar],
1068  0.01);
1069  } // end if unconstrained parameter
1070 
1071  gFFMin->GetVariableSettings(ipar, parSet);
1072  MF_LOG_VERBATIM("CovarianceMatrixFit")
1073  << parSet.Name()
1074  << " : "
1075  << parSet.Value()
1076  << " lower limit ("
1077  << parSet.HasLowerLimit()
1078  << ") "
1079  << parSet.LowerLimit()
1080  << " upper limit ("
1081  << parSet.HasUpperLimit()
1082  << ") "
1083  << parSet.UpperLimit();
1084 
1085  } // end loop over parameters
1086 
1087  // minimize
1088  if( !gFFMin->Minimize() ){
1089  MF_LOG_WARNING("CovarianceMatrixFit")
1090  << "Fit failed to converge d_CP with the "
1091  << gFFMin->Options().MinimizerAlgorithm()
1092  << " algorithm";
1093  }
1094  else{
1095  // the fit converged so compare to the previous minimization and
1096  // keep the lowest chi^2 result
1097  if(gFFMin->MinValue() < gMinChiSqr){
1098  gMinChiSqr = gFFMin->MinValue();
1099  gMinStatus = gFFMin->Status();
1100  for(size_t v = 0; v < gFFVals->size(); ++v) (*gFFVals)[v] = gFFMin->X()[v];
1101  }
1102  } // end if the fit converged
1103 
1104  }
1105 
1106  //......................................................................
1108  {
1109  // fill the MC spectrum
1110  if(loadFromEventList) cmf::CovarianceFitHelper::Instance()->FillMCSpectrum(*gMCEventLists);
1111 
1112  return fMCSpectrum;
1113  }
1114 
1115  //......................................................................
1116  std::unique_ptr<cmf::PointResult> CovarianceFitHelper::Result(bool loadFromEventLists)
1117  {
1118  // get the fit parameters, we want the last iteration in the vector
1119  // because that is where the fit ended
1121  for(size_t p = 0; p < fIterations.begin()->second.back().parNames.size(); ++p){
1122 
1123  parMap.emplace(cmf::StringToOscParmType(fIterations.begin()->second.back().parNames[p]),
1124  fIterations.begin()->second.back().parVals [p]);
1125  }
1126 
1127  return std::make_unique<cmf::PointResult>(gMinChiSqr,
1128  gMinStatus,
1129  parMap,
1130  this->BestFitSpectrum(loadFromEventLists));
1131  }
1132 
1133  //......................................................................
1134 // bool CovarianceFitHelper::ValidVectPosition(size_t vecSize,
1135 // size_t entry)
1136 // {
1137 // if(entry > vecSize - 1){
1138 // MF_LOG_WARNING("CovarianceFitHelper")
1139 // << "attempting to place value in position "
1140 // << entry
1141 // << " but size is "
1142 // << vecSize - 1;
1143 //
1144 // return false;
1145 // }
1146 //
1147 // return true;
1148 // }
1149 
1150 } // end namespace
T max(const caf::Proxy< T > &a, T b)
enum cmf::osc_params OscParm_t
void InitializeCovarianceMatrix(fhicl::ParameterSet const &pset)
void FillSpectrum(cmf::EventListColl const &eventLists, cmf::ExposureMap const &exposureMap, cmf::Spectrum &spectrum, cmf::Spectrum &count, cmf::InteractionType_t intType, bool applyExposureNorm)
enum BeamMode kRed
cmf::Spectrum fDataSpectrum
data spectrum in bins
cmf::Spectrum const & BestFitSpectrum(bool loadFromEventList=true)
void InitializeMinimizer(fhicl::ParameterSet const &minimizerPars)
static CovarianceFitHelper * gCovFitHelp
const std::vector< std::string > cFileTypeStrings({"Beam","FluxSwap","TauSwap","Data","CosmicBackground","RockFluxSwap","RockNonSwap","num_file_types","bad_file_type","UnknownFileType"})
cmf::DetType_t detector
Definition: Structs.h:114
const std::vector< std::string > cChiSqrCalcType_Strings({"CovMat","Poisson","CNP","Gauss","UnknownChiSqr"})
bool const & IsConstrained() const
Definition: Parameter.h:142
const char * p
Definition: xmltok.h:285
const std::vector< std::string > cDetType_Strings({"UnknownDet","NearDet","FarDet","MINOSNear","MINOSFar","AllDetectors"})
static const double kGarbageDouble
Definition: Constants.h:18
T sqrt(T number)
Definition: d0nt_math.hpp:156
constexpr T pow(T x)
Definition: pow.h:72
static long DetectorBeamSelectionTypesToKey(cmf::DetType_t const &det, cmf::BeamType_t const &bt, cmf::SelectionType_t const &sel)
Definition: StaticFuncs.h:61
cmf::Parameter const & ParameterInfo(std::string const &parName) const
Int_t par
Definition: SimpleIterate.C:24
static SelectionUtility * Instance()
std::vector< double > Spectrum
Definition: Constants.h:743
void FillChiSqrHistograms(cmf::ChiSqrCalc_t const &chiSqrCalc, cmf::Spectrum const &dataSpectrum, cmf::Spectrum const &mcSpectrum, TH1D *binByBin, TH1D *cumulative)
TCanvas * canv
::xsd::cxx::tree::exception< char > exception
Definition: Database.h:225
double FitFunction_ForROOT(const double *params)
void SelectionHistBinning(cmf::MetaData const &md, cmf::Spectrum &bins)
TH1F * MakeSpectrumHistogram(art::TFileDirectory &tfd, std::string const &baseName, std::string const &baseTitle, cmf::Spectrum const &spectrum)
double Weight(cmf::EventPtr const &curEvent, cmf::MetaData const &md)
enum cmf::sel_type SelectionType_t
void InitializeEventLists(fhicl::ParameterSet const &manipulatorPars, cmf::Spectrum const &dataSpectrum)
fhicl::ParameterSet fMinimizerPars
alternative algorithm to try if minimization fails
static bool IsAngleParameter(cmf::OscParm_t const &par)
Definition: StaticFuncs.h:354
cmf::Spectrum fDataCount
number of data events in each bin
void Deserialize(cmf::EventListColl &eventLists, cmf::DataMC_t dataMC=cmf::kBoth, std::set< cmf::DetType_t > const &detectors=std::set< cmf::DetType_t >({cmf::kNEARDET, cmf::kFARDET}))
static ParameterUtility * Instance()
std::map< cmf::ChiSqrCalc_t, std::vector< cmf::CovFitIteration > > fIterations
keep track of the minimizer iterations
void Minimize(cmf::ChiSqrCalc_t const &chiSqrCalc=cmf::kCovMat)
cmf::SelectionType_t selectionType
Definition: Structs.h:116
std::map< cmf::OscParm_t, float > OscillationParameterMap
Definition: Constants.h:745
void InitializeFitHelper(fhicl::ParameterSet const &helperPars)
void MakeEnergySpectraFromBins(cmf::Spectrum const &binSpec, cmf::Spectrum const &binCount, std::map< long, TH1D * > &energySpecMap, std::string const &name, art::TFileDirectory &tfd, std::string const &uniqueID)
void MinimizeCP(double const &dCPLow, double const &dCPHigh)
art::ServiceHandle< art::TFileService > fTFS
TFileService.
T get(std::string const &key) const
Definition: ParameterSet.h:231
void MakeCovarianceMatrixHistogram(art::TFileDirectory &tfd, std::string const &uniqueID)
int evt
ROOT::Math::Minimizer * gFFMin
void FindInitialGuess(std::vector< cmf::OscParamPoint > const &library)
cmf::ExposureMap const & ExposureMap() const
const std::vector< std::string > cSelectionType_Strings({"NuESel_AllPID","NuESel_LowPID","NuESel_MidPID","NuESel_HighPID","NuESel_Peripheral","NuMuSel","NuMuSelQ1","NuMuSelQ2","NuMuSelQ3","NuMuSelQ4","NCSel","UnknownSel"})
const std::vector< std::string > cBeamType_Strings({"FHC","RHC","0HC","UnknownBeam"})
std::unique_ptr< cmf::ExposureMap > gExposureMap
const Binning bins
static ShifterAndWeighter * Instance()
cmf::Spectrum fMCSpectrum
MC spectrum in bins.
void Make1DSpectra(art::TFileDirectory &tfd, cmf::EventListColl const &mcLists, std::string const &uniqueID)
void InitializeShifterAndWeighter(fhicl::ParameterSet const &sawPars)
std::map< int, double > fDataPOT
Data POT values for each detector/beam/selection.
static cmf::ChiSqrCalculator * Instance()
double ChiSqr(cmf::ChiSqrCalc_t const &chiSqrCalc, std::vector< std::string > const &pars, const double *vals)
static CovarianceFitHelper * Instance()
void FillMCSpectrum(cmf::EventListColl const &eventLists)
size_t TotalBins(bool allSels=false)
static bool IsOscillationParameter(std::string const &str)
void MakeDataMCCanv(std::map< long, TH1D * > &dataSpecMap, std::map< long, TH1D * > &mcSpecMap, cmf::SelectionType_t const &selVec, std::string const &canvName, art::TFileDirectory &tfd, std::string const &uniqueID)
std::string ToString() const
Definition: Structs.cxx:135
std::unique_ptr< cmf::EventListColl > gMCEventLists
Module to combine a set of results into a single file currently only does one data product type at a ...
Definition: Event.cxx:24
void AddIteration(double const &chi2, std::vector< std::string > const &pars, std::vector< double > const &vals, cmf::ChiSqrCalc_t const &chiSqrCalc=cmf::kCovMat)
std::set< cmf::DetType_t > const & DetectorsToUse()
void MakeResultPlots(std::string const &dirBaseName, std::string const &uniqueID=std::string(), bool fillFromLists=true)
std::vector< cmf::EventList > EventListColl
Definition: Event.h:150
std::string to_indented_string() const
void InitShiftsAndWeightsToUse(cmf::Location const &loc, fhicl::ParameterSet const &parset)
T sin(T number)
Definition: d0nt_math.hpp:132
std::unique_ptr< cmf::Location > gLoc
Float_t norm
static const double gPI
#define MF_LOG_VERBATIM(category)
void Initialize(fhicl::ParameterSet const &helperPars, fhicl::ParameterSet const &chiSqrCalcPars, fhicl::ParameterSet const &manipulatorPars, fhicl::ParameterSet const &minimizerPars, fhicl::ParameterSet const &sawPars)
std::unique_ptr< std::vector< double > > gFFVals
#define MF_LOG_DEBUG(id)
static PlotUtilities * Instance()
cmf::Location ParametersAsLocation()
int fNumCPRanges
number of ranges to divide up d_CP for seeding fits
TRandom3 r(0)
void SelectionsUsedOfType(cmf::SelectionType_t const &sel, DetBeamSelSet &sels)
const std::vector< std::string > cSelectionType_LatexStrings({"#nu_{e} Selection","#nu_{e} Selection - Low PID","#nu_{e} Selection - Mid PID","#nu_{e} Selection - High PID","#nu_{e} Selection - Peripheral","#nu_{#mu} Selection","#nu_{#mu} Selection - Quantile 1","#nu_{#mu} Selection - Quantile 2","#nu_{#mu} Selection - Quantile 3","#nu_{#mu} Selection - Quantile 4","NC Selection","Unknown Selection"})
double gMinChiSqr
#define MF_LOG_WARNING(category)
std::set< cmf::SelectionUtility::DetBeamSels > DetBeamSelSet
void FillDataSpectrum(cmf::EventListColl const &eventLists)
cmf::ChiSqrCalc_t gChiSqrCalc
T max(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
Definition: statistics.h:66
void SetCurrentVals(cmf::Location const &loc)
std::unique_ptr< cmf::PointResult > Result(bool loadFromEventList=true)
void NormalizeBinContents(TH1 *hist, double normToVal)
cmf::Spectrum fMCCount
number of MC events in each bin
void MakeIterationGraphs(art::TFileDirectory &tfd, std::string const &uniqueID)
std::string to_string(ModuleType const mt)
Definition: ModuleType.h:34
static cmf::OscParm_t StringToOscParmType(std::string const &str)
std::unique_ptr< std::vector< std::string > > gFFNames
enum cmf::chisqr_type ChiSqrCalc_t
void SetSpectrum(cmf::Spectrum const &spectrum, bool isData)
const std::vector< std::string > cBeamType_LatexStrings({"FHC","RHC","0HC""Unknown Beam"})
static CovarianceBinUtility * Instance()
enum BeamMode string