ATLAS Offline Software
Loading...
Searching...
No Matches
L1Calo_OutlierAndFlatnessTest.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3*/
4
8
11
12#include <dqm_core/AlgorithmManager.h>
13#include "dqm_core/exceptions.h"
14#include <dqm_core/AlgorithmConfig.h>
15#include <dqm_core/Result.h>
16
17#include <TH1.h>
18#include <TF1.h>
19#include <TClass.h>
20#include <cmath>
21
22namespace
23{
24 dqm_algorithms::L1Calo_OutlierAndFlatnessTest L1Calo_OutlierAndFlatnessTest( "L1Calo_OutlierAndFlatnessTest" );
25}
26
27
29 dqm_core::AlgorithmManager::instance().registerAlgorithm(name, this);
30 m_counterSkip = 0;
31}
32
36
37dqm_core::Result *dqm_algorithms::L1Calo_OutlierAndFlatnessTest::execute( const std::string& name, const TObject& object,
38 const dqm_core::AlgorithmConfig& config) {
39
40// if(m_counterSkip < counterSkipMax){
41// dqm_core::Result* result = new dqm_core::Result();
42// result->status_ = dqm_core::Result::Green;
43// m_counterSkip++;
44// return result;
45// }
46
47// m_counterSkip = 0;
48
49 TH1 const * histogram;
50 if( object.IsA()->InheritsFrom( "TH1" ) ) {
51 histogram = static_cast<TH1 const *>(&object);
52
53 if (histogram->GetDimension() > 2 ) {
54 throw dqm_core::BadConfig( ERS_HERE, name, "dimension > 2 " );
55 }
56 } else {
57 throw dqm_core::BadConfig( ERS_HERE, name, "does not inherit from TH1" );
58 }
59
60 const double minstat = tools::GetFirstFromMap( "MinStat", config.getParameters(), 1);
61
62 //Check for minimum statistics
63 if (histogram->GetEntries() < minstat ) {
64 dqm_core::Result* result = new dqm_core::Result();
65 result->status_ = dqm_core::Result::Green;
66 result->tags_["Not enough Signal Statistics"] = minstat;
67 //delete histogram;
68 return result;
69 }
70
71 //check if histogram contains only zeros
72 int checkZeroContent = (int) tools::GetFirstFromMap( "CheckZeroContent", config.getParameters(), 1 );
73
74 if ((checkZeroContent > 0) && (histogram->Integral() == 0) && (histogram->GetEntries() > 0)) {
75 ERS_DEBUG(1, "Histogram " <<histogram->GetName()<<" is filled with zeroes!");
76 dqm_core::Result* result = new dqm_core::Result();
77 result->status_ = dqm_core::Result::Red;
78 result->tags_["Integral"] = histogram->Integral();
79 //delete histogram;
80 return result;
81 }
82
83
84 int checkSigmaDev = 1;
85 int dontCountSigmaOutliers = 0;
86 int ignore0 = 1;
87 double sigmaDev = 0;
88 double absDev = 0;
89
90 //Get configuration parameters and set defaults
91 try {
92 ignore0 = (int) tools::GetFirstFromMap( "Ignore0", config.getParameters(), 1 );
93
94 checkSigmaDev = (int) tools::GetFirstFromMap( "CheckSigmaDev", config.getParameters(), 1 );
95
96 absDev = tools::GetFirstFromMap( "AbsDev", config.getParameters(), 15.0 );
97
98 if (checkSigmaDev) {
99 sigmaDev = tools::GetFirstFromMap( "SigmaDev", config.getParameters());
100 dontCountSigmaOutliers = (int) tools::GetFirstFromMap( "DontCountSigmaOutliers", config.getParameters(), 0);
101 }
102 }
103 catch( dqm_core::Exception & ex ) {
104 throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex );
105 }
106
107
108 const std::vector<int> range = dqm_algorithms::tools::GetBinRange(histogram, config.getParameters());
109 const int xminBin = range[0];
110 const int xmaxBin = range[1];
111
112 //compute the number of empty bins (or bins=0)
113 int zeroBins = 0;
114 for (int i = xminBin; i <= xmaxBin; i++) {
115 if (histogram->GetBinContent(i) == 0) zeroBins++;
116 }
117
118 //Compute outlier bins by using a simplified Grubb's test without cutting on a t-distribution but by giving an external threshold defining how many standard deviations a value has to differ from the mean to be classified as an outlier or by giving an absolute threshold for classifying values as outliers
119 int totalBadBins = 0;
120 double mean=0;
121 double stdev=0;
122
123 //compute the arithmetic mean
124 double sum=0,sum2=0;
125 int counter = 0;
126
127 for(int i=xminBin;i <= xmaxBin;i++){
128 if( histogram->GetBinContent(i) != 0 || ignore0 == false) {
129 sum += histogram->GetBinContent(i);
130 sum2 += histogram->GetBinContent(i)*histogram->GetBinContent(i);
131 counter++;
132 }
133 }
134
135 mean = counter > 0 ? sum/(double)counter : 0;
136 stdev = counter > 0 ? std::sqrt( sum2/static_cast<double>(counter) - mean*mean) : 0;
137
138
139 //check how many bins are out of N sigma range (SigmaDev) or out of the absolute dev (AbsDev) or over absolute limit (AbsLimit), count them as (uncounted) outliers
140 double dev;
141 double absdev_test = 0;
142 if (checkSigmaDev) {
143 for (int i = xminBin; i <= xmaxBin; i++) {
144 if ((histogram->GetBinContent(i) != 0) || (ignore0 == 0)) {
145 dev=std::abs(histogram->GetBinContent(i) - mean)/stdev;
146 absdev_test=std::abs(histogram->GetBinContent(i) - mean);
147 if ((dev > sigmaDev) && (absdev_test > absDev)) {
148 if (!dontCountSigmaOutliers){
149 totalBadBins++;
150 }
151 }
152 }
153 }
154 }
155
156 int totalBadBins_all = 0;
157 double mean_all=0;
158 double stdev_all=0;
159
160 //compute the arithmetic mean
161 double sum_all=0,sum2_all=0;
162 int counter_all = 0;
163
164 for(int i=0;i <= histogram->GetNbinsX() ;i++){
165 if( histogram->GetBinContent(i) != 0 || ignore0 == false) {
166 sum_all += histogram->GetBinContent(i);
167 sum2_all += histogram->GetBinContent(i)*histogram->GetBinContent(i);
168 counter_all++;
169 }
170 }
171
172 mean_all = counter_all > 0 ? sum_all/(double)counter_all : 0;
173 stdev_all = counter_all > 0 ? std::sqrt( sum2_all/static_cast<double>(counter_all) - mean_all*mean_all) : 0;
174
175
176 //check how many bins are out of N sigma range (SigmaDev) or out of the absolute dev (AbsDev) or over absolute limit (AbsLimit), count them as (uncounted) outliers
177 double dev_all;
178 double absdev_test_all = 0;
179 if (checkSigmaDev) {
180 for (int i=0;i <= histogram->GetNbinsX() ;i++) {
181 if ((histogram->GetBinContent(i) != 0) || (ignore0 == 0)) {
182 dev_all=std::abs(histogram->GetBinContent(i) - mean_all)/stdev_all;
183 absdev_test_all=std::abs(histogram->GetBinContent(i) - mean_all);
184 if ((dev_all > sigmaDev) && (absdev_test_all > absDev)) {
185 if (!dontCountSigmaOutliers){
186 totalBadBins_all++;
187 }
188 }
189 }
190 }
191 }
192
193
194 //Prepare map for results and commit outlier specific parts
195 std::map<std::string,double> algparams;
196 algparams["Number_of_outlier_bins"] = totalBadBins;
197 algparams["Number_of_outlier_bins_all"] = totalBadBins_all;
198 algparams["Mean"] = mean;
199 algparams["Standard_deviation"] = stdev;
200 algparams["Number_of_bins_equal_zero"] = zeroBins;
201
202
203 //Compare with given thresholds and compute DQ-Flag
204 dqm_core::Result *result = tools::MakeComparisons(algparams, config.getGreenThresholds(), config.getRedThresholds());
205
206
207 return result;
208}
209
211 out << m_name << ": derivation of OutlierAndFlatnessTest, slimmed and optimized for L1Calo needs"
212 "Checks TH1-inherited histograms for bins which lie either Nsigma or AbsDev away from the mean (by default excludes bins with zero entries). Can also check mean itself\n"
213 "Config Parameters:\n"
214 "\tCheckSigmaDev:\tCheck for deviation in units of standard deviations from mean (default 1).\n"
215 "\tMinStat:\tMinimum Statistics for the histogram to be checked (default 1).\n"
216 "\txmin and/or xmax:\tRestrict all counting to this x-axis interval (default: full axis range).\n"
217 "\txmin and/or xmax:\tThere is a second output parameter (Number_of_outlier_bins_all), which always uses the full range.\n"
218 "\tIgnore0:\tBins with 0 content are ignored for outlier/mean computation (default 1).\n"
219 "\tSigmaDev:\tNumber of Standard Deviations a single bin has to differ from the mean of the distribution to be classified as outlier. Has to be given if \"CheckSigmaDev\" is set to 1. (default 5)\n"
220 "\tAbsDev:\tAbsolute value a single bin has to differ from the mean of the distribution to be classified as outlier. Has to be given if \"CheckAbsDev\" is set to 1.\n"
221 "\tDontCountSigmaDev:\tBins deviating by a given number of standard deviations are not counted as outliers (default 0)."
222 "\tDontCountSigmaDev:\t(Not recommended to be switched on in current config)\n"
223 "Threshold Parameters:\n"
224 "\tStandard_deviation: \tStandard Deviation of distribution.\n"
225 "\tNumber_of_outlier_bins:\tNumber of bins classified as outliers using the given thresholds (in chosen histogram range).\n"
226 "\tNumber_of_outlier_bins_all:\tNumber of bins classified as outliers using the given thresholds (in full histogram range).\n"
227 "\tMean:\tMean of distribution.\n"
228 "\tNumber_of_bins_equal_zero:\tNumber of Bins with zero content." << std::endl;
229}
file declares the dqm_algorithms::L1Calo_OutlierAndFlatnessTest class.
std::string histogram
Definition chains.cxx:52
dqm_core::Result * execute(const std::string &, const TObject &, const dqm_core::AlgorithmConfig &)
void mean(std::vector< double > &bins, std::vector< double > &values, const std::vector< std::string > &files, const std::string &histname, const std::string &tplotname, const std::string &label="")
std::vector< int > GetBinRange(const TH1 *histogram, const std::map< std::string, double > &params)
double GetFirstFromMap(const std::string &paramName, const std::map< std::string, double > &params)
dqm_core::Result * MakeComparisons(const std::map< std::string, double > &algparams, const std::map< std::string, double > &gthreshold, const std::map< std::string, double > &rthreshold)
#define IsA
Declare the TObject style functions.