DAS  3.0
Das Analysis System
DAS::JetEnergy Namespace Reference

Classes

struct  AbstractFit
 
struct  BalanceHists
 
struct  ResolutionFit
 
struct  ResponseFit
 

Functions

void applyJERsmearing (const vector< fs::path > &inputs, const fs::path &output, const pt::ptree &config, const int steering, const DT::Slice slice={1, 0})
 
void applyJEScorrections (const vector< fs::path > inputs, const fs::path output, const pt::ptree &config, const int steering, const DT::Slice slice={1, 0})
 
std::vector< double > getBinning (int nBins, float first, float last)
 
void assertValidBinning (const std::vector< double > &v)
 
std::vector< float > GetLogBinning (float minpt, float maxpt, int nbins)
 
std::string getAlgo (const Darwin::Tools::MetaInfo &metainfo)
 
void FitResolution (TDirectory *dir, unique_ptr< TH1 > h, const int steering)
 
void loopDirsFromFitResponse (TDirectory *dIn, TDirectory *dOut, const int steering)
 
void fitJetResolution (const fs::path &input, const fs::path &output, const pt::ptree &config, const int steering)
 
vector< double > GetMergedBinning (TH1 *h, const int threshold=30)
 
pair< float, float > findDLogExtrema (const unique_ptr< TH1 > &DLog, const double mu, const pair< float, float > Range)
 
double round_to (double value, double precision=1.0)
 
TH1 * CumulativeResponse (TH1 *res1D)
 
void FitResponseByBin (TDirectory *dir, unique_ptr< TH2 > res2D, const int steering)
 
void loopDirsFromGetResponse (TDirectory *dIn, TDirectory *dOut, const int steering, const DT::Slice slice)
 
void fitJetResponse (const fs::path &input, const fs::path &output, const pt::ptree &config, const int steering, const DT::Slice slice={1, 0})
 
void getJetResponse (const vector< fs::path > &inputs, const fs::path &output, const pt::ptree &config, const int steering, const DT::Slice slice={1, 0})
 
void getJMEtable (const fs::path input, const fs::path output, const pt::ptree &config, const int steering)
 
void ProcessVariations (const vector< TH3 * > &variations, TDirectory &dOut)
 
void loopDirsFromGetBalance (TDirectory *dIn, TDirectory *dOut)
 
void getPtAveBalance (const fs::path &input, const fs::path &output, const pt::ptree &config, const int steering)
 
template<typename Jet >
bool DijetSelection (const std::vector< Jet > *jets, int iJES=0, const double alpha=0.3)
 
vector< TString > GetScaleVariations (const DT::MetaInfo &metainfo)
 
void getPtBalance (const vector< fs::path > inputs, const fs::path output, const pt::ptree &config, const int steering, const DT::Slice slice={1, 0})
 

Variables

static const std::vector< double > pt_JERC_edges = {15, 17, 20, 23, 27, 30, 35, 40, 45, 57, 72, 90, 120, 150, 200, 300, 400, 550, 750, 1000, 1500, 2000, 2500, 3000, 3500, 4000, 4500, 5000, 5500, 6000, 6500, 7000, 7500, 8000, 8500, 9000, 9500}
 
static const int nPtJERCbins = pt_JERC_edges.size()-1
 
static const std::vector< double > abseta_edges = { 0.000, 0.261, 0.522, 0.783, 1.044, 1.305, 1.566, 1.740, 1.930, 2.043, 2.172, 2.322, 2.500, 2.650, 2.853, 2.964, 3.139, 3.489, 3.839, 5.191 }
 
static const int nAbsEtaBins = abseta_edges.size()-1
 
static const std::vector< TString > absetaBins = MakeTitle(abseta_edges, "|#eta|", false, true, [](double v) { return Form("%.3f", v);})
 
static const std::map< int, std::vector< double > > rho_edges
 
static const std::map< int, int > nRhoBins
 
static const std::map< int, std::vector< TString > > rhoBins
 
static const std::vector< double > eta_unc_edges = {-5.4, -5.0, -4.4, -4.0, -3.5, -3.0, -2.8, -2.6, -2.4, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0 , 0.2 , 0.4 , 0.6 , 0.8 , 1.0 , 1.2 , 1.4 , 1.6 , 1.8 , 2.0 , 2.2 , 2.4 , 2.6 , 2.8 , 3.0, 3.5 , 4.0 , 4.4 , 5.0 , 5.4}
 
static const int nEtaUncBins = eta_unc_edges.size()-1
 
static const std::vector< std::string > JES_variations {"AbsoluteStat", "AbsoluteScale", "AbsoluteMPFBias", "Fragmentation", "SinglePionECAL", "SinglePionHCAL", "FlavorQCD", "RelativeJEREC1", "RelativeJEREC2", "RelativeJERHF", "RelativePtBB", "RelativePtEC1", "RelativePtEC2", "RelativePtHF", "RelativeBal", "RelativeSample", "RelativeFSR", "RelativeStatFSR", "RelativeStatEC", "RelativeStatHF", "PileUpDataMC", "PileUpPtRef", "PileUpPtBB", "PileUpPtEC1", "PileUpPtEC2", "PileUpPtHF"}
 
static const float w = 0.8
 
static const auto deps = numeric_limits<double>::epsilon()
 

Function Documentation

◆ applyJERsmearing()

void DAS::JetEnergy::applyJERsmearing ( const vector< fs::path > &  inputs,
const fs::path &  output,
const pt::ptree &  config,
const int  steering,
const DT::Slice  slice = {1,0} 
)

Get JER smearing corrections in the form of factors to store in the scales member of RecJet.

Todo:
investigate JER uncertainty breakdown (see Core#35)
Todo:
fix in case of offset (e.g. JES applied on MC)
Parameters
inputsinput ROOT files (n-tuples)
outputname of output ROOT files (n-tuples)
configconfig file from `DTOptions`
steeringsteering parameters from `DTOptions`
sliceslices for running
51  {1,0}
52  )
53 {
54  cout << __func__ << ' ' << slice << " start" << endl;
55 
56  unique_ptr<TChain> tIn = DT::GetChain(inputs);
57  unique_ptr<TFile> fOut(DT_GetOutput(output));
58  auto tOut = unique_ptr<TTree>(tIn->CloneTree(0));
59 
60  DT::MetaInfo metainfo(tOut);
61  metainfo.Check(config);
62  auto isMC = metainfo.Get<bool>("flags", "isMC");
63  auto R = metainfo.Get<int>("flags", "R");
64  if (!isMC) BOOST_THROW_EXCEPTION( DE::BadInput("Only MC may be used as input.",
65  make_unique<TFile>(inputs.front().c_str() )) );
66  JMEmatching<vector<RecJet>, vector<GenJet>>::maxDR = (R/10.)/2;
67 
68  GenEvent * genEvt = nullptr;
69  RecEvent * recEvt = nullptr;
70  PileUp * pu = nullptr;
71  tIn->SetBranchAddress("genEvent", &genEvt);
72  tIn->SetBranchAddress("recEvent", &recEvt);
73  tIn->SetBranchAddress("pileup", &pu);
74 
75  vector<GenJet> * genJets = nullptr;
76  vector<RecJet> * recJets = nullptr;
77  tIn->SetBranchAddress("genJets", &genJets);
78  tIn->SetBranchAddress("recJets", &recJets);
79 
80  const auto& tables = config.get<fs::path>("corrections.JER.tables");
81  metainfo.Set<fs::path>("corrections", "JER", "tables", tables);
82  if (!fs::exists(tables))
83  BOOST_THROW_EXCEPTION( fs::filesystem_error("File does not exists.",
84  tables, make_error_code(errc::no_such_file_or_directory)) );
85  const auto tag = config.get<string>("corrections.JER.tag"); // correction tag
86  metainfo.Set<string>("corrections", "JER", "tag", tag);
87  const auto& core_width = config.get<float>("corrections.JER.core_width");
88 
89  metainfo.Set<float>("corrections", "JER", "core_width", core_width);
90 
92  ControlPlots raw("raw");
93  vector<ControlPlots> calib { ControlPlots("nominal") };
94 
95  const bool applySyst = steering & DT::syst;
96  vector<string> vars {"nom"}; // keyword for correctionlib
98  if (applySyst) {
99  metainfo.Set<string>("variations", RecJet::ScaleVar, "JER" + SysDown);
100  metainfo.Set<string>("variations", RecJet::ScaleVar, "JER" + SysUp);
101 
102  calib.push_back(ControlPlots("JER" + SysDown));
103  calib.push_back(ControlPlots("JER" + SysUp));
104 
105  vars.push_back("up");
106  vars.push_back("down");
107  }
108 
109  // preparing correctionlib object
110  auto cset = correction::CorrectionSet::from_file(tables.string());
111  string algo = getAlgo(metainfo);
112  string keySF = tag + "_ScaleFactor_AK" + to_string(R < 6 ? 4 : 8) + "PF" + algo,
113  keyJER = tag + "_PtResolution_AK" + to_string(R < 6 ? 4 : 8) + "PF" + algo;
114  correction::Correction::Ref SF, JER;
115  try {
116  SF = cset->at(keySF );
117  JER = cset->at(keyJER);
118  }
119  catch (out_of_range) {
120  BOOST_THROW_EXCEPTION( invalid_argument("`" + keySF + "` or `" + keyJER +
121  "` could not be found in " + tables.string()) );
122  }
123 
124  // a few lambda functions
125  auto getSFs = [&SF,&vars](const RecJet& recjet) {
126  vector<float> sfs;
127  for (const string var: vars)
128  sfs.push_back(SF->evaluate({recjet.p4.Eta(), var}));
129  return sfs;
130  };
131  auto applySFs = [applySyst](RecJet& recjet, const vector<float>& sfs) {
132  float nom_scale = recjet.scales.front();
133  for (float& scale: recjet.scales)
134  scale *= sfs.front();
135 
136  if (applySyst) {
137  recjet.scales.push_back(nom_scale*sfs[1]);
138  recjet.scales.push_back(nom_scale*sfs[2]);
139  }
140  };
141  auto getJER = [pu,&JER](const RecJet& recjet) {
142  return JER->evaluate({recjet.p4.Eta(), recjet.CorrPt(), pu->rho});
143  };
144 
145  for (DT::Looper looper(tIn, slice); looper(); ++looper) {
146  [[ maybe_unused ]]
147  static auto& cout = steering & DT::verbose ? ::cout : DT::dev_null;
148  cout << "===============" << endl;
149 
150  raw(*genJets, genEvt->weights.front());
151  raw(*recJets, genEvt->weights.front() * recEvt->weights.front());
152 
153  cout << "Running matching" << endl;
154  JMEmatching matching(*recJets, *genJets);
155  auto fake_its = matching.fake_its; // we extract it because we will modify it
156 
157  cout << "Applying scaling smearing for jets matched in the core of the response" << endl;
158  for (const auto& [rec_it, gen_it]: matching.match_its) {
159  cout << "---------------" << endl;
160 
161  float genpt = gen_it->p4.Pt(),
162  recpt = rec_it->CorrPt();
163 
164  float response = recpt / genpt,
165  resolution = getJER(*rec_it);
166 
167  cout << "|- genpt = " << genpt << '\n'
168  << "|- recpt = " << recpt << '\n'
169  << "|- response = " << response << '\n'
170  << "|- resolution = " << resolution << endl;
171 
172  vector<float> sfs = getSFs(*rec_it);
173  if (abs(response - 1) > core_width * resolution) {
174  cout << "|- match in the tail" << endl;
175  fake_its.push_back(rec_it); // left for later, with stochastic smearing
176  continue;
177  }
178  cout << "|- match in the core" << endl;
179 
180  for (float& sf: sfs) {
181  cout << "|- " << sf;
182  sf = max(0.f, 1+(sf-1)*(recpt-genpt)/recpt);
183  cout << " -> " << sf << endl;
184  }
185 
186  cout << "|- applying SFs" << endl;
187  applySFs(*rec_it, sfs);
188  }
189 
190  cout << "Applying stochastic smearing for all other jets "
191  "(either unmatched, or matched in the tails of the response)" << endl;
192  for (auto& fake_it: fake_its) {
193 
194  float resolution = getJER(*fake_it);
195  normal_distribution<float> d{0,resolution};
196  static mt19937 m_random_generator(metainfo.Seed<20394242>(slice));
197  float response = d(m_random_generator);
198 
199  cout << "|- recpt = " << fake_it->CorrPt() << '\n'
200  << "|- response = " << response << '\n'
201  << "|- resolution = " << resolution << endl;
202 
203  vector<float> sfs = getSFs(*fake_it);
204  for (float& sf: sfs) {
205  cout << "|- " << sf;
206  sf = max(0.f, 1+response*sqrt(max(0.f, sf*sf-1)));
207  cout << " -> " << sf << endl;
208  }
209 
210  cout << "|- applying SFs" << endl;
211 
212  applySFs(*fake_it, sfs);
213  }
214 
215  cout << "Sorting by descending pt" << endl;
216  sort(recJets->begin(), recJets->end(), pt_sort);
217 
218  for (size_t i = 0; i < calib.size(); ++i) {
219  calib.at(i)(*genJets, genEvt->weights.front());
220  calib.at(i)(*recJets, genEvt->weights.front() * recEvt->weights.front(), i);
221  }
222 
223  cout << "Filling" << endl;
224  if (steering & DT::fill) tOut->Fill();
225  }
226 
227  metainfo.Set<bool>("git", "complete", true);
228  fOut->cd();
229  tOut->Write();
230  raw.Write(fOut.get());
231  for (auto& c: calib)
232  c.Write(fOut.get());
233 
234  cout << __func__ << ' ' << slice << " end" << endl;
235 }

