Jpp  18.1.0
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(MAKE_CSTRING(h1->GetName() << "_VS_" <<
130  h2->GetName() << "_Chi2TestSliceX"));
131 
132  if (nSlices1 != nSlices2) {
133  ERROR("Histograms with different binning. The objects: " << h1->GetName() << " and " << h2->GetName() << " can not be compared." << endl);
134  }
135 
136  for (int i=1 ; i<=nSlices1 ; ++i){
137 
138  std::string sliceName = MAKE_STRING(h3->GetName() << "_" << 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  if (!(s1->GetSumOfWeights() > 0 && s2->GetSumOfWeights() > 0)) { continue; }
144 
145  double chi2 = s1->Chi2Test(s2 , options.c_str());
146 
147  bool passed = (options.find("CHI2") != std::string::npos ?
148  (chi2 > threshold ? false : true) :
149  (chi2 < threshold ? false : true));
150 
151  if (!passed) nFailures++;
152 
153  h3->SetBinContent(i,chi2);
154  }
155 
156  bool passed = (nFailures/nSlices1 > failuresThreshold ? false : true);
157 
158  JResultTitle title(testName, parameterName, passed , nFailures);
159 
160  h3->SetTitle(title.getTitle().c_str());
161 
162  r = JTestResult(testName,
163  JRootObjectID(MAKE_STRING(h1->GetDirectory()->GetPath() << h1->GetName())),
164  JRootObjectID(MAKE_STRING(h2->GetDirectory()->GetPath() << h1->GetName())),
165  parameterName, nFailures, failuresThreshold, h3, passed);
166 
167  } else if (slice == 'y' || slice == 'Y') {
168 
169  int nSlices1 = h1->GetNbinsY();
170  int nSlices2 = h2->GetNbinsY();
171 
172  TH1* h3 = h1->ProjectionY(MAKE_CSTRING(h1->GetName() << "_VS_" <<
173  h2->GetName() << "_Chi2TestSliceY"));
174 
175  if (nSlices1 != nSlices2) {
176  ERROR("Histograms with different binning. The objects: " << h1->GetName() << " can not be compared." << endl);
177  }
178 
179  for (int i=1 ; i<=nSlices1 ; ++i){
180 
181  std::string sliceName = MAKE_STRING(h3->GetName() << "_" << to_string(i));
182 
183  TH1D* s1 = h1->ProjectionX (sliceName.c_str(),i,i);
184  TH1D* s2 = h2->ProjectionX (sliceName.c_str(),i,i);
185 
186  if (!(s1->GetSumOfWeights() > 0 && s2->GetSumOfWeights() > 0)) { continue; }
187 
188  double chi2 = s1 -> Chi2Test (s2 , options.c_str());
189 
190  bool passed = (options.find("CHI2") != std::string::npos ?
191  (chi2 > threshold ? false : true) :
192  (chi2 < threshold ? false : true));;
193 
194  if (!passed) nFailures++;
195 
196  h3->SetBinContent(i,chi2);
197  }
198 
199  bool passed = (nFailures/nSlices1 > failuresThreshold ? false : true);
200 
201  JResultTitle title(testName, parameterName, passed , nFailures);
202 
203  h3->SetTitle(title.getTitle().c_str());
204 
205  r = JTestResult (testName,
206  JRootObjectID(MAKE_STRING(h1->GetDirectory()->GetPath() << h1->GetName())),
207  JRootObjectID(MAKE_STRING(h2->GetDirectory()->GetPath() << h1->GetName())),
208  parameterName, nFailures, failuresThreshold, h3, passed);
209 
210  }
211 
212  return r;
213  };
214 
215 
216  /**
217  * Bin-by-Bin Chi2 comparison of 2D histograms.\n
218  * The Chi distance between h1 and h2 is calculated for each bin, and compared to the chi2Threshold() parameter.\n
219  * If the calculated Chi distance is above this threshold, the test is passed for that bin.\n
220  * If the fraction of failures is above the input parameter outliersThreshold(), the test is failed.
221  *
222  * \param h1 First object
223  * \param h2 Second object
224  * \param outliersThreshold fraction of bins allowed to fail the test
225  * \param chi2Threshold p-value
226  * \param parameterName Name of the parameter used to test the histograms
227  * \param testName Name of the test used to compare the histograms
228  *
229  * \return Test result.
230  */
231  JTestResult JChi2TestBin_2D(TH2* h1, TH2* h2, double outliersThreshold, double chi2Threshold, std::string testName, std::string parameterName) {
232 
233  using namespace std;
234  using namespace JPP;
235 
236  int nx1 = h1->GetNbinsX();
237  int nx2 = h2->GetNbinsX();
238  int ny1 = h1->GetNbinsY();
239  int ny2 = h2->GetNbinsY();
240 
241  double M = h1->Integral();
242  double N = h2->Integral();
243 
244  if(nx1 != nx2 || ny1 != ny2 || M == 0 || N == 0)
245  ERROR("Histograms with different binning. The objects: " << h1->GetName() << " can not be compared." << endl);
246 
247  TH2D* h3 = (TH2D*)h1->Clone(h1->GetName()==h2->GetName() ?
248  MAKE_CSTRING(to_string(h1->GetName())) :
249  MAKE_CSTRING(to_string(h1->GetName()) + "_VS_" + to_string(h2->GetName())));
250 
251  h3->Reset();
252 
253  double outliers = 0;
254 
255  for (int i=1 ; i<nx1 ; ++i){
256  for (int j=1 ; j<ny1 ; ++j){
257 
258  double m = h1 -> GetBinContent(i,j);
259  double n = h2 -> GetBinContent(i,j);
260  double chi2 = (n-m*N/M)/sqrt(m*N/M);
261  (fabs(chi2) > chi2Threshold ? outliers+=1./(nx1*ny1) : outliers+=0 );
262  h3->SetBinContent(i,j,chi2);
263  }
264  }
265 
266  bool passed;
267 
268  (outliers > outliersThreshold ? passed = false : passed = true);
269 
270  JResultTitle title(testName, parameterName , passed , 100*outliers);
271 
272  h3->SetTitle(title.getTitle().c_str());
273 
274  JTestResult r (testName,
275  JRootObjectID(MAKE_STRING(h1->GetDirectory()->GetPath() << h1->GetName())),
276  JRootObjectID(MAKE_STRING(h2->GetDirectory()->GetPath() << h1->GetName())),
277  parameterName, 100*outliers, 100*outliersThreshold, h3, passed);
278 
279  return r;
280  };
281  };
282 }
283 
284 #endif
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:231
#define MAKE_CSTRING(A)
Make C-string.
Definition: JPrint.hh:136
Auxiliary class to handle file name, ROOT directory and object name.
data_type r[M+1]
Definition: JPolint.hh:779
#define MAKE_STRING(A)
Make string.
Definition: JPrint.hh:127
const int n
Definition: JPolint.hh:697
JTestChi2_t()
Default constructor.
Definition: JTestChi2_t.hh:28
then usage $script[port]< option > nPossible options
#define ERROR(A)
Definition: JMessage.hh:66
then awk string
$WORKDIR ev_configure_dqsimulator txt echo process $DQ_SIMULATOR $i $SOURCE_HOST[$index] csh c(setenv ROOTSYS $ROOTSYS &&source $JPP_DIR/setenv.csh $JPP_DIR &&($DQ_SIMULATOR\-u\$NAME\$\-H\$SERVER\$\-M\$LOGGER\$\-d $DEBUG</dev/null > &/dev/null &))'
then usage $script< input file >[option[primary[working directory]]] nWhere option can be N
Definition: JMuonPostfit.sh:40
std::string to_string(const T &value)
Convert value to string.
then if[[!-f $DETECTOR]] then JDetector sh $DETECTOR fi cat $WORKDIR trigger_parameters txt<< EOFtrigger3DMuon.enabled=1;trigger3DMuon.numberOfHits=5;trigger3DMuon.gridAngle_deg=1;ctMin=0.0;TMaxLocal_ns=15.0;EOF set_variable TRIGGEREFFICIENCY_TRIGGERED_EVENTS_ONLY INPUT_FILES=() for((i=1;$i<=$NUMBER_OF_RUNS;++i));do JSirene.sh $DETECTOR $JPP_DATA/genhen.km3net_wpd_V2_0.evt.gz $WORKDIR/sirene_ ${i}.root JTriggerEfficiency.sh $DETECTOR $DETECTOR $WORKDIR/sirene_ ${i}.root $WORKDIR/trigger_efficiency_ ${i}.root $WORKDIR/trigger_parameters.txt $JPP_DATA/PMT_parameters.txt INPUT_FILES+=($WORKDIR/trigger_efficiency_ ${i}.root) done for ANGLE_DEG in $ANGLES_DEG[*];do set_variable SIGMA_NS 3.0 set_variable OUTLIERS 3 set_variable OUTPUT_FILE $WORKDIR/matrix\[${ANGLE_DEG}\deg\].root $JPP_DIR/examples/JReconstruction-f"$INPUT_FILES[*]"-o $OUTPUT_FILE-S ${SIGMA_NS}-A ${ANGLE_DEG}-O ${OUTLIERS}-d ${DEBUG}--!fiif[[$OPTION=="plot"]];then if((0));then for H1 in h0 h1;do JPlot1D-f"$WORKDIR/matrix["${^ANGLES_DEG}" deg].root:${H1}"-y"1 2e3"-Y-L TR-T""-\^"number of events [a.u.]"-> o chi2
Definition: JMatrixNZ.sh:106
Structure containing the result of the test.
Definition: JTestResult.hh:27
int j
Definition: JPolint.hh:703
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