Skip to content

Commit 3967853

Browse files
refactor: Change transformCoordinates to avoid recalculation of variables in Seedfinder (acts-project#1831)
This PR tries to optimise SeedFinder by removing unnecessary calculations
1 parent b4773cf commit 3967853

File tree

6 files changed

+176
-82
lines changed

6 files changed

+176
-82
lines changed

Core/include/Acts/Seeding/SeedFilterConfig.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ struct SeedFilterConfig {
5656

5757
// maximum number of lower quality seeds in seed confirmation
5858
std::size_t maxSeedsPerSpMConf = std::numeric_limits<std::size_t>::max();
59-
// maximum number of quality seeds for each middle-bottom SP-duplet in seed
59+
// maximum number of quality seeds for each middle-bottom SP-dublet in seed
6060
// confirmation if the limit is reached we check if there is a lower quality
6161
// seed to be replaced
6262
std::size_t maxQualitySeedsPerSpMConf =

Core/include/Acts/Seeding/SeedFinder.hpp

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -128,16 +128,36 @@ class SeedFinder {
128128
const sp_range_t& topSPs) const;
129129

130130
private:
131+
/// Iterates over dublets and tests the compatibility between them by applying
132+
/// a series of cuts that can be tested with only two SPs
133+
/// @param spacePointData object contaning the spacepoint data
134+
/// @param options frequently changing configuration (like beam position)
135+
/// @param grid spacepoint grid
136+
/// @param otherSPsNeighbours inner or outer space points to be used in the dublet
137+
/// @param mediumSP space point candidate to be used as middle SP in a seed
138+
/// @param linCircleVec vector contining inner or outer SP parameters after reference frame transformation to the u-v space
139+
/// @param outVec Output object containing top or bottom SPs that are compatible with a certain middle SPs
140+
/// @param deltaRMinSP minimum allowed r-distance between dublet components
141+
/// @param deltaRMaxSP maximum allowed r-distance between dublet components
142+
/// @param isBottom wheter otherSPs contains outer or inner SPs
131143
template <typename out_range_t>
132144
void getCompatibleDoublets(
145+
Acts::SpacePointData& spacePointData,
133146
const Acts::SeedFinderOptions& options,
134147
const Acts::SpacePointGrid<external_spacepoint_t>& grid,
135-
boost::container::small_vector<Acts::Neighbour<external_spacepoint_t>, 9>&
136-
otherSPs,
148+
boost::container::small_vector<Neighbour<external_spacepoint_t>, 9>&
149+
otherSPsNeighbours,
137150
const InternalSpacePoint<external_spacepoint_t>& mediumSP,
138-
out_range_t& outVec, const float& deltaRMinSP, const float& deltaRMaxSP,
139-
bool isBottom) const;
151+
std::vector<LinCircle>& linCircleVec, out_range_t& outVec,
152+
const float& deltaRMinSP, const float& deltaRMaxSP, bool isBottom) const;
140153

154+
/// Iterates over the seed candidates tests the compatibility between three
155+
/// SPs and calls for the seed confirmation
156+
/// @param spacePointData object contaning the spacepoint data
157+
/// @param SpM space point candidate to be used as middle SP in a seed
158+
/// @param options frequently changing configuration (like beam position)
159+
/// @param seedFilterState State object that holds memory used in SeedFilter
160+
/// @param state State object that holds memory used
141161
void filterCandidates(Acts::SpacePointData& spacePointData,
142162
const InternalSpacePoint<external_spacepoint_t>& SpM,
143163
const Acts::SeedFinderOptions& options,

Core/include/Acts/Seeding/SeedFinder.ipp

Lines changed: 90 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -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>
175179
template <typename out_range_t>
176180
inline void
177181
SeedFinder<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

298361
template <typename external_spacepoint_t, typename platform_t>
299-
300362
inline 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,

Core/include/Acts/Seeding/SeedFinderOrthogonal.ipp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ bool SeedFinderOrthogonal<external_spacepoint_t>::validTuple(
169169
}
170170

171171
/*
172-
* Cut: Ensure that the origin of the duplet (the intersection of the line
172+
* Cut: Ensure that the origin of the dublet (the intersection of the line
173173
* between them with the z axis) lies within the collision region.
174174
*/
175175
float zOrigin = zL - rL * cotTheta;
@@ -335,7 +335,6 @@ void SeedFinderOrthogonal<external_spacepoint_t>::filterCandidates(
335335
}
336336

337337
auto lb = linCircleBottom[b];
338-
seedFilterState.zOrigin = lb.Zo;
339338
float cotThetaB = lb.cotTheta;
340339
float Vb = lb.V;
341340
float Ub = lb.U;
@@ -476,6 +475,8 @@ void SeedFinderOrthogonal<external_spacepoint_t>::filterCandidates(
476475
continue;
477476
}
478477

478+
seedFilterState.zOrigin = middle.z() - rM * lb.cotTheta;
479+
479480
m_config.seedFilter->filterSeeds_2SpFixed(
480481
spacePointData, *bottom[b], middle, top_valid, curvatures,
481482
impactParameters, seedFilterState, candidates_collector);
@@ -498,7 +499,7 @@ void SeedFinderOrthogonal<external_spacepoint_t>::processFromMiddleSP(
498499
* bottom_lh_v denotes the candidates bottom seed points, assuming that the
499500
* track has monotonically _increasing_ z position. bottom_hl_v denotes the
500501
* candidate bottom points assuming that the track has monotonically
501-
* _decreaing_ z position. top_lh_v are the candidate top points for an
502+
* _decreasing_ z position. top_lh_v are the candidate top points for an
502503
* increasing z track, and top_hl_v are the candidate top points for a
503504
* decreasing z track.
504505
*/

Core/include/Acts/Seeding/SeedFinderUtils.hpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,13 @@
1616
namespace Acts {
1717
/// @brief A partial description of a circle in u-v space.
1818
struct LinCircle {
19-
float Zo;
2019
float cotTheta;
2120
float iDeltaR;
2221
float Er;
2322
float U;
2423
float V;
2524
float x;
2625
float y;
27-
float z;
28-
float r;
2926
};
3027

3128
/// @brief Transform two spacepoints to a u-v space circle.
@@ -57,7 +54,6 @@ LinCircle transformCoordinates(const external_spacepoint_t& sp,
5754
/// @param[in] spM The middle spacepoint.
5855
/// @param[in] bottom Should be true if vec are bottom spacepoints.
5956
/// @param[out] linCircleVec The output vector to write to.
60-
/// @returns Vector of sorted indexes for the vectors (vec and linCircleVec)
6157
template <typename external_spacepoint_t>
6258
void transformCoordinates(
6359
Acts::SpacePointData& spacePointData,
@@ -72,6 +68,12 @@ void transformCoordinates(Acts::SpacePointData& spacePointData,
7268
std::vector<LinCircle>& linCircleVec,
7369
callable_t&& extractFunction);
7470

71+
/// @brief Fills LineCircle object for a SP dublet in u-v frame.
72+
///
73+
/// @param[in] lineCircleVariables Vector contaning LineCircle variables
74+
inline LinCircle fillLineCircle(
75+
const std::array<float, 7>& lineCircleVariables);
76+
7577
/// @brief Check the compatibility of spacepoint coordinates in xyz assuming the Bottom-Middle direction with the strip meassument details
7678
///
7779
/// @tparam external_spacepoint_t The external spacepoint type.

0 commit comments

Comments
 (0)