20 asg::AsgMessaging(
"TrigGlobalEfficiencyCorrectionTool"),
23 m_dictionary(*
new std::map<std::size_t, std::string>),
24 m_hasher(*
new std::
hash<std::string>) {}
29 m_dictionary(
parent.m_dictionary),
30 m_hasher(
parent.m_hasher) {
42 const std::map<std::string, std::string>& overridenThresholds) {
48 std::vector<std::string>&
contents) {
53 std::ifstream
f(
name.c_str(), std::ios_base::in);
57 if (std::getline(
f,
line)) {
58 const std::string::size_type
i =
line.find(
'#');
59 if (
i != std::string::npos)
61 if (
line.length() >= 3)
66 ATH_MSG_ERROR(
"Issue encountered while reading configuration file "
84 if (def.
leg[0] == def.
leg[1] && def.
leg[1] == def.
leg[2])
86 else if (def.
leg[0] != def.
leg[1] && def.
leg[1] != def.
leg[2] &&
91 if (def.
leg[1] != def.
leg[0] && def.
leg[1] != def.
leg[2])
93 else if (def.
leg[2] != def.
leg[0] && def.
leg[2] != def.
leg[1])
103 std::vector<std::string>
config;
106 std::stringstream
ss;
107 std::string triggerName, token;
125 for (std::size_t&
leg : def.leg) {
139 <<
"' found in Triggers.cfg");
149 "Unknown trigger leg '"
151 <<
"' (inferred from trigger name) found in Triggers.cfg");
192 else if ((ne +
nm) == 1)
199 if (
std::count(def.leg.cbegin(), def.leg.cend(), def.leg[0]) == 4) {
203 }
else if (ne +
nm == 0 || ne == 3 ||
211 bool sym = (def.leg[0] == def.leg[1] || def.leg[1] == def.leg[2]);
218 else if (ne +
nm == 1)
230 else if (ne +
nm == 0)
232 else if (ne == 1 &&
nm == 1)
245 ATH_MSG_ERROR(
"Configuration issue for trigger " << triggerName);
252 const std::map<std::string, std::string>& overridenThresholds) {
254 std::vector<std::string>
config;
257 std::stringstream
ss;
269 else if (
unit !=
"MeV") {
271 <<
leg <<
"\" (missing unit)");
286 bool belowRecommended =
false;
287 for (
auto& kv : overridenThresholds) {
292 pt = std::stof(kv.second);
295 << kv.second <<
"\" to floating-point value");
301 <<
pt <<
" MeV) set for trigger leg " << kv.first
302 <<
", please make sure you provided the threshold in "
303 "MeV and not in GeV!");
306 belowRecommended =
true;
309 ATH_MSG_ERROR(
"Can't override threshold for unknown trigger leg "
314 if (belowRecommended) {
316 "Tool configured to use trigger thresholds below those recommended!");
323 std::vector<std::string>
config;
326 std::stringstream
ss;
328 std::pair<unsigned, unsigned>
runs;
347 std::vector<std::string>
config;
350 std::stringstream
ss;
351 std::string token,
unit;
352 std::map<std::size_t, std::vector<std::size_t> > aliases;
357 if (
line[0] ==
'[') {
360 Hierarchy{(short)m_hierarchyData.size(), 0, 0.f,
361 std::numeric_limits<float>::max()});
362 if (
line[1] ==
'-' &&
line[2] ==
']')
367 ss.ignore(2) >> meta.minPt >>
unit;
368 else if (
line[1] ==
'<')
369 ss.ignore(2) >> meta.maxPt >>
unit;
371 ss.ignore(1) >> meta.minPt >>
sep >> meta.maxPt >>
unit;
372 if (!
ss ||
sep !=
'-' || (
unit !=
"GeV]" &&
unit !=
"MeV]")) {
373 ATH_MSG_ERROR(
"Unable to parse pT restrictions in Hierarchies.cfg");
376 if (
unit ==
"GeV]") {
382 while (
ss >> token) {
384 auto itr = aliases.find(
h);
385 if (itr == aliases.end()) {
388 << token <<
"' found in Hierarchies.cfg");
396 if (
ss >> token && token !=
">")
400 success = success && meta.nLegs;
403 auto& legs = aliases[
m_hasher(token)];
404 if (
ss >> token && token ==
":=") {
406 while (
ss >> token) {
412 << token <<
"' found in Hierarchies.cfg");
415 if (
ss >> token && token !=
">")
418 success = success && legs.size();
434 std::map<std::size_t, std::map<std::size_t, int> >& keysPerLeg) {
436 std::vector<std::string>
config;
439 std::stringstream
ss;
441 bool reading =
false;
443 std::size_t
pos =
line.find(
"[VERSION]");
444 if (
pos != std::string::npos) {
448 while (std::getline(
ss, token,
',')) {
465 while (
ss >> token) {
468 if (insertion.second)
471 insertion.first->second |=
year;
474 if (!keysPerLeg.size()) {
475 ATH_MSG_ERROR(
"Unable to import the available map keys for the version "
483 const std::string&
period, std::pair<unsigned, unsigned>& boundaries) {
487 boundaries = itr->second;
492 if (
sep != std::string::npos) {
493 std::string kwMin =
period.substr(0,
sep);
494 std::string kwMax =
period.substr(
sep + 1);
499 boundaries = std::minmax({itrMin->second.first, itrMax->second.first,
500 itrMin->second.second, itrMax->second.second});
505 boundaries = std::minmax(std::stoi(kwMin), std::stoi(kwMax));
515 const std::string&
leg,
bool& success) {
517 if (
leg.length() >= 2 &&
leg[0] ==
'e' &&
leg[1] >=
'1' &&
leg[1] <=
'9')
519 else if (
leg.length() >= 3 &&
leg[0] ==
'm' &&
leg[1] ==
'u' &&
520 leg[2] >=
'1' &&
leg[2] <=
'9')
522 else if (
leg.length() >= 3 &&
leg[0] ==
'g' &&
leg[1] >=
'1' &&
leg[1] <=
'9')
524 else if (
leg.length() >= 4 &&
leg[0] ==
't' &&
leg[1] ==
'a' &&
525 leg[2] ==
'u' &&
leg[3] >=
'1' &&
leg[3] <=
'9')
528 return xAOD::Type::Other;
539 return xAOD::Type::Other;
543 const std::string& triggerString,
bool& success) {
545 if (
s.find(
"|||") != std::string::npos) {
547 << triggerString <<
"'");
553 auto i =
s.find(
"||");
554 if (
i == std::string::npos)
558 if (
s ==
"" ||
s ==
"|") {
560 << triggerString <<
"'");
565 std::set<std::size_t>
hashes;
566 std::stringstream
ss(
s);
567 while (std::getline(
ss,
s,
'|')) {
573 <<
s <<
"' found while parsing trigger combination");
577 if (!
hashes.insert(trig).second) {
579 <<
s <<
"' is present more than once in the combination");
585 success = success &&
triggers.size();
590 const std::map<std::string, std::string>& triggerCombination,
591 const std::string&
version, std::map<std::string, std::string>& legsPerKey,
598 std::map<std::size_t, int> legs;
600 for (
auto& kv : triggerCombination) {
608 for (
int k = 0;
k < 32; ++
k) {
611 itrPeriod->second.first <= itr->second.second &&
612 itrPeriod->second.second >= itr->second.first) {
620 for (std::size_t
leg : trig.leg) {
622 auto insertion = legs.emplace(
leg,
years);
623 if (!insertion.second)
624 insertion.first->second |=
years;
633 std::map<std::size_t, std::map<std::size_t, int> > allKeys;
636 std::map<std::size_t, std::vector<std::size_t> > allLegsPerKey;
637 std::set<std::size_t> legsWithMultipleKeys;
638 bool sameKeyForAllyears =
true;
639 while (legs.size()) {
640 allLegsPerKey.clear();
641 for (
auto& kvLegs : legs)
643 std::size_t
leg = kvLegs.first;
644 int years = kvLegs.second;
645 auto itrKeys = allKeys.find(
leg);
646 if (itrKeys != allKeys.end()) {
647 for (
auto& kvKeys : itrKeys->second)
649 auto y = (kvKeys.second &
years);
651 (!sameKeyForAllyears &&
655 auto insertion = allLegsPerKey.emplace(
656 kvKeys.first, std::vector<std::size_t>{
leg});
657 if (!insertion.second)
658 insertion.first->second.push_back(
leg);
663 "Sorry, no idea what the map key should be for the trigger leg '"
671 if (!allLegsPerKey.size()) {
672 if (sameKeyForAllyears) {
673 sameKeyForAllyears =
false;
680 using T = decltype(allLegsPerKey)::
value_type;
681 auto itrKey = std::max_element(
682 allLegsPerKey.begin(), allLegsPerKey.end(),
683 [](T&
x, T&
y) { return x.second.size() < y.second.size(); });
684 std::string& strLegs = legsPerKey[
m_dictionary.at(itrKey->first)];
685 for (std::size_t
leg : itrKey->second) {
686 int& wantedYears = legs.at(
leg);
687 int supportedYears = (allKeys.at(
leg).at(itrKey->first)) & wantedYears;
688 if (supportedYears != wantedYears || legsWithMultipleKeys.count(
leg)) {
689 legsWithMultipleKeys.insert(
leg);
690 for (
int i = 0;
i < 32; ++
i) {
691 if (supportedYears & (1
u <<
i)) {
692 if (strLegs.length() && strLegs.back() !=
',')
699 if (strLegs.length() && strLegs.back() !=
',')
703 if (supportedYears == wantedYears)
706 wantedYears &= ~supportedYears;
711 for (
auto& kv : legs) {
713 m_dictionary.at(kv.first));
716 for (
auto& [
key, legs] : legsPerKey) {
720 "Some of the requested triggers will result in "
721 "a default scale factor of 1 being returned");
730 std::vector<ImportData::TrigDef>&
triggers) {
732 std::set<std::size_t> extraItems;
733 std::vector<ImportData::TrigDef> updatedTriggers;
736 std::size_t
pos = 0, len =
name.find(
"_OR_");
737 if (len == std::string::npos) {
738 updatedTriggers.emplace_back(trig);
746 ATH_MSG_ERROR(
"while listing triggers for trigger matching; trigger \""
747 <<
item <<
"\" extracted from \"" <<
name
748 <<
"\" is not recognized");
751 if (extraItems.emplace(
h).second)
752 updatedTriggers.emplace_back(def->second);
753 if (len == std::string::npos)
757 if (len != std::string::npos)