Skip to content

Commit

Permalink
refactor: Allow track selection without reference surface (#3791)
Browse files Browse the repository at this point in the history
Adds a flag to allow track selection without reference surface, which is off by default. Also refactors the track selector config handling in python to avoid that different uses get out of sync.

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
	- Introduced a new configuration option, `requireReferenceSurface`, for track validation, enhancing track selection flexibility.
	- Added a function, `trackSelectorDefaultKWArgs`, to streamline track selection parameter configuration.

- **Improvements**
	- Refactored track validation logic for improved clarity and separation of concerns.
	- Enhanced configurability of track selection and seeding algorithms, allowing for more adaptable configurations.
	- Updated default values in the `TrackSelectorConfig` to accommodate the new field.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
  • Loading branch information
benjaminhuth authored Nov 27, 2024
1 parent 0c5aacc commit 9173bb4
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 59 deletions.
47 changes: 31 additions & 16 deletions Core/include/Acts/TrackFinding/TrackSelector.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ class TrackSelector {
std::size_t maxSharedHits = std::numeric_limits<std::size_t>::max();
double maxChi2 = inf;

/// Whether a reference surface is required for the track
/// If false, the parameter cuts are not evaluated
bool requireReferenceSurface = true;

// Defaults to: no cut
MeasurementCounter measurementCounter;

Expand Down Expand Up @@ -447,22 +451,33 @@ bool TrackSelector::isValidTrack(const track_proxy_t& track) const {

const Config& cuts = *cutsPtr;

return track.hasReferenceSurface() &&
within(track.transverseMomentum(), cuts.ptMin, cuts.ptMax) &&
(!m_isUnbinned || (within(absEta(), cuts.absEtaMin, cuts.absEtaMax) &&
within(_eta, cuts.etaMin, cuts.etaMax))) &&
within(track.phi(), cuts.phiMin, cuts.phiMax) &&
within(track.loc0(), cuts.loc0Min, cuts.loc0Max) &&
within(track.loc1(), cuts.loc1Min, cuts.loc1Max) &&
within(track.time(), cuts.timeMin, cuts.timeMax) &&
checkMin(track.nMeasurements(), cuts.minMeasurements) &&
checkMax(track.nHoles(), cuts.maxHoles) &&
checkMax(track.nOutliers(), cuts.maxOutliers) &&
checkMax(track.nHoles() + track.nOutliers(),
cuts.maxHolesAndOutliers) &&
checkMax(track.nSharedHits(), cuts.maxSharedHits) &&
checkMax(track.chi2(), cuts.maxChi2) &&
cuts.measurementCounter.isValidTrack(track);
auto parameterCuts = [&]() {
return within(track.transverseMomentum(), cuts.ptMin, cuts.ptMax) &&
(!m_isUnbinned ||
(within(absEta(), cuts.absEtaMin, cuts.absEtaMax) &&
within(_eta, cuts.etaMin, cuts.etaMax))) &&
within(track.phi(), cuts.phiMin, cuts.phiMax) &&
within(track.loc0(), cuts.loc0Min, cuts.loc0Max) &&
within(track.loc1(), cuts.loc1Min, cuts.loc1Max) &&
within(track.time(), cuts.timeMin, cuts.timeMax);
};

auto trackCuts = [&]() {
return checkMin(track.nMeasurements(), cuts.minMeasurements) &&
checkMax(track.nHoles(), cuts.maxHoles) &&
checkMax(track.nOutliers(), cuts.maxOutliers) &&
checkMax(track.nHoles() + track.nOutliers(),
cuts.maxHolesAndOutliers) &&
checkMax(track.nSharedHits(), cuts.maxSharedHits) &&
checkMax(track.chi2(), cuts.maxChi2) &&
cuts.measurementCounter.isValidTrack(track);
};

if (cuts.requireReferenceSurface) {
return track.hasReferenceSurface() && parameterCuts() && trackCuts();
} else {
return trackCuts();
}
}

inline TrackSelector::TrackSelector(
Expand Down
80 changes: 37 additions & 43 deletions Examples/Python/python/acts/examples/reconstruction.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,10 +123,42 @@
"maxSharedHits",
"maxChi2",
"nMeasurementsGroupMin",
"requireReferenceSurface",
],
defaults=[(None, None)] * 7 + [None] * 7,
defaults=[(None, None)] * 7 + [None] * 8,
)


def trackSelectorDefaultKWArgs(c):
"""
Encapsulate this boilerplate code into a function so different uses do not get out of sync
"""
return acts.examples.defaultKWArgs(
loc0Min=c.loc0[0],
loc0Max=c.loc0[1],
loc1Min=c.loc1[0],
loc1Max=c.loc1[1],
timeMin=c.time[0],
timeMax=c.time[1],
phiMin=c.phi[0],
phiMax=c.phi[1],
etaMin=c.eta[0],
etaMax=c.eta[1],
absEtaMin=c.absEta[0],
absEtaMax=c.absEta[1],
ptMin=c.pt[0],
ptMax=c.pt[1],
minMeasurements=c.nMeasurementsMin,
maxHoles=c.maxHoles,
maxOutliers=c.maxOutliers,
maxHolesAndOutliers=c.maxHolesAndOutliers,
maxSharedHits=c.maxSharedHits,
maxChi2=c.maxChi2,
measurementCounter=c.nMeasurementsGroupMin,
requireReferenceSurface=c.requireReferenceSurface,
)


CkfConfig = namedtuple(
"CkfConfig",
[
Expand Down Expand Up @@ -1424,32 +1456,10 @@ def addCKFTracks(
else trackSelectorConfig
)
)

overwriteArgs = dict() if len(tslist) == 1 else dict(absEtaMax=None)
cutSets = [
acts.TrackSelector.Config(
**acts.examples.defaultKWArgs(
loc0Min=c.loc0[0],
loc0Max=c.loc0[1],
loc1Min=c.loc1[0],
loc1Max=c.loc1[1],
timeMin=c.time[0],
timeMax=c.time[1],
phiMin=c.phi[0],
phiMax=c.phi[1],
etaMin=c.eta[0],
etaMax=c.eta[1],
absEtaMin=c.absEta[0],
absEtaMax=c.absEta[1] if len(tslist) == 1 else None,
ptMin=c.pt[0],
ptMax=c.pt[1],
minMeasurements=c.nMeasurementsMin,
maxHoles=c.maxHoles,
maxOutliers=c.maxOutliers,
maxHolesAndOutliers=c.maxHolesAndOutliers,
maxSharedHits=c.maxSharedHits,
maxChi2=c.maxChi2,
measurementCounter=c.nMeasurementsGroupMin,
)
)
acts.TrackSelector.Config(**(trackSelectorDefaultKWArgs(c) | overwriteArgs))
for c in tslist
]
if len(tslist) == 0:
Expand Down Expand Up @@ -1702,23 +1712,7 @@ def addTrackSelection(

# single cut config for implicit single bin eta configuration
selectorConfig = acts.TrackSelector.Config(
**acts.examples.defaultKWArgs(
loc0Min=trackSelectorConfig.loc0[0],
loc0Max=trackSelectorConfig.loc0[1],
loc1Min=trackSelectorConfig.loc1[0],
loc1Max=trackSelectorConfig.loc1[1],
timeMin=trackSelectorConfig.time[0],
timeMax=trackSelectorConfig.time[1],
phiMin=trackSelectorConfig.phi[0],
phiMax=trackSelectorConfig.phi[1],
etaMin=trackSelectorConfig.eta[0],
etaMax=trackSelectorConfig.eta[1],
absEtaMin=trackSelectorConfig.absEta[0],
absEtaMax=trackSelectorConfig.absEta[1],
ptMin=trackSelectorConfig.pt[0],
ptMax=trackSelectorConfig.pt[1],
minMeasurements=trackSelectorConfig.nMeasurementsMin,
)
**trackSelectorDefaultKWArgs(trackSelectorConfig)
)

trackSelector = acts.examples.TrackSelectorAlgorithm(
Expand Down
1 change: 1 addition & 0 deletions Examples/Python/src/ExampleAlgorithms.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ void addExampleAlgorithms(Context& ctx) {
ACTS_PYTHON_MEMBER(maxSharedHits);
ACTS_PYTHON_MEMBER(maxChi2);
ACTS_PYTHON_MEMBER(measurementCounter);
ACTS_PYTHON_MEMBER(requireReferenceSurface);
ACTS_PYTHON_STRUCT_END();

pythonRangeProperty(c, "loc0", &Config::loc0Min, &Config::loc0Max);
Expand Down

0 comments on commit 9173bb4

Please sign in to comment.