CMS 3D CMS Logo

SiStripPulseShape.cc
Go to the documentation of this file.
2 #include <TF1.h>
3 #include <TMath.h>
4 
5 /* New Pulse Shape Fit by G. Auzinger June 2017
6 following methods are used to describe a pulse shape for a 3 stage CR-CR-RC pre-amplifier (CR)
7 + shaper (CR + RC) with time constants x, y, z respectively
8 some special cases (x=0. y=z, x=0 && y=z) are considered (divergence of equation) and
9 the shaper CR y is approximated via a pol(6) of x which gives a resonable respresentation and
10 reduces the number of free parameters -- this shape is derived from first principle and can
11 be used to fit peak mode signals and deconvolution mode signals
12 following parameters are added in addition to the time constants x, z:
13 a_0 ... baseline offset amplitude
14 s ... scale parameter
15 t_0 ... turn_on time of the pulse
16 par[5] ... scale parameter for the time slices in deco mode
17 */
18 
19 double pulse_raw(double x, double y, double z, double t) {
20  double result1, result2, result3;
21 
22  result1 = z * y * exp(-t / y);
23  result1 /= pow(y, 2) - (x + z) * y + z * x;
24 
25  result2 = z * x * exp(-t / x);
26  result2 /= pow(x, 2) - (x - z) * y - z * x;
27 
28  result3 = pow(z, 2) * exp(-t / z);
29  result3 /= pow(z, 2) + (x - z) * y - z * x;
30 
31  return result1 + result2 + result3;
32 }
33 
34 double pulse_x0(double y, double z, double t) { return z / (y - z) * (exp(-t / y) - exp(-t / z)); }
35 
36 double pulse_yz(double x, double z, double t) {
37  double result1, result2;
38 
39  result1 = exp(-t / x) - exp(-t / z);
40  result1 *= z * x / (z - x);
41 
42  result2 = t * exp(-t / z);
43 
44  return (result1 + result2) / (z - x);
45 }
46 
47 double pulse_x0_yz(double z, double t) { return t / z * exp(-t / z); }
48 
49 double pulse(double x, double y, double z, double t) {
50  if (x > y) {
51  double pivot = x;
52  x = y;
53  y = pivot;
54  }
55 
56  if ((x == 0) && (y == z))
57  return pulse_x0_yz(z, t);
58  else if (x == 0)
59  return pulse_x0(y, z, t);
60  else if (y == z)
61  return pulse_yz(x, z, t);
62  else
63  return pulse_raw(x, y, z, t);
64 }
65 
66 double fpeak(double *x, double *par) {
67  double xx = par[0];
68  double y = par[1];
69  double z = par[2];
70  double a_0 = par[3];
71  double s = par[4];
72  double t_0 = par[5];
73  double t = x[0] - t_0;
74 
75  // below turn-on time return just a constant
76  if (x[0] < t_0)
77  return a_0;
78  // elswhere return the pulse
79  return a_0 + s * pulse(xx, y, z, t);
80 }
81 
82 double fturnOn(double *x, double *par) {
83  double a_0 = par[0];
84  double s = par[1];
85  double t_0 = par[2];
86  double width = par[3];
87 
88  return a_0 + s * TMath::Erf((x[0] - t_0) / width);
89 }
90 
91 double fdecay(double *x, double *par) {
92  double s = par[0];
93  double c_exp = par[1];
94  double c_pow = par[2];
95 
96  return s * TMath::Exp(x[0] * c_exp) * (1 + x[0] * c_pow);
97 }
98 
99 double fdecay(double *x, double *par);
100 
101 double fdeconv(double *x, double *par) {
102  double xm = par[6] * (x[0] - 25);
103  double xp = par[6] * (x[0] + 25);
104  double xz = par[6] * x[0];
105  return 1.2131 * fpeak(&xp, par) - 1.4715 * fpeak(&xz, par) + 0.4463 * fpeak(&xm, par);
106 }
107 
108 double fpeak_convoluted(double *x, double *par) {
109  TF1 f("peak_convoluted", fpeak, 0, 250, 4);
110  return f.IntegralError(x[0] - par[4] / 2., x[0] + par[4] / 2., par, nullptr, 1.) / (par[4]);
111 }
112 
113 double fdeconv_convoluted(double *x, double *par) {
114  double xm = (x[0] - 25);
115  double xp = (x[0] + 25);
116  double xz = x[0];
117  return 1.2131 * fpeak_convoluted(&xp, par) - 1.4715 * fpeak_convoluted(&xz, par) +
118  0.4463 * fpeak_convoluted(&xm, par);
119 }
double fdeconv_convoluted(double *x, double *par)
double pulse_x0(double y, double z, double t)
double fdecay(double *x, double *par)
double fpeak_convoluted(double *x, double *par)
constexpr int pow(int x)
Definition: conifer.h:24
double pulse_yz(double x, double z, double t)
double pulse(double x, double y, double z, double t)
float float float z
double fdeconv(double *x, double *par)
double pulse_raw(double x, double y, double z, double t)
double f[11][100]
double fpeak(double *x, double *par)
double fturnOn(double *x, double *par)
float x
double pulse_x0_yz(double z, double t)