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