11 #include <type_traits>
17 template <
typename external_spacepo
int_t>
20 : m_config(std::move(config)) {
37 template <
typename external_spacepo
int_t>
38 template <
typename sp_range_t>
39 std::vector<Seed<external_spacepoint_t>>
41 sp_range_t bottomSPs, sp_range_t middleSPs, sp_range_t topSPs)
const {
42 std::vector<Seed<external_spacepoint_t>> outputVec;
43 for (
auto spM : middleSPs) {
44 float rM = spM->radius();
46 float varianceRM = spM->varianceR();
47 float varianceZM = spM->varianceZ();
50 std::vector<const InternalSpacePoint<external_spacepoint_t>*>
53 for (
auto bottomSP : bottomSPs) {
54 float rB = bottomSP->radius();
57 if (deltaR > m_config.deltaRMax) {
61 if (deltaR < m_config.deltaRMin) {
65 float cotTheta = (zM - bottomSP->z()) / deltaR;
66 if (std::fabs(cotTheta) > m_config.cotThetaMax) {
70 float zOrigin = zM - rM * cotTheta;
71 if (zOrigin < m_config.collisionRegionMin ||
72 zOrigin > m_config.collisionRegionMax) {
75 compatBottomSP.push_back(bottomSP);
78 if (compatBottomSP.empty()) {
82 std::vector<const InternalSpacePoint<external_spacepoint_t>*> compatTopSP;
84 for (
auto topSP : topSPs) {
85 float rT = topSP->radius();
88 if (deltaR < m_config.deltaRMin) {
91 if (deltaR > m_config.deltaRMax) {
95 float cotTheta = (topSP->z() - zM) / deltaR;
96 if (std::fabs(cotTheta) > m_config.cotThetaMax) {
99 float zOrigin = zM - rM * cotTheta;
100 if (zOrigin < m_config.collisionRegionMin ||
101 zOrigin > m_config.collisionRegionMax) {
104 compatTopSP.push_back(topSP);
106 if (compatTopSP.empty()) {
111 std::vector<LinCircle> linCircleBottom;
113 std::vector<LinCircle> linCircleTop;
114 transformCoordinates(compatBottomSP, *spM,
true, linCircleBottom);
115 transformCoordinates(compatTopSP, *spM,
false, linCircleTop);
118 std::vector<const InternalSpacePoint<external_spacepoint_t>*> topSpVec;
119 std::vector<float> curvatures;
120 std::vector<float> impactParameters;
122 std::vector<std::pair<
123 float, std::unique_ptr<const InternalSeed<external_spacepoint_t>>>>
125 size_t numBotSP = compatBottomSP.size();
126 size_t numTopSP = compatTopSP.size();
128 for (
size_t b = 0;
b < numBotSP;
b++) {
129 auto lb = linCircleBottom[
b];
131 float cotThetaB = lb.cotTheta;
135 float iDeltaRB = lb.iDeltaR;
138 float iSinTheta2 = (1. + cotThetaB * cotThetaB);
148 float scatteringInRegion2 = m_config.maxScatteringAngle2 * iSinTheta2;
150 scatteringInRegion2 *=
151 m_config.sigmaScattering * m_config.sigmaScattering;
156 impactParameters.clear();
157 for (
size_t t = 0;
t < numTopSP;
t++) {
158 auto lt = linCircleTop[
t];
162 float error2 = lt.Er + ErB +
163 2 * (cotThetaB * lt.cotTheta * varianceRM + varianceZM) *
164 iDeltaRB * lt.iDeltaR;
166 float deltaCotTheta = cotThetaB - lt.cotTheta;
167 float deltaCotTheta2 = deltaCotTheta * deltaCotTheta;
169 float dCotThetaMinusError2;
172 if (deltaCotTheta2 - error2 > 0) {
173 deltaCotTheta =
std::abs(deltaCotTheta);
175 error = std::sqrt(error2);
176 dCotThetaMinusError2 =
177 deltaCotTheta2 + error2 - 2 * deltaCotTheta *
error;
183 if (dCotThetaMinusError2 > scatteringInRegion2) {
189 float dU = lt.U - Ub;
195 float A = (lt.V - Vb) / dU;
196 float S2 = 1. + A *
A;
197 float B = Vb - A * Ub;
201 if (S2 < B2 * m_config.minHelixDiameter2) {
205 float iHelixDiameter2 = B2 / S2;
207 float pT2scatter = 4 * iHelixDiameter2 * m_config.pT2perRadius;
211 float p2scatter = pT2scatter * iSinTheta2;
213 if ((deltaCotTheta2 - error2 > 0) &&
214 (dCotThetaMinusError2 >
215 p2scatter * m_config.sigmaScattering * m_config.sigmaScattering)) {
221 float Im =
std::abs((A - B * rM) * rM);
223 if (Im <= m_config.impactMax) {
224 topSpVec.push_back(compatTopSP[
t]);
227 curvatures.push_back(B / std::sqrt(S2));
228 impactParameters.push_back(Im);
231 if (!topSpVec.empty()) {
232 std::vector<std::pair<
233 float, std::unique_ptr<const InternalSeed<external_spacepoint_t>>>>
235 sameTrackSeeds = std::move(m_config.seedFilter->filterSeeds_2SpFixed(
236 *compatBottomSP[
b], *spM, topSpVec, curvatures, impactParameters,
238 seedsPerSpM.insert(seedsPerSpM.end(),
239 std::make_move_iterator(sameTrackSeeds.begin()),
240 std::make_move_iterator(sameTrackSeeds.end()));
243 m_config.seedFilter->filterSeeds_1SpFixed(seedsPerSpM, outputVec);
248 template <
typename external_spacepo
int_t>
252 std::vector<LinCircle>& linCircleVec)
const {
259 float cosPhiM = xM / rM;
260 float sinPhiM = yM / rM;
261 for (
auto sp : vec) {
262 float deltaX =
sp->x() - xM;
263 float deltaY =
sp->y() - yM;
264 float deltaZ =
sp->z() - zM;
269 float x = deltaX * cosPhiM + deltaY * sinPhiM;
270 float y = deltaY * cosPhiM - deltaX * sinPhiM;
272 float iDeltaR2 = 1. / (deltaX * deltaX + deltaY * deltaY);
273 float iDeltaR = std::sqrt(iDeltaR2);
275 int bottomFactor = 1 * (
int(!bottom)) - 1 * (
int(bottom));
277 float cot_theta = deltaZ * iDeltaR * bottomFactor;
282 l.
Zo = zM - rM * cot_theta;
293 l.
Er = ((varianceZM +
sp->varianceZ()) +
294 (cot_theta * cot_theta) * (varianceRM +
sp->varianceR())) *
296 linCircleVec.push_back(l);