File indexing completed on 2026-09-09 08:19:56
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "ActsExamples/Alignment/AlignmentAlgorithm.hpp"
0010
0011 #include "Acts/Surfaces/PerigeeSurface.hpp"
0012 #include "Acts/TrackFitting/GainMatrixSmoother.hpp"
0013 #include "Acts/TrackFitting/GainMatrixUpdater.hpp"
0014 #include "ActsExamples/EventData/IndexSourceLink.hpp"
0015 #include "ActsExamples/EventData/MeasurementCalibration.hpp"
0016 #include "ActsExamples/EventData/ProtoTrack.hpp"
0017 #include "ActsExamples/EventData/Trajectories.hpp"
0018 #include "ActsExamples/Framework/WhiteBoard.hpp"
0019
0020 namespace ActsExamples {
0021
0022 AlignmentAlgorithm::AlignmentAlgorithm(
0023 Config cfg, std::unique_ptr<const Acts::Logger> logger)
0024 : IAlgorithm("AlignmentAlgorithm", std::move(logger)),
0025 m_cfg(std::move(cfg)) {
0026 if (m_cfg.inputMeasurements.empty()) {
0027 throw std::invalid_argument("Missing input measurement collection");
0028 }
0029 if (m_cfg.inputProtoTracks.empty()) {
0030 throw std::invalid_argument("Missing input proto tracks collection");
0031 }
0032 if (m_cfg.inputInitialTrackParameters.empty()) {
0033 throw std::invalid_argument(
0034 "Missing input initial track parameters collection");
0035 }
0036 if (m_cfg.outputAlignmentParameters.empty()) {
0037 throw std::invalid_argument(
0038 "Missing output alignment parameters collection");
0039 }
0040
0041 m_inputMeasurements.initialize(m_cfg.inputMeasurements);
0042 m_inputProtoTracks.initialize(m_cfg.inputProtoTracks);
0043 m_inputInitialTrackParameters.initialize(m_cfg.inputInitialTrackParameters);
0044 m_outputAlignmentParameters.initialize(m_cfg.outputAlignmentParameters);
0045 }
0046
0047 ProcessCode AlignmentAlgorithm::execute(const AlgorithmContext& ctx) const {
0048
0049 const auto& measurements = m_inputMeasurements(ctx);
0050 const auto& protoTracks = m_inputProtoTracks(ctx);
0051 const auto& initialParameters = m_inputInitialTrackParameters(ctx);
0052
0053
0054 if (protoTracks.size() != initialParameters.size()) {
0055 ACTS_FATAL("Inconsistent number of proto tracks and parameters "
0056 << protoTracks.size() << " vs " << initialParameters.size());
0057 return ProcessCode::ABORT;
0058 }
0059
0060 std::size_t numTracksUsed = protoTracks.size();
0061 if (m_cfg.maxNumTracks > 0) {
0062 numTracksUsed =
0063 std::min(static_cast<std::size_t>(m_cfg.maxNumTracks), numTracksUsed);
0064 }
0065
0066
0067 std::vector<std::vector<IndexSourceLink>> sourceLinkTrackContainer;
0068 sourceLinkTrackContainer.reserve(numTracksUsed);
0069 std::vector<IndexSourceLink> trackSourceLinks;
0070 for (std::size_t itrack = 0; itrack < numTracksUsed; ++itrack) {
0071
0072 const auto& protoTrack = protoTracks[itrack];
0073
0074
0075 trackSourceLinks.clear();
0076 trackSourceLinks.reserve(protoTrack.size());
0077
0078
0079 for (auto measIndex : protoTrack) {
0080 const ConstVariableBoundMeasurementProxy measurement =
0081 measurements.getMeasurement(measIndex);
0082 IndexSourceLink sourceLink(measurement.geometryId(), measIndex);
0083 trackSourceLinks.push_back(sourceLink);
0084 }
0085 sourceLinkTrackContainer.push_back(trackSourceLinks);
0086 }
0087
0088
0089 AlignmentParameters alignedParameters;
0090
0091
0092 auto pSurface = Acts::Surface::makeShared<Acts::PerigeeSurface>(
0093 Acts::Vector3{0., 0., 0.});
0094
0095 Acts::KalmanFitterExtensions<Acts::VectorMultiTrajectory> extensions;
0096 PassThroughCalibrator pcalibrator;
0097 MeasurementCalibratorAdapter calibrator(pcalibrator, measurements);
0098 extensions.calibrator.connect<&MeasurementCalibratorAdapter::calibrate>(
0099 &calibrator);
0100 Acts::GainMatrixUpdater kfUpdater;
0101 Acts::GainMatrixSmoother kfSmoother;
0102 extensions.updater.connect<
0103 &Acts::GainMatrixUpdater::operator()<Acts::VectorMultiTrajectory>>(
0104 &kfUpdater);
0105 extensions.smoother.connect<
0106 &Acts::GainMatrixSmoother::operator()<Acts::VectorMultiTrajectory>>(
0107 &kfSmoother);
0108
0109
0110 TrackFitterOptions kfOptions(
0111 ctx.recoGeoContext, ctx.magFieldContext, ctx.calibContext, extensions,
0112 Acts::PropagatorPlainOptions(ctx.recoGeoContext, ctx.magFieldContext),
0113 &(*pSurface));
0114
0115
0116 ActsAlignment::AlignmentOptions<TrackFitterOptions> alignOptions(
0117 kfOptions, m_cfg.alignedTransformUpdater, m_cfg.alignedDetElements,
0118 m_cfg.chi2ONdfCutOff, m_cfg.deltaChi2ONdfCutOff, m_cfg.maxNumIterations);
0119
0120 ACTS_DEBUG("Invoke track-based alignment with " << numTracksUsed
0121 << " input tracks");
0122 auto result =
0123 (*m_cfg.align)(sourceLinkTrackContainer, initialParameters, alignOptions);
0124 if (result.ok()) {
0125 const auto& alignOutput = result.value();
0126 alignedParameters = alignOutput.alignedParameters;
0127 ACTS_VERBOSE(
0128 "Alignment finished with deltaChi2 = " << result.value().deltaChi2);
0129 } else {
0130 ACTS_WARNING("Alignment failed with " << result.error());
0131 }
0132
0133
0134 m_outputAlignmentParameters(ctx, std::move(alignedParameters));
0135 return ProcessCode::SUCCESS;
0136 }
0137
0138 }