]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PWGDQ/dielectron/AliDielectronSignalFunc.cxx
o update dielectron package
[u/mrichter/AliRoot.git] / PWGDQ / dielectron / AliDielectronSignalFunc.cxx
CommitLineData
572b0139 1/*************************************************************************
2* Copyright(c) 1998-2009, ALICE Experiment at CERN, All rights reserved. *
3* *
4* Author: The ALICE Off-line Project. *
5* Contributors are mentioned in the code where appropriate. *
6* *
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**************************************************************************/
15
16///////////////////////////////////////////////////////////////////////////
17// Dielectron SignalFunc //
18// //
19// //
20/*
21Dielectron signal extraction class using functions as input.
22
23A function to describe the signal as well as one to describe the background
24has to be deployed by the user. Alternatively on of the default implementaions
25can be used.
26
27*/
28// //
29///////////////////////////////////////////////////////////////////////////
30
31#include <TF1.h>
32#include <TH1.h>
33#include <TGraph.h>
34#include <TMath.h>
35#include <TString.h>
36#include <TPaveText.h>
bc75eeb5 37#include <TList.h>
38#include <TFitResult.h>
cafdf10b 39//#include <../hist/hist/src/TF1Helper.h>
572b0139 40
41#include <AliLog.h>
42
43#include "AliDielectronSignalFunc.h"
44
45ClassImp(AliDielectronSignalFunc)
46
5720c765 47TH1F* AliDielectronSignalFunc::fgHistSimPM=0x0;
48
572b0139 49AliDielectronSignalFunc::AliDielectronSignalFunc() :
3505bfad 50AliDielectronSignalBase(),
51fFuncSignal(0x0),
52fFuncBackground(0x0),
53fFuncSigBack(0x0),
54fParMass(1),
55fParMassWidth(2),
56fFitOpt("SMNQE"),
5720c765 57fUseIntegral(kFALSE),
58fPolDeg(0),
59fChi2Dof(0.0)
572b0139 60{
61 //
62 // Default Constructor
63 //
64
65}
66
67//______________________________________________
68AliDielectronSignalFunc::AliDielectronSignalFunc(const char* name, const char* title) :
3505bfad 69AliDielectronSignalBase(name, title),
70fFuncSignal(0x0),
71fFuncBackground(0x0),
72fFuncSigBack(0x0),
73fParMass(1),
74fParMassWidth(2),
75fFitOpt("SMNQE"),
5720c765 76fUseIntegral(kFALSE),
77fPolDeg(0),
78fChi2Dof(0.0)
572b0139 79{
80 //
81 // Named Constructor
82 //
83}
84
85//______________________________________________
86AliDielectronSignalFunc::~AliDielectronSignalFunc()
87{
88 //
89 // Default Destructor
90 //
bc75eeb5 91 if(fFuncSignal) delete fFuncSignal;
92 if(fFuncBackground) delete fFuncBackground;
93 if(fFuncSigBack) delete fFuncSigBack;
572b0139 94}
95
96
97//______________________________________________
bc75eeb5 98void AliDielectronSignalFunc::Process(TObjArray * const arrhist)
572b0139 99{
100 //
bc75eeb5 101 // Fit the invariant mass histograms and retrieve the signal and background
572b0139 102 //
bc75eeb5 103 switch(fMethod) {
5720c765 104 case kFittedMC :
105 ProcessFitIKF(arrhist);
106 break;
107
bc75eeb5 108 case kFitted :
109 ProcessFit(arrhist);
110 break;
3505bfad 111
bc75eeb5 112 case kLikeSign :
113 ProcessLS(arrhist);
114 break;
3505bfad 115
bc75eeb5 116 case kEventMixing :
3505bfad 117 ProcessEM(arrhist);
bc75eeb5 118 break;
3505bfad 119
bc75eeb5 120 default :
121 AliError("Background substraction method not known!");
572b0139 122 }
bc75eeb5 123}
572b0139 124
5720c765 125//______________________________________________
126void AliDielectronSignalFunc::ProcessFitIKF(TObjArray * const arrhist) {
127 //
128 // Fit the +- invariant mass distribution only
129 //
130 //
131
132 const Double_t bigNumber = 100000.;
133 Double_t chi2ndfm1 = bigNumber;
134 Double_t ratiom1 = bigNumber;
135 Double_t chi2ndf = bigNumber;
136 Int_t nDP =0;
137
138 Int_t maxPolDeg = 8;
139
140 fHistDataPM = (TH1F*)(arrhist->At(1))->Clone("histPM"); // +- SE
141 if(fRebin>1) fHistDataPM->Rebin(fRebin);
142
143 fgHistSimPM = (TH1F*)(arrhist->At(3))->Clone("histPMsim"); // +- mc shape
144 if (!fgHistSimPM) {
145 AliFatal("No mc peak shape found at idx 3.");
146 return;
147 }
148 if(fRebin>1) fgHistSimPM->Rebin(fRebin);
149
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));
153
154 FitOneMinv(hf1, fgHistSimPM, iPD);
155 if (fChi2Dof > 0) chi2ndf = fChi2Dof;
156 AliInfo(Form("nDP: %d, iPD: %d, chi2ndf: %f", nDP, iPD, chi2ndf));
157
158 ratiom1 = TMath::Abs(fChi2Dof - 1);
159 if (chi2ndfm1 > ratiom1) { // search for the closest to 1.
160 chi2ndfm1 = ratiom1;
161 nDP = iPD;
162 }
163 }
164
165
166 // fit again with the best polynomial degree
167 TH1F *h2 = (TH1F *) fHistDataPM->Clone(Form("h2_PD%d",nDP));
168
169 FitOneMinv(h2, fgHistSimPM, nDP);
170 AliInfo(Form("Best Fit: PD %d, chi^2/ndf %.3f, S/B %.3f",nDP,fChi2Dof,fValues(3)));
171
172}
173//______________________________________________
174void AliDielectronSignalFunc::FitOneMinv(TH1F *hMinv, TH1F *hSim, Int_t pod) {
175 //
176 // main function to fit an inv mass spectrum
177 //
178
179 TObjArray *arrResults = new TObjArray;
180 arrResults->SetOwner();
181 arrResults->AddAt(hMinv,0);
182
183 // Degree of polynomial
184 fPolDeg = pod;
185
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);
195
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
199
200 hBfit->Reset();
201 hSigF->Reset();
202 hBgrd->Reset();
203
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);
209
210 Int_t nBgnd = 2 + fPolDeg; // degree + c1st oefficient + higher coefficients
211 Int_t nMinv = nBgnd + 1; // bgrd + peakscale
212
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));
218 }
219 }
220
221
222 // =======
223 // 1.
224 // =======
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.);
231 }
232 hBfit->Fit(fBo,"0qR");
233 //hBfit->SetNameTitle("bgrd_fit");
234 arrResults->AddAt(fBo,1);
235
236
237 // =======
238 // 2.
239 // =======
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);
249
250
251 // =======
252 // 3.
253 // =======
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));
260 }
261 // create background histogram from background function
262 hBgrd->Eval(fB);
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);
268
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);
275 }
276 }
277 arrResults->AddAt(hBgrd,4);
278
279 // =======
280 // 4.
281 // =======
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);
289 }
290 }
291 hSigF->SetNameTitle("peak_only","");
292 arrResults->AddAt(hSigF,5);
293
294 // =======
295 // 5.
296 // =======
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);
303
304
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();
311
312 // fit results
313 Double_t chi2 = fSB->GetChisquare();
314 Int_t ndf = fSB->GetNDF();
315 fChi2Dof = chi2/ndf;
316
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
327
328
329 delete arrResults;
330
331}
332//______________________________________________________________________________
333Double_t AliDielectronSignalFunc::BgndFun(const Double_t *x, const Double_t *par) {
334 // parameters
335 // [0]: degree of polynomial
336 // [1]: constant polynomial coefficient
337 // [2]..: higher polynomial coefficients
338
339 Int_t deg = ((Int_t) par[0]);
340
341 Double_t f = 0.0;
342 Double_t yy = 1.0;
343 Double_t xx = x[0];
344
345 for (Int_t i = 0; i <= deg; i++) {
346 f += par[i+1] * yy;
347 yy *= xx;
348 }
349
350
351 return f;
352}
353//______________________________________________________________________________
354Double_t AliDielectronSignalFunc::PeakFun(const Double_t *x, const Double_t *par) {
355 // Fit MC signal shape
356 // parameters
357 // [0]: scale for simpeak
358
359 Double_t xx = x[0];
360
361 TH1F *hPeak = fgHistSimPM;
362 if (!hPeak) {
363 printf("F-AliDielectronSignalFunc::PeakFun: No histogram for peak fit defined!\n");
364 }
365
366 Int_t idx = hPeak->FindBin(xx);
367 if ((idx <= 1) ||
368 (idx >= hPeak->GetNbinsX())) {
369 return 0.0;
370 }
371
372 return (par[0] * hPeak->GetBinContent(idx));
373
374}
375
376//______________________________________________________________________________
377Double_t AliDielectronSignalFunc::MinvFun(const Double_t *x, const Double_t *par) {
378 // parameters
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
383
384 Int_t deg = ((Int_t) par[0]);
385 Double_t parPK[25], parBG[25];
386
387 parBG[0] = par[0]; // degree of polynomial
388
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
391
392 Double_t peak = PeakFun(x,parPK);
393 Double_t bgnd = BgndFun(x,parBG);
394 Double_t f = peak + bgnd;
395
396 return f;
397}
398
399//______________________________________________________________________________
400Double_t AliDielectronSignalFunc::PeakFunCB(const Double_t *x, const Double_t *par) {
401 // Crystal Ball function fit
402
403 Double_t alpha = par[0];
404 Double_t n = par[1];
405 Double_t meanx = par[2];
406 Double_t sigma = par[3];
407 Double_t nn = par[4];
408
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);
411
412 Double_t arg = (x[0] - meanx)/sigma;
413 Double_t fitval = 0;
414
415 if (arg > -1.*alpha) {
416 fitval = nn * TMath::Exp(-.5*arg*arg);
417 } else {
418 fitval = nn * a * TMath::Power((b-arg), (-1*n));
419 }
420
421 return fitval;
422}
423
572b0139 424
bc75eeb5 425//______________________________________________
426void AliDielectronSignalFunc::ProcessFit(TObjArray * const arrhist) {
427 //
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
431 //
3505bfad 432
bc75eeb5 433 fHistDataPM = (TH1F*)(arrhist->At(1))->Clone("histPM"); // +- SE
434 fHistDataPM->Sumw2();
435 if(fRebin>1)
436 fHistDataPM->Rebin(fRebin);
572b0139 437
5720c765 438 fHistSignal = new TH1F("HistSignal", "Fit substracted signal",
3505bfad 439 fHistDataPM->GetXaxis()->GetNbins(),
440 fHistDataPM->GetXaxis()->GetXmin(), fHistDataPM->GetXaxis()->GetXmax());
5720c765 441 fHistBackground = new TH1F("HistBackground", "Fit contribution",
3505bfad 442 fHistDataPM->GetXaxis()->GetNbins(),
443 fHistDataPM->GetXaxis()->GetXmin(), fHistDataPM->GetXaxis()->GetXmax());
444
445 // the starting parameters of the fit function and their limits can be tuned
bc75eeb5 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);
cafdf10b 449 //TFitResult *pmFitResult = pmFitPtr.Get(); // used only with TF1Helper
bc75eeb5 450 fFuncSignal->SetParameters(fFuncSigBack->GetParameters());
451 fFuncBackground->SetParameters(fFuncSigBack->GetParameters()+fFuncSignal->GetNpar());
572b0139 452
bc75eeb5 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);
458 Double_t ebknd = 0;
459 for(Int_t iPar=fFuncSignal->GetNpar(); iPar<fFuncSigBack->GetNpar(); iPar++) {
cafdf10b 460/* TF1Helper problem on alien compilation
bc75eeb5 461 for(Int_t jPar=iPar; jPar<fFuncSigBack->GetNpar(); jPar++) {
462 TF1 gradientIpar("gradientIpar",
3505bfad 463 ROOT::TF1Helper::TGradientParFunction(iPar-fFuncSignal->GetNpar(),fFuncBackground),0,0,0);
bc75eeb5 464 TF1 gradientJpar("gradientJpar",
3505bfad 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);
bc75eeb5 469 }
cafdf10b 470*/
bc75eeb5 471 }
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));
478 }
3505bfad 479
bc75eeb5 480 if(fUseIntegral) {
481 // signal
482 fValues(0) = fFuncSignal->Integral(fIntMin, fIntMax)/fHistDataPM->GetBinWidth(1);
483 fErrors(0) = 0;
484 for(Int_t iPar=0; iPar<fFuncSignal->GetNpar(); iPar++) {
cafdf10b 485/* TF1Helper problem on alien compilation
bc75eeb5 486 for(Int_t jPar=iPar; jPar<fFuncSignal->GetNpar(); jPar++) {
487 TF1 gradientIpar("gradientIpar",
3505bfad 488 ROOT::TF1Helper::TGradientParFunction(iPar,fFuncSignal),0,0,0);
bc75eeb5 489 TF1 gradientJpar("gradientJpar",
3505bfad 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);
bc75eeb5 494 }
cafdf10b 495*/
3505bfad 496 }
bc75eeb5 497 // background
498 fValues(1) = fFuncBackground->Integral(fIntMin, fIntMax)/fHistDataPM->GetBinWidth(1);
499 fErrors(1) = 0;
500 for(Int_t iPar=fFuncSignal->GetNpar(); iPar<fFuncSigBack->GetNpar(); iPar++) {
cafdf10b 501/* TF1Helper problem on alien compilation
bc75eeb5 502 for(Int_t jPar=iPar; jPar<fFuncSigBack->GetNpar(); jPar++) {
503 TF1 gradientIpar("gradientIpar",
3505bfad 504 ROOT::TF1Helper::TGradientParFunction(iPar-fFuncSignal->GetNpar(),fFuncBackground),0,0,0);
bc75eeb5 505 TF1 gradientJpar("gradientJpar",
3505bfad 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);
bc75eeb5 510 }
cafdf10b 511*/
bc75eeb5 512 }
572b0139 513 }
bc75eeb5 514 else {
515 // signal
516 fValues(0) = fHistSignal->IntegralAndError(fHistSignal->FindBin(fIntMin),
3505bfad 517 fHistSignal->FindBin(fIntMax), fErrors(0));
bc75eeb5 518 // background
519 fValues(1) = fHistBackground->IntegralAndError(fHistBackground->FindBin(fIntMin),
3505bfad 520 fHistBackground->FindBin(fIntMax),
521 fErrors(1));
8df8e382 522 }
bc75eeb5 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);
3505bfad 529
bc75eeb5 530 fProcessed = kTRUE;
572b0139 531}
532
533//______________________________________________
bc75eeb5 534void AliDielectronSignalFunc::ProcessLS(TObjArray * const arrhist) {
572b0139 535 //
bc75eeb5 536 // Substract background using the like-sign spectrum
572b0139 537 //
bc75eeb5 538 fHistDataPP = (TH1F*)(arrhist->At(0))->Clone("histPP"); // ++ SE
539 fHistDataPM = (TH1F*)(arrhist->At(1))->Clone("histPM"); // +- SE
3505bfad 540 fHistDataMM = (TH1F*)(arrhist->At(2))->Clone("histMM"); // -- SE
541 if (fRebin>1) {
bc75eeb5 542 fHistDataPP->Rebin(fRebin);
543 fHistDataPM->Rebin(fRebin);
544 fHistDataMM->Rebin(fRebin);
3505bfad 545 }
bc75eeb5 546 fHistDataPP->Sumw2();
547 fHistDataPM->Sumw2();
548 fHistDataMM->Sumw2();
3505bfad 549
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());
556
bc75eeb5 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
45b2b1b8 561// TFitResult *ppFitResult = 0x0;
562// TFitResult *mmFitResult = 0x0;
bc75eeb5 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);
45b2b1b8 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);
bc75eeb5 571 fHistDataMM->Fit(funcCloneMM, fFitOpt.Data(), "", fFitMin, fFitMax);
45b2b1b8 572// TFitResultPtr mmFitPtr = fHistDataMM->Fit(funcCloneMM, fFitOpt.Data(), "", fFitMin, fFitMax);
573// mmFitResult = mmFitPtr.Get();
3505bfad 574
bc75eeb5 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);
581 Double_t epp = 0;
582 for(Int_t iPar=0; iPar<funcClonePP->GetNpar(); iPar++) {
cafdf10b 583/* TF1Helper problem on alien compilation
bc75eeb5 584 for(Int_t jPar=iPar; jPar<funcClonePP->GetNpar(); jPar++) {
585 TF1 gradientIpar("gradientIpar",
3505bfad 586 ROOT::TF1Helper::TGradientParFunction(iPar,funcClonePP),0,0,0);
bc75eeb5 587 TF1 gradientJpar("gradientJpar",
3505bfad 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);
bc75eeb5 592 }
cafdf10b 593*/
bc75eeb5 594 }
595 Double_t emm = 0;
596 for(Int_t iPar=0; iPar<funcCloneMM->GetNpar(); iPar++) {
cafdf10b 597/* TF1Helper problem on alien compilation
bc75eeb5 598 for(Int_t jPar=iPar; jPar<funcCloneMM->GetNpar(); jPar++) {
599 TF1 gradientIpar("gradientIpar",
3505bfad 600 ROOT::TF1Helper::TGradientParFunction(iPar,funcCloneMM),0,0,0);
bc75eeb5 601 TF1 gradientJpar("gradientJpar",
3505bfad 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);
bc75eeb5 606 }
cafdf10b 607*/
bc75eeb5 608 }
3505bfad 609
bc75eeb5 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);
619 }
2a14a7b1 620
bc75eeb5 621 // signal
622 fValues(0) = fHistSignal->IntegralAndError(fHistSignal->FindBin(fIntMin),
3505bfad 623 fHistSignal->FindBin(fIntMax), fErrors(0));
bc75eeb5 624 // background
625 fValues(1) = fHistBackground->IntegralAndError(fHistBackground->FindBin(fIntMin),
3505bfad 626 fHistBackground->FindBin(fIntMax),
627 fErrors(1));
bc75eeb5 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);
3505bfad 634
bc75eeb5 635 fProcessed = kTRUE;
572b0139 636}
bc75eeb5 637
638//______________________________________________
3505bfad 639void AliDielectronSignalFunc::ProcessEM(TObjArray * const arrhist) {
bc75eeb5 640 //
641 // Substract background with the event mixing technique
642 //
3505bfad 643 arrhist->GetEntries(); // just to avoid the unused parameter warning
644 AliError("Event mixing for background substraction method not implemented!");
645}
bc75eeb5 646
572b0139 647//______________________________________________
bc75eeb5 648void AliDielectronSignalFunc::SetFunctions(TF1 * const combined, TF1 * const sig, TF1 * const back,
572b0139 649 Int_t parM, Int_t parMres)
650{
651 //
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!!!
bc75eeb5 656
572b0139 657 if (!sig||!back||!combined) {
658 AliError("Both, signal and background function need to be set!");
61d106d3 659 return;
572b0139 660 }
bc75eeb5 661 fFuncSignal=sig;
662 fFuncBackground=back;
663 fFuncSigBack=combined;
664 fParMass=parM;
665 fParMassWidth=parMres;
572b0139 666}
667
668//______________________________________________
669void AliDielectronSignalFunc::SetDefaults(Int_t type)
670{
671 //
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
678 //
572b0139 679
680 if (type==0){
bc75eeb5 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);
572b0139 684
bc75eeb5 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);
3505bfad 689 }
bc75eeb5 690 else if (type==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);
572b0139 694
bc75eeb5 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);
3505bfad 699 }
bc75eeb5 700 else if (type==2){
572b0139 701 // half gaussian, half exponential signal function
702 // exponential background
bc75eeb5 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);
572b0139 707
bc75eeb5 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);
572b0139 713 }
714}
715
716
717//______________________________________________
718void AliDielectronSignalFunc::Draw(const Option_t* option)
719{
720 //
721 // Draw the fitted function
722 //
bc75eeb5 723
572b0139 724 TString drawOpt(option);
725 drawOpt.ToLower();
3505bfad 726
572b0139 727 Bool_t optStat=drawOpt.Contains("stat");
728
bc75eeb5 729 fFuncSigBack->SetNpx(200);
730 fFuncSigBack->SetRange(fIntMin,fIntMax);
731 fFuncBackground->SetNpx(200);
732 fFuncBackground->SetRange(fIntMin,fIntMax);
572b0139 733
bc75eeb5 734 TGraph *grSig=new TGraph(fFuncSigBack);
572b0139 735 grSig->SetFillColor(kGreen);
736 grSig->SetFillStyle(3001);
3505bfad 737
bc75eeb5 738 TGraph *grBack=new TGraph(fFuncBackground);
572b0139 739 grBack->SetFillColor(kRed);
740 grBack->SetFillStyle(3001);
3505bfad 741
572b0139 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]);
744
745 grBack->SetPoint(0,grBack->GetX()[0],0.);
746 grBack->SetPoint(grBack->GetN()-1,grBack->GetX()[grBack->GetN()-1],0.);
747
bc75eeb5 748 fFuncSigBack->SetRange(fFitMin,fFitMax);
749 fFuncBackground->SetRange(fFitMin,fFitMax);
572b0139 750
751 if (!drawOpt.Contains("same")){
bc75eeb5 752 if (fHistDataPM){
753 fHistDataPM->Draw();
8df8e382 754 grSig->Draw("f");
755 } else {
756 grSig->Draw("af");
757 }
572b0139 758 } else {
759 grSig->Draw("f");
760 }
5720c765 761 if(fMethod==kFitted || fMethod==kFittedMC) grBack->Draw("f");
bc75eeb5 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);
3505bfad 769 fHistDataMM->SetLineColor(8);
bc75eeb5 770 fHistDataMM->Draw("same");
771 }
3505bfad 772
5720c765 773 if(fMethod==kFitted || fMethod==kFittedMC)
bc75eeb5 774 fFuncBackground->Draw("same");
3505bfad 775
8df8e382 776 if (optStat) DrawStats();
bc75eeb5 777
572b0139 778}