Skip to content

Commit c016a38

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 c016a38

File tree

6 files changed

+76
-1
lines changed

6 files changed

+76
-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: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,30 @@ Int_t TProfile::BufferFill(Double_t x, Double_t y, Double_t w)
416416
return -2;
417417
}
418418

419+
////////////////////////////////////////////////////////////////////////////////
420+
/// Run a Chi2Test between a TProfileD and another histogram.
421+
/// If the argument is also a TProfileD, this calls TH1::Chi2Test() with the option "WW".
422+
/// \see TH1::Chi2Test()
423+
424+
Double_t TProfile::Chi2Test(const TH1 *h2, Option_t *option, Double_t *res) const
425+
{
426+
TString opt = option;
427+
opt.ToUpper();
428+
429+
if (auto other = dynamic_cast<const TProfile *>(h2); other) {
430+
if (fErrorMode != kERRORMEAN || other->fErrorMode != kERRORMEAN)
431+
Error("Chi2Test", "Chi2 tests need TProfiles in 'error of mean' mode.");
432+
433+
opt += "WW";
434+
opt.ReplaceAll("UU", "WW");
435+
opt.ReplaceAll("UW", "WW");
436+
} else if (!opt.Contains("WW")) {
437+
Error("Chi2Test", "TProfiles need to be tested with the 'W' option. Either use option 'WW' or use histogram.Chi2Test(<profile>, 'UW')");
438+
}
439+
440+
return TH1::Chi2Test(h2, opt, res);
441+
}
442+
419443
////////////////////////////////////////////////////////////////////////////////
420444
/// Copy a Profile histogram to a new profile histogram.
421445

hist/hist/src/TProfile2D.cxx

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,30 @@ 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 a TProfile2D and another histogram.
384+
/// If the argument is also a TProfile2D, this calls TH1::Chi2Test() with the option "WW".
385+
/// \see TH1::Chi2Test()
386+
387+
Double_t TProfile2D::Chi2Test(const TH1 *h2, Option_t *option, Double_t *res) const
388+
{
389+
TString opt = option;
390+
opt.ToUpper();
391+
392+
if (auto other = dynamic_cast<const TProfile2D *>(h2); other) {
393+
if (fErrorMode != kERRORMEAN || other->fErrorMode != kERRORMEAN)
394+
Error("Chi2Test", "Chi2 tests need TProfiles in 'error of mean' mode.");
395+
396+
opt += "WW";
397+
opt.ReplaceAll("UU", "WW");
398+
opt.ReplaceAll("UW", "WW");
399+
} else if (!opt.Contains("WW")) {
400+
Error("Chi2Test", "TProfiles need to be tested with the 'W' option. Either use option 'WW' or use histogram.Chi2Test(<profile>, 'UW')");
401+
}
402+
403+
return TH1::Chi2Test(h2, opt, res);
404+
}
405+
382406
////////////////////////////////////////////////////////////////////////////////
383407
/// Copy a Profile2D histogram to a new profile2D histogram.
384408

hist/hist/src/TProfile3D.cxx

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,30 @@ 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 a TProfile3D and another histogram.
348+
/// If the argument is also a TProfile3D, this calls TH1::Chi2Test() with the option "WW".
349+
/// \see TH1::Chi2Test()
350+
351+
Double_t TProfile3D::Chi2Test(const TH1 *h2, Option_t *option, Double_t *res) const
352+
{
353+
TString opt = option;
354+
opt.ToUpper();
355+
356+
if (auto other = dynamic_cast<const TProfile3D *>(h2); other) {
357+
if (fErrorMode != kERRORMEAN || other->fErrorMode != kERRORMEAN)
358+
Error("Chi2Test", "Chi2 tests need TProfiles in 'error of mean' mode.");
359+
360+
opt += "WW";
361+
opt.ReplaceAll("UU", "WW");
362+
opt.ReplaceAll("UW", "WW");
363+
} else if (!opt.Contains("WW")) {
364+
Error("Chi2Test", "TProfiles need to be tested with the 'W' option. Either use option 'WW' or use histogram.Chi2Test(<profile>, 'UW')");
365+
}
366+
367+
return TH1::Chi2Test(h2, opt, res);
368+
}
369+
346370
////////////////////////////////////////////////////////////////////////////////
347371
/// Copy a Profile3D histogram to a new profile2D histogram.
348372

0 commit comments

Comments
 (0)