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("E-AliDielectronSignalFunc::PeakFun: No histogram for peak fit defined!\n");
367 Int_t idx = hPeak->FindBin(xx);
369 (idx >= hPeak->GetNbinsX())) {
373 return (par[0] * hPeak->GetBinContent(idx));
377 //______________________________________________________________________________
378 Double_t AliDielectronSignalFunc::MinvFun(const Double_t *x, const Double_t *par) {
380 // [0]: degree of polynomial -> [0] for BgndFun
381 // [1]: scale for simpeak -> [0] for PeakFun
382 // [2]: constant polynomial coefficient -> [1] for BgndFun
383 // [3]..: higher polynomial coefficients -> [2].. for BgndFun
385 Int_t deg = ((Int_t) par[0]);
386 Double_t parPK[25], parBG[25];
388 parBG[0] = par[0]; // degree of polynomial
390 parPK[0] = par[1]; // MC minv scale
391 for (Int_t i = 0; i <= deg; i++) parBG[i+1] = par[i+2]; // polynomial coefficients
393 Double_t peak = PeakFun(x,parPK);
394 Double_t bgnd = BgndFun(x,parBG);
395 Double_t f = peak + bgnd;
400 //______________________________________________________________________________
401 Double_t AliDielectronSignalFunc::PeakFunCB(const Double_t *x, const Double_t *par) {
402 // Crystal Ball function fit
404 Double_t alpha = par[0];
406 Double_t meanx = par[2];
407 Double_t sigma = par[3];
408 Double_t nn = par[4];
410 Double_t a = TMath::Power((n/TMath::Abs(alpha)), n) * TMath::Exp(-.5*alpha*alpha);
411 Double_t b = n/TMath::Abs(alpha) - TMath::Abs(alpha);
413 Double_t arg = (x[0] - meanx)/sigma;
416 if (arg > -1.*alpha) {
417 fitval = nn * TMath::Exp(-.5*arg*arg);
419 fitval = nn * a * TMath::Power((b-arg), (-1*n));
426 //______________________________________________
427 void AliDielectronSignalFunc::ProcessFit(TObjArray * const arrhist) {
429 // Fit the +- invariant mass distribution only
430 // Here we assume that the combined fit function is a sum of the signal and background functions
431 // and that the signal function is always the first term of this sum
434 fHistDataPM = (TH1F*)(arrhist->At(1))->Clone("histPM"); // +- SE
435 fHistDataPM->Sumw2();
437 fHistDataPM->Rebin(fRebin);
439 fHistSignal = new TH1F("HistSignal", "Fit substracted signal",
440 fHistDataPM->GetXaxis()->GetNbins(),
441 fHistDataPM->GetXaxis()->GetXmin(), fHistDataPM->GetXaxis()->GetXmax());
442 fHistBackground = new TH1F("HistBackground", "Fit contribution",
443 fHistDataPM->GetXaxis()->GetNbins(),
444 fHistDataPM->GetXaxis()->GetXmin(), fHistDataPM->GetXaxis()->GetXmax());
446 // the starting parameters of the fit function and their limits can be tuned
447 // by the user in its macro
448 fHistDataPM->Fit(fFuncSigBack, fFitOpt.Data(), "", fFitMin, fFitMax);
449 TFitResultPtr pmFitPtr = fHistDataPM->Fit(fFuncSigBack, fFitOpt.Data(), "", fFitMin, fFitMax);
450 //TFitResult *pmFitResult = pmFitPtr.Get(); // used only with TF1Helper
451 fFuncSignal->SetParameters(fFuncSigBack->GetParameters());
452 fFuncBackground->SetParameters(fFuncSigBack->GetParameters()+fFuncSignal->GetNpar());
454 for(Int_t iBin=1; iBin<=fHistDataPM->GetXaxis()->GetNbins(); iBin++) {
455 Double_t m = fHistDataPM->GetBinCenter(iBin);
456 Double_t pm = fHistDataPM->GetBinContent(iBin);
457 Double_t epm = fHistDataPM->GetBinError(iBin);
458 Double_t bknd = fFuncBackground->Eval(m);
460 for(Int_t iPar=fFuncSignal->GetNpar(); iPar<fFuncSigBack->GetNpar(); iPar++) {
461 /* TF1Helper problem on alien compilation
462 for(Int_t jPar=iPar; jPar<fFuncSigBack->GetNpar(); jPar++) {
463 TF1 gradientIpar("gradientIpar",
464 ROOT::TF1Helper::TGradientParFunction(iPar-fFuncSignal->GetNpar(),fFuncBackground),0,0,0);
465 TF1 gradientJpar("gradientJpar",
466 ROOT::TF1Helper::TGradientParFunction(jPar-fFuncSignal->GetNpar(),fFuncBackground),0,0,0);
467 ebknd += pmFitResult->CovMatrix(iPar,jPar)*
468 gradientIpar.Eval(m)*gradientJpar.Eval(m)*
469 (iPar==jPar ? 1.0 : 2.0);
473 Double_t signal = pm-bknd;
474 Double_t error = TMath::Sqrt(epm*epm+ebknd);
475 fHistSignal->SetBinContent(iBin, signal);
476 fHistSignal->SetBinError(iBin, error);
477 fHistBackground->SetBinContent(iBin, bknd);
478 fHistBackground->SetBinError(iBin, TMath::Sqrt(ebknd));
483 fValues(0) = fFuncSignal->Integral(fIntMin, fIntMax)/fHistDataPM->GetBinWidth(1);
485 for(Int_t iPar=0; iPar<fFuncSignal->GetNpar(); iPar++) {
486 /* TF1Helper problem on alien compilation
487 for(Int_t jPar=iPar; jPar<fFuncSignal->GetNpar(); jPar++) {
488 TF1 gradientIpar("gradientIpar",
489 ROOT::TF1Helper::TGradientParFunction(iPar,fFuncSignal),0,0,0);
490 TF1 gradientJpar("gradientJpar",
491 ROOT::TF1Helper::TGradientParFunction(jPar,fFuncSignal),0,0,0);
492 fErrors(0) += pmFitResult->CovMatrix(iPar,jPar)*
493 gradientIpar.Integral(fIntMin,fIntMax)*gradientJpar.Integral(fIntMin,fIntMax)*
494 (iPar==jPar ? 1.0 : 2.0);
499 fValues(1) = fFuncBackground->Integral(fIntMin, fIntMax)/fHistDataPM->GetBinWidth(1);
501 for(Int_t iPar=fFuncSignal->GetNpar(); iPar<fFuncSigBack->GetNpar(); iPar++) {
502 /* TF1Helper problem on alien compilation
503 for(Int_t jPar=iPar; jPar<fFuncSigBack->GetNpar(); jPar++) {
504 TF1 gradientIpar("gradientIpar",
505 ROOT::TF1Helper::TGradientParFunction(iPar-fFuncSignal->GetNpar(),fFuncBackground),0,0,0);
506 TF1 gradientJpar("gradientJpar",
507 ROOT::TF1Helper::TGradientParFunction(jPar-fFuncSignal->GetNpar(),fFuncBackground),0,0,0);
508 fErrors(1) += pmFitResult->CovMatrix(iPar,jPar)*
509 gradientIpar.Integral(fIntMin, fIntMax)*gradientJpar.Integral(fIntMin, fIntMax)*
510 (iPar==jPar ? 1.0 : 2.0);
517 fValues(0) = fHistSignal->IntegralAndError(fHistSignal->FindBin(fIntMin),
518 fHistSignal->FindBin(fIntMax), fErrors(0));
520 fValues(1) = fHistBackground->IntegralAndError(fHistBackground->FindBin(fIntMin),
521 fHistBackground->FindBin(fIntMax),
524 // S/B and significance
525 SetSignificanceAndSOB();
526 fValues(4) = fFuncSigBack->GetParameter(fParMass);
527 fErrors(4) = fFuncSigBack->GetParError(fParMass);
528 fValues(5) = fFuncSigBack->GetParameter(fParMassWidth);
529 fErrors(5) = fFuncSigBack->GetParError(fParMassWidth);
534 //______________________________________________
535 void AliDielectronSignalFunc::ProcessLS(TObjArray * const arrhist) {
537 // Substract background using the like-sign spectrum
539 fHistDataPP = (TH1F*)(arrhist->At(0))->Clone("histPP"); // ++ SE
540 fHistDataPM = (TH1F*)(arrhist->At(1))->Clone("histPM"); // +- SE
541 fHistDataMM = (TH1F*)(arrhist->At(2))->Clone("histMM"); // -- SE
543 fHistDataPP->Rebin(fRebin);
544 fHistDataPM->Rebin(fRebin);
545 fHistDataMM->Rebin(fRebin);
547 fHistDataPP->Sumw2();
548 fHistDataPM->Sumw2();
549 fHistDataMM->Sumw2();
551 fHistSignal = new TH1F("HistSignal", "Like-Sign substracted signal",
552 fHistDataPM->GetXaxis()->GetNbins(),
553 fHistDataPM->GetXaxis()->GetXmin(), fHistDataPM->GetXaxis()->GetXmax());
554 fHistBackground = new TH1F("HistBackground", "Like-sign contribution",
555 fHistDataPM->GetXaxis()->GetNbins(),
556 fHistDataPM->GetXaxis()->GetXmin(), fHistDataPM->GetXaxis()->GetXmax());
558 // fit the +- mass distribution
559 fHistDataPM->Fit(fFuncSigBack, fFitOpt.Data(), "", fFitMin, fFitMax);
560 fHistDataPM->Fit(fFuncSigBack, fFitOpt.Data(), "", fFitMin, fFitMax);
561 // declare the variables where the like-sign fit results will be stored
562 // TFitResult *ppFitResult = 0x0;
563 // TFitResult *mmFitResult = 0x0;
564 // fit the like sign background
565 TF1 *funcClonePP = (TF1*)fFuncBackground->Clone("funcClonePP");
566 TF1 *funcCloneMM = (TF1*)fFuncBackground->Clone("funcCloneMM");
567 fHistDataPP->Fit(funcClonePP, fFitOpt.Data(), "", fFitMin, fFitMax);
568 fHistDataPP->Fit(funcClonePP, fFitOpt.Data(), "", fFitMin, fFitMax);
569 // TFitResultPtr ppFitPtr = fHistDataPP->Fit(funcClonePP, fFitOpt.Data(), "", fFitMin, fFitMax);
570 // ppFitResult = ppFitPtr.Get();
571 fHistDataMM->Fit(funcCloneMM, fFitOpt.Data(), "", fFitMin, fFitMax);
572 fHistDataMM->Fit(funcCloneMM, fFitOpt.Data(), "", fFitMin, fFitMax);
573 // TFitResultPtr mmFitPtr = fHistDataMM->Fit(funcCloneMM, fFitOpt.Data(), "", fFitMin, fFitMax);
574 // mmFitResult = mmFitPtr.Get();
576 for(Int_t iBin=1; iBin<=fHistDataPM->GetXaxis()->GetNbins(); iBin++) {
577 Double_t m = fHistDataPM->GetBinCenter(iBin);
578 Double_t pm = fHistDataPM->GetBinContent(iBin);
579 Double_t pp = funcClonePP->Eval(m);
580 Double_t mm = funcCloneMM->Eval(m);
581 Double_t epm = fHistDataPM->GetBinError(iBin);
583 for(Int_t iPar=0; iPar<funcClonePP->GetNpar(); iPar++) {
584 /* TF1Helper problem on alien compilation
585 for(Int_t jPar=iPar; jPar<funcClonePP->GetNpar(); jPar++) {
586 TF1 gradientIpar("gradientIpar",
587 ROOT::TF1Helper::TGradientParFunction(iPar,funcClonePP),0,0,0);
588 TF1 gradientJpar("gradientJpar",
589 ROOT::TF1Helper::TGradientParFunction(jPar,funcClonePP),0,0,0);
590 epp += ppFitResult->CovMatrix(iPar,jPar)*
591 gradientIpar.Eval(m)*gradientJpar.Eval(m)*
592 (iPar==jPar ? 1.0 : 2.0);
597 for(Int_t iPar=0; iPar<funcCloneMM->GetNpar(); iPar++) {
598 /* TF1Helper problem on alien compilation
599 for(Int_t jPar=iPar; jPar<funcCloneMM->GetNpar(); jPar++) {
600 TF1 gradientIpar("gradientIpar",
601 ROOT::TF1Helper::TGradientParFunction(iPar,funcCloneMM),0,0,0);
602 TF1 gradientJpar("gradientJpar",
603 ROOT::TF1Helper::TGradientParFunction(jPar,funcCloneMM),0,0,0);
604 emm += mmFitResult->CovMatrix(iPar,jPar)*
605 gradientIpar.Eval(m)*gradientJpar.Eval(m)*
606 (iPar==jPar ? 1.0 : 2.0);
611 Double_t signal = pm-2.0*TMath::Sqrt(pp*mm);
612 Double_t background = 2.0*TMath::Sqrt(pp*mm);
613 // error propagation on the signal calculation above
614 Double_t esignal = TMath::Sqrt(epm*epm+(mm/pp)*epp+(pp/mm)*emm);
615 Double_t ebackground = TMath::Sqrt((mm/pp)*epp+(pp/mm)*emm);
616 fHistSignal->SetBinContent(iBin, signal);
617 fHistSignal->SetBinError(iBin, esignal);
618 fHistBackground->SetBinContent(iBin, background);
619 fHistBackground->SetBinError(iBin, ebackground);
623 fValues(0) = fHistSignal->IntegralAndError(fHistSignal->FindBin(fIntMin),
624 fHistSignal->FindBin(fIntMax), fErrors(0));
626 fValues(1) = fHistBackground->IntegralAndError(fHistBackground->FindBin(fIntMin),
627 fHistBackground->FindBin(fIntMax),
629 // S/B and significance
630 SetSignificanceAndSOB();
631 fValues(4) = fFuncSigBack->GetParameter(fParMass);
632 fErrors(4) = fFuncSigBack->GetParError(fParMass);
633 fValues(5) = fFuncSigBack->GetParameter(fParMassWidth);
634 fErrors(5) = fFuncSigBack->GetParError(fParMassWidth);
639 //______________________________________________
640 void AliDielectronSignalFunc::ProcessEM(TObjArray * const arrhist) {
642 // Substract background with the event mixing technique
644 arrhist->GetEntries(); // just to avoid the unused parameter warning
645 AliError("Event mixing for background substraction method not implemented!");
648 //______________________________________________
649 void AliDielectronSignalFunc::SetFunctions(TF1 * const combined, TF1 * const sig, TF1 * const back,
650 Int_t parM, Int_t parMres)
653 // Set the signal, background functions and combined fit function
654 // Note: The process method assumes that the first n parameters in the
655 // combined fit function correspond to the n parameters of the signal function
656 // and the n+1 to n+m parameters to the m parameters of the background function!!!
658 if (!sig||!back||!combined) {
659 AliError("Both, signal and background function need to be set!");
663 fFuncBackground=back;
664 fFuncSigBack=combined;
666 fParMassWidth=parMres;
669 //______________________________________________
670 void AliDielectronSignalFunc::SetDefaults(Int_t type)
673 // Setup some default functions:
674 // type = 0: gaus signal + linear background in 2.5 - 4 GeV inv. mass
675 // type = 1: gaus signal + exponential background in 2.5 - 4 GeV inv. mass
676 // type = 2: half gaussian, half exponential signal function
677 // type = 3: Crystal-Ball function
678 // type = 4: Crystal-Ball signal + exponential background
682 fFuncSignal=new TF1("DieleSignal","gaus",2.5,4);
683 fFuncBackground=new TF1("DieleBackground","pol1",2.5,4);
684 fFuncSigBack=new TF1("DieleCombined","gaus+pol1(3)",2.5,4);
686 fFuncSigBack->SetParameters(1,3.1,.05,2.5,1);
687 fFuncSigBack->SetParLimits(0,0,10000000);
688 fFuncSigBack->SetParLimits(1,3.05,3.15);
689 fFuncSigBack->SetParLimits(2,.02,.1);
692 fFuncSignal=new TF1("DieleSignal","gaus",2.5,4);
693 fFuncBackground=new TF1("DieleBackground","[0]*exp(-(x-[1])/[2])",2.5,4);
694 fFuncSigBack=new TF1("DieleCombined","gaus+[3]*exp(-(x-[4])/[5])",2.5,4);
696 fFuncSigBack->SetParameters(1,3.1,.05,1,2.5,1);
697 fFuncSigBack->SetParLimits(0,0,10000000);
698 fFuncSigBack->SetParLimits(1,3.05,3.15);
699 fFuncSigBack->SetParLimits(2,.02,.1);
702 // half gaussian, half exponential signal function
703 // exponential background
704 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);
705 fFuncBackground = new TF1("DieleBackground","[0]*exp(-(x-[1])/[2])+[3]",2.5,4);
706 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);
707 fFuncSigBack->SetParameters(1.,3.1,.05,.1,1,2.5,1,0);
709 fFuncSigBack->SetParLimits(0,0,10000000);
710 fFuncSigBack->SetParLimits(1,3.05,3.15);
711 fFuncSigBack->SetParLimits(2,.02,.1);
712 fFuncSigBack->FixParameter(6,2.5);
713 fFuncSigBack->FixParameter(7,0);
718 //______________________________________________
719 void AliDielectronSignalFunc::Draw(const Option_t* option)
722 // Draw the fitted function
725 TString drawOpt(option);
728 Bool_t optStat=drawOpt.Contains("stat");
730 fFuncSigBack->SetNpx(200);
731 fFuncSigBack->SetRange(fIntMin,fIntMax);
732 fFuncBackground->SetNpx(200);
733 fFuncBackground->SetRange(fIntMin,fIntMax);
735 TGraph *grSig=new TGraph(fFuncSigBack);
736 grSig->SetFillColor(kGreen);
737 grSig->SetFillStyle(3001);
739 TGraph *grBack=new TGraph(fFuncBackground);
740 grBack->SetFillColor(kRed);
741 grBack->SetFillStyle(3001);
743 grSig->SetPoint(0,grBack->GetX()[0],grBack->GetY()[0]);
744 grSig->SetPoint(grSig->GetN()-1,grBack->GetX()[grBack->GetN()-1],grBack->GetY()[grBack->GetN()-1]);
746 grBack->SetPoint(0,grBack->GetX()[0],0.);
747 grBack->SetPoint(grBack->GetN()-1,grBack->GetX()[grBack->GetN()-1],0.);
749 fFuncSigBack->SetRange(fFitMin,fFitMax);
750 fFuncBackground->SetRange(fFitMin,fFitMax);
752 if (!drawOpt.Contains("same")){
762 if(fMethod==kFitted || fMethod==kFittedMC) grBack->Draw("f");
763 fFuncSigBack->Draw("same");
764 fFuncSigBack->SetLineWidth(2);
765 if(fMethod==kLikeSign) {
766 fHistDataPP->SetLineWidth(2);
767 fHistDataPP->SetLineColor(6);
768 fHistDataPP->Draw("same");
769 fHistDataMM->SetLineWidth(2);
770 fHistDataMM->SetLineColor(8);
771 fHistDataMM->Draw("same");
774 if(fMethod==kFitted || fMethod==kFittedMC)
775 fFuncBackground->Draw("same");
777 if (optStat) DrawStats();