Jpp
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
JTestChi2_t.hh
Go to the documentation of this file.
1 #ifndef __JTESTCHI2_T__
2 #define __JTESTCHI2_T__
3 
4 #include <istream>
5 #include <ostream>
7 
8 /**
9  * \author rgruiz
10  */
11 
12 /**
13  * Implementation of the different Chi2-related tests.
14  */
16 {
17 public:
18 
19  /**
20  * Default constructor.
21  */
23 
24  /**
25  * Chi2 test for 1D histograms.\n
26  * The input parameter threshold, is used to evaluate whether the test is passed or failed.\n
27  * The evaluation is done by comparing the threshold value with the result of the Chi2 test. The output of a Chi2 test is a p-value.\n
28  * The parameter threshold should therefore be a real value between 0 and 1.
29  *
30  * \param h1 First histogram
31  * \param h2 Second histogram
32  * \param threshold Threshold value for the test result
33  * \param parameterName Name of the parameter used to test the histograms
34  * \param testName Name of the test used to compare the histograms
35  * \param options ROOT options for the test.
36  *
37  * \return Test result.
38  */
39  JTestResult JChi2Test(TH1* h1, TH1* h2, double threshold, std::string testName, std::string parameterName, std::string options) {
40 
41  using namespace std;
42  using namespace JPP;
43 
44  if(h1 -> GetNbinsX() != h2 -> GetNbinsX())
45  ERROR("Histograms with different bining. The objects: " << h1 -> GetName() << " can not be compared." << endl);
46 
47  double chi2 = h1 -> Chi2Test (h2 , options.c_str());
48 
49  double M = h1->Integral();
50  double N = h2->Integral();
51 
52  TH2D* h3 = (TH2D*)h1->Clone(h1->GetName()==h2->GetName() ?
53  MAKE_CSTRING(to_string(h1->GetName())) :
54  MAKE_CSTRING(to_string(h1->GetName()) + "_VS_" + to_string(h2->GetName())));
55 
56  h3->Reset();
57 
58  for (int i=1 ; i < h1->GetNbinsX() ; ++i){
59 
60  double m = h1->GetBinContent(i);
61  double n = h2->GetBinContent(i);
62  if(n!=0 && m!=0){
63 
64  double c = (M*n - N*m)/sqrt((n+m)*(N*M));
65  h3->SetBinContent(i,c);
66  }
67  }
68 
69  bool passed;
70 
71  if (options.find("CHI2") != std::string::npos) {
72  (chi2 > threshold ? passed = false : passed = true);
73  }else{
74  (chi2 < threshold ? passed = false : passed = true);
75  }
76 
77  JResultTitle title(testName, parameterName, passed , chi2);
78 
79  h3->SetTitle(title.getTitle().c_str());
80 
81  JTestResult r (testName,
82  string (h1->GetDirectory()->GetPath()).append(h1->GetName()),
83  string (h2->GetDirectory()->GetPath()).append(h2->GetName()),
84  h1->GetDirectory()->GetFile()->GetName(),
85  h2->GetDirectory()->GetFile()->GetName(),
86  parameterName, chi2, threshold, h3, passed);
87 
88  return r;
89 
90  };
91 
92  /**
93  * Chi2 test for sliced 2D histograms.\n
94  * The histograms are sliced along the axis specified by the slice parameter. A slice per bin is made.\n
95  * For each of the slices, the input parameter threshold, is used to evaluate whether the test is passed or failed.\n
96  * The evaluation is done by comparing the threshold value with the result of the Chi2 test. The output of a Chi2 test is a p-value.\n
97  * The parameter threshold should therefore be a real value between 0 and 1.\n
98  * The fraction of failed tests is compared to the input parameter failuresThreshold. If this fraction is larger than failuresThreshold, the test fails.
99  *
100  * \param h1 First histogram
101  * \param h2 Second histogram
102  * \param threshold Threshold value for the test result
103  * \param failuresThreshold Threshold value for the fraction of failed tests.
104  * \param parameterName Name of the parameter used to test the histograms
105  * \param testName Name of the test used to compare the histograms
106  * \param options ROOT options for the test.
107  * \param slice The axis along which the histogram is sliced.
108  *
109  * \return Test result.
110  */
111  JTestResult JChi2TestSlice(TH2* h1, TH2* h2, double threshold, double failuresThreshold, std::string testName, std::string parameterName, std::string options, char slice) {
112 
113  using namespace std;
114  using namespace JPP;
115 
116  int nFailures = 0;
117 
118  JTestResult r;
119 
120  if(slice == 'x' || slice == 'X'){
121 
122  int nSlices1 = h1->GetNbinsX();
123  int nSlices2 = h2->GetNbinsX();
124 
125  TH1* h3 = h1->ProjectionX(h1->GetName()==h2->GetName() ?
126  MAKE_CSTRING(to_string(h1->GetName())) :
127  MAKE_CSTRING(to_string(h1->GetName()) + "_VS_" + to_string(h2->GetName())));
128 
129  if(nSlices1 != nSlices2)
130  ERROR("Histograms with different binning. The objects: " << h1->GetName() << " and " << h2->GetName() << " can not be compared." << endl);
131 
132  for (int i=1 ; i<=nSlices1 ; ++i){
133 
134  std::string sliceName = MAKE_STRING(h1->GetName() + to_string("_") + to_string(i));
135 
136  TH1D* s1 = h1->ProjectionY (sliceName.c_str(),i,i);
137  TH1D* s2 = h2->ProjectionY (sliceName.c_str(),i,i);
138 
139  double chi2 = s1 -> Chi2Test (s2 , options.c_str());
140 
141  bool passed;
142 
143  if (options.find("CHI2") != std::string::npos) {
144  (chi2 > threshold ? passed = false : passed = true);
145  }else{
146  (chi2 < threshold ? passed = false : passed = true);
147  }
148 
149  if (!passed) nFailures++;
150 
151  h3->SetBinContent(i,chi2);
152 
153  }
154 
155  bool passed;
156 
157  (nFailures/nSlices1 > failuresThreshold ? passed = false : passed = true);
158 
159  JResultTitle title(testName, parameterName, passed , nFailures);
160 
161  h3->SetTitle(title.getTitle().c_str());
162 
163  r = JTestResult (testName,
164  string (h1->GetDirectory()->GetPath()).append(h1->GetName()),
165  string (h2->GetDirectory()->GetPath()).append(h2->GetName()),
166  h1->GetDirectory()->GetFile()->GetName(),
167  h2->GetDirectory()->GetFile()->GetName(),
168  parameterName, nFailures, failuresThreshold, h3, passed);
169 
170  }else if (slice == 'y' || slice == 'Y'){
171 
172  int nSlices1 = h1->GetNbinsY();
173  int nSlices2 = h2->GetNbinsY();
174 
175  TH1* h3 = h1->ProjectionY(h1->GetName()==h2->GetName() ?
176  MAKE_CSTRING(to_string(h1->GetName())) :
177  MAKE_CSTRING(to_string(h1->GetName()) + "_VS_" + to_string(h2->GetName())));
178 
179  if(nSlices1 != nSlices2)
180  ERROR("Histograms with different binning. The objects: " << h1->GetName() << " can not be compared." << endl);
181 
182  for (int i=1 ; i<=nSlices1 ; ++i){
183 
184  std::string sliceName = MAKE_STRING(h1->GetName() + to_string("_") + to_string(i));
185 
186  TH1D* s1 = h1->ProjectionX (sliceName.c_str(),i,i);
187  TH1D* s2 = h2->ProjectionX (sliceName.c_str(),i,i);
188 
189  double chi2 = s1 -> Chi2Test (s2 , options.c_str());
190 
191  bool passed;
192 
193  if (options.find("CHI2") != std::string::npos) {
194  (chi2 > threshold ? passed = false : passed = true);
195  }else{
196  (chi2 < threshold ? passed = false : passed = true);
197  }
198 
199  if (!passed) nFailures++;
200 
201  h3->SetBinContent(i,chi2);
202  }
203 
204  bool passed;
205 
206  (nFailures/nSlices1 > failuresThreshold ? passed = false : passed = true);
207 
208  JResultTitle title(testName, parameterName, passed , nFailures);
209 
210  h3->SetTitle(title.getTitle().c_str());
211 
212  r = JTestResult (testName,
213  string (h1->GetDirectory()->GetPath()).append(h1->GetName()),
214  string (h2->GetDirectory()->GetPath()).append(h2->GetName()),
215  h1->GetDirectory()->GetFile()->GetName(),
216  h2->GetDirectory()->GetFile()->GetName(),
217  parameterName, nFailures, failuresThreshold, h3, passed);
218 
219  }
220 
221  return r;
222  };
223 
224 
225  /**
226  * Bin-by-Bin Chi2 comparison of 2D histograms.\n
227  * The Chi distance between h1 and h2 is calculated for each bin, and compared to the chi2Threshold() parameter.\n
228  * If the calculated Chi distance is above this threshold, the test is passed for that bin.\n
229  * If the fraction of failures is above the input parameter outliersThreshold(), the test is failed.
230  *
231  * \param h1 First object
232  * \param h2 Second object
233  * \param outliersThreshold fraction of bins allowed to fail the test
234  * \param chi2Threshold p-value
235  * \param parameterName Name of the parameter used to test the histograms
236  * \param testName Name of the test used to compare the histograms
237  *
238  * \return Test result.
239  */
240  JTestResult JChi2TestBin_2D(TH2* h1, TH2* h2, double outliersThreshold, double chi2Threshold, std::string testName, std::string parameterName) {
241 
242  using namespace std;
243  using namespace JPP;
244 
245  int nx1 = h1->GetNbinsX();
246  int nx2 = h2->GetNbinsX();
247  int ny1 = h1->GetNbinsY();
248  int ny2 = h2->GetNbinsY();
249 
250  double M = h1->Integral();
251  double N = h2->Integral();
252 
253  if(nx1 != nx2 || ny1 != ny2 || M == 0 || N == 0)
254  ERROR("Histograms with different binning. The objects: " << h1->GetName() << " can not be compared." << endl);
255 
256  TH2D* h3 = (TH2D*)h1->Clone(h1->GetName()==h2->GetName() ?
257  MAKE_CSTRING(to_string(h1->GetName())) :
258  MAKE_CSTRING(to_string(h1->GetName()) + "_VS_" + to_string(h2->GetName())));
259 
260  h3->Reset();
261 
262  double outliers = 0;
263 
264  for (int i=1 ; i<nx1 ; ++i){
265  for (int j=1 ; j<ny1 ; ++j){
266 
267  double m = h1 -> GetBinContent(i,j);
268  double n = h2 -> GetBinContent(i,j);
269  double chi2 = (n-m*N/M)/sqrt(m*N/M);
270  (fabs(chi2) > chi2Threshold ? outliers+=1./(nx1*ny1) : outliers+=0 );
271  h3->SetBinContent(i,j,chi2);
272  }
273  }
274 
275  bool passed;
276 
277  (outliers > outliersThreshold ? passed = false : passed = true);
278 
279  JResultTitle title(testName, parameterName , passed , 100*outliers);
280 
281  h3->SetTitle(title.getTitle().c_str());
282 
283  JTestResult r (testName,
284  string (h1->GetDirectory()->GetPath()).append(h1->GetName()),
285  string (h2->GetDirectory()->GetPath()).append(h2->GetName()),
286  h1->GetDirectory()->GetFile()->GetName(),
287  h2->GetDirectory()->GetFile()->GetName(),
288  parameterName, 100*outliers, 100*outliersThreshold, h3, passed);
289 
290  return r;
291  };
292 };
293 
294 #endif
JTestChi2_t()
Default constructor.
Definition: JTestChi2_t.hh:22
do $JPP JMEstimator M
Definition: JMEstimator.sh:37
Class dedicated to standardize the title of the graphical objects produced by the JTest_t() derived c...
Definition: JTest_t.hh:22
#define MAKE_CSTRING(A)
Make C-string.
Definition: JPrint.hh:151
then for HISTOGRAM in h0 h1
Definition: JMatrixNZ.sh:69
data_type r[M+1]
Definition: JPolint.hh:742
Structure containing the result of the test.
Definition: JTest_t.hh:164
#define MAKE_STRING(A)
Make string.
Definition: JPrint.hh:142
then print u2 $script< option > print u2 Possible options
#define ERROR(A)
Definition: JMessage.hh:66
std::string getTitle()
Returns a standard string to be used as title of a graphical root object.
Definition: JTest_t.hh:67
JTestResult JChi2TestBin_2D(TH2 *h1, TH2 *h2, double outliersThreshold, double chi2Threshold, std::string testName, std::string parameterName)
Bin-by-Bin Chi2 comparison of 2D histograms.
Definition: JTestChi2_t.hh:240
alias put_queue eval echo n
Definition: qlib.csh:19
std::string to_string(const T &value)
Convert value to string.
Implementation of the different Chi2-related tests.
Definition: JTestChi2_t.hh:15
int j
Definition: JPolint.hh:666
JTestResult JChi2TestSlice(TH2 *h1, TH2 *h2, double threshold, double failuresThreshold, std::string testName, std::string parameterName, std::string options, char slice)
Chi2 test for sliced 2D histograms.
Definition: JTestChi2_t.hh:111
then usage $script[input file[working directory[option]]] nWhere option can be N
Definition: JMuonPostfit.sh:37
JTestResult JChi2Test(TH1 *h1, TH1 *h2, double threshold, std::string testName, std::string parameterName, std::string options)
Chi2 test for 1D histograms.
Definition: JTestChi2_t.hh:39