Skip to content

Commit 007bbba

Browse files
committed
- Add support for weighted likelihood fit of histogram (new option WL) and suppress old option LL
https://savannah.cern.ch/bugs/?79754 - fix a bug in TEfficiency::BetaShortestInterval when a=b=1 - remove in TH1::FindNewAxisLimits condition added in http://root.cern.ch/viewvc?view=rev&revision=11117 which does not seem to make sense. Some tests of merging histogram was failing in some particular cases due to that code git-svn-id: http://root.cern.ch/svn/root/trunk@39389 27541ba8-7e3a-0410-8455-c3a389f83636
1 parent 4ba65c6 commit 007bbba

File tree

3 files changed

+30
-18
lines changed

3 files changed

+30
-18
lines changed

hist/hist/src/HFitImpl.cxx

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ TFitResultPtr HFit::Fit(FitObject * h1, TF1 *f1 , Foption_t & fitOption , const
149149
if (fitOption.Like) opt.fUseEmpty = true; // use empty bins in log-likelihood fits
150150
if (special==300) opt.fCoordErrors = false; // no need to use coordinate errors in a pol0 fit
151151
if (fitOption.NoErrX) opt.fCoordErrors = false; // do not use coordinate errors when requested
152-
if (fitOption.W1) opt.fErrors1 = true;
152+
if (fitOption.W1 ) opt.fErrors1 = true;
153153
if (fitOption.W1 > 1) opt.fUseEmpty = true; // use empty bins with weight=1
154154

155155
//opt.fBinVolume = 1; // for testing
@@ -320,8 +320,10 @@ TFitResultPtr HFit::Fit(FitObject * h1, TF1 *f1 , Foption_t & fitOption , const
320320

321321
if (fitOption.User && userFcn) // user provided fit objective function
322322
fitok = fitter->FitFCN( userFcn );
323-
else if (fitOption.Like) // likelihood fit
324-
fitok = fitter->LikelihoodFit(*fitdata);
323+
else if (fitOption.Like) {// likelihood fit
324+
bool weight = (fitOption.Like > 1);
325+
fitok = fitter->LikelihoodFit(*fitdata,weight);
326+
}
325327
else // standard least square fit
326328
fitok = fitter->Fit(*fitdata);
327329

@@ -605,8 +607,8 @@ void ROOT::Fit::FitOptionsMake(const char *option, Foption_t &fitOption) {
605607
if (opt.Contains("L")) fitOption.Like = 1;
606608
if (opt.Contains("X")) fitOption.Chi2 = 1;
607609
if (opt.Contains("I")) fitOption.Integral= 1;
608-
if (opt.Contains("LL")) fitOption.Like = 2;
609610
if (opt.Contains("W")) fitOption.W1 = 1;
611+
if (opt.Contains("WL")) { fitOption.Like = 2; fitOption.W1=0; }
610612
if (opt.Contains("E")) fitOption.Errors = 1;
611613
if (opt.Contains("R")) fitOption.Range = 1;
612614
if (opt.Contains("G")) fitOption.Gradient= 1;
@@ -771,7 +773,14 @@ TFitResultPtr ROOT::Fit::UnBinFit(ROOT::Fit::UnBinData * fitdata, TF1 * fitfunc,
771773

772774
// implementations of ROOT::Fit::FitObject functions (defined in HFitInterface) in terms of the template HFit::Fit
773775

774-
TFitResultPtr ROOT::Fit::FitObject(TH1 * h1, TF1 *f1 , Foption_t & foption , const ROOT::Math::MinimizerOptions & moption, const char *goption, ROOT::Fit::DataRange & range) {
776+
TFitResultPtr ROOT::Fit::FitObject(TH1 * h1, TF1 *f1 , Foption_t & foption , const ROOT::Math::MinimizerOptions &
777+
moption, const char *goption, ROOT::Fit::DataRange & range) {
778+
// check fit options
779+
// check if have weights in case of weighted likelihood
780+
if (foption.Like > 1 && h1->GetSumw2N() == 0) {
781+
Warning("HFit::FitObject","A weighted likelihood fit is requested but histogram is not weighted - do a standard Likelihood fit");
782+
foption.Like = 1;
783+
}
775784
// histogram fitting
776785
return HFit::Fit(h1,f1,foption,moption,goption,range);
777786
}

hist/hist/src/TEfficiency.cxx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1302,7 +1302,7 @@ Bool_t TEfficiency::BetaShortestInterval(Double_t level,Double_t a,Double_t b, D
13021302
// special case when the shortest interval is undefined return the central interval
13031303
// can happen for a posterior when passed=total=0
13041304
//
1305-
if ( a==b && a<1.0) {
1305+
if ( a==b && a<=1.0) {
13061306
lower = BetaCentralInterval(level,a,b,kFALSE);
13071307
upper = BetaCentralInterval(level,a,b,kTRUE);
13081308
return kTRUE;

hist/hist/src/TH1.cxx

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3345,7 +3345,8 @@ TFitResultPtr TH1::Fit(TF1 *f1 ,Option_t *option ,Option_t *goption, Double_t xx
33453345
// = "I" Use integral of function in bin, normalized by the bin volume,
33463346
// instead of value at bin center
33473347
// = "L" Use Loglikelihood method (default is chisquare method)
3348-
// = "LL" Use Loglikelihood method and bin contents are not integers)
3348+
// = "WL" Use Loglikelihood method and bin contents are not integer,
3349+
// i.e. histogram is weighted (must have Sumw2() set)
33493350
// = "U" Use a User specified fitting algorithm (via SetFCN)
33503351
// = "Q" Quiet mode (minimum printing)
33513352
// = "V" Verbose mode (default is between Q and V)
@@ -3866,9 +3867,10 @@ Int_t TH1::FitOptionsMake(Option_t *choptin, Foption_t &fitOption)
38663867
if (opt.Contains("V")) {fitOption.Verbose = 1; fitOption.Quiet = 0;}
38673868
if (opt.Contains("X")) fitOption.Chi2 = 1;
38683869
if (opt.Contains("L")) fitOption.Like = 1;
3869-
if (opt.Contains("LL")) fitOption.Like = 2;
3870+
//if (opt.Contains("LL")) fitOption.Like = 2;
38703871
if (opt.Contains("W")) fitOption.W1 = 1;
38713872
if (opt.Contains("WW")) fitOption.W1 = 2; //all bins have weight=1, even empty bins
3873+
if (opt.Contains("WL")){ fitOption.Like = 2; fitOption.W1=0;}// (weighted likelihood)
38723874
if (opt.Contains("E")) fitOption.Errors = 1;
38733875
if (opt.Contains("M")) fitOption.More = 1;
38743876
if (opt.Contains("R")) fitOption.Range = 1;
@@ -3882,6 +3884,7 @@ Int_t TH1::FitOptionsMake(Option_t *choptin, Foption_t &fitOption)
38823884
if (opt.Contains("F")) fitOption.Minuit = 1;
38833885
if (opt.Contains("C")) fitOption.Nochisq = 1;
38843886
if (opt.Contains("S")) fitOption.StoreResult = 1;
3887+
38853888
return 1;
38863889
}
38873890

@@ -5615,23 +5618,23 @@ Bool_t TH1::FindNewAxisLimits(const TAxis* axis, const Double_t point, Double_t&
56155618
xmin = xmin - range;
56165619
range *= 2;
56175620
binsize *= 2;
5618-
// make sure that the merging will be correct
5619-
if ( xmin / binsize - TMath::Floor(xmin / binsize) >= 0.5) {
5620-
xmin += 0.5 * binsize;
5621-
xmax += 0.5 * binsize; // won't work with a histogram with only one bin, but I don't care
5622-
}
5621+
// // make sure that the merging will be correct
5622+
// if ( xmin / binsize - TMath::Floor(xmin / binsize) >= 0.5) {
5623+
// xmin += 0.5 * binsize;
5624+
// xmax += 0.5 * binsize; // won't work with a histogram with only one bin, but I don't care
5625+
// }
56235626
}
56245627
while (point >= xmax) {
56255628
if (ntimes++ > 64)
56265629
return kFALSE;
56275630
xmax = xmax + range;
56285631
range *= 2;
56295632
binsize *= 2;
5630-
// make sure that the merging will be correct
5631-
if ( xmin / binsize - TMath::Floor(xmin / binsize) >= 0.5) {
5632-
xmin -= 0.5 * binsize;
5633-
xmax -= 0.5 * binsize; // won't work with a histogram with only one bin, but I don't care
5634-
}
5633+
// // make sure that the merging will be correct
5634+
// if ( xmin / binsize - TMath::Floor(xmin / binsize) >= 0.5) {
5635+
// xmin -= 0.5 * binsize;
5636+
// xmax -= 0.5 * binsize; // won't work with a histogram with only one bin, but I don't care
5637+
// }
56355638
}
56365639
newMin = xmin;
56375640
newMax = xmax;

0 commit comments

Comments
 (0)