CMS 3D CMS Logo

MiniPropagators.cc
Go to the documentation of this file.
3 #include "vdt/atan2.h"
4 #include "vdt/tan.h"
5 #include "vdt/sincos.h"
6 #include "vdt/sqrt.h"
7 
9 
10  State::State(const MPlexLV& par, int ti) {
11  x = par.constAt(ti, 0, 0);
12  y = par.constAt(ti, 1, 0);
13  z = par.constAt(ti, 2, 0);
14  const float pt = 1.0f / par.constAt(ti, 3, 0);
15  px = pt * std::cos(par.constAt(ti, 4, 0));
16  py = pt * std::sin(par.constAt(ti, 4, 0));
17  pz = pt / std::tan(par.constAt(ti, 5, 0));
18  }
19 
20  bool InitialState::propagate_to_r(PropAlgo_e algo, float R, State& c, bool update_momentum) const {
21  switch (algo) {
22  case PA_Line: {
23  }
24  case PA_Quadratic: {
25  }
26 
27  case PA_Exact: {
28  // Momentum is always updated -- used as temporary for stepping.
29  const float k = 1.0f / inv_k;
30 
31  const float curv = 0.5f * inv_k * inv_pt;
32  const float oo_curv = 1.0f / curv; // 2 * radius of curvature
33  const float lambda = pz * inv_pt;
34 
35  float D = 0;
36 
37  c = *this;
38  c.dalpha = 0;
39  for (int i = 0; i < Config::Niter; ++i) {
40  // compute tangental and ideal distance for the current iteration.
41  // 3-rd order asin for symmetric incidence (shortest arc lenght).
42  float r0 = std::hypot(c.x, c.y);
43  float td = (R - r0) * curv;
44  float id = oo_curv * td * (1.0f + 0.16666666f * td * td);
45  // This would be for line approximation:
46  // float id = R - r0;
47  D += id;
48 
49  //printf("%-3d r0=%f R-r0=%f td=%f id=%f id_line=%f delta_id=%g\n",
50  // i, r0, R-r0, td, id, R - r0, id - (R-r0));
51 
52  float alpha = id * inv_pt * inv_k;
53  float sina, cosa;
54  vdt::fast_sincosf(alpha, sina, cosa);
55 
56  // update parameters
57  c.dalpha += alpha;
58  c.x += k * (c.px * sina - c.py * (1.0f - cosa));
59  c.y += k * (c.py * sina + c.px * (1.0f - cosa));
60 
61  const float o_px = c.px; // copy before overwriting
62  c.px = c.px * cosa - c.py * sina;
63  c.py = c.py * cosa + o_px * sina;
64  }
65 
66  c.z += lambda * D;
67  }
68  }
69  // should have some epsilon constant / member? relative vs. abs?
70  c.fail_flag = std::abs(std::hypot(c.x, c.y) - R) < 0.1f ? 0 : 1;
71  return c.fail_flag;
72  }
73 
74  bool InitialState::propagate_to_z(PropAlgo_e algo, float Z, State& c, bool update_momentum) const {
75  switch (algo) {
76  case PA_Line: {
77  }
78  case PA_Quadratic: {
79  }
80 
81  case PA_Exact: {
82  const float k = 1.0f / inv_k;
83 
84  const float dz = Z - z;
85  const float alpha = dz * inv_k / pz;
86 
87  float sina, cosa;
88  vdt::fast_sincosf(alpha, sina, cosa);
89 
90  c.dalpha = alpha;
91  c.x = x + k * (px * sina - py * (1.0f - cosa));
92  c.y = y + k * (py * sina + px * (1.0f - cosa));
93  c.z = Z;
94 
95  if (update_momentum) {
96  c.px = px * cosa - py * sina;
97  c.py = py * cosa + px * sina;
98  c.pz = pz;
99  }
100  } break;
101  }
102  c.fail_flag = 0;
103  return c.fail_flag;
104  }
105 
106  bool InitialState::propagate_to_plane(PropAlgo_e algo, const ModuleInfo& mi, State& c, bool update_momentum) const {
107  switch (algo) {
108  case PA_Line: {
109  // Momentum is never changed ... we simply step along its direction
110  // to hit the plane.
111  // const float k = 1.0f / inv_k;
112 
113  // const float curv = 0.5f * inv_k * inv_pt;
114  // const float oo_curv = 1.0f / curv; // 2 * radius of curvature
115  // const float lambda = pz * inv_pt;
116 
117  //X float dist = (x - mi.pos(0)) * mi.zdir(0) +
118  //X (y - mi.pos(1)) * mi.zdir(1) +
119  //X (z - mi.pos(2)) * mi.zdir(2);
120 
121  // t * p_vec intersects the plane:
122  float t = (mi.pos(0) * mi.zdir(0) + mi.pos(1) * mi.zdir(1) + mi.pos(2) * mi.zdir(2) - x * mi.zdir(0) -
123  y * mi.zdir(1) - z * mi.zdir(2)) /
124  (px * mi.zdir(0) + py * mi.zdir(1) + pz * mi.zdir(2));
125 
126  //X printf(" module-center: %.2f,%.2f,%.2f pos: %.2f,%.2f,%.2f normal: %.2f,%.2f,%.2f\n",
127  //X mi.pos(0),mi.pos(1),mi.pos(2), x, y, z, mi.zdir(0),mi.zdir(1),mi.zdir(2));
128 
129  c = *this;
130  c.x += t * c.px;
131  c.y += t * c.py;
132  c.z += t * c.pz;
133 
134  //X re-check ditance to plane
135  //X float dist2 = (c.x - mi.pos(0)) * mi.zdir(0) +
136  //X (c.y - mi.pos(1)) * mi.zdir(1) +
137  //X (c.z - mi.pos(2)) * mi.zdir(2);
138  //X printf(" dist = %.3f, t = %.4f ..... dist2 = %.4f\n", dist, t, dist2);
139  break;
140  }
141 
142  case PA_Quadratic: {
143  throw std::runtime_error("Quadratic prop_to_plane not implemented");
144  }
145 
146  case PA_Exact: {
147  throw std::runtime_error("Exact prop_to_plane not implemented");
148  }
149  }
150  return false;
151  }
152 
153  //===========================================================================
154  // Vectorized version
155  //===========================================================================
156 
157  MPF fast_atan2(const MPF& y, const MPF& x) {
158  MPF t;
159  for (int i = 0; i < y.kTotSize; ++i) {
160  t[i] = vdt::fast_atan2f(y[i], x[i]);
161  }
162  return t;
163  }
164 
165  MPF fast_tan(const MPF& a) {
166  MPF t;
167  for (int i = 0; i < a.kTotSize; ++i) {
168  t[i] = vdt::fast_tanf(a[i]);
169  }
170  return t;
171  }
172 
173  void fast_sincos(const MPF& a, MPF& s, MPF& c) {
174  for (int i = 0; i < a.kTotSize; ++i) {
175  vdt::fast_sincosf(a[i], s[i], c[i]);
176  }
177  }
178 
180  x = par.ReduceFixedIJ(0, 0);
181  y = par.ReduceFixedIJ(1, 0);
182  z = par.ReduceFixedIJ(2, 0);
183  const MPF pt = 1.0f / par.ReduceFixedIJ(3, 0);
184  fast_sincos(par.ReduceFixedIJ(4, 0), py, px);
185  px *= pt;
186  py *= pt;
187  pz = pt / fast_tan(par.ReduceFixedIJ(5, 0));
188  }
189 
190  // propagate to radius; returns number of failed propagations
192  PropAlgo_e algo, const MPF& R, StatePlex& c, bool update_momentum, int N_proc) const {
193  switch (algo) {
194  case PA_Line: {
195  }
196  case PA_Quadratic: {
197  }
198 
199  case PA_Exact: {
200  // Momentum is always updated -- used as temporary for stepping.
201  const MPF k = 1.0f / inv_k;
202 
203  const MPF curv = 0.5f * inv_k * inv_pt;
204  const MPF oo_curv = 1.0f / curv; // 2 * radius of curvature
205  const MPF lambda = pz * inv_pt;
206 
207  MPF D = 0;
208 
209  c = *this;
210  c.dalpha = 0;
211  for (int i = 0; i < Config::Niter; ++i) {
212  // compute tangental and ideal distance for the current iteration.
213  // 3-rd order asin for symmetric incidence (shortest arc lenght).
214  MPF r0 = Matriplex::hypot(c.x, c.y);
215  MPF td = (R - r0) * curv;
216  MPF id = oo_curv * td * (1.0f + 0.16666666f * td * td);
217  // This would be for line approximation:
218  // float id = R - r0;
219  D += id;
220 
221  //printf("%-3d r0=%f R-r0=%f td=%f id=%f id_line=%f delta_id=%g\n",
222  // i, r0, R-r0, td, id, R - r0, id - (R-r0));
223 
224  MPF alpha = id * inv_pt * inv_k;
225 
226  MPF sina, cosa;
227  fast_sincos(alpha, sina, cosa);
228 
229  // update parameters
230  c.dalpha += alpha;
231  c.x += k * (c.px * sina - c.py * (1.0f - cosa));
232  c.y += k * (c.py * sina + c.px * (1.0f - cosa));
233 
234  MPF o_px = c.px; // copy before overwriting
235  c.px = c.px * cosa - c.py * sina;
236  c.py = c.py * cosa + o_px * sina;
237  }
238 
239  c.z += lambda * D;
240  }
241  }
242 
243  // should have some epsilon constant / member? relative vs. abs?
244  MPF r = Matriplex::hypot(c.x, c.y);
245  c.fail_flag = 0;
246  int n_fail = 0;
247  for (int i = 0; i < N_proc; ++i) {
248  if (std::abs(R[i] - r[i]) > 0.1f) {
249  c.fail_flag[i] = 1;
250  ++n_fail;
251  }
252  }
253  return n_fail;
254  }
255 
257  PropAlgo_e algo, const MPF& Z, StatePlex& c, bool update_momentum, int N_proc) const {
258  switch (algo) {
259  case PA_Line: {
260  }
261  case PA_Quadratic: {
262  }
263 
264  case PA_Exact: {
265  MPF k = 1.0f / inv_k;
266 
267  MPF dz = Z - z;
268  MPF alpha = dz * inv_k / pz;
269 
270  MPF sina, cosa;
271  fast_sincos(alpha, sina, cosa);
272 
273  c.dalpha = alpha;
274  c.x = x + k * (px * sina - py * (1.0f - cosa));
275  c.y = y + k * (py * sina + px * (1.0f - cosa));
276  c.z = Z;
277 
278  if (update_momentum) {
279  c.px = px * cosa - py * sina;
280  c.py = py * cosa + px * sina;
281  c.pz = pz;
282  }
283  } break;
284  }
285  c.fail_flag = 0;
286  return 0;
287  }
288 
289 } // namespace mkfit::mini_propagators
MPlex< T, D1, D2, N > hypot(const MPlex< T, D1, D2, N > &a, const MPlex< T, D1, D2, N > &b)
Definition: Matriplex.h:616
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
int propagate_to_r(PropAlgo_e algo, const MPF &R, StatePlex &c, bool update_momentum, int N_proc=NN) const
int propagate_to_z(PropAlgo_e algo, const MPF &Z, StatePlex &c, bool update_momentum, int N_proc=NN) const
Matriplex::Matriplex< float, LL, 1, NN > MPlexLV
Definition: Matrix.h:54
bool propagate_to_z(PropAlgo_e algo, float Z, State &c, bool update_momentum) const
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
MPF fast_tan(const MPF &a)
bool propagate_to_plane(PropAlgo_e algo, const ModuleInfo &mi, State &c, bool update_momentum) const
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]
DecomposeProduct< arg, typename Div::arg > D
Definition: Factorize.h:141
double a
Definition: hdecay.h:121
float x
MPF fast_atan2(const MPF &y, const MPF &x)
void fast_sincos(const MPF &a, MPF &s, MPF &c)
bool propagate_to_r(PropAlgo_e algo, float R, State &c, bool update_momentum) const
constexpr int Niter
Definition: Config.h:50