File indexing completed on 2025-12-17 09:20:48
0001
0002
0003
0004
0005
0006 #include "TrackSeedHelper.h"
0007 #include "TrackSeed.h"
0008
0009 #include <trackbase/TrackFitUtils.h>
0010
0011 namespace
0012 {
0013
0014
0015 template <class T>
0016 inline constexpr T square(const T& x)
0017 {
0018 return x * x;
0019 }
0020 }
0021 std::pair<float, float> TrackSeedHelper::findRoot(const float& qOverR, const float& X0, const float& Y0)
0022 {
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035 const float R = std::abs(1./qOverR);
0036 const double miny = (std::sqrt(square(X0) * square(R) * square(Y0) + square(R) * pow(Y0, 4)) + square(X0) * Y0 + pow(Y0, 3)) / (square(X0) + square(Y0));
0037 const double miny2 = (-std::sqrt(square(X0) * square(R) * square(Y0) + square(R) * pow(Y0, 4)) + square(X0) * Y0 + pow(Y0, 3)) / (square(X0) + square(Y0));
0038
0039 const double minx = std::sqrt(square(R) - square(miny - Y0)) + X0;
0040 const double minx2 = -std::sqrt(square(R) - square(miny2 - Y0)) + X0;
0041
0042
0043 const float x = (std::abs(minx) < std::abs(minx2)) ? minx : minx2;
0044 const float y = (std::abs(miny) < std::abs(miny2)) ? miny : miny2;
0045 return {x, y};
0046 }
0047 std::pair<float, float> TrackSeedHelper::findRoot(TrackSeed const* seed)
0048 {
0049 return findRoot(seed->get_qOverR(), seed->get_X0(), seed->get_Y0());
0050 }
0051
0052
0053
0054
0055 float TrackSeedHelper::get_phi(TrackSeed const* seed, const TrackSeedHelper::position_map_t& positions)
0056 {
0057 const auto X0 = seed->get_X0();
0058 const auto Y0 = seed->get_Y0();
0059 const auto [x, y] = findRoot(seed);
0060
0061
0062
0063 float phi = std::atan2(-1 * (X0 - x), (Y0 - y));
0064 Acts::Vector3 pos0 = positions.find(*(seed->begin_cluster_keys()))->second;
0065 Acts::Vector3 pos1 = positions.find(*std::next(seed->begin_cluster_keys()))->second;
0066
0067
0068 double dx0 = pos0(0) - X0;
0069 double dy0 = pos0(1) - Y0;
0070 double phi0 = std::atan2(dy0, dx0);
0071 double dx1 = pos1(0) - X0;
0072 double dy1 = pos1(1) - Y0;
0073 double phi1 = std::atan2(dy1, dx1);
0074 double dphi = phi1 - phi0;
0075
0076
0077
0078 if (dphi > M_PI)
0079 {
0080 dphi -= 2.0 * M_PI;
0081 }
0082 if (dphi < -M_PI)
0083 {
0084 dphi += M_PI;
0085 }
0086
0087
0088 if (dphi < 0)
0089 {
0090 phi += M_PI;
0091 if (phi > M_PI)
0092 {
0093 phi -= 2. * M_PI;
0094 }
0095 }
0096
0097 return phi;
0098 }
0099
0100
0101 float TrackSeedHelper::get_phi_fastsim(TrackSeed const* seed)
0102 {
0103 const auto [x, y] = findRoot(seed);
0104 return std::atan2(-(seed->get_X0()-x), (seed->get_Y0() - y));
0105 }
0106
0107
0108 void TrackSeedHelper::circleFitByTaubin(
0109 TrackSeed* seed,
0110 const TrackSeedHelper::position_map_t& positions,
0111 uint8_t startLayer,
0112 uint8_t endLayer)
0113 {
0114 TrackFitUtils::position_vector_t positions_2d;
0115 for( auto key_iter = seed->begin_cluster_keys(); key_iter != seed->end_cluster_keys(); ++key_iter )
0116 {
0117 const auto& key(*key_iter);
0118 const auto layer = TrkrDefs::getLayer(key);
0119 if (layer < startLayer || layer > endLayer)
0120 {
0121 continue;
0122 }
0123
0124 const auto iter = positions.find(key);
0125
0126
0127 if (iter == positions.end())
0128 {
0129 continue;
0130 }
0131
0132
0133 const Acts::Vector3& pos = iter->second;
0134 positions_2d.emplace_back(pos.x(), pos.y());
0135 }
0136
0137
0138 if( positions_2d.size() < 3 ) { return; }
0139
0140
0141 const auto [r, x0, y0] = TrackFitUtils::circle_fit_by_taubin(positions_2d);
0142 float qOverR = 1./r;
0143
0144
0145 const auto& firstpos = positions_2d.at(0);
0146 const auto& secondpos = positions_2d.at(1);
0147
0148 const auto firstphi = atan2(firstpos.second, firstpos.first);
0149 const auto secondphi = atan2(secondpos.second, secondpos.first);
0150 auto dphi = secondphi - firstphi;
0151 if (dphi > M_PI)
0152 {
0153 dphi = 2.*M_PI-dphi;
0154 }
0155
0156 if (dphi < -M_PI)
0157 {
0158 dphi = 2*M_PI + dphi;
0159 }
0160 if (dphi > 0)
0161 {
0162 qOverR *= -1;
0163 }
0164
0165
0166 seed->set_X0(x0);
0167 seed->set_Y0(y0);
0168 seed->set_qOverR(qOverR);
0169 }
0170
0171
0172 void TrackSeedHelper::lineFit(
0173 TrackSeed* seed,
0174 const TrackSeedHelper::position_map_t& positions,
0175 uint8_t startLayer,
0176 uint8_t endLayer)
0177 {
0178 TrackFitUtils::position_vector_t positions_2d;
0179 for( auto key_iter = seed->begin_cluster_keys(); key_iter != seed->end_cluster_keys(); ++key_iter )
0180 {
0181 const auto& key(*key_iter);
0182 const auto layer = TrkrDefs::getLayer(key);
0183 if (layer < startLayer || layer > endLayer)
0184 {
0185 continue;
0186 }
0187
0188 const auto iter = positions.find(key);
0189
0190
0191 if (iter == positions.end())
0192 {
0193 continue;
0194 }
0195
0196
0197 const Acts::Vector3& pos = iter->second;
0198 positions_2d.emplace_back(std::sqrt(square(pos.x()) + square(pos.y())), pos.z());
0199 }
0200
0201
0202 if( positions_2d.size() < 2 ) { return; }
0203
0204
0205 const auto [slope, intercept] = TrackFitUtils::line_fit(positions_2d);
0206
0207
0208 seed->set_slope(slope);
0209 seed->set_Z0(intercept);
0210 }
0211
0212
0213 float TrackSeedHelper::get_x(TrackSeed const* seed)
0214 {
0215 return findRoot(seed).first;
0216 }
0217
0218
0219 float TrackSeedHelper::get_y(TrackSeed const* seed)
0220 {
0221 return findRoot(seed).second;
0222 }
0223
0224
0225 float TrackSeedHelper::get_z(TrackSeed const* seed)
0226 {
0227 return seed->get_Z0();
0228 }
0229
0230
0231 Acts::Vector3 TrackSeedHelper::get_xyz(TrackSeed const* seed)
0232 {
0233 const auto [x,y] = findRoot(seed);
0234 return {x,y,seed->get_Z0()};
0235 }