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