Jpp  18.6.0-rc.1
the software that should make you happy
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
JTestKolmogorov_Slice2D.hh
Go to the documentation of this file.
1 #ifndef __JCOMPAREHISTOGRAMS__JTESTKOLMOGOROV_SLICE2D__
2 #define __JCOMPAREHISTOGRAMS__JTESTKOLMOGOROV_SLICE2D__
3 
4 #include <istream>
5 #include <ostream>
6 
7 #include "JLang/JException.hh"
8 
10 
11 #include "TH2.h"
12 #include "TMath.h"
13 
14 
15 /**
16  * \author rgruiz, bjung
17  */
18 namespace JCOMPAREHISTOGRAMS {}
19 namespace JPP { using namespace JCOMPAREHISTOGRAMS; }
20 
21 namespace JCOMPAREHISTOGRAMS {
22 
23  /**
24  * Implementation of the Kolmogorov test for 2D histograms.\n
25  * 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
26  * This test compares two 2D histograms. If the parameter `slice` equals x, X y or Y, the histograms are sliced along the corresponding axis, and the Kolmogorov test is applied to each slice.\n
27  * The input parameter `threshold`, is used to evaluate whether the test is passed or failed for each slice or for the full 2D distribution.\n
28  * The evaluation is done by comparing the `threshold` value with the resulting p-value.\n
29  * The parameter `threshold` should therefore be a real value between 0 and 1.
30  */
32  public JTest_t
33  {
34  public:
35 
36  /**
37  * Default constructor.
38  */
40  JTest_t("KS_Slice2D", "p-Value(KS)")
41  {}
42 
43 
44  /**
45  * Applies Kolmogorov test for two ROOT TH2 histograms.
46  *
47  * \param o1 First histogram
48  * \param o2 Second histogram
49  */
50  void test(const TObject* o1, const TObject* o2) override
51  {
52  using namespace std;
53  using namespace JPP;
54 
55  const TH2* h1 = dynamic_cast<const TH2*>(o1);
56  const TH2* h2 = dynamic_cast<const TH2*>(o2);
57 
58  if (h1 == NULL || h2 == NULL) {
59  THROW(JValueOutOfRange, "JTestKolmogorov_Slice2D::test(): Could not cast given TObjects to TH2.");
60  }
61 
62  TH1* h3 = NULL;
63 
64  const char* const h3name = (h1->GetName() == h2->GetName() ?
65  MAKE_CSTRING(h1->GetName() << "_" << testName << "_" << slice) :
66  MAKE_CSTRING(h1->GetName() << "_VS_" << h2->GetName() << "_" << testName << "_" << slice));
67 
68  int nFailures = 0;
69  int nSlices = 0;
70 
71  if(slice == 'x' || slice == 'X') {
72 
73  const int nSlices1 = h1->GetNbinsX();
74  const int nSlices2 = h2->GetNbinsX();
75 
76  if (nSlices1 != nSlices2) {
77  THROW(JValueOutOfRange, "JTestKolmogorov_Slice2D::test(): Histograms with different binning. The objects: " << h1->GetName() << " and " << h2->GetName() << " can not be compared." << endl);
78  }
79 
80  nSlices = nSlices1;
81 
82  h3 = h1->ProjectionX(h3name);
83 
84  for (int i=1 ; i<=nSlices1 ; ++i) {
85 
86  const std::string sliceName = MAKE_STRING(h3->GetName() << "_" << to_string(i));
87 
88  const TH1* s1 = h1->ProjectionY (sliceName.c_str(),i,i);
89  const TH1* s2 = h2->ProjectionY (sliceName.c_str(),i,i);
90 
91  if (!(s1->GetSumOfWeights() > 0 && s2->GetSumOfWeights() > 0)) { continue; }
92 
93  const double p = s1 -> KolmogorovTest (s2);
94 
95  if (p < threshold) nFailures++;
96 
97  h3->SetBinContent(i,p);
98  }
99 
100  } else if (slice == 'y' || slice == 'Y') {
101 
102  const int nSlices1 = h1->GetNbinsY();
103  const int nSlices2 = h2->GetNbinsY();
104 
105  if (nSlices1 != nSlices2) {
106  THROW(JValueOutOfRange, "JTestKolmogorov_Slice2D::test(): Histograms with different binning. The objects: " << h1->GetName() << " and " << h2->GetName() << " can not be compared." << endl);
107  }
108 
109  nSlices = nSlices1;
110 
111  h3 = h1->ProjectionY(h3name);
112 
113  for (int i=1 ; i<=nSlices1 ; ++i){
114 
115  const std::string sliceName = MAKE_STRING(h3->GetName() << "_" << to_string(i));
116 
117  const TH1* s1 = h1->ProjectionX (sliceName.c_str(),i,i);
118  const TH1* s2 = h2->ProjectionX (sliceName.c_str(),i,i);
119 
120  if (!(s1->GetSumOfWeights() > 0 && s2->GetSumOfWeights() > 0)) { continue; }
121 
122  const double p = s1 -> KolmogorovTest (s2);
123 
124  if (p < threshold) nFailures++;
125 
126  h3->SetBinContent(i,p);
127  }
128  }
129 
130  const bool passed = (nFailures/nSlices < failuresThreshold);
131 
132  const JResultTitle title(testName, resultType, passed, nFailures);
133 
134  h3->SetTitle(title.getTitle().c_str());
135  h3->GetYaxis()->SetTitle(resultType.c_str());
136 
137  const JTestResult r(testName,
138  JRootObjectID(MAKE_STRING(h1->GetDirectory()->GetPath() << h1->GetName())),
139  JRootObjectID(MAKE_STRING(h2->GetDirectory()->GetPath() << h1->GetName())),
140  resultType, nFailures, failuresThreshold, h3, passed);
141 
142  this->push_back(r);
143  }
144 
145 
146  /**
147  * Read test parameters from input.
148  *
149  * \param in input stream
150  * \return input stream
151  */
152  std::istream& read(std::istream& in) override
153  {
154  using namespace JPP;
155 
156  in >> threshold >> failuresThreshold >> slice;
157 
158  if (threshold < 0.0 || threshold > 1.0) {
159  THROW(JValueOutOfRange, "JTestKolmogorov_Slice2D::read(): Invalid threshold value " << threshold);
160  }
161 
162  if (failuresThreshold < 0.0 || failuresThreshold > 1.0) {
163  THROW(JValueOutOfRange, "JTestKolmogorov_Slice2D::read(): Invalid failuresThreshold value " << failuresThreshold);
164  }
165 
166  if (slice != 'x' && slice != 'X' && slice != 'y' && slice != 'Y') {
167  THROW(JValueOutOfRange, "JTestKolmogorov_Slice2D::read(): Invalid slice option " << slice);
168  }
169 
170  return in;
171  }
172 
173  private:
174 
175  double threshold; //!< threshold p-value to decide if test is passed.
176  double failuresThreshold; //!< threshold p-value to decide if test is passed.
177  char slice; //!< axis to slice. x or X for x-axis, y or Y for y-axis, n or N for None.
178  };
179 }
180 
181 #endif
void test(const TObject *o1, const TObject *o2) override
Applies Kolmogorov test for two ROOT TH2 histograms.
Exceptions.
Interface to read input and write output for TObject tests.
Definition: JTest_t.hh:40
std::istream & read(std::istream &in) override
Read test parameters from input.
std::string getTitle() const
Returns a standard string to be used as title of a graphical root object.
Definition: JResultTitle.hh:57
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
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
double failuresThreshold
threshold p-value to decide if test is passed.
char slice
axis to slice. x or X for x-axis, y or Y for y-axis, n or N for None.
Implementation of the Kolmogorov test for 2D histograms.
const std::string resultType
test result type
Definition: JTest_t.hh:181
const std::string testName
test name
Definition: JTest_t.hh:180
double threshold
threshold p-value to decide if test is passed.
then fatal The output file must have the wildcard in the e g root fi 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.
Structure containing the result of the test.
Definition: JTestResult.hh:28