◆ applyJEScorrections()

void DAS::JetEnergy::applyJEScorrections ( const vector< fs::path >  inputs,
const fs::path  output,
const pt::ptree &  config,
const int  steering,
const DT::Slice  slice = {1,0} 
)

Apply JES corrections to data and MC *n*tuples, as well as uncertainties in data (all sources are considered separately)

Todo:
CorrPt?
Parameters
inputsinput ROOT files (n-tuples)
outputname of output root file containing the histograms
configconfig file from `DTOptions`
steeringsteering parameters from `DTOptions`
sliceslices for running
41  {1,0}
42  )
43 {
44  cout << __func__ << ' ' << slice << " start" << endl;
45 
46  unique_ptr<TChain> tIn = DT::GetChain(inputs);
47  unique_ptr<TFile> fOut(DT_GetOutput(output));
48  auto tOut = unique_ptr<TTree>(tIn->CloneTree(0));
49 
50  DT::MetaInfo metainfo(tOut);
51  metainfo.Check(config);
52  auto isMC = metainfo.Get<bool>("flags", "isMC");
53  auto R = metainfo.Get<int>("flags", "R");
54 
55  RecEvent * recEvt = nullptr;
56  GenEvent * genEvt = nullptr;
57  PileUp * pu = nullptr;
58  tIn->SetBranchAddress("recEvent", &recEvt);
59  if (isMC)
60  tIn->SetBranchAddress("genEvent", &genEvt);
61  tIn->SetBranchAddress("pileup", &pu);
62 
63  vector<RecJet> * recJets = nullptr;
64  tIn->SetBranchAddress("recJets", &recJets);
65 
66  const auto tables = config.get<fs::path>("corrections.JES.tables"); // path to directory containing corrections in JSON format
67  metainfo.Set<fs::path>("corrections", "JES", "tables", tables);
68  if (!fs::exists(tables))
69  BOOST_THROW_EXCEPTION( fs::filesystem_error("File does not exists.",
70  tables, make_error_code(errc::no_such_file_or_directory)) );
71  const auto tag = config.get<string>("corrections.JES.tag"); // correction tag
72  metainfo.Set<string>("corrections", "JES", "tag", tag);
73 
75  ControlPlots raw("raw");
76  vector<ControlPlots> calib { ControlPlots("nominal") };
77 
78  const bool applySyst = steering & DT::syst;
79 
80  if (applySyst)
81  for (string source: JES_variations) {
82  metainfo.Set<string>("variations", RecJet::ScaleVar, source + SysDown);
83  metainfo.Set<string>("variations", RecJet::ScaleVar, source + SysUp);
84 
85  calib.push_back(ControlPlots(source + SysDown));
86  calib.push_back(ControlPlots(source + SysUp));
87  }
88 
89  // prepare correctionlib
90  auto cset = correction::CorrectionSet::from_file(tables.string());
91  string algo = getAlgo(metainfo);
92  string key = tag + "_L1L2L3Res_AK" + to_string(R < 6 ? 4 : 8) + "PF" + algo;
93  correction::CompoundCorrection::Ref nomSF = cset->compound().at(key);
94  vector<correction::Correction::Ref> varSFs;
95  varSFs.reserve(JES_variations.size());
96  for (string source: JES_variations) {
97  key = tag + '_' + source + "_AK" + to_string(R < 6 ? 4 : 8) + "PF" + algo;
98  varSFs.push_back(cset->at(key));
99  }
100 
101  for (DT::Looper looper(tIn, slice); looper(); ++looper) {
102  [[ maybe_unused ]]
103  static auto& cout = steering & DT::verbose ? ::cout : DT::dev_null;
104 
105  double weight = recEvt->weights.front();
106  if (isMC) weight *= genEvt->weights.front();
107 
108  // CP before JES
109  raw(*recJets, weight);
110 
111  for (auto& recJet: *recJets) {
112 
113  // sanity check
114  if (recJet.scales.size() != 1 || recJet.scales.front() != 1)
115  BOOST_THROW_EXCEPTION( DE::AnomalousEvent("Unexpected JES corrections", tIn) );
116 
117  // nominal value
118  auto corr = nomSF->evaluate({recJet.area, recJet.p4.Eta(), recJet.p4.Pt(), pu->rho});
119  cout << recJet.p4.Pt() << ' ' << corr << '\n';
120  recJet.scales.front() = corr;
121 
122  if (!applySyst) continue;
123 
124  // load uncertainties in JECs
125  recJet.scales.reserve(JES_variations.size()*2+1);
126  for (const correction::Correction::Ref& varSF: varSFs) {
127  auto var = varSF->evaluate({recJet.p4.Eta(), recJet.p4.Pt()});
128  recJet.scales.push_back(corr*(1-var));
129  recJet.scales.push_back(corr*(1+var));
130  }
131  }
132  cout << flush;
133 
134  // CP after corrections
135  for (size_t i = 0; i < calib.size(); ++i)
136  calib.at(i)(*recJets, weight, i);
137 
138  sort(recJets->begin(), recJets->end(), pt_sort); // sort again the jets by pt
139  if (steering & DT::fill) tOut->Fill();
140  }
141 
142  metainfo.Set<bool>("git", "complete", true);
143  fOut->cd();
144  tOut->Write();
145  raw.Write(fOut.get());
146  for (auto& c: calib)
147  c.Write(fOut.get());
148 
149  cout << __func__ << ' ' << slice << " end" << endl;
150 }

◆ assertValidBinning()

void DAS::JetEnergy::assertValidBinning ( const std::vector< double > &  v)
inline
58 {
59  assert(v.size() > 1);
60  for (size_t i = 1; i<v.size(); ++i) {
61  if (v[i] > v[i-1]) continue;
62  std::cerr << i << ' ' << v[i] << ' ' << v[i-1] << '\n';
63  }
64 }

◆ CumulativeResponse()

TH1* DAS::JetEnergy::CumulativeResponse ( TH1 *  res1D)

Creating cumulative response histogram. Given a response 1D histogram, it adds to a bin the content of all previous bins.

