File indexing completed on 2025-01-18 09:10:43
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 =
0212 state.projectorSubspaceHelper().fullProjector().topLeftCorner(
0213 measdim, eBoundSize);
0214 alignState.projectionMatrix.block(iMeasurement, iParams, measdim,
0215 eBoundSize) = H;
0216
0217 alignState.residual.segment(iMeasurement, measdim) =
0218 state.effectiveCalibrated() - H * state.smoothed();
0219
0220
0221
0222 if (isAlignable) {
0223 iSurface -= 1;
0224 const auto surface = &state.referenceSurface();
0225 alignState.alignedSurfaces.at(surface).second = iSurface;
0226
0227 const FreeVector freeParams =
0228 Acts::MultiTrajectoryHelpers::freeSmoothed(gctx, state);
0229
0230 const Vector3 position = freeParams.segment<3>(eFreePos0);
0231
0232 const Vector3 direction = freeParams.segment<3>(eFreeDir0);
0233
0234
0235
0236
0237 FreeVector pathDerivative = FreeVector::Zero();
0238 pathDerivative.head<3>() = direction;
0239
0240 AlignmentToBoundMatrix alignToBound = surface->alignmentToBoundDerivative(
0241 gctx, position, direction, pathDerivative);
0242
0243
0244 resetAlignmentDerivative(alignToBound, alignMask);
0245
0246
0247
0248 alignState.alignmentToResidualDerivative.block(
0249 iMeasurement, iSurface * eAlignmentSize, measdim, eAlignmentSize) =
0250 -H * (alignToBound);
0251 }
0252
0253
0254
0255
0256 for (unsigned int iColState = 0; iColState < measurementStates.size();
0257 iColState++) {
0258 std::size_t colStateIndex = measurementStates.at(iColState).first;
0259
0260 CovMatrix correlation =
0261 sourceTrackParamsCov.block<eBoundSize, eBoundSize>(
0262 stateRowIndices.at(rowStateIndex),
0263 stateRowIndices.at(colStateIndex));
0264
0265 std::size_t iCol =
0266 alignState.trackParametersDim - (iColState + 1) * eBoundSize;
0267 alignState.trackParametersCovariance.block<eBoundSize, eBoundSize>(
0268 iParams, iCol) = correlation;
0269 }
0270 }
0271
0272
0273 alignState.chi2 = alignState.residual.transpose() *
0274 alignState.measurementCovariance.inverse() *
0275 alignState.residual;
0276 alignState.alignmentToChi2Derivative =
0277 ActsDynamicVector::Zero(alignState.alignmentDof);
0278 alignState.alignmentToChi2SecondDerivative =
0279 ActsDynamicMatrix::Zero(alignState.alignmentDof, alignState.alignmentDof);
0280
0281 alignState.residualCovariance = ActsDynamicMatrix::Zero(
0282 alignState.measurementDim, alignState.measurementDim);
0283 alignState.residualCovariance = alignState.measurementCovariance -
0284 alignState.projectionMatrix *
0285 alignState.trackParametersCovariance *
0286 alignState.projectionMatrix.transpose();
0287
0288 alignState.alignmentToChi2Derivative =
0289 2 * alignState.alignmentToResidualDerivative.transpose() *
0290 alignState.measurementCovariance.inverse() *
0291 alignState.residualCovariance *
0292 alignState.measurementCovariance.inverse() * alignState.residual;
0293 alignState.alignmentToChi2SecondDerivative =
0294 2 * alignState.alignmentToResidualDerivative.transpose() *
0295 alignState.measurementCovariance.inverse() *
0296 alignState.residualCovariance *
0297 alignState.measurementCovariance.inverse() *
0298 alignState.alignmentToResidualDerivative;
0299
0300 return alignState;
0301 }
0302
0303 }