Skip to content

Commit 328d5b6

Browse files
authored
fix: CompositeSpacePointLineFitter - Add forgotten parameter boundary check (acts-project#4707)
- Implement the parameter boundary checks post update step - Fix fast fit for straw measurements - Minor doxygen improvements
1 parent 5be6fe0 commit 328d5b6

File tree

2 files changed

+55
-33
lines changed

2 files changed

+55
-33
lines changed

Core/include/Acts/Seeding/CompositeSpacePointLineFitter.hpp

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -86,15 +86,6 @@ class CompositeSpacePointLineFitter {
8686
using RangeArray = std::array<std::array<double, 2>, s_nPars>;
8787
RangeArray ranges{};
8888
};
89-
90-
/// @brief Class constructor
91-
/// @param cfg Reference to the fitter configuration object
92-
/// @param logger
93-
explicit CompositeSpacePointLineFitter(
94-
const Config& cfg,
95-
std::unique_ptr<const Logger> logger = getDefaultLogger(
96-
"CompositeSpacePointLineFitter", Logging::Level::INFO));
97-
9889
/// @brief Auxiliary object to store the fitted parameters, covariance,
9990
/// the chi2 / nDoF & the number of required iterations
10091
struct FitParameters {
@@ -162,6 +153,16 @@ class CompositeSpacePointLineFitter {
162153
/// @brief Standard constructor
163154
FitOptions() = default;
164155
};
156+
157+
/// @brief Class constructor
158+
/// @param cfg Reference to the fitter configuration object
159+
/// @param logger Logger object used for debug print out
160+
explicit CompositeSpacePointLineFitter(
161+
const Config& cfg,
162+
std::unique_ptr<const Logger> logger = getDefaultLogger(
163+
"CompositeSpacePointLineFitter", Logging::Level::INFO));
164+
/// @brief Returns the instantiated configuration object
165+
const Config& config() const { return m_cfg; }
165166
/// @brief Counts how many measurements measure loc0, loc1 & time
166167
/// @param measurements: Collection of composite space points of interest
167168
template <CompositeSpacePointContainer Cont_t>
@@ -180,7 +181,9 @@ class CompositeSpacePointLineFitter {
180181
/// nonBending, bending & time
181182
static std::vector<FitParIndex> extractFitablePars(
182183
const std::array<std::size_t, 3>& hitCounts);
183-
184+
/// @brief Fit a line to a set of Composite space point measurements.
185+
/// @param fitOpts: Auxiliary object carrying all necessary input
186+
/// needed to execute the fit
184187
template <CompositeSpacePointContainer Cont_t,
185188
CompositeSpacePointCalibrator<Cont_t, Cont_t> Calibrator_t>
186189
FitResult<Cont_t> fit(FitOptions<Cont_t, Calibrator_t>&& fitOpts) const;
@@ -206,7 +209,7 @@ class CompositeSpacePointLineFitter {
206209
template <CompositeSpacePointContainer Cont_t>
207210
FitParameters fastFit(const Cont_t& measurements, const Line_t& initialGuess,
208211
const std::vector<FitParIndex>& parsToUse) const;
209-
212+
/// @brief Abrivation of the fit result returned by the FastStrawLineFitter
210213
using FastFitResult = std::optional<detail::FastStrawLineFitter::FitResult>;
211214

212215
/// @brief Executes the fast line fit in the bending direction. Returns

Core/include/Acts/Seeding/CompositeSpacePointLineFitter.ipp

Lines changed: 41 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ std::array<std::size_t, 3> CompositeSpacePointLineFitter::countDoF(
3131
std::size_t nValid{0};
3232
for (const auto& sp : measurements) {
3333
if (selector.connected() && !selector(*sp)) {
34+
ACTS_VERBOSE(__func__ << "() " << __LINE__
35+
<< " - Skip invalid measurement @"
36+
<< toString(sp->localPosition()));
37+
3438
continue;
3539
}
3640
++nValid;
@@ -96,9 +100,9 @@ CompositeSpacePointLineFitter::fastPrecFit(
96100
precResult->nIter += swappedPrecResult->nIter;
97101
ACTS_DEBUG(__func__ << "() " << __LINE__ << " - Fit did not improve "
98102
<< (*swappedPrecResult));
99-
return precResult;
100103
}
101104
}
105+
return precResult;
102106
}
103107
using ResidualIdx = detail::CompSpacePointAuxiliaries::ResidualIdx;
104108
return m_fastFitter.fit(measurements, ResidualIdx::bending);
@@ -300,7 +304,7 @@ CompositeSpacePointLineFitter::fit(
300304
double driftV{0.};
301305
double driftA{0.};
302306
// Calculate the residual & derivatives
303-
if (resCfg.parsToUse.back() == FitParIndex::t0) {
307+
if (pullCalculator.config().parsToUse.back() == FitParIndex::t0) {
304308
pullCalculator.updateFullResidual(line, t0, *spacePoint, driftV,
305309
driftA);
306310
} else {
@@ -313,37 +317,51 @@ CompositeSpacePointLineFitter::fit(
313317
result.chi2 = cache.chi2;
314318
// Now update the parameters
315319
UpdateStep update{UpdateStep::goodStep};
316-
switch (resCfg.parsToUse.size()) {
320+
switch (pullCalculator.config().parsToUse.size()) {
317321
// 2D fit (intercept + inclination angle)
318322
case 2: {
319-
update = updateParameters<2>(resCfg.parsToUse.front(), cache,
320-
result.parameters);
323+
update = updateParameters<2>(pullCalculator.config().parsToUse.front(),
324+
cache, result.parameters);
321325
break;
322326
}
323327
// 2D fit + time
324328
case 3: {
325-
update = updateParameters<3>(resCfg.parsToUse.front(), cache,
326-
result.parameters);
329+
update = updateParameters<3>(pullCalculator.config().parsToUse.front(),
330+
cache, result.parameters);
327331
break;
328332
}
329333
// 3D spatial fit (x0, y0, theta, phi)
330334
case 4: {
331-
update = updateParameters<4>(resCfg.parsToUse.front(), cache,
332-
result.parameters);
335+
update = updateParameters<4>(pullCalculator.config().parsToUse.front(),
336+
cache, result.parameters);
333337
break;
334338
}
335339
// full fit
336340
case 5: {
337-
update = updateParameters<5>(resCfg.parsToUse.front(), cache,
338-
result.parameters);
341+
update = updateParameters<5>(pullCalculator.config().parsToUse.front(),
342+
cache, result.parameters);
339343
break;
340344
}
341345
default:
342346
ACTS_WARNING(__func__ << "() " << __LINE__
343347
<< ": Invalid parameter size "
344-
<< resCfg.parsToUse.size());
348+
<< pullCalculator.config().parsToUse.size());
345349
return result;
346350
}
351+
/// Check whether the fit parameters are within range
352+
for (const FitParIndex par : pullCalculator.config().parsToUse) {
353+
const auto p = toUnderlying(par);
354+
if (m_cfg.ranges[p][0] < m_cfg.ranges[p][1] &&
355+
(result.parameters[p] < m_cfg.ranges[p][0] ||
356+
result.parameters[p] > m_cfg.ranges[p][1])) {
357+
ACTS_VERBOSE(__func__ << "() " << __LINE__ << ": The parameter "
358+
<< pullCalculator.parName(par) << " "
359+
<< result.parameters[p] << " is out range ["
360+
<< m_cfg.ranges[p][0] << ";" << m_cfg.ranges[p][1]
361+
<< "]");
362+
update = UpdateStep::outOfBounds;
363+
}
364+
}
347365
switch (update) {
348366
using enum UpdateStep;
349367
case converged: {
@@ -361,7 +379,8 @@ CompositeSpacePointLineFitter::fit(
361379
// Parameters converged
362380
if (result.converged) {
363381
const auto doF = countDoF(result.measurements, fitOpts.selector);
364-
result.nDoF = (doF[0] + doF[1] + doF[2]) - resCfg.parsToUse.size();
382+
result.nDoF =
383+
(doF[0] + doF[1] + doF[2]) - pullCalculator.config().parsToUse.size();
365384
line.updateParameters(result.parameters);
366385
const double t0 = result.parameters[toUnderlying(FitParIndex::t0)];
367386
// Recalibrate the measurements before returning
@@ -370,29 +389,29 @@ CompositeSpacePointLineFitter::fit(
370389
result.measurements);
371390

372391
// Assign the Hessian
373-
switch (resCfg.parsToUse.size()) {
392+
switch (pullCalculator.config().parsToUse.size()) {
374393
// 2D fit (intercept + inclination angle)
375394
case 2: {
376-
fillCovariance<2>(resCfg.parsToUse.front(), cache.hessian,
377-
result.covariance);
395+
fillCovariance<2>(pullCalculator.config().parsToUse.front(),
396+
cache.hessian, result.covariance);
378397
break;
379398
}
380399
// 2D fit + time
381400
case 3: {
382-
fillCovariance<3>(resCfg.parsToUse.front(), cache.hessian,
383-
result.covariance);
401+
fillCovariance<3>(pullCalculator.config().parsToUse.front(),
402+
cache.hessian, result.covariance);
384403
break;
385404
}
386405
// 3D spatial fit (x0, y0, theta, phi)
387406
case 4: {
388-
fillCovariance<4>(resCfg.parsToUse.front(), cache.hessian,
389-
result.covariance);
407+
fillCovariance<4>(pullCalculator.config().parsToUse.front(),
408+
cache.hessian, result.covariance);
390409
break;
391410
}
392411
// full fit
393412
case 5: {
394-
fillCovariance<5>(resCfg.parsToUse.front(), cache.hessian,
395-
result.covariance);
413+
fillCovariance<5>(pullCalculator.config().parsToUse.front(),
414+
cache.hessian, result.covariance);
396415
break;
397416
}
398417
// No need to warn here -> captured by the fit iterations

0 commit comments

Comments
 (0)