From e4db8ed8aa2440f81d20b051d1c1713f798e9be4 Mon Sep 17 00:00:00 2001 From: Rene Brun <Rene.Brun@cern.ch> Date: Fri, 21 Mar 2003 14:53:50 +0000 Subject: [PATCH] Fix from Christophe Delaere. All TH1F and TArrayF are replaced by TH1D and TArrayD respectively. This solves some numerical precision problems observed with the float implementation git-svn-id: http://root.cern.ch/svn/root/trunk@6337 27541ba8-7e3a-0410-8455-c3a389f83636 --- hist/inc/TLimit.h | 8 ++--- hist/inc/TLimitDataSource.h | 14 ++++----- hist/src/TLimit.cxx | 58 +++++++++++++++++------------------ hist/src/TLimitDataSource.cxx | 28 ++++++++--------- tutorials/limit.C | 10 +++--- 5 files changed, 59 insertions(+), 59 deletions(-) diff --git a/hist/inc/TLimit.h b/hist/inc/TLimit.h index 2925b548f5d..f7d7ac4c50e 100644 --- a/hist/inc/TLimit.h +++ b/hist/inc/TLimit.h @@ -1,4 +1,4 @@ -// @(#)root/hist:$Name: $:$Id: TLimit.h,v 1.34 2002/08/16 21:16:00 brun Exp $ +// @(#)root/hist:$Name: $:$Id: TLimit.h,v 1.1 2002/09/06 19:57:59 brun Exp $ // Author: Christophe.Delaere@cern.ch 21/08/2002 #ifndef ROOT_TLimit @@ -14,7 +14,7 @@ class TConfidenceLevel; class TRandom; class TLimitDataSource; -class TArrayF; +class TArrayD; class TOrdCollection; //____________________________________________________________________ @@ -41,9 +41,9 @@ class TLimit { static TLimitDataSource *Fluctuate(TLimitDataSource * input, bool init,TRandom *); inline static Double_t LogLikelihood(Double_t s, Double_t b, Double_t d) { return d * TMath::Log(1 + (s / b)); } private: - static TArrayF *fgTable; // a log table... just to speed up calculation + static TArrayD *fgTable; // a log table... just to speed up calculation static TOrdCollection *fgSystNames; // Collection of systematics names - ClassDef(TLimit, 1) // Class to compute 95% CL limits + ClassDef(TLimit, 2) // Class to compute 95% CL limits }; #endif diff --git a/hist/inc/TLimitDataSource.h b/hist/inc/TLimitDataSource.h index dab5f06a1f5..5bb9cc4586b 100644 --- a/hist/inc/TLimitDataSource.h +++ b/hist/inc/TLimitDataSource.h @@ -1,4 +1,4 @@ -// @(#)root/hist:$Name: $:$Id: TLimitDataSource.h,v 1.34 2002/08/16 21:16:00 brun Exp $ +// @(#)root/hist:$Name: $:$Id: TLimitDataSource.h,v 1.1 2002/09/06 19:57:59 brun Exp $ // Author: Christophe.Delaere@cern.ch 21/08/2002 #ifndef ROOT_TLimitDataSource @@ -8,7 +8,7 @@ #include "TObjArray.h" #endif -class TH1F; +class TH1D; //_______________________________________________________________________ // @@ -25,9 +25,9 @@ class TLimitDataSource { public: TLimitDataSource(); virtual ~TLimitDataSource() {} - TLimitDataSource(TH1F* s,TH1F* b,TH1F* d); - virtual void AddChannel(TH1F*,TH1F*,TH1F*); - virtual void AddChannel(TH1F*,TH1F*,TH1F*,TH1F*, TH1F*, TObjArray*); + TLimitDataSource(TH1D* s,TH1D* b,TH1D* d); + virtual void AddChannel(TH1D*,TH1D*,TH1D*); + virtual void AddChannel(TH1D*,TH1D*,TH1D*,TH1D*, TH1D*, TObjArray*); inline virtual TObjArray* GetSignal() { return &fSignal;} inline virtual TObjArray* GetBackground() { return &fBackground;} inline virtual TObjArray* GetCandidates() { return &fCandidates;} @@ -44,10 +44,10 @@ private: TObjArray fErrorOnBackground; //packed error sources for background TObjArray fIds; //packed IDs for the different error sources // some dummy objects that the class will use and delete - TObjArray fDummyTH1F; //array of dummy object (used for bookeeping) + TObjArray fDummyTH1D; //array of dummy object (used for bookeeping) TObjArray fDummyIds; //array of dummy object (used for bookeeping) - ClassDef(TLimitDataSource, 1 ) // input for TLimit routines + ClassDef(TLimitDataSource, 2 ) // input for TLimit routines }; #endif diff --git a/hist/src/TLimit.cxx b/hist/src/TLimit.cxx index 1f0289d19b2..c89ede1c35d 100644 --- a/hist/src/TLimit.cxx +++ b/hist/src/TLimit.cxx @@ -1,4 +1,4 @@ -// @(#)root/hist:$Name: $:$Id: TLimit.cxx,v 1.3 2002/09/06 21:41:23 brun Exp $ +// @(#)root/hist:$Name: $:$Id: TLimit.cxx,v 1.4 2002/09/10 14:59:15 rdm Exp $ // Author: Christophe.Delaere@cern.ch 21/08/2002 /////////////////////////////////////////////////////////////////////////// @@ -16,7 +16,7 @@ *************************************************************************/ #include "TLimit.h" -#include "TArrayF.h" +#include "TArrayD.h" #include "TOrdCollection.h" #include "TConfidenceLevel.h" #include "TLimitDataSource.h" @@ -31,7 +31,7 @@ ClassImp(TLimit) -TArrayF *TLimit::fgTable = new TArrayF(0); +TArrayD *TLimit::fgTable = new TArrayD(0); TOrdCollection *TLimit::fgSystNames = new TOrdCollection(); TConfidenceLevel *TLimit::ComputeLimit(TLimitDataSource * data, @@ -78,9 +78,9 @@ TConfidenceLevel *TLimit::ComputeLimit(TLimitDataSource * data, <BLOCKQUOTE><PRE> TFile* infile=new TFile("plotfile.root","READ"); infile->cd(); - TH1F* sh=(TH1F*)infile->Get("signal"); - TH1F* bh=(TH1F*)infile->Get("background"); - TH1F* dh=(TH1F*)infile->Get("data"); + TH1D* sh=(TH1D*)infile->Get("signal"); + TH1D* bh=(TH1D*)infile->Get("background"); + TH1D* dh=(TH1D*)infile->Get("data"); TLimitDataSource* mydatasource = new TLimitDataSource(sh,bh,dh); TConfidenceLevel *myconfidence = TLimit::ComputeLimit(mydatasource,50000); cout << " CLs : " << myconfidence->CLs() << endl; @@ -112,12 +112,12 @@ TConfidenceLevel *TLimit::ComputeLimit(TLimitDataSource * data, Int_t ncand = 0; Int_t i; for (i = 0; i <= data->GetSignal()->GetLast(); i++) { - nbins += ((TH1F *) (data->GetSignal()->At(i)))->GetNbinsX(); - maxbins = ((TH1F *) (data->GetSignal()->At(i)))->GetNbinsX() > maxbins ? - ((TH1F *) (data->GetSignal()->At(i)))->GetNbinsX() + 1 : maxbins; - nsig += ((TH1F *) (data->GetSignal()->At(i)))->Integral(); - nbg += ((TH1F *) (data->GetBackground()->At(i)))->Integral(); - ncand += (Int_t) ((TH1F *) (data->GetCandidates()->At(i)))->Integral(); + nbins += ((TH1D *) (data->GetSignal()->At(i)))->GetNbinsX(); + maxbins = ((TH1D *) (data->GetSignal()->At(i)))->GetNbinsX() > maxbins ? + ((TH1D *) (data->GetSignal()->At(i)))->GetNbinsX() + 1 : maxbins; + nsig += ((TH1D *) (data->GetSignal()->At(i)))->Integral(); + nbg += ((TH1D *) (data->GetBackground()->At(i)))->Integral(); + ncand += (Int_t) ((TH1D *) (data->GetCandidates()->At(i)))->Integral(); } result->SetBtot(nbg); result->SetStot(nsig); @@ -126,11 +126,11 @@ TConfidenceLevel *TLimit::ComputeLimit(TLimitDataSource * data, fgTable->Set(maxbins * (data->GetSignal()->GetLast() + 1)); for (Int_t channel = 0; channel <= data->GetSignal()->GetLast(); channel++) for (Int_t bin = 0; - bin <= ((TH1F *) (data->GetSignal()->At(channel)))->GetNbinsX(); + bin <= ((TH1D *) (data->GetSignal()->At(channel)))->GetNbinsX(); bin++) { - Double_t s = (Double_t) ((TH1F *) (data->GetSignal()->At(channel)))->GetBinContent(bin); - Double_t b = (Double_t) ((TH1F *) (data->GetBackground()->At(channel)))->GetBinContent(bin); - Double_t d = (Double_t) ((TH1F *) (data->GetCandidates()->At(channel)))->GetBinContent(bin); + Double_t s = (Double_t) ((TH1D *) (data->GetSignal()->At(channel)))->GetBinContent(bin); + Double_t b = (Double_t) ((TH1D *) (data->GetBackground()->At(channel)))->GetBinContent(bin); + Double_t d = (Double_t) ((TH1D *) (data->GetCandidates()->At(channel)))->GetBinContent(bin); // Compute the value of the "-2lnQ" for the actual data if ((b == 0) && (s > 0)) { cout << "WARNING: Ignoring bin " << bin << " of channel " @@ -168,22 +168,22 @@ TConfidenceLevel *TLimit::ComputeLimit(TLimitDataSource * data, for (Int_t channel = 0; channel <= fluctuated->GetSignal()->GetLast(); channel++) { for (Int_t bin = 0; - bin <=((TH1F *) (fluctuated->GetSignal()->At(channel)))->GetNbinsX(); + bin <=((TH1D *) (fluctuated->GetSignal()->At(channel)))->GetNbinsX(); bin++) { - if ((Double_t) ((TH1F *) (fluctuated->GetSignal()->At(channel)))->GetBinContent(bin) != 0) { + if ((Double_t) ((TH1D *) (fluctuated->GetSignal()->At(channel)))->GetBinContent(bin) != 0) { // s+b hypothesis - Double_t rate = (Double_t) ((TH1F *) (fluctuated->GetSignal()->At(channel)))->GetBinContent(bin) + - (Double_t) ((TH1F *) (fluctuated->GetBackground()->At(channel)))->GetBinContent(bin); + Double_t rate = (Double_t) ((TH1D *) (fluctuated->GetSignal()->At(channel)))->GetBinContent(bin) + + (Double_t) ((TH1D *) (fluctuated->GetBackground()->At(channel)))->GetBinContent(bin); Double_t rand = myrandom->Poisson(rate); tss[i] += rand * fgTable->At((channel * maxbins) + bin); - Double_t s = (Double_t) ((TH1F *) (fluctuated->GetSignal()->At(channel)))->GetBinContent(bin); - Double_t b = (Double_t) ((TH1F *) (fluctuated->GetBackground()->At(channel)))->GetBinContent(bin); + Double_t s = (Double_t) ((TH1D *) (fluctuated->GetSignal()->At(channel)))->GetBinContent(bin); + Double_t b = (Double_t) ((TH1D *) (fluctuated->GetBackground()->At(channel)))->GetBinContent(bin); if ((s > 0) && (b > 0)) lrs[i] += statistic(s, b, rand) - s; else if ((s > 0) && (b == 0)) lrs[i] += 20 * rand - s; // b hypothesis - rate = (Double_t) ((TH1F *) (fluctuated->GetBackground()->At(channel)))->GetBinContent(bin); + rate = (Double_t) ((TH1D *) (fluctuated->GetBackground()->At(channel)))->GetBinContent(bin); rand = myrandom->Poisson(rate); tsb[i] += rand * fgTable->At((channel * maxbins) + bin); if ((s > 0) && (b > 0)) @@ -254,11 +254,11 @@ TLimitDataSource *TLimit::Fluctuate(TLimitDataSource * input, bool init, serrf[channel] = 0; berrf[channel] = 0; for (Int_t bin = 0; - bin <=((TH1F *) (input->GetErrorOnSignal()->At(channel)))->GetNbinsX(); + bin <=((TH1D *) (input->GetErrorOnSignal()->At(channel)))->GetNbinsX(); bin++) { - serrf[channel] += ((TH1F *) (input->GetErrorOnSignal()->At(channel)))->GetBinContent(bin) * + serrf[channel] += ((TH1D *) (input->GetErrorOnSignal()->At(channel)))->GetBinContent(bin) * toss[fgSystNames->BinarySearch((TObjString*) (((TObjArray *) (input->GetErrorNames()->At(channel)))->At(bin)))]; - berrf[channel] += ((TH1F *) (input->GetErrorOnBackground()->At(channel)))->GetBinContent(bin) * + berrf[channel] += ((TH1D *) (input->GetErrorOnBackground()->At(channel)))->GetBinContent(bin) * toss[fgSystNames->BinarySearch((TObjString*) (((TObjArray *) (input->GetErrorNames()->At(channel)))->At(bin)))]; } if ((serrf[channel] < -1.0) || (berrf[channel] < -0.9)) { @@ -274,13 +274,13 @@ TLimitDataSource *TLimit::Fluctuate(TLimitDataSource * input, bool init, result->SetOwner(); for (Int_t channel = 0; channel <= input->GetSignal()->GetLast(); channel++) { - TH1F *newsignal = new TH1F(*(TH1F *) (input->GetSignal()->At(channel))); + TH1D *newsignal = new TH1D(*(TH1D *) (input->GetSignal()->At(channel))); newsignal->Scale(1 + serrf[channel]); newsignal->SetDirectory(0); - TH1F *newbackground = new TH1F(*(TH1F *) (input->GetBackground()->At(channel))); + TH1D *newbackground = new TH1D(*(TH1D *) (input->GetBackground()->At(channel))); newbackground->Scale(1 + berrf[channel]); newbackground->SetDirectory(0); - TH1F *newcandidates = new TH1F(*(TH1F *) (input->GetCandidates())); + TH1D *newcandidates = new TH1D(*(TH1D *) (input->GetCandidates())); newcandidates->SetDirectory(0); result->AddChannel(newsignal, newbackground, newcandidates); } diff --git a/hist/src/TLimitDataSource.cxx b/hist/src/TLimitDataSource.cxx index 0455cb2e60f..fdf6126a442 100644 --- a/hist/src/TLimitDataSource.cxx +++ b/hist/src/TLimitDataSource.cxx @@ -1,4 +1,4 @@ -// @(#)root/hist:$Name: $:$Id: TLimitDataSource.cxx,v 1.1 2002/09/06 19:58:00 brun Exp $ +// @(#)root/hist:$Name: $:$Id: TLimitDataSource.cxx,v 1.2 2002/09/13 15:23:56 brun Exp $ // Author: Christophe.Delaere@cern.ch 21/08/2002 /////////////////////////////////////////////////////////////////////////// @@ -19,50 +19,50 @@ ClassImp(TLimitDataSource) TLimitDataSource::TLimitDataSource() { // Default constructor - fDummyTH1F.SetOwner(); + fDummyTH1D.SetOwner(); fDummyIds.SetOwner(); } -TLimitDataSource::TLimitDataSource(TH1F * s, TH1F * b, TH1F * d) +TLimitDataSource::TLimitDataSource(TH1D * s, TH1D * b, TH1D * d) { // Another constructor, directly adds one channel // with signal, background and data given as input. - fDummyTH1F.SetOwner(); + fDummyTH1D.SetOwner(); fDummyIds.SetOwner(); AddChannel(s, b, d); } -void TLimitDataSource::AddChannel(TH1F * s, TH1F * b, TH1F * d) +void TLimitDataSource::AddChannel(TH1D * s, TH1D * b, TH1D * d) { // Adds a channel with signal, background and data given as input. - TH1F *empty; + TH1D *empty; TRandom3 generator; fSignal.AddLast(s); fBackground.AddLast(b); fCandidates.AddLast(d); char rndname[20]; sprintf(rndname, "rndname%f", generator.Rndm()); - empty = new TH1F(rndname, "", s->GetSize(), 0, 1); + empty = new TH1D(rndname, "", s->GetSize(), 0, 1); empty->SetDirectory(0); fErrorOnSignal.AddLast(empty); - fDummyTH1F.AddLast(empty); + fDummyTH1D.AddLast(empty); sprintf(rndname, "rndname%f", generator.Rndm()); - empty = new TH1F(rndname, "", s->GetSize(), 0, 1); + empty = new TH1D(rndname, "", s->GetSize(), 0, 1); empty->SetDirectory(0); fErrorOnBackground.AddLast(empty); - fDummyTH1F.AddLast(empty); + fDummyTH1D.AddLast(empty); TObjArray *dummy = new TObjArray(0); fIds.AddLast(dummy); fDummyIds.AddLast(dummy); } -void TLimitDataSource::AddChannel(TH1F * s, TH1F * b, TH1F * d, TH1F * es, - TH1F * eb, TObjArray * names) +void TLimitDataSource::AddChannel(TH1D * s, TH1D * b, TH1D * d, TH1D * es, + TH1D * eb, TObjArray * names) { // Adds a channel with signal, background and data given as input. // In addition, error sources are defined. - // TH1F are here used for convenience: each bin has to be seen as + // TH1D are here used for convenience: each bin has to be seen as // an error source (relative). // names is an array of strings containing the names of the sources. // Sources with the same name are correlated. @@ -87,7 +87,7 @@ void TLimitDataSource::SetOwner(bool swtch) fErrorOnSignal.SetOwner(swtch); fErrorOnBackground.SetOwner(swtch); fIds.SetOwner(swtch); - fDummyTH1F.SetOwner(!swtch); + fDummyTH1D.SetOwner(!swtch); fDummyIds.SetOwner(!swtch); } diff --git a/tutorials/limit.C b/tutorials/limit.C index 50cd833a987..ae9e40c462d 100644 --- a/tutorials/limit.C +++ b/tutorials/limit.C @@ -13,9 +13,9 @@ void limit() { c1->SetFillColor(42); // Create some histograms - TH1F* background = new TH1F("background","The expected background",30,-4,4); - TH1F* signal = new TH1F("signal","the expected signal",30,-4,4); - TH1F* data = new TH1F("data","some fake data points",30,-4,4); + TH1D* background = new TH1D("background","The expected background",30,-4,4); + TH1D* signal = new TH1D("signal","the expected signal",30,-4,4); + TH1D* data = new TH1D("data","some fake data points",30,-4,4); background->SetFillColor(48); signal->SetFillColor(41); data->SetMarkerStyle(21); @@ -61,8 +61,8 @@ void limit() { // Add some systematics cout << endl << "Computing limits with systematics... " << endl; - TH1F* errorb = new TH1F("errorb","errors on background",1,0,1); - TH1F* errors = new TH1F("errors","errors on signal",1,0,1); + TH1D* errorb = new TH1D("errorb","errors on background",1,0,1); + TH1D* errors = new TH1D("errors","errors on signal",1,0,1); TObjArray* names = new TObjArray(); TObjString name1("bg uncertainty"); TObjString name2("sig uncertainty"); -- GitLab