9 #include "CAFAna/Core/Binning.h" 11 #include "CAFAna/Core/Var.h" 30 #include "TMultiGraph.h" 32 #include "TLegendEntry.h" 36 #include "TPaveText.h" 40 #include "TAttMarker.h" 59 const double Enu =
kCCE(sr);
61 if(Enu < 0.75)
return 0.1 / 0.75;
62 if(Enu >= 0.75 && Enu < 1)
return 0.1 / 0.25;
63 if(Enu >= 1 && Enu < 2)
return 0.1 / 0.1;
64 if(Enu >= 2 && Enu < 3)
return 0.1 / 0.25;
65 if(Enu >= 3 && Enu < 4)
return 0.1 / 0.5;
66 if(Enu >= 4 && Enu < 5)
return 0.1 / 1;
74 TLatex*
prelim =
new TLatex(.9, .95,
"NO#nuA Preliminary");
75 prelim->SetTextColor(
kBlue);
77 prelim->SetTextSize(2/30.);
78 prelim->SetTextAlign(32);
93 for(
const auto& obj:*(gPad->GetListOfPrimitives()))
105 for(
const auto& obj:*(gPad->GetListOfPrimitives())) {
107 if(obj->InheritsFrom(
"TH1")) {
109 std::string XTit = ((TH1*)obj)->GetXaxis()->GetTitle();
110 if ( XTit.find(
"Reconstructed Neutrino Energ") != std::string::npos ) {
111 ((TH1*)obj)->GetYaxis()->SetTitle(
"Events / 0.1 GeV");
114 ((TH1*)obj)->GetXaxis()->Paint();
116 ((TH1*)obj)->GetYaxis()->Paint();
117 ((TH1*)obj)->GetZaxis()->Paint();
126 TCanvas* clone = (TCanvas*)can->DrawClone();
129 clone->SetCanvasSize(can->GetWw(), can->GetWh());
134 for(
const auto& obj:*(clone->GetListOfPrimitives()))
136 if(obj->InheritsFrom(
"TH1"))
139 for(
int i = 1;
i <= h->GetNbinsX(); ++
i)
141 int c = h->GetBinContent(
i);
142 if(c != 0 && c < min) min =
c;
143 if (c > max) max =
c;
151 for(
const auto& obj:*(clone->GetListOfPrimitives()))
153 if(obj->InheritsFrom(
"TH1"))
155 ((TH1*)obj)->SetMinimum(min);
156 ((TH1*)obj)->SetMaximum(max);
162 TString
name = TString(can->GetTitle()) +
"_logy";
163 clone->SetName(name);
164 clone->SetTitle(name);
209 fUps.reserve(systs.size());
210 fDowns.reserve(systs.size());
211 for(
const auto& syst:systs){
214 fUps .emplace_back(loaderMC, fAxis.fObj, fSel.fObj,
SystShifts(syst, +1), BinWeight);
215 fDowns.emplace_back(loaderMC, fAxis.fObj, fSel.fObj,
SystShifts(syst, -1), BinWeight);
222 {
return ShortName().c_str();};
234 assert(iSyst < fUps.size());
246 TLegend*
leg = DrawLegendPOT();
254 std::vector<Spectrum> normUps;
255 std::vector<Spectrum> normDowns;
257 Spectrum tempMC(fMC.ToTH1(fMC.POT()),fMC.POT(),fMC.Livetime());
258 tempMC.
OverridePOT(fMC.POT() * fMC.ToTH1(fData.POT())->GetSumOfWeights() / fData.ToTH1(fData.POT())->GetSumOfWeights());
264 normDowns.reserve(1);
269 normUps.reserve(fUps.size());
270 normDowns.reserve(fUps.size());
272 for(
size_t i = 0;
i < fUps.size(); ++
i)
275 if(iSyst >= 0 && (
int)
i != iSyst)
continue;
276 normUps.emplace_back(fUps[
i]);
280 for(
size_t i = 0;
i < fDowns.size(); ++
i)
283 if(iSyst >= 0 && (
int)
i != iSyst)
continue;
284 normDowns.emplace_back(fDowns[
i]);
297 const int tempcolor=kBlack;
298 const int tempmarker=kFullCircle;
299 TH1D* hDummy = fData.ToTH1(fData.POT());
300 hDummy->GetYaxis()->SetTitle(
"Events / 0.1 GeV");
302 hDummy->SetMarkerColor(tempcolor);
303 hDummy->SetMarkerStyle(tempmarker);
304 hDummy->SetLineColor(tempcolor);
307 DrawMCNormSyst(iSyst);
310 TLegend*
leg = DrawLegendArea();
319 const int iSyst = -1,
320 const int dataColor=kBlack,
321 const int extraColor=kGray+1,
322 const int dataMarker=kFullCircle,
323 const int extraMarker=kFullCircle)
const 327 DrawData(dataColor, dataMarker);
328 extraData.
DrawData(extraColor, extraMarker);
330 TLegend*
leg = DrawLegendPOT(dataColor, dataLegendTitle, dataMarker);
331 TH1F* colExtraData =
new TH1F();
332 colExtraData->SetMarkerColor(extraColor);
333 colExtraData->SetMarkerStyle(extraMarker);
334 colExtraData->SetLineColor(extraColor);
335 leg->AddEntry((TObject*)colExtraData, extraLegendTitle.c_str(),
"ple");
346 const int iSyst = -1,
347 const int dataColor=kBlack,
348 const int extraColor=kGray+1,
349 const int dataMarker=kFullCircle,
350 const int extraMarker=kFullCircle)
const 354 DrawMCNormSyst(iSyst);
355 DrawData(dataColor, dataMarker);
358 TLegend*
leg = DrawLegendArea(dataColor, dataLegendTitle, dataMarker);
359 TH1F* colExtraData =
new TH1F();
360 colExtraData->SetMarkerColor(extraColor);
361 colExtraData->SetMarkerStyle(extraMarker);
362 colExtraData->SetLineColor(extraColor);
363 leg->AddEntry((TObject*)colExtraData, extraLegendTitle.c_str(),
"ple");
371 const int dataMarker=kFullCircle)
const 376 TH1F* colMC =
new TH1F();
378 TH1F* colMCBkg =
new TH1F();
379 colMCBkg->SetLineColor(
kBlue);
380 TH1F* colData =
new TH1F();
381 colData->SetLineColor(dataColor);
382 colData->SetMarkerColor(dataColor);
383 colData->SetMarkerStyle(dataMarker);
385 leg->AddEntry((TObject*)colMC,
"Simulated Selected Events",
"l");
386 leg->AddEntry((TObject*)colMCBkg,
"Simulated Background",
"l");
387 leg->AddEntry((TObject*)colData, dataLegendTitle.c_str(),
"ple");
388 TLegendEntry *entryns1=leg->AddEntry(
"error",
"Shape-only 1-#sigma syst. range",
"f");
389 entryns1->SetFillStyle(1001);
390 entryns1->SetFillColor(
kRed-10);
391 leg->SetTextSize(0.04);
393 leg->SetFillColor(0);
394 leg->SetFillStyle(0);
396 for(
const auto& obj:*leg->GetListOfPrimitives())
398 if(obj->InheritsFrom(
"TAttFill")){
399 ((TAttFill*)obj)->SetFillStyle(0);
410 const int dataMarker=kFullCircle)
const 415 TH1F* colMC =
new TH1F();
417 TH1F* colMCBkg =
new TH1F();
418 colMCBkg->SetLineColor(
kBlue);
419 TH1F* colData =
new TH1F();
420 colData->SetLineColor(dataColor);
421 colData->SetMarkerColor(dataColor);
422 colData->SetMarkerStyle(dataMarker);
424 leg->AddEntry((TObject*)colMC,
"Simulated Selected Events",
"l");
425 leg->AddEntry((TObject*)colMCBkg,
"Simulated Background",
"l");
426 leg->AddEntry((TObject*)colData, dataLegendTitle.c_str(),
"ple");
427 TLegendEntry *entryns1=leg->AddEntry(
"error",
"Full 1-#sigma syst. range",
"f");
428 entryns1->SetFillStyle(1001);
429 entryns1->SetFillColor(
kRed-10);
430 leg->SetTextSize(0.04);
432 leg->SetFillColor(0);
433 leg->SetFillStyle(0);
435 for(
const auto& obj:*leg->GetListOfPrimitives())
437 if(obj->InheritsFrom(
"TAttFill")){
438 ((TAttFill*)obj)->SetFillStyle(0);
449 std::stringstream expo;
450 std::stringstream expoData;
451 std::stringstream expoMC;
452 float pot = fData.POT();
453 float dataMean = (fData.ToTH1(pot)) -> GetMean();
454 float dataMeanError = (fData.ToTH1(pot)) -> GetMeanError();
455 float MCMean = (fMC.ToTH1(pot)) -> GetMean();
456 float MCMeanError = (fMC.ToTH1(pot)) -> GetMeanError();
458 expoData.precision(2);
460 expo <<
"ND area norm., " 469 text.SetTextAlign(22);
470 text.SetTextSize(0.04);
475 text.DrawLatexNDC(place->GetX1(), place->GetY1(),
476 (
"#splitline{" + expo.str() +
"}{ #splitline{" +
477 expoData.str() +
"}{" + expoMC.str() +
"}}").c_str()
484 std::stringstream expo;
485 float pot = fData.POT();
487 expo <<
"ND POT norm., " 491 text.SetTextAlign(22);
492 text.SetTextSize(0.04);
494 text.DrawLatexNDC(place->GetX1(), place->GetY1(), expo.str().c_str());
496 if (ShortName().find(
"numuE") != std::string::npos) {
497 std::cout <<
"\n" << ShortName() <<
"\t Data: " << fData.ToTH1(pot)->Integral()
498 <<
"\t MC: " << fMC.ToTH1(pot)->Integral() <<
"\n";
518 TH1D* hData = fData.ToTH1(fData.POT());
519 hData->GetYaxis()->SetTitle(
"Events / 0.1 GeV");
520 hData->SetMarkerColor(
color);
521 hData->SetMarkerStyle(marker);
522 hData->SetLineColor(
color);
529 TH1D* hMCBkg = fMCBkg.ToTH1(fData.POT());
530 hMCBkg->GetYaxis()->SetTitle(
"Events / 0.1 GeV");
531 hMCBkg->SetLineColor(
kBlue);
532 hMCBkg->Draw(
"HIST SAME");
537 return 1 - fMCBkg.ToTH1(fData.POT())->
GetEntries() /
625 std::vector<std::string>
keys)
629 std::vector<DataMCPair>::iterator
it = list.end();
631 for(std::vector<DataMCPair>::iterator
entry = list.begin();
637 for(
const auto&
key:keys)
642 if(
entry->ShortName().find(
key) == std::string::npos)
660 if(nFound == 0)
throw "Failed to find match.";
661 if(nFound > 1)
throw "Found too many matches.";
670 std::ofstream
out(dir + name);
671 out << pair.fAxis.fBlurb << pair.
fSel.
fBlurb << extra;
680 while (OutName.find(
"_") != std::string::npos) OutName.replace(OutName.find(
"_"),1,
" ");
682 if (OutName.find(
"Qual") != std::string::npos) OutName.insert(OutName.find(
" Qual"),
", Cut level:");
684 if (OutName.find(
"pot") != std::string::npos) OutName.replace(OutName.find(
" pot"),4,
". With POT normalisation.");
686 if (OutName.find(
"area") != std::string::npos) OutName.replace(OutName.find(
" area"),5,
". With Area normalisation.");
688 std::string Cap =
"Plot showing the number of ND NuMi events in #nu_{#mu} Ana17 for variable: " + OutName;
706 const int NHadEFracQuantiles = 4;
708 std::string fdspecfile =
"/nova/app/users/karlwarb/Workspace/NuMuSystematics/FDQuantileHists/final_full_FD_histo_for_quantile_cuts.root";
709 TFile*
inFile = TFile::Open( fdspecfile.c_str() );
710 gDirectory->cd(
"dir_FDSpec2D");
711 TH2 *FDSpec2D = (TH2*)inFile->FindObjectAny(
"FDSpec2D");
718 std::vector<Cut> TieredCuts;
736 gStyle->SetMarkerStyle(kFullCircle);
737 TGaxis::SetMaxDigits(3);
740 std::string fnameNDMC =
"prod_caf_R17-03-01-prod3reco.d_nd_genie_nonswap_fhc_nova_v08_full_v1";
741 std::string fnameNDData =
"prod_caf_R17-03-01-prod3reco.d_nd_numi_fhc_full_v1_goodruns";
745 fnameNDMC =
"prod_sumdecaf_R17-03-01-prod3reco.d_nd_genie_nonswap_fhc_nova_v08_full_v1_numu2017_stride22";
747 fnameNDData=
"prod_sumdecaf_R17-03-01-prod3reco.d_nd_numi_fhc_full_v1_goodruns_numu2017";
765 std::vector<Selection> selections;
767 for (
size_t quant=0; quant < HadEFracQuantCuts.size(); ++quant) {
770 selections.emplace_back( TieredCuts[
cuts], CutNames[cuts]+
"_QuantAll",
771 "Selected events pass "+CutNames[cuts]+
" all quantiles");
773 selections.emplace_back( TieredCuts[
cuts] && HadEFracQuantCuts[quant], CutNames[
cuts]+
"_Quant"+
std::to_string(quant+1),
779 std::vector<TangibleAxis> variables;
784 variables.emplace_back( EnergyAxis ,
"MuonE" ,
"Reconstructed energy of primary muon track.");
785 variables.emplace_back( HadEAxis ,
"HadE" ,
"Hadronic enery, i.e. numu energy estimate minus muon track energy. " );
786 variables.emplace_back( HadEFracAxis ,
"HadEFrac" ,
"Hadronic enery fraction, i.e. ration of hadronic energy to numu energy. " );
787 variables.emplace_back( ReMIDAxis ,
"ReMIDScore",
"ReMId kNN score." );
788 variables.emplace_back( CVNNuMuAxis ,
"CVNNuMu" ,
"CVN muon identification score." );
860 std::vector<DataMCPair> pairs;
862 pairs.reserve(selections.size() * variables.size());
863 for(
const auto& sel:selections){
864 for(
const auto& variable:variables){
865 pairs.emplace_back(sel, variable, loaderData, loaderMC, systs, MyWeight, !
kIsNumuCC );
872 std::vector<TCanvas*>
cans;
874 for(
const auto& pair:pairs) {
876 std::cout <<
"\nNow looking pairs, " << pair.ShortName() <<
" - " << pair.CName() <<
", it has purity " << pair.Purity() <<
std::endl;
877 TString
name(TString(pair.CName()) +
"_allSysts_pot");
880 cans.push_back(
new TCanvas(name,name));
881 pair.OverlayDataMCSyst();
884 "Full systematic band shown. ",
885 "Near detector data/MC comparison for numu first analysis. " );
896 TString nameNorm(TString(pair.CName()) +
"_allSysts_area");
898 cans.push_back(
new TCanvas(nameNorm,nameNorm));
899 pair.OverlayDataMCSystNorm();
902 std::string(
"Each systematically shifted histogram (both up and down) ")
903 +
std::string(
"is normalized to the area of the MC distribution, ")
905 "Near detector data/MC comparison for numu first analysis. " );
921 TFile *
OutFile =
new TFile(
"nd_syst_plots/NearDet_NuMiData_Systs_NuMuAna17.root",
"RECREATE");
924 for(
const auto&
can:cans) {
928 can->SaveAs (TString(
"nd_syst_plots/") +
can->GetName() +
".pdf");
929 can->Write (
can->GetName() );
DataMCPair * findPair(std::vector< DataMCPair > &list, std::vector< std::string > keys)
Get a vector of all the numu group systs.
const Cut kIsNumuCC(CCFlavSel(14, 14))
Select CC .
void DrawData(const int color=kBlack, const int marker=kFullCircle) const
Cuts and Vars for the 2020 FD DiF Study.
const Cut kNumuContainND2017([](const caf::SRProxy *sr){if(!sr->vtx.elastic.IsValid) return false;for(unsigned int i=0;i< sr->vtx.elastic.fuzzyk.nshwlid;++i){TVector3 start=sr->vtx.elastic.fuzzyk.png[i].shwlid.start;TVector3 stop=sr->vtx.elastic.fuzzyk.png[i].shwlid.stop;if(std::min(start.X(), stop.X())< -180.0) return false;if(std::max(start.X(), stop.X()) > 180.0) return false;if(std::min(start.Y(), stop.Y())< -180.0) return false;if(std::max(start.Y(), stop.Y()) > 180.0) return false;if(std::min(start.Z(), stop.Z())< 20.0) return false;if(std::max(start.Z(), stop.Z()) > 1525.0) return false;}if(sr->trk.kalman.ntracks< 1) return false;for(unsigned int i=0;i< sr->trk.kalman.ntracks;++i){if(i==sr->trk.kalman.idxremid) continue;else if(sr->trk.kalman.tracks[i].start.Z() > 1275||sr->trk.kalman.tracks[i].stop.Z() > 1275) return false;}return(sr->trk.kalman.ntracks > sr->trk.kalman.idxremid &&sr->slc.firstplane > 1
&&sr->slc.lastplane< 212 &&sr->trk.kalman.tracks[0].start.Z()< 1100
&&(sr->trk.kalman.tracks[0].stop.Z()< 1275 ||sr->sel.contain.kalyposattrans< 55) &&sr->sel.contain.kalfwdcellnd > 5 &&sr->sel.contain.kalbakcellnd > 10);})
Simple record of shifts applied to systematic parameters.
void OverridePOT(double newpot)
DO NOT USE UNLESS YOU ARE 110% CERTAIN THERE ISN'T A BETTER WAY!
TGraphAsymmErrors * PlotWithSystErrorBand(IPrediction *pred, const std::vector< const ISyst * > &systs, osc::IOscCalc *calc, double pot, int col, int errCol, float headroom, bool newaxis, EBinType bintype, double alpha)
Plot prediction with +/-1sigma error band.
Proxy for caf::StandardRecord.
const HistAxis kHadEFracAxis("E_{had.} / E_{#nu}", Binning::Simple(200, 0, 1), kHadEFrac)
HistAxis that implements Hadronic Energy fraction binning used by L.Vinton to derive Hadronic Energy ...
Tangible< Cut > Selection
std::string ShortName() const
void SetSpillCut(const SpillCut &cut)
void CenterTitles(TH1 *histo)
double Integral(double exposure, double *err=0, EExposureType expotype=kPOT) const
Return total number of events scaled to pot.
std::vector< Spectrum > fUps
const Color_t kTotalMCErrorBandColor
const Var kTrkLength([](const caf::SRProxy *sr){if(sr->trk.kalman.ntracks< 1) return-5.f;return sr->trk.kalman.tracks[0].len/100;})
void OverlayDataMCSystExtraData(const DataMCPair &extraData, const std::string dataLegendTitle, const std::string extraLegendTitle, const int iSyst=-1, const int dataColor=kBlack, const int extraColor=kGray+1, const int dataMarker=kFullCircle, const int extraMarker=kFullCircle) const
Representation of a spectrum in any variable, with associated POT.
void AddExposureArea() const
void DrawMCSyst(const int iSyst=-1) const
const Var kBinWidthWeight([](const caf::SRProxy *sr){const double Enu=kCCE(sr); if(Enu< 0.75) return 0.1/0.75;if(Enu >=0.75 &&Enu< 1) return 0.1/0.25;if(Enu >=1 &&Enu< 2) return 0.1/0.1;if(Enu >=2 &&Enu< 3) return 0.1/0.25;if(Enu >=3 &&Enu< 4) return 0.1/0.5;if(Enu >=4 &&Enu< 5) return 0.1/1;else return 1.;})
void DrawData(const int color=kBlack, EBinType bintype=kBinContent) const
Draw data on plots, mostly for internal use.
Tangible(const T &obj, const std::string &shortName, const std::string &blurb)
std::vector< Spectrum > fDowns
Tangible< HistAxis > TangibleAxis
virtual void Go() override
Load all the registered spectra.
DataMCPair(Selection sel, TangibleAxis tanAxis, SpectrumLoader &loaderData, SpectrumLoader &loaderMC, std::vector< const ISyst * > systs, const Var BinWeight, const Cut &bkg=kNoCut)
const Cut kNumuPID2017([](const caf::SRProxy *sr){return(sr->sel.remid.pid > 0.5 &&sr->sel.cvn.numuid > 0.5);})
const char * CName() const
TCanvas * LogClone(const TCanvas *can)
const HistAxis kNumuCCOptimisedAxis("Reconstructed Neutrino Energy (GeV)", kNumuCCEOptimisedBinning, kCCE)
HistAxis that implements optimised numuCCE from L. Vinton. See docdb 16332. This was close to 'custC'...
const SystShifts kNoShift
TLegend * DrawLegendArea(const int dataColor=kBlack, std::string dataLegendTitle="Data", const int dataMarker=kFullCircle) const
static float min(const float a, const float b, const float c)
void hadEFrac_nd_data_mc_systs(bool RunBinNorm=false, bool IsTest=false)
void AestheticsPOT() const
void AestheticsArea() const
Collaborates with Spectrum and OscillatableSpectrum to fill spectra from CAF files.
TLegend * DrawLegendPOT(const int dataColor=kBlack, std::string dataLegendTitle="Data", const int dataMarker=kFullCircle) const
void OverlayDataMCSystNorm(const int iSyst=-1) const
std::vector< Cut > QuantileCutsFromTH2(TH2 *quantileHist, const HistAxis &independentAxis, const HistAxis &quantileAxis, const unsigned int &numQuantiles, const bool verbose)
: Do the same as the QuantileCuts function but taking in the TH2 instead of making it...
assert(nhit_max >=nhit_nbins)
string shortName
THUMBNAIL BLOCK: We need to make a thumbnail for each.
TLegend * AutoPlaceLegend(double dx, double dy, double yPin)
Create a legend, maximizing distance from all histograms.
const SpillCut kStandardSpillCuts
Apply this unless you're doing something special.
std::vector< const ISyst * > getAllDirectNumuSysts2017()
Get a vector of all the numu group systs.
void Format(TGraph *gr, int lcol, int lsty, int lwid, int mcol, int msty, double msiz)
const Color_t kTotalMCColor
std::string to_string(ModuleType mt)
T max(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
void MakeTextFile(std::string OutName)
void DrawMCNormSyst(const int iSyst=-1) const
static Binning Simple(int n, double lo, double hi, const std::vector< std::string > &labels={})
short int place(double jd_tt, object *cel_object, observer *location, double delta_t, short int coord_sys, short int accuracy, sky_pos *output)
void AddExposurePOT() const
void OverlayDataMCSyst(const int iSyst=-1) const
const Cut kNoCut
The simplest possible cut: pass everything, used as a default.
const Var kCosNumi([](const caf::SRProxy *sr){if(sr->trk.kalman.ntracks > 0 &&sr->trk.kalman.idxremid!=999){if(sr->hdr.det==1){return sr->trk.kalman.tracks[0].dir.Dot(beamDirND);}if(sr->hdr.det==2){return sr->trk.kalman.tracks[0].dir.Dot(beamDirFD);}}return-5.f;})
void OverlayDataMCSystNormExtraData(const DataMCPair &extraData, const std::string dataLegendTitle, const std::string extraLegendTitle, const int iSyst=-1, const int dataColor=kBlack, const int extraColor=kGray+1, const int dataMarker=kFullCircle, const int extraMarker=kFullCircle) const
void WriteBlurb(const DataMCPair &pair, std::string dir, std::string name, std::string extra="", std::string beginning="")
std::vector< std::string > CutNames