Jpp  18.5.2
the software that should make you happy
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
JTestChi2_Slice2D.hh
Go to the documentation of this file.
1 #ifndef __JCOMPAREHISTOGRAMS__JTESTCHI2_SLICE2D__
2 #define __JCOMPAREHISTOGRAMS__JTESTCHI2_SLICE2D__
3 
4 #include <istream>
5 #include <ostream>
6 
7 #include "JLang/JException.hh"
8 
11 
12 #include "TH1.h"
13 #include "TH2.h"
14 
15 
16 /**
17  * \author rgruiz, bjung
18  */
19 namespace JCOMPAREHISTOGRAMS {}
20 namespace JPP { using namespace JCOMPAREHISTOGRAMS; }
21 
22 namespace JCOMPAREHISTOGRAMS {
23 
24  /**
25  * Implementation of the Chi2 test for 2D histograms.\n
26  * This class is derived from the abstract class JTest_t(). For a general description of the implementation of this and other tests derived from JTest_t(), see its documentation.\n
27  * The parameter slice() can have the values x, X, y or Y. The histograms are sliced along the corresponding axis, and the JChi2Test() test is applied to each slice.\n
28  * The input parameter `threshold`, is used to evaluate whether the test is passed or failed for each slice.\n
29  * The evaluation is done by comparing the `threshold` value with the result produced by the Chi2 test for each slice. The output of JChi2Test() is a p-value.\n
30  * The parameter `threshold` should therefore be a real value between 0 and 1.
31  */
33  public JTest_t
34  {
35  public:
36 
37  /**
38  * Default constructor.
39  */
41  JTest_t("Chi2_Slice2D", "p-Value(chi2)")
42  {}
43 
44 
45  /**
46  * Applies Chi2 test for two ROOT TH2 histograms.
47  *
48  * \param o1 First histogram
49  * \param o2 Second histogram
50  */
51  void test(const TObject* o1, const TObject* o2) override
52  {
53  using namespace std;
54  using namespace JPP;
55 
56  const TH2* h1 = dynamic_cast<const TH2*>(o1);
57  const TH2* h2 = dynamic_cast<const TH2*>(o2);
58 
59  if (h1 == NULL || h2 == NULL) {
60  THROW(JValueOutOfRange, "JTestChi2_Slice2D::test(): Could not cast given TObjects to TH2");
61  }
62 
63  TH1* h3 = NULL;
64 
65  const char* const h3name = (h1->GetName() == h2->GetName() ?
66  MAKE_CSTRING(h1->GetName() << "_" << testName << "_" << slice) :
67  MAKE_CSTRING(h1->GetName() << "_VS_" << h2->GetName() << "_" << testName << "_" << slice));
68 
69  int nFailures = 0;
70  int nSlices = 0;
71 
72  if (slice == 'x' || slice == 'X') {
73 
74  const int nSlices1 = h1->GetNbinsX();
75  const int nSlices2 = h2->GetNbinsX();
76 
77  if (nSlices1 != nSlices2) {
78  THROW(JValueOutOfRange, "JTestChi2_Slice2D::test(): Histograms with different binning. The objects: " << h1->GetName() << " and " << h2->GetName() << " can not be compared." << endl);
79  }
80 
81  nSlices = nSlices1;
82 
83  h3 = h1->ProjectionX(h3name);
84 
85  for (int i=1 ; i<=nSlices1 ; ++i){
86 
87  const std::string sliceName = MAKE_STRING(h3->GetName() << "_" << to_string(i));
88 
89  const TH1* s1 = h1->ProjectionY(sliceName.c_str(),i,i);
90  const TH1* s2 = h2->ProjectionY(sliceName.c_str(),i,i);
91 
92  if (!(s1->GetSumOfWeights() > 0 && s2->GetSumOfWeights() > 0)) { continue; }
93 
94  const double chi2 = s1->Chi2Test(s2 , options.c_str());
95 
96  const bool failed = (options.find("CHI2") != std::string::npos ?
97  (chi2 > threshold ? true : false) :
98  (chi2 < threshold ? true : false));
99 
100  if (failed) nFailures++;
101 
102  h3->SetBinContent(i,chi2);
103  }
104 
105  } else if (slice == 'y' || slice == 'Y') {
106 
107  const int nSlices1 = h1->GetNbinsY();
108  const int nSlices2 = h2->GetNbinsY();
109 
110  if (nSlices1 != nSlices2) {
111  THROW(JValueOutOfRange, "JTestChi2_Slice2D::test(): Histograms with different binning. The objects: " << h1->GetName() << " and " << h2->GetName() << " can not be compared." << endl);
112  }
113 
114  nSlices = nSlices1;
115 
116  h3 = h1->ProjectionY(h3name);
117 
118  for (int i=1 ; i<=nSlices1 ; ++i){
119 
120  const std::string sliceName = MAKE_STRING(h3->GetName() << "_" << to_string(i));
121 
122  const TH1* s1 = h1->ProjectionX(sliceName.c_str(),i,i);
123  const TH1* s2 = h2->ProjectionX(sliceName.c_str(),i,i);
124 
125  if (!(s1->GetSumOfWeights() > 0 && s2->GetSumOfWeights() > 0)) { continue; }
126 
127  const double chi2 = s1->Chi2Test (s2 , options.c_str());
128 
129  const bool failed = (options.find("CHI2") != std::string::npos ?
130  (chi2 > threshold ? true : false) :
131  (chi2 < threshold ? true : false));;
132 
133  if (failed) nFailures++;
134 
135  h3->SetBinContent(i,chi2);
136  }
137  }
138 
139  const bool passed = (nFailures/nSlices < failuresThreshold);
140 
141  const JResultTitle title(testName, resultType, passed , nFailures);
142 
143  h3->SetTitle(title.getTitle().c_str());
144  h3->GetYaxis()->SetTitle(resultType.c_str());
145 
146  const JTestResult r(testName,
147  JRootObjectID(MAKE_STRING(h1->GetDirectory()->GetPath() << h1->GetName())),
148  JRootObjectID(MAKE_STRING(h2->GetDirectory()->GetPath() << h1->GetName())),
149  resultType, nFailures, failuresThreshold, h3, passed);
150 
151  this->push_back(r);
152  }
153 
154 
155  /**
156  * Read test parameters from input.
157  *
158  * \param in input stream
159  * \return input stream
160  */
161  std::istream& read(std::istream& in) override
162  {
163  using namespace JPP;
164 
165  in >> threshold >> failuresThreshold >> slice >> options;
166 
167  if (threshold < 0.0) {
168  THROW(JValueOutOfRange, "JTestChi2_Slice2D::read(): Invalid threshold value " << threshold);
169  }
170 
171  if (failuresThreshold < 0.0 || failuresThreshold > 1.0) {
172  THROW(JValueOutOfRange, "JTestChi2_Slice2D::read(): Invalid failuresThreshold value " << failuresThreshold);
173  }
174 
175  if (slice != 'x' && slice != 'X' && slice != 'y' && slice != 'Y') {
176  THROW(JValueOutOfRange, "JTestChi2_Slice2D::read(): Invalid slice option " << slice);
177  }
178 
179  return in;
180  }
181 
182 
183  private:
184 
185  double threshold; //!< threshold p-value to decide if test is passed.
186  double failuresThreshold; //!< threshold p-value to decide if test is passed.
187  char slice; //!< axis to slice.
188  std::string options; //!< options for the ROOT chi2 test.
189  };
190 }
191 
192 #endif
double failuresThreshold
threshold p-value to decide if test is passed.
Exceptions.
Interface to read input and write output for TObject tests.
Definition: JTest_t.hh:40
std::string getTitle() const
Returns a standard string to be used as title of a graphical root object.
Definition: JResultTitle.hh:57
std::istream & read(std::istream &in) override
Read test parameters from input.
Class dedicated to standardize the title of the graphical objects produced by the JTest_t() derived c...
Definition: JResultTitle.hh:25
#define THROW(JException_t, A)
Marco for throwing exception with std::ostream compatible message.
Definition: JException.hh:712
double threshold
threshold p-value to decide if test is passed.
Definition: JRoot.hh:19
#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:868
#define MAKE_STRING(A)
Make string.
Definition: JPrint.hh:127
std::string options
options for the ROOT chi2 test.
then awk string
const std::string resultType
test result type
Definition: JTest_t.hh:181
const std::string testName
test name
Definition: JTest_t.hh:180
then fatal Wrong number of arguments fi set_variable DETECTOR $argv[1] set_variable INPUT_FILE $argv[2] eval JPrintDetector a $DETECTOR O IDENTIFIER eval JPrintDetector a $DETECTOR O SUMMARY JAcoustics sh $DETECTOR_ID source JAcousticsToolkit sh CHECK_EXIT_CODE typeset A EMITTERS get_tripods $WORKDIR tripod txt EMITTERS get_transmitters $WORKDIR transmitter txt EMITTERS for EMITTER in
Definition: JCanberra.sh:48
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:28
void test(const TObject *o1, const TObject *o2) override
Applies Chi2 test for two ROOT TH2 histograms.
Implementation of the Chi2 test for 2D histograms.