307 {
308  double cont = 0;
309  const int NptBins = res1D->GetNbinsX();
310  for (int n = 1; n <= NptBins; ++n) {
311  cont+=res1D->GetBinContent(n);
312  res1D->SetBinContent(n, cont);
313  }
314  return res1D;
315 }

◆ DijetSelection()

bool DAS::JetEnergy::DijetSelection ( const std::vector< Jet > *  jets,
int  iJES = 0,
const double  alpha = 0.3 
)

Apply dijet topology selection independently from the level.

Parameters
jetsfull jet vector
iJESJES variation index (only for rec-level)
alphareject significant extra jets
50 {
51  if (jets->size() < 2) return false;
52 
53  // back-to-back
54  using ROOT::Math::VectorUtil::DeltaPhi;
55  if (DeltaPhi(jets->at(0).p4, jets->at(1).p4) < 2.7) return false;
56 
57  // ECAL acceptance
58  if (std::abs(jets->at(0).p4.Eta()) >= 3.0 ||
59  std::abs(jets->at(1).p4.Eta()) >= 3.0) return false;
60 
61  // impact of extra jets
62  if (jets->size() > 2) {
63  if constexpr (is_same<Jet,RecJet>()) {
64  const auto pt0 = jets->at(0).CorrPt(iJES),
65  pt1 = jets->at(1).CorrPt(iJES),
66  pt2 = jets->at(2).CorrPt(iJES);
67  if (pt2 > alpha*(pt0 + pt1)/2) return false;
68  }
69  else {
70  const auto pt0 = jets->at(0).p4.Pt(),
71  pt1 = jets->at(1).p4.Pt(),
72  pt2 = jets->at(2).p4.Pt();
73  if (pt2 > alpha*(pt0 + pt1)/2) return false;
74  }
75  }
76 
77  return true;
78 }

◆ findDLogExtrema()

pair<float,float> DAS::JetEnergy::findDLogExtrema ( const unique_ptr< TH1 > &  DLog,
const double  mu,
const pair< float, float >  Range 
)

Find the positions of the extrema, starting from the mean and within a given range (to avoid regions with too large fluctuations).

79 {
80  const int m = DLog->FindBin(mu);
81 
82  // find maximum on the LHS
83  int imax = m;
84  for (int i = m; i >= DLog->FindBin(Range.first); --i)
85  if (DLog->GetBinContent(i) > DLog->GetBinContent(imax)) imax = i;
86  float x1 = DLog->GetBinLowEdge(imax+1);
87 
88  // find minimum on the RHS
89  int imin = m;
90  for (int i = m; i <= DLog->FindBin(Range.second); ++i)
91  if (DLog->GetBinContent(i) < DLog->GetBinContent(imin)) imin = i;
92  float x2 = DLog->GetBinLowEdge(imin);
93 
94  return {x1,x2};
95 }

◆ fitJetResolution()

void DAS::JetEnergy::fitJetResolution ( const fs::path &  input,
const fs::path &  output,
const pt::ptree &  config,
const int  steering 
)

Fit resolution curves from fitJetResponse

Parameters
inputinput ROOT file (histograms)
outputname of output ROOT (histograms)
configconfig file from `DTOptions`
steeringsteering parameters from `DTOptions`
234 {
235  cout << __func__ << " start" << endl;
236 
237  auto fIn = make_unique<TFile>(input .c_str(), "READ"),
238  fOut = make_unique<TFile>(output.c_str(), "RECREATE");
239  JetEnergy::loopDirsFromFitResponse(fIn.get(), fOut.get(), steering);
240 
241  cout << __func__ << " stop" << endl;
242 }

◆ fitJetResponse()

void DAS::JetEnergy::fitJetResponse ( const fs::path &  input,
const fs::path &  output,
const pt::ptree &  config,
const int  steering,
const DT::Slice  slice = {1,0} 
)

Fit response distributions from getJetResponse

Parameters
inputinput ROOT file (histograms)
outputname of output ROOT (histograms)
configconfig file from `DTOptions`
steeringsteering parameters from `DTOptions`
slicenumber and index of slice
509  {1,0}
510  )
511 {
512  cout << __func__ << ' ' << slice << " start" << endl;
513 
514  auto fIn = make_unique<TFile>(input .c_str(), "READ"),
515  fOut = make_unique<TFile>(output.c_str(), "RECREATE");
516  JetEnergy::loopDirsFromGetResponse(fIn.get(), fOut.get(), steering, slice);
517 
518  cout << __func__ << ' ' << slice << " stop" << endl;
519 }

◆ FitResolution()

void DAS::JetEnergy::FitResolution ( TDirectory *  dir,
unique_ptr< TH1 >  h,
const int  steering 
)

Fit the resolution obtained from fitJetResponse in a given eta/rho bin.

Todo:
parameters in bins of eta (and rho/mu?)

--> one should probably give the directory with all eta bins as input

170 {
171  dir->cd();
172  TString stdPrint = h->GetTitle();
173  stdPrint.ReplaceAll(TString( h->GetName() ), "");
174  cout << h->GetName() << '\t' << stdPrint << endl;
175  auto& cout = (steering & DT::verbose) == DT::verbose ? ::cout : DT::dev_null;
176 
177  ResolutionFit res(h, cout);
178 
179  res.NSC();
180  res.NSCd();
181 
185 }

◆ FitResponseByBin()

void DAS::JetEnergy::FitResponseByBin ( TDirectory *  dir,
unique_ptr< TH2 >  res2D,
const int  steering 
)

Projection 2D histograms onto 1D histograms and fit response

Fit is currently performed in 3 stages:

  1. Fit the Gaussian core to get a better estimation of the mean and sigma.
  2. Extend the fit right range, transposing to a Single-Sided Crystal Ball fit, using the mean and sigma better define the fit parameters.
  3. Extend the fit left range, transposing to a Double-Sided Crystal Ball fit.

Fit iteratively on each stage by adjusting the fit range so that you minimize the amount of failed fits.

331 {
332  dir->cd();
333 
334  auto h_ptBins = unique_ptr<TH1>( dynamic_cast<TH1*>(res2D->ProjectionX("h_ptBins", 1, -1)) ); // Only for pt binnning extraction
335  h_ptBins->GetXaxis()->SetTitle("p_{T}^{gen}");
336 
337  // Declaring histograms (control plots)
338  map<TString, unique_ptr<TH1>> hists;
339  for (TString name: {"meanCore", "sigmaCore", // Obtained from DCB fit
340  "kLtail", "kRtail", // DCB tails transitions
341  "nLtail", "nRtail", // DCB tails slope
342  "Lcore", "Rcore", // estimates from derivative
343  "chi2ndf", "Median"}) {
344  // for successful fits
345  hists.insert( {name, unique_ptr<TH1>(dynamic_cast<TH1*>( h_ptBins->Clone(name) )) } );
346  hists[name]->Reset();
347  hists[name]->SetTitle(name);
348  hists[name]->SetDirectory(nullptr);
349 
350  // for failed fits
351  name += "Fail";
352  hists.insert( {name, unique_ptr<TH1>(dynamic_cast<TH1*>( h_ptBins->Clone(name) )) } );
353  hists[name]->Reset();
354  hists[name]->SetTitle(name);
355  hists[name]->SetDirectory(nullptr);
356  }
357 
358  int Npt = res2D->GetXaxis()->GetNbins();
359  for (int ptbin = 1; ptbin <= Npt; ++ptbin) { // Repeat fit procedure for all response distributions
360  double lowEdge = res2D->GetXaxis()->GetBinLowEdge(ptbin),
361  upEdge = res2D->GetXaxis()->GetBinUpEdge (ptbin);
362  const char * level = TString( res2D->GetXaxis()->GetTitle() ).Contains("gen") ? "gen" : "rec";
363  const char * hlt_level = TString( res2D->GetXaxis()->GetTitle() ).Contains("HLT") ? "HLT" : level;
364  TString title = Form("%.0f < p_{T}^{%s} < %.0f", lowEdge, hlt_level, upEdge),
365  stdPrint = TString( res2D->GetTitle() );
366  stdPrint.ReplaceAll("zx projection", "");
367  stdPrint.ReplaceAll(")", "");
368  stdPrint += ", " + title + ")";
369  cout << stdPrint << def << endl;
370  static auto& cout = (steering & DT::verbose) == DT::verbose ? ::cout : DT::dev_null;
371 
372  auto original = unique_ptr<TH1>( dynamic_cast<TH1*>(res2D->ProjectionY("original", ptbin, ptbin)) ); // Response distribution
373  if (original->GetEntries() < 100) {
374  cout << orange << "Skipped due to low number of events!" << def << endl;
375  continue;
376  }
377 
378  vector<double> edges = GetMergedBinning(original.get());
379  auto h = unique_ptr<TH1>( original->Rebin(edges.size()-1, "h", edges.data()) );
380  const char * h_title = TString( res2D->GetXaxis()->GetTitle() ).Contains("HLT") ? "HLT bin low edge" : "gen";
381  h->GetXaxis()->SetTitle(Form("#frac{p_{T}^{rec}}{p_{T}^{%s}}", h_title));
382  //h->Rebin(2);
383 
384  TDirectory * d_pt = dir->mkdir(Form("ptbin%d", ptbin), title);
385  d_pt->cd();
386  h->SetTitle(title);
387  h->SetDirectory(d_pt);
388  float normalisation = abs( h->Integral() );
389  h->Scale(1.f/normalisation, "width");
390  //cout << "normalisation = " << h->Integral() << endl;
391  h->Write();
392  int nQuantiles = 1;
393  double median;
394  double probability[1] = {0.5};
395  h->GetQuantiles(nQuantiles, &median, probability);
396 
397  TString hlt_title = Form("%.0f < p_{T}^{%s} < %.0f", lowEdge, hlt_level, upEdge);
398 
399  // Calculating Cumulative response histogram and storing it to directory
400  auto hc_tmp = dynamic_cast<TH1*>( h->Clone("hc_tmp") );
401  auto hc = CumulativeResponse(move(hc_tmp)); // Cumulative response
402  hc->SetNameTitle("h_cumulative", hlt_title);
403  hc->SetDirectory(d_pt);
404  hc->Write();
405 
406  // the complex fit is split over several steps using a ResponseFit object
407  ResponseFit resp(h, cout);
408 
409  hists.at("Lcore")->SetBinContent(ptbin, resp.p[ResponseFit::KL]);
410  hists.at("Rcore")->SetBinContent(ptbin, resp.p[ResponseFit::KR]);
411 
412  resp.gausCore();
413  resp.SSCB();
414  resp.DSCB();
415 
416  TString suffix = resp.good() ? "" : "Fail";
417 
418  // Save fit parameters into control plots
419  hists.at( "meanCore" + suffix)->SetBinContent(ptbin, resp.p[ResponseFit::MU]);
420  hists.at( "meanCore" + suffix)->SetBinError (ptbin, resp.e[ResponseFit::MU]);
421  hists.at("sigmaCore" + suffix)->SetBinContent(ptbin, resp.p[ResponseFit::SIGMA]);
422  hists.at("sigmaCore" + suffix)->SetBinError (ptbin, resp.e[ResponseFit::SIGMA]);
423 
424  hists.at("kLtail" + suffix)->SetBinContent(ptbin, resp.p[ResponseFit::KL]);
425  hists.at("kLtail" + suffix)->SetBinError (ptbin, resp.e[ResponseFit::KL]);
426  hists.at("nLtail" + suffix)->SetBinContent(ptbin, resp.p[ResponseFit::NL]);
427  hists.at("nLtail" + suffix)->SetBinError (ptbin, resp.e[ResponseFit::NL]);
428  hists.at("kRtail" + suffix)->SetBinContent(ptbin, resp.p[ResponseFit::KR]);
429  hists.at("kRtail" + suffix)->SetBinError (ptbin, resp.e[ResponseFit::KR]);
430  hists.at("nRtail" + suffix)->SetBinContent(ptbin, resp.p[ResponseFit::NR]);
431  hists.at("nRtail" + suffix)->SetBinError (ptbin, resp.e[ResponseFit::NR]);
432 
433  hists.at("chi2ndf" + suffix)->SetBinContent(ptbin, resp.chi2ndf .value_or(0));
434  hists.at("chi2ndf" + suffix)->SetBinError (ptbin, resp.chi2ndfErr.value_or(0));
435 
436  hists.at("Median" + suffix)->SetBinContent(ptbin, median);
437  }
438 
439  dir->cd();
440  TString title = res2D->GetTitle();
441  title.ReplaceAll("Response distribution", "");
442  title.ReplaceAll("zx projection", "");
443  for (auto&& h: hists) {
444  h.second->SetDirectory(dir);
445  h.second->SetTitle(h.second->GetTitle() + title);
446  h.second->Write();
447  }
448 }

