DAS  3.0
Das Analysis System
applyPrefiringWeights.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <cassert>
4 #include <cstdlib>
5 
6 #include <iostream>
7 #include <filesystem>
8 #include <tuple>
9 #include <vector>
10 
13 
16 
17 #include <TF1.h>
18 #include <TH2.h>
19 
20 #include <darwin.h>
21 
22 namespace fs = std::filesystem;
23 namespace DE = Darwin::Exceptions;
24 
25 static const auto feps = std::numeric_limits<float>::epsilon();
26 
27 namespace DAS::Prefiring {
28 
39 struct Functor {
40 
41  std::tuple<TH2*, TH2*, TH2*> prefBinnedWeights;
42  std::tuple<TF1 *, TF1*> prefSmoothWeights;
43 
44  using Operation = std::tuple<float,float,float> (Functor::*)(int,const RecJet&) const;
46 
47  const bool syst;
48 
49  std::vector<TH2 *> multiplicities;
50 
59  static std::tuple<TH2*, TH2*, TH2*> PrepareBinnedWeights (const std::unique_ptr<TH2>& hIn)
60  {
61  using namespace std;
62 
63  auto MapNo = dynamic_cast<TH2*>(hIn->Clone("nominal_map")),
64  MapUp = dynamic_cast<TH2*>(hIn->Clone("upper_map" )),
65  MapDn = dynamic_cast<TH2*>(hIn->Clone("lower_map" ));
66  MapNo->SetDirectory(0);
67  MapUp->SetDirectory(0);
68  MapDn->SetDirectory(0);
69  for (int etabin = 0; etabin <= hIn->GetNbinsX()+1; ++etabin)
70  for (int ptbin = 0; ptbin <= hIn->GetNbinsY()+1; ++ ptbin) {
71  auto proba = hIn->GetBinContent(etabin, ptbin),
72  error = hIn->GetBinError (etabin, ptbin);
73 
74  // uncertainty only in the forward region! (the following boolean is a trick :D)
75  bool Forward = (proba > feps); // means proba > 0
76  auto unc = Forward ? max(proba * 0.2f, error) : 0.f;
78 
79  // the map contains the probability, but we want the weight
80  auto weight = 1. - proba;
81 
82  MapNo->SetBinContent(etabin, ptbin, weight);
83  MapUp->SetBinContent(etabin, ptbin, weight+unc);
84  MapDn->SetBinContent(etabin, ptbin, weight-unc);
85 
86  //if (Forward) cout << green;
87  //cout << setw(10) << etabin << setw(10) << ptbin << setw(20) << proba << setw(15) << error << setw(20) << weight << setw(15) << unc << /*normal <<*/ endl;
88  }
89 
90  return { MapNo, MapUp, MapDn };
91  }
92 
99  static std::tuple<TF1*, TF1*> PrepareSmoothWeights (TString hname, std::unique_ptr<TFile> f)
100  {
101  using namespace std;
102 
103  cout << hname << endl;
104  auto f5 = f->Get<TF1>(hname + "_ybin5"),
105  f6 = f->Get<TF1>(hname + "_ybin6");
106  assert(f5 != nullptr);
107  assert(f6 != nullptr);
108  return {f5, f6};
109  }
110 
114  static std::vector<TH2 *> GetMultiplicityPlots (TH2 * templ, int n = 7)
115  {
116  using namespace std;
117 
118  vector<TH2*> v;
119  for (int i = 1; i <= n; ++i) {
120  auto h = dynamic_cast<TH2*>(templ->Clone(Form("multiplicity_nbin%d", i)));
121  h->Reset();
122  v.push_back(h);
123  }
124  return v;
125  }
126 
130  (const fs::path& file,
131  const std::string name,
132  const std::string type,
133  bool applySyst
134  ) :
135  GetWeights(type == "smooth" ? &Functor::GetSmoothWeights :
136  type == "binned" ? &Functor::GetBinnedWeights : nullptr),
137  syst(applySyst)
138  {
139  using namespace std;
140 
141  if (!fs::exists(file))
142  BOOST_THROW_EXCEPTION( fs::filesystem_error("File does not exists.",
143  file, make_error_code(errc::no_such_file_or_directory)) );
144 
145  auto f = make_unique<TFile>(file.c_str(), "READ");
146  string hname = file.stem().string();
147  auto h = unique_ptr<TH2>(f->Get<TH2>(hname.c_str()));
148  if (h.get() == nullptr) {
149  string what = "Map " + hname + " can't be found";
150  BOOST_THROW_EXCEPTION( DE::BadInput(what.c_str(), f) );
151  }
152  // this map contains the probabilities, not the weights (p + w = 1)
153 
154  // retrieve map in histograms
155  if (type == "binned")
157  else if (type == "smooth")
158  prefSmoothWeights = PrepareSmoothWeights(file.c_str(), move(f));
159  else
160  BOOST_THROW_EXCEPTION( invalid_argument("Types may only be 'smooth' and 'binned'.") );
161 
162  TH2 * templ = get<0>(prefBinnedWeights);
164 
165  cout << "Prefiring weights are ready" << endl;
166  }
167 
168 private:
171  std::tuple<float,float,float> GetBinnedWeights (int run, const RecJet& recjet) const
172  {
173  using namespace std;
174 
175  TH2 * MapNo = get<0>(prefBinnedWeights),
176  * MapUp = get<1>(prefBinnedWeights),
177  * MapDn = get<2>(prefBinnedWeights);
178 
179  FourVector p4 = recjet.p4;
180  p4 *= recjet.scales.front();
181 
182  auto eta = p4.Eta();
183 
184  if (std::abs(eta) < 2.0 || std::abs(eta) >= 3.0) return { 1, 1, 1};
185 
186  auto pt = p4.Pt();
187 
188  int etabin = MapNo->GetXaxis()->FindBin(eta),
189  ptbin = min(MapNo->GetYaxis()->FindBin(pt ), MapNo->GetNbinsY()); // i.e. don't take the overflow
190 
191  auto corr = MapNo->GetBinContent(etabin, ptbin),
192  varUp = MapUp->GetBinContent(etabin, ptbin),
193  varDn = MapDn->GetBinContent(etabin, ptbin);
194 
195  //cout << run << setw(15) << eta << setw(15) << pt << setw(10) << etabin << setw(10) << ptbin << setw(20) << corr << setw(10) << varUp << setw(10) << varDn << '\n';
196 
197  return {corr, varUp, varDn};
198  }
199 
202  std::tuple<float, float, float> GetSmoothWeights (int run, const RecJet& recjet) const
203  {
204  using namespace std;
205 
206  FourVector p4 = recjet.p4;
207  p4 *= recjet.scales.front();
208 
209  auto eta = p4.Eta();
210  int etabin = 1 + abs(eta)*2;
211 
212  //cout << eta << ' ' << etabin << endl;
213  if (etabin < 5 || etabin > 6) return { 1, 1, 1};
214 
215  auto f = etabin == 5 ? get<0>(prefSmoothWeights)
216  : get<1>(prefSmoothWeights);
217  auto pt = p4.Pt();
218  auto eval = f->Eval(pt);
219 
220  float corr = 1- eval,
221  varUp = 1-1.5*eval,
222  varDn = 1-0.75*eval;
223 
224  //cout << run << setw(15) << eta << setw(15) << pt << setw(10) << etabin << setw(20) << corr << setw(10) << varUp << setw(10) << varDn << '\n';
225 
226  return {corr, varUp, varDn};
227  }
228 
229 public:
232  void operator() (RecEvent & evnt, const std::vector<RecJet>& recjets)
233  {
234  using namespace std;
235  //cout << "=====" << endl;
236 
237  // first, get the weights as a function of all jets present at |eta| > 2.0
238  tuple<float,float,float> wAllJets { 1, 1, 1 };
239  for (const RecJet& recjet: recjets) {
240 
241  auto wJet = (this->*GetWeights)(evnt.runNo, recjet);
242 
243  get<0>(wAllJets) *= get<0>(wJet);
244  get<1>(wAllJets) *= get<1>(wJet);
245  get<2>(wAllJets) *= get<2>(wJet);
246  }
247 
248  // then fill control plots
249  size_t i = 0;
250  for (const RecJet& recjet: recjets) {
251 
252  float pt = recjet.CorrPt(0),
253  wEvt0 = evnt.weights.front(),
254  wJet0 = recjet.weights.front();
255 
256  // multiplicites
257  static const size_t n = multiplicities.size();
258  if (i >= n) continue;
259  multiplicities.at(i)->Fill(recjet.p4.Eta(), pt, wEvt0 * wJet0);
260  ++i;
261  }
262 
263  //cout << evnt.runNo << setw(20) << get<0>(wAllJets) << setw(20) << get<1>(wAllJets) << setw(20) << get<2>(wAllJets) << '\n';
264  //cout << "-----" << endl;
265 
266  // finally, modify the branches
267  float rw0 = evnt.weights.front();
268  assert(get<0>(wAllJets) > 0); // this could only arrive for jets < 30 GeV
269  evnt.weights /= get<0>(wAllJets);
270 
271  if (!syst) return;
272  evnt.weights.push_back(Weight{rw0 / get<1>(wAllJets)});
273  evnt.weights.push_back(Weight{rw0 / get<2>(wAllJets)});
275  }
276 
279  void Write (TDirectory * dir)
280  {
281  using namespace std;
282 
283  dir->cd();
284  TH2 * MapNo = get<0>(prefBinnedWeights),
285  * MapUp = get<1>(prefBinnedWeights),
286  * MapDn = get<2>(prefBinnedWeights);
287  for (TH2 * h: {MapNo, MapUp, MapDn}) {
288  if (h == nullptr) continue;
289  h->SetDirectory(dir);
290  TString name = h->GetName();
291  name = name(0, name.First('_')-1);
292  h->Write(name);
293  }
294  TF1 * f5 = get<0>(prefSmoothWeights),
295  * f6 = get<1>(prefSmoothWeights);
296  if (f5 != nullptr) f5->Write("ybin5");
297  if (f6 != nullptr) f6->Write("ybin6");
298 
299  for (auto m: multiplicities) {
300  m->SetDirectory(dir);
301  m->Write();
302  }
303  }
304 };
305 
306 } // end of namespace
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
jmarExample.pt
pt
Definition: jmarExample.py:19
DAS::PhysicsObject::p4
FourVector p4
raw four-momentum directly after reconstruction
Definition: PhysicsObject.h:50
DAS::Prefiring::Functor::GetBinnedWeights
std::tuple< float, float, float > GetBinnedWeights(int run, const RecJet &recjet) const
Subroutine to get weights for a give event directly from the maps.
Definition: applyPrefiringWeights.h:171
DAS::Prefiring::Functor
Definition: applyPrefiringWeights.h:39
Ntupliser_cfg.f
f
Definition: Ntupliser_cfg.py:256
DAS::RecEvent
Definition: Event.h:52
Event.h
DAS::RecJet
Definition: Jet.h:37
DAS::PhysicsObject::scales
std::vector< float > scales
energy scale corrections and variations
Definition: PhysicsObject.h:51
DAS::AbstractEvent::weights
Weights weights
e.g. cross section normalisation
Definition: Event.h:23
DAS::Prefiring::Functor::GetWeights
const Operation GetWeights
Definition: applyPrefiringWeights.h:45
Jet.h
feps
static const auto feps
Definition: applyPrefiringWeights.h:25
DAS::RecEvent::runNo
int runNo
6-digit run number
Definition: Event.h:55
DAS::Prefiring::Functor::Write
void Write(TDirectory *dir)
Write maps and control plots to output root file.
Definition: applyPrefiringWeights.h:279
DAS::Prefiring::Functor::prefBinnedWeights
std::tuple< TH2 *, TH2 *, TH2 * > prefBinnedWeights
weights extracted from the maps, indiced with run number (three variations)
Definition: applyPrefiringWeights.h:41
DAS::Prefiring::Functor::operator()
void operator()(RecEvent &evnt, const std::vector< RecJet > &recjets)
Operator overloading for event-by-event call.
Definition: applyPrefiringWeights.h:232
DAS::Prefiring
Definition: applyPrefiringWeights.cc:27
binnings.h
recjet
DAS::RecJet recjet
Definition: classes.h:15
weight
DAS::Weight weight
Definition: classes.h:11
Darwin::Exceptions
Handling of exceptions.
Definition: darwin.h:36
jercExample.unc
string unc
Definition: jercExample.py:70
DAS::Prefiring::Functor::PrepareBinnedWeights
static std::tuple< TH2 *, TH2 *, TH2 * > PrepareBinnedWeights(const std::unique_ptr< TH2 > &hIn)
Definition: applyPrefiringWeights.h:59
DAS::Prefiring::Functor::PrepareSmoothWeights
static std::tuple< TF1 *, TF1 * > PrepareSmoothWeights(TString hname, std::unique_ptr< TFile > f)
Definition: applyPrefiringWeights.h:99
Ntupliser_cfg.recjets
recjets
Definition: Ntupliser_cfg.py:273
toolbox.h
DAS::Prefiring::Functor::Functor
Functor(const fs::path &file, const std::string name, const std::string type, bool applySyst)
Functor to apply prefiring correction.
Definition: applyPrefiringWeights.h:130
DAS::Weight
Definition: Weight.h:16
DAS::PhysicsObject::CorrPt
float CorrPt(size_t i=0) const
corrected transverse momentum
Definition: PhysicsObject.h:55
DAS::Prefiring::Functor::Operation
std::tuple< float, float, float >(Functor::*)(int, const RecJet &) const Operation
Definition: applyPrefiringWeights.h:44
DAS::Prefiring::Functor::GetMultiplicityPlots
static std::vector< TH2 * > GetMultiplicityPlots(TH2 *templ, int n=7)
Definition: applyPrefiringWeights.h:114
DAS::Prefiring::Functor::multiplicities
std::vector< TH2 * > multiplicities
jets in the forward region in the same binning as the maps (before correction)
Definition: applyPrefiringWeights.h:49
DAS::Prefiring::Functor::syst
const bool syst
Definition: applyPrefiringWeights.h:47
DAS::PhysicsObject::weights
Weights weights
object weights
Definition: PhysicsObject.h:52
DAS::Prefiring::Functor::prefSmoothWeights
std::tuple< TF1 *, TF1 * > prefSmoothWeights
weights extracted from smooth functions, indiced with run number (two rapidity bins)
Definition: applyPrefiringWeights.h:42
DAS::Prefiring::Functor::GetSmoothWeights
std::tuple< float, float, float > GetSmoothWeights(int run, const RecJet &recjet) const
Subroutine to get weights for a give event from the smooth functions.
Definition: applyPrefiringWeights.h:202
generate_html.run
run
Definition: generate_html.py:86
DAS::FourVector
ROOT::Math::LorentzVector< ROOT::Math::PtEtaPhiM4D< float > > FourVector
Definition: PhysicsObject.h:15
Darwin::Exceptions::BadInput
Generic exception for ill-defined input (before the event loop).
Definition: exceptions.h:83
jmarExample.eta
eta
DeepAK8/ParticleNet tagging.
Definition: jmarExample.py:19