ATLAS Offline Software
BinContentComp.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 
10 #include <dqm_core/AlgorithmConfig.h>
13 #include <TH1.h>
14 #include <TF1.h>
15 #include <TProfile.h>
16 #include <TProfile2D.h>
17 #include <TClass.h>
18 #include <cmath>
19 #include <ers/ers.h>
20 
21 
22 #include <dqm_core/AlgorithmManager.h>
23 static dqm_algorithms::BinContentComp myInstance;
24 
25 
27 {
28  dqm_core::AlgorithmManager::instance().registerAlgorithm( "BinContentComp", this );
29 }
30 
32 {
33 }
34 
37 {
38  return new BinContentComp();
39 }
40 
41 
44  const TObject & object,
45  const dqm_core::AlgorithmConfig & config )
46 {
47  const TH1 * histogram;
48  TH1 * refhist;
49 
50  if(object.IsA()->InheritsFrom( "TH1" )) {
51  histogram = static_cast<const TH1*>(&object);
52  if (histogram->GetDimension() > 2 ){
53  throw dqm_core::BadConfig( ERS_HERE, name, "dimension > 2 " );
54  }
55  } else {
56  throw dqm_core::BadConfig( ERS_HERE, name, "does not inherit from TH1");
57  }
58 
59  double value=-99999;
60  try {
61  refhist = static_cast<TH1*>( config.getReference() );
62  }
63  catch (dqm_core::BadConfig &ex ) {
64  refhist=0;
65  try {
66  value = dqm_algorithms::tools::GetFirstFromMap( "Value", config.getParameters() );
67  }
68  catch( dqm_core::Exception & ex ) {
69  throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex );
70  }
71  }
72  if ( ! refhist ) {
73  try {
74  value = dqm_algorithms::tools::GetFirstFromMap( "Value", config.getParameters() );
75  }
76  catch( dqm_core::Exception & ex ) {
77  throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex );
78  }
79  } else {
80 
81  if (histogram->GetDimension() != refhist->GetDimension() ) {
82  throw dqm_core::BadRefHist( ERS_HERE, name, "Dimension" );
83  }
84 
85  if ((histogram->GetNbinsX() != refhist->GetNbinsX()) || (histogram->GetNbinsY() != refhist->GetNbinsY())) {
86  throw dqm_core::BadRefHist( ERS_HERE, "number of bins", name );
87  }
88 }
89 
90  const double minstat = dqm_algorithms::tools::GetFirstFromMap( "MinStat", config.getParameters(), -1);
91  if (histogram->GetEntries() < minstat ) {
93  result->tags_["InsufficientEntries"] = histogram->GetEntries();
94  return result;
95  }
96 
97  const TProfile* profile(nullptr);
98  const TProfile2D* profile2D(nullptr);
99  const double minBinEntries = dqm_algorithms::tools::GetFirstFromMap( "MinBinEntries", config.getParameters(), -1);
100  if(minBinEntries > 0) {
101  if (object.InheritsFrom("TProfile")) profile = dynamic_cast<const TProfile*>(&object);
102  else if (object.InheritsFrom("TProfile2D")) profile2D = dynamic_cast<const TProfile2D*>(&object);
103  }
104 
105  const bool ignorezero = (bool) dqm_algorithms::tools::GetFirstFromMap( "Ignore0", config.getParameters(), 0);
106  const bool ignoreInputZero = (bool) dqm_algorithms::tools::GetFirstFromMap( "IgnoreInput0", config.getParameters(), 0);
107  bool greaterthan = (bool) dqm_algorithms::tools::GetFirstFromMap( "GreaterThan", config.getParameters(), 0);
108  bool lessthan = (bool) dqm_algorithms::tools::GetFirstFromMap( "LessThan", config.getParameters(), 0);
109  const bool publish = (bool) dqm_algorithms::tools::GetFirstFromMap( "PublishBins", config.getParameters(), 0);
110  const int maxpublish = (int) dqm_algorithms::tools::GetFirstFromMap( "MaxPublish", config.getParameters(), 20);
111  const bool publishHistogram = (bool) dqm_algorithms::tools::GetFirstFromMap( "PublishHistogram", config.getParameters(), 1);
112  const bool normref = (bool) dqm_algorithms::tools::GetFirstFromMap( "NormRef", config.getParameters(), 0);
113  const double maxdiffabs = dqm_algorithms::tools::GetFirstFromMap( "MaxDiffAbs", config.getParameters(), -1);
114  const double maxdiffrel = dqm_algorithms::tools::GetFirstFromMap( "MaxDiffRel", config.getParameters(), -1);
115  const double fixerr = dqm_algorithms::tools::GetFirstFromMap( "FixedError", config.getParameters(), 0);
116  const bool increferr = (bool) dqm_algorithms::tools::GetFirstFromMap( "IncludeRefError", config.getParameters(), 0);
117 
118  if (greaterthan && lessthan) {
119  ERS_INFO("Both GreaterThan and LessThan parameters set: Will check for for both");
120  greaterthan = false;
121  lessthan = false;
122  }
123 
124  double bin_threshold;
125  double gthreshold;
126  double rthreshold;
127  try {
128  bin_threshold = dqm_algorithms::tools::GetFirstFromMap( "NSigma", config.getParameters() );
129  rthreshold = dqm_algorithms::tools::GetFromMap( "NBins", config.getRedThresholds() );
130  gthreshold = dqm_algorithms::tools::GetFromMap( "NBins", config.getGreenThresholds() );
131  }
132  catch( dqm_core::Exception & ex ) {
133  throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex );
134  }
135 
136 
137  int count = 0;
138 
139 
140  std::vector<int> range=dqm_algorithms::tools::GetBinRange(histogram, config.getParameters());
141 
143  double refcont =0;
144  TH1* resulthisto = nullptr;
145  if (publishHistogram) {
146  if (histogram->InheritsFrom("TH2")) {
147  resulthisto=(TH1*)(histogram->Clone());
148  } else if (histogram->InheritsFrom("TH1")) {
149  resulthisto=(TH1*)(histogram->Clone());
150  } else {
151  throw dqm_core::BadConfig( ERS_HERE, name, "does not inherit from TH1" );
152  }
153 
154  resulthisto->Reset();
155  }
156 
157  if (refhist && normref) {
158  double ratio=histogram->GetEntries()/refhist->GetEntries();
159  refhist->Scale(ratio);
160  }
161 
162  int nSkippedBins(0);
163  for ( int i = range[0]; i <= range[1]; ++i ) {
164  for ( int j = range[2]; j <= range[3]; ++j ) {
165  if (minBinEntries > 0) {
166  int bin = histogram->GetBin(i, j);
167  if (profile) {
168  if (profile->GetBinEntries(bin) < minBinEntries) {
169  ++nSkippedBins;
170  continue;
171  }
172  } else if (profile2D) {
173  if (profile2D->GetBinEntries(bin) < minBinEntries) {
174  ++nSkippedBins;
175  continue;
176  }
177  }
178  }
179 
180  if ( ! refhist ){
181  refcont=value;
182  } else {
183  refcont = refhist->GetBinContent(i,j);
184  }
185 
186  double histerr = histogram->GetBinError(i,j);
187  double inputerr=0;
188 
189 
190  if (increferr && refhist ) {
191  double referr = refhist->GetBinError(i,j);
192  inputerr = std::sqrt(std::pow(histerr,2)+std::pow(referr,2));
193  } else {
194  inputerr = histerr;
195  }
196 
197  if (fixerr) {
198  inputerr = fixerr;
199  }
200 
201  double inputcont = histogram->GetBinContent(i,j);
202  double diff=inputcont - refcont;
203  double reldiff=1;
204  if(refcont!=0) reldiff=diff/refcont;
205  else if(diff==0) reldiff=0;
206 
207  if (ignorezero && refcont==0) continue;
208  if (ignorezero && !refhist && inputcont==0) continue;
209  if (ignoreInputZero && inputcont==0) continue;
210 
211  if (inputerr !=0){
212  double sigma=diff/inputerr;
213  if (greaterthan && diff < 0. ) continue;
214  if (lessthan && diff > 0. ) continue;
215 
216  if ( (std::abs(sigma) > bin_threshold) && (std::abs(diff) > maxdiffabs) && (std::abs(reldiff) > maxdiffrel) ){
217  if (resulthisto) resulthisto->SetBinContent(i,j,inputcont);
218  ++count;
219  if (publish && count<maxpublish){
221  }
222  }
223  }
224  }
225  }
226 
227  if (value == -99999) {
228  ERS_DEBUG(1, "Number of bins " << bin_threshold << " Sigma away from reference is " << count);
229  }else {
230  ERS_DEBUG(1, "Number of bins " << bin_threshold << " Sigma away from "<<value<<" is " << count);
231  }
232 
233  ERS_DEBUG(1, "Green threshold: "<< gthreshold << " bin(s); Red threshold : " << rthreshold << " bin(s) ");
234 
235 
236  result->tags_["NBins"] = count;
237  result->tags_["NSkippedBins"] = nSkippedBins;
238  if (resulthisto) result->object_ = (boost::shared_ptr<TObject>)(TObject*)(resulthisto);
239 
240  if (gthreshold > rthreshold) {
241  if ( count >= gthreshold ) {
242  result->status_ = dqm_core::Result::Green;
243  } else if ( count > rthreshold ) {
244  result->status_ = dqm_core::Result::Yellow;
245  } else {
246  result->status_ = dqm_core::Result::Red;
247  }
248  } else {
249  if ( count <= gthreshold ) {
250  result->status_ = dqm_core::Result::Green;
251  } else if ( count < rthreshold ) {
252  result->status_ = dqm_core::Result::Yellow;
253  } else {
254  result->status_ = dqm_core::Result::Red;
255  }
256  }
257  return result;
258 
259 }
260 void
262 {
263 
264  out<<"BinContentComp: Checks number of bins N sigma away from reference histogram bin value or given Value\n"<<std::endl;
265 
266  out<<"Mandatory Parameter: NSigma: Number of sigma each bin must be within reference histogram value\n"<<std::endl;
267  out<<"Mandatory Parameter (If no reference): Value: Value to compare each bin\n"<<std::endl;
268 
269 
270  out<<"Mandatory Green/Red Threshold: NBins: number of bins N sigma away from reference histogram bin to give Green/Red result\n"<<std::endl;
271 
272  out<<"Optional Parameter: MinStat: Minimum histogram statistics needed to perform Algorithm"<<std::endl;
273  out<<"Optional Parameter: Ignore0: Ignore bins which have zero entries in reference histogram"<<std::endl;
274  out<<"Optional Parameter: IgnoreInput0: Ignore bins which have zero entries in tested histogram"<<std::endl;
275  out<<"Optional Parameter: xmin: minimum x range"<<std::endl;
276  out<<"Optional Parameter: xmax: maximum x range"<<std::endl;
277  out<<"Optional Parameter: ymin: minimum y range"<<std::endl;
278  out<<"Optional Parameter: ymax: maximum y range\n"<<std::endl;
279  out<<"Optional Parameter: GreaterThan: check only for bins which are GreaterThan average (set to 1)"<<std::endl;
280  out<<"Optional Parameter: LessThan: check only for bins which are LessThan average (set to 1)"<<std::endl;
281  out<<"Optional Parameter: PublishBins: Save bins which are different from average in Result (set to 1)"<<std::endl;
282  out<<"Optional Parameter: PublishHistogram: Save histogram with bins that are different from average in Result (by default: 1)"<<std::endl;
283  out<<"Optional Parameter: MaxPublish: Max number of bins to save (default 20)"<<std::endl;
284  out<<"Optional Parameter: NormRef: Normalize reference histogram to checked histogram statistics before checking bin contents (set to 1)"<<std::endl;
285  out<<"Optional Parameter: MaxDiffAbs: test fails if NBins more than NSigma away and NBins more than MaxDiffAbs (absolut difference) away"<<std::endl;
286  out<<"Optional Parameter: MaxDiffRel: test fails if NBins more than NSigma away and NBins more than MaxDiffRel (relative difference) away\n"<<std::endl;
287  out<<"Optional Parameter: FixedError: override the histogram errors with this value"<<std::endl;
288  out<<"Optional Parameter: IncludeRefError: use both the histogram and reference histogram errors in calculation"<<std::endl;
289  out<<"Optional Parameter: MinBinEntries: Minimum bin entries in profile histogram needed to check this bin (by default: -1)"<<std::endl;
290 
291 }
292 
dqm_algorithms::tools::GetBinRange
std::vector< int > GetBinRange(const TH1 *histogram, const std::map< std::string, double > &params)
Definition: AlgorithmHelper.cxx:380
dqm_algorithms::BinContentComp::execute
dqm_core::Result * execute(const std::string &, const TObject &, const dqm_core::AlgorithmConfig &)
Definition: BinContentComp.cxx:43
Undefined
@ Undefined
Definition: MaterialTypes.h:8
pdg_comparison.sigma
sigma
Definition: pdg_comparison.py:324
get_generator_info.result
result
Definition: get_generator_info.py:21
IsA
#define IsA
Declare the TObject style functions.
Definition: xAODTEventBranch.h:59
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
conifer::pow
constexpr int pow(int x)
Definition: conifer.h:20
TProfile2D
Definition: rootspy.cxx:531
python.AthDsoLogger.out
out
Definition: AthDsoLogger.py:71
bin
Definition: BinsDiffFromStripMedian.h:43
dqm_algorithms::BinContentComp::~BinContentComp
~BinContentComp()
Definition: BinContentComp.cxx:31
mc.diff
diff
Definition: mc.SFGenPy8_MuMu_DD.py:14
athena.value
value
Definition: athena.py:122
dqm_algorithms::tools::PublishBin
void PublishBin(const TH1 *histogram, int xbin, int ybin, double content, dqm_core::Result *result)
Definition: AlgorithmHelper.cxx:426
XMLtoHeader.count
count
Definition: XMLtoHeader.py:85
config
Definition: PhysicsAnalysis/AnalysisCommon/AssociationUtils/python/config.py:1
instance
std::map< std::string, double > instance
Definition: Run_To_Get_Tags.h:8
dqm_algorithms::BinContentComp::printDescription
void printDescription(std::ostream &out)
Definition: BinContentComp.cxx:261
TH1::SetBinContent
void SetBinContent(int, double)
Definition: rootspy.cxx:301
lumiFormat.i
int i
Definition: lumiFormat.py:92
Result
ICscStripFitter::Result Result
Definition: CalibCscStripFitter.cxx:13
plotBeamSpotVxVal.range
range
Definition: plotBeamSpotVxVal.py:195
python.handimod.Green
int Green
Definition: handimod.py:524
LArG4ValidationPlotter.profile
profile
Definition: LArG4ValidationPlotter.py:113
python.handimod.Red
Red
Definition: handimod.py:551
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
BinContentComp.h
dqm_algorithms::BinContentComp::BinContentComp
BinContentComp()
Definition: BinContentComp.cxx:26
TProfile
Definition: rootspy.cxx:515
TH1::GetBinContent
double GetBinContent(int) const
Definition: rootspy.cxx:298
python.compareTCTs.ratio
ratio
Definition: compareTCTs.py:295
TH1
Definition: rootspy.cxx:268
dqm_algorithms::BinContentComp::clone
BinContentComp * clone()
Definition: BinContentComp.cxx:36
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
dqm_algorithms::tools::GetFirstFromMap
double GetFirstFromMap(const std::string &paramName, const std::map< std::string, double > &params)
Definition: AlgorithmHelper.cxx:339
xAOD::bool
setBGCode setTAP setLVL2ErrorBits bool
Definition: TrigDecision_v1.cxx:60
TileRawChannelBuilderTestConfig.reldiff
def reldiff(a, b)
Definition: TileRawChannelBuilderTestConfig.py:18
histogram
std::string histogram
Definition: chains.cxx:52
dqm_algorithms::BinContentComp
Definition: BinContentComp.h:19