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 **************************************************************************/
18 ///////////////////////////////////////////////////////////////////////////
19 // Dielectron SignalFunc //
23 Dielectron signal extraction class using functions as input.
25 A function to describe the signal as well as one to describe the background
26 has to be deployed by the user. Alternatively on of the default implementaions
31 ///////////////////////////////////////////////////////////////////////////
38 #include <TPaveText.h>
40 #include <TFitResult.h>
41 //#include <../hist/hist/src/TF1Helper.h>
45 #include "AliDielectronSignalFunc.h"
47 ClassImp(AliDielectronSignalFunc)
49 AliDielectronSignalFunc::AliDielectronSignalFunc() :
50 AliDielectronSignalBase(),
60 // Default Constructor
65 //______________________________________________
66 AliDielectronSignalFunc::AliDielectronSignalFunc(const char* name, const char* title) :
67 AliDielectronSignalBase(name, title),
81 //______________________________________________
82 AliDielectronSignalFunc::~AliDielectronSignalFunc()
87 if(fFuncSignal) delete fFuncSignal;
88 if(fFuncBackground) delete fFuncBackground;
89 if(fFuncSigBack) delete fFuncSigBack;
93 //______________________________________________
94 void AliDielectronSignalFunc::Process(TObjArray * const arrhist)
97 // Fit the invariant mass histograms and retrieve the signal and background
113 AliError("Background substraction method not known!");
118 //______________________________________________
119 void AliDielectronSignalFunc::ProcessFit(TObjArray * const arrhist) {
121 // Fit the +- invariant mass distribution only
122 // Here we assume that the combined fit function is a sum of the signal and background functions
123 // and that the signal function is always the first term of this sum
126 fHistDataPM = (TH1F*)(arrhist->At(1))->Clone("histPM"); // +- SE
127 fHistDataPM->Sumw2();
129 fHistDataPM->Rebin(fRebin);
131 fHistSignal = new TH1F("HistSignal", "Like-Sign substracted signal",
132 fHistDataPM->GetXaxis()->GetNbins(),
133 fHistDataPM->GetXaxis()->GetXmin(), fHistDataPM->GetXaxis()->GetXmax());
134 fHistBackground = new TH1F("HistBackground", "Like-sign contribution",
135 fHistDataPM->GetXaxis()->GetNbins(),
136 fHistDataPM->GetXaxis()->GetXmin(), fHistDataPM->GetXaxis()->GetXmax());
138 // the starting parameters of the fit function and their limits can be tuned
139 // by the user in its macro
140 fHistDataPM->Fit(fFuncSigBack, fFitOpt.Data(), "", fFitMin, fFitMax);
141 TFitResultPtr pmFitPtr = fHistDataPM->Fit(fFuncSigBack, fFitOpt.Data(), "", fFitMin, fFitMax);
142 //TFitResult *pmFitResult = pmFitPtr.Get(); // used only with TF1Helper
143 fFuncSignal->SetParameters(fFuncSigBack->GetParameters());
144 fFuncBackground->SetParameters(fFuncSigBack->GetParameters()+fFuncSignal->GetNpar());
146 for(Int_t iBin=1; iBin<=fHistDataPM->GetXaxis()->GetNbins(); iBin++) {
147 Double_t m = fHistDataPM->GetBinCenter(iBin);
148 Double_t pm = fHistDataPM->GetBinContent(iBin);
149 Double_t epm = fHistDataPM->GetBinError(iBin);
150 Double_t bknd = fFuncBackground->Eval(m);
152 for(Int_t iPar=fFuncSignal->GetNpar(); iPar<fFuncSigBack->GetNpar(); iPar++) {
153 /* TF1Helper problem on alien compilation
154 for(Int_t jPar=iPar; jPar<fFuncSigBack->GetNpar(); jPar++) {
155 TF1 gradientIpar("gradientIpar",
156 ROOT::TF1Helper::TGradientParFunction(iPar-fFuncSignal->GetNpar(),fFuncBackground),0,0,0);
157 TF1 gradientJpar("gradientJpar",
158 ROOT::TF1Helper::TGradientParFunction(jPar-fFuncSignal->GetNpar(),fFuncBackground),0,0,0);
159 ebknd += pmFitResult->CovMatrix(iPar,jPar)*
160 gradientIpar.Eval(m)*gradientJpar.Eval(m)*
161 (iPar==jPar ? 1.0 : 2.0);
165 Double_t signal = pm-bknd;
166 Double_t error = TMath::Sqrt(epm*epm+ebknd);
167 fHistSignal->SetBinContent(iBin, signal);
168 fHistSignal->SetBinError(iBin, error);
169 fHistBackground->SetBinContent(iBin, bknd);
170 fHistBackground->SetBinError(iBin, TMath::Sqrt(ebknd));
175 fValues(0) = fFuncSignal->Integral(fIntMin, fIntMax)/fHistDataPM->GetBinWidth(1);
177 for(Int_t iPar=0; iPar<fFuncSignal->GetNpar(); iPar++) {
178 /* TF1Helper problem on alien compilation
179 for(Int_t jPar=iPar; jPar<fFuncSignal->GetNpar(); jPar++) {
180 TF1 gradientIpar("gradientIpar",
181 ROOT::TF1Helper::TGradientParFunction(iPar,fFuncSignal),0,0,0);
182 TF1 gradientJpar("gradientJpar",
183 ROOT::TF1Helper::TGradientParFunction(jPar,fFuncSignal),0,0,0);
184 fErrors(0) += pmFitResult->CovMatrix(iPar,jPar)*
185 gradientIpar.Integral(fIntMin,fIntMax)*gradientJpar.Integral(fIntMin,fIntMax)*
186 (iPar==jPar ? 1.0 : 2.0);
191 fValues(1) = fFuncBackground->Integral(fIntMin, fIntMax)/fHistDataPM->GetBinWidth(1);
193 for(Int_t iPar=fFuncSignal->GetNpar(); iPar<fFuncSigBack->GetNpar(); iPar++) {
194 /* TF1Helper problem on alien compilation
195 for(Int_t jPar=iPar; jPar<fFuncSigBack->GetNpar(); jPar++) {
196 TF1 gradientIpar("gradientIpar",
197 ROOT::TF1Helper::TGradientParFunction(iPar-fFuncSignal->GetNpar(),fFuncBackground),0,0,0);
198 TF1 gradientJpar("gradientJpar",
199 ROOT::TF1Helper::TGradientParFunction(jPar-fFuncSignal->GetNpar(),fFuncBackground),0,0,0);
200 fErrors(1) += pmFitResult->CovMatrix(iPar,jPar)*
201 gradientIpar.Integral(fIntMin, fIntMax)*gradientJpar.Integral(fIntMin, fIntMax)*
202 (iPar==jPar ? 1.0 : 2.0);
209 fValues(0) = fHistSignal->IntegralAndError(fHistSignal->FindBin(fIntMin),
210 fHistSignal->FindBin(fIntMax), fErrors(0));
212 fValues(1) = fHistBackground->IntegralAndError(fHistBackground->FindBin(fIntMin),
213 fHistBackground->FindBin(fIntMax),
216 // S/B and significance
217 SetSignificanceAndSOB();
218 fValues(4) = fFuncSigBack->GetParameter(fParMass);
219 fErrors(4) = fFuncSigBack->GetParError(fParMass);
220 fValues(5) = fFuncSigBack->GetParameter(fParMassWidth);
221 fErrors(5) = fFuncSigBack->GetParError(fParMassWidth);
226 //______________________________________________
227 void AliDielectronSignalFunc::ProcessLS(TObjArray * const arrhist) {
229 // Substract background using the like-sign spectrum
231 fHistDataPP = (TH1F*)(arrhist->At(0))->Clone("histPP"); // ++ SE
232 fHistDataPM = (TH1F*)(arrhist->At(1))->Clone("histPM"); // +- SE
233 fHistDataMM = (TH1F*)(arrhist->At(2))->Clone("histMM"); // -- SE
235 fHistDataPP->Rebin(fRebin);
236 fHistDataPM->Rebin(fRebin);
237 fHistDataMM->Rebin(fRebin);
239 fHistDataPP->Sumw2();
240 fHistDataPM->Sumw2();
241 fHistDataMM->Sumw2();
243 fHistSignal = new TH1F("HistSignal", "Like-Sign substracted signal",
244 fHistDataPM->GetXaxis()->GetNbins(),
245 fHistDataPM->GetXaxis()->GetXmin(), fHistDataPM->GetXaxis()->GetXmax());
246 fHistBackground = new TH1F("HistBackground", "Like-sign contribution",
247 fHistDataPM->GetXaxis()->GetNbins(),
248 fHistDataPM->GetXaxis()->GetXmin(), fHistDataPM->GetXaxis()->GetXmax());
250 // fit the +- mass distribution
251 fHistDataPM->Fit(fFuncSigBack, fFitOpt.Data(), "", fFitMin, fFitMax);
252 fHistDataPM->Fit(fFuncSigBack, fFitOpt.Data(), "", fFitMin, fFitMax);
253 // declare the variables where the like-sign fit results will be stored
254 // TFitResult *ppFitResult = 0x0;
255 // TFitResult *mmFitResult = 0x0;
256 // fit the like sign background
257 TF1 *funcClonePP = (TF1*)fFuncBackground->Clone("funcClonePP");
258 TF1 *funcCloneMM = (TF1*)fFuncBackground->Clone("funcCloneMM");
259 fHistDataPP->Fit(funcClonePP, fFitOpt.Data(), "", fFitMin, fFitMax);
260 fHistDataPP->Fit(funcClonePP, fFitOpt.Data(), "", fFitMin, fFitMax);
261 // TFitResultPtr ppFitPtr = fHistDataPP->Fit(funcClonePP, fFitOpt.Data(), "", fFitMin, fFitMax);
262 // ppFitResult = ppFitPtr.Get();
263 fHistDataMM->Fit(funcCloneMM, fFitOpt.Data(), "", fFitMin, fFitMax);
264 fHistDataMM->Fit(funcCloneMM, fFitOpt.Data(), "", fFitMin, fFitMax);
265 // TFitResultPtr mmFitPtr = fHistDataMM->Fit(funcCloneMM, fFitOpt.Data(), "", fFitMin, fFitMax);
266 // mmFitResult = mmFitPtr.Get();
268 for(Int_t iBin=1; iBin<=fHistDataPM->GetXaxis()->GetNbins(); iBin++) {
269 Double_t m = fHistDataPM->GetBinCenter(iBin);
270 Double_t pm = fHistDataPM->GetBinContent(iBin);
271 Double_t pp = funcClonePP->Eval(m);
272 Double_t mm = funcCloneMM->Eval(m);
273 Double_t epm = fHistDataPM->GetBinError(iBin);
275 for(Int_t iPar=0; iPar<funcClonePP->GetNpar(); iPar++) {
276 /* TF1Helper problem on alien compilation
277 for(Int_t jPar=iPar; jPar<funcClonePP->GetNpar(); jPar++) {
278 TF1 gradientIpar("gradientIpar",
279 ROOT::TF1Helper::TGradientParFunction(iPar,funcClonePP),0,0,0);
280 TF1 gradientJpar("gradientJpar",
281 ROOT::TF1Helper::TGradientParFunction(jPar,funcClonePP),0,0,0);
282 epp += ppFitResult->CovMatrix(iPar,jPar)*
283 gradientIpar.Eval(m)*gradientJpar.Eval(m)*
284 (iPar==jPar ? 1.0 : 2.0);
289 for(Int_t iPar=0; iPar<funcCloneMM->GetNpar(); iPar++) {
290 /* TF1Helper problem on alien compilation
291 for(Int_t jPar=iPar; jPar<funcCloneMM->GetNpar(); jPar++) {
292 TF1 gradientIpar("gradientIpar",
293 ROOT::TF1Helper::TGradientParFunction(iPar,funcCloneMM),0,0,0);
294 TF1 gradientJpar("gradientJpar",
295 ROOT::TF1Helper::TGradientParFunction(jPar,funcCloneMM),0,0,0);
296 emm += mmFitResult->CovMatrix(iPar,jPar)*
297 gradientIpar.Eval(m)*gradientJpar.Eval(m)*
298 (iPar==jPar ? 1.0 : 2.0);
303 Double_t signal = pm-2.0*TMath::Sqrt(pp*mm);
304 Double_t background = 2.0*TMath::Sqrt(pp*mm);
305 // error propagation on the signal calculation above
306 Double_t esignal = TMath::Sqrt(epm*epm+(mm/pp)*epp+(pp/mm)*emm);
307 Double_t ebackground = TMath::Sqrt((mm/pp)*epp+(pp/mm)*emm);
308 fHistSignal->SetBinContent(iBin, signal);
309 fHistSignal->SetBinError(iBin, esignal);
310 fHistBackground->SetBinContent(iBin, background);
311 fHistBackground->SetBinError(iBin, ebackground);
315 fValues(0) = fHistSignal->IntegralAndError(fHistSignal->FindBin(fIntMin),
316 fHistSignal->FindBin(fIntMax), fErrors(0));
318 fValues(1) = fHistBackground->IntegralAndError(fHistBackground->FindBin(fIntMin),
319 fHistBackground->FindBin(fIntMax),
321 // S/B and significance
322 SetSignificanceAndSOB();
323 fValues(4) = fFuncSigBack->GetParameter(fParMass);
324 fErrors(4) = fFuncSigBack->GetParError(fParMass);
325 fValues(5) = fFuncSigBack->GetParameter(fParMassWidth);
326 fErrors(5) = fFuncSigBack->GetParError(fParMassWidth);
331 //______________________________________________
332 void AliDielectronSignalFunc::ProcessEM(TObjArray * const arrhist) {
334 // Substract background with the event mixing technique
336 arrhist->GetEntries(); // just to avoid the unused parameter warning
337 AliError("Event mixing for background substraction method not implemented!");
340 //______________________________________________
341 void AliDielectronSignalFunc::SetFunctions(TF1 * const combined, TF1 * const sig, TF1 * const back,
342 Int_t parM, Int_t parMres)
345 // Set the signal, background functions and combined fit function
346 // Note: The process method assumes that the first n parameters in the
347 // combined fit function correspond to the n parameters of the signal function
348 // and the n+1 to n+m parameters to the m parameters of the background function!!!
350 if (!sig||!back||!combined) {
351 AliError("Both, signal and background function need to be set!");
355 fFuncBackground=back;
356 fFuncSigBack=combined;
358 fParMassWidth=parMres;
361 //______________________________________________
362 void AliDielectronSignalFunc::SetDefaults(Int_t type)
365 // Setup some default functions:
366 // type = 0: gaus signal + linear background in 2.5 - 4 GeV inv. mass
367 // type = 1: gaus signal + exponential background in 2.5 - 4 GeV inv. mass
368 // type = 2: half gaussian, half exponential signal function
369 // type = 3: Crystal-Ball function
370 // type = 4: Crystal-Ball signal + exponential background
374 fFuncSignal=new TF1("DieleSignal","gaus",2.5,4);
375 fFuncBackground=new TF1("DieleBackground","pol1",2.5,4);
376 fFuncSigBack=new TF1("DieleCombined","gaus+pol1(3)",2.5,4);
378 fFuncSigBack->SetParameters(1,3.1,.05,2.5,1);
379 fFuncSigBack->SetParLimits(0,0,10000000);
380 fFuncSigBack->SetParLimits(1,3.05,3.15);
381 fFuncSigBack->SetParLimits(2,.02,.1);
384 fFuncSignal=new TF1("DieleSignal","gaus",2.5,4);
385 fFuncBackground=new TF1("DieleBackground","[0]*exp(-(x-[1])/[2])",2.5,4);
386 fFuncSigBack=new TF1("DieleCombined","gaus+[3]*exp(-(x-[4])/[5])",2.5,4);
388 fFuncSigBack->SetParameters(1,3.1,.05,1,2.5,1);
389 fFuncSigBack->SetParLimits(0,0,10000000);
390 fFuncSigBack->SetParLimits(1,3.05,3.15);
391 fFuncSigBack->SetParLimits(2,.02,.1);
394 // half gaussian, half exponential signal function
395 // exponential background
396 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);
397 fFuncBackground = new TF1("DieleBackground","[0]*exp(-(x-[1])/[2])+[3]",2.5,4);
398 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);
399 fFuncSigBack->SetParameters(1.,3.1,.05,.1,1,2.5,1,0);
401 fFuncSigBack->SetParLimits(0,0,10000000);
402 fFuncSigBack->SetParLimits(1,3.05,3.15);
403 fFuncSigBack->SetParLimits(2,.02,.1);
404 fFuncSigBack->FixParameter(6,2.5);
405 fFuncSigBack->FixParameter(7,0);
410 //______________________________________________
411 void AliDielectronSignalFunc::Draw(const Option_t* option)
414 // Draw the fitted function
417 TString drawOpt(option);
420 Bool_t optStat=drawOpt.Contains("stat");
422 fFuncSigBack->SetNpx(200);
423 fFuncSigBack->SetRange(fIntMin,fIntMax);
424 fFuncBackground->SetNpx(200);
425 fFuncBackground->SetRange(fIntMin,fIntMax);
427 TGraph *grSig=new TGraph(fFuncSigBack);
428 grSig->SetFillColor(kGreen);
429 grSig->SetFillStyle(3001);
431 TGraph *grBack=new TGraph(fFuncBackground);
432 grBack->SetFillColor(kRed);
433 grBack->SetFillStyle(3001);
435 grSig->SetPoint(0,grBack->GetX()[0],grBack->GetY()[0]);
436 grSig->SetPoint(grSig->GetN()-1,grBack->GetX()[grBack->GetN()-1],grBack->GetY()[grBack->GetN()-1]);
438 grBack->SetPoint(0,grBack->GetX()[0],0.);
439 grBack->SetPoint(grBack->GetN()-1,grBack->GetX()[grBack->GetN()-1],0.);
441 fFuncSigBack->SetRange(fFitMin,fFitMax);
442 fFuncBackground->SetRange(fFitMin,fFitMax);
444 if (!drawOpt.Contains("same")){
454 if(fMethod==kFitted) grBack->Draw("f");
455 fFuncSigBack->Draw("same");
456 fFuncSigBack->SetLineWidth(2);
457 if(fMethod==kLikeSign) {
458 fHistDataPP->SetLineWidth(2);
459 fHistDataPP->SetLineColor(6);
460 fHistDataPP->Draw("same");
461 fHistDataMM->SetLineWidth(2);
462 fHistDataMM->SetLineColor(8);
463 fHistDataMM->Draw("same");
467 fFuncBackground->Draw("same");
469 if (optStat) DrawStats();