19 asg::AsgMessaging(
"TrigGlobalEfficiencyCorrectionTool"),
21 m_dictionary(*
new std::map<std::size_t,std::string>),
22 m_hasher(*
new std::
hash<std::string>)
29 m_dictionary(
parent.m_dictionary),
59 std::ifstream
f(
name.c_str(),std::ios_base::in);
65 if(std::getline(
f,
line))
67 const std::string::size_type
i =
line.find(
'#');
68 if(
i != std::string::npos)
line.resize(
i);
110 std::vector<std::string>
config;
111 if(!
readDataFile(
"TrigGlobalEfficiencyCorrection/Triggers.cfg",
config))
return false;
112 std::stringstream
ss;
113 std::string triggerName, token;
132 for(std::size_t&
leg : def.leg)
134 if(!(
ss >> token))
break;
149 ATH_MSG_ERROR(
"Unknown trigger leg '" << token <<
"' found in Triggers.cfg");
159 ATH_MSG_ERROR(
"Unknown trigger leg '" << triggerName <<
"' (inferred from trigger name) found in Triggers.cfg");
163 if(!success)
continue;
180 if(!ne)
std::swap(def.leg[0],def.leg[1]);
194 if(!ne)
std::swap(def.leg[0], def.leg[2]);
195 else if(ne==1)
std::swap(def.leg[1], def.leg[2]);
201 else if((ne+
nm)==1)
std::swap(def.leg[1], def.leg[2]);
214 else success =
false;
216 else if(ne+
nm==0 || ne==3 ||
nm==3)
222 bool sym = (def.leg[0]==def.leg[1] || def.leg[1]==def.leg[2]);
226 else success =
false;
234 else if(ne==1 &&
nm==1) def.type =
TT_E_MU;
235 else if(ne==1) def.type =
TT_E_G;
246 ATH_MSG_ERROR(
"Configuration issue for trigger " << triggerName);
255 std::vector<std::string>
config;
256 if(!
readDataFile(
"TrigGlobalEfficiencyCorrection/Thresholds.cfg",
config))
return false;
257 std::stringstream
ss;
269 if(
unit ==
"GeV")
pt *= 1e3f;
270 else if(
unit !=
"MeV")
272 ATH_MSG_ERROR(
"Unable to import pT threshold for leg \"" <<
leg <<
"\" (missing unit)");
290 bool belowRecommended =
false;
291 for(
auto& kv : overridenThresholds)
297 try {
pt = std::stof(kv.second); }
300 ATH_MSG_ERROR(
"Unable to convert threshold argument \""<<kv.second<<
"\" to floating-point value");
306 ATH_MSG_WARNING(
"Suspiciously low threshold (" <<
pt <<
" MeV) set for trigger leg " << kv.first
307 <<
", please make sure you provided the threshold in MeV and not in GeV!");
309 if(pt < itr->
second) belowRecommended =
true;
314 ATH_MSG_ERROR(
"Can't override threshold for unknown trigger leg " << kv.first);
320 ATH_MSG_WARNING(
"Tool configured to use trigger thresholds below those recommended!");
328 std::vector<std::string>
config;
329 if(!
readDataFile(
"TrigGlobalEfficiencyCorrection/DataPeriods.cfg",
config))
return false;
330 std::stringstream
ss;
332 std::pair<unsigned,unsigned>
runs;
353 std::vector<std::string>
config;
354 if(!
readDataFile(
"TrigGlobalEfficiencyCorrection/Hierarchies.cfg",
config))
return false;
355 std::stringstream
ss;
356 std::string token,
unit;
357 std::map<std::size_t, std::vector<std::size_t> > aliases;
366 if(
line[1]==
'-' &&
line[2]==
']')
ss.ignore(3);
370 if(
line[1]==
'>')
ss.ignore(2) >> meta.minPt >>
unit;
371 else if(
line[1]==
'<')
ss.ignore(2) >> meta.maxPt >>
unit;
372 else ss.ignore(1) >> meta.minPt >>
sep >> meta.maxPt >>
unit;
375 ATH_MSG_ERROR(
"Unable to parse pT restrictions in Hierarchies.cfg");
387 auto itr = aliases.find(
h);
388 if(itr == aliases.end())
392 ATH_MSG_ERROR(
"Unknown trigger leg '" << token <<
"' found in Hierarchies.cfg");
399 if(
ss >> token && token!=
">") success =
false;
402 success = success && meta.nLegs;
407 auto& legs = aliases[
m_hasher(token)];
408 if(
ss >> token && token==
":=")
418 ATH_MSG_ERROR(
"Unknown trigger leg '" << token <<
"' found in Hierarchies.cfg");
421 if(
ss >> token && token!=
">") success =
false;
423 success = success && legs.size();
425 else success =
false;
441 std::vector<std::string>
config;
443 std::stringstream
ss;
445 bool reading =
false;
448 std::size_t
pos =
line.find(
"[VERSION]");
449 if(
pos != std::string::npos)
454 while(std::getline(
ss, token,
','))
464 if(!reading)
continue;
477 else insertion.first->second |=
year;
480 if(!keysPerLeg.size())
494 boundaries = itr->second;
499 if(
sep!=std::string::npos)
501 std::string kwMin =
period.substr(0,
sep);
502 std::string kwMax =
period.substr(
sep+1);
508 boundaries = std::minmax({itrMin->second.first, itrMax->second.first, itrMin->second.second, itrMax->second.second});
514 boundaries = std::minmax(std::stoi(kwMin), std::stoi(kwMax));
531 return xAOD::Type::Other;
543 return xAOD::Type::Other;
549 if(
s.find(
"|||") != std::string::npos)
551 ATH_MSG_ERROR(
"Invalid format for the trigger combination '" << triggerString <<
"'");
558 auto i =
s.find(
"||");
559 if(
i == std::string::npos)
break;
564 ATH_MSG_ERROR(
"Invalid format for the trigger combination '" << triggerString <<
"'");
569 std::set<std::size_t>
hashes;
570 std::stringstream
ss(
s);
571 while(std::getline(
ss,
s,
'|'))
578 ATH_MSG_ERROR(
"Unknown trigger '" <<
s <<
"' found while parsing trigger combination");
582 if(!
hashes.insert(trig).second)
584 ATH_MSG_ERROR(
"The trigger '" <<
s <<
"' is present more than once in the combination");
590 success = success &&
triggers.size();
596 std::map<std::string,std::string>& legsPerKey,
603 std::map<std::size_t,int> legs;
605 for(
auto& kv : triggerCombination)
615 for(
int k=0;
k<32;++
k)
618 if(itr !=
m_dataPeriods.end() && itrPeriod->second.first <= itr->second.second
619 && itrPeriod->second.second >= itr->second.first)
625 if(!success)
continue;
628 for(std::size_t
leg : trig.leg)
632 auto insertion = legs.emplace(
leg,
years);
633 if(!insertion.second) insertion.first->second |=
years;
638 if(!success)
return false;
642 std::map<std::size_t,std::map<std::size_t,int> > allKeys;
644 std::map<std::size_t,std::vector<std::size_t> > allLegsPerKey;
645 std::set<std::size_t> legsWithMultipleKeys;
646 bool sameKeyForAllyears =
true;
649 allLegsPerKey.clear();
650 for(
auto& kvLegs : legs)
652 std::size_t
leg = kvLegs.first;
653 int years = kvLegs.second;
654 auto itrKeys = allKeys.find(
leg);
655 if(itrKeys != allKeys.end())
657 for(
auto& kvKeys : itrKeys->second)
659 auto y = (kvKeys.second &
years);
660 if((
y==
years) || (!sameKeyForAllyears &&
y!=0))
662 auto insertion = allLegsPerKey.emplace(kvKeys.first,std::vector<std::size_t>{
leg});
663 if(!insertion.second) insertion.first->second.push_back(
leg);
669 ATH_MSG_ERROR(
"Sorry, no idea what the map key should be for the trigger leg '"
676 if(!allLegsPerKey.size())
678 if(sameKeyForAllyears)
680 sameKeyForAllyears =
false;
687 using T = decltype(allLegsPerKey)::
value_type;
688 auto itrKey = std::max_element(allLegsPerKey.begin(), allLegsPerKey.end(),
689 [](T&
x,T&
y){return x.second.size()<y.second.size();});
690 std::string& strLegs = legsPerKey[
m_dictionary.at(itrKey->first)];
691 for(std::size_t
leg : itrKey->second)
693 int& wantedYears = legs.at(
leg);
694 int supportedYears = (allKeys.at(
leg).at(itrKey->first)) & wantedYears;
695 if(supportedYears!=wantedYears || legsWithMultipleKeys.count(
leg))
697 legsWithMultipleKeys.insert(
leg);
698 for(
int i=0;
i<32;++
i)
700 if(supportedYears & (1
u<<
i))
702 if(strLegs.length() && strLegs.back()!=
',') strLegs +=
',';
709 if(strLegs.length() && strLegs.back()!=
',') strLegs +=
',';
712 if(supportedYears == wantedYears) legs.erase(
leg);
713 else wantedYears &= ~supportedYears;
722 legsPerKey.emplace(
std::to_string(legsPerKey.size()), m_dictionary.at(kv.first));
725 for (
auto& [
key, legs]: legsPerKey)
730 "a default scale factor of 1 being returned");
733 if(!success) legsPerKey.clear();
740 std::set<std::size_t> extraItems;
741 std::vector<ImportData::TrigDef> updatedTriggers;
745 std::size_t
pos = 0, len =
name.find(
"_OR_");
746 if(len == std::string::npos)
748 updatedTriggers.emplace_back(trig);
758 ATH_MSG_ERROR(
"while listing triggers for trigger matching; trigger \"" <<
item <<
"\" extracted from \"" <<
name <<
"\" is not recognized");
761 if(extraItems.emplace(
h).second) updatedTriggers.emplace_back(def->second);
762 if(len == std::string::npos)
break;
765 if(len != std::string::npos) len -=
pos;