diff --git a/CMakeLists.txt b/CMakeLists.txt index 90915da960d81ca7c7819f097503369cdb9e071e..cf90a25ccea694ee3bd223587ec29f3d63667edb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,6 +34,12 @@ find_package(ROOT COMPONENTS Core RIO Tree MathCore GenVector Geom REQUIRED) find_package(DD4hep COMPONENTS DDG4 DDG4IO DDRec REQUIRED) find_package(Acts REQUIRED COMPONENTS Core PluginIdentification PluginTGeo PluginDD4hep PluginJson) +set(Acts_VERSION_MIN "15.1.0") +set(Acts_VERSION "${Acts_VERSION_MAJOR}.${Acts_VERSION_MINOR}.${Acts_VERSION_PATCH}") +if(${Acts_VERSION} VERSION_LESS ${Acts_VERSION_MIN} + AND NOT "${Acts_VERSION}" STREQUAL "9.9.9") + message(FATAL_ERROR "Acts version ${Acts_VERSION_MIN} or higher required, but ${Acts_VERSION} found") +endif() add_definitions("-DActs_VERSION_MAJOR=${Acts_VERSION_MAJOR}") add_definitions("-DActs_VERSION_MINOR=${Acts_VERSION_MINOR}") add_definitions("-DActs_VERSION_PATCH=${Acts_VERSION_PATCH}") diff --git a/JugTrack/JugTrack/GeometryContainers.hpp b/JugTrack/JugTrack/GeometryContainers.hpp index 3e580cd2f28a2a439634e8084e2f3e003912863f..99cc27ac33a492e401dd9e5b988cc34f4ab13eda 100644 --- a/JugTrack/JugTrack/GeometryContainers.hpp +++ b/JugTrack/JugTrack/GeometryContainers.hpp @@ -43,6 +43,12 @@ struct GeometryIdGetter { -> decltype(thing.geometryId(), Acts::GeometryIdentifier()) { return thing.geometryId(); } + // support reference_wrappers around such types as well + template <typename T> + inline auto operator()(std::reference_wrapper<T> thing) const + -> decltype(thing.get().geometryId(), Acts::GeometryIdentifier()) { + return thing.get().geometryId(); + } }; struct CompareGeometryId { diff --git a/JugTrack/JugTrack/IndexSourceLink.hpp b/JugTrack/JugTrack/IndexSourceLink.hpp index 5124ac3761632130a6999f696127df7dbeaae056..d64981a48995fa306ebffcb31ef1001d63401714 100644 --- a/JugTrack/JugTrack/IndexSourceLink.hpp +++ b/JugTrack/JugTrack/IndexSourceLink.hpp @@ -11,6 +11,8 @@ #include "JugTrack/GeometryContainers.hpp" #include "JugTrack/Index.hpp" +#include "Acts/EventData/SourceLink.hpp" + #include <cassert> namespace Jug { @@ -24,31 +26,28 @@ namespace Jug { /// Using an index instead of e.g. a pointer, means source link and /// measurement are decoupled and the measurement represenation can be /// easily changed without having to also change the source link. - class IndexSourceLink final { + class IndexSourceLink final : public Acts::SourceLink { public: /// Construct from geometry identifier and index. - constexpr IndexSourceLink(Acts::GeometryIdentifier gid, Index idx) : m_geometryId(gid), m_index(idx) {} + constexpr IndexSourceLink(Acts::GeometryIdentifier gid, Index idx) : SourceLink(gid), m_index(idx) {} // Construct an invalid source link. Must be default constructible to /// satisfy SourceLinkConcept. - IndexSourceLink() = default; + IndexSourceLink() : SourceLink{Acts::GeometryIdentifier{}} {} IndexSourceLink(const IndexSourceLink&) = default; IndexSourceLink(IndexSourceLink&&) = default; IndexSourceLink& operator=(const IndexSourceLink&) = default; IndexSourceLink& operator=(IndexSourceLink&&) = default; - /// Access the geometry identifier. - constexpr Acts::GeometryIdentifier geometryId() const { return m_geometryId; } /// Access the index. constexpr Index index() const { return m_index; } public: - Acts::GeometryIdentifier m_geometryId; Index m_index; friend constexpr bool operator==(const IndexSourceLink& lhs, const IndexSourceLink& rhs) { - return (lhs.m_geometryId == rhs.m_geometryId) and (lhs.m_index == rhs.m_index); + return (lhs.geometryId() == rhs.geometryId()) and (lhs.m_index == rhs.m_index); } friend constexpr bool operator!=(const IndexSourceLink& lhs, const IndexSourceLink& rhs) { return not(lhs == rhs); } }; @@ -57,12 +56,14 @@ namespace Jug { /// /// Since the source links provide a `.geometryId()` accessor, they can be /// stored in an ordered geometry container. - using IndexSourceLinkContainer = GeometryIdMultiset<IndexSourceLink>; + using IndexSourceLinkContainer = + GeometryIdMultiset<std::reference_wrapper<const IndexSourceLink>>; /// Accessor for the above source link container /// /// It wraps up a few lookup methods to be used in the Combinatorial Kalman /// Filter - using IndexSourceLinkAccessor = GeometryIdMultisetAccessor<IndexSourceLink>; + using IndexSourceLinkAccessor = + GeometryIdMultisetAccessor<std::reference_wrapper<const IndexSourceLink>>; } // namespace Jug diff --git a/JugTrack/JugTrack/Measurement.hpp b/JugTrack/JugTrack/Measurement.hpp index aa4c1f9bf2bd3c4e21078edf244daf474a60f5d3..7af36fa344831c07d1b32c64778642eafc90807d 100644 --- a/JugTrack/JugTrack/Measurement.hpp +++ b/JugTrack/JugTrack/Measurement.hpp @@ -2,6 +2,8 @@ #define JugTrack_Measurement_HH #include "Acts/EventData/Measurement.hpp" +#include "Acts/EventData/MultiTrajectory.hpp" +#include "Acts/EventData/SourceLink.hpp" #include "JugTrack/IndexSourceLink.hpp" #include <cassert> @@ -10,7 +12,7 @@ namespace Jug { /// Variable measurement type that can contain all possible combinations. - using Measurement = ::Acts::BoundVariantMeasurement<IndexSourceLink>; + using Measurement = ::Acts::BoundVariantMeasurement; /// Container of measurements. /// /// In contrast to the source links, the measurements themself must not be @@ -29,14 +31,15 @@ namespace Jug { /// Find the measurement corresponding to the source link. /// /// @tparam parameters_t Track parameters type - /// @param sourceLink Input source link - /// @param parameters Input track parameters (unused) - template <typename parameters_t> - const Measurement& operator()(const IndexSourceLink& sourceLink, const parameters_t& /* parameters */) const - { - assert(m_measurements and "Undefined measurement container in DigitizedCalibrator"); - assert((sourceLink.index() < m_measurements->size()) and "Source link index is outside the container bounds"); - return (*m_measurements)[sourceLink.m_index]; + /// @param gctx The geometry context (unused) + /// @param trackState The track state to calibrate + void calibrate(const Acts::GeometryContext& /*gctx*/, + Acts::MultiTrajectory::TrackStateProxy trackState) const { + const auto& sourceLink = + static_cast<const IndexSourceLink&>(trackState.uncalibrated()); + std::visit( + [&trackState](const auto& meas) { trackState.setCalibrated(meas); }, + (*m_measurements)[sourceLink.index()]); } private: diff --git a/JugTrack/JugTrack/Trajectories.hpp b/JugTrack/JugTrack/Trajectories.hpp index 30d1983dfed683f9c559ed04bded319c79862d9b..a104661b92b0d77d5acb0692269abac345ca4129 100644 --- a/JugTrack/JugTrack/Trajectories.hpp +++ b/JugTrack/JugTrack/Trajectories.hpp @@ -21,7 +21,7 @@ namespace Jug { struct Trajectories final { public: /// (Reconstructed) trajectory with multiple states. - using MultiTrajectory = ::Acts::MultiTrajectory<IndexSourceLink>; + using MultiTrajectory = ::Acts::MultiTrajectory; /// Fitted parameters identified by indices in the multi trajectory. using IndexedParameters = std::unordered_map<size_t, TrackParameters>; diff --git a/JugTrack/src/components/CKFTracking.cpp b/JugTrack/src/components/CKFTracking.cpp index 035dfcbe45e5cef52fe6628e43485ad72716e730..172cb16d4090fe891acdb1a69d6aaad05b6b3737 100644 --- a/JugTrack/src/components/CKFTracking.cpp +++ b/JugTrack/src/components/CKFTracking.cpp @@ -88,9 +88,13 @@ namespace Jug::Reco { debug() << "B(z=" << z << " mm) = " << b.transpose() << " T" << endmsg; } - // chi2 and #sourclinks per surface cutoffs + // eta bins, chi2 and #sourclinks per surface cutoffs m_sourcelinkSelectorCfg = { - {Acts::GeometryIdentifier(), {m_chi2CutOff, m_numMeasurementsCutOff}}, + {Acts::GeometryIdentifier(), + {m_etaBins, m_chi2CutOff, + {m_numMeasurementsCutOff.begin(), m_numMeasurementsCutOff.end()} + } + }, }; m_trackFinderFunc = CKFTracking::makeCKFTrackingFunction(m_geoSvc->trackingGeometry(), m_BField); auto im = _msgMap.find(msgLevel()); @@ -120,12 +124,27 @@ namespace Jug::Reco { Acts::PropagatorPlainOptions pOptions; pOptions.maxSteps = 10000; + MeasurementCalibrator calibrator{*measurements}; + Acts::GainMatrixUpdater kfUpdater; + Acts::GainMatrixSmoother kfSmoother; + Acts::MeasurementSelector measSel{m_sourcelinkSelectorCfg}; + + Acts::CombinatorialKalmanFilterExtensions extensions; + extensions.calibrator.connect<&MeasurementCalibrator::calibrate>(&calibrator); + extensions.updater.connect<&Acts::GainMatrixUpdater::operator()>(&kfUpdater); + extensions.smoother.connect<&Acts::GainMatrixSmoother::operator()>( + &kfSmoother); + extensions.measurementSelector.connect<&Acts::MeasurementSelector::select>( + &measSel); + // Set the CombinatorialKalmanFilter options CKFTracking::TrackFinderOptions options( - m_geoctx, m_fieldctx, m_calibctx, IndexSourceLinkAccessor(), MeasurementCalibrator(*measurements), - Acts::MeasurementSelector(m_sourcelinkSelectorCfg), Acts::LoggerWrapper{logger()}, pOptions, &(*pSurface)); + m_geoctx, m_fieldctx, m_calibctx, + IndexSourceLinkAccessor(), extensions, + Acts::LoggerWrapper{logger()}, + pOptions, &(*pSurface)); - auto results = m_trackFinderFunc(*src_links, *init_trk_params, options); + auto results = (*m_trackFinderFunc)(*src_links, *init_trk_params, options); for (std::size_t iseed = 0; iseed < init_trk_params->size(); ++iseed) { diff --git a/JugTrack/src/components/CKFTracking.h b/JugTrack/src/components/CKFTracking.h index 384f71e2b19baede70154e369e75c45a685bcb4c..375ef4a17ff8c1ef3a7e6547a268ceea8770a9e1 100644 --- a/JugTrack/src/components/CKFTracking.h +++ b/JugTrack/src/components/CKFTracking.h @@ -37,16 +37,26 @@ class CKFTracking : public GaudiAlgorithm { public: /// Track finder function that takes input measurements, initial trackstate /// and track finder options and returns some track-finder-specific result. - using TrackFinderOptions = Acts::CombinatorialKalmanFilterOptions<IndexSourceLinkAccessor, MeasurementCalibrator, Acts::MeasurementSelector>; - using TrackFinderResult = std::vector<Acts::Result<Acts::CombinatorialKalmanFilterResult<IndexSourceLink>>>; - using CKFTrackingFunction = std::function<TrackFinderResult( - const IndexSourceLinkContainer&, const TrackParametersContainer&, const TrackFinderOptions&)>; + using TrackFinderOptions = Acts::CombinatorialKalmanFilterOptions<IndexSourceLinkAccessor>; + using TrackFinderResult = std::vector<Acts::Result<Acts::CombinatorialKalmanFilterResult>>; + + /// Find function that takes the above parameters + /// @note This is separated into a virtual interface to keep compilation units + /// small + class CKFTrackingFunction { + public: + virtual ~CKFTrackingFunction() = default; + virtual TrackFinderResult operator()(const IndexSourceLinkContainer&, + const TrackParametersContainer&, + const TrackFinderOptions&) const = 0; + }; /// Create the track finder function implementation. /// The magnetic field is intentionally given by-value since the variant /// contains shared_ptr anyways. - static CKFTrackingFunction makeCKFTrackingFunction(std::shared_ptr<const Acts::TrackingGeometry> trackingGeometry, - std::shared_ptr<const Acts::MagneticFieldProvider> magneticField); + static std::shared_ptr<CKFTrackingFunction> makeCKFTrackingFunction( + std::shared_ptr<const Acts::TrackingGeometry> trackingGeometry, + std::shared_ptr<const Acts::MagneticFieldProvider> magneticField); public: DataHandle<IndexSourceLinkContainer> m_inputSourceLinks{"inputSourceLinks", Gaudi::DataHandle::Reader, this}; @@ -55,10 +65,11 @@ public: Gaudi::DataHandle::Reader, this}; DataHandle<TrajectoriesContainer> m_outputTrajectories{"outputTrajectories", Gaudi::DataHandle::Writer, this}; - Gaudi::Property<double> m_chi2CutOff{this, "chi2CutOff", 15.}; - Gaudi::Property<size_t> m_numMeasurementsCutOff{this, "numMeasurementsCutOff", 10}; + Gaudi::Property<std::vector<double>> m_etaBins{this, "etaBins", {}}; + Gaudi::Property<std::vector<double>> m_chi2CutOff{this, "chi2CutOff", {15.}}; + Gaudi::Property<std::vector<size_t>> m_numMeasurementsCutOff{this, "numMeasurementsCutOff", {10}}; - CKFTrackingFunction m_trackFinderFunc; + std::shared_ptr<CKFTrackingFunction> m_trackFinderFunc; SmartIF<IGeoSvc> m_geoSvc; std::shared_ptr<const Jug::BField::DD4hepBField> m_BField = nullptr; diff --git a/JugTrack/src/components/CKFTrackingFunction.cpp b/JugTrack/src/components/CKFTrackingFunction.cpp index b4993eb5e0a51825c3b457bc7cdbea1df1bb3b80..be6893eb3ce0117f16cb8ee9bb606521fba2ef60 100644 --- a/JugTrack/src/components/CKFTrackingFunction.cpp +++ b/JugTrack/src/components/CKFTrackingFunction.cpp @@ -28,13 +28,14 @@ namespace { using Stepper = Acts::EigenStepper<>; using Navigator = Acts::Navigator; using Propagator = Acts::Propagator<Stepper, Navigator>; - using CKF = Acts::CombinatorialKalmanFilter<Propagator, Updater, Smoother>; + using CKF = Acts::CombinatorialKalmanFilter<Propagator>; /** Finder implmentation . * * \ingroup track */ - struct CKFTrackingFunctionImpl { + struct CKFTrackingFunctionImpl + : public Jug::Reco::CKFTracking::CKFTrackingFunction { CKF trackFinder; CKFTrackingFunctionImpl(CKF&& f) : trackFinder(std::move(f)) {} @@ -42,7 +43,8 @@ namespace { Jug::Reco::CKFTracking::TrackFinderResult operator()(const Jug::IndexSourceLinkContainer& sourcelinks, const Jug::TrackParametersContainer& initialParameters, - const Jug::Reco::CKFTracking::TrackFinderOptions& options) const + const Jug::Reco::CKFTracking::TrackFinderOptions& options) + const override { return trackFinder.findTracks(sourcelinks, initialParameters, options); }; @@ -52,7 +54,8 @@ namespace { namespace Jug::Reco { - CKFTracking::CKFTrackingFunction CKFTracking::makeCKFTrackingFunction( + std::shared_ptr<CKFTracking::CKFTrackingFunction> + CKFTracking::makeCKFTrackingFunction( std::shared_ptr<const Acts::TrackingGeometry> trackingGeometry, std::shared_ptr<const Acts::MagneticFieldProvider> magneticField) { @@ -67,7 +70,7 @@ namespace Jug::Reco { CKF trackFinder(std::move(propagator)); // build the track finder functions. onws the track finder object. - return CKFTrackingFunctionImpl(std::move(trackFinder)); + return std::make_shared<CKFTrackingFunctionImpl>(std::move(trackFinder)); } } // namespace Jug::Reco diff --git a/JugTrack/src/components/SingleTrackSourceLinker.cpp b/JugTrack/src/components/SingleTrackSourceLinker.cpp index b05406a61450676164acc56ea5a424a6d3452ee2..06c92777baa3b55fb0e51668367c97ec8ecf0523 100644 --- a/JugTrack/src/components/SingleTrackSourceLinker.cpp +++ b/JugTrack/src/components/SingleTrackSourceLinker.cpp @@ -1,5 +1,3 @@ -#include "JugTrack/GeometryContainers.hpp" - // Gaudi #include "Gaudi/Property.h" #include "GaudiAlg/GaudiAlgorithm.h" @@ -27,6 +25,7 @@ #include "JugTrack/IndexSourceLink.hpp" #include "JugTrack/Measurement.hpp" #include "JugTrack/ProtoTrack.hpp" +#include "JugTrack/GeometryContainers.hpp" #include "eicd/TrackerHitCollection.h" @@ -40,10 +39,11 @@ namespace Jug::Reco { */ class SingleTrackSourceLinker : public GaudiAlgorithm { public: - DataHandle<eic::TrackerHitCollection> m_inputHitCollection{"inputHitCollection", Gaudi::DataHandle::Reader, this}; - DataHandle<IndexSourceLinkContainer> m_outputSourceLinks{"outputSourceLinks", Gaudi::DataHandle::Writer, this}; - DataHandle<MeasurementContainer> m_outputMeasurements{"outputMeasurements", Gaudi::DataHandle::Writer, this}; - DataHandle<ProtoTrackContainer> m_outputProtoTracks{"outputProtoTracks", Gaudi::DataHandle::Writer, this}; + DataHandle<eic::TrackerHitCollection> m_inputHitCollection{"inputHitCollection", Gaudi::DataHandle::Reader, this}; + DataHandle<std::list<IndexSourceLink>> m_sourceLinkStorage{"sourceLinkStorage", Gaudi::DataHandle::Writer, this}; + DataHandle<IndexSourceLinkContainer> m_outputSourceLinks{"outputSourceLinks", Gaudi::DataHandle::Writer, this}; + DataHandle<MeasurementContainer> m_outputMeasurements{"outputMeasurements", Gaudi::DataHandle::Writer, this}; + DataHandle<ProtoTrackContainer> m_outputProtoTracks{"outputProtoTracks", Gaudi::DataHandle::Writer, this}; /// Pointer to the geometry service SmartIF<IGeoSvc> m_geoSvc; @@ -51,6 +51,7 @@ namespace Jug::Reco { SingleTrackSourceLinker(const std::string& name, ISvcLocator* svcLoc) : GaudiAlgorithm(name, svcLoc) { declareProperty("inputHitCollection", m_inputHitCollection, ""); + declareProperty("sourceLinkStorage", m_sourceLinkStorage, ""); declareProperty("outputSourceLinks", m_outputSourceLinks, ""); declareProperty("outputMeasurements", m_outputMeasurements, ""); declareProperty("outputProtoTracks", m_outputProtoTracks, ""); @@ -74,6 +75,7 @@ namespace Jug::Reco { // input collection const eic::TrackerHitCollection* hits = m_inputHitCollection.get(); // Create output collections + auto linkStorage = m_sourceLinkStorage.createAndPut(); auto sourceLinks = m_outputSourceLinks.createAndPut(); auto measurements = m_outputMeasurements.createAndPut(); auto protoTracks = m_outputProtoTracks.createAndPut(); @@ -146,7 +148,8 @@ namespace Jug::Reco { // cov << 0.05, 0., 0., 0., 0.05, 0., 0., 0., 900. * Acts::UnitConstants::ps * Acts::UnitConstants::ps; // Acts::Vector3 par(localX, localY, simHit.time()); - IndexSourceLink sourceLink(surface->geometryId(), ihit); + linkStorage->emplace_back(surface->geometryId(), ihit); + IndexSourceLink& sourceLink = linkStorage->back(); auto meas = Acts::makeMeasurement(sourceLink, pos, cov, Acts::eBoundLoc0, Acts::eBoundLoc1); //, Acts::eBoundTime); @@ -174,7 +177,7 @@ namespace Jug::Reco { // add to output containers. since the input is already geometry-order, // new elements in geometry containers can just be appended at the end. - sourceLinks->emplace_hint(sourceLinks->end(), std::move(sourceLink)); + sourceLinks->emplace_hint(sourceLinks->end(), sourceLink); measurements->emplace_back(std::move(meas)); ihit++; diff --git a/JugTrack/src/components/TrackFindingAlgorithm.cpp b/JugTrack/src/components/TrackFindingAlgorithm.cpp index 8e83158a41c24e467f1510642e51c4f482275646..73b65c022661c99098d1280941b719c5824b1e2f 100644 --- a/JugTrack/src/components/TrackFindingAlgorithm.cpp +++ b/JugTrack/src/components/TrackFindingAlgorithm.cpp @@ -89,9 +89,13 @@ namespace Jug::Reco { debug() << "B(z=" << z << " mm) = " << b.transpose() << " T" << endmsg; } - // chi2 and #sourclinks per surface cutoffs + // eta bins, chi2 and #sourclinks per surface cutoffs m_sourcelinkSelectorCfg = { - {Acts::GeometryIdentifier(), {m_chi2CutOff, m_numMeasurementsCutOff}}, + {Acts::GeometryIdentifier(), + {m_etaBins, m_chi2CutOff, + {m_numMeasurementsCutOff.begin(), m_numMeasurementsCutOff.end()} + } + }, }; m_trackFinderFunc = TrackFindingAlgorithm::makeTrackFinderFunction(m_geoSvc->trackingGeometry(), m_BField); auto im = _msgMap.find(msgLevel()); @@ -121,12 +125,27 @@ namespace Jug::Reco { Acts::PropagatorPlainOptions pOptions; pOptions.maxSteps = 10000; + MeasurementCalibrator calibrator{*measurements}; + Acts::GainMatrixUpdater kfUpdater; + Acts::GainMatrixSmoother kfSmoother; + Acts::MeasurementSelector measSel{m_sourcelinkSelectorCfg}; + + Acts::CombinatorialKalmanFilterExtensions extensions; + extensions.calibrator.connect<&MeasurementCalibrator::calibrate>(&calibrator); + extensions.updater.connect<&Acts::GainMatrixUpdater::operator()>(&kfUpdater); + extensions.smoother.connect<&Acts::GainMatrixSmoother::operator()>( + &kfSmoother); + extensions.measurementSelector.connect<&Acts::MeasurementSelector::select>( + &measSel); + // Set the CombinatorialKalmanFilter options TrackFindingAlgorithm::TrackFinderOptions options( - m_geoctx, m_fieldctx, m_calibctx, IndexSourceLinkAccessor(), MeasurementCalibrator(*measurements), - Acts::MeasurementSelector(m_sourcelinkSelectorCfg), Acts::LoggerWrapper{logger()}, pOptions, &(*pSurface)); + m_geoctx, m_fieldctx, m_calibctx, + IndexSourceLinkAccessor(), extensions, + Acts::LoggerWrapper{logger()}, + pOptions, &(*pSurface)); - auto results = m_trackFinderFunc(*src_links, *init_trk_params, options); + auto results = (*m_trackFinderFunc)(*src_links, *init_trk_params, options); for (std::size_t iseed = 0; iseed < init_trk_params->size(); ++iseed) { diff --git a/JugTrack/src/components/TrackFindingAlgorithm.h b/JugTrack/src/components/TrackFindingAlgorithm.h index 93deba43a8e04147b770702c9b155bd17f559380..ac6ed014eab5170b34d5830ee8f5d193d93635a7 100644 --- a/JugTrack/src/components/TrackFindingAlgorithm.h +++ b/JugTrack/src/components/TrackFindingAlgorithm.h @@ -37,16 +37,26 @@ class TrackFindingAlgorithm : public GaudiAlgorithm { public: /// Track finder function that takes input measurements, initial trackstate /// and track finder options and returns some track-finder-specific result. - using TrackFinderOptions = Acts::CombinatorialKalmanFilterOptions<IndexSourceLinkAccessor, MeasurementCalibrator, Acts::MeasurementSelector>; - using TrackFinderResult = std::vector<Acts::Result<Acts::CombinatorialKalmanFilterResult<IndexSourceLink>>>; - using TrackFinderFunction = std::function<TrackFinderResult( - const IndexSourceLinkContainer&, const TrackParametersContainer&, const TrackFinderOptions&)>; + using TrackFinderOptions = Acts::CombinatorialKalmanFilterOptions<IndexSourceLinkAccessor>; + using TrackFinderResult = std::vector<Acts::Result<Acts::CombinatorialKalmanFilterResult>>; + + /// Find function that takes the above parameters + /// @note This is separated into a virtual interface to keep compilation units + /// small + class TrackFinderFunction { + public: + virtual ~TrackFinderFunction() = default; + virtual TrackFinderResult operator()(const IndexSourceLinkContainer&, + const TrackParametersContainer&, + const TrackFinderOptions&) const = 0; + }; /// Create the track finder function implementation. /// The magnetic field is intentionally given by-value since the variant /// contains shared_ptr anyways. - static TrackFinderFunction makeTrackFinderFunction(std::shared_ptr<const Acts::TrackingGeometry> trackingGeometry, - std::shared_ptr<const Acts::MagneticFieldProvider> magneticField); + static std::shared_ptr<TrackFinderFunction> makeTrackFinderFunction( + std::shared_ptr<const Acts::TrackingGeometry> trackingGeometry, + std::shared_ptr<const Acts::MagneticFieldProvider> magneticField); public: DataHandle<IndexSourceLinkContainer> m_inputSourceLinks{"inputSourceLinks", Gaudi::DataHandle::Reader, this}; @@ -55,10 +65,11 @@ public: Gaudi::DataHandle::Reader, this}; DataHandle<TrajectoriesContainer> m_outputTrajectories{"outputTrajectories", Gaudi::DataHandle::Writer, this}; - Gaudi::Property<double> m_chi2CutOff{this, "chi2CutOff", 15.}; - Gaudi::Property<size_t> m_numMeasurementsCutOff{this, "numMeasurementsCutOff", 10}; + Gaudi::Property<std::vector<double>> m_etaBins{this, "etaBins", {}}; + Gaudi::Property<std::vector<double>> m_chi2CutOff{this, "chi2CutOff", {15.}}; + Gaudi::Property<std::vector<size_t>> m_numMeasurementsCutOff{this, "numMeasurementsCutOff", {10}}; - TrackFinderFunction m_trackFinderFunc; + std::shared_ptr<TrackFinderFunction> m_trackFinderFunc; SmartIF<IGeoSvc> m_geoSvc; std::shared_ptr<const Jug::BField::DD4hepBField> m_BField = nullptr; diff --git a/JugTrack/src/components/TrackFindingAlgorithmFunction.cpp b/JugTrack/src/components/TrackFindingAlgorithmFunction.cpp index 1e2bfecee2d6b316c0dbf4fb602e0a7b243dc848..921b3e26399434a8b7efba9f69c981c4150a92be 100644 --- a/JugTrack/src/components/TrackFindingAlgorithmFunction.cpp +++ b/JugTrack/src/components/TrackFindingAlgorithmFunction.cpp @@ -28,13 +28,14 @@ namespace { using Stepper = Acts::EigenStepper<>; using Navigator = Acts::Navigator; using Propagator = Acts::Propagator<Stepper, Navigator>; - using CKF = Acts::CombinatorialKalmanFilter<Propagator, Updater, Smoother>; + using CKF = Acts::CombinatorialKalmanFilter<Propagator>; /** Finder implmentation . * * \ingroup track */ - struct TrackFinderFunctionImpl { + struct TrackFinderFunctionImpl + : public Jug::Reco::TrackFindingAlgorithm::TrackFinderFunction { CKF trackFinder; TrackFinderFunctionImpl(CKF&& f) : trackFinder(std::move(f)) {} @@ -42,7 +43,8 @@ namespace { Jug::Reco::TrackFindingAlgorithm::TrackFinderResult operator()(const Jug::IndexSourceLinkContainer& sourcelinks, const Jug::TrackParametersContainer& initialParameters, - const Jug::Reco::TrackFindingAlgorithm::TrackFinderOptions& options) const + const Jug::Reco::TrackFindingAlgorithm::TrackFinderOptions& options) + const override { return trackFinder.findTracks(sourcelinks, initialParameters, options); }; @@ -52,7 +54,8 @@ namespace { namespace Jug::Reco { - TrackFindingAlgorithm::TrackFinderFunction TrackFindingAlgorithm::makeTrackFinderFunction( + std::shared_ptr<TrackFindingAlgorithm::TrackFinderFunction> + TrackFindingAlgorithm::makeTrackFinderFunction( std::shared_ptr<const Acts::TrackingGeometry> trackingGeometry, std::shared_ptr<const Acts::MagneticFieldProvider> magneticField) { @@ -67,7 +70,7 @@ namespace Jug::Reco { CKF trackFinder(std::move(propagator)); // build the track finder functions. onws the track finder object. - return TrackFinderFunctionImpl(std::move(trackFinder)); + return std::make_shared<TrackFinderFunctionImpl>(std::move(trackFinder)); } } // namespace Jug::Reco diff --git a/JugTrack/src/components/TrackFittingAlgorithm.cpp b/JugTrack/src/components/TrackFittingAlgorithm.cpp index 31b3200c8368ecd1378d0c5cb748191e1325f0c1..640ff7c60fc03342e10c57720ac8aa9379a2de89 100644 --- a/JugTrack/src/components/TrackFittingAlgorithm.cpp +++ b/JugTrack/src/components/TrackFittingAlgorithm.cpp @@ -104,16 +104,19 @@ namespace Jug::Reco { // kfOptions.multipleScattering = m_cfg.multipleScattering; // kfOptions.energyLoss = m_cfg.energyLoss; - #if Acts_VERSION_MAJOR < 14 - Acts::KalmanFitterOptions<MeasurementCalibrator, Acts::VoidOutlierFinder> kfOptions( - m_geoctx, m_fieldctx, m_calibctx, MeasurementCalibrator(*measurements), - Acts::VoidOutlierFinder(), Acts::LoggerWrapper{logger()}, pOptions, &(*pSurface)); - #else - Acts::KalmanFitterOptions<MeasurementCalibrator, Acts::VoidOutlierFinder, Acts::VoidReverseFilteringLogic> kfOptions( - m_geoctx, m_fieldctx, m_calibctx, MeasurementCalibrator(*measurements), - Acts::VoidOutlierFinder(), Acts::VoidReverseFilteringLogic(), - Acts::LoggerWrapper{logger()}, pOptions, &(*pSurface)); - #endif + Acts::KalmanFitterExtensions extensions; + MeasurementCalibrator calibrator{*measurements}; + extensions.calibrator.connect<&MeasurementCalibrator::calibrate>(&calibrator); + Acts::GainMatrixUpdater kfUpdater; + Acts::GainMatrixSmoother kfSmoother; + extensions.updater.connect<&Acts::GainMatrixUpdater::operator()>(&kfUpdater); + extensions.smoother.connect<&Acts::GainMatrixSmoother::operator()>( + &kfSmoother); + + Acts::KalmanFitterOptions kfOptions( + m_geoctx, m_fieldctx, m_calibctx, extensions, + Acts::LoggerWrapper{logger()}, Acts::PropagatorPlainOptions(), + &(*pSurface)); // used for processing the data std::vector<IndexSourceLink> trackSourceLinks; @@ -142,18 +145,16 @@ namespace Jug::Reco { trackSourceLinks.reserve(protoTrack.size()); for (auto hitIndex : protoTrack) { - if (msgLevel(MSG::DEBUG)) { - debug() << " hit index = " << hitIndex << endmsg; - } - auto sourceLink = sourceLinks->nth(hitIndex); - auto geoId = sourceLink->geometryId(); - if (sourceLink == sourceLinks->end()) { - ACTS_FATAL("Proto track " << itrack << " contains invalid hit index " + if (auto it = sourceLinks->nth(hitIndex); it != sourceLinks->end()) { + const IndexSourceLink& sourceLink = *it; + auto geoId = sourceLink.geometryId(); + trackSourceLinks.push_back(std::cref(sourceLink)); + //surfSequence.push_back(m_cfg.trackingGeometry->findSurface(geoId)); + } else { + ACTS_FATAL("Proto track " << itrack << " contains invalid hit index" << hitIndex); return StatusCode::FAILURE; } - trackSourceLinks.push_back(*sourceLink); - //surfSequence.push_back(m_cfg.trackingGeometry->findSurface(geoId)); } if (msgLevel(MSG::DEBUG)) { diff --git a/JugTrack/src/components/TrackFittingAlgorithm.h b/JugTrack/src/components/TrackFittingAlgorithm.h index 33b5e446f4ebb538c6488681a58f61fd5666a047..2b4c312d5b87e81d12191d36dc4e2ce8be6a6a4f 100644 --- a/JugTrack/src/components/TrackFittingAlgorithm.h +++ b/JugTrack/src/components/TrackFittingAlgorithm.h @@ -43,20 +43,11 @@ namespace Jug::Reco { public: /// Track fitter function that takes input measurements, initial trackstate /// and fitter options and returns some track-fitter-specific result. - #if Acts_VERSION_MAJOR < 14 using TrackFitterOptions = - Acts::KalmanFitterOptions<MeasurementCalibrator, Acts::VoidOutlierFinder>; - #else - using TrackFitterOptions = - Acts::KalmanFitterOptions< - MeasurementCalibrator, - Acts::VoidOutlierFinder, - Acts::VoidReverseFilteringLogic - >; - #endif + Acts::KalmanFitterOptions; //using TrackFinderResult = Acts::Result<Acts::CombinatorialKalmanFilterResult<SourceLink>>; - using FitterResult = Acts::Result<Acts::KalmanFitterResult<IndexSourceLink>>; + using FitterResult = Acts::Result<Acts::KalmanFitterResult>; /// Fit function that takes input measurements, initial trackstate and fitter using FitterFunction = std::function<FitterResult( diff --git a/JugTrack/src/components/TrackFittingFunction.cpp b/JugTrack/src/components/TrackFittingFunction.cpp index 51ff3adf47deb57390a31a2cb396c81cefdef47d..1f2f7e801858aa3683d2a983bf2ac9ccf611defa 100644 --- a/JugTrack/src/components/TrackFittingFunction.cpp +++ b/JugTrack/src/components/TrackFittingFunction.cpp @@ -18,9 +18,9 @@ namespace { using Smoother = Acts::GainMatrixSmoother; using Stepper = Acts::EigenStepper<>; using Propagator = Acts::Propagator<Stepper, Acts::Navigator>; - using Fitter = Acts::KalmanFitter<Propagator, Updater, Smoother>; + using Fitter = Acts::KalmanFitter<Propagator>; using DirectPropagator = Acts::Propagator<Stepper, Acts::DirectNavigator>; - using DirectFitter = Acts::KalmanFitter<DirectPropagator, Updater, Smoother>; + using DirectFitter = Acts::KalmanFitter<DirectPropagator>; /** Fitter implmentation . @@ -38,36 +38,22 @@ namespace { const Jug::TrackParameters& initialParameters, const Jug::Reco::TrackFittingAlgorithm::TrackFitterOptions& options) const { - return trackFitter.fit(sourceLinks, initialParameters, options); + return trackFitter.fit(sourceLinks.begin(), sourceLinks.end(), initialParameters, options); } - //TrackFittingAlgorithm::TrackFitterResult - //operator()(const std::vector<SourceLink>& sourceLinks, - // const TrackParameters& initialParameters, - // const TrackFittingAlgorithm::TrackFitterOptions& options) const - //{ - // return trackFitter.fit(sourceLinks, initialParameters, options); - //}; }; } // namespace namespace Jug::Reco { - //using InputMagneticField = typename std::decay_t<decltype(inputField)>::element_type; - //using MagneticField = Acts::SharedBField<InputMagneticField>; - //using Stepper = Acts::EigenStepper<MagneticField>; - //using Navigator = Acts::Navigator; - //using Propagator = Acts::Propagator<Stepper, Navigator>; - //using Fitter = Acts::KalmanFitter<Propagator, Updater, Smoother>; - using Updater = Acts::GainMatrixUpdater; using Smoother = Acts::GainMatrixSmoother; using Stepper = Acts::EigenStepper<>; using Propagator = Acts::Propagator<Stepper, Acts::Navigator>; - using Fitter = Acts::KalmanFitter<Propagator, Updater, Smoother>; + using Fitter = Acts::KalmanFitter<Propagator>; using DirectPropagator = Acts::Propagator<Stepper, Acts::DirectNavigator>; - using DirectFitter = Acts::KalmanFitter<DirectPropagator, Updater, Smoother>; + using DirectFitter = Acts::KalmanFitter<DirectPropagator>; TrackFittingAlgorithm::FitterFunction TrackFittingAlgorithm::makeTrackFittingFunction( std::shared_ptr<const Acts::TrackingGeometry> trackingGeometry, diff --git a/JugTrack/src/components/TrackerSourceLinker.cpp b/JugTrack/src/components/TrackerSourceLinker.cpp index d835dc927a03254746b64ff384a28ce1a38d6630..2c8dbd1557ae5d116b6a8b3d03038eb692299760 100644 --- a/JugTrack/src/components/TrackerSourceLinker.cpp +++ b/JugTrack/src/components/TrackerSourceLinker.cpp @@ -43,6 +43,7 @@ namespace Jug::Reco { class TrackerSourceLinker : public GaudiAlgorithm { public: DataHandle<eic::TrackerHitCollection> m_inputHitCollection{"inputHitCollection", Gaudi::DataHandle::Reader, this}; + DataHandle<std::list<IndexSourceLink>> m_sourceLinkStorage{"sourceLinkStorage", Gaudi::DataHandle::Writer, this}; DataHandle<IndexSourceLinkContainer> m_outputSourceLinks{"outputSourceLinks", Gaudi::DataHandle::Writer, this}; DataHandle<MeasurementContainer> m_outputMeasurements{"outputMeasurements", Gaudi::DataHandle::Writer, this}; /// Pointer to the geometry service @@ -52,7 +53,8 @@ namespace Jug::Reco { TrackerSourceLinker(const std::string& name, ISvcLocator* svcLoc) : GaudiAlgorithm(name, svcLoc) { declareProperty("inputHitCollection", m_inputHitCollection, ""); - declareProperty("outputSourceLinks", m_outputSourceLinks, ""); + declareProperty("sourceLinkStorage", m_sourceLinkStorage, ""); + declareProperty("outputSourceLinks", m_outputSourceLinks, ""); declareProperty("outputMeasurements", m_outputMeasurements, ""); } @@ -77,7 +79,8 @@ namespace Jug::Reco { // input collection const eic::TrackerHitCollection* hits = m_inputHitCollection.get(); // Create output collections - auto sourceLinks = m_outputSourceLinks.createAndPut(); + auto linkStorage = m_sourceLinkStorage.createAndPut(); + auto sourceLinks = m_outputSourceLinks.createAndPut(); auto measurements = m_outputMeasurements.createAndPut(); sourceLinks->reserve(hits->size()); measurements->reserve(hits->size()); @@ -135,12 +138,13 @@ namespace Jug::Reco { // // variable hitIdx not used anywhere //Index hitIdx = measurements->size(); - IndexSourceLink sourceLink(surface->geometryId(), ihit); + linkStorage->emplace_back(surface->geometryId(), ihit); + IndexSourceLink& sourceLink = linkStorage->back(); auto meas = Acts::makeMeasurement(sourceLink, loc, cov, Acts::eBoundLoc0, Acts::eBoundLoc1); // add to output containers. since the input is already geometry-order, // new elements in geometry containers can just be appended at the end. - sourceLinks->emplace_hint(sourceLinks->end(), std::move(sourceLink)); + sourceLinks->emplace_hint(sourceLinks->end(), sourceLink); measurements->emplace_back(std::move(meas)); ihit++;