DAS  3.0
Das Analysis System
GenericSFApplier.h
Go to the documentation of this file.
1 #pragma once
2 
5 
6 #include <darwin.h>
7 
8 #include <TFile.h>
9 #include <TH1.h>
10 
11 #include <filesystem>
12 #include <map>
13 #include <utility>
14 #include <vector>
15 
16 namespace DAS {
17 
22 inline std::unique_ptr<TH1> getHistSafe (std::unique_ptr<TFile>& f,
23  const std::string& name)
24 {
26  auto h = std::unique_ptr<TH1>(f->Get<TH1>(name.c_str()));
27  if (!h) {
28  std::cerr << name << std::endl;
29  BOOST_THROW_EXCEPTION( Darwin::Exceptions::BadInput("Can't find required histogram", f) );
30  }
31  h->SetDirectory(nullptr);
32  return h;
33 }
34 
40 template<class Object>
41 Weights &weightsRef (Object& obj)
42 {
43  return obj.weights;
44 }
45 
85 template<class Object, class... Context>
87 {
88  std::unique_ptr<TFile> m_file;
89  bool m_correction,
91 
93  std::unique_ptr<TH1> m_nominal;
95  std::map<std::string, std::unique_ptr<TH1>> m_bin_wise_uncs;
97  std::map<std::string, std::unique_ptr<TH1>> m_global_uncs;
98 
99 public:
100  GenericSFApplier (const std::filesystem::path& filePath,
101  bool correction,
102  bool uncertainties);
103  virtual ~GenericSFApplier () noexcept = default;
104 
105  void operator() (Object& object, const Context&... ctx) const;
106  void operator() (std::vector<Object>& objects, const Context&... ctx) const;
107  std::vector<std::string> weightNames () const;
108 
109 protected:
116  };
117 
118  void loadNominal (const std::string& histPath);
119  void loadBinWiseUnc (const std::string& name,
120  const std::string& histPath,
122  void loadGlobalUnc (const std::string& name,
123  const std::string& histPath,
125 
132  virtual bool passes (const Object& obj, const Context&... ctx) const = 0;
133 
141  virtual int binIndex (const Object& obj,
142  const Context&... ctx,
143  const std::unique_ptr<TH1>& hist) const = 0;
144 };
145 
152 template<class Object, class... Context>
154  const std::filesystem::path& filePath,
155  bool correction,
156  bool uncertainties)
157  : m_correction(correction)
158  , m_uncertainties(uncertainties)
159 {
160  namespace fs = std::filesystem;
161 
162  if (!correction)
163  return;
164 
165  // Check that the file exists
166  if (!fs::exists(filePath))
167  BOOST_THROW_EXCEPTION(
168  fs::filesystem_error("Not found",
169  filePath,
170  make_error_code(std::errc::no_such_file_or_directory)));
171 
172  m_file = std::make_unique<TFile>(filePath.c_str(), "READ");
173 }
174 
175 
179 template<class Object, class... Context>
181  Object& obj, const Context&... ctx) const
182 {
183  auto& weights = weightsRef(obj);
184 
185  // For safety
186  if (weights.empty()) weights.emplace_back(DAS::Weight{1, 0});
187 
188  const float old = weights.front().v;
189  if (old == 0) return; // Don't bother
190 
191  // Apply the cut
192  if (!passes(obj, ctx...)) {
193  weights = {{0, 0}};
194  return; // Skip applying weights
195  }
196 
197  // Nominal correction
198  if (!m_correction) return;
199 
200  const int bin = binIndex(obj, ctx..., m_nominal);
201  const float sf = m_nominal->GetBinContent(bin);
202  weights *= sf;
203 
204  // Systematics
205  if (!m_uncertainties) return;
206 
207  // The order of the next two blocks must match weightNames()
208  for (const auto& [_, hist] : m_bin_wise_uncs) {
209  const float variation = hist->GetBinContent(bin);
210  weights.push_back({old * (sf + variation), bin});
211  weights.push_back({old * (sf - variation), bin});
212  }
213 
214  for (const auto& [_, hist] : m_global_uncs) {
215  const float variation = hist->GetBinContent(bin);
216  weights.push_back({old * (sf + variation), 0});
217  weights.push_back({old * (sf - variation), 0});
218  }
219 }
220 
224 template<class Object, class... Context>
226  std::vector<Object>& objects, const Context&... ctx) const
227 {
228  for (auto& obj: objects) {
229  (*this)(obj, ctx...);
230  }
231 }
232 
237 template<class Object, class... Context>
238 std::vector<std::string>
240 {
241  std::vector<std::string> names;
242  // The order of the next two blocks must match the call operator
243  for (const auto& [name, _] : m_bin_wise_uncs) {
244  names.push_back(name + SysUp);
245  names.push_back(name + SysDown);
246  }
247  for (const auto& [name, _] : m_global_uncs) {
248  names.push_back(name + SysUp);
249  names.push_back(name + SysDown);
250  }
251  return names;
252 }
253 
258 template<class Object, class... Context>
260  const std::string& histPath)
261 {
262  if (!m_correction) return;
263  m_nominal = getHistSafe(m_file, histPath);
264 }
265 
274 template<class Object, class... Context>
276  const std::string& name, const std::string& histPath, Interpretation intp)
277 {
278  if (!m_correction || !m_uncertainties) return;
279  auto hist = getHistSafe(m_file, histPath);
280  if (intp == UseBinError) // We always store variations in the bin contents
281  for (int i = 0; i <= hist->GetNcells(); ++i)
282  hist->SetBinContent(i, hist->GetBinError(i));
283  m_bin_wise_uncs[name] = std::move(hist);
284 }
285 
294 template<class Object, class... Context>
296  const std::string& name, const std::string& histPath, Interpretation intp)
297 {
298  if (!m_correction || !m_uncertainties) return;
299  auto hist = getHistSafe(m_file, histPath);
300  if (intp == UseBinError) // We always store variations in the bin contents
301  for (int i = 0; i <= hist->GetNcells(); ++i)
302  hist->SetBinContent(i, hist->GetBinError(i));
303  m_global_uncs[name] = std::move(hist);
304 }
305 
306 } // namespace DAS
DYToLL_M-50_13TeV_pythia8_cff_GEN_SIM_RECOBEFMIX_DIGI_L1_DIGI2RAW_L1Reco_RECO.name
name
Definition: DYToLL_M-50_13TeV_pythia8_cff_GEN_SIM_RECOBEFMIX_DIGI_L1_DIGI2RAW_L1Reco_RECO.py:48
DAS::Weights
std::vector< Weight > Weights
Definition: Weight.h:41
Ntupliser_cfg.cerr
cerr
Definition: Ntupliser_cfg.py:93
DAS
Definition: applyBTagSF.cc:31
DAS::GenericSFApplier::GenericSFApplier
GenericSFApplier(const std::filesystem::path &filePath, bool correction, bool uncertainties)
Constructor.
Definition: GenericSFApplier.h:153
DAS::GenericSFApplier::~GenericSFApplier
virtual ~GenericSFApplier() noexcept=default
DAS::GenericSFApplier::loadNominal
void loadNominal(const std::string &histPath)
Loads the histogram with the nominal scale factor. Has no effect when not applying the correction.
Definition: GenericSFApplier.h:259
DAS::GenericSFApplier::passes
virtual bool passes(const Object &obj, const Context &... ctx) const =0
Called to check whether an object passes the selection.
DAS::SysUp
const std::string SysUp
Suffix used for "up" uncertainties. Follows the Combine convention.
Definition: Format.h:8
DAS::GenericSFApplier::UseBinContent
@ UseBinContent
The histogram contains the uncertainty in the scale factors.
Definition: GenericSFApplier.h:113
DAS::GenericSFApplier::m_uncertainties
bool m_uncertainties
Calculate uncertainties?
Definition: GenericSFApplier.h:90
Format.h
Ntupliser_cfg.f
f
Definition: Ntupliser_cfg.py:252
DAS::GenericSFApplier< RecEvent, Trigger, vector< RecMuon > >::Interpretation
Interpretation
How loaded histograms should be interpreted.
Definition: GenericSFApplier.h:111
DAS::GenericSFApplier::binIndex
virtual int binIndex(const Object &obj, const Context &... ctx, const std::unique_ptr< TH1 > &hist) const =0
Called to retrieve the bin to use in the scale factor histograms.
DAS::GenericSFApplier::loadBinWiseUnc
void loadBinWiseUnc(const std::string &name, const std::string &histPath, Interpretation intp=UseBinContent)
Loads a systematic with bin-by-bin correlations.
Definition: GenericSFApplier.h:275
DAS::GenericSFApplier::m_global_uncs
std::map< std::string, std::unique_ptr< TH1 > > m_global_uncs
Histograms with uncertainties correlated.
Definition: GenericSFApplier.h:97
DAS::GenericSFApplier::m_file
std::unique_ptr< TFile > m_file
SFs are loaded from this file.
Definition: GenericSFApplier.h:88
DAS::GenericSFApplier::UseBinError
@ UseBinError
The histogram errors contain the uncertainty in the scale factors.
Definition: GenericSFApplier.h:115
DAS::GenericSFApplier::m_nominal
std::unique_ptr< TH1 > m_nominal
Histogram with the nominal SFs.
Definition: GenericSFApplier.h:93
DAS::getHistSafe
std::unique_ptr< TH1 > getHistSafe(std::unique_ptr< TFile > &f, const std::string &name)
Gets an histogram from a TFile.
Definition: GenericSFApplier.h:22
DAS::Weight
Definition: Weight.h:16
DAS::GenericSFApplier
A generic base class to simplify applying scale factors.
Definition: GenericSFApplier.h:87
DAS::GenericSFApplier::weightNames
std::vector< std::string > weightNames() const
Retrieves the name of weights added by this applier. Returns an empty vector when uncertainties are d...
Definition: GenericSFApplier.h:239
Weight.h
DAS::GenericSFApplier::m_bin_wise_uncs
std::map< std::string, std::unique_ptr< TH1 > > m_bin_wise_uncs
Histograms with uncertainties correlated bin-by-bin.
Definition: GenericSFApplier.h:95
DAS::SysDown
const std::string SysDown
Suffix used for "down" uncertainties. Follows the Combine convention.
Definition: Format.h:10
DAS::GenericSFApplier::m_correction
bool m_correction
Apply the scale factors?
Definition: GenericSFApplier.h:89
jercExample.sf
sf
Definition: jercExample.py:112
DAS::GenericSFApplier::loadGlobalUnc
void loadGlobalUnc(const std::string &name, const std::string &histPath, Interpretation intp=UseBinContent)
Loads a fully correlated systematic.
Definition: GenericSFApplier.h:295
DAS::weightsRef
Weights & weightsRef(Object &obj)
Customization point for how weights are retrieved from an object.
Definition: GenericSFApplier.h:41
weights
DAS::Weights weights
Definition: classes.h:12
DAS::GenericSFApplier::operator()
void operator()(Object &object, const Context &... ctx) const
Applies the selection and scale factors to a single object.
Definition: GenericSFApplier.h:180
Darwin::Exceptions::BadInput
Generic exception for ill-defined input (before the event loop).
Definition: exceptions.h:68