ATLAS Offline Software
TopFlavorTaggingCPTools.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
3  */
4 
6 
7 #include <map>
8 #include <string>
9 #include <algorithm>
10 #include <iterator>
11 
12 // Top includes
15 #include "TopEvent/EventTools.h"
16 
17 // PathResolver include(s):
19 
22 
23 namespace top {
25  asg::AsgTool(name) {
26  declareProperty("config", m_config);
27  }
28 
30  ATH_MSG_INFO("top::FlavorTaggingCPTools initialize...");
31 
32  if (m_config->isTruthDxAOD()) {
33  ATH_MSG_INFO("top::FlavorTaggingCPTools: no need to initialise anything on truth DxAOD");
34  return StatusCode::SUCCESS;
35  }
36 
37  if (!m_config->useJets()) {
38  ATH_MSG_INFO("top::FlavorTaggingCPTools: no need to initialise anything since not using jets");
39  return StatusCode::SUCCESS;
40  }
41 
42  // see https://twiki.cern.ch/twiki/bin/viewauth/AtlasProtected/BTagRecommendationsRelease22#Calibration_pre_recommendations
43  static const std::string cdi_file_default_MC20 =
44  "xAODBTaggingEfficiency/13TeV/2023-22-13TeV-MC20-CDI-2023-09-13_v1.root ";
45  static const std::string cdi_file_default_MC21 =
46  "xAODBTaggingEfficiency/13p6TeV/2023-22-13TeV-MC21-CDI-2023-09-13_v1.root";
47 
48  if (m_config->bTaggingCDIPath() != "Default") {
49  if (m_config->isRun3()) {
50  if (m_config->bTaggingCDIPath() != cdi_file_default_MC21) {
51  m_config->setPrintCDIpathWarning(true);
52  }
53  }
54  else {
55  if (m_config->bTaggingCDIPath() != cdi_file_default_MC20) {
56  m_config->setPrintCDIpathWarning(true);
57  }
58  }
59  m_cdi_file = m_config->bTaggingCDIPath();
60  } else {
61  if (m_config->isRun3()) {
62  m_cdi_file = cdi_file_default_MC21;
63  }
64  else {
65  m_cdi_file = cdi_file_default_MC20;
66  }
67  }
68  // This ordering needs to match the indexing in TDP (for missing cases, we use default which gives a MC/MC of 1 as
69  // its the same as the eff used in the calibration
70  // Pythia6;Herwigpp;Pythia8;Sherpa(2.2.1);Sherpa(2.1);aMC@NLO+Pythia8;Herwig7.1.3;Sherpa228;Sherpa2210;Herwigpp721;Sherpa2212;aMC@NLO+Herwig7
71  // based of https://twiki.cern.ch/twiki/bin/view/AtlasProtected/BTagRecommendationsRelease22
72 
73  // Run2
74  m_efficiency_maps = "default;default;410470;410250;default;410464;411233;default;700122;600666;700660;412116";
75  // Run3
76  if (m_config->isRun3()) {
77  m_efficiency_maps = "default;default;601229;doesnotexist;doesnotexist;doesnotexist;601414;doesnotexist;doesnotexist;doesnotexist;700660;doesnotexist";
78  }
79 
80  const std::string caloJets_collection = m_config->sgKeyJets();
81  const std::string trackJets_collection = m_config->sgKeyTrackJets();
82 
84  m_excluded_systs = m_config->bTagSystsExcludedFromEV() == "none" ? "" : m_config->bTagSystsExcludedFromEV();
85 
86  //------------------------------------------------------------
87  // Loop through all the different working points we have and create a
88  // BTaggingSelectionTool and corresponding BTaggingEfficiencyTool if the working point is calibrated.
89  //------------------------------------------------------------
90 
91  // initialize selection tools, for both calibrated and uncalibrated WPs
92  for (const auto& TaggerBtagWP : m_config->bTagAlgoWP()) {
93  top::check(setupBtagSelectionTool(TaggerBtagWP, m_config->sgKeyJets(), m_config->jetPtcut(), m_config->jetEtacut()),
94  "Failed to initialize btag selection tool");
95  }
96  for (const auto& TaggerBtagWP : m_config->bTagAlgoWP_calib()) {
97  top::check(setupBtagEfficiencyTool(TaggerBtagWP, m_config->sgKeyJets(), m_config->jetPtcut()),
98  "Failed to initialize btag selection tool");
99  }
100 
101  if (m_config->useTrackJets()) {
102  for (const auto& TaggerBtagWP : m_config->bTagAlgoWP_trkJet()) {
103  top::check(setupBtagSelectionTool(TaggerBtagWP, m_config->sgKeyTrackJets(), m_config->trackJetPtcut(), m_config->trackJetEtacut(), true),
104  "Failed to initialize btag selection tool");
105  }
106  for (const auto& TaggerBtagWP : m_config->bTagAlgoWP_calib_trkJet()) {
107  top::check(setupBtagEfficiencyTool(TaggerBtagWP, m_config->sgKeyTrackJets(), m_config->trackJetPtcut(), true),
108  "Failed to initialize btag selection tool");
109  }
110  }
111 
112  return StatusCode::SUCCESS;
113  }
114 
115  StatusCode FlavorTaggingCPTools::setupBtagSelectionTool(const std::pair<std::string, std::string>& btag_algo_WP,
116  const std::string& jetCollection,
117  double jetPtCut, double jetEtaCut,
118  bool trackJets) {
119  const std::string bTagWPName = btag_algo_WP.first + "_" + btag_algo_WP.second;
120  //------------------------------------------------------------
121  // Setup BTaggingSelectionTool
122  //------------------------------------------------------------
123  std::string btagsel_tool_name = "BTaggingSelectionTool_" + bTagWPName + "_" + jetCollection;
124  // due to a bug in the CDI files, track jets names are missing PV0 in the name
125  const std::string jetAuthor = (trackJets ? erasePV0fromJetsName(jetCollection) : jetCollection);
126 
127  BTaggingSelectionTool* btagsel = new BTaggingSelectionTool(btagsel_tool_name);
128  top::check(btagsel->setProperty("TaggerName", btag_algo_WP.first),
129  "Failed to set b-tagging selecton tool TaggerName");
130  top::check(btagsel->setProperty("JetAuthor", jetAuthor),
131  "Failed to set b-tagging selection JetAuthor");
132  top::check(btagsel->setProperty("FlvTagCutDefinitionsFileName", m_cdi_file),
133  "Failed to set b-tagging selection tool CDI file");
134  top::check(btagsel->setProperty("OperatingPoint", btag_algo_WP.second),
135  "Failed to set b-tagging selection tool OperatingPoint");
136  top::check(btagsel->setProperty("MinPt", jetPtCut),
137  "Failed to set b-tagging selection tool MinPt");
138  top::check(btagsel->setProperty("MaxEta", jetEtaCut),
139  "Failed to set b-tagging selection tool MaxEta");
140  top::check(btagsel->initialize(),
141  "Failed to initialize b-tagging selection tool: " + btagsel_tool_name);
142  m_btagging_selection_tools.push_back(btagsel);
143 
144  // for each algorithm (DL1r, DL1d, etc...) keep one selection tool instance for creating pb,pc,pu decorations
145  // internally use map to make sure only one tool for each algorithm is stored
146  m_config->addBTagAlgo(btag_algo_WP.first, btagsel_tool_name, trackJets);
147 
148  return StatusCode::SUCCESS;
149  }
150 
151  StatusCode FlavorTaggingCPTools::setupBtagEfficiencyTool(const std::pair<std::string, std::string>& btag_algo_WP,
152  const std::string& jetCollection,
153  double jetPtCut,
154  bool trackJets) {
155  const std::string bTagWPName = btag_algo_WP.first + "_" + btag_algo_WP.second;
156  std::string btageff_tool_name = "BTaggingEfficiencyTool_" + bTagWPName + "_" + jetCollection;
157  // due to a bug in the CDI files, track jets names are missing PV0 in the name
158  const std::string jetAuthor = (trackJets ? erasePV0fromJetsName(jetCollection) : jetCollection);
159 
160  BTaggingEfficiencyTool* btageff = new BTaggingEfficiencyTool(btageff_tool_name);
161  top::check(btageff->setProperty("TaggerName", btag_algo_WP.first),
162  "Failed to set b-tagging TaggerName");
163  top::check(btageff->setProperty("OperatingPoint", btag_algo_WP.second),
164  "Failed to set b-tagging OperatingPoint");
165  top::check(btageff->setProperty("JetAuthor", jetAuthor),
166  "Failed to set b-tagging JetAuthor");
167  top::check(btageff->setProperty("MinPt", jetPtCut),
168  "Failed to set b-tagging selection tool MinPt");
169  top::check(btageff->setProperty("EfficiencyFileName", m_calib_file_path),
170  "Failed to set path to b-tagging CDI file");
171  top::check(btageff->setProperty("ScaleFactorFileName", m_calib_file_path),
172  "Failed to set path to b-tagging CDI file");
173  top::check(btageff->setProperty("ScaleFactorBCalibration", m_config->bTaggingCalibration_B()),
174  "Failed to set b-tagging calibration (B): " + m_config->bTaggingCalibration_B());
175  top::check(btageff->setProperty("ScaleFactorCCalibration", m_config->bTaggingCalibration_C()),
176  "Failed to set b-tagging calibration (C): " + m_config->bTaggingCalibration_C());
177  // using same calibration for T as for C
178  top::check(btageff->setProperty("ScaleFactorTCalibration", m_config->bTaggingCalibration_C()),
179  "Failed to set b-tagging calibration (T): " + m_config->bTaggingCalibration_C());
180  top::check(btageff->setProperty("ScaleFactorLightCalibration", m_config->bTaggingCalibration_Light()),
181  "Failed to set b-tagging calibration (Light): " + m_config->bTaggingCalibration_Light());
182  for (auto jet_flav : m_jet_flavors) {
183  // 09/02/18 IC: The pseudo-continuous does not have MC/MC SF so we need to only apply default for this case
184  // 08/05/18 Francesco La Ruffa: The pseudo-continuous has now its own MC/MC SFs, no needed to set default
185  top::check(btageff->setProperty("Efficiency" + jet_flav + "Calibrations", m_efficiency_maps),
186  "Failed to set " + jet_flav + "-calibrations efficiency maps");
187  }
188  top::check(btageff->setProperty("ExcludeFromEigenVectorTreatment", m_excluded_systs),
189  "Failed to set b-tagging systematics to exclude from EV treatment");
190  top::check(btageff->initialize(), "Failed to initialize " + bTagWPName);
191  // Check the excludedSysts - Cannot check before the tool is initialised
192  if (this->checkExcludedSysts(btageff, m_excluded_systs) != StatusCode::SUCCESS) {
193  ATH_MSG_WARNING("Incorrect excluded systematics have been provided.");
194  }
195  m_btagging_efficiency_tools.push_back(btageff);
196  return StatusCode::SUCCESS;
197  }
198 
200  const std::string pv0 = "PV0";
201  auto it = jetCollectionName.find(pv0);
202  if (it == std::string::npos) return jetCollectionName;
203  jetCollectionName.erase(it, pv0.length());
204  return jetCollectionName;
205  }
206 
207  StatusCode FlavorTaggingCPTools::checkExcludedSysts(BTaggingEfficiencyTool* btageff, const std::string& excludedSysts) {
208  // We pass the pointer to the btagging efficiency tool which is being created and also the excludedSysts string
209  // which will be used
210  // If the string is empty, then nothing to check
211  if (excludedSysts == "") return StatusCode::SUCCESS;
212 
213  // Split by a semi-colon delimiter and then check the individual syst strings against the list from the CDI
214  std::vector<std::string> listOfExcludedSysts;
215  top::tokenize(excludedSysts, listOfExcludedSysts, ";");
216  ATH_MSG_INFO(" ------------------------------------------------ ");
217  ATH_MSG_INFO(" ------------- EXPERIMENTAL FEATURE ------------- ");
218  ATH_MSG_INFO(" ------ Please provide feedback to TopReco ------ ");
219  ATH_MSG_INFO(" ------------- EXPERIMENTAL FEATURE ------------- ");
220  ATH_MSG_INFO(" ------------------------------------------------ ");
221  ATH_MSG_INFO(" AnalysisTop - Checking excludedSysts for flavour tagging EV");
222  ATH_MSG_INFO(" This has been split on the semi-colon delimiter to find...");
223  for (const auto& s : listOfExcludedSysts) ATH_MSG_INFO("... " + s);
224  // Get the map(string, vector<string>) from the CDI tool
225  // Don't care about the flavours (this will be handled in the CDI)
226  std::vector<std::string> listOfScaleFactorSystematics;
227  for (auto flavour : btageff->listScaleFactorSystematics(false)) {
228  for (auto sys : flavour.second) {
229  listOfScaleFactorSystematics.push_back(sys);
230  }
231  }
232  // Make this a unique set and then we need to check that all systematics provided by the user are expected by the
233  // CDI
234  std::set<std::string> setOfExcludedSysts, setOfScaleFactorSystematics;
235 
236  for (auto sys : listOfExcludedSysts) {
237  setOfExcludedSysts.insert(sys);
238  }
239 
240  for (auto sys : listOfScaleFactorSystematics) {
241  setOfScaleFactorSystematics.insert(sys);
242  }
243 
244  //
245  std::vector<std::string> unionOfSystematics;
246  std::set_intersection(setOfExcludedSysts.begin(), setOfExcludedSysts.end(),
247  setOfScaleFactorSystematics.begin(), setOfScaleFactorSystematics.end(),
248  std::back_inserter(unionOfSystematics));
249  // Check we have the same systematics listed in unionOfSystematics
250  if (unionOfSystematics.size() != listOfExcludedSysts.size()) {
251  ATH_MSG_WARNING("Have not found all systematics listed to be excluded from b-tagging eigenvector method");
252  ATH_MSG_INFO("Permitted values are...");
253  for (const auto& sys : setOfScaleFactorSystematics) {
254  ATH_MSG_INFO(" ... " + sys);
255  }
256  return StatusCode::FAILURE;
257  } else {
258  ATH_MSG_INFO(" Summary of EV impact ");
259  for (const auto& sysRemove : listOfExcludedSysts) {
260  std::string flavourAffected = "";
261  for (auto flavour : btageff->listScaleFactorSystematics(false)) {
262  for (auto sysCDI : flavour.second) {
263  if (sysRemove == sysCDI) flavourAffected += flavour.first;
264  }
265  }
266  ATH_MSG_INFO(" ... " + sysRemove + " -> Removed from calibration(s) : [" + flavourAffected + "]");
267  }
268  ATH_MSG_INFO(" These will be dynamically matched to systematic tree names (if available)");
269  ATH_MSG_INFO(" All systematics are accepted by CDI file ");
270  }
271  // We have passed all the tests so now we store the systematics removed from the EV method and use a mapping to
272  // ASG/AT naming and return
273  ATH_MSG_INFO(" ------------------------------------------------ ");
274  return StatusCode::SUCCESS;
275  }
276 
277 
278 } // namespace top
python.SystemOfUnits.s
int s
Definition: SystemOfUnits.py:131
BTaggingEfficiencyTool
Definition: BTaggingEfficiencyTool.h:33
BTaggingSelectionTool::initialize
StatusCode initialize() override
Dummy implementation of the initialisation function.
Definition: BTaggingSelectionTool.cxx:59
top
TopConfig A simple configuration that is NOT a singleton.
Definition: AnalysisTrackingHelper.cxx:58
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
top::FlavorTaggingCPTools::m_excluded_systs
std::string m_excluded_systs
Definition: TopFlavorTaggingCPTools.h:40
AthCommonDataStore< AthCommonMsg< AlgTool > >::declareProperty
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T > &t)
Definition: AthCommonDataStore.h:145
BTaggingEfficiencyTool.h
top::FlavorTaggingCPTools::m_btagging_selection_tools
ToolHandleArray< IBTaggingSelectionTool > m_btagging_selection_tools
Definition: TopFlavorTaggingCPTools.h:47
top::tokenize
void tokenize(const std::string &input, Container &output, const std::string &delimiters=" ", bool trim_empty=false)
Tokenize an input string using a set of delimiters.
Definition: Tokenize.h:24
skel.it
it
Definition: skel.GENtoEVGEN.py:423
asg
Definition: DataHandleTestTool.h:28
top::FlavorTaggingCPTools::m_cdi_file
std::string m_cdi_file
Definition: TopFlavorTaggingCPTools.h:38
top::FlavorTaggingCPTools::setupBtagEfficiencyTool
StatusCode setupBtagEfficiencyTool(const std::pair< std::string, std::string > &btag_algo_WP, const std::string &jetCollection, double jetPtCut, bool trackJets=false)
Definition: TopFlavorTaggingCPTools.cxx:151
top::FlavorTaggingCPTools::checkExcludedSysts
StatusCode checkExcludedSysts(BTaggingEfficiencyTool *, const std::string &)
Definition: TopFlavorTaggingCPTools.cxx:207
mapkey::sys
@ sys
Definition: TElectronEfficiencyCorrectionTool.cxx:42
EventTools.h
A few functions for doing operations on particles / events. Currently holds code for dR,...
BTaggingEfficiencyTool::initialize
StatusCode initialize()
Initialise the tool.
Definition: BTaggingEfficiencyTool.cxx:213
top::FlavorTaggingCPTools::m_calib_file_path
std::string m_calib_file_path
Definition: TopFlavorTaggingCPTools.h:39
top::FlavorTaggingCPTools::m_jet_flavors
const std::vector< std::string > m_jet_flavors
Definition: TopFlavorTaggingCPTools.h:42
BTaggingSelectionTool
Definition: BTaggingSelectionTool.h:25
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
BTaggingSelectionTool.h
BTaggingEfficiencyTool::listScaleFactorSystematics
std::map< std::string, std::vector< std::string > > listScaleFactorSystematics(bool named=false) const
This merely passes on the request to the underlying CDI object (listSystematics() cannot be used here...
Definition: BTaggingEfficiencyTool.cxx:1192
top::check
void check(bool thingToCheck, const std::string &usefulFailureMessage)
Print an error message and terminate if thingToCheck is false.
Definition: EventTools.cxx:15
top::FlavorTaggingCPTools::m_btagging_efficiency_tools
ToolHandleArray< IBTaggingEfficiencyTool > m_btagging_efficiency_tools
Definition: TopFlavorTaggingCPTools.h:46
top::FlavorTaggingCPTools::erasePV0fromJetsName
std::string erasePV0fromJetsName(std::string jetCollectionName)
Definition: TopFlavorTaggingCPTools.cxx:199
PathResolver.h
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:192
TopConfig.h
PathResolverFindCalibFile
std::string PathResolverFindCalibFile(const std::string &logical_file_name)
Definition: PathResolver.cxx:431
TopFlavorTaggingCPTools.h
top::FlavorTaggingCPTools::m_config
std::shared_ptr< top::TopConfig > m_config
Definition: TopFlavorTaggingCPTools.h:37
top::FlavorTaggingCPTools::FlavorTaggingCPTools
FlavorTaggingCPTools(const std::string &name)
Definition: TopFlavorTaggingCPTools.cxx:24
PhysDESDM_VH_DV.jetCollectionName
jetCollectionName
Definition: PhysDESDM_VH_DV.py:50
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
Tokenize.h
top::FlavorTaggingCPTools::m_efficiency_maps
std::string m_efficiency_maps
Definition: TopFlavorTaggingCPTools.h:41
set_intersection
Set * set_intersection(Set *set1, Set *set2)
Perform an intersection of two sets.
top::FlavorTaggingCPTools::initialize
StatusCode initialize()
Dummy implementation of the initialisation function.
Definition: TopFlavorTaggingCPTools.cxx:29
top::FlavorTaggingCPTools::setupBtagSelectionTool
StatusCode setupBtagSelectionTool(const std::pair< std::string, std::string > &btag_algo_WP, const std::string &jetCollection, double jetPtCut, double jetEtaCut, bool trackJets=false)
Setup BTaggingSelectionTool for a given WP.
Definition: TopFlavorTaggingCPTools.cxx:115