ATLAS Offline Software
ChiComp.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3 */
4 
10 #include "dqm_algorithms/ChiComp.h"
11 #include "dqm_core/AlgorithmManager.h"
12 #include "dqm_core/AlgorithmConfig.h"
14 #include "ers/ers.h"
15 
16 #include "TH1.h"
17 #include "TF1.h"
18 #include "TProfile.h"
19 #include "TClass.h"
20 #include <cmath>
21 
22 
23 // Only 1 variation at the moment - might do more later
24 static dqm_algorithms::ChiComp Basic( "Basic" );
25 
26 dqm_algorithms::ChiComp::ChiComp( const std::string & name )
27  : m_name ( name )
28 {
29  dqm_core::AlgorithmManager::instance().registerAlgorithm( "AlgChiComp_"+ name, this );
30 }
31 
34 {
35  return new ChiComp( m_name );
36 }
37 
38 
40 dqm_algorithms::ChiComp::execute( const std::string & name,
41  const TObject & object,
42  const dqm_core::AlgorithmConfig & config )
43 {
44  // Histograms read from file
45  const TH1 * histogram;
46  TH1 * refhist;
47 
48  // Thresholds
49  double gthresho;
50  double rthresho;
51 
52  // Checks whether this is a Profile plot
53  bool profile=0;
54  if(object.IsA()->InheritsFrom( "TProfile" ))
55  profile=1;
56 
57  // Checks which type of histogram this is...
58  if(object.IsA()->InheritsFrom( "TH1" )) {
59  histogram = static_cast<const TH1*>( &object );
60  if (histogram->GetDimension() > 2 ){
61  throw dqm_core::BadConfig( ERS_HERE, name, "dimension > 2 " );
62  }
63  } else {
64  throw dqm_core::BadConfig( ERS_HERE, name, "does not inherit from TH1" );
65  }
66 
67  try {
68  refhist = static_cast<TH1 *>( config.getReference() );
69  }
70  catch ( dqm_core::Exception & ex ) {
71  throw dqm_core::BadRefHist(ERS_HERE,name," Could not retreive reference");
72  }
73 
74  if (histogram->GetDimension() != refhist->GetDimension() ) {
75  throw dqm_core::BadRefHist( ERS_HERE, name, "Dimension" );
76  }
77 
78  if ((histogram->GetNbinsX() != refhist->GetNbinsX()) || (histogram->GetNbinsY() != refhist->GetNbinsY())) {
79  throw dqm_core::BadRefHist( ERS_HERE, name, "number of bins" );
80  }
81 
82  // Get thresholds
83 
84  std::string thresh="ChiSqPerNdof";
85  try {
86  gthresho = dqm_algorithms::tools::GetFromMap( thresh, config.getGreenThresholds() );
87  rthresho = dqm_algorithms::tools::GetFromMap( thresh, config.getRedThresholds() );
88  }
89  catch ( dqm_core::Exception & ex ) {
90  throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex );
91  }
92 
93  // Here we clone the Reference so that we can scale it...
94  TH1 * reference = (TH1*)refhist->Clone();
95 
96  // Cast the histograms into TProfiles id needed
97  TProfile * prof_hist(0);
98  TProfile * prof_ref(0);
99  if(profile){
100  prof_hist = (TProfile*)histogram->Clone();
101  prof_ref = (TProfile*)refhist->Clone();
102  }
103 
104  // Force ROOT to use Sum of Squares to handle uncertainties correctly
105  // Scale Reference - No need to do this for Profile plots...
106  if(!profile)
107  {
108  reference->Sumw2();
109  if(histogram->Integral() != reference->Integral())
110  reference->Scale(histogram->Integral()/reference->Integral());
111  }
112 
113 
114  // Constant to check Validity of Test - Number of points contributing to Chi^2
115  int numchi = 0;
116 
117  // Chi Square Like Significance
118  double significance = 0;
119 
120  // Calculate Chi Square
121  for(int i=1; i<histogram->GetNbinsX()+1; i++){
122 
123  // Calculate the contribution
124  double diff = std::abs(histogram->GetBinContent(i) - reference->GetBinContent(i));
125 
126  double uncert1 = histogram->GetBinError(i);
127  double uncert2 = reference->GetBinError(i);
128  double uncert = std::sqrt(uncert1*uncert1 + uncert2*uncert2);
129 
130  bool badbin = 0;
131 
132  // Check whether this is a 0 uncertainty bin in a profile plot
133  // If it is the case, we have to ignore it...
134  if(profile)
135  badbin = prof_hist->GetBinEntries(i)<2 || prof_ref->GetBinEntries(i)<2;
136 
137  // Prevent Negative weights from MCatNLO from messing things up
138  // Also, zero bins become very problematic when comparng histogrames
139  // with vaslty different statistics - Remove them...
140 
141  if(!profile)
142  badbin = histogram->GetBinContent(i)<=0 || reference->GetBinContent(i)<=0;
143 
144  if(uncert !=0 && badbin ==0){
145  numchi++;
146  significance += (diff/uncert)*(diff/uncert);
147  }
148  }
149 
151 
152  std::string out ="ChiSqPerBin";
153  std::string out1="ChiSqTotal";
154  std::string out2="ChiSqUsedBins";
155 
156  if(numchi>0)
157  {
158  double value = significance/numchi;
159  result->tags_[out] = value;
160  result->tags_[out1] = significance;
161  result->tags_[out2] = numchi;
162  if ( value <= gthresho ) {
163  result->status_ = dqm_core::Result::Green;
164  } else if ( value < rthresho ) {
165  result->status_ = dqm_core::Result::Yellow;
166  } else {
167  result->status_ = dqm_core::Result::Red;
168  }
169  } else {
170  result->tags_[out] = 0;
171  result->tags_[out1]= 0;
172  result->tags_[out2]= 0;
174  }
175 
176 
177  // Print all the useful information for comparing plots
178  result->tags_["Entries"] = histogram->GetEntries();
179  result->tags_["Mean"] = histogram->GetMean();
180  result->tags_["RMS"] = histogram->GetRMS();
181  result->tags_["EntriesReference"] = refhist->GetEntries();
182  result->tags_["MeanReference"] = refhist->GetMean();
183  result->tags_["RMSReference"] = refhist->GetRMS();
184 
185  return result;
186 }
187 void
189 {
190  out<<"AlgChiComp_" << m_name << ": Gives back a Chi Squared like quantity per histogram bin in comparison to a reference histogram. Note that this assumes Gaussian statistics, and handles different numbers of events per histogram correctly. It is also fully compatible with TProfile graphs"<<std::endl;
191  out<<"Mandatory Green/Red Threshold ChiSqPerNdof: Chi Squared per bin for Green/Red results\n"<<std::endl;
192 }
Undefined
@ Undefined
Definition: MaterialTypes.h:8
get_generator_info.result
result
Definition: get_generator_info.py:21
dqm_algorithms::ChiComp
Definition: ChiComp.h:19
IsA
#define IsA
Declare the TObject style functions.
Definition: xAODTEventBranch.h:59
physval_make_web_display.thresh
thresh
Definition: physval_make_web_display.py:35
python.AthDsoLogger.out
out
Definition: AthDsoLogger.py:71
mc.diff
diff
Definition: mc.SFGenPy8_MuMu_DD.py:14
athena.value
value
Definition: athena.py:122
reference
Definition: hcg.cxx:437
config
Definition: PhysicsAnalysis/AnalysisCommon/AssociationUtils/python/config.py:1
instance
std::map< std::string, double > instance
Definition: Run_To_Get_Tags.h:8
ChiComp.h
lumiFormat.i
int i
Definition: lumiFormat.py:92
Result
ICscStripFitter::Result Result
Definition: CalibCscStripFitter.cxx:13
python.handimod.Green
int Green
Definition: handimod.py:524
LArG4ValidationPlotter.profile
profile
Definition: LArG4ValidationPlotter.py:113
dqm_algorithms::ChiComp::clone
ChiComp * clone()
Definition: ChiComp.cxx:33
python.handimod.Red
Red
Definition: handimod.py:551
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
dqm_algorithms::ChiComp::printDescription
void printDescription(std::ostream &out)
Definition: ChiComp.cxx:188
TProfile
Definition: rootspy.cxx:515
dqm_algorithms::ChiComp::ChiComp
ChiComp(const std::string &name)
Definition: ChiComp.cxx:26
TH1
Definition: rootspy.cxx:268
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::ChiComp::execute
dqm_core::Result * execute(const std::string &, const TObject &, const dqm_core::AlgorithmConfig &)
Definition: ChiComp.cxx:40
histogram
std::string histogram
Definition: chains.cxx:52