CbmRoot
Loading...
Searching...
No Matches
CbmKFMath.cxx
Go to the documentation of this file.
1/* Copyright (C) 2006-2019 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Denis Bertini [committer] */
4
5#include "CbmKFMath.h"
6
7#include "FairField.h"
8#include "FairTrackParam.h"
9
10#include <cmath>
11
12using std::exp;
13using std::fabs;
14using std::log;
15using std::sqrt;
16
18
19 Bool_t CbmKFMath::intersectCone(Double_t zCone, Double_t ZCone, Double_t rCone, Double_t RCone, const Double_t x[],
20 Double_t* z1, Double_t* z2)
21{
22 Double_t t = (RCone - rCone) / (ZCone - zCone);
23 Double_t A = (RCone * zCone - rCone * ZCone) / (ZCone - zCone);
24 Double_t x0 = x[0] - x[5] * x[2];
25 Double_t y0 = x[1] - x[5] * x[3];
26 Double_t tx = x[2];
27 Double_t ty = x[3];
28 Double_t a = tx * tx + ty * ty - t * t;
29 Double_t b = 2 * (tx * x0 + ty * y0 + t * A);
30 Double_t c = x0 * x0 + y0 * y0 - A * A;
31
32 if (fabs(a) < 1.E-4) {
33 return 1;
34 }
35 Double_t D = b * b - 4 * a * c;
36 if (D < 0.) {
37 return 1;
38 }
39 D = sqrt(D);
40 *z1 = (-b + D) / (2 * a);
41 *z2 = (-b - D) / (2 * a);
42 return 0;
43}
44
45
46void CbmKFMath::multQSQt(Int_t N, const Double_t Q[], const Double_t S[], Double_t S_out[])
47{
48 Double_t A[N * N];
49
50 for (Int_t i = 0, n = 0; i < N; i++) {
51 for (Int_t j = 0; j < N; j++, ++n) {
52 A[n] = 0;
53 for (Int_t k = 0; k < N; ++k) {
54 A[n] += S[indexS(i, k)] * Q[j * N + k];
55 }
56 }
57 }
58
59 for (Int_t i = 0; i < N; i++) {
60 for (Int_t j = 0; j <= i; j++) {
61 Int_t n = indexS(i, j);
62 S_out[n] = 0;
63 for (Int_t k = 0; k < N; k++) {
64 S_out[n] += Q[i * N + k] * A[k * N + j];
65 }
66 }
67 }
68}
69
70void CbmKFMath::multQtSQ(Int_t N, const Double_t Q[], const Double_t S[], Double_t S_out[])
71{
72 Double_t A[N * N];
73
74 for (Int_t i = 0, n = 0; i < N; i++) {
75 for (Int_t j = 0; j < N; j++, ++n) {
76 A[n] = 0;
77 for (Int_t k = 0; k < N; ++k) {
78 A[n] += S[indexS(i, k)] * Q[k * N + j];
79 }
80 }
81 }
82
83 for (Int_t i = 0; i < N; i++) {
84 for (Int_t j = 0; j <= i; j++) {
85 Int_t n = indexS(i, j);
86 S_out[n] = 0;
87 for (Int_t k = 0; k < N; k++) {
88 S_out[n] += Q[k * N + i] * A[k * N + j];
89 }
90 }
91 }
92}
93
94void CbmKFMath::multSSQ(const Double_t* A, const Double_t* B, Double_t* C, Int_t n)
95{
96 for (Int_t i = 0; i < n; ++i) {
97 for (Int_t j = 0; j < n; ++j) {
98 Int_t ind = i * n + j;
99 C[ind] = 0;
100 for (Int_t k = 0; k < n; ++k) {
101 C[ind] += A[indexS(i, k)] * B[indexS(k, j)];
102 }
103 }
104 }
105}
106
107void CbmKFMath::four_dim_inv(Double_t a[4][4])
108{
109 /**** Gaussian algorithm for 4x4 matrix inversion ****/
110 Int_t i, j, k, l;
111 Double_t factor;
112 Double_t temp[4];
113 Double_t b[4][4];
114
115 // Set b to I
116 for (i = 0; i < 4; i++) {
117 for (j = 0; j < 4; j++) {
118 b[i][j] = (i == j) ? 1.0 : 0.0;
119 }
120 }
121
122 for (i = 0; i < 4; i++) {
123 for (j = i + 1; j < 4; j++) {
124 if (fabs(a[i][i]) < fabs(a[j][i])) {
125 for (l = 0; l < 4; l++) {
126 temp[l] = a[i][l];
127 }
128 for (l = 0; l < 4; l++) {
129 a[i][l] = a[j][l];
130 }
131 for (l = 0; l < 4; l++) {
132 a[j][l] = temp[l];
133 }
134 for (l = 0; l < 4; l++) {
135 temp[l] = b[i][l];
136 }
137 for (l = 0; l < 4; l++) {
138 b[i][l] = b[j][l];
139 }
140 for (l = 0; l < 4; l++) {
141 b[j][l] = temp[l];
142 }
143 }
144 }
145 factor = a[i][i];
146 for (j = 4 - 1; j > -1; j--) {
147 b[i][j] /= factor;
148 a[i][j] /= factor;
149 }
150 for (j = i + 1; j < 4; j++) {
151 factor = -a[j][i];
152 for (k = 0; k < 4; k++) {
153 a[j][k] += a[i][k] * factor;
154 b[j][k] += b[i][k] * factor;
155 }
156 }
157 }
158 for (i = 3; i > 0; i--) {
159 for (j = i - 1; j > -1; j--) {
160 factor = -a[j][i];
161 for (k = 0; k < 4; k++) {
162 a[j][k] += a[i][k] * factor;
163 b[j][k] += b[i][k] * factor;
164 }
165 }
166 }
167
168 // copy b to a and return
169 for (i = 0; i < 4; i++) {
170 for (j = 0; j < 4; j++) {
171 a[i][j] = b[i][j];
172 }
173 }
174}
175
176void CbmKFMath::five_dim_inv(Double_t a[5][5])
177{
178 /**** Gaussian algorithm for 5x5 matrix inversion ****/
179 Int_t i, j, k, l;
180 Double_t factor;
181 Double_t temp[5];
182 Double_t b[5][5];
183
184 // Set b to I
185 for (i = 0; i < 5; i++) {
186 for (j = 0; j < 5; j++) {
187 b[i][j] = (i == j) ? 1. : 0.;
188 }
189 }
190
191
192 for (i = 0; i < 5; i++) {
193 for (j = i + 1; j < 5; j++) {
194 if (fabs(a[i][i]) < fabs(a[j][i])) {
195 for (l = 0; l < 5; l++) {
196 temp[l] = a[i][l];
197 }
198 for (l = 0; l < 5; l++) {
199 a[i][l] = a[j][l];
200 }
201 for (l = 0; l < 5; l++) {
202 a[j][l] = temp[l];
203 }
204 for (l = 0; l < 5; l++) {
205 temp[l] = b[i][l];
206 }
207 for (l = 0; l < 5; l++) {
208 b[i][l] = b[j][l];
209 }
210 for (l = 0; l < 5; l++) {
211 b[j][l] = temp[l];
212 }
213 }
214 }
215 factor = a[i][i];
216 // cout<<"Highest element "<<a[i][i]<<endl;
217 for (j = 5 - 1; j > -1; j--) {
218 b[i][j] /= factor;
219 a[i][j] /= factor;
220 }
221 for (j = i + 1; j < 5; j++) {
222 factor = -a[j][i];
223 for (k = 0; k < 5; k++) {
224 a[j][k] += a[i][k] * factor;
225 b[j][k] += b[i][k] * factor;
226 }
227 }
228 }
229 for (i = 4; i > 0; i--) {
230 for (j = i - 1; j > -1; j--) {
231 factor = -a[j][i];
232 for (k = 0; k < 5; k++) {
233 a[j][k] += a[i][k] * factor;
234 b[j][k] += b[i][k] * factor;
235 }
236 }
237 }
238
239 // copy b to a and return
240 for (i = 0; i < 5; i++) {
241 for (j = 0; j < 5; j++) {
242 a[i][j] = b[i][j];
243 }
244 }
245}
246
247Bool_t CbmKFMath::invS(Double_t A[], Int_t N)
248{
249
250 Bool_t ret = 0;
251
252 const Double_t ZERO = 1.E-20;
253
254 // input: simmetric > 0 NxN matrix A = {a11,a21,a22,a31..a33,..}
255 // output: inverse A, in case of problems fill zero and return 1
256
257 // A->low triangular Anew : A = Anew x Anew^T
258 // method:
259 // for(j=1,N) for(i=j,N) Aij=(Aii-sum_{k=1}^{j-1}Aik*Ajk )/Ajj
260 //
261
262 {
263 Double_t *j1 = A, *jj = A;
264 for (Int_t j = 1; j <= N; j1 += j++, jj += j) {
265 Double_t *ik = j1, x = 0;
266 while (ik != jj) {
267 x -= (*ik) * (*ik);
268 ik++;
269 }
270 x += *ik;
271 if (x > ZERO) {
272 x = sqrt(x);
273 *ik = x;
274 ik++;
275 x = 1 / x;
276 for (Int_t step = 1; step <= N - j; ik += ++step) { // ik==Ai1
277 Double_t sum = 0;
278 for (Double_t* jk = j1; jk != jj; sum += *(jk++) * *(ik++)) {
279 ;
280 }
281 *ik = (*ik - sum) * x; // ik == Aij
282 }
283 }
284 else {
285 Double_t* ji = jj;
286 for (Int_t i = j; i < N; i++) {
287 *(ji += i) = 0.;
288 }
289 ret = 1;
290 }
291 }
292 }
293
294 // A -> Ainv
295 // method :
296 // for(i=1,N){
297 // Aii = 1/Aii;
298 // for(j=1,i-1) Aij=-(sum_{k=j}^{i-1} Aik * Akj) / Aii ;
299 // }
300
301 {
302 Double_t *ii = A, *ij = A;
303 for (Int_t i = 1; i <= N; ij = ii + 1, ii += ++i) {
304 if (*ii > ZERO) {
305 Double_t x = -(*ii = 1. / *ii);
306 Double_t* jj = A;
307 for (Int_t j = 1; j < i; jj += ++j, ij++) {
308 Double_t *ik = ij, *kj = jj, sum = 0.;
309 for (Int_t k = j; ik != ii; kj += k++, ik++) {
310 sum += *ik * *kj;
311 }
312 *kj = sum * x;
313 }
314 }
315 else {
316 for (Double_t* ik = ij; ik != ii + 1; ik++) {
317 *ik = 0.;
318 }
319 ret = 1;
320 }
321 }
322 }
323
324 // A -> A^T x A
325 // method:
326 // Aij = sum_{k=i}^N Aki * Akj
327
328 {
329 Double_t *ii = A, *ij = A;
330 for (Int_t i = 1; i <= N; ii += ++i) {
331 do {
332 Double_t *ki = ii, *kj = ij, sum = 0.;
333 for (Int_t k = i; k <= N; ki += k, kj += k++) {
334 sum += (*ki) * (*kj);
335 }
336 *ij = sum;
337 } while ((ij++) != ii);
338 }
339 }
340 return ret;
341}
342
343Double_t CbmKFMath::getDeviation(Double_t x, Double_t y, Double_t C[], Double_t vx, Double_t vy, Double_t Cv[])
344{
345 Double_t dx = x - vx;
346 Double_t dy = y - vy;
347 Double_t c[3] = {0, 0, 0};
348 if (C) {
349 c[0] = C[0];
350 c[1] = C[1];
351 c[2] = C[2];
352 }
353 if (Cv) {
354 c[0] += Cv[0];
355 c[1] += Cv[1];
356 c[2] += Cv[2];
357 }
358 Double_t d = c[0] * c[2] - c[1] * c[1];
359 if (fabs(d) < 1.e-20) {
360 return 0;
361 }
362 return sqrt(fabs(0.5 * (dx * dx * c[0] - 2 * dx * dy * c[1] + dy * dy * c[2]) / d));
363}
364
365Double_t CbmKFMath::AnalyticQP(const Double_t T[], // track parameters (x,y,tx,ty,Q/p,z)
366 const Double_t V[], // vertex parameters (x,y,z)
367 FairField* MagneticField // magnetic field
368)
369{
370
371 const Double_t c_light = 0.000299792458;
372
373 Double_t x = T[0], y = T[1], tx = T[2], ty = T[3], qp0 = T[4], z = T[5],
374
375 vx = V[0],
376 //vy = V[1],
377 vz = V[2],
378
379 txtx = tx * tx, tyty = ty * ty, txty = tx * ty;
380
381 Double_t Ax = txty, Ay = -txtx - 1, Az = ty, Ayy = tx * (txtx * 3 + 3), Ayz = -2 * txty, Azy = Ayz,
382 Ayyy = -(15 * txtx * txtx + 18 * txtx + 3),
383
384 Bx = tyty + 1, By = -txty, Bz = -tx, Byy = ty * (txtx * 3 + 1), Byz = 2 * txtx + 1, Bzy = txtx - tyty,
385 Byyy = -txty * (txtx * 15 + 9);
386
387 Double_t t = c_light * sqrt(1. + txtx + tyty), h = t * qp0;
388
389 // integrals
390
391 Double_t Sx = 0, Sy = 0, Sz = 0, Syy = 0, Syz = 0, Szy = 0, Syyy = 0;
392
393 {
394 Double_t sx = 0, sy = 0, sz = 0, syy = 0, syz = 0, szy = 0, syyy = 0;
395
396 Double_t r[3] = {x, y, z};
397 Double_t B[3][3];
398
399 Int_t n = int(fabs(vz - z) / 5.);
400 if (n < 2) {
401 n = 2;
402 }
403 Double_t dz = (vz - z) / n;
404
405 {
406 MagneticField->GetFieldValue(r, B[0]);
407 r[0] += tx * dz;
408 r[1] += ty * dz;
409 r[2] += dz;
410 MagneticField->GetFieldValue(r, B[1]);
411 r[0] += tx * dz;
412 r[1] += ty * dz;
413 r[2] += dz;
414 MagneticField->GetFieldValue(r, B[2]);
415
416 sx = (B[0][0] + 4 * B[1][0] + B[2][0]) * dz * 2 / 6.;
417 sy = (B[0][1] + 4 * B[1][1] + B[2][1]) * dz * 2 / 6.;
418 sz = (B[0][2] + 4 * B[1][2] + B[2][2]) * dz * 2 / 6.;
419
420 Sx = (B[0][0] + 2 * B[1][0]) * dz * dz * 4 / 6.;
421 Sy = (B[0][1] + 2 * B[1][1]) * dz * dz * 4 / 6.;
422 Sz = (B[0][2] + 2 * B[1][2]) * dz * dz * 4 / 6.;
423
424 Double_t c2[3][3] = {{5, -4, -1}, {44, 80, -4}, {11, 44, 5}}; // /=360.
425 Double_t C2[3][3] = {{38, 8, -4}, {148, 208, -20}, {3, 36, 3}}; // /=2520.
426 for (Int_t k = 0; k < 3; k++) {
427 for (Int_t m = 0; m < 3; m++) {
428 syz += c2[k][m] * B[k][1] * B[m][2];
429 Syz += C2[k][m] * B[k][1] * B[m][2];
430 szy += c2[k][m] * B[k][2] * B[m][1];
431 Szy += C2[k][m] * B[k][2] * B[m][1];
432 }
433 }
434
435 syz *= dz * dz * 4 / 360.;
436 Syz *= dz * dz * dz * 8 / 2520.;
437
438 szy *= dz * dz * 4 / 360.;
439 Szy *= dz * dz * dz * 8 / 2520.;
440
441 syy = (B[0][1] + 4 * B[1][1] + B[2][1]) * dz * 2;
442 syyy = syy * syy * syy / 1296;
443 syy = syy * syy / 72;
444
445 Syy = (B[0][1] * (38 * B[0][1] + 156 * B[1][1] - B[2][1]) + B[1][1] * (208 * B[1][1] + 16 * B[2][1])
446 + B[2][1] * (3 * B[2][1]))
447 * dz * dz * dz * 8 / 2520.;
448 Syyy = (B[0][1]
449 * (B[0][1] * (85 * B[0][1] + 526 * B[1][1] - 7 * B[2][1]) + B[1][1] * (1376 * B[1][1] + 84 * B[2][1])
450 + B[2][1] * (19 * B[2][1]))
451 + B[1][1] * (B[1][1] * (1376 * B[1][1] + 256 * B[2][1]) + B[2][1] * (62 * B[2][1]))
452 + B[2][1] * B[2][1] * (3 * B[2][1]))
453 * dz * dz * dz * dz * 16 / 90720.;
454
455 x += tx * 2 * dz + h * (Sx * Ax + Sy * Ay + Sz * Az) + h * h * (Syy * Ayy + Syz * Ayz + Szy * Azy)
456 + h * h * h * Syyy * Ayyy;
457 y += ty * 2 * dz + h * (Sx * Bx + Sy * By + Sz * Bz) + h * h * (Syy * Byy + Syz * Byz + Szy * Bzy)
458 + h * h * h * Syyy * Byyy;
459 tx += h * (sx * Ax + sy * Ay + sz * Az) + h * h * (syy * Ayy + syz * Ayz + szy * Azy) + h * h * h * syyy * Ayyy;
460 ty += h * (sx * Bx + sy * By + sz * Bz) + h * h * (syy * Byy + syz * Byz + szy * Bzy) + h * h * h * syyy * Byyy;
461 z += 2 * dz;
462 txtx = tx * tx;
463 tyty = ty * ty;
464 txty = tx * ty;
465
466 Ax = txty;
467 Ay = -txtx - 1;
468 Az = ty;
469 Ayy = tx * (txtx * 3 + 3);
470 Ayz = -2 * txty;
471 Azy = Ayz;
472 Ayyy = -(15 * txtx * txtx + 18 * txtx + 3);
473
474 Bx = tyty + 1;
475 By = -txty;
476 Bz = -tx;
477 Byy = ty * (txtx * 3 + 1);
478 Byz = 2 * txtx + 1;
479 Bzy = txtx - tyty;
480 Byyy = -txty * (txtx * 15 + 9);
481
482 t = c_light * sqrt(1. + txtx + tyty);
483 h = t * qp0;
484 }
485
486 for (Int_t i = 2; i < n; i++) {
487
488 Double_t B0[3] = {B[0][0], B[0][1], B[0][2]};
489
490 B[0][0] = B[1][0];
491 B[0][1] = B[1][1];
492 B[0][2] = B[1][2];
493
494 B[1][0] = B[2][0];
495 B[1][1] = B[2][1];
496 B[1][2] = B[2][2];
497
498 // estimate B[2] at +dz
499
500 B[2][0] = B0[0] - 3 * B[0][0] + 3 * B[1][0];
501 B[2][1] = B0[1] - 3 * B[0][1] + 3 * B[1][1];
502 B[2][2] = B0[2] - 3 * B[0][2] + 3 * B[1][2];
503
504 Double_t Sx_, Sy_, Sz_, Syy_, Syz_, Szy_, Syyy_;
505
506 Sx_ = (-B[0][0] + 10 * B[1][0] + 3 * B[2][0]) * dz * dz * 4 / 96.;
507 Sy_ = (-B[0][1] + 10 * B[1][1] + 3 * B[2][1]) * dz * dz * 4 / 96.;
508 Sz_ = (-B[0][2] + 10 * B[1][2] + 3 * B[2][2]) * dz * dz * 4 / 96.;
509
510 Syz_ = Szy_ = 0;
511
512 Double_t c2[3][3] = {{5, -52, -13}, {-28, 320, 68}, {-37, 332, 125}}; // /=5760
513 Double_t C2[3][3] = {{13, -152, -29}, {-82, 1088, 170}, {-57, 576, 153}}; // /=80640
514
515 for (Int_t k = 0; k < 3; k++) {
516 for (Int_t m = 0; m < 3; m++) {
517 Syz_ += C2[k][m] * B[k][1] * B[m][2];
518 Szy_ += C2[k][m] * B[k][2] * B[m][1];
519 }
520 }
521
522 Syz_ *= dz * dz * dz * 8 / 80640.;
523 Szy_ *= dz * dz * dz * 8 / 80640.;
524
525 Syy_ = (B[0][1] * (13 * B[0][1] - 234 * B[1][1] - 86 * B[2][1]) + B[1][1] * (1088 * B[1][1] + 746 * B[2][1])
526 + B[2][1] * (153 * B[2][1]))
527 * dz * dz * dz * 8 / 80640.;
528
529 Syyy_ = (B[0][1]
530 * (B[0][1] * (-43 * B[0][1] + 1118 * B[1][1] + 451 * B[2][1])
531 + B[1][1] * (-9824 * B[1][1] - 7644 * B[2][1]) + B[2][1] * (-1669 * B[2][1]))
532 + B[1][1] * (B[1][1] * (29344 * B[1][1] + 32672 * B[2][1]) + B[2][1] * (13918 * B[2][1]))
533 + B[2][1] * B[2][1] * (2157 * B[2][1]))
534 * dz * dz * dz * dz * 16 / 23224320.;
535
536 r[2] += dz;
537 r[0] = x + tx * dz + h * (Sx_ * Ax + Sy_ * Ay + Sz_ * Az) + h * h * (Syy_ * Ayy + Syz_ * Ayz + Szy_ * Azy)
538 + h * h * h * Syyy_ * Ayyy;
539 r[1] = y + ty * dz + h * (Sx_ * Bx + Sy_ * By + Sz_ * Bz) + h * h * (Syy_ * Byy + Syz_ * Byz + Szy_ * Bzy)
540 + h * h * h * Syyy_ * Byyy;
541 /*
542 Syyy_+= dz*syyy+Sy_*syy+Syy_*sy+Syyy;
543 Syy_ += dz*syy + sy*Sy_ + Syy;
544 Syz_ += dz*syz + sz*Sy_ + Syz;
545 Szy_ += dz*szy + sy*Sz_ + Szy;
546 Sx_ += dz*sx + Sx;
547 Sy_ += dz*sy + Sy;
548 Sz_ += dz*sz + Sz;
549
550 r[2] += dz;
551 r[0] =
552 x + tx*(r[2]-z)
553 + h*( Sx_*Ax + Sy_*Ay + Sz_*Az )
554 + h*h*( Syy_*Ayy + Syz_*Ayz + Szy_*Azy )
555 + h*h*h*Syyy_*Ayyy;
556 r[1] = y + ty*(r[2]-z)
557 + h*( Sx_*Bx + Sy_*By + Sz_*Bz )
558 + h*h*( Syy_*Byy + Syz_*Byz + Szy_*Bzy )
559 + h*h*h*Syyy_*Byyy;
560 */
561 MagneticField->GetFieldValue(r, B[2]);
562
563 Double_t sx_, sy_, sz_, syy_, syz_, szy_, syyy_;
564
565 sx_ = (-B[0][0] + 8 * B[1][0] + 5 * B[2][0]) * dz * 2 / 24.;
566 sy_ = (-B[0][1] + 8 * B[1][1] + 5 * B[2][1]) * dz * 2 / 24.;
567 sz_ = (-B[0][2] + 8 * B[1][2] + 5 * B[2][2]) * dz * 2 / 24.;
568
569 Sx_ = (-B[0][0] + 10 * B[1][0] + 3 * B[2][0]) * dz * dz * 4 / 96.;
570 Sy_ = (-B[0][1] + 10 * B[1][1] + 3 * B[2][1]) * dz * dz * 4 / 96.;
571 Sz_ = (-B[0][2] + 10 * B[1][2] + 3 * B[2][2]) * dz * dz * 4 / 96.;
572
573 syz_ = Syz_ = szy_ = Szy_ = 0;
574
575 for (Int_t k = 0; k < 3; k++) {
576 for (Int_t m = 0; m < 3; m++) {
577 syz_ += c2[k][m] * B[k][1] * B[m][2];
578 Syz_ += C2[k][m] * B[k][1] * B[m][2];
579 szy_ += c2[k][m] * B[k][2] * B[m][1];
580 Szy_ += C2[k][m] * B[k][2] * B[m][1];
581 }
582 }
583
584 syz_ *= dz * dz * 4 / 5760.;
585 Syz_ *= dz * dz * dz * 8 / 80640.;
586
587 szy_ *= dz * dz * 4 / 5760.;
588 Szy_ *= dz * dz * dz * 8 / 80640.;
589
590 syy_ = (B[0][1] - 8 * B[1][1] - 5 * B[2][1]) * dz * 2;
591 syyy_ = -syy_ * syy_ * syy_ / 82944;
592 syy_ = syy_ * syy_ / 1152;
593
594 Syy_ = (B[0][1] * (13 * B[0][1] - 234 * B[1][1] - 86 * B[2][1]) + B[1][1] * (1088 * B[1][1] + 746 * B[2][1])
595 + B[2][1] * (153 * B[2][1]))
596 * dz * dz * dz * 8 / 80640.;
597
598 Syyy_ = (B[0][1]
599 * (B[0][1] * (-43 * B[0][1] + 1118 * B[1][1] + 451 * B[2][1])
600 + B[1][1] * (-9824 * B[1][1] - 7644 * B[2][1]) + B[2][1] * (-1669 * B[2][1]))
601 + B[1][1] * (B[1][1] * (29344 * B[1][1] + 32672 * B[2][1]) + B[2][1] * (13918 * B[2][1]))
602 + B[2][1] * B[2][1] * (2157 * B[2][1]))
603 * dz * dz * dz * dz * 16 / 23224320.;
604
605 x += tx * dz + h * (Sx_ * Ax + Sy_ * Ay + Sz_ * Az) + h * h * (Syy_ * Ayy + Syz_ * Ayz + Szy_ * Azy)
606 + h * h * h * Syyy_ * Ayyy;
607 y += ty * dz + h * (Sx_ * Bx + Sy_ * By + Sz_ * Bz) + h * h * (Syy_ * Byy + Syz_ * Byz + Szy_ * Bzy)
608 + h * h * h * Syyy_ * Byyy;
609 tx += h * (sx_ * Ax + sy_ * Ay + sz_ * Az) + h * h * (syy_ * Ayy + syz_ * Ayz + szy_ * Azy)
610 + h * h * h * syyy_ * Ayyy;
611 ty += h * (sx_ * Bx + sy_ * By + sz_ * Bz) + h * h * (syy_ * Byy + syz_ * Byz + szy_ * Bzy)
612 + h * h * h * syyy_ * Byyy;
613 z += dz;
614 txtx = tx * tx;
615 tyty = ty * ty;
616 txty = tx * ty;
617
618 Ax = txty;
619 Ay = -txtx - 1;
620 Az = ty;
621 Ayy = tx * (txtx * 3 + 3);
622 Ayz = -2 * txty;
623 Azy = Ayz;
624 Ayyy = -(15 * txtx * txtx + 18 * txtx + 3);
625
626 Bx = tyty + 1;
627 By = -txty;
628 Bz = -tx;
629 Byy = ty * (txtx * 3 + 1);
630 Byz = 2 * txtx + 1;
631 Bzy = txtx - tyty;
632 Byyy = -txty * (txtx * 15 + 9);
633
634 t = c_light * sqrt(1. + txtx + tyty);
635 h = t * qp0;
636
637
638 Syyy += dz * syyy + Sy_ * syy + Syy_ * sy + Syyy_;
639 Syy += dz * syy + sy * Sy_ + Syy_;
640 Syz += dz * syz + sz * Sy_ + Syz_;
641 Szy += dz * szy + sy * Sz_ + Szy_;
642 Sx += dz * sx + Sx_;
643 Sy += dz * sy + Sy_;
644 Sz += dz * sz + Sz_;
645
646 syyy += sy_ * syy + syy_ * sy + syyy_;
647 syy += sy * sy_ + syy_;
648 syz += sz * sy_ + syz_;
649 szy += sz * sz_ + szy_;
650 sx += sx_;
651 sy += sy_;
652 sz += sz_;
653 }
654 //cout<<x-vx<<" "<<y-vy<<" "<<z-vz<<" "<<1./qp0<<endl;
655 }
656
657 x = T[0];
658 y = T[1];
659 tx = T[2];
660 ty = T[3];
661 z = T[5];
662 txtx = tx * tx;
663 tyty = ty * ty;
664 txty = tx * ty;
665
666 Ax = txty;
667 Ay = -txtx - 1;
668 Az = ty;
669 Ayy = tx * (txtx * 3 + 3);
670 Ayz = -2 * txty;
671 Azy = Ayz;
672 Ayyy = -(15 * txtx * txtx + 18 * txtx + 3);
673
674 Bx = tyty + 1;
675 By = -txty;
676 Bz = -tx;
677 Byy = ty * (txtx * 3 + 1);
678 Byz = 2 * txtx + 1;
679 Bzy = txtx - tyty;
680 Byyy = -txty * (txtx * 15 + 9);
681
682 t = c_light * sqrt(1. + txtx + tyty);
683 h = t * qp0;
684
685 Double_t
686
687 c = (x - vx) + tx * (vz - z),
688 b = t * (Sx * Ax + Sy * Ay + Sz * Az), a = t * t * (Syy * Ayy + Syz * Ayz + Szy * Azy),
689 d = t * t * t * (Syyy * Ayyy);
690
691 Double_t C = d * qp0 * qp0 * qp0 + a * qp0 * qp0 + b * qp0 + c, B = 3 * d * qp0 * qp0 + 2 * a * qp0 + b,
692 A = 3 * d + a;
693
694 Double_t D = B * B - 4 * A * C;
695 if (D < 0.) {
696 D = 0.;
697 }
698 D = sqrt(D);
699
700 Double_t dqp1 = (-B + D) / 2 / A;
701 Double_t dqp2 = (-B - D) / 2 / A;
702 Double_t dqp = (fabs(dqp1) < fabs(dqp2)) ? dqp1 : dqp2;
703
704 return qp0 + dqp;
705}
706
707
708Bool_t CbmKFMath::GetThickness(Double_t z1, Double_t z2, Double_t mz, Double_t mthick, Double_t* mz_out,
709 Double_t* mthick_out)
710{
711 Double_t z, Z;
712
713 if (z1 < z2) {
714 z = z1;
715 Z = z2;
716 }
717 else {
718 Z = z1;
719 z = z2;
720 }
721
722 Double_t tmin = mz - mthick / 2, tmax = mz + mthick / 2;
723 if (tmin >= Z || z >= tmax) {
724 return 1;
725 }
726 if (z <= tmin && tmax <= Z) // case z |**| Z
727 {
728 *mz_out = mz;
729 *mthick_out = mthick;
730 }
731 else if (z <= tmin && tmin < Z && Z <= tmax) // case z |*Z*|
732 {
733 *mz_out = (tmin + Z) / 2;
734 *mthick_out = Z - tmin;
735 }
736 else if (tmax <= Z && tmin <= z && z < tmax) // case |*z*| Z
737 {
738 *mz_out = (tmax + z) / 2;
739 *mthick_out = tmax - z;
740 }
741 else if (tmin <= z && Z <= tmax) // case |*zZ*|
742 {
743 *mz_out = (Z + z) / 2;
744 *mthick_out = Z - z;
745 }
746 return 0;
747}
748
749
750Int_t CbmKFMath::GetNoise(Double_t Lrl, Double_t F, Double_t Fe, Double_t tx, Double_t ty, Double_t qp, Double_t mass,
751 Bool_t is_electron, Bool_t downstream_direction, Double_t* Q5, Double_t* Q8, Double_t* Q9,
752 Double_t* Ecor)
753{
754 *Q5 = 0;
755 *Q8 = 0;
756 *Q9 = 0;
757 *Ecor = 1.;
758 Double_t t = sqrt(1. + tx * tx + ty * ty);
759 if (!std::isfinite(t) || t > 1.e4) {
760 return 1;
761 }
762 t = sqrt(t);
763 Double_t l = t * Lrl;
764 if (l > 1.) {
765 l = 1.; // protect against l too big
766 }
767 Double_t s0 = (l > exp(-1. / 0.038)) ? F * .0136 * (1 + 0.038 * log(l)) * qp : 0.;
768 Double_t a = (1. + mass * mass * qp * qp) * s0 * s0 * t * t * l;
769
770 *Q5 = a * (1. + tx * tx);
771 *Q8 = a * tx * ty;
772 *Q9 = a * (1. + ty * ty);
773
774 // Apply correction for dE/dx energy loss
775
776 Double_t L = downstream_direction ? l : -l;
777
778 if (0 && is_electron) // Bremsstrahlung effect for e+,e-
779 {
780 *Ecor = exp(L);
781 }
782
783 if (1) // ionisation energy loss
784 {
785 Double_t m_energyLoss = Fe;
786 // Double_t m_energyLoss = 0.02145;//0.060;
787 Double_t corr = (1. - fabs(qp) * L * m_energyLoss);
788 if (corr > 0.001 * fabs(qp)) {
789 *Ecor *= 1. / corr;
790 }
791 else {
792 *Ecor = 1000. / fabs(qp);
793 }
794 }
795 return 0;
796}
797
798
799void CbmKFMath::CopyTC2TrackParam(FairTrackParam* par, Double_t T[], Double_t C[])
800{
801 if (T) {
802 par->SetX(T[0]);
803 par->SetY(T[1]);
804 par->SetZ(T[5]);
805 par->SetTx(T[2]);
806 par->SetTy(T[3]);
807 par->SetQp(T[4]);
808 }
809 if (C) {
810 for (Int_t i = 0, iCov = 0; i < 5; i++) {
811 for (Int_t j = 0; j <= i; j++, iCov++) {
812 par->SetCovariance(i, j, C[iCov]);
813 }
814 }
815 }
816}
817
818void CbmKFMath::CopyTrackParam2TC(const FairTrackParam* par, Double_t T[], Double_t C[])
819{
820 if (T) {
821 T[0] = par->GetX();
822 T[1] = par->GetY();
823 T[2] = par->GetTx();
824 T[3] = par->GetTy();
825 T[4] = par->GetQp();
826 T[5] = par->GetZ();
827 }
828 if (C) {
829 for (Int_t i = 0, iCov = 0; i < 5; i++) {
830 for (Int_t j = 0; j <= i; j++, iCov++) {
831 C[iCov] = par->GetCovariance(i, j);
832 }
833 }
834 }
835}
ClassImp(CbmKFMath) Bool_t CbmKFMath
Definition CbmKFMath.cxx:17
friend fvec sqrt(const fvec &a)
friend fvec exp(const fvec &a)
friend fvec log(const fvec &a)
static void multQtSQ(Int_t N, const Double_t Q[], const Double_t S[], Double_t S_out[])
Definition CbmKFMath.cxx:70
static void CopyTC2TrackParam(FairTrackParam *par, Double_t T[], Double_t C[])
static Double_t getDeviation(Double_t x, Double_t y, Double_t C[], Double_t vx, Double_t vy, Double_t Cv[]=nullptr)
static Bool_t GetThickness(Double_t z1, Double_t z2, Double_t mz, Double_t mthick, Double_t *mz_out, Double_t *mthick_out)
static Bool_t intersectCone(Double_t zCone, Double_t ZCone, Double_t rCone, Double_t RCone, const Double_t x[], Double_t *z1, Double_t *z2)
static Double_t AnalyticQP(const Double_t T[], const Double_t V[], FairField *MagneticField)
static void multSSQ(const Double_t *A, const Double_t *B, Double_t *C, Int_t n)
Definition CbmKFMath.cxx:94
static void five_dim_inv(Double_t a[5][5])
static Bool_t invS(Double_t A[], Int_t N)
static Int_t GetNoise(Double_t Lrl, Double_t F, Double_t Fe, Double_t tx, Double_t ty, Double_t qp, Double_t mass, Bool_t is_electron, Bool_t downstream_direction, Double_t *Q5, Double_t *Q8, Double_t *Q9, Double_t *Ecor)
static void four_dim_inv(Double_t a[4][4])
static void CopyTrackParam2TC(const FairTrackParam *par, Double_t T[], Double_t C[])
static void multQSQt(Int_t N, const Double_t Q[], const Double_t S[], Double_t S_out[])
Definition CbmKFMath.cxx:46
static Int_t indexS(Int_t i, Int_t j)
Definition CbmKFMath.h:34
Data class with information on a STS local track.