4 #include "TGraphAsymmErrors.h" 9 #include "Math/ProbFunc.h" 24 fEnergyFix(extra_options.
get<double>(
"EnergyFix")),
25 fDoEnergyFix(extra_options.
get<
bool>(
"DoEnergyFix")),
26 fPitch(extra_options.
get<double>(
"WirePitch")),
27 fZ0(extra_options.
get<double>(
"Z0")),
28 fMultinomial(extra_options.
get<
bool>(
"Multinomial", true)),
29 fEndZCut(extra_options.
get<double>(
"EndZCut")),
30 fSliceMethod(extra_options.
get<
std::
string>(
"SliceMethod")) {
32 fIn =
new TFile(
"end_slices.root",
"OPEN");
34 for (
int i = 1; i <= 735; ++i) {
50 TTree *
tree, std::vector<ThinSliceEvent> &
events,
51 std::vector<ThinSliceEvent> & fake_data_events,
52 int & split_val,
const bool & do_split) {
53 std::cout <<
"Filling MC Events" <<
std::endl;
57 double true_beam_interactingEnergy, reco_beam_interactingEnergy;
58 double true_beam_endP, true_beam_mass, true_beam_endZ;
59 double reco_beam_endZ, true_beam_startP;
61 std::vector<double> * reco_beam_incidentEnergies = 0x0,
62 * true_beam_incidentEnergies = 0x0,
63 * true_beam_traj_Z = 0x0,
64 * true_beam_traj_KE = 0x0,
65 * reco_daughter_track_thetas = 0x0,
66 * reco_daughter_track_scores = 0x0;
67 std::vector<int> * true_beam_slices = 0x0;
68 tree->SetBranchAddress(
"event", &event);
69 tree->SetBranchAddress(
"subrun", &subrun);
70 tree->SetBranchAddress(
"run", &run);
72 tree->SetBranchAddress(
"true_beam_PDG", &true_beam_PDG);
74 tree->SetBranchAddress(
"new_interaction_topology", &sample_ID);
75 tree->SetBranchAddress(
"selection_ID", &selection_ID);
76 tree->SetBranchAddress(
"true_beam_interactingEnergy",
77 &true_beam_interactingEnergy);
78 tree->SetBranchAddress(
"true_beam_endP", &true_beam_endP);
79 tree->SetBranchAddress(
"true_beam_endZ", &true_beam_endZ);
80 tree->SetBranchAddress(
"true_beam_mass", &true_beam_mass);
81 tree->SetBranchAddress(
"reco_beam_interactingEnergy",
82 &reco_beam_interactingEnergy);
83 tree->SetBranchAddress(
"reco_beam_endZ", &reco_beam_endZ);
84 tree->SetBranchAddress(
"reco_beam_incidentEnergies",
85 &reco_beam_incidentEnergies);
86 tree->SetBranchAddress(
"true_beam_incidentEnergies",
87 &true_beam_incidentEnergies);
88 tree->SetBranchAddress(
"true_beam_slices",
90 tree->SetBranchAddress(
"true_beam_startP", &true_beam_startP);
91 tree->SetBranchAddress(
"true_beam_traj_Z", &true_beam_traj_Z);
92 tree->SetBranchAddress(
"true_beam_traj_KE", &true_beam_traj_KE);
93 std::vector<double> * calibrated_dQdX = 0x0, * beam_EField = 0x0,
95 tree->SetBranchAddress(
"reco_beam_calibrated_dQdX_SCE", &calibrated_dQdX);
96 tree->SetBranchAddress(
"reco_beam_EField_SCE", &beam_EField);
97 tree->SetBranchAddress(
"reco_beam_TrkPitch_SCE", &track_pitch);
98 tree->SetBranchAddress(
"beam_inst_P", &beam_inst_P);
99 tree->SetBranchAddress(
"reco_daughter_allTrack_Theta", &reco_daughter_track_thetas);
100 tree->SetBranchAddress(
"reco_daughter_PFP_trackScore_collection",
101 &reco_daughter_track_scores);
103 std::vector<double> * g4rw_alt_primary_plus_sigma_weight = 0x0,
104 * g4rw_alt_primary_minus_sigma_weight = 0x0,
105 * g4rw_full_primary_plus_sigma_weight = 0x0,
106 * g4rw_full_primary_minus_sigma_weight = 0x0;
107 std::vector<std::vector<double>> * g4rw_primary_grid_weights = 0x0,
108 * g4rw_full_grid_weights = 0x0,
109 * g4rw_full_grid_proton_weights = 0x0;
110 tree->SetBranchAddress(
"g4rw_alt_primary_plus_sigma_weight",
111 &g4rw_alt_primary_plus_sigma_weight);
112 tree->SetBranchAddress(
"g4rw_alt_primary_minus_sigma_weight",
113 &g4rw_alt_primary_minus_sigma_weight);
114 tree->SetBranchAddress(
"g4rw_full_primary_plus_sigma_weight",
115 &g4rw_full_primary_plus_sigma_weight);
116 tree->SetBranchAddress(
"g4rw_full_primary_minus_sigma_weight",
117 &g4rw_full_primary_minus_sigma_weight);
118 tree->SetBranchAddress(
"g4rw_full_grid_weights", &g4rw_full_grid_weights);
119 tree->SetBranchAddress(
"g4rw_full_grid_proton_weights", &g4rw_full_grid_proton_weights);
121 tree->SetBranchAddress(
"g4rw_primary_grid_weights",
122 &g4rw_primary_grid_weights);
124 std::vector<std::vector<double>> * daughter_dQdXs = 0x0,
125 * daughter_resRanges = 0x0,
126 * daughter_EFields = 0x0;
127 tree->SetBranchAddress(
128 "reco_daughter_allTrack_calibrated_dQdX_SCE", &daughter_dQdXs);
129 tree->SetBranchAddress(
130 "reco_daughter_allTrack_resRange_SCE", &daughter_resRanges);
131 tree->SetBranchAddress(
132 "reco_daughter_allTrack_EField_SCE", &daughter_EFields);
134 tree->SetBranchAddress(
"has_shower_dist_energy", &has_pi0_shower);
138 split_val = tree->GetEntries()/2;
139 std::cout <<
"Note: Splitting MC in half. " <<
140 split_val <<
"/" << tree->GetEntries() <<
std::endl;
141 nentries = split_val;
144 std::vector<double> xs;
145 for (
size_t i = 0; i < 20; ++i) {xs.push_back(.1*(1 + i));}
147 for (
int i = 0; i <
nentries; ++i) {
151 events.back().SetSampleID(sample_ID);
152 events.back().SetSelectionID(selection_ID);
153 events.back().SetTrueInteractingEnergy(true_beam_interactingEnergy);
154 events.back().SetRecoInteractingEnergy(reco_beam_interactingEnergy);
155 events.back().SetTrueEndP(true_beam_endP);
156 events.back().SetTrueEndZ(true_beam_endZ);
157 events.back().SetTrueStartP(true_beam_startP);
158 events.back().SetTrueMass(true_beam_mass);
159 events.back().SetRecoEndZ(reco_beam_endZ);
161 events.back().SetRecoIncidentEnergies(*reco_beam_incidentEnergies);
162 events.back().SetTrueIncidentEnergies(*true_beam_incidentEnergies);
163 events.back().SetTrueTrajZ(*true_beam_traj_Z);
164 events.back().SetTrueTrajKE(*true_beam_traj_KE);
165 events.back().SetTrueSlices(*true_beam_slices);
166 events.back().SetdQdXCalibrated(*calibrated_dQdX);
167 events.back().SetEField(*beam_EField);
168 events.back().SetTrackPitch(*track_pitch);
169 events.back().SetBeamInstP(beam_inst_P);
170 events.back().SetPDG(true_beam_PDG);
171 events.back().SetRecoDaughterTrackThetas(*reco_daughter_track_thetas);
172 events.back().SetRecoDaughterTrackScores(*reco_daughter_track_scores);
173 events.back().SetHasPi0Shower(has_pi0_shower);
174 events.back().MakeG4RWBranch(
"g4rw_alt_primary_plus_sigma_weight",
175 *g4rw_alt_primary_plus_sigma_weight);
176 events.back().MakeG4RWBranch(
"g4rw_alt_primary_minus_sigma_weight",
177 *g4rw_alt_primary_minus_sigma_weight);
178 events.back().MakeG4RWBranch(
"g4rw_full_primary_plus_sigma_weight",
179 *g4rw_full_primary_plus_sigma_weight);
180 events.back().MakeG4RWBranch(
"g4rw_full_primary_minus_sigma_weight",
181 *g4rw_full_primary_minus_sigma_weight);
182 for (
size_t j = 0; j < daughter_dQdXs->size(); ++j) {
183 events.back().AddRecoDaughterTrackdQdX((*daughter_dQdXs)[j]);
184 events.back().AddRecoDaughterTrackResRange((*daughter_resRanges)[j]);
185 events.back().AddRecoDaughterEField((*daughter_EFields)[j]);
188 for (
size_t j = 0; j < g4rw_primary_grid_weights->size(); ++j) {
193 events.back().MakeG4RWBranch(name_full, (*g4rw_full_grid_weights)[j]);
196 std::string name_primary =
"g4rw_primary_grid_weights_" +
201 events.back().MakeG4RWBranch(name_primary,
202 (*g4rw_primary_grid_weights)[j]);
204 events.back().MakeG4RWBranch(
"g4rw_full_grid_proton_weights",
205 (*g4rw_full_grid_proton_weights)[0]);
209 for (
int i = split_val; i < tree->GetEntries(); ++i) {
213 fake_data_events.back().SetSampleID(sample_ID);
214 fake_data_events.back().SetSelectionID(selection_ID);
215 fake_data_events.back().SetTrueInteractingEnergy(true_beam_interactingEnergy);
216 fake_data_events.back().SetRecoInteractingEnergy(reco_beam_interactingEnergy);
217 fake_data_events.back().SetTrueEndP(true_beam_endP);
218 fake_data_events.back().SetTrueEndZ(true_beam_endZ);
219 fake_data_events.back().SetTrueStartP(true_beam_startP);
220 fake_data_events.back().SetTrueMass(true_beam_mass);
221 fake_data_events.back().SetRecoEndZ(reco_beam_endZ);
223 fake_data_events.back().SetRecoIncidentEnergies(*reco_beam_incidentEnergies);
224 fake_data_events.back().SetTrueIncidentEnergies(*true_beam_incidentEnergies);
225 fake_data_events.back().SetTrueTrajZ(*true_beam_traj_Z);
226 fake_data_events.back().SetTrueTrajKE(*true_beam_traj_KE);
227 fake_data_events.back().SetTrueSlices(*true_beam_slices);
228 fake_data_events.back().SetdQdXCalibrated(*calibrated_dQdX);
229 fake_data_events.back().SetEField(*beam_EField);
230 fake_data_events.back().SetTrackPitch(*track_pitch);
231 fake_data_events.back().SetBeamInstP(beam_inst_P);
232 fake_data_events.back().SetPDG(true_beam_PDG);
233 fake_data_events.back().SetRecoDaughterTrackThetas(*reco_daughter_track_thetas);
234 fake_data_events.back().SetRecoDaughterTrackScores(*reco_daughter_track_scores);
235 fake_data_events.back().SetHasPi0Shower(has_pi0_shower);
236 fake_data_events.back().MakeG4RWBranch(
"g4rw_alt_primary_plus_sigma_weight",
237 *g4rw_alt_primary_plus_sigma_weight);
238 fake_data_events.back().MakeG4RWBranch(
"g4rw_alt_primary_minus_sigma_weight",
239 *g4rw_alt_primary_minus_sigma_weight);
240 fake_data_events.back().MakeG4RWBranch(
"g4rw_full_primary_plus_sigma_weight",
241 *g4rw_full_primary_plus_sigma_weight);
242 fake_data_events.back().MakeG4RWBranch(
"g4rw_full_primary_minus_sigma_weight",
243 *g4rw_full_primary_minus_sigma_weight);
244 for (
size_t j = 0; j < daughter_dQdXs->size(); ++j) {
245 fake_data_events.back().AddRecoDaughterTrackdQdX((*daughter_dQdXs)[j]);
246 fake_data_events.back().AddRecoDaughterTrackResRange((*daughter_resRanges)[j]);
247 fake_data_events.back().AddRecoDaughterEField((*daughter_EFields)[j]);
250 for (
size_t j = 0; j < g4rw_primary_grid_weights->size(); ++j) {
255 fake_data_events.back().MakeG4RWBranch(name_full, (*g4rw_full_grid_weights)[j]);
257 std::string name_primary =
"g4rw_primary_grid_weights_" +
262 fake_data_events.back().MakeG4RWBranch(name_primary,
263 (*g4rw_primary_grid_weights)[j]);
265 fake_data_events.back().MakeG4RWBranch(
"g4rw_full_grid_proton_weights",
266 (*g4rw_full_grid_proton_weights)[0]);
270 std::cout <<
"Filled MC Events" <<
std::endl;
276 const std::vector<ThinSliceEvent> &
events,
277 std::map<
int,
std::vector<std::vector<ThinSliceSample>>> & samples,
278 const std::map<int, bool> & signal_sample_checks,
279 std::map<int, double> & nominal_fluxes,
280 std::map<
int,
std::vector<std::vector<double>>> & fluxes_by_sample,
281 std::vector<double> & beam_energy_bins) {
283 for (
size_t i = 0; i < events.size(); ++i) {
286 int sample_ID =
event.GetSampleID();
289 double true_beam_interactingEnergy =
event.GetTrueInteractingEnergy();
290 double reco_beam_interactingEnergy =
event.GetRecoInteractingEnergy();
291 double true_beam_endP =
event.GetTrueEndP();
292 double reco_beam_endZ =
event.GetRecoEndZ();
293 double true_beam_startP =
event.GetTrueStartP();
295 const std::vector<double> & reco_beam_incidentEnergies
296 =
event.GetRecoIncidentEnergies();
297 const std::vector<double> & true_beam_incidentEnergies
298 =
event.GetTrueIncidentEnergies();
299 const std::vector<double> & true_beam_traj_Z
300 =
event.GetTrueTrajZ();
301 const std::vector<double> & true_beam_traj_KE
302 =
event.GetTrueTrajKE();
303 const std::vector<int> & true_beam_slices
304 =
event.GetTrueSlices();
306 double end_energy = true_beam_interactingEnergy;
308 end_energy = sqrt(true_beam_endP*true_beam_endP*1.e6 + 139.57*139.57) - 139.57;
311 end_energy = sqrt(true_beam_endP*true_beam_endP*1.e6 + 139.57*139.57) - 139.57;
314 int bin =
fEndSlices->GetXaxis()->FindBin(true_beam_traj_Z.back());
316 end_energy =
fMeans.at(bin);
319 if (samples.find(sample_ID) == samples.end()) {
320 std::cout <<
"Warning: skipping sample " << sample_ID <<
std::endl;
326 true_beam_traj_Z, true_beam_traj_KE, true_beam_slices,
327 true_beam_incidentEnergies);
331 std::vector<ThinSliceSample> & samples_vec = samples.at(sample_ID)[
bin];
332 bool is_signal = signal_sample_checks.at(sample_ID);
336 this_sample = &samples_vec.at(0);
338 fluxes_by_sample[sample_ID][
bin][0] += 1.;
343 for (
size_t j = 1; j < samples_vec.size()-1; ++j) {
346 this_sample = &sample;
348 fluxes_by_sample[sample_ID][
bin][j] += 1.;
355 if (end_energy <= samples_vec[1].RangeLowEnd()) {
356 this_sample = &samples_vec[0];
358 fluxes_by_sample[sample_ID][
bin][0] += 1.;
360 else if (end_energy >
361 samples_vec[samples_vec.size()-2].RangeHighEnd()) {
362 this_sample = &samples_vec.back();
363 fluxes_by_sample[sample_ID][
bin].back() += 1.;
366 std::cout <<
"Warning: could not find true bin " <<
373 nominal_fluxes[flux_type] += 1.;
376 if (selection_ID == 4) {
379 if (selected_hist->FindBin(reco_beam_endZ) == 0) {
380 val[0] = selected_hist->GetBinCenter(1);
382 else if (selected_hist->FindBin(reco_beam_endZ) >
383 selected_hist->GetNbinsX()) {
384 val[0] = selected_hist->GetBinCenter(selected_hist->GetNbinsX());
387 val[0] = reco_beam_endZ;
390 else if (selection_ID > 4) {
393 else if (reco_beam_incidentEnergies.size()) {
394 double energy[1] = {reco_beam_interactingEnergy};
396 for (
size_t k = 1;
k < reco_beam_incidentEnergies.size(); ++
k) {
397 double deltaE = ((reco_beam_incidentEnergies)[
k-1] -
398 (reco_beam_incidentEnergies)[
k]);
407 if (selected_hist->FindBin(energy[0]) == 0) {
408 val[0] = selected_hist->GetBinCenter(1);
410 else if (selected_hist->FindBin(energy[0]) >
411 selected_hist->GetNbinsX()) {
412 val[0] = selected_hist->GetBinCenter(selected_hist->GetNbinsX());
421 val[0] = selected_hist->GetBinCenter(1);
428 if (true_beam_incidentEnergies.size() > 0) {
430 {(true_beam_incidentEnergies)[0],
439 const std::vector<ThinSliceEvent> &
events,
440 std::map<
int,
std::vector<std::vector<ThinSliceSample>>> & samples,
441 const std::map<int, bool> & signal_sample_checks,
442 std::vector<double> & beam_energy_bins,
443 const std::map<
int, std::vector<double>> & signal_pars,
444 const std::map<int, double> & flux_pars,
445 const std::map<std::string, ThinSliceSystematic> & syst_pars,
446 bool fit_under_over,
bool fill_incident) {
449 for (
auto it = samples.begin(); it != samples.end(); ++it) {
450 for (
size_t i = 0; i < it->second.size(); ++i) {
451 for (
size_t j = 0; j < it->second[i].size(); ++j) {
452 it->second[i][j].Reset();
458 for (
size_t i = 0; i < events.size(); ++i) {
460 int sample_ID =
event.GetSampleID();
463 double true_beam_interactingEnergy =
event.GetTrueInteractingEnergy();
464 double reco_beam_interactingEnergy =
event.GetRecoInteractingEnergy();
465 double true_beam_endP =
event.GetTrueEndP();
466 double reco_beam_endZ =
event.GetRecoEndZ();
467 double true_beam_startP =
event.GetTrueStartP();
469 const std::vector<double> & reco_beam_incidentEnergies
470 =
event.GetRecoIncidentEnergies();
471 const std::vector<double> & true_beam_incidentEnergies
472 =
event.GetTrueIncidentEnergies();
473 const std::vector<double> & true_beam_traj_Z
474 =
event.GetTrueTrajZ();
475 const std::vector<double> & true_beam_traj_KE
476 =
event.GetTrueTrajKE();
477 const std::vector<int> & true_beam_slices
478 =
event.GetTrueSlices();
479 double beam_inst_P =
event.GetBeamInstP();
480 const std::vector<double> calibrated_dQdX
481 =
event.GetdQdXCalibrated();
482 const std::vector<double> beam_EField
484 const std::vector<double> track_pitch
485 =
event.GetTrackPitch();
486 const std::vector<double> daughter_thetas
487 =
event.GetRecoDaughterTrackThetas();
491 double end_energy = true_beam_interactingEnergy;
493 end_energy = sqrt(true_beam_endP*true_beam_endP*1.e6 + 139.57*139.57) - 139.57;
496 end_energy = sqrt(true_beam_endP*true_beam_endP*1.e6 + 139.57*139.57) - 139.57;
499 int bin =
fEndSlices->GetXaxis()->FindBin(true_beam_traj_Z.back());
501 end_energy =
fMeans.at(bin);
504 if (samples.find(sample_ID) == samples.end()) {
505 std::cout <<
"Warning: skipping sample " << sample_ID <<
std::endl;
510 std::vector<double> good_true_incEnergies;
513 true_beam_traj_Z, true_beam_traj_KE, true_beam_slices,
514 true_beam_incidentEnergies);
523 std::vector<ThinSliceSample> & samples_vec = samples.at(sample_ID)[
bin];
524 bool is_signal = signal_sample_checks.at(sample_ID);
528 this_sample = &samples_vec.at(0);
533 for (
size_t j = 1; j < samples_vec.size()-1; ++j) {
536 this_sample = &sample;
541 int index = j - 1 + (fit_under_over ? 1 : 0);
542 weight *= signal_pars.at(sample_ID)[
index];
549 if (end_energy <= samples_vec[1].RangeLowEnd()) {
550 this_sample = &samples_vec[0];
551 if (fit_under_over) weight *= signal_pars.at(sample_ID)[0];
554 else if (end_energy >
555 samples_vec[samples_vec.size()-2].RangeHighEnd()) {
557 this_sample = &samples_vec.back();
558 if (fit_under_over) weight *= signal_pars.at(sample_ID).back();
561 std::cout <<
"Warning: could not find true bin " <<
568 if (flux_pars.find(flux_type) != flux_pars.end()) {
569 weight *= flux_pars.at(flux_type);
577 if (new_selection == 4) {
578 if (selected_hist->FindBin(reco_beam_endZ) == 0) {
579 val[0] = selected_hist->GetBinCenter(1);
581 else if (selected_hist->FindBin(reco_beam_endZ) >
582 selected_hist->GetNbinsX()) {
583 val[0] = selected_hist->GetBinCenter(selected_hist->GetNbinsX());
586 val[0] = reco_beam_endZ;
589 else if (new_selection > 4) {
592 else if (reco_beam_incidentEnergies.size()) {
595 if (syst_pars.find(
"dEdX_Cal") != syst_pars.end()) {
596 energy[0] = sqrt(beam_inst_P*beam_inst_P*1.e6 + 139.57*139.57) -
599 for (
size_t k = 0;
k < calibrated_dQdX.size()-1; ++
k) {
600 if ((calibrated_dQdX)[
k] < 0.)
continue;
602 double dedx = (1./(syst_pars.at(
"dEdX_Cal").GetValue()));
603 dedx *= (calibrated_dQdX)[
k];
611 energy[0] -= dedx*(track_pitch)[
k];
616 energy[0] = {reco_beam_interactingEnergy};
618 for (
size_t k = 1;
k < reco_beam_incidentEnergies.size(); ++
k) {
619 double deltaE = ((reco_beam_incidentEnergies)[
k-1] -
620 (reco_beam_incidentEnergies)[
k]);
628 if (selected_hist->FindBin(energy[0]) == 0) {
629 val[0] = selected_hist->GetBinCenter(1);
631 else if (selected_hist->FindBin(energy[0]) > selected_hist->GetNbinsX()) {
632 val[0] = selected_hist->GetBinCenter(selected_hist->GetNbinsX());
639 val[0] = selected_hist->GetBinCenter(1);
642 if (syst_pars.find(
"dEdX_Cal_Spline") != syst_pars.end()) {
643 int bin = selected_hist->FindBin(val[0]);
646 weight *= spline->Eval(syst_pars.at(
"dEdX_Cal_Spline").GetValue());
649 std::cout <<
"Weight went negative after dedx spline" <<
std::endl;
652 if (syst_pars.find(
"beam_shift_spline") != syst_pars.end()) {
653 int bin = selected_hist->FindBin(val[0]);
656 weight *= spline->Eval(syst_pars.at(
"beam_shift_spline").GetValue());
658 if (syst_pars.find(
"eff_var") != syst_pars.end()) {
659 int bin = selected_hist->FindBin(val[0]);
662 weight *= spline->Eval(syst_pars.at(
"eff_var").GetValue());
665 std::cout <<
"Weight went negative after eff var spline" <<
std::endl;
668 if (syst_pars.find(
"beam_shift_spline_2") != syst_pars.end()) {
669 int bin = selected_hist->FindBin(val[0]);
672 weight *= spline->Eval(syst_pars.at(
"beam_shift_spline_2").GetValue());
675 std::cout <<
"Weight went negative after beam shift spline" <<
std::endl;
683 std::cout <<
"Weight went negative after beam shift" <<
std::endl;
691 std::cout <<
"Weight went negative after eff" <<
std::endl;
695 std::cout <<
"Weight went negative after ediv" <<
std::endl;
700 std::cout <<
"Weight went negative after beam effs" <<
std::endl;
709 if (true_beam_incidentEnergies.size() > 0) {
711 {(true_beam_incidentEnergies)[0],
712 end_energy}, weight);
727 output_file.cd(
"SystBeamShift");
738 const std::vector<ThinSliceEvent> &
events,
739 std::map<
int,
std::vector<std::vector<ThinSliceSample>>> & samples,
740 const std::map<int, bool> & signal_sample_checks,
741 std::vector<double> & beam_energy_bins,
742 const std::map<std::string, ThinSliceSystematic> & pars,
745 if (pars.find(
"dEdX_Cal") != pars.end()) {
750 fRho = cal_set.
get<
double>(
"Rho");
751 fWion = cal_set.
get<
double>(
"Wion");
754 std::vector<fhicl::ParameterSet> PlanePars
755 = cal_set.
get<std::vector<fhicl::ParameterSet>>(
"PlaneParameters");
756 bool found_collection =
false;
757 for (
auto &
p : PlanePars) {
758 if (
p.get<
int>(
"PlaneID") == 2) {
760 found_collection =
true;
765 if (!found_collection) {
767 throw std::runtime_error(message);
770 else if (pars.find(
"dEdX_Cal_Spline") != pars.end()) {
774 fRho = cal_set.
get<
double>(
"Rho");
775 fWion = cal_set.
get<
double>(
"Wion");
778 std::vector<fhicl::ParameterSet> PlanePars
779 = cal_set.
get<std::vector<fhicl::ParameterSet>>(
"PlaneParameters");
780 bool found_collection =
false;
781 for (
auto &
p : PlanePars) {
782 if (
p.get<
int>(
"PlaneID") == 2) {
784 found_collection =
true;
789 if (!found_collection) {
791 throw std::runtime_error(message);
796 SetupSyst_G4RW(events, samples, signal_sample_checks, beam_energy_bins,
814 const std::map<std::string, ThinSliceSystematic> & pars) {
815 if (pars.find(
"eff_var_weight") == pars.end()) {
818 fEffVarF = pars.at(
"eff_var_weight").GetOption<
double>(
"F");
819 fEffVarCut = pars.at(
"eff_var_weight").GetOption<
double>(
"Cut");
825 const std::map<std::string, ThinSliceSystematic> & pars) {
827 if (pars.find(
"eff_var_weight") == pars.end())
return 1.;
830 if (selection_ID > 3)
return 1.;
832 const std::vector<double> daughter_thetas
833 =
event.GetRecoDaughterTrackThetas();
834 const std::vector<double> track_scores
835 =
event.GetRecoDaughterTrackScores();
837 for (
size_t i = 0; i < track_scores.size(); ++i) {
839 (daughter_thetas[i]*180./TMath::Pi() < 20.) &&
840 (daughter_thetas[i] > -999.))
847 if (selection_ID == 3) {
852 weight = (
std::pow(pars.at(
"eff_var_weight").GetValue(),
n));
862 const std::map<std::string, ThinSliceSystematic> & pars) {
863 if (pars.find(
"ediv_weight") == pars.end()) {
866 fEDivF = pars.at(
"ediv_weight").GetOption<
double>(
"F");
867 fEDivCut = pars.at(
"ediv_weight").GetOption<
double>(
"Cut");
871 const std::map<std::string, ThinSliceSystematic> & pars) {
872 if (pars.find(
"no_track_weight") == pars.end()) {
875 fNoTrackF = pars.at(
"no_track_weight").GetOption<
double>(
"F");
879 const std::map<std::string, ThinSliceSystematic> & pars) {
881 if (pars.find(
"beam_cut_weight") != pars.end()) {
882 fBeamCutF = pars.at(
"beam_cut_weight").GetOption<
double>(
"F");
884 if (pars.find(
"no_track_weight") != pars.end()) {
885 fNoTrackF = pars.at(
"no_track_weight").GetOption<
double>(
"F");
891 const std::map<std::string, ThinSliceSystematic> & pars) {
893 if (pars.find(
"ediv_weight") == pars.end())
return 1.;
896 if (selection_ID != 4)
return 1.;
898 const double endZ =
event.GetRecoEndZ();
901 double var = pars.at(
"ediv_weight").GetValue();
914 const std::map<std::string, ThinSliceSystematic> & pars) {
916 if (pars.find(
"no_track_weight") == pars.end()) {
923 double var = pars.at(
"no_track_weight").GetValue();
924 if (selection_ID == 6) {
937 const std::map<std::string, ThinSliceSystematic> & pars) {
939 if (pars.find(
"beam_cut_weight") == pars.end() &&
940 pars.find(
"no_track_weight") == pars.end()) {
943 else if (pars.find(
"beam_cut_weight") != pars.end() &&
944 pars.find(
"no_track_weight") == pars.end()) {
948 double var = pars.at(
"beam_cut_weight").GetValue();
949 if (selection_ID == 5) {
958 else if (pars.find(
"no_track_weight") != pars.end() &&
959 pars.find(
"beam_cut_weight") == pars.end()) {
963 double var = pars.at(
"no_track_weight").GetValue();
964 if (selection_ID == 6) {
977 double var_no_track = pars.at(
"no_track_weight").GetValue();
978 double var_beam_cut = pars.at(
"beam_cut_weight").GetValue();
979 if (selection_ID == 6) {
980 weight = var_no_track;
982 else if (selection_ID == 5) {
983 weight = var_beam_cut;
991 std::cout <<
"Negative beam cut weight: " << var_no_track <<
" " <<
1000 const std::vector<ThinSliceEvent> &
events,
1001 std::map<
int,
std::vector<std::vector<ThinSliceSample>>> & samples,
1002 const std::map<std::string, ThinSliceSystematic> & pars,
1005 if (pars.find(
"eff_var") == pars.end()) {
1013 std::vector<double> vars;
1014 for (
size_t i = 0; i < 11; ++i) {
1015 vars.push_back(.1*i);
1016 std::cout << vars.back() <<
" ";
1022 std::map<int, TH1D*> full_hists;
1026 for (
auto it = sel_hists.begin(); it != sel_hists.end(); ++it) {
1027 std::string sel_hist_name = it->second->GetName();
1028 sel_hist_name +=
"Syst_EffVar_Spline";
1031 for (
size_t k = 0;
k < vars.size(); ++
k) {
1034 fFullSelectionVars[
"EffVar_Spline"][it->first].push_back((TH1D*)it->second->Clone(shift_name.c_str()));
1039 sel_hist_name +=
"_FullVar";
1040 full_hists[it->first] = (TH1D*)it->second->Clone(sel_hist_name.c_str());
1041 full_hists[it->first]->Reset();
1044 for (
size_t i = 0; i < events.size(); ++i) {
1046 int sample_ID =
event.GetSampleID();
1049 double reco_beam_endZ =
event.GetRecoEndZ();
1051 const std::vector<double> & reco_beam_incidentEnergies
1052 =
event.GetRecoIncidentEnergies();
1053 double reco_beam_interactingEnergy =
event.GetRecoInteractingEnergy();
1054 const std::vector<double> calibrated_dQdX
1055 =
event.GetdQdXCalibrated();
1056 const std::vector<double> beam_EField
1057 =
event.GetEField();
1058 const std::vector<double> track_pitch
1059 =
event.GetTrackPitch();
1060 const std::vector<double> daughter_thetas
1061 =
event.GetRecoDaughterTrackThetas();
1062 const std::vector<double> track_scores
1063 =
event.GetRecoDaughterTrackScores();
1065 if (samples.find(sample_ID) == samples.end()) {
1066 std::cout <<
"Warning: skipping sample " << sample_ID <<
std::endl;
1070 std::vector<int> new_selections(vars.size(),
selection_ID);
1071 if (selection_ID < 3) {
1072 for (
size_t j = 0; j < vars.size(); ++j) {
1074 for (
size_t k = 0;
k < daughter_thetas.size(); ++
k) {
1075 if ((daughter_thetas[
k] > -999) &&
1076 (track_scores[
k] > .3) &&
1077 (daughter_thetas[
k]*180./TMath::Pi() < 20.)) {
1078 double r =
fRNG.Uniform();
1081 new_selections[j] = 3;
1089 std::vector<double> vals(vars.size(), 0.);
1090 if (selection_ID == 4) {
1091 TH1D * selected_hist
1093 if (selected_hist->FindBin(reco_beam_endZ) == 0) {
1094 for (
double & v : vals) v = selected_hist->GetBinCenter(1);
1096 else if (selected_hist->FindBin(reco_beam_endZ) >
1097 selected_hist->GetNbinsX()) {
1098 for (
double & v : vals)
1099 v = selected_hist->GetBinCenter(selected_hist->GetNbinsX());
1102 for (
double & v : vals) v = reco_beam_endZ;
1105 else if (selection_ID > 4) {
1106 for (
double & v : vals) v = .5;
1108 else if (reco_beam_incidentEnergies.size()) {
1109 double energy = reco_beam_interactingEnergy;
1111 for (
size_t k = 1;
k < reco_beam_incidentEnergies.size(); ++
k) {
1112 double deltaE = ((reco_beam_incidentEnergies)[
k-1] -
1113 (reco_beam_incidentEnergies)[
k]);
1120 for (
size_t j = 0; j < new_selections.size(); ++j) {
1121 TH1D * selected_hist
1123 if (selected_hist->FindBin(energy) == 0) {
1124 vals[j] = selected_hist->GetBinCenter(1);
1126 else if (selected_hist->FindBin(energy) >
1127 selected_hist->GetNbinsX()) {
1128 vals[j] = selected_hist->GetBinCenter(selected_hist->GetNbinsX());
1136 for (
size_t j = 0; j < new_selections.size(); ++j) {
1137 TH1D * selected_hist
1139 vals[j] = selected_hist->GetBinCenter(1);
1143 for (
size_t j = 0; j < vals.size(); ++j) {
1152 TDirectory *
dir = output_file.mkdir(
"EffVar_Spline_Syst");
1161 for (
auto it2 = samples.begin(); it2 != samples.end(); ++it2) {
1162 for (
size_t i = 0; i < it2->second.size(); ++i) {
1163 for (
size_t j = 0; j < it2->second[i].size(); ++j) {
1164 full_hists[
selection_ID]->Add(it2->second[i][j].GetSelectionHist(
1170 for (
size_t i = 0; i < it->second.size(); ++i) {
1171 it->second[i]->Write();
1172 it->second[i]->Divide(full_hists[selection_ID]);
1176 for (
int i = 1; i <= full_hists[
selection_ID]->GetNbinsX(); ++i) {
1177 std::vector<double> vals;
1178 for (
size_t j = 0; j < it->second.size(); ++j) {
1179 vals.push_back(it->second[j]->GetBinContent(i));
1186 new TSpline3(spline_name.c_str(), &vars[0], &vals[0], vals.size()));
1187 TCanvas
c(spline_name.c_str(),
"");
1196 const std::map<std::string, ThinSliceSystematic> & pars,
1198 if (pars.find(
"beam_shift") == pars.end()) {
1203 pars.at(
"beam_shift").GetOption<
std::string>(
"ShiftFile").c_str());
1205 fSystBeamShiftMap->SetDirectory(0);
1207 = pars.at(
"beam_shift").GetOption<std::pair<double, double>>(
"Limits");
1220 output_file.mkdir(
"SystBeamShift");
1221 output_file.cd(
"SystBeamShift");
1264 const std::vector<ThinSliceEvent> &
events,
1265 std::map<
int,
std::vector<std::vector<ThinSliceSample>>> & samples,
1266 const std::map<std::string, ThinSliceSystematic> & pars,
1268 if (pars.find(
"beam_shift_spline") == pars.end()) {
1273 pars.at(
"beam_shift_spline").GetOption<
std::string>(
"ShiftFile").c_str());
1274 std::pair<double, double>
limits 1275 = pars.at(
"beam_shift_spline").GetOption<std::pair<double, double>>(
"Limits");
1277 TGraph * gMeans = (TGraph*)shift_file.Get(
"gMeans");
1278 TGraph * gWidths = (TGraph*)shift_file.Get(
"gWidths");
1280 std::vector<double> means, widths, beam_shift_vals;
1282 for (
int i = ((gMeans->GetN() - 1)/2 - 2);
1283 i <= ((gMeans->GetN() - 1)/2 + 2); ++i) {
1284 means.push_back(gMeans->GetY()[i]);
1285 widths.push_back(gWidths->GetY()[i]);
1286 beam_shift_vals.push_back(n);
1290 double nominal_mean = gMeans->GetY()[(gMeans->GetN() - 1)/2];
1291 double nominal_width = gWidths->GetY()[(gWidths->GetN() - 1)/2];
1296 std::map<int, TH1D*> full_hists;
1300 for (
auto it = sel_hists.begin(); it != sel_hists.end(); ++it) {
1301 std::string sel_hist_name = it->second->GetName();
1302 sel_hist_name +=
"Syst_Beam_Shift_Spline";
1303 int shift_number = -2;
1306 for (
size_t k = 0;
k < beam_shift_vals.size(); ++
k) {
1309 fFullSelectionVars[
"Beam_Shift_Spline"][it->first].push_back((TH1D*)it->second->Clone(shift_name.c_str()));
1313 if (shift_number == 0)
1317 sel_hist_name +=
"_FullVar";
1318 full_hists[it->first] = (TH1D*)it->second->Clone(sel_hist_name.c_str());
1319 full_hists[it->first]->Reset();
1322 for (
size_t i = 0; i < events.size(); ++i) {
1324 int sample_ID =
event.GetSampleID();
1326 double reco_beam_endZ =
event.GetRecoEndZ();
1328 const std::vector<double> & reco_beam_incidentEnergies
1329 =
event.GetRecoIncidentEnergies();
1330 double reco_beam_interactingEnergy =
event.GetRecoInteractingEnergy();
1331 double beam_inst_P =
event.GetBeamInstP();
1332 const std::vector<double> calibrated_dQdX
1333 =
event.GetdQdXCalibrated();
1334 const std::vector<double> beam_EField
1335 =
event.GetEField();
1336 const std::vector<double> track_pitch
1337 =
event.GetTrackPitch();
1340 if (samples.find(sample_ID) == samples.end()) {
1341 std::cout <<
"Warning: skipping sample " << sample_ID <<
std::endl;
1345 std::vector<double> weights, y_vals;
1346 for (
size_t j = 0; j < means.size(); ++j) {
1347 double y_val = (beam_inst_P -
event.GetTrueStartP())/
1348 event.GetTrueStartP();
1349 y_vals.push_back(y_val);
1350 if (y_val < limits.first ||
1351 y_val > limits.second ||
event.GetPDG() != 211) {
1352 weights.push_back(1.);
1355 double varied_width = widths[j];
1356 double varied_mean = means[j];
1357 weights.push_back((nominal_width/varied_width)*
1358 exp(.5*
std::pow(((y_val - nominal_mean)/nominal_width), 2)
1359 - .5*
std::pow(((y_val - varied_mean)/varied_width), 2)));
1371 if (selection_ID == 4) {
1372 TH1D * selected_hist
1374 if (selected_hist->FindBin(reco_beam_endZ) == 0) {
1375 val = selected_hist->GetBinCenter(1);
1377 else if (selected_hist->FindBin(reco_beam_endZ) >
1378 selected_hist->GetNbinsX()) {
1379 val = selected_hist->GetBinCenter(selected_hist->GetNbinsX());
1382 val = reco_beam_endZ;
1385 else if (selection_ID > 4) {
1388 else if (reco_beam_incidentEnergies.size()) {
1389 double energy = reco_beam_interactingEnergy;
1391 for (
size_t k = 1;
k < reco_beam_incidentEnergies.size(); ++
k) {
1392 double deltaE = ((reco_beam_incidentEnergies)[
k-1] -
1393 (reco_beam_incidentEnergies)[
k]);
1399 TH1D * selected_hist
1401 if (selected_hist->FindBin(energy) == 0) {
1402 val = selected_hist->GetBinCenter(1);
1404 else if (selected_hist->FindBin(energy) >
1405 selected_hist->GetNbinsX()) {
1406 val = selected_hist->GetBinCenter(selected_hist->GetNbinsX());
1413 TH1D * selected_hist
1415 val = selected_hist->GetBinCenter(1);
1417 for (
size_t j = 0; j < weights.size(); ++j) {
1422 TDirectory *
dir = output_file.mkdir(
"Beam_Shift_Spline_Syst");
1431 for (
auto it2 = samples.begin(); it2 != samples.end(); ++it2) {
1432 for (
size_t i = 0; i < it2->second.size(); ++i) {
1433 for (
size_t j = 0; j < it2->second[i].size(); ++j) {
1434 full_hists[
selection_ID]->Add(it2->second[i][j].GetSelectionHist(
1440 for (
size_t i = 0; i < it->second.size(); ++i) {
1441 it->second[i]->Write();
1442 it->second[i]->Divide(full_hists[selection_ID]);
1446 for (
int i = 1; i <= full_hists[
selection_ID]->GetNbinsX(); ++i) {
1447 std::vector<double> vals;
1448 for (
size_t j = 0; j < it->second.size(); ++j) {
1449 vals.push_back(it->second[j]->GetBinContent(i));
1456 TSpline3 temp_spline = TSpline3(temp_name.c_str(), &beam_shift_vals[0],
1457 &vals[0], vals.size());
1461 std::cout <<
"Derivative, y at -2: " << temp_spline.Derivative(-2.) <<
1462 " " << temp_spline.Eval(-2.) <<
std::endl;
1463 std::cout <<
"Derivative, y at 2: " << temp_spline.Derivative(2.) <<
1464 " " << temp_spline.Eval(2.) <<
std::endl;
1466 std::vector<double> new_vals, new_beam_shift_vals;
1467 double neg_2_val = temp_spline.Eval(-2.);
1468 double neg_2_slope = temp_spline.Derivative(-2.);
1469 double neg_5_new_point = -3.*neg_2_slope + neg_2_val;
1470 if (neg_5_new_point < 0.)
1471 neg_5_new_point = 1.e-5;
1472 new_vals.push_back(neg_5_new_point);
1481 new_beam_shift_vals.push_back(-5.);
1483 for (
size_t j = 0; j < vals.size(); ++j) {
1484 new_vals.push_back(vals[j]);
1485 new_beam_shift_vals.push_back(beam_shift_vals[j]);
1488 double pos_2_val = temp_spline.Eval(2.);
1489 double pos_2_slope = temp_spline.Derivative(2.);
1490 double pos_5_new_point = 3.*pos_2_slope + pos_2_val;
1491 if (pos_5_new_point < 0.)
1492 pos_5_new_point = 1.e-5;
1493 new_vals.push_back(pos_5_new_point);
1501 new_beam_shift_vals.push_back(5.);
1503 TSpline3 *
spline =
new TSpline3(spline_name.c_str(), &new_beam_shift_vals[0],
1504 &new_vals[0], new_vals.size());
1506 TCanvas
c(spline_name.c_str(),
"");
1507 spline->SetMarkerStyle(20);
1510 spline->Write(spline_name.c_str());
1518 const std::vector<ThinSliceEvent> &
events,
1519 std::map<
int,
std::vector<std::vector<ThinSliceSample>>> & samples,
1520 const std::map<int, bool> & signal_sample_checks,
1521 std::vector<double> & beam_energy_bins,
1522 const std::map<std::string, ThinSliceSystematic> & pars,
1525 for (
auto it = pars.begin(); it != pars.end(); ++it) {
1526 if (it->first.find(
"g4rw") != std::string::npos ||
1527 it->first.find(
"G4RW") != std::string::npos) {
1528 std::cout <<
"Setting up g4rw syst: " << it->first <<
std::endl;
1536 dir_name +=
"_Syst_Dir";
1537 TDirectory *
dir = output_file.mkdir(dir_name.c_str());
1539 size_t position = it->second.GetOption<
size_t>(
"Position");
1542 bool is_grid = it->second.GetOption<
bool>(
"IsGrid");
1544 std::vector<double> syst_vals;
1548 it->second.GetLowerLimit(),
1549 it->second.GetCentral(),
1550 it->second.GetUpperLimit(),
1555 double delta = it->second.GetOption<
double>(
"GridDelta");
1556 double start = it->second.GetOption<
double>(
"GridStart");
1557 int n = it->second.GetOption<
int>(
"GridN");
1560 std::cout <<
"Added to grid: ";
1562 for (
int i = 0; i <
n; ++i) {
1563 syst_vals.push_back(start);
1564 std::cout << syst_vals.back() <<
" ";
1571 for (
auto it2 = samples.begin(); it2 != samples.end(); ++it2) {
1572 for (
size_t i = 0; i < it2->second.size(); ++i) {
1573 for (
size_t j = 0; j < it2->second[i].size(); ++j) {
1574 const std::map<int, TH1 *> & sel_hists
1575 = it2->second[i][j].GetSelectionHists();
1576 for (
auto it3 = sel_hists.begin(); it3 != sel_hists.end(); ++it3) {
1579 shift_name +=
"Minus";
1580 TH1D * temp_hist = (TH1D*)it3->second->Clone(shift_name.c_str());
1583 it2->second[i][j].AddSystematicShift(temp_hist, it->first,
1586 shift_name = it3->second->GetName();
1587 shift_name +=
"Plus";
1588 temp_hist = (TH1D*)it3->second->Clone(shift_name.c_str());
1591 it2->second[i][j].AddSystematicShift(temp_hist, it->first,
1595 for (
size_t k = 0;
k < syst_vals.size(); ++
k) {
1596 if (
k == ((syst_vals.size() - 1)/2))
continue;
1600 TH1D * temp_hist = (TH1D*)it3->second->Clone(shift_name.c_str());
1602 it2->second[i][j].AddSystematicShift(temp_hist, it->first,
1611 for (
size_t i = 0; i < events.size(); ++i) {
1613 int sample_ID =
event.GetSampleID();
1616 double reco_beam_endZ =
event.GetRecoEndZ();
1618 const std::vector<double> & reco_beam_incidentEnergies
1619 =
event.GetRecoIncidentEnergies();
1621 double reco_beam_interactingEnergy =
event.GetRecoInteractingEnergy();
1623 double end_energy =
event.GetTrueInteractingEnergy();
1624 double true_beam_endP =
event.GetTrueEndP();
1625 double true_beam_startP =
event.GetTrueStartP();
1626 const std::vector<double> & true_beam_traj_Z =
event.GetTrueTrajZ();
1628 end_energy = sqrt(true_beam_endP*true_beam_endP*1.e6 + 139.57*139.57) - 139.57;
1631 end_energy = sqrt(true_beam_endP*true_beam_endP*1.e6 + 139.57*139.57) - 139.57;
1634 int bin =
fEndSlices->GetXaxis()->FindBin(true_beam_traj_Z.back());
1636 end_energy =
fMeans.at(bin);
1639 if (samples.find(sample_ID) == samples.end()) {
1640 std::cout <<
"Warning: skipping sample " << sample_ID <<
std::endl;
1647 std::vector<ThinSliceSample> & samples_vec = samples.at(sample_ID)[
bin];
1648 bool is_signal = signal_sample_checks.at(sample_ID);
1652 this_sample = &samples_vec.at(0);
1657 for (
size_t j = 1; j < samples_vec.size()-1; ++j) {
1660 this_sample = &sample;
1667 if (end_energy <= samples_vec[1].RangeLowEnd()) {
1668 this_sample = &samples_vec[0];
1670 else if (end_energy >
1671 samples_vec[samples_vec.size()-2].RangeHighEnd()) {
1672 this_sample = &samples_vec.back();
1675 std::cout <<
"Warning: could not find true bin " <<
1681 std::vector<double> vals;
1682 std::vector<double> weights;
1684 vals = std::vector<double>(2, 0.);
1685 weights = {
event.GetG4RWWeight(minus_branch, position),
1686 event.GetG4RWWeight(plus_branch, position)};
1689 if (
event.HasG4RWBranch(grid_branch)) {
1690 if (!
event.GetG4RWBranch(grid_branch).size()) {
1691 weights = std::vector<double>(syst_vals.size(), 1.);
1692 vals = std::vector<double>(syst_vals.size(), 0.);
1695 weights =
event.GetG4RWBranch(grid_branch);
1696 vals = std::vector<double>(weights.size(), 0.);
1700 weights = std::vector<double>(syst_vals.size(), 1.);
1701 vals = std::vector<double>(syst_vals.size(), 0.);
1703 weights.erase(weights.begin() + ((weights.size()-1)/2));
1704 vals.erase(vals.begin() + ((vals.size()-1)/2));
1708 if (selection_ID == 4) {
1709 if (selected_hist->FindBin(reco_beam_endZ) == 0) {
1710 for (
double & v : vals) v = selected_hist->GetBinCenter(1);
1712 else if (selected_hist->FindBin(reco_beam_endZ) >
1713 selected_hist->GetNbinsX()) {
1714 for (
double & v : vals)
1715 v = selected_hist->GetBinCenter(selected_hist->GetNbinsX());
1718 for (
double & v : vals) v = reco_beam_endZ;
1721 else if (selection_ID > 4) {
1722 for (
double & v : vals) v = .5;
1724 else if (reco_beam_incidentEnergies.size()) {
1725 double energy = reco_beam_interactingEnergy;
1727 for (
size_t k = 1;
k < reco_beam_incidentEnergies.size(); ++
k) {
1728 double deltaE = ((reco_beam_incidentEnergies)[
k-1] -
1729 (reco_beam_incidentEnergies)[
k]);
1735 if (selected_hist->FindBin(energy) == 0) {
1736 for (
double & v : vals) v = selected_hist->GetBinCenter(1);
1738 else if (selected_hist->FindBin(energy) >
1739 selected_hist->GetNbinsX()) {
1740 for (
double & v : vals)
1741 v = selected_hist->GetBinCenter(selected_hist->GetNbinsX());
1744 for (
double & v : vals) v =
energy;
1748 for (
double & v : vals) v = selected_hist->GetBinCenter(1);
1752 for (
auto it2 = samples.begin(); it2 != samples.end(); ++it2) {
1753 for (
size_t i = 0; i < it2->second.size(); ++i) {
1754 for (
size_t j = 0; j < it2->second[i].size(); ++j) {
1755 it2->second[i][j].SetSystematicVals(it->first, syst_vals);
1756 it2->second[i][j].MakeSystematicSplines(it->first);
1757 it2->second[i][j].SaveSystematics(it->first, dir);
1766 const std::vector<ThinSliceEvent> &
events,
1767 std::map<
int,
std::vector<std::vector<ThinSliceSample>>> & samples,
1768 const std::map<std::string, ThinSliceSystematic> & pars,
1773 std::vector<double> C_cal_vars
1774 = pars.at(
"dEdX_Cal_Spline").GetOption<std::vector<double>>(
"C_cal_vars");
1778 if (C_cal_vars.size() % 2) {
1780 message +=
"odd number of variations to cal constant";
1781 throw std::runtime_error(message);
1784 TFile template_file(
1785 pars.at(
"dEdX_Cal_Spline").GetOption<
std::string>(
"TemplateFile").c_str());
1786 TProfile * prot_template = (TProfile*)template_file.Get(
"dedx_range_pro");
1790 std::map<int, TH1D*> full_hists;
1794 for (
auto it = sel_hists.begin(); it != sel_hists.end(); ++it) {
1795 std::string sel_hist_name = it->second->GetName();
1796 sel_hist_name +=
"Syst_dEdX_Cal_Spline";
1797 int shift_number = -2;
1800 for (
size_t k = 0;
k < C_cal_vars.size(); ++
k) {
1803 fFullSelectionVars[
"dEdX_Cal_Spline"][it->first].push_back((TH1D*)it->second->Clone(shift_name.c_str()));
1807 if (shift_number == 0)
1811 sel_hist_name +=
"_FullVar";
1812 full_hists[it->first] = (TH1D*)it->second->Clone(sel_hist_name.c_str());
1813 full_hists[it->first]->Reset();
1816 for (
size_t i = 0; i < events.size(); ++i) {
1818 int sample_ID =
event.GetSampleID();
1821 std::vector<int> new_selection_IDs;
1822 for (
double c : C_cal_vars) {
1829 new_selection_IDs.push_back(new_selection_ID);
1836 double reco_beam_endZ =
event.GetRecoEndZ();
1838 const std::vector<double> & reco_beam_incidentEnergies
1839 =
event.GetRecoIncidentEnergies();
1840 double beam_inst_P =
event.GetBeamInstP();
1841 const std::vector<double> calibrated_dQdX
1842 =
event.GetdQdXCalibrated();
1843 const std::vector<double> beam_EField
1844 =
event.GetEField();
1845 const std::vector<double> track_pitch
1846 =
event.GetTrackPitch();
1849 if (samples.find(sample_ID) == samples.end()) {
1850 std::cout <<
"Warning: skipping sample " << sample_ID <<
std::endl;
1854 std::vector<double> vals(C_cal_vars.size(), 0.);
1855 for (
size_t j = 0; j < vals.size(); ++j) {
1856 int new_selection_ID = new_selection_IDs[j];
1857 if (new_selection_ID == 4) {
1858 TH1D * selected_hist
1860 if (selected_hist->FindBin(reco_beam_endZ) == 0) {
1862 vals[j] = selected_hist->GetBinCenter(1);
1864 else if (selected_hist->FindBin(reco_beam_endZ) >
1865 selected_hist->GetNbinsX()) {
1868 vals[j] = selected_hist->GetBinCenter(selected_hist->GetNbinsX());
1872 vals[j] = reco_beam_endZ;
1875 else if (new_selection_ID > 4) {
1879 else if (reco_beam_incidentEnergies.size()) {
1881 double energy = sqrt(beam_inst_P*beam_inst_P*1.e6 + 139.57*139.57) -
1884 for (
size_t k = 0;
k < calibrated_dQdX.size()-1; ++
k) {
1885 if ((calibrated_dQdX)[
k] < 0.)
continue;
1887 double dedx = (C_cal_vars[j]);
1888 dedx *= (calibrated_dQdX)[
k];
1896 energy -= dedx*(track_pitch)[
k];
1899 TH1D * selected_hist
1901 if (selected_hist->FindBin(energy) == 0) {
1902 vals[j] = selected_hist->GetBinCenter(1);
1904 else if (selected_hist->FindBin(energy) >
1905 selected_hist->GetNbinsX()) {
1906 vals[j] = selected_hist->GetBinCenter(selected_hist->GetNbinsX());
1914 TH1D * selected_hist
1917 vals[j] = selected_hist->GetBinCenter(1);
1925 C_cal_vars.insert(C_cal_vars.begin() + C_cal_vars.size()/2,
1926 pars.at(
"dEdX_Cal_Spline").GetCentral());
1928 TDirectory *
dir = output_file.mkdir(
"dEdX_Cal_Spline_Syst");
1937 for (
auto it2 = samples.begin(); it2 != samples.end(); ++it2) {
1938 for (
size_t i = 0; i < it2->second.size(); ++i) {
1939 for (
size_t j = 0; j < it2->second[i].size(); ++j) {
1940 full_hists[
selection_ID]->Add(it2->second[i][j].GetSelectionHist(
1946 for (
size_t i = 0; i < it->second.size(); ++i) {
1947 it->second[i]->Write();
1948 it->second[i]->Divide(full_hists[selection_ID]);
1952 for (
int i = 1; i <= full_hists[
selection_ID]->GetNbinsX(); ++i) {
1953 std::vector<double> vals;
1954 for (
size_t j = 0; j < it->second.size(); ++j) {
1955 vals.push_back(it->second[j]->GetBinContent(i));
1957 vals.insert(vals.begin() + vals.size()/2, 1.);
1963 new TSpline3(spline_name.c_str(), &C_cal_vars[0], &vals[0], vals.size()));
1964 TCanvas
c(spline_name.c_str(),
"");
1974 const std::vector<ThinSliceEvent> &
events,
1975 std::map<
int,
std::vector<std::vector<ThinSliceSample>>> & samples,
1976 const std::map<std::string, ThinSliceSystematic> & pars,
1979 if (pars.find(
"beam_shift_spline_2") == pars.end()) {
1985 std::vector<double> beam_shift_vals
1986 = pars.at(
"beam_shift_spline_2").GetOption<std::vector<double>>(
"ShiftVals");
1990 if (beam_shift_vals.size() % 2) {
1992 message +=
"odd number of shifts to reco momentum";
1993 throw std::runtime_error(message);
1998 std::map<int, TH1D*> full_hists;
2002 for (
auto it = sel_hists.begin(); it != sel_hists.end(); ++it) {
2003 std::string sel_hist_name = it->second->GetName();
2004 sel_hist_name +=
"Syst_BeamShiftSpline2";
2005 int shift_number = -2;
2008 for (
size_t k = 0;
k < beam_shift_vals.size(); ++
k) {
2011 fFullSelectionVars[
"BeamShiftSpline2"][it->first].push_back((TH1D*)it->second->Clone(shift_name.c_str()));
2015 if (shift_number == 0)
2019 sel_hist_name +=
"_FullVar";
2020 full_hists[it->first] = (TH1D*)it->second->Clone(sel_hist_name.c_str());
2021 full_hists[it->first]->Reset();
2024 for (
size_t i = 0; i < events.size(); ++i) {
2026 int sample_ID =
event.GetSampleID();
2029 double reco_beam_endZ =
event.GetRecoEndZ();
2031 const std::vector<double> & reco_beam_incidentEnergies
2032 =
event.GetRecoIncidentEnergies();
2033 double beam_inst_P =
event.GetBeamInstP();
2034 const std::vector<double> calibrated_dQdX
2035 =
event.GetdQdXCalibrated();
2036 const std::vector<double> beam_EField
2037 =
event.GetEField();
2038 const std::vector<double> track_pitch
2039 =
event.GetTrackPitch();
2042 if (samples.find(sample_ID) == samples.end()) {
2043 std::cout <<
"Warning: skipping sample " << sample_ID <<
std::endl;
2047 std::vector<double> vals(beam_shift_vals.size(), 0.);
2048 for (
size_t j = 0; j < vals.size(); ++j) {
2049 if (selection_ID == 4) {
2050 TH1D * selected_hist
2052 if (selected_hist->FindBin(reco_beam_endZ) == 0) {
2053 vals[j] = selected_hist->GetBinCenter(1);
2055 else if (selected_hist->FindBin(reco_beam_endZ) >
2056 selected_hist->GetNbinsX()) {
2057 vals[j] = selected_hist->GetBinCenter(selected_hist->GetNbinsX());
2060 vals[j] = reco_beam_endZ;
2063 else if (selection_ID > 4) {
2066 else if (reco_beam_incidentEnergies.size()) {
2070 = sqrt(
std::pow(beam_inst_P*beam_shift_vals[j], 2)*1.e6 +
2071 139.57*139.57) - 139.57;
2074 for (
size_t k = 1;
k < reco_beam_incidentEnergies.size(); ++
k) {
2075 double deltaE = (reco_beam_incidentEnergies[
k-1] -
2076 reco_beam_incidentEnergies[
k]);
2084 TH1D * selected_hist
2086 if (selected_hist->FindBin(energy) == 0) {
2087 vals[j] = selected_hist->GetBinCenter(1);
2089 else if (selected_hist->FindBin(energy) >
2090 selected_hist->GetNbinsX()) {
2091 vals[j] = selected_hist->GetBinCenter(selected_hist->GetNbinsX());
2098 TH1D * selected_hist
2100 vals[j] = selected_hist->GetBinCenter(1);
2106 beam_shift_vals.insert(beam_shift_vals.begin() + beam_shift_vals.size()/2,
2107 pars.at(
"beam_shift_spline_2").GetCentral());
2109 TDirectory *
dir = output_file.mkdir(
"BeamShiftSpline2_Syst");
2118 for (
auto it2 = samples.begin(); it2 != samples.end(); ++it2) {
2119 for (
size_t i = 0; i < it2->second.size(); ++i) {
2120 for (
size_t j = 0; j < it2->second[i].size(); ++j) {
2121 full_hists[
selection_ID]->Add(it2->second[i][j].GetSelectionHist(
2127 for (
size_t i = 0; i < it->second.size(); ++i) {
2128 it->second[i]->Write();
2129 it->second[i]->Divide(full_hists[selection_ID]);
2133 for (
int i = 1; i <= full_hists[
selection_ID]->GetNbinsX(); ++i) {
2134 std::vector<double> vals;
2135 for (
size_t j = 0; j < it->second.size(); ++j) {
2136 vals.push_back(it->second[j]->GetBinContent(i));
2138 vals.insert(vals.begin() + vals.size()/2, 1.);
2144 new TSpline3(spline_name.c_str(), &beam_shift_vals[0], &vals[0], vals.size()));
2145 TCanvas
c(spline_name.c_str(),
"");
2155 const std::vector<ThinSliceEvent> &
events,
2156 std::map<
int,
std::vector<std::vector<ThinSliceSample>>> & samples,
2157 const std::map<std::string, ThinSliceSystematic> & pars,
2159 if (pars.find(
"beam_shift_ratio") == pars.end()) {
2165 int nBins = pars.at(
"beam_shift_ratio").GetOption<
int>(
"nBins");
2166 std::pair<double, double> binning
2167 = pars.at(
"beam_shift_ratio").GetOption<std::pair<double, double>>(
2170 binning.first, binning.second);
2171 std::vector<double> vals
2172 = pars.at(
"beam_shift_ratio").GetOption<std::vector<double>>(
"Vals");
2174 std::vector<TH1D*> var_hists;
2175 for (
size_t i = 0; i < vals.size(); ++i) {
2177 var_hists.push_back(
new TH1D(name.c_str(),
"",
nBins,
2178 binning.first, binning.second));
2181 for (
size_t i = 0; i < events.size(); ++i) {
2183 double beam_inst_P =
event.GetBeamInstP();
2184 fBeamShiftRatioNomHist.Fill(beam_inst_P);
2185 for (
size_t j = 0; j < vals.size(); ++j) {
2186 var_hists[j]->Fill(vals[j]*beam_inst_P);
2190 TDirectory *
dir = output_file.mkdir(
"BeamShiftRatio_Syst");
2193 for (
int i = 0; i < nBins + 2; ++i) {
2194 std::vector<double> ratios;
2195 for (
size_t j = 0; j < var_hists.size(); ++j) {
2197 fBeamShiftRatioNomHist.GetBinContent(i)/
2198 var_hists[j]->GetBinContent(i));
2202 fBeamShiftRatioSplines.push_back(
2203 new TSpline3(name.c_str(), &vals[0], &ratios[0], ratios.size()));
2205 TCanvas
c(name.c_str(),
"");
2206 fBeamShiftRatioSplines.back()->SetMarkerStyle(20);
2207 fBeamShiftRatioSplines.back()->Draw(
"P");
2215 const std::map<std::string, ThinSliceSystematic> & pars,
2220 if (std::isnan(pars.at(
s).GetValue())) {
2223 message +=
" has nan value";
2224 throw std::runtime_error(message);
2228 std::cout <<
"G4RW turned negative for " <<
s <<
std::endl;
2233 std::cout <<
"Warning: returning negative value for event " <<
2234 event.GetEventID() <<
" " <<
event.GetSubrunID() <<
" " <<
2242 const std::map<std::string, ThinSliceSystematic> & pars) {
2243 if (pars.find(
"beam_shift") == pars.end())
return 1.;
2244 if (event.
GetPDG() != 211)
return 1.;
2245 double x_val = pars.at(
"beam_shift").GetValue();
2246 double y_val = (
event.GetBeamInstP() -
event.GetTrueStartP())/
2248 if (y_val < fSystBeamShiftLimits.first/*fSystBeamShiftMap->GetYmin()*/ ||
2276 double weight = (nominal_width/varied_width)*
2277 exp(.5*
std::pow(((y_val - nominal_mean)/nominal_width), 2)
2278 - .5*
std::pow(((y_val - varied_mean)/varied_width), 2));
2350 double reco_beam_interactingEnergy, reco_beam_endZ;
2351 std::vector<double> * reco_beam_incidentEnergies = 0x0;
2352 tree->SetBranchAddress(
"selection_ID", &selection_ID);
2353 tree->SetBranchAddress(
"reco_beam_interactingEnergy",
2354 &reco_beam_interactingEnergy);
2355 tree->SetBranchAddress(
"reco_beam_endZ", &reco_beam_endZ);
2356 tree->SetBranchAddress(
"reco_beam_incidentEnergies",
2357 &reco_beam_incidentEnergies);
2359 tree->SetBranchAddress(
"beam_inst_P", &beam_inst_P);
2364 flux = tree->GetEntries() - split_val;
2366 for (
int i = split_val; i < tree->GetEntries(); ++i) {
2370 if (selection_ID == 4) {
2371 if (selected_hists[selection_ID]->
FindBin(reco_beam_endZ) == 0) {
2374 else if (selected_hists[selection_ID]->
FindBin(reco_beam_endZ) >
2375 selected_hists[selection_ID]->GetNbinsX()) {
2377 selected_hists[selection_ID]->GetNbinsX());
2380 val = reco_beam_endZ;
2383 else if (selection_ID > 4) {
2386 else if (reco_beam_incidentEnergies->size()) {
2387 for (
size_t j = 0; j < reco_beam_incidentEnergies->size(); ++j) {
2388 incident_hist.Fill((*reco_beam_incidentEnergies)[j]);
2390 if (selected_hists.find(selection_ID) != selected_hists.end()) {
2391 if (selection_ID != 4 && selection_ID != 5 && selection_ID != 6) {
2392 double energy = reco_beam_interactingEnergy;
2394 for (
size_t k = 1;
k < reco_beam_incidentEnergies->size(); ++
k) {
2395 double deltaE = ((*reco_beam_incidentEnergies)[
k-1] -
2396 (*reco_beam_incidentEnergies)[
k]);
2402 if (selected_hists[selection_ID]->
FindBin(energy) == 0) {
2405 else if (selected_hists[selection_ID]->
FindBin(energy) >
2406 selected_hists[selection_ID]->GetNbinsX()) {
2408 selected_hists[selection_ID]->GetNbinsX());
2427 std::map<
int,
std::vector<std::vector<ThinSliceSample>>> & samples,
2428 const std::map<int, bool> & signal_sample_checks,
2430 std::map<
int, std::vector<double>> & sample_scales,
2431 std::vector<double> & beam_energy_bins,
2434 if (routine ==
"SampleScales") {
2436 sample_scales, split_val);
2438 else if (routine ==
"G4RW") {
2439 FakeDataG4RW(tree, samples, signal_sample_checks, data_set, flux,
2440 sample_scales, split_val);
2442 else if (routine ==
"G4RWGrid") {
2444 sample_scales, beam_energy_bins,
2447 else if (routine ==
"EffVar") {
2448 FakeDataEffVar(tree, samples, signal_sample_checks, data_set, flux,
2449 sample_scales, split_val);
2451 else if (routine ==
"BinnedScales") {
2453 sample_scales, split_val);
2455 else if (routine ==
"dEdX") {
2456 FakeDatadEdX(tree, samples, signal_sample_checks, data_set, flux,
2457 sample_scales, split_val);
2459 else if (routine ==
"PionAngle") {
2461 sample_scales, split_val);
2463 else if (routine ==
"AngleVar") {
2465 sample_scales, split_val);
2467 else if (routine ==
"BeamWeight") {
2469 sample_scales, split_val);
2475 std::map<
int,
std::vector<std::vector<ThinSliceSample>>> & samples,
2476 const std::map<int, bool> & signal_sample_checks,
2478 std::map<
int, std::vector<double>> & sample_scales,
2483 std::vector<std::pair<int, double>> temp_vec
2486 std::map<int, double> fake_data_scales(temp_vec.begin(), temp_vec.end());
2489 double true_beam_interactingEnergy, reco_beam_interactingEnergy;
2490 double true_beam_endP;
2491 std::vector<double> * reco_beam_incidentEnergies = 0x0,
2492 * true_beam_traj_KE = 0x0,
2493 * true_beam_traj_Z = 0x0;
2494 std::vector<int> * true_beam_slices = 0x0;
2495 double reco_beam_endZ;
2496 tree->SetBranchAddress(
"reco_beam_endZ", &reco_beam_endZ);
2497 tree->SetBranchAddress(
"new_interaction_topology", &sample_ID);
2498 tree->SetBranchAddress(
"selection_ID", &selection_ID);
2499 tree->SetBranchAddress(
"true_beam_interactingEnergy",
2500 &true_beam_interactingEnergy);
2501 tree->SetBranchAddress(
"true_beam_endP", &true_beam_endP);
2502 tree->SetBranchAddress(
"true_beam_traj_Z", &true_beam_traj_Z);
2503 tree->SetBranchAddress(
"true_beam_traj_KE", &true_beam_traj_KE);
2504 tree->SetBranchAddress(
"true_beam_slices", &true_beam_slices);
2505 tree->SetBranchAddress(
"reco_beam_interactingEnergy",
2506 &reco_beam_interactingEnergy);
2507 tree->SetBranchAddress(
"reco_beam_incidentEnergies",
2508 &reco_beam_incidentEnergies);
2509 std::vector<double> * true_beam_incidentEnergies = 0x0;
2510 tree->SetBranchAddress(
"true_beam_incidentEnergies",
2511 &true_beam_incidentEnergies);
2516 double new_flux = 0.;
2517 flux = tree->GetEntries() - split_val;
2519 std::map<int, std::vector<double>> nominal_samples;
2520 for (
auto it = sample_scales.begin(); it != sample_scales.end(); ++it) {
2521 nominal_samples[it->first] = std::vector<double>(it->second.size(), 0.);
2524 for (
int i = split_val; i < tree->GetEntries(); ++i) {
2527 double end_energy = true_beam_interactingEnergy;
2529 end_energy = sqrt(true_beam_endP*true_beam_endP*1.e6 + 139.57*139.57) - 139.57;
2532 end_energy = sqrt(true_beam_endP*true_beam_endP*1.e6 + 139.57*139.57) - 139.57;
2535 int bin =
fEndSlices->GetXaxis()->FindBin(true_beam_traj_Z->back());
2537 end_energy =
fMeans.at(bin);
2541 if (samples.find(sample_ID) == samples.end())
2544 double scale = (fake_data_scales.find(sample_ID) != fake_data_scales.end() ?
2545 fake_data_scales.at(sample_ID) : 1.);
2549 bool is_signal = signal_sample_checks.at(sample_ID);
2552 std::vector<ThinSliceSample> & samples_vec = samples[sample_ID][0];
2555 for (
size_t j = 1; j < samples_vec.size()-1; ++j) {
2559 sample_scales[sample_ID][j] += scale;
2560 nominal_samples[sample_ID][j] += 1.;
2561 this_sample = &sample;
2568 if (end_energy < samples_vec[1].RangeLowEnd()) {
2569 this_sample = &samples_vec[0];
2570 sample_scales[sample_ID][0] += scale;
2571 nominal_samples[sample_ID][0] += 1.;
2573 else if (end_energy >
2574 samples_vec[samples_vec.size()-2].RangeHighEnd()) {
2576 this_sample = &samples_vec.back();
2577 sample_scales[sample_ID].back() += scale;
2578 nominal_samples[sample_ID].back() += 1.;
2583 sample_scales[sample_ID][0] += scale;
2584 nominal_samples[sample_ID][0] += 1.;
2585 this_sample = &samples[sample_ID][0][0];
2592 if (selection_ID == 4) {
2593 if (selected_hists[selection_ID]->
FindBin(reco_beam_endZ) == 0) {
2596 else if (selected_hists[selection_ID]->
FindBin(reco_beam_endZ) >
2597 selected_hists[selection_ID]->GetNbinsX()) {
2599 selected_hists[selection_ID]->GetNbinsX());
2602 val = reco_beam_endZ;
2605 else if (selection_ID > 4) {
2608 else if (reco_beam_incidentEnergies->size()) {
2609 for (
size_t j = 0; j < reco_beam_incidentEnergies->size(); ++j) {
2610 incident_hist.Fill((*reco_beam_incidentEnergies)[j]);
2612 if (selected_hists.find(selection_ID) != selected_hists.end()) {
2613 if (selection_ID != 4 && selection_ID != 5 && selection_ID != 6) {
2614 double energy = reco_beam_interactingEnergy;
2616 for (
size_t k = 1;
k < reco_beam_incidentEnergies->size(); ++
k) {
2617 double deltaE = ((*reco_beam_incidentEnergies)[
k-1] -
2618 (*reco_beam_incidentEnergies)[
k]);
2624 if (selected_hists[selection_ID]->
FindBin(energy) == 0) {
2627 else if (selected_hists[selection_ID]->
FindBin(energy) >
2628 selected_hists[selection_ID]->GetNbinsX()) {
2630 selected_hists[selection_ID]->GetNbinsX());
2644 *true_beam_traj_Z, *true_beam_traj_KE, *true_beam_slices,
2645 *true_beam_incidentEnergies);
2686 for (
auto it = sample_scales.begin(); it != sample_scales.end(); ++it) {
2687 for (
size_t i = 0; i < it->second.size(); ++i) {
2688 if (it->second[i] > 0.) {
2689 it->second[i] /= nominal_samples[it->first][i];
2694 it->second[i] *= (flux/new_flux);
2698 incident_hist.Scale(flux/new_flux);
2699 for (
auto it = selected_hists.begin(); it != selected_hists.end(); ++it) {
2700 it->second->Scale(flux/new_flux);
2706 std::map<
int,
std::vector<std::vector<ThinSliceSample>>> & samples,
2707 const std::map<int, bool> & signal_sample_checks,
2709 std::map<
int, std::vector<double>> & sample_scales,
int split_val) {
2712 std::vector<std::pair<int, std::vector<double>>> temp_vec
2714 "FakeDataBinnedScales");
2715 std::map<int, std::vector<double>> fake_data_scales(temp_vec.begin(), temp_vec.end());
2718 double true_beam_interactingEnergy, reco_beam_interactingEnergy;
2719 double true_beam_endP;
2720 std::vector<double> * reco_beam_incidentEnergies = 0x0,
2721 * true_beam_traj_KE = 0x0,
2722 * true_beam_traj_Z = 0x0;
2723 std::vector<int> * true_beam_slices = 0x0;
2724 double reco_beam_endZ;
2725 tree->SetBranchAddress(
"reco_beam_endZ", &reco_beam_endZ);
2726 tree->SetBranchAddress(
"new_interaction_topology", &sample_ID);
2727 tree->SetBranchAddress(
"selection_ID", &selection_ID);
2728 tree->SetBranchAddress(
"true_beam_interactingEnergy",
2729 &true_beam_interactingEnergy);
2730 tree->SetBranchAddress(
"true_beam_endP", &true_beam_endP);
2731 tree->SetBranchAddress(
"true_beam_traj_KE", &true_beam_traj_KE);
2732 tree->SetBranchAddress(
"true_beam_slices", &true_beam_slices);
2733 tree->SetBranchAddress(
"true_beam_traj_Z", &true_beam_traj_Z);
2734 tree->SetBranchAddress(
"reco_beam_interactingEnergy",
2735 &reco_beam_interactingEnergy);
2736 tree->SetBranchAddress(
"reco_beam_incidentEnergies",
2737 &reco_beam_incidentEnergies);
2738 std::vector<double> * true_beam_incidentEnergies = 0x0;
2739 tree->SetBranchAddress(
"true_beam_incidentEnergies",
2740 &true_beam_incidentEnergies);
2746 double new_flux = 0.;
2747 flux = tree->GetEntries() - split_val;
2749 std::map<int, std::vector<double>> nominal_samples;
2750 for (
auto it = sample_scales.begin(); it != sample_scales.end(); ++it) {
2751 nominal_samples[it->first] = std::vector<double>(it->second.size(), 0.);
2754 for (
int i = split_val; i < tree->GetEntries(); ++i) {
2757 double end_energy = true_beam_interactingEnergy;
2759 end_energy = sqrt(true_beam_endP*true_beam_endP*1.e6 + 139.57*139.57) - 139.57;
2762 end_energy = sqrt(true_beam_endP*true_beam_endP*1.e6 + 139.57*139.57) - 139.57;
2765 int bin =
fEndSlices->GetXaxis()->FindBin(true_beam_traj_Z->back());
2767 end_energy =
fMeans.at(bin);
2772 if (samples.find(sample_ID) == samples.end())
2776 bool is_scaled = (fake_data_scales.find(sample_ID) !=
2777 fake_data_scales.end());
2781 bool is_signal = signal_sample_checks.at(sample_ID);
2784 std::vector<ThinSliceSample> & samples_vec = samples[sample_ID][0];
2787 for (
size_t j = 1; j < samples_vec.size()-1; ++j) {
2792 scale = fake_data_scales.at(sample_ID)[j];
2793 sample_scales[sample_ID][j] += scale;
2794 nominal_samples[sample_ID][j] += 1.;
2796 this_sample = &sample;
2801 if (end_energy < samples_vec[1].RangeLowEnd()) {
2802 this_sample = &samples_vec[0];
2804 scale = fake_data_scales.at(sample_ID)[0];
2805 sample_scales[sample_ID][0] += scale;
2806 nominal_samples[sample_ID][0] += 1.;
2809 else if (end_energy >
2810 samples_vec[samples_vec.size()-2].RangeHighEnd()) {
2811 this_sample = &samples_vec.back();
2813 scale = fake_data_scales.at(sample_ID).back();
2814 sample_scales[sample_ID].back() += scale;
2815 nominal_samples[sample_ID].back() += 1.;
2822 scale = fake_data_scales.at(sample_ID)[0];
2823 sample_scales[sample_ID][0] += scale;
2824 nominal_samples[sample_ID][0] += 1.;
2826 this_sample = &samples[sample_ID][0][0];
2833 if (selection_ID == 4) {
2834 if (selected_hists[selection_ID]->
FindBin(reco_beam_endZ) == 0) {
2837 else if (selected_hists[selection_ID]->
FindBin(reco_beam_endZ) >
2838 selected_hists[selection_ID]->GetNbinsX()) {
2840 selected_hists[selection_ID]->GetNbinsX());
2843 val = reco_beam_endZ;
2846 else if (selection_ID > 4) {
2849 else if (reco_beam_incidentEnergies->size()) {
2850 for (
size_t j = 0; j < reco_beam_incidentEnergies->size(); ++j) {
2851 incident_hist.Fill((*reco_beam_incidentEnergies)[j]);
2853 if (selected_hists.find(selection_ID) != selected_hists.end()) {
2854 if (selection_ID != 4 && selection_ID != 5 && selection_ID != 6) {
2855 double energy = reco_beam_interactingEnergy;
2857 for (
size_t k = 1;
k < reco_beam_incidentEnergies->size(); ++
k) {
2858 double deltaE = ((*reco_beam_incidentEnergies)[
k-1] -
2859 (*reco_beam_incidentEnergies)[
k]);
2865 if (selected_hists[selection_ID]->
FindBin(energy) == 0) {
2868 else if (selected_hists[selection_ID]->
FindBin(energy) >
2869 selected_hists[selection_ID]->GetNbinsX()) {
2871 selected_hists[selection_ID]->GetNbinsX());
2885 *true_beam_traj_Z, *true_beam_traj_KE, *true_beam_slices,
2886 *true_beam_incidentEnergies);
2927 for (
auto it = sample_scales.begin(); it != sample_scales.end(); ++it) {
2928 for (
size_t i = 0; i < it->second.size(); ++i) {
2929 if (it->second[i] > 0.) {
2930 it->second[i] /= nominal_samples[it->first][i];
2935 it->second[i] *= (flux/new_flux);
2941 incident_hist.Scale(flux/new_flux);
2942 for (
auto it = selected_hists.begin(); it != selected_hists.end(); ++it) {
2943 it->second->Scale(flux/new_flux);
2949 std::map<
int,
std::vector<std::vector<ThinSliceSample>>> & samples,
2950 const std::map<int, bool> & signal_sample_checks,
2952 std::map<
int, std::vector<double>> & sample_scales,
2960 double true_beam_interactingEnergy, reco_beam_interactingEnergy;
2961 double true_beam_endP;
2962 std::vector<double> * reco_beam_incidentEnergies = 0x0;
2963 double reco_beam_endZ;
2964 std::vector<double> * g4rw_weight = 0x0;
2965 tree->SetBranchAddress(
"reco_beam_endZ", &reco_beam_endZ);
2966 tree->SetBranchAddress(
"new_interaction_topology", &sample_ID);
2967 tree->SetBranchAddress(
"selection_ID", &selection_ID);
2968 tree->SetBranchAddress(
"true_beam_interactingEnergy",
2969 &true_beam_interactingEnergy);
2970 tree->SetBranchAddress(
"true_beam_endP", &true_beam_endP);
2971 tree->SetBranchAddress(
"reco_beam_interactingEnergy",
2972 &reco_beam_interactingEnergy);
2973 tree->SetBranchAddress(
"reco_beam_incidentEnergies",
2974 &reco_beam_incidentEnergies);
2975 std::vector<double> * true_beam_traj_Z = 0x0,
2976 * true_beam_traj_KE = 0x0;
2977 std::vector<int> * true_beam_slices = 0x0;
2978 tree->SetBranchAddress(
"true_beam_traj_Z", &true_beam_traj_Z);
2979 tree->SetBranchAddress(
"true_beam_traj_KE", &true_beam_traj_KE);
2980 tree->SetBranchAddress(
"true_beam_slices", &true_beam_slices);
2981 std::vector<double> * true_beam_incidentEnergies = 0x0;
2982 tree->SetBranchAddress(
"true_beam_incidentEnergies",
2983 &true_beam_incidentEnergies);
2985 if (g4rw_options.
get<
int>(
"Shift") > 0) {
2986 if (g4rw_options.
get<
bool>(
"Full")) {
2987 std::cout <<
"Full weight" <<
std::endl;
2988 tree->SetBranchAddress(
"g4rw_full_primary_plus_sigma_weight", &g4rw_weight);
2991 tree->SetBranchAddress(
"g4rw_alt_primary_plus_sigma_weight", &g4rw_weight);
2995 if (g4rw_options.
get<
bool>(
"Full")) {
2996 std::cout <<
"Full weight" <<
std::endl;
2997 tree->SetBranchAddress(
"g4rw_full_primary_minus_sigma_weight", &g4rw_weight);
3000 tree->SetBranchAddress(
"g4rw_alt_primary_minus_sigma_weight", &g4rw_weight);
3004 size_t g4rw_pos = g4rw_options.
get<
size_t>(
"Position");
3009 double new_flux = 0.;
3010 flux = tree->GetEntries() - split_val;
3013 std::map<int, std::vector<double>> nominal_samples;
3014 for (
auto it = sample_scales.begin(); it != sample_scales.end(); ++it) {
3015 nominal_samples[it->first] = std::vector<double>(it->second.size(), 0.);
3018 for (
int i = split_val; i < tree->GetEntries(); ++i) {
3021 if (samples.find(sample_ID) == samples.end())
3024 double end_energy = true_beam_interactingEnergy;
3026 end_energy = sqrt(true_beam_endP*true_beam_endP*1.e6 + 139.57*139.57) - 139.57;
3029 end_energy = sqrt(true_beam_endP*true_beam_endP*1.e6 + 139.57*139.57) - 139.57;
3032 int bin =
fEndSlices->GetXaxis()->FindBin(true_beam_traj_Z->back());
3034 end_energy =
fMeans.at(bin);
3039 if (g4rw_weight->size() > 0) {
3040 scale = g4rw_weight->at(g4rw_pos);
3043 bool is_signal = signal_sample_checks.at(sample_ID);
3046 std::vector<ThinSliceSample> & samples_vec = samples[sample_ID][0];
3049 for (
size_t j = 1; j < samples_vec.size()-1; ++j) {
3053 sample_scales[sample_ID][j] += scale;
3054 nominal_samples[sample_ID][j] += 1.;
3055 this_sample = &sample;
3060 if (end_energy < samples_vec[1].RangeLowEnd()) {
3061 sample_scales[sample_ID][0] += scale;
3062 nominal_samples[sample_ID][0] += 1.;
3063 this_sample = &samples_vec[0];
3065 else if (end_energy >
3066 samples_vec[samples_vec.size()-2].RangeHighEnd()) {
3067 this_sample = &samples_vec.back();
3068 sample_scales[sample_ID].back() += scale;
3069 nominal_samples[sample_ID].back() += 1.;
3074 this_sample = &samples[sample_ID][0][0];
3075 sample_scales[sample_ID][0] += scale;
3076 nominal_samples[sample_ID][0] += 1.;
3081 if (selection_ID == 4) {
3082 if (selected_hists[selection_ID]->
FindBin(reco_beam_endZ) == 0) {
3085 else if (selected_hists[selection_ID]->
FindBin(reco_beam_endZ) >
3086 selected_hists[selection_ID]->GetNbinsX()) {
3088 selected_hists[selection_ID]->GetNbinsX());
3091 val = reco_beam_endZ;
3094 else if (selection_ID > 4) {
3097 else if (reco_beam_incidentEnergies->size()) {
3098 for (
size_t j = 0; j < reco_beam_incidentEnergies->size(); ++j) {
3099 incident_hist.Fill((*reco_beam_incidentEnergies)[j]);
3101 if (selected_hists.find(selection_ID) != selected_hists.end()) {
3102 if (selection_ID != 4 && selection_ID != 5 && selection_ID != 6) {
3103 double energy = reco_beam_interactingEnergy;
3105 for (
size_t k = 1;
k < reco_beam_incidentEnergies->size(); ++
k) {
3106 double deltaE = ((*reco_beam_incidentEnergies)[
k-1] -
3107 (*reco_beam_incidentEnergies)[
k]);
3113 if (selected_hists[selection_ID]->
FindBin(energy) == 0) {
3116 else if (selected_hists[selection_ID]->
FindBin(energy) >
3117 selected_hists[selection_ID]->GetNbinsX()) {
3119 selected_hists[selection_ID]->GetNbinsX());
3134 *true_beam_traj_Z, *true_beam_traj_KE, *true_beam_slices,
3135 *true_beam_incidentEnergies);
3175 for (
auto it = sample_scales.begin(); it != sample_scales.end(); ++it) {
3176 for (
size_t i = 0; i < it->second.size(); ++i) {
3177 if (it->second[i] > 0.) {
3178 it->second[i] /= nominal_samples[it->first][i];
3183 it->second[i] *= (flux/new_flux);
3187 incident_hist.Scale(flux/new_flux);
3188 for (
auto it = selected_hists.begin(); it != selected_hists.end(); ++it) {
3189 it->second->Scale(flux/new_flux);
3197 std::map<
int,
std::vector<std::vector<ThinSliceSample>>> & samples,
3198 const std::map<int, bool> & signal_sample_checks,
3200 std::map<
int, std::vector<double>> & sample_scales,
3201 std::vector<double> & beam_energy_bins,
3209 double true_beam_interactingEnergy, reco_beam_interactingEnergy;
3210 double true_beam_startP, true_beam_endP;
3211 std::vector<double> * reco_beam_incidentEnergies = 0x0;
3212 double reco_beam_endZ;
3213 tree->SetBranchAddress(
"reco_beam_endZ", &reco_beam_endZ);
3214 tree->SetBranchAddress(
"new_interaction_topology", &sample_ID);
3215 tree->SetBranchAddress(
"selection_ID", &selection_ID);
3216 tree->SetBranchAddress(
"true_beam_interactingEnergy",
3217 &true_beam_interactingEnergy);
3218 tree->SetBranchAddress(
"true_beam_endP", &true_beam_endP);
3219 tree->SetBranchAddress(
"reco_beam_interactingEnergy",
3220 &reco_beam_interactingEnergy);
3221 tree->SetBranchAddress(
"reco_beam_incidentEnergies",
3222 &reco_beam_incidentEnergies);
3223 tree->SetBranchAddress(
"true_beam_startP", &true_beam_startP);
3224 std::vector<double> * true_beam_traj_Z = 0x0,
3225 * true_beam_traj_KE = 0x0;
3226 std::vector<int> * true_beam_slices = 0x0;
3227 tree->SetBranchAddress(
"true_beam_traj_Z", &true_beam_traj_Z);
3228 tree->SetBranchAddress(
"true_beam_traj_KE", &true_beam_traj_KE);
3229 tree->SetBranchAddress(
"true_beam_slices", &true_beam_slices);
3230 std::vector<double> * true_beam_incidentEnergies = 0x0;
3231 tree->SetBranchAddress(
"true_beam_incidentEnergies",
3232 &true_beam_incidentEnergies);
3235 std::vector<std::vector<double>> * g4rw_full_grid_weights = 0x0;
3237 tree->SetBranchAddress(branch.c_str(), &g4rw_full_grid_weights);
3241 std::vector<size_t> g4rw_pos = g4rw_options.
get<std::vector<size_t>>(
"Position");
3242 std::vector<size_t> g4rw_shift = g4rw_options.
get<std::vector<size_t>>(
"Shift");
3247 double new_flux = 0.;
3248 flux = tree->GetEntries() - split_val;
3251 std::map<int, std::vector<double>> nominal_samples;
3252 for (
auto it = sample_scales.begin(); it != sample_scales.end(); ++it) {
3253 nominal_samples[it->first] = std::vector<double>(it->second.size(), 0.);
3256 for (
int i = split_val; i < tree->GetEntries(); ++i) {
3259 if (samples.find(sample_ID) == samples.end())
3262 double end_energy = true_beam_interactingEnergy;
3264 end_energy = sqrt(true_beam_endP*true_beam_endP*1.e6 + 139.57*139.57) - 139.57;
3267 end_energy = sqrt(true_beam_endP*true_beam_endP*1.e6 + 139.57*139.57) - 139.57;
3270 int bin =
fEndSlices->GetXaxis()->FindBin(true_beam_traj_Z->back());
3272 end_energy =
fMeans.at(bin);
3284 if (g4rw_full_grid_weights->size() > 0) {
3285 for (
size_t j = 0; j < g4rw_pos.size(); ++j) {
3286 size_t pos = g4rw_pos[j];
3287 size_t shift = g4rw_shift[j];
3288 if ((*g4rw_full_grid_weights)[
pos].size() > 0) {
3289 scale *= (*g4rw_full_grid_weights)[
pos][shift];
3312 bool is_signal = signal_sample_checks.at(sample_ID);
3315 std::vector<ThinSliceSample> & samples_vec = samples[sample_ID][
bin];
3318 for (
size_t j = 1; j < samples_vec.size()-1; ++j) {
3322 sample_scales[sample_ID][j] += scale;
3323 nominal_samples[sample_ID][j] += 1.;
3324 this_sample = &sample;
3329 if (end_energy < samples_vec[1].RangeLowEnd()) {
3330 sample_scales[sample_ID][0] += scale;
3331 nominal_samples[sample_ID][0] += 1.;
3332 this_sample = &samples_vec[0];
3334 else if (end_energy >
3335 samples_vec[samples_vec.size()-2].RangeHighEnd()) {
3336 this_sample = &samples_vec.back();
3337 sample_scales[sample_ID].back() += scale;
3338 nominal_samples[sample_ID].back() += 1.;
3341 std::cout <<
"Could not find the sample" <<
std::endl;
3346 this_sample = &samples[sample_ID][
bin][0];
3347 sample_scales[sample_ID][0] += scale;
3348 nominal_samples[sample_ID][0] += 1.;
3353 if (selection_ID == 4) {
3354 if (selected_hists[selection_ID]->
FindBin(reco_beam_endZ) == 0) {
3357 else if (selected_hists[selection_ID]->
FindBin(reco_beam_endZ) >
3358 selected_hists[selection_ID]->GetNbinsX()) {
3360 selected_hists[selection_ID]->GetNbinsX());
3363 val = reco_beam_endZ;
3366 else if (selection_ID > 4) {
3369 else if (reco_beam_incidentEnergies->size()) {
3370 for (
size_t j = 0; j < reco_beam_incidentEnergies->size(); ++j) {
3371 incident_hist.Fill((*reco_beam_incidentEnergies)[j]);
3373 if (selected_hists.find(selection_ID) != selected_hists.end()) {
3374 if (selection_ID != 4 && selection_ID != 5 && selection_ID != 6) {
3375 double energy = reco_beam_interactingEnergy;
3377 for (
size_t k = 1;
k < reco_beam_incidentEnergies->size(); ++
k) {
3378 double deltaE = ((*reco_beam_incidentEnergies)[
k-1] -
3379 (*reco_beam_incidentEnergies)[
k]);
3385 if (selected_hists[selection_ID]->
FindBin(energy) == 0) {
3388 else if (selected_hists[selection_ID]->
FindBin(energy) >
3389 selected_hists[selection_ID]->GetNbinsX()) {
3391 selected_hists[selection_ID]->GetNbinsX());
3406 *true_beam_traj_Z, *true_beam_traj_KE, *true_beam_slices,
3407 *true_beam_incidentEnergies);
3447 for (
auto it = sample_scales.begin(); it != sample_scales.end(); ++it) {
3448 for (
size_t i = 0; i < it->second.size(); ++i) {
3449 if (it->second[i] > 0.) {
3450 it->second[i] /= nominal_samples[it->first][i];
3455 it->second[i] *= (flux/new_flux);
3462 incident_hist.Scale(flux/new_flux);
3463 for (
auto it = selected_hists.begin(); it != selected_hists.end(); ++it) {
3464 it->second->Scale(flux/new_flux);
3472 std::map<
int,
std::vector<std::vector<ThinSliceSample>>> & samples,
3473 const std::map<int, bool> & signal_sample_checks,
3475 std::map<
int, std::vector<double>> & sample_scales,
int split_val) {
3482 double true_beam_interactingEnergy, reco_beam_interactingEnergy;
3483 double true_beam_endP, true_beam_endPx, true_beam_endPy, true_beam_endPz;
3484 std::vector<double> * true_beam_daughter_startPx = 0x0,
3485 * true_beam_daughter_startPy = 0x0,
3486 * true_beam_daughter_startPz = 0x0,
3487 * true_beam_daughter_startP = 0x0;
3488 std::vector<double> * reco_beam_incidentEnergies = 0x0;
3489 double reco_beam_endZ;
3490 tree->SetBranchAddress(
"reco_beam_endZ", &reco_beam_endZ);
3491 tree->SetBranchAddress(
"new_interaction_topology", &sample_ID);
3492 tree->SetBranchAddress(
"selection_ID", &selection_ID);
3493 tree->SetBranchAddress(
"true_beam_interactingEnergy",
3494 &true_beam_interactingEnergy);
3495 tree->SetBranchAddress(
"true_beam_endP", &true_beam_endP);
3496 tree->SetBranchAddress(
"true_beam_endPx", &true_beam_endPx);
3497 tree->SetBranchAddress(
"true_beam_endPy", &true_beam_endPy);
3498 tree->SetBranchAddress(
"true_beam_endPz", &true_beam_endPz);
3499 tree->SetBranchAddress(
"true_beam_daughter_startPx", &true_beam_daughter_startPx);
3500 tree->SetBranchAddress(
"true_beam_daughter_startPy", &true_beam_daughter_startPy);
3501 tree->SetBranchAddress(
"true_beam_daughter_startPz", &true_beam_daughter_startPz);
3502 tree->SetBranchAddress(
"true_beam_daughter_startP", &true_beam_daughter_startP);
3503 std::vector<int> * true_beam_daughter_PDG = 0x0;
3504 tree->SetBranchAddress(
"true_beam_daughter_PDG", &true_beam_daughter_PDG);
3505 tree->SetBranchAddress(
"reco_beam_interactingEnergy",
3506 &reco_beam_interactingEnergy);
3507 tree->SetBranchAddress(
"reco_beam_incidentEnergies",
3508 &reco_beam_incidentEnergies);
3509 std::vector<double> * true_beam_traj_Z = 0x0,
3510 * true_beam_traj_KE = 0x0;
3511 std::vector<int> * true_beam_slices = 0x0;
3512 tree->SetBranchAddress(
"true_beam_traj_Z", &true_beam_traj_Z);
3513 tree->SetBranchAddress(
"true_beam_traj_KE", &true_beam_traj_KE);
3514 tree->SetBranchAddress(
"true_beam_slices", &true_beam_slices);
3515 std::vector<double> * true_beam_incidentEnergies = 0x0;
3516 tree->SetBranchAddress(
"true_beam_incidentEnergies",
3517 &true_beam_incidentEnergies);
3522 TFile ratio_file(options.
get<
std::string>(
"RatioFile").c_str(),
"OPEN");
3523 std::vector<std::string> ratio_names
3524 = options.
get<std::vector<std::string>>(
"RatioNames");
3526 std::vector<TH1D *> ratios;
3527 for (
auto n : ratio_names) {
3528 ratios.push_back((TH1D*)ratio_file.Get(
n.c_str()));
3530 std::vector<double>
limits = options.
get<std::vector<double>>(
"Limits");
3532 double new_flux = 0.;
3533 flux = tree->GetEntries() - split_val;
3536 std::map<int, std::vector<double>> nominal_samples;
3537 for (
auto it = sample_scales.begin(); it != sample_scales.end(); ++it) {
3538 nominal_samples[it->first] = std::vector<double>(it->second.size(), 0.);
3541 for (
int i = split_val; i < tree->GetEntries(); ++i) {
3544 if (samples.find(sample_ID) == samples.end())
3547 double end_energy = true_beam_interactingEnergy;
3549 end_energy = sqrt(true_beam_endP*true_beam_endP*1.e6 + 139.57*139.57) - 139.57;
3552 end_energy = sqrt(true_beam_endP*true_beam_endP*1.e6 + 139.57*139.57) - 139.57;
3555 int bin =
fEndSlices->GetXaxis()->FindBin(true_beam_traj_Z->back());
3557 end_energy =
fMeans.at(bin);
3562 size_t n_piplus = 0, n_piminus = 0;
3563 for (
size_t j = 0; j < true_beam_daughter_PDG->size(); ++j) {
3564 if (true_beam_daughter_PDG->at(j) == 211) {
3567 else if (true_beam_daughter_PDG->at(j) == -211) {
3572 if (sample_ID == 3 && n_piplus == 1 && n_piminus == 0) {
3575 if (true_beam_endP >= limits.back()) {
3580 for (
size_t j = 1; j < limits.size(); ++j) {
3581 if (true_beam_endP >= limits[j-1] &&
3582 true_beam_endP < limits[j]) {
3592 for (
size_t j = 0; j < true_beam_daughter_PDG->size(); ++j) {
3593 if (true_beam_daughter_PDG->at(j) == 211) {
3594 double costheta = (true_beam_endPx*true_beam_daughter_startPx->at(j) +
3595 true_beam_endPy*true_beam_daughter_startPy->at(j) +
3596 true_beam_endPz*true_beam_daughter_startPz->at(j))/
3597 (true_beam_endP*true_beam_daughter_startP->at(j));
3599 int bin = h->FindBin(costheta);
3600 scale *= h->GetBinContent(bin);
3605 bool is_signal = signal_sample_checks.at(sample_ID);
3608 std::vector<ThinSliceSample> & samples_vec = samples[sample_ID][0];
3611 for (
size_t j = 1; j < samples_vec.size()-1; ++j) {
3615 sample_scales[sample_ID][j] += scale;
3616 nominal_samples[sample_ID][j] += 1.;
3617 this_sample = &sample;
3622 if (end_energy < samples_vec[1].RangeLowEnd()) {
3623 sample_scales[sample_ID][0] += scale;
3624 nominal_samples[sample_ID][0] += 1.;
3625 this_sample = &samples_vec[0];
3628 this_sample = &samples_vec.back();
3629 sample_scales[sample_ID].back() += scale;
3630 nominal_samples[sample_ID].back() += 1.;
3635 this_sample = &samples[sample_ID][0][0];
3636 sample_scales[sample_ID][0] += scale;
3637 nominal_samples[sample_ID][0] += 1.;
3642 if (selection_ID == 4) {
3643 if (selected_hists[selection_ID]->
FindBin(reco_beam_endZ) == 0) {
3646 else if (selected_hists[selection_ID]->
FindBin(reco_beam_endZ) >
3647 selected_hists[selection_ID]->GetNbinsX()) {
3649 selected_hists[selection_ID]->GetNbinsX());
3652 val = reco_beam_endZ;
3655 else if (selection_ID > 4) {
3658 else if (reco_beam_incidentEnergies->size()) {
3659 for (
size_t j = 0; j < reco_beam_incidentEnergies->size(); ++j) {
3660 incident_hist.Fill((*reco_beam_incidentEnergies)[j]);
3662 if (selected_hists.find(selection_ID) != selected_hists.end()) {
3664 if (selection_ID < 4) {
3665 double energy = reco_beam_interactingEnergy;
3667 for (
size_t k = 1;
k < reco_beam_incidentEnergies->size(); ++
k) {
3668 double deltaE = ((*reco_beam_incidentEnergies)[
k-1] -
3669 (*reco_beam_incidentEnergies)[
k]);
3675 if (selected_hists[selection_ID]->
FindBin(energy) == 0) {
3678 else if (selected_hists[selection_ID]->
FindBin(energy) >
3679 selected_hists[selection_ID]->GetNbinsX()) {
3681 selected_hists[selection_ID]->GetNbinsX());
3696 *true_beam_traj_Z, *true_beam_traj_KE, *true_beam_slices,
3697 *true_beam_incidentEnergies);
3701 for (
auto it = sample_scales.begin(); it != sample_scales.end(); ++it) {
3702 for (
size_t i = 0; i < it->second.size(); ++i) {
3703 if (it->second[i] > 0.) {
3704 it->second[i] /= nominal_samples[it->first][i];
3709 it->second[i] *= (flux/new_flux);
3713 incident_hist.Scale(flux/new_flux);
3714 for (
auto it = selected_hists.begin(); it != selected_hists.end(); ++it) {
3715 it->second->Scale(flux/new_flux);
3721 std::map<
int,
std::vector<std::vector<ThinSliceSample>>> & samples,
3722 const std::map<int, bool> & signal_sample_checks,
3724 std::map<
int, std::vector<double>> & sample_scales,
int split_val) {
3731 double true_beam_interactingEnergy, reco_beam_interactingEnergy;
3732 double true_beam_endP, true_beam_endPx, true_beam_endPy, true_beam_endPz;
3733 std::vector<double> * true_beam_daughter_startPx = 0x0,
3734 * true_beam_daughter_startPy = 0x0,
3735 * true_beam_daughter_startPz = 0x0,
3736 * true_beam_daughter_startP = 0x0;
3737 std::vector<double> * reco_beam_incidentEnergies = 0x0;
3738 double reco_beam_endZ;
3739 tree->SetBranchAddress(
"reco_beam_endZ", &reco_beam_endZ);
3740 tree->SetBranchAddress(
"new_interaction_topology", &sample_ID);
3741 tree->SetBranchAddress(
"selection_ID", &selection_ID);
3742 tree->SetBranchAddress(
"true_beam_interactingEnergy",
3743 &true_beam_interactingEnergy);
3744 tree->SetBranchAddress(
"true_beam_endP", &true_beam_endP);
3745 tree->SetBranchAddress(
"true_beam_endPx", &true_beam_endPx);
3746 tree->SetBranchAddress(
"true_beam_endPy", &true_beam_endPy);
3747 tree->SetBranchAddress(
"true_beam_endPz", &true_beam_endPz);
3748 tree->SetBranchAddress(
"true_beam_daughter_startPx", &true_beam_daughter_startPx);
3749 tree->SetBranchAddress(
"true_beam_daughter_startPy", &true_beam_daughter_startPy);
3750 tree->SetBranchAddress(
"true_beam_daughter_startPz", &true_beam_daughter_startPz);
3751 tree->SetBranchAddress(
"true_beam_daughter_startP", &true_beam_daughter_startP);
3752 std::vector<int> * true_beam_daughter_PDG = 0x0;
3753 tree->SetBranchAddress(
"true_beam_daughter_PDG", &true_beam_daughter_PDG);
3754 tree->SetBranchAddress(
"reco_beam_interactingEnergy",
3755 &reco_beam_interactingEnergy);
3756 tree->SetBranchAddress(
"reco_beam_incidentEnergies",
3757 &reco_beam_incidentEnergies);
3758 std::vector<double> * true_beam_traj_Z = 0x0,
3759 * true_beam_traj_KE = 0x0;
3760 std::vector<int> * true_beam_slices = 0x0;
3761 tree->SetBranchAddress(
"true_beam_traj_Z", &true_beam_traj_Z);
3762 tree->SetBranchAddress(
"true_beam_traj_KE", &true_beam_traj_KE);
3763 tree->SetBranchAddress(
"true_beam_slices", &true_beam_slices);
3764 std::vector<double> * true_beam_incidentEnergies = 0x0;
3765 tree->SetBranchAddress(
"true_beam_incidentEnergies",
3766 &true_beam_incidentEnergies);
3769 int check_PDG = options.
get<
int>(
"PDG");
3770 if (check_PDG == 2212) {
3771 tree->SetBranchAddress(
"leading_p_costheta", &leading_costheta);
3773 else if (check_PDG == 211) {
3774 tree->SetBranchAddress(
"leading_piplus_costheta", &leading_costheta);
3776 else if (check_PDG == 111) {
3777 tree->SetBranchAddress(
"leading_pi0_costheta", &leading_costheta);
3783 TFile ratio_file(options.
get<
std::string>(
"RatioFile").c_str(),
"OPEN");
3786 auto temp_ratio_names
3787 = options.
get<std::vector<std::pair<int, std::vector<std::string>>>>
3789 std::map<int, std::vector<std::string>> ratio_names(
3790 temp_ratio_names.begin(), temp_ratio_names.end());
3792 std::map<int, std::vector<TH1D *>> ratios;
3793 for (
int i = 1; i < 4; ++i) {
3794 ratios[i] = std::vector<TH1D *>();
3795 for (
auto n : ratio_names[i]) {
3797 ratios[i].push_back((TH1D*)ratio_file.Get(name.c_str()));
3798 std::cout << i <<
" " << name <<
" " << ratios[i].back() <<
std::endl;
3801 auto temp_limits = options.
get<std::vector<std::pair<int, std::vector<double>>>>(
"Limits");
3802 std::map<int, std::vector<double>>
limits(temp_limits.begin(), temp_limits.end());
3805 double new_flux = 0.;
3806 flux = tree->GetEntries() - split_val;
3809 std::map<int, std::vector<double>> nominal_samples;
3810 for (
auto it = sample_scales.begin(); it != sample_scales.end(); ++it) {
3811 nominal_samples[it->first] = std::vector<double>(it->second.size(), 0.);
3814 std::vector<double> all_scales;
3815 for (
int i = split_val; i < tree->GetEntries(); ++i) {
3818 if (samples.find(sample_ID) == samples.end())
3821 double end_energy = true_beam_interactingEnergy;
3823 end_energy = sqrt(true_beam_endP*true_beam_endP*1.e6 + 139.57*139.57) - 139.57;
3826 end_energy = sqrt(true_beam_endP*true_beam_endP*1.e6 + 139.57*139.57) - 139.57;
3829 int bin =
fEndSlices->GetXaxis()->FindBin(true_beam_traj_Z->back());
3831 end_energy =
fMeans.at(bin);
3836 size_t n_piplus = 0, n_pi0 = 0, n_p = 0;
3837 for (
size_t j = 0; j < true_beam_daughter_PDG->size(); ++j) {
3838 if (true_beam_daughter_PDG->at(j) == 211) {
3841 else if (true_beam_daughter_PDG->at(j) == 111) {
3844 else if (true_beam_daughter_PDG->at(j) == 2212) {
3849 if (sample_ID < 4 &&
3850 ((check_PDG == 211 && n_piplus > 0) ||
3851 (check_PDG == 2212 && n_p > 0) ||
3852 (check_PDG == 111 && n_pi0 > 0))) {
3855 if (end_energy >=
limits[sample_ID].back()) {
3856 h = ratios[sample_ID].back();
3860 for (
size_t j = 1; j <
limits[sample_ID].size(); ++j) {
3861 if (end_energy >=
limits[sample_ID][j-1] &&
3862 end_energy <
limits[sample_ID][j]) {
3863 h = ratios[sample_ID][j-1];
3872 int bin = h->FindBin(leading_costheta);
3873 scale *= h->GetBinContent(bin);
3875 all_scales.push_back(scale);
3877 bool is_signal = signal_sample_checks.at(sample_ID);
3880 std::vector<ThinSliceSample> & samples_vec = samples[sample_ID][0];
3883 for (
size_t j = 1; j < samples_vec.size()-1; ++j) {
3887 sample_scales[sample_ID][j] += scale;
3888 nominal_samples[sample_ID][j] += 1.;
3889 this_sample = &sample;
3894 if (end_energy < samples_vec[1].RangeLowEnd()) {
3895 sample_scales[sample_ID][0] += scale;
3896 nominal_samples[sample_ID][0] += 1.;
3897 this_sample = &samples_vec[0];
3900 this_sample = &samples_vec.back();
3901 sample_scales[sample_ID].back() += scale;
3902 nominal_samples[sample_ID].back() += 1.;
3907 this_sample = &samples[sample_ID][0][0];
3908 sample_scales[sample_ID][0] += scale;
3909 nominal_samples[sample_ID][0] += 1.;
3914 if (selection_ID == 4) {
3915 if (selected_hists[selection_ID]->
FindBin(reco_beam_endZ) == 0) {
3918 else if (selected_hists[selection_ID]->
FindBin(reco_beam_endZ) >
3919 selected_hists[selection_ID]->GetNbinsX()) {
3921 selected_hists[selection_ID]->GetNbinsX());
3924 val = reco_beam_endZ;
3927 else if (selection_ID > 4) {
3930 else if (reco_beam_incidentEnergies->size()) {
3931 for (
size_t j = 0; j < reco_beam_incidentEnergies->size(); ++j) {
3932 incident_hist.Fill((*reco_beam_incidentEnergies)[j]);
3934 if (selected_hists.find(selection_ID) != selected_hists.end()) {
3936 if (selection_ID < 4) {
3937 double energy = reco_beam_interactingEnergy;
3939 for (
size_t k = 1;
k < reco_beam_incidentEnergies->size(); ++
k) {
3940 double deltaE = ((*reco_beam_incidentEnergies)[
k-1] -
3941 (*reco_beam_incidentEnergies)[
k]);
3947 if (selected_hists[selection_ID]->
FindBin(energy) == 0) {
3950 else if (selected_hists[selection_ID]->
FindBin(energy) >
3951 selected_hists[selection_ID]->GetNbinsX()) {
3953 selected_hists[selection_ID]->GetNbinsX());
3968 *true_beam_traj_Z, *true_beam_traj_KE, *true_beam_slices,
3969 *true_beam_incidentEnergies);
3974 for (
auto s : all_scales) mean +=
s;
3975 mean /= all_scales.
size();
3976 std::cout <<
"Mean scale: " << mean <<
std::endl;
3978 for (
auto it = sample_scales.begin(); it != sample_scales.end(); ++it) {
3979 for (
size_t i = 0; i < it->second.size(); ++i) {
3980 if (it->second[i] > 0.) {
3981 it->second[i] /= nominal_samples[it->first][i];
3986 it->second[i] *= (flux/new_flux);
3990 incident_hist.Scale(flux/new_flux);
3991 for (
auto it = selected_hists.begin(); it != selected_hists.end(); ++it) {
3992 it->second->Scale(flux/new_flux);
3999 std::map<
int,
std::vector<std::vector<ThinSliceSample>>> & samples,
4000 const std::map<int, bool> & signal_sample_checks,
4002 std::map<
int, std::vector<double>> & sample_scales,
int split_val) {
4009 double true_beam_interactingEnergy, reco_beam_interactingEnergy;
4010 double true_beam_endP, true_beam_endPx, true_beam_endPy, true_beam_endPz;
4011 std::vector<double> * true_beam_daughter_startPx = 0x0,
4012 * true_beam_daughter_startPy = 0x0,
4013 * true_beam_daughter_startPz = 0x0,
4014 * true_beam_daughter_startP = 0x0;
4015 std::vector<double> * reco_beam_incidentEnergies = 0x0;
4016 double reco_beam_endZ;
4017 tree->SetBranchAddress(
"reco_beam_endZ", &reco_beam_endZ);
4018 tree->SetBranchAddress(
"new_interaction_topology", &sample_ID);
4019 tree->SetBranchAddress(
"selection_ID", &selection_ID);
4020 tree->SetBranchAddress(
"true_beam_interactingEnergy",
4021 &true_beam_interactingEnergy);
4022 tree->SetBranchAddress(
"true_beam_endP", &true_beam_endP);
4023 tree->SetBranchAddress(
"true_beam_endPx", &true_beam_endPx);
4024 tree->SetBranchAddress(
"true_beam_endPy", &true_beam_endPy);
4025 tree->SetBranchAddress(
"true_beam_endPz", &true_beam_endPz);
4026 tree->SetBranchAddress(
"true_beam_daughter_startPx", &true_beam_daughter_startPx);
4027 tree->SetBranchAddress(
"true_beam_daughter_startPy", &true_beam_daughter_startPy);
4028 tree->SetBranchAddress(
"true_beam_daughter_startPz", &true_beam_daughter_startPz);
4029 tree->SetBranchAddress(
"true_beam_daughter_startP", &true_beam_daughter_startP);
4030 std::vector<int> * true_beam_daughter_PDG = 0x0;
4031 tree->SetBranchAddress(
"true_beam_daughter_PDG", &true_beam_daughter_PDG);
4032 tree->SetBranchAddress(
"reco_beam_interactingEnergy",
4033 &reco_beam_interactingEnergy);
4034 tree->SetBranchAddress(
"reco_beam_incidentEnergies",
4035 &reco_beam_incidentEnergies);
4036 std::vector<double> * true_beam_traj_Z = 0x0,
4037 * true_beam_traj_KE = 0x0;
4038 std::vector<int> * true_beam_slices = 0x0;
4039 tree->SetBranchAddress(
"true_beam_traj_Z", &true_beam_traj_Z);
4040 tree->SetBranchAddress(
"true_beam_traj_KE", &true_beam_traj_KE);
4041 tree->SetBranchAddress(
"true_beam_slices", &true_beam_slices);
4042 std::vector<double> * true_beam_incidentEnergies = 0x0;
4043 tree->SetBranchAddress(
"true_beam_incidentEnergies",
4044 &true_beam_incidentEnergies);
4048 tree->SetBranchAddress(
"beam_inst_P", &beam_inst_P);
4053 TFile ratio_file(options.
get<
std::string>(
"RatioFile").c_str(),
"OPEN");
4054 TH1D *
ratio = (TH1D*)ratio_file.Get(
"r");
4056 double new_flux = 0.;
4057 flux = tree->GetEntries() - split_val;
4059 std::map<int, std::vector<double>> nominal_samples;
4060 for (
auto it = sample_scales.begin(); it != sample_scales.end(); ++it) {
4061 nominal_samples[it->first] = std::vector<double>(it->second.size(), 0.);
4064 for (
int i = split_val; i < tree->GetEntries(); ++i) {
4067 if (samples.find(sample_ID) == samples.end())
4070 double end_energy = true_beam_interactingEnergy;
4072 end_energy = sqrt(true_beam_endP*true_beam_endP*1.e6 + 139.57*139.57) - 139.57;
4075 end_energy = sqrt(true_beam_endP*true_beam_endP*1.e6 + 139.57*139.57) - 139.57;
4078 int bin =
fEndSlices->GetXaxis()->FindBin(true_beam_traj_Z->back());
4080 end_energy =
fMeans.at(bin);
4084 int bin = ratio->FindBin(beam_inst_P);
4085 double scale = ratio->GetBinContent(bin);;
4086 bool is_signal = signal_sample_checks.at(sample_ID);
4089 std::vector<ThinSliceSample> & samples_vec = samples[sample_ID][0];
4092 for (
size_t j = 1; j < samples_vec.size()-1; ++j) {
4096 sample_scales[sample_ID][j] += scale;
4097 nominal_samples[sample_ID][j] += 1.;
4098 this_sample = &sample;
4103 if (end_energy < samples_vec[1].RangeLowEnd()) {
4104 sample_scales[sample_ID][0] += scale;
4105 nominal_samples[sample_ID][0] += 1.;
4106 this_sample = &samples_vec[0];
4109 this_sample = &samples_vec.back();
4110 sample_scales[sample_ID].back() += scale;
4111 nominal_samples[sample_ID].back() += 1.;
4116 this_sample = &samples[sample_ID][0][0];
4117 sample_scales[sample_ID][0] += scale;
4118 nominal_samples[sample_ID][0] += 1.;
4123 if (selection_ID == 4) {
4124 if (selected_hists[selection_ID]->
FindBin(reco_beam_endZ) == 0) {
4127 else if (selected_hists[selection_ID]->
FindBin(reco_beam_endZ) >
4128 selected_hists[selection_ID]->GetNbinsX()) {
4130 selected_hists[selection_ID]->GetNbinsX());
4133 val = reco_beam_endZ;
4136 else if (selection_ID > 4) {
4139 else if (reco_beam_incidentEnergies->size()) {
4140 for (
size_t j = 0; j < reco_beam_incidentEnergies->size(); ++j) {
4141 incident_hist.Fill((*reco_beam_incidentEnergies)[j]);
4143 if (selected_hists.find(selection_ID) != selected_hists.end()) {
4145 if (selection_ID < 4) {
4146 double energy = reco_beam_interactingEnergy;
4148 for (
size_t k = 1;
k < reco_beam_incidentEnergies->size(); ++
k) {
4149 double deltaE = ((*reco_beam_incidentEnergies)[
k-1] -
4150 (*reco_beam_incidentEnergies)[
k]);
4156 if (selected_hists[selection_ID]->
FindBin(energy) == 0) {
4159 else if (selected_hists[selection_ID]->
FindBin(energy) >
4160 selected_hists[selection_ID]->GetNbinsX()) {
4162 selected_hists[selection_ID]->GetNbinsX());
4177 *true_beam_traj_Z, *true_beam_traj_KE, *true_beam_slices,
4178 *true_beam_incidentEnergies);
4182 for (
auto it = sample_scales.begin(); it != sample_scales.end(); ++it) {
4183 for (
size_t i = 0; i < it->second.size(); ++i) {
4184 if (it->second[i] > 0.) {
4185 it->second[i] /= nominal_samples[it->first][i];
4190 it->second[i] *= (flux/new_flux);
4194 incident_hist.Scale(flux/new_flux);
4195 for (
auto it = selected_hists.begin(); it != selected_hists.end(); ++it) {
4196 it->second->Scale(flux/new_flux);
4202 std::map<
int,
std::vector<std::vector<ThinSliceSample>>> & samples,
4203 const std::map<int, bool> & signal_sample_checks,
4205 std::map<
int, std::vector<double>> & sample_scales,
int split_val) {
4211 double betaP = cal_set.
get<
double>(
"betap");
4212 double rho = cal_set.get<
double>(
"Rho");
4213 double wion = cal_set.get<
double>(
"Wion");
4214 double alpha = cal_set.get<
double>(
"alpha");
4216 std::vector<fhicl::ParameterSet> PlanePars
4217 = cal_set.get<std::vector<fhicl::ParameterSet>>(
"PlaneParameters");
4218 bool found_collection =
false;
4219 double nominal_CCal = 1.;
4220 for (
auto &
p : PlanePars) {
4221 if (
p.get<
int>(
"PlaneID") == 2) {
4222 nominal_CCal =
p.get<
double>(
"calib_factor");
4223 found_collection =
true;
4228 if (!found_collection) {
4230 throw std::runtime_error(message);
4234 double varied_CCal = dEdX_options.
get<
double>(
"VariedCCal");
4238 double reco_beam_endZ;
4239 std::vector<double> * calibrated_dQdX = 0x0, * beam_EField = 0x0,
4240 * track_pitch = 0x0, * reco_beam_incidentEnergies = 0x0;
4241 tree->SetBranchAddress(
"selection_ID", &selection_ID);
4242 tree->SetBranchAddress(
"new_interaction_topology", &sample_ID);
4243 tree->SetBranchAddress(
"reco_beam_calibrated_dQdX_SCE", &calibrated_dQdX);
4244 tree->SetBranchAddress(
"reco_beam_EField_SCE", &beam_EField);
4245 tree->SetBranchAddress(
"reco_beam_TrkPitch_SCE", &track_pitch);
4246 tree->SetBranchAddress(
"reco_beam_incidentEnergies",
4247 &reco_beam_incidentEnergies);
4248 tree->SetBranchAddress(
"beam_inst_P", &beam_inst_P);
4249 tree->SetBranchAddress(
"reco_beam_endZ", &reco_beam_endZ);
4251 std::vector<double> * true_beam_traj_Z = 0x0,
4252 * true_beam_traj_KE = 0x0;
4253 std::vector<int> * true_beam_slices = 0x0;
4254 tree->SetBranchAddress(
"true_beam_traj_Z", &true_beam_traj_Z);
4255 tree->SetBranchAddress(
"true_beam_traj_KE", &true_beam_traj_KE);
4256 tree->SetBranchAddress(
"true_beam_slices", &true_beam_slices);
4257 std::vector<double> * true_beam_incidentEnergies = 0x0;
4258 tree->SetBranchAddress(
"true_beam_incidentEnergies",
4259 &true_beam_incidentEnergies);
4260 double true_beam_endP;
4261 double true_beam_interactingEnergy;
4262 tree->SetBranchAddress(
"true_beam_interactingEnergy",
4263 &true_beam_interactingEnergy);
4264 tree->SetBranchAddress(
"true_beam_endP", &true_beam_endP);
4267 flux = tree->GetEntries() - split_val;
4268 for (
int i = split_val; i < tree->GetEntries(); ++i) {
4270 TH1D * selection_hist = (TH1D*)selection_hists[selection_ID];
4273 if (selection_ID == 4) {
4274 if (selection_hist->FindBin(reco_beam_endZ) == 0) {
4275 val = selection_hist->GetBinCenter(1);
4277 else if (selection_hist->FindBin(reco_beam_endZ) >
4278 selection_hist->GetNbinsX()) {
4279 val = selection_hist->GetBinCenter(
4280 selection_hist->GetNbinsX());
4283 val = reco_beam_endZ;
4286 else if (selection_ID > 4) {
4289 else if (reco_beam_incidentEnergies->size()) {
4290 double energy = sqrt(beam_inst_P*beam_inst_P*1.e6 + 139.57*139.57) -
4292 for (
size_t k = 0;
k < calibrated_dQdX->size()-1; ++
k) {
4293 if ((*calibrated_dQdX)[
k] < 0.)
continue;
4295 double dedx = (nominal_CCal/varied_CCal);
4296 dedx *= (*calibrated_dQdX)[
k];
4297 dedx *= (betaP / ( rho * (*beam_EField)[
k] ) * wion);
4300 dedx *= ((rho*(*beam_EField)[
k])/betaP);
4304 energy -= dedx*(*track_pitch)[
k];
4308 if (selection_hist->FindBin(energy) == 0) {
4309 val = selection_hist->GetBinCenter(1);
4311 else if (selection_hist->FindBin(energy) >
4312 selection_hist->GetNbinsX()) {
4313 val = selection_hist->GetBinCenter(selection_hist->GetNbinsX());
4321 val = selection_hist->GetBinCenter(1);
4324 double end_energy = true_beam_interactingEnergy;
4326 end_energy = sqrt(true_beam_endP*true_beam_endP*1.e6 + 139.57*139.57) - 139.57;
4328 selection_hist->Fill(val);
4329 bool is_signal = signal_sample_checks.at(sample_ID);
4332 std::vector<ThinSliceSample> & samples_vec = samples[sample_ID][0];
4335 for (
size_t j = 1; j < samples_vec.size()-1; ++j) {
4338 this_sample = &sample;
4343 if (end_energy < samples_vec[1].RangeLowEnd()) {
4344 this_sample = &samples_vec[0];
4346 else if (end_energy >
4347 samples_vec[samples_vec.size()-2].RangeHighEnd()) {
4348 this_sample = &samples_vec.back();
4353 this_sample = &samples[sample_ID][0][0];
4357 *true_beam_traj_Z, *true_beam_traj_KE, *true_beam_slices,
4358 *true_beam_incidentEnergies);
4398 for (
auto it = sample_scales.begin(); it != sample_scales.end(); ++it) {
4399 for (
double &
s : it->second) {
4407 std::map<
int,
std::vector<std::vector<ThinSliceSample>>> & samples,
4408 const std::map<int, bool> & signal_sample_checks,
4410 std::map<
int, std::vector<double>> & sample_scales,
int split_val) {
4417 double true_beam_interactingEnergy, reco_beam_interactingEnergy;
4418 double true_beam_endP;
4419 std::vector<double> * reco_beam_incidentEnergies = 0x0;
4420 double reco_beam_endZ;
4421 tree->SetBranchAddress(
"reco_beam_endZ", &reco_beam_endZ);
4422 tree->SetBranchAddress(
"new_interaction_topology", &sample_ID);
4423 tree->SetBranchAddress(
"selection_ID", &selection_ID);
4424 tree->SetBranchAddress(
"true_beam_interactingEnergy",
4425 &true_beam_interactingEnergy);
4426 tree->SetBranchAddress(
"true_beam_endP", &true_beam_endP);
4427 tree->SetBranchAddress(
"reco_beam_interactingEnergy",
4428 &reco_beam_interactingEnergy);
4429 tree->SetBranchAddress(
"reco_beam_incidentEnergies",
4430 &reco_beam_incidentEnergies);
4431 std::vector<double> * true_beam_traj_Z = 0x0,
4432 * true_beam_traj_KE = 0x0;
4433 std::vector<int> * true_beam_slices = 0x0;
4434 tree->SetBranchAddress(
"true_beam_traj_Z", &true_beam_traj_Z);
4435 tree->SetBranchAddress(
"true_beam_traj_KE", &true_beam_traj_KE);
4436 tree->SetBranchAddress(
"true_beam_slices", &true_beam_slices);
4437 std::vector<double> * true_beam_incidentEnergies = 0x0;
4438 tree->SetBranchAddress(
"true_beam_incidentEnergies",
4439 &true_beam_incidentEnergies);
4441 std::vector<double> * daughter_Theta = 0x0;
4442 tree->SetBranchAddress(
"reco_daughter_allTrack_Theta",
4444 std::vector<int> * daughter_true_PDG = 0x0;
4445 tree->SetBranchAddress(
"reco_daughter_PFP_true_byHits_PDG",
4446 &daughter_true_PDG);
4447 std::vector<double> * daughter_track_score = 0x0;
4448 tree->SetBranchAddress(
"reco_daughter_PFP_trackScore_collection",
4449 &daughter_track_score);
4455 flux = tree->GetEntries() - split_val;
4458 std::map<int, std::vector<double>> nominal_samples;
4459 for (
auto it = sample_scales.begin(); it != sample_scales.end(); ++it) {
4460 nominal_samples[it->first] = std::vector<double>(it->second.size(), 0.);
4463 double check_val = options.
get<
double>(
"F");
4464 for (
int i = split_val; i < tree->GetEntries(); ++i) {
4467 if (samples.find(sample_ID) == samples.end())
4470 double end_energy = true_beam_interactingEnergy;
4472 end_energy = sqrt(true_beam_endP*true_beam_endP*1.e6 + 139.57*139.57) - 139.57;
4476 if (selection_ID == 4) {
4477 if (selected_hists[selection_ID]->
FindBin(reco_beam_endZ) == 0) {
4480 else if (selected_hists[selection_ID]->
FindBin(reco_beam_endZ) >
4481 selected_hists[selection_ID]->GetNbinsX()) {
4483 selected_hists[selection_ID]->GetNbinsX());
4486 val = reco_beam_endZ;
4489 else if (selection_ID > 4) {
4492 else if (reco_beam_incidentEnergies->size()) {
4493 for (
size_t j = 0; j < reco_beam_incidentEnergies->size(); ++j) {
4494 incident_hist.Fill((*reco_beam_incidentEnergies)[j]);
4496 if (selected_hists.find(selection_ID) != selected_hists.end()) {
4497 if (selection_ID != 4 && selection_ID != 5 && selection_ID != 6) {
4498 double energy = reco_beam_interactingEnergy;
4500 for (
size_t k = 1;
k < reco_beam_incidentEnergies->size(); ++
k) {
4501 double deltaE = ((*reco_beam_incidentEnergies)[
k-1] -
4502 (*reco_beam_incidentEnergies)[
k]);
4508 if (selected_hists[selection_ID]->
FindBin(energy) == 0) {
4511 else if (selected_hists[selection_ID]->
FindBin(energy) >
4512 selected_hists[selection_ID]->GetNbinsX()) {
4514 selected_hists[selection_ID]->GetNbinsX());
4526 bool is_signal = signal_sample_checks.at(sample_ID);
4529 std::vector<ThinSliceSample> & samples_vec = samples[sample_ID][0];
4532 for (
size_t j = 1; j < samples_vec.size()-1; ++j) {
4535 this_sample = &sample;
4540 if (end_energy < samples_vec[1].RangeLowEnd()) {
4541 this_sample = &samples_vec[0];
4543 else if (end_energy >
4544 samples_vec[samples_vec.size()-2].RangeHighEnd()) {
4545 this_sample = &samples_vec.back();
4550 this_sample = &samples[sample_ID][0][0];
4553 std::vector<double> good_true_incEnergies;
4592 if (selection_ID < 3) {
4594 for (
size_t j = 0; j < daughter_Theta->size(); ++j) {
4596 ((*daughter_track_score)[j] < 1. && (*daughter_track_score)[j] > .3) &&
4597 ((*daughter_Theta)[j] > -999) &&
4598 ((*daughter_Theta)[j]*180./TMath::Pi() < 20.)) {
4599 double r =
fRNG.Uniform();
4600 if (r < check_val) {
4606 selected_hists[new_selection]->Fill(val);
4613 for (
auto it = sample_scales.begin(); it != sample_scales.end(); ++it) {
4614 for (
size_t i = 0; i < it->second.size(); ++i) {
4621 std::map<
int,
std::vector<std::vector<ThinSliceSample>>> & samples,
4625 double alt_chi2 = 0.;
4627 size_t alt_nPoints = 0;
4630 double total_data = 0., total_mc = 0.;
4631 double data_integral = 0.;
4632 for (
auto it = selected_data_hists.begin();
4633 it != selected_data_hists.end(); ++it) {
4634 TH1D * data_hist = (TH1D*)it->second;
4636 if (data_hist->GetBinContent(0) > 0.) {
4637 std::cout <<
"Warning: underflow bin of " <<
selection_ID <<
4638 " has " << data_hist->GetBinContent(0) <<
" events" <<
4641 else if (data_hist->GetBinContent(data_hist->GetNbinsX()+1) > 0.) {
4642 std::cout <<
"Warning: overflow bin of " <<
selection_ID <<
4643 " has " << data_hist->GetBinContent(data_hist->GetNbinsX()+1) <<
4649 data_integral += data_hist->Integral();
4651 int end = data_hist->GetNbinsX();
4653 for (
int i = start; i <=
end; ++i) {
4654 double data_val = data_hist->GetBinContent(i);
4659 for (
auto it2 = samples.begin(); it2 != samples.end(); ++it2) {
4660 std::vector<std::vector<ThinSliceSample>> & samples_vec_2D = it2->second;
4661 for (
size_t j = 0; j < samples_vec_2D.size(); ++j) {
4662 std::vector<ThinSliceSample> & samples_vec = samples_vec_2D[j];
4663 for (
size_t k = 0;
k < samples_vec.size(); ++
k) {
4668 if (mc_hist->GetBinContent(0) > 0.) {
4669 std::cout <<
"Warning: underflow bin of " <<
selection_ID <<
4670 " has " << mc_hist->GetBinContent(0) <<
" events" <<
4673 else if (mc_hist->GetBinContent(mc_hist->GetNbinsX()+1) > 0.) {
4674 std::cout <<
"Warning: overflow bin of " <<
selection_ID <<
4675 " has " << mc_hist->GetBinContent(mc_hist->GetNbinsX()+1) <<
4682 if (mc_val < 1.
e-7) {
4686 alt_chi2 += (
std::pow((data_val - mc_val), 2) / mc_val);
4697 if (data_val > 1.
e-7)
4698 chi2 += 2*data_val*std::log(data_val/mc_val);
4706 total_data += data_val;
4723 std::pair<double, size_t> chi2_nPoints = {chi2, nPoints-1};
4724 std::pair<double, size_t> alt_chi2_nPoints = {alt_chi2, nPoints};
4725 return (
fMultinomial ? chi2_nPoints : alt_chi2_nPoints);
4729 std::map<
int,
std::vector<std::vector<ThinSliceSample>>> & samples,
4733 bool post_fit,
int nPars,
4734 TDirectory * plot_dir) {
4738 std::map<int, TH1*> data_hists
4742 for (
auto it = data_hists.begin(); it != data_hists.end(); ++it) {
4744 TH1D * data_hist = (TH1D*)it->second;
4745 data_hist->SetLineColor(kBlack);
4746 data_hist->SetMarkerColor(kBlack);
4747 data_hist->SetMarkerStyle(20);
4750 canvas_name_no_data += (post_fit ?
"PostFit" :
"Nominal") +
4753 TCanvas cSelectionNoData(canvas_name_no_data.c_str(),
"");
4754 cSelectionNoData.SetTicks();
4757 canvas_name += (post_fit ?
"PostFit" :
"Nominal") +
4759 TCanvas cSelection(canvas_name.c_str(),
"");
4760 cSelection.SetTicks();
4762 std::map<int, std::vector<TH1D *>> temp_hists;
4763 for (
auto it2 = samples.begin(); it2 != samples.end(); ++it2) {
4764 temp_hists[it2->first] = std::vector<TH1D *>();
4765 std::vector<ThinSliceSample> & vec = it2->second[0];
4766 for (
size_t i = 0; i < vec.size(); ++i) {
4767 temp_hists[it2->first].push_back((TH1D*)(
4769 vec[i].GetRebinnedSelectionHist(selection_ID) :
4770 vec[i].GetSelectionHist(selection_ID))->Clone());
4772 for (
size_t i = 1; i < it2->second.size(); ++i) {
4773 for (
size_t j = 0; j < it2->second[i].size(); ++j) {
4774 temp_hists[it2->first][j]->Add((TH1D*)(
4776 it2->second[i][j].GetRebinnedSelectionHist(selection_ID) :
4777 it2->second[i][j].GetSelectionHist(selection_ID)));
4782 std::string stack_name = (post_fit ?
"PostFit" :
"Nominal") +
4785 THStack mc_stack(stack_name.c_str(),
"");
4787 std::vector<TH1D*> temp_vec;
4790 for (
auto it2 = temp_hists.begin(); it2 != temp_hists.end(); ++it2) {
4791 for (
size_t i = 0; i < it2->second.size(); ++i) {
4792 TH1D * sel_hist = it2->second.at(i);
4794 sel_hist->SetFillColor(color_fill.first);
4795 sel_hist->SetFillStyle(color_fill.second);
4796 sel_hist->SetLineColor(kBlack);
4797 mc_stack.Add(sel_hist);
4798 temp_vec.push_back(sel_hist);
4804 for (
auto it = temp_vec.rbegin(); it != temp_vec.rend(); ++it) {
4808 cSelectionNoData.cd();
4809 mc_stack.Draw(
"hist");
4811 title_no_data += data_hist->GetXaxis()->GetTitle();
4812 mc_stack.SetTitle(title_no_data.c_str());
4813 mc_stack.GetHistogram()->SetTitleSize(.04,
"X");
4814 mc_stack.Draw(
"hist");
4815 if (it == data_hists.begin())
4816 leg.Write(
"leg_no_data");
4817 cSelectionNoData.Write();
4823 leg.AddEntry(data_hist,
"Data");
4825 std::pair<double, size_t> chi2 =
CalculateChi2(samples, data_set);
4826 if (chi2.first < 0. && chi2.first > -1.e7) {
4833 chi2_str.Form(
"#chi^{2} = %.2f", chi2.first);
4834 leg.AddEntry((TObject*)0x0, chi2_str,
"");
4841 title += data_hist->GetXaxis()->GetTitle();
4842 mc_stack.SetTitle(title.c_str());
4844 mc_stack.Draw(
"hist");
4845 double max_mc = mc_stack.GetHistogram()->GetMaximum();
4846 int max_data_bin = data_hist->GetMaximumBin();
4847 double max_data = data_hist->GetBinContent(max_data_bin) +
4848 data_hist->GetBinError(max_data_bin);
4849 mc_stack.SetMaximum((max_data > max_mc ? max_data : max_mc));
4850 mc_stack.Draw(
"hist");
4851 data_hist->Draw(
"e1 same");
4857 TList *
l = (TList*)mc_stack.GetHists();
4858 TH1D * hMC = (TH1D*)l->At(0)->Clone();
4859 for (
int i = 1; i < l->GetSize(); ++i) {
4860 hMC->Add((TH1D*)l->At(i));
4864 (post_fit ?
"PostFit" :
"Nominal");
4866 = (TH1D*)data_hist->Clone(ratio_name.c_str());
4867 hRatio->Divide(hMC);
4869 std::string total_name = (post_fit ?
"PostFit" :
"Nominal") +
4872 hMC->Write(total_name.c_str());
4874 canvas_name +=
"Ratio";
4875 TCanvas cRatio(canvas_name.c_str(),
"");
4877 TPad p1((canvas_name +
"pad1").c_str(),
"", 0, 0.3, 1., 1.);
4878 p1.SetBottomMargin(0.1);
4881 mc_stack.Draw(
"hist");
4882 mc_stack.GetHistogram()->SetTitle(
"Abs;;");
4883 for (
int i = 1; i < mc_stack.GetHistogram()->GetNbinsX(); ++i) {
4884 hRatio->GetXaxis()->SetBinLabel(
4885 i, mc_stack.GetHistogram()->GetXaxis()->GetBinLabel(i));
4886 mc_stack.GetHistogram()->GetXaxis()->SetBinLabel(i,
"");
4888 mc_stack.Draw(
"hist");
4889 data_hist->Draw(
"e1 same");
4892 TPad p2((canvas_name +
"pad2").c_str(),
"", 0, 0, 1., 0.3);
4893 p2.SetTopMargin(0.1);
4894 p2.SetBottomMargin(.2);
4909 hRatio->GetYaxis()->SetTitle(
"Data/MC");
4910 hRatio->SetTitleSize(.04,
"XY");
4918 TH1D * hMC2 = (TH1D*)l->At(0)->Clone();
4919 for (
int i = 1; i < l->GetSize(); ++i) {
4920 hMC2->Add((TH1D*)l->At(i));
4924 (post_fit ?
"PostFit" :
"Nominal");
4926 = (TH1D*)data_hist->Clone(diff_name.c_str());
4930 hDiff->Divide(hMC2);
4933 canvas_name +=
"Diff";
4934 TCanvas cDiff(canvas_name.c_str(),
"");
4968 hDiff->GetYaxis()->SetTitle(
"r");
4969 hDiff->SetTitleSize(.04,
"XY");
4978 double total_muons = 0.;
4980 for (
auto it = samples.begin(); it != samples.end(); ++it) {
4981 for (
size_t i = 0; i < it->second.size(); ++i) {
4982 for (
size_t j = 0; j < it->second[i].size(); ++j) {
4983 if (it->first == 5) {
4984 total_muons += it->second[i][j].GetVariedFlux();
4986 total += it->second[i][j].GetVariedFlux();
4993 std::map<
int,
std::vector<std::vector<ThinSliceSample>>> & samples,
4995 std::map<
int, std::vector<TH1*>> & throw_hists,
4996 bool plot_rebinned) {
4999 std::map<int, TH1*> data_hists
5004 for (
auto it = data_hists.begin(); it != data_hists.end(); ++it) {
5005 std::vector<double> bins;
5009 TH1D * temp_hist = (TH1D*)it->second->Clone(name.c_str());
5011 throw_hists[it->first].push_back(temp_hist);
5015 for (
auto it = throw_hists.begin(); it != throw_hists.end(); ++it) {
5017 for (
auto it2 = samples.begin(); it2 != samples.end(); ++it2) {
5018 std::vector<std::vector<ThinSliceSample>> & samples_vec_2D = it2->second;
5019 for (
size_t j = 0; j < samples_vec_2D.size(); ++j) {
5020 std::vector<ThinSliceSample> & samples_vec = samples_vec_2D[j];
5021 for (
size_t k = 0;
k < samples_vec.size(); ++
k) {
5023 for (
int i = 1; i <= it->second.back()->GetNbinsX(); ++i) {
5024 it->second.back()->AddBinContent(i,
5034 std::map<
int,
std::vector<std::vector<ThinSliceSample>>> & samples,
5035 std::map<
int, std::vector<TH1*>> & throw_hists,
5036 std::map<
int, std::vector<TH1*>> & throw_inc_hists,
5037 std::map<
int, std::vector<TH1*>> & throw_xsec_hists,
5038 const std::vector<int> & incident_samples,
5039 const std::map<
int, std::vector<double>> & signal_bins) {
5041 for (
auto it = samples.begin(); it != samples.end(); ++it) {
5043 std::vector<std::vector<ThinSliceSample>> & samples_vec_2D = it->second;
5044 size_t nBins = samples_vec_2D[0].size();
5047 TH1D * temp_hist =
new TH1D(name.c_str(),
"",
nBins, 0,
nBins);
5048 for (
size_t i = 0; i < samples_vec_2D.size(); ++i) {
5049 std::vector<ThinSliceSample> & samples_vec = samples_vec_2D[i];
5050 for (
size_t j = 0; j < it->second[i].size(); ++j) {
5051 temp_hist->AddBinContent(j+1, samples_vec[j].GetVariedFlux());
5054 throw_hists[it->first].push_back(temp_hist);
5057 for (
auto it = throw_inc_hists.begin(); it != throw_inc_hists.end(); ++it) {
5059 auto & samples_vec_2D = samples[
s];
5060 const std::vector<double> & bins = signal_bins.
at(s);
5062 name +=
"IncidentThrow" +
5064 TH1D * temp_inc_hist =
new TH1D(name.c_str(),
"", bins.size() - 1, &bins[0]);
5067 name = samples_vec_2D[0][0].GetName();
5068 name +=
"XSecThrow" +
5070 TH1D * temp_xsec_hist =
new TH1D(name.c_str(),
"", bins.size() - 1,
5072 for (
auto i_s : incident_samples) {
5073 auto & incident_vec_2D = samples[i_s];
5074 for (
size_t i = 0; i < incident_vec_2D.size(); ++i) {
5075 for (
size_t j = 0; j < incident_vec_2D[i].size(); ++j) {
5078 incident_vec_2D[i][j].FillESliceHist(*temp_inc_hist);
5081 incident_vec_2D[i][j].FillHistFromIncidentEnergies(*temp_inc_hist);
5086 throw_inc_hists[
s].push_back(temp_inc_hist);
5088 for (
int i = 1; i <= temp_xsec_hist->GetNbinsX(); ++i) {
5089 temp_xsec_hist->SetBinContent(
5090 i, throw_hists[s].back()->GetBinContent(i+1));
5092 temp_xsec_hist->Divide(temp_inc_hist);
5093 throw_xsec_hists[
s].push_back(temp_xsec_hist);
5098 ThinSliceDataSet & data_set, std::map<
int, std::vector<TH1*>> & throw_hists,
5099 std::map<
int,
std::vector<std::vector<ThinSliceSample>>> & samples,
5101 std::map<
int, std::vector<TH1*>> & truth_throw_hists,
5102 std::map<
int, std::vector<TH1*>> & truth_inc_hists,
5103 std::map<
int, std::vector<TH1*>> & truth_xsec_hists,
5104 std::map<int, TH1*> & best_fit_incs,
5105 std::map<int, TH1*> & best_fit_xsecs,
5106 std::map<int, TH1*> & nominal_incs,
5107 std::map<int, TH1*> & nominal_xsecs,
5109 std::map<
int, std::vector<double>> * sample_scales) {
5110 std::map<int, TH1*> data_hists
5116 std::map<int, TH1D*> best_fit_selection_hists;
5118 for (
auto it = data_hists.begin(); it != data_hists.end(); ++it ) {
5119 TH1D * best_fit_hist = (TH1D*)it->second->Clone();
5120 best_fit_hist->Reset();
5121 for (
auto it2 = samples.begin(); it2 != samples.end(); ++it2) {
5122 for (
size_t i = 0; i < it2->second.size(); ++i) {
5123 for (
size_t j = 0; j < it2->second[i].size(); ++j) {
5124 it2->second[i][j].SetFactorToBestFit();
5126 (TH1D*)(plot_rebinned ?
5127 it2->second[i][j].GetRebinnedSelectionHist(it->first) :
5128 it2->second[i][j].GetSelectionHist(it->first)));
5132 best_fit_selection_hists[it->first] = best_fit_hist;
5133 nBins += best_fit_hist->GetNbinsX();
5136 TH2D selection_cov(
"SelectionCov",
"", nBins, 0, nBins, nBins, 0, nBins);
5139 std::map<int, size_t> sample_bins;
5140 for (
auto it = samples.begin(); it != samples.end(); ++it) {
5141 nBins += it->second[0].size();
5142 sample_bins[it->first] = it->second[0].size();
5145 std::map<int, std::vector<double>> best_fit_truth;
5146 std::map<int, std::vector<double>> best_fit_errs;
5148 for (
auto it = samples.begin(); it != samples.end(); ++it) {
5149 best_fit_truth[it->first]
5150 = std::vector<double>(sample_bins[it->first], 0.);
5151 best_fit_errs[it->first]
5152 = std::vector<double>(sample_bins[it->first], 0.);
5154 for (
size_t i = 0; i < sample_bins[it->first]; ++i) {
5155 double best_fit_val_i = 0.;
5156 for (
size_t j = 0; j < it->second.size(); ++j) {
5157 best_fit_val_i += it->second[j][i].GetVariedFlux();
5160 best_fit_truth[it->first][i] = best_fit_val_i;
5164 TH2D interaction_cov(
"interaction_cov",
"", nBins, 0, nBins, nBins, 0, nBins);
5165 std::map<int, std::vector<double>> best_fit_inc_truth;
5166 std::map<int, std::vector<double>> best_fit_xsec_truth;
5167 std::map<int, std::vector<double>> best_fit_inc_errs;
5168 std::map<int, std::vector<double>> best_fit_xsec_errs;
5171 std::map<int, size_t> xsec_bins;
5172 for (
auto it = best_fit_incs.begin(); it != best_fit_incs.end(); ++it) {
5174 nBins += it->second->GetNbinsX();
5175 xsec_bins[
s] = it->second->GetNbinsX();
5177 best_fit_inc_truth[
s] = std::vector<double>(xsec_bins[
s], 0.);
5178 best_fit_xsec_truth[
s] = std::vector<double>(xsec_bins[
s], 0.);
5179 best_fit_inc_errs[
s] = std::vector<double>(xsec_bins[
s], 0.);
5180 best_fit_xsec_errs[
s] = std::vector<double>(xsec_bins[
s], 0.);
5182 for (
size_t i = 0; i < xsec_bins[
s]; ++i) {
5183 best_fit_inc_truth[
s][i] = it->second->GetBinContent(i+1);
5184 best_fit_xsec_truth[
s][i] = best_fit_xsecs[
s]->GetBinContent(i+1);
5189 TH2D xsec_cov(
"xsec_cov",
"", nBins, 0, nBins, nBins, 0, nBins);
5191 for (
size_t z = 0;
z < nThrows; ++
z) {
5193 for (
auto it = best_fit_selection_hists.begin();
5194 it != best_fit_selection_hists.end(); ++it) {
5195 TH1D * best_fit = it->second;
5197 std::vector<TH1*> & temp_throws = throw_hists[
selection_ID];
5198 for (
int i = 1; i <= best_fit->GetNbinsX(); ++i) {
5199 double best_fit_val_i = best_fit->GetBinContent(i);
5201 for (
auto it2 = best_fit_selection_hists.begin();
5202 it2 != best_fit_selection_hists.end(); ++it2) {
5204 TH1D * best_fit_2 = it2->second;
5205 int selection_ID_2 = it2->first;
5206 std::vector<TH1*> & temp_throws_2 = throw_hists[selection_ID_2];
5207 for (
int j = 1; j <= best_fit_2->GetNbinsX(); ++j) {
5208 double best_fit_val_j = best_fit_2->GetBinContent(j);
5209 double val = (best_fit_val_i - temp_throws[
z]->GetBinContent(i))*
5210 (best_fit_val_j - temp_throws_2[
z]->GetBinContent(j));
5211 selection_cov.SetBinContent(
5212 bin_i, bin_j, (val/temp_throws.size() +
5213 selection_cov.GetBinContent(bin_i, bin_j)));
5222 for (
auto it = samples.begin(); it != samples.end(); ++it) {
5223 std::vector<TH1 *> throw_hists_i = truth_throw_hists[it->first];
5225 for (
size_t i = 0; i < sample_bins[it->first]; ++i) {
5226 double best_fit_val_i = best_fit_truth[it->first][i];
5229 for (
auto it2 = samples.begin(); it2 != samples.end(); ++it2) {
5230 std::vector<TH1 *> throw_hists_j = truth_throw_hists[it2->first];
5231 for (
size_t j = 0; j < sample_bins[it2->first]; ++j) {
5232 double best_fit_val_j = best_fit_truth[it2->first][j];
5235 = (throw_hists_i[
z]->GetBinContent(i+1) - best_fit_val_i)*
5236 (throw_hists_j[
z]->GetBinContent(j+1) - best_fit_val_j);
5237 interaction_cov.SetBinContent(
5239 (interaction_cov.GetBinContent(bin_i, bin_j) +
5240 val/throw_hists_i.size()));
5241 if (bin_i == bin_j && (
z == nThrows - 1)) {
5242 best_fit_errs[it->first][i]
5243 = sqrt(interaction_cov.GetBinContent(bin_i, bin_j));
5254 for (
auto it = truth_inc_hists.begin(); it != truth_inc_hists.end(); ++it) {
5256 std::vector<TH1 *> xsec_hists_i = truth_xsec_hists[it->first];
5258 for (
size_t i = 0; i < xsec_bins[it->first]; ++i) {
5260 double best_fit_xsec_i = best_fit_xsec_truth[it->first][i];
5263 for (
auto it2 = truth_inc_hists.begin(); it2 != truth_inc_hists.end();
5265 std::vector<TH1 *> xsec_hists_j = truth_xsec_hists[it2->first];
5266 for (
size_t j = 0; j < xsec_bins[it2->first]; ++j) {
5267 double best_fit_xsec_j = best_fit_xsec_truth[it2->first][j];
5270 = (xsec_hists_i[
z]->GetBinContent(i+1) - best_fit_xsec_i)*
5271 (xsec_hists_j[
z]->GetBinContent(j+1) - best_fit_xsec_j);
5272 xsec_cov.SetBinContent(
5274 (xsec_cov.GetBinContent(bin_i, bin_j) +
5276 if (bin_i == bin_j && (
z == nThrows - 1)) {
5277 best_fit_xsec_errs[it->first][i]
5278 = sqrt(xsec_cov.GetBinContent(bin_i, bin_j));
5287 output_file.cd(
"Throws");
5288 selection_cov.Write();
5289 interaction_cov.Write();
5293 for (
auto it = data_hists.begin(); it != data_hists.end(); ++it) {
5295 std::vector<TH1*>
hists = throw_hists.at(selection_ID);
5299 TCanvas cThrow(canvas_name.c_str(),
"");
5303 auto data_hist = it->second;
5304 std::vector<double> xs, xs_width;
5305 std::vector<double>
ys, errs;
5307 i <= best_fit_selection_hists[it->first]->GetNbinsX(); ++i) {
5309 best_fit_selection_hists[it->first]->GetBinContent(i));
5311 sqrt(selection_cov.GetBinContent(bin_count+i, bin_count+i)));
5312 xs.push_back(data_hist->GetBinCenter(i));
5313 xs_width.push_back(data_hist->GetBinWidth(i)/2.);
5316 TGraphAsymmErrors throw_gr(data_hist->GetNbinsX(),
5318 &xs_width[0], &xs_width[0], &errs[0], &errs[0]);
5320 throw_gr.SetFillStyle(3144);
5321 throw_gr.SetFillColor(kRed);
5322 throw_gr.Draw(
"a2");
5323 data_hist->Draw(
"same e1");
5324 output_file.cd(
"Throws");
5327 bin_count += data_hist->GetNbinsX();
5331 for (
auto it = truth_throw_hists.begin(); it != truth_throw_hists.end(); ++it) {
5332 int sample_ID = it->first;
5334 std::vector<double> xs, xs_width;
5335 for (
size_t i = 0; i < sample_bins[it->first]; ++i) {
5336 xs.push_back(i + 0.5);
5337 xs_width.push_back(.5);
5341 TH1D temp_nominal(name.c_str(),
"", xs.size(), 0, xs.size());
5342 std::vector<std::vector<ThinSliceSample>> & samples_vec_2D
5343 = samples[sample_ID];
5344 for (
size_t i = 0; i < samples_vec_2D.size(); ++i) {
5345 for (
size_t j = 0; j < samples_vec_2D[i].size(); ++j) {
5346 temp_nominal.AddBinContent(j+1, samples_vec_2D[i][j].GetNominalFlux());
5351 for (
size_t i = 0; i < sample_bins[it->first]; ++i) {
5352 if ((best_fit_truth[sample_ID][i] + best_fit_errs[sample_ID][i]) > max)
5353 max = (best_fit_truth[sample_ID][i] + best_fit_errs[sample_ID][i]);
5355 if (temp_nominal.GetBinContent(i+1) >
max)
5356 max = temp_nominal.GetBinContent(i+1);
5359 output_file.cd(
"Throws");
5360 std::string canvas_name =
"cTruthThrow" + samples[sample_ID][0][0].GetName();
5361 TCanvas cThrow(canvas_name.c_str(),
"");
5363 TGraphAsymmErrors throw_gr(xs.size(),
5364 &xs[0], &best_fit_truth[it->first][0],
5365 &xs_width[0], &xs_width[0],
5366 &best_fit_errs[it->first][0],
5367 &best_fit_errs[it->first][0]);
5368 throw_gr.SetFillStyle(3144);
5369 throw_gr.SetFillColor(kRed);
5370 throw_gr.SetMinimum(0.);
5371 throw_gr.SetMaximum(1.5*max);
5372 throw_gr.Draw(
"a2");
5375 temp_nominal.SetMarkerColor(kBlue);
5376 temp_nominal.SetMarkerStyle(20);
5377 temp_nominal.Draw(
"same p");
5380 leg.AddEntry(&throw_gr,
"Throws",
"lpf");
5381 leg.AddEntry(&temp_nominal,
"Nominal",
"p");
5383 if (sample_scales) {
5384 name =
"hVaried" + samples[sample_ID][0][0].GetName();
5385 TH1D * temp_varied = (TH1D*)temp_nominal.Clone(name.c_str());
5386 for (
size_t i = 0; i < xs.size(); ++i) {
5387 temp_varied->SetBinContent(
5388 i+1, temp_varied->GetBinContent(i+1)*(*sample_scales)[sample_ID][i]);
5390 temp_varied->SetMarkerColor(kBlack);
5391 temp_varied->SetMarkerStyle(20);
5392 temp_varied->Draw(
"same p");
5393 leg.AddEntry(temp_varied,
"Fake Data",
"p");
5399 bin_count += xs.size();
5402 for (
auto it = best_fit_xsec_truth.begin(); it != best_fit_xsec_truth.end();
5404 int sample_ID = it->first;
5406 std::vector<double> xs, xs_width;
5407 for (
size_t i = 0; i < xsec_bins[sample_ID]; ++i) {
5408 xs.push_back(i + 0.5);
5409 xs_width.push_back(.5);
5412 output_file.cd(
"Throws");
5413 std::string canvas_name =
"cXSecThrow" + samples[sample_ID][0][0].GetName();
5414 TCanvas cThrow(canvas_name.c_str(),
"");
5416 TGraphAsymmErrors throw_gr(xs.size(),
5417 &xs[0], &best_fit_xsec_truth[it->first][0],
5418 &xs_width[0], &xs_width[0],
5419 &best_fit_xsec_errs[it->first][0],
5420 &best_fit_xsec_errs[it->first][0]);
5421 throw_gr.SetFillStyle(3144);
5422 throw_gr.SetFillColor(kRed);
5423 throw_gr.SetMinimum(0.);
5424 throw_gr.Draw(
"a2");
5434 TProfile * prot_template) {
5437 return event.GetSelectionID();
5442 const std::vector<double> & track_scores =
event.GetRecoDaughterTrackScores();
5443 for (
size_t i = 0; i < track_scores.size(); ++i) {
5445 if (track_scores[i] > 0.3) {
5447 std::vector<double> new_dEdX, new_res_range;
5448 const std::vector<double> & calibrated_dQdX
5449 =
event.GetRecoDaughterTrackdQdXs()[i];
5450 const std::vector<double> & daughter_EField
5451 =
event.GetRecoDaughterEFields()[i];
5452 const std::vector<double> & res_range
5453 =
event.GetRecoDaughterTrackResRanges()[i];
5454 for (
size_t j = 0; j < calibrated_dQdX.size(); ++j) {
5458 if (calibrated_dQdX[j] < 0)
5461 double dedx = C_cal;
5462 dedx *= (calibrated_dQdX)[j];
5466 dedx *= ((
fRho*(daughter_EField)[j])/
fBetaP);
5467 new_dEdX.push_back(dedx);
5468 new_res_range.push_back(res_range[j]);
5476 if (truncated_mean < 2.8 && truncated_mean > 0.5) {
5480 else if (truncated_mean > 2.8 && truncated_mean < 3.4) {
5481 std::pair<double, int> pid_chi2_ndof
5483 new_dEdX, new_res_range, prot_template);
5485 if (pid_chi2_ndof.second > 0 &&
5486 pid_chi2_ndof.first/pid_chi2_ndof.second > 70.) {
5505 if (!dEdX.size())
return -999.;
5506 std::vector<double> temp_dEdX;
5507 for (
auto d : dEdX) {
5508 if (
d < 0)
continue;
5509 temp_dEdX.push_back(
d);
5511 std::sort(temp_dEdX.begin(), temp_dEdX.end());
5512 size_t low = std::rint(temp_dEdX.size()*0.16);
5513 size_t high = std::rint(temp_dEdX.size()*0.84);
5514 std::vector<double>
temp;
5515 for (
size_t i = low; i < high; ++i) {
5516 temp.push_back(temp_dEdX[i]);
5518 if (temp.empty())
return -999.;
5519 return std::accumulate(temp.begin(), temp.end(), 0.0)/temp.size();
5523 const std::vector<double> & true_beam_traj_Z,
5524 const std::vector<double> & true_beam_traj_KE,
5525 const std::vector<int> & true_beam_slices,
5526 const std::vector<double> & true_beam_incidentEnergies) {
5527 std::vector<double> results;
5530 int next_slice_num = 0;
5531 for (
size_t j = 1; j < true_beam_traj_Z.size() - 1; ++j) {
5532 double z = true_beam_traj_Z[j];
5533 double ke = true_beam_traj_KE[j];
5539 if (z >= next_slice_z) {
5540 double temp_z = true_beam_traj_Z[j-1];
5541 double temp_e = true_beam_traj_KE[j-1];
5543 while (next_slice_z < z && next_slice_num <
fSliceCut) {
5544 double sub_z = next_slice_z - temp_z;
5545 double delta_e = true_beam_traj_KE[j-1] - ke;
5546 double delta_z = z - true_beam_traj_Z[j-1];
5547 temp_e -= (sub_z/delta_z)*delta_e;
5548 results.push_back(temp_e);
5549 temp_z = next_slice_z;
5557 for (
size_t j = 0; j < true_beam_incidentEnergies.size(); ++j) {
5558 int slice = true_beam_slices[j];
5560 results.push_back(true_beam_incidentEnergies[j]);
5564 int bin =
fEndSlices->GetXaxis()->FindBin(true_beam_traj_Z.back());
5565 for (
int i = 1; i <=
bin; ++i) {
5566 results.push_back(
fMeans.at(i));
5574 const std::vector<double> & beam_energy_bins,
5575 const double & true_beam_startP) {
5577 for (
size_t j = 1; j < beam_energy_bins.size(); ++j) {
5578 if ((beam_energy_bins[j-1] <= 1.e3*true_beam_startP) &&
5579 (1.e3*true_beam_startP < beam_energy_bins[j])) {
5587 throw std::runtime_error(message);
std::pair< double, double > fSystBeamShiftLimits
end
while True: pbar.update(maxval-len(onlies[E][S])) #print iS, "/", len(onlies[E][S]) found = False for...
double GetSystWeight_EffVar(const ThinSliceEvent &event, const std::map< std::string, ThinSliceSystematic > &pars)
void FakeDataG4RWGrid(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)
TGraph * fSystBeamShiftWidths
void SetupSyst_BeamShiftSpline2(const std::vector< ThinSliceEvent > &events, std::map< int, std::vector< std::vector< ThinSliceSample >>> &samples, const std::map< std::string, ThinSliceSystematic > &pars, TFile &output_file)
std::pair< int, int > GetColorAndStyle(size_t i, const std::vector< std::pair< int, int >> &plot_style)
void AddESliceEnergies(const std::pair< double, double > &vals, double weight=1.)
void GetCurrentHists(std::map< int, std::vector< std::vector< ThinSliceSample >>> &samples, ThinSliceDataSet &data_set, std::map< int, std::vector< TH1 * >> &throw_hists, bool plot_rebinned) override
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) override
bool GetHasPi0Shower() const
void AddVariedFlux(double val=1.)
std::map< std::string, std::map< int, std::vector< TSpline3 * > > > fFullSelectionSplines
double fSystBeamShiftWeight
double GetSystWeight_BeamEffs(const ThinSliceEvent &event, const std::map< std::string, ThinSliceSystematic > &pars)
std::vector< double > MakeTrueIncidentEnergies(const std::vector< double > &true_beam_traj_Z, const std::vector< double > &true_beam_traj_KE, const std::vector< int > &true_beam_slices, const std::vector< double > &true_beam_incidentEnergies)
void FakeDataBeamWeight(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, int split_val=0)
void FakeDatadEdX(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, int split_val=0)
std::map< int, TH1 * > & GetSelectionHists()
int GetBeamBin(const std::vector< double > &beam_energy_bins, const double &true_beam_startP)
std::map< int, double > fMeans
int FindBin(double value, std::vector< double > binning)
void FakeDataAngleVar(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, int split_val=0)
void FakeDataSampleScales(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, int split_val=0)
int RecalculateSelectionID(const ThinSliceEvent &event, double C_cal, TProfile *prot_template)
void SetupSyst_BeamEffsWeight(const std::map< std::string, ThinSliceSystematic > &pars)
double GetSystWeight_BeamShift(const ThinSliceEvent &event, const std::map< std::string, ThinSliceSystematic > &pars)
void SetupSyst_BeamShiftSpline(const std::vector< ThinSliceEvent > &events, std::map< int, std::vector< std::vector< ThinSliceSample >>> &samples, const std::map< std::string, ThinSliceSystematic > &pars, TFile &output_file)
double GetSystWeight_EDiv(const ThinSliceEvent &event, const std::map< std::string, ThinSliceSystematic > &pars)
void WrapUpSysts(TFile &output_file) override
double dEdX(double KE, const simb::MCParticle *part)
void AddIncidentEnergies(const std::vector< double > &vals, double weight=1.)
TH1D fBeamShiftRatioNomHist
void SetupSyst_dEdX_Cal(const std::vector< ThinSliceEvent > &events, std::map< int, std::vector< std::vector< ThinSliceSample >>> &samples, const std::map< std::string, ThinSliceSystematic > &pars, TFile &output_file)
void FakeDataPionAngle(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, int split_val=0)
void SetupSyst_EffVarWeight(const std::map< std::string, ThinSliceSystematic > &pars)
void SetupSyst_EDivWeight(const std::map< std::string, ThinSliceSystematic > &pars)
void AddFlux(double val=1.)
double GetTrueStartP() const
TGraph * fSystBeamShiftMeans
std::vector< TSpline3 * > fBeamShiftRatioSplines
TTree * fSystBeamShiftTree
double GetSplineWeight(std::string syst_name, double par_val, int selection_ID, double val) const
int GetSelectionID() const
double fSystBeamShiftWeightCap
TH1 * GetSelectionHist(int id)
void BuildDataHists(TTree *tree, ThinSliceDataSet &data_set, double &flux, int split_val=0) override
T get(std::string const &key) const
void FakeDataBinnedScales(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, int split_val=0)
double GetSystWeight_NoTrack(const ThinSliceEvent &event, const std::map< std::string, ThinSliceSystematic > &pars)
const std::map< int, TH1 * > & GetSelectionHists() const
std::map< int, TH1 * > & GetRebinnedSelectionHists()
bool fSystBeamShiftTreeSave
virtual void GetCurrentTruthHists(std::map< int, std::vector< std::vector< ThinSliceSample >>> &samples, std::map< int, std::vector< TH1 * >> &hists, std::map< int, std::vector< TH1 * >> &inc_hists, std::map< int, std::vector< TH1 * >> &xsec_hists, const std::vector< int > &incident_samples, const std::map< int, std::vector< double >> &signal_bins) override
ProtoDUNETrackUtils fTrackUtil
void PlotThrows(ThinSliceDataSet &data_set, std::map< int, std::vector< TH1 * >> &throw_hists, std::map< int, std::vector< std::vector< ThinSliceSample >>> &samples, size_t nThrows, 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, std::map< int, TH1 * > &best_fit_incs, std::map< int, TH1 * > &best_fit_xsecs, std::map< int, TH1 * > &nominal_incs, std::map< int, TH1 * > &nominal_xsecs, TFile &output_file, bool plot_rebinned, std::map< int, std::vector< double >> *sample_scales=0x0) override
double TruncatedMean(const std::vector< double > &dEdX)
static int max(int a, int b)
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) override
double GetSystWeight_G4RW(const ThinSliceEvent &event, const std::map< std::string, ThinSliceSystematic > &pars, const ThinSliceSample &sample, int selection_ID, double val)
void FillSelectionHist(int id, double val, double weight=1.)
void SetupSyst_EffVar(const std::vector< ThinSliceEvent > &events, std::map< int, std::vector< std::vector< ThinSliceSample >>> &samples, const std::map< std::string, ThinSliceSystematic > &pars, TFile &output_file)
void FillTrueIncidentHist(const std::vector< double > &vals, double weight=1.)
std::pair< double, int > Chi2PID(const std::vector< double > &track_dedx, const std::vector< double > &range, TProfile *profile)
fhicl::ParameterSet fExtraOptions
std::map< std::string, std::map< int, std::vector< TH1D * > > > fFullSelectionVars
std::vector< std::string > fActiveG4RWSysts
const int & GetFluxType() const
void SetupSyst_NoTrackWeight(const std::map< std::string, ThinSliceSystematic > &pars)
std::string & GetSelectionName(int id)
QTextStream & bin(QTextStream &s)
bool CheckInSignalRange(double val)
void FakeDataEffVar(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, int split_val=0)
void SetupSyst_BeamShiftRatio(const std::vector< ThinSliceEvent > &events, std::map< int, std::vector< std::vector< ThinSliceSample >>> &samples, const std::map< std::string, ThinSliceSystematic > &pars, TFile &output_file)
void FillMCEvents(TTree *tree, std::vector< ThinSliceEvent > &events, std::vector< ThinSliceEvent > &fake_data_events, int &split_val, const bool &do_split) override
void FillSystematicShift(std::string syst_name, int selection_ID, const std::vector< double > &vals)
void FakeDataG4RW(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, int split_val=0)
#define DECLARE_THINSLICEDRIVER_FACTORY_NS(driver, nsname, driverbase)
void CompareSelections(std::map< int, std::vector< std::vector< ThinSliceSample >>> &samples, ThinSliceDataSet &data_set, TFile &output_file, std::vector< std::pair< int, int >> plot_style, bool plot_rebinned, bool post_fit, int nPars, TDirectory *plot_dir) override
void SetupSyst_BeamShift(const std::map< std::string, ThinSliceSystematic > &pars, TFile &output_file)
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
void SetupSyst_G4RW(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)
std::pair< double, size_t > CalculateChi2(std::map< int, std::vector< std::vector< ThinSliceSample >>> &samples, ThinSliceDataSet &data_set) override
auto const & get(AssnsNode< L, R, D > const &r)
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) override
static constexpr double ys
TGraph2D * fSystBeamShiftMap
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) override
double mean(sqlite3 *db, std::string const &table_name, std::string const &column_name)
std::string to_string(ModuleType const mt)
AbsCexDriver(const fhicl::ParameterSet &extra_options)
QTextStream & endl(QTextStream &s)
Event finding and building.