ATLAS Offline Software
Loading...
Searching...
No Matches
CalibrationDataInterfaceTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4
6// CalibrationDataInterfaceTool.cxx, (c) ATLAS Detector software
8
12#include "JetEvent/Jet.h"
13
14#include "TF1.h"
15
16#include <map>
17
21
22using std::cerr;
23using std::endl;
24using std::string;
25
26//================ Constructor =================================================
27
29 const string& n,
30 const IInterface* p ) :
31 AthAlgTool(t,n,p),
32 m_broker("PerformanceBroker")
33{
34 declareProperty("taggerName", m_taggerName = "undefined",
35 "tagging algorithm name");
36 declareProperty("operatingPoints", m_operatingPoints,
37 "operating points for this tagging algorithm");
38 declareProperty("efficiencyCalibrationBName", m_EffcalibrationBName = "default",
39 "efficiency calibration curve for b jets");
40 declareProperty("efficiencyCalibrationCName", m_EffcalibrationCName = "default",
41 "efficiency calibration curve for c jets");
42 declareProperty("efficiencyCalibrationTName", m_EffcalibrationTName = "default",
43 "efficiency calibration curve for tau jets");
44 declareProperty("efficiencyCalibrationLightName", m_EffcalibrationLightName = "default",
45 "efficiency calibration curve for light-flavour jets");
46 declareProperty("scaleFactorCalibrationBName", m_SFcalibrationBName = "default",
47 "scale factor calibration curve for b jets");
48 declareProperty("scaleFactorCalibrationCName", m_SFcalibrationCName = "default",
49 "scale factor calibration curve for c jets");
50 declareProperty("scaleFactorCalibrationTName", m_SFcalibrationTName = "default",
51 "scale factor calibration curve for tau jets");
52 declareProperty("scaleFactorCalibrationLightName", m_SFcalibrationLightName = "default",
53 "scale factor calibration curve for light-flavour jets");
54 declareProperty("PerformanceBroker", m_broker,
55 "tool interfacing with COOL Database");
56}
57
58
60{
61
62// StatusCode sc = AthAlgTool::initialize();
63// if (sc.isFailure()) return sc;
64//
65// sc = m_broker.retrieve();
66// if (sc.isFailure()) {
67// ATH_MSG_FATAL("initialize() in " << name() << ": unable to retrieve CalibrationBroker tool!");
68// return sc;
69// }
70
71 string::size_type end;
72
73 std::vector<string> calibrationBNames;
74 if (m_EffcalibrationBName.size() > 0) {
75 do {
76 end = m_EffcalibrationBName.find(";");
77 calibrationBNames.push_back(m_EffcalibrationBName.substr(0,end));
78 if (end != string::npos) m_EffcalibrationBName = m_EffcalibrationBName.substr(end+1);
79 } while (end != string::npos);
80 }
81
82 std::vector<string> calibrationCNames;
83 if (m_EffcalibrationCName.size() > 0) {
84 do {
85 end = m_EffcalibrationCName.find(";");
86 calibrationCNames.push_back(m_EffcalibrationCName.substr(0,end));
87 if (end != string::npos) m_EffcalibrationCName = m_EffcalibrationCName.substr(end+1);
88 } while (end != string::npos);
89 }
90
91 std::vector<string> calibrationTNames;
92 if (m_EffcalibrationTName.size() > 0) {
93 do {
94 end = m_EffcalibrationTName.find(";");
95 calibrationTNames.push_back(m_EffcalibrationTName.substr(0,end));
96 if (end != string::npos) m_EffcalibrationTName = m_EffcalibrationTName.substr(end+1);
97 } while (end != string::npos);
98 }
99
100 std::vector<string> calibrationLightNames;
101 if (m_EffcalibrationLightName.size() > 0) {
102 do {
103 end = m_EffcalibrationLightName.find(";");
104 calibrationLightNames.push_back(m_EffcalibrationLightName.substr(0,end));
105 if (end != string::npos) m_EffcalibrationLightName = m_EffcalibrationLightName.substr(end+1);
106 } while (end != string::npos);
107 }
108
109
110 // insert the calibration names into a common object
111 std::map<string, std::vector<string> > effNames;
112 effNames["B"] = calibrationBNames;
113 effNames["C"] = calibrationCNames;
114 effNames["T"] = calibrationTNames;
115 effNames["Light"] = calibrationLightNames;
116 setEffCalibrationNames(effNames);
117
118 // insert the calibration names into a common object
119 std::map<string, string> calibrationNames;
120 calibrationNames["B"] = m_SFcalibrationBName;
121 calibrationNames["C"] = m_SFcalibrationCName;
122 calibrationNames["T"] = m_SFcalibrationTName;
123 calibrationNames["Light"] = m_SFcalibrationLightName;
124 setSFCalibrationNames(calibrationNames);
125
126 // register all objects
127 for (std::map<string, string>::const_iterator it = calibrationNames.begin();
128 it != calibrationNames.end(); ++it) {
129 for (std::vector<string>::const_iterator op = m_operatingPoints.begin();
130 op != m_operatingPoints.end(); ++op) {
131 registerObjects(it->first, *op);
132 }
133 }
134
135 ATH_MSG_INFO("initialize() successful in " << name());
136 return StatusCode::SUCCESS;
137}
138
139//============================================================================================
140
141//====================== efficiency scale factor retrieval =============================
142
145 const string& OP, Uncertainty unc) const
146{
147 // // For now, a calibration for the charm efficiency scale factor is assumed not to exist
148 // if (label == "C") return getScaleFactor(jet, "B", OP, unc);
149
150 // for light-flavour jets, rename from "N/A"
151 string flavour(label);
152 if (flavour == "N/A") flavour = "Light";
153
154 string author = jet.jetAuthor();
155
156 string sfName(getBasename(OP, flavour, "_SF", true));
157
158 // Return a dummy result if the object is not found
159 std::pair<CalibrationDataContainer*,bool> ret =
160 m_broker->retrieveTObject<CalibrationDataContainer>(m_taggerName, author, sfName);
162 if (! container) {
163 ATH_MSG_WARNING("in " << name() << ": unable to find SF calibration for object with "
164 << "tagger/jetCollection/flavour/operating point = "
165 << m_taggerName << "/" << author << "/" << flavour << "/" << OP);
167 }
168
169 /* Here, it isn't obvious what to do with the second element of the pair returned:
170 This indicates whether a new object has been loaded (presumably due to IOV changes),
171 but the CalibrationDataContainer should take of any necessary computations itself.
172 */
173
174 // fill the CalibrationDataVariables object
175 CalibrationDataVariables variables;
176 makeVariables (jet, variables);
177
178 // always retrieve the result itself
179 double value;
180 if (container->getResult(variables, value) == CalibrationDataContainer::kError)
182
183 // retrieve the statistical uncertainty if desired
184 double stat(0);
185 if (unc == Total || unc == Statistical) {
186 if (container->getStatUncertainty(variables, stat) == CalibrationDataContainer::kError)
187 cerr << "getScaleFactor: error retrieving Scale factor statistical uncertainty!"
188 << endl;
189 }
190 UncertaintyResult resSyst(0,0);
191 if (unc == Total || unc == Systematic) {
192 if (container->getSystUncertainty(variables, resSyst) == CalibrationDataContainer::kError)
193 cerr << "getScaleFactor: error retrieving Scale factor parameter systematic uncertainty!"
194 << endl;
195 }
196
197 double uncertainty = combinedUncertainty(stat, resSyst);
198 Analysis::CalibResult result = std::make_pair(value, uncertainty);
199
200 result.first = std::max(0., result.first);
201 if (std::abs(result.first) < Analysis::CalibZERO)
202 result.first = 1.;
203 return result;
204}
205
206//====================== "MC" efficiency retrieval ======================================
207
210 const string& OP, Uncertainty unc) const
211{
212 // extract the relevant jet quantities: kinematic variables and jet author
213
214 // for light-flavour jets, rename from "N/A"
215 string flavour(label);
216 if (flavour == "N/A") flavour = "Light";
217
218 string author = jet.jetAuthor();
219
220 string effName(getBasename(OP, flavour, "_Eff", false));
221
222 // Return a dummy result if the object is not found
223 std::pair<CalibrationDataContainer*,bool> ret =
224 m_broker->retrieveTObject<CalibrationDataContainer>(m_taggerName, author, effName);
226 if (! container) {
227 ATH_MSG_WARNING("in " << name() << ": unable to find Eff calibration for object with "
228 << "tagger/jetCollection/flavour/operating point = "
229 << m_taggerName << "/" << author << "/" << flavour << "/" << OP);
231 }
232
233 /* Here, it isn't obvious what to do with the second element of the pair returned:
234 This indicates whether a new object has been loaded (presumably due to IOV changes),
235 but the CalibrationDataContainer should take of any necessary computations itself.
236 */
237
238 // fill the CalibrationDataVariables object
239 CalibrationDataVariables variables;
240 makeVariables (jet, variables);
241
242 // always retrieve the result itself
243 double value;
244 if (container->getResult(variables, value) == CalibrationDataContainer::kError)
246
247 // retrieve the statistical uncertainty if desired
248 double stat(0);
249 if (unc == Total || unc == Statistical) {
250 if (container->getStatUncertainty(variables, stat) == CalibrationDataContainer::kError)
251 cerr << "getMCEfficiency: error retrieving MC efficiency statistical uncertainty!"
252 << endl;
253 }
254 UncertaintyResult resSyst(0,0);
255 if (unc == Total || unc == Systematic) {
256 if (container->getSystUncertainty(variables, resSyst) == CalibrationDataContainer::kError)
257 cerr << "getMCEfficiency: error retrieving MC efficiency parameter systematic uncertainty!"
258 << endl;
259 }
260
261 double uncertainty = combinedUncertainty(stat, resSyst);
262 Analysis::CalibResult result = std::make_pair(value, uncertainty);
263
264 result.first = std::max(0., std::min(1., result.first));
265 return result;
266}
267
268//====================== efficiency retrieval ==========================================
269
272 const string& OP, Uncertainty unc) const
273{
274 Analysis::CalibResult sfResult = getScaleFactor(jet, label, OP, unc);
275 Analysis::CalibResult effResult = getMCEfficiency(jet, label, OP, unc);
276
277 double relative = 0;
278 double value = effResult.first*sfResult.first;
279 if (value != 0) {
280 relative = effResult.second/effResult.first;
281 double sfRelative = sfResult.second/sfResult.first;
282 relative = std::sqrt(sfRelative*sfRelative + relative*relative);
283 } else {
284 ATH_MSG_WARNING("in " << name() << ": null result, SF=" << sfResult.first
285 << " MC eff=" << effResult.first);
286 relative = Analysis::dummyValue;
287 }
288
289 return std::make_pair(value,value*relative);
290}
291
292//============================================================================================
293
295 const string& OP) const
296{
297 static const string slash("/");
298
299 string common = OP; common += slash;
300 common += flavour; common += slash;
301 string nameEff(common); nameEff += EffCalibrationName(flavour); nameEff += "_Eff";
302 string nameSF(common); nameSF += SFCalibrationName(flavour); nameSF += "_SF";
303
304 m_broker->registerHistogram(m_taggerName, nameSF);
305 m_broker->registerHistogram(m_taggerName, nameEff);
306}
307
308void
311{
312 x.jetAuthor = jet.jetAuthor();
313 x.jetPt = jet.pt() * 0.001; // NB convert from MeV to GeV!
314 x.jetEta = jet.eta();
315}
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define x
This is the interface for the objects to be stored in the calibration ROOT file.
std::string m_taggerName
tagging algorithm name
const std::string & SFCalibrationName(const std::string &flavour) const
void setEffCalibrationNames(const std::map< std::string, std::vector< std::string > > &names)
void setSFCalibrationNames(const std::map< std::string, std::string > &names)
const std::string & EffCalibrationName(const std::string &flavour, unsigned int mapIndex=0) const
Main interface methods accessing the flavour tagging performance information.
std::string getBasename(const std::string &name) const
auxiliary function for retrieval of name within the directory
double combinedUncertainty(double stat, const std::pair< double, double > &syst) const
utility function for combination of statistical and (a priori asymmetric) systematic uncertainty.
CalibrationDataInterfaceTool(const std::string &, const std::string &, const IInterface *)
ToolHandle< CalibrationBroker > m_broker
pointer to the performance broker
std::string m_EffcalibrationBName
calibration curves for b, c, and light-flavour jets
CalibResult getEfficiency(const Jet &jet, const std::string &label, const std::string &OP, Uncertainty unc=None) const
Main interface methods accessing the flavour tagging performance information.
virtual StatusCode initialize() override
standard Athena-Algorithm method
void registerObjects(const std::string &folder, const std::string &OP) const
auxiliary function dealing with registration of objects
CalibResult getMCEfficiency(const Jet &jet, const std::string &label, const std::string &OP, Uncertainty unc=None) const
"MC" efficiency retrieval
void makeVariables(const Jet &jet, CalibrationDataVariables &x) const
auxiliary function to create the intermediate struct needed for the data layer
CalibResult getScaleFactor(const Jet &jet, const std::string &label, const std::string &OP, Uncertainty unc=None) const
efficiency scale factor retrieval
This class (struct, actually) is nothing but a light-weight container of (kinematic or other) variabl...
std::string label(const std::string &format, int i)
Definition label.h:19
const CalibResult dummyResult(dummyValue, dummyValue)
std::pair< double, double > CalibResult
std::pair< double, double > UncertaintyResult
The following typedef is for convenience: most uncertainties can be asymmetric.
Uncertainty
specification of type information requested by the user