File indexing completed on 2025-07-02 08:55:46
0001
0002
0003
0004 #include "CKFTracking.h"
0005
0006
0007 #include "Gaudi/Algorithm.h"
0008 #include "GaudiKernel/ToolHandle.h"
0009 #include "GaudiKernel/RndmGenerators.h"
0010 #include "Gaudi/Property.h"
0011
0012 #include "DDRec/CellIDPositionConverter.h"
0013 #include "DDRec/SurfaceManager.h"
0014 #include "DDRec/Surface.h"
0015
0016 #if Acts_VERSION_MAJOR < 36
0017 #include <Acts/EventData/Measurement.hpp>
0018 #endif
0019 #if Acts_VERSION_MAJOR >= 32
0020 #include "Acts/EventData/ProxyAccessor.hpp"
0021 #endif
0022 #include "Acts/Geometry/TrackingGeometry.hpp"
0023 #include "Acts/Plugins/DD4hep/DD4hepDetectorElement.hpp"
0024 #include "Acts/Surfaces/PerigeeSurface.hpp"
0025
0026 #if Acts_VERSION_MAJOR >= 39
0027 #include <Acts/TrackFinding/TrackStateCreator.hpp>
0028 #endif
0029 #include "Acts/TrackFitting/GainMatrixSmoother.hpp"
0030 #include "Acts/TrackFitting/GainMatrixUpdater.hpp"
0031 #include "Acts/Propagator/EigenStepper.hpp"
0032 #if Acts_VERSION_MAJOR >= 34
0033 #if Acts_VERSION_MAJOR >= 37
0034 #include "Acts/Propagator/ActorList.hpp"
0035 #else
0036 #include "Acts/Propagator/AbortList.hpp"
0037 #endif
0038 #include "Acts/Propagator/EigenStepper.hpp"
0039 #include "Acts/Propagator/MaterialInteractor.hpp"
0040 #include "Acts/Propagator/Navigator.hpp"
0041 #endif
0042 #include "Acts/Propagator/Propagator.hpp"
0043 #if Acts_VERSION_MAJOR >= 34
0044 #include "Acts/Propagator/StandardAborters.hpp"
0045 #endif
0046 #include "Acts/Definitions/Common.hpp"
0047 #include "Acts/Utilities/Helpers.hpp"
0048 #include "Acts/Utilities/Logger.hpp"
0049 #if Acts_VERSION_MAJOR >= 34
0050 #include "Acts/Utilities/TrackHelpers.hpp"
0051 #endif
0052 #include "Acts/Definitions/Units.hpp"
0053
0054 #include <k4FWCore/DataHandle.h>
0055 #include <k4Interface/IGeoSvc.h>
0056 #include "JugTrack/IActsGeoSvc.h"
0057 #include "JugTrack/DD4hepBField.h"
0058
0059 #include "ActsExamples/EventData/GeometryContainers.hpp"
0060 #include "ActsExamples/EventData/Measurement.hpp"
0061 #include "ActsExamples/EventData/MeasurementCalibration.hpp"
0062 #include "ActsExamples/EventData/Index.hpp"
0063 #include "ActsExamples/EventData/IndexSourceLink.hpp"
0064 #include "ActsExamples/EventData/Track.hpp"
0065
0066 #include <fmt/core.h>
0067 #include <fmt/ostream.h>
0068
0069 #include "edm4eic/TrackerHitCollection.h"
0070
0071 #include <functional>
0072 #include <stdexcept>
0073 #include <system_error>
0074 #include <type_traits>
0075 #include <vector>
0076 #include <random>
0077 #include <stdexcept>
0078
0079 template<> struct fmt::formatter<std::error_code> : fmt::ostream_formatter {};
0080
0081 static const std::map<int, Acts::Logging::Level> s_msgMap = {
0082 {MSG::DEBUG, Acts::Logging::DEBUG},
0083 {MSG::VERBOSE, Acts::Logging::VERBOSE},
0084 {MSG::INFO, Acts::Logging::INFO},
0085 {MSG::WARNING, Acts::Logging::WARNING},
0086 {MSG::FATAL, Acts::Logging::FATAL},
0087 {MSG::ERROR, Acts::Logging::ERROR},
0088 };
0089
0090 namespace Jug::Reco {
0091
0092 using namespace Acts::UnitLiterals;
0093
0094 CKFTracking::CKFTracking(const std::string& name, ISvcLocator* svcLoc)
0095 : Gaudi::Algorithm(name, svcLoc)
0096 {
0097 #if Acts_VERSION_MAJOR < 37 || (Acts_VERSION_MAJOR == 37 && Acts_VERSION_MINOR < 1)
0098 declareProperty("inputSourceLinks", m_inputSourceLinks, "");
0099 #endif
0100 declareProperty("inputMeasurements", m_inputMeasurements, "");
0101 declareProperty("inputInitialTrackParameters", m_inputInitialTrackParameters, "");
0102 declareProperty("outputTracks", m_outputTracks, "");
0103 declareProperty("outputTrajectories", m_outputTrajectories, "");
0104 }
0105
0106 StatusCode CKFTracking::initialize()
0107 {
0108 if (Gaudi::Algorithm::initialize().isFailure()) {
0109 return StatusCode::FAILURE;
0110 }
0111 m_geoSvc = service("GeoSvc");
0112 if (!m_geoSvc) {
0113 error() << "Unable to locate Geometry Service. "
0114 << "Make sure you have GeoSvc and SimSvc in the right order in the configuration." << endmsg;
0115 return StatusCode::FAILURE;
0116 }
0117 m_actsGeoSvc = service("ActsGeoSvc");
0118 if (!m_actsGeoSvc) {
0119 error() << "Unable to locate ACTS Geometry Service. "
0120 << "Make sure you have ActsGeoSvc in the right place in the configuration." << endmsg;
0121 return StatusCode::FAILURE;
0122 }
0123
0124 m_BField = std::dynamic_pointer_cast<const Jug::BField::DD4hepBField>(m_actsGeoSvc->getFieldProvider());
0125 m_fieldctx = Jug::BField::BFieldVariant(m_BField);
0126
0127
0128 m_sourcelinkSelectorCfg = {
0129 {Acts::GeometryIdentifier(),
0130 {m_etaBins, m_chi2CutOff,
0131 {m_numMeasurementsCutOff.begin(), m_numMeasurementsCutOff.end()}
0132 }
0133 },
0134 };
0135 m_trackFinderFunc = CKFTracking::makeCKFTrackingFunction(m_actsGeoSvc->trackingGeometry(), m_BField);
0136 auto im = s_msgMap.find(msgLevel());
0137 if (im != s_msgMap.end()) {
0138 m_actsLoggingLevel = im->second;
0139 }
0140 return StatusCode::SUCCESS;
0141 }
0142
0143 StatusCode CKFTracking::execute(const EventContext&) const
0144 {
0145
0146 #if Acts_VERSION_MAJOR < 37 || (Acts_VERSION_MAJOR == 37 && Acts_VERSION_MINOR < 1)
0147 const auto* const src_links = m_inputSourceLinks.get();
0148 #endif
0149 const auto* const init_trk_params = m_inputInitialTrackParameters.get();
0150 const auto* const measurements = m_inputMeasurements.get();
0151
0152
0153 auto* acts_trajectories = m_outputTrajectories.createAndPut();
0154 acts_trajectories->reserve(init_trk_params->size());
0155
0156
0157 auto pSurface = Acts::Surface::makeShared<Acts::PerigeeSurface>(Acts::Vector3{0., 0., 0.});
0158
0159 ACTS_LOCAL_LOGGER(Acts::getDefaultLogger("CKFTracking Logger", m_actsLoggingLevel));
0160
0161 #if Acts_VERSION_MAJOR >= 36
0162 Acts::PropagatorPlainOptions pOptions(m_geoctx, m_fieldctx);
0163 #else
0164 Acts::PropagatorPlainOptions pOptions;
0165 #endif
0166 pOptions.maxSteps = 10000;
0167
0168 ActsExamples::PassThroughCalibrator pcalibrator;
0169 ActsExamples::MeasurementCalibratorAdapter calibrator(pcalibrator, *measurements);
0170 Acts::GainMatrixUpdater kfUpdater;
0171 #if Acts_VERSION_MAJOR < 34
0172 Acts::GainMatrixSmoother kfSmoother;
0173 #endif
0174 Acts::MeasurementSelector measSel{m_sourcelinkSelectorCfg};
0175
0176 #if Acts_VERSION_MAJOR >= 36
0177 Acts::CombinatorialKalmanFilterExtensions<ActsExamples::TrackContainer>
0178 extensions;
0179 #else
0180 Acts::CombinatorialKalmanFilterExtensions<Acts::VectorMultiTrajectory>
0181 extensions;
0182 #endif
0183 #if Acts_VERSION_MAJOR < 39
0184 extensions.calibrator.connect<
0185 &ActsExamples::MeasurementCalibratorAdapter::calibrate>(
0186 &calibrator);
0187 #endif
0188 #if Acts_VERSION_MAJOR >= 36
0189 extensions.updater.connect<
0190 &Acts::GainMatrixUpdater::operator()<
0191 typename ActsExamples::TrackContainer::TrackStateContainerBackend>>(
0192 &kfUpdater);
0193 #else
0194 extensions.updater.connect<
0195 &Acts::GainMatrixUpdater::operator()<Acts::VectorMultiTrajectory>>(
0196 &kfUpdater);
0197 #endif
0198 #if Acts_VERSION_MAJOR < 34
0199 extensions.smoother.connect<
0200 &Acts::GainMatrixSmoother::operator()<Acts::VectorMultiTrajectory>>(
0201 &kfSmoother);
0202 #endif
0203 #if Acts_VERSION_MAJOR < 39
0204 extensions.measurementSelector
0205 .connect<&Acts::MeasurementSelector::select<Acts::VectorMultiTrajectory>>(
0206 &measSel);
0207 #endif
0208
0209 ActsExamples::IndexSourceLinkAccessor slAccessor;
0210 #if Acts_VERSION_MAJOR > 37 || (Acts_VERSION_MAJOR == 37 && Acts_VERSION_MINOR >= 1)
0211 slAccessor.container = &measurements->orderedIndices();
0212 #else
0213 slAccessor.container = src_links;
0214 #endif
0215 #if Acts_VERSION_MAJOR >=39
0216 using TrackStateCreatorType =
0217 Acts::TrackStateCreator<ActsExamples::IndexSourceLinkAccessor::Iterator,
0218 ActsExamples::TrackContainer>;
0219 TrackStateCreatorType trackStateCreator;
0220 trackStateCreator.sourceLinkAccessor
0221 .template connect<&ActsExamples::IndexSourceLinkAccessor::range>(&slAccessor);
0222 trackStateCreator.calibrator
0223 .template connect<&ActsExamples::MeasurementCalibratorAdapter::calibrate>(&calibrator);
0224 trackStateCreator.measurementSelector
0225 .template connect<&Acts::MeasurementSelector::select<Acts::VectorMultiTrajectory>>(&measSel);
0226
0227 extensions.createTrackStates
0228 .template connect<&TrackStateCreatorType::createTrackStates>(
0229 &trackStateCreator);
0230 #else
0231 Acts::SourceLinkAccessorDelegate<ActsExamples::IndexSourceLinkAccessor::Iterator>
0232 slAccessorDelegate;
0233 slAccessorDelegate.connect<&ActsExamples::IndexSourceLinkAccessor::range>(&slAccessor);
0234 #endif
0235
0236
0237 #if Acts_VERSION_MAJOR >= 39
0238 CKFTracking::TrackFinderOptions options(
0239 m_geoctx, m_fieldctx, m_calibctx,
0240 extensions, pOptions);
0241 #elif Acts_VERSION_MAJOR >= 34
0242 CKFTracking::TrackFinderOptions options(
0243 m_geoctx, m_fieldctx, m_calibctx, slAccessorDelegate,
0244 extensions, pOptions);
0245 #else
0246 CKFTracking::TrackFinderOptions options(
0247 m_geoctx, m_fieldctx, m_calibctx, slAccessorDelegate,
0248 extensions, pOptions, &(*pSurface));
0249 #endif
0250
0251 #if Acts_VERSION_MAJOR >= 36
0252 using Extrapolator = Acts::Propagator<Acts::EigenStepper<>, Acts::Navigator>;
0253 # if Acts_VERSION_MAJOR >= 37
0254 using ExtrapolatorOptions =
0255 Extrapolator::template Options<Acts::ActorList<Acts::MaterialInteractor,
0256 Acts::EndOfWorldReached>>;
0257 # else
0258 using ExtrapolatorOptions =
0259 Extrapolator::template Options<Acts::ActionList<Acts::MaterialInteractor>,
0260 Acts::AbortList<Acts::EndOfWorldReached>>;
0261 # endif
0262 Extrapolator extrapolator(
0263 Acts::EigenStepper<>(m_BField),
0264 Acts::Navigator({m_actsGeoSvc->trackingGeometry()},
0265 logger().cloneWithSuffix("Navigator")),
0266 logger().cloneWithSuffix("Propagator"));
0267 ExtrapolatorOptions extrapolationOptions(m_geoctx, m_fieldctx);
0268 #elif Acts_VERSION_MAJOR >= 34
0269 Acts::Propagator<Acts::EigenStepper<>, Acts::Navigator> extrapolator(
0270 Acts::EigenStepper<>(m_BField),
0271 Acts::Navigator({m_actsGeoSvc->trackingGeometry()},
0272 logger().cloneWithSuffix("Navigator")),
0273 logger().cloneWithSuffix("Propagator"));
0274
0275 Acts::PropagatorOptions<Acts::ActionList<Acts::MaterialInteractor>,
0276 Acts::AbortList<Acts::EndOfWorldReached>>
0277 extrapolationOptions(m_geoctx, m_fieldctx);
0278 #endif
0279
0280
0281 auto trackContainer = std::make_shared<Acts::VectorTrackContainer>();
0282 auto trackStateContainer = std::make_shared<Acts::VectorMultiTrajectory>();
0283 ActsExamples::TrackContainer tracks(trackContainer, trackStateContainer);
0284
0285
0286 tracks.addColumn<unsigned int>("seed");
0287 #if Acts_VERSION_MAJOR >= 32
0288 Acts::ProxyAccessor<unsigned int> seedNumber("seed");
0289 #else
0290 Acts::TrackAccessor<unsigned int> seedNumber("seed");
0291 #endif
0292 std::set<Acts::TrackIndexType> passed_tracks;
0293
0294
0295 for (std::size_t iseed = 0; iseed < init_trk_params->size(); ++iseed) {
0296 auto result =
0297 (*m_trackFinderFunc)(init_trk_params->at(iseed), options, tracks);
0298
0299 if (!result.ok()) {
0300 debug() << fmt::format("Track finding failed for seed {} with error {}", iseed, result.error()) << endmsg;
0301 continue;
0302 }
0303
0304
0305 auto& tracksForSeed = result.value();
0306 for (auto& track : tracksForSeed) {
0307
0308 #if Acts_VERSION_MAJOR >=34
0309 auto smoothingResult = Acts::smoothTrack(m_geoctx, track, logger());
0310 if (!smoothingResult.ok()) {
0311 ACTS_ERROR("Smoothing for seed "
0312 << iseed << " and track " << track.index()
0313 << " failed with error " << smoothingResult.error());
0314 continue;
0315 }
0316
0317 auto extrapolationResult = Acts::extrapolateTrackToReferenceSurface(
0318 track, *pSurface, extrapolator, extrapolationOptions,
0319 Acts::TrackExtrapolationStrategy::firstOrLast, logger());
0320 if (!extrapolationResult.ok()) {
0321 ACTS_ERROR("Extrapolation for seed "
0322 << iseed << " and track " << track.index()
0323 << " failed with error " << extrapolationResult.error());
0324 continue;
0325 }
0326 #endif
0327
0328 passed_tracks.insert(track.index());
0329 seedNumber(track) = iseed;
0330 }
0331 }
0332
0333 for (ssize_t track_index = static_cast<ssize_t>(tracks.size()) - 1; track_index >= 0; track_index--) {
0334 if (not passed_tracks.count(track_index)) {
0335
0336
0337
0338
0339 tracks.removeTrack(track_index);
0340 #if Acts_VERSION_MAJOR < 36 || (Acts_VERSION_MAJOR == 36 && Acts_VERSION_MINOR < 1)
0341
0342
0343 trackContainer->m_particleHypothesis.erase(trackContainer->m_particleHypothesis.begin() + track_index);
0344 #endif
0345 }
0346 }
0347
0348
0349
0350
0351 auto constTrackStateContainer =
0352 std::make_shared<Acts::ConstVectorMultiTrajectory>(
0353 std::move(*trackStateContainer));
0354
0355 auto constTrackContainer =
0356 std::make_shared<Acts::ConstVectorTrackContainer>(
0357 std::move(*trackContainer));
0358
0359 auto* constTracks = m_outputTracks.put(
0360 std::make_unique<ActsExamples::ConstTrackContainer>(constTrackContainer, constTrackStateContainer)
0361 );
0362
0363
0364 #if Acts_VERSION_MAJOR >= 32
0365 const Acts::ConstProxyAccessor<unsigned int> constSeedNumber("seed");
0366 #else
0367 const Acts::ConstTrackAccessor<unsigned int> constSeedNumber("seed");
0368 #endif
0369
0370
0371 ActsExamples::Trajectories::IndexedParameters parameters;
0372 std::vector<Acts::MultiTrajectoryTraits::IndexType> tips;
0373
0374 std::optional<unsigned int> lastSeed;
0375 for (const auto& track : *constTracks) {
0376 if (!lastSeed) {
0377 lastSeed = constSeedNumber(track);
0378 }
0379
0380 if (constSeedNumber(track) != lastSeed.value()) {
0381
0382 acts_trajectories->emplace_back(
0383 constTracks->trackStateContainer(),
0384 tips, parameters);
0385
0386 tips.clear();
0387 parameters.clear();
0388 }
0389
0390 lastSeed = constSeedNumber(track);
0391
0392 tips.push_back(track.tipIndex());
0393 parameters.emplace(
0394 std::pair{track.tipIndex(),
0395 ActsExamples::TrackParameters{track.referenceSurface().getSharedPtr(),
0396 track.parameters(), track.covariance(),
0397 track.particleHypothesis()}});
0398 }
0399
0400 if (tips.empty()) {
0401 info() << fmt::format("Last trajectory is empty") << endmsg;
0402 }
0403
0404
0405 acts_trajectories->emplace_back(
0406 constTracks->trackStateContainer(),
0407 std::move(tips), std::move(parameters));
0408
0409 return StatusCode::SUCCESS;
0410 }
0411
0412
0413 DECLARE_COMPONENT(CKFTracking)
0414 }