ATLAS Offline Software
Loading...
Searching...
No Matches
TrigGlobalEfficiencyCorrectionTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5// contact: jmaurer@cern.ch
6
8
9#include <algorithm>
10#include <array>
11#include <cctype>
12#include <cmath>
13#include <limits>
14#include <regex>
15#include <sstream>
16#include <type_traits>
17
23#include "xAODEgamma/Electron.h"
24#include "xAODEgamma/Photon.h"
26
32
33TrigGlobalEfficiencyCorrectionTool::TrigGlobalEfficiencyCorrectionTool(
34 const std::string& name)
35 : asg::AsgTool(name),
36 m_trigMatchTool("", nullptr),
37 m_checkElectronLegTag(false),
38 m_checkMuonLegTag(false),
39 m_seed(1),
40 m_validTrigMatchTool(false),
41 m_runNumberDecorator("RandomRunNumber"),
42 m_calculator() {
43 declareProperty("ElectronEfficiencyTools", m_suppliedElectronEfficiencyTools,
44 "electron MC efficiency tools (one for each kind of electron "
45 "trigger leg)");
46 declareProperty("ElectronScaleFactorTools",
47 m_suppliedElectronScaleFactorTools,
48 "electron scale factor tools (one for each kind of electron "
49 "trigger leg)");
50 declareProperty(
51 "PhotonEfficiencyTools", m_suppliedPhotonEfficiencyTools,
52 "photon MC efficiency tools (one for each kind of photon trigger leg)");
53 declareProperty(
54 "PhotonScaleFactorTools", m_suppliedPhotonScaleFactorTools,
55 "photon scale factor tools (one for each kind of photon trigger leg)");
56 declareProperty("MuonTools", m_suppliedMuonTools,
57 "muon efficiency/scale factor tool (one per year)");
58 declareProperty("ListOfLegsPerTool", m_legsPerTool,
59 "comma-separated list of trigger legs supported by each "
60 "electron or photon tool");
61 declareProperty("TriggerCombination", m_triggerCb,
62 "map of trigger combination per period and/or range of runs");
63 for (int y : {15, 16, 17, 18, 22, 23, 24, 25, 26}) {
64 std::string year = std::to_string(2000 + y);
65 declareProperty("TriggerCombination" + year, m_triggerCbPerYear[year] = "",
66 "trigger combination \"trigger1 || trigger2 || ...\"");
67 }
68 declareProperty("LeptonTagDecorations", m_leptonTagDecorations = "",
69 "comma-separated list of decorations for the lepton "
70 "selection tags, ordered by increasing tightness. "
71 "If a name ends with =, the tag is the decorated value, "
72 "otherwise it is the decoration name");
73 declareProperty(
74 "ListOfTagsPerTool", m_tagsPerTool,
75 "comma-separated list of lepton selection tags associated to each tool");
76 declareProperty("ElectronLegsPerTag", m_electronLegsPerTag,
77 "DEPRECATED, use ListOfLegsPerTag instead");
78 declareProperty("MuonLegsPerTag", m_muonLegsPerTag,
79 "DEPRECATED, use ListOfLegsPerTag instead");
80 declareProperty("ListOfLegsPerTag", m_legsPerTag,
81 "map of allowed trigger legs for each tag");
82 declareProperty(
83 "NumberOfToys", m_numberOfToys = 0,
84 "if different from 0, use toy experiments instead of explicit formulas");
85 declareProperty("OverrideThresholds", m_overrideThresholds,
86 "new thresholds (in MeV) for the plateaux of the indicated "
87 "trigger legs -- use at your own risk!");
88 declareProperty("UseInternalSeed", m_useInternalSeed = false,
89 "do not use event number as random number generation seed");
90 declareProperty("TriggerMatchingTool", m_trigMatchTool,
91 "handle to an IMatchingTool instance");
92
93 m_cpCode.ignore();
94}
95
99
101 if (m_initialized) {
102 ATH_MSG_ERROR("Tool has already been initialized");
103 return StatusCode::FAILURE;
104 }
105 ATH_MSG_INFO("Initializing " << name() << "...");
106
107 m_dictionary.emplace(0, "");
108
110 return StatusCode::FAILURE;
111
112 ATH_MSG_DEBUG("Importing data from configuration files");
113 ImportData data(*this);
114 if (!data.importAll(m_overrideThresholds))
115 return StatusCode::FAILURE;
117 m_hierarchyMeta = data.getHierarchyMeta();
118 m_hierarchyData = data.getHierarchyData();
119 m_thresholds = data.getTriggerThresholds();
120
121 ATH_MSG_DEBUG("Retrieving tools");
122 if (m_suppliedElectronEfficiencyTools.retrieve() != StatusCode::SUCCESS ||
123 m_suppliedElectronScaleFactorTools.retrieve() != StatusCode::SUCCESS ||
124 m_suppliedMuonTools.retrieve() != StatusCode::SUCCESS ||
125 m_suppliedPhotonEfficiencyTools.retrieve() != StatusCode::SUCCESS ||
126 m_suppliedPhotonScaleFactorTools.retrieve() != StatusCode::SUCCESS) {
127 ATH_MSG_ERROR("Unable to retrieve CP tools");
128 return StatusCode::FAILURE;
129 }
130
131 ATH_MSG_DEBUG("Retrieving trigger matching tool (if provided)");
132 m_validTrigMatchTool = false;
133 if (m_trigMatchTool.name() != "") {
134 if (m_trigMatchTool.retrieve() != StatusCode::SUCCESS) {
135 ATH_MSG_ERROR("Unable to retrieve trigger matching tool");
136 return StatusCode::FAILURE;
137 }
138 ATH_MSG_DEBUG("Trigger matching support enabled");
140 }
141
142 ATH_MSG_DEBUG("Basic checks");
143 CheckConfig checks(*this);
144 if (!checks.basicConfigChecks())
145 return StatusCode::FAILURE;
146
147 ATH_MSG_DEBUG("Enumerating tools");
148 flat_set<std::size_t> collectedElectronTags, collectedMuonTags,
149 collectedPhotonTags;
151 m_electronEffToolIndex, collectedElectronTags) ||
153 m_electronSfToolIndex, collectedElectronTags) ||
155 collectedMuonTags) ||
157 m_photonEffToolIndex, collectedPhotonTags) ||
159 m_photonSfToolIndex, collectedPhotonTags)) {
160 return StatusCode::FAILURE;
161 }
162 // List legs (if any) for which a dummy scale factor should be returned.
164 if (itr != m_legsPerTool.end()) {
165 bool success = true;
166 for (ToolKey leg : parseListOfLegs(data, itr->second, success)) {
167 m_unsupportedLegs.insert(leg);
168 }
169 }
170
171 ATH_MSG_DEBUG("Loading user-defined trigger combination");
172 bool useDefaultElectronTools =
173 (m_suppliedElectronEfficiencyTools.size() == 1) &&
175 (m_legsPerTool.size() == 0);
176 bool useDefaultPhotonTools = (m_suppliedPhotonEfficiencyTools.size() == 1) &&
177 (m_suppliedPhotonScaleFactorTools.size() == 1) &&
178 (m_legsPerTool.size() == 0);
179 if (!loadTriggerCombination(data, useDefaultElectronTools,
180 useDefaultPhotonTools))
181 return StatusCode::FAILURE;
182
183 ATH_MSG_DEBUG("Loading lepton selection tags decorators");
184 if (!loadTagDecorators(collectedElectronTags, collectedMuonTags,
185 collectedPhotonTags))
186 return StatusCode::FAILURE;
187
188 ATH_MSG_DEBUG("Loading list of legs allowed for each tag");
190 return StatusCode::FAILURE;
191
192 ATH_MSG_DEBUG("Advanced checks");
193 if (!checks.advancedConfigChecks())
194 return StatusCode::FAILURE;
195
196 ATH_MSG_INFO("Initialization successful");
197 m_initialized = true;
198 return StatusCode::SUCCESS;
199}
200
202 if (m_electronLegsPerTag.size()) {
204 "The property 'ElectronLegsPerTag' is deprecated, please use "
205 "'ListOfLegsPerTag' instead");
206 for (auto& kv : m_electronLegsPerTag) {
207 auto insert = m_legsPerTag.insert(kv);
208 if (!insert.second)
209 insert.first->second += "," + kv.second;
210 }
211 }
212 if (m_muonLegsPerTag.size()) {
214 "The property 'MuonLegsPerTag' is deprecated, please use "
215 "'ListOfLegsPerTag' instead");
216 for (auto& kv : m_muonLegsPerTag) {
217 auto insert = m_legsPerTag.insert(kv);
218 if (!insert.second)
219 insert.first->second += "," + kv.second;
220 }
221 }
222 return true;
223}
224
226 const std::string& tagstring, flat_set<std::size_t>& allTags) {
227 bool success = true;
228 const std::size_t star = m_hasher("*");
229 for (std::size_t tag : listNonOrderedCSValues(tagstring, success)) {
230 allTags.insert((tag != star) ? tag : 0);
231 }
232 if (!success) {
233 ATH_MSG_ERROR("List of tags \"" << tagstring
234 << "\" is not provided in a valid format");
235 }
236 return success;
237}
238
239template <class CPTool>
241 ImportData& data, ToolHandleArray<CPTool>& suppliedTools,
242 std::map<ToolKey, std::size_t>& toolIndex,
243 flat_set<std::size_t>& collectedTags) {
244 bool success = true;
245 for (unsigned index = 0; index < suppliedTools.size(); ++index) {
246 auto& handle = suppliedTools[index];
247 const std::string& name = handle.name();
248 const std::string& altname = handle->name(); // athena: not always the same
249 flat_set<ToolKey> listOfLegs;
251 if (suppliedTools.size() != 1 || m_legsPerTool.size() != 0) {
252 auto itrLegs = m_legsPerTool.find(name);
253 if (itrLegs == m_legsPerTool.end())
254 itrLegs = m_legsPerTool.find(altname);
255 if (itrLegs != m_legsPerTool.end()) {
256 listOfLegs = parseListOfLegs(data, itrLegs->second, success);
257 if (!success) {
259 "The 'ListOfLegsPerTool' property has an invalid entry for the "
260 "tool'"
261 << name << "'");
262 continue;
263 }
264 } else if (std::is_same<CPTool,
266 std::is_same<CPTool,
268 ATH_MSG_ERROR("Property 'ListOfLegsPerTool' empty for tool '" << name
269 << "'");
270 success = false;
271 continue;
272 } else {
273 listOfLegs.emplace();
274 }
275 } else
276 listOfLegs.emplace();
279 auto itrTags = m_tagsPerTool.find(name);
280 if (itrTags == m_tagsPerTool.end())
281 itrTags = m_tagsPerTool.find(altname);
282 if (itrTags != m_tagsPerTool.end()) {
283 success = success && parseTagString(itrTags->second, tags);
284 collectedTags.insert(tags.begin(), tags.end());
285 } else
286 tags.emplace(0);
287
289 unsigned short nUncheckedLegs = 0;
290 for (auto& key : listOfLegs) {
291 std::size_t leg = key.hash;
292 if (leg) {
293 auto flavour = data.associatedLeptonFlavour(leg, success);
294 if (!(flavour == xAOD::Type::Electron &&
295 std::is_same<CPTool,
297 !(flavour == xAOD::Type::Photon &&
298 std::is_same<CPTool,
300 ATH_MSG_ERROR("Unexpected association of trigger leg '"
301 << m_dictionary[leg] << "' to tool '" << name << "'");
302 success = false;
303 }
304 }
305 for (std::size_t tag : tags) {
306 if (!toolIndex.emplace(ToolKey(leg, tag, key.boundaries), index)
307 .second) {
308 if (leg && tag)
309 ATH_MSG_ERROR("Multiple tools associated to the selection tag '"
310 << m_dictionary[tag] << "' for the trigger leg '"
311 << m_dictionary[leg] << "'");
312 else if (leg)
313 ATH_MSG_ERROR("Multiple tools associated to the trigger leg '"
314 << m_dictionary[leg] << "'");
315 else if (tag)
316 ATH_MSG_ERROR("Multiple tools associated to the selection tag '"
317 << m_dictionary[tag] << "'");
318 else
320 "Multiple tools not associated to any trigger leg / selection "
321 "tag");
322 success = false;
323 }
324 }
325 ++nUncheckedLegs;
326 }
327 if (!nUncheckedLegs) {
328 ATH_MSG_ERROR("Tool " << name
329 << " hasn't been associated to any trigger leg");
330 success = false;
331 }
332 }
333 return success;
334}
335
337 ImportData& data, const std::string& inputList, bool& success)
339 if (!inputList.length())
340 return {};
341 std::regex rx(
342 "\\s*([[:alnum:]_]+)\\s*(?:\\[\\s*([^,\\[\\]]+)\\s*\\]\\s*)?(?:,|$)");
344 std::smatch sm;
345 auto itr = inputList.cbegin();
346 do {
347 if (sm.ready())
348 itr += sm.length();
349 if (!std::regex_search(itr, inputList.cend(), sm, rx) ||
350 sm.prefix().length()) {
351 ATH_MSG_ERROR("Invalid format for the property \"ListOfLegsPerTool\"");
352 success = false;
353 break;
354 }
355 std::size_t leg = m_hasher(sm[1].str());
356 if (m_thresholds.find(leg) == m_thresholds.end()) {
357 ATH_MSG_ERROR("Unknown trigger leg '"
358 << sm[1].str() << "' found in 'ListOfLegsPerTool'");
359 success = false;
360 continue;
361 }
362 ToolKey key(leg, 0);
363 if (sm.length(2)) {
364 if (!data.getPeriodBoundaries(sm[2].str(), key.boundaries)) {
365 ATH_MSG_ERROR("Invalid period \""
366 << sm[2].str()
367 << "\"found in the property \"ListOfLegsPerTool\"");
368 success = false;
369 continue;
370 }
371 }
372 if (!keys.emplace(key).second) {
373 ATH_MSG_ERROR("Trigger leg '"
374 << sm[1].str()
375 << "' mentioned several times with overlapping time "
376 "periods in the property 'ListOfLegsPerTool'");
377 success = false;
378 continue;
379 }
380 } while (sm.suffix().length());
381 return keys;
382}
383
385 ImportData& data, bool useDefaultElectronTools,
386 bool useDefaultPhotonTools) {
387 bool success = true, mustBeEmpty = m_triggerCb.size();
388 for (auto& kv : m_triggerCbPerYear) {
389 if (!kv.second.size())
390 continue;
391 if (mustBeEmpty) {
393 "You're not allowed to use simultaneously the 'TriggerCombination' "
394 "and 'TriggerCombination"
395 << kv.first << "' properties.");
396 return false;
397 }
398 m_triggerCb.insert(kv);
399 }
400
401 m_calculator = std::make_unique<Calculator>(*this, m_triggerCb.size());
402 std::set<std::size_t> allUniqueElectronLegs, allUniquePhotonLegs;
403 for (auto& kv : m_triggerCb) {
404 std::pair<unsigned, unsigned> boundaries;
405 if (!data.getPeriodBoundaries(kv.first, boundaries)) {
406 success = false;
407 continue;
408 }
409 std::size_t uniqueElectronLeg = !useDefaultElectronTools,
410 uniquePhotonLeg = !useDefaultPhotonTools;
411 if (!m_calculator->addPeriod(data, boundaries, kv.second, m_numberOfToys,
412 uniqueElectronLeg, uniquePhotonLeg)) {
413 success = false;
414 continue;
415 }
416 if (uniqueElectronLeg && useDefaultElectronTools)
417 allUniqueElectronLegs.insert(uniqueElectronLeg);
418 if (uniquePhotonLeg && useDefaultPhotonTools)
419 allUniquePhotonLegs.insert(uniquePhotonLeg);
420 }
421 if (!success)
422 return false;
423
424 auto remapTools = [](auto& toolIndex, auto& allUniqueLegs) {
425 typename std::remove_reference<decltype(toolIndex)>::type remappedToolIndex;
426 for (std::size_t leg : allUniqueLegs) {
427 if (!leg)
428 continue;
429 for (auto& kv : toolIndex) {
432 const ToolKey& key = kv.first;
433 remappedToolIndex.emplace(ToolKey(leg, key.hash, key.boundaries),
434 kv.second);
435 }
436 }
437 toolIndex.swap(remappedToolIndex);
438 };
439
440 if (useDefaultElectronTools && allUniqueElectronLegs.size()) {
441 remapTools(m_electronSfToolIndex, allUniqueElectronLegs);
442 remapTools(m_electronEffToolIndex, allUniqueElectronLegs);
443 }
444 if (useDefaultPhotonTools && allUniquePhotonLegs.size()) {
445 remapTools(m_photonSfToolIndex, allUniquePhotonLegs);
446 remapTools(m_photonEffToolIndex, allUniquePhotonLegs);
447 }
448 return success;
449}
450
452 const flat_set<std::size_t>& collectedElectronTags,
453 const flat_set<std::size_t>& collectedMuonTags,
454 const flat_set<std::size_t>& collectedPhotonTags) {
455 bool success = true;
456
457 flat_set<std::size_t> collectedTags(collectedElectronTags);
458 collectedTags.insert(collectedMuonTags.begin(), collectedMuonTags.end());
459 collectedTags.insert(collectedPhotonTags.begin(), collectedPhotonTags.end());
460 flat_set<std::size_t> allTags = collectedTags;
461
465 std::stringstream ss(
467 std::string decoration;
468 flat_set<std::size_t> allDecorations;
469 while (std::getline(ss, decoration, ',')) {
470 if (!decoration.length() || decoration == "?") {
472 "Found an empty string in the 'LeptonTagDecorations' property");
473 success = false;
474 break;
475 }
476
477 bool found = false, suffixed = false;
478 std::size_t h;
479 if (decoration.back() != '?') {
481 h = m_hasher(decoration);
482 found = (allTags.find(h) != allTags.end());
483 } else {
485 decoration.pop_back();
486 suffixed = true;
487 for (std::size_t tag :
488 allTags)
489 {
490 auto& s = m_dictionary[tag];
491 if (s.find(decoration) != 0)
492 continue;
493 if (std::all_of(s.begin() + decoration.length(), s.end(),
494 [](char c) { return std::isdigit(c); })) {
495 found = true;
496 break;
497 }
498 }
499 h = m_hasher(decoration);
500 }
501 if (!allDecorations.insert(h).second) {
503 "The selection tag '"
504 << decoration
505 << "' is listed twice in the property 'LeptonTagDecorations'");
506 success = false;
507 continue;
508 }
509 if (!found) {
511 "the selection tag '"
512 << decoration
513 << "' is only referred to in the property 'LeptonTagDecorations'");
514 success = false;
515 continue;
516 }
517 m_leptonTagDecorators.emplace_back(decoration, h, suffixed);
518 m_dictionary.emplace(h, decoration);
519 }
521 if (!success)
522 return false;
523
526 for (std::size_t tag : collectedTags) {
527 if (!tag)
528 continue;
529 auto itr =
530 std::find_if(m_leptonTagDecorators.begin(), m_leptonTagDecorators.end(),
531 [tag](const TagDecorator& ltd) {
532 return (!ltd.suffixed) && (ltd.hash == tag);
533 });
534 if (itr != m_leptonTagDecorators.end())
535 continue;
536 bool found = false;
537 auto& s = m_dictionary[tag];
538 for (auto& ltd : m_leptonTagDecorators) {
539 auto& name = m_dictionary[ltd.hash];
540 if (s.find(name) != 0)
541 continue;
542 if (std::all_of(s.begin() + name.length(), s.end(),
543 [](char c) { return std::isdigit(c); })) {
544 found = true;
545 break;
546 }
547 }
548 if (!found) {
549 ATH_MSG_ERROR("the selection tag '"
550 << m_dictionary[tag]
551 << "' hasn't been found in in 'LeptonTagDecorations'");
552 success = false;
553 continue;
554 }
555 }
556 if (!success)
557 return false;
558
559 return success;
560}
561
563 bool success = true;
564
567 for (auto& kv : m_legsPerTag) {
568 std::size_t tag;
569 if (!kv.first.size() || kv.first == "*")
570 tag = 0;
571 else
572 tag = m_hasher(kv.first);
573 auto listOfLegs = listNonOrderedCSValues(kv.second, success);
574 if (!success) {
576 "The property 'ListOfLegsPerTag' has an invalid entry for the tag '"
577 << kv.first << "'");
578 break;
579 }
580 for (std::size_t leg : listOfLegs) {
581 auto type =
583 if (type == xAOD::Type::Electron &&
584 m_electronSfToolIndex.find(ToolKey(leg, tag)) ==
585 m_electronSfToolIndex.end()) {
586 ATH_MSG_ERROR("No electron tool has been provided for trigger leg '"
587 << m_dictionary[leg] << "' and selection tag " << kv.first
588 << " mentioned in the property 'ListOfLegsPerTag'");
589 success = false;
590 } else if (type == xAOD::Type::Muon &&
591 m_muonToolIndex.find(ToolKey(0, tag)) ==
592 m_muonToolIndex.end()) {
593 ATH_MSG_ERROR("No muon tool has been provided for selection tag "
594 << kv.first
595 << " mentioned in the property 'ListOfLegsPerTag'");
596 success = false;
597 } else if (type == xAOD::Type::Photon &&
598 m_photonSfToolIndex.find(ToolKey(leg, tag)) ==
599 m_photonSfToolIndex.end()) {
600 ATH_MSG_ERROR("No photon tool has been provided for trigger leg '"
601 << m_dictionary[leg] << "' and selection tag " << kv.first
602 << " mentioned in the property 'ListOfLegsPerTag'");
603 success = false;
604 }
605 if (m_validLegTagPairs.insert(leg ^ tag).second) {
608 if (type == xAOD::Type::Muon)
609 m_checkMuonLegTag = true;
611 m_checkPhotonLegTag = true;
612 } else {
613 ATH_MSG_ERROR("The combination of trigger leg '"
614 << m_dictionary[leg] << "' and selection tag " << kv.first
615 << " is mentioned more than once in the property "
616 "'ListOfLegsPerTag'");
617 success = false;
618 }
619 }
620 }
621 if (!success)
622 return false;
623
624 return success;
625}
626
628 CP::CorrectionCode&& cc) {
629 cc.setChecked();
630 if (cc > m_cpCode)
631 m_cpCode = cc;
632 return cc == CP::CorrectionCode::Ok;
633}
634
639 const std::string& s, bool& success) -> flat_set<std::size_t> {
640 std::stringstream ss(TrigGlobEffCorr::removeWhitespaces(s));
642 std::string token;
643 while (std::getline(ss, token, ',')) {
644 if (token.length()) {
645 std::size_t h = m_hasher(token);
646 if (hashes.insert(h).second) {
647 m_dictionary.emplace(h, std::move(token));
648 } else {
649 success = false;
651 "Found duplicate entry while parsing comma-separated list '"
652 << s << "'");
653 }
654 } else {
655 success = false;
657 "Found null-length entry while parsing comma-separated list '"
658 << s << "'");
659 }
660 }
661 if (!success)
662 hashes.clear();
663 return hashes;
664}
665
666template <class ParticleType>
668 const ParticleType* p, unsigned runNumber, std::size_t leg, std::size_t tag,
669 Efficiencies& efficiencies) -> TLE_RESULT {
671 auto ptype = []() {
672 return std::is_same<ParticleType, xAOD::Electron>::value ? "electron"
673 : std::is_same<ParticleType, xAOD::Photon>::value ? "photon"
674 : "<unknown type>";
675 };
676 auto pp = static_cast<const xAOD::IParticle*>(p);
677 ATH_MSG_DEBUG("Retrieving efficiencies for "
678 << ptype() << ' ' << p << " (pt=" << pp->pt()
679 << ", eta=" << pp->eta() << ", tag='" << m_dictionary[tag]
680 << "') for trigger leg " << m_dictionary[leg]);
681 auto itrSf = GetScaleFactorToolIndex(p).find(ToolKey(leg, tag, runNumber));
682 auto itrEff = GetEfficiencyToolIndex(p).find(ToolKey(leg, tag, runNumber));
683 if (itrSf == GetScaleFactorToolIndex(p).end() ||
684 itrEff == GetEfficiencyToolIndex(p).end()) {
685 if (m_unsupportedLegs.count(ToolKey(leg, 0u, runNumber))) {
686 efficiencies.data() = 0.5;
687 efficiencies.mc() = 0.5;
688 return TLE_UNAVAILABLE;
689 }
690 if (!tag)
691 ATH_MSG_ERROR("Unable to find "
692 << ptype() << " tools needed for trigger leg "
693 << m_dictionary[leg] << " (run number = " << runNumber
694 << ")");
695 else
696 ATH_MSG_ERROR("Unable to find "
697 << ptype() << " tools needed for trigger leg "
698 << m_dictionary[leg] << " and selection tag "
699 << m_dictionary[tag] << " (run number = " << runNumber
700 << ")");
701 return TLE_ERROR;
702 }
703 double sf;
704 bool success =
705 checkAndRecord(GetScaleFactorTool(p, itrSf->second)
706 .getEfficiencyScaleFactor(*p, sf)) &&
707 checkAndRecord(GetEfficiencyTool(p, itrEff->second)
708 .getEfficiencyScaleFactor(*p, efficiencies.mc()));
709 efficiencies.data() = sf * efficiencies.mc();
710 ATH_MSG_DEBUG("found for that " << ptype()
711 << " eff(data) = " << efficiencies.data()
712 << " and eff(MC) = " << efficiencies.mc());
713 return success ? TLE_OK : TLE_ERROR;
714}
715
717 const xAOD::Electron* p, unsigned runNumber, std::size_t leg,
718 std::size_t tag, Efficiencies& efficiencies) -> TLE_RESULT {
719 return getEgammaTriggerLegEfficiencies(p, runNumber, leg, tag, efficiencies);
720}
721
723 const xAOD::Photon* p, unsigned runNumber, std::size_t leg, std::size_t tag,
724 Efficiencies& efficiencies) -> TLE_RESULT {
725 return getEgammaTriggerLegEfficiencies(p, runNumber, leg, tag, efficiencies);
726}
727
729 const xAOD::Muon* p, unsigned runNumber, std::size_t leg, std::size_t tag,
730 Efficiencies& efficiencies) -> TLE_RESULT {
731 ATH_MSG_DEBUG("Retrieving efficiencies for muon "
732 << p << " (pt=" << p->pt() << ", eta=" << p->eta() << ", tag='"
733 << m_dictionary[tag] << "') for trigger leg "
734 << m_dictionary[leg]);
735 if (m_unsupportedLegs.size() &&
736 m_unsupportedLegs.count(ToolKey(leg, 0u, runNumber))) {
737 efficiencies.data() = 0.5;
738 efficiencies.mc() = 0.5;
739 return TLE_UNAVAILABLE;
740 }
741 auto itr = m_muonToolIndex.find(ToolKey(0, tag, 0));
742 if (itr == m_muonToolIndex.end()) {
743 if (!tag)
744 ATH_MSG_ERROR("Unable to find muon tool");
745 else
746 ATH_MSG_ERROR("Unable to find muon tool needed for selection tag "
747 << m_dictionary[tag]);
749 return TLE_ERROR;
750 }
751 auto& tool = *m_suppliedMuonTools[itr->second];
752 auto& hltTrig = m_dictionary[leg ^ 0xB0DDD56fF8E3250D];
753 if (!hltTrig.size()) {
754 hltTrig = "HLT_" + m_dictionary[leg];
755 while (true) {
756 std::size_t i = hltTrig.find("_OR_m");
757 if (i == std::string::npos)
758 break;
759 hltTrig.insert(i + 4, "HLT_", 4);
760 }
761 }
762 bool success = checkAndRecord(tool.getTriggerEfficiency(*p, efficiencies.mc(),
763 hltTrig, kFALSE)) &&
764 checkAndRecord(tool.getTriggerEfficiency(
765 *p, efficiencies.data(), hltTrig, kTRUE));
766 ATH_MSG_DEBUG("found for that muon eff(data) = " << efficiencies.data()
767 << " and eff(MC) = "
768 << efficiencies.mc());
769 return success ? TLE_OK : TLE_ERROR;
770}
771
773 unsigned& runNumber) {
774 runNumber = 0;
775 auto eventInfo = evtStore()->retrieve<const xAOD::EventInfo>("EventInfo");
776 if (!eventInfo) {
777 ATH_MSG_ERROR("Can't retrieve 'EventInfo' from evtStore()");
778 return false;
779 }
780 if (eventInfo->eventType(xAOD::EventInfo::IS_SIMULATION)) {
781 if (!m_runNumberDecorator.isAvailable(*eventInfo)) {
782 ATH_MSG_ERROR("Can't retrieve 'RandomRunNumber' from EventInfo");
783 return false;
784 }
785 runNumber = m_runNumberDecorator(*eventInfo);
786 } else
787 runNumber = eventInfo->runNumber();
788 return true;
789}
790
792 unsigned long& eventNumber) {
793 auto eventInfo = evtStore()->retrieve<const xAOD::EventInfo>("EventInfo");
794 if (!eventInfo) {
795 ATH_MSG_WARNING("Can't retrieve event number from evtStore()");
796 eventNumber = 0;
797 return false;
798 }
799 eventNumber = eventInfo->eventNumber();
800 return true;
801}
802
803template <class Particle>
805 LeptonList& leptons, const std::vector<const Particle*>& particles) {
806 for (auto lep : particles) {
807 std::size_t tag = 0;
808 for (auto& ltd : m_leptonTagDecorators) {
809 if (ltd.decorator.isAvailable(*lep)) {
810 char v = ltd.decorator(*lep);
811 if (v) {
812 if (ltd.suffixed)
813 {
814 std::string s = m_dictionary.at(ltd.hash) + std::to_string(v);
815 tag = m_hasher(s);
816 m_dictionary.emplace(tag, s);
817 } else
818 tag = ltd.hash;
819 }
820 }
821 }
822 leptons.emplace_back(lep, tag);
823 }
824 return true;
825}
826
828 const std::vector<const xAOD::IParticle*>& leptons,
829 double& efficiencyScaleFactor) {
830 unsigned runNumber;
831 if (!retrieveRunNumber(runNumber))
833 return getEfficiencyScaleFactor(runNumber, leptons, efficiencyScaleFactor);
834}
835
837 const std::vector<const xAOD::IParticle*>& leptons, double& efficiencyData,
838 double& efficiencyMc) {
839 unsigned runNumber;
840 if (!retrieveRunNumber(runNumber))
842 return getEfficiency(runNumber, leptons, efficiencyData, efficiencyMc);
843}
844
846 unsigned runNumber, const std::vector<const xAOD::IParticle*>& particles,
847 double& efficiencyScaleFactor) {
850 efficiencyScaleFactor = 1.;
851
852 Efficiencies efficiencies;
853 auto cc = getEfficiency(runNumber, particles, efficiencies.data(),
854 efficiencies.mc());
855 if (cc == CP::CorrectionCode::Ok) {
856 if (efficiencies.data() > 0. && efficiencies.mc() > 0.) {
857 efficiencyScaleFactor = efficiencies.data() / efficiencies.mc();
859 } else {
860 efficiencyScaleFactor = 1.;
862 "Efficiencies do not seem valid, forcing the scale factor to 1.");
864 }
865 }
866 efficiencyScaleFactor = 1.;
867 return cc;
868}
869
871 unsigned runNumber, const std::vector<const xAOD::IParticle*>& particles,
872 double& efficiencyData, double& efficiencyMc) {
875 efficiencyData = 0.;
876 efficiencyMc = 0.;
877
878 ATH_MSG_DEBUG("Computing global trigger efficiency for this event with "
879 << particles.size()
880 << " lepton(s) as input; run number = " << runNumber);
881
882#ifdef XAOD_STANDALONE
883 if (!m_initialized) {
884 ATH_MSG_WARNING("Tool hasn't been initialized, trying now");
885 if (initialize() != StatusCode::SUCCESS) {
886 ATH_MSG_ERROR("Giving up.");
887 m_cpCode.ignore();
889 }
890 }
891#endif
892
893 LeptonList leptons;
894 updateLeptonList(leptons, particles);
895
896 Efficiencies efficiencies;
897 if (m_calculator->compute(*this, leptons, runNumber, efficiencies)) {
898 efficiencyData = efficiencies.data();
899 efficiencyMc = efficiencies.mc();
900 if (std::isnan(efficiencies.data()) || efficiencies.data() <= 0. ||
901 std::isnan(efficiencies.mc()) || efficiencies.mc() <= 0.) {
902 ATH_MSG_WARNING("Efficiencies do not seem valid");
903 m_cpCode.ignore();
905 }
906 } else {
909 }
910 }
911 return m_cpCode;
912}
913
915 bool& matched,
916 const std::vector<const xAOD::IParticle*>& particles) {
917 unsigned runNumber;
918 if (!retrieveRunNumber(runNumber)) {
920 "Unable to retrieve run number, aborting checkTriggerMatching()");
922 }
925 "A valid IMatchingTool instance should be provided via the property "
926 "'TriggerMatchingTool'");
928 }
929 LeptonList leptons;
930 updateLeptonList(leptons, particles);
931 return m_calculator->checkTriggerMatching(*this, matched, nullptr, leptons, runNumber)
934}
935
937 std::unordered_map<std::string, bool>& matched_per_trigger,
938 const std::vector<const xAOD::IParticle*>& particles) {
939 unsigned runNumber;
940 if (!retrieveRunNumber(runNumber)) {
942 "Unable to retrieve run number, aborting checkTriggerMatching()");
944 }
947 "A valid IMatchingTool instance should be provided via the property "
948 "'TriggerMatchingTool'");
950 }
951 LeptonList leptons;
952 updateLeptonList(leptons, particles);
953 bool flag;
954 return m_calculator->checkTriggerMatching(*this, flag, &matched_per_trigger, leptons, runNumber)
957}
958
960 std::vector<std::string>& triggers) {
961 unsigned runNumber;
962 if (!retrieveRunNumber(runNumber)) {
964 "Unable to retrieve run number, aborting getRelevantTriggers()");
966 }
967 return m_calculator->getRelevantTriggersForUser(*this, triggers, runNumber)
970}
971
973 const std::string& trigger, std::size_t& numberOfLegs) {
974 numberOfLegs = 0;
979 constexpr std::size_t magic = 0xa3bad03e613527c9;
980 const std::size_t name = m_hasher(trigger), key = name ^ magic;
981 std::string& value = m_dictionary[key];
982 if (!value.length()) {
984 if (!data.importTriggers())
986 auto itr = data.getTriggerDefs().find(name);
987 if (itr == data.getTriggerDefs().end()) {
988 m_dictionary.erase(key);
989 ATH_MSG_ERROR("The trigger " << trigger << " is not recognized");
991 }
992 auto type = itr->second.type;
994 if (type & TriggerType::TT_SINGLELEPTON_FLAG)
995 value = "~";
996 else if (type & TriggerType::TT_DILEPTON_FLAG)
997 value = "~~";
998 else if (type & TriggerType::TT_TRILEPTON_FLAG)
999 value = "~~~";
1000 else {
1001 m_dictionary.erase(key);
1002 ATH_MSG_ERROR("Unrecognized trigger type, implementation must be fixed!");
1004 }
1005 }
1006 numberOfLegs = value.length();
1008}
1009
1011 std::size_t leg) const {
1012 bool decision = (lepton.pt() >= m_thresholds.at(leg));
1013 if (m_validLegTagPairs.size()) {
1014 if ((lepton.type() == xAOD::Type::Electron && m_checkElectronLegTag) ||
1015 (lepton.type() == xAOD::Type::Muon && m_checkMuonLegTag) ||
1016 (lepton.type() == xAOD::Type::Photon && m_checkPhotonLegTag)) {
1017 decision = decision && (m_validLegTagPairs.find(leg ^ lepton.tag()) !=
1018 m_validLegTagPairs.end());
1019 }
1020 }
1021 ATH_MSG_DEBUG("Lepton " << lepton.particle() << " (pt=" << lepton.pt()
1022 << ") is " << (decision ? "" : "not ")
1023 << "considered suitable for firing trigger leg "
1024 << m_dictionary.at(leg));
1025 return decision;
1026}
1027
1029 const flat_set<std::size_t>& legs) {
1030 if (legs.size() < 2)
1031 return 0;
1032 std::size_t combinedHash = 0;
1033 for (auto& leg : legs)
1034 combinedHash ^= leg;
1035 return combinedHash;
1036}
1037
1039 std::size_t leg1, std::size_t leg2) {
1040 return leg1 ^
1041 leg2;
1042}
1043
1045 const flat_set<std::size_t>& legs) -> const flat_set<std::size_t>& {
1046 return legs;
1047}
1048
1049inline constexpr std::array<std::size_t, 2>
1051 std::size_t leg2) {
1052 if (leg1 < leg2)
1053 return {leg1, leg2};
1054 else
1055 return {leg2, leg1};
1056}
1057
1058template <class... ListOfLegs>
1060 const Lepton& lepton, ListOfLegs... legs) {
1061 auto combinedHash = getCombinedHash(legs...);
1062 if (!combinedHash)
1063 return 0xFEDCBA9876543210; // only one (distinct) leg
1064 auto cachedRankings = m_cachedLegRankings.equal_range(combinedHash);
1065 auto rankingItr = cachedRankings.first;
1066 float pt = lepton.pt();
1067 while (rankingItr != cachedRankings.second &&
1068 (pt < rankingItr->second.minPt || pt >= rankingItr->second.maxPt))
1069 ++rankingItr;
1070 if (rankingItr == cachedRankings.second) {
1072 if (r)
1073 m_cachedLegRankings.emplace(combinedHash, r);
1074 return r.ranking;
1075 }
1076 return rankingItr->second.ranking;
1077}
1078
1079template <class Container>
1081 const Container& legs)
1082 -> CachedRanking {
1083 const std::size_t nLegs = legs.size();
1085 r.ranking = std::numeric_limits<decltype(r.ranking)>::max();
1086 r.minPt = 0.f;
1087 r.maxPt = std::numeric_limits<float>::max();
1088 if (nLegs >= 2 * sizeof(r.ranking)) {
1090 "Implementation currently doesn't support ranking of more than "
1091 << 2 * sizeof(r.ranking) << " trigger legs");
1092 return r;
1093 }
1094 std::vector<uint8_t> counts(nLegs);
1095
1099 auto legI = legs.begin();
1100 for (unsigned i = 0; i < nLegs; ++i) {
1101 auto legJ = legI;
1102 for (unsigned j = i + 1; j < nLegs; ++j) {
1103 ++legJ;
1104 bool found = false;
1105 for (auto& meta : m_hierarchyMeta) {
1106 if (pt < meta.minPt || pt >= meta.maxPt)
1107 continue;
1108 auto data = m_hierarchyData.begin() + meta.offset;
1109 auto end = data + meta.nLegs;
1110 auto a = std::find(data, end, *legI);
1111 if (a == end)
1112 continue;
1113 auto b = std::find(data, end, *legJ);
1114 if (b == end)
1115 continue;
1116 r.minPt = std::max(r.minPt, meta.minPt);
1117 r.maxPt = std::min(r.maxPt, meta.maxPt);
1118 ++(counts[(a > b) ? i : j]);
1119 found = true;
1120 break;
1121 }
1122 if (!found) {
1125 ATH_MSG_ERROR("Unable to rank trigger legs "
1126 << m_dictionary[*legI] << " and " << m_dictionary[*legJ]);
1127 return r;
1128 }
1129 }
1130 ++legI;
1131 }
1132 decltype(r.ranking) ranking = 0;
1133 for (unsigned i = 0; i < nLegs; ++i) {
1134 unsigned char index =
1135 std::find(counts.begin(), counts.end(), i) - counts.begin();
1136 if (index >= nLegs) {
1137 ATH_MSG_ERROR("Inconsistency found while trying to rank "
1138 << nLegs << " trigger legs");
1139 return r;
1140 }
1141 ranking = (ranking << 4 | index);
1142 }
1143 r.ranking = ranking;
1144 return r;
1145}
1146
1148 const Lepton& lepton, std::size_t leg1, std::size_t leg2, bool& success) {
1149 auto ranking = getCachedTriggerLegsRanking(lepton, leg1, leg2);
1150 if (CachedRanking::invalid(ranking)) {
1151 success = false;
1152 return -1;
1153 }
1154 return forwardLegs(leg1, leg2)[ranking & 0xF];
1155}
1156
1157std::pair<std::size_t, std::size_t>
1159 const Lepton& lepton, const flat_set<std::size_t>& legs, bool& success) {
1160 auto ranking = getCachedTriggerLegsRanking(lepton, legs);
1161 if (CachedRanking::invalid(ranking)) {
1162 success = false;
1163 return {0, 0};
1164 }
1165 std::pair<std::size_t, std::size_t> looseLegs{0, 0};
1166 looseLegs.first = *legs.nth(ranking & 0xF);
1167 if (legs.size() >= 2)
1168 looseLegs.second = *legs.nth((ranking >> 4) & 0xF);
1169 return looseLegs;
1170}
1171
1173 const Lepton& lepton, const flat_set<std::size_t>& legs, bool& success) {
1174 flat_set<std::size_t> validLegs;
1175 for (auto leg : legs)
1176 if (aboveThreshold(lepton, leg))
1177 validLegs.insert(leg);
1178 if (validLegs.size() == 0)
1179 return 0;
1180 if (validLegs.size() == 1)
1181 return *validLegs.begin();
1182 auto ranking = getCachedTriggerLegsRanking(lepton, legs);
1183 if (CachedRanking::invalid(ranking)) {
1184 success = false;
1185 return 0;
1186 }
1187 return *legs.nth(ranking & 0xF);
1188}
1189
1191 const Lepton& lepton, const flat_set<std::size_t>& legs, bool& success) {
1192 const int nLegs = legs.size();
1193 unsigned long ranking = getCachedTriggerLegsRanking(lepton, legs);
1194 if (CachedRanking::invalid(ranking)) {
1195 success = false;
1196 ranking = 0xFEDCBA9876543210;
1197 }
1198 std::vector<std::size_t> sorted_legs(nLegs);
1199 for (int i = 0; i < nLegs; ++i) {
1200 sorted_legs[i] = *legs.nth(ranking & 0xF);
1201 ranking >>= 4;
1202 }
1203 return sorted_legs;
1204}
1205
1207 const std::map<std::string, std::string>& triggerCombination,
1208 const std::string& version, std::map<std::string, std::string>& legsPerKey,
1211 bool success =
1212 data.suggestEgammaMapKeys(triggerCombination, version, legsPerKey, type);
1214}
1215
1217 const CP::SystematicVariation& systematic) const {
1218 auto sys = affectingSystematics();
1219 return !systematic.empty() && sys.find(systematic) != sys.end();
1220}
1221
1226
1231
1233 const CP::SystematicSet& systematic) {
1234 for (auto&& t : m_suppliedElectronEfficiencyTools)
1235 ANA_CHECK(t->applySystematicVariation(systematic));
1236 for (auto&& t : m_suppliedElectronScaleFactorTools)
1237 ANA_CHECK(t->applySystematicVariation(systematic));
1238 for (auto&& t : m_suppliedPhotonEfficiencyTools)
1239 ANA_CHECK(t->applySystematicVariation(systematic));
1240 for (auto&& t : m_suppliedPhotonScaleFactorTools)
1241 ANA_CHECK(t->applySystematicVariation(systematic));
1242 for (auto&& t : m_suppliedMuonTools)
1243 ANA_CHECK(t->applySystematicVariation(systematic));
1244
1245 return StatusCode::SUCCESS;
1246}
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
TrigGlobEffCorr::ImportData ImportData
TrigGlobEffCorr::CheckConfig CheckConfig
#define ANA_CHECK(EXP)
check whether the given expression was successful
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11
static Double_t a
static Double_t ss
TrigGlobEffCorr::Efficiencies Efficiencies
TrigGlobEffCorr::Calculator Calculator
TrigGlobEffCorr::Lepton Lepton
ParticleType
Definition TruthClasses.h:8
#define y
#define max(a, b)
Definition cfImp.cxx:41
ServiceHandle< StoreGateSvc > & evtStore()
Header file for AthHistogramAlgorithm.
Return value from object correction CP tools.
@ Error
Some error happened during the object correction.
@ OutOfValidityRange
Input object is out of validity range.
@ Ok
The correction was done successfully.
Class to wrap a set of SystematicVariations.
bool empty() const
returns: whether this is an empty systematic, i.e.
static std::string toolnameForDefaultScaleFactor()
To be used with the ListOfLegsPerTool property:
storage of the time histories of all the cells
xAOD::Type::ObjectType associatedLeptonFlavour(std::size_t leg, bool &success)
std::size_t tag() const
Definition Lepton.h:30
float pt() const
Definition Lepton.h:28
const xAOD::IParticle * particle() const
Definition Lepton.h:40
xAOD::Type::ObjectType type() const
Definition Lepton.h:29
std::size_t getLoosestLeg(const TrigGlobEffCorr::Lepton &lepton, std::size_t leg1, std::size_t leg2, bool &success)
std::map< ToolKey, std::size_t > m_electronSfToolIndex
decltype(m_electronEffToolIndex) & GetEfficiencyToolIndex(const xAOD::Electron *)
std::unique_ptr< TrigGlobEffCorr::Calculator > m_calculator
ToolHandleArray< IAsgPhotonEfficiencyCorrectionTool > m_suppliedPhotonScaleFactorTools
virtual CP::CorrectionCode getEfficiencyScaleFactor(const std::vector< const xAOD::IParticle * > &particles, double &efficiencyScaleFactor) override
std::vector< TrigGlobEffCorr::Lepton > LeptonList
bool checkAndRecord(CP::CorrectionCode &&cc)
Internal methods (III) – misc. helpers.
flat_set< ToolKey > parseListOfLegs(TrigGlobEffCorr::ImportData &data, const std::string &inputList, bool &success)
std::multimap< std::size_t, CachedRanking > m_cachedLegRankings
virtual CP::CorrectionCode checkTriggerMatching(bool &matched, const std::vector< const xAOD::IParticle * > &particles) override
std::map< std::string, std::string > m_overrideThresholds
virtual CP::SystematicSet recommendedSystematics() const override
the list of all systematics this tool recommends to use
std::map< std::string, std::string > m_muonLegsPerTag
deprecated
bool parseTagString(const std::string &tagstring, flat_set< std::size_t > &tags)
ToolHandleArray< IAsgPhotonEfficiencyCorrectionTool > m_suppliedPhotonEfficiencyTools
std::map< std::string, std::string > m_tagsPerTool
std::size_t getCombinedHash(const flat_set< std::size_t > &legs)
std::map< ToolKey, std::size_t > m_photonEffToolIndex
std::vector< std::size_t > getSortedLegs(const TrigGlobEffCorr::Lepton &lepton, const flat_set< std::size_t > &legs, bool &success)
virtual StatusCode applySystematicVariation(const CP::SystematicSet &systConfig) override
effects: configure this tool for the given list of systematic variations.
std::map< std::size_t, std::string > m_dictionary
virtual CP::CorrectionCode countTriggerLegs(const std::string &trigger, std::size_t &numberOfLegs) override
This utility function provides the number of legs for the specified trigger.
IAsgElectronEfficiencyCorrectionTool & GetEfficiencyTool(const xAOD::Electron *, std::size_t index)
decltype(m_electronSfToolIndex) & GetScaleFactorToolIndex(const xAOD::Electron *)
virtual CP::CorrectionCode getRelevantTriggers(std::vector< std::string > &triggers) override
This will fill the 'triggers' argument with the names of the triggers relevant for the current run nu...
flat_set< std::size_t > listNonOrderedCSValues(const std::string &s, bool &success)
Parses the input string (comma-separated list) and returns a set of hashes Watch out: since a flat_se...
std::map< std::string, std::string > m_triggerCb
std::pair< std::size_t, std::size_t > getTwoLoosestLegs(const TrigGlobEffCorr::Lepton &lepton, const flat_set< std::size_t > &legs, bool &success)
bool loadTagDecorators(const flat_set< std::size_t > &collectedElectronTags, const flat_set< std::size_t > &collectedMuonTags, const flat_set< std::size_t > &collectedPhotonTags)
bool enumerateTools(TrigGlobEffCorr::ImportData &data, ToolHandleArray< CPTool > &suppliedTools, std::map< ToolKey, std::size_t > &toolIndex, flat_set< std::size_t > &collectedTags)
bool aboveThreshold(const TrigGlobEffCorr::Lepton &p, std::size_t leg) const
SG::AuxElement::ConstAccessor< unsigned int > m_runNumberDecorator
std::map< std::string, std::string > m_electronLegsPerTag
TLE_RESULT getTriggerLegEfficiencies(const xAOD::Electron *p, unsigned runNumber, std::size_t leg, std::size_t tag, TrigGlobEffCorr::Efficiencies &efficiencies)
TLE_RESULT getEgammaTriggerLegEfficiencies(const ParticleType *p, unsigned runNumber, std::size_t leg, std::size_t tag, TrigGlobEffCorr::Efficiencies &efficiencies)
static constexpr const flat_set< std::size_t > & forwardLegs(const flat_set< std::size_t > &legs)
virtual CP::SystematicSet affectingSystematics() const override
the list of all systematics this tool can be affected by
bool loadTriggerCombination(TrigGlobEffCorr::ImportData &data, bool useDefaultElectronTools, bool useDefaultPhotonTools)
virtual CP::CorrectionCode getEfficiency(const std::vector< const xAOD::IParticle * > &particles, double &efficiencyData, double &efficiencyMc) override
bool retrieveRunNumber(unsigned &runNumber)
Internal methods (II) – core task.
CachedRanking rankTriggerLegs(float pt, const Container &legs)
std::map< std::string, std::string > m_triggerCbPerYear
static CP::CorrectionCode suggestEgammaMapKeys(const std::map< std::string, std::string > &triggerCombination, const std::string &version, std::map< std::string, std::string > &legsPerKey, xAOD::Type::ObjectType type)
ToolHandleArray< IAsgElectronEfficiencyCorrectionTool > m_suppliedElectronEfficiencyTools
Properties:
std::map< ToolKey, std::size_t > m_electronEffToolIndex
ToolHandleArray< CP::IMuonTriggerScaleFactors > m_suppliedMuonTools
unsigned long getCachedTriggerLegsRanking(const TrigGlobEffCorr::Lepton &lepton, ListOfLegs... legs)
std::size_t getLoosestLegAboveThreshold(const TrigGlobEffCorr::Lepton &lepton, const flat_set< std::size_t > &legs, bool &success)
bool updateLeptonList(LeptonList &leptons, const std::vector< const Particle * > &particles)
IAsgElectronEfficiencyCorrectionTool & GetScaleFactorTool(const xAOD::Electron *, std::size_t index)
virtual ASG_TOOL_CLASS(TrigGlobalEfficiencyCorrectionTool, ITrigGlobalEfficiencyCorrectionTool) TrigGlobalEfficiencyCorrectionTool(const std ~TrigGlobalEfficiencyCorrectionTool()
std::map< std::string, std::string > m_legsPerTag
deprecated
std::map< std::string, std::string > m_legsPerTool
virtual StatusCode initialize() override
Dummy implementation of the initialisation function.
virtual bool isAffectedBySystematic(const CP::SystematicVariation &systematic) const override
Declare the interface that this class provides.
ToolHandleArray< IAsgElectronEfficiencyCorrectionTool > m_suppliedElectronScaleFactorTools
@ IS_SIMULATION
true: simulation, false: data
Class providing the definition of the 4-vector interface.
int r
Definition globals.cxx:22
std::vector< std::string > tags
Definition hcg.cxx:105
std::string removeWhitespaces(const std::string &s)
Definition ImportData.h:170
Definition index.py:1
-diff
void reverse(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of reverse for DataVector/List.
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
@ Muon
The object is a muon.
Definition ObjectType.h:48
@ Electron
The object is an electron.
Definition ObjectType.h:46
EventInfo_v1 EventInfo
Definition of the latest event info version.
Muon_v1 Muon
Reference the current persistent version:
Photon_v1 Photon
Definition of the current "egamma version".
Electron_v1 Electron
Definition of the current "egamma version".
ElementLink_p1< typename GenerateELinkIndexType_p1< typename LINK::index_type >::type > type