1 /*************************************************************************
2 * Copyright(c) 1998-2009, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
16 ///////////////////////////////////////////////////////////////////////////
17 // Dielectron SignalFunc //
21 Dielectron signal extraction class using functions as input.
23 A function to describe the signal as well as one to describe the background
24 has to be deployed by the user. Alternatively on of the default implementaions
29 ///////////////////////////////////////////////////////////////////////////
36 #include <TPaveText.h>
38 #include <TFitResult.h>
39 //#include <../hist/hist/src/TF1Helper.h>
43 #include "AliDielectronSignalFunc.h"
45 ClassImp(AliDielectronSignalFunc)
47 TH1F* AliDielectronSignalFunc::fgHistSimPM=0x0;
49 AliDielectronSignalFunc::AliDielectronSignalFunc() :
50 AliDielectronSignalBase(),
62 // Default Constructor
67 //______________________________________________
68 AliDielectronSignalFunc::AliDielectronSignalFunc(const char* name, const char* title) :
69 AliDielectronSignalBase(name, title),
85 //______________________________________________
86 AliDielectronSignalFunc::~AliDielectronSignalFunc()
91 if(fFuncSignal) delete fFuncSignal;
92 if(fFuncBackground) delete fFuncBackground;
93 if(fFuncSigBack) delete fFuncSigBack;
97 //______________________________________________
98 void AliDielectronSignalFunc::Process(TObjArray * const arrhist)
101 // Fit the invariant mass histograms and retrieve the signal and background
105 ProcessFitIKF(arrhist);
121 AliError("Background substraction method not known!");
125 //______________________________________________
126 void AliDielectronSignalFunc::ProcessFitIKF(TObjArray * const arrhist) {
128 // Fit the +- invariant mass distribution only
132 const Double_t bigNumber = 100000.;
133 Double_t chi2ndfm1 = bigNumber;
134 Double_t ratiom1 = bigNumber;
135 Double_t chi2ndf = bigNumber;
140 fHistDataPM = (TH1F*)(arrhist->At(1))->Clone("histPM"); // +- SE
141 if(fRebin>1) fHistDataPM->Rebin(fRebin);
143 fgHistSimPM = (TH1F*)(arrhist->At(3))->Clone("histPMsim"); // +- mc shape
145 AliFatal("No mc peak shape found at idx 3.");
148 if(fRebin>1) fgHistSimPM->Rebin(fRebin);
150 // try out the polynomial degrees
151 for (Int_t iPD=0; iPD<=maxPolDeg; iPD++) {
152 TH1F *hf1 = (TH1F *) fHistDataPM->Clone(Form("hf1_PD%d",iPD));
154 FitOneMinv(hf1, fgHistSimPM, iPD);
155 if (fChi2Dof > 0) chi2ndf = fChi2Dof;
156 AliInfo(Form("nDP: %d, iPD: %d, chi2ndf: %f", nDP, iPD, chi2ndf));
158 ratiom1 = TMath::Abs(fChi2Dof - 1);
159 if (chi2ndfm1 > ratiom1) { // search for the closest to 1.
166 // fit again with the best polynomial degree
167 TH1F *h2 = (TH1F *) fHistDataPM->Clone(Form("h2_PD%d",nDP));
169 FitOneMinv(h2, fgHistSimPM, nDP);
170 AliInfo(Form("Best Fit: PD %d, chi^2/ndf %.3f, S/B %.3f",nDP,fChi2Dof,fValues(3)));
173 //______________________________________________
174 void AliDielectronSignalFunc::FitOneMinv(TH1F *hMinv, TH1F *hSim, Int_t pod) {
176 // main function to fit an inv mass spectrum
179 TObjArray *arrResults = new TObjArray;
180 arrResults->SetOwner();
181 arrResults->AddAt(hMinv,0);
183 // Degree of polynomial
186 // inclusion and exclusion areas (values)
187 const Double_t kJPMass = 3.096916;
188 // inclusion and exclusion areas (bin numbers)
189 const Int_t binIntLo = hMinv->FindBin(fIntMin);
190 const Int_t binIntHi = hMinv->FindBin(fIntMax);
191 // for error calculation
192 Double_t intAreaEdgeLo = hMinv->GetBinLowEdge(binIntLo);
193 Double_t intAreaEdgeHi = hMinv->GetBinLowEdge(binIntHi)+hMinv->GetBinWidth(binIntHi);
194 Double_t norm = (binIntHi-binIntLo)/(fIntMax - fIntMin);
196 TH1F *hBfit = (TH1F *) hMinv->Clone(); // for bg only fit (excluding peak region)
197 TH1F *hSigF = (TH1F *) hMinv->Clone(); // signal with subtracted bg
198 TH1F *hBgrd = (TH1F *) hMinv->Clone(); // bg histogram
204 // extract start parameter for the MC signal fit
205 Double_t bgvalAv = (hMinv->Integral(1,hMinv->GetNbinsX()+1) - hMinv->Integral(binIntLo,binIntHi)) / (hMinv->GetNbinsX()+1 - (binIntHi-binIntLo));
206 Double_t pkval = hMinv->GetBinContent(hMinv->FindBin(kJPMass)) - bgvalAv;
207 Double_t heightMC = hSim->GetBinContent(hSim->FindBin(kJPMass));
208 Double_t peakScale = (heightMC > 0. ? pkval/heightMC : 0.0);
210 Int_t nBgnd = 2 + fPolDeg; // degree + c1st oefficient + higher coefficients
211 Int_t nMinv = nBgnd + 1; // bgrd + peakscale
213 // Create the spectra without peak region
214 for (Int_t iBin = 0; iBin <= hMinv->GetNbinsX(); iBin++) {
215 if ((iBin < binIntLo) || (iBin > binIntHi)) {
216 hBfit->SetBinContent(iBin,hMinv->GetBinContent(iBin));
217 hBfit->SetBinError(iBin,hMinv->GetBinError(iBin));
225 // Do the fit to the background spectrum
226 TF1 *fBo = new TF1("bgrd_fit",BgndFun,fFitMin,fFitMax,nBgnd);
227 for (Int_t iPar=0; iPar<nBgnd; iPar++) {
228 if (iPar == 0) fBo->FixParameter(0, fPolDeg);
229 if (iPar == 1) fBo->SetParameter(iPar, bgvalAv);
230 if (iPar >= 2) fBo->SetParameter(iPar, 0.);
232 hBfit->Fit(fBo,"0qR");
233 //hBfit->SetNameTitle("bgrd_fit");
234 arrResults->AddAt(fBo,1);
240 // Fit the whole spectrum with peak and background
241 TF1 *fSB = new TF1("bgrd_peak_fit",MinvFun,fFitMin,fFitMax,nMinv);
242 fSB->FixParameter(0, fPolDeg);
243 fSB->SetParameter(1, peakScale);
244 // copy the polynomial parameters
245 for (Int_t iPar=0; iPar<=fPolDeg; iPar++)
246 fSB->SetParameter(2+iPar, fBo->GetParameter(iPar+1));
247 hMinv->Fit(fSB,"0qR");
248 arrResults->AddAt(fSB,2);
254 // Create the background function
255 TF1 *fB = new TF1("bgrdOnly_fkt",BgndFun,fFitMin,fFitMax,nBgnd);
256 fB->FixParameter(0,fPolDeg);
257 for (Int_t iDeg=0; iDeg<=fPolDeg; iDeg++) {
258 fB->SetParameter(1+iDeg,fSB->GetParameter(2+iDeg));
259 fB->SetParError(1+iDeg,fSB->GetParError(2+iDeg));
261 // create background histogram from background function
263 hBgrd->Fit(fB,"0qR");
264 // calculate the integral and integral error from fit function
265 Double_t intc = fB->Integral(intAreaEdgeLo, intAreaEdgeHi) * norm;
266 Double_t inte = fB->IntegralError(intAreaEdgeLo, intAreaEdgeHi) * norm;
267 arrResults->AddAt(fB,3);
269 // Fill the background spectrum erros. Use the error from the fit function for the background fB
270 for (Int_t iBin = 0; iBin <= hBgrd->GetNbinsX(); iBin++) {
271 Double_t x = hBgrd->GetBinCenter(iBin);
272 if ((x >= fFitMin) && (x <= fFitMax)) {
273 Double_t binte = inte / TMath::Sqrt((binIntHi-binIntLo)+1);
274 hBgrd->SetBinError(iBin,binte);
277 arrResults->AddAt(hBgrd,4);
282 // Subtract the background
283 hSigF->Add(hMinv,hBgrd,1.0,-1.0);
284 for (Int_t iBin = 0; iBin <= hSigF->GetNbinsX(); iBin++) {
285 Double_t x = hSigF->GetBinCenter(iBin);
286 if ((x < fFitMin) || (x > fFitMax)) {
287 hSigF->SetBinContent(iBin,0.0);
288 hSigF->SetBinError(iBin,0.0);
291 hSigF->SetNameTitle("peak_only","");
292 arrResults->AddAt(hSigF,5);
297 // Fit the background-subtracted spectrum
298 TF1 *fS = new TF1("peakOnly_fit",PeakFunCB,fFitMin,fFitMax,5);
299 fS->SetParameters(-.05,1,kJPMass,.003,700);
300 fS->SetParNames("alpha","n","meanx","sigma","N");
301 hSigF->Fit(fS,"0qR");
302 arrResults->AddAt(fS,6);
305 // connect data members
306 fFuncSignal = (TF1*) arrResults->At(6)->Clone();
307 fFuncBackground = (TF1*) arrResults->At(3)->Clone();
308 fFuncSigBack = (TF1*) arrResults->At(2)->Clone();
309 fHistSignal = (TH1F*)arrResults->At(5)->Clone();
310 fHistBackground = (TH1F*)arrResults->At(4)->Clone();
313 Double_t chi2 = fSB->GetChisquare();
314 Int_t ndf = fSB->GetNDF();
317 // signal + signal error
318 fValues(0) = hSigF->IntegralAndError(binIntLo, binIntHi, fErrors(0));
319 fValues(1) = intc; // background
320 fErrors(1) = inte; // background error
321 // S/B (2) and significance (3)
322 SetSignificanceAndSOB();
323 fValues(4) = fS->GetParameter(2); // mass
324 fErrors(4) = fS->GetParError(2); // mass error
325 fValues(5) = fS->GetParameter(3); // mass wdth
326 fErrors(5) = fS->GetParError(3); // mass wdth error
332 //______________________________________________________________________________
333 Double_t AliDielectronSignalFunc::BgndFun(const Double_t *x, const Double_t *par) {
335 // [0]: degree of polynomial
336 // [1]: constant polynomial coefficient
337 // [2]..: higher polynomial coefficients
339 Int_t deg = ((Int_t) par[0]);
345 for (Int_t i = 0; i <= deg; i++) {
353 //______________________________________________________________________________
354 Double_t AliDielectronSignalFunc::PeakFun(const Double_t *x, const Double_t *par) {
355 // Fit MC signal shape
357 // [0]: scale for simpeak
361 TH1F *hPeak = fgHistSimPM;
363 printf("F-AliDielectronSignalFunc::PeakFun: No histogram for peak fit defined!\n");
366 Int_t idx = hPeak->FindBin(xx);
368 (idx >= hPeak->GetNbinsX())) {
372 return (par[0] * hPeak->GetBinContent(idx));
376 //______________________________________________________________________________
377 Double_t AliDielectronSignalFunc::MinvFun(const Double_t *x, const Double_t *par) {
379 // [0]: degree of polynomial -> [0] for BgndFun
380 // [1]: scale for simpeak -> [0] for PeakFun
381 // [2]: constant polynomial coefficient -> [1] for BgndFun
382 // [3]..: higher polynomial coefficients -> [2].. for BgndFun
384 Int_t deg = ((Int_t) par[0]);
385 Double_t parPK[25], parBG[25];
387 parBG[0] = par[0]; // degree of polynomial
389 parPK[0] = par[1]; // MC minv scale
390 for (Int_t i = 0; i <= deg; i++) parBG[i+1] = par[i+2]; // polynomial coefficients
392 Double_t peak = PeakFun(x,parPK);
393 Double_t bgnd = BgndFun(x,parBG);
394 Double_t f = peak + bgnd;
399 //______________________________________________________________________________
400 Double_t AliDielectronSignalFunc::PeakFunCB(const Double_t *x, const Double_t *par) {
401 // Crystal Ball function fit
403 Double_t alpha = par[0];
405 Double_t meanx = par[2];
406 Double_t sigma = par[3];
407 Double_t nn = par[4];
409 Double_t a = TMath::Power((n/TMath::Abs(alpha)), n) * TMath::Exp(-.5*alpha*alpha);
410 Double_t b = n/TMath::Abs(alpha) - TMath::Abs(alpha);
412 Double_t arg = (x[0] - meanx)/sigma;
415 if (arg > -1.*alpha) {
416 fitval = nn * TMath::Exp(-.5*arg*arg);
418 fitval = nn * a * TMath::Power((b-arg), (-1*n));
425 //______________________________________________
426 void AliDielectronSignalFunc::ProcessFit(TObjArray * const arrhist) {
428 // Fit the +- invariant mass distribution only
429 // Here we assume that the combined fit function is a sum of the signal and background functions
430 // and that the signal function is always the first term of this sum
433 fHistDataPM = (TH1F*)(arrhist->At(1))->Clone("histPM"); // +- SE
434 fHistDataPM->Sumw2();
436 fHistDataPM->Rebin(fRebin);
438 fHistSignal = new TH1F("HistSignal", "Fit substracted signal",
439 fHistDataPM->GetXaxis()->GetNbins(),
440 fHistDataPM->GetXaxis()->GetXmin(), fHistDataPM->GetXaxis()->GetXmax());
441 fHistBackground = new TH1F("HistBackground", "Fit contribution",
442 fHistDataPM->GetXaxis()->GetNbins(),
443 fHistDataPM->GetXaxis()->GetXmin(), fHistDataPM->GetXaxis()->GetXmax());
445 // the starting parameters of the fit function and their limits can be tuned
446 // by the user in its macro
447 fHistDataPM->Fit(fFuncSigBack, fFitOpt.Data(), "", fFitMin, fFitMax);
448 TFitResultPtr pmFitPtr = fHistDataPM->Fit(fFuncSigBack, fFitOpt.Data(), "", fFitMin, fFitMax);
449 //TFitResult *pmFitResult = pmFitPtr.Get(); // used only with TF1Helper
450 fFuncSignal->SetParameters(fFuncSigBack->GetParameters());
451 fFuncBackground->SetParameters(fFuncSigBack->GetParameters()+fFuncSignal->GetNpar());
453 for(Int_t iBin=1; iBin<=fHistDataPM->GetXaxis()->GetNbins(); iBin++) {
454 Double_t m = fHistDataPM->GetBinCenter(iBin);
455 Double_t pm = fHistDataPM->GetBinContent(iBin);
456 Double_t epm = fHistDataPM->GetBinError(iBin);
457 Double_t bknd = fFuncBackground->Eval(m);
459 for(Int_t iPar=fFuncSignal->GetNpar(); iPar<fFuncSigBack->GetNpar(); iPar++) {
460 /* TF1Helper problem on alien compilation
461 for(Int_t jPar=iPar; jPar<fFuncSigBack->GetNpar(); jPar++) {
462 TF1 gradientIpar("gradientIpar",
463 ROOT::TF1Helper::TGradientParFunction(iPar-fFuncSignal->GetNpar(),fFuncBackground),0,0,0);
464 TF1 gradientJpar("gradientJpar",
465 ROOT::TF1Helper::TGradientParFunction(jPar-fFuncSignal->GetNpar(),fFuncBackground),0,0,0);
466 ebknd += pmFitResult->CovMatrix(iPar,jPar)*
467 gradientIpar.Eval(m)*gradientJpar.Eval(m)*
468 (iPar==jPar ? 1.0 : 2.0);
472 Double_t signal = pm-bknd;
473 Double_t error = TMath::Sqrt(epm*epm+ebknd);
474 fHistSignal->SetBinContent(iBin, signal);
475 fHistSignal->SetBinError(iBin, error);
476 fHistBackground->SetBinContent(iBin, bknd);
477 fHistBackground->SetBinError(iBin, TMath::Sqrt(ebknd));
482 fValues(0) = fFuncSignal->Integral(fIntMin, fIntMax)/fHistDataPM->GetBinWidth(1);
484 for(Int_t iPar=0; iPar<fFuncSignal->GetNpar(); iPar++) {
485 /* TF1Helper problem on alien compilation
486 for(Int_t jPar=iPar; jPar<fFuncSignal->GetNpar(); jPar++) {
487 TF1 gradientIpar("gradientIpar",
488 ROOT::TF1Helper::TGradientParFunction(iPar,fFuncSignal),0,0,0);
489 TF1 gradientJpar("gradientJpar",
490 ROOT::TF1Helper::TGradientParFunction(jPar,fFuncSignal),0,0,0);
491 fErrors(0) += pmFitResult->CovMatrix(iPar,jPar)*
492 gradientIpar.Integral(fIntMin,fIntMax)*gradientJpar.Integral(fIntMin,fIntMax)*
493 (iPar==jPar ? 1.0 : 2.0);
498 fValues(1) = fFuncBackground->Integral(fIntMin, fIntMax)/fHistDataPM->GetBinWidth(1);
500 for(Int_t iPar=fFuncSignal->GetNpar(); iPar<fFuncSigBack->GetNpar(); iPar++) {
501 /* TF1Helper problem on alien compilation
502 for(Int_t jPar=iPar; jPar<fFuncSigBack->GetNpar(); jPar++) {
503 TF1 gradientIpar("gradientIpar",
504 ROOT::TF1Helper::TGradientParFunction(iPar-fFuncSignal->GetNpar(),fFuncBackground),0,0,0);
505 TF1 gradientJpar("gradientJpar",
506 ROOT::TF1Helper::TGradientParFunction(jPar-fFuncSignal->GetNpar(),fFuncBackground),0,0,0);
507 fErrors(1) += pmFitResult->CovMatrix(iPar,jPar)*
508 gradientIpar.Integral(fIntMin, fIntMax)*gradientJpar.Integral(fIntMin, fIntMax)*
509 (iPar==jPar ? 1.0 : 2.0);
516 fValues(0) = fHistSignal->IntegralAndError(fHistSignal->FindBin(fIntMin),
517 fHistSignal->FindBin(fIntMax), fErrors(0));
519 fValues(1) = fHistBackground->IntegralAndError(fHistBackground->FindBin(fIntMin),
520 fHistBackground->FindBin(fIntMax),
523 // S/B and significance
524 SetSignificanceAndSOB();
525 fValues(4) = fFuncSigBack->GetParameter(fParMass);
526 fErrors(4) = fFuncSigBack->GetParError(fParMass);
527 fValues(5) = fFuncSigBack->GetParameter(fParMassWidth);
528 fErrors(5) = fFuncSigBack->GetParError(fParMassWidth);
533 //______________________________________________
534 void AliDielectronSignalFunc::ProcessLS(TObjArray * const arrhist) {
536 // Substract background using the like-sign spectrum
538 fHistDataPP = (TH1F*)(arrhist->At(0))->Clone("histPP"); // ++ SE
539 fHistDataPM = (TH1F*)(arrhist->At(1))->Clone("histPM"); // +- SE
540 fHistDataMM = (TH1F*)(arrhist->At(2))->Clone("histMM"); // -- SE
542 fHistDataPP->Rebin(fRebin);
543 fHistDataPM->Rebin(fRebin);
544 fHistDataMM->Rebin(fRebin);
546 fHistDataPP->Sumw2();
547 fHistDataPM->Sumw2();
548 fHistDataMM->Sumw2();
550 fHistSignal = new TH1F("HistSignal", "Like-Sign substracted signal",
551 fHistDataPM->GetXaxis()->GetNbins(),
552 fHistDataPM->GetXaxis()->GetXmin(), fHistDataPM->GetXaxis()->GetXmax());
553 fHistBackground = new TH1F("HistBackground", "Like-sign contribution",
554 fHistDataPM->GetXaxis()->GetNbins(),
555 fHistDataPM->GetXaxis()->GetXmin(), fHistDataPM->GetXaxis()->GetXmax());
557 // fit the +- mass distribution
558 fHistDataPM->Fit(fFuncSigBack, fFitOpt.Data(), "", fFitMin, fFitMax);
559 fHistDataPM->Fit(fFuncSigBack, fFitOpt.Data(), "", fFitMin, fFitMax);
560 // declare the variables where the like-sign fit results will be stored
561 // TFitResult *ppFitResult = 0x0;
562 // TFitResult *mmFitResult = 0x0;
563 // fit the like sign background
564 TF1 *funcClonePP = (TF1*)fFuncBackground->Clone("funcClonePP");
565 TF1 *funcCloneMM = (TF1*)fFuncBackground->Clone("funcCloneMM");
566 fHistDataPP->Fit(funcClonePP, fFitOpt.Data(), "", fFitMin, fFitMax);
567 fHistDataPP->Fit(funcClonePP, fFitOpt.Data(), "", fFitMin, fFitMax);
568 // TFitResultPtr ppFitPtr = fHistDataPP->Fit(funcClonePP, fFitOpt.Data(), "", fFitMin, fFitMax);
569 // ppFitResult = ppFitPtr.Get();
570 fHistDataMM->Fit(funcCloneMM, fFitOpt.Data(), "", fFitMin, fFitMax);
571 fHistDataMM->Fit(funcCloneMM, fFitOpt.Data(), "", fFitMin, fFitMax);
572 // TFitResultPtr mmFitPtr = fHistDataMM->Fit(funcCloneMM, fFitOpt.Data(), "", fFitMin, fFitMax);
573 // mmFitResult = mmFitPtr.Get();
575 for(Int_t iBin=1; iBin<=fHistDataPM->GetXaxis()->GetNbins(); iBin++) {
576 Double_t m = fHistDataPM->GetBinCenter(iBin);
577 Double_t pm = fHistDataPM->GetBinContent(iBin);
578 Double_t pp = funcClonePP->Eval(m);
579 Double_t mm = funcCloneMM->Eval(m);
580 Double_t epm = fHistDataPM->GetBinError(iBin);
582 for(Int_t iPar=0; iPar<funcClonePP->GetNpar(); iPar++) {
583 /* TF1Helper problem on alien compilation
584 for(Int_t jPar=iPar; jPar<funcClonePP->GetNpar(); jPar++) {
585 TF1 gradientIpar("gradientIpar",
586 ROOT::TF1Helper::TGradientParFunction(iPar,funcClonePP),0,0,0);
587 TF1 gradientJpar("gradientJpar",
588 ROOT::TF1Helper::TGradientParFunction(jPar,funcClonePP),0,0,0);
589 epp += ppFitResult->CovMatrix(iPar,jPar)*
590 gradientIpar.Eval(m)*gradientJpar.Eval(m)*
591 (iPar==jPar ? 1.0 : 2.0);
596 for(Int_t iPar=0; iPar<funcCloneMM->GetNpar(); iPar++) {
597 /* TF1Helper problem on alien compilation
598 for(Int_t jPar=iPar; jPar<funcCloneMM->GetNpar(); jPar++) {
599 TF1 gradientIpar("gradientIpar",
600 ROOT::TF1Helper::TGradientParFunction(iPar,funcCloneMM),0,0,0);
601 TF1 gradientJpar("gradientJpar",
602 ROOT::TF1Helper::TGradientParFunction(jPar,funcCloneMM),0,0,0);
603 emm += mmFitResult->CovMatrix(iPar,jPar)*
604 gradientIpar.Eval(m)*gradientJpar.Eval(m)*
605 (iPar==jPar ? 1.0 : 2.0);
610 Double_t signal = pm-2.0*TMath::Sqrt(pp*mm);
611 Double_t background = 2.0*TMath::Sqrt(pp*mm);
612 // error propagation on the signal calculation above
613 Double_t esignal = TMath::Sqrt(epm*epm+(mm/pp)*epp+(pp/mm)*emm);
614 Double_t ebackground = TMath::Sqrt((mm/pp)*epp+(pp/mm)*emm);
615 fHistSignal->SetBinContent(iBin, signal);
616 fHistSignal->SetBinError(iBin, esignal);
617 fHistBackground->SetBinContent(iBin, background);
618 fHistBackground->SetBinError(iBin, ebackground);
622 fValues(0) = fHistSignal->IntegralAndError(fHistSignal->FindBin(fIntMin),
623 fHistSignal->FindBin(fIntMax), fErrors(0));
625 fValues(1) = fHistBackground->IntegralAndError(fHistBackground->FindBin(fIntMin),
626 fHistBackground->FindBin(fIntMax),
628 // S/B and significance
629 SetSignificanceAndSOB();
630 fValues(4) = fFuncSigBack->GetParameter(fParMass);
631 fErrors(4) = fFuncSigBack->GetParError(fParMass);
632 fValues(5) = fFuncSigBack->GetParameter(fParMassWidth);
633 fErrors(5) = fFuncSigBack->GetParError(fParMassWidth);
638 //______________________________________________
639 void AliDielectronSignalFunc::ProcessEM(TObjArray * const arrhist) {
641 // Substract background with the event mixing technique
643 arrhist->GetEntries(); // just to avoid the unused parameter warning
644 AliError("Event mixing for background substraction method not implemented!");
647 //______________________________________________
648 void AliDielectronSignalFunc::SetFunctions(TF1 * const combined, TF1 * const sig, TF1 * const back,
649 Int_t parM, Int_t parMres)
652 // Set the signal, background functions and combined fit function
653 // Note: The process method assumes that the first n parameters in the
654 // combined fit function correspond to the n parameters of the signal function
655 // and the n+1 to n+m parameters to the m parameters of the background function!!!
657 if (!sig||!back||!combined) {
658 AliError("Both, signal and background function need to be set!");
662 fFuncBackground=back;
663 fFuncSigBack=combined;
665 fParMassWidth=parMres;
668 //______________________________________________
669 void AliDielectronSignalFunc::SetDefaults(Int_t type)
672 // Setup some default functions:
673 // type = 0: gaus signal + linear background in 2.5 - 4 GeV inv. mass
674 // type = 1: gaus signal + exponential background in 2.5 - 4 GeV inv. mass
675 // type = 2: half gaussian, half exponential signal function
676 // type = 3: Crystal-Ball function
677 // type = 4: Crystal-Ball signal + exponential background
681 fFuncSignal=new TF1("DieleSignal","gaus",2.5,4);
682 fFuncBackground=new TF1("DieleBackground","pol1",2.5,4);
683 fFuncSigBack=new TF1("DieleCombined","gaus+pol1(3)",2.5,4);
685 fFuncSigBack->SetParameters(1,3.1,.05,2.5,1);
686 fFuncSigBack->SetParLimits(0,0,10000000);
687 fFuncSigBack->SetParLimits(1,3.05,3.15);
688 fFuncSigBack->SetParLimits(2,.02,.1);
691 fFuncSignal=new TF1("DieleSignal","gaus",2.5,4);
692 fFuncBackground=new TF1("DieleBackground","[0]*exp(-(x-[1])/[2])",2.5,4);
693 fFuncSigBack=new TF1("DieleCombined","gaus+[3]*exp(-(x-[4])/[5])",2.5,4);
695 fFuncSigBack->SetParameters(1,3.1,.05,1,2.5,1);
696 fFuncSigBack->SetParLimits(0,0,10000000);
697 fFuncSigBack->SetParLimits(1,3.05,3.15);
698 fFuncSigBack->SetParLimits(2,.02,.1);
701 // half gaussian, half exponential signal function
702 // exponential background
703 fFuncSignal = new TF1("DieleSignal","(x<[1])*([0]*(exp(-0.5*((x-[1])/[2])^2)+exp((x-[1])/[3])*(1-exp(-0.5*((x-[1])/[2])^2))))+(x>=[1])*([0]*exp(-0.5*((x-[1])/[2])^2))",2.5,4);
704 fFuncBackground = new TF1("DieleBackground","[0]*exp(-(x-[1])/[2])+[3]",2.5,4);
705 fFuncSigBack = new TF1("DieleCombined","(x<[1])*([0]*(exp(-0.5*((x-[1])/[2])^2)+exp((x-[1])/[3])*(1-exp(-0.5*((x-[1])/[2])^2))))+(x>=[1])*([0]*exp(-0.5*((x-[1])/[2])^2))+[4]*exp(-(x-[5])/[6])+[7]",2.5,4);
706 fFuncSigBack->SetParameters(1.,3.1,.05,.1,1,2.5,1,0);
708 fFuncSigBack->SetParLimits(0,0,10000000);
709 fFuncSigBack->SetParLimits(1,3.05,3.15);
710 fFuncSigBack->SetParLimits(2,.02,.1);
711 fFuncSigBack->FixParameter(6,2.5);
712 fFuncSigBack->FixParameter(7,0);
717 //______________________________________________
718 void AliDielectronSignalFunc::Draw(const Option_t* option)
721 // Draw the fitted function
724 TString drawOpt(option);
727 Bool_t optStat=drawOpt.Contains("stat");
729 fFuncSigBack->SetNpx(200);
730 fFuncSigBack->SetRange(fIntMin,fIntMax);
731 fFuncBackground->SetNpx(200);
732 fFuncBackground->SetRange(fIntMin,fIntMax);
734 TGraph *grSig=new TGraph(fFuncSigBack);
735 grSig->SetFillColor(kGreen);
736 grSig->SetFillStyle(3001);
738 TGraph *grBack=new TGraph(fFuncBackground);
739 grBack->SetFillColor(kRed);
740 grBack->SetFillStyle(3001);
742 grSig->SetPoint(0,grBack->GetX()[0],grBack->GetY()[0]);
743 grSig->SetPoint(grSig->GetN()-1,grBack->GetX()[grBack->GetN()-1],grBack->GetY()[grBack->GetN()-1]);
745 grBack->SetPoint(0,grBack->GetX()[0],0.);
746 grBack->SetPoint(grBack->GetN()-1,grBack->GetX()[grBack->GetN()-1],0.);
748 fFuncSigBack->SetRange(fFitMin,fFitMax);
749 fFuncBackground->SetRange(fFitMin,fFitMax);
751 if (!drawOpt.Contains("same")){
761 if(fMethod==kFitted || fMethod==kFittedMC) grBack->Draw("f");
762 fFuncSigBack->Draw("same");
763 fFuncSigBack->SetLineWidth(2);
764 if(fMethod==kLikeSign) {
765 fHistDataPP->SetLineWidth(2);
766 fHistDataPP->SetLineColor(6);
767 fHistDataPP->Draw("same");
768 fHistDataMM->SetLineWidth(2);
769 fHistDataMM->SetLineColor(8);
770 fHistDataMM->Draw("same");
773 if(fMethod==kFitted || fMethod==kFittedMC)
774 fFuncBackground->Draw("same");
776 if (optStat) DrawStats();