CMS 3D CMS Logo

PropagationMPlexPlane.cc
Go to the documentation of this file.
5 
6 #include "PropagationMPlex.h"
7 
8 //#define DEBUG
9 #include "Debug.h"
10 
11 namespace {
12  using namespace mkfit;
13 
14  void MultHelixPlaneProp(const MPlexLL& A, const MPlexLS& B, MPlexLL& C) {
15  // C = A * B
16 
17  typedef float T;
18  const Matriplex::idx_t N = NN;
19 
20  const T* a = A.fArray;
21  ASSUME_ALIGNED(a, 64);
22  const T* b = B.fArray;
23  ASSUME_ALIGNED(b, 64);
24  T* c = C.fArray;
25  ASSUME_ALIGNED(c, 64);
26 
27 #include "MultHelixPlaneProp.ah"
28  }
29 
30  void MultHelixPlanePropTransp(const MPlexLL& A, const MPlexLL& B, MPlexLS& C) {
31  // C = B * AT;
32 
33  typedef float T;
34  const Matriplex::idx_t N = NN;
35 
36  const T* a = A.fArray;
37  ASSUME_ALIGNED(a, 64);
38  const T* b = B.fArray;
39  ASSUME_ALIGNED(b, 64);
40  T* c = C.fArray;
41  ASSUME_ALIGNED(c, 64);
42 
43 #include "MultHelixPlanePropTransp.ah"
44  }
45 
46 } // namespace
47 
48 // ============================================================================
49 // BEGIN STUFF FROM PropagationMPlex.icc
50 namespace {
51 
52  using MPF = MPlexQF;
53 
54  MPF getBFieldFromZXY(const MPF& z, const MPF& x, const MPF& y) {
55  MPF b;
56  for (int n = 0; n < NN; ++n)
57  b[n] = Config::bFieldFromZR(z[n], hipo(x[n], y[n]));
58  return b;
59  }
60 
61  void JacErrPropCurv1(const MPlex65& A, const MPlex55& B, MPlex65& C) {
62  // C = A * B
63  typedef float T;
64  const Matriplex::idx_t N = NN;
65 
66  const T* a = A.fArray;
67  ASSUME_ALIGNED(a, 64);
68  const T* b = B.fArray;
69  ASSUME_ALIGNED(b, 64);
70  T* c = C.fArray;
71  ASSUME_ALIGNED(c, 64);
72 
73 #include "JacErrPropCurv1.ah"
74  }
75 
76  void JacErrPropCurv2(const MPlex65& A, const MPlex56& B, MPlexLL& __restrict__ C) {
77  // C = A * B
78  typedef float T;
79  const Matriplex::idx_t N = NN;
80 
81  const T* a = A.fArray;
82  ASSUME_ALIGNED(a, 64);
83  const T* b = B.fArray;
84  ASSUME_ALIGNED(b, 64);
85  T* c = C.fArray;
86  ASSUME_ALIGNED(c, 64);
87 
88 #include "JacErrPropCurv2.ah"
89  }
90 
91  void parsFromPathL_impl(const MPlexLV& __restrict__ inPar,
92  MPlexLV& __restrict__ outPar,
93  const MPlexQF& __restrict__ kinv,
94  const MPlexQF& __restrict__ s) {
95  namespace mpt = Matriplex;
96  using MPF = MPlexQF;
97 
98  MPF alpha = s * mpt::fast_sin(inPar(5, 0)) * inPar(3, 0) * kinv;
99 
100  MPF sinah, cosah;
102  mpt::sincos4(0.5f * alpha, sinah, cosah);
103  } else {
104  mpt::fast_sincos(0.5f * alpha, sinah, cosah);
105  }
106 
107  MPF sin_mom_phi, cos_mom_phi;
108  mpt::fast_sincos(inPar(4, 0), sin_mom_phi, cos_mom_phi);
109 
110  MPF sin_mom_tht, cos_mom_tht;
111  mpt::fast_sincos(inPar(5, 0), sin_mom_tht, cos_mom_tht);
112 
113  outPar.aij(0, 0) = inPar(0, 0) + 2.f * sinah * (cos_mom_phi * cosah - sin_mom_phi * sinah) / (inPar(3, 0) * kinv);
114  outPar.aij(1, 0) = inPar(1, 0) + 2.f * sinah * (sin_mom_phi * cosah + cos_mom_phi * sinah) / (inPar(3, 0) * kinv);
115  outPar.aij(2, 0) = inPar(2, 0) + alpha / kinv * cos_mom_tht / (inPar(3, 0) * sin_mom_tht);
116  outPar.aij(3, 0) = inPar(3, 0);
117  outPar.aij(4, 0) = inPar(4, 0) + alpha;
118  outPar.aij(5, 0) = inPar(5, 0);
119  }
120 
121  //*****************************************************************************************************
122 
123  //should kinv and D be templated???
124  void parsAndErrPropFromPathL_impl(const MPlexLV& __restrict__ inPar,
125  const MPlexQI& __restrict__ inChg,
126  MPlexLV& __restrict__ outPar,
127  const MPlexQF& __restrict__ kinv,
128  const MPlexQF& __restrict__ s,
129  MPlexLL& __restrict__ errorProp,
130  const int N_proc,
131  const PropagationFlags& pf) {
132  //iteration should return the path length s, then update parameters and compute errors
133 
134  namespace mpt = Matriplex;
135  using MPF = MPlexQF;
136 
137  parsFromPathL_impl(inPar, outPar, kinv, s);
138 
139  MPF sinPin, cosPin;
140  mpt::fast_sincos(inPar(4, 0), sinPin, cosPin);
141  MPF sinPout, cosPout;
142  mpt::fast_sincos(outPar(4, 0), sinPout, cosPout);
143  MPF sinT, cosT;
144  mpt::fast_sincos(inPar(5, 0), sinT, cosT);
145 
146  // use code from AnalyticalCurvilinearJacobian::computeFullJacobian for error propagation in curvilinear coordinates, then convert to CCS
147  // main difference from the above function is that we assume that the magnetic field is purely along z (which also implies that there is no change in pz)
148  // this simplifies significantly the code
149 
150  MPlex55 errorPropCurv;
151 
152  const MPF qbp = mpt::negate_if_ltz(sinT * inPar(3, 0), inChg);
153  // calculate transport matrix
154  // Origin: TRPRFN
155  const MPF t11 = cosPin * sinT;
156  const MPF t12 = sinPin * sinT;
157  const MPF t21 = cosPout * sinT;
158  const MPF t22 = sinPout * sinT;
159  const MPF cosl1 = 1.f / sinT;
160  // define average magnetic field and gradient
161  // at initial point - inlike TRPRFN
162  const MPF bF = (pf.use_param_b_field ? Const::sol_over_100 * getBFieldFromZXY(inPar(2, 0), inPar(0, 0), inPar(1, 0))
163  : Const::sol_over_100 * Config::Bfield);
164  const MPF q = -bF * qbp;
165  const MPF theta = q * s;
166  MPF sint, cost;
167  mpt::fast_sincos(theta, sint, cost);
168  const MPF dx1 = inPar(0, 0) - outPar(0, 0);
169  const MPF dx2 = inPar(1, 0) - outPar(1, 0);
170  const MPF dx3 = inPar(2, 0) - outPar(2, 0);
171  MPF au = mpt::fast_isqrt(t11 * t11 + t12 * t12);
172  const MPF u11 = -au * t12;
173  const MPF u12 = au * t11;
174  const MPF v11 = -cosT * u12;
175  const MPF v12 = cosT * u11;
176  const MPF v13 = t11 * u12 - t12 * u11;
177  au = mpt::fast_isqrt(t21 * t21 + t22 * t22);
178  const MPF u21 = -au * t22;
179  const MPF u22 = au * t21;
180  const MPF v21 = -cosT * u22;
181  const MPF v22 = cosT * u21;
182  const MPF v23 = t21 * u22 - t22 * u21;
183  // now prepare the transport matrix
184  const MPF omcost = 1.f - cost;
185  const MPF tmsint = theta - sint;
186  // 1/p - doesn't change since |p1| = |p2|
187  errorPropCurv.aij(0, 0) = 1.f;
188  for (int i = 1; i < 5; ++i)
189  errorPropCurv.aij(0, i) = 0.f;
190  // lambda
191  errorPropCurv.aij(1, 0) = 0.f;
192  errorPropCurv.aij(1, 1) =
193  cost * (v11 * v21 + v12 * v22 + v13 * v23) + sint * (-v12 * v21 + v11 * v22) + omcost * v13 * v23;
194  errorPropCurv.aij(1, 2) = (cost * (u11 * v21 + u12 * v22) + sint * (-u12 * v21 + u11 * v22)) * sinT;
195  errorPropCurv.aij(1, 3) = 0.f;
196  errorPropCurv.aij(1, 4) = 0.f;
197  // phi
198  errorPropCurv.aij(2, 0) = bF * v23 * (t21 * dx1 + t22 * dx2 + cosT * dx3) * cosl1;
199  errorPropCurv.aij(2, 1) = (cost * (v11 * u21 + v12 * u22) + sint * (-v12 * u21 + v11 * u22) +
200  v23 * (-sint * (v11 * t21 + v12 * t22 + v13 * cosT) + omcost * (-v11 * t22 + v12 * t21) -
201  tmsint * cosT * v13)) *
202  cosl1;
203  errorPropCurv.aij(2, 2) = (cost * (u11 * u21 + u12 * u22) + sint * (-u12 * u21 + u11 * u22) +
204  v23 * (-sint * (u11 * t21 + u12 * t22) + omcost * (-u11 * t22 + u12 * t21))) *
205  cosl1 * sinT;
206  errorPropCurv.aij(2, 3) = -q * v23 * (u11 * t21 + u12 * t22) * cosl1;
207  errorPropCurv.aij(2, 4) = -q * v23 * (v11 * t21 + v12 * t22 + v13 * cosT) * cosl1;
208 
209  // yt
210  for (int n = 0; n < N_proc; ++n) {
211  float cutCriterion = fabs(s[n] * sinT[n] * inPar(n, 3, 0));
212  const float limit = 5.f; // valid for propagations with effectively float precision
213  if (cutCriterion > limit) {
214  const float pp = 1.f / qbp[n];
215  errorPropCurv(n, 3, 0) = pp * (u21[n] * dx1[n] + u22[n] * dx2[n]);
216  errorPropCurv(n, 4, 0) = pp * (v21[n] * dx1[n] + v22[n] * dx2[n] + v23[n] * dx3[n]);
217  } else {
218  const float temp1 = -t12[n] * u21[n] + t11[n] * u22[n];
219  const float s2 = s[n] * s[n];
220  const float secondOrder41 = -0.5f * bF[n] * temp1 * s2;
221  const float temp2 = -t11[n] * u21[n] - t12[n] * u22[n];
222  const float s3 = s2 * s[n];
223  const float s4 = s3 * s[n];
224  const float h2 = bF[n] * bF[n];
225  const float h3 = h2 * bF[n];
226  const float qbp2 = qbp[n] * qbp[n];
227  const float thirdOrder41 = 1.f / 3 * h2 * s3 * qbp[n] * temp2;
228  const float fourthOrder41 = 1.f / 8 * h3 * s4 * qbp2 * temp1;
229  errorPropCurv(n, 3, 0) = secondOrder41 + (thirdOrder41 + fourthOrder41);
230  const float temp3 = -t12[n] * v21[n] + t11[n] * v22[n];
231  const float secondOrder51 = -0.5f * bF[n] * temp3 * s2;
232  const float temp4 = -t11[n] * v21[n] - t12[n] * v22[n] - cosT[n] * v23[n];
233  const float thirdOrder51 = 1.f / 3 * h2 * s3 * qbp[n] * temp4;
234  const float fourthOrder51 = 1.f / 8 * h3 * s4 * qbp2 * temp3;
235  errorPropCurv(n, 4, 0) = secondOrder51 + (thirdOrder51 + fourthOrder51);
236  }
237  }
238 
239  errorPropCurv.aij(3, 1) = (sint * (v11 * u21 + v12 * u22) + omcost * (-v12 * u21 + v11 * u22)) / q;
240  errorPropCurv.aij(3, 2) = (sint * (u11 * u21 + u12 * u22) + omcost * (-u12 * u21 + u11 * u22)) * sinT / q;
241  errorPropCurv.aij(3, 3) = (u11 * u21 + u12 * u22);
242  errorPropCurv.aij(3, 4) = (v11 * u21 + v12 * u22);
243  // zt
244  errorPropCurv.aij(4, 1) =
245  (sint * (v11 * v21 + v12 * v22 + v13 * v23) + omcost * (-v12 * v21 + v11 * v22) + tmsint * v23 * v13) / q;
246  errorPropCurv.aij(4, 2) = (sint * (u11 * v21 + u12 * v22) + omcost * (-u12 * v21 + u11 * v22)) * sinT / q;
247  errorPropCurv.aij(4, 3) = (u11 * v21 + u12 * v22);
248  errorPropCurv.aij(4, 4) = (v11 * v21 + v12 * v22 + v13 * v23);
249 
250 //debug = true;
251 #ifdef DEBUG
252  for (int n = 0; n < NN; ++n) {
253  if (debug && g_debug && n < N_proc) {
254  dmutex_guard;
255  std::cout << n << ": errorPropCurv" << std::endl;
256  printf("%5f %5f %5f %5f %5f\n",
257  errorPropCurv(n, 0, 0),
258  errorPropCurv(n, 0, 1),
259  errorPropCurv(n, 0, 2),
260  errorPropCurv(n, 0, 3),
261  errorPropCurv(n, 0, 4));
262  printf("%5f %5f %5f %5f %5f\n",
263  errorPropCurv(n, 1, 0),
264  errorPropCurv(n, 1, 1),
265  errorPropCurv(n, 1, 2),
266  errorPropCurv(n, 1, 3),
267  errorPropCurv(n, 1, 4));
268  printf("%5f %5f %5f %5f %5f\n",
269  errorPropCurv(n, 2, 0),
270  errorPropCurv(n, 2, 1),
271  errorPropCurv(n, 2, 2),
272  errorPropCurv(n, 2, 3),
273  errorPropCurv(n, 2, 4));
274  printf("%5f %5f %5f %5f %5f\n",
275  errorPropCurv(n, 3, 0),
276  errorPropCurv(n, 3, 1),
277  errorPropCurv(n, 3, 2),
278  errorPropCurv(n, 3, 3),
279  errorPropCurv(n, 3, 4));
280  printf("%5f %5f %5f %5f %5f\n",
281  errorPropCurv(n, 4, 0),
282  errorPropCurv(n, 4, 1),
283  errorPropCurv(n, 4, 2),
284  errorPropCurv(n, 4, 3),
285  errorPropCurv(n, 4, 4));
286  printf("\n");
287  }
288  }
289 #endif
290 
291  //now we need jacobians to convert to/from curvilinear and CCS
292  // code from TrackState::jacobianCCSToCurvilinear
293  MPlex56 jacCCS2Curv(0.0f);
294  jacCCS2Curv.aij(0, 3) = mpt::negate_if_ltz(sinT, inChg);
295  jacCCS2Curv.aij(0, 5) = mpt::negate_if_ltz(cosT * inPar(3, 0), inChg);
296  jacCCS2Curv.aij(1, 5) = -1.f;
297  jacCCS2Curv.aij(2, 4) = 1.f;
298  jacCCS2Curv.aij(3, 0) = -sinPin;
299  jacCCS2Curv.aij(3, 1) = cosPin;
300  jacCCS2Curv.aij(4, 0) = -cosPin * cosT;
301  jacCCS2Curv.aij(4, 1) = -sinPin * cosT;
302  jacCCS2Curv.aij(4, 2) = sinT;
303 
304  // code from TrackState::jacobianCurvilinearToCCS
305  MPlex65 jacCurv2CCS(0.0f);
306  jacCurv2CCS.aij(0, 3) = -sinPout;
307  jacCurv2CCS.aij(0, 4) = -cosT * cosPout;
308  jacCurv2CCS.aij(1, 3) = cosPout;
309  jacCurv2CCS.aij(1, 4) = -cosT * sinPout;
310  jacCurv2CCS.aij(2, 4) = sinT;
311  jacCurv2CCS.aij(3, 0) = mpt::negate_if_ltz(1.f / sinT, inChg);
312  jacCurv2CCS.aij(3, 1) = outPar(3, 0) * cosT / sinT;
313  jacCurv2CCS.aij(4, 2) = 1.f;
314  jacCurv2CCS.aij(5, 1) = -1.f;
315 
316  //need to compute errorProp = jacCurv2CCS*errorPropCurv*jacCCS2Curv
317  MPlex65 tmp;
318  JacErrPropCurv1(jacCurv2CCS, errorPropCurv, tmp);
319  JacErrPropCurv2(tmp, jacCCS2Curv, errorProp);
320  /*
321  Matriplex::multiplyGeneral(jacCurv2CCS, errorPropCurv, tmp);
322  for (int kk = 0; kk < 1; ++kk) {
323  std::cout << "jacCurv2CCS" << std::endl;
324  for (int i = 0; i < 6; ++i) {
325  for (int j = 0; j < 5; ++j)
326  std::cout << jacCurv2CCS.constAt(kk, i, j) << " ";
327  std::cout << std::endl;;
328  }
329  std::cout << std::endl;;
330  std::cout << "errorPropCurv" << std::endl;
331  for (int i = 0; i < 5; ++i) {
332  for (int j = 0; j < 5; ++j)
333  std::cout << errorPropCurv.constAt(kk, i, j) << " ";
334  std::cout << std::endl;;
335  }
336  std::cout << std::endl;;
337  std::cout << "tmp" << std::endl;
338  for (int i = 0; i < 6; ++i) {
339  for (int j = 0; j < 5; ++j)
340  std::cout << tmp.constAt(kk, i, j) << " ";
341  std::cout << std::endl;;
342  }
343  std::cout << std::endl;;
344  std::cout << "jacCCS2Curv" << std::endl;
345  for (int i = 0; i < 5; ++i) {
346  for (int j = 0; j < 6; ++j)
347  std::cout << jacCCS2Curv.constAt(kk, i, j) << " ";
348  std::cout << std::endl;;
349  }
350  }
351  Matriplex::multiplyGeneral(tmp, jacCCS2Curv, errorProp);
352  */
353  }
354 
355  // from P.Avery's notes (http://www.phys.ufl.edu/~avery/fitting/transport.pdf eq. 5)
356  float getS(float delta0,
357  float delta1,
358  float delta2,
359  float eta0,
360  float eta1,
361  float eta2,
362  float sinP,
363  float cosP,
364  float sinT,
365  float cosT,
366  float pt,
367  int q,
368  float kinv) {
369  float A = delta0 * eta0 + delta1 * eta1 + delta2 * eta2;
370  float ip = sinT / pt;
371  float p0[3] = {pt * cosP, pt * sinP, cosT / ip};
372  float B = (p0[0] * eta0 + p0[1] * eta1 + p0[2] * eta2) * ip;
373  float rho = kinv * ip;
374  float C = (eta0 * p0[1] - eta1 * p0[0]) * rho * 0.5f * ip;
375  float sqb2m4ac = std::sqrt(B * B - 4.f * A * C);
376  float s1 = (-B + sqb2m4ac) * 0.5f / C;
377  float s2 = (-B - sqb2m4ac) * 0.5f / C;
378 #ifdef DEBUG
379  if (debug)
380  std::cout << "A=" << A << " B=" << B << " C=" << C << " s1=" << s1 << " s2=" << s2 << std::endl;
381 #endif
382  //take the closest
383  return (std::abs(s1) > std::abs(s2) ? s2 : s1);
384  }
385 
386  void helixAtPlane_impl(const MPlexLV& __restrict__ inPar,
387  const MPlexQI& __restrict__ inChg,
388  const MPlexHV& __restrict__ plPnt,
389  const MPlexHV& __restrict__ plNrm,
390  MPlexQF& __restrict__ s,
391  MPlexLV& __restrict__ outPar,
392  MPlexLL& __restrict__ errorProp,
393  MPlexQI& __restrict__ outFailFlag, // expected to be initialized to 0
394  const int N_proc,
395  const PropagationFlags& pf) {
396  namespace mpt = Matriplex;
397  using MPF = MPlexQF;
398 
399 #ifdef DEBUG
400  for (int n = 0; n < N_proc; ++n) {
401  dprint_np(n,
402  "input parameters"
403  << " inPar(n, 0, 0)=" << std::setprecision(9) << inPar(n, 0, 0) << " inPar(n, 1, 0)="
404  << std::setprecision(9) << inPar(n, 1, 0) << " inPar(n, 2, 0)=" << std::setprecision(9)
405  << inPar(n, 2, 0) << " inPar(n, 3, 0)=" << std::setprecision(9) << inPar(n, 3, 0)
406  << " inPar(n, 4, 0)=" << std::setprecision(9) << inPar(n, 4, 0)
407  << " inPar(n, 5, 0)=" << std::setprecision(9) << inPar(n, 5, 0));
408  }
409 #endif
410 
412  if (pf.use_param_b_field) {
413  kinv *= getBFieldFromZXY(inPar(2, 0), inPar(0, 0), inPar(1, 0));
414  } else {
415  kinv *= Config::Bfield;
416  }
417 
418  MPF delta0 = inPar(0, 0) - plPnt(0, 0);
419  MPF delta1 = inPar(1, 0) - plPnt(1, 0);
420  MPF delta2 = inPar(2, 0) - plPnt(2, 0);
421 
422  MPF sinP, cosP;
423  mpt::fast_sincos(inPar(4, 0), sinP, cosP);
424  MPF sinT, cosT;
425  mpt::fast_sincos(inPar(5, 0), sinT, cosT);
426 
427  // determine solution for straight line
428  MPF sl = -(plNrm(0, 0) * delta0 + plNrm(1, 0) * delta1 + plNrm(2, 0) * delta2) /
429  (plNrm(0, 0) * cosP * sinT + plNrm(1, 0) * sinP * sinT + plNrm(2, 0) * cosT);
430 
431  //float s[nmax - nmin];
432  //first iteration outside the loop
433 #pragma omp simd
434  for (int n = 0; n < NN; ++n) {
435  s[n] = (std::abs(plNrm(n, 2, 0)) < 1.f ? getS(delta0[n],
436  delta1[n],
437  delta2[n],
438  plNrm(n, 0, 0),
439  plNrm(n, 1, 0),
440  plNrm(n, 2, 0),
441  sinP[n],
442  cosP[n],
443  sinT[n],
444  cosT[n],
445  inPar(n, 3, 0),
446  inChg(n, 0, 0),
447  kinv[n])
448  : (plPnt.constAt(n, 2, 0) - inPar.constAt(n, 2, 0)) / cosT[n]);
449  }
450 
451  MPlexLV outParTmp;
452 
454  for (int i = 0; i < Config::Niter - 1; ++i) {
455  parsFromPathL_impl(inPar, outParTmp, kinv, s);
456 
457  delta0 = outParTmp(0, 0) - plPnt(0, 0);
458  delta1 = outParTmp(1, 0) - plPnt(1, 0);
459  delta2 = outParTmp(2, 0) - plPnt(2, 0);
460 
461  mpt::fast_sincos(outParTmp(4, 0), sinP, cosP);
462  // Note, sinT/cosT not updated
463 
464 #pragma omp simd
465  for (int n = 0; n < NN; ++n) {
466  s[n] += (std::abs(plNrm(n, 2, 0)) < 1.f
467  ? getS(delta0[n],
468  delta1[n],
469  delta2[n],
470  plNrm(n, 0, 0),
471  plNrm(n, 1, 0),
472  plNrm(n, 2, 0),
473  sinP[n],
474  cosP[n],
475  sinT[n],
476  cosT[n],
477  inPar(n, 3, 0),
478  inChg(n, 0, 0),
479  kinv[n])
480  : (plPnt.constAt(n, 2, 0) - outParTmp.constAt(n, 2, 0)) / std::cos(outParTmp.constAt(n, 5, 0)));
481  }
482  } //end Niter-1
483 
484  // use linear approximation if s did not converge (for very high pT tracks)
485  for (int n = 0; n < NN; ++n) {
486 #ifdef DEBUG
487  if (debug)
488  std::cout << "s[n]=" << s[n] << " sl[n]=" << sl[n] << " std::isnan(s[n])=" << std::isnan(s[n])
489  << " std::isfinite(s[n])=" << std::isfinite(s[n]) << " std::isnormal(s[n])=" << std::isnormal(s[n])
490  << std::endl;
491 #endif
492  if ((std::abs(sl[n]) > std::abs(s[n])) || std::isnormal(s[n]) == false)
493  s[n] = sl[n];
494  }
495 
496 #ifdef DEBUG
497  if (debug)
498  std::cout << "s=" << s[0] << std::endl;
499 #endif
500  parsAndErrPropFromPathL_impl(inPar, inChg, outPar, kinv, s, errorProp, N_proc, pf);
501  }
502 
503 } // namespace
504 // END STUFF FROM PropagationMPlex.icc
505 // ============================================================================
506 
507 namespace mkfit {
508 
509  void helixAtPlane(const MPlexLV& inPar,
510  const MPlexQI& inChg,
511  const MPlexHV& plPnt,
512  const MPlexHV& plNrm,
513  MPlexQF& pathL,
514  MPlexLV& outPar,
515  MPlexLL& errorProp,
516  MPlexQI& outFailFlag,
517  const int N_proc,
518  const PropagationFlags& pflags) {
519  errorProp.setVal(0.f);
520  outFailFlag.setVal(0.f);
521 
522  helixAtPlane_impl(inPar, inChg, plPnt, plNrm, pathL, outPar, errorProp, outFailFlag, N_proc, pflags);
523  }
524 
526  const MPlexLV& inPar,
527  const MPlexQI& inChg,
528  const MPlexHV& plPnt,
529  const MPlexHV& plNrm,
530  MPlexLS& outErr,
531  MPlexLV& outPar,
532  MPlexQI& outFailFlag,
533  const int N_proc,
534  const PropagationFlags& pflags,
535  const MPlexQI* noMatEffPtr) {
536  // debug = true;
537 
538  outErr = inErr;
539  outPar = inPar;
540 
541  MPlexQF pathL;
542  MPlexLL errorProp;
543 
544  helixAtPlane(inPar, inChg, plPnt, plNrm, pathL, outPar, errorProp, outFailFlag, N_proc, pflags);
545 
546 #ifdef DEBUG
547  for (int n = 0; n < N_proc; ++n) {
548  dprint_np(
549  n,
550  "propagation to plane end, dump parameters\n"
551  //<< " D = " << s[n] << " alpha = " << s[n] * std::sin(inPar(n, 5, 0)) * inPar(n, 3, 0) * kinv[n] << " kinv = " << kinv[n] << std::endl
552  << " pos = " << outPar(n, 0, 0) << " " << outPar(n, 1, 0) << " " << outPar(n, 2, 0) << "\t\t r="
553  << std::sqrt(outPar(n, 0, 0) * outPar(n, 0, 0) + outPar(n, 1, 0) * outPar(n, 1, 0)) << std::endl
554  << " mom = " << outPar(n, 3, 0) << " " << outPar(n, 4, 0) << " " << outPar(n, 5, 0) << std::endl
555  << " charge = " << inChg(n, 0, 0) << std::endl
556  << " cart= " << std::cos(outPar(n, 4, 0)) / outPar(n, 3, 0) << " "
557  << std::sin(outPar(n, 4, 0)) / outPar(n, 3, 0) << " " << 1. / (outPar(n, 3, 0) * tan(outPar(n, 5, 0)))
558  << "\t\tpT=" << 1. / std::abs(outPar(n, 3, 0)) << std::endl);
559  }
560 
561  if (debug && g_debug) {
562  for (int kk = 0; kk < N_proc; ++kk) {
563  dprintf("inPar %d\n", kk);
564  for (int i = 0; i < 6; ++i) {
565  dprintf("%8f ", inPar.constAt(kk, i, 0));
566  }
567  dprintf("\n");
568  dprintf("inErr %d\n", kk);
569  for (int i = 0; i < 6; ++i) {
570  for (int j = 0; j < 6; ++j)
571  dprintf("%8f ", inErr.constAt(kk, i, j));
572  dprintf("\n");
573  }
574  dprintf("\n");
575 
576  for (int kk = 0; kk < N_proc; ++kk) {
577  dprintf("plNrm %d\n", kk);
578  for (int j = 0; j < 3; ++j)
579  dprintf("%8f ", plNrm.constAt(kk, 0, j));
580  }
581  dprintf("\n");
582 
583  for (int kk = 0; kk < N_proc; ++kk) {
584  dprintf("pathL %d\n", kk);
585  for (int j = 0; j < 1; ++j)
586  dprintf("%8f ", pathL.constAt(kk, 0, j));
587  }
588  dprintf("\n");
589 
590  dprintf("errorProp %d\n", kk);
591  for (int i = 0; i < 6; ++i) {
592  for (int j = 0; j < 6; ++j)
593  dprintf("%8f ", errorProp.At(kk, i, j));
594  dprintf("\n");
595  }
596  dprintf("\n");
597  }
598  }
599 #endif
600 
601  // Matriplex version of:
602  // result.errors = ROOT::Math::Similarity(errorProp, outErr);
603  MPlexLL temp;
604  MultHelixPlaneProp(errorProp, outErr, temp);
605  MultHelixPlanePropTransp(errorProp, temp, outErr);
606  // MultHelixPropFull(errorProp, outErr, temp);
607  // for (int kk = 0; kk < 1; ++kk) {
608  // std::cout << "errorProp" << std::endl;
609  // for (int i = 0; i < 6; ++i) {
610  // for (int j = 0; j < 6; ++j)
611  // std::cout << errorProp.constAt(kk, i, j) << " ";
612  // std::cout << std::endl;;
613  // }
614  // std::cout << std::endl;;
615  // std::cout << "outErr" << std::endl;
616  // for (int i = 0; i < 6; ++i) {
617  // for (int j = 0; j < 6; ++j)
618  // std::cout << outErr.constAt(kk, i, j) << " ";
619  // std::cout << std::endl;;
620  // }
621  // std::cout << std::endl;;
622  // std::cout << "temp" << std::endl;
623  // for (int i = 0; i < 6; ++i) {
624  // for (int j = 0; j < 6; ++j)
625  // std::cout << temp.constAt(kk, i, j) << " ";
626  // std::cout << std::endl;;
627  // }
628  // std::cout << std::endl;;
629  // }
630  // MultHelixPropTranspFull(errorProp, temp, outErr);
631 
632 #ifdef DEBUG
633  if (debug && g_debug) {
634  for (int kk = 0; kk < N_proc; ++kk) {
635  dprintf("outErr %d\n", kk);
636  for (int i = 0; i < 6; ++i) {
637  for (int j = 0; j < 6; ++j)
638  dprintf("%8f ", outErr.constAt(kk, i, j));
639  dprintf("\n");
640  }
641  dprintf("\n");
642  }
643  }
644 #endif
645 
646  if (pflags.apply_material) {
647  MPlexQF hitsRl;
648  MPlexQF hitsXi;
649  MPlexQF propSign;
650 
651  const TrackerInfo& tinfo = *pflags.tracker_info;
652 
653 #pragma omp simd
654  for (int n = 0; n < NN; ++n) {
655  if (n >= N_proc || (noMatEffPtr && noMatEffPtr->constAt(n, 0, 0))) {
656  hitsRl(n, 0, 0) = 0.f;
657  hitsXi(n, 0, 0) = 0.f;
658  } else {
659  const float hypo = std::hypot(outPar(n, 0, 0), outPar(n, 1, 0));
660  auto mat = tinfo.material_checked(std::abs(outPar(n, 2, 0)), hypo);
661  hitsRl(n, 0, 0) = mat.radl;
662  hitsXi(n, 0, 0) = mat.bbxi;
663  }
664  propSign(n, 0, 0) = (pathL(n, 0, 0) > 0.f ? 1.f : -1.f);
665  }
666  applyMaterialEffects(hitsRl, hitsXi, propSign, plNrm, outErr, outPar, N_proc);
667 #ifdef DEBUG
668  if (debug && g_debug) {
669  for (int kk = 0; kk < N_proc; ++kk) {
670  dprintf("propSign %d\n", kk);
671  for (int i = 0; i < 1; ++i) {
672  dprintf("%8f ", propSign.constAt(kk, i, 0));
673  }
674  dprintf("\n");
675  dprintf("plNrm %d\n", kk);
676  for (int i = 0; i < 3; ++i) {
677  dprintf("%8f ", plNrm.constAt(kk, i, 0));
678  }
679  dprintf("\n");
680  dprintf("outErr(after material) %d\n", kk);
681  for (int i = 0; i < 6; ++i) {
682  for (int j = 0; j < 6; ++j)
683  dprintf("%8f ", outErr.constAt(kk, i, j));
684  dprintf("\n");
685  }
686  dprintf("\n");
687  }
688  }
689 #endif
690  }
691 
692  squashPhiMPlex(outPar, N_proc); // ensure phi is between |pi|
693 
694  // PROP-FAIL-ENABLE To keep physics changes minimal, we always restore the
695  // state to input when propagation fails -- as was the default before.
696  // if (pflags.copy_input_state_on_fail) {
697  for (int i = 0; i < N_proc; ++i) {
698  if (outFailFlag(i, 0, 0)) {
699  outPar.copySlot(i, inPar);
700  outErr.copySlot(i, inErr);
701  }
702  }
703  // }
704  }
705 
706 } // namespace mkfit
void sincos4(const MPlex< T, D1, D2, N > &a, MPlex< T, D1, D2, N > &s, MPlex< T, D1, D2, N > &c)
Definition: Matriplex.h:696
def isnan(num)
Matriplex::Matriplex< float, LL, LL, NN > MPlexLL
Definition: Matrix.h:53
MPlex< T, D1, D2, N > hypot(const MPlex< T, D1, D2, N > &a, const MPlex< T, D1, D2, N > &b)
Definition: Matriplex.h:616
constexpr float sol_over_100
Definition: Config.h:14
Definition: APVGainStruct.h:7
#define dprint_np(n, x)
Definition: Debug.h:96
for(int i=first, nt=offsets[nh];i< nt;i+=gridDim.x *blockDim.x)
Matriplex::Matriplex< float, HH, 1, NN > MPlexHV
Definition: Matrix.h:58
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
#define CMS_UNROLL_LOOP_COUNT(N)
Definition: CMSUnrollLoop.h:48
const TrackerInfo * tracker_info
void applyMaterialEffects(const MPlexQF &hitsRl, const MPlexQF &hitsXi, const MPlexQF &propSign, const MPlexHV &plNrm, MPlexLS &outErr, MPlexLV &outPar, const int N_proc)
Matriplex::Matriplex< float, LL, 1, NN > MPlexLV
Definition: Matrix.h:54
Matriplex::Matriplex< float, 5, 5, NN > MPlex55
Definition: Matrix.h:64
void squashPhiMPlex(MPlexLV &par, const int N_proc)
bool g_debug
Definition: Debug.cc:2
void propagateHelixToPlaneMPlex(const MPlexLS &inErr, const MPlexLV &inPar, const MPlexQI &inChg, const MPlexHV &plPnt, const MPlexHV &plNrm, MPlexLS &outErr, MPlexLV &outPar, MPlexQI &outFailFlag, const int N_proc, const PropagationFlags &pflags, const MPlexQI *noMatEffPtr=nullptr)
T sqrt(T t)
Definition: SSEVec.h:23
constexpr Matriplex::idx_t NN
Definition: Matrix.h:48
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
constexpr float Bfield
Definition: Config.h:60
Tan< T >::type tan(const T &t)
Definition: Tan.h:22
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
double f[11][100]
MPlex< T, D1, D2, N > negate_if_ltz(const MPlex< T, D1, D2, N > &a, const MPlex< TT, D1, D2, N > &sign)
Definition: Matriplex.h:504
constexpr bool useTrigApprox
Definition: Config.h:51
Matriplex::Matriplex< int, 1, 1, NN > MPlexQI
Definition: Matrix.h:81
Matriplex::Matriplex< float, 5, 6, NN > MPlex56
Definition: Matrix.h:65
#define debug
Definition: HDRShower.cc:19
Matriplex::Matriplex< float, 1, 1, NN > MPlexQF
Definition: Matrix.h:80
#define N
Definition: blowfish.cc:9
float hipo(float x, float y)
Definition: Matrix.h:9
float bFieldFromZR(const float z, const float r)
Definition: Config.h:131
double b
Definition: hdecay.h:120
void helixAtPlane(const MPlexLV &inPar, const MPlexQI &inChg, const MPlexHV &plPnt, const MPlexHV &plNrm, MPlexQF &pathL, MPlexLV &outPar, MPlexLL &errorProp, MPlexQI &outFailFlag, const int N_proc, const PropagationFlags &pflags)
double a
Definition: hdecay.h:121
Definition: Config.py:1
Matriplex::MatriplexSym< float, LL, NN > MPlexLS
Definition: Matrix.h:55
float x
Material material_checked(float z, float r) const
Definition: TrackerInfo.h:275
Definition: APVGainStruct.h:7
void fast_sincos(const MPF &a, MPF &s, MPF &c)
tmp
align.sh
Definition: createJobs.py:716
long double T
#define ASSUME_ALIGNED(a, b)
Matriplex::Matriplex< float, 6, 5, NN > MPlex65
Definition: Matrix.h:66
#define dprintf(...)
Definition: Debug.h:98
constexpr int Niter
Definition: Config.h:50