BmnRoot 26.10.0-210-gc52d34b0
Software framework of the BM@N experiment
Loading...
Searching...
No Matches
KFParticleBase.cxx
Go to the documentation of this file.
1//---------------------------------------------------------------------------------
2// Implementation of the KFParticleBase class
3// .
4// @author S.Gorbunov, I.Kisel, I.Kulakov, M.Zyzak
5// @version 1.0
6// @since 13.05.07
7//
8// Class to reconstruct and store the decayed particle parameters.
9// The method is described in CBM-SOFT note 2007-003,
10// ``Reconstruction of decayed particles based on the Kalman filter'',
11// http://www.gsi.de/documents/DOC-2007-May-14-1.pdf
12//
13// This class describes general mathematics which is used by KFParticle class
14//
15// -= Copyright &copy ALICE HLT and CBM L1 Groups =-
16//_________________________________________________________________________________
17
18#include "KFParticleBase.h"
19
20#include "TMath.h"
21
22#include <iostream>
23
25 : fQ(0)
26 , fNDF(-3)
27 , fChi2(0)
28 , fSFromDecay(0)
30 , fIsLinearized(0)
33 , fMassHypo(-1)
34 , fId(-1)
36 , fPDG(0)
37{
38 //* Constructor
39
40 Initialize();
41}
42
43void KFParticleBase::Initialize(const Double_t Param[], const Double_t Cov[], Int_t Charge, Double_t Mass)
44{
45 // Constructor from "cartesian" track, particle mass hypothesis should be provided
46 //
47 // Param[6] = { X, Y, Z, Px, Py, Pz } - position and momentum
48 // Cov [21] = lower-triangular part of the covariance matrix:
49 //
50 // ( 0 . . . . . )
51 // ( 1 2 . . . . )
52 // Cov. matrix = ( 3 4 5 . . . ) - numbering of covariance elements in Cov[]
53 // ( 6 7 8 9 . . )
54 // ( 10 11 12 13 14 . )
55 // ( 15 16 17 18 19 20 )
56
57 for (Int_t i = 0; i < 6; i++)
58 fP[i] = Param[i];
59 for (Int_t i = 0; i < 21; i++)
60 fC[i] = Cov[i];
61
62 Double_t energy = TMath::Sqrt(Mass * Mass + fP[3] * fP[3] + fP[4] * fP[4] + fP[5] * fP[5]);
63 fP[6] = energy;
64 fP[7] = 0;
65 fQ = Charge;
66 fNDF = 0;
67 fChi2 = 0;
69 fIsLinearized = 0;
70 fSFromDecay = 0;
71
72 Double_t energyInv = 1. / energy;
73 Double_t h0 = fP[3] * energyInv, h1 = fP[4] * energyInv, h2 = fP[5] * energyInv;
74
75 fC[21] = h0 * fC[6] + h1 * fC[10] + h2 * fC[15];
76 fC[22] = h0 * fC[7] + h1 * fC[11] + h2 * fC[16];
77 fC[23] = h0 * fC[8] + h1 * fC[12] + h2 * fC[17];
78 fC[24] = h0 * fC[9] + h1 * fC[13] + h2 * fC[18];
79 fC[25] = h0 * fC[13] + h1 * fC[14] + h2 * fC[19];
80 fC[26] = h0 * fC[18] + h1 * fC[19] + h2 * fC[20];
81 fC[27] = (h0 * h0 * fC[9] + h1 * h1 * fC[14] + h2 * h2 * fC[20]
82 + 2 * (h0 * h1 * fC[13] + h0 * h2 * fC[18] + h1 * h2 * fC[19]));
83 for (Int_t i = 28; i < 36; i++)
84 fC[i] = 0;
85 fC[35] = 1.;
86
87 SumDaughterMass = Mass;
88 fMassHypo = Mass;
89}
90
92{
93 //* Initialise covariance matrix and set current parameters to 0.0
94
95 for (Int_t i = 0; i < 8; i++)
96 fP[i] = 0;
97 for (Int_t i = 0; i < 36; ++i)
98 fC[i] = 0.;
99 fC[0] = fC[2] = fC[5] = 100.;
100 fC[35] = 1.;
101 fNDF = -3;
102 fChi2 = 0.;
103 fQ = 0;
104 fSFromDecay = 0;
106 fVtxGuess[0] = fVtxGuess[1] = fVtxGuess[2] = 0.;
107 fIsLinearized = 0;
108 SumDaughterMass = 0;
109 fMassHypo = -1;
110}
111
113{
114 //* Set decay vertex parameters for linearisation
115
116 fVtxGuess[0] = x;
117 fVtxGuess[1] = y;
118 fVtxGuess[2] = z;
119 fIsLinearized = 1;
120}
121
123{
124 //* Calculate particle momentum
125
126 Double_t x = fP[3];
127 Double_t y = fP[4];
128 Double_t z = fP[5];
129 Double_t x2 = x * x;
130 Double_t y2 = y * y;
131 Double_t z2 = z * z;
132 Double_t p2 = x2 + y2 + z2;
133 p = TMath::Sqrt(p2);
134 error = (x2 * fC[9] + y2 * fC[14] + z2 * fC[20] + 2 * (x * y * fC[13] + x * z * fC[18] + y * z * fC[19]));
135 if (error > 1.e-16 && p > 1.e-4) {
136 error = TMath::Sqrt(error) / p;
137 return 0;
138 }
139 error = 1.e8;
140 return 1;
141}
142
144{
145 //* Calculate particle transverse momentum
146
147 Double_t px = fP[3];
148 Double_t py = fP[4];
149 Double_t px2 = px * px;
150 Double_t py2 = py * py;
151 Double_t pt2 = px2 + py2;
152 pt = TMath::Sqrt(pt2);
153 error = (px2 * fC[9] + py2 * fC[14] + 2 * px * py * fC[13]);
154 if (error > 0 && pt > 1.e-4) {
155 error = TMath::Sqrt(error) / pt;
156 return 0;
157 }
158 error = 1.e10;
159 return 1;
160}
161
163{
164 //* Calculate particle pseudorapidity
165
166 Double_t px = fP[3];
167 Double_t py = fP[4];
168 Double_t pz = fP[5];
169 Double_t pt2 = px * px + py * py;
170 Double_t p2 = pt2 + pz * pz;
171 Double_t p = TMath::Sqrt(p2);
172 Double_t a = p + pz;
173 Double_t b = p - pz;
174 eta = 1.e10;
175 if (b > 1.e-8) {
176 Double_t c = a / b;
177 if (c > 1.e-8)
178 eta = 0.5 * TMath::Log(c);
179 }
180 Double_t h3 = -px * pz;
181 Double_t h4 = -py * pz;
182 Double_t pt4 = pt2 * pt2;
183 Double_t p2pt4 = p2 * pt4;
184 error = (h3 * h3 * fC[9] + h4 * h4 * fC[14] + pt4 * fC[20]
185 + 2 * (h3 * (h4 * fC[13] + fC[18] * pt2) + pt2 * h4 * fC[19]));
186
187 if (error > 0 && p2pt4 > 1.e-10) {
188 error = TMath::Sqrt(error / p2pt4);
189 return 0;
190 }
191
192 error = 1.e10;
193 return 1;
194}
195
197{
198 //* Calculate particle polar angle
199
200 Double_t px = fP[3];
201 Double_t py = fP[4];
202 Double_t px2 = px * px;
203 Double_t py2 = py * py;
204 Double_t pt2 = px2 + py2;
205 phi = TMath::ATan2(py, px);
206 error = (py2 * fC[9] + px2 * fC[14] - 2 * px * py * fC[13]);
207 if (error > 0 && pt2 > 1.e-4) {
208 error = TMath::Sqrt(error) / pt2;
209 return 0;
210 }
211 error = 1.e10;
212 return 1;
213}
214
216{
217 //* Calculate distance to the origin
218
219 Double_t x = fP[0];
220 Double_t y = fP[1];
221 Double_t x2 = x * x;
222 Double_t y2 = y * y;
223 r = TMath::Sqrt(x2 + y2);
224 error = (x2 * fC[0] + y2 * fC[2] - 2 * x * y * fC[1]);
225 if (error > 0 && r > 1.e-4) {
226 error = TMath::Sqrt(error) / r;
227 return 0;
228 }
229 error = 1.e10;
230 return 1;
231}
232
234{
235 //* Calculate particle mass
236
237 // s = sigma^2 of m2/2
238
239 Double_t s = (fP[3] * fP[3] * fC[9] + fP[4] * fP[4] * fC[14] + fP[5] * fP[5] * fC[20] + fP[6] * fP[6] * fC[27]
240 + 2
241 * (+fP[3] * fP[4] * fC[13] + fP[5] * (fP[3] * fC[18] + fP[4] * fC[19])
242 - fP[6] * (fP[3] * fC[24] + fP[4] * fC[25] + fP[5] * fC[26])));
243 // Double_t m2 = TMath::Abs(fP[6]*fP[6] - fP[3]*fP[3] - fP[4]*fP[4] - fP[5]*fP[5]);
244 // m = TMath::Sqrt(m2);
245 // if( m>1.e-10 ){
246 // if( s>=0 ){
247 // error = TMath::Sqrt(s)/m;
248 // return 0;
249 // }
250 // }
251 // error = 1.e20;
252 Double_t m2 = (fP[6] * fP[6] - fP[3] * fP[3] - fP[4] * fP[4] - fP[5] * fP[5]);
253
254 if (m2 < 0.) {
255 error = 1.e20;
256 m = -TMath::Sqrt(-m2);
257 return 1;
258 }
259
260 m = TMath::Sqrt(m2);
261 if (m > 1.e-6) {
262 if (s >= 0) {
263 error = TMath::Sqrt(s) / m;
264 return 0;
265 }
266 } else {
267 error = 1.e20;
268 return 0;
269 }
270 error = 1.e20;
271
272 return 1;
273}
274
276{
277 //* Calculate particle decay length [cm]
278
279 Double_t x = fP[3];
280 Double_t y = fP[4];
281 Double_t z = fP[5];
282 Double_t t = fP[7];
283 Double_t x2 = x * x;
284 Double_t y2 = y * y;
285 Double_t z2 = z * z;
286 Double_t p2 = x2 + y2 + z2;
287 l = t * TMath::Sqrt(p2);
288 if (p2 > 1.e-4) {
289 error =
290 p2 * fC[35]
291 + t * t / p2
292 * (x2 * fC[9] + y2 * fC[14] + z2 * fC[20] + 2 * (x * y * fC[13] + x * z * fC[18] + y * z * fC[19]))
293 + 2 * t * (x * fC[31] + y * fC[32] + z * fC[33]);
294 error = TMath::Sqrt(TMath::Abs(error));
295 return 0;
296 }
297 error = 1.e20;
298 return 1;
299}
300
302{
303 //* Calculate particle decay length in XY projection [cm]
304
305 Double_t x = fP[3];
306 Double_t y = fP[4];
307 Double_t t = fP[7];
308 Double_t x2 = x * x;
309 Double_t y2 = y * y;
310 Double_t pt2 = x2 + y2;
311 l = t * TMath::Sqrt(pt2);
312 if (pt2 > 1.e-4) {
313 error = pt2 * fC[35] + t * t / pt2 * (x2 * fC[9] + y2 * fC[14] + 2 * x * y * fC[13])
314 + 2 * t * (x * fC[31] + y * fC[32]);
315 error = TMath::Sqrt(TMath::Abs(error));
316 return 0;
317 }
318 error = 1.e20;
319 return 1;
320}
321
323{
324 //* Calculate particle decay time [s]
325
326 Double_t m, dm;
327 GetMass(m, dm);
328 Double_t cTM = (-fP[3] * fC[31] - fP[4] * fC[32] - fP[5] * fC[33] + fP[6] * fC[34]);
329 tauC = fP[7] * m;
330 error = m * m * fC[35] + 2 * fP[7] * cTM + fP[7] * fP[7] * dm * dm;
331 if (error > 0) {
332 error = TMath::Sqrt(error);
333 return 0;
334 }
335 error = 1.e20;
336 return 1;
337}
338
340{
341 //* Add daughter via operator+=
342
343 AddDaughter(Daughter);
344}
345
347{
348 //* Get big enough correction for S error to let the particle Part be fitted to XYZ point
349
350 Double_t d[3] = {XYZ[0] - Part[0], XYZ[1] - Part[1], XYZ[2] - Part[2]};
351 Double_t p2 = Part[3] * Part[3] + Part[4] * Part[4] + Part[5] * Part[5];
352 // Double_t sigmaS = (p2>1.e-4) ? ( 10.1+3.*TMath::Sqrt( d[0]*d[0]+d[1]*d[1]+d[2]*d[2]) )/TMath::Sqrt(p2) : 1.;
353 Double_t sigmaS =
354 (p2 > 1.e-4) ? (0.1 + 10. * TMath::Sqrt(d[0] * d[0] + d[1] * d[1] + d[2] * d[2])) / TMath::Sqrt(p2) : 1.;
355 return sigmaS;
356}
357
359{
360 //* Get additional covariances V used during measurement
361
362 Double_t b[3];
363 GetFieldValue(XYZ, b);
364 const Double_t kCLight = 0.000299792458;
365 b[0] *= kCLight;
366 b[1] *= kCLight;
367 b[2] *= kCLight;
368 // std::cout << " DStoPoint "<< (GetDStoPoint(XYZ)) << std::endl;
369 Transport(GetDStoPoint(XYZ), m, V);
370 // std::cout << "x " << XYZ[0] << " " << m[0] <<" y " << XYZ[1] << " " << m[1] <<" z " << XYZ[2] << " " << m[2]
371 // <<std::endl;
372 Double_t sigmaS = GetSCorrection(m, XYZ);
373
374 Double_t h[6];
375
376 h[0] = m[3] * sigmaS;
377 h[1] = m[4] * sigmaS;
378 h[2] = m[5] * sigmaS;
379 h[3] = (h[1] * b[2] - h[2] * b[1]) * GetQ();
380 h[4] = (h[2] * b[0] - h[0] * b[2]) * GetQ();
381 h[5] = (h[0] * b[1] - h[1] * b[0]) * GetQ();
382
383 V[0] += h[0] * h[0];
384 V[1] += h[1] * h[0];
385 V[2] += h[1] * h[1];
386 V[3] += h[2] * h[0];
387 V[4] += h[2] * h[1];
388 V[5] += h[2] * h[2];
389
390 V[6] += h[3] * h[0];
391 V[7] += h[3] * h[1];
392 V[8] += h[3] * h[2];
393 V[9] += h[3] * h[3];
394
395 V[10] += h[4] * h[0];
396 V[11] += h[4] * h[1];
397 V[12] += h[4] * h[2];
398 V[13] += h[4] * h[3];
399 V[14] += h[4] * h[4];
400
401 V[15] += h[5] * h[0];
402 V[16] += h[5] * h[1];
403 V[17] += h[5] * h[2];
404 V[18] += h[5] * h[3];
405 V[19] += h[5] * h[4];
406 V[20] += h[5] * h[5];
407}
408
410{
411 if (fNDF < -1) { // first daughter -> just copy
412 fNDF = -1;
413 fQ = Daughter.GetQ();
414 for (Int_t i = 0; i < 7; i++)
415 fP[i] = Daughter.fP[i];
416 for (Int_t i = 0; i < 28; i++)
417 fC[i] = Daughter.fC[i];
418 fSFromDecay = 0;
419 fMassHypo = Daughter.fMassHypo;
421 return;
422 }
423
424 if (fConstructMethod == 0)
425 AddDaughterWithEnergyFit(Daughter);
426 else if (fConstructMethod == 1)
428 else if (fConstructMethod == 2)
430
432 fMassHypo = -1;
433}
434
436{
437 //* Energy considered as an independent veriable, fitted independently from momentum, without any constraints on
438 // mass
439
440 //* Add daughter
441
443
444 Double_t b[3];
445 Int_t maxIter = 1;
446
447 if (!fIsLinearized) {
448 if (fNDF == -1) {
449 Double_t ds, ds1;
450 GetDStoParticle(Daughter, ds, ds1);
451 TransportToDS(ds);
452 Double_t m[8];
453 Double_t mCd[36];
454 Daughter.Transport(ds1, m, mCd);
455 fVtxGuess[0] = .5 * (fP[0] + m[0]);
456 fVtxGuess[1] = .5 * (fP[1] + m[1]);
457 fVtxGuess[2] = .5 * (fP[2] + m[2]);
458 } else {
459 fVtxGuess[0] = fP[0];
460 fVtxGuess[1] = fP[1];
461 fVtxGuess[2] = fP[2];
462 }
463 maxIter = 3;
464 }
465
466 for (Int_t iter = 0; iter < maxIter; iter++) {
467
468 {
470 const Double_t kCLight = 0.000299792458;
471 b[0] *= kCLight;
472 b[1] *= kCLight;
473 b[2] *= kCLight;
474 }
475
476 Double_t *ffP = fP, *ffC = fC, tmpP[8], tmpC[36];
477 if (fNDF == -1) {
478 GetMeasurement(fVtxGuess, tmpP, tmpC);
479 ffP = tmpP;
480 ffC = tmpC;
481 }
482
483 Double_t m[8], mV[36];
484
485 if (Daughter.fC[35] > 0) {
486 Daughter.GetMeasurement(fVtxGuess, m, mV);
487 } else {
488 for (Int_t i = 0; i < 8; i++)
489 m[i] = Daughter.fP[i];
490 for (Int_t i = 0; i < 36; i++)
491 mV[i] = Daughter.fC[i];
492 }
493 //*
494
495 Double_t mS[6];
496 {
497 Double_t mSi[6] = {ffC[0] + mV[0], ffC[1] + mV[1], ffC[2] + mV[2],
498 ffC[3] + mV[3], ffC[4] + mV[4], ffC[5] + mV[5]};
499
500 mS[0] = mSi[2] * mSi[5] - mSi[4] * mSi[4];
501 mS[1] = mSi[3] * mSi[4] - mSi[1] * mSi[5];
502 mS[2] = mSi[0] * mSi[5] - mSi[3] * mSi[3];
503 mS[3] = mSi[1] * mSi[4] - mSi[2] * mSi[3];
504 mS[4] = mSi[1] * mSi[3] - mSi[0] * mSi[4];
505 mS[5] = mSi[0] * mSi[2] - mSi[1] * mSi[1];
506
507 Double_t s = (mSi[0] * mS[0] + mSi[1] * mS[1] + mSi[3] * mS[3]);
508 s = (TMath::Abs(s) > 1.E-20) ? 1. / s : 0;
509 mS[0] *= s;
510 mS[1] *= s;
511 mS[2] *= s;
512 mS[3] *= s;
513 mS[4] *= s;
514 mS[5] *= s;
515 }
516 //* Residual (measured - estimated)
517
518 Double_t zeta[3] = {m[0] - ffP[0], m[1] - ffP[1], m[2] - ffP[2]};
519
520 //* CHt = CH' - D'
521
522 Double_t mCHt0[7], mCHt1[7], mCHt2[7];
523
524 mCHt0[0] = ffC[0];
525 mCHt1[0] = ffC[1];
526 mCHt2[0] = ffC[3];
527 mCHt0[1] = ffC[1];
528 mCHt1[1] = ffC[2];
529 mCHt2[1] = ffC[4];
530 mCHt0[2] = ffC[3];
531 mCHt1[2] = ffC[4];
532 mCHt2[2] = ffC[5];
533 mCHt0[3] = ffC[6] - mV[6];
534 mCHt1[3] = ffC[7] - mV[7];
535 mCHt2[3] = ffC[8] - mV[8];
536 mCHt0[4] = ffC[10] - mV[10];
537 mCHt1[4] = ffC[11] - mV[11];
538 mCHt2[4] = ffC[12] - mV[12];
539 mCHt0[5] = ffC[15] - mV[15];
540 mCHt1[5] = ffC[16] - mV[16];
541 mCHt2[5] = ffC[17] - mV[17];
542 mCHt0[6] = ffC[21] - mV[21];
543 mCHt1[6] = ffC[22] - mV[22];
544 mCHt2[6] = ffC[23] - mV[23];
545
546 //* Kalman gain K = mCH'*S
547
548 Double_t k0[7], k1[7], k2[7];
549
550 for (Int_t i = 0; i < 7; ++i) {
551 k0[i] = mCHt0[i] * mS[0] + mCHt1[i] * mS[1] + mCHt2[i] * mS[3];
552 k1[i] = mCHt0[i] * mS[1] + mCHt1[i] * mS[2] + mCHt2[i] * mS[4];
553 k2[i] = mCHt0[i] * mS[3] + mCHt1[i] * mS[4] + mCHt2[i] * mS[5];
554 }
555
556 //* New estimation of the vertex position
557
558 if (iter < maxIter - 1) {
559 for (Int_t i = 0; i < 3; ++i)
560 fVtxGuess[i] = ffP[i] + k0[i] * zeta[0] + k1[i] * zeta[1] + k2[i] * zeta[2];
561 continue;
562 }
563
564 // last itearation -> update the particle
565
566 //* Add the daughter momentum to the particle momentum
567
568 ffP[3] += m[3];
569 ffP[4] += m[4];
570 ffP[5] += m[5];
571 ffP[6] += m[6];
572
573 ffC[9] += mV[9];
574 ffC[13] += mV[13];
575 ffC[14] += mV[14];
576 ffC[18] += mV[18];
577 ffC[19] += mV[19];
578 ffC[20] += mV[20];
579 ffC[24] += mV[24];
580 ffC[25] += mV[25];
581 ffC[26] += mV[26];
582 ffC[27] += mV[27];
583
584 //* New estimation of the vertex position r += K*zeta
585
586 for (Int_t i = 0; i < 7; ++i)
587 fP[i] = ffP[i] + k0[i] * zeta[0] + k1[i] * zeta[1] + k2[i] * zeta[2];
588
589 //* New covariance matrix C -= K*(mCH')'
590
591 for (Int_t i = 0, k = 0; i < 7; ++i) {
592 for (Int_t j = 0; j <= i; ++j, ++k) {
593 fC[k] = ffC[k] - (k0[i] * mCHt0[j] + k1[i] * mCHt1[j] + k2[i] * mCHt2[j]);
594 }
595 }
596
597 //* Calculate Chi^2
598
599 fNDF += 2;
600 fQ += Daughter.GetQ();
601 fSFromDecay = 0;
602 fChi2 += (mS[0] * zeta[0] + mS[1] * zeta[1] + mS[3] * zeta[2]) * zeta[0]
603 + (mS[1] * zeta[0] + mS[2] * zeta[1] + mS[4] * zeta[2]) * zeta[1]
604 + (mS[3] * zeta[0] + mS[4] * zeta[1] + mS[5] * zeta[2]) * zeta[2];
605 }
606}
607
609{
610 //* Energy considered as a dependent variable, calculated from the momentum and mass hypothesis
611
612 //* Add daughter
613
615
616 Double_t b[3];
617 Int_t maxIter = 1;
618
619 if (!fIsLinearized) {
620 if (fNDF == -1) {
621 Double_t ds, ds1;
622 GetDStoParticle(Daughter, ds, ds1);
623 TransportToDS(ds);
624 Double_t m[8];
625 Double_t mCd[36];
626 Daughter.Transport(ds1, m, mCd);
627 fVtxGuess[0] = .5 * (fP[0] + m[0]);
628 fVtxGuess[1] = .5 * (fP[1] + m[1]);
629 fVtxGuess[2] = .5 * (fP[2] + m[2]);
630 } else {
631 fVtxGuess[0] = fP[0];
632 fVtxGuess[1] = fP[1];
633 fVtxGuess[2] = fP[2];
634 }
635 maxIter = 3;
636 }
637
638 for (Int_t iter = 0; iter < maxIter; iter++) {
639
640 {
642 const Double_t kCLight = 0.000299792458;
643 b[0] *= kCLight;
644 b[1] *= kCLight;
645 b[2] *= kCLight;
646 }
647
648 Double_t *ffP = fP, *ffC = fC, tmpP[8], tmpC[36];
649 if (fNDF == -1) {
650 GetMeasurement(fVtxGuess, tmpP, tmpC);
651 ffP = tmpP;
652 ffC = tmpC;
653 }
654
655 Double_t m[8], mV[36];
656
657 if (Daughter.fC[35] > 0) {
658 Daughter.GetMeasurement(fVtxGuess, m, mV);
659 } else {
660 for (Int_t i = 0; i < 8; i++)
661 m[i] = Daughter.fP[i];
662 for (Int_t i = 0; i < 36; i++)
663 mV[i] = Daughter.fC[i];
664 }
665
666 double massMf2 = m[6] * m[6] - (m[3] * m[3] + m[4] * m[4] + m[5] * m[5]);
667 double massRf2 = fP[6] * fP[6] - (fP[3] * fP[3] + fP[4] * fP[4] + fP[5] * fP[5]);
668
669 //*
670
671 Double_t mS[6];
672 {
673 Double_t mSi[6] = {ffC[0] + mV[0], ffC[1] + mV[1], ffC[2] + mV[2],
674 ffC[3] + mV[3], ffC[4] + mV[4], ffC[5] + mV[5]};
675
676 mS[0] = mSi[2] * mSi[5] - mSi[4] * mSi[4];
677 mS[1] = mSi[3] * mSi[4] - mSi[1] * mSi[5];
678 mS[2] = mSi[0] * mSi[5] - mSi[3] * mSi[3];
679 mS[3] = mSi[1] * mSi[4] - mSi[2] * mSi[3];
680 mS[4] = mSi[1] * mSi[3] - mSi[0] * mSi[4];
681 mS[5] = mSi[0] * mSi[2] - mSi[1] * mSi[1];
682
683 Double_t s = (mSi[0] * mS[0] + mSi[1] * mS[1] + mSi[3] * mS[3]);
684
685 s = (s > 1.E-20) ? 1. / s : 0;
686 mS[0] *= s;
687 mS[1] *= s;
688 mS[2] *= s;
689 mS[3] *= s;
690 mS[4] *= s;
691 mS[5] *= s;
692 }
693
694 //* Residual (measured - estimated)
695
696 Double_t zeta[3] = {m[0] - ffP[0], m[1] - ffP[1], m[2] - ffP[2]};
697
698 //* CHt = CH' - D'
699
700 Double_t mCHt0[6], mCHt1[6], mCHt2[6];
701
702 mCHt0[0] = ffC[0];
703 mCHt1[0] = ffC[1];
704 mCHt2[0] = ffC[3];
705 mCHt0[1] = ffC[1];
706 mCHt1[1] = ffC[2];
707 mCHt2[1] = ffC[4];
708 mCHt0[2] = ffC[3];
709 mCHt1[2] = ffC[4];
710 mCHt2[2] = ffC[5];
711 mCHt0[3] = ffC[6] - mV[6];
712 mCHt1[3] = ffC[7] - mV[7];
713 mCHt2[3] = ffC[8] - mV[8];
714 mCHt0[4] = ffC[10] - mV[10];
715 mCHt1[4] = ffC[11] - mV[11];
716 mCHt2[4] = ffC[12] - mV[12];
717 mCHt0[5] = ffC[15] - mV[15];
718 mCHt1[5] = ffC[16] - mV[16];
719 mCHt2[5] = ffC[17] - mV[17];
720
721 //* Kalman gain K = mCH'*S
722
723 Double_t k0[6], k1[6], k2[6];
724
725 for (Int_t i = 0; i < 6; ++i) {
726 k0[i] = mCHt0[i] * mS[0] + mCHt1[i] * mS[1] + mCHt2[i] * mS[3];
727 k1[i] = mCHt0[i] * mS[1] + mCHt1[i] * mS[2] + mCHt2[i] * mS[4];
728 k2[i] = mCHt0[i] * mS[3] + mCHt1[i] * mS[4] + mCHt2[i] * mS[5];
729 }
730
731 //* New estimation of the vertex position
732
733 if (iter < maxIter - 1) {
734 for (Int_t i = 0; i < 3; ++i)
735 fVtxGuess[i] = ffP[i] + k0[i] * zeta[0] + k1[i] * zeta[1] + k2[i] * zeta[2];
736 continue;
737 }
738
739 //* find mf and mVf - optimum value of the measurement and its covariance matrix
740 //* mVHt = V*H'
741 Double_t mVHt0[6], mVHt1[6], mVHt2[6];
742
743 mVHt0[0] = mV[0];
744 mVHt1[0] = mV[1];
745 mVHt2[0] = mV[3];
746 mVHt0[1] = mV[1];
747 mVHt1[1] = mV[2];
748 mVHt2[1] = mV[4];
749 mVHt0[2] = mV[3];
750 mVHt1[2] = mV[4];
751 mVHt2[2] = mV[5];
752 mVHt0[3] = mV[6];
753 mVHt1[3] = mV[7];
754 mVHt2[3] = mV[8];
755 mVHt0[4] = mV[10];
756 mVHt1[4] = mV[11];
757 mVHt2[4] = mV[12];
758 mVHt0[5] = mV[15];
759 mVHt1[5] = mV[16];
760 mVHt2[5] = mV[17];
761
762 //* Kalman gain Km = mCH'*S
763
764 Double_t km0[6], km1[6], km2[6];
765
766 for (Int_t i = 0; i < 6; ++i) {
767 km0[i] = mVHt0[i] * mS[0] + mVHt1[i] * mS[1] + mVHt2[i] * mS[3];
768 km1[i] = mVHt0[i] * mS[1] + mVHt1[i] * mS[2] + mVHt2[i] * mS[4];
769 km2[i] = mVHt0[i] * mS[3] + mVHt1[i] * mS[4] + mVHt2[i] * mS[5];
770 }
771
772 Double_t mf[7] = {m[0], m[1], m[2], m[3], m[4], m[5], m[6]};
773
774 for (Int_t i = 0; i < 6; ++i)
775 mf[i] = mf[i] - km0[i] * zeta[0] - km1[i] * zeta[1] - km2[i] * zeta[2];
776
777 Double_t energyMf = TMath::Sqrt(massMf2 + (mf[3] * mf[3] + mf[4] * mf[4] + mf[5] * mf[5]));
778
779 Double_t mVf[28];
780 for (Int_t iC = 0; iC < 28; iC++)
781 mVf[iC] = mV[iC];
782
783 //* hmf = d(energyMf)/d(mf)
784 Double_t hmf[7];
785 if (TMath::Abs(energyMf) < 1.e-10)
786 hmf[3] = 0;
787 else
788 hmf[3] = mf[3] / energyMf;
789 if (TMath::Abs(energyMf) < 1.e-10)
790 hmf[4] = 0;
791 else
792 hmf[4] = mf[4] / energyMf;
793 if (TMath::Abs(energyMf) < 1.e-10)
794 hmf[5] = 0;
795 else
796 hmf[5] = mf[5] / energyMf;
797 // if( TMath::Abs(energyMf) < 1.e-10) hmf[6] = 0; else hmf[6] = mf[6]/energyMf;
798 hmf[6] = 0;
799
800 for (Int_t i = 0, k = 0; i < 6; ++i) {
801 for (Int_t j = 0; j <= i; ++j, ++k) {
802 mVf[k] = mVf[k] - (km0[i] * mVHt0[j] + km1[i] * mVHt1[j] + km2[i] * mVHt2[j]);
803 }
804 }
805 Double_t mVf24 = mVf[24], mVf25 = mVf[25], mVf26 = mVf[26];
806 mVf[21] = mVf[6] * hmf[3] + mVf[10] * hmf[4] + mVf[15] * hmf[5] + mVf[21] * hmf[6];
807 mVf[22] = mVf[7] * hmf[3] + mVf[11] * hmf[4] + mVf[16] * hmf[5] + mVf[22] * hmf[6];
808 mVf[23] = mVf[8] * hmf[3] + mVf[12] * hmf[4] + mVf[17] * hmf[5] + mVf[23] * hmf[6];
809 mVf[24] = mVf[9] * hmf[3] + mVf[13] * hmf[4] + mVf[18] * hmf[5] + mVf[24] * hmf[6];
810 mVf[25] = mVf[13] * hmf[3] + mVf[14] * hmf[4] + mVf[19] * hmf[5] + mVf[25] * hmf[6];
811 mVf[26] = mVf[18] * hmf[3] + mVf[19] * hmf[4] + mVf[20] * hmf[5] + mVf[26] * hmf[6];
812 mVf[27] = mVf[24] * hmf[3] + mVf[25] * hmf[4] + mVf[26] * hmf[5]
813 + (mVf24 * hmf[3] + mVf25 * hmf[4] + mVf26 * hmf[5] + mVf[27] * hmf[6])
814 * hmf[6]; // here mVf[] are already modified
815
816 mf[6] = energyMf;
817
818 //* find rf and mCf - optimum value of the measurement and its covariance matrix
819
820 //* mCCHt = C*H'
821 Double_t mCCHt0[6], mCCHt1[6], mCCHt2[6];
822
823 mCCHt0[0] = ffC[0];
824 mCCHt1[0] = ffC[1];
825 mCCHt2[0] = ffC[3];
826 mCCHt0[1] = ffC[1];
827 mCCHt1[1] = ffC[2];
828 mCCHt2[1] = ffC[4];
829 mCCHt0[2] = ffC[3];
830 mCCHt1[2] = ffC[4];
831 mCCHt2[2] = ffC[5];
832 mCCHt0[3] = ffC[6];
833 mCCHt1[3] = ffC[7];
834 mCCHt2[3] = ffC[8];
835 mCCHt0[4] = ffC[10];
836 mCCHt1[4] = ffC[11];
837 mCCHt2[4] = ffC[12];
838 mCCHt0[5] = ffC[15];
839 mCCHt1[5] = ffC[16];
840 mCCHt2[5] = ffC[17];
841
842 //* Kalman gain Krf = mCH'*S
843
844 Double_t krf0[6], krf1[6], krf2[6];
845
846 for (Int_t i = 0; i < 6; ++i) {
847 krf0[i] = mCCHt0[i] * mS[0] + mCCHt1[i] * mS[1] + mCCHt2[i] * mS[3];
848 krf1[i] = mCCHt0[i] * mS[1] + mCCHt1[i] * mS[2] + mCCHt2[i] * mS[4];
849 krf2[i] = mCCHt0[i] * mS[3] + mCCHt1[i] * mS[4] + mCCHt2[i] * mS[5];
850 }
851 Double_t rf[7] = {ffP[0], ffP[1], ffP[2], ffP[3], ffP[4], ffP[5], ffP[6]};
852
853 for (Int_t i = 0; i < 6; ++i)
854 rf[i] = rf[i] + krf0[i] * zeta[0] + krf1[i] * zeta[1] + krf2[i] * zeta[2];
855
856 Double_t energyRf = TMath::Sqrt(massRf2 + (rf[3] * rf[3] + rf[4] * rf[4] + rf[5] * rf[5]));
857
858 Double_t mCf[28];
859 for (Int_t iC = 0; iC < 28; iC++)
860 mCf[iC] = ffC[iC];
861 //* hrf = d(Erf)/d(rf)
862 Double_t hrf[7];
863 if (TMath::Abs(energyRf) < 1.e-10)
864 hrf[3] = 0;
865 else
866 hrf[3] = rf[3] / energyRf;
867 if (TMath::Abs(energyRf) < 1.e-10)
868 hrf[4] = 0;
869 else
870 hrf[4] = rf[4] / energyRf;
871 if (TMath::Abs(energyRf) < 1.e-10)
872 hrf[5] = 0;
873 else
874 hrf[5] = rf[5] / energyRf;
875 // if( TMath::Abs(energyRf) < 1.e-10) hrf[6] = 0; else hrf[6] = rf[6]/energyRf;
876 hrf[6] = 0;
877
878 for (Int_t i = 0, k = 0; i < 6; ++i) {
879 for (Int_t j = 0; j <= i; ++j, ++k) {
880 mCf[k] = mCf[k] - (krf0[i] * mCCHt0[j] + krf1[i] * mCCHt1[j] + krf2[i] * mCCHt2[j]);
881 }
882 }
883 Double_t mCf24 = mCf[24], mCf25 = mCf[25], mCf26 = mCf[26];
884 mCf[21] = mCf[6] * hrf[3] + mCf[10] * hrf[4] + mCf[15] * hrf[5] + mCf[21] * hrf[6];
885 mCf[22] = mCf[7] * hrf[3] + mCf[11] * hrf[4] + mCf[16] * hrf[5] + mCf[22] * hrf[6];
886 mCf[23] = mCf[8] * hrf[3] + mCf[12] * hrf[4] + mCf[17] * hrf[5] + mCf[23] * hrf[6];
887 mCf[24] = mCf[9] * hrf[3] + mCf[13] * hrf[4] + mCf[18] * hrf[5] + mCf[24] * hrf[6];
888 mCf[25] = mCf[13] * hrf[3] + mCf[14] * hrf[4] + mCf[19] * hrf[5] + mCf[25] * hrf[6];
889 mCf[26] = mCf[18] * hrf[3] + mCf[19] * hrf[4] + mCf[20] * hrf[5] + mCf[26] * hrf[6];
890 mCf[27] = mCf[24] * hrf[3] + mCf[25] * hrf[4] + mCf[26] * hrf[5]
891 + (mCf24 * hrf[3] + mCf25 * hrf[4] + mCf26 * hrf[5] + mCf[27] * hrf[6])
892 * hrf[6]; // here mCf[] are already modified
893
894 for (Int_t iC = 21; iC < 28; iC++) {
895 ffC[iC] = mCf[iC];
896 mV[iC] = mVf[iC];
897 }
898
899 fP[6] = energyRf + energyMf;
900 rf[6] = energyRf;
901
902 // Double_t Dvv[3][3]; do not need this
903 Double_t mDvp[3][3];
904 Double_t mDpv[3][3];
905 Double_t mDpp[3][3];
906 Double_t mDe[7];
907
908 for (int i = 0; i < 3; i++) {
909 for (int j = 0; j < 3; j++) {
910 mDvp[i][j] = km0[i + 3] * mCCHt0[j] + km1[i + 3] * mCCHt1[j] + km2[i + 3] * mCCHt2[j];
911 mDpv[i][j] = km0[i] * mCCHt0[j + 3] + km1[i] * mCCHt1[j + 3] + km2[i] * mCCHt2[j + 3];
912 mDpp[i][j] = km0[i + 3] * mCCHt0[j + 3] + km1[i + 3] * mCCHt1[j + 3] + km2[i + 3] * mCCHt2[j + 3];
913 }
914 }
915
916 mDe[0] = hmf[3] * mDvp[0][0] + hmf[4] * mDvp[1][0] + hmf[5] * mDvp[2][0];
917 mDe[1] = hmf[3] * mDvp[0][1] + hmf[4] * mDvp[1][1] + hmf[5] * mDvp[2][1];
918 mDe[2] = hmf[3] * mDvp[0][2] + hmf[4] * mDvp[1][2] + hmf[5] * mDvp[2][2];
919 mDe[3] = hmf[3] * mDpp[0][0] + hmf[4] * mDpp[1][0] + hmf[5] * mDpp[2][0];
920 mDe[4] = hmf[3] * mDpp[0][1] + hmf[4] * mDpp[1][1] + hmf[5] * mDpp[2][1];
921 mDe[5] = hmf[3] * mDpp[0][2] + hmf[4] * mDpp[1][2] + hmf[5] * mDpp[2][2];
922 mDe[6] = 2 * (mDe[3] * hrf[3] + mDe[4] * hrf[4] + mDe[5] * hrf[5]);
923
924 // last itearation -> update the particle
925
926 //* Add the daughter momentum to the particle momentum
927
928 ffP[3] += m[3];
929 ffP[4] += m[4];
930 ffP[5] += m[5];
931
932 ffC[9] += mV[9];
933 ffC[13] += mV[13];
934 ffC[14] += mV[14];
935 ffC[18] += mV[18];
936 ffC[19] += mV[19];
937 ffC[20] += mV[20];
938 ffC[24] += mV[24];
939 ffC[25] += mV[25];
940 ffC[26] += mV[26];
941 ffC[27] += mV[27];
942
943 ffC[21] += mDe[0];
944 ffC[22] += mDe[1];
945 ffC[23] += mDe[2];
946 ffC[24] += mDe[3];
947 ffC[25] += mDe[4];
948 ffC[26] += mDe[5];
949 ffC[27] += mDe[6];
950
951 //* New estimation of the vertex position r += K*zeta
952
953 for (Int_t i = 0; i < 6; ++i)
954 fP[i] = ffP[i] + k0[i] * zeta[0] + k1[i] * zeta[1] + k2[i] * zeta[2];
955
956 //* New covariance matrix C -= K*(mCH')'
957
958 for (Int_t i = 0, k = 0; i < 6; ++i) {
959 for (Int_t j = 0; j <= i; ++j, ++k) {
960 fC[k] = ffC[k] - (k0[i] * mCHt0[j] + k1[i] * mCHt1[j] + k2[i] * mCHt2[j]);
961 }
962 }
963
964 for (int i = 21; i < 28; i++)
965 fC[i] = ffC[i];
966
967 //* Calculate Chi^2
968
969 fNDF += 2;
970 fQ += Daughter.GetQ();
971 fSFromDecay = 0;
972 fChi2 += (mS[0] * zeta[0] + mS[1] * zeta[1] + mS[3] * zeta[2]) * zeta[0]
973 + (mS[1] * zeta[0] + mS[2] * zeta[1] + mS[4] * zeta[2]) * zeta[1]
974 + (mS[3] * zeta[0] + mS[4] * zeta[1] + mS[5] * zeta[2]) * zeta[2];
975 }
976}
977
979{
980 //* Energy considered as an independent variable, fitted independently from momentum, without any constraints on
981 // mass
982
983 //* Add daughter
984
986
987 Double_t b[3];
988 Int_t maxIter = 1;
989
990 if (!fIsLinearized) {
991 if (fNDF == -1) {
992 Double_t ds, ds1;
993 GetDStoParticle(Daughter, ds, ds1);
994 TransportToDS(ds);
995 Double_t m[8];
996 Double_t mCd[36];
997 Daughter.Transport(ds1, m, mCd);
998 fVtxGuess[0] = .5 * (fP[0] + m[0]);
999 fVtxGuess[1] = .5 * (fP[1] + m[1]);
1000 fVtxGuess[2] = .5 * (fP[2] + m[2]);
1001 } else {
1002 fVtxGuess[0] = fP[0];
1003 fVtxGuess[1] = fP[1];
1004 fVtxGuess[2] = fP[2];
1005 }
1006 maxIter = 3;
1007 }
1008
1009 for (Int_t iter = 0; iter < maxIter; iter++) {
1010
1011 {
1013 const Double_t kCLight = 0.000299792458;
1014 b[0] *= kCLight;
1015 b[1] *= kCLight;
1016 b[2] *= kCLight;
1017 }
1018
1019 Double_t *ffP = fP, *ffC = fC, tmpP[8], tmpC[36];
1020 if (fNDF == -1) {
1021 GetMeasurement(fVtxGuess, tmpP, tmpC);
1022 ffP = tmpP;
1023 ffC = tmpC;
1024 }
1025 Double_t m[8], mV[36];
1026
1027 if (Daughter.fC[35] > 0) {
1028 Daughter.GetMeasurement(fVtxGuess, m, mV);
1029 } else {
1030 for (Int_t i = 0; i < 8; i++)
1031 m[i] = Daughter.fP[i];
1032 for (Int_t i = 0; i < 36; i++)
1033 mV[i] = Daughter.fC[i];
1034 }
1035 //*
1036
1037 Double_t mS[6];
1038 {
1039 Double_t mSi[6] = {ffC[0] + mV[0], ffC[1] + mV[1], ffC[2] + mV[2],
1040 ffC[3] + mV[3], ffC[4] + mV[4], ffC[5] + mV[5]};
1041
1042 mS[0] = mSi[2] * mSi[5] - mSi[4] * mSi[4];
1043 mS[1] = mSi[3] * mSi[4] - mSi[1] * mSi[5];
1044 mS[2] = mSi[0] * mSi[5] - mSi[3] * mSi[3];
1045 mS[3] = mSi[1] * mSi[4] - mSi[2] * mSi[3];
1046 mS[4] = mSi[1] * mSi[3] - mSi[0] * mSi[4];
1047 mS[5] = mSi[0] * mSi[2] - mSi[1] * mSi[1];
1048
1049 Double_t s = (mSi[0] * mS[0] + mSi[1] * mS[1] + mSi[3] * mS[3]);
1050
1051 s = (s > 1.E-20) ? 1. / s : 0;
1052 mS[0] *= s;
1053 mS[1] *= s;
1054 mS[2] *= s;
1055 mS[3] *= s;
1056 mS[4] *= s;
1057 mS[5] *= s;
1058 }
1059 //* Residual (measured - estimated)
1060
1061 Double_t zeta[3] = {m[0] - ffP[0], m[1] - ffP[1], m[2] - ffP[2]};
1062
1063 //* CHt = CH'
1064
1065 Double_t mCHt0[7], mCHt1[7], mCHt2[7];
1066
1067 mCHt0[0] = ffC[0];
1068 mCHt1[0] = ffC[1];
1069 mCHt2[0] = ffC[3];
1070 mCHt0[1] = ffC[1];
1071 mCHt1[1] = ffC[2];
1072 mCHt2[1] = ffC[4];
1073 mCHt0[2] = ffC[3];
1074 mCHt1[2] = ffC[4];
1075 mCHt2[2] = ffC[5];
1076 mCHt0[3] = ffC[6];
1077 mCHt1[3] = ffC[7];
1078 mCHt2[3] = ffC[8];
1079 mCHt0[4] = ffC[10];
1080 mCHt1[4] = ffC[11];
1081 mCHt2[4] = ffC[12];
1082 mCHt0[5] = ffC[15];
1083 mCHt1[5] = ffC[16];
1084 mCHt2[5] = ffC[17];
1085 mCHt0[6] = ffC[21];
1086 mCHt1[6] = ffC[22];
1087 mCHt2[6] = ffC[23];
1088
1089 //* Kalman gain K = mCH'*S
1090
1091 Double_t k0[7], k1[7], k2[7];
1092
1093 for (Int_t i = 0; i < 7; ++i) {
1094 k0[i] = mCHt0[i] * mS[0] + mCHt1[i] * mS[1] + mCHt2[i] * mS[3];
1095 k1[i] = mCHt0[i] * mS[1] + mCHt1[i] * mS[2] + mCHt2[i] * mS[4];
1096 k2[i] = mCHt0[i] * mS[3] + mCHt1[i] * mS[4] + mCHt2[i] * mS[5];
1097 }
1098
1099 //* New estimation of the vertex position
1100
1101 if (iter < maxIter - 1) {
1102 for (Int_t i = 0; i < 3; ++i)
1103 fVtxGuess[i] = ffP[i] + k0[i] * zeta[0] + k1[i] * zeta[1] + k2[i] * zeta[2];
1104 continue;
1105 }
1106
1107 // last itearation -> update the particle
1108
1109 //* VHt = VH'
1110
1111 Double_t mVHt0[7], mVHt1[7], mVHt2[7];
1112
1113 mVHt0[0] = mV[0];
1114 mVHt1[0] = mV[1];
1115 mVHt2[0] = mV[3];
1116 mVHt0[1] = mV[1];
1117 mVHt1[1] = mV[2];
1118 mVHt2[1] = mV[4];
1119 mVHt0[2] = mV[3];
1120 mVHt1[2] = mV[4];
1121 mVHt2[2] = mV[5];
1122 mVHt0[3] = mV[6];
1123 mVHt1[3] = mV[7];
1124 mVHt2[3] = mV[8];
1125 mVHt0[4] = mV[10];
1126 mVHt1[4] = mV[11];
1127 mVHt2[4] = mV[12];
1128 mVHt0[5] = mV[15];
1129 mVHt1[5] = mV[16];
1130 mVHt2[5] = mV[17];
1131 mVHt0[6] = mV[21];
1132 mVHt1[6] = mV[22];
1133 mVHt2[6] = mV[23];
1134
1135 //* Kalman gain Km = mCH'*S
1136
1137 Double_t km0[7], km1[7], km2[7];
1138
1139 for (Int_t i = 0; i < 7; ++i) {
1140 km0[i] = mVHt0[i] * mS[0] + mVHt1[i] * mS[1] + mVHt2[i] * mS[3];
1141 km1[i] = mVHt0[i] * mS[1] + mVHt1[i] * mS[2] + mVHt2[i] * mS[4];
1142 km2[i] = mVHt0[i] * mS[3] + mVHt1[i] * mS[4] + mVHt2[i] * mS[5];
1143 }
1144
1145 for (Int_t i = 0; i < 7; ++i)
1146 ffP[i] = ffP[i] + k0[i] * zeta[0] + k1[i] * zeta[1] + k2[i] * zeta[2];
1147
1148 for (Int_t i = 0; i < 7; ++i)
1149 m[i] = m[i] - km0[i] * zeta[0] - km1[i] * zeta[1] - km2[i] * zeta[2];
1150
1151 for (Int_t i = 0, k = 0; i < 7; ++i) {
1152 for (Int_t j = 0; j <= i; ++j, ++k) {
1153 ffC[k] = ffC[k] - (k0[i] * mCHt0[j] + k1[i] * mCHt1[j] + k2[i] * mCHt2[j]);
1154 }
1155 }
1156
1157 for (Int_t i = 0, k = 0; i < 7; ++i) {
1158 for (Int_t j = 0; j <= i; ++j, ++k) {
1159 mV[k] = mV[k] - (km0[i] * mVHt0[j] + km1[i] * mVHt1[j] + km2[i] * mVHt2[j]);
1160 }
1161 }
1162
1163 Double_t mDf[7][7];
1164
1165 for (Int_t i = 0; i < 7; ++i) {
1166 for (Int_t j = 0; j < 7; ++j) {
1167 mDf[i][j] = (km0[i] * mCHt0[j] + km1[i] * mCHt1[j] + km2[i] * mCHt2[j]);
1168 }
1169 }
1170
1171 Double_t mJ1[7][7], mJ2[7][7];
1172 for (Int_t iPar1 = 0; iPar1 < 7; iPar1++) {
1173 for (Int_t iPar2 = 0; iPar2 < 7; iPar2++) {
1174 mJ1[iPar1][iPar2] = 0;
1175 mJ2[iPar1][iPar2] = 0;
1176 }
1177 }
1178
1179 Double_t mMassParticle = ffP[6] * ffP[6] - (ffP[3] * ffP[3] + ffP[4] * ffP[4] + ffP[5] * ffP[5]);
1180 Double_t mMassDaughter = m[6] * m[6] - (m[3] * m[3] + m[4] * m[4] + m[5] * m[5]);
1181 if (mMassParticle > 0)
1182 mMassParticle = TMath::Sqrt(mMassParticle);
1183 if (mMassDaughter > 0)
1184 mMassDaughter = TMath::Sqrt(mMassDaughter);
1185
1186 if (fMassHypo > -0.5)
1187 SetMassConstraint(ffP, ffC, mJ1, fMassHypo);
1188 else if ((mMassParticle < SumDaughterMass) || (ffP[6] < 0))
1189 SetMassConstraint(ffP, ffC, mJ1, SumDaughterMass);
1190
1191 if (Daughter.fMassHypo > -0.5)
1192 SetMassConstraint(m, mV, mJ2, Daughter.fMassHypo);
1193 else if ((mMassDaughter < Daughter.SumDaughterMass) || (m[6] < 0))
1194 SetMassConstraint(m, mV, mJ2, Daughter.SumDaughterMass);
1195
1196 Double_t mDJ[7][7];
1197
1198 for (Int_t i = 0; i < 7; i++) {
1199 for (Int_t j = 0; j < 7; j++) {
1200 mDJ[i][j] = 0;
1201 for (Int_t k = 0; k < 7; k++) {
1202 mDJ[i][j] += mDf[i][k] * mJ1[j][k];
1203 }
1204 }
1205 }
1206
1207 for (Int_t i = 0; i < 7; ++i) {
1208 for (Int_t j = 0; j < 7; ++j) {
1209 mDf[i][j] = 0;
1210 for (Int_t l = 0; l < 7; l++) {
1211 mDf[i][j] += mJ2[i][l] * mDJ[l][j];
1212 }
1213 }
1214 }
1215
1216 //* Add the daughter momentum to the particle momentum
1217
1218 ffP[3] += m[3];
1219 ffP[4] += m[4];
1220 ffP[5] += m[5];
1221 ffP[6] += m[6];
1222
1223 ffC[9] += mV[9];
1224 ffC[13] += mV[13];
1225 ffC[14] += mV[14];
1226 ffC[18] += mV[18];
1227 ffC[19] += mV[19];
1228 ffC[20] += mV[20];
1229 ffC[24] += mV[24];
1230 ffC[25] += mV[25];
1231 ffC[26] += mV[26];
1232 ffC[27] += mV[27];
1233
1234 ffC[6] += mDf[3][0];
1235 ffC[7] += mDf[3][1];
1236 ffC[8] += mDf[3][2];
1237 ffC[10] += mDf[4][0];
1238 ffC[11] += mDf[4][1];
1239 ffC[12] += mDf[4][2];
1240 ffC[15] += mDf[5][0];
1241 ffC[16] += mDf[5][1];
1242 ffC[17] += mDf[5][2];
1243 ffC[21] += mDf[6][0];
1244 ffC[22] += mDf[6][1];
1245 ffC[23] += mDf[6][2];
1246
1247 ffC[9] += mDf[3][3] + mDf[3][3];
1248 ffC[13] += mDf[4][3] + mDf[3][4];
1249 ffC[14] += mDf[4][4] + mDf[4][4];
1250 ffC[18] += mDf[5][3] + mDf[3][5];
1251 ffC[19] += mDf[5][4] + mDf[4][5];
1252 ffC[20] += mDf[5][5] + mDf[5][5];
1253 ffC[24] += mDf[6][3] + mDf[3][6];
1254 ffC[25] += mDf[6][4] + mDf[4][6];
1255 ffC[26] += mDf[6][5] + mDf[5][6];
1256 ffC[27] += mDf[6][6] + mDf[6][6];
1257
1258 //* New estimation of the vertex position r += K*zeta
1259
1260 for (Int_t i = 0; i < 7; ++i)
1261 fP[i] = ffP[i];
1262
1263 //* New covariance matrix C -= K*(mCH')'
1264
1265 for (Int_t i = 0, k = 0; i < 7; ++i) {
1266 for (Int_t j = 0; j <= i; ++j, ++k) {
1267 fC[k] = ffC[k];
1268 }
1269 }
1270 //* Calculate Chi^2
1271
1272 fNDF += 2;
1273 fQ += Daughter.GetQ();
1274 fSFromDecay = 0;
1275 fChi2 += (mS[0] * zeta[0] + mS[1] * zeta[1] + mS[3] * zeta[2]) * zeta[0]
1276 + (mS[1] * zeta[0] + mS[2] * zeta[1] + mS[4] * zeta[2]) * zeta[1]
1277 + (mS[3] * zeta[0] + mS[4] * zeta[1] + mS[5] * zeta[2]) * zeta[2];
1278 }
1279}
1280
1282{
1283 //* Set production vertex for the particle, when the particle was not used in the vertex fit
1284
1285 const Double_t *m = Vtx.fP, *mV = Vtx.fC;
1286
1287 Bool_t noS = (fC[35] <= 0); // no decay length allowed
1288
1289 if (noS) {
1291 fP[7] = 0;
1292 fC[28] = fC[29] = fC[30] = fC[31] = fC[32] = fC[33] = fC[34] = fC[35] = 0;
1293 } else {
1295 fP[7] = -fSFromDecay;
1296 fC[28] = fC[29] = fC[30] = fC[31] = fC[32] = fC[33] = fC[34] = 0;
1297 fC[35] = 0.1;
1298
1299 Convert(1);
1300 }
1301
1302 Double_t mAi[6];
1303
1304 InvertSym3(fC, mAi);
1305
1306 Double_t mB[5][3];
1307
1308 mB[0][0] = fC[6] * mAi[0] + fC[7] * mAi[1] + fC[8] * mAi[3];
1309 mB[0][1] = fC[6] * mAi[1] + fC[7] * mAi[2] + fC[8] * mAi[4];
1310 mB[0][2] = fC[6] * mAi[3] + fC[7] * mAi[4] + fC[8] * mAi[5];
1311
1312 mB[1][0] = fC[10] * mAi[0] + fC[11] * mAi[1] + fC[12] * mAi[3];
1313 mB[1][1] = fC[10] * mAi[1] + fC[11] * mAi[2] + fC[12] * mAi[4];
1314 mB[1][2] = fC[10] * mAi[3] + fC[11] * mAi[4] + fC[12] * mAi[5];
1315
1316 mB[2][0] = fC[15] * mAi[0] + fC[16] * mAi[1] + fC[17] * mAi[3];
1317 mB[2][1] = fC[15] * mAi[1] + fC[16] * mAi[2] + fC[17] * mAi[4];
1318 mB[2][2] = fC[15] * mAi[3] + fC[16] * mAi[4] + fC[17] * mAi[5];
1319
1320 mB[3][0] = fC[21] * mAi[0] + fC[22] * mAi[1] + fC[23] * mAi[3];
1321 mB[3][1] = fC[21] * mAi[1] + fC[22] * mAi[2] + fC[23] * mAi[4];
1322 mB[3][2] = fC[21] * mAi[3] + fC[22] * mAi[4] + fC[23] * mAi[5];
1323
1324 mB[4][0] = fC[28] * mAi[0] + fC[29] * mAi[1] + fC[30] * mAi[3];
1325 mB[4][1] = fC[28] * mAi[1] + fC[29] * mAi[2] + fC[30] * mAi[4];
1326 mB[4][2] = fC[28] * mAi[3] + fC[29] * mAi[4] + fC[30] * mAi[5];
1327
1328 Double_t z[3] = {m[0] - fP[0], m[1] - fP[1], m[2] - fP[2]};
1329
1330 {
1331 Double_t mAVi[6] = {fC[0] - mV[0], fC[1] - mV[1], fC[2] - mV[2], fC[3] - mV[3], fC[4] - mV[4], fC[5] - mV[5]};
1332
1333 if (!InvertSym3(mAVi, mAVi)) {
1334
1335 Double_t dChi2 = (+(mAVi[0] * z[0] + mAVi[1] * z[1] + mAVi[3] * z[2]) * z[0]
1336 + (mAVi[1] * z[0] + mAVi[2] * z[1] + mAVi[4] * z[2]) * z[1]
1337 + (mAVi[3] * z[0] + mAVi[4] * z[1] + mAVi[5] * z[2]) * z[2]);
1338
1339 // Take Abs(dChi2) here. Negative value of 'det' or 'dChi2' shows that the particle
1340 // was not used in the production vertex fit
1341
1342 fChi2 += TMath::Abs(dChi2);
1343 }
1344 fNDF += 2;
1345 }
1346
1347 fP[0] = m[0];
1348 fP[1] = m[1];
1349 fP[2] = m[2];
1350 fP[3] += mB[0][0] * z[0] + mB[0][1] * z[1] + mB[0][2] * z[2];
1351 fP[4] += mB[1][0] * z[0] + mB[1][1] * z[1] + mB[1][2] * z[2];
1352 fP[5] += mB[2][0] * z[0] + mB[2][1] * z[1] + mB[2][2] * z[2];
1353 fP[6] += mB[3][0] * z[0] + mB[3][1] * z[1] + mB[3][2] * z[2];
1354 fP[7] += mB[4][0] * z[0] + mB[4][1] * z[1] + mB[4][2] * z[2];
1355
1356 Double_t d0, d1, d2;
1357
1358 fC[0] = mV[0];
1359 fC[1] = mV[1];
1360 fC[2] = mV[2];
1361 fC[3] = mV[3];
1362 fC[4] = mV[4];
1363 fC[5] = mV[5];
1364
1365 d0 = mB[0][0] * mV[0] + mB[0][1] * mV[1] + mB[0][2] * mV[3] - fC[6];
1366 d1 = mB[0][0] * mV[1] + mB[0][1] * mV[2] + mB[0][2] * mV[4] - fC[7];
1367 d2 = mB[0][0] * mV[3] + mB[0][1] * mV[4] + mB[0][2] * mV[5] - fC[8];
1368
1369 fC[6] += d0;
1370 fC[7] += d1;
1371 fC[8] += d2;
1372 fC[9] += d0 * mB[0][0] + d1 * mB[0][1] + d2 * mB[0][2];
1373
1374 d0 = mB[1][0] * mV[0] + mB[1][1] * mV[1] + mB[1][2] * mV[3] - fC[10];
1375 d1 = mB[1][0] * mV[1] + mB[1][1] * mV[2] + mB[1][2] * mV[4] - fC[11];
1376 d2 = mB[1][0] * mV[3] + mB[1][1] * mV[4] + mB[1][2] * mV[5] - fC[12];
1377
1378 fC[10] += d0;
1379 fC[11] += d1;
1380 fC[12] += d2;
1381 fC[13] += d0 * mB[0][0] + d1 * mB[0][1] + d2 * mB[0][2];
1382 fC[14] += d0 * mB[1][0] + d1 * mB[1][1] + d2 * mB[1][2];
1383
1384 d0 = mB[2][0] * mV[0] + mB[2][1] * mV[1] + mB[2][2] * mV[3] - fC[15];
1385 d1 = mB[2][0] * mV[1] + mB[2][1] * mV[2] + mB[2][2] * mV[4] - fC[16];
1386 d2 = mB[2][0] * mV[3] + mB[2][1] * mV[4] + mB[2][2] * mV[5] - fC[17];
1387
1388 fC[15] += d0;
1389 fC[16] += d1;
1390 fC[17] += d2;
1391 fC[18] += d0 * mB[0][0] + d1 * mB[0][1] + d2 * mB[0][2];
1392 fC[19] += d0 * mB[1][0] + d1 * mB[1][1] + d2 * mB[1][2];
1393 fC[20] += d0 * mB[2][0] + d1 * mB[2][1] + d2 * mB[2][2];
1394
1395 d0 = mB[3][0] * mV[0] + mB[3][1] * mV[1] + mB[3][2] * mV[3] - fC[21];
1396 d1 = mB[3][0] * mV[1] + mB[3][1] * mV[2] + mB[3][2] * mV[4] - fC[22];
1397 d2 = mB[3][0] * mV[3] + mB[3][1] * mV[4] + mB[3][2] * mV[5] - fC[23];
1398
1399 fC[21] += d0;
1400 fC[22] += d1;
1401 fC[23] += d2;
1402 fC[24] += d0 * mB[0][0] + d1 * mB[0][1] + d2 * mB[0][2];
1403 fC[25] += d0 * mB[1][0] + d1 * mB[1][1] + d2 * mB[1][2];
1404 fC[26] += d0 * mB[2][0] + d1 * mB[2][1] + d2 * mB[2][2];
1405 fC[27] += d0 * mB[3][0] + d1 * mB[3][1] + d2 * mB[3][2];
1406
1407 d0 = mB[4][0] * mV[0] + mB[4][1] * mV[1] + mB[4][2] * mV[3] - fC[28];
1408 d1 = mB[4][0] * mV[1] + mB[4][1] * mV[2] + mB[4][2] * mV[4] - fC[29];
1409 d2 = mB[4][0] * mV[3] + mB[4][1] * mV[4] + mB[4][2] * mV[5] - fC[30];
1410
1411 fC[28] += d0;
1412 fC[29] += d1;
1413 fC[30] += d2;
1414 fC[31] += d0 * mB[0][0] + d1 * mB[0][1] + d2 * mB[0][2];
1415 fC[32] += d0 * mB[1][0] + d1 * mB[1][1] + d2 * mB[1][2];
1416 fC[33] += d0 * mB[2][0] + d1 * mB[2][1] + d2 * mB[2][2];
1417 fC[34] += d0 * mB[3][0] + d1 * mB[3][1] + d2 * mB[3][2];
1418 fC[35] += d0 * mB[4][0] + d1 * mB[4][1] + d2 * mB[4][2];
1419
1420 if (noS) {
1421 fP[7] = 0;
1422 fC[28] = fC[29] = fC[30] = fC[31] = fC[32] = fC[33] = fC[34] = fC[35] = 0;
1423 } else {
1424 TransportToDS(fP[7]);
1425 Convert(0);
1426 }
1427
1428 fSFromDecay = 0;
1429}
1430
1432{
1433 //* Set nonlinear mass constraint (Mass) on the state vector mP with a covariance matrix mC.
1434
1435 const Double_t energy2 = mP[6] * mP[6], p2 = mP[3] * mP[3] + mP[4] * mP[4] + mP[5] * mP[5], mass2 = mass * mass;
1436
1437 const Double_t a = energy2 - p2 + 2. * mass2;
1438 const Double_t b = -2. * (energy2 + p2);
1439 const Double_t c = energy2 - p2 - mass2;
1440
1441 Double_t lambda = 0;
1442 if (TMath::Abs(b) > 1.e-10)
1443 lambda = -c / b;
1444
1445 Double_t d = 4. * energy2 * p2 - mass2 * (energy2 - p2 - 2. * mass2);
1446 if (d >= 0 && TMath::Abs(a) > 1.e-10)
1447 lambda = (energy2 + p2 - sqrt(d)) / a;
1448
1449 if (mP[6] < 0) // If energy < 0 we need a lambda < 0
1450 lambda = -1000000.; // Empirical, a better solution should be found
1451
1452 Int_t iIter = 0;
1453 for (iIter = 0; iIter < 100; iIter++) {
1454 Double_t lambda2 = lambda * lambda;
1455 Double_t lambda4 = lambda2 * lambda2;
1456
1457 Double_t lambda0 = lambda;
1458
1459 Double_t f = -mass2 * lambda4 + a * lambda2 + b * lambda + c;
1460 Double_t df = -4. * mass2 * lambda2 * lambda + 2. * a * lambda + b;
1461 if (TMath::Abs(df) < 1.e-10)
1462 break;
1463 lambda -= f / df;
1464 if (TMath::Abs(lambda0 - lambda) < 1.e-8)
1465 break;
1466 }
1467
1468 const Double_t lpi = 1. / (1. + lambda);
1469 const Double_t lmi = 1. / (1. - lambda);
1470 const Double_t lp2i = lpi * lpi;
1471 const Double_t lm2i = lmi * lmi;
1472
1473 Double_t lambda2 = lambda * lambda;
1474
1475 Double_t dfl = -4. * mass2 * lambda2 * lambda + 2. * a * lambda + b;
1476 Double_t dfx[7] = {0}; //,0,0,0};
1477 dfx[0] = -2. * (1. + lambda) * (1. + lambda) * mP[3];
1478 dfx[1] = -2. * (1. + lambda) * (1. + lambda) * mP[4];
1479 dfx[2] = -2. * (1. + lambda) * (1. + lambda) * mP[5];
1480 dfx[3] = 2. * (1. - lambda) * (1. - lambda) * mP[6];
1481 Double_t dlx[4] = {1, 1, 1, 1};
1482 if (TMath::Abs(dfl) > 1.e-10) {
1483 for (int i = 0; i < 4; i++)
1484 dlx[i] = -dfx[i] / dfl;
1485 }
1486
1487 Double_t dxx[4] = {mP[3] * lm2i, mP[4] * lm2i, mP[5] * lm2i, -mP[6] * lp2i};
1488
1489 for (Int_t i = 0; i < 7; i++)
1490 for (Int_t j = 0; j < 7; j++)
1491 mJ[i][j] = 0;
1492 mJ[0][0] = 1.;
1493 mJ[1][1] = 1.;
1494 mJ[2][2] = 1.;
1495
1496 for (Int_t i = 3; i < 7; i++)
1497 for (Int_t j = 3; j < 7; j++)
1498 mJ[i][j] = dlx[j - 3] * dxx[i - 3];
1499
1500 for (Int_t i = 3; i < 6; i++)
1501 mJ[i][i] += lmi;
1502 mJ[6][6] += lpi;
1503
1504 Double_t mCJ[7][7];
1505
1506 for (Int_t i = 0; i < 7; i++) {
1507 for (Int_t j = 0; j < 7; j++) {
1508 mCJ[i][j] = 0;
1509 for (Int_t k = 0; k < 7; k++) {
1510 mCJ[i][j] += mC[IJ(i, k)] * mJ[j][k];
1511 }
1512 }
1513 }
1514
1515 for (Int_t i = 0; i < 7; ++i) {
1516 for (Int_t j = 0; j <= i; ++j) {
1517 mC[IJ(i, j)] = 0;
1518 for (Int_t l = 0; l < 7; l++) {
1519 mC[IJ(i, j)] += mJ[i][l] * mCJ[l][j];
1520 }
1521 }
1522 }
1523
1524 mP[3] *= lmi;
1525 mP[4] *= lmi;
1526 mP[5] *= lmi;
1527 mP[6] *= lpi;
1528}
1529
1531{
1532 //* Set nonlinear mass constraint (mass)
1533
1534 Double_t mJ[7][7];
1535 SetMassConstraint(fP, fC, mJ, mass);
1536 fMassHypo = mass;
1537 SumDaughterMass = mass;
1538}
1539
1541{
1542 //* Set hard( SigmaMass=0 ) or soft (SigmaMass>0) mass constraint
1543
1544 fMassHypo = Mass;
1545 SumDaughterMass = Mass;
1546
1547 Double_t m2 = Mass * Mass; // measurement, weighted by Mass
1548 Double_t s2 = m2 * SigmaMass * SigmaMass; // sigma^2
1549
1550 Double_t p2 = fP[3] * fP[3] + fP[4] * fP[4] + fP[5] * fP[5];
1551 Double_t e0 = TMath::Sqrt(m2 + p2);
1552
1553 Double_t mH[8];
1554 mH[0] = mH[1] = mH[2] = 0.;
1555 mH[3] = -2 * fP[3];
1556 mH[4] = -2 * fP[4];
1557 mH[5] = -2 * fP[5];
1558 mH[6] = 2 * fP[6]; // e0;
1559 mH[7] = 0;
1560
1561 Double_t zeta = e0 * e0 - e0 * fP[6];
1562 zeta = m2 - (fP[6] * fP[6] - p2);
1563
1564 Double_t mCHt[8], s2_est = 0;
1565 for (Int_t i = 0; i < 8; ++i) {
1566 mCHt[i] = 0.0;
1567 for (Int_t j = 0; j < 8; ++j)
1568 mCHt[i] += Cij(i, j) * mH[j];
1569 s2_est += mH[i] * mCHt[i];
1570 }
1571
1572 if (s2_est < 1.e-20)
1573 return; // calculated mass error is already 0,
1574 // the particle can not be constrained on mass
1575
1576 Double_t w2 = 1. / (s2 + s2_est);
1577 fChi2 += zeta * zeta * w2;
1578 fNDF += 1;
1579 for (Int_t i = 0, ii = 0; i < 8; ++i) {
1580 Double_t ki = mCHt[i] * w2;
1581 fP[i] += ki * zeta;
1582 for (Int_t j = 0; j <= i; ++j)
1583 fC[ii++] -= ki * mCHt[j];
1584 }
1585}
1586
1588{
1589 //* Set no decay length for resonances
1590
1592
1593 Double_t h[8];
1594 h[0] = h[1] = h[2] = h[3] = h[4] = h[5] = h[6] = 0;
1595 h[7] = 1;
1596
1597 Double_t zeta = 0 - fP[7];
1598 for (Int_t i = 0; i < 8; ++i)
1599 zeta -= h[i] * (fP[i] - fP[i]);
1600
1601 Double_t s = fC[35];
1602 if (s > 1.e-20) {
1603 s = 1. / s;
1604 fChi2 += zeta * zeta * s;
1605 fNDF += 1;
1606 for (Int_t i = 0, ii = 0; i < 7; ++i) {
1607 Double_t ki = fC[28 + i] * s;
1608 fP[i] += ki * zeta;
1609 for (Int_t j = 0; j <= i; ++j)
1610 fC[ii++] -= ki * fC[28 + j];
1611 }
1612 }
1613 fP[7] = 0;
1614 fC[28] = fC[29] = fC[30] = fC[31] = fC[32] = fC[33] = fC[34] = fC[35] = 0;
1615}
1616
1618 Int_t nDaughters,
1619 const KFParticleBase* Parent,
1620 Double_t Mass,
1621 Bool_t IsConstrained)
1622{
1623 //* Full reconstruction in one go
1624
1625 Int_t maxIter = 1;
1626 bool wasLinearized = fIsLinearized;
1627 if (!fIsLinearized || IsConstrained) {
1628 // fVtxGuess[0] = fVtxGuess[1] = fVtxGuess[2] = 0; //!!!!
1629 Double_t ds = 0., ds1 = 0.;
1630 Double_t P[8], C[36];
1631 vDaughters[0]->GetDStoParticle(*vDaughters[1], ds, ds1);
1632 vDaughters[0]->Transport(ds, P, C);
1633 fVtxGuess[0] = P[0];
1634 fVtxGuess[1] = P[1];
1635 fVtxGuess[2] = P[2];
1636 /* fVtxGuess[0] = GetX();
1637 fVtxGuess[1] = GetY();
1638 fVtxGuess[2] = GetZ();*/
1639
1640 fIsLinearized = 1;
1641 maxIter = 3;
1642 }
1643
1644 Double_t constraintC[6];
1645
1646 if (IsConstrained) {
1647 for (Int_t i = 0; i < 6; ++i)
1648 constraintC[i] = fC[i];
1649 } else {
1650 for (Int_t i = 0; i < 6; ++i)
1651 constraintC[i] = 0.;
1652 // constraintC[0] = constraintC[2] = constraintC[5] = 100.;
1653 constraintC[0] = 100. * vDaughters[0]->fC[0];
1654 constraintC[2] = 100. * vDaughters[0]->fC[2];
1655 constraintC[5] = 100. * vDaughters[0]->fC[5];
1656 }
1657
1658 for (Int_t iter = 0; iter < maxIter; iter++) {
1660 fSFromDecay = 0;
1661 fP[0] = fVtxGuess[0];
1662 fP[1] = fVtxGuess[1];
1663 fP[2] = fVtxGuess[2];
1664 fP[3] = 0;
1665 fP[4] = 0;
1666 fP[5] = 0;
1667 fP[6] = 0;
1668 fP[7] = 0;
1669 SumDaughterMass = 0;
1670
1671 for (Int_t i = 0; i < 6; ++i)
1672 fC[i] = constraintC[i];
1673 for (Int_t i = 6; i < 36; ++i)
1674 fC[i] = 0.;
1675 fC[35] = 1.;
1676
1677 fNDF = IsConstrained ? 0 : -3;
1678 fChi2 = 0.;
1679 fQ = 0;
1680
1681 for (Int_t itr = 0; itr < nDaughters; itr++) {
1682 AddDaughter(*vDaughters[itr]);
1683 }
1684 if (iter < maxIter - 1) {
1685 for (Int_t i = 0; i < 3; i++)
1686 fVtxGuess[i] = fP[i];
1687 }
1688 }
1689 fIsLinearized = wasLinearized;
1690
1691 if (Mass >= 0)
1692 SetMassConstraint(Mass);
1693 if (Parent)
1694 SetProductionVertex(*Parent);
1695}
1696
1697void KFParticleBase::Convert(bool ToProduction)
1698{
1699 //* Tricky function - convert the particle error along its trajectory to
1700 //* the value which corresponds to its production/decay vertex
1701 //* It is done by combination of the error of decay length with the position errors
1702
1703 Double_t fld[3];
1704 {
1705 GetFieldValue(fP, fld);
1706 const Double_t kCLight = fQ * 0.000299792458;
1707 fld[0] *= kCLight;
1708 fld[1] *= kCLight;
1709 fld[2] *= kCLight;
1710 }
1711
1712 Double_t h[6];
1713
1714 h[0] = fP[3];
1715 h[1] = fP[4];
1716 h[2] = fP[5];
1717 if (ToProduction) {
1718 h[0] = -h[0];
1719 h[1] = -h[1];
1720 h[2] = -h[2];
1721 }
1722 h[3] = h[1] * fld[2] - h[2] * fld[1];
1723 h[4] = h[2] * fld[0] - h[0] * fld[2];
1724 h[5] = h[0] * fld[1] - h[1] * fld[0];
1725
1726 Double_t c;
1727
1728 c = fC[28] + h[0] * fC[35];
1729 fC[0] += h[0] * (c + fC[28]);
1730 fC[28] = c;
1731
1732 fC[1] += h[1] * fC[28] + h[0] * fC[29];
1733 c = fC[29] + h[1] * fC[35];
1734 fC[2] += h[1] * (c + fC[29]);
1735 fC[29] = c;
1736
1737 fC[3] += h[2] * fC[28] + h[0] * fC[30];
1738 fC[4] += h[2] * fC[29] + h[1] * fC[30];
1739 c = fC[30] + h[2] * fC[35];
1740 fC[5] += h[2] * (c + fC[30]);
1741 fC[30] = c;
1742
1743 fC[6] += h[3] * fC[28] + h[0] * fC[31];
1744 fC[7] += h[3] * fC[29] + h[1] * fC[31];
1745 fC[8] += h[3] * fC[30] + h[2] * fC[31];
1746 c = fC[31] + h[3] * fC[35];
1747 fC[9] += h[3] * (c + fC[31]);
1748 fC[31] = c;
1749
1750 fC[10] += h[4] * fC[28] + h[0] * fC[32];
1751 fC[11] += h[4] * fC[29] + h[1] * fC[32];
1752 fC[12] += h[4] * fC[30] + h[2] * fC[32];
1753 fC[13] += h[4] * fC[31] + h[3] * fC[32];
1754 c = fC[32] + h[4] * fC[35];
1755 fC[14] += h[4] * (c + fC[32]);
1756 fC[32] = c;
1757
1758 fC[15] += h[5] * fC[28] + h[0] * fC[33];
1759 fC[16] += h[5] * fC[29] + h[1] * fC[33];
1760 fC[17] += h[5] * fC[30] + h[2] * fC[33];
1761 fC[18] += h[5] * fC[31] + h[3] * fC[33];
1762 fC[19] += h[5] * fC[32] + h[4] * fC[33];
1763 c = fC[33] + h[5] * fC[35];
1764 fC[20] += h[5] * (c + fC[33]);
1765 fC[33] = c;
1766
1767 fC[21] += h[0] * fC[34];
1768 fC[22] += h[1] * fC[34];
1769 fC[23] += h[2] * fC[34];
1770 fC[24] += h[3] * fC[34];
1771 fC[25] += h[4] * fC[34];
1772 fC[26] += h[5] * fC[34];
1773}
1774
1776{
1777 //* Transport the particle to its decay vertex
1778
1779 if (fSFromDecay != 0)
1782 Convert(0);
1784}
1785
1787{
1788 //* Transport the particle to its production vertex
1789
1790 if (fSFromDecay != -fP[7])
1793 Convert(1);
1795}
1796
1798{
1799 //* Transport the particle on dS parameter (SignedPath/Momentum)
1800
1801 Transport(dS, fP, fC);
1802 fSFromDecay += dS;
1803}
1804
1806{
1807 //* Get dS to a certain space point without field
1808
1809 Double_t p2 = fP[3] * fP[3] + fP[4] * fP[4] + fP[5] * fP[5];
1810 if (p2 < 1.e-4)
1811 p2 = 1;
1812 return (fP[3] * (xyz[0] - fP[0]) + fP[4] * (xyz[1] - fP[1]) + fP[5] * (xyz[2] - fP[2])) / p2;
1813}
1814
1816{
1817
1818 //* Get dS to a certain space point for Bz field
1819 const Double_t kCLight = 0.000299792458;
1820 Double_t bq = B * fQ * kCLight;
1821 Double_t pt2 = fP[3] * fP[3] + fP[4] * fP[4];
1822 if (pt2 < 1.e-4)
1823 return 0;
1824 Double_t dx = xyz[0] - fP[0];
1825 Double_t dy = xyz[1] - fP[1];
1826 Double_t a = dx * fP[3] + dy * fP[4];
1827 Double_t dS;
1828
1829 if (TMath::Abs(bq) < 1.e-8)
1830 dS = a / pt2;
1831 else
1832 dS = TMath::ATan2(bq * a, pt2 + bq * (dy * fP[3] - dx * fP[4])) / bq;
1833
1834 if (0) {
1835
1836 Double_t px = fP[3];
1837 Double_t py = fP[4];
1838 Double_t pz = fP[5];
1839 Double_t ss[2], g[2][5];
1840
1841 ss[0] = dS;
1842 ss[1] = -dS;
1843 for (Int_t i = 0; i < 2; i++) {
1844 Double_t bs = bq * ss[i];
1845 Double_t c = TMath::Cos(bs), s = TMath::Sin(bs);
1846 Double_t cB, sB;
1847 if (TMath::Abs(bq) > 1.e-8) {
1848 cB = (1 - c) / bq;
1849 sB = s / bq;
1850 } else {
1851 const Double_t kOvSqr6 = 1. / TMath::Sqrt(6.);
1852 sB = (1. - bs * kOvSqr6) * (1. + bs * kOvSqr6) * ss[i];
1853 cB = .5 * sB * bs;
1854 }
1855 g[i][0] = fP[0] + sB * px + cB * py;
1856 g[i][1] = fP[1] - cB * px + sB * py;
1857 g[i][2] = fP[2] + ss[i] * pz;
1858 g[i][3] = +c * px + s * py;
1859 g[i][4] = -s * px + c * py;
1860 }
1861
1862 Int_t i = 0;
1863
1864 Double_t dMin = 1.e10;
1865 for (Int_t j = 0; j < 2; j++) {
1866 Double_t xx = g[j][0] - xyz[0];
1867 Double_t yy = g[j][1] - xyz[1];
1868 Double_t zz = g[j][2] - xyz[2];
1869 Double_t d = xx * xx + yy * yy + zz * zz;
1870 if (d < dMin) {
1871 dMin = d;
1872 i = j;
1873 }
1874 }
1875
1876 dS = ss[i];
1877
1878 Double_t x = g[i][0], y = g[i][1], z = g[i][2], ppx = g[i][3], ppy = g[i][4];
1879 Double_t ddx = x - xyz[0];
1880 Double_t ddy = y - xyz[1];
1881 Double_t ddz = z - xyz[2];
1882 Double_t c = ddx * ppx + ddy * ppy + ddz * pz;
1883 Double_t pp2 = ppx * ppx + ppy * ppy + pz * pz;
1884 if (TMath::Abs(pp2) > 1.e-8) {
1885 dS += c / pp2;
1886 }
1887 }
1888 return dS;
1889}
1890
1892{
1893
1894 //* Get dS to a certain space point for Bz field
1895 const Double_t kCLight = 0.000299792458;
1896 Double_t bq = B * fQ * kCLight;
1897 Double_t pt2 = fP[3] * fP[3] + fP[5] * fP[5];
1898 if (pt2 < 1.e-4)
1899 return 0;
1900 Double_t dx = xyz[0] - fP[0];
1901 Double_t dy = -xyz[2] + fP[2];
1902 Double_t a = dx * fP[3] - dy * fP[5];
1903 Double_t dS;
1904
1905 if (TMath::Abs(bq) < 1.e-8)
1906 dS = a / pt2;
1907 else
1908 dS = TMath::ATan2(bq * a, pt2 + bq * (dy * fP[3] + dx * fP[5])) / bq;
1909
1910 return dS;
1911}
1912
1914{
1915 //* Get dS to another particle for Bz field
1916 Double_t px = fP[3];
1917 Double_t py = fP[4];
1918 Double_t pz = fP[5];
1919
1920 Double_t px1 = p.fP[3];
1921 Double_t py1 = p.fP[4];
1922 Double_t pz1 = p.fP[5];
1923
1924 const Double_t kCLight = 0.000299792458;
1925
1926 Double_t bq = B * fQ * kCLight;
1927 Double_t bq1 = B * p.fQ * kCLight;
1928 Double_t s = 0, ds = 0, s1 = 0, ds1 = 0;
1929
1930 if (TMath::Abs(bq) > 1.e-8 || TMath::Abs(bq1) > 1.e-8) {
1931
1932 Double_t dx = (p.fP[0] - fP[0]);
1933 Double_t dy = (p.fP[1] - fP[1]);
1934 Double_t d2 = (dx * dx + dy * dy);
1935
1936 Double_t p2 = (px * px + py * py);
1937 Double_t p21 = (px1 * px1 + py1 * py1);
1938
1939 if (TMath::Abs(p2) < 1.e-8 || TMath::Abs(p21) < 1.e-8) {
1940 DS = 0.;
1941 DS1 = 0.;
1942 return;
1943 }
1944
1945 Double_t a = (px * py1 - py * px1);
1946 Double_t b = (px * px1 + py * py1);
1947
1948 Double_t ldx = bq * bq1 * dx - bq1 * py + bq * py1;
1949 Double_t ldy = bq * bq1 * dy + bq1 * px - bq * px1;
1950 Double_t l2 = ldx * ldx + ldy * ldy;
1951
1952 Double_t cS = bq1 * p2 + bq * bq1 * (dy * px - dx * py) - bq * b;
1953 Double_t cS1 = bq * p21 - bq * bq1 * (dy * px1 - dx * py1) - bq1 * b;
1954
1955 Double_t ca = bq * bq * bq1 * d2 + 2 * (cS + bq * bq * (py1 * dx - px1 * dy));
1956 Double_t ca1 = bq * bq1 * bq1 * d2 + 2 * (cS1 - bq1 * bq1 * (py * dx - px * dy));
1957
1958 Double_t sa = 4 * l2 * p2 - ca * ca;
1959 Double_t sa1 = 4 * l2 * p21 - ca1 * ca1;
1960
1961 if (sa < 0)
1962 sa = 0;
1963 if (sa1 < 0)
1964 sa1 = 0;
1965
1966 if (TMath::Abs(bq) > 1.e-8) {
1967 s = TMath::ATan2(bq * (bq1 * (dx * px + dy * py) + a), cS) / bq;
1968 ds = TMath::ATan2(TMath::Sqrt(sa), ca) / bq;
1969 } else {
1970 s = ((dx * px + dy * py) + (py * px1 - px * py1) / bq1) / p2;
1971 ds = s * s - (d2 - 2 * (px1 * dy - py1 * dx) / bq1) / p2;
1972 if (ds < 0)
1973 ds = 0;
1974 ds = TMath::Sqrt(ds);
1975 }
1976
1977 if (TMath::Abs(bq1) > 1.e-8) {
1978 s1 = TMath::ATan2(-bq1 * (bq * (dx * px1 + dy * py1) + a), cS1) / bq1;
1979 ds1 = TMath::ATan2(TMath::Sqrt(sa1), ca1) / bq1;
1980 } else {
1981 s1 = (-(dx * px1 + dy * py1) + (py * px1 - px * py1) / bq) / p21;
1982 ds1 = s1 * s1 - (d2 + 2 * (px * dy - py * dx) / bq) / p21;
1983 if (ds1 < 0)
1984 ds1 = 0;
1985 ds1 = TMath::Sqrt(ds1);
1986 }
1987 }
1988 Double_t ss[2], ss1[2], g[2][5], g1[2][5];
1989
1990 ss[0] = s + ds;
1991 ss[1] = s - ds;
1992 ss1[0] = s1 + ds1;
1993 ss1[1] = s1 - ds1;
1994
1995 for (Int_t i = 0; i < 2; i++) {
1996 Double_t bs = bq * ss[i];
1997 Double_t c = TMath::Cos(bs), sss = TMath::Sin(bs);
1998 Double_t cB, sB;
1999 if (TMath::Abs(bq) > 1.e-8) {
2000 cB = (1 - c) / bq;
2001 sB = sss / bq;
2002 } else {
2003 const Double_t kOvSqr6 = 1. / TMath::Sqrt(6.);
2004 sB = (1. - bs * kOvSqr6) * (1. + bs * kOvSqr6) * ss[i];
2005 cB = .5 * sB * bs;
2006 }
2007 g[i][0] = fP[0] + sB * px + cB * py;
2008 g[i][1] = fP[1] - cB * px + sB * py;
2009 g[i][2] = fP[2] + ss[i] * pz;
2010 g[i][3] = +c * px + sss * py;
2011 g[i][4] = -sss * px + c * py;
2012
2013 bs = bq1 * ss1[i];
2014 c = TMath::Cos(bs);
2015 sss = TMath::Sin(bs);
2016 if (TMath::Abs(bq1) > 1.e-8) {
2017 cB = (1 - c) / bq1;
2018 sB = sss / bq1;
2019 } else {
2020 const Double_t kOvSqr6 = 1. / TMath::Sqrt(6.);
2021 sB = (1. - bs * kOvSqr6) * (1. + bs * kOvSqr6) * ss1[i];
2022 cB = .5 * sB * bs;
2023 }
2024
2025 g1[i][0] = p.fP[0] + sB * px1 + cB * py1;
2026 g1[i][1] = p.fP[1] - cB * px1 + sB * py1;
2027 g1[i][2] = p.fP[2] + ss1[i] * pz1;
2028 g1[i][3] = +c * px1 + sss * py1;
2029 g1[i][4] = -sss * px1 + c * py1;
2030 }
2031
2032 Int_t i = 0, i1 = 0;
2033
2034 Double_t dMin = 1.e10;
2035 for (Int_t j = 0; j < 2; j++) {
2036 for (Int_t j1 = 0; j1 < 2; j1++) {
2037 Double_t xx = g[j][0] - g1[j1][0];
2038 Double_t yy = g[j][1] - g1[j1][1];
2039 Double_t zz = g[j][2] - g1[j1][2];
2040 Double_t d = xx * xx + yy * yy + zz * zz;
2041 if (d < dMin) {
2042 dMin = d;
2043 i = j;
2044 i1 = j1;
2045 }
2046 }
2047 }
2048
2049 DS = ss[i];
2050 DS1 = ss1[i1];
2051 if (0) {
2052 Double_t x = g[i][0], y = g[i][1], z = g[i][2], ppx = g[i][3], ppy = g[i][4];
2053 Double_t x1 = g1[i1][0], y1 = g1[i1][1], z1 = g1[i1][2], ppx1 = g1[i1][3], ppy1 = g1[i1][4];
2054 Double_t dx = x1 - x;
2055 Double_t dy = y1 - y;
2056 Double_t dz = z1 - z;
2057 Double_t a = ppx * ppx1 + ppy * ppy1 + pz * pz1;
2058 Double_t b = dx * ppx1 + dy * ppy1 + dz * pz1;
2059 Double_t c = dx * ppx + dy * ppy + dz * pz;
2060 Double_t pp2 = ppx * ppx + ppy * ppy + pz * pz;
2061 Double_t pp21 = ppx1 * ppx1 + ppy1 * ppy1 + pz1 * pz1;
2062 Double_t det = pp2 * pp21 - a * a;
2063 if (TMath::Abs(det) > 1.e-8) {
2064 DS += (a * b - pp21 * c) / det;
2065 DS1 += (a * c - pp2 * b) / det;
2066 }
2067 }
2068}
2069
2071{
2072 //* Get dS to another particle for Bz field
2073 Double_t px = fP[3];
2074 Double_t py = -fP[5];
2075 Double_t pz = fP[4];
2076
2077 Double_t px1 = p.fP[3];
2078 Double_t py1 = -p.fP[5];
2079 Double_t pz1 = p.fP[4];
2080
2081 const Double_t kCLight = 0.000299792458;
2082
2083 Double_t bq = B * fQ * kCLight;
2084 Double_t bq1 = B * p.fQ * kCLight;
2085 Double_t s = 0, ds = 0, s1 = 0, ds1 = 0;
2086
2087 if (TMath::Abs(bq) > 1.e-8 || TMath::Abs(bq1) > 1.e-8) {
2088
2089 Double_t dx = (p.fP[0] - fP[0]);
2090 Double_t dy = (-p.fP[2] + fP[2]);
2091 Double_t d2 = (dx * dx + dy * dy);
2092
2093 Double_t p2 = (px * px + py * py);
2094 Double_t p21 = (px1 * px1 + py1 * py1);
2095
2096 if (TMath::Abs(p2) < 1.e-8 || TMath::Abs(p21) < 1.e-8) {
2097 DS = 0.;
2098 DS1 = 0.;
2099 return;
2100 }
2101
2102 Double_t a = (px * py1 - py * px1);
2103 Double_t b = (px * px1 + py * py1);
2104
2105 Double_t ldx = bq * bq1 * dx - bq1 * py + bq * py1;
2106 Double_t ldy = bq * bq1 * dy + bq1 * px - bq * px1;
2107 Double_t l2 = ldx * ldx + ldy * ldy;
2108
2109 Double_t cS = bq1 * p2 + bq * bq1 * (dy * px - dx * py) - bq * b;
2110 Double_t cS1 = bq * p21 - bq * bq1 * (dy * px1 - dx * py1) - bq1 * b;
2111
2112 Double_t ca = bq * bq * bq1 * d2 + 2 * (cS + bq * bq * (py1 * dx - px1 * dy));
2113 Double_t ca1 = bq * bq1 * bq1 * d2 + 2 * (cS1 - bq1 * bq1 * (py * dx - px * dy));
2114
2115 Double_t sa = 4 * l2 * p2 - ca * ca;
2116 Double_t sa1 = 4 * l2 * p21 - ca1 * ca1;
2117
2118 if (sa < 0)
2119 sa = 0;
2120 if (sa1 < 0)
2121 sa1 = 0;
2122
2123 if (TMath::Abs(bq) > 1.e-8) {
2124 s = TMath::ATan2(bq * (bq1 * (dx * px + dy * py) + a), cS) / bq;
2125 ds = TMath::ATan2(TMath::Sqrt(sa), ca) / bq;
2126 } else {
2127 s = ((dx * px + dy * py) + (py * px1 - px * py1) / bq1) / p2;
2128 ds = s * s - (d2 - 2 * (px1 * dy - py1 * dx) / bq1) / p2;
2129 if (ds < 0)
2130 ds = 0;
2131 ds = TMath::Sqrt(ds);
2132 }
2133
2134 if (TMath::Abs(bq1) > 1.e-8) {
2135 s1 = TMath::ATan2(-bq1 * (bq * (dx * px1 + dy * py1) + a), cS1) / bq1;
2136 ds1 = TMath::ATan2(TMath::Sqrt(sa1), ca1) / bq1;
2137 } else {
2138 s1 = (-(dx * px1 + dy * py1) + (py * px1 - px * py1) / bq) / p21;
2139 ds1 = s1 * s1 - (d2 + 2 * (px * dy - py * dx) / bq) / p21;
2140 if (ds1 < 0)
2141 ds1 = 0;
2142 ds1 = TMath::Sqrt(ds1);
2143 }
2144 }
2145 Double_t ss[2], ss1[2], g[2][5], g1[2][5];
2146
2147 ss[0] = s + ds;
2148 ss[1] = s - ds;
2149 ss1[0] = s1 + ds1;
2150 ss1[1] = s1 - ds1;
2151
2152 for (Int_t i = 0; i < 2; i++) {
2153 Double_t bs = bq * ss[i];
2154 Double_t c = TMath::Cos(bs), sss = TMath::Sin(bs);
2155 Double_t cB, sB;
2156 if (TMath::Abs(bq) > 1.e-8) {
2157 cB = (1 - c) / bq;
2158 sB = sss / bq;
2159 } else {
2160 const Double_t kOvSqr6 = 1. / TMath::Sqrt(6.);
2161 sB = (1. - bs * kOvSqr6) * (1. + bs * kOvSqr6) * ss[i];
2162 cB = .5 * sB * bs;
2163 }
2164 g[i][0] = fP[0] + sB * px + cB * py;
2165 g[i][1] = -fP[2] - cB * px + sB * py;
2166 g[i][2] = fP[1] + ss[i] * pz;
2167 g[i][3] = +c * px + sss * py;
2168 g[i][4] = -sss * px + c * py;
2169
2170 bs = bq1 * ss1[i];
2171 c = TMath::Cos(bs);
2172 sss = TMath::Sin(bs);
2173 if (TMath::Abs(bq1) > 1.e-8) {
2174 cB = (1 - c) / bq1;
2175 sB = sss / bq1;
2176 } else {
2177 const Double_t kOvSqr6 = 1. / TMath::Sqrt(6.);
2178 sB = (1. - bs * kOvSqr6) * (1. + bs * kOvSqr6) * ss1[i];
2179 cB = .5 * sB * bs;
2180 }
2181
2182 g1[i][0] = p.fP[0] + sB * px1 + cB * py1;
2183 g1[i][1] = -p.fP[2] - cB * px1 + sB * py1;
2184 g1[i][2] = p.fP[1] + ss1[i] * pz1;
2185 g1[i][3] = +c * px1 + sss * py1;
2186 g1[i][4] = -sss * px1 + c * py1;
2187 }
2188
2189 Int_t i = 0, i1 = 0;
2190
2191 Double_t dMin = 1.e10;
2192 for (Int_t j = 0; j < 2; j++) {
2193 for (Int_t j1 = 0; j1 < 2; j1++) {
2194 Double_t xx = g[j][0] - g1[j1][0];
2195 Double_t yy = g[j][1] - g1[j1][1];
2196 Double_t zz = g[j][2] - g1[j1][2];
2197 Double_t d = xx * xx + yy * yy + zz * zz;
2198 if (d < dMin) {
2199 dMin = d;
2200 i = j;
2201 i1 = j1;
2202 }
2203 }
2204 }
2205
2206 DS = ss[i];
2207 DS1 = ss1[i1];
2208}
2209
2211 Double_t const& dS,
2212 Double_t x[3],
2213 Double_t dx[3],
2214 Double_t ddx[3]) const
2215{
2216 Double_t ssx = 0, ssy = 0, ssz = 0, ssyy = 0, ssyz = 0, ssyyy = 0;
2217 Double_t dssx = 0, dssy = 0, dssz = 0, dssyy = 0, dssyz = 0, dssyyy = 0; // d(...)/dS
2218 Double_t ddssx = 0, ddssy = 0, ddssz = 0, ddssyy = 0, ddssyz = 0, ddssyyy = 0; // d2(...)/dS2
2219 Double_t Kssx = 0, Kssy = 0, Kssz = 0, Kssyy = 0, Kssyz = 0, Kssyyy = 0;
2220
2221 const Double_t kCLight = 0.000299792458;
2222 Double_t c = fQ * kCLight;
2223
2224 // get field integrals
2225
2226 Double_t fld[3][3];
2227 Double_t p0[3], p1[3], p2[3];
2228
2229 // line track approximation
2230
2231 p0[0] = p.fP[0];
2232 p0[1] = p.fP[1];
2233 p0[2] = p.fP[2];
2234
2235 p2[0] = p.fP[0] + p.fP[3] * dS;
2236 p2[1] = p.fP[1] + p.fP[4] * dS;
2237 p2[2] = p.fP[2] + p.fP[5] * dS;
2238
2239 p1[0] = 0.5 * (p0[0] + p2[0]);
2240 p1[1] = 0.5 * (p0[1] + p2[1]);
2241 p1[2] = 0.5 * (p0[2] + p2[2]);
2242
2243 // first order track approximation
2244 {
2245 GetFieldValue(p0, fld[0]);
2246 GetFieldValue(p1, fld[1]);
2247 GetFieldValue(p2, fld[2]);
2248
2249 Double_t ssy1 = (7 * fld[0][1] + 6 * fld[1][1] - fld[2][1]) * c * dS * dS / 96.;
2250 Double_t ssy2 = (fld[0][1] + 2 * fld[1][1]) * c * dS * dS / 6.;
2251
2252 p1[0] -= ssy1 * p.fP[5];
2253 p1[2] += ssy1 * p.fP[3];
2254 p2[0] -= ssy2 * p.fP[5];
2255 p2[2] += ssy2 * p.fP[3];
2256 }
2257
2258 GetFieldValue(p0, fld[0]);
2259 GetFieldValue(p1, fld[1]);
2260 GetFieldValue(p2, fld[2]);
2261
2262 Kssx = c * (fld[0][0] + 2 * fld[1][0]) / 6.;
2263 Kssy = c * (fld[0][1] + 2 * fld[1][1]) / 6.;
2264 Kssz = c * (fld[0][2] + 2 * fld[1][2]) / 6.;
2265
2266 // Double_t c2[3][3] = { { 5, -4, -1},{ 44, 80, -4},{ 11, 44, 5} }; // /=360.
2267 Double_t cc2[3][3] = {{38, 8, -4}, {148, 208, -20}, {3, 36, 3}}; // /=2520.
2268 for (Int_t n = 0; n < 3; n++)
2269 for (Int_t m = 0; m < 3; m++) {
2270 Kssyz += cc2[n][m] * fld[n][1] * fld[m][2];
2271 }
2272 Kssyz *= c * c / 2520.;
2273
2274 Kssyy = (fld[0][1] * (38 * fld[0][1] + 156 * fld[1][1] - fld[2][1]) + fld[1][1] * (208 * fld[1][1] + 16 * fld[2][1])
2275 + fld[2][1] * (3 * fld[2][1]))
2276 * c * c / 2520.;
2277 Kssyyy = (fld[0][1]
2278 * (fld[0][1] * (85 * fld[0][1] + 526 * fld[1][1] - 7 * fld[2][1])
2279 + fld[1][1] * (1376 * fld[1][1] + 84 * fld[2][1]) + fld[2][1] * (19 * fld[2][1]))
2280 + fld[1][1] * (fld[1][1] * (1376 * fld[1][1] + 256 * fld[2][1]) + fld[2][1] * (62 * fld[2][1]))
2281 + fld[2][1] * fld[2][1] * (3 * fld[2][1]))
2282 * c * c * c / 90720.;
2283
2284 ssx = Kssx * dS * dS;
2285 ssy = Kssy * dS * dS;
2286 ssz = Kssz * dS * dS;
2287 ssyz = Kssyz * dS * dS * dS;
2288 ssyy = Kssyy * dS * dS * dS;
2289 ssyyy = Kssyyy * dS * dS * dS * dS;
2290
2291 dssx = 2. * Kssx * dS;
2292 dssy = 2. * Kssy * dS;
2293 dssz = 2. * Kssz * dS;
2294 dssyz = 3. * Kssyz * dS * dS;
2295 dssyy = 3. * Kssyy * dS * dS;
2296 dssyyy = 4. * Kssyyy * dS * dS * dS;
2297
2298 ddssx = 2. * Kssx;
2299 ddssy = 2. * Kssy;
2300 ddssz = 2. * Kssz;
2301 ddssyz = 2. * 3. * Kssyz * dS;
2302 ddssyy = 2. * 3. * Kssyy * dS;
2303 ddssyyy = 3. * 4. * Kssyyy * dS * dS;
2304
2305 Double_t mJ[3][3];
2306 for (Int_t iJ = 0; iJ < 3; iJ++)
2307 for (Int_t jJ = 0; jJ < 3; jJ++)
2308 mJ[iJ][jJ] = 0;
2309
2310 mJ[0][0] = dS - ssyy;
2311 mJ[0][1] = ssx;
2312 mJ[0][2] = ssyyy - ssy;
2313 mJ[1][0] = -ssz;
2314 mJ[1][1] = dS;
2315 mJ[1][2] = ssx + ssyz;
2316 mJ[2][0] = ssy - ssyyy;
2317 mJ[2][1] = -ssx;
2318 mJ[2][2] = dS - ssyy;
2319
2320 x[0] = p.fP[0] + mJ[0][0] * p.fP[3] + mJ[0][1] * p.fP[4] + mJ[0][2] * p.fP[5];
2321 x[1] = p.fP[1] + mJ[1][0] * p.fP[3] + mJ[1][1] * p.fP[4] + mJ[1][2] * p.fP[5];
2322 x[2] = p.fP[2] + mJ[2][0] * p.fP[3] + mJ[2][1] * p.fP[4] + mJ[2][2] * p.fP[5];
2323
2324 mJ[0][0] = 1 - dssyy;
2325 mJ[0][1] = dssx;
2326 mJ[0][2] = dssyyy - dssy;
2327 mJ[1][0] = -dssz;
2328 mJ[1][1] = 1;
2329 mJ[1][2] = dssx + dssyz;
2330 mJ[2][0] = dssy - dssyyy;
2331 mJ[2][1] = -dssx;
2332 mJ[2][2] = 1 - dssyy;
2333
2334 dx[0] = p.fP[0] + mJ[0][0] * p.fP[3] + mJ[0][1] * p.fP[4] + mJ[0][2] * p.fP[5];
2335 dx[1] = p.fP[1] + mJ[1][0] * p.fP[3] + mJ[1][1] * p.fP[4] + mJ[1][2] * p.fP[5];
2336 dx[2] = p.fP[2] + mJ[2][0] * p.fP[3] + mJ[2][1] * p.fP[4] + mJ[2][2] * p.fP[5];
2337
2338 mJ[0][0] = -ddssyy;
2339 mJ[0][1] = ddssx;
2340 mJ[0][2] = ddssyyy - ddssy;
2341 mJ[1][0] = -ddssz;
2342 mJ[1][1] = 0;
2343 mJ[1][2] = ddssx + ddssyz;
2344 mJ[2][0] = ddssy - ddssyyy;
2345 mJ[2][1] = -ddssx;
2346 mJ[2][2] = -ddssyy;
2347
2348 ddx[0] = p.fP[0] + mJ[0][0] * p.fP[3] + mJ[0][1] * p.fP[4] + mJ[0][2] * p.fP[5];
2349 ddx[1] = p.fP[1] + mJ[1][0] * p.fP[3] + mJ[1][1] * p.fP[4] + mJ[1][2] * p.fP[5];
2350 ddx[2] = p.fP[2] + mJ[2][0] * p.fP[3] + mJ[2][1] * p.fP[4] + mJ[2][2] * p.fP[5];
2351}
2352
2354{
2355 //* Transport the particle on dS, output to P[],C[], for CBM field
2356
2357 Double_t dS = 0;
2358 // Linear approximation
2359
2360 Double_t fld[3];
2361 GetFieldValue(fP, fld);
2362 //
2363 // GetDStoParticleBy(fld[1],p,dS,dS1);
2364 dS = GetDStoPointLine(xyz);
2365
2366 if (fQ == 0) {
2367 return dS;
2368 }
2369
2370 dS = GetDStoPointBy(fld[1], xyz);
2371
2372 // const Double_t &px = fP[3], &py = fP[4], &pz = fP[5];
2373
2374 // construct coefficients
2375 // int NIt;
2376 // for(int i=0; i<100; i++)
2377 // {
2378 // //std::cout << " dS temp "<<dS << std::endl;
2379 // Double_t x[3], dx[3], ddx[3];
2380 //
2381 // GetDSIter(*this, dS, x, dx, ddx);
2382 //
2383 // Double_t dr[3] = { x[0] - xyz[0], x[1] - xyz[1], x[2] - xyz[2] };
2384 //
2385 // Double_t dS0 = dS;
2386 //
2387 // Double_t f = dx[0] * dr[0] + dx[1] * dr[1] + dx[2] * dr[2];
2388 // Double_t df = ddx[0] * dr[0] + ddx[1] * dr[1] + ddx[2] * dr[2] + dx[0]*dx[0] + dx[1]*dx[1] + dx[2]*dx[2];
2389 //
2390 // dS = dS - f/df;
2391 // NIt++;
2392 // if(fabs(dS - dS0) < fabs(dS)*0.001) break;
2393 // }
2394 // std::cout << "NIt " << NIt <<" dS "<< dS << std::endl;
2395 return dS;
2396}
2397
2399{
2400 Double_t p12 = fP[3] * fP[3] + fP[4] * fP[4] + fP[5] * fP[5];
2401 Double_t p22 = p.fP[3] * p.fP[3] + p.fP[4] * p.fP[4] + p.fP[5] * p.fP[5];
2402 Double_t p1p2 = fP[3] * p.fP[3] + fP[4] * p.fP[4] + fP[5] * p.fP[5];
2403
2404 Double_t drp1 = fP[3] * (p.fP[0] - fP[0]) + fP[4] * (p.fP[1] - fP[1]) + fP[5] * (p.fP[2] - fP[2]);
2405 Double_t drp2 = p.fP[3] * (p.fP[0] - fP[0]) + p.fP[4] * (p.fP[1] - fP[1]) + p.fP[5] * (p.fP[2] - fP[2]);
2406
2407 Double_t detp = p1p2 * p1p2 - p12 * p22;
2408 if (fabs(detp) < 1.e-4)
2409 detp = 1; // TODO correct!!!
2410
2411 dS = (drp2 * p1p2 - drp1 * p22) / detp;
2412 dS1 = (drp2 * p12 - drp1 * p1p2) / detp;
2413}
2414
2416{
2417 //* Transport the particle on dS, output to P[],C[], for CBM field
2418
2419 GetDStoParticleLine(p, dS, dS1);
2420 if (fQ == 0) {
2421 return;
2422 }
2423
2424 Double_t fld[3];
2425 GetFieldValue(fP, fld);
2426
2427 Double_t fld1[3];
2428 GetFieldValue(p.fP, fld1);
2429
2430 GetDStoParticleBy((fld[1] + fld1[1]) / 2, p, dS, dS1);
2431
2432 // construct coefficients
2433 // int NIt;
2434 // for(int i=0; i<10; i++)
2435 // {
2436 // /*std::cout << " dS temp "<<dS << " dS1 temp "<< dS1 << std::endl;*/
2437 // Double_t x[3], dx[3], ddx[3];
2438 // Double_t x1[3], dx1[3], ddx1[3];
2439 //
2440 // GetDSIter(*this, dS, x, dx, ddx);
2441 // GetDSIter(p, dS1, x1, dx1, ddx1);
2442 //
2443 // Double_t dr[3] = { x[0] - x1[0], x[1] - x1[1], x[2] - x1[2] };
2444 //
2445 // Double_t dS0 = dS;
2446 // Double_t dS10 = dS1;
2447 //
2448 // Double_t f = dx[0] * dr[0] + dx[1] * dr[1] + dx[2] * dr[2];
2449 // Double_t dfs = ddx[0] * dr[0] + ddx[1] * dr[1] + ddx[2] * dr[2] + dx[0]*dx[0] + dx[1]*dx[1] + dx[2]*dx[2];
2450 // Double_t dfs1 = -ddx[0] * ddx1[0] - ddx[1] * ddx1[1] - ddx[2] * ddx1[2];
2451 //
2452 // Double_t f1 = dx1[0] * dr[0] + dx1[1] * dr[1] + dx1[2] * dr[2];
2453 // Double_t df1s1 = ddx1[0] * dr[0] + ddx1[1] * dr[1] + ddx1[2] * dr[2] - dx1[0]*dx1[0] - dx1[1]*dx1[1] -
2454 // dx1[2]*dx1[2]; Double_t df1s = -dfs1;
2455 //
2456 // Double_t det = dfs*df1s1 - dfs1*df1s;
2457 // if(fabs(det) < 1.e-8) det = 1.e-8;
2458 //
2459 // Double_t DS = dfs1*f1 - f*df1s1;
2460 // Double_t DS1 = f*df1s - f1*dfs;
2461 //
2462 // dS += DS/det;
2463 // dS1 += DS1/det;
2464 // NIt++;
2465 // /* if( (fabs(dS - dS0) < fabs(dS)*0.001) && (fabs(dS1 - dS10) < fabs(dS1)*0.001)) break;*/
2466 // }
2467 // std::cout << "NIt " << NIt <<" dS "<< dS << " dS1 "<< dS1 << std::endl;
2468}
2469
2471{
2472 //* Transport the particle on dS, output to P[],C[], for CBM field
2473
2474 if (fQ == 0) {
2475 TransportLine(dS, P, C);
2476 return;
2477 }
2478
2479 const Double_t kCLight = 0.000299792458;
2480
2481 Double_t c = fQ * kCLight;
2482
2483 // construct coefficients
2484
2485 Double_t px = fP[3], py = fP[4], pz = fP[5];
2486
2487 Double_t sx = 0, sy = 0, sz = 0, syy = 0, syz = 0, syyy = 0, ssx = 0, ssy = 0, ssz = 0, ssyy = 0, ssyz = 0,
2488 ssyyy = 0;
2489
2490 { // get field integrals
2491
2492 Double_t fld[3][3];
2493 Double_t p0[3], p1[3], p2[3];
2494
2495 // line track approximation
2496
2497 p0[0] = fP[0];
2498 p0[1] = fP[1];
2499 p0[2] = fP[2];
2500
2501 p2[0] = fP[0] + px * dS;
2502 p2[1] = fP[1] + py * dS;
2503 p2[2] = fP[2] + pz * dS;
2504
2505 p1[0] = 0.5 * (p0[0] + p2[0]);
2506 p1[1] = 0.5 * (p0[1] + p2[1]);
2507 p1[2] = 0.5 * (p0[2] + p2[2]);
2508
2509 // first order track approximation
2510 {
2511 GetFieldValue(p0, fld[0]);
2512 GetFieldValue(p1, fld[1]);
2513 GetFieldValue(p2, fld[2]);
2514
2515 Double_t ssy1 = (7 * fld[0][1] + 6 * fld[1][1] - fld[2][1]) * c * dS * dS / 96.;
2516 Double_t ssy2 = (fld[0][1] + 2 * fld[1][1]) * c * dS * dS / 6.;
2517
2518 p1[0] -= ssy1 * pz;
2519 p1[2] += ssy1 * px;
2520 p2[0] -= ssy2 * pz;
2521 p2[2] += ssy2 * px;
2522 }
2523
2524 GetFieldValue(p0, fld[0]);
2525 GetFieldValue(p1, fld[1]);
2526 GetFieldValue(p2, fld[2]);
2527
2528 sx = c * (fld[0][0] + 4 * fld[1][0] + fld[2][0]) * dS / 6.;
2529 sy = c * (fld[0][1] + 4 * fld[1][1] + fld[2][1]) * dS / 6.;
2530 sz = c * (fld[0][2] + 4 * fld[1][2] + fld[2][2]) * dS / 6.;
2531
2532 ssx = c * (fld[0][0] + 2 * fld[1][0]) * dS * dS / 6.;
2533 ssy = c * (fld[0][1] + 2 * fld[1][1]) * dS * dS / 6.;
2534 ssz = c * (fld[0][2] + 2 * fld[1][2]) * dS * dS / 6.;
2535
2536 Double_t c2[3][3] = {{5, -4, -1}, {44, 80, -4}, {11, 44, 5}}; // /=360.
2537 Double_t cc2[3][3] = {{38, 8, -4}, {148, 208, -20}, {3, 36, 3}}; // /=2520.
2538 for (Int_t n = 0; n < 3; n++)
2539 for (Int_t m = 0; m < 3; m++) {
2540 syz += c2[n][m] * fld[n][1] * fld[m][2];
2541 ssyz += cc2[n][m] * fld[n][1] * fld[m][2];
2542 }
2543
2544 syz *= c * c * dS * dS / 360.;
2545 ssyz *= c * c * dS * dS * dS / 2520.;
2546
2547 syy = c * (fld[0][1] + 4 * fld[1][1] + fld[2][1]) * dS;
2548 syyy = syy * syy * syy / 1296;
2549 syy = syy * syy / 72;
2550
2551 ssyy = (fld[0][1] * (38 * fld[0][1] + 156 * fld[1][1] - fld[2][1])
2552 + fld[1][1] * (208 * fld[1][1] + 16 * fld[2][1]) + fld[2][1] * (3 * fld[2][1]))
2553 * dS * dS * dS * c * c / 2520.;
2554 ssyyy = (fld[0][1]
2555 * (fld[0][1] * (85 * fld[0][1] + 526 * fld[1][1] - 7 * fld[2][1])
2556 + fld[1][1] * (1376 * fld[1][1] + 84 * fld[2][1]) + fld[2][1] * (19 * fld[2][1]))
2557 + fld[1][1] * (fld[1][1] * (1376 * fld[1][1] + 256 * fld[2][1]) + fld[2][1] * (62 * fld[2][1]))
2558 + fld[2][1] * fld[2][1] * (3 * fld[2][1]))
2559 * dS * dS * dS * dS * c * c * c / 90720.;
2560 }
2561
2562 Double_t mJ[8][8];
2563 for (Int_t i = 0; i < 8; i++)
2564 for (Int_t j = 0; j < 8; j++)
2565 mJ[i][j] = 0;
2566
2567 mJ[0][0] = 1;
2568 mJ[0][1] = 0;
2569 mJ[0][2] = 0;
2570 mJ[0][3] = dS - ssyy;
2571 mJ[0][4] = ssx;
2572 mJ[0][5] = ssyyy - ssy;
2573 mJ[1][0] = 0;
2574 mJ[1][1] = 1;
2575 mJ[1][2] = 0;
2576 mJ[1][3] = -ssz;
2577 mJ[1][4] = dS;
2578 mJ[1][5] = ssx + ssyz;
2579 mJ[2][0] = 0;
2580 mJ[2][1] = 0;
2581 mJ[2][2] = 1;
2582 mJ[2][3] = ssy - ssyyy;
2583 mJ[2][4] = -ssx;
2584 mJ[2][5] = dS - ssyy;
2585
2586 mJ[3][0] = 0;
2587 mJ[3][1] = 0;
2588 mJ[3][2] = 0;
2589 mJ[3][3] = 1 - syy;
2590 mJ[3][4] = sx;
2591 mJ[3][5] = syyy - sy;
2592 mJ[4][0] = 0;
2593 mJ[4][1] = 0;
2594 mJ[4][2] = 0;
2595 mJ[4][3] = -sz;
2596 mJ[4][4] = 1;
2597 mJ[4][5] = sx + syz;
2598 mJ[5][0] = 0;
2599 mJ[5][1] = 0;
2600 mJ[5][2] = 0;
2601 mJ[5][3] = sy - syyy;
2602 mJ[5][4] = -sx;
2603 mJ[5][5] = 1 - syy;
2604 mJ[6][6] = mJ[7][7] = 1;
2605
2606 P[0] = fP[0] + mJ[0][3] * px + mJ[0][4] * py + mJ[0][5] * pz;
2607 P[1] = fP[1] + mJ[1][3] * px + mJ[1][4] * py + mJ[1][5] * pz;
2608 P[2] = fP[2] + mJ[2][3] * px + mJ[2][4] * py + mJ[2][5] * pz;
2609 P[3] = mJ[3][3] * px + mJ[3][4] * py + mJ[3][5] * pz;
2610 P[4] = mJ[4][3] * px + mJ[4][4] * py + mJ[4][5] * pz;
2611 P[5] = mJ[5][3] * px + mJ[5][4] * py + mJ[5][5] * pz;
2612 P[6] = fP[6];
2613 P[7] = fP[7];
2614
2615 MultQSQt(mJ[0], fC, C);
2616}
2617
2619{
2620 //* Transport the particle on dS, output to P[],C[], for Bz field
2621
2622 const Double_t kCLight = 0.000299792458;
2623 b = b * fQ * kCLight;
2624 Double_t bs = b * t;
2625 Double_t s = TMath::Sin(bs), c = TMath::Cos(bs);
2626 Double_t sB, cB;
2627 if (TMath::Abs(bs) > 1.e-10) {
2628 sB = s / b;
2629 cB = (1 - c) / b;
2630 } else {
2631 const Double_t kOvSqr6 = 1. / TMath::Sqrt(6.);
2632 sB = (1. - bs * kOvSqr6) * (1. + bs * kOvSqr6) * t;
2633 cB = .5 * sB * bs;
2634 }
2635
2636 Double_t px = fP[3];
2637 Double_t py = fP[4];
2638 Double_t pz = fP[5];
2639
2640 p[0] = fP[0] + sB * px + cB * py;
2641 p[1] = fP[1] - cB * px + sB * py;
2642 p[2] = fP[2] + t * pz;
2643 p[3] = c * px + s * py;
2644 p[4] = -s * px + c * py;
2645 p[5] = fP[5];
2646 p[6] = fP[6];
2647 p[7] = fP[7];
2648
2649 /*
2650 Double_t mJ[8][8] = { {1,0,0, sB, cB, 0, 0, 0 },
2651 {0,1,0, -cB, sB, 0, 0, 0 },
2652 {0,0,1, 0, 0, t, 0, 0 },
2653 {0,0,0, c, s, 0, 0, 0 },
2654 {0,0,0, -s, c, 0, 0, 0 },
2655 {0,0,0, 0, 0, 1, 0, 0 },
2656 {0,0,0, 0, 0, 0, 1, 0 },
2657 {0,0,0, 0, 0, 0, 0, 1 } };
2658 Double_t mA[8][8];
2659 for( Int_t k=0,i=0; i<8; i++)
2660 for( Int_t j=0; j<=i; j++, k++ ) mA[i][j] = mA[j][i] = fC[k];
2661
2662 Double_t mJC[8][8];
2663 for( Int_t i=0; i<8; i++ )
2664 for( Int_t j=0; j<8; j++ ){
2665 mJC[i][j]=0;
2666 for( Int_t k=0; k<8; k++ ) mJC[i][j]+=mJ[i][k]*mA[k][j];
2667 }
2668
2669 for( Int_t k=0,i=0; i<8; i++)
2670 for( Int_t j=0; j<=i; j++, k++ ){
2671 e[k] = 0;
2672 for( Int_t l=0; l<8; l++ ) e[k]+=mJC[i][l]*mJ[j][l];
2673 }
2674
2675 return;
2676 */
2677
2678 Double_t c6 = fC[6], c7 = fC[7], c8 = fC[8], c17 = fC[17], c18 = fC[18], c24 = fC[24], c31 = fC[31];
2679
2680 Double_t cBC13 = cB * fC[13], mJC13 = c7 - cB * fC[9] + sB * fC[13], mJC14 = fC[11] - cBC13 + sB * fC[14],
2681 mJC23 = c8 + t * c18, mJC24 = fC[12] + t * fC[19], mJC33 = c * fC[9] + s * fC[13],
2682 mJC34 = c * fC[13] + s * fC[14], mJC43 = -s * fC[9] + c * fC[13], mJC44 = -s * fC[13] + c * fC[14];
2683
2684 e[0] = fC[0] + 2 * (sB * c6 + cB * fC[10]) + (sB * fC[9] + 2 * cBC13) * sB + cB * cB * fC[14];
2685 e[1] = fC[1] - cB * c6 + sB * fC[10] + mJC13 * sB + mJC14 * cB;
2686 e[2] = fC[2] - cB * c7 + sB * fC[11] - mJC13 * cB + mJC14 * sB;
2687 e[3] = fC[3] + t * fC[15] + mJC23 * sB + mJC24 * cB;
2688 e[4] = fC[4] + t * fC[16] - mJC23 * cB + mJC24 * sB;
2689
2690 e[15] = fC[15] + c18 * sB + fC[19] * cB;
2691 e[16] = fC[16] - c18 * cB + fC[19] * sB;
2692 e[17] = c17 + fC[20] * t;
2693 e[18] = c18 * c + fC[19] * s;
2694 e[19] = -c18 * s + fC[19] * c;
2695
2696 e[5] = fC[5] + (c17 + e[17]) * t;
2697
2698 e[6] = c * c6 + s * fC[10] + mJC33 * sB + mJC34 * cB;
2699 e[7] = c * c7 + s * fC[11] - mJC33 * cB + mJC34 * sB;
2700 e[8] = c * c8 + s * fC[12] + e[18] * t;
2701 e[9] = mJC33 * c + mJC34 * s;
2702 e[10] = -s * c6 + c * fC[10] + mJC43 * sB + mJC44 * cB;
2703
2704 e[11] = -s * c7 + c * fC[11] - mJC43 * cB + mJC44 * sB;
2705 e[12] = -s * c8 + c * fC[12] + e[19] * t;
2706 e[13] = mJC43 * c + mJC44 * s;
2707 e[14] = -mJC43 * s + mJC44 * c;
2708 e[20] = fC[20];
2709 e[21] = fC[21] + fC[25] * cB + c24 * sB;
2710 e[22] = fC[22] - c24 * cB + fC[25] * sB;
2711 e[23] = fC[23] + fC[26] * t;
2712 e[24] = c * c24 + s * fC[25];
2713 e[25] = c * fC[25] - c24 * s;
2714 e[26] = fC[26];
2715 e[27] = fC[27];
2716 e[28] = fC[28] + fC[32] * cB + c31 * sB;
2717 e[29] = fC[29] - c31 * cB + fC[32] * sB;
2718 e[30] = fC[30] + fC[33] * t;
2719 e[31] = c * c31 + s * fC[32];
2720 e[32] = c * fC[32] - s * c31;
2721 e[33] = fC[33];
2722 e[34] = fC[34];
2723 e[35] = fC[35];
2724}
2725
2727{
2728 //* Calculate distance from vertex [cm]
2729
2730 return GetDistanceFromVertex(Vtx.fP);
2731}
2732
2734{
2735 //* Calculate distance from vertex [cm]
2736
2737 Double_t mP[8], mC[36];
2738 Transport(GetDStoPoint(vtx), mP, mC);
2739 Double_t d[3] = {vtx[0] - mP[0], vtx[1] - mP[1], vtx[2] - mP[2]};
2740 return TMath::Sqrt(d[0] * d[0] + d[1] * d[1] + d[2] * d[2]);
2741}
2742
2744{
2745 //* Calculate distance to other particle [cm]
2746
2747 Double_t dS, dS1;
2748 GetDStoParticle(p, dS, dS1);
2749 Double_t mP[8], mC[36], mP1[8], mC1[36];
2750 Transport(dS, mP, mC);
2751 p.Transport(dS1, mP1, mC1);
2752 Double_t dx = mP[0] - mP1[0];
2753 Double_t dy = mP[1] - mP1[1];
2754 Double_t dz = mP[2] - mP1[2];
2755 return TMath::Sqrt(dx * dx + dy * dy + dz * dz);
2756}
2757
2759{
2760 //* Calculate sqrt(Chi2/ndf) deviation from vertex
2761
2762 return GetDeviationFromVertex(Vtx.fP, Vtx.fC);
2763}
2764
2766{
2767 //* Calculate sqrt(Chi2/ndf) deviation from vertex
2768 //* v = [xyz], Cv=[Cxx,Cxy,Cyy,Cxz,Cyz,Czz]-covariance matrix
2769
2770 Double_t mP[8];
2771 Double_t mC[36];
2772
2773 Transport(GetDStoPoint(v), mP, mC);
2774
2775 Double_t d[3] = {v[0] - mP[0], v[1] - mP[1], v[2] - mP[2]};
2776
2777 Double_t sigmaS = .1
2778 + 10.
2779 * TMath::Sqrt((d[0] * d[0] + d[1] * d[1] + d[2] * d[2])
2780 / (mP[3] * mP[3] + mP[4] * mP[4] + mP[5] * mP[5]));
2781
2782 Double_t h[3] = {mP[3] * sigmaS, mP[4] * sigmaS, mP[5] * sigmaS};
2783
2784 Double_t mSi[6] = {mC[0] + h[0] * h[0], mC[1] + h[1] * h[0], mC[2] + h[1] * h[1],
2785 mC[3] + h[2] * h[0], mC[4] + h[2] * h[1], mC[5] + h[2] * h[2]};
2786
2787 if (Cv) {
2788 mSi[0] += Cv[0];
2789 mSi[1] += Cv[1];
2790 mSi[2] += Cv[2];
2791 mSi[3] += Cv[3];
2792 mSi[4] += Cv[4];
2793 mSi[5] += Cv[5];
2794 }
2795
2796 Double_t mS[6];
2797
2798 mS[0] = mSi[2] * mSi[5] - mSi[4] * mSi[4];
2799 mS[1] = mSi[3] * mSi[4] - mSi[1] * mSi[5];
2800 mS[2] = mSi[0] * mSi[5] - mSi[3] * mSi[3];
2801 mS[3] = mSi[1] * mSi[4] - mSi[2] * mSi[3];
2802 mS[4] = mSi[1] * mSi[3] - mSi[0] * mSi[4];
2803 mS[5] = mSi[0] * mSi[2] - mSi[1] * mSi[1];
2804
2805 Double_t s = (mSi[0] * mS[0] + mSi[1] * mS[1] + mSi[3] * mS[3]);
2806 s = (s > 1.E-20) ? 1. / s : 0;
2807
2808 return TMath::Sqrt(TMath::Abs(s
2809 * ((mS[0] * d[0] + mS[1] * d[1] + mS[3] * d[2]) * d[0]
2810 + (mS[1] * d[0] + mS[2] * d[1] + mS[4] * d[2]) * d[1]
2811 + (mS[3] * d[0] + mS[4] * d[1] + mS[5] * d[2]) * d[2]))
2812 / 2);
2813}
2814
2816{
2817 //* Calculate sqrt(Chi2/ndf) deviation from other particle
2818
2819 Double_t dS, dS1;
2820 GetDStoParticle(p, dS, dS1);
2821 Double_t mP1[8], mC1[36];
2822 p.Transport(dS1, mP1, mC1);
2823
2824 Double_t d[3] = {fP[0] - mP1[0], fP[1] - mP1[1], fP[2] - mP1[2]};
2825
2826 Double_t sigmaS = .1
2827 + 10.
2828 * TMath::Sqrt((d[0] * d[0] + d[1] * d[1] + d[2] * d[2])
2829 / (mP1[3] * mP1[3] + mP1[4] * mP1[4] + mP1[5] * mP1[5]));
2830
2831 Double_t h[3] = {mP1[3] * sigmaS, mP1[4] * sigmaS, mP1[5] * sigmaS};
2832
2833 mC1[0] += h[0] * h[0];
2834 mC1[1] += h[1] * h[0];
2835 mC1[2] += h[1] * h[1];
2836 mC1[3] += h[2] * h[0];
2837 mC1[4] += h[2] * h[1];
2838 mC1[5] += h[2] * h[2];
2839
2840 return GetDeviationFromVertex(mP1, mC1) * TMath::Sqrt(2. / 1.);
2841}
2842
2844{
2845 //* Subtract the particle from the vertex
2846
2847 Double_t fld[3];
2848 {
2849 GetFieldValue(Vtx.fP, fld);
2850 const Double_t kCLight = 0.000299792458;
2851 fld[0] *= kCLight;
2852 fld[1] *= kCLight;
2853 fld[2] *= kCLight;
2854 }
2855
2856 Double_t m[8];
2857 Double_t mCm[36];
2858
2859 if (Vtx.fIsLinearized) {
2860 GetMeasurement(Vtx.fVtxGuess, m, mCm);
2861 } else {
2862 GetMeasurement(Vtx.fP, m, mCm);
2863 }
2864
2865 Double_t mV[6];
2866
2867 mV[0] = mCm[0];
2868 mV[1] = mCm[1];
2869 mV[2] = mCm[2];
2870 mV[3] = mCm[3];
2871 mV[4] = mCm[4];
2872 mV[5] = mCm[5];
2873
2874 //*
2875
2876 Double_t mS[6];
2877 {
2878 Double_t mSi[6] = {mV[0] - Vtx.fC[0], mV[1] - Vtx.fC[1], mV[2] - Vtx.fC[2],
2879 mV[3] - Vtx.fC[3], mV[4] - Vtx.fC[4], mV[5] - Vtx.fC[5]};
2880
2881 mS[0] = mSi[2] * mSi[5] - mSi[4] * mSi[4];
2882 mS[1] = mSi[3] * mSi[4] - mSi[1] * mSi[5];
2883 mS[2] = mSi[0] * mSi[5] - mSi[3] * mSi[3];
2884 mS[3] = mSi[1] * mSi[4] - mSi[2] * mSi[3];
2885 mS[4] = mSi[1] * mSi[3] - mSi[0] * mSi[4];
2886 mS[5] = mSi[0] * mSi[2] - mSi[1] * mSi[1];
2887
2888 Double_t s = (mSi[0] * mS[0] + mSi[1] * mS[1] + mSi[3] * mS[3]);
2889 s = (s > 1.E-20) ? 1. / s : 0;
2890 mS[0] *= s;
2891 mS[1] *= s;
2892 mS[2] *= s;
2893 mS[3] *= s;
2894 mS[4] *= s;
2895 mS[5] *= s;
2896 }
2897
2898 //* Residual (measured - estimated)
2899
2900 Double_t zeta[3] = {m[0] - Vtx.fP[0], m[1] - Vtx.fP[1], m[2] - Vtx.fP[2]};
2901
2902 //* mCHt = mCH' - D'
2903
2904 Double_t mCHt0[3], mCHt1[3], mCHt2[3];
2905
2906 mCHt0[0] = Vtx.fC[0];
2907 mCHt1[0] = Vtx.fC[1];
2908 mCHt2[0] = Vtx.fC[3];
2909 mCHt0[1] = Vtx.fC[1];
2910 mCHt1[1] = Vtx.fC[2];
2911 mCHt2[1] = Vtx.fC[4];
2912 mCHt0[2] = Vtx.fC[3];
2913 mCHt1[2] = Vtx.fC[4];
2914 mCHt2[2] = Vtx.fC[5];
2915
2916 //* Kalman gain K = mCH'*S
2917
2918 Double_t k0[3], k1[3], k2[3];
2919
2920 for (Int_t i = 0; i < 3; ++i) {
2921 k0[i] = mCHt0[i] * mS[0] + mCHt1[i] * mS[1] + mCHt2[i] * mS[3];
2922 k1[i] = mCHt0[i] * mS[1] + mCHt1[i] * mS[2] + mCHt2[i] * mS[4];
2923 k2[i] = mCHt0[i] * mS[3] + mCHt1[i] * mS[4] + mCHt2[i] * mS[5];
2924 }
2925
2926 //* New estimation of the vertex position r += K*zeta
2927
2928 Double_t dChi2 = -(mS[0] * zeta[0] + mS[1] * zeta[1] + mS[3] * zeta[2]) * zeta[0]
2929 + (mS[1] * zeta[0] + mS[2] * zeta[1] + mS[4] * zeta[2]) * zeta[1]
2930 + (mS[3] * zeta[0] + mS[4] * zeta[1] + mS[5] * zeta[2]) * zeta[2];
2931
2932 if (Vtx.fChi2 - dChi2 < 0)
2933 return;
2934
2935 for (Int_t i = 0; i < 3; ++i)
2936 Vtx.fP[i] -= k0[i] * zeta[0] + k1[i] * zeta[1] + k2[i] * zeta[2];
2937
2938 //* New covariance matrix C -= K*(mCH')'
2939
2940 for (Int_t i = 0, k = 0; i < 3; ++i) {
2941 for (Int_t j = 0; j <= i; ++j, ++k)
2942 Vtx.fC[k] += k0[i] * mCHt0[j] + k1[i] * mCHt1[j] + k2[i] * mCHt2[j];
2943 }
2944
2945 //* Calculate Chi^2
2946
2947 Vtx.fNDF -= 2;
2948 Vtx.fChi2 -= dChi2;
2949}
2950
2952{
2953 //* Transport the particle as a straight line
2954
2955 P[0] = fP[0] + dS * fP[3];
2956 P[1] = fP[1] + dS * fP[4];
2957 P[2] = fP[2] + dS * fP[5];
2958 P[3] = fP[3];
2959 P[4] = fP[4];
2960 P[5] = fP[5];
2961 P[6] = fP[6];
2962 P[7] = fP[7];
2963
2964 Double_t c6 = fC[6] + dS * fC[9];
2965 Double_t c11 = fC[11] + dS * fC[14];
2966 Double_t c17 = fC[17] + dS * fC[20];
2967 Double_t sc13 = dS * fC[13];
2968 Double_t sc18 = dS * fC[18];
2969 Double_t sc19 = dS * fC[19];
2970
2971 C[0] = fC[0] + dS * (fC[6] + c6);
2972 C[2] = fC[2] + dS * (fC[11] + c11);
2973 C[5] = fC[5] + dS * (fC[17] + c17);
2974
2975 C[7] = fC[7] + sc13;
2976 C[8] = fC[8] + sc18;
2977 C[9] = fC[9];
2978
2979 C[12] = fC[12] + sc19;
2980
2981 C[1] = fC[1] + dS * (fC[10] + C[7]);
2982 C[3] = fC[3] + dS * (fC[15] + C[8]);
2983 C[4] = fC[4] + dS * (fC[16] + C[12]);
2984 C[6] = c6;
2985
2986 C[10] = fC[10] + sc13;
2987 C[11] = c11;
2988
2989 C[13] = fC[13];
2990 C[14] = fC[14];
2991 C[15] = fC[15] + sc18;
2992 C[16] = fC[16] + sc19;
2993 C[17] = c17;
2994
2995 C[18] = fC[18];
2996 C[19] = fC[19];
2997 C[20] = fC[20];
2998 C[21] = fC[21] + dS * fC[24];
2999 C[22] = fC[22] + dS * fC[25];
3000 C[23] = fC[23] + dS * fC[26];
3001
3002 C[24] = fC[24];
3003 C[25] = fC[25];
3004 C[26] = fC[26];
3005 C[27] = fC[27];
3006 C[28] = fC[28] + dS * fC[31];
3007 C[29] = fC[29] + dS * fC[32];
3008 C[30] = fC[30] + dS * fC[33];
3009
3010 C[31] = fC[31];
3011 C[32] = fC[32];
3012 C[33] = fC[33];
3013 C[34] = fC[34];
3014 C[35] = fC[35];
3015}
3016
3017void KFParticleBase::ConstructGammaBz(const KFParticleBase& daughter1, const KFParticleBase& daughter2, double Bz)
3018{
3019 //* Create gamma
3020
3021 const KFParticleBase* daughters[2] = {&daughter1, &daughter2};
3022
3023 double v0[3];
3024
3025 if (!fIsLinearized) {
3026 Double_t ds, ds1;
3027 Double_t m[8];
3028 Double_t mCd[36];
3029 daughter1.GetDStoParticle(daughter2, ds, ds1);
3030 daughter1.Transport(ds, m, mCd);
3031 fP[0] = m[0];
3032 fP[1] = m[1];
3033 fP[2] = m[2];
3034 daughter2.Transport(ds1, m, mCd);
3035 fP[0] = .5 * (fP[0] + m[0]);
3036 fP[1] = .5 * (fP[1] + m[1]);
3037 fP[2] = .5 * (fP[2] + m[2]);
3038 } else {
3039 fP[0] = fVtxGuess[0];
3040 fP[1] = fVtxGuess[1];
3041 fP[2] = fVtxGuess[2];
3042 }
3043
3044 double daughterP[2][8], daughterC[2][36];
3045 double vtxMom[2][3];
3046
3047 int nIter = fIsLinearized ? 1 : 2;
3048
3049 for (int iter = 0; iter < nIter; iter++) {
3050
3051 v0[0] = fP[0];
3052 v0[1] = fP[1];
3053 v0[2] = fP[2];
3054
3056 fSFromDecay = 0;
3057 fP[0] = v0[0];
3058 fP[1] = v0[1];
3059 fP[2] = v0[2];
3060 fP[3] = 0;
3061 fP[4] = 0;
3062 fP[5] = 0;
3063 fP[6] = 0;
3064 fP[7] = 0;
3065
3066 // fit daughters to the vertex guess
3067
3068 {
3069 for (int id = 0; id < 2; id++) {
3070
3071 double* p = daughterP[id];
3072 double* mC = daughterC[id];
3073
3074 daughters[id]->GetMeasurement(v0, p, mC);
3075
3076 Double_t mAi[6];
3077 InvertSym3(mC, mAi);
3078
3079 Double_t mB[3][3];
3080
3081 mB[0][0] = mC[6] * mAi[0] + mC[7] * mAi[1] + mC[8] * mAi[3];
3082 mB[0][1] = mC[6] * mAi[1] + mC[7] * mAi[2] + mC[8] * mAi[4];
3083 mB[0][2] = mC[6] * mAi[3] + mC[7] * mAi[4] + mC[8] * mAi[5];
3084
3085 mB[1][0] = mC[10] * mAi[0] + mC[11] * mAi[1] + mC[12] * mAi[3];
3086 mB[1][1] = mC[10] * mAi[1] + mC[11] * mAi[2] + mC[12] * mAi[4];
3087 mB[1][2] = mC[10] * mAi[3] + mC[11] * mAi[4] + mC[12] * mAi[5];
3088
3089 mB[2][0] = mC[15] * mAi[0] + mC[16] * mAi[1] + mC[17] * mAi[3];
3090 mB[2][1] = mC[15] * mAi[1] + mC[16] * mAi[2] + mC[17] * mAi[4];
3091 mB[2][2] = mC[15] * mAi[3] + mC[16] * mAi[4] + mC[17] * mAi[5];
3092
3093 Double_t z[3] = {v0[0] - p[0], v0[1] - p[1], v0[2] - p[2]};
3094
3095 vtxMom[id][0] = p[3] + mB[0][0] * z[0] + mB[0][1] * z[1] + mB[0][2] * z[2];
3096 vtxMom[id][1] = p[4] + mB[1][0] * z[0] + mB[1][1] * z[1] + mB[1][2] * z[2];
3097 vtxMom[id][2] = p[5] + mB[2][0] * z[0] + mB[2][1] * z[1] + mB[2][2] * z[2];
3098
3099 daughters[id]->Transport(daughters[id]->GetDStoPoint(v0), p, mC);
3100 }
3101
3102 } // fit daughters to guess
3103
3104 // fit new vertex
3105 {
3106
3107 double mpx0 = vtxMom[0][0] + vtxMom[1][0];
3108 double mpy0 = vtxMom[0][1] + vtxMom[1][1];
3109 double mpt0 = TMath::Sqrt(mpx0 * mpx0 + mpy0 * mpy0);
3110 // double a0 = TMath::ATan2(mpy0,mpx0);
3111
3112 double ca0 = mpx0 / mpt0;
3113 double sa0 = mpy0 / mpt0;
3114 double r[3] = {v0[0], v0[1], v0[2]};
3115 double mC[3][3] = {{1000., 0, 0}, {0, 1000., 0}, {0, 0, 1000.}};
3116 double chi2 = 0;
3117
3118 for (int id = 0; id < 2; id++) {
3119 const Double_t kCLight = 0.000299792458;
3120 Double_t q = Bz * daughters[id]->GetQ() * kCLight;
3121 Double_t px0 = vtxMom[id][0];
3122 Double_t py0 = vtxMom[id][1];
3123 Double_t pz0 = vtxMom[id][2];
3124 Double_t pt0 = TMath::Sqrt(px0 * px0 + py0 * py0);
3125 Double_t mG[3][6], mB[3], mH[3][3];
3126 // r = {vx,vy,vz};
3127 // m = {x,y,z,Px,Py,Pz};
3128 // V = daughter.C
3129 // G*m + B = H*r;
3130 // q*x + Py - q*vx - sin(a)*Pt = 0
3131 // q*y - Px - q*vy + cos(a)*Pt = 0
3132 // (Px*cos(a) + Py*sin(a) ) (vz -z) - Pz( cos(a)*(vx-x) + sin(a)*(vy-y)) = 0
3133
3134 mG[0][0] = q;
3135 mG[0][1] = 0;
3136 mG[0][2] = 0;
3137 mG[0][3] = -sa0 * px0 / pt0;
3138 mG[0][4] = 1 - sa0 * py0 / pt0;
3139 mG[0][5] = 0;
3140 mH[0][0] = q;
3141 mH[0][1] = 0;
3142 mH[0][2] = 0;
3143 mB[0] = py0 - sa0 * pt0 - mG[0][3] * px0 - mG[0][4] * py0;
3144
3145 // q*y - Px - q*vy + cos(a)*Pt = 0
3146
3147 mG[1][0] = 0;
3148 mG[1][1] = q;
3149 mG[1][2] = 0;
3150 mG[1][3] = -1 + ca0 * px0 / pt0;
3151 mG[1][4] = +ca0 * py0 / pt0;
3152 mG[1][5] = 0;
3153 mH[1][0] = 0;
3154 mH[1][1] = q;
3155 mH[1][2] = 0;
3156 mB[1] = -px0 + ca0 * pt0 - mG[1][3] * px0 - mG[1][4] * py0;
3157
3158 // (Px*cos(a) + Py*sin(a) ) (z -vz) - Pz( cos(a)*(x-vx) + sin(a)*(y-vy)) = 0
3159
3160 mG[2][0] = -pz0 * ca0;
3161 mG[2][1] = -pz0 * sa0;
3162 mG[2][2] = px0 * ca0 + py0 * sa0;
3163 mG[2][3] = 0;
3164 mG[2][4] = 0;
3165 mG[2][5] = 0;
3166
3167 mH[2][0] = mG[2][0];
3168 mH[2][1] = mG[2][1];
3169 mH[2][2] = mG[2][2];
3170
3171 mB[2] = 0;
3172
3173 // fit the vertex
3174
3175 // V = GVGt
3176
3177 double mGV[3][6];
3178 double mV[6];
3179 double m[3];
3180 for (int i = 0; i < 3; i++) {
3181 m[i] = mB[i];
3182 for (int k = 0; k < 6; k++)
3183 m[i] += mG[i][k] * daughterP[id][k];
3184 }
3185 for (int i = 0; i < 3; i++) {
3186 for (int j = 0; j < 6; j++) {
3187 mGV[i][j] = 0;
3188 for (int k = 0; k < 6; k++)
3189 mGV[i][j] += mG[i][k] * daughterC[id][IJ(k, j)];
3190 }
3191 }
3192 for (int i = 0, k = 0; i < 3; i++) {
3193 for (int j = 0; j <= i; j++, k++) {
3194 mV[k] = 0;
3195 for (int l = 0; l < 6; l++)
3196 mV[k] += mGV[i][l] * mG[j][l];
3197 }
3198 }
3199
3200 //* CHt
3201
3202 Double_t mCHt[3][3];
3203 Double_t mHCHt[6];
3204 Double_t mHr[3];
3205 for (int i = 0; i < 3; i++) {
3206 mHr[i] = 0;
3207 for (int k = 0; k < 3; k++)
3208 mHr[i] += mH[i][k] * r[k];
3209 }
3210
3211 for (int i = 0; i < 3; i++) {
3212 for (int j = 0; j < 3; j++) {
3213 mCHt[i][j] = 0;
3214 for (int k = 0; k < 3; k++)
3215 mCHt[i][j] += mC[i][k] * mH[j][k];
3216 }
3217 }
3218
3219 for (int i = 0, k = 0; i < 3; i++) {
3220 for (int j = 0; j <= i; j++, k++) {
3221 mHCHt[k] = 0;
3222 for (int l = 0; l < 3; l++)
3223 mHCHt[k] += mH[i][l] * mCHt[l][j];
3224 }
3225 }
3226
3227 Double_t mS[6] = {mHCHt[0] + mV[0], mHCHt[1] + mV[1], mHCHt[2] + mV[2],
3228 mHCHt[3] + mV[3], mHCHt[4] + mV[4], mHCHt[5] + mV[5]};
3229
3230 InvertSym3(mS, mS);
3231
3232 //* Residual (measured - estimated)
3233
3234 Double_t zeta[3] = {m[0] - mHr[0], m[1] - mHr[1], m[2] - mHr[2]};
3235
3236 //* Kalman gain K = mCH'*S
3237
3238 Double_t k[3][3];
3239
3240 for (Int_t i = 0; i < 3; ++i) {
3241 k[i][0] = mCHt[i][0] * mS[0] + mCHt[i][1] * mS[1] + mCHt[i][2] * mS[3];
3242 k[i][1] = mCHt[i][0] * mS[1] + mCHt[i][1] * mS[2] + mCHt[i][2] * mS[4];
3243 k[i][2] = mCHt[i][0] * mS[3] + mCHt[i][1] * mS[4] + mCHt[i][2] * mS[5];
3244 }
3245
3246 //* New estimation of the vertex position r += K*zeta
3247
3248 for (Int_t i = 0; i < 3; ++i)
3249 r[i] = r[i] + k[i][0] * zeta[0] + k[i][1] * zeta[1] + k[i][2] * zeta[2];
3250
3251 //* New covariance matrix C -= K*(mCH')'
3252
3253 for (Int_t i = 0; i < 3; ++i) {
3254 for (Int_t j = 0; j <= i; ++j) {
3255 mC[i][j] = mC[i][j] - (k[i][0] * mCHt[j][0] + k[i][1] * mCHt[j][1] + k[i][2] * mCHt[j][2]);
3256 mC[j][i] = mC[i][j];
3257 }
3258 }
3259
3260 //* Calculate Chi^2
3261
3262 chi2 += ((mS[0] * zeta[0] + mS[1] * zeta[1] + mS[3] * zeta[2]) * zeta[0]
3263 + (mS[1] * zeta[0] + mS[2] * zeta[1] + mS[4] * zeta[2]) * zeta[1]
3264 + (mS[3] * zeta[0] + mS[4] * zeta[1] + mS[5] * zeta[2]) * zeta[2]);
3265 }
3266
3267 // store vertex
3268
3269 fNDF = 2;
3270 fChi2 = chi2;
3271 for (int i = 0; i < 3; i++)
3272 fP[i] = r[i];
3273 for (int i = 0, k = 0; i < 3; i++) {
3274 for (int j = 0; j <= i; j++, k++) {
3275 fC[k] = mC[i][j];
3276 }
3277 }
3278 }
3279
3280 } // iterations
3281
3282 // now fit daughters to the vertex
3283
3284 fQ = 0;
3285 fSFromDecay = 0;
3286
3287 for (Int_t i = 3; i < 8; ++i)
3288 fP[i] = 0.;
3289 for (Int_t i = 6; i < 35; ++i)
3290 fC[i] = 0.;
3291 fC[35] = 100.;
3292
3293 for (int id = 0; id < 2; id++) {
3294
3295 double* p = daughterP[id];
3296 double* mC = daughterC[id];
3297 daughters[id]->GetMeasurement(v0, p, mC);
3298
3299 const Double_t *m = fP, *mV = fC;
3300
3301 Double_t mAi[6];
3302 InvertSym3(mC, mAi);
3303
3304 Double_t mB[4][3];
3305
3306 mB[0][0] = mC[6] * mAi[0] + mC[7] * mAi[1] + mC[8] * mAi[3];
3307 mB[0][1] = mC[6] * mAi[1] + mC[7] * mAi[2] + mC[8] * mAi[4];
3308 mB[0][2] = mC[6] * mAi[3] + mC[7] * mAi[4] + mC[8] * mAi[5];
3309
3310 mB[1][0] = mC[10] * mAi[0] + mC[11] * mAi[1] + mC[12] * mAi[3];
3311 mB[1][1] = mC[10] * mAi[1] + mC[11] * mAi[2] + mC[12] * mAi[4];
3312 mB[1][2] = mC[10] * mAi[3] + mC[11] * mAi[4] + mC[12] * mAi[5];
3313
3314 mB[2][0] = mC[15] * mAi[0] + mC[16] * mAi[1] + mC[17] * mAi[3];
3315 mB[2][1] = mC[15] * mAi[1] + mC[16] * mAi[2] + mC[17] * mAi[4];
3316 mB[2][2] = mC[15] * mAi[3] + mC[16] * mAi[4] + mC[17] * mAi[5];
3317
3318 mB[3][0] = mC[21] * mAi[0] + mC[22] * mAi[1] + mC[23] * mAi[3];
3319 mB[3][1] = mC[21] * mAi[1] + mC[22] * mAi[2] + mC[23] * mAi[4];
3320 mB[3][2] = mC[21] * mAi[3] + mC[22] * mAi[4] + mC[23] * mAi[5];
3321
3322 Double_t z[3] = {m[0] - p[0], m[1] - p[1], m[2] - p[2]};
3323
3324 // {
3325 // Double_t mAV[6] = { mC[0]-mV[0], mC[1]-mV[1], mC[2]-mV[2],
3326 // mC[3]-mV[3], mC[4]-mV[4], mC[5]-mV[5] };
3327 //
3328 // Double_t mAVi[6];
3329 // if( !InvertSym3(mAV, mAVi) ){
3330 // Double_t dChi2 = ( +(mAVi[0]*z[0] + mAVi[1]*z[1] + mAVi[3]*z[2])*z[0]
3331 // +(mAVi[1]*z[0] + mAVi[2]*z[1] + mAVi[4]*z[2])*z[1]
3332 // +(mAVi[3]*z[0] + mAVi[4]*z[1] + mAVi[5]*z[2])*z[2] );
3333 // fChi2+= TMath::Abs( dChi2 );
3334 // }
3335 // fNDF += 2;
3336 // }
3337
3338 //* Add the daughter momentum to the particle momentum
3339
3340 fP[3] += p[3] + mB[0][0] * z[0] + mB[0][1] * z[1] + mB[0][2] * z[2];
3341 fP[4] += p[4] + mB[1][0] * z[0] + mB[1][1] * z[1] + mB[1][2] * z[2];
3342 fP[5] += p[5] + mB[2][0] * z[0] + mB[2][1] * z[1] + mB[2][2] * z[2];
3343 fP[6] += p[6] + mB[3][0] * z[0] + mB[3][1] * z[1] + mB[3][2] * z[2];
3344
3345 Double_t d0, d1, d2;
3346
3347 d0 = mB[0][0] * mV[0] + mB[0][1] * mV[1] + mB[0][2] * mV[3] - mC[6];
3348 d1 = mB[0][0] * mV[1] + mB[0][1] * mV[2] + mB[0][2] * mV[4] - mC[7];
3349 d2 = mB[0][0] * mV[3] + mB[0][1] * mV[4] + mB[0][2] * mV[5] - mC[8];
3350
3351 // fC[6]+= mC[ 6] + d0;
3352 // fC[7]+= mC[ 7] + d1;
3353 // fC[8]+= mC[ 8] + d2;
3354 fC[9] += mC[9] + d0 * mB[0][0] + d1 * mB[0][1] + d2 * mB[0][2];
3355
3356 d0 = mB[1][0] * mV[0] + mB[1][1] * mV[1] + mB[1][2] * mV[3] - mC[10];
3357 d1 = mB[1][0] * mV[1] + mB[1][1] * mV[2] + mB[1][2] * mV[4] - mC[11];
3358 d2 = mB[1][0] * mV[3] + mB[1][1] * mV[4] + mB[1][2] * mV[5] - mC[12];
3359
3360 // fC[10]+= mC[10]+ d0;
3361 // fC[11]+= mC[11]+ d1;
3362 // fC[12]+= mC[12]+ d2;
3363 fC[13] += mC[13] + d0 * mB[0][0] + d1 * mB[0][1] + d2 * mB[0][2];
3364 fC[14] += mC[14] + d0 * mB[1][0] + d1 * mB[1][1] + d2 * mB[1][2];
3365
3366 d0 = mB[2][0] * mV[0] + mB[2][1] * mV[1] + mB[2][2] * mV[3] - mC[15];
3367 d1 = mB[2][0] * mV[1] + mB[2][1] * mV[2] + mB[2][2] * mV[4] - mC[16];
3368 d2 = mB[2][0] * mV[3] + mB[2][1] * mV[4] + mB[2][2] * mV[5] - mC[17];
3369
3370 // fC[15]+= mC[15]+ d0;
3371 // fC[16]+= mC[16]+ d1;
3372 // fC[17]+= mC[17]+ d2;
3373 fC[18] += mC[18] + d0 * mB[0][0] + d1 * mB[0][1] + d2 * mB[0][2];
3374 fC[19] += mC[19] + d0 * mB[1][0] + d1 * mB[1][1] + d2 * mB[1][2];
3375 fC[20] += mC[20] + d0 * mB[2][0] + d1 * mB[2][1] + d2 * mB[2][2];
3376
3377 d0 = mB[3][0] * mV[0] + mB[3][1] * mV[1] + mB[3][2] * mV[3] - mC[21];
3378 d1 = mB[3][0] * mV[1] + mB[3][1] * mV[2] + mB[3][2] * mV[4] - mC[22];
3379 d2 = mB[3][0] * mV[3] + mB[3][1] * mV[4] + mB[3][2] * mV[5] - mC[23];
3380
3381 // fC[21]+= mC[21] + d0;
3382 // fC[22]+= mC[22] + d1;
3383 // fC[23]+= mC[23] + d2;
3384 fC[24] += mC[24] + d0 * mB[0][0] + d1 * mB[0][1] + d2 * mB[0][2];
3385 fC[25] += mC[25] + d0 * mB[1][0] + d1 * mB[1][1] + d2 * mB[1][2];
3386 fC[26] += mC[26] + d0 * mB[2][0] + d1 * mB[2][1] + d2 * mB[2][2];
3387 fC[27] += mC[27] + d0 * mB[3][0] + d1 * mB[3][1] + d2 * mB[3][2];
3388 }
3389
3390 // SetMassConstraint(0,0);
3392}
3393
3395{
3396 // example:
3397 // KFParticle PosParticle(...)
3398 // KFParticle NegParticle(...)
3399 // Gamma.ConstructGamma(PosParticle, NegParticle);
3400 // Double_t VertexGamma[3] = {Gamma.GetX(), Gamma.GetY(), Gamma.GetZ()};
3401 // PosParticle.TransportToPoint(VertexGamma);
3402 // NegParticle.TransportToPoint(VertexGamma);
3403 // Double_t armenterosQtAlfa[2] = {0.};
3404 // KFParticle::GetArmenterosPodolanski(PosParticle, NegParticle, armenterosQtAlfa );
3405
3406 Double_t alpha = 0., qt = 0.;
3407 Double_t spx = positive.GetPx() + negative.GetPx();
3408 Double_t spy = positive.GetPy() + negative.GetPy();
3409 Double_t spz = positive.GetPz() + negative.GetPz();
3410 Double_t sp = sqrt(spx * spx + spy * spy + spz * spz);
3411 if (sp == 0.0)
3412 return;
3413 Double_t pn, pp, pln, plp;
3414
3415 pn = TMath::Sqrt(negative.GetPx() * negative.GetPx() + negative.GetPy() * negative.GetPy()
3416 + negative.GetPz() * negative.GetPz());
3417 pp = TMath::Sqrt(positive.GetPx() * positive.GetPx() + positive.GetPy() * positive.GetPy()
3418 + positive.GetPz() * positive.GetPz());
3419 pln = (negative.GetPx() * spx + negative.GetPy() * spy + negative.GetPz() * spz) / sp;
3420 plp = (positive.GetPx() * spx + positive.GetPy() * spy + positive.GetPz() * spz) / sp;
3421
3422 if (pn == 0.0)
3423 return;
3424 Double_t ptm = (1. - ((pln / pn) * (pln / pn)));
3425 qt = (ptm >= 0.) ? pn * sqrt(ptm) : 0;
3426 alpha = (plp - pln) / (plp + pln);
3427
3428 QtAlfa[0] = qt;
3429 QtAlfa[1] = alpha;
3430}
3431
3433{
3434 // Rotates the KFParticle object around OZ axis, OZ axis is set by the vertex position
3435 // Double_t angle - angle of rotation in XY plane in [rad]
3436 // Double_t Vtx[3] - position of the vertex in [cm]
3437
3438 // Before rotation the center of the coordinat system should be moved to the vertex position; move back after
3439 // rotation
3440 X() = X() - Vtx[0];
3441 Y() = Y() - Vtx[1];
3442 Z() = Z() - Vtx[2];
3443
3444 // Rotate the kf particle
3445 Double_t c = TMath::Cos(angle);
3446 Double_t s = TMath::Sin(angle);
3447
3448 Double_t mA[8][8];
3449 for (Int_t i = 0; i < 8; i++) {
3450 for (Int_t j = 0; j < 8; j++) {
3451 mA[i][j] = 0;
3452 }
3453 }
3454 for (int i = 0; i < 8; i++) {
3455 mA[i][i] = 1;
3456 }
3457 mA[0][0] = c;
3458 mA[0][1] = s;
3459 mA[1][0] = -s;
3460 mA[1][1] = c;
3461 mA[3][3] = c;
3462 mA[3][4] = s;
3463 mA[4][3] = -s;
3464 mA[4][4] = c;
3465
3466 Double_t mAC[8][8];
3467 Double_t mAp[8];
3468
3469 for (Int_t i = 0; i < 8; i++) {
3470 mAp[i] = 0;
3471 for (Int_t k = 0; k < 8; k++) {
3472 mAp[i] += mA[i][k] * fP[k];
3473 }
3474 }
3475
3476 for (Int_t i = 0; i < 8; i++) {
3477 fP[i] = mAp[i];
3478 }
3479
3480 for (Int_t i = 0; i < 8; i++) {
3481 for (Int_t j = 0; j < 8; j++) {
3482 mAC[i][j] = 0;
3483 for (Int_t k = 0; k < 8; k++) {
3484 mAC[i][j] += mA[i][k] * GetCovariance(k, j);
3485 }
3486 }
3487 }
3488
3489 for (Int_t i = 0; i < 8; i++) {
3490 for (Int_t j = 0; j <= i; j++) {
3491 Double_t xx = 0;
3492 for (Int_t k = 0; k < 8; k++) {
3493 xx += mAC[i][k] * mA[j][k];
3494 }
3495 Covariance(i, j) = xx;
3496 }
3497 }
3498
3499 X() = GetX() + Vtx[0];
3500 Y() = GetY() + Vtx[1];
3501 Z() = GetZ() + Vtx[2];
3502}
3503
3505{
3506 //* Invert symmetric matric stored in low-triagonal form
3507
3508 bool ret = 0;
3509 double a0 = A[0], a1 = A[1], a2 = A[2], a3 = A[3];
3510
3511 Ai[0] = a2 * A[5] - A[4] * A[4];
3512 Ai[1] = a3 * A[4] - a1 * A[5];
3513 Ai[3] = a1 * A[4] - a2 * a3;
3514 Double_t det = (a0 * Ai[0] + a1 * Ai[1] + a3 * Ai[3]);
3515 if (fabs(det) > 1.e-20)
3516 det = 1. / det;
3517 else {
3518 det = 0;
3519 ret = 1;
3520 }
3521 Ai[0] *= det;
3522 Ai[1] *= det;
3523 Ai[3] *= det;
3524 Ai[2] = (a0 * A[5] - a3 * a3) * det;
3525 Ai[4] = (a1 * a3 - a0 * A[4]) * det;
3526 Ai[5] = (a0 * a2 - a1 * a1) * det;
3527 return ret;
3528}
3529
3531{
3532 //* Matrix multiplication Q*S*Q^T, Q - square matrix, S - symmetric
3533
3534 const Int_t kN = 8;
3535 Double_t mA[kN * kN];
3536
3537 for (Int_t i = 0, ij = 0; i < kN; i++) {
3538 for (Int_t j = 0; j < kN; j++, ++ij) {
3539 mA[ij] = 0;
3540 for (Int_t k = 0; k < kN; ++k)
3541 mA[ij] += S[(k <= i) ? i * (i + 1) / 2 + k : k * (k + 1) / 2 + i] * Q[j * kN + k];
3542 }
3543 }
3544
3545 for (Int_t i = 0; i < kN; i++) {
3546 for (Int_t j = 0; j <= i; j++) {
3547 Int_t ij = (j <= i) ? i * (i + 1) / 2 + j : j * (j + 1) / 2 + i;
3548 SOut[ij] = 0;
3549 for (Int_t k = 0; k < kN; k++)
3550 SOut[ij] += Q[i * kN + k] * mA[k * kN + j];
3551 }
3552 }
3553}
3554
3555// 72-charachters line to define the printer border
3556// 3456789012345678901234567890123456789012345678901234567890123456789012
friend F32vec4 fabs(const F32vec4 &a)
Definition P4_F32vec4.h:52
__m128 v
Definition P4_F32vec4.h:1
int i
Definition P4_F32vec4.h:22
__m128 m
Definition P4_F32vec4.h:27
bool Bool_t
int Int_t
double Double_t
void Convert(bool ToProduction)
void GetMeasurement(const Double_t XYZ[], Double_t m[], Double_t V[]) const
void SetProductionVertex(const KFParticleBase &Vtx)
const Int_t & Q() const
void AddDaughterWithEnergyFitMC(const KFParticleBase &Daughter)
Int_t GetPhi(Double_t &Phi, Double_t &SigmaPhi) const
const Double_t & Y() const
const Double_t & S() const
Double_t fVtxGuess[3]
static void MultQSQt(const Double_t Q[], const Double_t S[], Double_t SOut[])
Double_t GetPz() const
void GetDStoParticleBz(Double_t Bz, const KFParticleBase &p, Double_t &dS, Double_t &dS1) const
Double_t GetDStoPointCBM(const Double_t xyz[]) const
void SetNonlinearMassConstraint(Double_t Mass)
Double_t GetDStoPointLine(const Double_t xyz[]) const
void AddDaughter(const KFParticleBase &Daughter)
Double_t & Cij(Int_t i, Int_t j)
void AddDaughterWithEnergyCalc(const KFParticleBase &Daughter)
static Bool_t InvertSym3(const Double_t A[], Double_t Ainv[])
Int_t GetLifeTime(Double_t &T, Double_t &SigmaT) const
Int_t GetEta(Double_t &Eta, Double_t &SigmaEta) const
Int_t GetDecayLength(Double_t &L, Double_t &SigmaL) const
Int_t GetR(Double_t &R, Double_t &SigmaR) const
Double_t SumDaughterMass
static Double_t GetSCorrection(const Double_t Part[], const Double_t XYZ[])
const Double_t & Z() const
void TransportCBM(Double_t dS, Double_t P[], Double_t C[]) const
Int_t GetMomentum(Double_t &P, Double_t &SigmaP) const
Double_t GetY() const
void GetDSIter(const KFParticleBase &p, Double_t const &dS, Double_t x[3], Double_t dx[3], Double_t ddx[3]) const
void SubtractFromVertex(KFParticleBase &Vtx) const
virtual void GetDStoParticle(const KFParticleBase &p, Double_t &DS, Double_t &DSp) const =0
Bool_t fAtProductionVertex
Double_t GetDistanceFromVertex(const Double_t vtx[]) const
Double_t GetDStoPointBz(Double_t Bz, const Double_t xyz[]) const
void GetDStoParticleCBM(const KFParticleBase &p, Double_t &dS, Double_t &dS1) const
void TransportLine(Double_t S, Double_t P[], Double_t C[]) const
Double_t GetPx() const
Double_t GetZ() const
Int_t GetQ() const
virtual void Transport(Double_t dS, Double_t P[], Double_t C[]) const =0
Double_t GetDistanceFromParticle(const KFParticleBase &p) const
void operator+=(const KFParticleBase &Daughter)
Double_t GetDeviationFromParticle(const KFParticleBase &p) const
Double_t GetCovariance(Int_t i) const
void SetVtxGuess(Double_t x, Double_t y, Double_t z)
void GetDStoParticleLine(const KFParticleBase &p, Double_t &dS, Double_t &dS1) const
void RotateXY(Double_t angle, Double_t Vtx[3])
virtual void GetFieldValue(const Double_t xyz[], Double_t B[]) const =0
std::vector< int > fDaughtersIds
Int_t GetMass(Double_t &M, Double_t &SigmaM) const
void TransportToProductionVertex()
Double_t GetPy() const
void TransportBz(Double_t Bz, Double_t dS, Double_t P[], Double_t C[]) const
const Double_t & X() const
Int_t GetDecayLengthXY(Double_t &L, Double_t &SigmaL) const
static Int_t IJ(Int_t i, Int_t j)
Double_t GetX() const
void Construct(const KFParticleBase *vDaughters[], Int_t nDaughters, const KFParticleBase *ProdVtx=0, Double_t Mass=-1, Bool_t IsConstrained=0)
void SetMassConstraint(Double_t Mass, Double_t SigmaMass=0)
Double_t GetDeviationFromVertex(const Double_t v[], const Double_t Cv[]=0) const
static void GetArmenterosPodolanski(KFParticleBase &positive, KFParticleBase &negative, Double_t QtAlfa[2])
Double_t fC[36]
void ConstructGammaBz(const KFParticleBase &daughter1, const KFParticleBase &daughter2, double Bz)
void GetDStoParticleBy(Double_t B, const KFParticleBase &p, Double_t &dS, Double_t &dS1) const
Double_t & Covariance(Int_t i)
Double_t GetDStoPointBy(Double_t By, const Double_t xyz[]) const
void TransportToDS(Double_t dS)
Int_t GetPt(Double_t &Pt, Double_t &SigmaPt) const
void AddDaughterWithEnergyFit(const KFParticleBase &Daughter)
virtual Double_t GetDStoPoint(const Double_t xyz[]) const =0
RVec< PromoteType< T > > sqrt(const RVec< T > &v)
Double_t ATan2(Double_t y, Double_t x)
Double_t Log(Double_t x)
Double_t Sqrt(Double_t x)
Double_t Cos(Double_t)
Double_t Abs(Double_t d)
Double_t Sin(Double_t)