◆ getAlgo()

std::string DAS::JetEnergy::getAlgo ( const Darwin::Tools::MetaInfo metainfo)
inline

Determine from metainfo if CHS or PUPPI has been used to reconstruct the jets.

87 {
88  if (metainfo.Find("flags", "labels", "CHS" )) return "chs";
89  if (metainfo.Find("flags", "labels", "PUPPI")) return "puppi";
90 
91  std::cerr << orange << "Couldn't identify CHS or PUPPI. Running default "
92  "CHS for Run 2 (PUPPI foir Run 3)\n" << def;
93 
94  auto year = metainfo.Get<int>("flag", "year");
95  if (year > 2019) return "puppi"; // run 3
96  if (year > 2014) return "chs"; // run 2
97  return ""; // run 1
98 }

◆ getBinning()

std::vector<double> DAS::JetEnergy::getBinning ( int  nBins,
float  first,
float  last 
)
inline
50 {
51  std::vector<double> bins(nBins+1);
52  for(int i = 0; i <= nBins; ++i)
53  bins[i] = first + ((last-first)/nBins) * i;
54  return bins;
55 }

◆ getJetResponse()

void DAS::JetEnergy::getJetResponse ( const vector< fs::path > &  inputs,
const fs::path &  output,
const pt::ptree &  config,
const int  steering,
const DT::Slice  slice = {1,0} 
)

Get JER differential resolution and balance.

Todo:
with gen level weight too?
Todo:
remove upper boundaries from titles of last bins
Parameters
inputsinput ROOT files (n-tuples)
outputname of output ROOT file (histograms)
configconfig file from `DTOptions`
steeringsteering parameters from `DTOptions`
sliceslices for running
47  {1,0}
48  )
49 {
50  cout << __func__ << ' ' << slice << " start" << endl;
51 
52  unique_ptr<TChain> tIn = DT::GetChain(inputs);
53  unique_ptr<TFile> fOut(DT_GetOutput(output));
54  auto tOut = unique_ptr<TTree>(tIn->CloneTree(0));
55 
56  DT::MetaInfo metainfo(tOut);
57  metainfo.Check(config);
58  auto isMC = metainfo.Get<bool>("flags", "isMC");
59  if (!isMC)
60  BOOST_THROW_EXCEPTION( DE::BadInput("Only MC may be used as input.", metainfo) );
61 
62  const auto R = metainfo.Get<int>("flags", "R");
63 
64  JMEmatching<>::maxDR = R/10./2.;
65  cout << "Radius for matching: " << JMEmatching<>::maxDR << endl;
66 
67  RecEvent * rEv = nullptr;
68  tIn->SetBranchAddress("recEvent", &rEv);
69  const auto hiPU = config.get<bool>("skims.pileup");
70  PileUp * pileUp = nullptr;
71  if (hiPU)
72  tIn->SetBranchAddress("pileup", &pileUp);
73 
74  vector<RecJet> * recjets = nullptr;
75  vector<GenJet> * genjets = nullptr;
76  tIn->SetBranchAddress("recJets", &recjets);
77  tIn->SetBranchAddress("genJets", &genjets);
78 
79  unique_ptr<TH3> inclResp = makeRespHist("inclusive", "JER"); // Response inclusive in rho
80  vector<unique_ptr<TH3>> rhobinsResp, // Response in bins of rho
81  mubinsResp; // Response in bins of mu (true pileup)
82 
83  const auto year = metainfo.Get<int>("flags", "year");
84  if (hiPU) {
85  rhobinsResp.reserve(nRhoBins.at(year));
86  mubinsResp.reserve(nRhoBins.at(year));
87  for (int rhobin = 1; rhobin <= nRhoBins.at(year); ++rhobin) {
88  rhobinsResp.push_back( makeRespHist( Form("rhobin%d", rhobin) , "JER") );
89  mubinsResp.push_back( makeRespHist( Form( "mubin%d", rhobin) , "JER") );
90  }
91  }
92 
93  for (DT::Looper looper(tIn, slice); looper(); ++looper) {
94  [[ maybe_unused ]]
95  static auto& cout = steering & DT::verbose ? ::cout : DT::dev_null;
96 
97  auto recWgt = rEv->weights.front();
98  optional<size_t> irho, imu;
99  if (hiPU) {
100  static const size_t nrho = static_cast<size_t>(nRhoBins.at(year));
101  for (irho = 0; pileUp->rho > rho_edges.at(year).at(*irho+1) && *irho < nrho; ++*irho);
102  if (*irho >= nrho)
103  BOOST_THROW_EXCEPTION( DE::AnomalousEvent(Form("irho = %lu > nRhoBins.at(%d) = %d",
104  *irho, year, nRhoBins.at(year)), tIn) );
105  static const size_t imuMax = mubinsResp.size()-1;
106  imu = static_cast<size_t>(pileUp->GetTrPU())/10;
107  *imu = min(*imu,imuMax);
108  }
109 
110  // Matching
111  if (genjets->size() > 3) genjets->resize(3); // Keep only three leading gen jets
112  JMEmatching matching(*recjets, *genjets);
113  matching.match_its.resize(min(matching.match_its.size(),3lu));
114 
115  for (auto& [rec_it,gen_it]: matching.match_its) {
116  auto ptrec = rec_it->CorrPt();
117  auto ptgen = gen_it->p4.Pt();
118 
119  // Fill resolution from smearing
120  auto response = ptrec/ptgen;
121  auto etarec = abs( rec_it->p4.Eta() );
122 
123  inclResp->Fill(ptgen, etarec, response, recWgt);
124  if (irho) rhobinsResp.at(*irho)->Fill(ptgen, etarec, response, recWgt);
125  if (imu ) mubinsResp.at(*imu )->Fill(ptgen, etarec, response, recWgt);
126 
128  } // End of for (pairs) loop
129  } // End of while (event) loop
130 
131  // Creating directory hierarchy and saving histograms
132  inclResp->SetDirectory(fOut.get());
133  inclResp->SetTitle("Response (inclusive)");
134  inclResp->Write("Response");
135  if (hiPU)
136  for (int irho = 0; irho < nRhoBins.at(year); ++irho) {
137 
139 
140  TString title = Form("%.2f < #rho < %.2f", rho_edges.at(year).at(irho), rho_edges.at(year).at(irho+1));
141  fOut->cd();
142  TDirectory * d_rho = fOut->mkdir(Form("rhobin%d", irho+1), title);
143  d_rho->cd();
144  rhobinsResp.at(irho)->SetDirectory(fOut.get());
145  rhobinsResp.at(irho)->SetTitle("Response (" + title + ")");
146  rhobinsResp.at(irho)->Write("Response");
147 
148  title = Form("%d < #mu < %d", irho*10, (irho+1)*10);
149  fOut->cd();
150  TDirectory * d_mu = fOut->mkdir(Form("mubin%d", irho+1), title);
151  d_mu->cd();
152  mubinsResp.at(irho)->SetDirectory(fOut.get());
153  mubinsResp.at(irho)->SetTitle("Response (" + title + ")");
154  mubinsResp.at(irho)->Write("Response");
155  }
156 
157  fOut->cd();
158  metainfo.Set<bool>("git", "complete", true);
159  tOut->Write();
160 
161  cout << __func__ << ' ' << slice << " end" << endl;
162 }

