//////////////////////////////////////////////////////////////////////////
// //
// GFMultiDmFitter //
//
// Author: Gero Flucke
// Date: June 10th, 2003
// last update: $Date: 2005/11/15 17:27:52 $
// by: $Author: flucke $
// //
// fitting several delta m histogramms using DstarDmFitter //
// //
//////////////////////////////////////////////////////////////////////////
#include "GFMultiDmFitter.h"
#include <iostream>
using namespace std;
#include "TH1.h"
#include "TH2.h"
#include "TF1.h"
#include "GFUtils/GFHistArray.h"
#include "GFUtils/GFHistManip.h"
#include "GFUtils/GFDstarRunPeriods.h"
#include "GFAnalysis/GFDstarCount.h"
#include "/afs/desy.de/user/f/flucke/h1/root/DstarDmFitter/DstarDmFitter.h"
ClassImp(GFMultiDmFitter)
GFMultiDmFitter::GFMultiDmFitter()
{
this->Init();
}
GFMultiDmFitter::~GFMultiDmFitter()
{
delete fFitter;
delete fHists1D; // really?
delete fHists1DWc; // dito?
}
//__________________________________________________________________
void GFMultiDmFitter::SetSmartMode(Bool_t s)
{
fFitter->SetSmartMode(s);
}
//__________________________________________________________________
void GFMultiDmFitter::Init()
{
fFitter = new DstarDmFitter;
fFitter->SetSmartMode(kFALSE); // fixme
fStartUsqr = -1.; // < 0 indicates: ignore and use default from DstarDmFitter
fFitModeAll = 0;
fFitModeBins = 1011;
fFitOrNotFlag = 0;
fMergeNBins = 1;
fOldParams[0] = fOldParams[1] = fOldParams[2] = fOldParams[3] = 0.;
fOldParams[4] = 1.;
fStartDmSignal = GFDstarRunPeriods::fgStartDmSignal;
fEndDmSignal = GFDstarRunPeriods::fgEndDmSignal;
fStartDmBackgr = GFDstarRunPeriods::fgStartDmBackgr;
fEndDmBackgr = GFDstarRunPeriods::fgEndDmBackgr;
fHists1D = NULL;
fHists1DWc = NULL;
fHistSignalBack = NULL;
}
//__________________________________________________________________
TH1* GFMultiDmFitter::Fit(TH2* hist2D, TH1* histRef, TH2* hist2DWc, TH1* histWcRef)
{
// hist2D has x-axis bins in delta m!
// If histAll given it will be taken as reference hist for fixing parameters,
// otherwise the projection of hist2D is taken.
// This method allocates memory:
// - the returned histogram
// - the 1-D hists that can be accessed via GFHistArray* GetHists1D()
// (but the array is owned by this class!)
// - dito for WC 1-D hists if hist2DWc is given (accessed via GFHistArray* GetHists1DWc()
// - the histogram of the signal/background ratios, to be accessed via GetHistSignalBack()
if(!hist2D) return NULL;
if(hist2DWc && hist2D->GetNbinsY() != hist2DWc->GetNbinsY()){
this->Error("Fit", "WC hist has %d instead of %d bins in Y",
hist2DWc->GetNbinsY(), hist2D->GetNbinsY());
return NULL;
}
Bool_t setSmart = kTRUE;
if(hist2DWc) setSmart = fFitter->SetSmartMode(kFALSE);
TH1* refHistInt = NULL;
if(histRef) refHistInt = histRef;
else refHistInt = hist2D->ProjectionX("tmpRefHist", -1, -1, "e");
TH1* refHistIntWc = NULL;
if(histWcRef || !hist2DWc) refHistIntWc = histWcRef;
else refHistIntWc = hist2DWc->ProjectionX("tmpRefHistWc", -1, -1, "e");
if(fFitOrNotFlag == 0 || fFitOrNotFlag == 5) {
this->FitAll(refHistInt, refHistIntWc);
}
if(fHists1D) delete fHists1D;
fHists1D = GFHistManip::CreateHistArray1D(hist2D, hist2D->GetYaxis()->GetTitle(), NULL,
Form("m%dou", fMergeNBins));
if(fHists1DWc) delete fHists1DWc;
fHists1DWc = (hist2DWc ?
GFHistManip::CreateHistArray1D(hist2DWc, hist2DWc->GetYaxis()->GetTitle(),
NULL, Form("m%dou", fMergeNBins)) : NULL);
TH1* histNumDstar = GFHistManip::CreateHistYBins(hist2D, "", fMergeNBins);
fHistSignalBack = GFHistManip::CreateHistYBins(hist2D, "", fMergeNBins);
fHistSignalBack->SetTitle(Form("S/B;%s;S/B", fHistSignalBack->GetXaxis()->GetTitle()));
// if over-/underflow are empty, remove them:
if (fHists1D->First()->Integral() == 0. && fHists1D->Last()->Integral() == 0.) {
delete fHists1D->RemoveAt(0);
delete fHists1D->Remove(fHists1D->Last());
if (fHists1DWc) {
delete fHists1DWc->RemoveAt(0);
delete fHists1DWc->Remove(fHists1DWc->Last());
}
} else { // else merge them in first hist
GFHistManip::Add2ndTo1st(fHists1D->First(), fHists1D->Last(), 1.);
fHists1D->First()->SetTitle(Form("%s || %s", fHists1D->First()->GetTitle(),
fHists1D->Last()->GetTitle()));
delete fHists1D->Remove(fHists1D->Last());
if (fHists1DWc) {
GFHistManip::Add2ndTo1st(fHists1DWc->First(), fHists1DWc->Last(), 1.);
fHists1DWc->First()->SetTitle(Form("%s || %s", fHists1DWc->First()->GetTitle(),
fHists1DWc->Last()->GetTitle()));
delete fHists1DWc->Remove(fHists1DWc->Last());
}
}
Double_t sumw2 = 0.;
for (Int_t i = 0; i < fHists1D->GetEntriesFast(); ++i) {
if (!fHists1D->At(i)) continue; // empty slots due to removal of under/overflow
TH1* hWc = (fHists1DWc ? fHists1DWc->At(i) : NULL);
TArrayD nErrSB = this->FitSingle(fHists1D->At(i), hWc);
histNumDstar->SetBinContent(i, nErrSB[0]);
histNumDstar->SetBinError(i, nErrSB[1]);
fHistSignalBack->SetBinContent(i, nErrSB[2]);
sumw2 += nErrSB[1]*nErrSB[1];
}
fHists1D->Compress(); // remove empty slots
if (fHists1DWc) fHists1DWc->Compress();
histNumDstar->SetEntries(histNumDstar->Integral());
Stat_t s[11];
histNumDstar->GetStats(s);
s[0] = histNumDstar->GetEntries();
s[1] = sumw2;
histNumDstar->PutStats(s);
if(histRef != refHistInt) delete refHistInt;
if(histWcRef != refHistIntWc) delete refHistIntWc;
// fOldParams[0] = fOldParams[1] = fOldParams[2] = fOldParams[3] = 0.;
// fOldParams[4] = 1.;
if(hist2DWc && setSmart) fFitter->SetSmartMode(kTRUE);
return histNumDstar;
}
//__________________________________________________________________
TArrayD GFMultiDmFitter::FitAll(TH1* hist, TH1* histWc)
{
// fit hist with fFitModeAll (histWc as possible WC-background hist),
// return array {N(D*), err(ND*), S/B-ratio, scale to be applied to histWc}
// to get same normalisation of the background part
// if fit not successful, result is an empty array
// (fOldParams is filled with result of this fit - if successful!)
fFitter->ResetFitParameters();
if(fStartUsqr >= 0.) fFitter->SetBackgrSqr(fStartUsqr);
// reset old params, should be set in the following for flag 0 and 5:
fOldParams[0] = fOldParams[1] = fOldParams[2] = fOldParams[3] = 0.;
fOldParams[4] = 1.;
TArrayD result(4);
switch(fFitOrNotFlag){
case 0:
if(fFitter->Fit(fFitModeAll, hist, histWc)){
result[0] = fFitter->GetNDstar();
result[1] = fFitter->GetNDstarErr();
result[2] = fFitter->GetSignalBack();
if(histWc) result[3] = fFitter->GetWcScale();
fOldParams[0] = fFitter->GetMean(); // store parameters of reference fit
fOldParams[1] = fFitter->GetSigma();
fOldParams[2] = fFitter->GetBackgrExp();
fOldParams[3] = fFitter->GetBackgrSqr();
fOldParams[4] = result[3];//fFitter->GetWcScale();
break;
}
this->Warning("FitAll", "not fitted: count signal region and subtract background est.");
case 1: // count signal region, but subtract background estimate (latter may be from hWc)
result = this->CountSignal(hist, histWc, kTRUE);
break;
case 2: // count signal region
result = this->CountSignal(hist, NULL, kFALSE);
break;
case 3: // count whole delta m
for(Int_t j = 1; j <= hist->GetNbinsX(); ++j){
result[0] += hist->GetBinContent(j);
result[1] += (hist->GetBinError(j) * hist->GetBinError(j));
}
result[1] = TMath::Sqrt(result[1]);
break;
case 4: // subtract the fit to scaled background in signal region
result = GFDstarCount::NDstarBackgrFuncSubtracted(hist, histWc, fStartDmSignal,fEndDmSignal,
fStartDmBackgr, fEndDmBackgr);
break;
case 5: // fit, subtract background function integral from counted signal (in 3-sigma)
if(fFitter->Fit(fFitModeAll, hist, histWc)){
const Int_t bin3SigmaL = hist->FindBin(fFitter->GetMean() - 3.* fFitter->GetSigma());
const Int_t bin3SigmaU = hist->FindBin(fFitter->GetMean() + 3.* fFitter->GetSigma());
result[0] = hist->Integral(bin3SigmaL, bin3SigmaU);
result[1] = (result[0] ? TMath::Sqrt(result[0])/result[0] : 0.); // relative error so far
TF1 backGr(*(fFitter->GetFittedBackgrFunc()));
Double_t subtract = backGr.Integral(hist->GetXaxis()->GetBinLowEdge(bin3SigmaL),
hist->GetXaxis()->GetBinUpEdge(bin3SigmaU));
subtract /= fFitter->GetHistBinSize();
result[0] -= subtract;
result[1] *= result[0]; // relative error of SR count
this->Warning("FitAll", "flag 5: relative error from count of SR, only 1 try to fit");
result[2] = (subtract ? result[0]/subtract : 0.); // S/B
if(histWc) result[3] = fFitter->GetWcScale();
fOldParams[0] = fFitter->GetMean(); // store parameters of reference fit
fOldParams[1] = fFitter->GetSigma();
fOldParams[2] = fFitter->GetBackgrExp();
fOldParams[3] = fFitter->GetBackgrSqr();
fOldParams[4] = result[3];//fFitter->GetWcScale();
} else {
this->Warning("FitAll", "flag 5: fit did not succeed");
}
break;
default:
this->Warning("FitAll", "don't know fitOrNotFlag = %d", fFitOrNotFlag);
}
// if(fFitter->Fit(fFitModeAll, hist, histWc)){
// fOldParams[0] = fFitter->GetMean(); // store parameters of reference fit
// fOldParams[1] = fFitter->GetSigma();
// fOldParams[2] = fFitter->GetBackgrExp();
// fOldParams[3] = fFitter->GetBackgrSqr();
// fOldParams[4] = fFitter->GetWcScale();
// result[0] = fFitter->GetNDstar();
// result[1] = fFitter->GetNDstarErr();
// result[2] = fFitter->GetSignalBack();
// if(histWc) result[3] = fOldParams[4];
// }
return result;
}
//__________________________________________________________________
TArrayD GFMultiDmFitter::FitSingle(TH1* hist, TH1* hWc) const
{
// returning TArrayD of length 4:
// N(D*), error, S/B-ratio, scale between hist and hWc fit normalisation
const Int_t minEntries = 28; // for fit
const Int_t minEntFull = 200; // for fit with other option than 1111
TArrayD result(4); // N(D*), error, S/B-ratio, scale for WC hist if existing
Double_t histEntriesD = hist->Integral();
const Int_t histEntries = static_cast<Int_t>(histEntriesD);
if(TMath::Abs(histEntriesD - histEntries) > 1.e-10) {
// weighted entries/scaled hists: use effective number of filling actions
Stat_t s[11];
hist->GetStats(s);//now s[1] is sum of squares of weights, s[0] is sum of weights
histEntriesD = s[0]*s[0]/s[1]; // effective number of entries, cf. LOOK manual
}
switch(fFitOrNotFlag){
case 0:
if(histEntriesD >= minEntries){ // real fit
const Int_t fitMode = (histEntriesD >= minEntFull) ? fFitModeBins : 1111;
if(fitMode != fFitModeBins) {
fFitter->SetMean(fOldParams[0]); // need original parameters for fit!
fFitter->SetSigma(fOldParams[1]);
fFitter->SetBackgrExp(fOldParams[2]);
fFitter->SetBackgrSqr(fOldParams[3]);
fFitter->SetWcScale(fOldParams[4]);
this->Warning("FitSingle", "%s with %.1f (effective) entries: fit with mode 1111n",
hist->GetName(), histEntriesD);
}
Bool_t fitOK = fFitter->Fit(fitMode, hist, hWc);
if((!fitOK || fFitter->GetBackgrExp() < 0.) && fitMode != 1111){
if(!fitOK) this->Warning("FitSingle", "fit not OK, try mode 1111");
else {
this->Warning("FitSingle","U_exp = %.3f, fit with mode 1111",fFitter->GetBackgrExp());
}
fFitter->SetMean(fOldParams[0]); // need original parameters for next fit!
fFitter->SetSigma(fOldParams[1]);
fFitter->SetBackgrExp(fOldParams[2]);
fFitter->SetBackgrSqr(fOldParams[3]);
fFitter->SetWcScale(fOldParams[4]);
fitOK = fFitter->Fit(1111, hist, hWc);
}
if(fitOK){
result[0] = fFitter->GetNDstar();
result[1] = fFitter->GetNDstarErr();
result[2] = fFitter->GetSignalBack();
if(hWc) result[3] = fFitter->GetWcScale();
break;
}
}
this->Warning("FitSingle", "%s with %.1f (effective) entries not fitted:ncount signal "
"region and subtract background estimation!", hist->GetName(), histEntriesD);
case 1: // count signal region, but subtract background estimate (latter may be from hWc)
result = this->CountSignal(hist, hWc, kTRUE);
break;
case 2: // count signal region
result = this->CountSignal(hist, NULL, kFALSE);
break;
case 3: // count whole delta m
for(Int_t j = 1; j <= hist->GetNbinsX(); ++j){
result[0] += hist->GetBinContent(j);
result[1] += (hist->GetBinError(j) * hist->GetBinError(j));
}
result[1] = TMath::Sqrt(result[1]);
// result[0] = hist->Integral();
// Stat_t stats[11];
// hist->GetStats(stats);
// result[1] = TMath::Sqrt(stats[1]);
break;
case 4: // subtract the fit to scaled background in signal region
result = GFDstarCount::NDstarBackgrFuncSubtracted(hist, hWc, fStartDmSignal, fEndDmSignal,
fStartDmBackgr, fEndDmBackgr);
break;
case 5: // fit, subtract background function integral from counted signal (in 3-sigma)
if(fFitter->Fit(fFitModeBins, hist, hWc)){
const Int_t bin3SigmaL = hist->FindBin(fFitter->GetMean() - 3.* fFitter->GetSigma());
const Int_t bin3SigmaU = hist->FindBin(fFitter->GetMean() + 3.* fFitter->GetSigma());
result[0] = hist->Integral(bin3SigmaL, bin3SigmaU);
result[1] = (result[0] ? TMath::Sqrt(result[0])/result[0] : 0.); // relative error so far
TF1 backGr(*(fFitter->GetFittedBackgrFunc()));
Double_t subtract = backGr.Integral(hist->GetXaxis()->GetBinLowEdge(bin3SigmaL),
hist->GetXaxis()->GetBinUpEdge(bin3SigmaU));
subtract /= fFitter->GetHistBinSize();
result[0] -= subtract;
result[1] *= result[0]; // relative error of SR count
this->Warning("FitSingle", "flag 5: relative error from count of SR, only 1 try to fit");
result[2] = (subtract ? result[0]/subtract : 0.); // S/B
if(hWc) result[3] = fFitter->GetWcScale();
} else {
this->Warning("FitSingle", "flag 5: fit did not succeed");
}
break;
default:
this->Warning("FitSingle", "don't know fitOrNotFlag = %d", fFitOrNotFlag);
}
return result;
}
//__________________________________________________________________
TArrayD GFMultiDmFitter::CountSignal(TH1* hist, TH1* hWc, Bool_t subtractBack) const
{
// returning array of length 4: first 2 are number of D* in signal region and error
// - if hWc != NULL:
// subtract the entries in signal region (i.e. fStartDmSignal -> fEndDmSignal)
// from the signal region of 'hist'. Scale the number from WC hist like the ratio
// of entries in background region (fStartDmBackgr -> fEndDmBackgr).
// Assuming same binning for both hists!
// - if subtractBack == kTRUE && hWc == NULL:
// subtracts
// (mean bin content from fStartDmBackgr to fEndDmBackgr) times (number of signal bins)
// from number of entries in signal region (fStartDmSignal to fEndDmSignal)
// makes only sense for low statistics distributions with few entries
// in the background region (otherwise we get sometimes negative results)
// - if subtractBack == kFALSE && hWc == NULL:
// just integrate full signal region (i.e. fStartDmSignal -> fEndDmSignal
//
// third position of array is ratio signal/(subtracted background)
// (empty if subtractBack == kFALSE && hWc == NULL)
// fourth position is scale applied to hWc (empty if hWc == NULL)
TArrayD result(4);
if(!hist) return result;
const Int_t firstSignalBin = hist->FindBin(fStartDmSignal);
const Int_t lastSignalBin = hist->FindBin(fEndDmSignal);
const Double_t numSignal = hist->Integral(firstSignalBin, lastSignalBin);
const Int_t firstBackgrBin = hist->FindBin(fStartDmBackgr);
const Int_t lastBackgrBin = hist->FindBin(fEndDmBackgr);
if(hWc){
const Double_t numBackGr = hist->Integral(firstBackgrBin, lastBackgrBin);
const Double_t numBackGrWc = hWc->Integral(firstBackgrBin, lastBackgrBin);
const Double_t wcScale = (numBackGrWc ? numBackGr/numBackGrWc : 1.);
const Double_t numSignalWc = hWc->Integral(firstSignalBin, lastSignalBin);
result[0] = numSignal - numSignalWc * wcScale;
const Double_t variance = numSignal + 3. * numSignalWc * wcScale; // cf. logbook 18.4.2004
result[1] = (variance ? TMath::Sqrt(variance) : 0.);
result[2] = ((numSignalWc * wcScale) ? result[0]/(numSignalWc * wcScale) : 0.);
result[3] = wcScale;
} else if(subtractBack){
const Double_t numBackgr = hist->Integral(firstBackgrBin, lastBackgrBin);
const Double_t backGrWidth = (lastBackgrBin - firstBackgrBin + 1);//+1: num. of bins
const Double_t sigByBackWidth = (lastSignalBin - firstSignalBin + 1)/backGrWidth;
const Double_t backGr = numBackgr * sigByBackWidth;
result[0] = numSignal - backGr;
// result[1] = (result[0] > 0. ? TMath::Sqrt(result[0]) : 0.);
// sigma^2 = sigma_sig^2 + (sigByBackWidth * sigma_back)^2
result[1] = TMath::Sqrt(numSignal + numBackgr * sigByBackWidth*sigByBackWidth);
result[2] = (backGr ? result[0]/backGr : 0.);
} else {
result[0] = numSignal;
for(Int_t i = firstSignalBin; i <= lastSignalBin; ++i){
const Stat_t error = hist->GetBinError(i);
result[1] += (error * error);
}
result[1] = TMath::Sqrt(result[1]);
}
return result;
}
ROOT page - Class index - Top of the page
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.