File indexing completed on 2026-09-20 08:19:24
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include "Acts/Definitions/Alignment.hpp"
0012 #include "Acts/Definitions/TrackParametrization.hpp"
0013 #include "Acts/EventData/MultiTrajectory.hpp"
0014 #include "Acts/EventData/MultiTrajectoryHelpers.hpp"
0015 #include "Acts/Geometry/GeometryContext.hpp"
0016 #include "Acts/Surfaces/Surface.hpp"
0017 #include "Acts/Utilities/Logger.hpp"
0018 #include "ActsAlignment/Kernel/AlignmentMask.hpp"
0019
0020 #include <unordered_map>
0021 #include <vector>
0022
0023 namespace ActsAlignment {
0024 struct AlignmentResult;
0025 }
0026
0027 namespace ActsAlignment::detail {
0028
0029
0030
0031
0032 struct TrackAlignmentState {
0033
0034 std::size_t measurementDim = 0;
0035
0036
0037 std::size_t trackParametersDim = 0;
0038
0039
0040 std::size_t alignmentDof = 0;
0041
0042
0043 Acts::DynamicMatrix measurementCovariance;
0044
0045
0046 Acts::DynamicMatrix trackParametersCovariance;
0047
0048
0049 Acts::DynamicMatrix projectionMatrix;
0050
0051
0052 Acts::DynamicVector residual;
0053
0054
0055 Acts::DynamicMatrix residualCovariance;
0056
0057
0058 double chi2 = 0;
0059
0060
0061 Acts::DynamicMatrix alignmentToResidualDerivative;
0062
0063
0064 Acts::DynamicVector alignmentToChi2Derivative;
0065
0066
0067 Acts::DynamicMatrix alignmentToChi2SecondDerivative;
0068
0069
0070
0071 std::unordered_map<const Acts::Surface*, std::pair<std::size_t, std::size_t>>
0072 alignedSurfaces;
0073 };
0074
0075
0076
0077
0078
0079
0080 void resetAlignmentDerivative(Acts::AlignmentToBoundMatrix& alignToBound,
0081 AlignmentMask mask);
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097 void finaliseTrackAlignState(TrackAlignmentState& alignState);
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111 void solveAlignmentParameters(
0112 const std::vector<TrackAlignmentState>& trackAlignmentStates,
0113 AlignmentResult& alignResult, const Acts::Logger& logger);
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139 template <typename traj_t>
0140 TrackAlignmentState trackAlignmentState(
0141 const Acts::GeometryContext& gctx, const traj_t& multiTraj,
0142 Acts::TrackIndexType entryIndex,
0143 const std::pair<Acts::DynamicMatrix,
0144 std::unordered_map<std::size_t, std::size_t>>&
0145 globalTrackParamsCov,
0146 const std::unordered_map<const Acts::Surface*, std::size_t>&
0147 idxedAlignSurfaces,
0148 const AlignmentMask& alignMask) {
0149
0150 TrackAlignmentState alignState;
0151
0152
0153 std::vector<std::pair<Acts::TrackIndexType, bool>> measurementStates;
0154 measurementStates.reserve(15);
0155
0156
0157
0158 std::size_t nAlignSurfaces = 0;
0159
0160
0161 multiTraj.visitBackwards(entryIndex, [&](const auto& ts) {
0162
0163 if (ts.hasSmoothed()) {
0164
0165
0166 } else {
0167
0168 return true;
0169 }
0170
0171
0172
0173 if (!ts.typeFlags().isMeasurement()) {
0174 return true;
0175 }
0176
0177 bool isAlignable = false;
0178 const auto surface = &ts.referenceSurface();
0179 if (auto it = idxedAlignSurfaces.find(surface);
0180 it != idxedAlignSurfaces.end()) {
0181 isAlignable = true;
0182
0183 alignState.alignedSurfaces[surface].first = it->second;
0184 nAlignSurfaces++;
0185 }
0186
0187
0188 measurementStates.push_back({ts.index(), isAlignable});
0189
0190 alignState.measurementDim += ts.calibratedSize();
0191 return true;
0192 });
0193
0194
0195 if (nAlignSurfaces == 0) {
0196 return alignState;
0197 }
0198
0199
0200 alignState.alignmentDof = Acts::eAlignmentSize * nAlignSurfaces;
0201
0202 alignState.trackParametersDim = Acts::eBoundSize * measurementStates.size();
0203
0204
0205
0206
0207 alignState.measurementCovariance = Acts::DynamicMatrix::Zero(
0208 alignState.measurementDim, alignState.measurementDim);
0209
0210 alignState.projectionMatrix = Acts::DynamicMatrix::Zero(
0211 alignState.measurementDim, alignState.trackParametersDim);
0212
0213 alignState.alignmentToResidualDerivative = Acts::DynamicMatrix::Zero(
0214 alignState.measurementDim, alignState.alignmentDof);
0215
0216 alignState.trackParametersCovariance = Acts::DynamicMatrix::Zero(
0217 alignState.trackParametersDim, alignState.trackParametersDim);
0218
0219 alignState.residual = Acts::DynamicVector::Zero(alignState.measurementDim);
0220
0221
0222
0223
0224
0225 const auto& [sourceTrackParamsCov, stateRowIndices] = globalTrackParamsCov;
0226
0227
0228
0229 std::size_t iMeasurement = alignState.measurementDim;
0230 std::size_t iParams = alignState.trackParametersDim;
0231 std::size_t iSurface = nAlignSurfaces;
0232 for (const auto& [rowStateIndex, isAlignable] : measurementStates) {
0233 const auto& state = multiTraj.getTrackState(rowStateIndex);
0234 const std::size_t measdim = state.calibratedSize();
0235
0236 iMeasurement -= measdim;
0237 iParams -= Acts::eBoundSize;
0238
0239 const Acts::DynamicMatrix measCovariance =
0240 state.effectiveCalibratedCovariance();
0241 alignState.measurementCovariance.block(iMeasurement, iMeasurement, measdim,
0242 measdim) = measCovariance;
0243
0244
0245 const Acts::DynamicMatrix H =
0246 state.projectorSubspaceHelper().fullProjector().topLeftCorner(
0247 measdim, Acts::eBoundSize);
0248 alignState.projectionMatrix.block(iMeasurement, iParams, measdim,
0249 Acts::eBoundSize) = H;
0250
0251 alignState.residual.segment(iMeasurement, measdim) =
0252 state.effectiveCalibrated() - H * state.smoothed();
0253
0254
0255
0256 if (isAlignable) {
0257 iSurface -= 1;
0258 const auto surface = &state.referenceSurface();
0259 alignState.alignedSurfaces.at(surface).second = iSurface;
0260
0261 const Acts::FreeVector freeParams =
0262 Acts::MultiTrajectoryHelpers::freeSmoothed(gctx, state);
0263
0264 const Acts::Vector3 position = freeParams.segment<3>(Acts::eFreePos0);
0265
0266 const Acts::Vector3 direction = freeParams.segment<3>(Acts::eFreeDir0);
0267
0268
0269
0270
0271 Acts::FreeVector pathDerivative = Acts::FreeVector::Zero();
0272 pathDerivative.head<3>() = direction;
0273
0274 Acts::AlignmentToBoundMatrix alignToBound =
0275 surface->alignmentToBoundDerivative(gctx, position, direction,
0276 pathDerivative);
0277
0278
0279 resetAlignmentDerivative(alignToBound, alignMask);
0280
0281
0282
0283 alignState.alignmentToResidualDerivative.block(
0284 iMeasurement, iSurface * Acts::eAlignmentSize, measdim,
0285 Acts::eAlignmentSize) = -H * alignToBound;
0286 }
0287
0288
0289
0290
0291 for (unsigned int iColState = 0; iColState < measurementStates.size();
0292 iColState++) {
0293 std::size_t colStateIndex = measurementStates.at(iColState).first;
0294
0295 Acts::BoundMatrix correlation =
0296 sourceTrackParamsCov.block<Acts::eBoundSize, Acts::eBoundSize>(
0297 stateRowIndices.at(rowStateIndex),
0298 stateRowIndices.at(colStateIndex));
0299
0300 std::size_t iCol =
0301 alignState.trackParametersDim - (iColState + 1) * Acts::eBoundSize;
0302 alignState.trackParametersCovariance
0303 .block<Acts::eBoundSize, Acts::eBoundSize>(iParams, iCol) =
0304 correlation;
0305 }
0306 }
0307 finaliseTrackAlignState(alignState);
0308
0309 return alignState;
0310 }
0311
0312 }