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