File indexing completed on 2024-04-06 12:28:19
0001 #include "RecoTracker/MkFitCore/src/MiniPropagators.h"
0002 #include "vdt/atan2.h"
0003 #include "vdt/tan.h"
0004 #include "vdt/sincos.h"
0005 #include "vdt/sqrt.h"
0006
0007 namespace mkfit::mini_propagators {
0008
0009 State::State(const MPlexLV& par, int ti) {
0010 x = par.constAt(ti, 0, 0);
0011 y = par.constAt(ti, 1, 0);
0012 z = par.constAt(ti, 2, 0);
0013 const float pt = 1.0f / par.constAt(ti, 3, 0);
0014 px = pt * std::cos(par.constAt(ti, 4, 0));
0015 py = pt * std::sin(par.constAt(ti, 4, 0));
0016 pz = pt / std::tan(par.constAt(ti, 5, 0));
0017 }
0018
0019 bool InitialState::propagate_to_r(PropAlgo_e algo, float R, State& c, bool update_momentum) const {
0020 switch (algo) {
0021 case PA_Line: {
0022 }
0023 case PA_Quadratic: {
0024 }
0025
0026 case PA_Exact: {
0027
0028 const float k = 1.0f / inv_k;
0029
0030 const float curv = 0.5f * inv_k * inv_pt;
0031 const float oo_curv = 1.0f / curv;
0032 const float lambda = pz * inv_pt;
0033
0034 float D = 0;
0035
0036 c = *this;
0037 c.dalpha = 0;
0038 for (int i = 0; i < Config::Niter; ++i) {
0039
0040
0041 float r0 = std::hypot(c.x, c.y);
0042 float td = (R - r0) * curv;
0043 float id = oo_curv * td * (1.0f + 0.16666666f * td * td);
0044
0045
0046 D += id;
0047
0048
0049
0050
0051 float alpha = id * inv_pt * inv_k;
0052 float sina, cosa;
0053 vdt::fast_sincosf(alpha, sina, cosa);
0054
0055
0056 c.dalpha += alpha;
0057 c.x += k * (c.px * sina - c.py * (1.0f - cosa));
0058 c.y += k * (c.py * sina + c.px * (1.0f - cosa));
0059
0060 const float o_px = c.px;
0061 c.px = c.px * cosa - c.py * sina;
0062 c.py = c.py * cosa + o_px * sina;
0063 }
0064
0065 c.z += lambda * D;
0066 }
0067 }
0068
0069 c.fail_flag = std::abs(std::hypot(c.x, c.y) - R) < 0.1f ? 0 : 1;
0070 return c.fail_flag;
0071 }
0072
0073 bool InitialState::propagate_to_z(PropAlgo_e algo, float Z, State& c, bool update_momentum) const {
0074 switch (algo) {
0075 case PA_Line: {
0076 }
0077 case PA_Quadratic: {
0078 }
0079
0080 case PA_Exact: {
0081 const float k = 1.0f / inv_k;
0082
0083 const float dz = Z - z;
0084 const float alpha = dz * inv_k / pz;
0085
0086 float sina, cosa;
0087 vdt::fast_sincosf(alpha, sina, cosa);
0088
0089 c.dalpha = alpha;
0090 c.x = x + k * (px * sina - py * (1.0f - cosa));
0091 c.y = y + k * (py * sina + px * (1.0f - cosa));
0092 c.z = Z;
0093
0094 if (update_momentum) {
0095 c.px = px * cosa - py * sina;
0096 c.py = py * cosa + px * sina;
0097 c.pz = pz;
0098 }
0099 } break;
0100 }
0101 c.fail_flag = 0;
0102 return c.fail_flag;
0103 }
0104
0105
0106
0107
0108
0109 MPF fast_atan2(const MPF& y, const MPF& x) {
0110 MPF t;
0111 for (int i = 0; i < y.kTotSize; ++i) {
0112 t[i] = vdt::fast_atan2f(y[i], x[i]);
0113 }
0114 return t;
0115 }
0116
0117 MPF fast_tan(const MPF& a) {
0118 MPF t;
0119 for (int i = 0; i < a.kTotSize; ++i) {
0120 t[i] = vdt::fast_tanf(a[i]);
0121 }
0122 return t;
0123 }
0124
0125 void fast_sincos(const MPF& a, MPF& s, MPF& c) {
0126 for (int i = 0; i < a.kTotSize; ++i) {
0127 vdt::fast_sincosf(a[i], s[i], c[i]);
0128 }
0129 }
0130
0131 StatePlex::StatePlex(const MPlexLV& par) {
0132 x = par.ReduceFixedIJ(0, 0);
0133 y = par.ReduceFixedIJ(1, 0);
0134 z = par.ReduceFixedIJ(2, 0);
0135 const MPF pt = 1.0f / par.ReduceFixedIJ(3, 0);
0136 fast_sincos(par.ReduceFixedIJ(4, 0), py, px);
0137 px *= pt;
0138 py *= pt;
0139 pz = pt / fast_tan(par.ReduceFixedIJ(5, 0));
0140 }
0141
0142
0143 int InitialStatePlex::propagate_to_r(
0144 PropAlgo_e algo, const MPF& R, StatePlex& c, bool update_momentum, int N_proc) const {
0145 switch (algo) {
0146 case PA_Line: {
0147 }
0148 case PA_Quadratic: {
0149 }
0150
0151 case PA_Exact: {
0152
0153 const MPF k = 1.0f / inv_k;
0154
0155 const MPF curv = 0.5f * inv_k * inv_pt;
0156 const MPF oo_curv = 1.0f / curv;
0157 const MPF lambda = pz * inv_pt;
0158
0159 MPF D = 0;
0160
0161 c = *this;
0162 c.dalpha = 0;
0163 for (int i = 0; i < Config::Niter; ++i) {
0164
0165
0166 MPF r0 = Matriplex::hypot(c.x, c.y);
0167 MPF td = (R - r0) * curv;
0168 MPF id = oo_curv * td * (1.0f + 0.16666666f * td * td);
0169
0170
0171 D += id;
0172
0173
0174
0175
0176 MPF alpha = id * inv_pt * inv_k;
0177
0178 MPF sina, cosa;
0179 fast_sincos(alpha, sina, cosa);
0180
0181
0182 c.dalpha += alpha;
0183 c.x += k * (c.px * sina - c.py * (1.0f - cosa));
0184 c.y += k * (c.py * sina + c.px * (1.0f - cosa));
0185
0186 MPF o_px = c.px;
0187 c.px = c.px * cosa - c.py * sina;
0188 c.py = c.py * cosa + o_px * sina;
0189 }
0190
0191 c.z += lambda * D;
0192 }
0193 }
0194
0195
0196 MPF r = Matriplex::hypot(c.x, c.y);
0197 c.fail_flag = 0;
0198 int n_fail = 0;
0199 for (int i = 0; i < N_proc; ++i) {
0200 if (std::abs(R[i] - r[i]) > 0.1f) {
0201 c.fail_flag[i] = 1;
0202 ++n_fail;
0203 }
0204 }
0205 return n_fail;
0206 }
0207
0208 int InitialStatePlex::propagate_to_z(
0209 PropAlgo_e algo, const MPF& Z, StatePlex& c, bool update_momentum, int N_proc) const {
0210 switch (algo) {
0211 case PA_Line: {
0212 }
0213 case PA_Quadratic: {
0214 }
0215
0216 case PA_Exact: {
0217 MPF k = 1.0f / inv_k;
0218
0219 MPF dz = Z - z;
0220 MPF alpha = dz * inv_k / pz;
0221
0222 MPF sina, cosa;
0223 fast_sincos(alpha, sina, cosa);
0224
0225 c.dalpha = alpha;
0226 c.x = x + k * (px * sina - py * (1.0f - cosa));
0227 c.y = y + k * (py * sina + px * (1.0f - cosa));
0228 c.z = Z;
0229
0230 if (update_momentum) {
0231 c.px = px * cosa - py * sina;
0232 c.py = py * cosa + px * sina;
0233 c.pz = pz;
0234 }
0235 } break;
0236 }
0237 c.fail_flag = 0;
0238 return 0;
0239 }
0240
0241 }