wavecatcher-analysis
Loading...
Searching...
No Matches
FitFunctions.h
Go to the documentation of this file.
1
6class Fitf {
7public:
17 double operator() (double* x, double* p) {
18 double sum = 0;
19 int kmax = static_cast<int>(ceil(p[1])) * 10;
20
21 double mu = p[1];
22 double lambda = p[2];
23
24 double sigma0 = p[3];
25 double sigma1 = p[4];
26
27 double G = p[5];
28 double B = p[6];
29
30 for (int kint = 0; kint <= kmax; kint++) {
31 double k = static_cast<double>(kint);
32 double sigmaK = sqrt(sigma0 * sigma0 + k * sigma1 * sigma1);
33 //generalized poisson envelope
34 double gp = mu * TMath::Power((mu + k * lambda), k - 1) * TMath::Exp(-(mu + k * lambda)) / TMath::Factorial(kint);
35
36 sum += p[0] * gp * (1. / sqrt(2. * TMath::Pi()) / sigmaK) * TMath::Exp(-TMath::Power(((x[0] - (k * G + B)) / sqrt(2) / sigmaK), 2.));
37 }
38 return sum;
39 };
40};
41
49class Fitf_full {
50public:
62 double operator() (double* x, double* p) {
63 double sum = 0;
64 int kmax = static_cast<int>(ceil(p[1])) * 10;
65
66 double mu = p[1];
67 double lambda = p[2];
68
69 double sigma0 = p[3];
70 double sigma1 = p[4];
71
72 double G = p[5];
73 double B = p[6];
74
75 double alpha = p[7];
76 double beta = p[8];
77
78 for (int kint = 0; kint <= kmax; kint++) {
79 //numbe of fired cells
80 double k = static_cast<double>(kint);
81 //pulse width
82 double sigmaK = sqrt(sigma0 * sigma0 + k * sigma1 * sigma1);
83 double gausnormsigmak = 1. / (sqrt(2. * TMath::Pi()) * sigmaK);
84 //gauss peak
85 double gauss = gausnormsigmak * TMath::Exp(-1. * TMath::Power(x[0] - (k * G + B), 2.) / (sigmaK * sigmaK * 2.));
86
87 //generalized poisson envelope
88 double gp = p[0] * mu * TMath::Power((mu + k * lambda), k - 1) * TMath::Exp(-(mu + k * lambda)) / TMath::Factorial(kint);
89
90 if (kint == 0) {
91 sum += (gp * gauss);
92 }
93 else {
94 //after-pulse + delayed cross talk
95 double bk0 = TMath::Power(1. - alpha, k);
96 double bk1 = TMath::Factorial(kint) / TMath::Factorial(kint - 1) * alpha * TMath::Power(1. - alpha, k - 1);
97 double pk1 = TMath::Exp(-1. * (x[0] - (k * G + B)) / beta) * gausnormsigmak / beta * sigmaK * sqrt(TMath::Pi() / 2) * (TMath::Erf((x[0] - (k * G + B)) / (sqrt(2) * sigmaK)) + 1.);
98
99
100 if (kint == 1) sum += gp * (bk0 * gauss + bk1 * pk1);
101 else {
102 double api2k = 0.;
103 for (int ii = 2; ii < kint; ii++) {
104 double iid = static_cast<double>(ii);
105 double bkialpha = TMath::Factorial(kint) / (TMath::Factorial(ii) * TMath::Factorial(kint - ii)) * TMath::Power(alpha, iid) * TMath::Power((1. - alpha), (k - iid));
106 double dpkidph = 0;
107 if (x[0] > (k * G + B)) dpkidph = TMath::Power((x[0] - (k * G + B)), (iid - 1.)) / (TMath::Factorial(ii - 1) * TMath::Power(beta, iid)) * TMath::Exp(-1. * (x[0] - (k * G + B)) / beta);
108 api2k += bkialpha * dpkidph;
109 }
110 sum += gp * (bk0 * gauss + bk1 * pk1 + api2k);
111 }
112 }
113 }
114 return sum;
115 };
116};
117
124public:
137 double operator() (double* x, double* p) {
138 double sum = 0;
139 int kmax = static_cast<int>(ceil(p[1])) * 10;
140
141 double mu = p[1];
142 double lambda = p[2];
143
144 double sigma0 = p[3];
145 double sigma1 = p[4];
146
147 double G = p[5];
148 double B = p[6];
149
150 double a_ped = p[7];
151 double x_ped = p[8];
152
153 for (int kint = 0; kint <= kmax; kint++) {
154 double k = static_cast<double>(kint);
155 double sigmaK = sqrt(sigma0 * sigma0 + k * sigma1 * sigma1);
156 //generalized poisson envelope
157 double gp = mu * TMath::Power((mu + k * lambda), k - 1) * TMath::Exp(-(mu + k * lambda)) / TMath::Factorial(kint);
158
159 if (kint == 0) {
160 sum += a_ped * p[0] * gp * (1. / sqrt(2. * TMath::Pi()) / sigmaK) * TMath::Exp(-TMath::Power(((x[0] - x_ped) / sqrt(2) / sigmaK), 2));
161 }
162 else {
163 sum += p[0] * gp * (1. / sqrt(2. * TMath::Pi()) / sigmaK) * TMath::Exp(-TMath::Power(((x[0] - (k * G + B)) / sqrt(2) / sigmaK), 2));
164 }
165 }
166 return sum;
167 };
168};
169
174class Fitf_PMT {
175public:
187 double operator() (double* x, double* p) {
188 double pmt_charge_spectrum = 0.;
189 int kmax = static_cast<int>(ceil(p[5])) * 10;
190
191 for (int kint = 0; kint <= kmax; kint++) {
192 double k = static_cast<double>(kint);
193
194 double poiss = TMath::Power(p[5], k) * TMath::Exp(-p[5]) / TMath::Factorial(kint);
195
196 double normgn_term = 1.;
197 if (kint != 0) normgn_term /= (p[6] * TMath::Sqrt(2. * TMath::Pi() * k));
198 double gn_term = (1. - p[1]) * normgn_term;
199 if (kint != 0) gn_term *= TMath::Exp(-1. * TMath::Power(x[0] - k * p[7] - p[4], 2.) / (2. * k * p[6] * p[6]));
200 else if (x[0] != p[4]) gn_term *= 0.; // delta function
201
202 double Qn = p[4] + k * p[7];
203 double sigman = TMath::Sqrt(p[3] * p[3] + k * p[6] * p[6]);
204 double ignxe_term_exp = p[2] / 2. * TMath::Exp(-1. * p[2] * (x[0] - Qn - p[2] * sigman * sigman));
205
206 double sgn_arg = x[0] - Qn - sigman * sigman * p[2];
207 double arg_sgn = 1.;
208 if (sgn_arg < 0.) arg_sgn = -1.;
209 double ignxe_term_erf = TMath::Erf(fabs(p[4] - Qn - sigman * sigman * p[2]) / (sigman * TMath::Sqrt(2.))) + arg_sgn * TMath::Erf(fabs(sgn_arg) / (sigman * TMath::Sqrt(2.)));
210
211 pmt_charge_spectrum += p[0] * poiss * (gn_term + p[1] * ignxe_term_exp * ignxe_term_erf);
212 }
213 if (pmt_charge_spectrum < 0.) pmt_charge_spectrum = 0.;
214 return pmt_charge_spectrum;
215 };
216};
217
224public:
237 double operator() (double* x, double* p) {
238 double pmt_charge_spectrum = 0.;
239 int kmax = static_cast<int>(ceil(p[5])) * 10;
240
241 for (int kint = 0; kint <= kmax; kint++) {
242 double k = static_cast<double>(kint);
243
244 double poiss = TMath::Power(p[5], k) * TMath::Exp(-p[5]) / TMath::Factorial(kint);
245
246 double normgn_term = 1.;
247 if (kint != 0) normgn_term /= (p[6] * TMath::Sqrt(2. * TMath::Pi() * k));
248 else normgn_term *= p[8] / (p[3] * TMath::Sqrt(2. * TMath::Pi()));
249 double gn_term = (1. - p[1]) * normgn_term;
250 if (kint != 0) gn_term *= TMath::Exp(-1. * TMath::Power(x[0] - k * p[7] - p[4], 2.) / (2. * k * p[6] * p[6]));
251 else gn_term *= TMath::Exp(-1. * TMath::Power(x[0] - p[4], 2.) / (2. * p[3] * p[3]));
252
253 double Qn = p[4] + k * p[7];
254 double sigman = TMath::Sqrt(p[3] * p[3] + k * p[6] * p[6]);
255 double ignxe_term_exp = p[2] / 2. * TMath::Exp(-1. * p[2] * (x[0] - Qn - p[2] * sigman * sigman));
256
257 double sgn_arg = x[0] - Qn - sigman * sigman * p[2];
258 double arg_sgn = 1.;
259 if (sgn_arg < 0.) arg_sgn = -1.;
260 double ignxe_term_erf = TMath::Erf(fabs(p[4] - Qn - sigman * sigman * p[2]) / (sigman * TMath::Sqrt(2.))) + arg_sgn * TMath::Erf(fabs(sgn_arg) / (sigman * TMath::Sqrt(2.)));
261
262 pmt_charge_spectrum += p[0] * poiss * (gn_term + p[1] * ignxe_term_exp * ignxe_term_erf);
263 }
264 if (pmt_charge_spectrum < 0.) pmt_charge_spectrum = 0.;
265 return pmt_charge_spectrum;
266 };
267};
268
275public:
283 double operator() (double* x, double* p) {
284 double pmt_charge_spectrum = 0.;
285
286 int kmax = static_cast<int>(ceil(p[1])) * 10;
287
288 for (int kint = 1; kint <= kmax; kint++) {
289 double k = static_cast<double>(kint);
290
291 double poiss = TMath::Power(p[1], k) * TMath::Exp(-p[1]) / TMath::Factorial(kint);
292
293 double norm = 1. / (p[2] * TMath::Sqrt(2. * TMath::Pi() * k));
294
295 double gauss = TMath::Exp(-1. * TMath::Power(x[0] - k * p[3], 2) / (2. * k * p[2] * p[2]));
296
297 pmt_charge_spectrum += p[0] * poiss * norm * gauss;
298 }
299 return pmt_charge_spectrum;
300 };
301};
302
313public:
321 double operator() (double* x, double* par) {
322 // Numeric constants
323 double invsq2pi = 0.3989422804014; // (2 pi)^(-1/2)
324 double mpshift = -0.22278298; // Landau maximum location
325
326 // Control constants
327 double np = 100.0; // number of convolution steps
328 double sc = 5.0; // convolution extends to +-sc Gaussian sigmas
329
330 // Variables
331 double xx;
332 double mpc;
333 double fland;
334 double sum = 0.0;
335 double xlow, xupp;
336 double step;
337 double i;
338
339
340 // MP shift correction
341 mpc = par[1] - mpshift * par[0];
342
343 // Range of convolution integral
344 xlow = x[0] - sc * par[3];
345 xupp = x[0] + sc * par[3];
346
347 step = (xupp - xlow) / np;
348
349 // Convolution integral of Landau and Gaussian by sum
350 for (i = 1.0; i <= np / 2; i++) {
351 xx = xlow + (i - .5) * step;
352 fland = TMath::Landau(xx, mpc, par[0]) / par[0];
353 sum += fland * TMath::Gaus(x[0], xx, par[3]);
354
355 xx = xupp - (i - .5) * step;
356 fland = TMath::Landau(xx, mpc, par[0]) / par[0];
357 sum += fland * TMath::Gaus(x[0], xx, par[3]);
358 }
359
360 return (par[2] * step * sum * invsq2pi / par[3]);
361 };
362};
363
370public:
382 double operator() (double* x, double* p) {
383 double sum = 0;
384 int kmax = static_cast<int>(ceil(p[1])) * 10;
385
386 double mu = p[1];
387 double lambda = p[2];
388
389 double sigma0 = p[3];
390 double sigma1 = p[4];
391
392 double G = p[5];
393 double B = p[6];
394
395 double mu_dc = p[7];
396 double N0_dc = p[8];
397
398 for (int kint = 0; kint <= kmax; kint++) {
399 double k = static_cast<double>(kint);
400 double sigmaK = sqrt(sigma0 * sigma0 + k * sigma1 * sigma1);
401 //generalized poisson envelope
402 double gp = ((1. - N0_dc) * (mu * TMath::Power((mu + k * lambda), k - 1) * TMath::Exp(-(mu + k * lambda))) + N0_dc * (mu_dc * TMath::Power((mu_dc + k * lambda), k - 1) * TMath::Exp(-(mu_dc + k * lambda)))) / TMath::Factorial(kint);
403
404 sum += p[0] * gp * (1. / sqrt(2. * TMath::Pi()) / sigmaK) * TMath::Exp(-TMath::Power(((x[0] - (k * G + B)) / sqrt(2) / sigmaK), 2));
405 }
406 return sum;
407 };
408};
409
412public:
420 double operator() (double* x, double* p) {
421 double k = 0;
422 int k_pm = 2; // how many Gaussians to consider -> k_pm=2 means 2+1+2=5 Gaussians
423 double A = p[0];
424 double mu = p[1];
425 double sigma = p[2];
426 double B = p[3];
427
428 double gauss = 0.;
429
430 for (int kint = -k_pm; kint <= k_pm; kint++) {
431 k = static_cast<double>(kint);
432 // periodic gauss
433 gauss += A * TMath::Exp(-TMath::Power(x[0] - mu + k * 360., 2.) / (2. * sigma * sigma));
434 }
435 return gauss + B;
436 };
437};
438
441public:
450 double operator() (double* x, double* par) {
451 // Control constants
452 Double_t sc = 5.; // integral extends to MPV-sc*(Gaussian sigma + Landau width)
453
454 // Variables
455 Double_t start = par[1] - sc * (par[0] + par[3]);
456
457 Fitf_langaus langaus;
458 TF1* langaus_fun = new TF1("fun", langaus, start - 1, x[0] + 1, 4);
459 langaus_fun->SetParameter(0, par[0]);
460 langaus_fun->SetParameter(1, par[1]);
461 langaus_fun->SetParameter(2, par[2]);
462 langaus_fun->SetParameter(3, par[3]);
463
464 return (par[4] * (1. - langaus_fun->Integral(start, x[0])));
465 };
466};
467
473public:
483
485 double operator() (double* x, double* par) {
486 // Range of the sum (should be significantly larger than the mean number of MIPs)
487 int kmax = static_cast<int>(ceil(par[5])) * 10;
488
489 Fitf_langaus langaus;
490 TF1* langaus_fun = new TF1("fun", langaus, 0, 1, 4);
491 langaus_fun->SetParameter(0, par[0]);
492 langaus_fun->SetParameter(2, par[2]);
493
494 double sum = 0.;
495 for (int kint = 1; kint <= kmax; kint++) {
496 double k = static_cast<double>(kint);
497
498 double peak_shift = (k - 1) * par[6];
499 langaus_fun->SetParameter(1, par[1] + peak_shift);
500
501 double sigmaK = sqrt(par[3] * par[3] + (k - 1) * par[4] * par[4]);
502 langaus_fun->SetParameter(3, sigmaK);
503
504 //poisson envelope
505 double poiss = TMath::Power(par[5], k) / (TMath::Factorial(kint) * (TMath::Exp(par[5]) - 1.));
506
507 sum += langaus_fun->Eval(x[0]) * poiss;
508 }
509 return sum;
510 };
511};
512
519public:
526 double operator() (double* x, double* par) {
527 double tau_eff = par[0];
528 double sigma_gauss = par[1];
529 double t_0 = par[2];
530 double norm = par[3];
531
532 double e_g = norm / (2 * TMath::Abs(tau_eff)) *
533 TMath::Exp((sigma_gauss * sigma_gauss + 2 * t_0 * tau_eff - 2 * tau_eff * x[0]) /
534 (2 * tau_eff * tau_eff)) *
535 TMath::Erfc((sigma_gauss * sigma_gauss + tau_eff * (t_0 - x[0])) /
536 (TMath::Sqrt2() * TMath::Abs(tau_eff) * sigma_gauss));
537
538 return e_g;
539 };
540};
Ideal PMT charge spectrum.
double operator()(double *x, double *p)
Gauss-Poisson distribution for fit of PMT charge spectra.
double operator()(double *x, double *p)
Gauss-Poisson distribution for fit of PMT charge spectra.
double operator()(double *x, double *p)
Fit function for SiPMs missing after-pulses and dark counts but with biased pedestal.
double operator()(double *x, double *p)
Convolution of an exponential and a gaussian.
double operator()(double *x, double *par)
Default fit function for SiPMs with after-pulses missing dark counts.
double operator()(double *x, double *p)
Integral of Landau-Gauss-Convolution ("S-curve")
double operator()(double *x, double *par)
Poisson-distributed Landau-Gauss-Convolutions.
double operator()(double *x, double *par)
Landau-Gauss-convolution.
double operator()(double *x, double *par)
Periodic gauss fit function for angular reconstruction of SiPM array signal (SHiP SBT WOM tube)
double operator()(double *x, double *p)
Fit function for SiPMs missing after-pulses and dark counts but including additional dark count spect...
double operator()(double *x, double *p)
Default fit function for SiPMs missing after-pulses and dark counts.
Definition FitFunctions.h:6
double operator()(double *x, double *p)