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