ATLAS Offline Software
Loading...
Searching...
No Matches
CheckConfig.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
11#include <flat_set>
12
13#include <cctype>
14
17
19 : asg::AsgMessaging(&parent), m_parent(parent) {
20 msg().setLevel(parent.msg().level());
21}
22
23template <class CPTool>
24ToolHandle<CPTool>* CheckConfig::findToolByName(
25 ToolHandleArray<CPTool>& suppliedTools, const std::string& name) {
26 for (auto& tool : suppliedTools) {
27 if (tool.name() == name ||
28 tool->name() == name) // athena: not always the same
29 {
30 return &tool;
31 }
32 }
33 return nullptr;
34}
35
37 bool success = true;
38
39 if (m_parent.m_suppliedElectronEfficiencyTools.size() !=
40 m_parent.m_suppliedElectronScaleFactorTools.size()) {
42 "The numbers of electron tools supplied via the "
43 "'ElectronEfficiencyTools' and 'ElectronScaleFactorTools' properties "
44 "should be identical");
45 return false;
46 }
47
48 if (m_parent.m_suppliedPhotonEfficiencyTools.size() !=
49 m_parent.m_suppliedPhotonScaleFactorTools.size()) {
51 "The numbers of photon tools supplied via the 'PhotonEfficiencyTools' "
52 "and 'PhotonScaleFactorTools' properties should be identical");
53 return false;
54 }
55
59 for (auto& kv : m_parent.m_legsPerTool) {
60 auto& name = kv.first;
61 if (name ==
63 continue;
64 if (findToolByName(m_parent.m_suppliedElectronEfficiencyTools, name) ||
65 findToolByName(m_parent.m_suppliedElectronScaleFactorTools, name) ||
66 findToolByName(m_parent.m_suppliedPhotonEfficiencyTools, name) ||
67 findToolByName(m_parent.m_suppliedPhotonScaleFactorTools, name))
68 continue;
69 success = false;
70 if (findToolByName(m_parent.m_suppliedMuonTools, name)) {
71 ATH_MSG_ERROR("Muon tool "
72 << name
73 << " mentioned in property 'ListOfLegsPerTool', which is "
74 "only aimed at electron and photon tools");
75 } else {
76 std::string known_tools = "; the known tools are";
77 for (auto& tool : m_parent.m_suppliedElectronEfficiencyTools)
78 known_tools += " " + tool.name();
79 for (auto& tool : m_parent.m_suppliedElectronScaleFactorTools)
80 known_tools += " " + tool.name();
81 for (auto& tool : m_parent.m_suppliedPhotonEfficiencyTools)
82 known_tools += " " + tool.name();
83 for (auto& tool : m_parent.m_suppliedPhotonScaleFactorTools)
84 known_tools += " " + tool.name();
85 ATH_MSG_ERROR("Unknown tool "
86 << name << " mentioned in property 'ListOfLegsPerTool'"
87 << known_tools);
88 }
89 }
90 if (!success)
91 return false;
92
95 auto toolsHaveLegInfo = [this](auto& effTools, auto& sfTools,
96 const char* type) {
97 if (effTools.size() < 2)
98 return true;
99 bool success = true;
100 for (int i = 0; i < 2; ++i) {
101 for (auto& tool : (i ? effTools : sfTools)) {
102 const std::string& name = tool.name();
103 if (m_parent.m_legsPerTool.find(name) == m_parent.m_legsPerTool.end()) {
105 << " tool " << name
106 << " associated trigger legs are not indicated in "
107 "'ListOfLegsPerTool', "
108 "doing so is mandatory when several tools are used");
109 success = false;
110 }
111 }
112 }
113 return success;
114 };
115 success &=
116 toolsHaveLegInfo(m_parent.m_suppliedElectronEfficiencyTools,
117 m_parent.m_suppliedElectronScaleFactorTools, "Electron");
118 success &=
119 toolsHaveLegInfo(m_parent.m_suppliedPhotonEfficiencyTools,
120 m_parent.m_suppliedPhotonScaleFactorTools, "Photon");
121 if (!success)
122 return false;
123
127
128 if (m_parent.m_leptonTagDecorations == "") {
129 if (m_parent.m_muonLegsPerTag.size() ||
130 m_parent.m_electronLegsPerTag.size() || m_parent.m_legsPerTag.size() ||
131 m_parent.m_tagsPerTool.size()) {
133 "the property 'LeptonTagDecorations' must be filled when any of "
134 "'ListOfTagsPerTool'"
135 " / 'ListOfLegsPerTag' / 'MuonLegsPerTag' / 'ElectronLegsPerTag' "
136 "is.");
137 return false;
138 }
139 return true;
140 }
141
143 unsigned nElectronToolsWithTags = 0, nMuonToolsWithTags = 0,
144 nPhotonToolsWithTags = 0;
145 for (auto& kv : m_parent.m_tagsPerTool) {
146 auto& name = kv.first;
147 if (findToolByName(m_parent.m_suppliedElectronEfficiencyTools, name) ||
148 findToolByName(m_parent.m_suppliedElectronScaleFactorTools, name))
149 ++nElectronToolsWithTags;
150 else if (findToolByName(m_parent.m_suppliedMuonTools, name))
151 ++nMuonToolsWithTags;
152 else if (findToolByName(m_parent.m_suppliedPhotonEfficiencyTools, name) ||
153 findToolByName(m_parent.m_suppliedPhotonScaleFactorTools, name))
154 ++nPhotonToolsWithTags;
155 else {
156 success = false;
157 std::string all_tools = "; the known tools are";
158 for (auto& tool : m_parent.m_suppliedElectronEfficiencyTools)
159 all_tools += " " + tool.name();
160 for (auto& tool : m_parent.m_suppliedElectronScaleFactorTools)
161 all_tools += " " + tool.name();
162 for (auto& tool : m_parent.m_suppliedPhotonEfficiencyTools)
163 all_tools += " " + tool.name();
164 for (auto& tool : m_parent.m_suppliedPhotonScaleFactorTools)
165 all_tools += " " + tool.name();
166 ATH_MSG_ERROR("Unknown tool "
167 << name << " mentioned in property 'ListOfTagsPerTool'");
168 }
169 }
171 if (nMuonToolsWithTags &&
172 (nMuonToolsWithTags != m_parent.m_suppliedMuonTools.size())) {
174 "Not all muon tools have been associated with tags in the "
175 "'ListOfTagsPerTool' property");
176 success = false;
177 }
179 unsigned nSupplied = m_parent.m_suppliedElectronEfficiencyTools.size() +
180 m_parent.m_suppliedElectronScaleFactorTools.size();
181 if (nElectronToolsWithTags && (nElectronToolsWithTags != nSupplied)) {
183 "Not all electron tools have been associated with tags in the "
184 "'ListOfTagsPerTool' property");
185 success = false;
186 }
187 if (!success)
188 return false;
190 nSupplied = m_parent.m_suppliedPhotonEfficiencyTools.size() +
191 m_parent.m_suppliedPhotonScaleFactorTools.size();
192 if (nPhotonToolsWithTags && (nPhotonToolsWithTags != nSupplied)) {
194 "Not all photon tools have been associated with tags in the "
195 "'ListOfTagsPerTool' property");
196 success = false;
197 }
198 if (!success)
199 return false;
200
201 /*
202 * More checks that are done in other places (or still need to be
203 * implemented!):
204 *
205 * - [advancedConfigChecks()] for each entry in ListOfLegsPerTag there must be
206 * a suitable tool for that tag and leg(s)
207 * - [enumerateTools()] no two electron/photon tools share the same {leg,tag}
208 * combination
209 * - [enumerateTools()] no two muon tools share the same tag
210 * - [advancedConfigChecks()] electron efficiency and scale factors have
211 * identical configurations: for each eff. tool leg/tag we must find a SF
212 * tool, and the other leg/tag pairs associated to those tools must be
213 * identical.
214 * - [UNCHECKED] if tags are used with electron (resp. muon, photon) tools,
215 * then all electron (muon, photon) tools must have an entry in
216 * ListOfTagsPerTool. Done partially in this function, but the case where no
217 * tools are tagged (yet tags are used, according to ListOfLegsPerTag or
218 * LeptonTagDecorations) escapes detection.
219 * - [loadTagsConfiguration()] each entry of ListOfLegsPerTag can be matched
220 * to a suitable tool
221 * - [UNCHECKED] suffixed tag read from a lepton must correspond to a know tag
222 * - [enumerateTools()] list of legs associated to each tool contains only
223 * known legs
224 * - [UNCHECKED TrigGlobEffCorrImportData import* functions] various
225 * consistency checks of the configuration files
226 * - [advancedConfigChecks()] user-specified periods are orthogonal
227 * - [ImportData::parseTriggerString()] no duplicated triggers in the
228 * combination
229 * - [UNCHECKED] for each configured electron/photon tool there is at least
230 * one associated tag^leg pair in 'ListOfLegsPerTag' (unless no
231 * electron/photon tags used)
232 * - [UNCHECKED] for each configured muon tool there is at least one
233 * associated tag in 'MuonLegsPerTag' (unless empty)
234 * - [enumerateTools()] electron tools can't be associated to photon legs; and
235 * reciprocally
236 */
237
238 return success;
239}
240
246 bool success = true;
247
249
252 auto checkConsistency = [this](auto& effToolIndex, auto& sfToolIndex,
253 const char* type) {
254 bool mismatch = (effToolIndex.size() != sfToolIndex.size());
255 if (!mismatch) {
256 for (auto& kv : sfToolIndex) {
257 auto itr = effToolIndex.find(kv.first);
258 if (itr != effToolIndex.end()) {
259 std::size_t index1 = kv.second, index2 = itr->second;
260 std::flat_set<ToolKey> pairs1, pairs2;
261 for (auto& kv : sfToolIndex)
262 if (kv.second == index1)
263 pairs1.insert(kv.first);
264 for (auto& kv : effToolIndex)
265 if (kv.second == index2)
266 pairs2.insert(kv.first);
267 if (pairs1 != pairs2)
268 mismatch = true;
269 } else
270 mismatch = true;
271 }
272 }
273 if (mismatch) {
275 "There must be a one-to-one correspondence between the "
276 << type
277 << " efficiency and scale factor tools "
278 "(including their associated trigger legs and selection tags)");
279 return false;
280 }
281 return true;
282 };
283 if (!checkConsistency(m_parent.m_electronEffToolIndex,
284 m_parent.m_electronSfToolIndex, "electron"))
285 return false;
286 if (!checkConsistency(m_parent.m_photonEffToolIndex,
287 m_parent.m_photonSfToolIndex, "photon"))
288 return false;
289
291 for (auto& kv : m_parent.m_legsPerTag) {
292 std::size_t tag = (kv.first != "*") ? m_parent.m_hasher(kv.first) : 0;
293 for (std::size_t leg :
294 m_parent.listNonOrderedCSValues(kv.second, success)) {
296 m_parent.m_dictionary[leg], success);
297 if (type == xAOD::Type::Electron) {
298 if (m_parent.m_electronEffToolIndex.find(ToolKey(leg, tag)) ==
299 m_parent.m_electronEffToolIndex.end()) {
301 "No electron tool provided for the combination of trigger leg '"
302 << m_parent.m_dictionary[leg] << "' and selection tag '"
303 << kv.first << "' mentioned in the property 'ListOfLegsPerTag'");
304 success = false;
305 }
306 } else if (type == xAOD::Type::Muon) {
307 if (m_parent.m_muonToolIndex.find(ToolKey(0, tag)) ==
308 m_parent.m_muonToolIndex.end()) {
310 "No muon tool provided for the combination of trigger leg '"
311 << m_parent.m_dictionary[leg] << "' and selection tag '"
312 << kv.first << "' mentioned in the property 'ListOfLegsPerTag'");
313 success = false;
314 }
315 } else if (type == xAOD::Type::Photon) {
316 if (m_parent.m_photonEffToolIndex.find(ToolKey(leg, tag)) ==
317 m_parent.m_photonEffToolIndex.end()) {
319 "No photon tool provided for the combination of trigger leg '"
320 << m_parent.m_dictionary[leg] << "' and selection tag '"
321 << kv.first << "' mentioned in the property 'ListOfLegsPerTag'");
322 success = false;
323 }
324 } else {
326 "Unable to determine which lepton flavour is associated to the "
327 "trigger leg '"
328 << m_parent.m_dictionary[leg]
329 << "' in the property 'ListOfLegsPerTag'");
330 success = false;
331 }
332 }
333 }
334 if (!success)
335 return false;
336
338 auto periods = m_parent.m_calculator->m_periods;
339 const auto periods_end = periods.end();
340 for (auto itr1 = periods.begin(); itr1 != periods_end; ++itr1) {
341 auto& x = itr1->m_boundaries;
342 if (x.second < x.first) {
344 "One of the periods specified in TriggerCombination has runMin ("
345 << x.first << ") > runMax (" << x.second << ")");
346 success = false;
347 }
348 for (auto itr2 = itr1 + 1; itr2 != periods_end; ++itr2) {
349 auto& y = itr2->m_boundaries;
350 if ((x.first >= y.first && x.first <= y.second) ||
351 (x.second >= y.first && x.second <= y.second)) {
352 ATH_MSG_ERROR("The periods specified in TriggerCombination overlap");
353 success = false;
354 }
355 }
356 }
357 if (!success)
358 return false;
359
360 return success;
361}
#define ATH_MSG_ERROR(x,...)
TrigGlobEffCorr::ImportData ImportData
TrigGlobEffCorr::CheckConfig CheckConfig
#define y
#define x
static std::string toolnameForDefaultScaleFactor()
To be used with the ListOfLegsPerTool property:
CheckConfig(TrigGlobalEfficiencyCorrectionTool &parent)
static ToolHandle< CPTool > * findToolByName(ToolHandleArray< CPTool > &suppliedTools, const std::string &name)
TrigGlobalEfficiencyCorrectionTool & m_parent
Definition CheckConfig.h:26
xAOD::Type::ObjectType associatedLeptonFlavour(std::size_t leg, bool &success)
MsgStream & msg() const
The standard message stream.
AsgMessaging(const std::string &name)
Constructor with a name.
@ 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