Skip to content

Commit d3d1505

Browse files
committed
[hist] Use WW comparison when TH1::Chi2Test is invoked with TProfiles.
The test can only work if the uncertainties are taken into account correctly, so the Chi2Test function was overridden for all TProfile classes. Furthermore, the function will check if the profiles have the correct error option set. See also the discussion in: https://root-forum.cern.ch/t/chi2test-using-tprofile/64156/
1 parent 7a5a5c6 commit d3d1505

File tree

6 files changed

+61
-1
lines changed

6 files changed

+61
-1
lines changed

hist/hist/inc/TProfile.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,8 @@ class TProfile : public TH1D {
8989
Bool_t Add(const TH1 *h1, const TH1 *h2, Double_t c1=1, Double_t c2=1) override; // *MENU*
9090
static void Approximate(Bool_t approx=kTRUE);
9191
Int_t BufferEmpty(Int_t action=0) override;
92-
void BuildOptions(Double_t ymin, Double_t ymax, Option_t *option);
92+
void BuildOptions(Double_t ymin, Double_t ymax, Option_t *option);
93+
Double_t Chi2Test(const TH1* h2, Option_t *option = "WW", Double_t *res = nullptr) const override;
9394
void Copy(TObject &hnew) const override;
9495
Bool_t Divide(TF1 *h1, Double_t c1=1) override;
9596
Bool_t Divide(const TH1 *h1) override;

hist/hist/inc/TProfile2D.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ class TProfile2D : public TH2D {
9595
static void Approximate(Bool_t approx=kTRUE);
9696
void BuildOptions(Double_t zmin, Double_t zmax, Option_t *option);
9797
Int_t BufferEmpty(Int_t action=0) override;
98+
Double_t Chi2Test(const TH1* h2, Option_t *option = "WW", Double_t *res = nullptr) const override;
9899
void Copy(TObject &hnew) const override;
99100
Bool_t Divide(TF1 *h1, Double_t c1=1) override;
100101
Bool_t Divide(const TH1 *h1) override;

hist/hist/inc/TProfile3D.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ class TProfile3D : public TH3D {
100100
static void Approximate(Bool_t approx=kTRUE);
101101
void BuildOptions(Double_t tmin, Double_t tmax, Option_t *option);
102102
Int_t BufferEmpty(Int_t action=0) override;
103+
Double_t Chi2Test(const TH1* h2, Option_t *option = "WW", Double_t *res = nullptr) const override;
103104
void Copy(TObject &hnew) const override;
104105
Bool_t Divide(TF1 *h1, Double_t c1=1) override;
105106
Bool_t Divide(const TH1 *h1) override;

hist/hist/src/TProfile.cxx

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,25 @@ Int_t TProfile::BufferFill(Double_t x, Double_t y, Double_t w)
416416
return -2;
417417
}
418418

419+
////////////////////////////////////////////////////////////////////////////////
420+
/// Run a Chi2Test between two TProfiles.
421+
/// This calls TH1::Chi2Test() with the option "WW".
422+
423+
Double_t TProfile::Chi2Test(const TH1 *h2, Option_t *option, Double_t *res) const
424+
{
425+
TString opt = option;
426+
opt.ToUpper();
427+
opt += "WW";
428+
opt.ReplaceAll("UU", "");
429+
opt.ReplaceAll("UW", "");
430+
431+
if (auto other = dynamic_cast<const TProfile *>(h2);
432+
fErrorMode != kERRORMEAN || (other && other->fErrorMode != kERRORMEAN))
433+
Warning("TProfile::Chi2Test", "Chi2 tests only make sense if the error on the mean is used.");
434+
435+
return TH1::Chi2Test(h2, opt, res);
436+
}
437+
419438
////////////////////////////////////////////////////////////////////////////////
420439
/// Copy a Profile histogram to a new profile histogram.
421440

hist/hist/src/TProfile2D.cxx

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,25 @@ Int_t TProfile2D::BufferFill(Double_t x, Double_t y, Double_t z, Double_t w)
379379
return -2;
380380
}
381381

382+
////////////////////////////////////////////////////////////////////////////////
383+
/// Run a Chi2Test between two TProfile2D.
384+
/// This calls TH1::Chi2Test() with the option "WW".
385+
386+
Double_t TProfile2D::Chi2Test(const TH1 *h2, Option_t *option, Double_t *res) const
387+
{
388+
TString opt = option;
389+
opt.ToUpper();
390+
opt += "WW";
391+
opt.ReplaceAll("UU", "WW");
392+
opt.ReplaceAll("UW", "WW");
393+
394+
if (auto other = dynamic_cast<const TProfile2D *>(h2);
395+
fErrorMode != kERRORMEAN || (other && other->fErrorMode != kERRORMEAN))
396+
Warning("TProfile3D::Chi2Test", "Chi2 tests only make sense if the error on the mean is used.");
397+
398+
return TH1::Chi2Test(h2, opt, res);
399+
}
400+
382401
////////////////////////////////////////////////////////////////////////////////
383402
/// Copy a Profile2D histogram to a new profile2D histogram.
384403

hist/hist/src/TProfile3D.cxx

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,25 @@ Int_t TProfile3D::BufferFill(Double_t x, Double_t y, Double_t z, Double_t t, Dou
343343
return -2;
344344
}
345345

346+
////////////////////////////////////////////////////////////////////////////////
347+
/// Run a Chi2Test between two TProfile3D.
348+
/// This calls TH1::Chi2Test() with the option "WW".
349+
350+
Double_t TProfile3D::Chi2Test(const TH1 *h2, Option_t *option, Double_t *res) const
351+
{
352+
TString opt = option;
353+
opt.ToUpper();
354+
opt += "WW";
355+
opt.ReplaceAll("UU", "WW");
356+
opt.ReplaceAll("UW", "WW");
357+
358+
if (auto other = dynamic_cast<const TProfile3D *>(h2);
359+
fErrorMode != kERRORMEAN || (other && other->fErrorMode != kERRORMEAN))
360+
Warning("TProfile3D::Chi2Test", "Chi2 tests only make sense if the error on the mean is used.");
361+
362+
return TH1::Chi2Test(h2, opt, res);
363+
}
364+
346365
////////////////////////////////////////////////////////////////////////////////
347366
/// Copy a Profile3D histogram to a new profile2D histogram.
348367

0 commit comments

Comments
 (0)