ThinSliceSample.h
Go to the documentation of this file.
1 #ifndef THINSLICESAMPLE_hh
2 #define THINSLICESAMPLE_hh
3 
4 #include "TH1D.h"
5 #include "TH2D.h"
6 #include "TH3D.h"
7 #include "TSpline.h"
8 #include "TDirectory.h"
9 #include "TCanvas.h"
10 
11 #include <map>
12 #include <sstream>
13 #include <stdexcept>
14 
15 #include "fhiclcpp/ParameterSet.h"
16 
17 namespace protoana {
18 std::string PreciseToString(const double val, const int n = 2);
19 
20 
21 //Need to split up samples by its true incident energy (from the beam line)
22 
24  public:
25  ThinSliceSample(std::string name, int flux_type,
26  const std::vector<fhicl::ParameterSet> & selections,
27  const std::vector<double> & incident_bins,
28  const std::vector<double> & true_incident_bins,
29  size_t beam_energy_bin,
30  bool is_signal = false, std::pair<double, double> range = {0., 0.});
31 
33 
34  void SetFactor(double f) {fFactor = f;};
35 
36  const std::map<int, TH1 *> & GetSelectionHists() const {
37  return fSelectionHists;
38  };
39 
40  const std::map<int, std::vector<TH1 *>> &
41  GetShifts(std::string syst_name) const {
42  return fSystematicShifts.at(syst_name);
43  };
44 
45  const std::map<int, std::vector<TSpline3 *>> &
46  GetSplines(std::string syst_name) const {
47  return fSystematicSplines.at(syst_name);
48  };
49 
50  const std::map<std::string, std::map<int, std::vector<TSpline3 *>>> &
51  GetAllSplines() const {
52  return fSystematicSplines;
53  };
54 
55  void SetSystematicSplines(const std::map<std::string, std::map<int, std::vector<TSpline3 *>>> & input) {
57  };
58 
59  double GetSplineWeight(std::string syst_name, double par_val,
60  int selection_ID, double val) const {
61  int bin = fSelectionHists.at(selection_ID)->FindBin(val);
62  return fSystematicSplines.at(syst_name).at(selection_ID).at(bin-1)->Eval(par_val);
63  };
64 
65  void AddSystematicShift(TH1 * hist, std::string syst_name,
66  int selection_ID) {
67  fSystematicShifts[syst_name][selection_ID].push_back(hist);
68  };
69 
70  void SaveSystematics(std::string syst_name, TDirectory * dir) {
71  dir->cd();
72  //for (auto it = fSystematicShifts[syst_name].begin();
73  // it != fSystematicShifts[syst_name].end(); ++it) {
74  // for (size_t i = 0; i < it->second.size(); ++i) {
75  // it->second[i]->Write();
76  // }
77  //}
78  for (auto it = fSystematicSplines[syst_name].begin();
79  it != fSystematicSplines[syst_name].end(); ++it) {
80  for (size_t i = 0; i < it->second.size(); ++i) {
81  TCanvas c(it->second[i]->GetName(), "");
82  it->second[i]->Draw();
83  std::string name = syst_name + std::to_string(i);
84  c.Write(syst_name.c_str());
85  }
86  }
87  };
88 
89  const std::map<int, TH1 *> & GetRebinnedSelectionHists() const {
91  };
92 
93  TH1 * GetSelectionHist(int id) {
94  return fSelectionHists.at(id);
95  };
96 
97  /*
98  TH1D & GetIncidentHist() {
99  return fIncidentHist;
100  };*/
101 
103  return fTrueIncidentHist;
104  };
105 
106 /*
107  TH1D & GetRebinnedIncidentHist() {
108  return fIncidentHistRebinned;
109  };*/
110 
111  TH1 * GetRebinnedSelectionHist(int id) {
112  return fSelectionHistsRebinned.at(id);
113  };
114 
115  const std::string & GetName() const {
116  return fSampleName;
117  };
118 
119  const int & GetFluxType() const {
120  return fFluxType;
121  };
122 
123  const double & GetNominalFlux() const {
124  return fNominalFlux;
125  };
126 
127  const double & GetVariedFlux() const {
128  return fVariedFlux;
129  };
130 
131  void AddFlux(double val = 1.) {
132  fNominalFlux += val;
133  fVariedFlux += val;
134  };
135 
136  void AddVariedFlux(double val = 1.) {
137  fVariedFlux += val;
138  }
139 
141  int selection_ID,
142  const std::vector<double> & vals) {
143  if (vals.size() !=
144  fSystematicShifts[syst_name][selection_ID].size()) {
145  std::string message = "ThinSliceSample: Input systematic shift values and number of shift hists differ";
146  throw std::runtime_error(message);
147  }
148 
149  for (size_t i = 0; i < vals.size(); ++i) {
150  fSystematicShifts[syst_name][selection_ID][i]->Fill(vals[i]);
151  }
152  };
153 
155  int selection_ID,
156  const std::vector<double> & vals,
157  const std::vector<double> & weights) {
158  if (vals.size() !=
159  fSystematicShifts[syst_name][selection_ID].size()) {
160  std::string message = "ThinSliceSample: Input systematic shift values and number of shift hists differ";
161  throw std::runtime_error(message);
162  }
163 
164  for (size_t i = 0; i < vals.size(); ++i) {
165  fSystematicShifts[syst_name][selection_ID][i]->Fill(vals[i], weights[i]);
166  }
167  };
168 
169  void SetSystematicVals(std::string syst_name, std::vector<double> & vals) {
170  fSystematicVals[syst_name] = vals;
171  };
172 
173  void MakeSystematicSplines(std::string syst_name/*, bool do_insert = true*/) {
174  for (auto it2 = fSystematicShifts[syst_name].begin();
175  it2 != fSystematicShifts[syst_name].end(); ++it2) {
176  int selection_ID = it2->first;
177  std::vector<TH1*> hists = it2->second;
178  TH1D * selection_hist = (TH1D*)fSelectionHists[selection_ID];
179  for (int i = 1; i <= selection_hist->GetNbinsX(); ++i) {
180  std::vector<double> vars;
181  for (size_t j = 0; j < hists.size(); ++j) {
182  if (selection_hist->GetBinContent(i) < 1.e-5) {
183  vars.push_back(1.);
184  }
185  else {
186  vars.push_back(
187  hists[j]->GetBinContent(i)/selection_hist->GetBinContent(i));
188  }
189  }
190  //if (do_insert)
191  vars.insert(vars.begin() + vars.size()/2, 1.);
192  std::string spline_name = selection_hist->GetName();
193  spline_name += "_" + syst_name + "_Spline_" + std::to_string(i);
194  fSystematicSplines[syst_name][selection_ID].push_back(
195  new TSpline3(spline_name.c_str(), &fSystematicVals[syst_name][0],
196  &vars[0], vars.size()));
197  }
198  }
199  };
200 
201 /*
202  void FillIncidentHist(const std::vector<double> & vals) {
203  for (size_t i = 0; i < vals.size(); ++i) {
204  fIncidentHist.Fill(vals.at(i));
205  }
206  };*/
207 
208  void AddIncidentEnergies(const std::vector<double> & vals, double weight = 1.) {
209  for (auto v : vals)
210  fIncidentEnergies.push_back({v, weight});
211  };
212 
213  void AddESliceEnergies(const std::pair<double, double> & vals, double weight = 1.) {
214  fESliceEnergies.push_back({vals, weight});
215  };
216 
217  void FillTrueIncidentHist(const std::vector<double> & vals, double weight = 1.) {
218  for (size_t i = 0; i < vals.size(); ++i) {
219  fTrueIncidentHist.Fill(vals.at(i), weight);
220  }
221  };
222 
223  void FillSelectionHist(int id, double val, double weight = 1.) {
224  if (fSelectionHists.find(id) != fSelectionHists.end()) {
225  fSelectionHists.at(id)->Fill(val, weight);
226  }
227  };
228 
229  template <size_t N> void FillSelectionHist(int id, const double (& vals)[N],
230  double weight = 1.) {
231  if (N < 1 || N > 3) {
232  std::string message = "Error: trying to fill hists with too many values";
233  message += std::to_string(N);
234  throw std::runtime_error(message);
235  }
236 
237  if (fSelectionHists.find(id) != fSelectionHists.end()) {
238  if (N == 1) {
239  fSelectionHists.at(id)->Fill(vals[0], weight);
240  }
241  else if (N == 2) {
242  ((TH2D*)fSelectionHists.at(id))->Fill(vals[0], vals[1], weight);
243  }
244  else if (N == 3) {
245  ((TH3D*)fSelectionHists.at(id))->Fill(vals[0], vals[1], vals[2], weight);
246  }
247  }
248  }
249 
251  for (auto vals : fIncidentEnergies) {
252  //hist.Fill(vals.first, fFactor/*vals.second*/);
253  hist.Fill(vals.first, fFactor*vals.second);
254  }
255  };
256 
257  void FillESliceHist(TH1D & hist) {
258  for (auto e : fESliceEnergies) {
259  std::pair<double, double> vals = e.first;
260  double w = e.second;
261  int last_bin = hist.FindBin(vals.first);
262  int first_bin = hist.FindBin(vals.second);
263  for (int i = first_bin; i <= last_bin; ++i)
264  //hist.AddBinContent(i, fFactor);
265  hist.AddBinContent(i, fFactor*w);
266  }
267  };
268 
269  void ScaleHists(double val) {
270  for (auto it = fSelectionHists.begin(); it != fSelectionHists.end(); ++it) {
271  it->second->Scale(val);
272  }
274 
275  fTrueIncidentHist.Scale(val);
276  };
277 
278  void ScaleIncidentEnergies(double val) {
279  for (auto it = fIncidentEnergies.begin();
280  it != fIncidentEnergies.end(); ++it) {
281  it->second *= val;
282  }
283  };
284 
285  void ScaleESliceEnergies(double val) {
286  for (auto it = fESliceEnergies.begin();
287  it != fESliceEnergies.end(); ++it) {
288  it->second *= val;
289  }
290  };
291 
292  void Reset() {
293  fVariedFlux = 0.;
294  for (auto it = fSelectionHists.begin(); it != fSelectionHists.end(); ++it) {
295  it->second->Reset();
296  }
297 
298  fTrueIncidentHist.Reset();
299 
300  fIncidentEnergies.clear();
301  fESliceEnergies.clear();
302  fFactor = 1.;
303  };
304 
305  void ScaleVariedFlux(double val) {
306  fVariedFlux *= val;
307  };
308 
309  void ScaleToDataMC() {
314  }
315 
316  void SetDataMCScale(double val) {
317  fDataMCScale = val;
320  fNominalFlux *= val;
321  fVariedFlux *= val;
322  };
323 
324  void SetFactorAndScale(double val) {
325  ResetFactor();
326  fFactor = val;
327  fVariedFlux *= val;
328  ScaleHists(val);
329  };
330 
331  void ExtraFactor(double val) {
333  };
334 
335  double GetFactor() {
336  return fFactor;
337  };
338 
339  void ResetFactor() {
340  ScaleHists(1./fFactor);
341  fVariedFlux *= (1./fFactor);
342  fFactor = 1.;
343  };
344 
347  };
348 
349  double GetBestFitFactor() {
350  return fBestFitFactor;
351  };
352 
353  void SetBestFit() {
354  if (fBestFitIsSet) {
355  return;
356  }
357 
359  fBestFitIsSet = true;
360  };
361 
362  bool CheckIsSignal() {return fIsSignal;};
363  bool CheckInSignalRange(double val) {return ((fRange.first < val) &&
364  (val <= fRange.second));};
365  double RangeLowEnd() {return fRange.first;};
366  double RangeHighEnd() {return fRange.second;};
367 
368  const std::pair<double, double> & GetRange() const {return fRange;};
369 
370  void RefillRebinnedHists();
371  void MakeRebinnedHists();
372 
373  private:
374  double fFactor = 1., fBestFitFactor = 1.;
375  bool fBestFitIsSet = false;
378  double fNominalFlux = 0.;
379  double fVariedFlux = 0.;
380  double fDataMCScale = 1.;
381  bool fIsSignal;
382  std::pair<double, double> fRange;
383 
384  void Rebin1D(TH1 * sel_hist, TH1 * rebinned);
385  void Rebin2D(TH1 * sel_hist, TH1 * rebinned);
386  void Rebin3D(TH1 * sel_hist, TH1 * rebinned);
387  std::map<int, TH1 *> fSelectionHists;
388  //TH1D fIncidentHist;
390  std::map<int, TH1 *> fSelectionHistsRebinned;
391  //TH1D fIncidentHistRebinned;
392 
393  bool fMadeRebinned = false;
394 
395  //Consider changing to a class itself
396  // syst name selection id
397  // string in 1st map: syst name
398  // int in 2nd map: selection ID
399  // index of vector: bin of corresponding selection hist
400  std::map<std::string, std::map<int, std::vector<TSpline3 *>>>
402  std::map<std::string, std::map<int, std::vector<TH1 *>>>
404  std::map<std::string, std::vector<double>> fSystematicVals;
405 
406 
407  std::vector<std::pair<double, double>> fIncidentEnergies;
408  std::vector<std::pair<std::pair<double, double>, double>> fESliceEnergies;
409 
410 };
411 
412 }
413 #endif
static QCString name
Definition: declinfo.cpp:673
std::map< std::string, std::map< int, std::vector< TH1 * > > > fSystematicShifts
void FillSystematicShift(std::string syst_name, int selection_ID, const std::vector< double > &vals, const std::vector< double > &weights)
void AddESliceEnergies(const std::pair< double, double > &vals, double weight=1.)
void FillESliceHist(TH1D &hist)
const std::pair< double, double > & GetRange() const
std::string string
Definition: nybbler.cc:12
void AddVariedFlux(double val=1.)
void ScaleVariedFlux(double val)
TH1 * GetRebinnedSelectionHist(int id)
std::pair< double, double > fRange
string dir
void ScaleIncidentEnergies(double val)
const double & GetVariedFlux() const
weight
Definition: test.py:257
const std::map< int, std::vector< TH1 * > > & GetShifts(std::string syst_name) const
void AddIncidentEnergies(const std::vector< double > &vals, double weight=1.)
std::vector< std::pair< double, double > > fIncidentEnergies
std::map< std::string, std::map< int, std::vector< TSpline3 * > > > fSystematicSplines
std::vector< std::pair< std::pair< double, double >, double > > fESliceEnergies
void AddFlux(double val=1.)
const double e
static int input(void)
Definition: code.cpp:15695
double GetSplineWeight(std::string syst_name, double par_val, int selection_ID, double val) const
void ExtraFactor(double val)
TH1 * GetSelectionHist(int id)
std::map< std::string, std::vector< double > > fSystematicVals
void SetDataMCScale(double val)
std::void_t< T > n
void Rebin1D(TH1 *sel_hist, TH1 *rebinned)
const std::map< int, TH1 * > & GetSelectionHists() const
const std::map< int, TH1 * > & GetRebinnedSelectionHists() const
void SaveSystematics(std::string syst_name, TDirectory *dir)
ThinSliceSample(std::string name, int flux_type, const std::vector< fhicl::ParameterSet > &selections, const std::vector< double > &incident_bins, const std::vector< double > &true_incident_bins, size_t beam_energy_bin, bool is_signal=false, std::pair< double, double > range={0., 0.})
void SetSystematicSplines(const std::map< std::string, std::map< int, std::vector< TSpline3 * >>> &input)
std::map< int, TH1 * > fSelectionHistsRebinned
const double & GetNominalFlux() const
const std::map< int, std::vector< TSpline3 * > > & GetSplines(std::string syst_name) const
std::map< int, TH1 * > fSelectionHists
void SetFactorAndScale(double val)
void FillSelectionHist(int id, double val, double weight=1.)
auto selection_ID
void FillTrueIncidentHist(const std::vector< double > &vals, double weight=1.)
void Rebin3D(TH1 *sel_hist, TH1 *rebinned)
void MakeSystematicSplines(std::string syst_name)
void ScaleESliceEnergies(double val)
void SetSystematicVals(std::string syst_name, std::vector< double > &vals)
const int & GetFluxType() const
void ScaleHists(double val)
QTextStream & bin(QTextStream &s)
bool CheckInSignalRange(double val)
void FillSystematicShift(std::string syst_name, int selection_ID, const std::vector< double > &vals)
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
Definition: StdUtils.h:72
std::string PreciseToString(const double val, const int n=2)
void AddSystematicShift(TH1 *hist, std::string syst_name, int selection_ID)
void FillHistFromIncidentEnergies(TH1D &hist)
const std::string & GetName() const
std::string to_string(ModuleType const mt)
Definition: ModuleType.h:34
const std::map< std::string, std::map< int, std::vector< TSpline3 * > > > & GetAllSplines() const
void FillSelectionHist(int id, const double(&vals)[N], double weight=1.)
void Rebin2D(TH1 *sel_hist, TH1 *rebinned)