DAS  3.0
Das Analysis System
DAS::BTagging Namespace Reference

Classes

struct  JetWeight
 

Functions

void applyBTagSF (const vector< fs::path > &inputs, const fs::path &output, const pt::ptree &config, const int steering, const DT::Slice slice={1, 0})
 
vector< double > GetDeepJetEdges (int year, bool HIPM=false)
 
void getBTagBinnedDiscriminant (const vector< fs::path > &inputs, const fs::path &output, const pt::ptree &config, const int steering, const DT::Slice slice={1, 0})
 
void getBTagFraction (const vector< fs::path > &inputs, const fs::path &output, const int steering)
 
void getBTagPerformance (const vector< fs::path > &inputs, const fs::path &output, const int steering)
 

Function Documentation

◆ applyBTagSF()

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

Apply the multi-WP calibration with fix-WPs tables.

Parameters
inputsinput ROOT files (n-tuples)
outputoutput ROOT file (n-tuple)
configconfig handled with `Darwin::Tools::options`
steeringparameters obtained from explicit options
slicenumber and index of slice
120  {1,0}
121  )
122 {
123  cout << __func__ << ' ' << slice << " start" << endl;
124 
125  unique_ptr<TChain> tIn = DT::GetChain(inputs);
126  unique_ptr<TFile> fOut(DT_GetOutput(output));
127  auto tOut = unique_ptr<TTree>(tIn->CloneTree(0));
128 
129  DT::MetaInfo metainfo(tOut);
130  metainfo.Check(config);
131  auto isMC = metainfo.Get<bool>("flags", "isMC");
132  if (!isMC) BOOST_THROW_EXCEPTION( DE::BadInput("Only MC may be used as input.",
133  make_unique<TFile>(inputs.front().c_str() )) );
134  auto R = metainfo.Get<int>("flags", "R");
135  if (R != 4) BOOST_THROW_EXCEPTION( DE::BadInput("Only AK4 jets may be used.",
136  make_unique<TFile>(inputs.front().c_str() )) );
137 
138  vector<RecJet> * recJets = nullptr;
139  tIn->SetBranchAddress("recJets", &recJets);
140 
141  if (steering & DT::syst)
142  BOOST_THROW_EXCEPTION( logic_error("B-tagging variations not yet implemented\n") );
143 
144  auto discriminant = config.get<fs::path>("corrections.btagging.discriminant"),
145  SFtables = config.get<fs::path>("corrections.btagging.SFtables");
146  JetWeight w(SFtables, discriminant);
147 
148  metainfo.Set<fs::path>("corrections", "btagging", "discriminant", discriminant);
149  metainfo.Set<fs::path>("corrections", "btagging", "SFtables" , SFtables );
150 
151  for (DT::Looper looper(tIn, slice); looper(); ++looper) {
152  [[ maybe_unused]]
153  static auto& cout = steering & DT::verbose ? ::cout : DT::dev_null;
154 
155  for (auto& jet: *recJets)
156  jet.weights *= w(jet);
157 
158  if (steering & DT::fill) tOut->Fill();
159  }
160 
161  fOut->cd();
162  metainfo.Set<bool>("git", "complete", true);
163  tOut->Write();
164 
165  cout << __func__ << ' ' << slice << " stop" << endl;
166 }

◆ getBTagBinnedDiscriminant()

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

Get B-tagged binned discriminant in bins of pt, true flavour, and discriminant value. Works for both data and MC (although in the case of data, the true flavour is always trivial).