◆ getJMEtable()

void DAS::JetEnergy::getJMEtable ( const fs::path  input,
const fs::path  output,
const pt::ptree &  config,
const int  steering 
)

Obtain corrections and uncertainties in ROOT format for plotting and comparison.

Todo:
identify algo
Todo:
check binning
Parameters
inputJetMET JES tables in JSON format
outputname of output root file
configconfig file from `DTOptions`
steeringsteering parameters from `DTOptions`
39 {
40  cout << __func__ << " start" << endl;
41 
42  unique_ptr<TFile> fOut(DT_GetOutput(output));
43 
44  auto R = config.get<int>("flags.R");
45  auto year = config.get<int>("flags.year");
46  string algo = "chs";
47  cout << R << ' ' << year << ' ' << algo << endl;
48 
49  const auto tag = config.get<string>("corrections.JES.tag"), // correction tag
50  level = config.get<string>("corrections.JES.level"); // correction level
51  string key = tag + "_" + level + "_AK" + to_string(R) + "PF" + algo;
52  cout << key << endl;
53 
54  auto cset = correction::CorrectionSet::from_file(input.string());
55  correction::Correction::Ref sf;
56  try {
57  sf = cset->at(key);
58  }
59  catch (std::out_of_range& e) {
60  BOOST_THROW_EXCEPTION( std::invalid_argument("Nothing corresponding to that key") );
61  }
62 
63  cout << "Declaring histogram" << endl;
64  unique_ptr<TH1> h;
65  map<string, correction::Variable::Type> named_inputs;
66  if (level == "L1FastJet" || level == "PtResolution") {
67  h = make_unique<TH3D>(level.c_str(), level.c_str(),
68  nAbsEtaBins, abseta_edges .data(),
69  nPtJERCbins, pt_JERC_edges.data(),
70  rho_edges.at(year).size()-1,
71  rho_edges.at(year).data());
72  named_inputs["JetA"] = M_PI * pow(R*0.1, 2); // Jet area estimation
73  }
74  else if (level == "L2Relative" || level == "L2L3Residual")
75  h = make_unique<TH2D>(level.c_str(), level.c_str(),
76  nAbsEtaBins, abseta_edges .data(),
77  nPtJERCbins, pt_JERC_edges.data());
78  else if (level == "ScaleFactor") {
79  h = make_unique<TH1D>(level.c_str(), level.c_str(),
80  nAbsEtaBins, abseta_edges .data());
81  named_inputs["systematic"] = "nom";
82  }
83  else // assuming uncertainties
84  h = make_unique<TH2D>(level.c_str(), level.c_str(),
85  nEtaUncBins, eta_unc_edges.data(),
86  nPtJERCbins, pt_JERC_edges.data());
87 
88  cout << "dim = " << h->GetDimension() << endl;
89  for (int etabin = 1; etabin <= h->GetNbinsX(); ++etabin)
90  for (int ptbin = 1; ptbin <= h->GetNbinsY(); ++ ptbin)
91  for (int rhobin = 1; rhobin <= h->GetNbinsZ(); ++rhobin) {
92  // set values by name
93  named_inputs["JetEta"] = h->GetXaxis()->GetBinCenter(etabin);
94  named_inputs["JetPt" ] = h->GetYaxis()->GetBinCenter( ptbin);
95  named_inputs["Rho" ] = h->GetZaxis()->GetBinCenter(rhobin);
96 
97  // order the input value in the necessary order
98  vector<correction::Variable::Type> inputs;
99  for (const correction::Variable& input: sf->inputs())
100  inputs.push_back(named_inputs.at(input.name()));
101 
102  // get and fill the value
103  double value = sf->evaluate(inputs);
104 
105  cout << setw(5) << ptbin << setw(5) << etabin << setw(5) << rhobin << setw(15) << value << endl;
106 
107  if (level == "L1FastJet")
108  h->SetBinContent(etabin, ptbin, rhobin, value);
109  else if (level == "ScaleFactor")
110  h->SetBinContent(etabin, value);
111  else
112  h->SetBinContent(etabin, ptbin, value);
113  }
114  h->Write();
115 
116  cout << __func__ << " end" << endl;
117 }

◆ GetLogBinning()

std::vector<float> DAS::JetEnergy::GetLogBinning ( float  minpt,
float  maxpt,
int  nbins 
)
inline

Make equidistant binning in log pt.

Todo:
this accumulates imprecision --> improve
69 {
70  assert(maxpt > minpt);
71  assert(minpt > 0);
72  assert(nbins > 1);
73 
74  std::vector<float> edges;
75 
76  float R = pow(maxpt/minpt,1./nbins);
77  for (float pt = minpt; pt <= maxpt; pt *= R) edges.push_back(pt);
79  std::cout << edges.size() << std::endl;
80 
81  return edges;
82 }

◆ GetMergedBinning()

vector<double> DAS::JetEnergy::GetMergedBinning ( TH1 *  h,
const int  threshold = 30 
)

Provide a new binning ensuring a sufficient number of entries in each bin to assume Gaussian uncertainties.

For a gaussian distribution, as it is assumed for the number of events in each bin, the error is given as sqrt(n) where n the number of events in the bin. Assuming both the bin content and error have been normalised, by taking the division of the (BinContent/BinError)^2 ~ n, one can estimate the number of events in that bin.

There is no special treatment for negative weights, as the samples used to develop the code have no such weight. A warning is however displayed in case negative bins are found.

50 {
51  const int N = h->GetNbinsX();
52  vector<double> edges(1,0);
53  edges.reserve(N);
54  int sum = 0;
55  for (int i = 1; i <= N; ++i) {
56  auto content = h->GetBinContent(i);
57  if (content == 0) continue;
58  if (content < 0)
59  cerr << orange << "Found negative bins in "
60  << h->GetName() << def << '\n';
61  auto error = h->GetBinError(i);
62  sum += pow(content/error,2);
63  if (sum < threshold) continue;
64  sum = 0;
65  edges.push_back(h->GetBinLowEdge(i+1));
66  }
67  if (edges.back() != h->GetBinLowEdge(N+1))
68  edges.push_back(h->GetBinLowEdge(N+1));
69 
70  return edges;
71 }

◆ getPtAveBalance()

void DAS::JetEnergy::getPtAveBalance ( const fs::path &  input,
const fs::path &  output,
const pt::ptree &  config,
const int  steering 
)

This function iterate over the histograms produced by getPtBalance and produces the the momentum balance histograms in bins of ptave and eta. It calls the loopDir() function defined above.

Todo:
use config and steering (e.g. for verbosity)
Parameters
inputinput ROOT file (histograms)
outputname of output ROOT (histograms)
configconfig file from `DTOptions`
steeringsteering parameters from `DTOptions`
233 {
235  auto fIn = make_unique<TFile>(input .c_str(), "READ"),
236  fOut = make_unique<TFile>(output.c_str(), "RECREATE");
237  JetEnergy::loopDirsFromGetBalance(fIn.get(), fOut.get());
238 }

◆ getPtBalance()

void DAS::JetEnergy::getPtBalance ( const vector< fs::path >  inputs,
const fs::path  output,
const pt::ptree &  config,
const int  steering,
const DT::Slice  slice = {1,0} 
)

Get Pt balance.

Parameters
inputsinput ROOT files (n-tuples)
outputname of output root file containing the histograms
configconfig file from `DTOptions`
steeringsteering parameters from `DTOptions`
sliceslices for running
171  {1,0}
172  )
173 {
174  cout << __func__ << ' ' << slice << " start" << endl;
175 
176  unique_ptr<TChain> tIn = DT::GetChain(inputs);
177  unique_ptr<TFile> fOut(DT_GetOutput(output));
178  auto tOut = unique_ptr<TTree>(tIn->CloneTree(0));
179 
180  DT::MetaInfo metainfo(tOut);
181  metainfo.Check(config);
182  auto isMC = metainfo.Get<bool>("flags", "isMC");
183 
184  RecEvent * rEv = nullptr;
185  GenEvent * gEv = nullptr;
186  tIn->SetBranchAddress("recEvent", &rEv);
187  if (isMC)
188  tIn->SetBranchAddress("genEvent", &gEv);
189  vector<RecJet> * recjets = nullptr;
190  vector<GenJet> * genjets = nullptr;
191  tIn->SetBranchAddress("recJets", &recjets);
192  if (isMC)
193  tIn->SetBranchAddress("genJets", &genjets);
194 
195  const bool applySyst = (steering & DT::syst) == DT::syst;
196  const auto variations = applySyst && !isMC ? GetScaleVariations(metainfo)
197  : vector<TString>{"nominal"};
198 
199  // detector level
200  vector<BalanceHists<RecJet>> recBalances;
201  recBalances.emplace_back("rec_barrel_vs_any", variations);
202 
203  // hadron level
204  vector<BalanceHists<GenJet>> genBalances;
205  if (isMC)
206  genBalances.emplace_back("gen_barrel_vs_any", vector<TString>{"nominal"});
207 
208  TRandom3 r3(metainfo.Seed<39856>(slice));
209  for (DT::Looper looper(tIn, slice); looper(); ++looper) {
210  [[ maybe_unused ]]
211  static auto& cout = (steering & DT::verbose) == DT::verbose ? ::cout : DT::dev_null;
212 
213  auto gw = isMC ? gEv->weights.front() : Weight{1.,0},
214  rw = rEv->weights.front();
215 
216  // we take the probe and the tag randomly
217  auto r = r3.Uniform();
218  int itag = (r<0.5),
219  iprobe = (r>=0.5);
220 
221  if (DijetSelection<RecJet>(recjets))
222  for (auto bal: recBalances)
223  bal(recjets->at(itag), recjets->at(iprobe), gw*rw);
224 
225  if (!isMC) continue;
226 
227  if (DijetSelection<GenJet>(genjets))
228  for (auto bal: genBalances)
229  bal(genjets->at(itag), genjets->at(iprobe), gw);
230 
231  } // end of event loop
232 
233  for (auto p: recBalances) p.Write(fOut.get());
234  for (auto p: genBalances) p.Write(fOut.get());
235 
236  fOut->cd();
237  metainfo.Set<bool>("git", "complete", true);
238  tOut->Write();
239 
240  cout << __func__ << ' ' << slice << " stop" << endl;
241 }

