Skip to content

Commit

Permalink
refactor: Track Finding and Fitting algorithms output Tracks only (#1858
Browse files Browse the repository at this point in the history
)

This removes the `Trajectories` output writing, completely moving to the separate conversion algorithm introduced in #1857

Blocked by:
- #1854
- #1839 
- #1857
  • Loading branch information
paulgessinger committed Feb 14, 2023
1 parent 1e06090 commit 9b60cd0
Show file tree
Hide file tree
Showing 17 changed files with 94 additions and 119 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,6 @@ class TrackFindingAlgorithm final : public BareAlgorithm {
/// Input initial track parameter estimates for for each proto track.
std::string inputInitialTrackParameters;
/// Output find trajectories collection.
std::string outputTrajectories;
/// Output find tracks collection.
std::string outputTracks;
/// Type erased track finder function.
std::shared_ptr<TrackFinderFunction> findTracks;
Expand Down
38 changes: 10 additions & 28 deletions Examples/Algorithms/TrackFinding/src/TrackFindingAlgorithm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@
#include "ActsExamples/TrackFinding/TrackFindingAlgorithm.hpp"

#include "Acts/EventData/MultiTrajectory.hpp"
#include "Acts/EventData/Track.hpp"
#include "Acts/EventData/VectorMultiTrajectory.hpp"
#include "Acts/EventData/VectorTrackContainer.hpp"
#include "Acts/Surfaces/PerigeeSurface.hpp"
#include "Acts/TrackFitting/GainMatrixSmoother.hpp"
#include "Acts/TrackFitting/GainMatrixUpdater.hpp"
#include "ActsExamples/EventData/Measurement.hpp"
#include "ActsExamples/EventData/Track.hpp"
#include "ActsExamples/EventData/Trajectories.hpp"
#include "ActsExamples/Framework/ProcessCode.hpp"
#include "ActsExamples/Framework/WhiteBoard.hpp"

Expand All @@ -39,9 +39,6 @@ ActsExamples::TrackFindingAlgorithm::TrackFindingAlgorithm(
throw std::invalid_argument(
"Missing initial track parameters input collection");
}
if (m_cfg.outputTrajectories.empty()) {
throw std::invalid_argument("Missing trajectories output collection");
}
if (m_cfg.outputTracks.empty()) {
throw std::invalid_argument("Missing tracks output collection");
}
Expand All @@ -57,11 +54,6 @@ ActsExamples::ProcessCode ActsExamples::TrackFindingAlgorithm::execute(
const auto& initialParameters = ctx.eventStore.get<TrackParametersContainer>(
m_cfg.inputInitialTrackParameters);

// Prepare the output data with MultiTrajectory
// @TODO: Refactor to remove Trajectories
TrajectoriesContainer trajectories;
trajectories.reserve(initialParameters.size());

// Construct a perigee surface as the target surface
auto pSurface = Acts::Surface::makeShared<Acts::PerigeeSurface>(
Acts::Vector3{0., 0., 0.});
Expand Down Expand Up @@ -107,51 +99,41 @@ ActsExamples::ProcessCode ActsExamples::TrackFindingAlgorithm::execute(

TrackContainer tracks(trackContainer, trackStateContainer);

tracks.addColumn<unsigned int>("trackGroup");
Acts::TrackAccessor<unsigned int> seedNumber("trackGroup");

unsigned int nSeed = 0;

for (std::size_t iseed = 0; iseed < initialParameters.size(); ++iseed) {
auto result =
(*m_cfg.findTracks)(initialParameters.at(iseed), options, tracks);
m_nTotalSeeds++;
nSeed++;

if (!result.ok()) {
m_nFailedSeeds++;
ACTS_WARNING("Track finding failed for seed " << iseed << " with error"
<< result.error());
// Track finding failed. Add an empty result so the output container has
// the same number of entries as the input.
trajectories.push_back(Trajectories());
continue;
}

auto& tracksForSeed = result.value();
std::vector<Acts::MultiTrajectoryTraits::IndexType> tips;
tips.reserve(tracksForSeed.size());
Trajectories::IndexedParameters parameters;
parameters.reserve(tracksForSeed.size());

for (auto& track : tracksForSeed) {
tips.push_back(track.tipIndex());
parameters.emplace(
std::pair{track.tipIndex(),
TrackParameters{track.referenceSurface().getSharedPtr(),
track.parameters(), track.covariance()}});
seedNumber(track) = nSeed;
}

// Create a Trajectories result struct
trajectories.emplace_back(*trackStateContainer, std::move(tips),
std::move(parameters));
}

// Compute shared hits from all the reconstructed tracks
if (m_cfg.computeSharedHits) {
computeSharedHits(sourceLinks, tracks);
}

ACTS_DEBUG("Finalized track finding with " << trajectories.size()
ACTS_DEBUG("Finalized track finding with " << tracks.size()
<< " track candidates.");

m_memoryStatistics.local().hist +=
tracks.trackStateContainer().statistics().hist;

ctx.eventStore.add(m_cfg.outputTrajectories, std::move(trajectories));
ctx.eventStore.add(m_cfg.outputTracks, std::move(tracks));
return ActsExamples::ProcessCode::SUCCESS;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,6 @@ class TrackFittingAlgorithm final : public BareAlgorithm {
std::string inputProtoTracks;
/// Input initial track parameter estimates for for each proto track.
std::string inputInitialTrackParameters;
/// Output fitted trajectories collection.
std::string outputTrajectories;
/// Output fitted tracks collection.
std::string outputTracks;
/// Type erased fitter function.
Expand Down
29 changes: 1 addition & 28 deletions Examples/Algorithms/TrackFitting/src/TrackFittingAlgorithm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
#include "Acts/TrackFitting/GainMatrixSmoother.hpp"
#include "Acts/TrackFitting/GainMatrixUpdater.hpp"
#include "ActsExamples/EventData/ProtoTrack.hpp"
#include "ActsExamples/EventData/Trajectories.hpp"
#include "ActsExamples/Framework/WhiteBoard.hpp"

#include <stdexcept>
Expand All @@ -38,9 +37,6 @@ ActsExamples::TrackFittingAlgorithm::TrackFittingAlgorithm(
if (not m_cfg.trackingGeometry) {
throw std::invalid_argument("Missing tracking geometry");
}
if (m_cfg.outputTrajectories.empty()) {
throw std::invalid_argument("Missing output trajectories collection");
}
if (m_cfg.outputTracks.empty()) {
throw std::invalid_argument("Missing output tracks collection");
}
Expand All @@ -64,10 +60,6 @@ ActsExamples::ProcessCode ActsExamples::TrackFittingAlgorithm::execute(
return ProcessCode::ABORT;
}

// Prepare the output data with MultiTrajectory
TrajectoriesContainer trajectories;
trajectories.reserve(protoTracks.size());

// Construct a perigee surface as the target surface
auto pSurface = Acts::Surface::makeShared<Acts::PerigeeSurface>(
Acts::Vector3{0., 0., 0.});
Expand Down Expand Up @@ -101,7 +93,6 @@ ActsExamples::ProcessCode ActsExamples::TrackFittingAlgorithm::execute(
// We can have empty tracks which must give empty fit results so the number
// of entries in input and output containers matches.
if (protoTrack.empty()) {
trajectories.push_back(Trajectories());
ACTS_WARNING("Empty track " << itrack << " found.");
continue;
}
Expand Down Expand Up @@ -139,42 +130,24 @@ ActsExamples::ProcessCode ActsExamples::TrackFittingAlgorithm::execute(

if (result.ok()) {
// Get the fit output object
auto& track = result.value();
// The track entry indices container. One element here.
std::vector<Acts::MultiTrajectoryTraits::IndexType> trackTips;
trackTips.reserve(1);
trackTips.emplace_back(track.tipIndex());
// The fitted parameters container. One element (at most) here.
Trajectories::IndexedParameters indexedParams;
const auto& track = result.value();
if (track.hasReferenceSurface()) {
ACTS_VERBOSE("Fitted parameters for track " << itrack);
ACTS_VERBOSE(" " << track.parameters().transpose());
// Push the fitted parameters to the container
indexedParams.emplace(
std::pair{track.tipIndex(),
TrackParameters{track.referenceSurface().getSharedPtr(),
track.parameters(), track.covariance()}});
} else {
ACTS_DEBUG("No fitted parameters for track " << itrack);
}
// store the result
trajectories.emplace_back(*trackStateContainer, std::move(trackTips),
std::move(indexedParams));
} else {
ACTS_WARNING("Fit failed for track "
<< itrack << " with error: " << result.error() << ", "
<< result.error().message());
// Fit failed. Add an empty result so the output container has
// the same number of entries as the input.
trajectories.push_back(Trajectories());
}
}

std::stringstream ss;
trackStateContainer->statistics().toStream(ss);
ACTS_DEBUG(ss.str());

ctx.eventStore.add(m_cfg.outputTrajectories, std::move(trajectories));
ctx.eventStore.add(m_cfg.outputTracks, std::move(tracks));
return ActsExamples::ProcessCode::SUCCESS;
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,6 @@ class TrackFittingChi2Algorithm final : public BareAlgorithm {
/// Input initial track parameter estimates for for each proto track.
std::string inputInitialTrackParameters;
/// Output fitted trajectories collection.
std::string outputTrajectories;
/// Output fitted tracks collection.
std::string outputTracks;
/// number of update steps
unsigned int nUpdates = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
#include "Acts/EventData/Track.hpp"
#include "Acts/Surfaces/PerigeeSurface.hpp"
#include "ActsExamples/EventData/ProtoTrack.hpp"
#include "ActsExamples/EventData/Trajectories.hpp"
#include "ActsExamples/Framework/WhiteBoard.hpp"

#include <stdexcept>
Expand All @@ -36,9 +35,6 @@ ActsExamples::TrackFittingChi2Algorithm::TrackFittingChi2Algorithm(
if (not m_cfg.trackingGeometry) {
throw std::invalid_argument("Missing tracking geometry");
}
if (m_cfg.outputTrajectories.empty()) {
throw std::invalid_argument("Missing output trajectories collection");
}
if (m_cfg.outputTracks.empty()) {
throw std::invalid_argument("Missing output track collection");
}
Expand All @@ -62,10 +58,6 @@ ActsExamples::ProcessCode ActsExamples::TrackFittingChi2Algorithm::execute(
return ProcessCode::ABORT;
}

// Prepare the output data with MultiTrajectory
TrajectoriesContainer trajectories;
trajectories.reserve(protoTracks.size());

// Set Chi2 options
Acts::Experimental::Chi2FitterExtensions<Acts::VectorMultiTrajectory>
extensions;
Expand All @@ -86,6 +78,7 @@ ActsExamples::ProcessCode ActsExamples::TrackFittingChi2Algorithm::execute(
TrackContainer tracks(trackContainer, trackStateContainer);

tracks.addColumn<Acts::ActsScalar>("chi2");

static Acts::ConstTrackAccessor<Acts::ActsScalar> chisquare{"chi2"};

// Perform the fit for each input track
Expand All @@ -104,7 +97,6 @@ ActsExamples::ProcessCode ActsExamples::TrackFittingChi2Algorithm::execute(
// We can have empty tracks which must give empty fit results so the number
// of entries in input and output containers matches.
if (protoTrack.empty()) {
trajectories.push_back(Trajectories());
ACTS_WARNING("Empty track " << itrack << " found.");
continue;
}
Expand Down Expand Up @@ -138,41 +130,23 @@ ActsExamples::ProcessCode ActsExamples::TrackFittingChi2Algorithm::execute(
if (result.ok()) {
ACTS_DEBUG("result ok");
// Get the fit output object
auto& track = result.value();
// The track entry indices container. One element here.
std::vector<Acts::MultiTrajectoryTraits::IndexType> trackTips;
trackTips.reserve(1);
trackTips.emplace_back(track.tipIndex());
// The fitted parameters container. One element (at most) here.
Trajectories::IndexedParameters indexedParams;
const auto& track = result.value();
ACTS_VERBOSE("final χ² = " << chisquare(track));
ACTS_VERBOSE("lastMeasurementIndex = " << track.tipIndex());

if (track.hasReferenceSurface()) {
ACTS_VERBOSE("Fitted parameters for track "
<< itrack << ": " << track.parameters().transpose());
// Push the fitted parameters to the container
indexedParams.emplace(
std::pair{track.tipIndex(),
TrackParameters{track.referenceSurface().getSharedPtr(),
track.parameters(), track.covariance()}});
} else {
ACTS_DEBUG("No fitted parameters for track " << itrack);
}
// store the result
trajectories.emplace_back(*trackStateContainer, std::move(trackTips),
std::move(indexedParams));
} else {
ACTS_WARNING("Fit failed for track "
<< itrack << " with error: " << result.error() << ", "
<< result.error().message());
// Fit failed. Add an empty result so the output container has
// the same number of entries as the input.
trajectories.push_back(Trajectories());
}
}

ctx.eventStore.add(m_cfg.outputTrajectories, std::move(trajectories));
ctx.eventStore.add(m_cfg.outputTracks, std::move(tracks));
// TODO: add chi2 values as output?
return ActsExamples::ProcessCode::SUCCESS;
Expand Down
33 changes: 25 additions & 8 deletions Examples/Python/python/acts/examples/reconstruction.py
Original file line number Diff line number Diff line change
Expand Up @@ -773,7 +773,6 @@ def addKalmanTracks(
inputSourceLinks="sourcelinks",
inputProtoTracks=inputProtoTracks,
inputInitialTrackParameters="estimatedparameters",
outputTrajectories="kfTrajectories",
outputTracks="kfTracks",
directNavigation=directNavigation,
pickTrack=-1,
Expand All @@ -784,7 +783,14 @@ def addKalmanTracks(
)
s.addAlgorithm(fitAlg)

s.addWhiteboardAlias("trajectories", fitAlg.config.outputTrajectories)
trackConverter = acts.examples.TracksToTrajectories(
level=customLogLevel(),
inputTracks=fitAlg.config.outputTracks,
outputTrajectories="kfTrajectories",
)
s.addAlgorithm(trackConverter)

s.addWhiteboardAlias("trajectories", trackConverter.config.outputTrajectories)

return s

Expand Down Expand Up @@ -814,16 +820,21 @@ def addTruthTrackingGsf(
inputSourceLinks="sourcelinks",
inputProtoTracks="prototracks",
inputInitialTrackParameters="estimatedparameters",
outputTrajectories="gsf_trajectories",
outputTracks="gsf_tracks",
directNavigation=False,
pickTrack=-1,
trackingGeometry=trackingGeometry,
fit=acts.examples.makeGsfFitterFunction(trackingGeometry, field, **gsfOptions),
)

s.addAlgorithm(gsfAlg)

trackConverter = acts.examples.TracksToTrajectories(
level=customLogLevel(),
inputTracks=gsfAlg.config.outputTracks,
outputTrajectories="gsf_trajectories",
)
s.addAlgorithm(trackConverter)

return s


Expand Down Expand Up @@ -880,21 +891,27 @@ def addCKFTracks(
inputMeasurements="measurements",
inputSourceLinks="sourcelinks",
inputInitialTrackParameters="estimatedparameters",
outputTrajectories="ckfTrajectories",
outputTracks="ckfTracks",
findTracks=acts.examples.TrackFindingAlgorithm.makeTrackFinderFunction(
trackingGeometry, field
),
)
s.addAlgorithm(trackFinder)

s.addWhiteboardAlias("trajectories", trackFinder.config.outputTrajectories)
trackConverter = acts.examples.TracksToTrajectories(
level=customLogLevel(),
inputTracks=trackFinder.config.outputTracks,
outputTrajectories="trajectories-from-tracks",
)
s.addAlgorithm(trackConverter)

s.addWhiteboardAlias("trajectories", trackConverter.config.outputTrajectories)

if trackSelectorRanges is not None:
trackSelector = addTrackSelection(
s,
trackSelectorRanges,
inputTrajectories=trackFinder.config.outputTrajectories,
inputTrajectories=trackConverter.config.outputTrajectories,
outputTrajectories="selectedTrajectories",
logLevel=customLogLevel(),
)
Expand All @@ -904,7 +921,7 @@ def addCKFTracks(
addTrajectoryWriters(
s,
name="ckf",
trajectories=trackFinder.config.outputTrajectories,
trajectories=trackConverter.config.outputTrajectories,
ckfPerformanceConfig=ckfPerformanceConfig,
outputDirCsv=outputDirCsv,
outputDirRoot=outputDirRoot,
Expand Down
1 change: 0 additions & 1 deletion Examples/Python/src/TrackFinding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,6 @@ void addTrackFinding(Context& ctx) {
ACTS_PYTHON_MEMBER(inputMeasurements);
ACTS_PYTHON_MEMBER(inputSourceLinks);
ACTS_PYTHON_MEMBER(inputInitialTrackParameters);
ACTS_PYTHON_MEMBER(outputTrajectories);
ACTS_PYTHON_MEMBER(outputTracks);
ACTS_PYTHON_MEMBER(findTracks);
ACTS_PYTHON_MEMBER(measurementSelectorCfg);
Expand Down

0 comments on commit 9b60cd0

Please sign in to comment.