]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PWGDQ/dielectron/AliDielectronSignalFunc.cxx
New macros for the kaon train
[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) {
ac390e40 363 printf("E-AliDielectronSignalFunc::PeakFun: No histogram for peak fit defined!\n");
364 return 0.0;
5720c765 365 }
366
367 Int_t idx = hPeak->FindBin(xx);
368 if ((idx <= 1) ||
369 (idx >= hPeak->GetNbinsX())) {
370 return 0.0;
371 }
372
373 return (par[0] * hPeak->GetBinContent(idx));
374
375}
376
377//______________________________________________________________________________
378Double_t AliDielectronSignalFunc::MinvFun(const Double_t *x, const Double_t *par) {
379 // parameters
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
384
385 Int_t deg = ((Int_t) par[0]);
386 Double_t parPK[25], parBG[25];
387
388 parBG[0] = par[0]; // degree of polynomial
389
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
392
393 Double_t peak = PeakFun(x,parPK);
394 Double_t bgnd = BgndFun(x,parBG);
395 Double_t f = peak + bgnd;
396
397 return f;
398}
399
400//______________________________________________________________________________
401Double_t AliDielectronSignalFunc::PeakFunCB(const Double_t *x, const Double_t *par) {
402 // Crystal Ball function fit
403
404 Double_t alpha = par[0];
405 Double_t n = par[1];
406 Double_t meanx = par[2];
407 Double_t sigma = par[3];
408 Double_t nn = par[4];
409
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);
412
413 Double_t arg = (x[0] - meanx)/sigma;
414 Double_t fitval = 0;
415
416 if (arg > -1.*alpha) {
417 fitval = nn * TMath::Exp(-.5*arg*arg);
418 } else {
419 fitval = nn * a * TMath::Power((b-arg), (-1*n));
420 }
421
422 return fitval;
423}
424
572b0139 425
bc75eeb5 426//______________________________________________
427void AliDielectronSignalFunc::ProcessFit(TObjArray * const arrhist) {
428 //
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
432 //
3505bfad 433
bc75eeb5 434 fHistDataPM = (TH1F*)(arrhist->At(1))->Clone("histPM"); // +- SE
435 fHistDataPM->Sumw2();
436 if(fRebin>1)
437 fHistDataPM->Rebin(fRebin);
572b0139 438
5720c765 439 fHistSignal = new TH1F("HistSignal", "Fit substracted signal",
3505bfad 440 fHistDataPM->GetXaxis()->GetNbins(),
441 fHistDataPM->GetXaxis()->GetXmin(), fHistDataPM->GetXaxis()->GetXmax());
5720c765 442 fHistBackground = new TH1F("HistBackground", "Fit contribution",
3505bfad 443 fHistDataPM->GetXaxis()->GetNbins(),
444 fHistDataPM->GetXaxis()->GetXmin(), fHistDataPM->GetXaxis()->GetXmax());
445
446 // the starting parameters of the fit function and their limits can be tuned
bc75eeb5 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);
cafdf10b 450 //TFitResult *pmFitResult = pmFitPtr.Get(); // used only with TF1Helper
bc75eeb5 451 fFuncSignal->SetParameters(fFuncSigBack->GetParameters());
452 fFuncBackground->SetParameters(fFuncSigBack->GetParameters()+fFuncSignal->GetNpar());
572b0139 453
bc75eeb5 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);
459 Double_t ebknd = 0;
460 for(Int_t iPar=fFuncSignal->GetNpar(); iPar<fFuncSigBack->GetNpar(); iPar++) {
cafdf10b 461/* TF1Helper problem on alien compilation
bc75eeb5 462 for(Int_t jPar=iPar; jPar<fFuncSigBack->GetNpar(); jPar++) {
463 TF1 gradientIpar("gradientIpar",
3505bfad 464 ROOT::TF1Helper::TGradientParFunction(iPar-fFuncSignal->GetNpar(),fFuncBackground),0,0,0);
bc75eeb5 465 TF1 gradientJpar("gradientJpar",
3505bfad 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);
bc75eeb5 470 }
cafdf10b 471*/
bc75eeb5 472 }
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));
479 }
3505bfad 480
bc75eeb5 481 if(fUseIntegral) {
482 // signal
483 fValues(0) = fFuncSignal->Integral(fIntMin, fIntMax)/fHistDataPM->GetBinWidth(1);
484 fErrors(0) = 0;
485 for(Int_t iPar=0; iPar<fFuncSignal->GetNpar(); iPar++) {
cafdf10b 486/* TF1Helper problem on alien compilation
bc75eeb5 487 for(Int_t jPar=iPar; jPar<fFuncSignal->GetNpar(); jPar++) {
488 TF1 gradientIpar("gradientIpar",
3505bfad 489 ROOT::TF1Helper::TGradientParFunction(iPar,fFuncSignal),0,0,0);
bc75eeb5 490 TF1 gradientJpar("gradientJpar",
3505bfad 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);
bc75eeb5 495 }
cafdf10b 496*/
3505bfad 497 }
bc75eeb5 498 // background
499 fValues(1) = fFuncBackground->Integral(fIntMin, fIntMax)/fHistDataPM->GetBinWidth(1);
500 fErrors(1) = 0;
501 for(Int_t iPar=fFuncSignal->GetNpar(); iPar<fFuncSigBack->GetNpar(); iPar++) {
cafdf10b 502/* TF1Helper problem on alien compilation
bc75eeb5 503 for(Int_t jPar=iPar; jPar<fFuncSigBack->GetNpar(); jPar++) {
504 TF1 gradientIpar("gradientIpar",
3505bfad 505 ROOT::TF1Helper::TGradientParFunction(iPar-fFuncSignal->GetNpar(),fFuncBackground),0,0,0);
bc75eeb5 506 TF1 gradientJpar("gradientJpar",
3505bfad 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);
bc75eeb5 511 }
cafdf10b 512*/
bc75eeb5 513 }
572b0139 514 }
bc75eeb5 515 else {
516 // signal
517 fValues(0) = fHistSignal->IntegralAndError(fHistSignal->FindBin(fIntMin),
3505bfad 518 fHistSignal->FindBin(fIntMax), fErrors(0));
bc75eeb5 519 // background
520 fValues(1) = fHistBackground->IntegralAndError(fHistBackground->FindBin(fIntMin),
3505bfad 521 fHistBackground->FindBin(fIntMax),
522 fErrors(1));
8df8e382 523 }
bc75eeb5 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);
3505bfad 530
bc75eeb5 531 fProcessed = kTRUE;
572b0139 532}
533
534//______________________________________________
bc75eeb5 535void AliDielectronSignalFunc::ProcessLS(TObjArray * const arrhist) {
572b0139 536 //
bc75eeb5 537 // Substract background using the like-sign spectrum
572b0139 538 //
bc75eeb5 539 fHistDataPP = (TH1F*)(arrhist->At(0))->Clone("histPP"); // ++ SE
540 fHistDataPM = (TH1F*)(arrhist->At(1))->Clone("histPM"); // +- SE
3505bfad 541 fHistDataMM = (TH1F*)(arrhist->At(2))->Clone("histMM"); // -- SE
542 if (fRebin>1) {
bc75eeb5 543 fHistDataPP->Rebin(fRebin);
544 fHistDataPM->Rebin(fRebin);
545 fHistDataMM->Rebin(fRebin);
3505bfad 546 }
bc75eeb5 547 fHistDataPP->Sumw2();
548 fHistDataPM->Sumw2();
549 fHistDataMM->Sumw2();
3505bfad 550
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());
557
bc75eeb5 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
45b2b1b8 562// TFitResult *ppFitResult = 0x0;
563// TFitResult *mmFitResult = 0x0;
bc75eeb5 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);
45b2b1b8 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);
bc75eeb5 572 fHistDataMM->Fit(funcCloneMM, fFitOpt.Data(), "", fFitMin, fFitMax);
45b2b1b8 573// TFitResultPtr mmFitPtr = fHistDataMM->Fit(funcCloneMM, fFitOpt.Data(), "", fFitMin, fFitMax);
574// mmFitResult = mmFitPtr.Get();
3505bfad 575
bc75eeb5 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);
582 Double_t epp = 0;
583 for(Int_t iPar=0; iPar<funcClonePP->GetNpar(); iPar++) {
cafdf10b 584/* TF1Helper problem on alien compilation
bc75eeb5 585 for(Int_t jPar=iPar; jPar<funcClonePP->GetNpar(); jPar++) {
586 TF1 gradientIpar("gradientIpar",
3505bfad 587 ROOT::TF1Helper::TGradientParFunction(iPar,funcClonePP),0,0,0);
bc75eeb5 588 TF1 gradientJpar("gradientJpar",
3505bfad 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);
bc75eeb5 593 }
cafdf10b 594*/
bc75eeb5 595 }
596 Double_t emm = 0;
597 for(Int_t iPar=0; iPar<funcCloneMM->GetNpar(); iPar++) {
cafdf10b 598/* TF1Helper problem on alien compilation
bc75eeb5 599 for(Int_t jPar=iPar; jPar<funcCloneMM->GetNpar(); jPar++) {
600 TF1 gradientIpar("gradientIpar",
3505bfad 601 ROOT::TF1Helper::TGradientParFunction(iPar,funcCloneMM),0,0,0);
bc75eeb5 602 TF1 gradientJpar("gradientJpar",
3505bfad 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);
bc75eeb5 607 }
cafdf10b 608*/
bc75eeb5 609 }
3505bfad 610
bc75eeb5 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);
620 }
2a14a7b1 621
bc75eeb5 622 // signal
623 fValues(0) = fHistSignal->IntegralAndError(fHistSignal->FindBin(fIntMin),
3505bfad 624 fHistSignal->FindBin(fIntMax), fErrors(0));
bc75eeb5 625 // background
626 fValues(1) = fHistBackground->IntegralAndError(fHistBackground->FindBin(fIntMin),
3505bfad 627 fHistBackground->FindBin(fIntMax),
628 fErrors(1));
bc75eeb5 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);
3505bfad 635
bc75eeb5 636 fProcessed = kTRUE;
572b0139 637}
bc75eeb5 638
639//______________________________________________
3505bfad 640void AliDielectronSignalFunc::ProcessEM(TObjArray * const arrhist) {
bc75eeb5 641 //
642 // Substract background with the event mixing technique
643 //
3505bfad 644 arrhist->GetEntries(); // just to avoid the unused parameter warning
645 AliError("Event mixing for background substraction method not implemented!");
646}
bc75eeb5 647
572b0139 648//______________________________________________
bc75eeb5 649void AliDielectronSignalFunc::SetFunctions(TF1 * const combined, TF1 * const sig, TF1 * const back,
572b0139 650 Int_t parM, Int_t parMres)
651{
652 //
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!!!
bc75eeb5 657
572b0139 658 if (!sig||!back||!combined) {
659 AliError("Both, signal and background function need to be set!");
61d106d3 660 return;
572b0139 661 }
bc75eeb5 662 fFuncSignal=sig;
663 fFuncBackground=back;
664 fFuncSigBack=combined;
665 fParMass=parM;
666 fParMassWidth=parMres;
572b0139 667}
668
669//______________________________________________
670void AliDielectronSignalFunc::SetDefaults(Int_t type)
671{
672 //
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
679 //
572b0139 680
681 if (type==0){
bc75eeb5 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);
572b0139 685
bc75eeb5 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);
3505bfad 690 }
bc75eeb5 691 else if (type==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);
572b0139 695
bc75eeb5 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);
3505bfad 700 }
bc75eeb5 701 else if (type==2){
572b0139 702 // half gaussian, half exponential signal function
703 // exponential background
bc75eeb5 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);
572b0139 708
bc75eeb5 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);
572b0139 714 }
715}
716
717
718//______________________________________________
719void AliDielectronSignalFunc::Draw(const Option_t* option)
720{
721 //
722 // Draw the fitted function
723 //
bc75eeb5 724
572b0139 725 TString drawOpt(option);
726 drawOpt.ToLower();
3505bfad 727
572b0139 728 Bool_t optStat=drawOpt.Contains("stat");
729
bc75eeb5 730 fFuncSigBack->SetNpx(200);
731 fFuncSigBack->SetRange(fIntMin,fIntMax);
732 fFuncBackground->SetNpx(200);
733 fFuncBackground->SetRange(fIntMin,fIntMax);
572b0139 734
bc75eeb5 735 TGraph *grSig=new TGraph(fFuncSigBack);
572b0139 736 grSig->SetFillColor(kGreen);
737 grSig->SetFillStyle(3001);
3505bfad 738
bc75eeb5 739 TGraph *grBack=new TGraph(fFuncBackground);
572b0139 740 grBack->SetFillColor(kRed);
741 grBack->SetFillStyle(3001);
3505bfad 742
572b0139 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]);
745
746 grBack->SetPoint(0,grBack->GetX()[0],0.);
747 grBack->SetPoint(grBack->GetN()-1,grBack->GetX()[grBack->GetN()-1],0.);
748
bc75eeb5 749 fFuncSigBack->SetRange(fFitMin,fFitMax);
750 fFuncBackground->SetRange(fFitMin,fFitMax);
572b0139 751
752 if (!drawOpt.Contains("same")){
bc75eeb5 753 if (fHistDataPM){
754 fHistDataPM->Draw();
8df8e382 755 grSig->Draw("f");
756 } else {
757 grSig->Draw("af");
758 }
572b0139 759 } else {
760 grSig->Draw("f");
761 }
5720c765 762 if(fMethod==kFitted || fMethod==kFittedMC) grBack->Draw("f");
bc75eeb5 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);
3505bfad 770 fHistDataMM->SetLineColor(8);
bc75eeb5 771 fHistDataMM->Draw("same");
772 }
3505bfad 773
5720c765 774 if(fMethod==kFitted || fMethod==kFittedMC)
bc75eeb5 775 fFuncBackground->Draw("same");
3505bfad 776
8df8e382 777 if (optStat) DrawStats();
bc75eeb5 778
572b0139 779}