]>
Commit | Line | Data |
---|---|---|
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 | /* | |
21 | ||
22 | Class used for extracting the signal from an invariant mass spectrum. | |
23 | It implements the AliDielectronSignalBase and -Ext classes and it uses user provided | |
24 | functions to fit the spectrum with a combined signa+background fit. | |
25 | Used invariant mass spectra are provided via an array of histograms. There are serveral method | |
26 | to estimate the background and to extract the raw yield from the background subtracted spectra. | |
27 | ||
28 | Example usage: | |
29 | ||
30 | AliDielectronSignalFunc *sig = new AliDielectronSignalFunc(); | |
31 | ||
32 | ||
33 | 1) invariant mass input spectra | |
34 | ||
35 | 1.1) Assuming a AliDielectronCF container as data format (check class for more details) | |
36 | AliDielectronCFdraw *cf = new AliDielectronCFdraw("path/to/the/output/file.root"); | |
37 | TObjArray *arrHists = cf->CollectMinvProj(cf->FindStep("Config")); | |
38 | ||
39 | 1.2) Assuming a AliDielectronHF grid as data format (check class for more details) | |
40 | AliDielectronHFhelper *hf = new AliDielectronHFhelper("path/to/the/output/file.root", "ConfigName"); | |
41 | TObjArray *arrHists = hf->CollectHistos(AliDielectronVarManager::kM); | |
42 | ||
43 | 1.3) Assuming a single histograms | |
44 | TObjArray *histoArray = new TObjArray(); | |
45 | arrHists->Add(signalPP); // add the spectrum histograms to the array | |
46 | arrHists->Add(signalPM); // the order is important !!! | |
47 | arrHists->Add(signalMM); | |
48 | ||
49 | ||
50 | 2) background estimation | |
51 | ||
52 | 2.1) set the method for the background estimation (methods can be found in AliDielectronSignalBase) | |
53 | sig->SetMethod(AliDielectronSignalBase::kFitted); | |
54 | 2.2) rebin the spectras if needed | |
55 | // sig->SetRebin(2); | |
56 | 2.3) add any background function you like | |
57 | TF1 *fB = new TF1("fitBgrd","pol3",minFit,maxFit); | |
58 | ||
59 | ||
60 | 3) configure the signal extraction | |
61 | ||
62 | 3.1) chose one of the signal functions (MCshape, CrystalBall, Gauss) | |
63 | TF1 *fS = new TF1("fitSign",AliDielectronSignalFunc::PeakFunCB,minFit,maxFit,5); // has 5 parameters | |
64 | // TF1 *fS = new TF1("fitSign",AliDielectronSignalFunc::PeakFunGaus,minFit,maxFit,3); // has 3 parameters | |
65 | // sig->SetMCSignalShape(hMCsign); | |
66 | // TF1 *fS = new TF1("fitSign",AliDielectronSignalFunc::PeakFunMC,minFit,maxFit,1); // requires a MC shape | |
67 | 3.2) set the method for the signal extraction (methods can be found in AliDielectronSignalBase) | |
68 | depending on the method serveral inputs are needed (e.g. MC shape, PDG code of the particle of interest) | |
69 | // sig->SetParticleOfInterest(443); //default is jpsi | |
70 | // sig->SetMCSignalShape(signalMC); | |
71 | // sig->SetIntegralRange(minInt, maxInt); | |
72 | sig->SetExtractionMethod(AliDielectronSignal::BinCounting); // this is the default | |
73 | ||
74 | ||
75 | 4) combined fit of bgrd+signal | |
76 | ||
77 | 4.1) combine the two functions | |
78 | sig->CombineFunc(fS,fB); | |
79 | 4.2) apply fitting ranges and the fit options | |
80 | sig->SetFitRange(minFit, maxFit); | |
81 | sig->SetFitOption("NR"); | |
82 | ||
83 | ||
84 | 5) start the processing | |
85 | ||
86 | sig->Process(arrHists); | |
87 | sig->Print(""); // print values and errors extracted | |
88 | ||
89 | ||
90 | 6) access the spectra and values created | |
91 | ||
92 | 6.1) standard spectra as provided filled in AliDielectronSignalExt | |
93 | TH1F *hsign = (TH1F*) sig->GetUnlikeSignHistogram(); // same as the input (rebinned) | |
94 | TH1F *hbgrd = (TH1F*) sig->GetBackgroundHistogram(); // filled histogram with fitBgrd | |
95 | TH1F *hextr = (TH1F*) sig->GetSignalHistogram(); // after backgound extraction (rebinned) | |
96 | TObject *oPeak = (TObject*) sig->GetPeakShape(); // can be a TF1 or TH1 depending on the method | |
97 | 6.2) flow spectra | |
98 | TF1 *fFitSign = sig->GetCombinedFunction(); // combined fit function | |
99 | TF1 *fFitExtr = sig->GetSignalFunction(); // signal function | |
100 | TF1 *fFitBgrd = sig->GetBackgroundFunction(); // background function | |
101 | 6.3) access the extracted values and errors | |
102 | sig->GetValues(); or GetErrors(); // yield extraction | |
103 | ||
104 | */ | |
105 | // // | |
106 | /////////////////////////////////////////////////////////////////////////// | |
107 | ||
108 | #include <TF1.h> | |
109 | #include <TH1.h> | |
110 | #include <TGraph.h> | |
111 | #include <TMath.h> | |
112 | #include <TString.h> | |
113 | #include <TPaveText.h> | |
114 | #include <TList.h> | |
115 | #include <TFitResult.h> | |
116 | //#include <../hist/hist/src/TF1Helper.h> | |
117 | ||
118 | #include <AliLog.h> | |
119 | ||
120 | #include "AliDielectronSignalFunc.h" | |
121 | ||
122 | ClassImp(AliDielectronSignalFunc) | |
123 | ||
124 | //TH1F* AliDielectronSignalFunc::fgHistSimPM=0x0; | |
125 | TF1* AliDielectronSignalFunc::fFuncSignal=0x0; | |
126 | TF1* AliDielectronSignalFunc::fFuncBackground=0x0; | |
127 | Int_t AliDielectronSignalFunc::fNparPeak=0; | |
128 | Int_t AliDielectronSignalFunc::fNparBgnd=0; | |
129 | ||
130 | ||
131 | AliDielectronSignalFunc::AliDielectronSignalFunc() : | |
132 | AliDielectronSignalExt(), | |
133 | fFuncSigBack(0x0), | |
134 | fParMass(1), | |
135 | fParMassWidth(2), | |
136 | fFitOpt("SMNQE"), | |
137 | fUseIntegral(kFALSE), | |
138 | fDof(0), | |
139 | fChi2Dof(0.0) | |
140 | { | |
141 | // | |
142 | // Default Constructor | |
143 | // | |
144 | ||
145 | } | |
146 | ||
147 | //______________________________________________ | |
148 | AliDielectronSignalFunc::AliDielectronSignalFunc(const char* name, const char* title) : | |
149 | AliDielectronSignalExt(name, title), | |
150 | fFuncSigBack(0x0), | |
151 | fParMass(1), | |
152 | fParMassWidth(2), | |
153 | fFitOpt("SMNQE"), | |
154 | fUseIntegral(kFALSE), | |
155 | fDof(0), | |
156 | fChi2Dof(0.0) | |
157 | { | |
158 | // | |
159 | // Named Constructor | |
160 | // | |
161 | } | |
162 | ||
163 | //______________________________________________ | |
164 | AliDielectronSignalFunc::~AliDielectronSignalFunc() | |
165 | { | |
166 | // | |
167 | // Default Destructor | |
168 | // | |
169 | if(fFuncSigBack) delete fFuncSigBack; | |
170 | } | |
171 | ||
172 | ||
173 | //______________________________________________ | |
174 | void AliDielectronSignalFunc::Process(TObjArray * const arrhist) | |
175 | { | |
176 | // | |
177 | // Fit the invariant mass histograms and retrieve the signal and background | |
178 | // | |
179 | switch(fMethod) { | |
180 | case kFitted : | |
181 | ProcessFit(arrhist); | |
182 | break; | |
183 | ||
184 | case kLikeSignFit : | |
185 | ProcessFitLS(arrhist); | |
186 | break; | |
187 | ||
188 | case kEventMixingFit : | |
189 | ProcessFitEM(arrhist); | |
190 | break; | |
191 | ||
192 | case kLikeSign : | |
193 | case kLikeSignArithm : | |
194 | case kLikeSignRcorr: | |
195 | case kLikeSignArithmRcorr: | |
196 | ProcessLS(arrhist); // process like-sign subtraction method | |
197 | break; | |
198 | ||
199 | case kEventMixing : | |
200 | ProcessEM(arrhist); // process event mixing method | |
201 | break; | |
202 | ||
203 | case kRotation: | |
204 | ProcessRotation(arrhist); | |
205 | break; | |
206 | ||
207 | default : | |
208 | AliError("Background substraction method not known!"); | |
209 | } | |
210 | } | |
211 | //______________________________________________________________________________ | |
212 | Double_t AliDielectronSignalFunc::PeakFunMC(const Double_t *x, const Double_t *par) { | |
213 | // Fit MC signal shape | |
214 | // parameters | |
215 | // [0]: scale for simpeak | |
216 | ||
217 | Double_t xx = x[0]; | |
218 | ||
219 | TH1F *hPeak = fgHistSimPM; | |
220 | if (!hPeak) { | |
221 | printf("E-AliDielectronSignalFunc::PeakFun: No histogram for peak fit defined!\n"); | |
222 | return 0.0; | |
223 | } | |
224 | ||
225 | Int_t idx = hPeak->FindBin(xx); | |
226 | if ((idx <= 1) || | |
227 | (idx >= hPeak->GetNbinsX())) { | |
228 | return 0.0; | |
229 | } | |
230 | ||
231 | return (par[0] * hPeak->GetBinContent(idx)); | |
232 | ||
233 | } | |
234 | ||
235 | //______________________________________________________________________________ | |
236 | Double_t AliDielectronSignalFunc::PeakFunCB(const Double_t *x, const Double_t *par) { | |
237 | // Crystal Ball fit function | |
238 | ||
239 | Double_t alpha = par[0]; | |
240 | Double_t n = par[1]; | |
241 | Double_t meanx = par[2]; | |
242 | Double_t sigma = par[3]; | |
243 | Double_t nn = par[4]; | |
244 | ||
245 | Double_t a = TMath::Power((n/TMath::Abs(alpha)), n) * TMath::Exp(-.5*alpha*alpha); | |
246 | Double_t b = n/TMath::Abs(alpha) - TMath::Abs(alpha); | |
247 | ||
248 | Double_t arg = (x[0] - meanx)/sigma; | |
249 | Double_t fitval = 0; | |
250 | ||
251 | if (arg > -1.*alpha) { | |
252 | fitval = nn * TMath::Exp(-.5*arg*arg); | |
253 | } else { | |
254 | fitval = nn * a * TMath::Power((b-arg), (-1*n)); | |
255 | } | |
256 | ||
257 | return fitval; | |
258 | } | |
259 | ||
260 | //______________________________________________________________________________ | |
261 | Double_t AliDielectronSignalFunc::PeakFunGaus(const Double_t *x, const Double_t *par) { | |
262 | // Gaussian fit function | |
263 | //printf("fNparBgrd %d \n",fNparBgnd); | |
264 | Double_t n = par[0]; | |
265 | Double_t mean = par[1]; | |
266 | Double_t sigma = par[2]; | |
267 | Double_t xx = x[0]; | |
268 | ||
269 | return ( n*TMath::Exp(-0.5*TMath::Power((xx-mean)/sigma,2)) ); | |
270 | } | |
271 | ||
272 | //______________________________________________ | |
273 | void AliDielectronSignalFunc::ProcessFit(TObjArray * const arrhist) { | |
274 | // | |
275 | // Fit the +- invariant mass distribution only | |
276 | // Here we assume that the combined fit function is a sum of the signal and background functions | |
277 | // and that the signal function is always the first term of this sum | |
278 | // | |
279 | ||
280 | fHistDataPM = (TH1F*)(arrhist->At(1))->Clone("histPM"); // +- SE | |
281 | fHistDataPM->Sumw2(); | |
282 | if(fRebin>1) | |
283 | fHistDataPM->Rebin(fRebin); | |
284 | ||
285 | fHistSignal = new TH1F("HistSignal", "Fit substracted signal", | |
286 | fHistDataPM->GetXaxis()->GetNbins(), | |
287 | fHistDataPM->GetXaxis()->GetXmin(), fHistDataPM->GetXaxis()->GetXmax()); | |
288 | fHistBackground = new TH1F("HistBackground", "Fit contribution", | |
289 | fHistDataPM->GetXaxis()->GetNbins(), | |
290 | fHistDataPM->GetXaxis()->GetXmin(), fHistDataPM->GetXaxis()->GetXmax()); | |
291 | ||
292 | // the starting parameters of the fit function and their limits can be tuned | |
293 | // by the user in its macro | |
294 | fHistDataPM->Fit(fFuncSigBack, fFitOpt.Data(), "", fFitMin, fFitMax); | |
295 | TFitResultPtr pmFitPtr = fHistDataPM->Fit(fFuncSigBack, fFitOpt.Data(), "", fFitMin, fFitMax); | |
296 | //TFitResult *pmFitResult = pmFitPtr.Get(); // used only with TF1Helper | |
297 | //fFuncBackground->SetParameters(fFuncSigBack->GetParameters()); | |
298 | fFuncSignal->SetParameters(fFuncSigBack->GetParameters()); | |
299 | fFuncBackground->SetParameters(fFuncSigBack->GetParameters()+fFuncSignal->GetNpar()); | |
300 | ||
301 | // fill the background spectrum | |
302 | fHistBackground->Eval(fFuncBackground); | |
303 | // set the error for the background histogram | |
304 | fHistBackground->Fit(fFuncBackground,"0qR","",fFitMin,fFitMax); | |
305 | Double_t inte = fFuncBackground->IntegralError(fIntMin, fIntMax)/fHistDataPM->GetBinWidth(1); | |
306 | Double_t binte = inte / TMath::Sqrt((fHistDataPM->FindBin(fIntMax)-fHistDataPM->FindBin(fIntMin))+1); | |
307 | for(Int_t iBin=fHistDataPM->FindBin(fIntMin); iBin<=fHistDataPM->FindBin(fIntMax); iBin++) { | |
308 | fHistBackground->SetBinError(iBin, binte); | |
309 | } | |
310 | ||
311 | for(Int_t iBin=1; iBin<=fHistDataPM->GetXaxis()->GetNbins(); iBin++) { | |
312 | // Double_t m = fHistDataPM->GetBinCenter(iBin); | |
313 | Double_t pm = fHistDataPM->GetBinContent(iBin); | |
314 | Double_t epm = fHistDataPM->GetBinError(iBin); | |
315 | Double_t bknd = fHistBackground->GetBinContent(iBin); | |
316 | Double_t ebknd = fHistBackground->GetBinError(iBin); | |
317 | for(Int_t iPar=fFuncSignal->GetNpar(); iPar<fFuncSigBack->GetNpar(); iPar++) { | |
318 | /* TF1Helper problem on alien compilation | |
319 | for(Int_t jPar=iPar; jPar<fFuncSigBack->GetNpar(); jPar++) { | |
320 | TF1 gradientIpar("gradientIpar", | |
321 | ROOT::TF1Helper::TGradientParFunction(iPar-fFuncSignal->GetNpar(),fFuncBackground),0,0,0); | |
322 | TF1 gradientJpar("gradientJpar", | |
323 | ROOT::TF1Helper::TGradientParFunction(jPar-fFuncSignal->GetNpar(),fFuncBackground),0,0,0); | |
324 | ebknd += pmFitResult->CovMatrix(iPar,jPar)* | |
325 | gradientIpar.Eval(m)*gradientJpar.Eval(m)* | |
326 | (iPar==jPar ? 1.0 : 2.0); | |
327 | } | |
328 | */ | |
329 | } | |
330 | Double_t signal = pm-bknd; | |
331 | Double_t error = TMath::Sqrt(epm*epm+ebknd); | |
332 | fHistSignal->SetBinContent(iBin, signal); | |
333 | fHistSignal->SetBinError(iBin, error); | |
334 | } | |
335 | ||
336 | if(fUseIntegral) { | |
337 | // signal | |
338 | fValues(0) = fFuncSignal->Integral(fIntMin, fIntMax)/fHistDataPM->GetBinWidth(1); | |
339 | fErrors(0) = 0; | |
340 | for(Int_t iPar=0; iPar<fFuncSignal->GetNpar(); iPar++) { | |
341 | /* TF1Helper problem on alien compilation | |
342 | for(Int_t jPar=iPar; jPar<fFuncSignal->GetNpar(); jPar++) { | |
343 | TF1 gradientIpar("gradientIpar", | |
344 | ROOT::TF1Helper::TGradientParFunction(iPar,fFuncSignal),0,0,0); | |
345 | TF1 gradientJpar("gradientJpar", | |
346 | ROOT::TF1Helper::TGradientParFunction(jPar,fFuncSignal),0,0,0); | |
347 | fErrors(0) += pmFitResult->CovMatrix(iPar,jPar)* | |
348 | gradientIpar.Integral(fIntMin,fIntMax)*gradientJpar.Integral(fIntMin,fIntMax)* | |
349 | (iPar==jPar ? 1.0 : 2.0); | |
350 | } | |
351 | */ | |
352 | } | |
353 | // background | |
354 | fValues(1) = fFuncBackground->Integral(fIntMin, fIntMax)/fHistDataPM->GetBinWidth(1); | |
355 | fErrors(1) = fFuncBackground->IntegralError(fIntMin, fIntMax)/fHistDataPM->GetBinWidth(1); | |
356 | for(Int_t iPar=fFuncSignal->GetNpar(); iPar<fFuncSigBack->GetNpar(); iPar++) { | |
357 | /* TF1Helper problem on alien compilation | |
358 | for(Int_t jPar=iPar; jPar<fFuncSigBack->GetNpar(); jPar++) { | |
359 | TF1 gradientIpar("gradientIpar", | |
360 | ROOT::TF1Helper::TGradientParFunction(iPar-fFuncSignal->GetNpar(),fFuncBackground),0,0,0); | |
361 | TF1 gradientJpar("gradientJpar", | |
362 | ROOT::TF1Helper::TGradientParFunction(jPar-fFuncSignal->GetNpar(),fFuncBackground),0,0,0); | |
363 | fErrors(1) += pmFitResult->CovMatrix(iPar,jPar)* | |
364 | gradientIpar.Integral(fIntMin, fIntMax)*gradientJpar.Integral(fIntMin, fIntMax)* | |
365 | (iPar==jPar ? 1.0 : 2.0); | |
366 | } | |
367 | */ | |
368 | } | |
369 | } | |
370 | else { | |
371 | // signal | |
372 | fValues(0) = fHistSignal->IntegralAndError(fHistSignal->FindBin(fIntMin), | |
373 | fHistSignal->FindBin(fIntMax), fErrors(0)); | |
374 | // background | |
375 | fValues(1) = fHistBackground->IntegralAndError(fHistBackground->FindBin(fIntMin), | |
376 | fHistBackground->FindBin(fIntMax), | |
377 | fErrors(1)); | |
378 | } | |
379 | // S/B and significance | |
380 | SetSignificanceAndSOB(); | |
381 | fValues(4) = fFuncSigBack->GetParameter(fParMass); | |
382 | fErrors(4) = fFuncSigBack->GetParError(fParMass); | |
383 | fValues(5) = fFuncSigBack->GetParameter(fParMassWidth); | |
384 | fErrors(5) = fFuncSigBack->GetParError(fParMassWidth); | |
385 | ||
386 | fProcessed = kTRUE; | |
387 | ||
388 | fHistBackground->GetListOfFunctions()->Add(fFuncBackground); | |
389 | ||
390 | } | |
391 | ||
392 | //______________________________________________ | |
393 | void AliDielectronSignalFunc::ProcessFitLS(TObjArray * const arrhist) { | |
394 | // | |
395 | // Substract background using the like-sign spectrum | |
396 | // | |
397 | fHistDataPP = (TH1F*)(arrhist->At(0))->Clone("histPP"); // ++ SE | |
398 | fHistDataPM = (TH1F*)(arrhist->At(1))->Clone("histPM"); // +- SE | |
399 | fHistDataMM = (TH1F*)(arrhist->At(2))->Clone("histMM"); // -- SE | |
400 | if (fRebin>1) { | |
401 | fHistDataPP->Rebin(fRebin); | |
402 | fHistDataPM->Rebin(fRebin); | |
403 | fHistDataMM->Rebin(fRebin); | |
404 | } | |
405 | fHistDataPP->Sumw2(); | |
406 | fHistDataPM->Sumw2(); | |
407 | fHistDataMM->Sumw2(); | |
408 | ||
409 | fHistSignal = new TH1F("HistSignal", "Like-Sign substracted signal", | |
410 | fHistDataPM->GetXaxis()->GetNbins(), | |
411 | fHistDataPM->GetXaxis()->GetXmin(), fHistDataPM->GetXaxis()->GetXmax()); | |
412 | fHistBackground = new TH1F("HistBackground", "Like-sign contribution", | |
413 | fHistDataPM->GetXaxis()->GetNbins(), | |
414 | fHistDataPM->GetXaxis()->GetXmin(), fHistDataPM->GetXaxis()->GetXmax()); | |
415 | ||
416 | // fit the +- mass distribution | |
417 | fHistDataPM->Fit(fFuncSigBack, fFitOpt.Data(), "", fFitMin, fFitMax); | |
418 | fHistDataPM->Fit(fFuncSigBack, fFitOpt.Data(), "", fFitMin, fFitMax); | |
419 | // declare the variables where the like-sign fit results will be stored | |
420 | // TFitResult *ppFitResult = 0x0; | |
421 | // TFitResult *mmFitResult = 0x0; | |
422 | // fit the like sign background | |
423 | TF1 *funcClonePP = (TF1*)fFuncBackground->Clone("funcClonePP"); | |
424 | TF1 *funcCloneMM = (TF1*)fFuncBackground->Clone("funcCloneMM"); | |
425 | fHistDataPP->Fit(funcClonePP, fFitOpt.Data(), "", fFitMin, fFitMax); | |
426 | fHistDataPP->Fit(funcClonePP, fFitOpt.Data(), "", fFitMin, fFitMax); | |
427 | // TFitResultPtr ppFitPtr = fHistDataPP->Fit(funcClonePP, fFitOpt.Data(), "", fFitMin, fFitMax); | |
428 | // ppFitResult = ppFitPtr.Get(); | |
429 | fHistDataMM->Fit(funcCloneMM, fFitOpt.Data(), "", fFitMin, fFitMax); | |
430 | fHistDataMM->Fit(funcCloneMM, fFitOpt.Data(), "", fFitMin, fFitMax); | |
431 | // TFitResultPtr mmFitPtr = fHistDataMM->Fit(funcCloneMM, fFitOpt.Data(), "", fFitMin, fFitMax); | |
432 | // mmFitResult = mmFitPtr.Get(); | |
433 | ||
434 | for(Int_t iBin=1; iBin<=fHistDataPM->GetXaxis()->GetNbins(); iBin++) { | |
435 | Double_t m = fHistDataPM->GetBinCenter(iBin); | |
436 | Double_t pm = fHistDataPM->GetBinContent(iBin); | |
437 | Double_t pp = funcClonePP->Eval(m); | |
438 | Double_t mm = funcCloneMM->Eval(m); | |
439 | Double_t epm = fHistDataPM->GetBinError(iBin); | |
440 | Double_t epp = 0; | |
441 | for(Int_t iPar=0; iPar<funcClonePP->GetNpar(); iPar++) { | |
442 | /* TF1Helper problem on alien compilation | |
443 | for(Int_t jPar=iPar; jPar<funcClonePP->GetNpar(); jPar++) { | |
444 | TF1 gradientIpar("gradientIpar", | |
445 | ROOT::TF1Helper::TGradientParFunction(iPar,funcClonePP),0,0,0); | |
446 | TF1 gradientJpar("gradientJpar", | |
447 | ROOT::TF1Helper::TGradientParFunction(jPar,funcClonePP),0,0,0); | |
448 | epp += ppFitResult->CovMatrix(iPar,jPar)* | |
449 | gradientIpar.Eval(m)*gradientJpar.Eval(m)* | |
450 | (iPar==jPar ? 1.0 : 2.0); | |
451 | } | |
452 | */ | |
453 | } | |
454 | Double_t emm = 0; | |
455 | for(Int_t iPar=0; iPar<funcCloneMM->GetNpar(); iPar++) { | |
456 | /* TF1Helper problem on alien compilation | |
457 | for(Int_t jPar=iPar; jPar<funcCloneMM->GetNpar(); jPar++) { | |
458 | TF1 gradientIpar("gradientIpar", | |
459 | ROOT::TF1Helper::TGradientParFunction(iPar,funcCloneMM),0,0,0); | |
460 | TF1 gradientJpar("gradientJpar", | |
461 | ROOT::TF1Helper::TGradientParFunction(jPar,funcCloneMM),0,0,0); | |
462 | emm += mmFitResult->CovMatrix(iPar,jPar)* | |
463 | gradientIpar.Eval(m)*gradientJpar.Eval(m)* | |
464 | (iPar==jPar ? 1.0 : 2.0); | |
465 | } | |
466 | */ | |
467 | } | |
468 | ||
469 | Double_t signal = pm-2.0*TMath::Sqrt(pp*mm); | |
470 | Double_t background = 2.0*TMath::Sqrt(pp*mm); | |
471 | // error propagation on the signal calculation above | |
472 | Double_t esignal = TMath::Sqrt(epm*epm+(mm/pp)*epp+(pp/mm)*emm); | |
473 | Double_t ebackground = TMath::Sqrt((mm/pp)*epp+(pp/mm)*emm); | |
474 | fHistSignal->SetBinContent(iBin, signal); | |
475 | fHistSignal->SetBinError(iBin, esignal); | |
476 | fHistBackground->SetBinContent(iBin, background); | |
477 | fHistBackground->SetBinError(iBin, ebackground); | |
478 | } | |
479 | ||
480 | // signal | |
481 | fValues(0) = fHistSignal->IntegralAndError(fHistSignal->FindBin(fIntMin), | |
482 | fHistSignal->FindBin(fIntMax), fErrors(0)); | |
483 | // background | |
484 | fValues(1) = fHistBackground->IntegralAndError(fHistBackground->FindBin(fIntMin), | |
485 | fHistBackground->FindBin(fIntMax), | |
486 | fErrors(1)); | |
487 | // S/B and significance | |
488 | SetSignificanceAndSOB(); | |
489 | fValues(4) = fFuncSigBack->GetParameter(fParMass); | |
490 | fErrors(4) = fFuncSigBack->GetParError(fParMass); | |
491 | fValues(5) = fFuncSigBack->GetParameter(fParMassWidth); | |
492 | fErrors(5) = fFuncSigBack->GetParError(fParMassWidth); | |
493 | ||
494 | fProcessed = kTRUE; | |
495 | } | |
496 | ||
497 | //______________________________________________ | |
498 | void AliDielectronSignalFunc::ProcessFitEM(TObjArray * const arrhist) { | |
499 | // | |
500 | // Substract background with the event mixing technique | |
501 | // | |
502 | arrhist->GetEntries(); // just to avoid the unused parameter warning | |
503 | AliError("Event mixing for background substraction method not implemented!"); | |
504 | } | |
505 | ||
506 | //______________________________________________ | |
507 | void AliDielectronSignalFunc::SetFunctions(TF1 * const combined, TF1 * const sig, TF1 * const back, | |
508 | Int_t parM, Int_t parMres) | |
509 | { | |
510 | // | |
511 | // Set the signal, background functions and combined fit function | |
512 | // Note: The process method assumes that the first n parameters in the | |
513 | // combined fit function correspond to the n parameters of the signal function | |
514 | // and the n+1 to n+m parameters to the m parameters of the background function!!! | |
515 | ||
516 | if (!sig||!back||!combined) { | |
517 | AliError("Both, signal and background function need to be set!"); | |
518 | return; | |
519 | } | |
520 | fFuncSignal=sig; | |
521 | fFuncBackground=back; | |
522 | fFuncSigBack=combined; | |
523 | fParMass=parM; | |
524 | fParMassWidth=parMres; | |
525 | ||
526 | } | |
527 | ||
528 | //______________________________________________ | |
529 | void AliDielectronSignalFunc::SetDefaults(Int_t type) | |
530 | { | |
531 | // | |
532 | // Setup some default functions: | |
533 | // type = 0: gaus signal + linear background in 2.5 - 4 GeV inv. mass | |
534 | // type = 1: gaus signal + exponential background in 2.5 - 4 GeV inv. mass | |
535 | // type = 2: half gaussian, half exponential signal function | |
536 | // type = 3: Crystal-Ball function | |
537 | // type = 4: Crystal-Ball signal + exponential background | |
538 | // | |
539 | ||
540 | if (type==0){ | |
541 | fFuncSignal=new TF1("DieleSignal","gaus",2.5,4); | |
542 | fFuncBackground=new TF1("DieleBackground","pol1",2.5,4); | |
543 | fFuncSigBack=new TF1("DieleCombined","gaus+pol1(3)",2.5,4); | |
544 | ||
545 | fFuncSigBack->SetParameters(1,3.1,.05,2.5,1); | |
546 | fFuncSigBack->SetParLimits(0,0,10000000); | |
547 | fFuncSigBack->SetParLimits(1,3.05,3.15); | |
548 | fFuncSigBack->SetParLimits(2,.02,.1); | |
549 | } | |
550 | else if (type==1){ | |
551 | fFuncSignal=new TF1("DieleSignal","gaus",2.5,4); | |
552 | fFuncBackground=new TF1("DieleBackground","[0]*exp(-(x-[1])/[2])",2.5,4); | |
553 | fFuncSigBack=new TF1("DieleCombined","gaus+[3]*exp(-(x-[4])/[5])",2.5,4); | |
554 | ||
555 | fFuncSigBack->SetParameters(1,3.1,.05,1,2.5,1); | |
556 | fFuncSigBack->SetParLimits(0,0,10000000); | |
557 | fFuncSigBack->SetParLimits(1,3.05,3.15); | |
558 | fFuncSigBack->SetParLimits(2,.02,.1); | |
559 | } | |
560 | else if (type==2){ | |
561 | // half gaussian, half exponential signal function | |
562 | // exponential background | |
563 | 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); | |
564 | fFuncBackground = new TF1("DieleBackground","[0]*exp(-(x-[1])/[2])+[3]",2.5,4); | |
565 | 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); | |
566 | fFuncSigBack->SetParameters(1.,3.1,.05,.1,1,2.5,1,0); | |
567 | ||
568 | fFuncSigBack->SetParLimits(0,0,10000000); | |
569 | fFuncSigBack->SetParLimits(1,3.05,3.15); | |
570 | fFuncSigBack->SetParLimits(2,.02,.1); | |
571 | fFuncSigBack->FixParameter(6,2.5); | |
572 | fFuncSigBack->FixParameter(7,0); | |
573 | } | |
574 | } | |
575 | ||
576 | ||
577 | //______________________________________________ | |
578 | void AliDielectronSignalFunc::Draw(const Option_t* option) | |
579 | { | |
580 | // | |
581 | // Draw the fitted function | |
582 | // | |
583 | ||
584 | TString drawOpt(option); | |
585 | drawOpt.ToLower(); | |
586 | ||
587 | Bool_t optStat=drawOpt.Contains("stat"); | |
588 | ||
589 | fFuncSigBack->SetNpx(200); | |
590 | fFuncSigBack->SetRange(fIntMin,fIntMax); | |
591 | fFuncBackground->SetNpx(200); | |
592 | fFuncBackground->SetRange(fIntMin,fIntMax); | |
593 | ||
594 | TGraph *grSig=new TGraph(fFuncSigBack); | |
595 | grSig->SetFillColor(kGreen); | |
596 | grSig->SetFillStyle(3001); | |
597 | ||
598 | TGraph *grBack=new TGraph(fFuncBackground); | |
599 | grBack->SetFillColor(kRed); | |
600 | grBack->SetFillStyle(3001); | |
601 | ||
602 | grSig->SetPoint(0,grBack->GetX()[0],grBack->GetY()[0]); | |
603 | grSig->SetPoint(grSig->GetN()-1,grBack->GetX()[grBack->GetN()-1],grBack->GetY()[grBack->GetN()-1]); | |
604 | ||
605 | grBack->SetPoint(0,grBack->GetX()[0],0.); | |
606 | grBack->SetPoint(grBack->GetN()-1,grBack->GetX()[grBack->GetN()-1],0.); | |
607 | ||
608 | fFuncSigBack->SetRange(fFitMin,fFitMax); | |
609 | fFuncBackground->SetRange(fFitMin,fFitMax); | |
610 | ||
611 | if (!drawOpt.Contains("same")){ | |
612 | if (fHistDataPM){ | |
613 | fHistDataPM->Draw(); | |
614 | grSig->Draw("f"); | |
615 | } else { | |
616 | grSig->Draw("af"); | |
617 | } | |
618 | } else { | |
619 | grSig->Draw("f"); | |
620 | } | |
621 | if(fMethod==kFitted || fMethod==kFittedMC) grBack->Draw("f"); | |
622 | fFuncSigBack->Draw("same"); | |
623 | fFuncSigBack->SetLineWidth(2); | |
624 | if(fMethod==kLikeSign) { | |
625 | fHistDataPP->SetLineWidth(2); | |
626 | fHistDataPP->SetLineColor(6); | |
627 | fHistDataPP->Draw("same"); | |
628 | fHistDataMM->SetLineWidth(2); | |
629 | fHistDataMM->SetLineColor(8); | |
630 | fHistDataMM->Draw("same"); | |
631 | } | |
632 | ||
633 | if(fMethod==kFitted || fMethod==kFittedMC) | |
634 | fFuncBackground->Draw("same"); | |
635 | ||
636 | if (optStat) DrawStats(); | |
637 | ||
638 | } | |
639 | ||
640 | ||
641 | //______________________________________________________________________________ | |
642 | void AliDielectronSignalFunc::CombineFunc(TF1 * const peak, TF1 * const bgnd) { | |
643 | // | |
644 | // combine the bgnd and the peak function | |
645 | // | |
646 | ||
647 | if (!peak||!bgnd) { | |
648 | AliError("Both, signal and background function need to be set!"); | |
649 | return; | |
650 | } | |
651 | fFuncSignal=peak; | |
652 | fFuncBackground=bgnd; | |
653 | ||
654 | fNparPeak = fFuncSignal->GetNpar(); | |
655 | fNparBgnd = fFuncBackground->GetNpar(); | |
656 | ||
657 | fFuncSigBack = new TF1("BgndPeak",AliDielectronSignalFunc::PeakBgndFun, fFitMin,fFitMax, fNparPeak+fNparBgnd); | |
658 | return; | |
659 | } | |
660 | ||
661 | //______________________________________________________________________________ | |
662 | Double_t AliDielectronSignalFunc::PeakBgndFun(const Double_t *x, const Double_t *par) { | |
663 | // | |
664 | // merge peak and bgnd functions | |
665 | // | |
666 | return (fFuncSignal->EvalPar(x,par) + fFuncBackground->EvalPar(x,par+fNparPeak)); | |
667 | } | |
668 |