Skip to content

Commit c8f9806

Browse files
authored
refactor: StrawLineSeeder - Use forwarding in constructor & minor clean (#4884)
PLEASE DESCRIBE YOUR CHANGES. THIS MESSAGE ENDS UP AS THE COMMIT MESSAGE. DO NOT USE @-MENTIONS HERE!
1 parent 2922783 commit c8f9806

File tree

4 files changed

+106
-65
lines changed

4 files changed

+106
-65
lines changed

Core/include/Acts/Seeding/CompositeSpacePointLineSeeder.hpp

Lines changed: 44 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,12 @@ concept CompositeSpacePointSeedFiller =
4343
/// @param t0: Offse in the time of arrival of the particle
4444
/// @param testSp: Reference to the straw space point to test
4545
{
46-
filler.candidatePull(cctx, pos, dir, t0, testSp)
46+
filler.candidateChi2(cctx, pos, dir, t0, testSp)
4747
} -> std::same_as<double>;
48+
/// @brief Returns the radius of the straw tube in which the space point
49+
/// is recorded
50+
/// @param testSp: Reference to the straw space point
51+
{ filler.strawRadius(testSp) } -> std::same_as<double>;
4852
/// @brief Creates a new empty container to construct a new segment seed
4953
/// @param cctx: Calibration context in case that the container shall be
5054
/// part of a predefined memory block
@@ -81,8 +85,7 @@ concept CompositeSpacePointSeedFiller =
8185
/// the following attributes
8286
///
8387
/// using SpVec_t = Standard container satisfiyng the
84-
/// CompositeSpacePointContainer concept
85-
///
88+
/// CompositeSpacePointContainer concept
8689
///
8790
/// const std::vector<SpVec_t>& strawHits();
8891
/// const std::vector<SpVec_t>& stripHits();
@@ -101,6 +104,8 @@ concept CompositeSpacePointSorter =
101104
} -> std::same_as<const std::vector<SpacePointCont_t>&>;
102105
};
103106

