41 if (
m_parent.m_suppliedElectronEfficiencyTools.size() !=
42 m_parent.m_suppliedElectronScaleFactorTools.size()) {
44 "The numbers of electron tools supplied via the "
45 "'ElectronEfficiencyTools' and 'ElectronScaleFactorTools' properties "
46 "should be identical");
50 if (
m_parent.m_suppliedPhotonEfficiencyTools.size() !=
51 m_parent.m_suppliedPhotonScaleFactorTools.size()) {
53 "The numbers of photon tools supplied via the 'PhotonEfficiencyTools' "
54 "and 'PhotonScaleFactorTools' properties should be identical");
61 for (
auto& kv :
m_parent.m_legsPerTool) {
62 auto& name = kv.first;
75 <<
" mentioned in property 'ListOfLegsPerTool', which is "
76 "only aimed at electron and photon tools");
78 std::string known_tools =
"; the known tools are";
79 for (
auto& tool :
m_parent.m_suppliedElectronEfficiencyTools)
80 known_tools +=
" " + tool.name();
81 for (
auto& tool :
m_parent.m_suppliedElectronScaleFactorTools)
82 known_tools +=
" " + tool.name();
83 for (
auto& tool :
m_parent.m_suppliedPhotonEfficiencyTools)
84 known_tools +=
" " + tool.name();
85 for (
auto& tool :
m_parent.m_suppliedPhotonScaleFactorTools)
86 known_tools +=
" " + tool.name();
88 << name <<
" mentioned in property 'ListOfLegsPerTool'"
97 auto toolsHaveLegInfo = [
this](
auto& effTools,
auto& sfTools,
99 if (effTools.size() < 2)
102 for (
int i = 0; i < 2; ++i) {
103 for (
auto& tool : (i ? effTools : sfTools)) {
104 const std::string& name = tool.name();
108 <<
" associated trigger legs are not indicated in "
109 "'ListOfLegsPerTool', "
110 "doing so is mandatory when several tools are used");
118 toolsHaveLegInfo(
m_parent.m_suppliedElectronEfficiencyTools,
119 m_parent.m_suppliedElectronScaleFactorTools,
"Electron");
121 toolsHaveLegInfo(
m_parent.m_suppliedPhotonEfficiencyTools,
122 m_parent.m_suppliedPhotonScaleFactorTools,
"Photon");
130 if (
m_parent.m_leptonTagDecorations ==
"") {
131 if (
m_parent.m_muonLegsPerTag.size() ||
135 "the property 'LeptonTagDecorations' must be filled when any of "
136 "'ListOfTagsPerTool'"
137 " / 'ListOfLegsPerTag' / 'MuonLegsPerTag' / 'ElectronLegsPerTag' "
145 unsigned nElectronToolsWithTags = 0, nMuonToolsWithTags = 0,
146 nPhotonToolsWithTags = 0;
147 for (
auto& kv :
m_parent.m_tagsPerTool) {
148 auto& name = kv.first;
151 ++nElectronToolsWithTags;
153 ++nMuonToolsWithTags;
156 ++nPhotonToolsWithTags;
159 std::string all_tools =
"; the known tools are";
160 for (
auto& tool :
m_parent.m_suppliedElectronEfficiencyTools)
161 all_tools +=
" " + tool.name();
162 for (
auto& tool :
m_parent.m_suppliedElectronScaleFactorTools)
163 all_tools +=
" " + tool.name();
164 for (
auto& tool :
m_parent.m_suppliedPhotonEfficiencyTools)
165 all_tools +=
" " + tool.name();
166 for (
auto& tool :
m_parent.m_suppliedPhotonScaleFactorTools)
167 all_tools +=
" " + tool.name();
169 << name <<
" mentioned in property 'ListOfTagsPerTool'");
173 if (nMuonToolsWithTags &&
174 (nMuonToolsWithTags !=
m_parent.m_suppliedMuonTools.size())) {
176 "Not all muon tools have been associated with tags in the "
177 "'ListOfTagsPerTool' property");
181 unsigned nSupplied =
m_parent.m_suppliedElectronEfficiencyTools.size() +
182 m_parent.m_suppliedElectronScaleFactorTools.size();
183 if (nElectronToolsWithTags && (nElectronToolsWithTags != nSupplied)) {
185 "Not all electron tools have been associated with tags in the "
186 "'ListOfTagsPerTool' property");
192 nSupplied =
m_parent.m_suppliedPhotonEfficiencyTools.size() +
193 m_parent.m_suppliedPhotonScaleFactorTools.size();
194 if (nPhotonToolsWithTags && (nPhotonToolsWithTags != nSupplied)) {
196 "Not all photon tools have been associated with tags in the "
197 "'ListOfTagsPerTool' property");
254 auto checkConsistency = [
this](
auto& effToolIndex,
auto& sfToolIndex,
256 bool mismatch = (effToolIndex.size() != sfToolIndex.size());
258 for (
auto& kv : sfToolIndex) {
259 auto itr = effToolIndex.find(kv.first);
260 if (itr != effToolIndex.end()) {
261 std::size_t index1 = kv.second, index2 = itr->second;
263 for (
auto& kv : sfToolIndex)
264 if (kv.second == index1)
265 pairs1.insert(kv.first);
266 for (
auto& kv : effToolIndex)
267 if (kv.second == index2)
268 pairs2.insert(kv.first);
269 if (pairs1 != pairs2)
277 "There must be a one-to-one correspondence between the "
279 <<
" efficiency and scale factor tools "
280 "(including their associated trigger legs and selection tags)");
285 if (!checkConsistency(
m_parent.m_electronEffToolIndex,
286 m_parent.m_electronSfToolIndex,
"electron"))
288 if (!checkConsistency(
m_parent.m_photonEffToolIndex,
289 m_parent.m_photonSfToolIndex,
"photon"))
293 for (
auto& kv :
m_parent.m_legsPerTag) {
294 std::size_t tag = (kv.first !=
"*") ?
m_parent.m_hasher(kv.first) : 0;
295 for (std::size_t leg :
296 m_parent.listNonOrderedCSValues(kv.second, success)) {
298 m_parent.m_dictionary[leg], success);
300 if (
m_parent.m_electronEffToolIndex.find(ToolKey(leg, tag)) ==
301 m_parent.m_electronEffToolIndex.end()) {
303 "No electron tool provided for the combination of trigger leg '"
304 <<
m_parent.m_dictionary[leg] <<
"' and selection tag '"
305 << kv.first <<
"' mentioned in the property 'ListOfLegsPerTag'");
309 if (
m_parent.m_muonToolIndex.find(ToolKey(0, tag)) ==
312 "No muon tool provided for the combination of trigger leg '"
313 <<
m_parent.m_dictionary[leg] <<
"' and selection tag '"
314 << kv.first <<
"' mentioned in the property 'ListOfLegsPerTag'");
318 if (
m_parent.m_photonEffToolIndex.find(ToolKey(leg, tag)) ==
319 m_parent.m_photonEffToolIndex.end()) {
321 "No photon tool provided for the combination of trigger leg '"
322 <<
m_parent.m_dictionary[leg] <<
"' and selection tag '"
323 << kv.first <<
"' mentioned in the property 'ListOfLegsPerTag'");
328 "Unable to determine which lepton flavour is associated to the "
331 <<
"' in the property 'ListOfLegsPerTag'");
340 auto periods =
m_parent.m_calculator->m_periods;
341 const auto periods_end = periods.end();
342 for (
auto itr1 = periods.begin(); itr1 != periods_end; ++itr1) {
343 auto&
x = itr1->m_boundaries;
344 if (
x.second <
x.first) {
346 "One of the periods specified in TriggerCombination has runMin ("
347 <<
x.first <<
") > runMax (" <<
x.second <<
")");
350 for (
auto itr2 = itr1 + 1; itr2 != periods_end; ++itr2) {
351 auto&
y = itr2->m_boundaries;
352 if ((
x.first >=
y.first &&
x.first <=
y.second) ||
353 (
x.second >=
y.first &&
x.second <=
y.second)) {
354 ATH_MSG_ERROR(
"The periods specified in TriggerCombination overlap");