Todo:
GSP?
Todo:
loop over variations
Todo:
gen event weight
Parameters
inputsinput ROOT files (n-tuples)
outputoutput ROOT file (n-tuple)
configconfig handled with `Darwin::Tools::options`
steeringparameters obtained from explicit options
slicenumber and index of slice
59  {1,0}
60  )
61 {
62  cout << __func__ << ' ' << slice << " start" << endl;
63 
64  unique_ptr<TChain> tIn = DT::GetChain(inputs);
65  unique_ptr<TFile> fOut(DT_GetOutput(output));
66  auto tOut = unique_ptr<TTree>(tIn->CloneTree(0));
67 
68  DT::MetaInfo metainfo(tOut);
69  metainfo.Check(config);
70  //auto isMC = metainfo.Get<bool>("flags", "isMC");
71  auto year = metainfo.Get<int>("flags", "year");
72  bool HIPM = metainfo.Find("flags", "labels");
73  if (HIPM && year != 2016)
74  cerr << orange << "The HIPM label may only be used for 2016 samples. It will be just ignored for other years.\n" << def;
75 
76  const vector<double> flavour_edges = {0.5, 1.5, 2.5, 3.5, 4.5, 5.5},
77  disc_edges = GetDeepJetEdges(year, HIPM);
78  const int nFlBins = flavour_edges.size()-1,
79  nDiscBins = disc_edges.size()-1;
80  auto discriminant = make_unique<TH3D>("discriminant", "B-tag discriminant",
81  nPtBins, pt_edges.data(),
82  nFlBins, flavour_edges.data(),
83  nDiscBins, disc_edges.data());
84 
85  if (steering & DT::syst)
86  BOOST_THROW_EXCEPTION( logic_error("B-tagging variations not yet implemented\n") );
87 
88  //GenEvent * genEvent = nullptr; /// \todo genEvent??
89  RecEvent * recEvent = nullptr;
90  tIn->SetBranchAddress("recEvent", &recEvent);
91  vector<RecJet> * recJets = nullptr;
92  tIn->SetBranchAddress("recJets", &recJets);
93 
94  for (DT::Looper looper(tIn, slice); looper(); ++looper) {
95  [[ maybe_unused]]
96  static auto& cout = steering & DT::verbose ? ::cout : DT::dev_null;
97 
99 
100  auto evWgt = recEvent->weights.front();
102  //if (isMC) evWgt *= genEvt->weights.front();
103 
104  for (const RecJet& jet: *recJets) {
105  auto jWgt = jet.weights.front();
106  discriminant->Fill(jet.CorrPt(), jet.hadronFlavour(), jet.DeepJet.B(), jWgt*evWgt);
107  }
108  }
109 
110  fOut->cd();
111  discriminant->SetDirectory(fOut.get());
112  discriminant->Write();
113  metainfo.Set<bool>("git", "complete", true);
114  tOut->Write();
115 
116  cout << __func__ << ' ' << slice << " stop" << endl;
117 }

◆ getBTagFraction()

void DAS::BTagging::getBTagFraction ( const vector< fs::path > &  inputs,
const fs::path &  output,
const int  steering 
)

Extract the B-tagged fraction from the output of getBTagDiscriminant. Works for both data and MC.

Parameters
inputsinput ROOT files (histograms)
outputoutput ROOT file (histograms)
steeringparameters obtained from explicit options
36 {
37  [[ maybe_unused]]
38  static auto& cout = steering & DT::verbose ? ::cout : DT::dev_null;
39 
40  cout << __func__ << " start" << endl;
41 
42  unique_ptr<TH3> hIn = DT::GetHist<TH3>(inputs, "discriminant");
43  if (hIn->GetNbinsZ() != 4) {
44  const char * what = Form("Found %d working points (expecting 4)", hIn->GetNbinsZ());
45  BOOST_THROW_EXCEPTION( DE::BadInput(what, hIn) );
46  }
47 
48  unique_ptr<TFile> fOut(DT_GetOutput(output));
49 
50  auto project = [&hIn](const char * name, int bin) {
51  return unique_ptr<TH1>( hIn->ProjectionX(name, 0, -1, bin, 4) );
52  };
53 
54  auto hIncl = project("inclusive", 1);
55  int im = hIncl->FindBin(22), // because the btagging calib starts with pt > 20 GeV
56  iM = hIncl->GetNbinsX();
57  auto integrate = [im,iM](const unique_ptr<TH1>& h) {
58  return h->Integral(im, iM);
59  };
60  double sum = integrate(hIncl);
61 
62  map<TString, int> WPs { {"loose", 2}, {"medium", 3}, {"tight", 4} };
63  for (const auto& WP: WPs) {
64  auto h = project(WP.first, WP.second);
65  h->SetTitle("B-tagged jet fraction for " + WP.first + " working point");
66  cout << h->GetTitle() << ": " << integrate(h)/sum << endl;
67  h->Divide(h.get(), hIncl.get(), 1, 1, "b");
68  h->Write();
69  }
70 
71  cout << __func__ << " stop" << endl;
72 }

◆ getBTagPerformance()

