ATLAS Offline Software
Loading...
Searching...
No Matches
Chi2Test_2D.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3*/
4
9
10#include <dqm_core/AlgorithmConfig.h>
13#include <TH1.h>
14#include <TF1.h>
15#include <TH2.h>
16#include <TF2.h>
17#include <TClass.h>
18#include <TGraph.h>
19#include <TGraphErrors.h>
20#include <ers/ers.h>
21#include <vector>
22#include <cctype>
23#include <map>//also has std::pair
24#include <cmath>
25
26#include <dqm_core/AlgorithmManager.h>
28
29
31 {
32 dqm_core::AlgorithmManager::instance().registerAlgorithm("Chi2Test_2D", this );
33}
34
40
41
42dqm_core::Result *
43dqm_algorithms::Chi2Test_2D::execute( const std::string & name ,
44 const TObject & object,
45 const dqm_core::AlgorithmConfig & config )
46{
47 const TH2 * inputgraph;
48
49 if(object.IsA()->InheritsFrom( "TH1" )) {
50 inputgraph = static_cast<const TH2*>( &object );
51
52 } else {
53 throw dqm_core::BadConfig( ERS_HERE, name, "does not inherit from TH1" );
54 }
55
56 //Make sure the input histogram has enough statistics
57 double minstat = dqm_algorithms::tools::GetFirstFromMap( "MinStat", config.getParameters(), 1 );
58
59 if (inputgraph->GetEntries() < minstat ) {
60 dqm_core::Result *result = new dqm_core::Result(dqm_core::Result::Undefined);
61 result->tags_["InsufficientEntries"] = inputgraph->GetEntries();
62 return result;
63 }
64
65
66 TH2 * refhist;
67 double gthresho;
68 double rthresho;
69 std::string option;
70
71
72 //read in the threshold values
73 std::string thresholdname="NBins";
74
75 try {
76 gthresho = dqm_algorithms::tools::GetFromMap( thresholdname, config.getGreenThresholds() );
77 rthresho = dqm_algorithms::tools::GetFromMap( thresholdname, config.getRedThresholds() );
78 }
79 catch ( dqm_core::Exception & ex ) {
80 throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex );
81
82 }
83
84//try and get the reference, and make sure that it is good
85 try {
86 refhist = static_cast<TH2 *>( config.getReference() );
87 }
88 catch ( dqm_core::Exception & ex ) {
89 throw dqm_core::BadRefHist(ERS_HERE,name," Could not retreive reference");
90 }
91
92 if (inputgraph->GetDimension() != refhist->GetDimension() ) {
93 throw dqm_core::BadRefHist( ERS_HERE, "Dimension", name );
94 }
95
96 if ((inputgraph->GetNbinsX() != refhist->GetNbinsX()) || (inputgraph->GetNbinsY() != refhist->GetNbinsY())) {
97 throw dqm_core::BadRefHist( ERS_HERE, "number of bins", name );
98 }
99
100
101
102
103//check if the value "normalize" is 1. If it is, must scale the histogram. Also, make sure that there is an
104//error associated with the bin, because you should only be calling normalize on a histogram that has a #of jets in a bin
105//that error should be sqrt(n).
106// can call sumw2() before scaling to make sure that this is the case, and then can use the rest of the algorithm as normal,
107//because the correct errors should all be set
108int normalize = dqm_algorithms::tools::GetFirstFromMap( "normalize", config.getParameters(), 1 );
109
110
111if(normalize==1)
112{double ref_entries=refhist->GetEntries();
113 double input_entries=inputgraph->GetEntries();
114 //call sumw2() to make sure that you have the errors as sqrt(n)
115 const_cast<TH2*>(inputgraph)->Sumw2();
116 refhist->Sumw2();
117//now, rescale the reference histogram to the inputgraph histogram. The errors should scale properly, now that I have called Sumw2()
118 refhist->Scale(input_entries/ref_entries);
119}
120
121
122//read in the values for NSigma, and the number of bins to print out at the end, and the value for MaxSigma
123double NSigma = dqm_algorithms::tools::GetFirstFromMap( "NSigma", config.getParameters(), 1 );
124int Num_to_print = dqm_algorithms::tools::GetFirstFromMap( "Num_to_print", config.getParameters(), 1 );
125double MaxSigma = dqm_algorithms::tools::GetFirstFromMap( "MaxSigma", config.getParameters(), 1 );
126
127//read in the values for the maximum and minimum x bin
128std::vector<int> range;
129try{
130range=dqm_algorithms::tools::GetBinRange(inputgraph,config.getParameters());
131}
132catch( dqm_core::Exception & ex ) {
133 throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex );
134 }
135
136
137 int i=0;
138 int j=0;
139 double chisq=0;
140 double errsquared;
141 double inputerr;
142 double referr;
143 double val;
144 double refval;
145 double partsum;
146 int count_ndf=0;
147
148 //define a vector to store the chisq value at the highest ranking bins,which can then be sorted
149 // so that you can find out what the location of the high chisq values are after you have sorted them
150 //define a map, with the chisq partsum value as the key, and the global bin number as the element.
151 std::vector<double> ChisqValues;
152 std::map<double,int> mymap;
153
154 for(i=range[0];i<(range[1]+1);i++)
155 {
156 for(j=range[2];j<(range[3]+1);j++)
157 {
158 val=inputgraph->GetBinContent(i,j);
159 refval=refhist->GetBinContent(i,j);
160 inputerr=inputgraph->GetBinError(i,j);
161 referr=refhist->GetBinError(i,j);
162 errsquared=referr*referr+inputerr*inputerr;
163 if(errsquared > 0.000001)
164 {
165 partsum=((val-refval)*(val-refval))/errsquared;
166 }
167 else
168 {partsum=-1;
169 }
170
171 if (partsum != -1)
172 { chisq=chisq+partsum;
173 count_ndf++;
174
175 if(partsum>=NSigma*NSigma)
176 { ChisqValues.push_back(std::sqrt(partsum));
177 mymap.insert(std::pair<double,int>(std::sqrt(partsum),inputgraph->GetBin(i,j)));
178 }
179
180 }
181
182
183 }
184
185 }
186
187 double ndf=count_ndf-1;
188 double value=chisq/ndf;
189 dqm_core::Result* result = new dqm_core::Result();
190 //write out this chisq/ndf value to the website
191 result->tags_["Chisq_per_NDF"]=value;
192
193
194
195//sort the chisq values for the points that had more than N sigma
196 std::sort(ChisqValues.begin(),ChisqValues.end());
197
198//Output the top Num_to_print values for chisquares at individual points
199//define an iterator
200 std::vector<double>::iterator p;
201 p=ChisqValues.end();
202
203//since the iterator points to one past the end, must decrement before we use it.
204 --p;
205
206//define a second iterator for the map, do not decrement it, as it will be assigned to a point in the map before use
207 std::map<double,int>::iterator p2;
208
209
210char ctag[256];
211int k=0;
212int global_bin=0;
213int xbinnumber;
214int ybinnumber;
215int zbinnumber;
216int& xBin = xbinnumber;
217int& yBin = ybinnumber;
218int& zBin = zbinnumber;
219int globalbinint=0;
220double eta;
221double phi;
222
223//declare a variable that will be set to true if the value MaxSigma is exceeded for any bin. This will automatically flag the histogram red
224int veto=0;
225
226
227//if mymap has no elements, then output that there were no elements above, and skip the next section
228if(mymap.size()==0)
229{result->tags_["No flagged bins were found"]=1.0;
230}
231
232
233while(mymap.size()>0)
234{
235
236//find the value of eta/phi that goes along with the previous chisq value
237//first find the global bin number from the map
238
239 p2=mymap.find(*p);
240 if(p2 !=mymap.end())
241 { global_bin=p2->second;
242 globalbinint= (int) global_bin;
243 inputgraph->GetBinXYZ(globalbinint,xBin,yBin,zBin);
244 eta=inputgraph->GetXaxis()->GetBinCenter(xBin);
245 phi=inputgraph->GetYaxis()->GetBinCenter(yBin);
246
247 //write the coordinates and Sigma value to the website
248 sprintf(ctag," (eta,phi)=(%f,%f) ",eta,phi);
249 result->tags_[ctag] = *p;
250 //set the veto variable
251 if(*p>=MaxSigma)
252 {veto = 1;}
253
254 }
255
256 else
257 {
258 sprintf(ctag,"eta_%i_error",k);
259 result->tags_[ctag]=0.0;
260 sprintf(ctag,"phi_%i_error",k);
261 result->tags_[ctag]=0.0;
262 }
263
264
265 if(p==ChisqValues.begin()||k>Num_to_print)
266 {break;}
267
268 --p;
269 k++;
270 }
271
272//write out what value of NSigma you were using
273//and the maximum number of bins to publish
274result->tags_["MaxSigma"]=MaxSigma;
275result->tags_["NSigma"]=NSigma;
276result->tags_["Max Bins to Publish"]=Num_to_print;
277
278//write out the number of bins that were above the threshold to the screen
279
280 int BinsOver=ChisqValues.size();
281 result->tags_["NBinsOver"]=BinsOver;
282
283//check the thresholds
284
285 if ( (BinsOver <= gthresho) && veto==0 ) {
286 result->status_ = dqm_core::Result::Green;
287 } else if ( (BinsOver < rthresho) && veto==0 ) {
288 result->status_ = dqm_core::Result::Yellow;
289 } else {
290 result->status_ = dqm_core::Result::Red;
291 }
292
293 ERS_DEBUG(2,"Result: "<<*result);
294
295 return result;
296
297}
298void
300{
301
302 out<<"Chi2Test_2D: Gives back the position of the highest NBins relative to the reference, and also computes the chisq/ndf "<<std::endl;
303
304 out<<"Mandatory Green/Red Threshold: NBins to give Green/Red result\n"<<std::endl;
305
306 out<<"Optional Parameter: MinStat: Minimum histogram statistics needed to perform Algorithm\n"<<std::endl;
307
308}
309
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
static dqm_algorithms::BinContentComp myInstance
file declares the dqm_algorithms::Chi2Test_2D class.
Double_t normalize(TF1 *func, Double_t *rampl=NULL, Double_t from=0., Double_t to=0., Double_t step=1.)
std::vector< std::string > veto
these patterns are anded
Definition listroot.cxx:191
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)
const T & GetFromMap(const std::string &pname, const std::map< std::string, T > &params)
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
void printDescription(std::ostream &out)
dqm_core::Result * execute(const std::string &, const TObject &, const dqm_core::AlgorithmConfig &)
#define IsA
Declare the TObject style functions.