ATLAS Offline Software
Loading...
Searching...
No Matches
IsolationSelectionTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
4
11#include <TF2.h>
12#include <TFile.h>
13#include <TH3.h>
14#include <TKey.h>
15#include <TObjString.h>
16#include <TROOT.h>
18
20
21namespace CP {
24const std::vector<std::unique_ptr<IsolationWP>>&
28const std::vector<std::unique_ptr<IsolationWP>>&
32const std::vector<std::unique_ptr<IsolationWP>>&
36const std::vector<std::unique_ptr<IsolationWP>>&
41
44 ATH_MSG_INFO("Initialising...");
45
46 ATH_MSG_INFO("IsoDecSuffix: " << m_isoDecSuffix);
47
48 if (!m_calibFileName.empty()) {
49 std::string filename = PathResolverFindCalibFile(m_calibFileName);
50
51 ATH_MSG_INFO("Reading input file " << m_calibFileName << " from "
52 << filename);
53 m_calibFile = std::make_unique<TFile>(filename.c_str(), "READ");
54
55 TObjString* versionInfo{nullptr};
56 m_calibFile->GetObject("VersionInfo", versionInfo);
57 if (versionInfo)
58 ATH_MSG_INFO("VersionInfo:" << versionInfo->String());
59 else
60 ATH_MSG_WARNING("VersionInfo of input file (" << filename
61 << ") is missing.");
62 }
63
64 if (m_doInterpE || m_doInterpM) {
65 // special setting for electrons
66 // do not apply interpolation in crack vicinity for topoetcone
67 std::vector<std::pair<double, double>> rangeEtaNoInt;
68 std::pair<double, double> apair(1.26, 1.665);
69 rangeEtaNoInt.push_back(apair);
70 // do not apply interpolation between Z defined and J/Psi defined cuts (pT <
71 // > 15 GeV/c) for both calo and track iso
72 std::vector<std::pair<double, double>> rangePtNoInt;
73 apair.first = 12.5;
74 apair.second = 17.5;
75 rangePtNoInt.push_back(apair);
76 std::map<std::string, Interp3D::VetoInterp> amap;
78 veto.xRange = rangePtNoInt;
79 veto.yRange = std::vector<std::pair<double, double>>();
80 amap.insert(std::make_pair(std::string("el_cutValues_ptvarcone20"), veto));
81 veto.yRange = rangeEtaNoInt;
82 amap.insert(std::make_pair(std::string("el_cutValues_topoetcone20"), veto));
83 m_Interp = std::make_unique<Interp3D>(amap);
84 m_Interp->debug(false);
85 }
86
88 if (m_phWPname != "Undefined")
90 if (m_elWPname != "Undefined")
92 if (m_muWPname != "Undefined")
94 for (const std::string& c : m_muWPvec)
96 for (const std::string& c : m_elWPvec)
98 for (const std::string& c : m_phWPvec)
100
101 m_calibFile.reset();
102#ifndef XAOD_STANDALONE
103 ATH_CHECK(m_isoDecors.initialize());
104#endif
106 return StatusCode::SUCCESS;
107}
108
110 const IsolationWP& wp) {
111 if (container.empty())
112 return;
113 for (const std::unique_ptr<IsolationCondition>& cond : wp.conditions()) {
114 for (unsigned int acc = 0; acc < cond->num_types(); ++acc) {
115 m_isoDecors.emplace_back(
116 container + "." +
117 SG::AuxTypeRegistry::instance().getName(cond->accessor(acc).auxid()));
118 }
119 }
120}
121
123 xAOD::Type::ObjectType ObjType) {
124 if (ObjType == xAOD::Type::Electron) {
127 } else if (ObjType == xAOD::Type::Muon) {
130 } else if (ObjType == xAOD::Type::Photon) {
133 } else {
134 return StatusCode::FAILURE;
135 }
136
137 return StatusCode::SUCCESS;
138}
139
141 IsolationWP* wp, const std::string& key_in,
142 const xAOD::Iso::IsolationType t, const std::string& expression,
143 const xAOD::Iso::IsolationType isoCutRemap) {
144 if (!m_calibFile) {
145 ATH_MSG_ERROR("Calibration File (" << m_calibFileName << ") is missing.");
146 return StatusCode::FAILURE;
147 }
148
149 std::string varname(xAOD::Iso::toCString(isoCutRemap));
150 std::string key = key_in + varname;
151
152 TH3F* calibHisto{nullptr};
153 m_calibFile->GetObject(key.c_str(), calibHisto);
154 if (!calibHisto) {
155 ATH_MSG_FATAL(" Failed to load " << key << " from "
156 << m_calibFile->GetName());
157 return StatusCode::FAILURE;
158 }
159 calibHisto->SetDirectory(nullptr);
160 std::unique_ptr<TH3F> histogram(calibHisto);
161 std::unique_ptr<IsolationConditionHist> ich =
162 std::make_unique<IsolationConditionHist>(varname, t, expression,
163 std::move(histogram));
164 if ((m_doInterpM && key.find("Muon") != std::string::npos) ||
165 (m_doInterpE && key.find("Electron") != std::string::npos))
166 ich->setInterp(m_Interp);
167 wp->addCut(std::move(ich));
168
169 return StatusCode::SUCCESS;
170}
171
173 const std::string& key,
175 const std::string& expression) {
176 return addCutToWP(wp, key, t, expression, t);
177}
178
179StatusCode IsolationSelectionTool::addMuonWP(const std::string& muWPname) {
180 std::unique_ptr<IsolationWP> wp = std::make_unique<IsolationWP>(muWPname);
181 if (muWPname == "HighPtTrackOnly") {
182 wp->addCut(std::make_unique<IsolationConditionFormula>(
183 "ptcone20_Tight_1p25",
185 false, m_isoDecSuffix)); // units are MeV!
186 } else if (muWPname == "TightTrackOnly_FixedRad") {
187 wp->addCut(std::make_unique<IsolationConditionFormula>(
188 "MuonFixedCutHighMuTrackOnly_lowPt",
190 "0.06*(x>50e3?1e9:x)", false, m_isoDecSuffix));
191 wp->addCut(std::make_unique<IsolationConditionFormula>(
192 "MuonFixedCutHighMuTrackOnly_highPt",
194 "0.06*(x>50e3?x:1e9)", false, m_isoDecSuffix));
195 } else if (muWPname == "Tight_FixedRad") {
196 wp->addCut(std::make_unique<IsolationConditionFormula>(
197 "MuonFixedCutHighMuTight_track_lowPt",
199 "0.04*(x>50e3?1e9:x)", false, m_isoDecSuffix));
200 wp->addCut(std::make_unique<IsolationConditionFormula>(
201 "MuonFixedCutHighMuTight_track_highPt",
203 "0.04*(x>50e3?x:1e9)", false, m_isoDecSuffix));
204 wp->addCut(std::make_unique<IsolationConditionFormula>(
205 "MuonFixedCutHighMuTight_calo", xAOD::Iso::topoetcone20, "0.15*x",
206 false, m_isoDecSuffix));
207 } else if (muWPname == "Loose_FixedRad") {
208 wp->addCut(std::make_unique<IsolationConditionFormula>(
209 "MuonFixedCutHighMuLoose_track_lowPt",
211 "0.15*(x>50e3?1e9:x)", false, m_isoDecSuffix));
212 wp->addCut(std::make_unique<IsolationConditionFormula>(
213 "MuonFixedCutHighMuLoose_track_highPt",
215 "0.15*(x>50e3?x:1e9)", false, m_isoDecSuffix));
216 wp->addCut(std::make_unique<IsolationConditionFormula>(
217 "MuonFixedCutHighMuLoose_calo", xAOD::Iso::topoetcone20, "0.30*x",
218 false, m_isoDecSuffix));
219 } else if (muWPname == "TightTrackOnly_VarRad") {
220 wp->addCut(std::make_unique<IsolationConditionFormula>(
221 "MuonFixedCutHighMuTrackOnly",
223 false, m_isoDecSuffix));
224 } else if (muWPname == "Tight_VarRad") {
225 wp->addCut(std::make_unique<IsolationConditionFormula>(
226 "MuonFixedCutHighMuTight_track",
228 false, m_isoDecSuffix));
229 wp->addCut(std::make_unique<IsolationConditionFormula>(
230 "MuonFixedCutHighMuTight_calo", xAOD::Iso::topoetcone20, "0.15*x",
231 false, m_isoDecSuffix));
232 } else if (muWPname == "Loose_VarRad") {
233 wp->addCut(std::make_unique<IsolationConditionFormula>(
234 "MuonFixedCutHighMuLoose_track",
236 false, m_isoDecSuffix));
237 wp->addCut(std::make_unique<IsolationConditionFormula>(
238 "MuonFixedCutHighMuLoose_calo", xAOD::Iso::topoetcone20, "0.30*x",
239 false, m_isoDecSuffix));
240 } else if (muWPname == "PflowTight_FixedRad") {
241 std::vector<xAOD::Iso::IsolationType> isoTypesHighPt{
244 std::vector<xAOD::Iso::IsolationType> isoTypesLowPt{
247 wp->addCut(std::make_unique<IsolationConditionCombined>(
248 "MuonPFlowTightLowPt", isoTypesLowPt,
249 std::make_unique<TF2>("pflowTFunctionLowPt", "fabs(x)+0.4*(y>0?y:0)"),
250 "0.045*(x>50e3?1e9:x)", m_isoDecSuffix));
251 wp->addCut(std::make_unique<IsolationConditionCombined>(
252 "MuonPFlowTightHighPt", isoTypesHighPt,
253 std::make_unique<TF2>("pflowTFunctionHighPt", "fabs(x)+0.4*(y>0?y:0)"),
254 "0.045*(x>50e3?x:1e9)", m_isoDecSuffix));
255 } else if (muWPname == "PflowTight_VarRad") {
256 std::vector<xAOD::Iso::IsolationType> isoTypes{
259 wp->addCut(std::make_unique<IsolationConditionCombined>(
260 "MuonPFlowTight", isoTypes,
261 std::make_unique<TF2>("pflowTFunction", "fabs(x)+0.4*(y>0?y:0)"),
262 "0.045*x", m_isoDecSuffix));
263 } else if (muWPname == "PflowLoose_FixedRad") {
264 std::vector<xAOD::Iso::IsolationType> isoTypesHighPt{
267 std::vector<xAOD::Iso::IsolationType> isoTypesLowPt{
270 wp->addCut(std::make_unique<IsolationConditionCombined>(
271 "MuonPFlowLooseLowPt", isoTypesLowPt,
272 std::make_unique<TF2>("pflowLFunctionLowPt", "fabs(x)+0.4*(y>0?y:0)"),
273 "0.16*(x>50e3?1e9:x)", m_isoDecSuffix));
274 wp->addCut(std::make_unique<IsolationConditionCombined>(
275 "MuonPFlowLooseHighPt", isoTypesHighPt,
276 std::make_unique<TF2>("pflowLFunctionHighPt", "fabs(x)+0.4*(y>0?y:0)"),
277 "0.16*(x>50e3?x:1e9)", m_isoDecSuffix));
278 } else if (muWPname == "PflowLoose_VarRad") {
279 std::vector<xAOD::Iso::IsolationType> isoTypes{
282 wp->addCut(std::make_unique<IsolationConditionCombined>(
283 "MuonPFlowLoose", isoTypes,
284 std::make_unique<TF2>("pflowTFunction", "fabs(x)+0.4*(y>0?y:0)"),
285 "0.16*x", m_isoDecSuffix));
286 } else if (muWPname == "R3PLITasPLIVefficiencyTight") {
287 const std::vector<std::string>& isoTypes = {"PLIT_TPLTmu_pmuxpromp",
288 "PLIT_TPLTmu_pnpxall"};
289 const std::vector<double> boundaries = {5500.0, 10000.0, 15000.0,
290 20000.0, 25000.0, 32000.0,
291 43000.0, 60000.0, 95000.0};
292 const std::vector<std::vector<double>> parameters = {
293 {3.75},
294 {2.4599999999999946, 0.0002400000000000006},
295 {2.6437499999999883, 0.00023250000000000085},
296 {5.576250000000033, 2.249999999999814e-05},
297 {7.061249999999798, -5.2499999999991085e-05},
298 {6.933482142856749, -4.553571428570058e-05},
299 {7.271590909090752, -5.5909090909086746e-05},
300 {5.105882352941061, -1.1764705882350721e-05},
301 {4.4250000000000025, -2.97364147850582e-20},
302 {4.425000000000001}};
303 const std::string cutFunction =
304 createPieceWisePolinomialFunction(boundaries, parameters, true);
305 wp->addCut(std::make_unique<IsolationConditionCombined>(
306 "R3PLITasPLIVefficiencyTight", isoTypes,
307 std::make_unique<TF2>("muonPLIT", "TMath::Log(x / y)"), cutFunction,
308 m_isoDecSuffix, true));
309 } else if (muWPname == "R3PLITasPLIVefficiencyVeryTight") {
310 const std::vector<std::string>& isoTypes = {"PLIT_TPLTmu_pmuxpromp",
311 "PLIT_TPLTmu_pnpxall"};
312 const std::vector<double> boundaries = {5500.0, 10000.0, 15000.0,
313 20000.0, 25000.0, 32000.0,
314 43000.0, 60000.0, 95000.0};
315 const std::vector<std::vector<double>> parameters = {
316 {4.050000000000001},
317 {2.5912499999999903, 0.0002625000000000011},
318 {2.8012499999999214, 0.00024750000000000623},
319 {5.677499999999787, 4.500000000001207e-05},
320 {6.2137499999998145, 2.2500000000008228e-05},
321 {7.09151785714283, -1.8749999999999094e-05},
322 {8.57727272727282, -6.545454545454794e-05},
323 {5.969852941176529, -1.0294117647059968e-05},
324 {5.528483606557319, -2.581967213113981e-06},
325 {5.324999999999999}};
326 const std::string cutFunction =
327 createPieceWisePolinomialFunction(boundaries, parameters, true);
328 wp->addCut(std::make_unique<IsolationConditionCombined>(
329 "R3PLITasPLIVefficiencyVeryTight", isoTypes,
330 std::make_unique<TF2>("muonPLIT", "TMath::Log(x / y)"), cutFunction,
331 m_isoDecSuffix, true));
332 } else if (muWPname == "R3PLITasPLIVrejectionTight") {
333 const std::vector<std::string>& isoTypes = {"PLIT_TPLTmu_pmuxpromp",
334 "PLIT_TPLTmu_pnpxall"};
335 const std::vector<double> boundaries = {5500.0, 10000.0, 15000.0,
336 20000.0, 25000.0, 32000.0,
337 43000.0, 60000.0, 95000.0};
338 const std::vector<std::vector<double>> parameters = {
339 {3.6750000000000007},
340 {2.4374999999999987, 0.00022500000000000008},
341 {2.572499999999916, 0.00022500000000000666},
342 {5.351249999999845, 2.2500000000008773e-05},
343 {7.113749999999581, -6.749999999998147e-05},
344 {7.213392857142764, -6.964285714285394e-05},
345 {7.4778409090906415, -7.977272727272016e-05},
346 {4.105790441176434, -1.3419117647058116e-05},
347 {3.590163934426209, -4.180327868852198e-06},
348 {3.1499999999999986}};
349 const std::string cutFunction =
350 createPieceWisePolinomialFunction(boundaries, parameters, true);
351 wp->addCut(std::make_unique<IsolationConditionCombined>(
352 "R3PLITasPLIVrejectionTight", isoTypes,
353 std::make_unique<TF2>("muonPLIT", "TMath::Log(x / y)"), cutFunction,
354 m_isoDecSuffix, true));
355 } else if (muWPname == "R3PLITasPLIVrejectionVeryTight") {
356 const std::vector<std::string>& isoTypes = {"PLIT_TPLTmu_pmuxpromp",
357 "PLIT_TPLTmu_pnpxall"};
358 const std::vector<double> boundaries = {5500.0, 10000.0, 15000.0,
359 20000.0, 25000.0, 32000.0,
360 43000.0, 60000.0, 95000.0};
361 const std::vector<std::vector<double>> parameters = {
362 {3.974999999999998},
363 {2.5875000000000035, 0.0002549999999999993},
364 {2.8687499999999373, 0.00023250000000000495},
365 {5.527499999999797, 4.500000000001146e-05},
366 {6.048749999999677, 2.2500000000014293e-05},
367 {7.019196428571157, -2.4107142857133378e-05},
368 {8.878977272727232, -8.38636363636353e-05},
369 {5.708823529411479, -1.76470588235239e-05},
370 {5.215573770491751, -7.131147540982918e-06},
371 {4.649999999999999}};
372 const std::string cutFunction =
373 createPieceWisePolinomialFunction(boundaries, parameters, true);
374 wp->addCut(std::make_unique<IsolationConditionCombined>(
375 "R3PLITasPLIVrejectionVeryTight", isoTypes,
376 std::make_unique<TF2>("muonPLIT", "TMath::Log(x / y)"), cutFunction,
377 m_isoDecSuffix, true));
378 } else if (muWPname == "R2PLITasPLIVefficiencyTight") {
379 const std::vector<std::string>& isoTypes = {"PLIT_TPLTmu_pmuxpromp",
380 "PLIT_TPLTmu_pnpxall"};
381 const std::vector<double> boundaries = {5500.0, 10000.0, 15000.0,
382 20000.0, 25000.0, 32000.0,
383 43000.0, 60000.0, 95000.0};
384 const std::vector<std::vector<double>> parameters = {
385 {3.974999999999998},
386 {2.789999999999986, 0.00021000000000000172},
387 {2.39249999999993, 0.00025500000000000555},
388 {5.737499999999933, 1.5000000000003797e-05},
389 {7.413749999999598, -6.749999999998225e-05},
390 {7.098214285714245, -5.3571428571427186e-05},
391 {6.934090909090853, -4.909090909090761e-05},
392 {5.253676470587868, -1.6176470588228218e-05},
393 {4.275000000000021, -3.17095862137587e-19},
394 {4.349999999999998}};
395 const std::string cutFunction =
396 createPieceWisePolinomialFunction(boundaries, parameters, true);
397 wp->addCut(std::make_unique<IsolationConditionCombined>(
398 "R2PLITasPLIVefficiencyTight", isoTypes,
399 std::make_unique<TF2>("muonPLIT", "TMath::Log(x / y)"), cutFunction,
400 m_isoDecSuffix, true));
401 } else if (muWPname == "R2PLITasPLIVefficiencyVeryTight") {
402 const std::vector<std::string>& isoTypes = {"PLIT_TPLTmu_pmuxpromp",
403 "PLIT_TPLTmu_pnpxall"};
404 const std::vector<double> boundaries = {5500.0, 10000.0, 15000.0,
405 20000.0, 25000.0, 32000.0,
406 43000.0, 60000.0, 95000.0};
407 const std::vector<std::vector<double>> parameters = {
408 {4.199999999999999},
409 {2.9625000000000026, 0.00022499999999999956},
410 {2.7674999999999454, 0.0002550000000000043},
411 {5.752499999999801, 4.500000000001117e-05},
412 {6.2887499999995, 2.2500000000022112e-05},
413 {7.265625000000208, -2.4107142857150163e-05},
414 {8.287500000000128, -5.863636363636705e-05},
415 {5.99329044117658, -1.194852941176682e-05},
416 {5.653893442622939, -5.5327868852457475e-06},
417 {5.25}};
418 const std::string cutFunction =
419 createPieceWisePolinomialFunction(boundaries, parameters, true);
420 wp->addCut(std::make_unique<IsolationConditionCombined>(
421 "R2PLITasPLIVefficiencyVeryTight", isoTypes,
422 std::make_unique<TF2>("muonPLIT", "TMath::Log(x / y)"), cutFunction,
423 m_isoDecSuffix, true));
424 } else if (muWPname == "R2PLITasPLIVrejectionTight") {
425 const std::vector<std::string>& isoTypes = {"PLIT_TPLTmu_pmuxpromp",
426 "PLIT_TPLTmu_pnpxall"};
427 const std::vector<double> boundaries = {5500.0, 10000.0, 15000.0,
428 20000.0, 25000.0, 32000.0,
429 43000.0, 60000.0, 95000.0};
430 const std::vector<std::vector<double>> parameters = {
431 {3.8999999999999986},
432 {2.853749999999994, 0.00018750000000000065},
433 {2.321250000000002, 0.0002474999999999998},
434 {5.426250000000083, 2.2499999999995095e-05},
435 {7.312499999999872, -7.499999999999437e-05},
436 {7.552232142857126, -8.303571428571374e-05},
437 {7.140340909090713, -7.022727272726753e-05},
438 {4.7727941176470186, -2.499999999999921e-05},
439 {3.679918032786865, -5.409836065573509e-06},
440 {3.0}};
441 const std::string cutFunction =
442 createPieceWisePolinomialFunction(boundaries, parameters, true);
443 wp->addCut(std::make_unique<IsolationConditionCombined>(
444 "R2PLITasPLIVrejectionTight", isoTypes,
445 std::make_unique<TF2>("muonPLIT", "TMath::Log(x / y)"), cutFunction,
446 m_isoDecSuffix, true));
447 } else if (muWPname == "R2PLITasPLIVrejectionVeryTight") {
448 const std::vector<std::string>& isoTypes = {"PLIT_TPLTmu_pmuxpromp",
449 "PLIT_TPLTmu_pnpxall"};
450 const std::vector<double> boundaries = {5500.0, 10000.0, 15000.0,
451 20000.0, 25000.0, 32000.0,
452 43000.0, 60000.0, 95000.0};
453 const std::vector<std::vector<double>> parameters = {
454 {4.199999999999999},
455 {2.9887499999999982, 0.0002175000000000001},
456 {2.9287500000000426, 0.0002324999999999965},
457 {5.602499999999976, 4.500000000000134e-05},
458 {6.262499999999722, 1.5000000000012243e-05},
459 {7.651339285714248, -4.5535714285712985e-05},
460 {8.947159090908924, -8.659090909090467e-05},
461 {5.994117647058617, -2.3529411764701903e-05},
462 {4.8565573770491985, -2.213114754098622e-06},
463 {4.349999999999998}};
464 const std::string cutFunction =
465 createPieceWisePolinomialFunction(boundaries, parameters, true);
466 wp->addCut(std::make_unique<IsolationConditionCombined>(
467 "R2PLITasPLIVrejectionVeryTight", isoTypes,
468 std::make_unique<TF2>("muonPLIT", "TMath::Log(x / y)"), cutFunction,
469 m_isoDecSuffix, true));
470 } else if (muWPname == "R3PLITVeryLoose") {
471 const std::vector<std::string>& isoTypes = {"PLIT_TPLTmu_pmuxpromp",
472 "PLIT_TPLTmu_pnpxall"};
473 const std::vector<double> boundaries = {
474 15000.0, 20000.0, 25000.0, 30000.0, 40000.0, 50000.0,
475 75000.0, 100000.0, 110000.0, 120000.0, 160000.0};
476 const std::vector<std::vector<double>> parameters = {
477 {-0.3040909, 0.0002809},
478 {1.56375, 9.75e-05},
479 {1.22625, 9.75e-05},
480 {1.4625, 7.5e-05},
481 {1.4622506, 6.45e-05},
482 {1.6695205, 4.62e-05},
483 {1.9120284, 3.31e-05},
484 {2.9462838, 1.26e-05},
485 {3.375},
486 {3.45},
487 {3.225},
488 {3.3}};
489 const std::string cutFunction =
490 createPieceWisePolinomialFunction(boundaries, parameters, true);
491 wp->addCut(std::make_unique<IsolationConditionCombined>(
492 "R3PLITVeryLoose", isoTypes,
493 std::make_unique<TF2>("muonPLIT", "TMath::Log(x / y)"), cutFunction,
494 m_isoDecSuffix, true));
495 } else if (muWPname == "R2PLITVeryLoose") {
496 const std::vector<std::string>& isoTypes = {"PLIT_TPLTmu_pmuxpromp",
497 "PLIT_TPLTmu_pnpxall"};
498 const std::vector<double> boundaries = {
499 15000.0, 20000.0, 25000.0, 30000.0, 40000.0, 50000.0,
500 75000.0, 100000.0, 110000.0, 120000.0, 160000.0};
501 const std::vector<std::vector<double>> parameters = {{0.0886364, 0.0002536},
502 {1.8651869, 8.55e-05},
503 {1.7625, 7.5e-05},
504 {1.4625, 7.5e-05},
505 {1.5238217, 6.21e-05},
506 {1.743375, 4.43e-05},
507 {2.1522807, 2.78e-05},
508 {2.3787162, 1.74e-05},
509 {3.3},
510 {3.45},
511 {3.15},
512 {3.075}};
513 const std::string cutFunction =
514 createPieceWisePolinomialFunction(boundaries, parameters, true);
515 wp->addCut(std::make_unique<IsolationConditionCombined>(
516 "R2PLITVeryLoose", isoTypes,
517 std::make_unique<TF2>("muonPLIT", "TMath::Log(x / y)"), cutFunction,
518 m_isoDecSuffix, true));
519 } else {
520 ATH_MSG_ERROR("Unknown muon isolation WP: " << muWPname);
521 return StatusCode::FAILURE;
522 }
523 m_muonAccept.addCut(wp->name(), wp->name());
524#ifndef XAOD_STANDALONE
526#endif
527 m_muWPs.push_back(std::move(wp));
528 return StatusCode::SUCCESS;
529}
530
531StatusCode IsolationSelectionTool::addPhotonWP(const std::string& phWPname) {
532 std::unique_ptr<IsolationWP> wp = std::make_unique<IsolationWP>(phWPname);
533 if (phWPname == "TightCaloOnly") {
534 wp->addCut(std::make_unique<IsolationConditionFormula>(
535 "PhFixedCut_calo40", xAOD::Iso::topoetcone40, "0.022*x+2450", false,
537 } else if (phWPname == "FixedCutTight") {
538 wp->addCut(std::make_unique<IsolationConditionFormula>(
539 "PhFixedCut_calo40", xAOD::Iso::topoetcone40, "0.022*x+2450", false,
541 wp->addCut(std::make_unique<IsolationConditionFormula>(
542 "PhFixedCut_track20", xAOD::Iso::ptcone20, "0.05*x", false,
544 } else if (phWPname == "FixedCutLoose") {
545 wp->addCut(std::make_unique<IsolationConditionFormula>(
546 "PhFixedCut_calo20", xAOD::Iso::topoetcone20, "0.065*x", false,
548 wp->addCut(std::make_unique<IsolationConditionFormula>(
549 "PhFixedCut_track20", xAOD::Iso::ptcone20, "0.05*x", false,
551 } else if (phWPname == "Tight") {
552 wp->addCut(std::make_unique<IsolationConditionFormula>(
553 "PhFixedCut_calo40", xAOD::Iso::topoetcone40, "0.022*x+2450", false,
555 wp->addCut(std::make_unique<IsolationConditionFormula>(
556 "PhFixedCut_Tighttrack20",
559 } else if (phWPname == "Loose") {
560 wp->addCut(std::make_unique<IsolationConditionFormula>(
561 "PhFixedCut_calo20", xAOD::Iso::topoetcone20, "0.065*x", false,
563 wp->addCut(std::make_unique<IsolationConditionFormula>(
564 "PhFixedCut_Tighttrack20",
567 } else {
568 ATH_MSG_ERROR("Unknown photon isolation WP: " << phWPname);
569 return StatusCode::FAILURE;
570 }
571
572 m_photonAccept.addCut(wp->name(), wp->name());
573#ifndef XAOD_STANDALONE
575#endif
576 m_phWPs.push_back(std::move(wp));
577
578 // Return gracefully:
579 return StatusCode::SUCCESS;
580}
581
582StatusCode IsolationSelectionTool::addElectronWP(const std::string& elWPname) {
583 std::unique_ptr<IsolationWP> wp = std::make_unique<IsolationWP>(elWPname);
584
585 if (elWPname == "HighPtCaloOnly") {
586 wp->addCut(std::make_unique<IsolationConditionFormula>(
587 "FCHighPtCaloOnly_calo", xAOD::Iso::topoetcone20,
588 "std::max(0.015*x,3.5E3)", false, m_isoDecSuffix)); // units are MeV!
589 } else if (elWPname == "Tight_VarRad") {
590 wp->addCut(std::make_unique<IsolationConditionFormula>(
591 "ElecTight_track",
593 "0.06*x", false, m_isoDecSuffix));
594 wp->addCut(std::make_unique<IsolationConditionFormula>(
595 "ElecTight_calo", xAOD::Iso::topoetcone20, "0.06*x", false,
597 } else if (elWPname == "Loose_VarRad") {
598 wp->addCut(std::make_unique<IsolationConditionFormula>(
599 "ElecLoose_track",
601 "0.15*x", false, m_isoDecSuffix));
602 wp->addCut(std::make_unique<IsolationConditionFormula>(
603 "ElecLoose_calo", xAOD::Iso::topoetcone20, "0.20*x", false,
605 } else if (elWPname == "TightTrackOnly_VarRad") {
606 wp->addCut(std::make_unique<IsolationConditionFormula>(
607 "ElecTightTrackOnly",
609 "0.06*x", false, m_isoDecSuffix));
610 } else if (elWPname == "TightTrackOnly_FixedRad") {
611 wp->addCut(std::make_unique<IsolationConditionFormula>(
612 "ElecTightTrackOnly_lowPt",
614 "0.06*(x>50e3?1e9:x)", false, m_isoDecSuffix));
615 wp->addCut(std::make_unique<IsolationConditionFormula>(
616 "ElecTightTrackOnly_highPt",
618 "0.06*(x>50e3?x:1e9)", false, m_isoDecSuffix));
619 } else if (elWPname == "PflowTight_FixedRad") {
620 std::vector<xAOD::Iso::IsolationType> isoTypesHighPt{
623 std::vector<xAOD::Iso::IsolationType> isoTypesLowPt{
626 wp->addCut(std::make_unique<IsolationConditionCombined>(
627 "ElecPFlowTightLowPt", isoTypesLowPt,
628 std::make_unique<TF2>("pflowTFunctionLowPt", "fabs(x)+0.4*(y>0?y:0)"),
629 "0.045*(x>50e3?1e9:x)", m_isoDecSuffix));
630 wp->addCut(std::make_unique<IsolationConditionCombined>(
631 "ElecPFlowTightHighPt", isoTypesHighPt,
632 std::make_unique<TF2>("pflowTFunctionHighPt", "fabs(x)+0.4*(y>0?y:0)"),
633 "0.045*(x>50e3?x:1e9)", m_isoDecSuffix));
634 } else if (elWPname == "PflowTight") {
635 std::vector<xAOD::Iso::IsolationType> isoTypes{
638 wp->addCut(std::make_unique<IsolationConditionCombined>(
639 "ElecPFlowTight", isoTypes,
640 std::make_unique<TF2>("pflowLFunction", "fabs(x)+0.4*(y>0?y:0)"),
641 "0.045*x", m_isoDecSuffix));
642 } else if (elWPname == "PflowLoose_FixedRad") {
643 std::vector<xAOD::Iso::IsolationType> isoTypesHighPt{
646 std::vector<xAOD::Iso::IsolationType> isoTypesLowPt{
649 wp->addCut(std::make_unique<IsolationConditionCombined>(
650 "ElecPFlowLooseLowPt", isoTypesLowPt,
651 std::make_unique<TF2>("pflowLFunctionLowPt", "fabs(x)+0.4*(y>0?y:0)"),
652 "0.16*(x>50e3?1e9:x)", m_isoDecSuffix));
653 wp->addCut(std::make_unique<IsolationConditionCombined>(
654 "ElecPFlowLooseHighPt", isoTypesHighPt,
655 std::make_unique<TF2>("pflowLFunctionHighPt", "fabs(x)+0.4*(y>0?y:0)"),
656 "0.16*(x>50e3?x:1e9)", m_isoDecSuffix));
657 } else if (elWPname == "PflowLoose") {
658 std::vector<xAOD::Iso::IsolationType> isoTypes{
661 wp->addCut(std::make_unique<IsolationConditionCombined>(
662 "ElecPFlowLoose", isoTypes,
663 std::make_unique<TF2>("pflowLFunction", "fabs(x)+0.4*(y>0?y:0)"),
664 "0.16*x", m_isoDecSuffix));
665 } else if (elWPname == "isolPLITVeryTightRun3" ||
666 elWPname == "isolPLITTightRun3" ||
667 elWPname == "isolPLITVeryLooseRun3" ||
668 elWPname == "isolPLITVeryTightRun2" ||
669 elWPname == "isolPLITTightRun2" ||
670 elWPname == "isolPLITVeryLooseRun2"
671 ) {
672 // open the file path to read out WP definition file
673 // if (!m_filePathName.empty()) { should never be empty --> default value
674 std::string filename =
675 PathResolverFindCalibFile(m_filePathName + "/" + elWPname + ".root");
676
677 ATH_MSG_INFO("Reading input file " << elWPname << " from " << m_filePathName
678 << " " << filename << ": " << (m_filePathName + "/" + elWPname + ".root"));
679 m_WPdefinitionFile = std::make_unique<TFile>(filename.c_str(), "READ");
680
681 if (!m_WPdefinitionFile || m_WPdefinitionFile->IsZombie()) {
682 ATH_MSG_ERROR("Error opening file " << filename);
683 return StatusCode::FAILURE;
684 }
685
686 // read out histograms/graphs
687 TH1F* binning = dynamic_cast<TH1F*>(m_WPdefinitionFile->Get("binning"));
688 if (!binning) {
690 "Could not retrieve binning histogram in filename=" << filename);
691 return StatusCode::FAILURE;
692 }
693
694 std::vector<std::unique_ptr<TGraph>> cutGraphUPtr;
695
696 TIter nextkey(m_WPdefinitionFile->GetListOfKeys());
697 TKey* key;
698
699 while ((key = (TKey*)nextkey())) {
700 TObject* obj = key->ReadObj();
701 if (obj->InheritsFrom(TGraph::Class())) {
702 std::unique_ptr<TGraph> graph(static_cast<TGraph*>(obj));
703 cutGraphUPtr.push_back(std::move(graph));
704
705 // keep this as hint on how to read out RunNumber validity
706 // TObjArray* tokens = Obj_name.Tokenize("_");
707 // int n = tokens->GetEntries();
708 // double min_runnumber = ((TObjString*)tokens->At(n -
709 // 4))->GetString().Atof(); double max_runnumber =
710 // ((TObjString*)tokens->At(n - 3))->GetString().Atof();
711 }
712 }
713
714 static const std::vector<std::string> isoTypes = {"PLIT_PLITel_pelxpromp",
715 "PLIT_PLITel_pnpxall"};
716
717 if (elWPname == "isolPLITVeryTightRun3" ||
718 elWPname == "isolPLITTightRun3" ||
719 elWPname == "isolPLITVeryLooseRun3" ||
720 elWPname == "isolPLITVeryTightRun2" ||
721 elWPname == "isolPLITTightRun2" ||
722 elWPname == "isolPLITVeryLooseRun2") {
723 wp->addCut(std::make_unique<IsolationConditionGraph>(
724 elWPname, isoTypes,
725 std::make_unique<TF2>("elePLIT", "TMath::Log(x / y)"), std::move(cutGraphUPtr),
726 std::make_unique<TH1F>(*binning), m_isoDecSuffix.value(), true));
727 }
728 else {
729 ATH_MSG_ERROR("Unknown electron isolation WP: " << elWPname);
730 return StatusCode::FAILURE;
731 }
732 } else {
733 ATH_MSG_ERROR("Unknown electron isolation WP: " << elWPname);
734 return StatusCode::FAILURE;
735 }
736
737 m_electronAccept.addCut(wp->name(), wp->name());
738#ifndef XAOD_STANDALONE
740#endif
741 m_elWPs.push_back(std::move(wp));
742
743 // Return gracefully:
744 return StatusCode::SUCCESS;
745}
746
748 const std::string& WPname, xAOD::Type::ObjectType ObjType,
749 std::vector<std::pair<xAOD::Iso::IsolationType, std::string>>& cuts,
750 std::string key, IsoWPType type) {
751 std::vector<std::unique_ptr<IsolationWP>>* wps(nullptr);
752 asg::AcceptInfo* ac = nullptr;
753 if (ObjType == xAOD::Type::Electron) {
754 if (key == "")
755 key = m_elWPKey;
756 wps = &m_elWPs;
757 ac = &m_electronAccept;
758 } else if (ObjType == xAOD::Type::Muon) {
759 if (key == "")
760 key = m_muWPKey;
761 wps = &m_muWPs;
762 ac = &m_muonAccept;
763 } else if (ObjType == xAOD::Type::Photon) {
764 if (key == "")
765 key = m_phWPKey;
766 wps = &m_phWPs;
767 ac = &m_photonAccept;
768 } else if (ObjType == xAOD::Type::Other) {
769 if (key == "")
770 return StatusCode::FAILURE;
771 wps = &m_objWPs;
772 ac = &m_objAccept;
773 } else {
774 return StatusCode::FAILURE;
775 }
776
777 std::unique_ptr<IsolationWP> wp = std::make_unique<IsolationWP>(WPname);
778 if (type == Efficiency) {
779 for (auto& c : cuts)
780 ATH_CHECK(addCutToWP(wp.get(), key, c.first, c.second));
781 } else if (type == Cut) {
782 for (auto& c : cuts)
783 wp->addCut(std::make_unique<IsolationConditionFormula>(
784 xAOD::Iso::toCString(c.first), c.first, c.second));
785 } else {
786 ATH_MSG_ERROR("Unknown isolation WP type -- should not happen.");
787 return StatusCode::FAILURE;
788 }
789
790 ac->addCut(wp->name(), wp->name());
791 wps->push_back(std::move(wp));
792 return StatusCode::SUCCESS;
793}
794
795StatusCode IsolationSelectionTool::addWP(const std::string& WP,
796 xAOD::Type::ObjectType ObjType) {
797 if (ObjType == xAOD::Type::Electron) {
798 return addElectronWP(WP);
799 } else if (ObjType == xAOD::Type::Muon) {
800 return addMuonWP(WP);
801 } else if (ObjType == xAOD::Type::Photon) {
802 return addPhotonWP(WP);
803 }
804
805 return StatusCode::FAILURE;
806}
807StatusCode IsolationSelectionTool::addWP(std::unique_ptr<IsolationWP> wp,
808 xAOD::Type::ObjectType ObjType) {
809 if (ObjType == xAOD::Type::Electron) {
810 m_electronAccept.addCut(wp->name(), wp->name());
811 m_elWPs.push_back(std::move(wp));
812 } else if (ObjType == xAOD::Type::Muon) {
813 m_muonAccept.addCut(wp->name(), wp->name());
814 m_muWPs.push_back(std::move(wp));
815
816 } else if (ObjType == xAOD::Type::Photon) {
817 m_photonAccept.addCut(wp->name(), wp->name());
818 m_phWPs.push_back(std::move(wp));
819
820 } else if (ObjType == xAOD::Type::Other) {
821 m_objAccept.addCut(wp->name(), wp->name());
822 m_objWPs.push_back(std::move(wp));
823 } else {
824 return StatusCode::FAILURE;
825 }
826
827 return StatusCode::SUCCESS;
828}
829template <typename T>
831 const T& x, const std::vector<std::unique_ptr<IsolationWP>>& WP,
832 asg::AcceptData& accept) const {
833 accept.clear();
834 for (const std::unique_ptr<IsolationWP>& i : WP) {
835 if (i->accept(x))
836 accept.setCutResult(i->name(), true);
837 }
838}
844
850
856
858 if (x.type() == xAOD::Type::Electron) {
861 return accept;
862 } else if (x.type() == xAOD::Type::Muon) {
865 return accept;
866 } else if (x.type() == xAOD::Type::Photon) {
869 return accept;
870 }
871
872 else if (m_iparAcceptInfo && m_iparWPs) {
875 return accept;
876 }
877 ATH_MSG_ERROR("Someting here makes really no sense");
879}
880
882 if (x.type == xAOD::Type::Electron) {
885 return accept;
886 } else if (x.type == xAOD::Type::Muon) {
889 return accept;
890 } else if (x.type == xAOD::Type::Photon) {
893 return accept;
894 } else {
897 return accept;
898 }
900}
901
905
909
916
918 const std::vector<double>& boundaries,
919 const std::vector<std::vector<double>>& parameters, bool isOpen) const {
920
921 if (isOpen && boundaries.size() != parameters.size() - 1) {
923 "The number of region boundaries must be one less than the number of "
924 "parameters for the piecewise polynomial function.");
925 return "";
926 } else if (!isOpen && boundaries.size() != parameters.size() + 1) {
928 "The number of region boundaries must be one more than the number of "
929 "parameters for the piecewise polynomial function.");
930 return "";
931 }
932
933 std::ostringstream oss;
934 oss << std::setprecision(16);
935
936 // a lambda for the polynomial expression
937 // one could remove the zeroes in the parameters vector
938 auto polynomial = [](const std::vector<double>& params) {
939 std::ostringstream oss;
940 oss << std::setprecision(16);
941 oss << "(";
942 for (size_t i = 0; i < params.size(); ++i) {
943 if (i > 0)
944 oss << " + ";
945 if (i == 0) {
946 oss << params[i]; // constant term
947 } else if (i == 1) {
948 oss << params[i] << " * x"; // linear term
949 } else { // higher order terms
950 oss << params[i] << " * pow(x, " << i << ")"; // higher order terms
951 }
952 }
953 oss << ")";
954 return oss.str();
955 };
956
957 // Start the function definition, using concateation of ternary operators
958 // if isOpen==false, just nullify the function before the first and after the
959 // last boundary just create a copy of params, and insert 0.0 at the beginning
960 // and end if isOpen==false
961 std::vector<std::vector<double>> params = parameters;
962 if (!isOpen) {
963 params.insert(params.begin(), {0.0}); // add a zero vector at the beginning
964 params.push_back({0.0}); // add a zero vector at the end
965 }
966
967 // now loop over the boundaries and parameters (we can ignore isOpen finally)
968 for (size_t i = 0; i < boundaries.size(); ++i) {
969 if (i == 0)
970 oss << "(";
971 oss << "(x < " << boundaries[i] << ") ? " << polynomial(params[i]) << " : ";
972 }
973 oss << polynomial(params.back()) << ")"; // last segment, no ternary operator
974
975 return oss.str();
976}
977
978} // namespace CP
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
std::string PathResolverFindCalibFile(const std::string &logical_file_name)
#define x
std::string histogram
Definition chains.cxx:52
Gaudi::Property< bool > m_doInterpM
Gaudi::Property< std::string > m_muWPname
Gaudi::Property< std::vector< std::string > > m_muWPvec
Gaudi::Property< std::vector< std::string > > m_phWPvec
SG::ReadDecorHandleKeyArray< xAOD::IParticleContainer > m_isoDecors
virtual ~IsolationSelectionTool()
Destructor.
virtual const asg::AcceptInfo & getObjAcceptInfo() const override
void evaluateWP(const T &x, const std::vector< std::unique_ptr< IsolationWP > > &WP, asg::AcceptData &accept) const
Gaudi::Property< std::string > m_inElecContainer
Gaudi::Property< std::string > m_isoDecSuffix
asg::AcceptInfo m_photonAccept
AcceptInfo's.
StatusCode addMuonWP(const std::string &wpname)
virtual const asg::AcceptInfo & getMuonAcceptInfo() const override
std::vector< std::unique_ptr< IsolationWP > > m_muWPs
internal use
Gaudi::Property< bool > m_doInterpE
std::string createPieceWisePolinomialFunction(const std::vector< double > &boundaries, const std::vector< std::vector< double > > &parameters, bool isOpen=false) const
Gaudi::Property< std::string > m_phWPname
StatusCode addUserDefinedWP(const std::string &WPname, xAOD::Type::ObjectType ObjType, std::vector< std::pair< xAOD::Iso::IsolationType, std::string > > &cuts, std::string key="", IsoWPType type=Efficiency)
virtual StatusCode initialize() override
Function initialising the tool.
IsolationSelectionTool(const std::string &name)
Create a proper constructor for Athena.
std::vector< std::unique_ptr< IsolationWP > > m_objWPs
StatusCode addWP(const std::string &WP, xAOD::Type::ObjectType type)
std::unique_ptr< TFile > m_calibFile
Gaudi::Property< std::string > m_elWPname
void addDependencies(const std::string &container, const IsolationWP &wp)
IsoWPType
Function finalizing the tool.
virtual const std::vector< std::unique_ptr< IsolationWP > > & getElectronWPs() const override
std::shared_ptr< Interp3D > m_Interp
Gaudi::Property< std::string > m_calibFileName
input file
virtual const std::vector< std::unique_ptr< IsolationWP > > & getMuonWPs() const override
virtual asg::AcceptData accept(const xAOD::Photon &x) const override
Declare the interface that the class provides.
std::unique_ptr< TFile > m_WPdefinitionFile
StatusCode addCutToWP(IsolationWP *wp, const std::string &key_in, const xAOD::Iso::IsolationType t, const std::string &expression, const xAOD::Iso::IsolationType isoCutRemap)
std::vector< std::unique_ptr< IsolationWP > > * m_iparWPs
Iparticle interface.
virtual const asg::AcceptInfo & getPhotonAcceptInfo() const override
Gaudi::Property< std::string > m_phWPKey
std::vector< std::unique_ptr< IsolationWP > > m_phWPs
virtual const std::vector< std::unique_ptr< IsolationWP > > & getObjWPs() const override
Gaudi::Property< std::string > m_filePathName
cvfms path for files containing WP definitions (e.g. for TGraphs)
Gaudi::Property< std::vector< std::string > > m_elWPvec
virtual StatusCode setIParticleCutsFrom(xAOD::Type::ObjectType ObjType) override
virtual const std::vector< std::unique_ptr< IsolationWP > > & getPhotonWPs() const override
std::vector< std::unique_ptr< IsolationWP > > m_elWPs
virtual const asg::AcceptInfo & getElectronAcceptInfo() const override
StatusCode addElectronWP(const std::string &wpname)
Gaudi::Property< std::string > m_inPhotContainer
Gaudi::Property< std::string > m_elWPKey
StatusCode addPhotonWP(const std::string &wpname)
Gaudi::Property< std::string > m_inMuonContainer
Properties to declare the data dependencies to the avalanche scheduler.
Gaudi::Property< std::string > m_muWPKey
static AuxTypeRegistry & instance()
Return the singleton registry instance.
int addCut(const std::string &cutName, const std::string &cutDescription)
Add a cut; returning the cut position.
Definition AcceptInfo.h:53
AsgTool(const std::string &name)
Constructor specifying the tool instance's name.
Definition AsgTool.cxx:58
const std::string & getName(const void *ptr) const
Get the name of an object that is / should be in the event store.
Definition AsgTool.cxx:106
Class providing the definition of the 4-vector interface.
std::vector< std::string > veto
these patterns are anded
Definition listroot.cxx:191
Select isolated Photons, Electrons and Muons.
ObjectType
Type of objects that have a representation in the xAOD EDM.
Definition ObjectType.h:32
@ Photon
The object is a photon.
Definition ObjectType.h:47
@ Other
An object not falling into any of the other categories.
Definition ObjectType.h:34
@ Muon
The object is a muon.
Definition ObjectType.h:48
@ Electron
The object is an electron.
Definition ObjectType.h:46
IsolationType
Overall enumeration for isolation types in xAOD files.
@ ptvarcone30_Nonprompt_All_MaxWeightTTVA_pt1000
@ ptcone20_Nonprompt_All_MaxWeightTTVA_pt1000
@ ptcone20_Nonprompt_All_MaxWeightTTVA_pt500
Ptcone http://arxiv.org/abs/1007.2221 for high mu.
@ ptvarcone30_Nonprompt_All_MaxWeightTTVA_pt500
@ neflowisol20
Neutral eflow isolation.
@ ptcone20_Nonprompt_All_MaxWeightTTVALooseCone_pt500
Ptcone http://arxiv.org/abs/1007.2221 for high mu.
@ topoetcone20
Topo-cluster ET-sum.
@ ptcone20_Nonprompt_All_MaxWeightTTVALooseCone_pt1000
@ ptvarcone30_Nonprompt_All_MaxWeightTTVALooseCone_pt1000
@ ptcone20
Track isolation.
@ ptvarcone30_Nonprompt_All_MaxWeightTTVALooseCone_pt500
static const char * toCString(IsolationConeSize conesize)
Muon_v1 Muon
Reference the current persistent version:
Photon_v1 Photon
Definition of the current "egamma version".
static const SG::AuxElement::Accessor< ElementLink< IParticleContainer > > acc("originalObjectLink")
Object used for setting/getting the dynamic decoration in question.
Electron_v1 Electron
Definition of the current "egamma version".