13 #include "cetlib_except/exception.h" 25 #include "TDirectory.h" 30 #include "TDecompChol.h" 43 : fOutputFile(output_file.c_str(),
"RECREATE") {
45 gStyle->SetOptStat(0);
52 catch (
const std::runtime_error &
e) {
65 fMinimizer = std::unique_ptr<ROOT::Math::Minimizer>
66 (ROOT::Math::Factory::CreateMinimizer(
"Minuit2",
"Migrad"));
73 TH1D parsHist(
"preFitPars",
"", total_parameters, 0, total_parameters);
75 total_parameters, 0, total_parameters);
80 for (
size_t i = 0; i < it->second.size(); ++i) {
82 it->second[i] =
fRNG.Gaus(1., .1);
88 parsHist.SetBinContent(n_par+1, it->second[i]);
89 parsHist.SetBinError(n_par+1, 0.);
107 it->second =
fRNG.Gaus(1., .1);
113 parsHist.SetBinContent(n_par+1, it->second);
114 parsHist.SetBinError(n_par+1, 0.);
127 std::cout <<
"Adding parameter " << it->second.GetName().c_str() <<
128 " " << it->second.GetCentral() <<
std::endl;
129 double val = it->second.GetCentral();
131 it->second.SetValue(
fRNG.Gaus(1., .1)*it->second.GetCentral());
132 val = it->second.GetValue();
134 fMinimizer->SetVariable(n_par, it->second.GetName().c_str(),
137 fMinimizer->SetVariableLimits(n_par, it->second.GetLowerLimit(),
138 it->second.GetUpperLimit());
141 std::cout <<
"Fixing variable " << it->second.GetName() <<
149 fParLimits.push_back(it->second.GetThrowLimit());
151 if (
abs(it->second.GetCentral()) < 1.
e-5) {
152 parsHist.SetBinContent(n_par+1, val + 1.);
156 std::cout <<
"1 Set Error: " << it->first <<
" " <<
161 parsHist.SetBinContent(n_par+1,
162 val/it->second.GetCentral());
165 parsHist.SetBinError(n_par+1,
167 std::cout <<
"2 Set Error: " << it->first <<
" " <<
168 sqrt((*
fCovMatrixDisplay)[cov_bin][cov_bin]) <<
" " << it->second.GetCentral() <<
" " <<
178 n_par+1, it->second.GetName().c_str());
186 parsHist.SetMarkerColor(kBlue);
187 parsHist.SetMarkerStyle(20);
198 int sample_ID = sample_set.
get<
int>(
"ID");
201 fSamples[sample_ID] = std::vector<std::vector<ThinSliceSample>>();
202 fFakeSamples[sample_ID] = std::vector<std::vector<ThinSliceSample>>();
208 int flux_type = sample_set.
get<
int>(
"FluxType");
209 std::vector<double> bins
210 = sample_set.
get<std::vector<double>>(
"SignalBins");
214 fSamples[sample_ID].push_back(std::vector<ThinSliceSample>());
215 fFakeSamples[sample_ID].push_back(std::vector<ThinSliceSample>());
218 if (sample_set.
get<
bool>(
"IsSignal")) {
226 sample_name +
"Underflow",
229 fSamples[sample_ID].back().push_back(underflow_sample);
232 sample_name +
"FakeUnderflow",
235 fFakeSamples[sample_ID].back().push_back(fake_underflow_sample);
240 std::string par_name =
"par_" + sample_name +
"_underflow";
248 for (
size_t k = 1;
k < bins.size(); ++
k) {
252 {bins[
k-1], bins[
k]});
258 {bins[
k-1], bins[
k]});
259 fSamples[sample_ID].back().push_back(sample);
265 std::string par_name =
"par_" + sample_name +
"_" +
278 fSamples[sample_ID].back().push_back(overflow_sample);
286 std::string par_name =
"par_" + sample_name +
"_overflow";
291 fFakeSamples[sample_ID].back().push_back(fake_overflow_sample);
298 fSamples[sample_ID].back().push_back(sample);
339 for (
size_t i = 0; i < it->second.size(); ++i) {
340 for (
size_t j = 0; j < it->second[i].size(); ++j) {
342 it->second[i][j].GetAllSplines());
352 std::cout <<
"Filling MC Events" <<
std::endl;
356 double true_beam_interactingEnergy, reco_beam_interactingEnergy;
357 double true_beam_endP, true_beam_mass, true_beam_endZ;
358 double reco_beam_endZ, true_beam_startP;
360 std::vector<double> * reco_beam_incidentEnergies = 0x0,
361 * true_beam_incidentEnergies = 0x0,
362 * true_beam_traj_Z = 0x0,
363 * true_beam_traj_KE = 0x0,
364 * reco_daughter_track_thetas = 0x0,
365 * reco_daughter_track_scores = 0x0;
366 std::vector<int> * true_beam_slices = 0x0;
367 fMCTree->SetBranchAddress(
"event", &event);
368 fMCTree->SetBranchAddress(
"subrun", &subrun);
369 fMCTree->SetBranchAddress(
"run", &run);
371 fMCTree->SetBranchAddress(
"true_beam_PDG", &true_beam_PDG);
373 fMCTree->SetBranchAddress(
"new_interaction_topology", &sample_ID);
374 fMCTree->SetBranchAddress(
"selection_ID", &selection_ID);
375 fMCTree->SetBranchAddress(
"true_beam_interactingEnergy",
376 &true_beam_interactingEnergy);
377 fMCTree->SetBranchAddress(
"true_beam_endP", &true_beam_endP);
378 fMCTree->SetBranchAddress(
"true_beam_endZ", &true_beam_endZ);
379 fMCTree->SetBranchAddress(
"true_beam_mass", &true_beam_mass);
380 fMCTree->SetBranchAddress(
"reco_beam_interactingEnergy",
381 &reco_beam_interactingEnergy);
382 fMCTree->SetBranchAddress(
"reco_beam_endZ", &reco_beam_endZ);
383 fMCTree->SetBranchAddress(
"reco_beam_incidentEnergies",
384 &reco_beam_incidentEnergies);
385 fMCTree->SetBranchAddress(
"true_beam_incidentEnergies",
386 &true_beam_incidentEnergies);
387 fMCTree->SetBranchAddress(
"true_beam_slices",
389 fMCTree->SetBranchAddress(
"true_beam_startP", &true_beam_startP);
390 fMCTree->SetBranchAddress(
"true_beam_traj_Z", &true_beam_traj_Z);
391 fMCTree->SetBranchAddress(
"true_beam_traj_KE", &true_beam_traj_KE);
392 std::vector<double> * calibrated_dQdX = 0x0, * beam_EField = 0x0,
394 fMCTree->SetBranchAddress(
"reco_beam_calibrated_dQdX_SCE", &calibrated_dQdX);
395 fMCTree->SetBranchAddress(
"reco_beam_EField_SCE", &beam_EField);
396 fMCTree->SetBranchAddress(
"reco_beam_TrkPitch_SCE", &track_pitch);
397 fMCTree->SetBranchAddress(
"beam_inst_P", &beam_inst_P);
398 fMCTree->SetBranchAddress(
"reco_daughter_allTrack_Theta", &reco_daughter_track_thetas);
399 fMCTree->SetBranchAddress(
"reco_daughter_PFP_trackScore_collection",
400 &reco_daughter_track_scores);
402 std::vector<double> * g4rw_alt_primary_plus_sigma_weight = 0x0,
403 * g4rw_alt_primary_minus_sigma_weight = 0x0,
404 * g4rw_full_primary_plus_sigma_weight = 0x0,
405 * g4rw_full_primary_minus_sigma_weight = 0x0;
406 std::vector<std::vector<double>> * g4rw_primary_grid_weights = 0x0,
407 * g4rw_full_grid_weights = 0x0,
408 * g4rw_full_grid_proton_weights = 0x0;
409 fMCTree->SetBranchAddress(
"g4rw_alt_primary_plus_sigma_weight",
410 &g4rw_alt_primary_plus_sigma_weight);
411 fMCTree->SetBranchAddress(
"g4rw_alt_primary_minus_sigma_weight",
412 &g4rw_alt_primary_minus_sigma_weight);
413 fMCTree->SetBranchAddress(
"g4rw_full_primary_plus_sigma_weight",
414 &g4rw_full_primary_plus_sigma_weight);
415 fMCTree->SetBranchAddress(
"g4rw_full_primary_minus_sigma_weight",
416 &g4rw_full_primary_minus_sigma_weight);
417 fMCTree->SetBranchAddress(
"g4rw_full_grid_weights", &g4rw_full_grid_weights);
418 fMCTree->SetBranchAddress(
"g4rw_full_grid_proton_weights", &g4rw_full_grid_proton_weights);
420 fMCTree->SetBranchAddress(
"g4rw_primary_grid_weights",
421 &g4rw_primary_grid_weights);
423 std::vector<std::vector<double>> * daughter_dQdXs = 0x0,
424 * daughter_resRanges = 0x0,
425 * daughter_EFields = 0x0;
427 "reco_daughter_allTrack_calibrated_dQdX_SCE", &daughter_dQdXs);
429 "reco_daughter_allTrack_resRange_SCE", &daughter_resRanges);
431 "reco_daughter_allTrack_EField_SCE", &daughter_EFields);
433 fMCTree->SetBranchAddress(
"has_shower_dist_energy", &has_pi0_shower);
438 std::cout <<
"Note: Splitting MC in half. " <<
442 for (
int i = 0; i <
nentries; ++i) {
446 fEvents.back().SetSampleID(sample_ID);
447 fEvents.back().SetSelectionID(selection_ID);
448 fEvents.back().SetTrueInteractingEnergy(true_beam_interactingEnergy);
449 fEvents.back().SetRecoInteractingEnergy(reco_beam_interactingEnergy);
450 fEvents.back().SetTrueEndP(true_beam_endP);
451 fEvents.back().SetTrueEndZ(true_beam_endZ);
452 fEvents.back().SetTrueStartP(true_beam_startP);
453 fEvents.back().SetTrueMass(true_beam_mass);
454 fEvents.back().SetRecoEndZ(reco_beam_endZ);
456 fEvents.back().SetRecoIncidentEnergies(*reco_beam_incidentEnergies);
457 fEvents.back().SetTrueIncidentEnergies(*true_beam_incidentEnergies);
458 fEvents.back().SetTrueTrajZ(*true_beam_traj_Z);
459 fEvents.back().SetTrueTrajKE(*true_beam_traj_KE);
460 fEvents.back().SetTrueSlices(*true_beam_slices);
461 fEvents.back().SetdQdXCalibrated(*calibrated_dQdX);
462 fEvents.back().SetEField(*beam_EField);
463 fEvents.back().SetTrackPitch(*track_pitch);
464 fEvents.back().SetBeamInstP(beam_inst_P);
465 fEvents.back().SetPDG(true_beam_PDG);
466 fEvents.back().SetRecoDaughterTrackThetas(*reco_daughter_track_thetas);
467 fEvents.back().SetRecoDaughterTrackScores(*reco_daughter_track_scores);
468 fEvents.back().SetHasPi0Shower(has_pi0_shower);
469 fEvents.back().MakeG4RWBranch(
"g4rw_alt_primary_plus_sigma_weight",
470 *g4rw_alt_primary_plus_sigma_weight);
471 fEvents.back().MakeG4RWBranch(
"g4rw_alt_primary_minus_sigma_weight",
472 *g4rw_alt_primary_minus_sigma_weight);
473 fEvents.back().MakeG4RWBranch(
"g4rw_full_primary_plus_sigma_weight",
474 *g4rw_full_primary_plus_sigma_weight);
475 fEvents.back().MakeG4RWBranch(
"g4rw_full_primary_minus_sigma_weight",
476 *g4rw_full_primary_minus_sigma_weight);
477 for (
size_t j = 0; j < daughter_dQdXs->size(); ++j) {
478 fEvents.back().AddRecoDaughterTrackdQdX((*daughter_dQdXs)[j]);
479 fEvents.back().AddRecoDaughterTrackResRange((*daughter_resRanges)[j]);
480 fEvents.back().AddRecoDaughterEField((*daughter_EFields)[j]);
483 for (
size_t j = 0; j < g4rw_primary_grid_weights->size(); ++j) {
485 fEvents.back().MakeG4RWBranch(name_full, (*g4rw_full_grid_weights)[j]);
487 std::string name_primary =
"g4rw_primary_grid_weights_" +
489 fEvents.back().MakeG4RWBranch(name_primary,
490 (*g4rw_primary_grid_weights)[j]);
492 fEvents.back().MakeG4RWBranch(
"g4rw_full_grid_proton_weights",
493 (*g4rw_full_grid_proton_weights)[0]);
502 fFakeDataEvents.back().SetTrueInteractingEnergy(true_beam_interactingEnergy);
503 fFakeDataEvents.back().SetRecoInteractingEnergy(reco_beam_interactingEnergy);
510 fFakeDataEvents.back().SetRecoIncidentEnergies(*reco_beam_incidentEnergies);
511 fFakeDataEvents.back().SetTrueIncidentEnergies(*true_beam_incidentEnergies);
520 fFakeDataEvents.back().SetRecoDaughterTrackThetas(*reco_daughter_track_thetas);
521 fFakeDataEvents.back().SetRecoDaughterTrackScores(*reco_daughter_track_scores);
523 fFakeDataEvents.back().MakeG4RWBranch(
"g4rw_alt_primary_plus_sigma_weight",
524 *g4rw_alt_primary_plus_sigma_weight);
525 fFakeDataEvents.back().MakeG4RWBranch(
"g4rw_alt_primary_minus_sigma_weight",
526 *g4rw_alt_primary_minus_sigma_weight);
527 fFakeDataEvents.back().MakeG4RWBranch(
"g4rw_full_primary_plus_sigma_weight",
528 *g4rw_full_primary_plus_sigma_weight);
529 fFakeDataEvents.back().MakeG4RWBranch(
"g4rw_full_primary_minus_sigma_weight",
530 *g4rw_full_primary_minus_sigma_weight);
531 for (
size_t j = 0; j < daughter_dQdXs->size(); ++j) {
533 fFakeDataEvents.back().AddRecoDaughterTrackResRange((*daughter_resRanges)[j]);
537 for (
size_t j = 0; j < g4rw_primary_grid_weights->size(); ++j) {
539 fFakeDataEvents.back().MakeG4RWBranch(name_full, (*g4rw_full_grid_weights)[j]);
541 std::string name_primary =
"g4rw_primary_grid_weights_" +
544 (*g4rw_primary_grid_weights)[j]);
547 (*g4rw_full_grid_proton_weights)[0]);
550 std::cout <<
"Filled MC Events" <<
std::endl;
555 for (
auto it = selected_hists.begin(); it != selected_hists.end(); ++it) {
561 for (
size_t i = 0; i < it->second.size(); ++i) {
562 for (
size_t j = 0; j < it->second[i].size(); ++j) {
574 double total_nominal = 0.;
577 for (
size_t i = 0; i < it->second.size(); ++i) {
578 for (
size_t j = 0; j < it->second[i].size(); ++j) {
579 total_nominal += it->second[i][j].GetNominalFlux();
596 for (
size_t i = 0; i < it->second.size(); ++i) {
597 for (
size_t j = 0; j < it->second[i].size(); ++j) {
605 double new_total_mc = 0., new_total_data = 0., mc_flux = 0.;
606 double data_bins = 0., mc_bins = 0.;
608 for (
size_t i = 0; i < it->second.size(); ++i) {
609 for (
size_t j = 0; j < it->second[i].size(); ++j) {
612 mc_flux += it->second[i][j].GetNominalFlux();
613 const std::map<int, TH1 *> &
hists 614 = it->second[i][j].GetSelectionHists();
615 for (
auto it2 = hists.begin(); it2 != hists.end(); ++it2) {
616 new_total_mc += it2->second->Integral();
617 for (
int k = 1;
k <= it2->second->GetNbinsX(); ++
k) {
618 mc_bins += it2->second->GetBinContent(
k);
625 for (
auto it = selected_hists.begin(); it != selected_hists.end(); ++it) {
626 new_total_data += it->second->Integral();
627 for (
int k = 1;
k <= it->second->GetNbinsX(); ++
k) {
628 data_bins += it->second->GetBinContent(
k);
641 double new_factor = data_bins/mc_bins;
645 for (
size_t i = 0; i < it->second.size(); ++i) {
646 for (
size_t j = 0; j < it->second[i].size(); ++j) {
648 it->second[i][j].ExtraFactor(new_factor);
682 std::cout <<
"Doing Asimov" <<
std::endl;
684 std::vector<ThinSliceSample> & samples_vec = it->second[0];
685 fFakeDataScales[it->first] = std::vector<double>(samples_vec.size(), 1.);
688 std::vector<double> vals;
691 for (
size_t i = 0; i < it->second.size(); ++i) {
692 vals.push_back(it->second[i]);
697 vals.push_back(it->second);
702 vals.push_back(it->second.GetValue());
717 for (
size_t i = 0; i < it->second.size(); ++i) {
718 for (
size_t j = 0; j < it->second[i].size(); ++j) {
719 it->second[i][j].Reset();
724 std::vector<ThinSliceSample> & samples_vec = it->second[0];
725 fFakeDataScales[it->first] = std::vector<double>(samples_vec.size(), 0.);
739 TDirectory * out = (TDirectory *)
fOutputFile.mkdir(
"Data");
743 for (
auto it = selected_hists.begin(); it != selected_hists.end(); ++it) {
756 for (
size_t i = 0; i < it->second.size(); ++i) {
757 auto vec = it->second.at(i);
758 for (
size_t j = 0; j < vec.size(); ++j) {
759 const std::map<int, TH1 *> &
hists = vec[j].GetSelectionHists();
760 for (
auto it2 = hists.begin(); it2 != hists.end(); ++it2) {
761 it2->second->Write();
770 std::string extra_name, TDirectory * xsec_dir, TDirectory * plot_dir,
783 auto & samples_vec_2D
786 std::vector<double> signal_bins =
fSignalBins[sample_ID];
790 signal_name += samples_vec_2D[0][1].GetName() +
"Hist";
791 TH1D signal_hist(signal_name.c_str(),
"", signal_bins.size() - 1,
794 for (
size_t j = 0; j < samples_vec_2D.size(); ++j) {
795 auto & samples_vec = samples_vec_2D[j];
797 k < samples_vec.size()-1; ++
k) {
811 inc_name +=
"TotalIncident" + samples_vec_2D[0][0].GetName();
813 TH1D * total_incident_hist =
new TH1D(inc_name.c_str(),
"",
814 signal_bins.size() - 1,
816 std::map<int, std::vector<TH1D*>> temp_hists;
819 temp_hists[fIncidentSamples[i]] = std::vector<TH1D*>();
820 for (
size_t j = 0; j < vec_2D.size(); ++j) {
821 auto & samples_vec = vec_2D[j];
822 for (
size_t k = 0;
k < samples_vec.size(); ++
k) {
825 name +=
"Incident" + samples_vec_2D[0][1].GetName() +
827 std::string title = samples_vec[
k].GetSelectionHists().begin()->second->GetTitle();
828 temp_hists[fIncidentSamples[i]].push_back(
829 new TH1D(name.c_str(),
831 signal_bins.size() - 1,
835 samples_vec[
k].FillESliceHist(*total_incident_hist);
836 samples_vec[
k].FillESliceHist(
837 *(temp_hists[fIncidentSamples[i]][
k]));
840 samples_vec[
k].FillHistFromIncidentEnergies(*total_incident_hist);
841 samples_vec[
k].FillHistFromIncidentEnergies(
842 *(temp_hists[fIncidentSamples[i]][
k]));
847 total_incident_hist->Write();
855 std::string xsec_name = extra_name + samples_vec_2D[0][1].GetName() +
857 TH1D * xsec_hist = (TH1D*)signal_hist.Clone(xsec_name.c_str());
859 xsec_hist->Divide(total_incident_hist);
861 for (
int i = 1; i <= xsec_hist->GetNbinsX(); ++i) {
862 xsec_hist->SetBinContent(i, -1.*log(1. - xsec_hist->GetBinContent(i)));
864 xsec_hist->Scale(1.E27*39.948/(1.4 * 6.022E23));
865 for (
int i = 1; i <= xsec_hist->GetNbinsX(); ++i) {
867 double bethe_val =
BetheBloch(xsec_hist->GetBinCenter(i), 139.57);
869 xsec_hist->SetBinContent(i, (bethe_val*
870 xsec_hist->GetBinContent(i)/
871 xsec_hist->GetBinWidth(i)));
875 for (
int i = 1; i <= xsec_hist->GetNbinsX(); ++i) {
876 xsec_hist->SetBinContent(i, -1.*log(1. - xsec_hist->GetBinContent(i)));
878 xsec_hist->Scale(1.E27*39.948/(
fPitch * 1.4 * 6.022E23));
881 for (
int i = 1; i <= xsec_hist->GetNbinsX(); ++i) {
882 xsec_hist->SetBinContent(i, -1.*log(1. - xsec_hist->GetBinContent(i)));
884 xsec_hist->Scale(1.E27/ (
fPitch * 1.4 * 6.022E23 / 39.948 ));
895 stack_name +=
"IncidentStack" + samples_vec_2D[0][1].GetName();
896 THStack inc_stack(stack_name.c_str(),
";Reconstructed KE (MeV)");
898 for (
auto it = temp_hists.begin(); it != temp_hists.end(); ++it) {
899 for (
size_t i = 0; i < it->second.size(); ++i) {
900 std::pair<int, int> color_fill =
902 it->second[i]->SetFillColor(color_fill.first);
903 it->second[i]->SetFillStyle(color_fill.second);
904 it->second[i]->SetLineColor(1);
905 inc_stack.Add(it->second[i]);
913 std::map<int, std::vector<TH1*>> temp_map;
916 for (
auto it = temp_map.begin(); it != temp_map.end(); ++it) {
923 = std::vector<double>(it->second[0].size(), 0.);
925 for (
size_t i = 0; i < it->second[0].size(); ++i) {
926 double best_fit_val_i = 0.;
927 for (
size_t j = 0; j < it->second.size(); ++j) {
928 best_fit_val_i += it->second[j][i].GetVariedFlux();
938 bool found_minimum =
false;
944 std::cerr <<
"exiting safely" <<
std::endl;
948 TVector output_fit_status(1);
951 if (!found_minimum) {
952 std::cout <<
"Failed to find minimum" <<
std::endl;
954 output_fit_status.Write(
"fit_status");
963 std::vector<double> vals;
968 std::cout <<
"chi2 Syst: " << chi2_syst <<
std::endl;
969 std::cout <<
"chi2 Stat: " << chi2_stat <<
std::endl;
973 std::cout <<
"Running Hesse" <<
std::endl;
975 std::cout <<
"hesse good? " << hesse_good <<
std::endl;
976 TVector output_hesse_status(1);
979 output_hesse_status[0] = (hesse_good ? 1 : 0);
980 output_hesse_status.Write(
"hesse_status");
988 std::cout << total_parameters <<
std::endl;
989 for (
size_t i = 0; i < total_parameters; ++i) {
995 TH2D covHist(
"covHist",
"", total_parameters, 0,
996 total_parameters, total_parameters, 0,
998 TH2D corrHist(
"corrHist",
"", total_parameters, 0,
999 total_parameters, total_parameters, 0,
1002 TH1D parsHist(
"postFitPars",
"", total_parameters, 0,
1004 TH1D parsHist_normal_val(
"postFitParsNormal",
"",
1005 total_parameters, 0, total_parameters);
1006 TH1D * toyParsHist = 0x0,
1007 * toyParsHist_normal = 0x0;
1009 toyParsHist = (TH1D*)parsHist.Clone(
"toyPars");
1010 toyParsHist->Reset();
1011 toyParsHist_normal = (TH1D*)parsHist.Clone(
"toyPars_normal");
1012 toyParsHist_normal->Reset();
1020 for (
size_t i = 0; i < it->second.size(); ++i) {
1021 parsHist.SetBinContent(n_par+1,
fMinimizer->X()[n_par]);
1022 parsHist.SetBinError(n_par+1,
1024 parsHist.GetXaxis()->SetBinLabel(
1027 parsHist_normal_val.SetBinContent(n_par+1,
fMinimizer->X()[n_par]);
1028 parsHist_normal_val.SetBinError(
1029 n_par+1, sqrt(
fMinimizer->CovMatrix(n_par, n_par)));
1030 parsHist_normal_val.GetXaxis()->SetBinLabel(
1034 toyParsHist->SetBinContent(n_par+1, -999.);
1051 parsHist.SetBinContent(n_par+1,
fMinimizer->X()[n_par]);
1052 parsHist.SetBinError(n_par+1,
1054 parsHist.GetXaxis()->SetBinLabel(
1057 parsHist_normal_val.SetBinContent(n_par+1,
fMinimizer->X()[n_par]);
1058 parsHist_normal_val.SetBinError(
1059 n_par+1, sqrt(
fMinimizer->CovMatrix(n_par, n_par)));
1060 parsHist_normal_val.GetXaxis()->SetBinLabel(
1065 toyParsHist->SetBinContent(n_par+1, -999.);
1082 if (
abs(it->second.GetCentral()) < 1.e-5) {
1083 parsHist.SetBinContent(n_par+1,
fMinimizer->X()[n_par] + 1.);
1084 parsHist.SetBinError(n_par+1,
1087 toyParsHist->SetBinContent(n_par+1,
fToyValues[it->first] + 1.);
1091 parsHist.SetBinContent(n_par+1,
fMinimizer->X()[n_par]/it->second.GetCentral());
1092 parsHist.SetBinError(n_par+1,
1093 sqrt(
fMinimizer->CovMatrix(n_par, n_par))/it->second.GetCentral());
1095 toyParsHist->SetBinContent(n_par+1,
fToyValues[it->first]/it->second.GetCentral());
1099 toyParsHist_normal->SetBinContent(n_par+1,
fToyValues[it->first]);
1101 toyParsHist_normal->SetBinError(
1105 parsHist.GetXaxis()->SetBinLabel(
1106 n_par+1, it->second.GetName().c_str());
1108 parsHist_normal_val.SetBinContent(n_par+1,
fMinimizer->X()[n_par]);
1109 parsHist_normal_val.SetBinError(
1110 n_par+1, sqrt(
fMinimizer->CovMatrix(n_par, n_par)));
1111 parsHist_normal_val.GetXaxis()->SetBinLabel(
1112 n_par+1, it->second.GetName().c_str());
1127 TMatrixD * cov =
new TMatrixD(total_parameters, total_parameters);
1130 for (
size_t i = 0; i < total_parameters; ++i) {
1131 for (
size_t j = 0; j < total_parameters; ++j) {
1132 double cov_val =
fMinimizer->CovMatrix(i, j);
1133 covHist.SetBinContent(i+1, j+1, cov_val);
1134 corrHist.SetBinContent(i+1, j+1,
fMinimizer->Correlation(i, j));
1147 covHist.SetBinContent(n_par+1, n_par+1,
1166 output_fit_status.Write(
"fit_status");
1167 parsHist.SetFillColor(kRed);
1168 parsHist.SetFillStyle(3144);
1169 parsHist.SetMarkerColor(kRed);
1170 parsHist.SetMarkerStyle(20);
1172 parsHist_normal_val.Write();
1174 TVectorD chi2_syst_out(1);
1175 chi2_syst_out[0] = chi2_syst;
1176 chi2_syst_out.Write(
"chi2_syst");
1177 TVectorD chi2_stat_out(1);
1178 chi2_stat_out[0] = chi2_stat;
1179 chi2_stat_out.Write(
"chi2_stat");
1186 TCanvas cPars(
"cParameters",
"");
1188 parsHist.GetYaxis()->SetTitle(
"Parameter Values");
1189 parsHist.SetTitleSize(.05,
"Y");
1191 TH1D * preFitParsHist = (TH1D*)
fOutputFile.Get(
"preFitPars");
1192 preFitParsHist->SetTitle(
";Parameter;Parameter Value");
1193 preFitParsHist->GetXaxis()->SetTitleOffset(.8);
1194 preFitParsHist->GetYaxis()->SetTitleOffset(.8);
1195 preFitParsHist->SetTitleSize(.05,
"XY");
1196 preFitParsHist->SetFillColor(kBlue);
1197 preFitParsHist->SetFillStyle(3001);
1199 preFitParsHist->SetMaximum(3.);
1200 preFitParsHist->SetMinimum(-1.);
1201 preFitParsHist->Draw(
"pe2");
1202 parsHist.Draw(
"e2 same");
1203 TLine
l(0., 1., parsHist.GetXaxis()->GetBinUpEdge(parsHist.GetNbinsX()), 1.);
1204 l.SetLineColor(kBlack);
1206 TLegend
leg(.15, .65, .45, .85);
1207 leg.AddEntry(preFitParsHist,
"Pre-Fit #pm 1 #sigma",
"pf");
1208 leg.AddEntry(&parsHist,
"Post-Fit #pm 1 #sigma",
"pf");
1211 toyParsHist->SetMarkerStyle(20);
1212 toyParsHist->SetMarkerColor(kBlack);
1213 toyParsHist->Draw(
"same p");
1214 leg.AddEntry(toyParsHist,
"Toy Value",
"p");
1215 toyParsHist->Write();
1216 toyParsHist_normal->Write();
1218 preFitParsHist->SetLineWidth(0);
1219 preFitParsHist->Draw(
"p same");
1220 parsHist.SetLineWidth(0);
1221 parsHist.Draw(
"p same");
1236 covHist.SetTitle(
";Parameter;Parameter");
1237 covHist.SetTitleSize(.05,
"XY");
1238 covHist.GetXaxis()->SetTitleOffset(.8);
1239 covHist.GetYaxis()->SetTitleOffset(.8);
1241 cov->Write(
"CovMatrix");
1242 corrHist.SetTitle(
";Parameter;Parameter");
1243 corrHist.SetTitleSize(.05,
"XY");
1244 corrHist.GetXaxis()->SetTitleOffset(.8);
1245 corrHist.GetYaxis()->SetTitleOffset(.8);
1246 corrHist.SetMaximum(1.);
1247 corrHist.SetMinimum(-1.);
1250 TCanvas cCorr(
"cCorr",
"");
1251 corrHist.Draw(
"colz");
1263 TDirectory * top_dir =
fOutputFile.GetDirectory(
"");
1264 TDirectory * xsec_dir =
fOutputFile.mkdir(
"PostFitXSec");
1268 DoThrows(parsHist_normal_val, cov);
1282 TTree pulls_tree(
"pulls_tree",
"");
1283 std::vector<double> pulls;
1284 pulls_tree.Branch(
"pulls", &pulls);
1285 std::vector<double> vals;
1286 pulls_tree.Branch(
"vals", &vals);
1289 for (
size_t i = 0; i <
fNPulls; ++i) {
1290 std::cout <<
"Fitting for pulls: " << i <<
"/" << fNPulls <<
std::endl;
1292 std::cout <<
"\tGenerating fluctuation" <<
std::endl;
1297 std::cout <<
"Fit successful" <<
std::endl;
1300 for (
size_t j = 0; j < total_parameters; ++j) {
1303 pulls.push_back(pull_val);
1334 TDirectory * top_dir =
fOutputFile.GetDirectory(
"");
1335 TDirectory * xsec_dir =
fOutputFile.mkdir(
"PreFitXSec");
1351 throw std::runtime_error(message);
1364 =
"Error: Need to include systematic term and covariance matrix";
1365 throw std::runtime_error(message);
1368 std::vector<double> vals, init_vals;
1371 for (
size_t i = 0; i < it->second.size(); ++i) {
1372 vals.push_back(it->second.at(i));
1373 init_vals.push_back(it->second.at(i));
1378 vals.push_back(it->second);
1379 init_vals.push_back(it->second);
1382 std::vector<size_t> bins;
1383 std::vector<std::string>
names;
1387 names.push_back(it->first);
1388 init_vals.push_back(it->second.GetValue());
1394 std::vector<double> toy_vals
1396 for (
double & v : toy_vals) {
1400 for (
size_t i = 0; i < vals.size(); ++i) {
1401 std::cout << vals[i] <<
" ";
1402 if (i >= base_par) {
1403 std::cout << names[i - base_par];
1411 bool rethrow =
true;
1413 bool all_pos =
true;
1416 rand[i] =
fRNG.Gaus();
1418 TVectorD rand_times_chol =
fInputChol->GetU()*rand;
1421 double val = rand_times_chol[bins[i]] + init_vals[base_par + i];
1425 std::cout <<
"Rethrowing " << i <<
" " << val <<
1432 std::cout <<
"Rethrowing " << i <<
" " << val <<
1444 rand_times_chol[bins[i]] + init_vals[base_par + i] :
1447 vals.push_back(val);
1454 std::cout <<
"Vals: " << vals.size() <<
" total " <<
1457 for (
size_t i = 0; i < vals.size(); ++i) {
1458 std::cout << vals[i] <<
" ";
1460 std::cout << names[i - base_par];
1479 std::vector<double> results;
1483 for (
size_t i = 0; i < it->second.size(); ++i) {
1484 results.push_back(it->second.at(i));
1489 results.push_back(it->second);
1494 results.push_back(it->second.GetValue());
1502 TDirectory * out = (TDirectory *)
fOutputFile.mkdir(
"Scans");
1506 std::cout <<
"Total parameters " << total_parameters <<
std::endl;
1510 for (
size_t i = 0; i < total_parameters; ++i) {
1515 gr.Write(
fMinimizer->VariableName(i).c_str());
1524 std::vector<std::vector<double>> vals;
1525 TVectorD rand(pars.GetNbinsX());
1527 TDecompChol chol(*cov);
1528 bool success = chol.Decompose();
1537 TTree throws_tree(
"tree",
"");
1538 std::vector<double> throws_branches;
1539 std::vector<TVectorD *> throws_arrays;
1540 std::vector<TVectorD *> throws_xsec_arrays;
1545 for (
size_t i = 0; i < it->second.size(); ++i) {
1546 throws_arrays.push_back(
new TVectorD(
fNThrows));
1547 throws_xsec_arrays.push_back(
new TVectorD(
fNThrows));
1552 throws_arrays.push_back(
new TVectorD(
fNThrows));
1556 throws_arrays.push_back(
new TVectorD(
fNThrows));
1561 TCanvas cPars(
"cParametersThrown",
"");
1565 std::map<int, std::vector<TH1*>> throw_hists;
1568 throw_hists[it->first] = std::vector<TH1*>();
1571 std::map<int, std::vector<TH1*>> truth_throw_hists;
1573 truth_throw_hists[it->first] = std::vector<TH1*>();
1576 std::map<int, std::vector<TH1*>> truth_inc_throw_hists,
1577 truth_xsec_throw_hists;
1580 truth_inc_throw_hists[*it] = std::vector<TH1*>();
1581 truth_xsec_throw_hists[*it] = std::vector<TH1*>();
1591 for (
size_t i = 0; i <
fNThrows; ++i) {
1593 std::cout <<
"Throw " << i <<
"/" << fNThrows <<
std::endl;
1596 vals.push_back(std::vector<double>(pars.GetNbinsX(), 1.));
1598 bool rethrow =
true;
1599 size_t nRethrows = 0;
1601 bool all_pos =
true;
1602 for (
int j = 1; j <= pars.GetNbinsX(); ++j) {
1603 rand[j-1] =
fRNG.Gaus();
1606 TVectorD rand_times_chol = chol.GetU()*rand;
1608 for (
int j = 1; j <= pars.GetNbinsX(); ++j) {
1610 vals.back()[j-1] = pars.GetBinContent(j) + rand_times_chol[j-1];
1615 std::cout <<
"Rethrowing " << j-1 <<
" " << vals.back()[j-1] <<
" " <<
fParLimits[j-1] <<
std::endl;
1619 std::cout <<
"Rethrowing " << j-1 <<
" " << vals.back()[j-1] <<
" " <<
fParLimitsUp[j-1] <<
std::endl;
1628 for (
size_t j = 0; j < vals.back().size(); ++j) {
1629 throws_branches[j] = vals.back()[j];
1630 (*throws_arrays[j])[i] = vals.back()[j];
1639 truth_inc_throw_hists,
1640 truth_xsec_throw_hists);
1642 for(
auto it = truth_xsec_throw_hists.begin();
1643 it != truth_xsec_throw_hists.end(); ++it) {
1644 TH1 * xsec_hist = it->second.back();
1646 for (
int j = 1; j <= xsec_hist->GetNbinsX(); ++j) {
1647 xsec_hist->SetBinContent(j, -1.*log(1. - xsec_hist->GetBinContent(j)));
1649 xsec_hist->Scale(1.E27*39.948/(1.4 * 6.022E23));
1650 for (
int j = 1; j <= xsec_hist->GetNbinsX(); ++j) {
1652 double bethe_val =
BetheBloch(xsec_hist->GetBinCenter(j), 139.57);
1654 xsec_hist->SetBinContent(i, (bethe_val*
1655 xsec_hist->GetBinContent(j)/
1656 xsec_hist->GetBinWidth(j)));
1660 for (
int j = 1; j <= xsec_hist->GetNbinsX(); ++j) {
1661 xsec_hist->SetBinContent(j, -1.*log(1. - xsec_hist->GetBinContent(j)));
1663 xsec_hist->Scale(1.E27*39.948/(
fPitch * 1.4 * 6.022E23));
1666 for (
int j = 1; j <= xsec_hist->GetNbinsX(); ++j) {
1667 xsec_hist->SetBinContent(j, -1.*log(1. - xsec_hist->GetBinContent(j)));
1669 xsec_hist->Scale(1.E27/ (
fPitch * 1.4 * 6.022E23 / 39.948 ));
1671 for (
int j = 1; j <= xsec_hist->GetNbinsX(); ++j) {
1672 (*throws_xsec_arrays[xsec_bin])[i] = xsec_hist->GetBinContent(j);
1678 throws_tree.Write();
1679 for (
size_t i = 0; i < throws_arrays.size(); ++i) {
1681 throws_arrays[i]->Write(name.c_str());
1683 for (
size_t i = 0; i < throws_xsec_arrays.size(); ++i) {
1685 throws_xsec_arrays[i]->Write(name.c_str());
1689 truth_inc_throw_hists, truth_xsec_throw_hists);
1694 TDirectory * shift_dir =
fOutputFile.mkdir((prefit ?
"PreFit1DShifts" :
"1DShifts"));
1698 for (
int i = 1; i <= pars.GetNbinsX(); ++i) {
1700 std::string par_name = pars.GetXaxis()->GetBinLabel(i);
1702 std::vector<double> vals;
1703 if (pars.GetBinError(i) < 1.e-9)
continue;
1705 for (
int j = 1; j <= pars.GetNbinsX(); ++j) {
1707 vals.push_back(pars.GetBinContent(j) + pars.GetBinError(i));
1710 vals.push_back(pars.GetBinContent(j));
1717 TDirectory * plus_dir = shift_dir->mkdir(dir_name.c_str());
1718 TDirectory * xsec_dir = plus_dir->mkdir(
"XSec");
1724 for (
int j = 1; j <= pars.GetNbinsX(); ++j) {
1726 vals.push_back(pars.GetBinContent(j) - pars.GetBinError(i));
1729 vals.push_back(pars.GetBinContent(j));
1735 dir_name = par_name +
"_MinusSigma";
1736 TDirectory * minus_dir = shift_dir->mkdir(dir_name.c_str());
1737 xsec_dir = minus_dir->mkdir(
"XSec");
1745 [&](
double const * coeffs) {
1753 size_t par_position = 0;
1756 for (
size_t i = 0; i < it->second.size(); ++i) {
1757 it->second.at(i) = coeffs[par_position];
1763 it->second = coeffs[par_position];
1769 it->second.SetValue(coeffs[par_position]);
1793 for (
size_t i = 0; i < it->second.size(); ++i) {
1794 for (
size_t j = 0; j < it->second[i].size(); ++j) {
1795 it->second[i][j].ScaleToDataMC();
1802 double total_varied_flux = 0.;
1803 double total_nominal_flux = 0.;
1810 int sample_ID = it->first;
1811 std::vector<std::vector<ThinSliceSample>> & samples_2D
1813 for (
size_t i = 0; i < samples_2D.size(); ++i) {
1814 std::vector<ThinSliceSample> & samples = samples_2D[i];
1815 for (
size_t j = 0; j < samples.size(); ++j) {
1818 if (flux_type == 1) {
1835 double total_flux_factor = (total_nominal_flux/total_varied_flux);
1837 double nominal_primary = 0., varied_primary = 0.;
1838 for (
size_t i = 0; i < nominal_flux.size(); ++i) {
1839 nominal_primary += nominal_flux[i];
1840 varied_primary += varied_flux[i];
1843 std::vector<double> flux_factor = nominal_flux;
1844 for (
size_t i = 0; i < flux_factor.size(); ++i) {
1845 flux_factor[i] = (nominal_flux[i] > 1.e-7 ?
1846 flux_factor[i] / varied_flux[i] :
1847 0.)*(varied_primary/nominal_primary);
1852 for (
size_t i = 0; i < it->second.size(); ++i) {
1853 for (
size_t j = 0; j < it->second[i].size(); ++j) {
1854 int flux_type = it->second[i][j].GetFluxType();
1860 it->second[i][j].SetFactorAndScale(
1861 total_flux_factor*(flux_type == 1 ? flux_factor[i] : 1.));
1869 for (
size_t i = 0; i < it->second.size(); ++i) {
1870 for (
size_t j = 0; j < it->second[i].size(); ++j) {
1871 int flux_type = it->second[i][j].GetFluxType();
1876 it->second[i][j].SetFactorAndScale(
1877 total_flux_factor*(flux_type == 1 ? flux_factor[i] : 1.));
1884 std::pair<double, size_t> chi2_points
1895 return (chi2_points.first + syst_chi2 );
1905 char const* fhicl_env =
getenv(
"FHICL_FILE_PATH");
1909 std::cerr <<
"Expected environment variable FHICL_FILE_PATH is missing " <<
1910 "or empty: using \".\"\n";
1935 fSampleSets = pset.
get<std::vector<fhicl::ParameterSet>>(
"Samples");
1936 std::vector<std::pair<int, std::string>> temp_vec
1937 = pset.
get<std::vector<std::pair<int, std::string>>>(
"FluxTypes");
1938 fFluxTypes = std::map<int, std::string>(temp_vec.begin(), temp_vec.end());
1942 for (
size_t i = 0; i < temp_vec.size() - 1; ++i) {
1956 fPlotStyle = pset.
get<std::vector<std::pair<int,int>>>(
"PlotStyle");
1962 fPitch = fAnalysisOptions.get<
double>(
"WirePitch");
1964 fMultinomial = fAnalysisOptions.get<
bool>(
"Multinomial",
true);
1977 if (fFixVariables) {
1978 std::vector<std::pair<std::string, double>> temp_vec
1979 = pset.
get<std::vector<std::pair<std::string, double>>>(
"SystsToFix");
1980 fSystsToFix = std::map<std::string, double>(temp_vec.begin(), temp_vec.end());
1993 fRNG = TRandom3(pset.
get<
int>(
"RNGSeed", 0));
2001 std::vector<fhicl::ParameterSet> par_vec
2002 = pset.
get<std::vector<fhicl::ParameterSet>>(
"Systematics");
2003 for (
size_t i = 0; i < par_vec.size(); ++i) {
2010 std::vector<std::pair<std::string, int>> temp_vec
2011 = pset.
get<std::vector<std::pair<std::string, int>>>(
"CovarianceBins");
2013 = std::map<std::string, size_t>(temp_vec.begin(), temp_vec.end());
2019 if (!fCovMatrix->IsSymmetric()) {
2021 message +=
"Error. Input covariance matrix ";
2022 message +=
"is not symmetric";
2023 throw std::runtime_error(message);
2029 fCovMatrix->Invert();
2036 for (
size_t i = 0; i < it->second.size(); ++i) {
2037 for (
size_t j = 0; j < it->second[i].size(); ++j) {
2038 it->second[i][j].SetBestFit();
2046 std::map<
int, std::vector<TH1*>> & throw_hists,
2047 std::map<
int, std::vector<TH1*>> & truth_throw_hists,
2048 std::map<
int, std::vector<TH1*>> & truth_inc_hists,
2049 std::map<
int, std::vector<TH1*>> & truth_xsec_hists) {
2050 std::map<int, TH1*> data_hists
2058 for (
auto it = data_hists.begin(); it != data_hists.end(); ++it ) {
2074 nBins += it->second->GetNbinsX();
2077 TH2D selection_cov(
"SelectionCov",
"", nBins, 0, nBins, nBins, 0, nBins);
2080 std::map<int, size_t> sample_bins;
2082 nBins += it->second[0].size();
2083 sample_bins[it->first] = it->second[0].size();
2087 std::map<int, std::vector<double>> best_fit_errs;
2092 best_fit_errs[it->first]
2093 = std::vector<double>(sample_bins[it->first], 0.);
2105 TH2D interaction_cov(
"interaction_cov",
"", nBins, 0, nBins, nBins, 0, nBins);
2106 std::map<int, std::vector<double>> best_fit_inc_truth;
2107 std::map<int, std::vector<double>> best_fit_xsec_truth;
2108 std::map<int, std::vector<double>> best_fit_inc_errs;
2109 std::map<int, std::vector<double>> best_fit_xsec_errs;
2112 std::map<int, size_t> xsec_bins;
2115 nBins += it->second->GetNbinsX();
2116 xsec_bins[
s] = it->second->GetNbinsX();
2118 best_fit_inc_truth[
s] = std::vector<double>(xsec_bins[
s], 0.);
2119 best_fit_xsec_truth[
s] = std::vector<double>(xsec_bins[
s], 0.);
2120 best_fit_inc_errs[
s] = std::vector<double>(xsec_bins[
s], 0.);
2121 best_fit_xsec_errs[
s] = std::vector<double>(xsec_bins[
s], 0.);
2123 for (
size_t i = 0; i < xsec_bins[
s]; ++i) {
2124 best_fit_inc_truth[
s][i] = it->second->GetBinContent(i+1);
2130 TH2D xsec_cov(
"xsec_cov",
"", nBins, 0, nBins, nBins, 0, nBins);
2131 TH2D xsec_corr(
"xsec_corr",
"", nBins, 0, nBins, nBins, 0, nBins);
2132 xsec_cov.SetTitle(
";Cross Section Bin;Cross section Bin");
2133 xsec_cov.SetTitleSize(.05,
"XY");
2134 xsec_cov.GetXaxis()->SetTitleOffset(.8);
2135 xsec_corr.SetTitle(
";Cross Section Bin;Cross section Bin");
2136 xsec_corr.SetTitleSize(.05,
"XY");
2137 xsec_corr.GetXaxis()->SetTitleOffset(.8);
2138 xsec_corr.SetMaximum(1.);
2139 xsec_corr.SetMinimum(-1.);
2140 TMatrixD xsec_cov_matrix(nBins, nBins);
2142 std::map<int, std::vector<double>> mean_xsecs;
2144 for (
auto it = truth_xsec_hists.begin(); it != truth_xsec_hists.end(); ++it) {
2145 std::vector<TH1 *> xsec_hists_i = it->second;
2147 mean_xsecs[it->first] = std::vector<double>(xsec_bins[it->first], 0.);
2148 for (
size_t i = 0; i < xsec_bins[it->first]; ++i) {
2149 mean_xsecs[it->first][i] += xsec_hists_i[
z]->GetBinContent(i+1)/
fNThrows;
2158 TH1D * best_fit = it->second;
2160 std::vector<TH1*> & temp_throws = throw_hists[
selection_ID];
2161 for (
int i = 1; i <= best_fit->GetNbinsX(); ++i) {
2162 double best_fit_val_i = best_fit->GetBinContent(i);
2167 TH1D * best_fit_2 = it2->second;
2168 int selection_ID_2 = it2->first;
2169 std::vector<TH1*> & temp_throws_2 = throw_hists[selection_ID_2];
2170 for (
int j = 1; j <= best_fit_2->GetNbinsX(); ++j) {
2171 double best_fit_val_j = best_fit_2->GetBinContent(j);
2172 double val = (best_fit_val_i - temp_throws[
z]->GetBinContent(i))*
2173 (best_fit_val_j - temp_throws_2[
z]->GetBinContent(j));
2174 selection_cov.SetBinContent(
2175 bin_i, bin_j, (val/temp_throws.size() +
2176 selection_cov.GetBinContent(bin_i, bin_j)));
2186 std::vector<TH1 *> throw_hists_i = truth_throw_hists[it->first];
2188 for (
size_t i = 0; i < sample_bins[it->first]; ++i) {
2193 std::vector<TH1 *> throw_hists_j = truth_throw_hists[it2->first];
2194 for (
size_t j = 0; j < sample_bins[it2->first]; ++j) {
2198 = (throw_hists_i[
z]->GetBinContent(i+1) - best_fit_val_i)*
2199 (throw_hists_j[
z]->GetBinContent(j+1) - best_fit_val_j);
2200 interaction_cov.SetBinContent(
2202 (interaction_cov.GetBinContent(bin_i, bin_j) +
2203 val/throw_hists_i.size()));
2204 if (bin_i == bin_j && (
z == fNThrows - 1)) {
2205 best_fit_errs[it->first][i]
2206 = sqrt(interaction_cov.GetBinContent(bin_i, bin_j));
2220 for (
auto it = truth_inc_hists.begin(); it != truth_inc_hists.end(); ++it) {
2221 std::vector<TH1 *> xsec_hists_i = truth_xsec_hists[it->first];
2222 for (
size_t i = 0; i < xsec_bins[it->first]; ++i) {
2224 double best_fit_xsec_i = best_fit_xsec_truth[it->first][i];
2227 for (
auto it2 = truth_inc_hists.begin(); it2 != truth_inc_hists.end();
2229 std::vector<TH1 *> xsec_hists_j = truth_xsec_hists[it2->first];
2230 for (
size_t j = 0; j < xsec_bins[it2->first]; ++j) {
2232 double best_fit_xsec_j = best_fit_xsec_truth[it2->first][j];
2235 = (xsec_hists_i[
z]->GetBinContent(i+1) - best_fit_xsec_i)*
2236 (xsec_hists_j[
z]->GetBinContent(j+1) - best_fit_xsec_j);
2237 xsec_cov.SetBinContent(
2239 (xsec_cov.GetBinContent(bin_i, bin_j) +
2241 if (bin_i == bin_j && (
z == fNThrows - 1)) {
2242 best_fit_xsec_errs[it->first][i]
2243 = sqrt(xsec_cov.GetBinContent(bin_i, bin_j));
2253 for (
int i = 0; i <
nBins; ++i) {
2254 for (
int j = 0; j <
nBins; ++j) {
2255 xsec_cov_matrix[i][j] = xsec_cov.GetBinContent(i+1, j+1);
2257 xsec_cov.GetBinContent(i+1, j+1)/
2258 sqrt(xsec_cov.GetBinContent(i+1, i+1)*
2259 xsec_cov.GetBinContent(j+1, j+1));
2260 xsec_corr.SetBinContent(i+1, j+1, corr_val);
2263 xsec_cov_matrix.Invert();
2267 selection_cov.Write();
2268 interaction_cov.Write();
2272 TCanvas cXSecCorr(
"cXSecCorr",
"");
2273 xsec_corr.Draw(
"colz");
2278 double nominal_xsec_chi2 = 0.;
2279 double fake_xsec_chi2 = 0.;
2281 for (
auto it = best_fit_xsec_truth.
begin(); it != best_fit_xsec_truth.end();
2283 for (
size_t i = 0; i < it->second.size(); ++i) {
2284 double measured_val_i = it->second[i];
2285 double mc_val_i =
fNominalXSecs[it->first]->GetBinContent(i+1);
2290 for (
auto it2 = best_fit_xsec_truth.
begin();
2291 it2 != best_fit_xsec_truth.end();
2293 for (
size_t j = 0; j < it2->second.size(); ++j) {
2294 double measured_val_j = it2->second[j];
2295 double mc_val_j =
fNominalXSecs[it2->first]->GetBinContent(j+1);
2299 nominal_xsec_chi2 += ((measured_val_i - mc_val_i)*
2300 xsec_cov_matrix[bin_i][bin_j]*
2301 (measured_val_j - mc_val_j));
2303 fake_xsec_chi2 += ((measured_val_i - fake_val_i)*
2304 xsec_cov_matrix[bin_i][bin_j]*
2305 (measured_val_j - fake_val_j));
2317 for (
auto it = data_hists.begin(); it != data_hists.end(); ++it) {
2319 std::vector<TH1*>
hists = throw_hists.at(selection_ID);
2323 TCanvas cThrow(canvas_name.c_str(),
"");
2327 auto data_hist = it->second;
2328 std::vector<double> xs, xs_width;
2329 std::vector<double>
ys, errs;
2335 sqrt(selection_cov.GetBinContent(bin_count+i, bin_count+i)));
2336 xs.push_back(data_hist->GetBinCenter(i));
2337 xs_width.push_back(data_hist->GetBinWidth(i)/2.);
2340 TGraphAsymmErrors throw_gr(data_hist->GetNbinsX(),
2342 &xs_width[0], &xs_width[0], &errs[0], &errs[0]);
2345 throw_gr.GetXaxis()->SetTitle(data_hist->GetXaxis()->GetTitle());
2346 throw_gr.SetFillStyle(3144);
2347 throw_gr.SetFillColor(kRed);
2349 throw_gr.Draw(
"same a2");
2350 data_hist->Draw(
"same e1");
2354 bin_count += data_hist->GetNbinsX();
2358 for (
auto it = truth_throw_hists.begin(); it != truth_throw_hists.end(); ++it) {
2359 int sample_ID = it->first;
2361 std::vector<double> xs, xs_width;
2362 for (
size_t i = 0; i < sample_bins[it->first]; ++i) {
2363 xs.push_back(i + 0.5);
2364 xs_width.push_back(.5);
2368 TH1D temp_nominal(name.c_str(),
"", xs.size(), 0, xs.size());
2370 TH1D
dummy(dummy_name.c_str(),
"", xs.size(), 0, xs.size());
2372 dummy.GetXaxis()->SetBinLabel(1,
"Underflow");
2373 dummy.GetXaxis()->SetBinLabel(
dummy.GetNbinsX(),
"Overflow");
2374 for (
int i = 2; i <
dummy.GetNbinsX(); ++i) {
2375 std::ostringstream low_stream, high_stream;
2376 low_stream.precision(2);
2377 high_stream.precision(2);
2378 low_stream << std::fixed <<
2379 fSamples[sample_ID][0][i-1].RangeLowEnd();
2382 fSamples[sample_ID][0][i-1].RangeHighEnd();
2385 label += high_stream.str();
2390 dummy.GetXaxis()->SetBinLabel(i, label.c_str());
2394 dummy.GetXaxis()->SetBinLabel(1,
"");
2398 std::vector<std::vector<ThinSliceSample>> & samples_vec_2D
2400 for (
size_t i = 0; i < samples_vec_2D.size(); ++i) {
2401 for (
size_t j = 0; j < samples_vec_2D[i].size(); ++j) {
2402 temp_nominal.AddBinContent(j+1, samples_vec_2D[i][j].GetNominalFlux());
2407 for (
size_t i = 0; i < sample_bins[it->first]; ++i) {
2411 if (temp_nominal.GetBinContent(i+1) >
max)
2412 max = temp_nominal.GetBinContent(i+1);
2417 TCanvas cThrow(canvas_name.c_str(),
"");
2419 TGraphAsymmErrors throw_gr(xs.size(),
2421 &xs_width[0], &xs_width[0],
2422 &best_fit_errs[it->first][0],
2423 &best_fit_errs[it->first][0]);
2424 throw_gr.SetFillStyle(3144);
2425 throw_gr.SetFillColor(kRed);
2426 throw_gr.SetMinimum(0.);
2427 throw_gr.SetMaximum(1.5*max);
2428 dummy.SetMaximum(1.5*max);
2431 throw_gr.Draw(
"same 2");
2434 temp_nominal.SetMarkerColor(kBlue);
2435 temp_nominal.SetMarkerStyle(20);
2436 temp_nominal.Draw(
"same p");
2439 leg.AddEntry(&throw_gr,
"Throws",
"lpf");
2440 leg.AddEntry(&temp_nominal,
"Nominal",
"p");
2443 name =
"hVaried" +
fSamples[sample_ID][0][0].GetName();
2444 TH1D * temp_varied = (TH1D*)temp_nominal.Clone(name.c_str());
2445 for (
size_t i = 0; i < xs.size(); ++i) {
2446 temp_varied->SetBinContent(
2449 temp_varied->SetMarkerColor(kBlack);
2450 temp_varied->SetMarkerStyle(20);
2451 temp_varied->Draw(
"same p");
2452 leg.AddEntry(temp_varied,
"Fake Data",
"p");
2458 bin_count += xs.size();
2461 for (
auto it = best_fit_xsec_truth.begin(); it != best_fit_xsec_truth.end();
2463 int sample_ID = it->first;
2465 std::vector<double> xs, xs_width;
2466 for (
size_t i = 0; i < xsec_bins[sample_ID]; ++i) {
2467 xs.push_back(i + 0.5);
2468 xs_width.push_back(.5);
2474 TCanvas cThrow(canvas_name.c_str(),
"");
2478 TH1D
dummy(dummy_name.c_str(),
"", xs.size(), 0, xs.size());
2479 for (
int i = 1; i <=
dummy.GetNbinsX(); ++i) {
2480 std::ostringstream low_stream, high_stream;
2481 low_stream.precision(2);
2482 high_stream.precision(2);
2483 low_stream << std::fixed <<
2484 fSamples[sample_ID][0][i].RangeLowEnd();
2487 fSamples[sample_ID][0][i].RangeHighEnd();
2490 label += high_stream.str();
2495 dummy.GetXaxis()->SetBinLabel(i, label.c_str());
2498 TGraphAsymmErrors throw_gr(xs.size(),
2499 &xs[0], &best_fit_xsec_truth[it->first][0],
2500 &xs_width[0], &xs_width[0],
2501 &best_fit_xsec_errs[it->first][0],
2502 &best_fit_xsec_errs[it->first][0]);
2505 for (
size_t i = 0; i < best_fit_xsec_truth[it->first].size(); ++i) {
2506 if ((best_fit_xsec_truth[it->first][i] +
2507 best_fit_xsec_errs[it->first][0]) >
max) {
2508 max = (best_fit_xsec_truth[it->first][i] +
2509 best_fit_xsec_errs[it->first][0]);
2514 throw_gr.SetMarkerStyle(20);
2515 throw_gr.SetMinimum(0.);
2516 dummy.SetMaximum(1.5*max);
2517 dummy.SetMinimum(0.);
2519 dummy.GetXaxis()->SetTitle(
"Kinetic Energy (MeV)");
2520 dummy.GetYaxis()->SetTitle(
"#sigma (mb)");
2522 throw_gr.Draw(
"same 2");
2526 std::vector<double> nominal_xsec_vals;
2527 for (
size_t i = 0; i < xs.size(); ++i) {
2528 nominal_xsec_vals.push_back(
2531 TGraph nominal_gr(xs.size(), &xs[0], &nominal_xsec_vals[0]);
2532 nominal_gr.SetMarkerColor(kBlue);
2533 nominal_gr.SetMarkerStyle(20);
2534 nominal_gr.Draw(
"same p");
2537 leg.AddEntry(&throw_gr,
"Measured",
"lpf");
2539 leg.AddEntry(&nominal_gr,
"Nominal",
"p");
2543 std::vector<double> fake_xsec_vals;
2545 for (
size_t i = 0; i < xs.size(); ++i) {
2550 fake_xsec_vals.push_back(
2554 TGraph * fake_gr =
new TGraph(xs.size(), &xs[0], &fake_xsec_vals[0]);
2556 fake_gr->SetMarkerColor(kRed);
2557 fake_gr->SetMarkerStyle(20);
2558 fake_gr->Draw(
"same p");
2559 leg.AddEntry(fake_gr,
"Fake Data",
"p");
2563 chi2_str.Form(
"Nominal #chi^{2} = %.2f", nominal_xsec_chi2);
2564 leg.AddEntry((TObject*)0x0, chi2_str,
"");
2572 TString fake_chi2_str;
2573 fake_chi2_str.Form(
"Fake Data #chi^{2} = %.2f", fake_xsec_chi2);
2574 leg.AddEntry((TObject*)0x0, fake_chi2_str,
"");
2579 throw_gr.Write(gr_name.c_str());
2582 TVectorD fake_chi2_out(1);
2583 fake_chi2_out[0] = fake_xsec_chi2;
2584 fake_chi2_out.Write(
"FakeDataChi2");
2586 TVectorD nominal_chi2_out(1);
2587 nominal_chi2_out[0] = nominal_xsec_chi2;
2588 nominal_chi2_out.Write(
"NominalChi2");
2592 std::map<
int, std::vector<TH1*>> & throw_hists,
2593 std::map<
int, std::vector<TH1*>> & throw_inc_hists,
2594 std::map<
int, std::vector<TH1*>> & throw_xsec_hists) {
2598 std::vector<std::vector<ThinSliceSample>> & samples_vec_2D = it->second;
2599 size_t nBins = samples_vec_2D[0].size();
2602 TH1D * temp_hist =
new TH1D(name.c_str(),
"",
nBins, 0,
nBins);
2603 for (
size_t i = 0; i < samples_vec_2D.size(); ++i) {
2604 std::vector<ThinSliceSample> & samples_vec = samples_vec_2D[i];
2605 for (
size_t j = 0; j < it->second[i].size(); ++j) {
2606 temp_hist->AddBinContent(j+1, samples_vec[j].GetVariedFlux());
2609 throw_hists[it->first].push_back(temp_hist);
2612 for (
auto it = throw_inc_hists.begin(); it != throw_inc_hists.end(); ++it) {
2617 name +=
"IncidentThrow" +
2619 TH1D * temp_inc_hist =
new TH1D(name.c_str(),
"", bins.size() - 1, &bins[0]);
2622 name = samples_vec_2D[0][0].GetName();
2623 name +=
"XSecThrow" +
2625 TH1D * temp_xsec_hist =
new TH1D(name.c_str(),
"", bins.size() - 1,
2628 auto & incident_vec_2D =
fSamples[i_s];
2629 for (
size_t i = 0; i < incident_vec_2D.size(); ++i) {
2630 for (
size_t j = 0; j < incident_vec_2D[i].size(); ++j) {
2632 incident_vec_2D[i][j].FillESliceHist(*temp_inc_hist);
2635 incident_vec_2D[i][j].FillHistFromIncidentEnergies(*temp_inc_hist);
2640 throw_inc_hists[
s].push_back(temp_inc_hist);
2642 for (
int i = 1; i <= temp_xsec_hist->GetNbinsX(); ++i) {
2643 temp_xsec_hist->SetBinContent(
2644 i, throw_hists[s].back()->GetBinContent(i+1));
2646 temp_xsec_hist->Divide(temp_inc_hist);
2647 throw_xsec_hists[
s].push_back(temp_xsec_hist);
2658 for (
size_t i = 0; i < it->second.size(); ++i) {
2659 for (
size_t j = 0; j < it->second[i].size(); ++j) {
2660 std::cout <<
"Fake scale " << it->first <<
" " << i <<
" " << j <<
" " <<
fFakeDataScales[it->first][j] <<
std::endl;
2667 std::map<int, TH1D*> fake_data_totals;
2674 samples_vec_2D[0][1].GetName() +
"XSec";
2675 TH1D * temp_xsec =
new TH1D(xsec_name.c_str(),
"",
2677 for (
size_t i = 0; i < samples_vec_2D.size(); ++i) {
2678 for (
size_t j = 1; j < samples_vec_2D[i].size() - 1; ++j) {
2679 temp_xsec->AddBinContent(j, samples_vec_2D[i][j].GetVariedFlux());
2686 samples_vec_2D[0][1].GetName() +
"Inc";
2687 TH1D * temp_inc =
new TH1D(inc_name.c_str(),
"",
fSignalBins[
s].size() - 1,
2692 for (
size_t j = 0; j < vec_2D.size(); ++j) {
2693 auto & samples_vec = vec_2D[j];
2694 for (
size_t k = 0;
k < samples_vec.size(); ++
k) {
2696 samples_vec[
k].FillESliceHist(*temp_inc);
2699 samples_vec[
k].FillHistFromIncidentEnergies(*temp_inc);
2706 samples_vec_2D[0][1].GetName() +
"Tot";
2707 fake_data_totals[
s] = (TH1D*)temp_xsec->Clone(tot_name.c_str());
2708 temp_xsec->Divide(temp_inc);
2711 for (
int i = 1; i <= temp_xsec->GetNbinsX(); ++i) {
2712 temp_xsec->SetBinContent(i, -1.*log(1. - temp_xsec->GetBinContent(i)));
2714 temp_xsec->Scale(1.E27*39.948/(1.4 * 6.022E23));
2715 for (
int i = 1; i <= temp_xsec->GetNbinsX(); ++i) {
2717 double bethe_val =
BetheBloch(temp_xsec->GetBinCenter(i), 139.57);
2719 temp_xsec->SetBinContent(i, (bethe_val*
2720 temp_xsec->GetBinContent(i)/
2721 temp_xsec->GetBinWidth(i)));
2725 for (
int i = 1; i <= temp_xsec->GetNbinsX(); ++i) {
2726 temp_xsec->SetBinContent(i, -1.*log(1. - temp_xsec->GetBinContent(i)));
2728 temp_xsec->Scale(1.E27*39.948/(
fPitch * 1.4 * 6.022E23));
2731 for (
int i = 1; i <= temp_xsec->GetNbinsX(); ++i) {
2732 temp_xsec->SetBinContent(i, -1.*log(1. - temp_xsec->GetBinContent(i)));
2734 temp_xsec->Scale(1.E27/ (
fPitch * 1.4 * 6.022E23 / 39.948 ));
2741 fake_data_totals[
s]->SetDirectory(0);
2750 TDirectory * out = (TDirectory *)
fOutputFile.mkdir(
"FakeDataXSecs");
2753 it->second->Write();
2755 fake_data_totals[it->first]->Write();
2765 double val_1 = it->second.GetValue();
2766 double val_2 = it2->second.GetValue();
2767 double central_1 = it->second.GetCentral();
2768 double central_2 = it2->second.GetCentral();
2772 result += (val_1 - central_1)*(val_2 - central_2)*
2773 (*fCovMatrix)[bin_1][bin_2];
2781 for (
size_t i = 0; i < it->second.size(); ++i) {
2782 branches.push_back(0.);
2789 branches.push_back(0.);
2795 branches.push_back(0.);
2796 tree.Branch(it->second.GetName().c_str(), &branches.back());
2804 for (
size_t i = 0; i < it->second.size()-1; ++i) {
2805 result +=
std::pow((it->second[i] - it->second[i+1]), 2);
std::vector< ThinSliceEvent > fEvents
virtual void BuildDataHists(TTree *tree, ThinSliceDataSet &data_set, double &flux, int split_val=0)=0
std::vector< int > fMeasurementSamples
std::string fDataFileName
size_t fTotalFluxParameters
std::pair< int, int > GetColorAndStyle(size_t i, const std::vector< std::pair< int, int >> &plot_style)
std::map< int, TH1 * > fBestFitXSecs
std::map< int, std::vector< std::vector< ThinSliceSample > > > fSamples
virtual void BuildMCSamples(const std::vector< ThinSliceEvent > &events, std::map< int, std::vector< std::vector< ThinSliceSample >>> &samples, const std::map< int, bool > &signal_sample_checks, std::map< int, double > &nominal_fluxes, std::map< int, std::vector< std::vector< double >>> &fluxes_by_sample, std::vector< double > &beam_energy_bins)=0
void CompareDataMC(std::map< int, std::vector< std::vector< ThinSliceSample >>> &samples, ThinSliceDataSet &data_set, TFile &output_file, std::vector< std::pair< int, int >> plot_style, int nPars, TDirectory *plot_dir, bool plot_rebinned=false, bool post_fit=false)
virtual void RefillMCSamples(const std::vector< ThinSliceEvent > &events, std::map< int, std::vector< std::vector< ThinSliceSample >>> &samples, const std::map< int, bool > &signal_sample_checks, std::vector< double > &beam_energy_bins, const std::map< int, std::vector< double >> &signal_pars, const std::map< int, double > &flux_pars, const std::map< std::string, ThinSliceSystematic > &syst_pars, bool fit_under_over, bool fill_incident=false)=0
std::map< int, TH1 * > fFakeDataXSecs
void Configure(std::string fcl_file)
virtual void FillMCEvents(TTree *tree, std::vector< ThinSliceEvent > &events, std::vector< ThinSliceEvent > &fake_data_events, int &split_val, const bool &do_split)=0
double CalcChi2SystTerm()
std::vector< double > fTrueIncidentBins
std::map< int, std::vector< int > > fFluxParsToSamples
static ParameterSet make(intermediate_table const &tbl)
std::map< std::string, ThinSliceSystematic > fSystParameters
std::vector< double > fBeamEnergyBins
void MakeThrowsTree(TTree &tree, std::vector< double > &branches)
std::map< int, double > fFluxParameters
std::vector< int > fIncidentSamples
TMatrixD * fCovMatrixDisplay
std::vector< std::pair< int, int > > fPlotStyle
void GetCurrentTruthHists(std::map< int, std::vector< TH1 * >> &throw_hists, std::map< int, std::vector< TH1 * >> &throw_inc_hists, std::map< int, std::vector< TH1 * >> &throw_xsec_hists)
std::map< int, TH1D * > fBestFitSelectionHists
std::map< int, TH1 * > fNominalXSecs
std::vector< double > fIncidentRecoBins
std::vector< ThinSliceEvent > fFakeDataEvents
std::vector< double > fParLimitsUp
std::map< std::string, double > fToyValues
std::map< int, double > fBestFitFluxPars
ROOT::Math::Functor fFitFunction
std::map< int, TH1 * > & GetSelectionHists()
std::map< int, std::vector< std::vector< double > > > fFakeFluxesBySample
std::map< int, double > fFakeFluxes
std::vector< fhicl::ParameterSet > fSampleSets
const double & GetVariedFlux() const
std::map< int, std::vector< double > > fBestFitTruthVals
std::map< int, TH1 * > fBestFitIncs
virtual std::pair< double, size_t > CalculateChi2(std::map< int, std::vector< std::vector< ThinSliceSample >>> &samples, ThinSliceDataSet &data_set)=0
std::map< int, std::vector< double > > fBestFitSignalPars
std::map< std::string, ThinSliceSystematic > fBestFitSystPars
std::map< int, std::vector< std::string > > fSignalParameterNames
std::unique_ptr< ROOT::Math::Minimizer > fMinimizer
std::map< std::string, size_t > fCovarianceBins
void PrintAvailableDrivers() const
std::map< int, std::vector< double > > fSignalParameters
virtual void SetupSysts(const std::vector< ThinSliceEvent > &events, std::map< int, std::vector< std::vector< ThinSliceSample >>> &samples, const std::map< int, bool > &signal_sample_checks, std::vector< double > &beam_energy_bins, const std::map< std::string, ThinSliceSystematic > &pars, TFile &output_file)=0
std::string fFakeDataRoutine
std::string getenv(std::string const &name)
T get(std::string const &key) const
size_t fTotalSystParameters
std::map< int, std::vector< std::vector< ThinSliceSample > > > fFakeSamples
std::map< int, TH1 * > fFakeDataIncs
void FillHistsFromSamples(const std::map< int, std::vector< std::vector< ThinSliceSample >>> &samples, double &flux)
PDSPThinSliceFitter(std::string fcl_file, std::string output_file)
void GenerateStatFluctuation()
std::map< int, TH1 * > & GetRebinnedSelectionHists()
static ThinSliceDriverRegistry * Instance()
std::map< int, TH1 * > fNominalIncs
std::map< int, std::vector< std::vector< double > > > fFluxesBySample
static int max(int a, int b)
virtual void GetCurrentHists(std::map< int, std::vector< std::vector< ThinSliceSample >>> &samples, ThinSliceDataSet &data_set, std::map< int, std::vector< TH1 * >> &hists, bool plot_rebinned)=0
double BetheBloch(double energy, double mass)
std::map< int, std::vector< double > > fSignalBins
void PlotThrows(std::map< int, std::vector< TH1 * >> &throw_hists, std::map< int, std::vector< TH1 * >> &truth_throw_hists, std::map< int, std::vector< TH1 * >> &truth_inc_hists, std::map< int, std::vector< TH1 * >> &truth_xsec_hists)
virtual void WrapUpSysts(TFile &output_file)=0
std::vector< double > fMinimizerInitVals
std::map< int, std::string > fFluxParameterNames
const int & GetFluxType() const
bool fFillIncidentInFunction
void InitializeMCSamples()
void CompareDataMC(std::string extra_name, TDirectory *xsec_dir, TDirectory *plot_dir, bool post_fit=false)
std::string & GetSelectionName(int id)
std::vector< fhicl::ParameterSet > fSelectionSets
cet::LibraryManager dummy("noplugin")
std::vector< double > GetBestFitParsVec()
std::map< int, std::vector< double > > fFakeDataScales
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
std::string PreciseToString(const double val, const int n=2)
std::map< std::string, double > fSystsToFix
std::map< int, bool > fIsSignalSample
size_t fTotalSignalParameters
std::map< int, std::string > fFluxTypes
void BuildFakeDataXSecs(bool use_scales=true)
static std::vector< std::string > const names
ThinSliceDriver * GetDriver(const std::string &name, const fhicl::ParameterSet &extra_options)
static constexpr double ys
std::vector< double > fParLimits
void Do1DShifts(const TH1D &pars, bool prefit=false)
void DoThrows(const TH1D &pars, const TMatrixD *cov)
fhicl::ParameterSet fAnalysisOptions
ThinSliceDataSet fDataSet
std::string to_string(ModuleType const mt)
ThinSliceDriver * fThinSliceDriver
cet::coded_exception< error, detail::translate > exception
QTextStream & endl(QTextStream &s)
virtual void BuildFakeData(TTree *tree, std::map< int, std::vector< std::vector< ThinSliceSample >>> &samples, const std::map< int, bool > &signal_sample_checks, ThinSliceDataSet &data_set, double &flux, std::map< int, std::vector< double >> &sample_scales, std::vector< double > &beam_energy_bins, int split_val=0)=0
std::map< int, double > fNominalFluxes