File indexing completed on 2025-11-02 09:08:39
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011
0012 #include "Acts/Seeding/GbtsDataStorage.hpp" //includes geo which has trigindetsilayer, may move this to trigbase
0013 #include "Acts/Utilities/Logger.hpp"
0014
0015 #include <algorithm>
0016 #include <cmath>
0017 #include <cstring>
0018 #include <iostream>
0019 #include <list>
0020 #include <vector>
0021
0022 namespace Acts::Experimental {
0023
0024 template <typename external_spacepoint_t>
0025 struct GbtsEdgeState {
0026 public:
0027 struct Compare {
0028 bool operator()(const struct GbtsEdgeState* s1,
0029 const struct GbtsEdgeState* s2) {
0030 return s1->m_J > s2->m_J;
0031 }
0032 };
0033
0034 GbtsEdgeState() = default;
0035
0036 GbtsEdgeState(bool f) : m_initialized(f) {}
0037
0038 void initialize(GbtsEdge<external_spacepoint_t>* pS) {
0039 m_initialized = true;
0040
0041 m_J = 0.0;
0042 m_vs.clear();
0043
0044
0045
0046 float dx = pS->m_n1->m_spGbts.SP->x() - pS->m_n2->m_spGbts.SP->x();
0047 float dy = pS->m_n1->m_spGbts.SP->y() - pS->m_n2->m_spGbts.SP->y();
0048 float L = std::sqrt(dx * dx + dy * dy);
0049
0050 m_s = dy / L;
0051 m_c = dx / L;
0052
0053
0054
0055
0056
0057 m_refY = pS->m_n2->m_spGbts.r();
0058 m_refX =
0059 pS->m_n2->m_spGbts.SP->x() * m_c + pS->m_n2->m_spGbts.SP->y() * m_s;
0060
0061
0062
0063 m_X[0] =
0064 -pS->m_n2->m_spGbts.SP->x() * m_s + pS->m_n2->m_spGbts.SP->y() * m_c;
0065 m_X[1] = 0.0;
0066 m_X[2] = 0.0;
0067
0068
0069
0070 m_Y[0] = pS->m_n2->m_spGbts.SP->z();
0071 m_Y[1] = (pS->m_n1->m_spGbts.SP->z() - pS->m_n2->m_spGbts.SP->z()) /
0072 (pS->m_n1->m_spGbts.r() - pS->m_n2->m_spGbts.r());
0073
0074 memset(&m_Cx[0][0], 0, sizeof(m_Cx));
0075 memset(&m_Cy[0][0], 0, sizeof(m_Cy));
0076
0077 m_Cx[0][0] = 0.25;
0078 m_Cx[1][1] = 0.001;
0079 m_Cx[2][2] = 0.001;
0080
0081 m_Cy[0][0] = 1.5;
0082 m_Cy[1][1] = 0.001;
0083 }
0084
0085 void clone(const struct GbtsEdgeState& st) {
0086 memcpy(&m_X[0], &st.m_X[0], sizeof(m_X));
0087 memcpy(&m_Y[0], &st.m_Y[0], sizeof(m_Y));
0088 memcpy(&m_Cx[0][0], &st.m_Cx[0][0], sizeof(m_Cx));
0089 memcpy(&m_Cy[0][0], &st.m_Cy[0][0], sizeof(m_Cy));
0090 m_refX = st.m_refX;
0091 m_refY = st.m_refY;
0092 m_c = st.m_c;
0093 m_s = st.m_s;
0094 m_J = st.m_J;
0095 m_vs.clear();
0096 m_vs.reserve(st.m_vs.size());
0097 std::copy(st.m_vs.begin(), st.m_vs.end(), std::back_inserter(m_vs));
0098
0099 m_initialized = true;
0100 }
0101
0102 float m_J{};
0103
0104 std::vector<GbtsEdge<external_spacepoint_t>*> m_vs;
0105
0106 float m_X[3]{}, m_Y[2]{}, m_Cx[3][3]{}, m_Cy[2][2]{};
0107 float m_refX{}, m_refY{}, m_c{}, m_s{};
0108
0109 bool m_initialized{false};
0110 };
0111
0112 #define MAX_EDGE_STATE 2500
0113
0114 template <typename external_spacepoint_t>
0115 class GbtsTrackingFilter {
0116 public:
0117 GbtsTrackingFilter(const std::vector<TrigInDetSiLayer>& g,
0118 std::vector<GbtsEdge<external_spacepoint_t>>& sb,
0119 std::unique_ptr<const Acts::Logger> logger =
0120 Acts::getDefaultLogger("Filter",
0121 Acts::Logging::Level::INFO))
0122 : m_geo(g), m_segStore(sb), m_logger(std::move(logger)) {}
0123
0124 void followTrack(GbtsEdge<external_spacepoint_t>* pS,
0125 GbtsEdgeState<external_spacepoint_t>& output) {
0126 if (pS->m_level == -1) {
0127 return;
0128 }
0129 m_globalStateCounter = 0;
0130
0131
0132
0133 GbtsEdgeState<external_spacepoint_t>* pInitState =
0134 &m_stateStore[m_globalStateCounter++];
0135
0136 pInitState->initialize(pS);
0137
0138 m_stateVec.clear();
0139
0140
0141
0142 propagate(pS, *pInitState);
0143
0144 if (m_stateVec.empty()) {
0145 return;
0146 }
0147 std::ranges::sort(m_stateVec,
0148 typename GbtsEdgeState<external_spacepoint_t>::Compare());
0149
0150 GbtsEdgeState<external_spacepoint_t>* best = (*m_stateVec.begin());
0151
0152 output.clone(*best);
0153
0154 m_globalStateCounter = 0;
0155 }
0156
0157 protected:
0158 void propagate(GbtsEdge<external_spacepoint_t>* pS,
0159 GbtsEdgeState<external_spacepoint_t>& ts) {
0160 if (m_globalStateCounter >= MAX_EDGE_STATE) {
0161 return;
0162 }
0163 GbtsEdgeState<external_spacepoint_t>* p_new_ts =
0164 &m_stateStore[m_globalStateCounter++];
0165
0166 GbtsEdgeState<external_spacepoint_t>& new_ts = *p_new_ts;
0167 new_ts.clone(ts);
0168
0169 new_ts.m_vs.push_back(pS);
0170
0171 bool accepted = update(pS, new_ts);
0172
0173 if (!accepted) {
0174 return;
0175 }
0176 int level = pS->m_level;
0177
0178 std::list<GbtsEdge<external_spacepoint_t>*> lCont;
0179
0180 for (int nIdx = 0; nIdx < pS->m_nNei;
0181 nIdx++) {
0182 unsigned int nextSegmentIdx = pS->m_vNei[nIdx];
0183
0184 GbtsEdge<external_spacepoint_t>* pN = &(m_segStore.at(nextSegmentIdx));
0185
0186 if (pN->m_level == -1) {
0187 continue;
0188 }
0189 if (pN->m_level == level - 1) {
0190 lCont.push_back(pN);
0191 }
0192 }
0193 if (lCont.empty()) {
0194
0195
0196 if (m_globalStateCounter < MAX_EDGE_STATE) {
0197 if (m_stateVec.empty()) {
0198 GbtsEdgeState<external_spacepoint_t>* p =
0199 &m_stateStore[m_globalStateCounter++];
0200 p->clone(new_ts);
0201 m_stateVec.push_back(p);
0202 } else {
0203 float best_so_far = (*m_stateVec.begin())->m_J;
0204 if (new_ts.m_J > best_so_far) {
0205 GbtsEdgeState<external_spacepoint_t>* p =
0206 &m_stateStore[m_globalStateCounter++];
0207 p->clone(new_ts);
0208 m_stateVec.push_back(p);
0209 }
0210 }
0211 }
0212 } else {
0213 int nBranches = 0;
0214 for (typename std::list<GbtsEdge<external_spacepoint_t>*>::iterator sIt =
0215 lCont.begin();
0216 sIt != lCont.end(); ++sIt, nBranches++) {
0217 propagate((*sIt), new_ts);
0218 }
0219 }
0220 }
0221
0222 bool update(GbtsEdge<external_spacepoint_t>* pS,
0223 GbtsEdgeState<external_spacepoint_t>& ts) {
0224 const float sigma_t = 0.0003;
0225 const float sigma_w = 0.00009;
0226
0227 const float sigmaMS = 0.016;
0228
0229 const float sigma_x = 0.25;
0230 const float sigma_y = 2.5;
0231
0232 const float weight_x = 0.5;
0233 const float weight_y = 0.5;
0234
0235 const float maxDChi2_x = 60.0;
0236 const float maxDChi2_y = 60.0;
0237
0238 const float add_hit = 14.0;
0239
0240 if (ts.m_Cx[2][2] < 0.0 || ts.m_Cx[1][1] < 0.0 || ts.m_Cx[0][0] < 0.0) {
0241 ACTS_WARNING("Negative covariance detected in X components: "
0242 << "cov[2][2]=" << ts.m_Cx[2][2] << " cov[1][1]="
0243 << ts.m_Cx[1][1] << " cov[0][0]=" << ts.m_Cx[0][0]);
0244 }
0245
0246 if (ts.m_Cy[1][1] < 0.0 || ts.m_Cy[0][0] < 0.0) {
0247 ACTS_WARNING("Negative covariance detected in Y components: "
0248 << "cov[1][1]=" << ts.m_Cy[1][1]
0249 << " cov[0][0]=" << ts.m_Cy[0][0]);
0250 }
0251
0252
0253
0254 ts.m_Cx[2][2] += sigma_w * sigma_w;
0255 ts.m_Cx[1][1] += sigma_t * sigma_t;
0256
0257 int type1 = getLayerType(pS->m_n1->m_spGbts.combined_ID);
0258
0259 float t2 = type1 == 0 ? 1.0 + ts.m_Y[1] * ts.m_Y[1]
0260 : 1.0 + 1.0 / (ts.m_Y[1] * ts.m_Y[1]);
0261 float s1 = sigmaMS * t2;
0262 float s2 = s1 * s1;
0263
0264 s2 *= std::sqrt(t2);
0265
0266 ts.m_Cy[1][1] += s2;
0267
0268
0269
0270 float X[3], Y[2];
0271 float Cx[3][3], Cy[2][2];
0272
0273 float refX{}, refY{}, mx{}, my{};
0274
0275 float x{}, y{}, z{}, r{};
0276
0277 x = pS->m_n1->m_spGbts.SP->x();
0278 y = pS->m_n1->m_spGbts.SP->y();
0279 z = pS->m_n1->m_spGbts.SP->z();
0280 r = pS->m_n1->m_spGbts.r();
0281
0282 refX = x * ts.m_c + y * ts.m_s;
0283 mx = -x * ts.m_s + y * ts.m_c;
0284 refY = r;
0285 my = z;
0286
0287 float A = refX - ts.m_refX;
0288 float B = 0.5 * A * A;
0289 float dr = refY - ts.m_refY;
0290
0291 X[0] = ts.m_X[0] + ts.m_X[1] * A + ts.m_X[2] * B;
0292 X[1] = ts.m_X[1] + ts.m_X[2] * A;
0293 X[2] = ts.m_X[2];
0294
0295 Cx[0][0] = ts.m_Cx[0][0] + 2 * ts.m_Cx[0][1] * A + 2 * ts.m_Cx[0][2] * B +
0296 A * A * ts.m_Cx[1][1] + 2 * A * B * ts.m_Cx[1][2] +
0297 B * B * ts.m_Cx[2][2];
0298 Cx[0][1] = Cx[1][0] = ts.m_Cx[0][1] + ts.m_Cx[1][1] * A +
0299 ts.m_Cx[1][2] * B + ts.m_Cx[0][2] * A +
0300 A * A * ts.m_Cx[1][2] + A * B * ts.m_Cx[2][2];
0301 Cx[0][2] = Cx[2][0] = ts.m_Cx[0][2] + ts.m_Cx[1][2] * A + ts.m_Cx[2][2] * B;
0302
0303 Cx[1][1] = ts.m_Cx[1][1] + 2 * A * ts.m_Cx[1][2] + A * A * ts.m_Cx[2][2];
0304 Cx[1][2] = Cx[2][1] = ts.m_Cx[1][2] + ts.m_Cx[2][2] * A;
0305
0306 Cx[2][2] = ts.m_Cx[2][2];
0307
0308 Y[0] = ts.m_Y[0] + ts.m_Y[1] * dr;
0309 Y[1] = ts.m_Y[1];
0310
0311 Cy[0][0] = ts.m_Cy[0][0] + 2 * ts.m_Cy[0][1] * dr + dr * dr * ts.m_Cy[1][1];
0312 Cy[0][1] = Cy[1][0] = ts.m_Cy[0][1] + dr * ts.m_Cy[1][1];
0313 Cy[1][1] = ts.m_Cy[1][1];
0314
0315 float resid_x = mx - X[0];
0316 float resid_y = my - Y[0];
0317
0318 float CHx[3] = {Cx[0][0], Cx[0][1], Cx[0][2]};
0319 float CHy[2] = {Cy[0][0], Cy[0][1]};
0320
0321 float sigma_rz = 0.0;
0322
0323 int type = getLayerType(pS->m_n1->m_spGbts.combined_ID);
0324
0325 if (type == 0) {
0326 sigma_rz = sigma_y * sigma_y;
0327 } else {
0328 sigma_rz = sigma_y * ts.m_Y[1];
0329 sigma_rz = sigma_rz * sigma_rz;
0330 }
0331
0332 float Dx = 1.0 / (Cx[0][0] + sigma_x * sigma_x);
0333
0334 float Dy = 1.0 / (Cy[0][0] + sigma_rz);
0335
0336 float dchi2_x = resid_x * resid_x * Dx;
0337 float dchi2_y = resid_y * resid_y * Dy;
0338
0339 if (dchi2_x > maxDChi2_x || dchi2_y > maxDChi2_y) {
0340 return false;
0341 }
0342
0343 ts.m_J += add_hit - dchi2_x * weight_x - dchi2_y * weight_y;
0344
0345
0346 float Kx[3] = {Dx * Cx[0][0], Dx * Cx[0][1], Dx * Cx[0][2]};
0347 float Ky[2] = {Dy * Cy[0][0], Dy * Cy[0][1]};
0348
0349 for (int i = 0; i < 3; i++) {
0350 ts.m_X[i] = X[i] + Kx[i] * resid_x;
0351 }
0352 for (int i = 0; i < 2; i++) {
0353 ts.m_Y[i] = Y[i] + Ky[i] * resid_y;
0354 }
0355
0356 for (int i = 0; i < 3; i++) {
0357 for (int j = 0; j < 3; j++) {
0358 ts.m_Cx[i][j] = Cx[i][j] - Kx[i] * CHx[j];
0359 }
0360 }
0361
0362 for (int i = 0; i < 2; i++) {
0363 for (int j = 0; j < 2; j++) {
0364 ts.m_Cy[i][j] = Cy[i][j] - Ky[i] * CHy[j];
0365 }
0366 }
0367
0368 ts.m_refX = refX;
0369 ts.m_refY = refY;
0370
0371 return true;
0372 }
0373
0374 int getLayerType(int l) {
0375 auto iterator = find_if(m_geo.begin(), m_geo.end(), [l](auto n) {
0376 return n.m_subdet == l;
0377 });
0378 int index = std::distance(m_geo.begin(), iterator);
0379
0380 return m_geo.at(index).m_type;
0381 }
0382
0383 const std::vector<TrigInDetSiLayer>& m_geo;
0384
0385 std::vector<GbtsEdge<external_spacepoint_t>>& m_segStore;
0386
0387 std::vector<GbtsEdgeState<external_spacepoint_t>*> m_stateVec;
0388
0389 GbtsEdgeState<external_spacepoint_t> m_stateStore[MAX_EDGE_STATE];
0390
0391 int m_globalStateCounter{0};
0392
0393 const Acts::Logger& logger() const { return *m_logger; }
0394 std::unique_ptr<const Acts::Logger> m_logger{nullptr};
0395 };
0396
0397 }