ATLAS Offline Software
SystematicVariation.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 
7 
8 //
9 // includes
10 //
11 
13 
14 #include <cmath>
15 #include <regex>
16 #include <sstream>
17 #include <RootCoreUtils/Assert.h>
18 #include <RootCoreUtils/ThrowMsg.h>
19 
21 {
22  return a.name() < b.name();
23 }
24 
25 
27 {
28  return a.name() == b.name();
29 }
30 
31 //
32 // method implementations
33 //
34 
35 namespace CP
36 {
37  namespace
38  {
45  std::string packUnsigned (unsigned value)
46  {
47  std::ostringstream result;
48  result << value;
49  return result.str();
50  }
51 
52 
60  unsigned unpackUnsigned (const std::string& value)
61  {
62  std::istringstream str (value);
63  unsigned result = 0;
64  if (!(str >> result))
65  RCU_THROW_MSG ("failed to parse \"" + value + "\" into an unsigned");
66  char c;
67  if (str >> c)
68  RCU_THROW_MSG ("failed to parse \"" + value + "\" into an unsigned");
69  return result;
70  }
71 
72 
73 
80  std::string packFloat (float value, const std::string& plus,
81  const std::string& minus)
82  {
83  std::string separator = plus;
84  if (value < 0)
85  {
86  separator = minus;
87  value *= -1;
88  }
89  RCU_ASSERT (!separator.empty());
90 
91  std::ostringstream str;
92  str << rint (value * 10000);
93  std::string number = str.str();
94 
95  while (number.size() < 5)
96  number = "0" + number;
97  return number.substr (0, number.size() - 4) + separator + number.substr (number.size() - 4);
98  }
99 
100 
101 
110  bool unpackFloatHelper (const std::string& value,
111  const std::string& separator,
112  float& result)
113  {
114  if (!separator.empty())
115  {
116  std::string::size_type split = value.rfind (separator);
117  if (split != std::string::npos)
118  {
119  std::istringstream str (value.substr (0, split) + "." + value.substr (split + separator.size()));
120  if (!(str >> result))
121  RCU_THROW_MSG ("failed to parse into a float: " + value);
122  char c;
123  if (str >> c)
124  RCU_THROW_MSG ("failed to parse into a float: " + value);
125  return true;
126  }
127  }
128  return false;
129  }
130 
131 
132 
140  float unpackFloat (const std::string& value, const std::string& plus,
141  const std::string& minus)
142  {
143  float result = 0;
144  if (unpackFloatHelper (value, plus, result))
145  return result;
146  if (unpackFloatHelper (value, minus, result))
147  {
148  result *= -1;
149  return result;
150  }
151  RCU_THROW_MSG ("failed to parse into a float: " + value);
152  return 0; //compiler dummy
153  }
154  }
155 
156 
157 
159  testInvariant () const
160  {
161  //RCU_INVARIANT (this != 0);
162  }
163 
164 
165 
168  {
169  RCU_NEW_INVARIANT (this);
170  }
171 
172 
173 
175  SystematicVariation (const std::string& val_name)
176  : m_name (val_name)
177  {
178  RCU_NEW_INVARIANT (this);
179  }
180 
181 
182 
184  SystematicVariation (const std::string& val_basename,
185  const std::string& val_subvariation)
186  : m_name (val_basename + "__" + val_subvariation)
187  {
188  RCU_NEW_INVARIANT (this);
189  }
190 
191 
192 
194  SystematicVariation (const std::string& val_basename,
195  float val_parameter)
196  {
197  std::string separator = "up";
198  if (val_parameter < 0)
199  {
200  separator = "down";
201  val_parameter *= -1;
202  }
203  std::ostringstream str;
204  str << rint (val_parameter * 10000);
205  std::string number = str.str();
206 
207  while (number.size() < 5)
208  number = "0" + number;
209 
213  if (number != "00000")
214  {
215  m_name = val_basename + "__" + number.substr (0, number.size()-4)
216  + separator + number.substr (number.size()-4);
217  while (m_name[m_name.size()-1] == '0')
218  m_name.resize (m_name.size()-1);
219  }
220 
221  RCU_NEW_INVARIANT (this);
222  }
223 
224 
225 
226  #ifndef __CINT__
228  SystematicVariation (const std::string& val_basename, CONTINUOUS_ARG)
229  : m_name (val_basename + "__continuous")
230  {
231  RCU_NEW_INVARIANT (this);
232  }
233  #endif
234 
235 
236 
238  makeToyVariation (const std::string& basename,
239  unsigned toyIndex, float toyScale)
240  {
241  RCU_REQUIRE (toyIndex > 0);
242  RCU_REQUIRE (toyScale > 0);
243  return SystematicVariation
244  (basename, "toy_" + packUnsigned (toyIndex) + "_" + packFloat (toyScale, "scale", ""));
245  }
246 
247 
248 
250  makeContinuousEnsemble (const std::string& basename)
251  {
253  }
254 
255 
256 
258  makeToyEnsemble (const std::string& basename)
259  {
260  return SystematicVariation (basename, "toy_ensemble");
261  }
262 
263 
264 
266  makeContinuous (const std::string& basename)
267  {
268  return SystematicVariation (basename + "__continuous");
269  }
270 
271 
272 
274  SystematicVariation (const std::set<SystematicVariation>& systematics,
275  const std::string& val_basename)
276  {
277  RCU_NEW_INVARIANT (this);
278 
279  for (std::set<SystematicVariation>::const_iterator
280  sys = systematics.begin(),
281  end = systematics.end(); sys != end; ++ sys)
282  {
283  if (sys->basename() == val_basename)
284  {
285  *this = *sys;
286  return;
287  }
288  }
289  }
290 
291 
292 
294  empty () const
295  {
296  RCU_READ_INVARIANT (this);
297  return m_name.empty();
298  }
299 
300 
301 
302  const std::string& SystematicVariation ::
303  name () const
304  {
305  RCU_READ_INVARIANT (this);
306  return m_name;
307  }
308 
309 
310 
312  basename () const
313  {
314  RCU_READ_INVARIANT (this);
315 
316  std::string::size_type split = m_name.rfind ("__");
317  if (split != std::string::npos)
318  return m_name.substr (0, split);
319  else
320  return m_name;
321  }
322 
323 
324 
326  subvariation () const
327  {
328  RCU_READ_INVARIANT (this);
329 
330  std::string::size_type split = m_name.rfind ("__");
331  if (split != std::string::npos)
332  return m_name.substr (split + 2);
333  else
334  return "";
335  }
336 
337 
338 
340  parameter () const
341  {
342  RCU_READ_INVARIANT (this);
343 
344  std::string subvariation = this->subvariation();
345 
346  std::string::size_type split = subvariation.rfind ("up");
347  if (split != std::string::npos)
348  {
349  std::istringstream str (subvariation.substr (0, split) + "." + subvariation.substr (split + 2));
350  float result;
351  if (str >> result)
352  return result;
353  else
354  return 0;
355  }
356 
357  split = subvariation.rfind ("down");
358  if (split != std::string::npos)
359  {
360  std::istringstream str (subvariation.substr (0, split) + "." + subvariation.substr (split + 4));
361  float result;
362  if (str >> result)
363  return -result;
364  else
365  return 0;
366  }
367 
368  return 0;
369  }
370 
371 
372 
373  std::pair<unsigned,float> SystematicVariation ::
374  getToyVariation () const
375  {
376  // no invariant used
377 
378  std::string variation = subvariation();
379 
380  const std::size_t prefixSize = 4;
381  const auto split1 = variation.find ("toy_");
382  if (split1 != 0)
383  RCU_THROW_MSG ("not a toy variation: " + name());
384  const auto split2 = variation.find ("_", split1 + prefixSize);
385  if (split2 == std::string::npos)
386  RCU_THROW_MSG ("not a toy variation: " + name());
387 
388  const auto sub1 = variation.substr (prefixSize, split2 - prefixSize);
389  const auto sub2 = variation.substr (split2 + 1);
390  return std::make_pair (unpackUnsigned (sub1), unpackFloat (sub2, "scale", ""));
391  }
392 
393 
394 
396  isToyEnsemble () const
397  {
398  // no invariant used
399  return subvariation() == "toy_ensemble";
400  }
401 
402 
403 
405  isContinuousEnsemble () const
406  {
407  // no invariant used
408  return subvariation() == "continuous";
409  }
410 
411 
412 
414  isEnsemble () const
415  {
416  // no invariant used
417  return isToyEnsemble() || isContinuousEnsemble();
418  }
419 
420 
421 
424  {
425  if (basename() != sys.basename())
426  return false;
427  if (isContinuousEnsemble() && sys.isContinuousVariation())
428  return true;
429  if (isToyEnsemble() && sys.isToyVariation())
430  return true;
431  return false;
432  }
433 
434 
435 
437  isToyVariation () const
438  {
439  static const std::regex pattern (".*__toy_[0-9]+_[0-9]+((scale)[0-9]{1,4})?");
440  return regex_match (m_name, pattern);
441  }
442 
443 
444 
446  isContinuousVariation () const
447  {
448  static const std::regex pattern (".*__[0-9]+((up)|(down))([0-9]{1,4})?");
449  return regex_match (m_name, pattern);
450  }
451 
452 
453 
454  std::ostream& operator << (std::ostream& str, const CP::SystematicVariation& obj)
455  {
456  return str << obj.name();
457  }
458 }
CP::SystematicVariation::SystematicVariation
SystematicVariation()
effects: standard default constructor guarantee: no-fail
Definition: SystematicVariation.cxx:167
mergePhysValFiles.pattern
pattern
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:26
CP::SystematicVariation::CONTINUOUS
@ CONTINUOUS
Definition: SystematicVariation.h:79
get_generator_info.result
result
Definition: get_generator_info.py:21
CP::SystematicVariation::makeToyVariation
static SystematicVariation makeToyVariation(const std::string &basename, unsigned toyIndex, float toyScale)
constructor for toy systematics
Definition: SystematicVariation.cxx:238
CP::SystematicVariation::basename
std::string basename() const
description: the base name, i.e.
Definition: SystematicVariation.cxx:312
RCU_REQUIRE
#define RCU_REQUIRE(x)
Definition: Assert.h:208
CP::SystematicVariation::name
const std::string & name() const
description: the full systematics name, for use in strings, etc.
Definition: SystematicVariation.cxx:303
CP::SystematicVariation::ensembleContains
bool ensembleContains(const SystematicVariation &sys) const
whether this is an ensemble that contains the given systematic variation
Definition: SystematicVariation.cxx:423
athena.value
value
Definition: athena.py:124
Assert.h
CP::SystematicVariation
Definition: SystematicVariation.h:47
CP
Select isolated Photons, Electrons and Muons.
Definition: Control/xAODRootAccess/xAODRootAccess/TEvent.h:48
CP::SystematicVariation::isToyVariation
bool isToyVariation() const
whether this represents a toy variation
Definition: SystematicVariation.cxx:437
mapkey::sys
@ sys
Definition: TElectronEfficiencyCorrectionTool.cxx:42
mergePhysValFiles.end
end
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:93
PrepareReferenceFile.regex
regex
Definition: PrepareReferenceFile.py:43
CP::SystematicVariation::isContinuousVariation
bool isContinuousVariation() const
whether this represents a continuous variation
Definition: SystematicVariation.cxx:446
operator<
bool operator<(const CP::SystematicVariation &a, const CP::SystematicVariation &b)
Definition: SystematicVariation.cxx:20
CP::SystematicVariation::CONTINUOUS_ARG
CONTINUOUS_ARG
effects: constructor for indicating continuous systematics guarantee: strong failures: out of memory ...
Definition: SystematicVariation.h:79
CP::SystematicVariation::isEnsemble
bool isEnsemble() const
whether this represents any form of ensemble
Definition: SystematicVariation.cxx:414
CP::SystematicVariation::testInvariant
void testInvariant() const
effects: test the invariant of this object guarantee: no-fail
Definition: SystematicVariation.cxx:159
CheckAppliedSFs.systematics
def systematics
Definition: CheckAppliedSFs.py:231
python.selection.number
number
Definition: selection.py:20
CP::SystematicVariation::makeContinuousEnsemble
static SystematicVariation makeContinuousEnsemble(const std::string &basename)
constructor for continuous systematics ensemble
Definition: SystematicVariation.cxx:250
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:77
ThrowMsg.h
CP::SystematicVariation::makeContinuous
static SystematicVariation makeContinuous(const std::string &basename)
Named constructor for continuous systematics.
Definition: SystematicVariation.cxx:266
operator==
bool operator==(const CP::SystematicVariation &a, const CP::SystematicVariation &b)
Definition: SystematicVariation.cxx:26
CP::operator<<
std::ostream & operator<<(std::ostream &str, const CP::SystematicVariation &obj)
Definition: SystematicVariation.cxx:454
CP::SystematicVariation::getToyVariation
std::pair< unsigned, float > getToyVariation() const
unpack the toy variation
Definition: SystematicVariation.cxx:374
a
TList * a
Definition: liststreamerinfos.cxx:10
python.CaloScaleNoiseConfig.str
str
Definition: CaloScaleNoiseConfig.py:78
CP::SystematicVariation::empty
bool empty() const
returns: whether this is an empty systematic, i.e.
Definition: SystematicVariation.cxx:294
str
Definition: BTagTrackIpAccessor.cxx:11
RCU_THROW_MSG
#define RCU_THROW_MSG(message)
Definition: PrintMsg.h:58
python.PyAthena.obj
obj
Definition: PyAthena.py:132
RCU_ASSERT
#define RCU_ASSERT(x)
Definition: Assert.h:222
CP::SystematicVariation::makeToyEnsemble
static SystematicVariation makeToyEnsemble(const std::string &basename)
constructor for toy systematics ensemble
Definition: SystematicVariation.cxx:258
python.compressB64.c
def c
Definition: compressB64.py:93
CP::SystematicVariation::subvariation
std::string subvariation() const
description: the part of the name that indicates by how many sigmas we varied guarantee: strong failu...
Definition: SystematicVariation.cxx:326
RCU_READ_INVARIANT
#define RCU_READ_INVARIANT(x)
Definition: Assert.h:229
Trk::split
@ split
Definition: LayerMaterialProperties.h:38
SystematicVariation.h
CP::SystematicVariation::isToyEnsemble
bool isToyEnsemble() const
whether this represents a toy ensemble
Definition: SystematicVariation.cxx:396
CP::SystematicVariation::isContinuousEnsemble
bool isContinuousEnsemble() const
whether this represents a continuous ensemble
Definition: SystematicVariation.cxx:405
CP::SystematicVariation::m_name
std::string m_name
description: members directly corresponding to accessors
Definition: SystematicVariation.h:264
CP::SystematicVariation::parameter
float parameter() const
description: the numeric parameter contained in the subvariation(), or 0 if the subvariation can't be...
Definition: SystematicVariation.cxx:340
RCU_NEW_INVARIANT
#define RCU_NEW_INVARIANT(x)
Definition: Assert.h:233
beamspotman.basename
basename
Definition: beamspotman.py:640