◆ GetScaleVariations()

vector<TString> DAS::JetEnergy::GetScaleVariations ( const DT::MetaInfo metainfo)
146 {
147  vector<TString> variations{"nominal"};
148  const TList * groupContents = metainfo.List("variations", RecJet::ScaleVar);
149  if (!groupContents)
150  BOOST_THROW_EXCEPTION( invalid_argument(groupContents->GetName()) );
151 
152  for (const TObject * obj: *groupContents) {
153  const auto os = dynamic_cast<const TObjString*>(obj);
154  if (!os) BOOST_THROW_EXCEPTION( invalid_argument(obj->GetName()) );
155  TString s = os->GetString();
156  s.ReplaceAll(SysUp, "");
157  s.ReplaceAll(SysDown, "");
158  if (find(begin(JES_variations), end(JES_variations), s) != end(JES_variations))
159  variations.push_back(os->GetString());
160  }
161  return variations;
162 }

◆ loopDirsFromFitResponse()

void DAS::JetEnergy::loopDirsFromFitResponse ( TDirectory *  dIn,
TDirectory *  dOut,
const int  steering 
)

Copy directory structure. Given an input directory dIn recursively loop over all directory hierarchy/contents and reproduce it in the directory dOut of the output file. For each TH1 instance found containing the resolution, perform a NSC fit by calling FitResolution() function.

196 {
197  auto& cout = (steering & DT::verbose) == DT::verbose ? ::cout : DT::dev_null;
198  for (const auto&& obj: *(dIn->GetListOfKeys())) {
199  auto const key = dynamic_cast<TKey*>(obj);
200  if ( key->IsFolder() ) {
201  auto ddIn = dynamic_cast<TDirectory*>( key->ReadObj() );
202  if ( TString( ddIn->GetName() ).Contains("ptbin") ) continue;
203  TDirectory * ddOut = dOut->mkdir(ddIn->GetName(), ddIn->GetTitle());
204  ddOut->cd();
205  cout << bold << ddIn->GetPath() << def << endl;
206 
207  loopDirsFromFitResponse(ddIn, ddOut, steering);
208  }
209  else if ( TString( key->ReadObj()->GetName() ).Contains("sigmaCore") ) {
210  auto res = unique_ptr<TH1>( dynamic_cast<TH1*>(key->ReadObj()) );
211  res->SetDirectory(dOut);
212  dOut->cd();
213  res->Write();
214 
215  if ( TString(res->GetName()).Contains("Fail") ) continue;
216 
217  // Fit resolution
218  FitResolution(dOut, move(res), steering);
219  }
220  else cout << orange << "Ignoring " << key->ReadObj()->GetName() << " of `"
221  << key->ReadObj()->ClassName() << "` type" << def << endl;
222  } // End of for (list of keys) loop
223  cout << def << flush;
224 }

◆ loopDirsFromGetBalance()

void DAS::JetEnergy::loopDirsFromGetBalance ( TDirectory *  dIn,
TDirectory *  dOut 
)

This function is called by getPtAveBalance(). Recusively iterates over the internal structure of a file/directory and each it fins a serie of TH3 in the file, it interpret it as the many variations of the jet energy balance and us it to calculate the mean of the balance and also the balance curves in bins of pt and eta.

