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