void DAS::BTagging::getBTagPerformance ( const vector< fs::path > &  inputs,
const fs::path &  output,
const int  steering 
)

Extract the B-tagged performance from the output of getBTagBinnedDiscriminant. The B-tagging efficiency and mistag rates are calculated.

Todo:
crash if under- or overflow non-empty
Parameters
inputsinput ROOT files (histograms)
outputoutput ROOT file (histograms)
steeringparameters obtained from explicit options
36 {
37  [[ maybe_unused]]
38  static auto& cout = steering & DT::verbose ? ::cout : DT::dev_null;
39 
40  cout << __func__ << " start" << endl;
41 
42  unique_ptr<TH3> hIn = DT::GetHist<TH3>(inputs, "discriminant");
43  if (hIn->GetNbinsZ() != 4) {
44  const char * what = Form("Found %d working points (expecting 4)", hIn->GetNbinsZ());
45  BOOST_THROW_EXCEPTION( DE::BadInput(what, hIn) );
46  }
47 
48  unique_ptr<TFile> fOut(DT_GetOutput(output));
49 
50  map<TString, int> flavours { {"light" , 0}, {"charm" , 4}, {"bottom", 5} };
51  map<TString, int> WPs { {"loose", 2}, {"medium", 3}, {"tight", 4} };
52  for (const auto& WP: WPs) {
53 
54  int tagBin = WP.second;
55 
56  auto hIncl = unique_ptr<TH1>( hIn->ProjectionX("inclusive", 0, -1, tagBin, 4) );
57 
58  for (const auto& flavour: flavours) {
59 
60  TString name = WP.first + '_' + flavour.first;
61 
62  int flBin = flavour.second;
63 
64  auto h = unique_ptr<TH1>( hIn->ProjectionX(name, flBin, flBin, tagBin, 4) );
65  TString title = flavour.first + " for " + WP.first + " working point";
66  cout << title << endl;
67  h->SetTitle(title);
68  h->Divide(h.get(), hIncl.get(), 1, 1, "b");
69  h->Write();
70  }
71  }
72 
74 
75  cout << __func__ << " stop" << endl;
76 }

◆ GetDeepJetEdges()

vector<double> DAS::BTagging::GetDeepJetEdges ( int  year,
bool  HIPM = false 
)

Working points provided by BTV for Full-Run-2 Ultra-Legacy samples.

Reference: Wiki

35 {
36  switch (year) {
37  case 2016:
38  if (HIPM) return { 0., 0.0508, 0.2598, 0.6502, 1. };
39  else return { 0., 0.0480, 0.2489, 0.6377, 1. };
40  case 2017:
41  return {0., 0.0532, 0.3040, 0.7476, 1.};
42  case 2018:
43  return {0., 0.0490, 0.2783, 0.7100, 1.};
44  default:
45  const char * what = Form("The year %d is currently not supported", year);
46  BOOST_THROW_EXCEPTION( invalid_argument(what) );
47  }
48 }
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
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
Ntupliser_cfg.year
int year
Definition: Ntupliser_cfg.py:63
Ntupliser_cfg.flavour
string flavour
Definition: Ntupliser_cfg.py:42
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
DAS::pt_edges
static const std::vector< double > pt_edges
Definition: binnings.h:33
DAS::JetEnergy::w
static const float w
Definition: common.h:47
Darwin::Tools::MetaInfo
Generic meta-information for n-tuple (including speficities to Darwin).
Definition: MetaInfo.h:65
Darwin::Tools::fill
@ fill
activate -f to fill the tree
Definition: Options.h:28
DAS::BTagging::GetDeepJetEdges
vector< double > GetDeepJetEdges(int year, bool HIPM=false)
Definition: getBTagBinnedDiscriminant.cc:34
Ntupliser_cfg.config
config
Definition: Ntupliser_cfg.py:263
gitlab_post_comment.project
project
Definition: gitlab_post_comment.py:7
orange
static const char * orange
Definition: colours.h:6
DAS::nPtBins
static const int nPtBins
Definition: binnings.h:39
Ntupliser_cfg.isMC
string isMC
Definition: Ntupliser_cfg.py:59
jercExample.inputs
def inputs
Definition: jercExample.py:118
Darwin::Tools::dev_null
static std::ostream dev_null(nullptr)
to redirect output stream to nowhere
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