ATLAS Offline Software
LastBinThreshold.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
3 */
4 
9 #include "dqm_core/AlgorithmConfig.h"
10 #include "dqm_core/AlgorithmManager.h"
13 #include "ers/ers.h"
14 
15 #include "TClass.h"
16 #include "TObject.h"
17 #include "TH1.h"
18 
19 #include <iostream>
20 #include <cmath>
21 
22 namespace { // anonymous
23 dqm_algorithms::LastBinThreshold instance("LastBinThreshold"); // global instance to have this algorithm registered with the manager
24 }
25 
27  m_nBinsToWatch(0)
28  , m_nBinsToExceed(0)
29  , m_greaterThan(false)
30  , m_valueThresholds(false)
31  , m_getEntries(0)
32  , m_grn(0.)
33  , m_red(0.)
34  , m_name(name)
35 {
36  dqm_core::AlgorithmManager::instance().registerAlgorithm(m_name, this);
37 }
38 
40 {
41  /* noop */
42 }
43 
45 {
46  return new LastBinThreshold(m_name); // somebody else must delete this
47 }
48 
49 dqm_core::Result *dqm_algorithms::LastBinThreshold::execute(const std::string &name, const TObject &object, const dqm_core::AlgorithmConfig &config)
50 {
51  if (!object.IsA()->InheritsFrom("TH1")) { // this could also be TH2 or TH3
52  throw dqm_core::BadConfig(ERS_HERE, name, "does not inherit from TH1");
53  }
54  const TH1 &histogram = dynamic_cast<const TH1 &>(object); // should be possible after the previous check (otherwise we'd get a std::bad_cast)
55  if (histogram.GetDimension() > 1) { // only one-dimensional histograms have a last bin, but feel free to generalise this for D > 1 if you like
56  throw dqm_core::BadConfig(ERS_HERE, name, "has more than one dimension");
57  }
58 
60  getThresholds(name, config);
61 
62  dqm_core::Result *result = new dqm_core::Result(); // somebody else must delete this
63  int grnExceeded = 0; // how many of the checked bins exceeded the green threshold
64  int redExceeded = 0; // how many of the checked bins exceeded the red threshold
65 
66  int currentBin = histogram.GetNbinsX(); // this is the last proper bin (we don't want the overflow bin)
67  if (m_getEntries == 0) { // skip trailing bins with zero content
68  while ((histogram.GetBinContent(currentBin) == 0) && (currentBin > 0)) --currentBin;
69  } else if (m_getEntries == 1) { // assume that this value corresponds to the bin number of the last bin
70  currentBin = histogram.GetEntries();
71  } else if (m_getEntries == 2) { /* noop */ } // just start checking from the rightmost bin
72 
73  result->tags_["LastBinNumber"] = currentBin; // report where we began the checks (mostly for debugging)
74  result->tags_["LastBinCenter"] = histogram.GetBinCenter(currentBin); // report where that is on the x-axis
75  // if the histogram is completely empty then currentBin is now zero, and we shouldn't check anything,
76  // therefore the break statement is at the front (!) of the following loop
77 
78  for (int i = 0; i < m_nBinsToWatch; ++i) { // step through the final NBinsToWatch bins
79  if (currentBin == 0) break; // we hit the left end (and we don't want the underflow bin)
80  double content = histogram.GetBinContent(currentBin);
81  if (m_valueThresholds) {
82  if (m_greaterThan) content = histogram.GetXaxis()->GetBinUpEdge(currentBin);
83  else content = histogram.GetXaxis()->GetBinLowEdge(currentBin);
84  }
85  if (exceeds(content, m_grn)) ++grnExceeded; // can be less-than or greater-than relation
86  if (exceeds(content, m_red)) ++redExceeded; // can be less-than or greater-than relation
87  --currentBin;
88  }
89 
90  result->tags_["GreenExceeded"] = grnExceeded;
91  result->tags_["RedExceeded"] = redExceeded;
92  if (grnExceeded < redExceeded) // sanity check, this should never happen because getThresholds() makes sure the thresholds have the right order
93  throw dqm_core::BadConfig(ERS_HERE, name, "more bins exceeded the red threshold than the green threshold, this shouldn't happen");
94 
95  if (grnExceeded < m_nBinsToExceed) result->status_ = dqm_core::Result::Green;
96  else if (redExceeded < m_nBinsToExceed) result->status_ = dqm_core::Result::Yellow;
97  else result->status_ = dqm_core::Result::Red;
98  return result;
99 }
100 
102 {
103  out << m_name << ": Checks whether the last bin(s) of a histogram exceed the given thresholds.\n"
104  "Mandatory green/red thresholds: Threshold - the thresholds against which the bin contents are compared.\n"
105  "Optional parameter: NBinsToWatch - number of final bins that will be checked. (NBinsToWatch >= 1, default = 1)\n"
106  " The result of the algorithm is the worst-case result of all checked bins.\n"
107  "Optional parameter: NBinsToExceed - minimal number of checked bins that have to exceed the given thresholds\n"
108  " before the corresponding result is returned. (1 <= NBinsToExceed <= NBinsToWatch, default = 1)\n"
109  "Optional parameter: GreaterThan - how the values will be compared. (GreaterThan = {0, 1}, default = 1)\n"
110  " GreaterThan == 0: the given thresholds are lower thresholds. (requires green >= red)\n"
111  " GreaterThan == 1: the given thresholds are upper thresholds. (requires green <= red)\n"
112  "Optional parameter: ValueThresholds - which values will be compared. (ValueThresholds = {0, 1}, default = 0)\n"
113  " ValueThresholds == 0: the thresholds correspond to the bin content.\n"
114  " ValueThresholds == 1: the thresholds correspond to the bin x-axis value.\n"
115  "Optional parameter: GetEntries - how to determine which bin is the last. (GetEntries = {0, 1, 2}, default = 0)\n"
116  " GetEntries == 0: find the rightmost non-zero bin, ignore trailing zero bins.\n"
117  " GetEntries == 1: take the return value of TH1::GetEntries() as the number of the last bin.\n"
118  " GetEntries == 2: take the rightmost bin as the last bin, regardless of the bin content.\n"
119  "Returned value: LastBinNumber - the bin number of the last checked (i. e. non-zero) bin.\n"
120  "Returned value: LastBinCenter - the centre of that bin on the horizontal axis.\n"
121  "Returned value: GreenExceeded - how many bins exceeded the green threshold.\n"
122  "Returned value: RedExceeded - how many bins exceeded the red threshold." << std::endl;
123 }
124 
125 void dqm_algorithms::LastBinThreshold::getParameters(const std::string &name, const dqm_core::AlgorithmConfig &config)
126 {
127  // The following intermediate variables do not yet have the correct type,
128  // since dqm_core::AlgorithmConfig::getParameters can only return values of type double.
129  // We cannot cast them immediately because we still need to perform some manual range checks.
130  //
131  const double par0 = dqm_algorithms::tools::GetFirstFromMap("NBinsToWatch", config.getParameters(), 1); // default = 1
132  const double par1 = dqm_algorithms::tools::GetFirstFromMap("NBinsToExceed", config.getParameters(), 1); // default = 1
133  const double par2 = dqm_algorithms::tools::GetFirstFromMap("GreaterThan", config.getParameters(), 1); // default = true
134  const double par3 = dqm_algorithms::tools::GetFirstFromMap("ValueThresholds", config.getParameters(), 0); // default = false
135  const double par4 = dqm_algorithms::tools::GetFirstFromMap("GetEntries", config.getParameters(), 0); // default = 0
136 
137  if (par0 < 1)
138  throw dqm_core::BadConfig(ERS_HERE, name, "NBinsToWatch must be 1 or greater");
139  if (par1 < 1)
140  throw dqm_core::BadConfig(ERS_HERE, name, "NBinsToExceed must be 1 or greater");
141  if (par1 > par0)
142  throw dqm_core::BadConfig(ERS_HERE, name, "NBinsToExceed must not be greater than NBinsToWatch");
143  if ((par2 != 0) && (par2 != 1))
144  throw dqm_core::BadConfig(ERS_HERE, name, "GreaterThan must be 0 or 1");
145  if ((par3 != 0) && (par3 != 1))
146  throw dqm_core::BadConfig(ERS_HERE, name, "ValueThresholds must be 0 or 1");
147  if ((par4 != 0) && (par4 != 1) && (par4 != 2))
148  throw dqm_core::BadConfig(ERS_HERE, name, "GetEntries must be 0, 1 or 2");
149 
150  m_nBinsToWatch = static_cast<int>(par0);
151  m_nBinsToExceed = static_cast<int>(par1);
152  m_greaterThan = static_cast<bool>(par2);
153  m_valueThresholds = static_cast<bool>(par3);
154  m_getEntries = static_cast<int>(par4);
155 }
156 
157 void dqm_algorithms::LastBinThreshold::getThresholds(const std::string &name, const dqm_core::AlgorithmConfig &config)
158 {
159  m_grn = dqm_algorithms::tools::GetFromMap("Threshold", config.getGreenThresholds());
160  m_red = dqm_algorithms::tools::GetFromMap("Threshold", config.getRedThresholds());
161 
162  if (m_greaterThan && (m_red < m_grn))
163  throw dqm_core::BadConfig(ERS_HERE, name, "using greater-than comparison, but red threshold is less than green threshold");
164  else if (!m_greaterThan && (m_red > m_grn))
165  throw dqm_core::BadConfig(ERS_HERE, name, "using less-than comparison, but red threshold is greater than green threshold");
166 }
167 
169 {
170  if (m_greaterThan)
171  return value > threshold;
172  else
173  return value < threshold;
174  // We could derive that behaviour from testing whether (m_grn < m_red) or (m_grn > m_red), but then we
175  // weren't able to find a reasonable behaviour if (m_grn == m_red), i. e. for people who never want yellow.
176 }
dqm_algorithms::LastBinThreshold::getParameters
void getParameters(const std::string &name, const dqm_core::AlgorithmConfig &config)
Definition: LastBinThreshold.cxx:125
dqm_algorithms::LastBinThreshold::~LastBinThreshold
virtual ~LastBinThreshold()
Definition: LastBinThreshold.cxx:39
get_generator_info.result
result
Definition: get_generator_info.py:21
IsA
#define IsA
Declare the TObject style functions.
Definition: xAODTEventBranch.h:59
python.AthDsoLogger.out
out
Definition: AthDsoLogger.py:71
athena.value
value
Definition: athena.py:122
dqm_algorithms::LastBinThreshold
Definition: LastBinThreshold.h:19
config
Definition: PhysicsAnalysis/AnalysisCommon/AssociationUtils/python/config.py:1
instance
std::map< std::string, double > instance
Definition: Run_To_Get_Tags.h:8
grepfile.content
string content
Definition: grepfile.py:56
dqm_algorithms::LastBinThreshold::printDescription
virtual void printDescription(std::ostream &out)
Definition: LastBinThreshold.cxx:101
lumiFormat.i
int i
Definition: lumiFormat.py:92
Result
ICscStripFitter::Result Result
Definition: CalibCscStripFitter.cxx:13
dqm_algorithms::LastBinThreshold::clone
virtual LastBinThreshold * clone()
Definition: LastBinThreshold.cxx:44
python.handimod.Green
int Green
Definition: handimod.py:524
python.handimod.Red
Red
Definition: handimod.py:551
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
dqm_algorithms::LastBinThreshold::execute
virtual dqm_core::Result * execute(const std::string &name, const TObject &object, const dqm_core::AlgorithmConfig &config)
Definition: LastBinThreshold.cxx:49
threshold
Definition: chainparser.cxx:74
dqm_algorithms::LastBinThreshold::LastBinThreshold
LastBinThreshold(const std::string &name)
Definition: LastBinThreshold.cxx:26
dqm_algorithms::LastBinThreshold::getThresholds
void getThresholds(const std::string &name, const dqm_core::AlgorithmConfig &config)
Definition: LastBinThreshold.cxx:157
dqm_algorithms::LastBinThreshold::m_name
const std::string m_name
Definition: LastBinThreshold.h:51
PowhegPy8EG_H2a.getParameters
def getParameters()
Definition: PowhegPy8EG_H2a.py:39
TH1
Definition: rootspy.cxx:268
dqm_algorithms::LastBinThreshold::exceeds
bool exceeds(double value, double threshold) const
Definition: LastBinThreshold.cxx:168
AlgorithmHelper.h
dqm_algorithms::tools::GetFromMap
const T & GetFromMap(const std::string &pname, const std::map< std::string, T > &params)
Definition: AlgorithmHelper.h:114
pickleTool.object
object
Definition: pickleTool.py:30
LastBinThreshold.h
dqm_algorithms::tools::GetFirstFromMap
double GetFirstFromMap(const std::string &paramName, const std::map< std::string, double > &params)
Definition: AlgorithmHelper.cxx:339
dumpTgcDigiThreshold.threshold
list threshold
Definition: dumpTgcDigiThreshold.py:34
histogram
std::string histogram
Definition: chains.cxx:52