From 1413111c28f5c4e95e3710f4bd7102197fc6e450 Mon Sep 17 00:00:00 2001 From: minjungkim12 Date: Tue, 4 Jun 2024 05:32:27 +0200 Subject: [PATCH] implementation of ambiguity resolution solver from ACTS (#1383) ### Briefly, what does this PR introduce? * implementation of ambiguity resolution solver from ACTS; removing duplicate tracks from realistic seeding * new factory called after CKFtracking; taking CKFtracking outputs as inputs; provides a set of output collections ### What kind of change does this PR introduce? - [ ] Bug fix (issue #__) - [x] New feature (issue #__) - [ ] Documentation update - [ ] Other: __ ### Please check if this PR fulfills the following: - [ ] Tests for the changes have been added - [ ] Documentation has been added / updated - [x] Changes have been communicated to collaborators ### Does this PR introduce breaking changes? What changes might users need to make to their code? * No change required; ### Does this PR change default behavior? * adding 3 PodIO output collection --------- Co-authored-by: Minjung Kim Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Minjung Kim Co-authored-by: Wouter Deconinck Co-authored-by: Dmitry Kalinkin Co-authored-by: Minjung Kim Co-authored-by: Barak Schmookler --- src/algorithms/tracking/ActsToTracks.cc | 5 +- src/algorithms/tracking/AmbiguitySolver.cc | 121 ++++++++++++++++++ src/algorithms/tracking/AmbiguitySolver.h | 42 ++++++ .../tracking/AmbiguitySolverConfig.h | 17 +++ src/global/tracking/AmbiguitySolver_factory.h | 52 ++++++++ src/global/tracking/tracking.cc | 71 ++++++++-- src/services/io/podio/JEventProcessorPODIO.cc | 8 ++ 7 files changed, 304 insertions(+), 12 deletions(-) create mode 100644 src/algorithms/tracking/AmbiguitySolver.cc create mode 100644 src/algorithms/tracking/AmbiguitySolver.h create mode 100644 src/algorithms/tracking/AmbiguitySolverConfig.h create mode 100644 src/global/tracking/AmbiguitySolver_factory.h diff --git a/src/algorithms/tracking/ActsToTracks.cc b/src/algorithms/tracking/ActsToTracks.cc index 0bfeee2bd4..179d1541cf 100644 --- a/src/algorithms/tracking/ActsToTracks.cc +++ b/src/algorithms/tracking/ActsToTracks.cc @@ -3,7 +3,6 @@ #include #include -#include #include #include #include @@ -13,7 +12,6 @@ #include #include #include -#include #include #include #include @@ -58,8 +56,7 @@ void ActsToTracks::process(const Input& input, const Output& output) const { } // Loop over all trajectories in a multiTrajectory - // FIXME: we only retain the first trackTips entry - for (auto trackTip : decltype(trackTips){trackTips.front()}) { + for (auto trackTip : trackTips) { // Collect the trajectory summary info auto trajectoryState = Acts::MultiTrajectoryHelpers::trajectoryState(mj, trackTip); diff --git a/src/algorithms/tracking/AmbiguitySolver.cc b/src/algorithms/tracking/AmbiguitySolver.cc new file mode 100644 index 0000000000..4be8faa411 --- /dev/null +++ b/src/algorithms/tracking/AmbiguitySolver.cc @@ -0,0 +1,121 @@ +// SPDX-License-Identifier: LGPL-3.0-or-later +// Copyright (C) 2024 Minjung Kim, Barak Schmookler +#include "AmbiguitySolver.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Acts/Utilities/Logger.hpp" +#include "AmbiguitySolverConfig.h" +#include "extensions/spdlog/SpdlogFormatters.h" // IWYU pragma: keep +#include "extensions/spdlog/SpdlogToActs.h" + +namespace eicrecon { + +Acts::GreedyAmbiguityResolution::Config +transformConfig(const eicrecon::AmbiguitySolverConfig& cfg) { + Acts::GreedyAmbiguityResolution::Config result; + result.maximumSharedHits = cfg.maximum_shared_hits; + result.maximumIterations = cfg.maximum_iterations; + result.nMeasurementsMin = cfg.n_measurements_min; + return result; +} + +static std::size_t sourceLinkHash(const Acts::SourceLink& a) { + return static_cast(a.get().index()); +} + +static bool sourceLinkEquality(const Acts::SourceLink& a, const Acts::SourceLink& b) { + return a.get().index() == + b.get().index(); +} + + +AmbiguitySolver::AmbiguitySolver() {} + + +void AmbiguitySolver::init(std::shared_ptr log) { + + m_log = log; + m_acts_logger = eicrecon::getSpdlogLogger("AmbiguitySolver", m_log); + m_acts_cfg = transformConfig(m_cfg); + m_core = std::make_unique(m_acts_cfg, logger().clone()); +} + + +std::tuple, std::vector> +AmbiguitySolver::process(std::vector input_container, + const edm4eic::Measurement2DCollection& meas2Ds) { + + // Assuming ActsExamples::ConstTrackContainer is compatible with Acts::ConstVectorTrackContainer + // Create track container + std::vector output_trajectories; + std::vector output_tracks; + + auto& input_trks = input_container.front(); + Acts::GreedyAmbiguityResolution::State state; + m_core->computeInitialState(*input_trks, state, &sourceLinkHash, &sourceLinkEquality); + m_core->resolve(state); + + ActsExamples::TrackContainer solvedTracks{std::make_shared(), + std::make_shared()}; + solvedTracks.ensureDynamicColumns(*input_trks); + + for (auto iTrack : state.selectedTracks) { + + auto destProxy = solvedTracks.getTrack(solvedTracks.addTrack()); + auto srcProxy = input_trks->getTrack(state.trackTips.at(iTrack)); + destProxy.copyFrom(srcProxy, false); + destProxy.tipIndex() = srcProxy.tipIndex(); + + } + + output_tracks.push_back(new ActsExamples::ConstTrackContainer( + std::make_shared(std::move(solvedTracks.container())), + input_trks->trackStateContainerHolder())); + + //Make output trajectories + ActsExamples::Trajectories::IndexedParameters parameters; + std::vector tips; + + for (const auto& track : *(output_tracks.front())) { + + tips.clear(); + parameters.clear(); + + tips.push_back(track.tipIndex()); + parameters.emplace( + std::pair{track.tipIndex(), + ActsExamples::TrackParameters{track.referenceSurface().getSharedPtr(), + track.parameters(), track.covariance(), + track.particleHypothesis()}}); + + output_trajectories.push_back(new ActsExamples::Trajectories( + ((*output_tracks.front())).trackStateContainer(), + tips, parameters)); + + } + + return std::make_tuple(std::move(output_tracks), std::move(output_trajectories)); +} + +} // namespace eicrecon diff --git a/src/algorithms/tracking/AmbiguitySolver.h b/src/algorithms/tracking/AmbiguitySolver.h new file mode 100644 index 0000000000..6244626500 --- /dev/null +++ b/src/algorithms/tracking/AmbiguitySolver.h @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: LGPL-3.0-or-later +// Copyright (C) 2024 Minjung Kim, Barak Schmookler +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Acts/AmbiguityResolution/GreedyAmbiguityResolution.hpp" +#include "AmbiguitySolverConfig.h" +#include "algorithms/interfaces/WithPodConfig.h" + +namespace eicrecon { + +/*Reco Track Filtering Based on Greedy ambiguity resolution solver adopted from ACTS*/ +class AmbiguitySolver : public WithPodConfig { +public: + AmbiguitySolver(); + + void init(std::shared_ptr log); + +std::tuple< + std::vector, + std::vector + > + process(std::vector input_container,const edm4eic::Measurement2DCollection& meas2Ds); + +private: + std::shared_ptr m_log; + Acts::GreedyAmbiguityResolution::Config m_acts_cfg; + std::unique_ptr m_core; + /// Private access to the logging instance + std::shared_ptr m_acts_logger{nullptr}; + const Acts::Logger& logger() const { return *m_acts_logger; } +}; + +} // namespace eicrecon diff --git a/src/algorithms/tracking/AmbiguitySolverConfig.h b/src/algorithms/tracking/AmbiguitySolverConfig.h new file mode 100644 index 0000000000..f16296f049 --- /dev/null +++ b/src/algorithms/tracking/AmbiguitySolverConfig.h @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: LGPL-3.0-or-later +// Copyright (C) 2024 Minjung Kim + +#pragma once + +#include + +namespace eicrecon { +struct AmbiguitySolverConfig { + /// Maximum amount of shared hits per track. + std::uint32_t maximum_shared_hits = 1; + /// Maximum number of iterations + std::uint32_t maximum_iterations = 100000; + /// Minimum number of measurement to form a track. + std::size_t n_measurements_min = 3; +}; +} // namespace eicrecon diff --git a/src/global/tracking/AmbiguitySolver_factory.h b/src/global/tracking/AmbiguitySolver_factory.h new file mode 100644 index 0000000000..a72dad6db0 --- /dev/null +++ b/src/global/tracking/AmbiguitySolver_factory.h @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: LGPL-3.0-or-later +// Copyright (C) 2024 Minjung Kim, Barak Schmookler +#pragma once + +#include "algorithms/tracking/AmbiguitySolver.h" +#include "algorithms/tracking/AmbiguitySolverConfig.h" +#include "extensions/jana/JOmniFactory.h" +#include "extensions/spdlog/SpdlogMixin.h" +#include +#include +#include +#include +#include +#include + +namespace eicrecon { + +class AmbiguitySolver_factory + : public JOmniFactory { + +private: + using AlgoT = eicrecon::AmbiguitySolver; + std::unique_ptr m_algo; + + Input m_acts_tracks_input {this}; + PodioInput m_measurements_input {this}; + Output m_acts_tracks_output {this}; + Output m_acts_trajectories_output {this}; + + ParameterRef m_maximumSharedHits{this, "maximumSharedHits", config().maximum_shared_hits, + "Maximum number of shared hits allowed"}; + ParameterRef m_maximumIterations{this, "maximumIterations", config().maximum_iterations, + "Maximum number of iterations"}; + ParameterRef m_nMeasurementsMin{ + this, "nMeasurementsMin", config().n_measurements_min, + "Number of measurements required for further reconstruction"}; + +public: + void Configure() { + m_algo = std::make_unique(); + m_algo->applyConfig(config()); + m_algo->init(logger()); + } + + void ChangeRun(int64_t run_number) {} + + void Process(int64_t run_number, uint64_t event_number) { + std::tie(m_acts_tracks_output(),m_acts_trajectories_output()) = m_algo->process(m_acts_tracks_input(),*m_measurements_input()); + } +} ; + +} // namespace eicrecon diff --git a/src/global/tracking/tracking.cc b/src/global/tracking/tracking.cc index fa37a317d8..06a259441c 100644 --- a/src/global/tracking/tracking.cc +++ b/src/global/tracking/tracking.cc @@ -14,6 +14,7 @@ #include "ActsToTracks.h" #include "ActsToTracks_factory.h" +#include "AmbiguitySolver_factory.h" #include "CKFTracking_factory.h" #include "IterativeVertexFinder_factory.h" #include "TrackParamTruthInit_factory.h" @@ -62,10 +63,10 @@ void InitPlugin(JApplication *app) { std::vector input_collections; auto readouts = app->GetService()->detector()->readouts(); for (const auto& [hit_collection, rec_collection] : possible_collections) { - if (readouts.find(hit_collection) != readouts.end()) { - // Add the collection to the list of input collections - input_collections.push_back(rec_collection); - } + if (readouts.find(hit_collection) != readouts.end()) { + // Add the collection to the list of input collections + input_collections.push_back(rec_collection); + } } // Tracker hits collector @@ -89,8 +90,35 @@ void InitPlugin(JApplication *app) { "CentralTrackerMeasurements" }, { - "CentralCKFActsTrajectories", - "CentralCKFActsTracks", + "CentralCKFActsTrajectoriesUnfiltered", + "CentralCKFActsTracksUnfiltered", + }, + app + )); + + app->Add(new JOmniFactoryGeneratorT( + "CentralCKFTracksUnfiltered", + { + "CentralTrackerMeasurements", + "CentralCKFActsTrajectoriesUnfiltered", + }, + { + "CentralCKFTrajectoriesUnfiltered", + "CentralCKFTrackParametersUnfiltered", + "CentralCKFTracksUnfiltered", + }, + app + )); + + app->Add(new JOmniFactoryGeneratorT( + "AmbiguityResolutionSolver", + { + "CentralCKFActsTracksUnfiltered", + "CentralTrackerMeasurements" + }, + { + "CentralCKFActsTracks", + "CentralCKFActsTrajectories", }, app )); @@ -124,8 +152,35 @@ void InitPlugin(JApplication *app) { "CentralTrackerMeasurements" }, { - "CentralCKFSeededActsTrajectories", - "CentralCKFSeededActsTracks", + "CentralCKFSeededActsTrajectoriesUnfiltered", + "CentralCKFSeededActsTracksUnfiltered", + }, + app + )); + + app->Add(new JOmniFactoryGeneratorT( + "CentralCKFSeededTracksUnfiltered", + { + "CentralTrackerMeasurements", + "CentralCKFSeededActsTrajectoriesUnfiltered", + }, + { + "CentralCKFSeededTrajectoriesUnfiltered", + "CentralCKFSeededTrackParametersUnfiltered", + "CentralCKFSeededTracksUnfiltered", + }, + app + )); + + app->Add(new JOmniFactoryGeneratorT( + "SeededAmbiguityResolutionSolver", + { + "CentralCKFSeededActsTracksUnfiltered", + "CentralTrackerMeasurements" + }, + { + "CentralCKFSeededActsTracks", + "CentralCKFSeededActsTrajectories", }, app )); diff --git a/src/services/io/podio/JEventProcessorPODIO.cc b/src/services/io/podio/JEventProcessorPODIO.cc index 6ebcdd13b0..7b36d2f66f 100644 --- a/src/services/io/podio/JEventProcessorPODIO.cc +++ b/src/services/io/podio/JEventProcessorPODIO.cc @@ -186,6 +186,14 @@ JEventProcessorPODIO::JEventProcessorPODIO() { "CentralCKFSeededTrajectories", "CentralCKFSeededTracks", "CentralCKFSeededTrackParameters", + //tracking properties - true seeding + "CentralCKFTrajectoriesUnfiltered", + "CentralCKFTracksUnfiltered", + "CentralCKFTrackParametersUnfiltered", + //tracking properties - realistic seeding + "CentralCKFSeededTrajectoriesUnfiltered", + "CentralCKFSeededTracksUnfiltered", + "CentralCKFSeededTrackParametersUnfiltered", "InclusiveKinematicsDA", "InclusiveKinematicsJB", "InclusiveKinematicsSigma",