NOTE: additional remark on the implementation: Once the TH3 representing the binned in pt_balance, eta, y (presumably in the order (x, y, z), the pt_balance is projected into a 1-D histogram for each bin of rapidity and pt_ave (this done for each of the variations). For each bin of rapidity, the mean of the pt_balance is computed (see formula in th comments of ProcessVariations() the standard deviations from the balance are calculated from the statistical uncertainities and from the variations (presumably the variations of the JES).

185 {
186  // Recursively explore the directory present in the file.
187  // At each level where there are TH3, they are stored in a vector.
188  vector<TH3*> variations;
189  for (const auto&& obj: *(dIn->GetListOfKeys())) {
190  auto const key = dynamic_cast<TKey*>(obj);
191  if ( key->IsFolder() ) {
192  auto ddIn = dynamic_cast<TDirectory*>( key->ReadObj() );
193  if (ddIn == nullptr) {
194  cerr << red << "ddIn = " << ddIn << '\n' << def;
195  continue;
196  }
197  TDirectory * ddOut = dOut->mkdir(ddIn->GetName(), ddIn->GetTitle());
198  ddOut->cd();
199  cout << "creating directory " << bold << ddIn->GetPath() << normal << endl;
200 
201  loopDirsFromGetBalance(ddIn, ddOut);
202  }
203  else if ( ( TString( key->ReadObj()->ClassName() ).Contains("TH3") ) ) {
204  auto bal3D = dynamic_cast<TH3*>( key->ReadObj() );
205  bal3D->SetDirectory(0);
206  variations.push_back(bal3D);
207  }
208  else cout << "Found " << orange << key->ReadObj()->GetName() << normal << ".. Is of "
209  << underline << key->ReadObj()->ClassName() << normal << " type, ignoring it" << endl;
210  } // End of for (listof keys) loop
211 
220  if (variations.size() > 0)
221  ProcessVariations(variations, *dOut);
222 }

◆ loopDirsFromGetResponse()

void DAS::JetEnergy::loopDirsFromGetResponse ( TDirectory *  dIn,
TDirectory *  dOut,
const int  steering,
const DT::Slice  slice 
)

Copy directory structure. Given an input file dIn recursively loop over all directory hierarchy/contents and reproduce it in output file dOut. For each TH3 instance found containing the response perform a DCB fit by calling FitResponseByBin() function.

460 {
461  for (const auto&& obj: *(dIn->GetListOfKeys())) {
462  auto const key = dynamic_cast<TKey*>(obj);
463  if ( key->IsFolder() ) {
464  auto ddIn = dynamic_cast<TDirectory*>( key->ReadObj() );
465  if (ddIn == nullptr) continue;
466  TDirectory * ddOut = dOut->mkdir(ddIn->GetName(), ddIn->GetTitle());
467  ddOut->cd();
468  cout << bold << ddIn->GetPath() << def << endl;
469 
470  loopDirsFromGetResponse(ddIn, ddOut, steering, slice);
471  }
472  else if ( TString( key->ReadObj()->ClassName() ).Contains("TH3") ) {
473  // Assuming for axis, x: pt bins, y: eta bins, z: resolution bins
474  auto hist3D = unique_ptr<TH3>( dynamic_cast<TH3*>(key->ReadObj()) );
475  hist3D->SetDirectory(0);
476  bool isAbsEta = hist3D->GetYaxis()->GetBinLowEdge(1) >= 0;
477  TDirectory * ddOut = dOut->mkdir(key->GetName(), key->ReadObj()->GetTitle());
478  for (int etabin = 1; etabin <= hist3D->GetNbinsY(); ++etabin) {
479  static int ieta = 0; // Used for parallelisation
480  ++ieta;
481  if (slice.second != ieta % slice.first) continue;
482 
483  float lowedge = hist3D->GetYaxis()->GetBinLowEdge(etabin),
484  upedge = hist3D->GetYaxis()->GetBinUpEdge (etabin);
485  TString title = isAbsEta ? Form("%.3f < |#eta| < %.3f", lowedge, upedge)
486  : Form("%.3f < #eta < %.3f" , lowedge, upedge);
487  hist3D->GetYaxis()->SetRange(etabin, etabin);
488  auto hist2D = unique_ptr<TH2>( dynamic_cast<TH2*>(hist3D->Project3D("ZX")) ); // Z vs X, where Z is vertical and X is horizontal axis
489  hist2D->SetTitle( TString( hist2D->GetTitle() ).ReplaceAll(") ", ", " + title + ")") );
490  ddOut->cd();
491  TDirectory * dddOut = ddOut->mkdir(Form("etabin%d", etabin), title);
492  cout << bold << dddOut->GetPath() << def << endl;
493 
494  FitResponseByBin(dddOut, move(hist2D), steering);
495  }
496  }
497  else cout << orange << "Ignoring " << key->ReadObj()->GetName() << " of `"
498  << key->ReadObj()->ClassName() << "` type" << def << endl;
499  } // End of for (list of keys) loop
500 }

◆ ProcessVariations()

void DAS::JetEnergy::ProcessVariations ( const vector< TH3 * > &  variations,
TDirectory &  dOut 
)

This function is called by loopDirsFromGetBalance(). It takes as argument a vector of TH3 which presumabilly represents the transverse momentum balance ($p_{T}^{bal}$) histograms in bins of ($p_{T}^{bal}$, $p_{T}^{ave}$, $y_{probe}$) for different variations of the JES. This function project the pt_balance histogram in 1-D for each bin of $p_{T}^{ave}$ and $y_{probe}$. This function calculates the histogram of the mean value of the balance in bins of $p_{T}^{ave}$ for each bin, it calculates the incertainty bands deduced from the statistical variations of the mean and the systematics of the JES variations.

NOTE: for an explicit definition of the variables, see the additional docstring in the core of the code.

The second arguments of this function is the directory in which the histograms are written. This function creates the subdirectory structure necessary to store each series of variations corresponding to each $y_{probe}$ and $p_{T}^{ave}$ bins in a given directory. The structure of the output is:

file/ > dOut/ > eta1/ > nominal (TH1, mean value of the $p_{T}^{bal}$ with statistical unc.)
> upper (upper limit of the variations statistical+systematics)
> lower (lower limit of the variations staistical + systematics)
> ptbin1 > rec_any_vs_any_balance_0
> ...
> rec_any_vs_any_balance_${nVariations}
> ptbin2
> ...
> ptbin${nPtbins}
> ...
> eta${nYbins}

The structure at file/dOut/ level is identical to the structure of the input file.

We use the terminology used in AN2019_167_v13:

  • The balance A is : \(A = 2 \frac{p_{T,1}-p_{T,2}}{p_{T,1} + p_{T,2}} \)
  • The mean balance is the quantity: \( R = \frac{1 - \fac{ \left\langle A \right\rangle }{2}}{1 + \frac{ \left\langle A \right\rangle }{2}}\)
72 {
73  const int N = variations.size();
74  Int_t nBins_local = variations.front()->GetNbinsY();
75 
76  // Filling an array with the lower edges of each bins in transverse momentum + the upper edge of the last bin.
77  double LowEdges[nBins_local] = {0.};
78  variations.front()->GetYaxis()->GetLowEdge(LowEdges);
79  double genBins_local[nBins_local + 1];
80  for (int i = 0 ; i<nBins_local ; ++i) genBins_local[i]=LowEdges[i];
81  genBins_local[nBins_local] = variations.front()->GetYaxis()->GetBinUpEdge(nBins_local);
82 
83  // Iterating over the rapidity bins
84  for (int y = 1 ; y <= variations.front()->GetNbinsZ() ; ++y) {
85 
86  // Create the directory "eta_bin"
87  TDirectory *direta = dOut.mkdir( Form("eta%d", y) );
88  cout <<"Creating directory " << bold << direta->GetPath() << normal << endl;
89  direta->cd();
90 
91  // `nominal`, `upper` and `lower` contains average value of $p_{T,1}/p_{T,2}$ in bins of $p_{T,ave}$
92  TH1 *nominal = new TH1F("nominal", "", nBins_local, genBins_local),
93  *upper = new TH1F("upper", "", nBins_local, genBins_local),
94  *lower = new TH1F("lower", "", nBins_local, genBins_local);
95 
96  // Setting the directory in which to write the histograms
97  nominal->SetDirectory(direta);
98  upper->SetDirectory(direta);
99  lower->SetDirectory(direta);
100 
101  // Setting the title of the axis
102  nominal->SetXTitle("p_{T,ave}");
103  nominal->SetYTitle("#frac{1 - #LT #frac{#Delta p_{T}}{p_{T,ave}} #GT}{1 + #LT #frac{#Delta p_{T}}{p_{T,ave}} #GT }");
104  upper->SetXTitle("p_{T,ave}");
105  upper->SetYTitle("#frac{1 - #LT #frac{#Delta p_{T}}{p_{T,ave}} #GT}{1 + #LT #frac{#Delta p_{T}}{p_{T,ave}} #GT }");
106  lower->SetXTitle("p_{T,ave}");
107  lower->SetYTitle("#frac{1 - #LT #frac{#Delta p_{T}}{p_{T,ave}} #GT}{1 + #LT #frac{#Delta p_{T}}{p_{T,ave}} #GT }");
108 
109  // Iterating over the pT_Ave bins.
110  for (int ipt = 1 ; ipt <= nBins_local ; ++ipt) {
111 
112  // `errUp` contains the error coming from the 'above' variations.
113  // `errDn` contains the error coming from the 'under' variations.
114  double errUp = variations.front()->GetBinError(ipt),
115  errDn = errUp, content=0;
116 
117  TDirectory *dirpt = direta->mkdir( Form("ptbin%d",ipt) );
118  dirpt->cd();
119  cout <<"Creating directory " << bold << dirpt->GetPath() << normal << endl;
120 
121  // Iterating over the variations.
122  for (int sv=0 ; sv<N ; ++sv) {
123  auto balance = variations[sv]->ProjectionX("py", ipt, ipt, y, y, "e");
124  balance->SetName(variations[sv]->GetName());
125  balance->SetTitle(variations[sv]->GetTitle());
126  balance->SetDirectory(dirpt);
127  double I = balance->Integral();
128 
129  if (std::abs(I)<deps) {
130  cout << "integral is null in bin (pt, eta): (" << ipt << "," << y << ") in variation: " << sv << endl;
131  continue;
132  }
133  else balance->Scale(1./I);
134 
135  double mean = balance->GetMean();
136  double meanErr = balance->GetMeanError();
137 
138  if (sv == 0) {
144  double R = (1.-mean/2.)/(1.+mean/2.),
145  Rup = (1.-(mean+meanErr)/2.)/(1.+(mean+meanErr)/2.),
146  Rdn = (1.-(mean-meanErr)/2.)/(1.+(mean-meanErr)/2.);
147  // The nominal value is set once for each bins of \f$p_{T,ave}\f$
148  // while iterating over the variations.
149  nominal->SetBinContent(ipt, R);
150  nominal->SetBinError(ipt, std::abs(Rup-Rdn)/2.);
151 
152  // the nominal content is set once while iterating over the variations
153  content=mean;
154  }
155  else {
156  // Iteration over the 'non-nominal' variations (sv>1).
157  // For each variation, if the variation is above the nominal content, var-content
158  // is added to errUp. Else var-content is added to errDn.
159  // errUp or errDn are reach via the address `err` which contain
160  // errDn or errUp depending on the need.
161  double& err = mean > content ? errUp : errDn;
162  err = hypot(err, mean - content);
163  }
164  balance->Write();
165  }
166  // See comment l.136 (close to the filling of `nominal`.
167  // Content contains the nominal mean value of balance in each bins of pt.
168  upper->SetBinContent(ipt, (1.-(content+errUp)/2)/(1.+(content+errUp)/2) );
169  lower->SetBinContent(ipt, (1.-(content-errDn)/2)/(1.+(content-errDn)/2) );
170  }
171  direta->cd();
172  nominal->Write();
173  upper->Write();
174  lower->Write();
175  }
176 }

◆ round_to()

double DAS::JetEnergy::round_to ( double  value,
double  precision = 1.0 
)
inline

Round number value to precision. Recover "lost" precision.

101 {
102  return round(value / precision) * precision;
103 }

Variable Documentation

◆ abseta_edges

const std::vector<double> abseta_edges = { 0.000, 0.261, 0.522, 0.783, 1.044, 1.305, 1.566, 1.740, 1.930, 2.043, 2.172, 2.322, 2.500, 2.650, 2.853, 2.964, 3.139, 3.489, 3.839, 5.191 }
inlinestatic

JERC binning (taken from JERCProtoLab repo, /macros/common_info/common_binning.hpp)

◆ absetaBins

const std::vector<TString> absetaBins = MakeTitle(abseta_edges, "|#eta|", false, true, [](double v) { return Form("%.3f", v);})
inlinestatic

◆ deps

const auto deps = numeric_limits<double>::epsilon()
static

◆ eta_unc_edges

const std::vector<double> eta_unc_edges = {-5.4, -5.0, -4.4, -4.0, -3.5, -3.0, -2.8, -2.6, -2.4, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0 , 0.2 , 0.4 , 0.6 , 0.8 , 1.0 , 1.2 , 1.4 , 1.6 , 1.8 , 2.0 , 2.2 , 2.4 , 2.6 , 2.8 , 3.0, 3.5 , 4.0 , 4.4 , 5.0 , 5.4}
inlinestatic

binning for JES uncertainties (taken from JES files)

◆ JES_variations

const std::vector<std::string> JES_variations {"AbsoluteStat", "AbsoluteScale", "AbsoluteMPFBias", "Fragmentation", "SinglePionECAL", "SinglePionHCAL", "FlavorQCD", "RelativeJEREC1", "RelativeJEREC2", "RelativeJERHF", "RelativePtBB", "RelativePtEC1", "RelativePtEC2", "RelativePtHF", "RelativeBal", "RelativeSample", "RelativeFSR", "RelativeStatFSR", "RelativeStatEC", "RelativeStatHF", "PileUpDataMC", "PileUpPtRef", "PileUpPtBB", "PileUpPtEC1", "PileUpPtEC2", "PileUpPtHF"}
inlinestatic

◆ nAbsEtaBins

const int nAbsEtaBins = abseta_edges.size()-1
inlinestatic

◆ nEtaUncBins

const int nEtaUncBins = eta_unc_edges.size()-1
inlinestatic

◆ nPtJERCbins

const int nPtJERCbins = pt_JERC_edges.size()-1
inlinestatic

◆ nRhoBins

const std::map<int,int> nRhoBins
inlinestatic
Initial value:
= {
{2016, rho_edges.at(2016).size()-1 },
{2017, rho_edges.at(2017).size()-1 },
{2018, rho_edges.at(2018).size()-1 }
}

◆ pt_JERC_edges

const std::vector<double> pt_JERC_edges = {15, 17, 20, 23, 27, 30, 35, 40, 45, 57, 72, 90, 120, 150, 200, 300, 400, 550, 750, 1000, 1500, 2000, 2500, 3000, 3500, 4000, 4500, 5000, 5500, 6000, 6500, 7000, 7500, 8000, 8500, 9000, 9500}
inlinestatic

◆ rho_edges

const std::map<int,std::vector<double> > rho_edges
inlinestatic
Initial value:
= {
{ 2016, {0, 6.69, 12.39, 18.09, 23.79, 29.49, 35.19, 40.9, 999} },
{ 2017, {0, 7.47, 13.49, 19.52, 25.54, 31.57, 37.59, 999} },
{ 2018, {0, 7.35, 13.26, 19.17, 25.08, 30.99, 36.9, 999} }
}

◆ rhoBins

const std::map<int,std::vector<TString> > rhoBins
inlinestatic
Initial value:
= {
{ 2016, MakeTitle(rho_edges.at(2016), "#rho", false, false, [](double v) { return Form("%.2f", v);}) },
{ 2017, MakeTitle(rho_edges.at(2017), "#rho", false, false, [](double v) { return Form("%.2f", v);}) },
{ 2018, MakeTitle(rho_edges.at(2018), "#rho", false, false, [](double v) { return Form("%.2f", v);}) }
}

◆ w

const float w = 0.8
inlinestatic
Todo:
check exact list of variations with JME group
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
Ntupliser_cfg.cerr
cerr
Definition: Ntupliser_cfg.py:93
metPhiCorrectionExample.bins
bins
Definition: metPhiCorrectionExample.py:89
DAS::JetEnergy::rho_edges
static const std::map< int, std::vector< double > > rho_edges
Definition: common.h:22
DAS::JetEnergy::loopDirsFromGetResponse
void loopDirsFromGetResponse(TDirectory *dIn, TDirectory *dOut, const int steering, const DT::Slice slice)
Definition: fitJetResponse.cc:456
jmarExample.pt
pt
Definition: jmarExample.py:19
Darwin::Tools::syst
@ syst
activate -s to systematic uncertainties
Definition: Options.h:30
Step::verbose
static bool verbose
Definition: Step.h:40
Step::def
static const char * def
Definition: Step.h:36
DAS::PhysicsObject::p4
FourVector p4
raw four-momentum directly after reconstruction
Definition: PhysicsObject.h:47
DAS::JetEnergy::eta_unc_edges
static const std::vector< double > eta_unc_edges
binning for JES uncertainties (taken from JES files)
Definition: common.h:42
underline
static const char * underline
Definition: colours.h:10
DAS::JetEnergy::GetMergedBinning
vector< double > GetMergedBinning(TH1 *h, const int threshold=30)
Definition: fitJetResponse.cc:49
jercExample.algo
string algo
Definition: jercExample.py:60
Darwin::Tools::UserInfo::Get
T Get(TList *mother, const char *key) const
Definition: UserInfo.h:75
DAS::JetEnergy::loopDirsFromGetBalance
void loopDirsFromGetBalance(TDirectory *dIn, TDirectory *dOut)
Definition: getPtAveBalance.cc:184
DAS::SysUp
const std::string SysUp
Suffix used for "up" uncertainties. Follows the Combine convention.
Definition: Format.h:8
Ntupliser_cfg.year
int year
Definition: Ntupliser_cfg.py:63
jercExample.cset
cset
Definition: jercExample.py:90
DAS::MakeTitle
std::vector< TString > MakeTitle(const std::vector< double > &edges, const char *v, bool lowEdge, bool highEdge, std::function< const char *(double)> format)
Make a vector of properly formated titles from bin edges.
Definition: binnings.h:13
DYToLL_M-50_13TeV_pythia8_cff_GEN_SIM_RECOBEFMIX_DIGI_L1_DIGI2RAW_L1Reco_RECO.source
source
Definition: DYToLL_M-50_13TeV_pythia8_cff_GEN_SIM_RECOBEFMIX_DIGI_L1_DIGI2RAW_L1Reco_RECO.py:39
DAS::JetEnergy::GetScaleVariations
vector< TString > GetScaleVariations(const DT::MetaInfo &metainfo)
Definition: getPtBalance.cc:145
DAS::JetEnergy::pt_JERC_edges
static const std::vector< double > pt_JERC_edges
Definition: common.h:13
Darwin::Tools::Looper
Facility to loop over a n-tuple, including parallelisation and printing.
Definition: Looper.h:33
Darwin::Tools::GetChain
std::unique_ptr< TChain > GetChain(std::vector< std::filesystem::path > inputs, const char *name="events")
Load chain from a list of files.
Definition: FileUtils.cc:67
Ntupliser_cfg.p
p
Definition: Ntupliser_cfg.py:361
Ntupliser_cfg.f
f
Definition: Ntupliser_cfg.py:255
DAS::JetEnergy::CumulativeResponse
TH1 * CumulativeResponse(TH1 *res1D)
Definition: fitJetResponse.cc:306
DAS::PhysicsObject::scales
std::vector< float > scales
energy scale corrections and variations
Definition: PhysicsObject.h:48
jercExample.key
string key
Definition: jercExample.py:109
Darwin::Tools::MetaInfo
Generic meta-information for n-tuple (including speficities to Darwin).
Definition: MetaInfo.h:65
DAS::JetEnergy::ProcessVariations
void ProcessVariations(const vector< TH3 * > &variations, TDirectory &dOut)
Definition: getPtAveBalance.cc:71
DAS::JetEnergy::FitResponseByBin
void FitResponseByBin(TDirectory *dir, unique_ptr< TH2 > res2D, const int steering)
Definition: fitJetResponse.cc:328
DAS::Normalisation::makeRespHist
unique_ptr< TH3 > makeRespHist(TString name, TString study)
Create TH3 histograms for the Jet response and HLT response.
Definition: MakeResponseHistos.h:20
DAS::pt_sort
bool pt_sort(const PhysicsObject &j1, const PhysicsObject &j2)
Definition: toolbox.h:18
DAS::MN::minpt
static const double minpt
Definition: getMNobservables.cc:42
DAS::JetEnergy::JES_variations
static const std::vector< std::string > JES_variations
Definition: common.h:45
Ntupliser_cfg.genjets
genjets
Definition: Ntupliser_cfg.py:271
Ntupliser_cfg.jets
string jets
Definition: Ntupliser_cfg.py:41
Darwin::Tools::fill
@ fill
activate -f to fill the tree
Definition: Options.h:28
recjet
DAS::RecJet recjet
Definition: classes.h:15
weight
DAS::Weight weight
Definition: classes.h:11
Step::red
static const char * red
Definition: Step.h:34
jercExample.unc
string unc
Definition: jercExample.py:70
Ntupliser_cfg.config
config
Definition: Ntupliser_cfg.py:263
DAS::Uncertainties::nominal
const Variation nominal
Definition: Variation.h:109
DAS::MN::maxpt
static const double maxpt
Definition: getMNobservables.cc:42
gitlab_post_comment.response
response
Definition: gitlab_post_comment.py:23
orange
static const char * orange
Definition: colours.h:6
DYToLL_M-50_13TeV_pythia8_cff_GEN_SIM_RECOBEFMIX_DIGI_L1_DIGI2RAW_L1Reco_RECO.input
input
Definition: DYToLL_M-50_13TeV_pythia8_cff_GEN_SIM_RECOBEFMIX_DIGI_L1_DIGI2RAW_L1Reco_RECO.py:35
Darwin::Tools::UserInfo::Find
bool Find(TList *mother, const char *key) const
Recursive finder.
Definition: UserInfo.h:107
Ntupliser_cfg.recjets
recjets
Definition: Ntupliser_cfg.py:272
DAS::JetEnergy::nEtaUncBins
static const int nEtaUncBins
Definition: common.h:43
DAS::JetEnergy::abseta_edges
static const std::vector< double > abseta_edges
JERC binning (taken from JERCProtoLab repo, /macros/common_info/common_binning.hpp)
Definition: common.h:18
normal
static const char * normal
Definition: colours.h:8
DAS::PhysicsObject::CorrPt
float CorrPt(size_t i=0) const
corrected transverse momentum
Definition: PhysicsObject.h:52
DAS::JetEnergy::deps
static const auto deps
Definition: getPtAveBalance.cc:38
DAS::SysDown
const std::string SysDown
Suffix used for "down" uncertainties. Follows the Combine convention.
Definition: Format.h:10
Darwin::Tools::UserInfo::List
TList * List(TList *mother, const char *key) const
Accest do daughter list from a mother list.
Definition: UserInfo.cc:33
Ntupliser_cfg.isMC
string isMC
Definition: Ntupliser_cfg.py:59
DAS::JetEnergy::getAlgo
std::string getAlgo(const Darwin::Tools::MetaInfo &metainfo)
Determine from metainfo if CHS or PUPPI has been used to reconstruct the jets.
Definition: common.h:86
DAS::JetEnergy::nRhoBins
static const std::map< int, int > nRhoBins
Definition: common.h:28
DAS::Normalisation::threshold
const float threshold
Definition: sigmoid.h:14
jercExample.sf
sf
Definition: jercExample.py:112
jercExample.inputs
def inputs
Definition: jercExample.py:118
Darwin::Exceptions::AnomalousEvent
Generic exception for problematic event (during event loop).
Definition: exceptions.h:48
DAS::JetEnergy::loopDirsFromFitResponse
void loopDirsFromFitResponse(TDirectory *dIn, TDirectory *dOut, const int steering)
Definition: fitJetResolution.cc:193
DAS::JetEnergy::nPtJERCbins
static const int nPtJERCbins
Definition: common.h:14
Darwin::Tools::dev_null
static std::ostream dev_null(nullptr)
to redirect output stream to nowhere
DAS::JetEnergy::FitResolution
void FitResolution(TDirectory *dir, unique_ptr< TH1 > h, const int steering)
Fit the resolution obtained from fitJetResponse in a given eta/rho bin.
Definition: fitJetResolution.cc:167
DT_GetOutput
#define DT_GetOutput(output)
Definition: FileUtils.h:96
Darwin::Exceptions::BadInput
Generic exception for ill-defined input (before the event loop).
Definition: exceptions.h:68
jmarExample.eta
eta
DeepAK8/ParticleNet tagging.
Definition: jmarExample.py:19
DAS::nYbins
static const int nYbins
Definition: binnings.h:38
DAS::JetEnergy::nAbsEtaBins
static const int nAbsEtaBins
Definition: common.h:19
Step::bold
static const char * bold
Definition: Step.h:35