File indexing completed on 2025-08-05 08:09:44
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/MeasurementCalibration.hpp"
0015 #include "ActsExamples/EventData/ProtoTrack.hpp"
0016 #include "ActsExamples/EventData/Trajectories.hpp"
0017 #include "ActsExamples/Framework/WhiteBoard.hpp"
0018
0019 ActsExamples::AlignmentAlgorithm::AlignmentAlgorithm(Config cfg,
0020 Acts::Logging::Level lvl)
0021 : ActsExamples::IAlgorithm("AlignmentAlgorithm", lvl),
0022 m_cfg(std::move(cfg)) {
0023 if (m_cfg.inputMeasurements.empty()) {
0024 throw std::invalid_argument("Missing input measurement collection");
0025 }
0026 if (m_cfg.inputSourceLinks.empty()) {
0027 throw std::invalid_argument("Missing input source links 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_inputSourceLinks.initialize(m_cfg.inputSourceLinks);
0043 m_inputProtoTracks.initialize(m_cfg.inputProtoTracks);
0044 m_inputInitialTrackParameters.initialize(m_cfg.inputInitialTrackParameters);
0045 m_outputAlignmentParameters.initialize(m_cfg.outputAlignmentParameters);
0046 }
0047
0048 ActsExamples::ProcessCode ActsExamples::AlignmentAlgorithm::execute(
0049 const ActsExamples::AlgorithmContext& ctx) const {
0050
0051 const auto& measurements = m_inputMeasurements(ctx);
0052 const auto& sourceLinks = m_inputSourceLinks(ctx);
0053 const auto& protoTracks = m_inputProtoTracks(ctx);
0054 const auto& initialParameters = m_inputInitialTrackParameters(ctx);
0055
0056
0057 if (protoTracks.size() != initialParameters.size()) {
0058 ACTS_FATAL("Inconsistent number of proto tracks and parameters "
0059 << protoTracks.size() << " vs " << initialParameters.size());
0060 return ProcessCode::ABORT;
0061 }
0062
0063 std::size_t numTracksUsed = protoTracks.size();
0064 if (m_cfg.maxNumTracks > 0 &&
0065 m_cfg.maxNumTracks < static_cast<int>(protoTracks.size())) {
0066 numTracksUsed = m_cfg.maxNumTracks;
0067 }
0068
0069
0070 std::vector<std::vector<IndexSourceLink>> sourceLinkTrackContainer;
0071 sourceLinkTrackContainer.reserve(numTracksUsed);
0072 std::vector<IndexSourceLink> trackSourceLinks;
0073 for (std::size_t itrack = 0; itrack < numTracksUsed; ++itrack) {
0074
0075 const auto& protoTrack = protoTracks[itrack];
0076
0077
0078 trackSourceLinks.clear();
0079 trackSourceLinks.reserve(protoTrack.size());
0080
0081
0082 for (auto hitIndex : protoTrack) {
0083 auto sourceLink = sourceLinks.nth(hitIndex);
0084 if (sourceLink == sourceLinks.end()) {
0085 ACTS_FATAL("Proto track " << itrack << " contains invalid hit index"
0086 << hitIndex);
0087 return ProcessCode::ABORT;
0088 }
0089 trackSourceLinks.push_back(*sourceLink);
0090 }
0091 sourceLinkTrackContainer.push_back(trackSourceLinks);
0092 }
0093
0094
0095 AlignmentParameters alignedParameters;
0096
0097
0098 auto pSurface = Acts::Surface::makeShared<Acts::PerigeeSurface>(
0099 Acts::Vector3{0., 0., 0.});
0100
0101 Acts::KalmanFitterExtensions<Acts::VectorMultiTrajectory> extensions;
0102 PassThroughCalibrator pcalibrator;
0103 MeasurementCalibratorAdapter calibrator(pcalibrator, measurements);
0104 extensions.calibrator.connect<&MeasurementCalibratorAdapter::calibrate>(
0105 &calibrator);
0106 Acts::GainMatrixUpdater kfUpdater;
0107 Acts::GainMatrixSmoother kfSmoother;
0108 extensions.updater.connect<
0109 &Acts::GainMatrixUpdater::operator()<Acts::VectorMultiTrajectory>>(
0110 &kfUpdater);
0111 extensions.smoother.connect<
0112 &Acts::GainMatrixSmoother::operator()<Acts::VectorMultiTrajectory>>(
0113 &kfSmoother);
0114
0115
0116 TrackFitterOptions kfOptions(ctx.geoContext, ctx.magFieldContext,
0117 ctx.calibContext, extensions,
0118 Acts::PropagatorPlainOptions(), &(*pSurface));
0119
0120
0121 ActsAlignment::AlignmentOptions<TrackFitterOptions> alignOptions(
0122 kfOptions, m_cfg.alignedTransformUpdater, m_cfg.alignedDetElements,
0123 m_cfg.chi2ONdfCutOff, m_cfg.deltaChi2ONdfCutOff, m_cfg.maxNumIterations);
0124
0125 ACTS_DEBUG("Invoke track-based alignment with " << numTracksUsed
0126 << " input tracks");
0127 auto result =
0128 (*m_cfg.align)(sourceLinkTrackContainer, initialParameters, alignOptions);
0129 if (result.ok()) {
0130 const auto& alignOutput = result.value();
0131 alignedParameters = alignOutput.alignedParameters;
0132 ACTS_VERBOSE(
0133 "Alignment finished with deltaChi2 = " << result.value().deltaChi2);
0134 } else {
0135 ACTS_WARNING("Alignment failed with " << result.error());
0136 }
0137
0138
0139 m_outputAlignmentParameters(ctx, std::move(alignedParameters));
0140 return ActsExamples::ProcessCode::SUCCESS;
0141 }