CbmRoot
Loading...
Searching...
No Matches
PairAnalysisFunction.cxx
Go to the documentation of this file.
1/* Copyright (C) 2015-2020 Justus-Liebig-Universitaet Giessen, Giessen
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Julian Book [committer] */
4
6// PairAnalysis Function //
7// //
8// //
9/*
10
11 1) add any background function you like
12 TF1 *fB = new TF1("fitBgrd","pol3",minFit,maxFit);
13
14 2) configure the signal extraction
15
16 2.1) chose one of the signal functions (MCshape, CrystalBall, Gauss, PowGaussPow, ExpGaussExp)
17 TF1 *fS = new TF1("fitSign",PairAnalysisFunction::PeakFunCB,minFit,maxFit,5); // has 5 parameters
18 // sig->SetMCSignalShape(hMCsign);
19 // TF1 *fS = new TF1("fitSign",PairAnalysisFunction::PeakFunMC,minFit,maxFit,1); // requires a MC shape
20
21 OR
22
23 2.2) one of the other predefined function (Boltzmann, PtExp, Hagedorn, Levi)
24
25
26 3) combined fit of bgrd+signal
27
28 3.1) combine the two functions
29 sig->CombineFunc(fS,fB);
30 3.2) apply fitting ranges and the fit options
31 sig->SetFitRange(minFit, maxFit);
32 sig->SetFitOption("NR");
33
34
35 6) access the spectra and values created
36
37 6.1) fit function
38 TF1 *fFitSign = sig->GetCombinedFunction(); // combined fit function
39 TF1 *fFitExtr = sig->GetSignalFunction(); // signal function
40 TF1 *fFitBgrd = sig->GetBackgroundFunction(); // background function
41
42*/
43// //
45
46#include <TF1.h>
47#include <TFitResult.h>
48#include <TGraph.h>
49#include <TH1.h>
50#include <TList.h>
51#include <TMath.h>
52#include <TNamed.h>
53#include <TPaveText.h>
54#include <TString.h>
55//#include <../hist/hist/src/TF1Helper.h>
56
58
59
61
63
64PairAnalysisFunction::PairAnalysisFunction() : PairAnalysisFunction("PairAnalysisFunction", "fcttitle")
65{
66 //
67 // Default Constructor
68 //
69}
70
71//______________________________________________
72PairAnalysisFunction::PairAnalysisFunction(const char* name, const char* title) : TNamed(name, title)
73{
74 //
75 // Named Constructor
76 //
77}
78
79//______________________________________________
81 : TNamed(c.GetName(), c.GetTitle())
82 , fFitMin(c.GetFitMin())
83 , fFitMax(c.GetFitMax())
84 , fPOIpdg(c.GetParticleOfInterest())
85{
86 //
87 // Copy Constructor
88 //
89}
90
91
92//______________________________________________
94{
95 //
96 // Default Destructor
97 //
98 if (fFuncSigBack) delete fFuncSigBack;
99 if (fFuncSignal) delete fFuncSignal;
101}
102
103
104//______________________________________________________________________________
105Double_t PairAnalysisFunction::PeakFunMC(const Double_t* x, const Double_t* par)
106{
107 // Fit MC signal shape
108 // parameters
109 // [0]: scale for simpeak
110
111 Double_t xx = x[0];
112
113 TH1F* hPeak = fgHistSimPM;
114 if (!hPeak) {
115 printf("E-PairAnalysisFunction::PeakFun: No histogram for peak fit defined!\n");
116 return 0.0;
117 }
118
119 Int_t idx = hPeak->FindBin(xx);
120 if ((idx <= 1) || (idx >= hPeak->GetNbinsX())) { return 0.0; }
121
122 return (par[0] * hPeak->GetBinContent(idx));
123}
124
125//______________________________________________________________________________
126Double_t PairAnalysisFunction::PeakFunCB(const Double_t* x, const Double_t* par)
127{
128 // Crystal Ball fit function
129
130 Double_t n = par[0];
131 Double_t alpha = par[1];
132 Double_t meanx = par[2];
133 Double_t sigma = par[3];
134 Double_t nn = par[4];
135
136 Double_t a = TMath::Power((n / TMath::Abs(alpha)), n) * TMath::Exp(-.5 * alpha * alpha);
137 Double_t b = n / TMath::Abs(alpha) - TMath::Abs(alpha);
138
139 Double_t arg = (x[0] - meanx) / sigma;
140 Double_t fitval = 0;
141
142 if (arg > -1. * alpha) {
143 fitval = nn * TMath::Exp(-.5 * arg * arg); //gaussian part
144 }
145 else {
146 fitval = nn * a * TMath::Power((b - arg), (-1 * n));
147 }
148
149 return fitval;
150}
151
152//______________________________________________________________________________
153Double_t PairAnalysisFunction::PeakFunPowGaussPow(const Double_t* x, const Double_t* par)
154{
155 // PowGaussPow function fit function (both sided Crystall Ball)
156
157 Double_t n = par[0];
158 Double_t alpha = par[1];
159 Double_t nn = par[4];
160 Double_t meanx = par[2];
161 Double_t sigma = par[3];
162
163 Double_t a = TMath::Power((n / TMath::Abs(alpha)), n) * TMath::Exp(-.5 * alpha * alpha);
164 Double_t b = n / TMath::Abs(alpha) - TMath::Abs(alpha);
165
166 Double_t arg = (x[0] - meanx) / sigma;
167 Double_t fitval = 0;
168
169 if (arg > alpha) { fitval = nn * a * TMath::Power((b + arg), (-1 * n)); }
170 else if (arg < -alpha) {
171 fitval = nn * a * TMath::Power((b - arg), (-1 * n));
172 }
173 else {
174 fitval = nn * TMath::Exp(-0.5 * arg * arg); //gaussian part
175 }
176
177 return fitval;
178}
179
180//______________________________________________________________________________
181Double_t PairAnalysisFunction::PeakFunExpGaussExp(const Double_t* x, const Double_t* par)
182{
183 // ExpGaussExp function fit function
184
185 Double_t n = par[0];
186 Double_t alpha = par[1];
187
188 Double_t meanx = par[2];
189 Double_t sigma = par[3];
190
191 Double_t arg = (x[0] - meanx) / sigma;
192 Double_t fitval = 0;
193
194 if (arg > alpha) { fitval = n * TMath::Exp(-0.5 * alpha * alpha - alpha * arg); }
195 else if (arg < -alpha) {
196 fitval = n * TMath::Exp(-0.5 * alpha * alpha + alpha * arg);
197 }
198 else {
199 fitval = n * TMath::Exp(-0.5 * arg * arg); //gaussian part
200 }
201
202 return fitval;
203}
204
205//______________________________________________________________________________
206Double_t PairAnalysisFunction::PeakFunGauss(const Double_t* x, const Double_t* par)
207{
208 // Gaussian fit function
209
210 //printf("fNparBgrd %d \n",fNparBgnd);
211 Double_t n = par[0];
212 Double_t mean = par[1];
213 Double_t sigma = par[2];
214 Double_t xx = x[0];
215
216 return (n * TMath::Exp(-0.5 * TMath::Power((xx - mean) / sigma, 2)));
217}
218
219//______________________________________________
220void PairAnalysisFunction::SetFunctions(TF1* const combined, TF1* const sig, TF1* const back, Int_t parM, Int_t parMres)
221{
222 //
223 // Set the signal, background functions and combined fit function
224 // Note: The process method assumes that the first n parameters in the
225 // combined fit function correspond to the n parameters of the signal function
226 // and the n+1 to n+m parameters to the m parameters of the background function!!!
227
228 if (!sig || !back || !combined) {
229 Error("SetFunctions", "Both, signal and background function need to be set!");
230 return;
231 }
232 fFuncSignal = sig;
233 fFuncBackground = back;
234 fFuncSigBack = combined;
235 fParMass = parM;
236 fParMassWidth = parMres;
237}
238
239//______________________________________________
241{
245 switch (predefinedFunc) {
246 case EFunction::kBoltzmann: GetBoltzmann(); break;
247 case EFunction::kPtExp: GetPtExp(); break;
248 case EFunction::kHagedorn: GetHagedorn(); break;
249 case EFunction::kLevi: GetLevi(); break;
250 default: Error("SetDefault", "predefined function not yet implemented");
251 }
252}
253
254//______________________________________________
256{
257 //
258 // Setup some default functions:
259 // type = 0: gaus signal + linear background in 2.5 - 4 GeV inv. mass
260 // type = 1: gaus signal + exponential background in 2.5 - 4 GeV inv. mass
261 // type = 2: half gaussian, half exponential signal function
262 // type = 3: Crystal-Ball function
263 // type = 4: Crystal-Ball signal + exponential background
264 //
265 // TODO: use PDG mass and width + fPOI for parameter settings
266
267 if (type == 0) {
268 fFuncSignal = new TF1("DieleSignal", "gaus", 2.5, 4);
269 fFuncBackground = new TF1("DieleBackground", "pol1", 2.5, 4);
270 fFuncSigBack = new TF1("DieleCombined", "gaus+pol1(3)", 2.5, 4);
271
272 fFuncSigBack->SetParameters(1, 3.1, .05, 2.5, 1);
273 fFuncSigBack->SetParLimits(0, 0, 10000000);
274 fFuncSigBack->SetParLimits(1, 3.05, 3.15);
275 fFuncSigBack->SetParLimits(2, .02, .1);
276 }
277 else if (type == 1) {
278 fFuncSignal = new TF1("DieleSignal", "gaus", 2.5, 4);
279 fFuncBackground = new TF1("DieleBackground", "[0]*exp(-(x-[1])/[2])", 2.5, 4);
280 fFuncSigBack = new TF1("DieleCombined", "gaus+[3]*exp(-(x-[4])/[5])", 2.5, 4);
281
282 fFuncSigBack->SetParameters(1, 3.1, .05, 1, 2.5, 1);
283 fFuncSigBack->SetParLimits(0, 0, 10000000);
284 fFuncSigBack->SetParLimits(1, 3.05, 3.15);
285 fFuncSigBack->SetParLimits(2, .02, .1);
286 }
287 else if (type == 2) {
288 // half gaussian, half exponential signal function
289 // exponential background
290 fFuncSignal = new TF1("DieleSignal",
291 "(x<[1])*([0]*(exp(-0.5*((x-[1])/[2])^2)+exp((x-[1])/"
292 "[3])*(1-exp(-0.5*((x-[1])/"
293 "[2])^2))))+(x>=[1])*([0]*exp(-0.5*((x-[1])/[2])^2))",
294 2.5, 4);
295 fFuncBackground = new TF1("DieleBackground", "[0]*exp(-(x-[1])/[2])+[3]", 2.5, 4);
296 fFuncSigBack = new TF1("DieleCombined",
297 "(x<[1])*([0]*(exp(-0.5*((x-[1])/[2])^2)+exp((x-[1])/"
298 "[3])*(1-exp(-0.5*((x-[1])/[2])^2))))+(x>=[1])*([0]*exp(-0.5*((x-[1])/"
299 "[2])^2))+[4]*exp(-(x-[5])/[6])+[7]",
300 2.5, 4);
301 fFuncSigBack->SetParameters(1., 3.1, .05, .1, 1, 2.5, 1, 0);
302
303 fFuncSigBack->SetParLimits(0, 0, 10000000);
304 fFuncSigBack->SetParLimits(1, 3.05, 3.15);
305 fFuncSigBack->SetParLimits(2, .02, .1);
306 fFuncSigBack->FixParameter(6, 2.5);
307 fFuncSigBack->FixParameter(7, 0);
308 }
309}
310
311//______________________________________________________________________________
312void PairAnalysisFunction::CombineFunc(TF1* const peak, TF1* const bgnd)
313{
314 //
315 // combine the bgnd and the peak function
316 //
317
318 if (!peak) {
319 Error("CombineFunc", "signal function need to be set!");
320 return;
321 }
322 fFuncSignal = peak;
323 fFuncBackground = bgnd;
324
325 fNparPeak = fFuncSignal->GetNpar();
326 fNparBgnd = (bgnd ? fFuncBackground->GetNpar() : 0);
327
329 return;
330}
331
332//______________________________________________________________________________
333Double_t PairAnalysisFunction::PeakBgndFun(const Double_t* x, const Double_t* par)
334{
335 //
336 // merge peak and bgnd functions
337 //
338 return (fFuncSignal->EvalPar(x, par) + (fFuncBackground ? fFuncBackground->EvalPar(x, par + fNparPeak) : 0.));
339}
340
341//______________________________________________
342//void PairAnalysisFunction::Print(Option_t */*option*/) const
343//{
344//
345// Print the statistics
346//
347// printf("Fit int. : %.5g - %.5g \n",fFitMin,fFitMax);
348// printf("Fit chi/%d: %.5g \n",fDof,fChi2Dof);
349//}
350
351
352//______________________________________________
354{
355 // Boltzmann (exp in 1/mt*dNdmT times mt) as a function of dNdpt
356 fFuncSigBack = new TF1("Boltzmann", "[1]*x*sqrt(x*x+[0]*[0])*exp(-sqrt(x*x+[0]*[0])/[2])", 0., 10.);
357 // fFuncSigBack->SetParameters(fPOI->Mass(), norm, temp);
358 if (fPOI) fFuncSigBack->FixParameter(0, fPOI->Mass());
359 fFuncSigBack->SetParLimits(2, 0.01, 10);
360 fFuncSigBack->SetParNames("mass", "norm", "T");
361 return fFuncSigBack;
362}
363
364//______________________________________________
366{
367 // Simple exponential in 1/pt*dNdpT, as a function of dNdpt
368 fFuncSigBack = new TF1("Exponential", "[0]*x*exp(-x/[1])", 0., 10.);
369 // fFuncSigBack->SetParameters(norm, temp);
370 fFuncSigBack->SetParLimits(1, 0.01, 10);
371 fFuncSigBack->SetParNames("norm", "T");
372 return fFuncSigBack;
373}
374
375//______________________________________________
377{
378 // PowerLaw function, dNdpt
379 // power law Nuclear Physics B, Vol. 335, No. 2. (7 May 1990), pp. 261-287.
380 // This is sometimes also called Hagedorn or modified Hagedorn
381 fFuncSigBack = new TF1("Hagedorn", "x*[0]*( 1 + x/[1] )^(-[2])", 0., 10.);
382 // fFuncSigBack->SetParameters(norm, pt0, n);
383 fFuncSigBack->SetParLimits(1, 0.01, 10);
384 //fFuncSigBack->SetParLimits(2, 0.01, 50);
385 fFuncSigBack->SetParNames("norm", "pt0", "n");
386 return fFuncSigBack;
387}
388
389//______________________________________________
391{
392 // Levi function (aka Tsallis), dNdpt
393 fFuncSigBack = new TF1("Levi-Tsallis",
394 "( x*[0]*([1]-1)*([1]-2) )/( [1]*[2]*( [1]*[2]+[3]*([1]-2) ) ) * "
395 "( 1 + (sqrt([3]*[3]+x*x) -[3])/([1]*[2]) )^(-[1])",
396 0., 10.);
397 // fFuncSigBack->SetParameters(norm, n, temp,mass);
398 if (fPOI) fFuncSigBack->FixParameter(3, fPOI->Mass());
399 fFuncSigBack->SetParLimits(2, 0.01, 10);
400 fFuncSigBack->SetParNames("norm (dN/dy)", "n", "T", "mass");
401 return fFuncSigBack;
402}
ClassImp(CbmConverterManager)
void SetFunctions(TF1 *const combined, TF1 *const sig=0, TF1 *const back=0, Int_t parM=1, Int_t parMres=2)
Double_t PeakFunExpGaussExp(const Double_t *x, const Double_t *par)
Double_t PeakFunGauss(const Double_t *x, const Double_t *par)
Double_t PeakBgndFun(const Double_t *x, const Double_t *par)
Double_t PeakFunMC(const Double_t *x, const Double_t *par)
void CombineFunc(TF1 *const peak=0, TF1 *const bgnd=0)
Double_t PeakFunPowGaussPow(const Double_t *x, const Double_t *par)
Double_t PeakFunCB(const Double_t *x, const Double_t *par)
void SetDefault(EFunction predefinedFunc)