fake_future_data.C
Go to the documentation of this file.
12 #include "CAFAna/FC/FCSurface.h"
16 #include "CAFAna/Vars/FitVars.h"
17 #include "OscLib/IOscCalc.h"
18 #include "./sensitivity_tools.h"
19 
20 #include "TCanvas.h"
21 #include "TBox.h"
22 #include "TColor.h"
23 #include "TGraph.h"
24 #include "TVectorD.h"
25 #include "TF1.h"
26 #include "TLegend.h"
27 #include "TText.h"
28 #include "TLatex.h"
29 #include "TPad.h"
30 #include "TLine.h"
31 #include "TMarker.h"
32 #include "TStyle.h"
33 #include "TSystem.h"
34 #include "TGaxis.h"
35 
36 #include <algorithm>
37 #include <vector>
38 #include <string>
39 
40 
41 using namespace ana;
42 
43 void fake_future_data(int num = 1, bool throwexp = true, bool corrSysts = true,
44  TString options="fake2018")
45 {
46  // arguments:
47  // num - number of fake experiments you'd like to study
48  // throwexp - generation part, if false - read from the file and analyse
49  // corrSysts - stat or syst
50  // options - which osc.params to use for fake data
51 
52  bool fake2017 = options.Contains("fake2017");
53  bool fake2018 = options.Contains("fake2018");
54 
55  auto filename = "throw_exp_"+options + (corrSysts?"_with_syst_":"_just_stat_")+std::to_string(num)+".root";
56 
57  //////////////////////////////////////////////////
58  // Load Nue and Numu experiments
59  //////////////////////////////////////////////////
60 
61 
62  std::vector <const IPrediction * > preds;
63  std::vector <std::pair <TH1D*, double > > cosmics;
64  std::vector <const IExperiment * > expts;
65  double POT, Livetime;
66 
67  auto calc_fake = DefaultOscCalc();
68  double th23, dmsq, dcp;
69  if(fake2017) {th23 = 0.51; dmsq = 2.44e-3; dcp = 1.21;}
70  //SetFakeCalc(calc_fake, 0.51, 2.44e-3, 1.21);
71  if(fake2018) {th23 = 0.58; dmsq = 2.51e-3; dcp = 0.17;}
72  //SetFakeCalc(calc_fake, 0.58, 2.51e-3, 0.17);
73 
74  //nue fhc
75  preds.push_back(GetNuePrediction2018("combo", DefaultOscCalc(), corrSysts, "fhc", false));
76  cosmics.push_back(GetNueCosmics2018("fhc"));
77  //nue rhc
78  preds.push_back(GetNuePrediction2018("prop", DefaultOscCalc(), corrSysts, "rhc", false)); //make decomp choosable?
79  cosmics.push_back(GetNueCosmics2018("rhc"));
80  //fhc numu
81  int nnumu = 4;
82  auto numu_preds = GetNumuPredictions2018(nnumu, corrSysts, "fhc");
83  preds.insert(preds.end(),numu_preds.begin(), numu_preds.end());
84  auto numu_cosmics = GetNumuCosmics2018(nnumu, "fhc"); //leave numu cosmic as it is for 2018 ana, probably need to make own cosmic for 1600s of livetime
85  cosmics.insert(cosmics.end(),numu_cosmics.begin(), numu_cosmics.end());
86  //numu rhc
87  numu_preds = GetNumuPredictions2018(nnumu, corrSysts, "rhc");
88  preds.insert(preds.end(),numu_preds.begin(), numu_preds.end());
89  numu_cosmics = GetNumuCosmics2018(nnumu, "rhc");
90  cosmics.insert(cosmics.end(),numu_cosmics.begin(), numu_cosmics.end());
91 
92  // make fake data with random osc parameters based on the 2018 fit and random syst.shift
93  // then apply stat. fluctuations to the MC and cosmic
94 
95  if(throwexp) {
96 
97  // Randomize the oscillation parameters, this process will base on the result contous and slices. Use them as inputs and choose random points on the surface/slice.
98  // contours - th23 vs delta (take degeneracies into account)
99  // slice - dmsq23
100 
101  TFile* file = new TFile(filename,"recreate");
102 
103  TFile* histFHCNH = new TFile("/nova/ana/nu_e_ana/Ana2018/Results/FHCOnly/contours/delta_th23/syst/hist_contours_2018_joint_realData_FHCOnly_onlyNHcombo_systs.root","read");
104  TFile* histFHCIH = new TFile("/nova/ana/nu_e_ana/Ana2018/Results/FHCOnly/contours/delta_th23/syst/hist_contours_2018_joint_realData_FHCOnly_onlyIHcombo_systs.root","read");
105 
106  TH2F* histNH_pdf = new TH2F("histNH_pdf","histNH_pdf", 30, 0, 2*M_PI, 30, 0.3, 0.7);
107  TH2F* histIH_pdf = new TH2F("histIH_pdf","histIH_pdf", 30, 0, 2*M_PI, 30, 0.3, 0.7);
108 
109  auto histNH = (TH2F*)histFHCNH->Get("delta_th23_NH");
110  auto histIH = (TH2F*)histFHCIH->Get("delta_th23_IH");
111 
112  //make "pdf" from the chi2 surface
113  //
114  for(int i = 1; i<=30; i++){
115  for(int j = 1; j<=30; j++){
116  double binNH = histNH->GetBinContent(i,j);
117  histNH_pdf->SetBinContent(i, j, exp(-binNH/2.0));
118  double binIH = histIH->GetBinContent(i,j);
119  histIH_pdf->SetBinContent(i, j, exp(-binIH/2.0));
120  }
121  }
122 
123  new TCanvas();
124  histNH_pdf->Draw("colz");
125  gPad->Print("plots/pdf_transform_hist2d_delta_th23_nh.pdf");
126 
127  new TCanvas();
128  histIH_pdf->Draw("colz");
129  gPad->Print("plots/pdf_transform_hist2d_delta_th23_ih.pdf");
130 
131 
132  cout<<"integrals: "<<histNH_pdf->Integral()<<" and ih is "<<histIH_pdf->Integral()<<endl;
133  double sep = histNH_pdf->Integral()/(histNH_pdf->Integral()+histIH_pdf->Integral());
134 
135  // should count the probability to get the ih and nh, also bases on the "pdf". And then throw the hierarchy as uniform distribution
136 
137  cout<<"probablilty to get the NH is "<<histNH_pdf->Integral()/(histNH_pdf->Integral()+histIH_pdf->Integral())<<" and to get the ih is "<<histIH_pdf->Integral()/(histNH_pdf->Integral()+histIH_pdf->Integral())<<endl;
138 
139  TFile* dmsqFHC = new TFile("/nova/ana/nu_e_ana/Ana2018/Results/FHCOnly/slices/syst/hist_slices_2017_joint_realData_FHCOnlycombo_systs_dmsq_noOct.root","read");
140 
141  TH1F* histdmsqNH_pdf = new TH1F("histdmsqNH_pdf", "histdmsqNH_pdf", 60, 2e-3, 3e-3);
142  TH1F* histdmsqIH_pdf = new TH1F("histdmsqIH_pdf", "histdmsqIH_pdf", 60, -3e-3, -2e-3);
143 
144  auto histdmsqNH = (TH1F*)dmsqFHC->Get("slice_dmsq_NH");
145  auto histdmsqIH = (TH1F*)dmsqFHC->Get("slice_dmsq_IH");
146 
147  // count "pdf" for slice too
148 
149  for(int i = 1; i<=60; i++){
150  double binNH = histdmsqNH->GetBinContent(i);
151  histdmsqNH_pdf->SetBinContent(i, exp(-binNH/2.0));
152  double binIH = histdmsqIH->GetBinContent(i);
153  histdmsqIH_pdf->SetBinContent(i, exp(-binIH/2.0));
154  }
155 
156  new TCanvas();
157  histdmsqNH_pdf->Draw("hist");
158  gPad->Print("plots/pdf_transform_dmsq32_nh.pdf");
159 
160  new TCanvas();
161  histdmsqIH_pdf->Draw("hist");
162  gPad->Print("plots/pdf_transform_dmsq32_ih.pdf");
163 
164  //start doing experiments, j will count the experiment number
165 
166  for (int j = 0; j<num; j++){
167 
168  TDirectory* d = file->mkdir(("ex_"+std::to_string(j)).c_str());
169  file->cd(("ex_"+std::to_string(j)).c_str());
170 
171  TRandom3 rnd(0);
172 
173  //throw hierarchy as x in (0,1), compare to the probabilities we got from the surface's pdf
174 
175  double hie = rnd.Uniform(1);
176  cout<<"hie is "<<hie<<" hie separator is "<<sep<<endl;
177  bool isNH;
178  if(hie<sep) isNH = true;
179  else isNH = false;
180  double thisdcp, thisth23, thisdmsq, thisth13;
181  // get random osc. parameters from the surface and slice
182  if (isNH) {
183  histNH_pdf->GetRandom2(thisdcp, thisth23);
184  thisdmsq= histdmsqNH_pdf->GetRandom();
185  }
186  else{
187  histIH_pdf->GetRandom2(thisdcp, thisth23);
188  thisdmsq = histdmsqIH_pdf->GetRandom();
189  }
190  // get random th13 for the pdg constraint
191  thisth13 = rnd.Gaus(0.082, 0.004);
192 
193  // use fake osc. parameters for this experiment
194 
195  calc_fake->SetdCP(thisdcp*M_PI);
196  calc_fake->SetTh23(asin(sqrt(thisth23)));
197  calc_fake->SetDmsq32(thisdmsq);
198  calc_fake->SetTh13(asin(sqrt(thisth13))/2);
199  // save to the .root file just in case
200  TVectorD v(4);
201  v[0] = thisdmsq;
202  v[1] = thisth23;
203  v[2] = thisdcp;
204  v[3] = thisth13;
205  v.Write((std::to_string(j)+"_osc_pars").c_str());
206  cout<<"osc pars in exp "<<j<<" are "<<thisdmsq<<" "<<thisth23<<" "<<thisdcp<<endl;
207 
208  // randomize the systematic shiftes for this experiment
209 
210  struct systshifts{
211  double shift;
212  TString systname;
213  };
214 
215  std::vector <systshifts> shifts;
216 
217  auto systs = GetJointFitSystematicList(corrSysts, false, false, true, true, true);
218  // save to the file and make a lable in order to get the correct shift later
219  for (auto &s:systs){
220  auto sh = rnd.Gaus(0, 1);
221  shifts.push_back({sh, s->ShortName().c_str()});
222  cout<<s->ShortName().c_str()<<"("<<sh<<"), ";
223  TVectorD vs(1);
224  vs[0] = sh;
225  vs.Write((std::to_string(j)+"_"+s->ShortName()).c_str());
226  }
227 
228  cout<<"\n\n";
229 
230  // enter the loop for all spectra we analyze, nue fhc, nue rhc, 4 numu fhc, 4 numu rhc = 10 spectra we need to randomize
231 
232  for(int i=0; i < 10; i++){
233 
234 
235  if(i==0) {POT = kFutureFHCPOT; Livetime = kFutureFHCLivetime;}
236  if(i==1) {POT = kFutureRHCPOT; Livetime = kFutureRHCLivetime;}
237  if(i >= 2 && i < 6) {POT = kFutureFHCPOT; Livetime = kFutureFHCLivetime;}
238  if(i >= 6 && i < 10) {POT = kFutureRHCPOT; Livetime = kFutureRHCLivetime;}
239 
240  auto check_wo_syst = preds[i]->Predict(calc_fake).ToTH1(POT);
241  cout<<" before random syst shifts the integral was "<<check_wo_syst->Integral()<<endl;
242 
243  // get systematics for this particular spectra (remember we have some systematics unique for nue/numu or fhc/rhc)
244  // and assign them syst shifts we got earlier for this experiment j
245  // if systematics are the same for some nue/numu/rhc/fhc spectra the shifts should be the same for them
246 
247  SystShifts sshifts;
248 
249  if(corrSysts){
250  if(i==0) systs = getAllAna2018Systs(kNueAna2018, true, kFHC);
251  if(i==1) systs = getAllAna2018Systs(kNueAna2018, true, kRHC);
252  if(i>= 2) systs = getAllAna2018Systs(kNumuAna2018); // doesn't play any role
253  }
254  for (auto &s:systs){
255  for(auto &sh:shifts){ if(s->ShortName() == sh.systname) {sshifts.SetShift(s, sh.shift); cout<<s->ShortName()<<" "<<sh.shift<<", ";} }
256  }
257  cout<<"\n\n";
258  // make prediction based on the random parameters and random syst shiftes
259  auto temphist = preds[i]->PredictSyst(calc_fake, sshifts).ToTH1(POT); // get full spectra for i experiment (make by components and then sum them up?)
260  // we have an issue with numu cosmic prediction which was done for the 2018 exposure, so we need to scale it to the future exposure
261  auto tempcosm = (TH1D*)cosmics[i].first->Clone(UniqueName().c_str());
262  if(i>1) {
263  double denom;
264  if(i >= 2 && i < 6) denom = kAna2018FHCLivetime;
265  if(i >= 6 && i < 10) denom = kAna2018RHCLivetime;
266  cout<<"numu file was made with "<<denom<<" livetime, need to scale to the "<<Livetime<<endl;
267  cout<<"before scaling "<<tempcosm->Integral()<<endl;
268  tempcosm->Scale(Livetime/denom);
269  cout<<"after scaling "<<tempcosm->Integral()<<endl;
270  }
271  //sum cosmic and mc prediction
272  auto total = Spectrum(tempcosm, POT, 0);
273  total+=Spectrum(temphist, POT,0);
274 
275  cout<<"mock experiment integral is "<<temphist->Integral()<<" and cosmic is "<<tempcosm->Integral()<<endl;
276  //apply poissonian fluctuation
277  auto mockexp = total.MockData(POT);
278  cout<<"mock experiment after Pois. fluct "<<mockexp.Integral(POT)<<endl;
279  // save to the file; we have fake data now
280  mockexp.SaveTo(d, (std::to_string(i)+"_mockexp").c_str());
281  }
282  }
283  }
284 
285 
286  if(!throwexp){
287 
288  // the part for the analyzing the fake data
289 
290  TFile* file = new TFile(filename,"read");
291 
292  // loop over all experiments in file
293 
294  for (int j = 0; j<num; j++){
295 
296  for(int i = 0; i < 10; ++i){
297  // read fake data
298  auto thisdata = LoadFromFile<Spectrum>(file, TString::Format("ex_%s/%s_mockexp", std::to_string(j).c_str(), std::to_string(i).c_str()).Data()).release();
299  if(i==0) {POT = kFutureFHCPOT; Livetime = kFutureFHCLivetime;}
300  if(i==1) {POT = kFutureRHCPOT; Livetime = kFutureRHCLivetime;}
301  if(i >= 2 && i < 6) {POT = kFutureFHCPOT; Livetime = kFutureFHCLivetime;}
302  if(i >= 6 && i < 10) {POT = kFutureRHCPOT; Livetime = kFutureRHCLivetime;}
303  // scale the cosmic again, for making the prediction for fit
304  auto tempcosm = (TH1D*)cosmics[i].first->Clone(UniqueName().c_str());
305  if(i>1) {
306  double denom;
307  if(i >= 2 && i < 6) denom = kAna2018FHCLivetime;
308  if(i >= 6 && i < 10) denom = kAna2018RHCLivetime;
309  tempcosm->Scale(Livetime/denom);
310  }
311  cout<<i<<" POT "<<POT<<" tot MC "<<preds[i]->Predict(calc_fake).Integral(POT)<<" cos "<<tempcosm->Integral()<<" cos er "<<1/sqrt(tempcosm->Integral())<<" analyze data "<<thisdata->Integral(POT)<<endl;
312  // push mc prediction, fake data, scaled cosmic and its error for the fit
313  expts.push_back(new SingleSampleExperiment(preds[i],*thisdata, tempcosm,1/sqrt(tempcosm->Integral())));
314  }
315 
316  ////////////////////////////////////////////////////////////
317  // Add constraints, make experiments
318  ////////////////////////////////////////////////////////////
319 
320 
321  std::cout << "\nCreating multiexperiment\n" << std::endl;
322 
323  expts.push_back(WorldReactorConstraint2017()); std::cout << "Adding WorldReactorConstraint2017\n";
324  std::cout << "Creating Multiexperiment with a total of "
325  << expts.size() << " experiments\n\n" << std::endl;
326  auto exptThis = new MultiExperiment(expts);
327 
328  ////////////////////////////////////////////////////////////
329  // Systematics
330  ////////////////////////////////////////////////////////////
331 
332  std::cout << "Systematics for the fit:\n";
333  auto systs = GetJointFitSystematicList(corrSysts, false, false, true, true, true);
334 
335  std::cout << "\n\nSystematic correlations...\n";
336 
337  exptThis->SetSystCorrelations(0, GetCorrelations(true, true));
338  exptThis->SetSystCorrelations(1, GetCorrelations(true, false));
339  auto notfornumu = GetCorrelations(false, true);
340  for(int i =0; i < 8; ++i) exptThis->SetSystCorrelations(i+2, notfornumu);
341 
342  std::cout << "Starting the fit" << std::endl;
343 
345 
346  SystShifts auxShifts = SystShifts::Nominal();
347  std::vector <SystShifts> seedShifts = {};
348 
349  // make seeds for the fit
350 
351  struct th23helper{
352  std::vector<double> seeds;
353  const IFitVar * var;
354  TString label;
355  };
356 
357  std::vector <th23helper> th23seeds;
358 
359  bool octantSlice =true;
360 
361  if(octantSlice) {
362  th23seeds.push_back( { {0.499, 0.45}, kFitSinSqTheta23LowerOctant, "LO"});
363  th23seeds.push_back( { {0.501, 0.55}, kFitSinSqTheta23UpperOctant, "UO"});
364  }
365  else th23seeds.push_back({ {0.45, 0.5, 0.55}, &kFitSinSqTheta23, ""});
366 
367  std::vector<double> delta_seeds = {0, 0.5, 1., 1.5};
368 
369  // start searching the bf by looping the NH/IH, upper and lower octants. The lowest chi2 will be the best fit
370 
371  double minchi23 = 1E20;
372  for(int hie:{-1, 1}){
373  for (auto & thseed:th23seeds){
374 
375  std::cout << "\n\nFinding best fit " << (hie > 0 ? "NH " : "IH ")
376  << thseed.label << ", "
377  << "ssth23 seeds ";
378  for (auto const & s:thseed.seeds) std::cout << s << ", ";
379  std::cout << std::endl;
380  std::vector <const IFitVar*> fitvars = {&kFitDeltaInPiUnits,
381  thseed.var,
384  MinuitFitter fit23(exptThis, fitvars, systs);
385  auto thisminchi = fit23.Fit(calc, auxShifts,
386  {
387  { &kFitDmSq32Scaled, {hie*2.5} },
388  { thseed.var, thseed.seeds },
389  { &kFitDeltaInPiUnits, delta_seeds }
390  }, seedShifts,
391  IFitter::kQuiet)->EvalMetricVal();
392  minchi23= min(minchi23, thisminchi);
393 
394  // plot the systamtic pulls for this octant and hierarchy
395  if(corrSysts){
396  auto shifts = PlotSystShifts(auxShifts);
397  TString str = "Best fit " ;
398  for (auto &v:fitvars){
399  str += TString::Format(" %s=%.3f ",v->LatexName().c_str(),v->GetValue(calc));
400  }
401  str+= TString::Format(" LL=%.6f", thisminchi);
402  shifts->SetTitle(str);
403  gPad->Update();
404  TLine *l=new TLine(gPad->GetUxmin(),0,gPad->GetUxmax(),0);
405  l->Draw("same");
406  gPad->Print("syst_shifts_for_exp_" +std::to_string(j)+
407  (hie>0? "_NH": "_IH") + thseed.label + ".pdf");
408  }
409 
410  ResetOscCalcToDefault(calc);
411  auxShifts.ResetToNominal();
412  }
413  }
414  std::cout << "\nFound overall minchi " << minchi23 << "\n\n";
415  expts.clear();
416  }
417  }
418 }
Cuts and Vars for the 2020 FD DiF Study.
Definition: vars.h:6
void ResetOscCalcToDefault(osc::IOscCalcAdjustable *calc)
Reset calculator to default assumptions for all parameters.
Definition: Calcs.cxx:23
TH1 * PlotSystShifts(const SystShifts &shifts, bool sortName)
Definition: Plots.cxx:1495
std::vector< SystGroupDef > systs
Definition: syst_header.h:385
double th23
Definition: runWimpSim.h:98
Simple record of shifts applied to systematic parameters.
Definition: SystShifts.h:20
T sqrt(T number)
Definition: d0nt_math.hpp:156
const FitSinSqTheta23UpperOctant kFitSinSqTheta23UpperOctant
Definition: FitVars.cxx:16
const double kFutureRHCPOT
Definition: Exposures.h:245
string filename
Definition: shutoffs.py:106
const double kFutureFHCPOT
Definition: Exposures.h:244
std::vector< const IPrediction * > GetNumuPredictions2018(const int nq=4, bool useSysts=true, std::string beam="fhc", bool GetFromUPS=false, ENu2018ExtrapType numuExtrap=kNuMu, bool minimizeMemory=false, bool NERSC=false)
static SystShifts Nominal()
Definition: SystShifts.h:34
osc::OscCalcDumb calc
osc::IOscCalcAdjustable * DefaultOscCalc()
Create a new calculator with default assumptions for all parameters.
Definition: Calcs.cxx:49
#define M_PI
Definition: SbMath.h:34
const char * label
const XML_Char * s
Definition: expat.h:262
std::vector< const ISyst * > getAllAna2018Systs(const EAnaType2018 ana, const bool smallgenie, const BeamType2018 beam, bool isFit)
const double kFutureFHCLivetime
Definition: Exposures.h:247
virtual std::unique_ptr< IFitSummary > Fit(osc::IOscCalcAdjustable *seed, SystShifts &bestSysts=junkShifts, const SeedList &seedPts=SeedList(), const std::vector< SystShifts > &systSeedPts={}, Verbosity verb=kVerbose) const
Master fitting method. Depends on FitHelper and FitHelperSeeded.
Definition: IFitter.cxx:64
fvar< T > exp(const fvar< T > &x)
Definition: exp.hpp:10
Float_t d
Definition: plot.C:236
const ReactorExperiment * WorldReactorConstraint2017()
Reactor constraint from PDG 2017.
const double j
Definition: BetheBloch.cxx:29
const ConstrainedFitVarWithPrior fitDmSq32Scaled_UniformPrior & kFitDmSq32Scaled
std::vector< float > Spectrum
Definition: Constants.h:527
const double kFutureRHCLivetime
Definition: Exposures.h:248
std::vector< std::pair< TH1D *, double > > GetNumuCosmics2018(const int nq=4, std::string beam="fhc", bool GetFromUPS=false, bool NERSC=false)
const char sep
OStream cout
Definition: OStream.cxx:6
std::vector< double > POT
static float min(const float a, const float b, const float c)
Definition: absgeo.cxx:45
Combine multiple component experiments.
std::pair< TH1D *, double > GetNueCosmics2018(std::string beam, bool GetFromUPS=false, bool NERSC=false)
const FitSinSqTheta23LowerOctant kFitSinSqTheta23LowerOctant
Definition: FitVars.cxx:17
void ResetToNominal()
Definition: SystShifts.cxx:141
int num
Definition: f2_nu.C:119
const ConstrainedFitVarWithPrior fitSsqTh23_UniformPriorSsqTh23 & kFitSinSqTheta23
TFile * file
Definition: cellShifts.C:17
Interface definition for fittable variables.
Definition: IFitVar.h:16
std::vector< std::pair< const ISyst *, const ISyst * > > GetCorrelations(bool isNue, bool isFHC, bool ptExtrap)
void Format(TGraph *gr, int lcol, int lsty, int lwid, int mcol, int msty, double msiz)
Definition: Style.cxx:154
const FitSinSq2Theta13 kFitSinSq2Theta13
Definition: FitVars.cxx:13
const IPrediction * GetNuePrediction2018(std::string decomp, osc::IOscCalc *calc, bool corrSysts, std::string beam, bool isFakeData, bool GetFromUPS=false, bool minimizeMemory=false, bool NERSC=false)
std::string to_string(ModuleType mt)
Definition: ModuleType.h:32
void fake_future_data(int num=1, bool throwexp=true, bool corrSysts=true, TString options="fake2018")
Float_t e
Definition: plot.C:35
#define for
Definition: msvc_pragmas.h:3
const FitVarWithPrior fitDeltaInPiUnits_UniformPriordCP & kFitDeltaInPiUnits
std::vector< const ISyst * > GetJointFitSystematicList(bool corrSysts, bool nueExclusive=false, bool numuExclusive=false, bool isFHC=true, bool isRHC=true, bool intersection=true, bool ptExtrap=true)
void SetShift(const ISyst *syst, double shift, bool force=false)
Definition: SystShifts.cxx:78
std::string UniqueName()
Return a different string each time, for creating histograms.
Definition: Utilities.cxx:30
const double kAna2018FHCLivetime
Definition: Exposures.h:213
const double kAna2018RHCLivetime
Definition: Exposures.h:214
T asin(T number)
Definition: d0nt_math.hpp:60
Compare a single data spectrum to the MC + cosmics expectation.
Perform MINUIT fits in one or two dimensions.
Definition: MinuitFitter.h:17