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  DT::Flow flow(steering);
126  auto tIn = flow.GetInputTree(inputs, slice);
127  auto tOut = flow.GetOutputTree(output);
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  auto recJets = flow.GetBranchReadWrite<vector<RecJet>>("recJets");
139 
140  if (steering & DT::syst)
141  BOOST_THROW_EXCEPTION( logic_error("B-tagging variations not yet implemented\n") );
142 
143  auto discriminant = config.get<fs::path>("corrections.btagging.discriminant"),
144  SFtables = config.get<fs::path>("corrections.btagging.SFtables");
145  JetWeight w(SFtables, discriminant);
146 
147  metainfo.Set<fs::path>("corrections", "btagging", "discriminant", discriminant);
148  metainfo.Set<fs::path>("corrections", "btagging", "SFtables" , SFtables );
149 
150  for (DT::Looper looper(tIn); looper(); ++looper) {
151  [[ maybe_unused]]
152  static auto& cout = steering & DT::verbose ? ::cout : DT::dev_null;
153 
154  for (auto& jet: *recJets)
155  jet.weights *= w(jet);
156 
157  if (steering & DT::fill) tOut->Fill();
158  }
159 
160  metainfo.Set<bool>("git", "complete", true);
161 
162  cout << __func__ << ' ' << slice << " stop" << endl;
163 }

◆ 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  DT::Flow flow(steering);
65  auto tIn = flow.GetInputTree(inputs, slice);
66  auto [fOut, tOut] = flow.GetOutput(output);
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  auto recEvent = flow.GetBranchReadOnly<RecEvent>("recEvent");
90  auto recJets = flow.GetBranchReadOnly<vector<RecJet>>("recJets");
91 
92  for (DT::Looper looper(tIn); looper(); ++looper) {
93  [[ maybe_unused]]
94  static auto& cout = steering & DT::verbose ? ::cout : DT::dev_null;
95 
97 
98  auto evWgt = recEvent->weights.front();
100  //if (isMC) evWgt *= genEvt->weights.front();
101 
102  for (const RecJet& jet: *recJets) {
103  auto jWgt = jet.weights.front();
104  discriminant->Fill(jet.CorrPt(), jet.hadronFlavour(), jet.DeepJet.B(), jWgt*evWgt);
105  }
106  }
107 
108  fOut->cd();
109  discriminant->SetDirectory(fOut);
110  discriminant->Write();
111  metainfo.Set<bool>("git", "complete", true);
112 
113  cout << __func__ << ' ' << slice << " stop" << endl;
114 }

◆ 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  auto fOut = DT::GetOutputFile(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  auto fOut = DT::GetOutputFile(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::fill
@ fill
activate -f to fill the tree
Definition: Options.h:27
Darwin::Tools::Flow
User-friendly handling of input and output n-tuples.
Definition: Flow.h:55
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:32
DAS::pt_edges
static const std::vector< double > pt_edges
Definition: binnings.h:33
Darwin::Tools::syst
@ syst
activate -s to systematic uncertainties
Definition: Options.h:29
DAS::JetEnergy::w
static const float w
Definition: common.h:51
Darwin::Tools::MetaInfo
Generic meta-information for n-tuple (including speficities to Darwin).
Definition: MetaInfo.h:65
Darwin::Tools::GetOutputFile
std::shared_ptr< TFile > GetOutputFile(const std::filesystem::path &, const std::source_location=std::source_location::current())
Shortcut to create a reproducible output file (see ROOT Doxygen for details)
Definition: FileUtils.cc:124
DAS::BTagging::GetDeepJetEdges
vector< double > GetDeepJetEdges(int year, bool HIPM=false)
Definition: getBTagBinnedDiscriminant.cc:34
Ntupliser_cfg.config
config
Definition: Ntupliser_cfg.py:260
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
Darwin::Exceptions::BadInput
Generic exception for ill-defined input (before the event loop).
Definition: exceptions.h:83