PandaRoot
PndFTSCATrackParamVector.h
Go to the documentation of this file.
1 //****************************************************************************
2 //* This file is part of PandaRoot. *
3 //* *
4 //* PandaRoot is distributed under the terms of the *
5 //* GNU General Public License (GPL) version 3, *
6 //* copied verbatim in the file "LICENSE". *
7 //* *
8 //* Copyright (C) 2006 - 2024 FAIR GmbH and copyright holders of PandaRoot *
9 //* The copyright holders are listed in the file "COPYRIGHTHOLDERS". *
10 //* The authors are listed in the file "AUTHORS". *
11 //****************************************************************************
12 
13 //-*- Mode: C++ -*-
14 // $Id: PndFTSCATrackParamVector.h,v 1.3 2011/01/31 17:18:32 fisyak Exp $
15 // ************************************************************************
16 // This file is property of and copyright by the ALICE HLT Project *
17 // ALICE Experiment at CERN, All rights reserved. *
18 // See cxx source for full Copyright notice *
19 // *
20 //*************************************************************************
21 
22 #ifndef PNDFTSCATRACKPARAMVECTOR_H
23 #define PNDFTSCATRACKPARAMVECTOR_H
24 
25 class PndFTSCATrackParam;
26 
27 #ifdef PANDA_FTS
28 
29 #include "PndFTSCADef.h"
30 #include "PndFTSVector.h"
31 #include "PndFTSCAMath.h"
32 #include "L1XYMeasurementInfo.h"
33 #include "L1MaterialInfo.h"
34 #include "L1Field.h"
35 
36 #include "FairField.h"
37 #include "FairRunAna.h"
38 // #include "CAX1X2MeasurementInfo.h"
39 #include "FTSCAStation.h"
40 
41 class PndFTSCAParam;
42 class FTSCAHit;
43 class FTSCAHitV;
44 class FTSCATarget;
45 
54  friend std::istream &operator>>(std::istream &, PndFTSCATrackParamVector &);
55  friend std::ostream &operator<<(std::ostream &, const PndFTSCATrackParamVector &);
56 
57  public:
59  : fX(0.f), fY(0.f), fTx(0.f), fTy(0.f), fQP(0.f), fZ(0.f), fC00(0.f), fC10(0.f), fC11(0.f), fC20(0.f), fC21(0.f), fC22(0.f), fC30(0.f), fC31(0.f), fC32(0.f), fC33(0.f),
60  fC40(0.f), fC41(0.f), fC42(0.f), fC43(0.f), fC44(0.f), fChi2(0.f), fNDF(0.f)
61  {
62  fZB[0] = fZB[1] = 10e10;
63  fDirection = true;
64  }
65 
66  void SetTrackParam(const PndFTSCATrackParamVector &param, const float_m &m = float_m(true))
67  {
68  for (int i = 0; i < 5; i++)
69  Par(i)(m) = param.Par(i);
70  for (int i = 0; i < 15; i++)
71  Cov(i)(m) = param.Cov(i);
72  fX(m) = param.X();
73  fChi2(m) = param.Chi2();
74  fZ(m) = param.Z();
75  fNDF(static_cast<int_m>(m)) = param.NDF();
76  fAlpha(static_cast<int_m>(m)) = param.Angle();
77  }
78 
79  void SetTrackParamOne(int iV, const PndFTSCATrackParamVector &param, int iVa)
80  {
81  for (int i = 0; i < 5; i++)
82  Par(i)[iV] = param.Par(i)[iVa];
83  for (int i = 0; i < 15; i++)
84  Cov(i)[iV] = param.Cov(i)[iVa];
85  fX[iV] = param.X()[iVa];
86  fZ[iV] = param.Z()[iVa];
87  fChi2[iV] = param.Chi2()[iVa];
88  fNDF[iV] = param.NDF()[iVa];
89  fAlpha[iV] = param.Angle()[iVa];
90  }
91 
92  void ConvertTrackParamToVector(PndFTSCATrackParam t0[float_v::Size], int nTracksV);
93 
94  void PrintCovMat()
95  {
96  cout << "CovMat " << endl;
97  // for ( int i = 0; i < 15; i++ )
98  cout << Cov(0) << endl;
99  cout << Cov(1) << " " << Cov(2) << endl;
100  cout << Cov(3) << " " << Cov(4) << " " << Cov(5) << endl;
101  cout << Cov(6) << " " << Cov(7) << " " << Cov(8) << " " << Cov(9) << endl;
102  cout << Cov(10) << " " << Cov(11) << " " << Cov(12) << " " << Cov(13) << " " << Cov(14) << endl;
103  /*cout << Cov(0)[0] << endl;
104  cout << Cov(1)[0] << " "<< Cov(2)[0] << endl;
105  cout << Cov(3)[0] << " "<< Cov(4)[0] <<" "<< Cov(5)[0] << endl;
106  cout << Cov(6)[0] << " "<< Cov(7)[0] <<" "<< Cov(8)[0] <<" "<< Cov(9)[0] << endl;
107  cout << Cov(10)[0] <<" "<< Cov(11)[0] <<" "<< Cov(12)[0] <<" "<< Cov(13)[0] <<" "<< Cov(14)[0];*/
108  }
109 
110  void InitCovMatrix(float_v d2QMom = 0.f);
111  void InitByTarget(const FTSCATarget &target);
112  void InitByHit(const FTSCAHitV &hit, const PndFTSCAParam &param, const float_v &dQP);
113 
114  void InitDirection(float_v r0, float_v r1, float_v r2)
115  { // initialize direction parameters according to a given tangent vector r = { r0, r1, r2 }
116  float_m mask = (r0 > 0.f);
117  float_v tx(Vc::Zero);
118  tx(mask) = r1 / r0;
119  float_v ty(Vc::Zero);
120  ty(mask) = r2 / r0;
121  SetTx(tx);
122  SetTy(ty);
123  }
124 
125  float_v X() const { return fX; }
126  float_v Y() const { return fY; }
127  float_v Z() const { return fZ; }
128  float_v Tx() const { return fTx; }
129  float_v Ty() const { return fTy; }
130  float_v QP() const { return fQP; }
131 
132  float_v Bx() const { return fBx; }
133  float_v By() const { return fBy; }
134 
135  float_v Chi2() const { return fChi2; }
136  int_v NDF() const { return fNDF; }
137 
138  float_v Angle() const { return fAlpha; }
139 
140  float_v X0() const { return Z(); }
141  float_v X1() const { return X(); }
142  float_v X2() const { return Y(); }
143  float_v Tx1() const { return Tx(); }
144  float_v Tx2() const { return Ty(); }
145  float_v QMomentum() const { return QP(); } // used for triplets comparison
146  float_v SinPhi() const
147  { // dx/dxz
148  const float_v tx12 = Tx1() * Tx1();
149  return sqrt(tx12 / (1.f + tx12));
150  }
151 
152  const float_v &Par(int i) const
153  {
154  switch (i) {
155  case 0: return fX;
156  case 1: return fY;
157  case 2: return fTx;
158  case 3: return fTy;
159  case 4: return fQP;
160  case 5: return fZ;
161  };
162  assert(0);
163  return fX;
164  }
165 
166  const float_v &Cov(int i) const
167  {
168  switch (i) {
169  case 0: return fC00;
170  case 1: return fC10;
171  case 2: return fC11;
172  case 3: return fC20;
173  case 4: return fC21;
174  case 5: return fC22;
175  case 6: return fC30;
176  case 7: return fC31;
177  case 8: return fC32;
178  case 9: return fC33;
179  case 10: return fC40;
180  case 11: return fC41;
181  case 12: return fC42;
182  case 13: return fC43;
183  case 14: return fC44;
184  };
185  assert(0);
186  return fC00;
187  }
188 
189  float_v Err2X1() const { return Err2X(); }
190  float_v Err2X2() const { return Err2Y(); }
191 
192  float_v Err2X() const { return fC00; }
193  float_v Err2Y() const { return fC11; }
194  float_v Err2QP() const { return fC44; }
195  float_v Err2QMomentum() const { return Err2QP(); }
196 
197  void SetX(const float_v &v) { fX = v; }
198  void SetY(const float_v &v) { fY = v; }
199  void SetZ(const float_v &v) { fZ = v; }
200  void SetTx(const float_v &v) { fTx = v; }
201  void SetTy(const float_v &v) { fTy = v; }
202  void SetQP(const float_v &v) { fQP = v; }
203  void SetQMomentum(const float_v &v) { fQP = v; }
204  void SetBx(const float_v &v) { fBx = v; }
205  void SetBy(const float_v &v) { fBy = v; }
206 
207  void SetChi2(const float_v &v) { fChi2 = v; }
208  void SetNDF(int v) { fNDF = v; }
209  void SetNDF(const int_v &v) { fNDF = v; }
210 
211  void SetAngle(const float_v &v) { fAlpha = v; }
212 
213  void SetPar(int i, float_v v)
214  {
215  switch (i) {
216  case 0: fX = v; break;
217  case 1: fY = v; break;
218  case 2: fTx = v; break;
219  case 3: fTy = v; break;
220  case 4: fQP = v; break;
221  }
222  }
223  void SetCov(int i, float_v v)
224  {
225  switch (i) {
226  case 0: fC00 = v; break;
227  case 1: fC10 = v; break;
228  case 2: fC11 = v; break;
229  case 3: fC20 = v; break;
230  case 4: fC21 = v; break;
231  case 5: fC22 = v; break;
232  case 6: fC30 = v; break;
233  case 7: fC31 = v; break;
234  case 8: fC32 = v; break;
235  case 9: fC33 = v; break;
236  case 10: fC40 = v; break;
237  case 11: fC41 = v; break;
238  case 12: fC42 = v; break;
239  case 13: fC43 = v; break;
240  case 14: fC44 = v; break;
241  }
242  }
243 
244  void SetDirection(bool b) { fDirection = b; }
245 
246  float_v &Par(int i)
247  {
248  switch (i) {
249  case 0: return fX;
250  case 1: return fY;
251  case 2: return fTx;
252  case 3: return fTy;
253  case 4: return fQP;
254  };
255  assert(0);
256  return fX;
257  }
258 
259  float_v &Cov(int i)
260  {
261  switch (i) {
262  case 0: return fC00;
263  case 1: return fC10;
264  case 2: return fC11;
265  case 3: return fC20;
266  case 4: return fC21;
267  case 5: return fC22;
268  case 6: return fC30;
269  case 7: return fC31;
270  case 8: return fC32;
271  case 9: return fC33;
272  case 10: return fC40;
273  case 11: return fC41;
274  case 12: return fC42;
275  case 13: return fC43;
276  case 14: return fC44;
277  };
278  assert(0);
279  return fC00;
280  }
281 
282  void SetX(const float_v &v, const float_m &m) { fX(m) = v; }
283  void SetY(const float_v &v, const float_m &m) { fY(m) = v; }
284  void SetZ(const float_v &v, const float_m &m) { fZ(m) = v; }
285  void SetTx(const float_v &v, const float_m &m) { fTx(m) = v; }
286  void SetTy(const float_v &v, const float_m &m) { fTy(m) = v; }
287  void SetQP(const float_v &v, const float_m &m) { fQP(m) = v; }
288  void SetQMomentum(const float_v &v, const float_m &m) { fQP(m) = v; }
289 
290  void SetChi2(const float_v &v, const float_m &m) { fChi2(m) = v; }
291  void SetNDF(const int_v &v, const int_m &m) { fNDF(m) = v; }
292 
293  void SetField(int i, const CAFieldValue &b, const float_v &zb)
294  {
295  fB[i] = b;
296  fZB[i] = zb;
297  }
298 
299  void UpdateFieldValues(const FTSCAHitV &hit, const PndFTSCAParam &param, L1FieldRegion &f, const float_m &mask);
300  void UpdateFieldValues(const FTSCAHitV &hit, int_v &iVrt, float_v &zVirtualStation, const PndFTSCAParam &param, L1FieldRegion &f, const float_m &mask);
301 
302  void SetCovX12(float_v v00, float_v v10, float_v v11)
303  {
304  fC00 = v00;
305  fC10 = v10;
306  fC11 = v11;
307  }
308 
309  // float_m Transport(const int_v& ista, const int_v& iVSta, const PndFTSCAParam& param, const float_m&mask = float_m( true ) );
310  // float_m Transport( const int_v& ista, const PndFTSCAParam& param, const float_m &mask = float_m( true ) );
311 
312  float_m Transport(const FTSCAHitV &hit, const PndFTSCAParam &p, float_v &qp0, const float_m &mask = float_m(true));
313  float_m Transport(const FTSCAHitV &hit, const PndFTSCAParam &p, const float_m &mask = float_m(true));
314 
315  float_m TransportByLine(const FTSCAHitV &hit, const PndFTSCAParam &param, const float_m &mask = float_m(true));
316 
317  float_m Filter(const FTSCAHitV &hit, const PndFTSCAParam &param, const float_m &mask = float_m(true), const float_v &chi2Cut = 10e10f);
318 
319  float_m Transport(const FTSCAHit &hit, const PndFTSCAParam &p, const float_m &mask = float_m(true));
320  float_m Filter(const FTSCAHit &hit, const PndFTSCAParam &param, const float_m &mask = float_m(true), const float_v &chi2Cut = 10e10f);
321 
322  float_m AddTarget(const FTSCATarget &t, const float_m &mask = float_m(true));
323 
324  private:
325  // float_m Transport( const FTSCAHitV& hit, const L1FieldRegion& F, const PndFTSCAParam& p, const float_m &mask = float_m( true ) ); // dbg TODO delme
326 
327  float_m TransportToX0WithMaterial(const float_v &x0, const L1FieldRegion &F, const L1MaterialInfo &material, float_v &qp0, const float_m &mask = float_m(true));
328  float_m TransportToX0(const float_v &x0, const L1FieldRegion &F, const float_v &qp0, const float_m &mask = float_m(true));
329  float_m RK4TransportToX0(const float_v &x0_out, const L1FieldRegion &F, const float_v &qp0, const float_m &mask = float_m(true));
330  float_m TransportToX0Line(const float_v &x0, const float_m &mask = float_m(true));
331  float_m PassMaterial(const L1MaterialInfo &info, const float_v &qp0, const float_m &mask = float_m(true));
332  void EnergyLossCorrection(const float_v &mass2, const float_v &radThick, float_v &qp0, float_v direction, const float_m &mask);
333  float_v ApproximateBetheBloch(const float_v &bg2);
334 
335  float_m Filter(const float_v &y0, const float_v &z0, const float_v &r, const FTSCAStripInfoVector &info, float_v err2, const float_m &active, const float_v &chi2Cut = 10e10f);
336 
337  float_m FilterVtx(const float_v &xV, const float_v &yV, const L1XYMeasurementInfo &info, float_v &extrDx, float_v &extrDy, float_v J[], const float_m &active = float_m(true));
338 
339  float_m TransportJXY0ToX0(const float_v &x0, const L1FieldRegion &F, float_v &extrDx, float_v &extrDy, float_v &J04, float_v &J14, const float_m &active = float_m(true));
340 
341  float_v fX, fY, fTx, fTy, fQP, fZ, fC00, fC10, fC11, fC20, fC21, fC22, fC30, fC31, fC32, fC33, fC40, fC41, fC42, fC43, fC44;
342 
343  float_v fChi2; // the chi^2 value
344  int_v fNDF; // the Number of Degrees of Freedom
345 
346  float_v fBx;
347  float_v fBy;
348  CAFieldValue fB[2]; // field at two previous points, which track passed
349  float_v fZB[2]; // fZ position of the filld point
350  bool fDirection;
351  float_v fAlpha; // coor system
352  float_v fDelta;
353 };
354 
355 #include "debug.h"
356 
357 inline float_m PndFTSCATrackParamVector::TransportToX0Line(const float_v &x0_out, const float_m &mask)
358 {
359  float_v dz = (x0_out - fZ);
360  // cout<<"dz "<<dz<<endl;
361 
362  fX(mask) += fTx * dz;
363  fY(mask) += fTy * dz;
364  fZ(mask) += dz;
365 
366  const float_v dzC32_in = dz * fC32;
367 
368  fC21(mask) += dzC32_in;
369  fC10(mask) += dz * (fC21 + fC30);
370 
371  const float_v C20_in = fC20;
372 
373  fC20(mask) += dz * fC22;
374  fC00(mask) += dz * (fC20 + C20_in);
375 
376  const float_v C31_in = fC31;
377 
378  fC31(mask) += dz * fC33;
379  fC11(mask) += dz * (fC31 + C31_in);
380  fC30(mask) += dzC32_in;
381 
382  fC40(mask) += dz * fC42;
383  fC41(mask) += dz * fC43;
384 
385  return mask;
386 }
387 
388 inline float_m PndFTSCATrackParamVector::Filter(
389  const float_v &x0, const float_v &y0, const float_v &r, const FTSCAStripInfoVector &info, float_v err2, const float_m &active,
390  const float_v & /*chi2Cut*/) //[R.K. 9/2018] unused
391  // Adds the tube measurement with the Kalman filter
392  // @beta is angle between the strip and z-axis, clockwise. The wire equation is: {x,y,z} - {x0,y0,z0} = t*e_s, where ort e_s = { 0, -sinB, cos B }
393 {
394  // linearize track in current point, which must be x == x0
395  // distance between wire and track are : r = - ({x,y,z} - {x0,y0,z0}) * e_o / |e_o|, where ort e_o = |[e_t x e_s]|
396 
397  float_m success = active;
398 
399  success &= (err2 > 1.e-8f);
400 
401  // const float_v& h0 = info.cos;
402  // const float_v& h1 = info.sin;
403  float_v h0(Vc::Zero);
404  float_v h1(Vc::Zero);
405  h0(active) = info.cos;
406  h1(active) = info.sin;
407  /*foreach_bit(unsigned short iV, active) {
408  h0[iV] = info.cos;
409  h1[iV] = info.sin;
410  }*/
411 
412  const float_v tx = h0 * fTx + h1 * fTy;
413 
414  float_v zeta;
415 
416  // float_v Sign_1 = float_v(0.0);
417 
418  float_v rCorrection = sqrt(1.f + tx * tx);
419 
420  float_v Diff = h0 * (fX - x0) + h1 * (fY - y0);
421  float_v zeta_1, zeta_2;
422  zeta_1 = h0 * (fX - x0) + h1 * (fY - y0) - r * rCorrection;
423  zeta_2 = h0 * (fX - x0) + h1 * (fY - y0) + r * rCorrection;
424 
425  for (int iDiff = 0; iDiff < 4; iDiff++) {
426  float Diff_f = (float)Diff[iDiff];
427  if (Diff_f > 0.f) {
428  // zeta = h0*(fX - x0) + h1*(fY - y0) - r*rCorrection;
429  zeta[iDiff] = zeta_1[iDiff];
430  } else {
431  zeta[iDiff] = zeta_2[iDiff];
432  }
433 
434  } // iDiff
435 
436  // const float_v zeta2 = h0*(fX - x0) + h1*(fY - y0) + r*rCorrection;
437 
438  if (err2[0] < 0.01f)
439  err2[0] = err2[0] + r[0] * r[0];
440  err2 *= rCorrection * rCorrection;
441 
442  float_v wi, zetawi, HCH;
443  float_v F0, F1, F2, F3, F4;
444  float_v K1, K2, K3, K4;
445 
446  if (fC00[0] < 0.f)
447  fC00[0] = 0.f;
448 
449  // F = CH'
450  F0 = h0 * fC00 + h1 * fC10;
451  F1 = h0 * fC10 + h1 * fC11;
452 
453  // HCH = ( F0*h0 + F1*h1 );
454  HCH = (h0 * h0 * fC00 + 2.f * h0 * h1 * fC10) + h1 * h1 * fC11;
455 
456  F2 = h0 * fC20 + h1 * fC21;
457  F3 = h0 * fC30 + h1 * fC31;
458  F4 = h0 * fC40 + h1 * fC41;
459 
460  float_v dChi2(Vc::Zero);
461 #if 0 // use mask
462  cout<<"we don't have to be here for now \n";
463  const float_m mask = success && (HCH > err2 * 16.f);
464  HCH(mask) += err2;
465  wi(mask) = 1.f/HCH ;
466  zetawi(mask) = zeta *wi;
467  dChi2(mask) += (zeta * zetawi);
468  fChi2 += dChi2;
469 #else
470  wi = 1.f / (err2 + HCH);
471  zetawi = zeta * wi;
472  dChi2(success) += zeta * zetawi;
473  // success &= dChi2 < chi2Cut;
474  fChi2 += dChi2;
475  // fChi2(success) += zeta * zetawi;
476 #endif // 0
477 
478  // success &= fChi2 < chi2Cut;
479 
480  K1 = F1 * wi;
481  K2 = F2 * wi;
482  K3 = F3 * wi;
483  K4 = F4 * wi;
484 
485  fX(success) -= F0 * zetawi;
486  fY(success) -= F1 * zetawi;
487  fTx(success) -= F2 * zetawi;
488  fTy(success) -= F3 * zetawi;
489  fQP(success) -= F4 * zetawi;
490 
491  fC00(success) -= F0 * F0 * wi;
492  fC10(success) -= K1 * F0;
493  fC11(success) -= K1 * F1;
494  fC20(success) -= K2 * F0;
495  fC21(success) -= K2 * F1;
496  fC22(success) -= K2 * F2;
497  fC30(success) -= K3 * F0;
498  fC31(success) -= K3 * F1;
499  fC32(success) -= K3 * F2;
500  fC33(success) -= K3 * F3;
501  fC40(success) -= K4 * F0;
502  fC41(success) -= K4 * F1;
503  fC42(success) -= K4 * F2;
504  fC43(success) -= K4 * F3;
505  fC44(success) -= K4 * F4;
506 
507  fNDF(static_cast<int_m>(success)) += 1;
508 
509  return success;
510 }
511 
512 inline float_m PndFTSCATrackParamVector::TransportToX0WithMaterial(const float_v &x0, const L1FieldRegion &F, const L1MaterialInfo &material, float_v &qp0, const float_m &mask)
513 { // TODO material
514  float_m active = mask;
515  active &= TransportToX0(x0, F, qp0, active);
516  // active &= TransportToX0Line(x0, active);
517  // active &= RK4TransportToX0( x0, F, qp0, active );
518  active &= PassMaterial(material, qp0, active);
519  const float_v mass2 = 0.13957f * 0.13957f;
520  float_v direction = -1.f;
521  if (fDirection)
522  direction = 1.f;
523  // std::cout << "qp " << qp0[0] << " " << " fQP " << fQP[0]<<" ";
524  EnergyLossCorrection(mass2, material.RadThick, qp0, direction, active);
525  // std::cout << qp0[0] << " " << fQP[0] << std::endl;
526  return active;
527 }
528 
529 inline float_m PndFTSCATrackParamVector::RK4TransportToX0(const float_v &x0_out, const L1FieldRegion & /*F*/, const float_v & /*qp0*/, const float_m &mask) //[R.K. 9/2018] 2 unused
530 {
531  // Forth-order Runge-Kutta method for solution of the equation
532  // of motion of a particle with parameter qp = Q /P
533  // in the magnetic field B()
534  //
535  // | x | tx
536  // | y | ty
537  // d/dz = | tx| = ft * ( ty * ( B(3)+tx*b(1) ) - (1+tx**2)*B(2) )
538  // | ty| ft * (-tx * ( B(3)+ty+b(2) - (1+ty**2)*B(1) ) ,
539  //
540  // where ft = c_light*qp*sqrt ( 1 + tx**2 + ty**2 ) .
541  //
542  // In the following for RK step :
543  //
544  // x=x[0], y=x[1], tx=x[3], ty=x[4].
545  //
546  //========================================================================
547 
548  // const float ZERO = 0.0, ONE = 1.;
549 
550  // RK4ORDER
551  float_v xOut[5];
552  float_v Fmat[25];
553  const float_v fC = 0.000299792458f;
554 
555  float_v coef[4];
556  coef[0] = 0.f;
557  coef[1] = 0.5f;
558  coef[2] = 0.5f;
559  coef[3] = 1.f;
560 
561  float_v xIn[4];
562  xIn[0] = fX;
563  xIn[2] = fTx;
564  xIn[1] = fY;
565  xIn[3] = fTy;
566  xIn[4] = fQP;
567 
568  float_v Ax[4], Ay[4];
569  float_v dAx_dtx[4], dAy_dtx[4], dAx_dty[4], dAy_dty[4];
570  float_v k[4][4];
571 
572  float_v h = x0_out - fZ;
573  // cout<<"Step h: "<<h<<endl;
574  float_v hC = h * fC;
575  float_v hCqp = h * fC * xIn[4];
576  float_v x0[4];
577 
578  float_v x[4];
579  x[0] = fX;
580  x[2] = fTx;
581  x[1] = fY;
582  x[3] = fTy; // x[4] = fQP;
583 
584  for (unsigned int iStep = 0; iStep < 4; iStep++) { // 1
585  if (iStep > 0) {
586 
587  x[0] = xIn[0] + coef[iStep] * k[0][iStep - 1];
588  x[1] = xIn[1] + coef[iStep] * k[1][iStep - 1];
589  x[2] = xIn[2] + coef[iStep] * k[2][iStep - 1];
590  x[3] = xIn[3] + coef[iStep] * k[3][iStep - 1];
591  }
592 
593  float_v bx(0.f), by(0.f), bz(0.f);
594  double p[3];
595  double b[3];
596  for (int xxx = 0; xxx < float_v::Size; xxx++) {
597  // if (fabs(x[0][xxx])>0.001)
598  {
599  // double p[3] = {fX[ctr], fY[ctr], fZ[ctr]};
600  // double b[3] = {0., 0., 0.};
601  p[0] = x[0][xxx];
602  p[1] = x[1][xxx];
603  p[2] = fZ[xxx] + coef[iStep][xxx] * h[xxx];
604  b[0] = 0;
605  b[1] = 0;
606  b[2] = 0;
607  FairRunAna::Instance()->GetField()->Field(p, b); // CbmKF::Instance()->GetMagneticField()->GetFieldValue(p,b);
608  bx[xxx] = b[0];
609  by[xxx] = b[1];
610  bz[xxx] = b[2];
611  }
612  }
613  // fField->GetFieldValue(x[0], x[1], zIn + coef[iStep] * h, Bx, By, Bz);
614  float_v tx = x[2];
615  float_v ty = x[3];
616  float_v txtx = tx * tx;
617  float_v tyty = ty * ty;
618  float_v txty = tx * ty;
619  float_v txtxtyty1 = 1.f + txtx + tyty;
620  float_v t1 = sqrt(txtxtyty1);
621  float_v t2 = 1.f / txtxtyty1;
622 
623  Ax[iStep] = (txty * bx + ty * bz - (1.f + txtx) * by) * t1;
624  Ay[iStep] = (-txty * by - tx * bz + (1.f + tyty) * bx) * t1;
625 
626  dAx_dtx[iStep] = Ax[iStep] * tx * t2 + (ty * bx - 2.f * tx * by) * t1;
627  dAx_dty[iStep] = Ax[iStep] * ty * t2 + (tx * bx + bz) * t1;
628  dAy_dtx[iStep] = Ay[iStep] * tx * t2 + (-ty * by - bz) * t1;
629  dAy_dty[iStep] = Ay[iStep] * ty * t2 + (-tx * by + 2.f * ty * bx) * t1;
630 
631  k[0][iStep] = tx * h;
632  k[1][iStep] = ty * h;
633  k[2][iStep] = Ax[iStep] * hCqp;
634  k[3][iStep] = Ay[iStep] * hCqp;
635 
636  } // 1
637 
638  // in + k[0]/6.f + k[1]/3.f + k[2]/3.f + k[3]/6.f;
639  // for (unsigned int i = 0; i < 4; i++) { xOut[i] = CalcOut(xIn[i], k[i]); }
640  xOut[0] = xIn[0] + k[0][0] / 6.f + k[0][1] / 3.f + k[0][2] / 3.f + k[0][3] / 6.f;
641  xOut[1] = xIn[1] + k[1][0] / 6.f + k[1][1] / 3.f + k[1][2] / 3.f + k[1][3] / 6.f;
642  xOut[2] = xIn[2] + k[2][0] / 6.f + k[2][1] / 3.f + k[2][2] / 3.f + k[2][3] / 6.f;
643  xOut[3] = xIn[3] + k[3][0] / 6.f + k[3][1] / 3.f + k[3][2] / 3.f + k[3][3] / 6.f;
644  xOut[4] = xIn[4];
645 
646  fX(mask) = xOut[0];
647  fY(mask) = xOut[1];
648  fTx(mask) = xOut[2];
649  fTy(mask) = xOut[3];
650  fQP(mask) = xOut[4];
651  fZ(mask) += h;
652  // Calculation of the derivatives
653 
654  // derivatives dx/dx and dx/dy
655  // dx/dx
656  Fmat[0] = 1.f;
657  Fmat[5] = 0.f;
658  Fmat[10] = 0.f;
659  Fmat[15] = 0.f;
660  Fmat[20] = 0.f;
661  // dx/dy
662  Fmat[1] = 0.f;
663  Fmat[6] = 1.f;
664  Fmat[11] = 0.f;
665  Fmat[16] = 0.f;
666  Fmat[21] = 0.f;
667  // end of derivatives dx/dx and dx/dy
668 
669  // Derivatives dx/tx
670  x[0] = x0[0] = 0.f;
671  x[1] = x0[1] = 0.f;
672  x[2] = x0[2] = 1.f;
673  x[3] = x0[3] = 0.f;
674  for (unsigned int iStep = 0; iStep < 4; iStep++) { // 2
675  if (iStep > 0) {
676  x[0] = xIn[0] + coef[iStep] * k[0][iStep - 1];
677  x[1] = xIn[1] + coef[iStep] * k[1][iStep - 1];
678  x[3] = xIn[3] + coef[iStep] * k[3][iStep - 1];
679  }
680 
681  k[0][iStep] = x[2] * h;
682  k[1][iStep] = x[3] * h;
683  // k[2][iStep] = (dAx_dtx[iStep] * x[2] + dAx_dty[iStep] * x[3]) * hCqp;
684  k[3][iStep] = (dAy_dtx[iStep] * x[2] + dAy_dty[iStep] * x[3]) * hCqp;
685  } // 2
686 
687  Fmat[2] = x0[0] + k[0][0] / 6.f + k[0][1] / 3.f + k[0][2] / 3.f + k[0][3] / 6.f;
688 
689  Fmat[7] = x0[1] + k[1][0] / 6.f + k[1][1] / 3.f + k[1][2] / 3.f + k[1][3] / 6.f;
690  Fmat[12] = 1.f;
691 
692  Fmat[17] = x0[3] + k[3][0] / 6.f + k[3][1] / 3.f + k[3][2] / 3.f + k[3][3] / 6.f;
693  Fmat[22] = 0.f;
694  // end of derivatives dx/dtx
695 
696  // Derivatives dx/ty
697  x[0] = x0[0] = 0.f;
698  x[1] = x0[1] = 0.f;
699  x[2] = x0[2] = 0.f;
700  x[3] = x0[3] = 1.f;
701  for (unsigned int iStep = 0; iStep < 4; iStep++) { // 4
702  if (iStep > 0) {
703  x[0] = xIn[0] + coef[iStep] * k[0][iStep - 1];
704  x[1] = xIn[1] + coef[iStep] * k[1][iStep - 1];
705  x[2] = xIn[2] + coef[iStep] * k[2][iStep - 1];
706  }
707 
708  k[0][iStep] = x[2] * h;
709  k[1][iStep] = x[3] * h;
710  k[2][iStep] = (dAx_dtx[iStep] * x[2] + dAx_dty[iStep] * x[3]) * hCqp;
711  // k[3][iStep] = (dAy_dtx[iStep] * x[2] + dAy_dty[iStep] * x[3]) * hCqp;
712  } // 4
713 
714  Fmat[3] = x0[0] + k[0][0] / 6.f + k[0][1] / 3.f + k[0][2] / 3.f + k[0][3] / 6.f;
715 
716  Fmat[8] = x0[1] + k[1][0] / 6.f + k[1][1] / 3.f + k[1][2] / 3.f + k[1][3] / 6.f;
717 
718  Fmat[13] = x0[2] + k[2][0] / 6.f + k[2][1] / 3.f + k[2][2] / 3.f + k[2][3] / 6.f;
719  Fmat[18] = 1.f;
720  Fmat[23] = 0.f;
721  // end of derivatives dx/dty
722 
723  // Derivatives dx/dqp
724  x[0] = x0[0] = 0.f;
725  x[1] = x0[1] = 0.f;
726  x[2] = x0[2] = 0.f;
727  x[3] = x0[3] = 0.f;
728  for (unsigned int iStep = 0; iStep < 4; iStep++) { // 4
729  if (iStep > 0) {
730  x[0] = xIn[0] + coef[iStep] * k[0][iStep - 1];
731  x[1] = xIn[1] + coef[iStep] * k[1][iStep - 1];
732  x[2] = xIn[2] + coef[iStep] * k[2][iStep - 1];
733  x[3] = xIn[3] + coef[iStep] * k[3][iStep - 1];
734  }
735 
736  k[0][iStep] = x[2] * h;
737  k[1][iStep] = x[3] * h;
738  k[2][iStep] = Ax[iStep] * hC + hCqp * (dAx_dtx[iStep] * x[2] + dAx_dty[iStep] * x[3]);
739  k[3][iStep] = Ay[iStep] * hC + hCqp * (dAy_dtx[iStep] * x[2] + dAy_dty[iStep] * x[3]);
740  } // 4
741 
742  Fmat[4] = x0[0] + k[0][0] / 6.f + k[0][1] / 3.f + k[0][2] / 3.f + k[0][3] / 6.f;
743 
744  Fmat[9] = x0[1] + k[1][0] / 6.f + k[1][1] / 3.f + k[1][2] / 3.f + k[1][3] / 6.f;
745 
746  Fmat[14] = x0[2] + k[2][0] / 6.f + k[2][1] / 3.f + k[2][2] / 3.f + k[2][3] / 6.f;
747 
748  Fmat[19] = x[3] + k[3][0] / 6.f + k[3][1] / 3.f + k[3][2] / 3.f + k[3][3] / 6.f;
749  Fmat[24] = 1.f;
750  // end of derivatives dx/dqp
751 
752  // end calculation of the derivatives
753  // F*C*Ft
754  float_v A = fC20 + Fmat[2] * fC22 + Fmat[3] * fC32 + Fmat[4] * fC42;
755  float_v B = fC30 + Fmat[2] * fC32 + Fmat[3] * fC33 + Fmat[4] * fC43;
756  float_v C = fC40 + Fmat[2] * fC42 + Fmat[3] * fC43 + Fmat[4] * fC44;
757 
758  float_v D = fC21 + Fmat[7] * fC22 + Fmat[8] * fC32 + Fmat[9] * fC42;
759  float_v E = fC31 + Fmat[7] * fC32 + Fmat[8] * fC33 + Fmat[9] * fC43;
760  float_v G = fC41 + Fmat[7] * fC42 + Fmat[8] * fC43 + Fmat[9] * fC44;
761 
762  float_v H = fC22 + Fmat[13] * fC32 + Fmat[14] * fC42;
763  float_v I = fC32 + Fmat[13] * fC33 + Fmat[14] * fC43;
764  float_v J = fC42 + Fmat[13] * fC43 + Fmat[14] * fC44;
765 
766  float_v K = fC43 + Fmat[17] * fC42 + Fmat[19] * fC44;
767 
768  fC00(mask) = fC00 + Fmat[2] * fC20 + Fmat[3] * fC30 + Fmat[4] * fC40 + A * Fmat[2] + B * Fmat[3] + C * Fmat[4];
769  fC10(mask) = fC10 + Fmat[2] * fC21 + Fmat[3] * fC31 + Fmat[4] * fC41 + A * Fmat[7] + B * Fmat[8] + C * Fmat[9];
770  fC20(mask) = A + B * Fmat[13] + C * Fmat[14];
771  fC30(mask) = B + A * Fmat[17] + C * Fmat[19];
772  fC40(mask) = C;
773 
774  fC11(mask) = fC11 + Fmat[7] * fC21 + Fmat[8] * fC31 + Fmat[9] * fC41 + D * Fmat[7] + E * Fmat[8] + G * Fmat[9];
775  fC21(mask) = D + E * Fmat[13] + G * Fmat[14];
776  fC31(mask) = E + D * Fmat[17] + G * Fmat[19];
777  fC41(mask) = G;
778 
779  fC22(mask) = H + I * Fmat[13] + J * Fmat[14];
780  fC32(mask) = I + H * Fmat[17] + J * Fmat[19];
781  fC42(mask) = J;
782 
783  fC33(mask) = fC33 + Fmat[17] * fC32 + Fmat[19] * fC43 + (Fmat[17] * fC22 + fC32 + Fmat[19] * fC42) * Fmat[17] + K * Fmat[19];
784  fC43(mask) = K;
785 
786  fC44(mask) = fC44;
787 
788  return mask;
789 }
790 
791 inline float_m PndFTSCATrackParamVector::TransportToX0(const float_v &x0_out, const L1FieldRegion &F, const float_v &qp0, const float_m &mask)
792 {
793 
794  // cout<<"Extrapolation..."<<endl;
795  //
796  // Part of the analytic extrapolation formula with error (c_light*B*dz)^4/4!
797  //
798  /*cout<<"before extrp fX fY fTx fTy fQP "<<fX[0]<<" "<<fY[0]<<" "<<fTx[0]<<" "<<fTy[0]<<" "<<fQP[0] << " z " << fZ[0] <<endl;
799  cout<<"transport to x0 "<<x0_out[0]<<endl;*/
800  const float_v c_light = 0.000299792458f;
801  // std::cout <<"Extrapolate 0 " <<std::endl;
802  // std::cout << "fX " << fX << " fY " << fY << " fZ " << fZ << std::endl;
803  // std::cout << "fTx " << fTx << " fTy " << fTy << " Qp " << fQP << std::endl;
804 
805  const float_v c1 = 1.f, c2 = 2.f, c3 = 3.f, c4 = 4.f, c6 = 6.f, c9 = 9.f, c15 = 15.f, c18 = 18.f, c45 = 45.f, c2i = 1.f / 2.f, c3i = 1.f / 3.f, c6i = 1.f / 6.f,
806  c12i = 1.f / 12.f;
807 
808  float_v dz(Vc::Zero);
809  dz(mask) = (x0_out - fZ);
810  // const float_v dz = (x0_out - fZ);
811  const float_v dz2 = dz * dz;
812  const float_v dz3 = dz2 * dz;
813  // construct coefficients
814 
815  const float_v x = fTx;
816  const float_v y = fTy;
817  const float_v xx = x * x;
818  const float_v xy = x * y;
819  const float_v yy = y * y;
820  const float_v y2 = y * c2;
821  const float_v x2 = x * c2;
822  const float_v x4 = x * c4;
823  const float_v xx31 = xx * c3 + c1;
824  const float_v xx159 = xx * c15 + c9;
825 
826  const float_v Ay = -xx - c1;
827  const float_v Ayy = x * (xx * c3 + c3);
828  const float_v Ayz = -c2 * xy;
829  const float_v Ayyy = -(c15 * xx * xx + c18 * xx + c3);
830 
831  const float_v Ayy_fX = c3 * xx31;
832  const float_v Ayyy_fX = -x4 * xx159;
833 
834  const float_v bx = yy + c1;
835  const float_v Byy = y * xx31;
836  const float_v Byz = c2 * xx + c1;
837  const float_v Byyy = -xy * xx159;
838 
839  const float_v Byy_fX = c6 * xy;
840  const float_v Byyy_fX = -y * (c45 * xx + c9);
841  const float_v Byyy_fY = -x * xx159;
842 
843  // end of coefficients calculation
844 
845  const float_v t2 = c1 + xx + yy;
846  const float_v t = sqrt(t2);
847  const float_v h = qp0 * c_light;
848  const float_v ht = h * t;
849 
850  // get field integrals
851  const float_v ddz = fZ - F.z0;
852  float_v Fx0 = F.cx0 + F.cx1 * ddz + F.cx2 * ddz * ddz;
853  float_v Fx1 = (F.cx1 + c2 * F.cx2 * ddz) * dz;
854  float_v Fx2 = F.cx2 * dz2;
855  float_v Fy0 = F.cy0 + F.cy1 * ddz + F.cy2 * ddz * ddz;
856  float_v Fy1 = (F.cy1 + c2 * F.cy2 * ddz) * dz;
857  float_v Fy2 = F.cy2 * dz2;
858  float_v Fz0 = F.cz0 + F.cz1 * ddz + F.cz2 * ddz * ddz;
859  float_v Fz1 = (F.cz1 + c2 * F.cz2 * ddz) * dz;
860  float_v Fz2 = F.cz2 * dz2;
861 
862  const float_v sx = (Fx0 + Fx1 * c2i + Fx2 * c3i);
863  const float_v sy = (Fy0 + Fy1 * c2i + Fy2 * c3i);
864  const float_v sz = (Fz0 + Fz1 * c2i + Fz2 * c3i);
865 
866  const float_v Sx = (Fx0 * c2i + Fx1 * c6i + Fx2 * c12i);
867  const float_v Sy = (Fy0 * c2i + Fy1 * c6i + Fy2 * c12i);
868  const float_v Sz = (Fz0 * c2i + Fz1 * c6i + Fz2 * c12i);
869 
870  float_v syz;
871  {
872  const float_v d = 1.f / 360.f, c00 = 30.f * 6.f * d, c01 = 30.f * 2.f * d, c02 = 30.f * d, c10 = 3.f * 40.f * d, c11 = 3.f * 15.f * d, c12 = 3.f * 8.f * d,
873  c20 = 2.f * 45.f * d, c21 = 2.f * 2.f * 9.f * d, c22 = 2.f * 2.f * 5.f * d;
874  syz = Fy0 * (c00 * Fz0 + c01 * Fz1 + c02 * Fz2) + Fy1 * (c10 * Fz0 + c11 * Fz1 + c12 * Fz2) + Fy2 * (c20 * Fz0 + c21 * Fz1 + c22 * Fz2);
875  }
876 
877  float_v Syz;
878  {
879  const float_v d = 1.f / 2520.f, c00 = 21.f * 20.f * d, c01 = 21.f * 5.f * d, c02 = 21.f * 2.f * d, c10 = 7.f * 30.f * d, c11 = 7.f * 9.f * d, c12 = 7.f * 4.f * d,
880  c20 = 2.f * 63.f * d, c21 = 2.f * 21.f * d, c22 = 2.f * 10.f * d;
881  Syz = Fy0 * (c00 * Fz0 + c01 * Fz1 + c02 * Fz2) + Fy1 * (c10 * Fz0 + c11 * Fz1 + c12 * Fz2) + Fy2 * (c20 * Fz0 + c21 * Fz1 + c22 * Fz2);
882  }
883 
884  const float_v syy = sy * sy * c2i;
885  const float_v syyy = syy * sy * c3i;
886 
887  float_v Syy;
888  {
889  const float_v d = 1.f / 2520.f, c00 = 420.f * d, c01 = 21.f * 15.f * d, c02 = 21.f * 8.f * d, c03 = 63.f * d, c04 = 70.f * d, c05 = 20.f * d;
890  Syy = Fy0 * (c00 * Fy0 + c01 * Fy1 + c02 * Fy2) + Fy1 * (c03 * Fy1 + c04 * Fy2) + c05 * Fy2 * Fy2;
891  }
892 
893  float_v Syyy;
894  {
895  const float_v d = 1.f / 181440.f, c000 = 7560 * d, c001 = 9 * 1008 * d, c002 = 5 * 1008 * d, c011 = 21 * 180 * d, c012 = 24 * 180 * d, c022 = 7 * 180 * d, c111 = 540 * d,
896  c112 = 945 * d, c122 = 560 * d, c222 = 112 * d;
897  const float_v Fy22 = Fy2 * Fy2;
898  Syyy = Fy0 * (Fy0 * (c000 * Fy0 + c001 * Fy1 + c002 * Fy2) + Fy1 * (c011 * Fy1 + c012 * Fy2) + c022 * Fy22) + Fy1 * (Fy1 * (c111 * Fy1 + c112 * Fy2) + c122 * Fy22) +
899  c222 * Fy22 * Fy2;
900  }
901 
902  const float_v sA1 = sx * xy + sy * Ay + sz * y;
903  const float_v sA1_fX = sx * y - sy * x2;
904  const float_v sA1_fY = sx * x + sz;
905 
906  const float_v sB1 = sx * bx - sy * xy - sz * x;
907  const float_v sB1_fX = -sy * y - sz;
908  const float_v sB1_fY = sx * y2 - sy * x;
909 
910  const float_v SA1 = Sx * xy + Sy * Ay + Sz * y;
911  const float_v SA1_fX = Sx * y - Sy * x2;
912  const float_v SA1_fY = Sx * x + Sz;
913 
914  const float_v SB1 = Sx * bx - Sy * xy - Sz * x;
915  const float_v SB1_fX = -Sy * y - Sz;
916  const float_v SB1_fY = Sx * y2 - Sy * x;
917 
918  const float_v sA2 = syy * Ayy + syz * Ayz;
919  const float_v sA2_fX = syy * Ayy_fX - syz * y2;
920  const float_v sA2_fY = -syz * x2;
921  const float_v sB2 = syy * Byy + syz * Byz;
922  const float_v sB2_fX = syy * Byy_fX + syz * x4;
923  const float_v sB2_fY = syy * xx31;
924 
925  const float_v SA2 = Syy * Ayy + Syz * Ayz;
926  const float_v SA2_fX = Syy * Ayy_fX - Syz * y2;
927  const float_v SA2_fY = -Syz * x2;
928  const float_v SB2 = Syy * Byy + Syz * Byz;
929  const float_v SB2_fX = Syy * Byy_fX + Syz * x4;
930  const float_v SB2_fY = Syy * xx31;
931 
932  const float_v sA3 = syyy * Ayyy;
933  const float_v sA3_fX = syyy * Ayyy_fX;
934  const float_v sB3 = syyy * Byyy;
935  const float_v sB3_fX = syyy * Byyy_fX;
936  const float_v sB3_fY = syyy * Byyy_fY;
937 
938  const float_v SA3 = Syyy * Ayyy;
939  const float_v SA3_fX = Syyy * Ayyy_fX;
940  const float_v SB3 = Syyy * Byyy;
941  const float_v SB3_fX = Syyy * Byyy_fX;
942  const float_v SB3_fY = Syyy * Byyy_fY;
943 
944  const float_v ht1 = ht * dz;
945  const float_v ht2 = ht * ht * dz2;
946  const float_v ht3 = ht * ht * ht * dz3;
947  const float_v ht1sA1 = ht1 * sA1;
948  const float_v ht1sB1 = ht1 * sB1;
949  const float_v ht1SA1 = ht1 * SA1;
950  const float_v ht1SB1 = ht1 * SB1;
951  const float_v ht2sA2 = ht2 * sA2;
952  const float_v ht2SA2 = ht2 * SA2;
953  const float_v ht2sB2 = ht2 * sB2;
954  const float_v ht2SB2 = ht2 * SB2;
955  const float_v ht3sA3 = ht3 * sA3;
956  const float_v ht3sB3 = ht3 * sB3;
957  const float_v ht3SA3 = ht3 * SA3;
958  const float_v ht3SB3 = ht3 * SB3;
959 
960  fX(mask) += ((x + ht1SA1 + ht2SA2 + ht3SA3) * dz);
961  fY(mask) += ((y + ht1SB1 + ht2SB2 + ht3SB3) * dz);
962  fTx(mask) += (ht1sA1 + ht2sA2 + ht3sA3);
963  fTy(mask) += (ht1sB1 + ht2sB2 + ht3sB3);
964  fZ(mask) += (dz);
965 
966  // std::cout <<"Extrapolate 1 " <<std::endl;
967  // std::cout << "fX " << fX << " fY " << fY << " fZ " << fZ << std::endl;
968  // std::cout << "fTx " << fTx << " fTy " << fTy << " Qp " << fQP << std::endl;
969 
970  const float_v ctdz = c_light * t * dz;
971  const float_v ctdz2 = c_light * t * dz2;
972 
973  const float_v dqp = fQP - qp0;
974  const float_v t2i = c1 * rcp(t2); // /t2;
975  const float_v xt2i = x * t2i;
976  const float_v yt2i = y * t2i;
977  const float_v tmp0 = ht1SA1 + c2 * ht2SA2 + c3 * ht3SA3;
978  const float_v tmp1 = ht1SB1 + c2 * ht2SB2 + c3 * ht3SB3;
979  const float_v tmp2 = ht1sA1 + c2 * ht2sA2 + c3 * ht3sA3;
980  const float_v tmp3 = ht1sB1 + c2 * ht2sB2 + c3 * ht3sB3;
981 
982  const float_v j02 = dz * (c1 + xt2i * tmp0 + ht1 * SA1_fX + ht2 * SA2_fX + ht3 * SA3_fX);
983  const float_v j12 = dz * (xt2i * tmp1 + ht1 * SB1_fX + ht2 * SB2_fX + ht3 * SB3_fX);
984  const float_v j22 = c1 + xt2i * tmp2 + ht1 * sA1_fX + ht2 * sA2_fX + ht3 * sA3_fX;
985  const float_v j32 = xt2i * tmp3 + ht1 * sB1_fX + ht2 * sB2_fX + ht3 * sB3_fX;
986 
987  const float_v j03 = dz * (yt2i * tmp0 + ht1 * SA1_fY + ht2 * SA2_fY);
988  const float_v j13 = dz * (c1 + yt2i * tmp1 + ht1 * SB1_fY + ht2 * SB2_fY + ht3 * SB3_fY);
989  const float_v j23 = yt2i * tmp2 + ht1 * sA1_fY + ht2 * sA2_fY;
990  const float_v j33 = c1 + yt2i * tmp3 + ht1 * sB1_fY + ht2 * sB2_fY + ht3 * sB3_fY;
991 
992  const float_v j04 = ctdz2 * (SA1 + c2 * ht1 * SA2 + c3 * ht2 * SA3);
993  const float_v j14 = ctdz2 * (SB1 + c2 * ht1 * SB2 + c3 * ht2 * SB3);
994  const float_v j24 = ctdz * (sA1 + c2 * ht1 * sA2 + c3 * ht2 * sA3);
995  const float_v j34 = ctdz * (sB1 + c2 * ht1 * sB2 + c3 * ht2 * sB3);
996 
997  // extrapolate inverse momentum
998  fX(mask) += j04 * dqp;
999  fY(mask) += j14 * dqp;
1000  fTx(mask) += j24 * dqp;
1001  fTy(mask) += j34 * dqp;
1002 
1003  // std::cout <<"Extrapolate 2 " <<std::endl;
1004  // std::cout << "fX " << fX << " fY " << fY << " fZ " << fZ << std::endl;
1005  // std::cout << "fTx " << fTx << " fTy " << fTy << " Qp " << fQP << std::endl;
1006  // covariance matrix transport
1007 
1008  const float_v c42 = fC42, c43 = fC43;
1009 
1010  const float_v cj00 = fC00 + fC20 * j02 + fC30 * j03 + fC40 * j04;
1011  // const float_v cj10 = fC10 + fC21*j02 + fC31*j03 + fC41*j04;
1012  const float_v cj20 = fC20 + fC22 * j02 + fC32 * j03 + c42 * j04;
1013  const float_v cj30 = fC30 + fC32 * j02 + fC33 * j03 + c43 * j04;
1014 
1015  const float_v cj01 = fC10 + fC20 * j12 + fC30 * j13 + fC40 * j14;
1016  const float_v cj11 = fC11 + fC21 * j12 + fC31 * j13 + fC41 * j14;
1017  const float_v cj21 = fC21 + fC22 * j12 + fC32 * j13 + c42 * j14;
1018  const float_v cj31 = fC31 + fC32 * j12 + fC33 * j13 + c43 * j14;
1019 
1020  // const float_v cj02 = fC20*j22 + fC30*j23 + fC40*j24;
1021  // const float_v cj12 = fC21*j22 + fC31*j23 + fC41*j24;
1022  const float_v cj22 = fC22 * j22 + fC32 * j23 + c42 * j24;
1023  const float_v cj32 = fC32 * j22 + fC33 * j23 + c43 * j24;
1024 
1025  // const float_v cj03 = fC20*j32 + fC30*j33 + fC40*j34;
1026  // const float_v cj13 = fC21*j32 + fC31*j33 + fC41*j34;
1027  const float_v cj23 = fC22 * j32 + fC32 * j33 + c42 * j34;
1028  const float_v cj33 = fC32 * j32 + fC33 * j33 + c43 * j34;
1029 
1030  fC40(mask) += (c42 * j02 + c43 * j03 + fC44 * j04); // cj40
1031  fC41(mask) += (c42 * j12 + c43 * j13 + fC44 * j14); // cj41
1032  fC42(mask) = (c42 * j22 + c43 * j23 + fC44 * j24); // cj42
1033  fC43(mask) = (c42 * j32 + c43 * j33 + fC44 * j34); // cj43
1034 
1035  fC00(mask) = (cj00 + j02 * cj20 + j03 * cj30 + j04 * fC40);
1036  fC10(mask) = (cj01 + j02 * cj21 + j03 * cj31 + j04 * fC41);
1037  fC11(mask) = (cj11 + j12 * cj21 + j13 * cj31 + j14 * fC41);
1038 
1039  // cout<<"transport \n";
1040  // cout<<" C00 " << fC00 << " C10 " << fC10 << " C11 " << fC11 << endl;
1041  fC20(mask) = (j22 * cj20 + j23 * cj30 + j24 * fC40);
1042  fC30(mask) = (j32 * cj20 + j33 * cj30 + j34 * fC40);
1043  fC21(mask) = (j22 * cj21 + j23 * cj31 + j24 * fC41);
1044  fC31(mask) = (j32 * cj21 + j33 * cj31 + j34 * fC41);
1045  fC22(mask) = (j22 * cj22 + j23 * cj32 + j24 * fC42);
1046  fC32(mask) = (j32 * cj22 + j33 * cj32 + j34 * fC42);
1047  fC33(mask) = (j32 * cj23 + j33 * cj33 + j34 * fC43);
1048 
1049  return mask;
1050 }
1051 
1052 inline float_m PndFTSCATrackParamVector::PassMaterial(const L1MaterialInfo &info, const float_v &qp0, const float_m &mask)
1053 {
1054  const float_v mass2 = 0.1395679f * 0.1395679f;
1055 
1056  float_v txtx = fTx * fTx;
1057  float_v tyty = fTy * fTy;
1058  float_v txtx1 = txtx + 1.f;
1059  float_v h = txtx + tyty;
1060  float_v t = sqrt(txtx1 + tyty);
1061  float_v h2 = h * h;
1062  float_v qp0t = qp0 * t;
1063 
1064  const float_v c1 = 0.0136f, c2 = c1 * 0.038f, c3 = c2 * 0.5f, c4 = -c3 / 2.0f, c5 = c3 / 3.0f, c6 = -c3 / 4.0f;
1065 
1066  float_v s0 = (c1 + c2 * info.logRadThick + c3 * h + h2 * (c4 + c5 * h + c6 * h2)) * qp0t;
1067  float_v a = ((t + mass2 * qp0 * qp0t) * info.RadThick * s0 * s0);
1068  // std::cout<<"info.RadThick info.logRadThick "<<info.RadThick<<" "<<info.logRadThick<<std::endl;
1069  // std::cout <<" a " << a << std::endl;
1070  // a=0.000005;
1071  fC22(mask) += txtx1 * a;
1072  fC32(mask) += fTx * fTy * a;
1073  fC33(mask) += (1.f + tyty) * a;
1074 
1075  return mask;
1076 }
1077 
1078 inline float_v PndFTSCATrackParamVector::ApproximateBetheBloch(const float_v &bg2)
1079 {
1080  //
1081  // This is the parameterization of the Bethe-Bloch formula inspired by Geant.
1082  //
1083  // bg2 - (beta*gamma)^2
1084  // kp0 - density [g/cm^3]
1085  // kp1 - density effect first junction point
1086  // kp2 - density effect second junction point
1087  // kp3 - mean excitation energy [GeV]
1088  // kp4 - mean Z/A
1089  //
1090  // The default values for the kp* parameters are for silicon.
1091  // The returned value is in [GeV/(g/cm^2)].
1092  //
1093 
1094  const float_v &kp0 = 2.33f;
1095  const float_v &kp1 = 0.20f;
1096  const float_v &kp2 = 3.00f;
1097  const float_v &kp3 = 173e-9f;
1098  const float_v &kp4 = 0.49848f;
1099 
1100  const float mK = 0.307075e-3f; // [GeV*cm^2/g]
1101  const float _2me = 1.022e-3f; // [GeV/c^2]
1102  const float_v &rho = kp0;
1103  const float_v &x0 = kp1 * 2.303f;
1104  const float_v &x1 = kp2 * 2.303f;
1105  const float_v &mI = kp3;
1106  const float_v &mZA = kp4;
1107  const float_v &maxT = _2me * bg2; // neglecting the electron mass
1108 
1109  //*** Density effect
1110  float_v d2(Vc::Zero);
1111  const float_v x = 0.5f * log(bg2);
1112  const float_v lhwI = log(28.816f * 1e-9f * sqrt(rho * mZA) / mI);
1113 
1114  float_m init = x > x1;
1115 
1116  d2(init) = lhwI + x - 0.5f;
1117  const float_v &r = (x1 - x) / (x1 - x0);
1118  init = (x > x0) & (x1 > x);
1119  d2(init) = (lhwI + x - 0.5f + (0.5f - lhwI - x0) * r * r * r);
1120 
1121  return mK * mZA * (1.f + bg2) / bg2 * (0.5f * log(_2me * bg2 * maxT / (mI * mI)) - bg2 / (1.f + bg2) - d2);
1122 }
1123 
1124 inline void PndFTSCATrackParamVector::EnergyLossCorrection(const float_v &mass2, const float_v &radThick, float_v &qp0, float_v direction, const float_m &mask)
1125 {
1126  const float_v &p2 = 1.f / (qp0 * qp0);
1127  const float_v &E2 = mass2 + p2;
1128 
1129  const float_v &bethe = ApproximateBetheBloch(p2 / mass2);
1130 
1131  float_v tr = sqrt(1.f + fTx * fTx + fTy * fTy);
1132 
1133  const float_v &dE = bethe * radThick * tr * 2.33f * 9.34961f;
1134 
1135  const float_v &E2Corrected = (sqrt(E2) + direction * dE) * (sqrt(E2) + direction * dE);
1136  float_v corr = sqrt(p2 / (E2Corrected - mass2));
1137  // cout<<"corr "<<corr<<endl;
1138  float_m init = !(corr == corr) || !(mask);
1139  corr(init) = 1.f;
1140  qp0(mask) *= corr;
1141  fQP(mask) *= corr;
1142  fC40(mask) *= corr;
1143  fC41(mask) *= corr;
1144  fC42(mask) *= corr;
1145  fC43(mask) *= corr;
1146  fC44(mask) *= corr * corr;
1147 }
1148 
1149 inline float_m
1150 PndFTSCATrackParamVector::FilterVtx(const float_v &xV, const float_v &yV, const L1XYMeasurementInfo &info, float_v &extrDx, float_v &extrDy, float_v J[], const float_m &active)
1151 {
1152  float_v zeta0, zeta1, S00, S10, S11, si;
1153  float_v F00, F10, F20, F30, F40, F01, F11, F21, F31, F41;
1154  float_v K00, K10, K20, K30, K40, K01, K11, K21, K31, K41;
1155 
1156  zeta0 = fX + extrDx - xV;
1157  zeta1 = fY + extrDy - yV;
1158 
1159  // H = 1 0 J[0] J[1] J[2]
1160  // 0 1 J[3] J[4] J[5]
1161 
1162  // F = CH'
1163  F00 = fC00;
1164  F01 = fC10;
1165  F10 = fC10;
1166  F11 = fC11;
1167  F20 = J[0] * fC22;
1168  F21 = J[3] * fC22;
1169  F30 = J[1] * fC33;
1170  F31 = J[4] * fC33;
1171  F40 = J[2] * fC44;
1172  F41 = J[5] * fC44;
1173 
1174  S00 = info.C00 + F00 + J[0] * F20 + J[1] * F30 + J[2] * F40;
1175  S10 = info.C10 + F10 + J[3] * F20 + J[4] * F30 + J[5] * F40;
1176  S11 = info.C11 + F11 + J[3] * F21 + J[4] * F31 + J[5] * F41;
1177 
1178  si = 1.f / (S00 * S11 - S10 * S10);
1179  float_v S00tmp = S00;
1180  S00 = si * S11;
1181  S10 = -si * S10;
1182  S11 = si * S00tmp;
1183 
1184  fChi2(active) += zeta0 * zeta0 * S00 + 2.f * zeta0 * zeta1 * S10 + zeta1 * zeta1 * S11;
1185 
1186  K00 = F00 * S00 + F01 * S10;
1187  K01 = F00 * S10 + F01 * S11;
1188  K10 = F10 * S00 + F11 * S10;
1189  K11 = F10 * S10 + F11 * S11;
1190  K20 = F20 * S00 + F21 * S10;
1191  K21 = F20 * S10 + F21 * S11;
1192  K30 = F30 * S00 + F31 * S10;
1193  K31 = F30 * S10 + F31 * S11;
1194  K40 = F40 * S00 + F41 * S10;
1195  K41 = F40 * S10 + F41 * S11;
1196 
1197  fX(active) -= K00 * zeta0 + K01 * zeta1;
1198  fY(active) -= K10 * zeta0 + K11 * zeta1;
1199  fTx(active) -= K20 * zeta0 + K21 * zeta1;
1200  fTy(active) -= K30 * zeta0 + K31 * zeta1;
1201  fQP(active) -= K40 * zeta0 + K41 * zeta1;
1202 
1203  fC00(active) -= (K00 * F00 + K01 * F01);
1204  fC10(active) -= (K10 * F00 + K11 * F01);
1205  fC11(active) -= (K10 * F10 + K11 * F11);
1206  fC20(active) = -(K20 * F00 + K21 * F01);
1207  fC21(active) = -(K20 * F10 + K21 * F11);
1208  fC22(active) -= (K20 * F20 + K21 * F21);
1209  fC30(active) = -(K30 * F00 + K31 * F01);
1210  fC31(active) = -(K30 * F10 + K31 * F11);
1211  fC32(active) = -(K30 * F20 + K31 * F21);
1212  fC33(active) -= (K30 * F30 + K31 * F31);
1213  fC40(active) = -(K40 * F00 + K41 * F01);
1214  fC41(active) = -(K40 * F10 + K41 * F11);
1215  fC42(active) = -(K40 * F20 + K41 * F21);
1216  fC43(active) = -(K40 * F30 + K41 * F31);
1217  fC44(active) -= (K40 * F40 + K41 * F41);
1218 
1219  return active;
1220 }
1221 
1222 inline float_m
1223 PndFTSCATrackParamVector::TransportJXY0ToX0(const float_v &x0, const L1FieldRegion &F, float_v &extrDx, float_v &extrDy, float_v &J04, float_v &J14, const float_m &active)
1224 {
1225  const float_v c_light = 0.000299792458f, c1 = 1.f, c2i = 0.5f, c6i = 1.f / 6.f, c12i = 1.f / 12.f;
1226 
1227  const float_v dz = x0 - fZ;
1228  float_v dz2 = dz * dz;
1229  float_v dzc6i = dz * c6i;
1230  float_v dz2c12i = dz2 * c12i;
1231 
1232  float_v xx = fTx * fTx;
1233  float_v yy = fTy * fTy;
1234  float_v xy = fTx * fTy;
1235 
1236  float_v Ay = -xx - c1;
1237  float_v bx = yy + c1;
1238 
1239  float_v ctdz2 = c_light * sqrt(c1 + xx + yy) * dz2;
1240 
1241  float_v Sx = F.cx0 * c2i + F.cx1 * dzc6i + F.cx2 * dz2c12i;
1242  float_v Sy = F.cy0 * c2i + F.cy1 * dzc6i + F.cy2 * dz2c12i;
1243  float_v Sz = F.cz0 * c2i + F.cz1 * dzc6i + F.cz2 * dz2c12i;
1244 
1245  extrDx(active) = (fTx)*dz;
1246  extrDy(active) = (fTy)*dz;
1247  J04(active) = ctdz2 * (Sx * xy + Sy * Ay + Sz * fTy);
1248  J14(active) = ctdz2 * (Sx * bx - Sy * xy - Sz * fTx);
1249 
1250  return active;
1251 }
1252 
1253 #else // PANDA_FTS
1254 
1255 #include "PndFTSCADef.h"
1256 #include "PndFTSVector.h"
1257 #include "PndFTSCAMath.h"
1258 #include "CAX1X2MeasurementInfo.h"
1259 #include "FTSCAStation.h"
1260 
1262 class PndFTSCAParam;
1263 class FTSCAHit;
1264 class FTSCAHitV;
1265 class FTSCATarget;
1266 
1267 namespace std {
1268 template <typename T>
1270 template <typename _CharT, typename _Traits>
1271 class basic_istream;
1272 typedef basic_istream<char, char_traits<char>> istream;
1273 template <typename _CharT, typename _Traits>
1274 class basic_ostream;
1275 typedef basic_ostream<char, char_traits<char>> ostream;
1276 } // namespace std
1277 
1286  friend std::istream &operator>>(std::istream &, PndFTSCATrackParamVector &);
1287  friend std::ostream &operator<<(std::ostream &, const PndFTSCATrackParamVector &);
1288 
1289  public:
1290  PndFTSCATrackParamVector() : fX(Vc::Zero), fSignCosPhi(Vc::Zero), fChi2(Vc::Zero), fNDF(Vc::Zero)
1291  {
1292  for (int i = 0; i < 5; ++i)
1293  fP[i].setZero();
1294  for (int i = 0; i < 15; ++i)
1295  fC[i].setZero();
1296  }
1297 
1298  void ConvertTrackParamToVector(PndFTSCATrackParam t0[float_v::Size], int nTracksV);
1299 
1300  void InitCovMatrix(float_v d2QMom = 0.f);
1301  void InitByTarget(const FTSCATarget &target);
1302  void InitByHit(const FTSCAHitV &hit, const PndFTSCAParam &param, const float_v &dQMom);
1303 
1304  void InitDirection(float_v r0, float_v r1, float_v r2) // initialize direction parameters according to a given tangent vector
1305  {
1306  const float_v r = sqrt(r0 * r0 + r1 * r1);
1307  SetSinPhi(r1 / r);
1308  SetSignCosPhi(r0 / abs(r0));
1309  SetDzDs(r2 / r);
1310  }
1311 
1313  float_v fBethe;
1314  float_v fE;
1315  float_v fTheta2;
1316  float_v fEP2;
1317  float_v fSigmadE2;
1318  float_v fK22;
1319  float_v fK33;
1320  float_v fK43;
1321  float_v fK44;
1322  };
1323 
1324  float_v X() const { return fX; }
1325  float_v Y() const { return fP[0]; }
1326  float_v Z() const { return fP[1]; }
1327  float_v SinPhi() const { return fP[2]; }
1328  float_v DzDs() const { return fP[3]; }
1329  float_v QPt() const { return fP[4]; }
1330 
1331  float_v Angle() const { return fAlpha; }
1332 
1333  float_v X0() const { return X(); }
1334  float_v X1() const { return Y(); }
1335  float_v X2() const { return Z(); }
1336  float_v Tx1() const { return SinPhi() / (SignCosPhi() * sqrt(1 - SinPhi() * SinPhi())); } // CHECKME
1337  float_v Tx2() const { return DzDs() / (SignCosPhi() * sqrt(1 - SinPhi() * SinPhi())); } // dx2/dx0 = dz/dx
1338  float_v QMomentum() const { return QPt(); } // used for triplets comparison
1339 
1344  float_v SignCosPhi() const { return fSignCosPhi; }
1345  float_v Chi2() const { return fChi2; }
1346  int_v NDF() const { return fNDF; }
1347 
1348  float_v Err2Y() const { return fC[0]; }
1349  float_v Err2Z() const { return fC[2]; }
1350  float_v Err2SinPhi() const { return fC[5]; }
1351  float_v Err2DzDs() const { return fC[9]; }
1352  float_v Err2QPt() const { return fC[14]; }
1353 
1354  float_v GetX() const { return fX; }
1355  float_v GetY() const { return fP[0]; }
1356  float_v GetZ() const { return fP[1]; }
1357  float_v GetSinPhi() const { return fP[2]; }
1358  float_v GetDzDs() const { return fP[3]; }
1359  float_v GetQPt() const { return fP[4]; }
1360  float_v GetSignCosPhi() const { return fSignCosPhi; }
1361  float_v GetChi2() const { return fChi2; }
1362  int_v GetNDF() const { return fNDF; }
1363 
1364  float_v GetKappa(const float_v &Bz) const { return fP[4] * Bz; }
1365  float_v GetCosPhiPositive() const { return CAMath::Sqrt(float_v(Vc::One) - SinPhi() * SinPhi()); }
1366  float_v GetCosPhi() const { return fSignCosPhi * CAMath::Sqrt(float_v(Vc::One) - SinPhi() * SinPhi()); }
1367 
1368  float_v Err2X1() const { return fC[0]; }
1369  float_v Err2X2() const { return fC[2]; }
1370  // float_v GetErr2SinPhi() const { return fC[5]; }
1371  // float_v GetErr2DzDs() const { return fC[9]; }
1372  float_v Err2QMomentum() const { return fC[14]; }
1373 
1374  const float_v &Par(int i) const { return fP[i]; }
1375  const float_v &Cov(int i) const { return fC[i]; }
1376 
1377  private:
1378  friend class PndFTSCATrackParam;
1379  const float_v *Par() const { return fP; }
1380  const float_v *Cov() const { return fC; }
1381  float_v *Par() { return fP; }
1382  float_v *Cov() { return fC; }
1383 
1384  public:
1385  void SetTrackParam(const PndFTSCATrackParamVector &param, const float_m &m = float_m(true))
1386  {
1387  for (int i = 0; i < 5; i++)
1388  fP[i](m) = param.Par()[i];
1389  for (int i = 0; i < 15; i++)
1390  fC[i](m) = param.Cov()[i];
1391  fX(m) = param.X();
1392  fSignCosPhi(m) = param.SignCosPhi();
1393  fChi2(m) = param.GetChi2();
1394  fNDF(static_cast<int_m>(m)) = param.GetNDF();
1395  fAlpha(static_cast<int_m>(m)) = param.Angle();
1396  }
1397 
1398  void SetTrackParamOne(int iV, const PndFTSCATrackParamVector &param, int iVa)
1399  {
1400  for (int i = 0; i < 5; i++)
1401  fP[i][iV] = param.Par()[i][iVa];
1402  for (int i = 0; i < 15; i++)
1403  fC[i][iV] = param.Cov()[i][iVa];
1404  fX[iV] = param.X()[iVa];
1405  fSignCosPhi[iV] = param.SignCosPhi()[iVa];
1406  fChi2[iV] = param.GetChi2()[iVa];
1407  fNDF[iV] = param.GetNDF()[iVa];
1408  fAlpha[iV] = param.Angle()[iVa];
1409  }
1410 
1411  void SetPar(int i, const float_v &v) { fP[i] = v; }
1412  void SetPar(int i, const float_v &v, const float_m &m) { fP[i](m) = v; }
1413  void SetCov(int i, const float_v &v) { fC[i] = v; }
1414  void SetCov(int i, const float_v &v, const float_m &m) { fC[i](m) = v; }
1415 
1416  void SetX(const float_v &v) { fX = v; }
1417  void SetY(const float_v &v) { fP[0] = v; }
1418  void SetZ(const float_v &v) { fP[1] = v; }
1419  void SetX(const float_v &v, const float_m &m) { fX(m) = v; }
1420  void SetY(const float_v &v, const float_m &m) { fP[0](m) = v; }
1421  void SetZ(const float_v &v, const float_m &m) { fP[1](m) = v; }
1422  void SetSinPhi(const float_v &v) { fP[2] = v; }
1423  void SetSinPhi(const float_v &v, const float_m &m) { fP[2](m) = v; }
1424  void SetDzDs(const float_v &v) { fP[3] = v; }
1425  void SetDzDs(const float_v &v, const float_m &m) { fP[3](m) = v; }
1426  void SetQPt(const float_v &v) { fP[4] = v; }
1427  void SetQMomentum(const float_v &v) { SetQPt(v); }
1428  void SetQPt(const float_v &v, const float_m &m) { fP[4](m) = v; }
1429  void SetSignCosPhi(const float_v &v) { fSignCosPhi = v; }
1430  void SetSignCosPhi(const float_v &v, const float_m &m) { fSignCosPhi(m) = v; }
1431  void SetChi2(const float_v &v) { fChi2 = v; }
1432  void SetChi2(const float_v &v, const float_m &m) { fChi2(m) = v; }
1433  void SetNDF(int v) { fNDF = v; }
1434  void SetNDF(const int_v &v) { fNDF = v; }
1435  void SetNDF(const int_v &v, const int_m &m) { fNDF(m) = v; }
1436 
1437  void SetAngle(const float_v &v) { fAlpha = v; }
1438  void SetAngle(const float_v &v, const float_m &m) { fAlpha(m) = v; }
1439 
1440  void SetErr2Y(float_v v) { fC[0] = v; }
1441  void SetErr2Z(float_v v) { fC[2] = v; }
1442  void SetErr2QPt(float_v v) { fC[14] = v; }
1443 
1444  float_v GetDist2(const PndFTSCATrackParamVector &t) const;
1445  float_v GetDistXZ2(const PndFTSCATrackParamVector &t) const;
1446 
1447  float_v GetS(const float_v &x, const float_v &y, const float_v &Bz) const;
1448 
1449  void GetDCAPoint(const float_v &x, const float_v &y, const float_v &z, float_v *px, float_v *py, float_v *pz, const float_v &Bz) const;
1450 
1451  float_m TransportToX0WithMaterial(const float_v &x, const float_v &XOverX0, const float_v &XThimesRho, const float_v &Bz, const float maxSinPhi = .999f);
1452 
1453  float_m TransportToX0(const float_v &x, const float_v &Bz, const float maxSinPhi = .999f, const float_m &mask = float_m(true));
1454 
1455  float_m
1456  TransportToX0(const float_v &x, PndFTSCATrackLinearisationVector &t0, const float_v &Bz, const float maxSinPhi = .999f, float_v *DL = 0, const float_m &mask = float_m(true));
1457 
1458  float_m TransportToX0(const float_v &x, const float_v &sinPhi0, const float_v &Bz, const float_v maxSinPhi = .999f, const float_m &mask = float_m(true));
1459 
1460  float_m TransportToX0WithMaterial(const float_v &x, PndFTSCATrackLinearisationVector &t0, PndFTSCATrackFitParam &par, const float_v &XOverX0, const float_v &XThimesRho,
1461  const float_v &Bz, const float maxSinPhi = .999f, const float_m &mask = float_m(true));
1462 
1463  float_m
1464  TransportToX0WithMaterial(const float_v &x, PndFTSCATrackFitParam &par, const float_v &XOverX0, const float_v &XThimesRho, const float_v &Bz, const float maxSinPhi = .999f);
1465 
1466  float_m Rotate(const float_v &alpha, PndFTSCATrackLinearisationVector &t0, const float maxSinPhi = .999f, const float_m &mask = float_m(true));
1467  float_m Rotate(const float_v &alpha, const float maxSinPhi = .999f, const float_m &mask = float_m(true));
1468  void RotateXY(float_v alpha, float_v &x, float_v &y, float_v &sin, const float_m &mask = float_m(true)) const;
1469 
1470  float_m FilterWithMaterial(const float_v &y, const float_v &z, float_v err2Y, float_v errYZ, float_v err2Z, float maxSinPhi = 0.999f, const float_m &mask = float_m(true),
1471  const int_v &hitNDF = int_v(2), const float_v &chi2Cut = 10e10f); // filters 2-D measurement
1472 
1473  float_m FilterWithMaterial(const float_v &y, const float_v &z, const FTSCAStripInfo &info, float_v err2, float maxSinPhi = 0.999f, const float_m &mask = float_m(true),
1474  const float_v &chi2Cut = 10e10f); // filters 1-D measurement
1475  float_m FilterWithMaterial(const float_v &y, const float_v &z, const float_v &r, const FTSCAStripInfo &info, float_v err2, float maxSinPhi = 0.999f,
1476  const float_m &mask = float_m(true), const float_v &chi2Cut = 10e10f); // filters tube measurement
1477 
1478  static float_v ApproximateBetheBloch(const float_v &beta2);
1479  static float_v BetheBlochGeant(const float_v &bg, const float_v &kp0 = 2.33f, const float_v &kp1 = 0.20f, const float_v &kp2 = 3.00f, const float_v &kp3 = 173e-9f,
1480  const float_v &kp4 = 0.49848f);
1481  static float_v BetheBlochSolid(const float_v &bg);
1482  static float_v BetheBlochGas(const float_v &bg);
1483 
1484  void CalculateFitParameters(PndFTSCATrackFitParam &par, const float_v &mass = 0.13957f);
1485  float_m CorrectForMeanMaterial(const float_v &xOverX0, const float_v &xTimesRho, const PndFTSCATrackFitParam &par, const float_m &_mask);
1486 
1487  // float_m FilterDelta( const float_m &mask, const float_v &dy, const float_v &dz,
1488  // float_v err2Y, float_v err2Z, const float maxSinPhi = .999f );
1489  // float_m Filter( const float_m &mask, const float_v &y, const float_v &z,
1490  // float_v err2Y, float_v err2Z, const float maxSinPhi = .999f );
1491 
1492  float_m FilterVtx(const float_v &xV, const float_v &yV, const CAX1X2MeasurementInfo &info, float_v &extrDx, float_v &extrDy, float_v J[], const float_m &active = float_m(true));
1493  float_m TransportJ0ToX0(const float_v &x0, const float_v &cBz, float_v &extrDy, float_v &extrDz, float_v J[], const float_m &active = float_m(true));
1494 
1495  float_m Transport(const int_v &ista, const PndFTSCAParam &param, const float_m &mask = float_m(true));
1496  float_m Transport(const FTSCAHitV &hit, const PndFTSCAParam &p, const float_m &mask = float_m(true));
1497  float_m Filter(const FTSCAHitV &hit, const PndFTSCAParam &param, const float_m &mask = float_m(true), const float_v &chi2Cut = 10e10f);
1498 
1499  float_m Transport(const FTSCAHit &hit, const PndFTSCAParam &p, const float_m &mask = float_m(true));
1500  float_m Filter(const FTSCAHit &hit, const PndFTSCAParam &param, const float_m &mask = float_m(true), const float_v &chi2Cut = 10e10f);
1501 
1502  float_m AddTarget(const FTSCATarget &target, const float_m &mask = float_m(true));
1503 
1504  private:
1505  float_v fX; // x position
1506  float_v fSignCosPhi; // sign of cosPhi
1507  float_v fP[5]; // 'active' track parameters: Y, Z, SinPhi = dy/sqrt(dx*dx + dy*dy), DzDs = dz/sqrt(dx*dx + dy*dy), q/Pt // if q/pt = 0 then track equation is [dr x e] = 0, where
1508  // e = { sqrt( ( 1 - SinPhi^2 )/( 1 + DzDs^2 ) ), sqrt( SinPhi^2/( 1 + DzDs^2 ) ), sqrt( 1 /( 1 + DzDs^2 ) ) }
1509  float_v fC[15]; // the covariance matrix for Y,Z,SinPhi,..
1510  float_v fChi2; // the chi^2 value
1511  int_v fNDF; // the Number of Degrees of Freedom
1512 
1513  float_v fAlpha; // coor system
1514 };
1515 
1516 #include "debug.h"
1517 
1518 inline float_m PndFTSCATrackParamVector::TransportToX0(const float_v &x, const float_v &sinPhi0, const float_v &Bz, const float_v maxSinPhi, const float_m &_mask)
1519 {
1520  //* Transport the track parameters to X=x, using linearization at phi0 with 0 curvature,
1521  //* and the field value Bz
1522  //* maxSinPhi is the max. allowed value for |t0.SinPhi()|
1523  //* linearisation of trajectory t0 is also transported to X=x,
1524  //* returns 1 if OK
1525  //*
1526 
1527  debugKF() << "Start TransportToX0(" << x << ", " << _mask << ")\n" << *this << std::endl;
1528 
1529  const float_v &ey = sinPhi0;
1530  const float_v &dx = x - X();
1531  const float_v &exi = float_v(Vc::One) * CAMath::RSqrt(float_v(Vc::One) - ey * ey); // RSqrt
1532 
1533  const float_v &dxBz = dx * Bz;
1534  const float_v &dS = dx * exi;
1535  const float_v &h2 = dS * exi * exi;
1536  const float_v &h4 = .5f * h2 * dxBz;
1537 //#define LOSE_DEBUG
1538 #ifdef LOSE_DEBUG
1539  std::cout << " TrTo-sinPhi0 = " << sinPhi0 << std::endl;
1540 #endif
1541  // const float_v &sinPhi = SinPhi() * (float_v( Vc::One ) - 0.5f * dxBz * QPt() *dxBz * QPt()/ ( float_v( Vc::One ) - SinPhi()*SinPhi() )) + dxBz * QPt();
1543  const float_v &sinPhi = SinPhi() + dxBz * QPt();
1545 #ifdef LOSE_DEBUG
1546  std::cout << " TrTo-sinPhi = " << sinPhi << std::endl;
1547 #endif
1548  float_m mask = _mask && CAMath::Abs(exi) <= 1.e4f;
1549  mask &= ((CAMath::Abs(sinPhi) <= maxSinPhi) || (maxSinPhi <= 0.f));
1550 
1551  fX(mask) += dx;
1552  fP[0](mask) += dS * ey + h2 * (SinPhi() - ey) + h4 * QPt();
1553  fP[1](mask) += dS * DzDs();
1554  fP[2](mask) = sinPhi;
1555 
1556  // const float_v c00 = fC[0];
1557  // const float_v c11 = fC[2];
1558  const float_v c20 = fC[3];
1559  // const float_v c21 = fC[4];
1560  const float_v c22 = fC[5];
1561  // const float_v c30 = fC[6];
1562  const float_v c31 = fC[7];
1563  // const float_v c32 = fC[8];
1564  const float_v c33 = fC[9];
1565  const float_v c40 = fC[10];
1566  // const float_v c41 = fC[11];
1567  const float_v c42 = fC[12];
1568  // const float_v c43 = fC[13];
1569  const float_v c44 = fC[14];
1570 
1571  const float_v two(2.f);
1572 
1573  fC[0](mask) += h2 * h2 * c22 + h4 * h4 * c44 + two * (h2 * c20 + h4 * (c40 + h2 * c42));
1574 
1575  // fC[1] ( mask ) += h2 * c21 + h4 * c41 + dS * ( c30 + h2 * c32 + h4 * c43 );
1576  fC[2](mask) += dS * (two * c31 + dS * c33);
1577 
1578  fC[3](mask) += h2 * c22 + h4 * c42 + dxBz * (c40 + h2 * c42 + h4 * c44);
1579  // fC[4] ( mask ) += dS * c32 + dxBz * ( c41 + dS * c43 );
1580  const float_v &dxBz_c44 = dxBz * c44;
1581  fC[12](mask) += dxBz_c44;
1582  fC[5](mask) += dxBz * (two * c42 + dxBz_c44);
1583 
1584  // fC[6] ( mask ) += h2 * c32 + h4 * c43;
1585  fC[7](mask) += dS * c33;
1586  // fC[8] ( mask ) += dxBz * c43;
1587  // fC[9] ( mask ) = c33;
1588 
1589  fC[10](mask) += h2 * c42 + h4 * c44;
1590  // fC[11]( mask ) += dS * c43;
1591  // fC[13]( mask ) = c43;
1592  // fC[14]( mask ) = c44;
1593 
1594  debugKF() << mask << "\n" << *this << std::endl;
1595  return mask;
1596 }
1597 
1598 #include <assert.h>
1599 
1600 #ifdef NVALGRIND
1601 #define VALGRIND_CHECK_VALUE_IS_DEFINED(mask)
1602 #define VALGRIND_CHECK_MASKED_VECTOR_IS_DEFINED(v, k)
1603 #define VALGRIND_CHECK_MEM_IS_DEFINED(v, k) ;
1604 #define VALGRIND_CHECK_MEM_IS_ADDRESSABLE(v, k) ;
1605 #else
1606 #include <valgrind/memcheck.h>
1607 #define VALGRIND_CHECK_MASKED_VECTOR_IS_DEFINED(v, k) \
1608  { \
1609  __typeof__(v + v) tmp(v); \
1610  tmp.setZero(!k); \
1611  VALGRIND_CHECK_VALUE_IS_DEFINED(tmp); \
1612  }
1613 #endif
1614 
1615 // inline float_m PndFTSCATrackParamVector::FilterDelta( const float_m &mask, const float_v &dy, const float_v &dz,
1616 // float_v err2Y, float_v err2Z, const float maxSinPhi )
1617 // {
1618 // debugKF() << "Kalman filter( " << mask
1619 // << "\n " << dy
1620 // << "\n " << dz
1621 // << "\n " << err2Y
1622 // << "\n " << err2Z
1623 // << "\n):" << std::endl;
1624 
1625 // assert( err2Y > 0.f || !mask );
1626 // assert( err2Z > 0.f || !mask );
1627 // VALGRIND_CHECK_VALUE_IS_DEFINED( mask );
1628 // VALGRIND_CHECK_MASKED_VECTOR_IS_DEFINED( dy, mask );
1629 // VALGRIND_CHECK_MASKED_VECTOR_IS_DEFINED( dz, mask );
1630 // VALGRIND_CHECK_MASKED_VECTOR_IS_DEFINED( err2Y, mask );
1631 // VALGRIND_CHECK_MASKED_VECTOR_IS_DEFINED( err2Z, mask );
1632 // #ifndef NVALGRIND
1633 // err2Y.setZero( !mask );
1634 // err2Z.setZero( !mask );
1635 // #endif
1636 // VALGRIND_CHECK_VALUE_IS_DEFINED( maxSinPhi );
1637 
1638 // //* Add the y,z measurement with the Kalman filter
1639 
1640 // const float_v c00 = fC[ 0];
1641 // const float_v c11 = fC[ 2];
1642 // const float_v c20 = fC[ 3];
1643 // const float_v c31 = fC[ 7];
1644 // const float_v c40 = fC[10];
1645 
1646 // VALGRIND_CHECK_VALUE_IS_DEFINED( c00 );
1647 // VALGRIND_CHECK_VALUE_IS_DEFINED( c11 );
1648 // VALGRIND_CHECK_VALUE_IS_DEFINED( c20 );
1649 // VALGRIND_CHECK_VALUE_IS_DEFINED( c40 );
1650 // VALGRIND_CHECK_VALUE_IS_DEFINED( c31 );
1651 
1652 // err2Y += c00;
1653 // err2Z += c11;
1654 // #ifndef NODEBUG
1655 // if ( !( err2Y > 0.f || !mask ).isFull() ) {
1656 // std::cerr << err2Y << mask << ( err2Y > 0.f || !mask ) << c00 << std::endl;
1657 // }
1658 // #endif
1659 // assert( err2Y > 0.f || !mask );
1660 // assert( err2Z > 0.f || !mask );
1661 
1662 // VALGRIND_CHECK_VALUE_IS_DEFINED( fP[0] );
1663 // VALGRIND_CHECK_VALUE_IS_DEFINED( fP[1] );
1664 // VALGRIND_CHECK_VALUE_IS_DEFINED( fP[2] );
1665 
1666 // const float_v &z0 = dy;
1667 // const float_v &z1 = dz;
1668 
1669 // const float_v &mS0 = float_v( Vc::One ) / err2Y;
1670 // const float_v &mS2 = float_v( Vc::One ) / err2Z;
1671 // //const float_v &mS0 = CAMath::Reciprocal( err2Y );
1672 // //const float_v &mS2 = CAMath::Reciprocal( err2Z );
1673 // debugKF() << "delta(mS0): " << CAMath::Abs( float_v( Vc::One ) / err2Y - mS0 ) << std::endl;
1674 // debugKF() << "delta(mS2): " << CAMath::Abs( float_v( Vc::One ) / err2Z - mS2 ) << std::endl;
1675 // assert( mS0 > 0.f || !mask );
1676 // assert( mS2 > 0.f || !mask );
1677 
1678 // // K = CHtS
1679 
1680 // const float_v &k00 = c00 * mS0;
1681 // const float_v &k20 = c20 * mS0;
1682 // const float_v &k40 = c40 * mS0;
1683 
1684 // const float_v &k11 = c11 * mS2;
1685 // const float_v &k31 = c31 * mS2;
1686 
1687 // debugKF() << "delta(k00): " << ( c00 / err2Y - k00 ) << std::endl;
1688 // debugKF() << "delta(k20): " << ( c20 / err2Y - k20 ) << std::endl;
1689 // debugKF() << "delta(k40): " << ( c40 / err2Y - k40 ) << std::endl;
1690 
1691 // debugKF() << "delta(k11): " << ( c11 / err2Z - k11 ) << std::endl;
1692 // debugKF() << "delta(k31): " << ( c31 / err2Z - k31 ) << std::endl;
1693 
1694 // const float_v &sinPhi = fP[2] + k20 * z0 ;
1695 // debugKF() << "delta(sinPhi): " << ( z0 * c20 / err2Y + fP[2] - sinPhi ) << std::endl;
1696 
1697 // assert( maxSinPhi > 0.f );
1698 // VALGRIND_CHECK_MASKED_VECTOR_IS_DEFINED( sinPhi, mask );
1699 // const float_m &success = mask && err2Y >= 1.e-8f && err2Z >= 1.e-8f && CAMath::Abs( sinPhi ) < maxSinPhi;
1700 // VALGRIND_CHECK_VALUE_IS_DEFINED( success );
1701 
1702 // fNDF ( static_cast<int_m>( success ) ) += 2;
1703 // fChi2 ( success ) += mS0 * z0 * z0 + mS2 * z1 * z1 ;
1704 
1705 // fP[ 0]( success ) += k00 * z0 ;
1706 // fP[ 1]( success ) += k11 * z1 ;
1707 // fP[ 2]( success ) = sinPhi ;
1708 // fP[ 3]( success ) += k31 * z1 ;
1709 // fP[ 4]( success ) += k40 * z0 ;
1710 
1711 // fC[ 0]( success ) -= k00 * c00 ;
1712 // fC[ 3]( success ) -= k20 * c00 ;
1713 // fC[ 5]( success ) -= k20 * c20 ;
1714 // fC[10]( success ) -= k40 * c00 ;
1715 // fC[12]( success ) -= k40 * c20 ;
1716 // fC[14]( success ) -= k40 * c40 ;
1717 
1718 // fC[ 2]( success ) -= k11 * c11 ;
1719 // fC[ 7]( success ) -= k31 * c11 ;
1720 // fC[ 9]( success ) -= k31 * c31 ;
1721 // #if 1
1722 // const float_m check = ( fC[ 0] >= 0.f ) && ( fC[ 2] >= 0.f ) && ( fC[ 5] >= 0.f ) && ( fC[ 9] >= 0.f ) && ( fC[14] >= 0.f );
1723 // #else
1724 // assert( fC[ 0] >= 0.f );
1725 // assert( fC[ 2] >= 0.f );
1726 // assert( fC[ 5] >= 0.f );
1727 // assert( fC[ 9] >= 0.f );
1728 // assert( fC[14] >= 0.f );
1729 // #endif
1730 // return success && check;
1731 // }
1732 
1733 // inline float_m PndFTSCATrackParamVector::Filter( const float_m &mask, const float_v &y, const float_v &z,
1734 // float_v err2Y, float_v err2Z, const float maxSinPhi )
1735 // {
1736 // debugKF() << "Kalman filter( " << mask
1737 // << "\n " << y
1738 // << "\n " << z
1739 // << "\n " << err2Y
1740 // << "\n " << err2Z
1741 // << "\n):" << std::endl;
1742 
1743 // assert( err2Y > 0.f || !mask );
1744 // assert( err2Z > 0.f || !mask );
1745 // VALGRIND_CHECK_VALUE_IS_DEFINED( mask );
1746 // VALGRIND_CHECK_MASKED_VECTOR_IS_DEFINED( y, mask );
1747 // VALGRIND_CHECK_MASKED_VECTOR_IS_DEFINED( z, mask );
1748 // VALGRIND_CHECK_MASKED_VECTOR_IS_DEFINED( err2Y, mask );
1749 // VALGRIND_CHECK_MASKED_VECTOR_IS_DEFINED( err2Z, mask );
1750 // #ifndef NVALGRIND
1751 // err2Y.setZero( !mask );
1752 // err2Z.setZero( !mask );
1753 // #endif
1754 // VALGRIND_CHECK_VALUE_IS_DEFINED( maxSinPhi );
1755 
1756 // //* Add the y,z measurement with the Kalman filter
1757 
1758 // const float_v c00 = fC[ 0];
1759 // const float_v c11 = fC[ 2];
1760 // const float_v c20 = fC[ 3];
1761 // const float_v c31 = fC[ 7];
1762 // const float_v c40 = fC[10];
1763 
1764 // VALGRIND_CHECK_VALUE_IS_DEFINED( c00 );
1765 // VALGRIND_CHECK_VALUE_IS_DEFINED( c11 );
1766 // VALGRIND_CHECK_VALUE_IS_DEFINED( c20 );
1767 // VALGRIND_CHECK_VALUE_IS_DEFINED( c40 );
1768 // VALGRIND_CHECK_VALUE_IS_DEFINED( c31 );
1769 
1770 // err2Y += c00;
1771 // err2Z += c11;
1772 // #ifndef NODEBUG
1773 // if ( !( err2Y > 0.f || !mask ).isFull() ) {
1774 // std::cerr << err2Y << mask << ( err2Y > 0.f || !mask ) << c00 << std::endl;
1775 // }
1776 // #endif
1777 // assert( err2Y > 0.f || !mask );
1778 // assert( err2Z > 0.f || !mask );
1779 
1780 // VALGRIND_CHECK_VALUE_IS_DEFINED( fP[0] );
1781 // VALGRIND_CHECK_VALUE_IS_DEFINED( fP[1] );
1782 // VALGRIND_CHECK_VALUE_IS_DEFINED( fP[2] );
1783 
1784 // const float_v &z0 = y - fP[0];
1785 // const float_v &z1 = z - fP[1];
1786 
1787 // const float_v &mS0 = float_v( Vc::One ) / err2Y;
1788 // const float_v &mS2 = float_v( Vc::One ) / err2Z;
1789 // //const float_v &mS0 = CAMath::Reciprocal( err2Y );
1790 // //const float_v &mS2 = CAMath::Reciprocal( err2Z );
1791 // debugKF() << "delta(mS0): " << CAMath::Abs( float_v( Vc::One ) / err2Y - mS0 ) << std::endl;
1792 // debugKF() << "delta(mS2): " << CAMath::Abs( float_v( Vc::One ) / err2Z - mS2 ) << std::endl;
1793 // assert( mS0 > 0.f || !mask );
1794 // assert( mS2 > 0.f || !mask );
1795 
1796 // // K = CHtS
1797 
1798 // const float_v &k00 = c00 * mS0;
1799 // const float_v &k20 = c20 * mS0;
1800 // const float_v &k40 = c40 * mS0;
1801 
1802 // const float_v &k11 = c11 * mS2;
1803 // const float_v &k31 = c31 * mS2;
1804 
1805 // debugKF() << "delta(k00): " << ( c00 / err2Y - k00 ) << std::endl;
1806 // debugKF() << "delta(k20): " << ( c20 / err2Y - k20 ) << std::endl;
1807 // debugKF() << "delta(k40): " << ( c40 / err2Y - k40 ) << std::endl;
1808 
1809 // debugKF() << "delta(k11): " << ( c11 / err2Z - k11 ) << std::endl;
1810 // debugKF() << "delta(k31): " << ( c31 / err2Z - k31 ) << std::endl;
1811 
1812 // const float_v &sinPhi = fP[2] + k20 * z0 ;
1813 // debugKF() << "delta(sinPhi): " << ( z0 * c20 / err2Y + fP[2] - sinPhi ) << std::endl;
1814 
1815 // assert( maxSinPhi > 0.f );
1816 // VALGRIND_CHECK_MASKED_VECTOR_IS_DEFINED( sinPhi, mask );
1817 // const float_m &success = mask && err2Y >= 1.e-8f && err2Z >= 1.e-8f && CAMath::Abs( sinPhi ) < maxSinPhi;
1818 // VALGRIND_CHECK_VALUE_IS_DEFINED( success );
1819 
1820 // fNDF ( static_cast<int_m>( success ) ) += 2;
1821 // fChi2 ( success ) += mS0 * z0 * z0 + mS2 * z1 * z1 ;
1822 
1823 // fP[ 0]( success ) += k00 * z0 ;
1824 // fP[ 1]( success ) += k11 * z1 ;
1825 // fP[ 2]( success ) = sinPhi ;
1826 // fP[ 3]( success ) += k31 * z1 ;
1827 // fP[ 4]( success ) += k40 * z0 ;
1828 
1829 // fC[ 0]( success ) -= k00 * c00 ;
1830 // fC[ 3]( success ) -= k20 * c00 ;
1831 // fC[ 5]( success ) -= k20 * c20 ;
1832 // fC[10]( success ) -= k40 * c00 ;
1833 // fC[12]( success ) -= k40 * c20 ;
1834 // fC[14]( success ) -= k40 * c40 ;
1835 
1836 // fC[ 2]( success ) -= k11 * c11 ;
1837 // fC[ 7]( success ) -= k31 * c11 ;
1838 // fC[ 9]( success ) -= k31 * c31 ;
1839 // #if 1
1840 // const float_m check = ( fC[ 0] >= 0.f ) && ( fC[ 2] >= 0.f ) && ( fC[ 5] >= 0.f ) && ( fC[ 9] >= 0.f ) && ( fC[14] >= 0.f );
1841 // #else
1842 // assert( fC[ 0] >= 0.f );
1843 // assert( fC[ 2] >= 0.f );
1844 // assert( fC[ 5] >= 0.f );
1845 // assert( fC[ 9] >= 0.f );
1846 // assert( fC[14] >= 0.f );
1847 // #endif
1848 // return success && check;
1849 // }
1850 
1851 inline float_m PndFTSCATrackParamVector::Rotate(const float_v &alpha, const float maxSinPhi, const float_m &mask)
1852 {
1853  //* Rotate the coordinate system in XY on the angle alpha
1854  if ((abs(alpha) < 1e-6f || !mask).isFull())
1855  return mask;
1856 
1857  const float_v cA = CAMath::Cos(alpha);
1858  const float_v sA = CAMath::Sin(alpha);
1859  const float_v x = X(), y = Y(), sP = SinPhi(), cP = GetCosPhi();
1860  const float_v cosPhi = cP * cA + sP * sA;
1861  const float_v sinPhi = -cP * sA + sP * cA;
1862 
1863  float_m mReturn = mask && (CAMath::Abs(sinPhi) < maxSinPhi) && (CAMath::Abs(cosPhi) > 1.e-2f) && (CAMath::Abs(cP) > 1.e-2f);
1864 
1865  mReturn &= abs(alpha) < 3.1415f * 0.25f; // allow turn by 45 degree only
1866 
1867  const float_v j0 = cP / cosPhi;
1868  const float_v j2 = cosPhi / cP;
1869 
1870  SetX(x * cA + y * sA, mReturn);
1871  SetY(-x * sA + y * cA, mReturn);
1872  SetSignCosPhi(CAMath::Abs(cosPhi) / cosPhi, mReturn);
1873  SetSinPhi(sinPhi, mReturn);
1874 
1875  // float J[5][5] = { { j0, 0, 0, 0, 0 }, // Y
1876  // { 0, 1, 0, 0, 0 }, // Z
1877  // { 0, 0, j2, 0, 0 }, // SinPhi
1878  // { 0, 0, 0, 1, 0 }, // DzDs
1879  // { 0, 0, 0, 0, 1 } }; // Kappa
1880  // cout<<"alpha="<<alpha<<" "<<x<<" "<<y<<" "<<sP<<" "<<cP<<" "<<j0<<" "<<j2<<endl;
1881  // cout<<" "<<fC[0]<<" "<<fC[1]<<" "<<fC[6]<<" "<<fC[10]<<" "<<fC[4]<<" "<<fC[5]<<" "<<fC[8]<<" "<<fC[12]<<endl;
1882  fC[0](mReturn) *= j0 * j0;
1883  fC[1](mReturn) *= j0;
1884  fC[3](mReturn) *= j0;
1885  fC[6](mReturn) *= j0;
1886  fC[10](mReturn) *= j0;
1887 
1888  fC[3](mReturn) *= j2;
1889  fC[4](mReturn) *= j2;
1890  fC[5](mReturn) *= j2 * j2;
1891  fC[8](mReturn) *= j2;
1892  fC[12](mReturn) *= j2;
1893 
1894  fAlpha(mReturn) += alpha;
1895  // cout<<" "<<fC[0]<<" "<<fC[1]<<" "<<fC[6]<<" "<<fC[10]<<" "<<fC[4]<<" "<<fC[5]<<" "<<fC[8]<<" "<<fC[12]<<endl;
1896  return mReturn;
1897 }
1898 
1899 inline void PndFTSCATrackParamVector::RotateXY(float_v alpha, float_v &x, float_v &y, float_v &sin, const float_m &mask) const
1900 {
1901  //* Rotate the coordinate system in XY on the angle alpha
1902  if ((abs(alpha) < 1e-6f || !mask).isFull())
1903  return;
1904 
1905  const float_v cA = CAMath::Cos(alpha);
1906  const float_v sA = CAMath::Sin(alpha);
1907 
1908  x(mask) = (X() * cA + Y() * sA);
1909  y(mask) = (-X() * sA + Y() * cA);
1910  sin(mask) = -GetCosPhi() * sA + SinPhi() * cA;
1911 }
1912 
1913 inline float_m
1914 PndFTSCATrackParamVector::FilterVtx(const float_v &yV, const float_v &zV, const CAX1X2MeasurementInfo &info, float_v &extrDy, float_v &extrDz, float_v J[], const float_m &active)
1915 {
1916  float_v zeta0, zeta1, S00, S10, S11, si;
1917  float_v F00, F10, F20, F30, F40, F01, F11, F21, F31, F41;
1918  float_v K00, K10, K20, K30, K40, K01, K11, K21, K31, K41;
1919  float_v &c00 = fC[0];
1920  float_v &c10 = fC[1];
1921  float_v &c11 = fC[2];
1922  float_v &c20 = fC[3];
1923  float_v &c21 = fC[4];
1924  float_v &c22 = fC[5];
1925  float_v &c30 = fC[6];
1926  float_v &c31 = fC[7];
1927  float_v &c32 = fC[8];
1928  float_v &c33 = fC[9];
1929  float_v &c40 = fC[10];
1930  float_v &c41 = fC[11];
1931  float_v &c42 = fC[12];
1932  float_v &c43 = fC[13];
1933  float_v &c44 = fC[14];
1934 
1935  zeta0 = Y() + extrDy - yV;
1936  zeta1 = Z() + extrDz - zV;
1937 
1938  // H = 1 0 J[0] J[1] J[2]
1939  // 0 1 J[3] J[4] J[5]
1940 
1941  // F = CH'
1942  F00 = c00;
1943  F01 = c10;
1944  F10 = c10;
1945  F11 = c11;
1946  F20 = J[0] * c22;
1947  F21 = J[3] * c22;
1948  F30 = J[1] * c33;
1949  F31 = J[4] * c33;
1950  F40 = J[2] * c44;
1951  F41 = J[5] * c44;
1952 
1953  S00 = info.C00() + F00 + J[0] * F20 + J[1] * F30 + J[2] * F40;
1954  S10 = info.C10() + F10 + J[3] * F20 + J[4] * F30 + J[5] * F40;
1955  S11 = info.C11() + F11 + J[3] * F21 + J[4] * F31 + J[5] * F41;
1956 
1957  si = 1.f / (S00 * S11 - S10 * S10);
1958  float_v S00tmp = S00;
1959  S00 = si * S11;
1960  S10 = -si * S10;
1961  S11 = si * S00tmp;
1962 
1963  fChi2(active) += zeta0 * zeta0 * S00 + 2.f * zeta0 * zeta1 * S10 + zeta1 * zeta1 * S11;
1964 
1965  K00 = F00 * S00 + F01 * S10;
1966  K01 = F00 * S10 + F01 * S11;
1967  K10 = F10 * S00 + F11 * S10;
1968  K11 = F10 * S10 + F11 * S11;
1969  K20 = F20 * S00 + F21 * S10;
1970  K21 = F20 * S10 + F21 * S11;
1971  K30 = F30 * S00 + F31 * S10;
1972  K31 = F30 * S10 + F31 * S11;
1973  K40 = F40 * S00 + F41 * S10;
1974  K41 = F40 * S10 + F41 * S11;
1975 
1976  fP[0](active) -= K00 * zeta0 + K01 * zeta1;
1977  fP[1](active) -= K10 * zeta0 + K11 * zeta1;
1978  fP[2](active) -= K20 * zeta0 + K21 * zeta1;
1979  fP[3](active) -= K30 * zeta0 + K31 * zeta1;
1980  fP[4](active) -= K40 * zeta0 + K41 * zeta1;
1981 
1982  c00(active) -= (K00 * F00 + K01 * F01);
1983  c10(active) -= (K10 * F00 + K11 * F01);
1984  c11(active) -= (K10 * F10 + K11 * F11);
1985  c20(active) = -(K20 * F00 + K21 * F01);
1986  c21(active) = -(K20 * F10 + K21 * F11);
1987  c22(active) -= (K20 * F20 + K21 * F21);
1988  c30(active) = -(K30 * F00 + K31 * F01);
1989  c31(active) = -(K30 * F10 + K31 * F11);
1990  c32(active) = -(K30 * F20 + K31 * F21);
1991  c33(active) -= (K30 * F30 + K31 * F31);
1992  c40(active) = -(K40 * F00 + K41 * F01);
1993  c41(active) = -(K40 * F10 + K41 * F11);
1994  c42(active) = -(K40 * F20 + K41 * F21);
1995  c43(active) = -(K40 * F30 + K41 * F31);
1996  c44(active) -= (K40 * F40 + K41 * F41);
1997 
1998  return active;
1999 }
2000 
2001 inline float_m PndFTSCATrackParamVector::TransportJ0ToX0(const float_v &x, const float_v &cBz, float_v &extrDy, float_v &extrDz, float_v J[], const float_m &active)
2002 {
2003  const float_v &ey = SinPhi();
2004  const float_v &dx = x - X();
2005  const float_v &exi = CAMath::RSqrt(float_v(Vc::One) - ey * ey); // RSqrt
2006 
2007  const float_v &dxBz = dx * cBz;
2008  const float_v &dS = dx * exi;
2009  const float_v &h2 = dS * exi * exi;
2010  const float_v &h4 = .5f * h2 * dxBz;
2011 
2012  float_m mask = active && CAMath::Abs(exi) <= 1.e4f;
2013 
2014  extrDy(active) = dS * ey;
2015  extrDz(active) = dS * DzDs();
2016  J[0](active) = dS;
2017  J[1](active) = 0;
2018  J[2](active) = h4;
2019  J[3](active) = dS;
2020  J[4](active) = dS;
2021  J[5](active) = 0;
2022  return active;
2023 }
2024 
2025 std::istream &operator>>(std::istream &in, PndFTSCATrackParamVector &ot);
2026 std::ostream &operator<<(std::ostream &out, const PndFTSCATrackParamVector &ot);
2027 
2028 #endif // !PANDA_FTS
2029 
2031 
2032 #endif
float_v cy1
Definition: L1Field.h:130
basic_istream< char, char_traits< char > > istream
void SetCov(int i, const float_v &v)
void RotateXY(float_v alpha, float_v &x, float_v &y, float_v &sin, const float_m &mask=float_m(true)) const
void SetAngle(const float_v &v, const float_m &m)
void InitByHit(const FTSCAHitV &hit, const PndFTSCAParam &param, const float_v &dQMom)
__m128 m
Definition: P4_F32vec4.h:38
float_m CorrectForMeanMaterial(const float_v &xOverX0, const float_v &xTimesRho, const PndFTSCATrackFitParam &par, const float_m &_mask)
float_v GetKappa(const float_v &Bz) const
friend F32vec4 sqrt(const F32vec4 &a)
Definition: P4_F32vec4.h:40
void GetDCAPoint(const float_v &x, const float_v &y, const float_v &z, float_v *px, float_v *py, float_v *pz, const float_v &Bz) const
static T Sqrt(const T &x)
Definition: PndCAMath.h:57
float_v cz1
Definition: L1Field.h:131
void SetSignCosPhi(const float_v &v)
float_v GetDist2(const PndFTSCATrackParamVector &t) const
float_v cz2
Definition: L1Field.h:131
friend F32vec4 sin(const F32vec4 &a)
Definition: P4_F32vec4.h:130
static T Sin(const T &x)
Definition: PndCAMath.h:83
friend F32vec4 log(const F32vec4 &a)
Definition: P4_F32vec4.h:129
STL namespace.
float_v cx1
Definition: L1Field.h:129
void SetTrackParamOne(int iV, const PndFTSCATrackParamVector &param, int iVa)
void SetNDF(const int_v &v, const int_m &m)
void SetSinPhi(const float_v &v)
const float_v & C00() const
static float_v BetheBlochGeant(const float_v &bg, const float_v &kp0=2.33f, const float_v &kp1=0.20f, const float_v &kp2=3.00f, const float_v &kp3=173e-9f, const float_v &kp4=0.49848f)
static T Cos(const T &x)
Definition: PndCAMath.h:88
static float_v BetheBlochSolid(const float_v &bg)
void SetZ(const float_v &v, const float_m &m)
__m128 v
Definition: P4_F32vec4.h:15
float_m Rotate(const float_v &alpha, PndFTSCATrackLinearisationVector &t0, const float maxSinPhi=.999f, const float_m &mask=float_m(true))
void SetSinPhi(const float_v &v, const float_m &m)
unsigned int i
Definition: P4_F32vec4.h:33
float_m AddTarget(const FTSCATarget &target, const float_m &mask=float_m(true))
T rcp(T val)
Definition: PndFTSCADef.h:67
static T Abs(const T &x)
Definition: PndCAMath.h:68
float_m FilterVtx(const float_v &xV, const float_v &yV, const CAX1X2MeasurementInfo &info, float_v &extrDx, float_v &extrDy, float_v J[], const float_m &active=float_m(true))
static T RSqrt(const T &x)
Definition: PndCAMath.h:62
void SetCov(int i, const float_v &v, const float_m &m)
void SetChi2(const float_v &v, const float_m &m)
float_m Transport(const int_v &ista, const PndFTSCAParam &param, const float_m &mask=float_m(true))
void InitDirection(float_v r0, float_v r1, float_v r2)
const float_v & Par(int i) const
float_m TransportJ0ToX0(const float_v &x0, const float_v &cBz, float_v &extrDy, float_v &extrDz, float_v J[], const float_m &active=float_m(true))
const float * Par() const
const float * Cov() const
float_v cx0
Definition: L1Field.h:129
void SetY(const float_v &v, const float_m &m)
void SetQPt(const float_v &v, const float_m &m)
void CalculateFitParameters(PndFTSCATrackFitParam &par, const float_v &mass=0.13957f)
void InitCovMatrix(float_v d2QMom=0.f)
friend std::istream & operator>>(std::istream &, PndFTSCATrackParamVector &)
float_v GetS(const float_v &x, const float_v &y, const float_v &Bz) const
float_v GetDistXZ2(const PndFTSCATrackParamVector &t) const
const float_v & C10() const
float_m TransportToX0WithMaterial(const float_v &x, const float_v &XOverX0, const float_v &XThimesRho, const float_v &Bz, const float maxSinPhi=.999f)
float_m FilterWithMaterial(const float_v &y, const float_v &z, float_v err2Y, float_v errYZ, float_v err2Z, float maxSinPhi=0.999f, const float_m &mask=float_m(true), const int_v &hitNDF=int_v(2), const float_v &chi2Cut=10e10f)
PndFTSCATrackParamVector TrackParamVector
float_v cy0
Definition: L1Field.h:130
void SetQMomentum(const float_v &v)
static float_v ApproximateBetheBloch(const float_v &beta2)
const float_v & Cov(int i) const
float_m TransportToX0(const float_v &x, const float_v &Bz, const float maxSinPhi=.999f, const float_m &mask=float_m(true))
float_v cy2
Definition: L1Field.h:130
float f
Definition: P4_F32vec4.h:32
float_v cz0
Definition: L1Field.h:131
void SetSignCosPhi(const float_v &v, const float_m &m)
void SetPar(int i, const float_v &v)
basic_ostream< char, char_traits< char > > ostream
void InitByTarget(const FTSCATarget &target)
void SetDzDs(const float_v &v, const float_m &m)
double alpha
Definition: f_Init.h:31
float_v cx2
Definition: L1Field.h:129
float_v z0
Definition: L1Field.h:132
void SetTrackParam(const PndFTSCATrackParamVector &param, const float_m &m=float_m(true))
const float_v & C11() const
friend std::ostream & operator<<(std::ostream &, const PndFTSCATrackParamVector &)
void SetX(const float_v &v, const float_m &m)
void ConvertTrackParamToVector(PndFTSCATrackParam t0[float_v::Size], int nTracksV)
PndFTSCANoDebugStream & debugKF()
Definition: debug.h:138
static float_v BetheBlochGas(const float_v &bg)
double pz[39]
Definition: pipisigmas.h:25
float_m Filter(const FTSCAHitV &hit, const PndFTSCAParam &param, const float_m &mask=float_m(true), const float_v &chi2Cut=10e10f)
void SetPar(int i, const float_v &v, const float_m &m)