ATLAS Offline Software
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 
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>
27 static dqm_algorithms::Chi2Test_2D myInstance;
28 
29 
31  {
32  dqm_core::AlgorithmManager::instance().registerAlgorithm("Chi2Test_2D", this );
33 }
34 
37 {
38  return new Chi2Test_2D();
39 }
40 
41 
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 ) {
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
108 int normalize = dqm_algorithms::tools::GetFirstFromMap( "normalize", config.getParameters(), 1 );
109 
110 
111 if(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
123 double NSigma = dqm_algorithms::tools::GetFirstFromMap( "NSigma", config.getParameters(), 1 );
124 int Num_to_print = dqm_algorithms::tools::GetFirstFromMap( "Num_to_print", config.getParameters(), 1 );
125 double MaxSigma = dqm_algorithms::tools::GetFirstFromMap( "MaxSigma", config.getParameters(), 1 );
126 
127 //read in the values for the maximum and minimum x bin
128 std::vector<int> range;
129 try{
130 range=dqm_algorithms::tools::GetBinRange(inputgraph,config.getParameters());
131 }
132 catch( 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;
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
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
208 
209 
210 char ctag[256];
211 int k=0;
212 int global_bin=0;
213 int xbinnumber;
214 int ybinnumber;
215 int zbinnumber;
216 int& xBin = xbinnumber;
217 int& yBin = ybinnumber;
218 int& zBin = zbinnumber;
219 int globalbinint=0;
220 double eta;
221 double 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
224 int veto=0;
225 
226 
227 //if mymap has no elements, then output that there were no elements above, and skip the next section
228 if(mymap.size()==0)
229 {result->tags_["No flagged bins were found"]=1.0;
230 }
231 
232 
233 while(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
274 result->tags_["MaxSigma"]=MaxSigma;
275 result->tags_["NSigma"]=NSigma;
276 result->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 }
298 void
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 
dqm_algorithms::Chi2Test_2D::execute
dqm_core::Result * execute(const std::string &, const TObject &, const dqm_core::AlgorithmConfig &)
Definition: Chi2Test_2D.cxx:43
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
covarianceTool.ndf
ndf
Definition: covarianceTool.py:678
dqm_algorithms::tools::GetBinRange
std::vector< int > GetBinRange(const TH1 *histogram, const std::map< std::string, double > &params)
Definition: AlgorithmHelper.cxx:380
dqm_algorithms::Chi2Test_2D::Chi2Test_2D
Chi2Test_2D()
Definition: Chi2Test_2D.cxx:30
Undefined
@ Undefined
Definition: MaterialTypes.h:8
get_generator_info.result
result
Definition: get_generator_info.py:21
python.PerfMonSerializer.p
def p
Definition: PerfMonSerializer.py:743
phi
Scalar phi() const
phi method
Definition: AmgMatrixBasePlugin.h:64
IsA
#define IsA
Declare the TObject style functions.
Definition: xAODTEventBranch.h:59
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
eta
Scalar eta() const
pseudorapidity method
Definition: AmgMatrixBasePlugin.h:79
python.AthDsoLogger.out
out
Definition: AthDsoLogger.py:71
athena.value
value
Definition: athena.py:122
dqm_algorithms::Chi2Test_2D::printDescription
void printDescription(std::ostream &out)
Definition: Chi2Test_2D.cxx:299
normalize
Double_t normalize(TF1 *func, Double_t *rampl=NULL, Double_t from=0., Double_t to=0., Double_t step=1.)
Definition: LArPhysWaveHECTool.cxx:825
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::Chi2Test_2D
Definition: Chi2Test_2D.h:22
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
Chi2Test_2D.h
TH2
Definition: rootspy.cxx:373
python.handimod.Red
Red
Definition: handimod.py:551
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
Pythia8_RapidityOrderMPI.val
val
Definition: Pythia8_RapidityOrderMPI.py:14
dqm_algorithms::Chi2Test_2D::clone
Chi2Test_2D * clone()
Definition: Chi2Test_2D.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
veto
std::vector< std::string > veto
these patterns are anded
Definition: listroot.cxx:191
dqm_algorithms::tools::GetFirstFromMap
double GetFirstFromMap(const std::string &paramName, const std::map< std::string, double > &params)
Definition: AlgorithmHelper.cxx:339
fitman.k
k
Definition: fitman.py:528