ATLAS Offline Software
TopTauCPTools.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 
7 // Top includes
9 #include "TopEvent/EventTools.h"
10 
11 // PathResolver include(s):
13 
14 // Tau include(s):
19 #include "TauAnalysisTools/Enums.h"
20 
21 // c++ includes
22 #include <map>
23 #include <memory>
24 #include <string>
25 
26 namespace top {
27  TauCPTools::TauCPTools(const std::string& name) :
28  asg::AsgTool(name),
29  m_pileupReweightingTool("PileupReweightingTool") {
30  declareProperty("config", m_config);
31 
32  declareProperty("TauSmearingTool", m_tauSmearingTool);
33  declareProperty("TauTruthMatchingTool", m_truthMatchingTool);
34  }
35 
37  ATH_MSG_INFO("top::TauCPTools initialize...");
38 
39  if (m_config->isTruthDxAOD()) {
40  ATH_MSG_INFO("top::TauCPTools: no need to initialise anything on truth DxAOD");
41  return StatusCode::SUCCESS;
42  }
43 
44  if (!m_config->useTaus()) {
45  ATH_MSG_INFO("top::TauCPTools: no need to initialise anything since not using taus");
46  return StatusCode::SUCCESS;
47  }
48 
49  if (m_config->makeAllCPTools()) {// skiping calibrations on mini-xAODs
50  top::check(setupCalibration(), "Failed to setup Tau calibration tools");
51  }
52  if (m_config->isMC()) {// scale-factors are only for MC
53  top::check(setupScaleFactors(), "Failed to setup Tau scale-factor tools");
54  }
55  return StatusCode::SUCCESS;
56  }
57 
59  /************************************************************
60  *
61  * Setup the tools needed for Tau Analysis
62  * ----------------------------------------
63  *
64  * TauSelectionTool:
65  * to select taus
66  * TauEfficiencyCorrectionTool:
67  * to apply efficiency corrections
68  * (this is setup with the selection tool)
69  * TauSmearingTool:
70  * to calibrate and smear taus
71  *
72  ************************************************************/
73 
74  //============================================================
75  // Convert tau jet IDWP string to int
76  // Updated: using enums from TauAnalysisTools package
77  //============================================================
78 
79  auto tau_JetIDWP_to_enum = [](const std::string& s) {
80  if (s == "None") return TauAnalysisTools::JETIDNONE;
81  if (s == "RNNLoose") return TauAnalysisTools::JETIDRNNLOOSE;
82  if (s == "RNNMedium") return TauAnalysisTools::JETIDRNNMEDIUM;
83  if (s == "RNNTight") return TauAnalysisTools::JETIDRNNTIGHT;
84  // If we haven't found the correct WP, then return 0
86  };
87 
88  // convert taujetIDWP from string to int and check it's valid
89  const int tauJetIDWP = tau_JetIDWP_to_enum(m_config->tauJetIDWP());
90 
91  top::check(tauJetIDWP > 0, m_config->tauJetIDWP() + " is not a supported tau Jet ID WP");
92 
93  // convert taujetIDWPLoose from string to int and check it's valid
94  const int tauJetIDWPLoose = tau_JetIDWP_to_enum(m_config->tauJetIDWPLoose());
95  top::check(tauJetIDWPLoose > 0, m_config->tauJetIDWPLoose() + " is not a supported tau Jet ID WP");
96 
97  auto tau_EleIDWP_to_enum = [](const std::string& s) {
98  if (s == "None") return TauAnalysisTools::ELEIDNONE;
99  if (s == "RNNLoose") return TauAnalysisTools::ELEIDRNNLOOSE;
100  if (s == "RNNMedium") return TauAnalysisTools::ELEIDRNNMEDIUM;
101  if (s == "RNNTight") return TauAnalysisTools::ELEIDRNNTIGHT;
102  // If we haven't found the correct WP, then return 0
104  };
105 
106  // convert tauEleIDWP from string to int and check it's valid
107  const int tauEleIDWP = tau_EleIDWP_to_enum(m_config->tauEleIDWP());
108  top::check(tauEleIDWP > 0, m_config->tauEleIDWP() + " is not a supported tau electron ID WP");
109 
110  // convert tauEleIDWPLoose from string to int and check it's valid
111  const int tauEleIDWPLoose = tau_EleIDWP_to_enum(m_config->tauEleIDWPLoose());
112  top::check(tauEleIDWPLoose > 0, m_config->tauEleIDWPLoose() + " is not a supported tau electron ID WP");
113 
114  const double absCharge = 1.;
115  const std::vector<size_t> nTracks = {
116  1, 3
117  };
118 
119  //============================================================
120  // PathResolve tau config files. If set to default then
121  // set to empty string.
122  //============================================================
123 
124  std::string tauJetConfigFile = m_config->tauJetConfigFile();
125  if (tauJetConfigFile != "Default")
126  tauJetConfigFile = PathResolverFindCalibFile(tauJetConfigFile);
127  else
128  tauJetConfigFile.clear();
129  std::string tauJetConfigFileLoose = m_config->tauJetConfigFileLoose();
130  if (tauJetConfigFileLoose != "Default")
131  tauJetConfigFileLoose = PathResolverFindCalibFile(tauJetConfigFileLoose);
132  else
133  tauJetConfigFileLoose.clear();
134 
135  // bitmap in case not using the config files
136  //WARNING: if we add more configurable cuts, they need to be added in this list
137  // a priori we alway apply these cuts below
138  int iSelectionCuts = 0;
139  iSelectionCuts |= TauAnalysisTools::CutPt;
140  iSelectionCuts |= TauAnalysisTools::CutAbsEta;
141  iSelectionCuts |= TauAnalysisTools::CutAbsCharge;
142  iSelectionCuts |= TauAnalysisTools::CutNTrack;
143  iSelectionCuts |= TauAnalysisTools::CutJetIDWP;
144  iSelectionCuts |= TauAnalysisTools::CutEleIDWP;
145 
146  int iSelectionCutsLoose = iSelectionCuts;
147 
148  //============================================================
149  // Nominal Tau Selection
150  //============================================================
151 
152 
153  // Alias long tool names
154  using ITauSelTool = TauAnalysisTools::ITauSelectionTool;
155  using ITauEffCorrTool = TauAnalysisTools::ITauEfficiencyCorrectionsTool;
156  using ITauSmearTool = TauAnalysisTools::ITauSmearingTool;
157  using ITauTruthMatchTool = TauAnalysisTools::ITauTruthMatchingTool;
158  using TauSelTool = TauAnalysisTools::TauSelectionTool;
159  using TauEffCorrTool = TauAnalysisTools::TauEfficiencyCorrectionsTool;
160  using TauSmearTool = TauAnalysisTools::TauSmearingTool;
161  using TauTruthMatchTool = TauAnalysisTools::TauTruthMatchingTool;
162 
163  // Names of tools here for a little clarity
164  const std::string tauSelName = "TauAnalysisTools::TauSelectionTool";
165  const std::string tauEffCorrName = "TauAnalysisTools::TauEfficiencyCorrectionsTool";
166 
168  if (asg::ToolStore::contains<ITauSelTool>(tauSelName)) {
169  m_tauSelectionTool = asg::ToolStore::get<ITauSelTool>(tauSelName);
170  } else {
171  std::unique_ptr<ITauSelTool> tauSelectionTool = std::make_unique<TauAnalysisTools::TauSelectionTool>(tauSelName);
172  if (!tauJetConfigFile.empty()) {
173  top::check(asg::setProperty(tauSelectionTool, "ConfigPath", tauJetConfigFile),
174  "Failed to set tau selection tool configuration path");
175  top::check(asg::setProperty(tauSelectionTool, "OutputLevel", MSG::INFO),
176  "Failed to set tau OutputLevel");
177  } else {
178  // set the ConfigPath to empty value is no file was provided (otherwise it creates conflicts)
179  top::check(asg::setProperty(tauSelectionTool, "ConfigPath", ""),
180  "Failed to set tau selection tool configuration path");
181  top::check(asg::setProperty(tauSelectionTool, "OutputLevel", MSG::INFO),
182  "Failed to set tau OutputLevel");
183  //WARNING: if we add more configurable cuts, they need to be added in the iSelectionCuts (see above)
184  top::check(asg::setProperty(tauSelectionTool, "SelectionCuts", iSelectionCuts),
185  "Failed to set tau SelectionCuts");
186  top::check(asg::setProperty(tauSelectionTool, "PtMin", static_cast<double>(m_config->tauPtcut() / 1e3)),
187  "Failed to set tau pT cut");
188  top::check(asg::setProperty(tauSelectionTool, "AbsEtaRegion", m_config->tauEtaRegions() ),
189  "Failed to set tau AbsEtaRegion");
190  top::check(asg::setProperty(tauSelectionTool, "AbsCharge", absCharge),
191  "Failed to set tau AbsCharge");
192  top::check(asg::setProperty(tauSelectionTool, "NTracks", nTracks),
193  "Failed to set tau NTracks");
194  top::check(asg::setProperty(tauSelectionTool, "JetIDWP", tauJetIDWP),
195  "Failed to set tau JetIDWP");
196  top::check(asg::setProperty(tauSelectionTool, "EleIDWP", tauEleIDWP),
197  "Failed to set tau EleIDWP");
198  top::check(asg::setProperty(tauSelectionTool, "MuonOLR", m_config->tauMuOLR()),
199  "Failed to set tau MuonOLR");
200  }
201  top::check(tauSelectionTool->initialize(), "Failed to initialize tauSelectionTool");
202  m_tauSelectionTool = tauSelectionTool.release();
203 
205  if (asg::ToolStore::contains<ITauEffCorrTool>(tauEffCorrName)) {
206  m_tauEffCorrTool = asg::ToolStore::get<ITauEffCorrTool>(tauEffCorrName);
207  } else {
208  std::unique_ptr<ITauEffCorrTool> tauEffCorrTool
209  = std::make_unique<TauAnalysisTools::TauEfficiencyCorrectionsTool>(tauEffCorrName);
210  if (m_config->isMC()) {
211 
212  if(!m_config->isDataOverlay()){
213  top::check(m_pileupReweightingTool.retrieve(), "Failed to retireve pileup reweighting tool");
214  top::check(asg::setProperty(tauEffCorrTool, "PileupReweightingTool", m_pileupReweightingTool),
215  "Failed to set PileupReweightingTool for " + tauEffCorrName);
216  }
217 
218  top::check(asg::setProperty(tauEffCorrTool, "UseTauSubstructure", m_config->tauSubstructureSF()),
219  "Failed to set UseTauSubstructure for " + tauEffCorrName);
220 
221  top::check(asg::setProperty(tauEffCorrTool, "isAFII", m_config->isAFII()),
222  "Failed to set isAFII for " + tauEffCorrName);
223  }
224 
225  top::check(asg::setProperty(tauEffCorrTool, "TauSelectionTool", m_tauSelectionTool),
226  "Failed to set TauSelectionTool for " + tauEffCorrName);
227 
228  top::check(tauEffCorrTool->initialize(), "Failed to initialize");
229  m_tauEffCorrTool = tauEffCorrTool.release();
230  }
231  }
232 
233  //============================================================
234  // 'Loose' Tau Selection
235  //============================================================
236 
238  const std::string tauSelNameLoose = "TauAnalysisTools::TauSelectionToolLoose";
239  const std::string tauEffCorrNameLoose = "TauAnalysisTools::TauEfficiencyCorrectionsToolLoose";
240 
242  if (asg::ToolStore::contains<ITauSelTool>(tauSelNameLoose)) {
243  m_tauSelectionToolLoose = asg::ToolStore::get<ITauSelTool>(tauSelNameLoose);
244  } else {
245  std::unique_ptr<ITauSelTool> tauSelectionTool = std::make_unique<TauSelTool>(tauSelNameLoose);
246  if (!tauJetConfigFileLoose.empty()) {
247  top::check(asg::setProperty(tauSelectionTool, "ConfigPath", tauJetConfigFileLoose),
248  "Failed to set tau selection tool configuration path");
249  top::check(asg::setProperty(tauSelectionTool, "OutputLevel", MSG::INFO),
250  "Failed to set tau OutputLevel");
251  } else {
252  // set the ConfigPath to empty value is no file was provided (otherwise it creates conflicts)
253  top::check(asg::setProperty(tauSelectionTool, "ConfigPath", ""),
254  "Failed to set tau selection tool configuration path");
255  top::check(asg::setProperty(tauSelectionTool, "OutputLevel", MSG::INFO),
256  "Failed to set tau OutputLevel");
257  //WARNING: if we add more configurable cuts, they need to be added in the iSelectionCuts (see above)
258  top::check(asg::setProperty(tauSelectionTool, "SelectionCuts", iSelectionCutsLoose),
259  "Failed to set tau SelectionCuts");
260  top::check(asg::setProperty(tauSelectionTool, "PtMin", static_cast<double>(m_config->tauPtcut() / 1e3)),
261  "Failed to set tau pT cut");
262  top::check(asg::setProperty(tauSelectionTool, "AbsEtaRegion", m_config->tauEtaRegions()),
263  "Failed to set loose tau AbsEtaRegion");
264  top::check(asg::setProperty(tauSelectionTool, "AbsCharge", absCharge),
265  "Failed to set loose tau AbsCharge");
266  top::check(asg::setProperty(tauSelectionTool, "NTracks", nTracks),
267  "Failed to set loose tau NTracks");
268  top::check(asg::setProperty(tauSelectionTool, "JetIDWP", tauJetIDWPLoose),
269  "Failed to set loose tau JetIDWP");
270  top::check(asg::setProperty(tauSelectionTool, "EleIDWP", tauEleIDWPLoose),
271  "Failed to set loose tau EleIDWP");
272  top::check(asg::setProperty(tauSelectionTool, "MuonOLR", m_config->tauMuOLRLoose()),
273  "Failed to set tau MuonOLR");
274  }
275  top::check(tauSelectionTool->initialize(), "Failed to initialize tauSelectionTool");
276  m_tauSelectionToolLoose = tauSelectionTool.release();
277 
279  if (asg::ToolStore::contains<ITauEffCorrTool>(tauEffCorrNameLoose)) {
280  m_tauEffCorrTool = asg::ToolStore::get<ITauEffCorrTool>(tauEffCorrNameLoose);
281  } else {
282  std::unique_ptr<ITauEffCorrTool> tauEffCorrTool
283  = std::make_unique<TauEffCorrTool>(tauEffCorrNameLoose);
284  if (m_config->isMC()) {
285 
286  if(!m_config->isDataOverlay()) {
287  top::check(m_pileupReweightingTool.retrieve(), "Failed to retireve pileup reweighting tool");
288  top::check(asg::setProperty(tauEffCorrTool, "PileupReweightingTool", m_pileupReweightingTool),
289  "Failed to set PileupReweightingTool for " + tauEffCorrNameLoose);
290  }
291 
292  top::check(asg::setProperty(tauEffCorrTool, "UseTauSubstructure", m_config->tauSubstructureSFLoose()),
293  "Failed to set UseTauSubstructure for " + tauEffCorrNameLoose);
294 
295  top::check(asg::setProperty(tauEffCorrTool, "isAFII", m_config->isAFII()),
296  "Failed to set isAFII for " + tauEffCorrNameLoose);
297  }
298 
299  top::check(asg::setProperty(tauEffCorrTool, "TauSelectionTool", m_tauSelectionToolLoose),
300  "Failed to set TauSelectionTool for " + tauEffCorrNameLoose);
301 
302  top::check(tauEffCorrTool->initialize(), "Failed to initialize");
303  m_tauEffCorrToolLoose = tauEffCorrTool.release();
304  }
305  }
306 
308  static const std::string tauSmearName = "TauSmearingTool";
309  if (asg::ToolStore::contains<ITauSmearTool>(tauSmearName)) {
310  m_tauSmearingTool = asg::ToolStore::get<ITauSmearTool>(tauSmearName);
311  } else {
312  std::unique_ptr<TauSmearTool> tauSmearingTool = std::make_unique<TauSmearTool>(tauSmearName);
313  top::check(asg::setProperty(tauSmearingTool, "isAFII", m_config->isAFII()),
314  "Failed to set TauSmearingTools isAFII property");
315  top::check(tauSmearingTool->initialize(), "Failed to initialize");
316  m_tauSmearingTool = tauSmearingTool.release();
317  }
318 
320  if (m_config->isMC()) {
321  static const std::string tauTruthMatchingName = "TauAnalysisTools::TauTruthMatchingTool";
322  if (asg::ToolStore::contains<ITauTruthMatchTool>(tauTruthMatchingName)) {
323  m_truthMatchingTool = asg::ToolStore::get<ITauTruthMatchTool>(tauTruthMatchingName);
324  } else {
325  std::unique_ptr<TauTruthMatchTool> tauMatchingTool = std::make_unique<TauTruthMatchTool>(tauTruthMatchingName);
326  top::check(tauMatchingTool->setProperty("TruthJetContainerName", "AntiKt4TruthDressedWZJets"), "Failed to set truth collection for tau truth matching tool");
327  top::check(tauMatchingTool->initialize(), "Failed to initialize");
328  m_truthMatchingTool = tauMatchingTool.release();
329  }
330  }
331 
332 
333  return StatusCode::SUCCESS;
334  }
335 
344  return StatusCode::SUCCESS;
345  }
346 } // namespace top
top::TauCPTools::m_tauSelectionToolLoose
ToolHandle< TauAnalysisTools::ITauSelectionTool > m_tauSelectionToolLoose
Definition: TopTauCPTools.h:43
TauAnalysisTools::CutAbsEta
@ CutAbsEta
Definition: PhysicsAnalysis/TauID/TauAnalysisTools/TauAnalysisTools/Enums.h:43
TauAnalysisTools::ITauSmearingTool
Definition: ITauSmearingTool.h:30
TauTruthMatchingTool.h
python.SystemOfUnits.s
int s
Definition: SystemOfUnits.py:131
Enums.h
TauAnalysisTools::ELEIDNONEUNCONFIGURED
@ ELEIDNONEUNCONFIGURED
Definition: PhysicsAnalysis/TauID/TauAnalysisTools/TauAnalysisTools/Enums.h:31
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::TauCPTools::m_tauSelectionTool
ToolHandle< TauAnalysisTools::ITauSelectionTool > m_tauSelectionTool
Definition: TopTauCPTools.h:39
TauAnalysisTools::JETIDRNNTIGHT
@ JETIDRNNTIGHT
Definition: PhysicsAnalysis/TauID/TauAnalysisTools/TauAnalysisTools/Enums.h:22
TauAnalysisTools::TauSelectionTool
Definition: TauSelectionTool.h:53
AthCommonDataStore< AthCommonMsg< AlgTool > >::declareProperty
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T > &t)
Definition: AthCommonDataStore.h:145
TauAnalysisTools::JETIDRNNMEDIUM
@ JETIDRNNMEDIUM
Definition: PhysicsAnalysis/TauID/TauAnalysisTools/TauAnalysisTools/Enums.h:21
top::TauCPTools::m_tauSmearingTool
ToolHandle< TauAnalysisTools::ITauSmearingTool > m_tauSmearingTool
Definition: TopTauCPTools.h:46
top::TauCPTools::m_config
std::shared_ptr< top::TopConfig > m_config
Definition: TopTauCPTools.h:37
top::TauCPTools::setupScaleFactors
StatusCode setupScaleFactors()
Definition: TopTauCPTools.cxx:336
asg
Definition: DataHandleTestTool.h:28
top::TauCPTools::TauCPTools
TauCPTools(const std::string &name)
Definition: TopTauCPTools.cxx:27
TauAnalysisTools::JETIDRNNLOOSE
@ JETIDRNNLOOSE
Definition: PhysicsAnalysis/TauID/TauAnalysisTools/TauAnalysisTools/Enums.h:20
TauAnalysisTools::JETIDNONE
@ JETIDNONE
Definition: PhysicsAnalysis/TauID/TauAnalysisTools/TauAnalysisTools/Enums.h:14
TauAnalysisTools::CutJetIDWP
@ CutJetIDWP
Definition: PhysicsAnalysis/TauID/TauAnalysisTools/TauAnalysisTools/Enums.h:47
TauAnalysisTools::ITauSelectionTool
Interface for tau selector tool.
Definition: ITauSelectionTool.h:33
EventTools.h
A few functions for doing operations on particles / events. Currently holds code for dR,...
TauAnalysisTools::ELEIDRNNLOOSE
@ ELEIDRNNLOOSE
Definition: PhysicsAnalysis/TauID/TauAnalysisTools/TauAnalysisTools/Enums.h:33
top::TauCPTools::m_truthMatchingTool
ToolHandle< TauAnalysisTools::ITauTruthMatchingTool > m_truthMatchingTool
Definition: TopTauCPTools.h:47
CheckAppliedSFs.e3
e3
Definition: CheckAppliedSFs.py:264
TauEfficiencyCorrectionsTool.h
TauAnalysisTools::ELEIDNONE
@ ELEIDNONE
Definition: PhysicsAnalysis/TauID/TauAnalysisTools/TauAnalysisTools/Enums.h:32
TauSmearingTool.h
TauAnalysisTools::TauSmearingTool
Definition: TauSmearingTool.h:32
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
TauAnalysisTools::TauEfficiencyCorrectionsTool
Definition: TauEfficiencyCorrectionsTool.h:34
top::TauCPTools::m_tauEffCorrToolLoose
ToolHandle< TauAnalysisTools::ITauEfficiencyCorrectionsTool > m_tauEffCorrToolLoose
Definition: TopTauCPTools.h:44
TauAnalysisTools::ITauTruthMatchingTool
Definition: ITauTruthMatchingTool.h:33
top::check
void check(bool thingToCheck, const std::string &usefulFailureMessage)
Print an error message and terminate if thingToCheck is false.
Definition: EventTools.cxx:15
TauAnalysisTools::TauTruthMatchingTool
Definition: TauTruthMatchingTool.h:25
TopTauCPTools.h
TauAnalysisTools::ELEIDRNNMEDIUM
@ ELEIDRNNMEDIUM
Definition: PhysicsAnalysis/TauID/TauAnalysisTools/TauAnalysisTools/Enums.h:34
PathResolver.h
TauAnalysisTools::CutNTrack
@ CutNTrack
Definition: PhysicsAnalysis/TauID/TauAnalysisTools/TauAnalysisTools/Enums.h:45
TauAnalysisTools::ELEIDRNNTIGHT
@ ELEIDRNNTIGHT
Definition: PhysicsAnalysis/TauID/TauAnalysisTools/TauAnalysisTools/Enums.h:35
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:192
TauSelectionTool.h
TopConfig.h
top::TauCPTools::setupCalibration
StatusCode setupCalibration()
Definition: TopTauCPTools.cxx:58
TauAnalysisTools::CutEleIDWP
@ CutEleIDWP
Definition: PhysicsAnalysis/TauID/TauAnalysisTools/TauAnalysisTools/Enums.h:49
PathResolverFindCalibFile
std::string PathResolverFindCalibFile(const std::string &logical_file_name)
Definition: PathResolver.cxx:431
TauAnalysisTools::CutAbsCharge
@ CutAbsCharge
Definition: PhysicsAnalysis/TauID/TauAnalysisTools/TauAnalysisTools/Enums.h:46
top::TauCPTools::m_pileupReweightingTool
ToolHandle< CP::IPileupReweightingTool > m_pileupReweightingTool
Definition: TopTauCPTools.h:41
top::TauCPTools::m_tauEffCorrTool
ToolHandle< TauAnalysisTools::ITauEfficiencyCorrectionsTool > m_tauEffCorrTool
Definition: TopTauCPTools.h:40
TauAnalysisTools::CutPt
@ CutPt
Definition: PhysicsAnalysis/TauID/TauAnalysisTools/TauAnalysisTools/Enums.h:42
TauAnalysisTools::JETIDNONEUNCONFIGURED
@ JETIDNONEUNCONFIGURED
Definition: PhysicsAnalysis/TauID/TauAnalysisTools/TauAnalysisTools/Enums.h:13
TauAnalysisTools::ITauEfficiencyCorrectionsTool
Definition: ITauEfficiencyCorrectionsTool.h:31
top::TauCPTools::initialize
StatusCode initialize()
Dummy implementation of the initialisation function.
Definition: TopTauCPTools.cxx:36