Crombie Tools
src/include/crombie/Correction.h
Go to the documentation of this file.
1 #ifndef CROMBIE_CORRECTION_H
2 #define CROMBIE_CORRECTION_H 1
3 
4 #include <map>
5 #include <string>
6 #include <memory>
7 
8 #include "TH2.h"
9 #include "TFile.h"
10 
11 // ROOT won't let us open files, load histograms, and close files peacefully,
12 // but at least we can avoid opening files multiple times
13 namespace {
14  std::map<std::string, std::unique_ptr<TFile>> files;
15 }
16 
17 /**
18  @ingroup skimminggroup
19  @class Correction
20  @brief A rewrite of the Corrector that allows easy standalone correction application
21 
22  @param H The type of the histogram to read
23 */
24 
25 template<typename H>
26 class Correction {
27  public:
28  /**
29  Reads in one or two histograms from a file.
30 
31  Both histograms must have the same binning.
32  If two histograms are given the corrector applies the first histogram divided by the second.
33  */
34  Correction(std::string filename, const std::string& histname, const std::string& denom = "");
35  ~Correction() { delete hist; }
36 
37  /// Get the correction value from the histogram
38  double GetCorrection(const double xval, const double yval);
39  double GetCorrection(const double xval);
40 
41  private:
42  H* hist;
43  double get(const int bin);
44  using minmax = std::pair<double, double>;
45  minmax xminmax {};
46  minmax yminmax {};
47 
48  double Filter(const minmax& mm, double val);
49 
50 };
51 
52 template<typename H>
53 Correction<H>::Correction(std::string filename, const std::string& histname, const std::string& denom)
54 {
55  if (files.find(filename) == files.end()) {
56  std::unique_ptr<TFile> handle {TFile::Open(filename.data())};
57  files[filename] = std::move(handle);
58  }
59  auto& in = files[filename];
60 
61  hist = static_cast<H*>(in->Get(histname.data())->Clone());
62  if (denom.size())
63  hist->Divide(static_cast<H*>(in->Get(denom.data())));
64 
65  auto* axis = hist->GetXaxis();
66  xminmax.first = axis->GetBinCenter(axis->GetFirst());
67  xminmax.second = axis->GetBinCenter(axis->GetLast());
68 
69  if (dynamic_cast<const TH2*>(hist)) {
70  axis = hist->GetYaxis();
71  yminmax.first = axis->GetBinCenter(axis->GetFirst());
72  yminmax.second = axis->GetBinCenter(axis->GetLast());
73  }
74 }
75 
76 template<typename H>
77 double Correction<H>::GetCorrection(const double xval, const double yval) {
78  return get(hist->FindBin(Filter(xminmax, xval), Filter(yminmax, yval)));
79 };
80 
81 template<typename H>
82 double Correction<H>::GetCorrection(const double xval) {
83  return get(hist->FindBin(Filter(xminmax, xval)));
84 };
85 
86 template<typename H>
87 double Correction<H>::get(const int bin) {
88  return hist->GetBinContent(bin);
89 };
90 
91 template<typename H>
92 double Correction<H>::Filter(const Correction::minmax& mm, double val) {
93  return std::max(mm.first, std::min(mm.second, val));
94 }
95 
96 #endif