@@ -120,7 +120,9 @@ void SeedFinder<external_spacepoint_t, platform_t>::createSeedsForGroup(
120120 }
121121 }
122122
123- getCompatibleDoublets (options, grid, state.topNeighbours , *spM.get (),
123+ // Iterate over middle-top dublets
124+ getCompatibleDoublets (state.spacePointData , options, grid,
125+ state.topNeighbours , *spM.get (), state.linCircleTop ,
124126 state.compatTopSP , m_config.deltaRMinTopSP ,
125127 m_config.deltaRMaxTopSP , false );
126128
@@ -151,9 +153,11 @@ void SeedFinder<external_spacepoint_t, platform_t>::createSeedsForGroup(
151153 }
152154 }
153155
154- getCompatibleDoublets (options, grid, state.bottomNeighbours , *spM.get (),
155- state.compatBottomSP , m_config.deltaRMinBottomSP ,
156- m_config.deltaRMaxBottomSP , true );
156+ // Iterate over middle-bottom dublets
157+ getCompatibleDoublets (
158+ state.spacePointData , options, grid, state.bottomNeighbours , *spM.get (),
159+ state.linCircleBottom , state.compatBottomSP , m_config.deltaRMinBottomSP ,
160+ m_config.deltaRMaxBottomSP , true );
157161
158162 // no bottom SP found -> try next spM
159163 if (state.compatBottomSP .empty ()) {
@@ -175,23 +179,31 @@ template <typename external_spacepoint_t, typename platform_t>
175179template <typename out_range_t >
176180inline void
177181SeedFinder<external_spacepoint_t , platform_t >::getCompatibleDoublets(
182+ Acts::SpacePointData& spacePointData,
178183 const Acts::SeedFinderOptions& options,
179184 const Acts::SpacePointGrid<external_spacepoint_t >& grid,
180185 boost::container::small_vector<Neighbour<external_spacepoint_t >, 9 >&
181186 otherSPsNeighbours,
182187 const InternalSpacePoint<external_spacepoint_t >& mediumSP,
183- out_range_t & outVec, const float & deltaRMinSP, const float & deltaRMaxSP ,
184- bool isBottom) const {
188+ std::vector<LinCircle>& linCircleVec, out_range_t & outVec ,
189+ const float & deltaRMinSP, const float & deltaRMaxSP, bool isBottom) const {
185190 const int sign = isBottom ? -1 : 1 ;
186191
187192 outVec.clear ();
193+ linCircleVec.clear ();
188194
189195 const float & rM = mediumSP.radius ();
190196 const float & xM = mediumSP.x ();
191197 const float & yM = mediumSP.y ();
192198 const float & zM = mediumSP.z ();
193- const float ratio_xM_rM = xM / rM;
194- const float ratio_yM_rM = yM / rM;
199+ const float & varianceRM = mediumSP.varianceR ();
200+ const float & varianceZM = mediumSP.varianceZ ();
201+ const float cosPhiM = xM / rM;
202+ const float sinPhiM = yM / rM;
203+ float vIPAbs = 0 ;
204+ if (m_config.interactionPointCut ) {
205+ vIPAbs = m_config.impactMax / (rM * rM);
206+ }
195207
196208 for (auto & otherSPCol : otherSPsNeighbours) {
197209 const auto & otherSPs = grid.at (otherSPCol.index );
@@ -209,6 +221,7 @@ SeedFinder<external_spacepoint_t, platform_t>::getCompatibleDoublets(
209221 const float rO = otherSP->radius ();
210222 float deltaR = sign * (rO - rM);
211223
224+ // if r-distance is too small, try next SP in bin
212225 if (deltaR < deltaRMinSP) {
213226 if (isBottom) {
214227 break ;
@@ -251,34 +264,69 @@ SeedFinder<external_spacepoint_t, platform_t>::getCompatibleDoublets(
251264 continue ;
252265 }
253266
267+ const float deltaX = otherSP->x () - xM;
268+ const float deltaY = otherSP->y () - yM;
269+
270+ // calculate projection fraction of spM->sp vector pointing in same
271+ // direction as
272+ // vector origin->spM (x) and projection fraction of spM->sp vector
273+ // pointing orthogonal to origin->spM (y)
274+ const float xNewFrame = deltaX * cosPhiM + deltaY * sinPhiM;
275+ const float yNewFrame = deltaY * cosPhiM - deltaX * sinPhiM;
276+
277+ const float deltaR2 = (deltaX * deltaX + deltaY * deltaY);
278+ const float iDeltaR2 = 1 . / deltaR2;
279+
280+ // conformal transformation u=x/(x²+y²) v=y/(x²+y²) transform the
281+ // circle into straight lines in the u/v plane the line equation can
282+ // be described in terms of aCoef and bCoef, where v = aCoef * u +
283+ // bCoef
284+ const float uT = xNewFrame * iDeltaR2;
285+ const float vT = yNewFrame * iDeltaR2;
286+
287+ // continue if interactionPointCut is disabled
254288 if (not m_config.interactionPointCut ) {
289+ const float iDeltaR = std::sqrt (iDeltaR2);
290+ cotTheta = deltaZ * iDeltaR;
291+
292+ // error term for sp-pair without correlation of middle space point
293+ const float Er =
294+ ((varianceZM + otherSP->varianceZ ()) +
295+ (cotTheta * cotTheta) * (varianceRM + otherSP->varianceR ())) *
296+ iDeltaR2;
297+
298+ // fill output vectors
299+ linCircleVec.push_back (fillLineCircle (
300+ {deltaZ * iDeltaR, iDeltaR, Er, uT, vT, xNewFrame, yNewFrame}));
301+ spacePointData.setDeltaR (otherSP->index (),
302+ std::sqrt (deltaR2 + (deltaZ * deltaZ)));
255303 outVec.push_back (otherSP.get ());
256304 continue ;
257305 }
258306
259- const float xVal =
260- (otherSP->x () - xM) * ratio_xM_rM + (otherSP->y () - yM) * ratio_yM_rM;
261- const float yVal =
262- (otherSP->y () - yM) * ratio_xM_rM - (otherSP->x () - xM) * ratio_yM_rM;
263-
264- if (std::abs (rM * yVal) <= sign * m_config.impactMax * xVal) {
307+ if (std::abs (rM * yNewFrame) <= sign * m_config.impactMax * xNewFrame) {
308+ const float iDeltaR = std::sqrt (iDeltaR2);
309+ cotTheta = deltaZ * iDeltaR;
310+
311+ // error term for sp-pair without correlation of middle space point
312+ const float Er =
313+ ((varianceZM + otherSP->varianceZ ()) +
314+ (cotTheta * cotTheta) * (varianceRM + otherSP->varianceR ())) *
315+ iDeltaR2;
316+
317+ // fill output vectors
318+ linCircleVec.push_back (fillLineCircle (
319+ {deltaZ * iDeltaR, iDeltaR, Er, uT, vT, xNewFrame, yNewFrame}));
320+ spacePointData.setDeltaR (otherSP->index (),
321+ std::sqrt (deltaR2 + (deltaZ * deltaZ)));
265322 outVec.push_back (otherSP.get ());
266323 continue ;
267324 }
268325
269- // conformal transformation u=x/(x²+y²) v=y/(x²+y²) transform the
270- // circle into straight lines in the u/v plane the line equation can
271- // be described in terms of aCoef and bCoef, where v = aCoef * u +
272- // bCoef
273- const float uT = xVal / (xVal * xVal + yVal * yVal);
274- const float vT = yVal / (xVal * xVal + yVal * yVal);
275326 // in the rotated frame the interaction point is positioned at x = -rM
276327 // and y ~= impactParam
277328 const float uIP = -1 . / rM;
278- float vIP = m_config.impactMax / (rM * rM);
279- if (sign * yVal > 0 .) {
280- vIP = -vIP;
281- }
329+ const float vIP = (sign * yNewFrame > 0 .) ? -vIPAbs : vIPAbs;
282330 // we can obtain aCoef as the slope dv/du of the linear function,
283331 // estimated using du and dv between the two SP bCoef is obtained by
284332 // inserting aCoef into the linear equation
@@ -290,13 +338,27 @@ SeedFinder<external_spacepoint_t, platform_t>::getCompatibleDoublets(
290338 if ((bCoef * bCoef) * options.minHelixDiameter2 > (1 + aCoef * aCoef)) {
291339 continue ;
292340 }
341+
342+ const float iDeltaR = std::sqrt (iDeltaR2);
343+ cotTheta = deltaZ * iDeltaR;
344+
345+ // error term for sp-pair without correlation of middle space point
346+ const float Er =
347+ ((varianceZM + otherSP->varianceZ ()) +
348+ (cotTheta * cotTheta) * (varianceRM + otherSP->varianceR ())) *
349+ iDeltaR2;
350+
351+ // fill output vectors
352+ linCircleVec.push_back (fillLineCircle (
353+ {deltaZ * iDeltaR, iDeltaR, Er, uT, vT, xNewFrame, yNewFrame}));
354+ spacePointData.setDeltaR (otherSP->index (),
355+ std::sqrt (deltaR2 + (deltaZ * deltaZ)));
293356 outVec.push_back (otherSP.get ());
294357 }
295358 }
296359}
297360
298361template <typename external_spacepoint_t , typename platform_t >
299-
300362inline void SeedFinder<external_spacepoint_t , platform_t >::filterCandidates(
301363 Acts::SpacePointData& spacePointData,
302364 const InternalSpacePoint<external_spacepoint_t >& spM,
@@ -306,16 +368,8 @@ inline void SeedFinder<external_spacepoint_t, platform_t>::filterCandidates(
306368 float varianceRM = spM.varianceR ();
307369 float varianceZM = spM.varianceZ ();
308370
309- state.linCircleBottom .clear ();
310- state.linCircleTop .clear ();
311-
312371 std::size_t numTopSP = state.compatTopSP .size ();
313372
314- transformCoordinates (state.spacePointData , state.compatBottomSP , spM, true ,
315- state.linCircleBottom );
316- transformCoordinates (state.spacePointData , state.compatTopSP , spM, false ,
317- state.linCircleTop );
318-
319373 // sort: make index vector
320374 std::vector<std::size_t > sorted_bottoms (state.linCircleBottom .size ());
321375 for (std::size_t i (0 ); i < sorted_bottoms.size (); ++i) {
@@ -356,7 +410,6 @@ inline void SeedFinder<external_spacepoint_t, platform_t>::filterCandidates(
356410 }
357411
358412 auto lb = state.linCircleBottom [b];
359- seedFilterState.zOrigin = lb.Zo ;
360413 float cotThetaB = lb.cotTheta ;
361414 float Vb = lb.V ;
362415 float Ub = lb.U ;
@@ -515,6 +568,7 @@ inline void SeedFinder<external_spacepoint_t, platform_t>::filterCandidates(
515568
516569 float deltaCotTheta = cotThetaB - cotThetaT;
517570 float deltaCotTheta2 = deltaCotTheta * deltaCotTheta;
571+
518572 // Apply a cut on the compatibility between the r-z slope of the two
519573 // seed segments. This is done by comparing the squared difference
520574 // between slopes, and comparing to the squared uncertainty in this
@@ -571,7 +625,6 @@ inline void SeedFinder<external_spacepoint_t, platform_t>::filterCandidates(
571625
572626 // sqrt(S2)/B = 2 * helixradius
573627 // calculated radius must not be smaller than minimum radius
574-
575628 if (S2 < B2 * options.minHelixDiameter2 ) {
576629 continue ;
577630 }
@@ -629,6 +682,8 @@ inline void SeedFinder<external_spacepoint_t, platform_t>::filterCandidates(
629682 continue ;
630683 }
631684
685+ seedFilterState.zOrigin = spM.z () - rM * lb.cotTheta ;
686+
632687 m_config.seedFilter ->filterSeeds_2SpFixed (
633688 state.spacePointData , *state.compatBottomSP [b], spM, state.topSpVec ,
634689 state.curvatures , state.impactParameters , seedFilterState,
0 commit comments