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 "CxxUtils/flat_set.h"
12template <typename Key>
14
15#include <cctype>
16
19
21 : asg::AsgMessaging(&parent), m_parent(parent) {
22 msg().setLevel(parent.msg().level());
23}
24
25template <class CPTool>
26ToolHandle<CPTool>* CheckConfig::findToolByName(
27 ToolHandleArray<CPTool>& suppliedTools, const std::string& name) {
28 for (auto& tool : suppliedTools) {
29 if (tool.name() == name ||
30 tool->name() == name) // athena: not always the same
31 {
32 return &tool;
33 }
34 }
35 return nullptr;
36}
37
39 bool success = true;
40
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");
47 return false;
48 }
49
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");
55 return false;
56 }
57
61 for (auto& kv : m_parent.m_legsPerTool) {
62 auto& name = kv.first;
63 if (name ==
65 continue;
66 if (findToolByName(m_parent.m_suppliedElectronEfficiencyTools, name) ||
67 findToolByName(m_parent.m_suppliedElectronScaleFactorTools, name) ||
68 findToolByName(m_parent.m_suppliedPhotonEfficiencyTools, name) ||
69 findToolByName(m_parent.m_suppliedPhotonScaleFactorTools, name))
70 continue;
71 success = false;
72 if (findToolByName(m_parent.m_suppliedMuonTools, name)) {
73 ATH_MSG_ERROR("Muon tool "
74 << name
75 << " mentioned in property 'ListOfLegsPerTool', which is "
76 "only aimed at electron and photon tools");
77 } else {
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();
87 ATH_MSG_ERROR("Unknown tool "
88 << name << " mentioned in property 'ListOfLegsPerTool'"
89 << known_tools);
90 }
91 }
92 if (!success)
93 return false;
94
97 auto toolsHaveLegInfo = [this](auto& effTools, auto& sfTools,
98 const char* type) {
99 if (effTools.size() < 2)
100 return true;
101 bool success = true;
102 for (int i = 0; i < 2; ++i) {
103 for (auto& tool : (i ? effTools : sfTools)) {
104 const std::string& name = tool.name();
105 if (m_parent.m_legsPerTool.find(name) == m_parent.m_legsPerTool.end()) {
107 << " tool " << name
108 << " associated trigger legs are not indicated in "
109 "'ListOfLegsPerTool', "
110 "doing so is mandatory when several tools are used");
111 success = false;
112 }
113 }
114 }
115 return success;
116 };
117 success &=
118 toolsHaveLegInfo(m_parent.m_suppliedElectronEfficiencyTools,
119 m_parent.m_suppliedElectronScaleFactorTools, "Electron");
120 success &=
121 toolsHaveLegInfo(m_parent.m_suppliedPhotonEfficiencyTools,
122 m_parent.m_suppliedPhotonScaleFactorTools, "Photon");
123 if (!success)
124 return false;
125
129
130 if (m_parent.m_leptonTagDecorations == "") {
131 if (m_parent.m_muonLegsPerTag.size() ||
132 m_parent.m_electronLegsPerTag.size() || m_parent.m_legsPerTag.size() ||
133 m_parent.m_tagsPerTool.size()) {
135 "the property 'LeptonTagDecorations' must be filled when any of "
136 "'ListOfTagsPerTool'"
137 " / 'ListOfLegsPerTag' / 'MuonLegsPerTag' / 'ElectronLegsPerTag' "
138 "is.");
139 return false;
140 }
141 return true;
142 }
143
145 unsigned nElectronToolsWithTags = 0, nMuonToolsWithTags = 0,
146 nPhotonToolsWithTags = 0;
147 for (auto& kv : m_parent.m_tagsPerTool) {
148 auto& name = kv.first;
149 if (findToolByName(m_parent.m_suppliedElectronEfficiencyTools, name) ||
150 findToolByName(m_parent.m_suppliedElectronScaleFactorTools, name))
151 ++nElectronToolsWithTags;
152 else if (findToolByName(m_parent.m_suppliedMuonTools, name))
153 ++nMuonToolsWithTags;
154 else if (findToolByName(m_parent.m_suppliedPhotonEfficiencyTools, name) ||
155 findToolByName(m_parent.m_suppliedPhotonScaleFactorTools, name))
156 ++nPhotonToolsWithTags;
157 else {
158 success = false;
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();
168 ATH_MSG_ERROR("Unknown tool "
169 << name << " mentioned in property 'ListOfTagsPerTool'");
170 }
171 }
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");
178 success = false;
179 }
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");
187 success = false;
188 }
189 if (!success)
190 return false;
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");
198 success = false;
199 }
200 if (!success)
201 return false;
202
203 /*
204 * More checks that are done in other places (or still need to be
205 * implemented!):
206 *
207 * - [advancedConfigChecks()] for each entry in ListOfLegsPerTag there must be
208 * a suitable tool for that tag and leg(s)
209 * - [enumerateTools()] no two electron/photon tools share the same {leg,tag}
210 * combination
211 * - [enumerateTools()] no two muon tools share the same tag
212 * - [advancedConfigChecks()] electron efficiency and scale factors have
213 * identical configurations: for each eff. tool leg/tag we must find a SF
214 * tool, and the other leg/tag pairs associated to those tools must be
215 * identical.
216 * - [UNCHECKED] if tags are used with electron (resp. muon, photon) tools,
217 * then all electron (muon, photon) tools must have an entry in
218 * ListOfTagsPerTool. Done partially in this function, but the case where no
219 * tools are tagged (yet tags are used, according to ListOfLegsPerTag or
220 * LeptonTagDecorations) escapes detection.
221 * - [loadTagsConfiguration()] each entry of ListOfLegsPerTag can be matched
222 * to a suitable tool
223 * - [UNCHECKED] suffixed tag read from a lepton must correspond to a know tag
224 * - [enumerateTools()] list of legs associated to each tool contains only
225 * known legs
226 * - [UNCHECKED TrigGlobEffCorrImportData import* functions] various
227 * consistency checks of the configuration files
228 * - [advancedConfigChecks()] user-specified periods are orthogonal
229 * - [ImportData::parseTriggerString()] no duplicated triggers in the
230 * combination
231 * - [UNCHECKED] for each configured electron/photon tool there is at least
232 * one associated tag^leg pair in 'ListOfLegsPerTag' (unless no
233 * electron/photon tags used)
234 * - [UNCHECKED] for each configured muon tool there is at least one
235 * associated tag in 'MuonLegsPerTag' (unless empty)
236 * - [enumerateTools()] electron tools can't be associated to photon legs; and
237 * reciprocally
238 */
239
240 return success;
241}
242
248 bool success = true;
249
251
254 auto checkConsistency = [this](auto& effToolIndex, auto& sfToolIndex,
255 const char* type) {
256 bool mismatch = (effToolIndex.size() != sfToolIndex.size());
257 if (!mismatch) {
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;
262 flat_set<ToolKey> pairs1, pairs2;
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)
270 mismatch = true;
271 } else
272 mismatch = true;
273 }
274 }
275 if (mismatch) {
277 "There must be a one-to-one correspondence between the "
278 << type
279 << " efficiency and scale factor tools "
280 "(including their associated trigger legs and selection tags)");
281 return false;
282 }
283 return true;
284 };
285 if (!checkConsistency(m_parent.m_electronEffToolIndex,
286 m_parent.m_electronSfToolIndex, "electron"))
287 return false;
288 if (!checkConsistency(m_parent.m_photonEffToolIndex,
289 m_parent.m_photonSfToolIndex, "photon"))
290 return false;
291
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);
299 if (type == xAOD::Type::Electron) {
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'");
306 success = false;
307 }
308 } else if (type == xAOD::Type::Muon) {
309 if (m_parent.m_muonToolIndex.find(ToolKey(0, tag)) ==
310 m_parent.m_muonToolIndex.end()) {
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'");
315 success = false;
316 }
317 } else if (type == xAOD::Type::Photon) {
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'");
324 success = false;
325 }
326 } else {
328 "Unable to determine which lepton flavour is associated to the "
329 "trigger leg '"
330 << m_parent.m_dictionary[leg]
331 << "' in the property 'ListOfLegsPerTag'");
332 success = false;
333 }
334 }
335 }
336 if (!success)
337 return false;
338
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 << ")");
348 success = false;
349 }
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");
355 success = false;
356 }
357 }
358 }
359 if (!success)
360 return false;
361
362 return success;
363}
#define ATH_MSG_ERROR(x)
CxxUtils::flat_set< Key > flat_set
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.
Wrapper for C++23 std::flat_set.
boost::container::flat_set< KEY, COMPARE, KEYCONTAINER > flat_set
Definition flat_set.h:40
@ 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