Jpp  15.0.1-rc.1-highqe
the software that should make you happy
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
JTestChi2_t.hh
Go to the documentation of this file.
1 #ifndef __JCOMPAREHISTOGRAMS__JTESTCHI2_T__
2 #define __JCOMPAREHISTOGRAMS__JTESTCHI2_T__
3 
4 #include <istream>
5 #include <ostream>
6 
9 
10 
11 /**
12  * \author rgruiz
13  */
14 namespace JCOMPAREHISTOGRAMS {
15 
17 
18  /**
19  * Implementation of the different Chi2-related tests.
20  */
21  class JTestChi2_t
22  {
23  public:
24 
25  /**
26  * Default constructor.
27  */
29 
30  /**
31  * Chi2 test for 1D histograms.\n
32  * The input parameter threshold, is used to evaluate whether the test is passed or failed.\n
33  * 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
34  * The parameter threshold should therefore be a real value between 0 and 1.
35  *
36  * \param h1 First histogram
37  * \param h2 Second histogram
38  * \param threshold Threshold value for the test result
39  * \param parameterName Name of the parameter used to test the histograms
40  * \param testName Name of the test used to compare the histograms
41  * \param options ROOT options for the test.
42  *
43  * \return Test result.
44  */
45  JTestResult JChi2Test(TH1* h1, TH1* h2, double threshold, std::string testName, std::string parameterName, std::string options) {
46 
47  using namespace std;
48  using namespace JPP;
49 
50  if(h1 -> GetNbinsX() != h2 -> GetNbinsX())
51  ERROR("Histograms with different bining. The objects: " << h1 -> GetName() << " can not be compared." << endl);
52 
53  double chi2 = h1 -> Chi2Test (h2 , options.c_str());
54 
55  double M = h1->Integral();
56  double N = h2->Integral();
57 
58  TH2D* h3 = (TH2D*)h1->Clone(h1->GetName()==h2->GetName() ?
59  MAKE_CSTRING(to_string(h1->GetName())) :
60  MAKE_CSTRING(to_string(h1->GetName()) + "_VS_" + to_string(h2->GetName())));
61 
62  h3->Reset();
63 
64  for (int i=1 ; i < h1->GetNbinsX() ; ++i){
65 
66  double m = h1->GetBinContent(i);
67  double n = h2->GetBinContent(i);
68  if(n!=0 && m!=0){
69 
70  double c = (M*n - N*m)/sqrt((n+m)*(N*M));
71  h3->SetBinContent(i,c);
72  }
73  }
74 
75  bool passed;
76 
77  if (options.find("CHI2") != std::string::npos) {
78  (chi2 > threshold ? passed = false : passed = true);
79  }else{
80  (chi2 < threshold ? passed = false : passed = true);
81  }
82 
83  JResultTitle title(testName, parameterName, passed , chi2);
84 
85  h3->SetTitle(title.getTitle().c_str());
86 
87  JTestResult r (testName,
88  JRootObjectID(MAKE_STRING(h1->GetDirectory()->GetPath() << h1->GetName())),
89  JRootObjectID(MAKE_STRING(h2->GetDirectory()->GetPath() << h1->GetName())),
90  parameterName, chi2, threshold, h3, passed);
91 
92  return r;
93 
94  };
95 
96  /**
97  * Chi2 test for sliced 2D histograms.\n
98  * The histograms are sliced along the axis specified by the slice parameter. A slice per bin is made.\n
99  * For each of the slices, the input parameter threshold, is used to evaluate whether the test is passed or failed.\n
100  * 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
101  * The parameter threshold should therefore be a real value between 0 and 1.\n
102  * The fraction of failed tests is compared to the input parameter failuresThreshold. If this fraction is larger than failuresThreshold, the test fails.
103  *
104  * \param h1 First histogram
105  * \param h2 Second histogram
106  * \param threshold Threshold value for the test result
107  * \param failuresThreshold Threshold value for the fraction of failed tests.
108  * \param parameterName Name of the parameter used to test the histograms
109  * \param testName Name of the test used to compare the histograms
110  * \param options ROOT options for the test.
111  * \param slice The axis along which the histogram is sliced.
112  *
113  * \return Test result.
114  */
115  JTestResult JChi2TestSlice(TH2* h1, TH2* h2, double threshold, double failuresThreshold, std::string testName, std::string parameterName, std::string options, char slice) {
116 
117  using namespace std;
118  using namespace JPP;
119 
120  int nFailures = 0;
121 
122  JTestResult r;
123 
124  if(slice == 'x' || slice == 'X'){
125 
126  int nSlices1 = h1->GetNbinsX();
127  int nSlices2 = h2->GetNbinsX();
128 
129  TH1* h3 = h1->ProjectionX(h1->GetName()==h2->GetName() ?
130  MAKE_CSTRING(to_string(h1->GetName())) :
131  MAKE_CSTRING(to_string(h1->GetName()) + "_VS_" + to_string(h2->GetName())));
132 
133  if(nSlices1 != nSlices2)
134  ERROR("Histograms with different binning. The objects: " << h1->GetName() << " and " << h2->GetName() << " can not be compared." << endl);
135 
136  for (int i=1 ; i<=nSlices1 ; ++i){
137 
138  std::string sliceName = MAKE_STRING(h1->GetName() + to_string("_") + to_string(i));
139 
140  TH1D* s1 = h1->ProjectionY (sliceName.c_str(),i,i);
141  TH1D* s2 = h2->ProjectionY (sliceName.c_str(),i,i);
142 
143  double chi2 = s1 -> Chi2Test (s2 , options.c_str());
144 
145  bool passed;
146 
147  if (options.find("CHI2") != std::string::npos) {
148  (chi2 > threshold ? passed = false : passed = true);
149  }else{
150  (chi2 < threshold ? passed = false : passed = true);
151  }
152 
153  if (!passed) nFailures++;
154 
155  h3->SetBinContent(i,chi2);
156 
157  }
158 
159  bool passed;
160 
161  (nFailures/nSlices1 > failuresThreshold ? passed = false : passed = true);
162 
163  JResultTitle title(testName, parameterName, passed , nFailures);
164 
165  h3->SetTitle(title.getTitle().c_str());
166 
167  r = JTestResult(testName,
168  JRootObjectID(MAKE_STRING(h1->GetDirectory()->GetPath() << h1->GetName())),
169  JRootObjectID(MAKE_STRING(h2->GetDirectory()->GetPath() << h1->GetName())),
170  parameterName, nFailures, failuresThreshold, h3, passed);
171 
172  }else if (slice == 'y' || slice == 'Y'){
173 
174  int nSlices1 = h1->GetNbinsY();
175  int nSlices2 = h2->GetNbinsY();
176 
177  TH1* h3 = h1->ProjectionY(h1->GetName()==h2->GetName() ?
178  MAKE_CSTRING(to_string(h1->GetName())) :
179  MAKE_CSTRING(to_string(h1->GetName()) + "_VS_" + to_string(h2->GetName())));
180 
181  if(nSlices1 != nSlices2)
182  ERROR("Histograms with different binning. The objects: " << h1->GetName() << " can not be compared." << endl);
183 
184  for (int i=1 ; i<=nSlices1 ; ++i){
185 
186  std::string sliceName = MAKE_STRING(h1->GetName() + to_string("_") + to_string(i));
187 
188  TH1D* s1 = h1->ProjectionX (sliceName.c_str(),i,i);
189  TH1D* s2 = h2->ProjectionX (sliceName.c_str(),i,i);
190 
191  double chi2 = s1 -> Chi2Test (s2 , options.c_str());
192 
193  bool passed;
194 
195  if (options.find("CHI2") != std::string::npos) {
196  (chi2 > threshold ? passed = false : passed = true);
197  }else{
198  (chi2 < threshold ? passed = false : passed = true);
199  }
200 
201  if (!passed) nFailures++;
202 
203  h3->SetBinContent(i,chi2);
204  }
205 
206  bool passed;
207 
208  (nFailures/nSlices1 > failuresThreshold ? passed = false : passed = true);
209 
210  JResultTitle title(testName, parameterName, passed , nFailures);
211 
212  h3->SetTitle(title.getTitle().c_str());
213 
214  r = JTestResult (testName,
215  JRootObjectID(MAKE_STRING(h1->GetDirectory()->GetPath() << h1->GetName())),
216  JRootObjectID(MAKE_STRING(h2->GetDirectory()->GetPath() << h1->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  JRootObjectID(MAKE_STRING(h1->GetDirectory()->GetPath() << h1->GetName())),
285  JRootObjectID(MAKE_STRING(h2->GetDirectory()->GetPath() << h1->GetName())),
286  parameterName, 100*outliers, 100*outliersThreshold, h3, passed);
287 
288  return r;
289  };
290  };
291 }
292 
293 #endif
do $JPP JMEstimator M
Definition: JMEstimator.sh:37
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:115
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:45
Class dedicated to standardize the title of the graphical objects produced by the JTest_t() derived c...
Definition: JResultTitle.hh:22
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
then JShowerPostfit f $INPUT_FILE o $OUTPUT_FILE N
#define MAKE_CSTRING(A)
Make C-string.
Definition: JPrint.hh:151
then for HISTOGRAM in h0 h1
Definition: JMatrixNZ.sh:71
Auxiliary class to handle file name, ROOT directory and object name.
data_type r[M+1]
Definition: JPolint.hh:742
#define MAKE_STRING(A)
Make string.
Definition: JPrint.hh:142
const int n
Definition: JPolint.hh:660
JTestChi2_t()
Default constructor.
Definition: JTestChi2_t.hh:28
then usage $script[port]< option > nPossible options
#define ERROR(A)
Definition: JMessage.hh:66
std::string to_string(const T &value)
Convert value to string.
Structure containing the result of the test.
Definition: JTestResult.hh:27
int j
Definition: JPolint.hh:666
std::string getTitle()
Returns a standard string to be used as title of a graphical root object.
Definition: JResultTitle.hh:64
Implementation of the different Chi2-related tests.
Definition: JTestChi2_t.hh:21