107+
/// @brief Concept of the interface for the auxiliary class such that the
108+
/// CompositeSpacePointLineSeeder can construct segment seeds
104109
template <typename SeedAuxiliary_t, typename UnCalibCont_t,
105110
typename CalibCont_t>
106111
concept CompSpacePointSeederDelegate =
@@ -131,21 +136,36 @@ concept CompSpacePointSeederDelegate =
131136
/// compatible strip measurements from each strip layer are added.
132137
class CompositeSpacePointLineSeeder {
133138
public:
139+
/// @brief Use the assignment of the parameter indices from the CompSpacePointAuxiliaries
140+
using ParIdx = detail::CompSpacePointAuxiliaries::FitParIndex;
141+
/// @brief Use the assignment of the parameter indices from the CompSpacePointAuxiliaries
142+
using CovIdx = detail::CompSpacePointAuxiliaries::ResidualIdx;
143+
/// @brief Use the vector from the CompSpacePointAuxiliaires
144+
using Vector = detail::CompSpacePointAuxiliaries::Vector;
145+
/// @brief Vector containing the 5 straight segment line parameters
146+
using SeedParam_t = std::array<double, toUnderlying(ParIdx::nPars)>;
147+
/// @brief Abrivation of the straight line. The first element is the
148+
/// reference position and the second element is the direction
149+
using Line_t = std::pair<Vector, Vector>;
150+
134151
/// @brief Configuration of the cuts to sort out generated
135152
/// seeds with poor quality.
136153
struct Config {
137154
/// @brief Cut on the theta angle
138-
std::array<double, 2> thetaRange{0, 0};
155+
std::array<double, 2> thetaRange{0., 0.};
139156
/// @brief Cut on the intercept range
140-
std::array<double, 2> interceptRange{0, 0};
141-
157+
std::array<double, 2> interceptRange{0., 0.};
142158
/// @brief Upper cut on the hit chi2 w.r.t. seed in order to be associated to the seed
143159
double hitPullCut{5.};
144160
/// @brief How many drift circles may be on a layer to be used for seeding
145161
std::size_t busyLayerLimit{2};
146162
/// @brief Layers may contain measurements with bad hits and hence the
147163
bool busyLimitCountGood{true};
148-
164+
/// @brief Try at the first time the external seed parameters as candidate
165+
bool startWithPattern{false};
166+
/// @brief Use explicitly the line distance and the driftRadius to calculate
167+
/// the pull from the seed line to the space point.
168+
bool useSimpleStrawPull{true};
149169
/// @brief How many drift circle hits needs the seed to contain in order to be valid
150170
std::size_t nStrawHitCut{3};
151171
/// @brief Hit cut based on the fraction of collected tube layers.
@@ -167,15 +187,6 @@ class CompositeSpacePointLineSeeder {
167187
"CompositeSpacePointLineSeeder", Logging::Level::INFO));
168188
/// @brief Return the configuration object of the seeder
169189
const Config& config() const { return m_cfg; }
170-
/// @brief Use the assignment of the parameter indices from the CompSpacePointAuxiliaries
171-
using ParIdx = detail::CompSpacePointAuxiliaries::FitParIndex;
172-
/// @brief Use the vector from the CompSpacePointAuxiliaires
173-
using Vector = detail::CompSpacePointAuxiliaries::Vector;
174-
/// @brief Vector containing the 5 straight segment line parameters
175-
using SeedParam_t = std::array<double, toUnderlying(ParIdx::nPars)>;
176-
/// @brief Abrivation of the straight line. The first element is the
177-
/// reference position and the second element is the direction
178-
using Line_t = std::pair<Vector, Vector>;
179190

180191
/// @brief Enumeration to pick one of the four tangent lines to
181192
/// the straw circle pair.
@@ -325,14 +336,16 @@ class CompositeSpacePointLineSeeder {
325336
detail::CompSpacePointSeederDelegate<UncalibCont_t, CalibCont_t>
326337
Delegate_t>
327338
struct SeedingState : public Delegate_t {
328-
/// @brief Use all constructors from the base class for this one as well
329-
using Delegate_t::Delegate_t;
330-
/// @brief radius of the straw tubes used to reject hits outside the tube
331-
double strawRadius{0.};
332-
/// @brief Try at the first time the external seed parameters as candidate
333-
bool startWithPattern{false};
334-
/// @brief Estimated parameters from pattern
335-
SeedParam_t patternParams{};
339+
/// @brief Declare the public constructor by explicitly forwarding the
340+
/// constructor arguments to the (protected) base class constructor
341+
/// @param initialPars: Initial parameters from an external pattern seed
342+
/// (Needed to combine the precision parameters with a
343+
/// non-precision estimate)
344+
/// @param args: Arguments to be forwarded to the base class constructor
345+
template <typename... args_t>
346+
explicit SeedingState(const SeedParam_t& initialPars, args_t&&... args)
347+
: Delegate_t{std::forward<args_t>(args)...},
348+
m_initialPars{initialPars} {}
336349
/// @brief Stringstream output operator
337350
friend std::ostream& operator<<(std::ostream& ostr,
338351
const SeedingState& opts) {
@@ -341,6 +354,8 @@ class CompositeSpacePointLineSeeder {
341354
}
342355
/// @brief Return the number of generated seeds
343356
std::size_t nGenSeeds() const { return m_seenSolutions.size(); }
357+
/// @brief Returns the pattern parameters
358+
const SeedParam_t& initialParameters() const { return m_initialPars; }
344359
/// @brief Grant the embedding class access to the private members
345360
friend CompositeSpacePointLineSeeder;
346361

@@ -361,8 +376,13 @@ class CompositeSpacePointLineSeeder {
361376
std::size_t m_nStrawCut{0ul};
362377
/// @brief Flag toggling whether the upper of the lower layer shall be moved
363378
bool m_moveUpLayer{true};
379+
/// @brief Flag toggling whether the pattern parameters shall be returned as
380+
/// first seed
381+
bool m_patternSeedProduced{false};
364382
/// @brief Prints the seed solution to the screen
365383
void print(std::ostream& ostr) const;
384+
/// @brief Estimated parameters from pattern
385+
SeedParam_t m_initialPars{};
366386
};
367387
/// @brief Main interface method provided by the SeederClass. The user instantiates
368388
/// a SeedingState object containing all the straw hit candidates from

Core/include/Acts/Seeding/CompositeSpacePointLineSeeder.ipp

Lines changed: 42 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ CompositeSpacePointLineSeeder::TwoCircleTangentPars
2424
CompositeSpacePointLineSeeder::constructTangentLine(const Sp_t& topHit,
2525
const Sp_t& bottomHit,
2626
const TangentAmbi ambi) {
27-
using ResidualIdx = detail::CompSpacePointAuxiliaries::ResidualIdx;
2827
using namespace Acts::UnitLiterals;
2928
using namespace Acts::detail;
3029
TwoCircleTangentPars result{};
@@ -46,9 +45,9 @@ CompositeSpacePointLineSeeder::constructTangentLine(const Sp_t& topHit,
4645
const double dZ = D.dot(eZ);
4746

4847
const double thetaTubes = std::atan2(dY, dZ);
49-
const double distTubes = Acts::fastHypot(dY, dZ);
48+
const double distTubes = fastHypot(dY, dZ);
5049
assert(distTubes > 1._mm);
51-
constexpr auto covIdx = Acts::toUnderlying(ResidualIdx::bending);
50+
constexpr auto covIdx = toUnderlying(CovIdx::bending);
5251
const double combDriftUncert{topHit.covariance()[covIdx] +
5352
bottomHit.covariance()[covIdx]};
5453
const double R =
@@ -170,8 +169,8 @@ void CompositeSpacePointLineSeeder::SeedingState<
170169
<< toString(encodeAmbiguity(s_signCombo[m_signComboIndex][0],
171170
s_signCombo[m_signComboIndex][1]))
172171
<< "\n";
173-
ostr << " start with pattern " << startWithPattern << " nGenSeeds "
174-
<< nGenSeeds() << " nStrawCut " << m_nStrawCut << "\n";
172+
ostr << "Number of seeds " << nGenSeeds() << " nStrawCut " << m_nStrawCut
173+
<< "\n";
175174
if (nGenSeeds() > 0ul) {
176175
for (const auto& seen : m_seenSolutions) {
177176
ostr << "################################################" << std::endl;
@@ -288,17 +287,18 @@ CompositeSpacePointLineSeeder::nextSeed(
288287
state.m_nStrawCut = m_cfg.nStrawHitCut;
289288
/// Check whether the seeding can start with the external pattern
290289
/// parameters
291-
if (state.startWithPattern &&
292-
std::ranges::any_of(strawLayers, [&](const UncalibCont_t& layerHits) {
293-
return countHits(layerHits, selector) > m_cfg.busyLayerLimit;
294-
})) {
295-
state.startWithPattern = false;
290+
if (!state.m_patternSeedProduced &&
291+
(!m_cfg.startWithPattern ||
292+
std::ranges::any_of(strawLayers, [&](const UncalibCont_t& layerHits) {
293+
return countHits(layerHits, selector) > m_cfg.busyLayerLimit;
294+
}))) {
295+
state.m_patternSeedProduced = true;
296296
}
297-
if (state.startWithPattern) {
298-
SegmentSeed<CalibCont_t> patternSeed{state.patternParams,
297+
if (!state.m_patternSeedProduced) {
298+
SegmentSeed<CalibCont_t> patternSeed{state.initialParameters(),
299299
state.newContainer(cctx)};
300300

301-
const auto [pos, dir] = makeLine(state.patternParams);
301+
const auto [pos, dir] = makeLine(state.initialParameters());
302302
const double t0 = patternSeed.parameters[toUnderlying(ParIdx::t0)];
303303

304304
auto append = [&](const StrawLayers_t<UncalibCont_t>& hitLayers) {
@@ -310,7 +310,7 @@ CompositeSpacePointLineSeeder::nextSeed(
310310
};
311311
append(strawLayers);
312312
append(state.stripHits());
313-
state.startWithPattern = false;
313+
state.m_patternSeedProduced = true;
314314
return patternSeed;
315315
}
316316
ACTS_DEBUG(__func__ << "() " << __LINE__ << " - Instantiate layers. ");
@@ -450,10 +450,6 @@ CompositeSpacePointLineSeeder::buildSeed(
450450

451451
ACTS_DEBUG(__func__ << "() " << __LINE__ << " - Try to draw new seed from \n"
452452
<< state << ".");
453-
if (state.strawRadius <= Acts::s_epsilon) {
454-
throw std::invalid_argument(
455-
"buildSeed() - Please configure the state's strawRadius");
456-
}
457453
const auto& upperHit =
458454
*strawLayers.at(state.m_upperLayer.value()).at(state.m_upperHitIndex);
459455
const auto& lowerHit =
@@ -484,7 +480,7 @@ CompositeSpacePointLineSeeder::buildSeed(
484480
return std::nullopt;
485481
}
486482
/// Continue to construct a new solution
487-
const double t0 = state.patternParams[toUnderlying(ParIdx::t0)];
483+
const double t0 = state.initialParameters()[toUnderlying(ParIdx::t0)];
488484
SeedSolution<UncalibCont_t, Delegate_t> newSolution{seedPars, state};
489485

490486
ACTS_DEBUG(__func__ << "() " << __LINE__
@@ -493,6 +489,9 @@ CompositeSpacePointLineSeeder::buildSeed(
493489
const Line_t tangentSeed{seedPars.y0 * Vector3::UnitY(),
494490
makeDirection(lowerHit, seedPars.theta)};
495491
const auto& [seedPos, seedDir] = tangentSeed;
492+
const double maxPullSq{Acts::square(m_cfg.hitPullCut)};
493+
constexpr auto covIdx = Acts::toUnderlying(CovIdx::bending);
494+
496495
for (const auto& [layerNr, hitsInLayer] :
497496
Acts::enumerate(state.strawHits())) {
498497
bool hadGoodHit{false};
@@ -504,17 +503,28 @@ CompositeSpacePointLineSeeder::buildSeed(
504503
// the hits are ordered in the layer so we assume that once we found good
505504
// hits we are moving away from the seed line so we can abort the hit
506505
// association
507-
if (distance < state.strawRadius &&
508-
state.candidatePull(cctx, seedPos, seedDir, t0, *testMe) <
509-
Acts::pow(m_cfg.hitPullCut, 2u)) {
510-
ACTS_VERBOSE(__func__ << "() " << __LINE__ << " - layer,hit = ("
511-
<< layerNr << "," << hitNr
512-
<< ") -> spacePoint: " << Acts::toString(*testMe)
513-
<< " is close enough: " << distance);
514-
hadGoodHit = true;
515-
newSolution.append(layerNr, hitNr);
516-
newSolution.nStrawHits += selector(*testMe);
517-
continue;
506+
const double rMax = state.strawRadius(*testMe);
507+
assert(rMax > Acts::s_epsilon);
508+
assert(testMe->covariance()[covIdx] > Acts::s_epsilon);
509+
if (distance < rMax) {
510+
const double pullSq =
511+
m_cfg.useSimpleStrawPull
512+
? Acts::square(distance - Acts::abs(testMe->driftRadius())) /
513+
testMe->covariance()[covIdx]
514+
: state.candidateChi2(cctx, seedPos, seedDir, t0, *testMe);
515+
516+
if (pullSq < maxPullSq) {
517+
ACTS_VERBOSE(__func__
518+
<< "() " << __LINE__ << " - layer,hit = (" << layerNr
519+
<< "," << hitNr
520+
<< ") -> spacePoint: " << Acts::toString(*testMe)
521+
<< " is close enough: " << distance
522+
<< ", pull: " << std::sqrt(pullSq));
523+
hadGoodHit = true;
524+
newSolution.append(layerNr, hitNr);
525+
newSolution.nStrawHits += selector(*testMe);
526+
continue;
527+
}
518528
}
519529
if (hadGoodHit) {
520530
break;
@@ -539,7 +549,7 @@ CompositeSpacePointLineSeeder::consructSegmentSeed(
539549
ACTS_DEBUG(__func__ << "() " << __LINE__ << " Construct new seed from \n"
540550
<< newSolution);
541551
SegmentSeed<CalibCont_t> finalSeed{
542-
combineWithPattern(tangentSeed, state.patternParams),
552+
combineWithPattern(tangentSeed, state.initialParameters()),
543553
state.newContainer(cctx)};
544554
const auto [seedPos, seedDir] = makeLine(finalSeed.parameters);
545555
/// Append the collected straws to the seed
@@ -561,7 +571,7 @@ CompositeSpacePointLineSeeder::consructSegmentSeed(
561571
/// Find the hit with the lowest pull
562572
for (const auto& [hitIdx, testMe] : Acts::enumerate(stripLayerHits)) {
563573
const double chi2 =
564-
state.candidatePull(cctx, seedPos, seedDir, t0, *testMe);
574+
state.candidateChi2(cctx, seedPos, seedDir, t0, *testMe);
565575
if (testMe->measuresLoc0() && chi2 < bestChi2Loc0) {
566576
bestChi2Loc0 = chi2;
567577
bestIdxLoc0 = hitIdx;

Tests/UnitTests/Core/Seeding/StrawHitGeneratorHelper.hpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,10 @@ static_assert(
391391

392392
/// @brief Split the composite space point container into straw and strip measurements
393393
class SpSorter {
394-
public:
394+
protected:
395+
/// @brief Protected constructor to instantiate the SpSorter.
396+
/// @param hits: List of space points to sort per layer
397+
/// @param calibrator: Space point calibrator to recalibrate the hits
395398
SpSorter(const Container_t& hits, const SpCalibrator* calibrator)
396399
: m_calibrator{calibrator} {
397400
for (const auto& spPtr : hits) {
@@ -402,9 +405,14 @@ class SpSorter {
402405
pushMe[spPtr->layer()].push_back(spPtr);
403406
}
404407
}
408+
409+
public:
410+
/// @brief Return the sorted straw hits
405411
const std::vector<Container_t>& strawHits() const { return m_straws; }
412+
/// @brief Returns the sorted strip hits
406413
const std::vector<Container_t>& stripHits() const { return m_strips; }
407-
414+
/// @brief Returns whether the candidate space point is a good hit or not
415+
/// @param testPoint: Hit to test
408416
bool goodCandidate(const FitTestSpacePoint& testPoint) const {
409417
return testPoint.isGood();
410418
}
@@ -417,7 +425,7 @@ class SpSorter {
417425
/// @param dir: Direction of the candidate seed line
418426
/// @param t0: Offse in the time of arrival of the particle
419427
/// @param testSp: Reference to the straw space point to test
420-
double candidatePull(const CalibrationContext& /* cctx*/, const Vector3& pos,
428+
double candidateChi2(const CalibrationContext& /* cctx*/, const Vector3& pos,
421429
const Vector3& dir, const double /*t0*/,
422430
const FitTestSpacePoint& testSp) const {
423431
return CompSpacePointAuxiliaries::chi2Term(pos, dir, testSp);
@@ -440,6 +448,9 @@ class SpSorter {
440448
const std::size_t upperLayer) const {
441449
return lowerLayer >= upperLayer;
442450
}
451+
double strawRadius(const FitTestSpacePoint& /*testSp*/) const {
452+
return 15._mm;
453+
}
443454

444455
private:
445456
const SpCalibrator* m_calibrator{nullptr};

Tests/UnitTests/Core/Seeding/StrawLineSeederTest.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -67,13 +67,13 @@ void testSeeder(RandomEngine& engine, TFile& outFile) {
6767
using SeedState_t =
6868
CompositeSpacePointLineSeeder::SeedingState<Container_t, Container_t,
6969
SpSorter>;
70-
SeedState_t seedOpts{testTubes, calibrator.get()};
71-
seedOpts.strawRadius = 15._mm;
72-
ACTS_DEBUG(seedOpts);
70+
SeedState_t seedState{startParameters(line, testTubes), testTubes,
71+
calibrator.get()};
72+
ACTS_DEBUG(seedState);
7373
nSeeds = 0;
7474
CalibrationContext cctx{};
75-
while (auto seed = seeder.nextSeed(cctx, seedOpts)) {
76-
ACTS_DEBUG("Seed finder loop " << seedOpts);
75+
while (auto seed = seeder.nextSeed(cctx, seedState)) {
76+
ACTS_DEBUG("Seed finder loop " << seedState);
7777
if (seed == std::nullopt) {
7878
break;
7979
}
@@ -192,7 +192,7 @@ BOOST_AUTO_TEST_CASE(SeedTangents) {
192192
Seeder::constructTangentLine(topTube, bottomTube, trueAmbi);
193193
/// Construct line parameters
194194
ACTS_DEBUG(__func__
195-
<< "() " << __LINE__ << " - Line tan theta: " << lineTanBeta
195+
<< "() " << __LINE__ << " - Line tan beta: " << lineTanBeta
196196
<< ", reconstructed tan theta: " << std::tan(seedPars.theta)
197197
<< ", line y0: " << lineY0
198198
<< ", reconstructed y0: " << seedPars.y0);

0 commit comments

Comments
 (0)