ATLAS Offline Software
Loading...
Searching...
No Matches
SystematicSet.cxx
Go to the documentation of this file.
1// Author: Steve Farrell (steven.farrell@cern.ch)
2
3
4//
5// includes
6//
7
8#include <stdexcept>
9#include <map>
10#include <functional>
11
14
15// Comparison operator for std::map sorting
17{
18 return a.name() < b.name();
19}
20
21// Equality operator for unordered containers
23{
24 return a.name() == b.name();
25}
26
27
28//
29// method implementations
30//
31
32namespace CP
33{
34
35 // Default constructor
39
40 // Constructor for splitting a single systematics string
43 {
44 if (!systematics.empty()) {
45 std::string::size_type split = 0, split2 = 0;
46 while ((split = systematics.find ("-", split2)) != std::string::npos) {
47 m_sysVariations.insert (systematics.substr (split2, split - split2));
48 split2 = split + 1;
49 }
50 m_sysVariations.insert (systematics.substr (split2, split - split2));
51 }
52 }
53
54
55 // Constructor for a vector of systematic names
56 SystematicSet::SystematicSet(const std::vector<std::string>& systematics)
58 {
59 for (const auto & sys : systematics) {
60 m_sysVariations.insert(sys);
61 }
62 }
63
64 // Constructor for a vector of SystematicVariation
66 (const std::vector<SystematicVariation>& systematics)
68 {
69 for (const auto & sys : systematics) {
70 m_sysVariations.insert(sys);
71 }
72 }
73
74
75 // Constructor for an initializer_list of SystematicVariation
77 (const std::initializer_list<SystematicVariation>& systematics)
79 {
80 for (const auto & sys : systematics) {
81 m_sysVariations.insert(sys);
82 }
83 }
84
85
86 // Insert a systematic into the set
88 {
89 // If insert doesn't change the set, don't change cache flag
90 if(m_sysVariations.insert(systematic).second) {
91 m_joinedName.reset();
92 m_hash.reset();
93 }
94 }
95
96
97 // Insert a SystematicSet into this set
99 {
100 for (const auto & sys : systematics) {
101 insert(sys);
102 }
103 }
104
105
106 // Swap elements of the set
108 {
109 m_sysVariations.swap(otherSet.m_sysVariations);
110 m_joinedName.reset();
111 otherSet.m_joinedName.reset();
112 m_hash.reset();
113 otherSet.m_hash.reset();
114 }
115
116
117 // Clear the systematics and the rest of the state
119 {
120 m_sysVariations.clear();
121 m_joinedName.reset();
122 m_hash.reset();
123 }
124
125
126 // Match full systematic or continuous systematic
128 MATCHTYPE type) const
129 {
130 if (m_sysVariations.find(systematic) != m_sysVariations.end()) {
131 return true;
132 }
133 if (type == FULLORCONTINUOUS) {
134 const SystematicVariation continuous(systematic.basename(),
136 if (m_sysVariations.find(continuous) != m_sysVariations.end()) {
137 return true;
138 }
139 }
140 return false;
141 }
142
143
144 // Get subset of systematics matching basename
146 (const std::string& basename) const
147 {
148 SystematicSet filteredSysts;
149 for (const auto & sys : m_sysVariations) {
150 if (sys.basename() == basename)
151 filteredSysts.insert(sys);
152 }
153 return filteredSysts;
154 }
155
156
157 // Get the set of systematic base names
158 std::set<std::string> SystematicSet::getBaseNames() const
159 {
160 std::set<std::string> baseNames;
161 for (const auto & sys : m_sysVariations) {
162 baseNames.insert(sys.basename());
163 }
164 return baseNames;
165 }
166
167
168 // Get the first systematic that matches basename
171 {
172 const SystematicVariation* sysMatched = NULL;
173 for (const auto & sys : m_sysVariations) {
174 if(sys.basename() == basename) {
175 if(!sysMatched) sysMatched = &sys;
176 else {
177 std::string error = "SystematicSet::getSystematicByBaseName ERROR: ";
178 error += "Multiple matches for requested basename ";
179 error += basename;
180 // Redundant?
181 //std::cerr << error << std::endl;
182 throw std::runtime_error(error);
183 }
184 }
185 }
186 if(sysMatched) return *sysMatched;
187 return SystematicVariation();
188 }
189
190
191 float SystematicSet ::
192 getParameterByBaseName(const std::string& basename) const
193 {
194 return getSystematicByBaseName (basename).parameter();
195 }
196
197
198
199 std::pair<unsigned,float> SystematicSet ::
200 getToyVariationByBaseName (const std::string& basename) const
201 {
202 const auto var = getSystematicByBaseName (basename);
203 if (var.empty())
204 return std::make_pair (0, 0);
205 return var.getToyVariation();
206 }
207
208
209
210 // Filter requested systematics with affecting systematics
212 (const SystematicSet& systConfig, const SystematicSet& affectingSysts,
213 SystematicSet& filteredSysts)
214 {
215 using namespace msgSystematics;
216
217 // the final filtered systematics to report
219
220 // the map of all requested systematics by base name
221 std::map<std::string,SystematicVariation> requestedMap;
222
223 // the list of all inconsistent systematics we encountered
224 std::set<SystematicVariation> inconsistentList;
225
226 // fill requestedMap, reporting errors in case of duplication
227 for (auto& sys : systConfig)
228 {
229 std::string basename = sys.basename();
230 auto iter = requestedMap.find (basename);
231 if (iter != requestedMap.end())
232 {
233 ANA_MSG_ERROR ("inconsistent systematic variations requested: " << sys << " and " << iter->second);
234 return StatusCode::FAILURE;
235 }
236 requestedMap.insert (std::make_pair (basename, sys));
237 }
238
239 // check which of the systematics match the affecting
240 for (auto& sys : affectingSysts)
241 {
242 std::string basename = sys.basename();
243 auto iter = requestedMap.find (basename);
244 if (iter != requestedMap.end())
245 {
246 if (iter->second == sys ||
247 sys.ensembleContains (iter->second))
248 {
249 result.insert (iter->second);
250 } else
251 {
252 // let's remember this as a potential problem
253 inconsistentList.insert (iter->second);
254 }
255 }
256 }
257
258 // check whether any of of the requested variations matched the
259 // base names of our systematics, but not the systematics
260 // supported
261 for (auto& sys : inconsistentList)
262 {
263 if (result.find (sys) == result.end())
264 {
265 ANA_MSG_ERROR ("unsupported systematic variation " << sys << " requested for systematic " << sys.basename());
266 return StatusCode::FAILURE;
267 }
268 }
269
270 // everything worked out, let's commit now
271 result.swap (filteredSysts);
272 return StatusCode::SUCCESS;
273 }
274
275
276 // Return the cached joined systematic name
277 std::string SystematicSet::name() const
278 {
279 if(!m_joinedName.isValid())
280 {
281 m_joinedName.set (joinNames());
282 }
283 return *m_joinedName.ptr();
284 }
285
286
287 // Return the cached hash value
288 std::size_t SystematicSet::hash() const
289 {
290 if(!m_hash.isValid()) {
291 m_hash.set (computeHash());
292 }
293 return *m_hash.ptr();
294 }
295
296
297 // Join systematics into a single string
298 std::string SystematicSet::joinNames() const
299 {
300 std::string joinedName;
301 for (const auto & sys : m_sysVariations) {
302 if (!joinedName.empty()) {
303 joinedName += "-";
304 }
305 joinedName += sys.name();
306 }
307 return joinedName;
308 }
309
310
311 // Compute the hash value for this SystematicSet
312 std::size_t SystematicSet::computeHash() const
313 {
314 static const std::hash<std::string> hashFunction;
315 return hashFunction(name());
316 }
317
318 // Hash function for boost hash
319 std::size_t hash_value(const SystematicSet& sysSet)
320 {
321 return sysSet.hash();
322 }
323
324}
#define ANA_MSG_ERROR(xmsg)
Macro printing error messages.
static Double_t a
static const std::vector< std::string > systematics
bool operator<(const CP::SystematicSet &a, const CP::SystematicSet &b)
bool operator==(const CP::SystematicSet &a, const CP::SystematicSet &b)
Class to wrap a set of SystematicVariations.
std::string name() const
returns: the systematics joined into a single string.
std::set< SystematicVariation > m_sysVariations
description: the set of systematics encapsulated in this class
bool matchSystematic(const SystematicVariation &systematic, MATCHTYPE type=FULL) const
std::size_t hash() const
returns: hash value for the joined string.
void clear()
description: clear the set
MATCHTYPE
description: match systematic or continuous version
void insert(const SystematicVariation &systematic)
description: insert a systematic into the set
SystematicSet()
construct an empty set
CxxUtils::CachedValue< std::string > m_joinedName
description: cache the joined string, useful for hash
void swap(SystematicSet &otherSet)
description: swap elements of a set
SystematicSet filterByBaseName(const std::string &basename) const
description: get the subset of systematics matching basename Should this return a StatusCode instead?
static StatusCode filterForAffectingSystematics(const SystematicSet &systConfig, const SystematicSet &affectingSystematics, SystematicSet &filteredSystematics)
description: filter the systematics for the affected systematics returns: success guarantee: strong f...
std::string joinNames() const
description: join systematic names into single string
std::size_t computeHash() const
description: compute and store the hash value
std::set< std::string > getBaseNames() const
description: get the set of base systematic names from this set
SystematicVariation getSystematicByBaseName(const std::string &basename) const
description: get the first systematic matching basename
CxxUtils::CachedValue< std::size_t > m_hash
description: cached hash value for quick retrieval in unordered containers
std::string basename() const
description: the base name, i.e.
void reset()
Reset the value to invalid.
SystematicSet()
construct an empty set
std::vector< std::string > split(const std::string &s, const std::string &t=":")
Definition hcg.cxx:177
Select isolated Photons, Electrons and Muons.
std::size_t hash_value(const SystematicSet &)
Hash function specifically for boost::hash.
std::string basename(std::string name)
Definition utils.cxx:207