ATLAS Offline Software
Loading...
Searching...
No Matches
Track_fitting

Namespaces

namespace  MuonExperimental::Gx2fConstants

Classes

struct  MuonExperimental::Gx2fMaterialProperties
 A container to store material properties for each material surface. More...
struct  MuonExperimental::Gx2FitterExtensions< traj_t >
 Extension struct which holds delegates to customise the GX2F behaviour. More...
struct  MuonExperimental::Gx2FitterOptions< traj_t >
 Combined options for the Global-Chi-Square fitter. More...
struct  MuonExperimental::Gx2FitterResult< traj_t >
 Result container for a global chi-square fit. More...
struct  MuonExperimental::Gx2fSystem
 A container to manage all properties of a gx2f system. More...
class  MuonExperimental::Gx2Fitter< propagator_t, traj_t >
 Global Chi Square fitter (GX2F) implementation. More...

Functions

void MuonExperimental::addMeasurementToGx2fSumsBackend (Gx2fSystem &extendedSystem, const std::vector< BoundMatrix > &jacobianFromStart, const std::vector< std::size_t > &materialIndices, const std::vector< double > &qOverPderiv, const Eigen::MatrixXd &covarianceMeasurement, const BoundVector &predicted, const Eigen::VectorXd &measurement, const Eigen::MatrixXd &projector, const Logger &logger)
 Adds a measurement to the GX2F equation system in a modular backend function.
template<std::size_t kMeasDim, typename track_state_t>
void MuonExperimental::addMeasurementToGx2fSums (Gx2fSystem &extendedSystem, const std::vector< BoundMatrix > &jacobianFromStart, const std::vector< std::size_t > &materialIndices, const std::vector< double > &qOverPderiv, const track_state_t &trackState, const Logger &logger)
 Process measurements and fill the aMatrix and bVector.
template<TrackProxyConcept track_proxy_t>
void MuonExperimental::fillGx2fSystem (const track_proxy_t track, Gx2fSystem &extendedSystem, const std::unordered_map< GeometryIdentifier, Gx2fMaterialProperties > &materialMap, const std::vector< std::size_t > &materialParamIndices, std::vector< GeometryIdentifier > &geoIdVector, const Logger &logger)
 Fill the GX2F system with data from a track.
Eigen::VectorXd MuonExperimental::computeGx2fDeltaParams (const Gx2fSystem &extendedSystem)
 Solve the gx2f system to get the delta parameters for the update.
void MuonExperimental::updateGx2fParams (BoundTrackParameters &params, const Eigen::VectorXd &deltaParamsExtended, std::unordered_map< GeometryIdentifier, Gx2fMaterialProperties > &materialMap, const std::vector< GeometryIdentifier > &geoIdVector)
 Update parameters (and scattering angles if applicable).
void MuonExperimental::updateGx2fCovarianceParams (BoundMatrix &fullCovariancePredicted, Gx2fSystem &extendedSystem)
 Calculate and update the covariance of the fitted parameters.

Detailed Description

Function Documentation

◆ addMeasurementToGx2fSums()

template<std::size_t kMeasDim, typename track_state_t>
void MuonExperimental::addMeasurementToGx2fSums ( Gx2fSystem & extendedSystem,
const std::vector< BoundMatrix > & jacobianFromStart,
const std::vector< std::size_t > & materialIndices,
const std::vector< double > & qOverPderiv,
const track_state_t & trackState,
const Logger & logger )

Process measurements and fill the aMatrix and bVector.

The function processes each measurement for the GX2F Actor fitting process. It extracts the information from the track state and adds it to aMatrix, bVector, and chi2sum.

Template Parameters
kMeasDimNumber of dimensions of the measurement
track_state_tThe type of the track state
Parameters
extendedSystemAll parameters of the current equation system to update
jacobianFromStartThe Jacobian matrix from start to the current state
trackStateThe track state to analyse
loggerA logger instance

Definition at line 545 of file Chi2Fitter.h.

550 {
551 const SquareMatrix<kMeasDim> covarianceMeasurement =
552 trackState.template calibratedCovariance<kMeasDim>();
553
554 const BoundVector predicted = trackState.smoothed();
555
556 const Vector<kMeasDim> measurement =
557 trackState.template calibrated<kMeasDim>();
558
559 const Matrix<kMeasDim, eBoundSize> projector =
560 trackState.template projectorSubspaceHelper<kMeasDim>().projector();
561
563 extendedSystem, jacobianFromStart, materialIndices, qOverPderiv,
564 covarianceMeasurement, predicted, measurement, projector, logger);
565}
void addMeasurementToGx2fSumsBackend(Gx2fSystem &extendedSystem, const std::vector< BoundMatrix > &jacobianFromStart, const std::vector< std::size_t > &materialIndices, const std::vector< double > &qOverPderiv, const Eigen::MatrixXd &covarianceMeasurement, const BoundVector &predicted, const Eigen::VectorXd &measurement, const Eigen::MatrixXd &projector, const Logger &logger)
Adds a measurement to the GX2F equation system in a modular backend function.
static Root::TMsgLogger logger("iLumiCalc")

◆ addMeasurementToGx2fSumsBackend()

void MuonExperimental::addMeasurementToGx2fSumsBackend ( Gx2fSystem & extendedSystem,
const std::vector< BoundMatrix > & jacobianFromStart,
const std::vector< std::size_t > & materialIndices,
const std::vector< double > & qOverPderiv,
const Eigen::MatrixXd & covarianceMeasurement,
const BoundVector & predicted,
const Eigen::VectorXd & measurement,
const Eigen::MatrixXd & projector,
const Logger & logger )

Adds a measurement to the GX2F equation system in a modular backend function.

This function processes measurement data and integrates it into the GX2F system.

Parameters
extendedSystemAll parameters of the current equation system to update.
jacobianFromStartThe Jacobian matrix from the start to the current state.
covarianceMeasurementThe covariance matrix of the measurement.
predictedThe predicted state vector based on the track state.
measurementThe measurement vector.
projectorThe projection matrix.
loggerA logger instance.
Note
The dynamic Eigen matrices are suboptimal. We could think of templating again in the future on kMeasDims. We currently use dynamic matrices to reduce the memory during compile time.

Definition at line 213 of file Chi2Fitter.cxx.

220 {
221 // First, we try to invert the covariance matrix. If the inversion fails, we
222 // can already abort.
223 const auto safeInvCovMeasurement = safeInverse(covarianceMeasurement);
224 if (!safeInvCovMeasurement) {
225 ACTS_WARNING("addMeasurementToGx2fSums: safeInvCovMeasurement failed.");
226 ACTS_VERBOSE(" covarianceMeasurement:\n" << covarianceMeasurement);
227 return;
228 }
229 ACTS_VERBOSE("Jacobian size: " << jacobianFromStart.size());
230 // Create an extended Jacobian. This one contains only eBoundSize rows,
231 // because the rest is irrelevant. We fill it in the next steps.
232 // TODO make dimsExtendedParams template with unrolling
233 Eigen::MatrixXd extendedJacobian =
234 Eigen::MatrixXd::Zero(eBoundSize, extendedSystem.nDims());
235
236 // This part of the Jacobian comes from the material-less propagation
237 extendedJacobian.topLeftCorner<eBoundSize, eBoundSize>() =
238 jacobianFromStart[0];
239
240 // If we have material, loop here over all Jacobians. We add extra columns for
241 // their phi-theta projections. These parts account for the propagation of the
242 // scattering angles. if energy loss is enabled, we also add the q/p
243 // projection.
244 for (std::size_t matSurface = 1; matSurface < jacobianFromStart.size();
245 matSurface++) {
246 const BoundMatrix& jac = jacobianFromStart[matSurface];
247
248 // The position, where we need to insert the values in the extended Jacobian
249 // accounting for material effects
250 const std::size_t deltaPosition = materialIndices.at(matSurface - 1);
251 ACTS_DEBUG("Update material jacobian " << deltaPosition << ", "
252 << extendedSystem.nDims());
253
254 // check the dimension of the material map: 2 means only scattering, 3 means
255 // scattering and energy loss amd 1 only energy loss
256 const std::size_t matDim = materialIndices.at(matSurface) - deltaPosition;
257
258 // check if energy loss is enabled, if yes, we need to add the q/p
259 // projection in the extended jacobian
260 switch (matDim) {
261 case 1: { // energy loss only
262 Acts::Matrix<eBoundSize, 1> proj = qOverPProjector;
263 proj(eBoundQOverP, 0) = qOverPderiv.at(matSurface - 1);
264 extendedJacobian.block<eBoundSize, 1>(0, deltaPosition) = jac * proj;
265 break;
266 }
267 case 2: // scattering only
268 extendedJacobian.block<eBoundSize, 2>(0, deltaPosition) =
269 jac * phiThetaProjector;
270 break;
271 case 3: { // scattering and energy loss
272 Acts::Matrix<eBoundSize, 3> proj = phiThetaQOverPProjector;
273 proj(eBoundQOverP, 2) = qOverPderiv.at(matSurface - 1);
274 extendedJacobian.block<eBoundSize, 3>(0, deltaPosition) = jac * proj;
275 break;
276 }
277 default:
278 ACTS_ERROR("Invalid material dimension: "
279 << matDim << " - this should be 1, 2, or 3.");
280 throw std::domain_error("Invalid material dimension.");
281 }
282 }
283
284 const Eigen::MatrixXd projJacobian = projector * extendedJacobian;
285
286 const Eigen::VectorXd projPredicted = projector * predicted;
287
288 const Eigen::VectorXd residual = measurement - projPredicted;
289
290 // Finally contribute to chi2sum, aMatrix, and bVector
291 extendedSystem.chi2() +=
292 (residual.transpose() * (*safeInvCovMeasurement) * residual)(0, 0);
293
294 extendedSystem.aMatrix() +=
295 (projJacobian.transpose() * (*safeInvCovMeasurement) * projJacobian)
296 .eval();
297
298 extendedSystem.bVector() +=
299 (residual.transpose() * (*safeInvCovMeasurement) * projJacobian)
300 .eval()
301 .transpose();
302
303 ACTS_VERBOSE(
304 "Contributions in addMeasurementToGx2fSums:\n"
305 << " predicted: " << predicted.transpose() << "\n"
306 << " measurement: " << measurement.transpose() << "\n"
307 << " covarianceMeasurement:\n"
308 << covarianceMeasurement << "\n"
309 << " projector:\n"
310 << projector.eval() << "\n"
311 << " projJacobian:\n"
312 << projJacobian.eval() << "\n"
313 << " projPredicted: " << (projPredicted.transpose()).eval() << "\n"
314 << " residual: " << (residual.transpose()).eval() << "\n"
315 << " extendedJacobian:\n"
316 << extendedJacobian << "\n"
317 << " aMatrix contribution:\n"
318 << (projJacobian.transpose() * (*safeInvCovMeasurement) * projJacobian)
319 .eval()
320 << "\n"
321 << " bVector contribution: "
322 << (residual.transpose() * (*safeInvCovMeasurement) * projJacobian).eval()
323 << "\n"
324 << " chi2sum contribution: "
325 << (residual.transpose() * (*safeInvCovMeasurement) * residual)(0, 0)
326 << "\n"
327 << " safeInvCovMeasurement:\n"
328 << (*safeInvCovMeasurement));
329}
const Acts::Matrix< eBoundSize, 2 > phiThetaProjector
const Acts::Matrix< eBoundSize, 3 > phiThetaQOverPProjector
const Acts::Matrix< eBoundSize, 1 > qOverPProjector
double chi2() const
Accessor for the accumulated chi-squared value (const version).
Definition Chi2Fitter.h:433
std::size_t nDims() const
Accessor for the number of dimensions of the extended system.
Definition Chi2Fitter.h:429
const Eigen::VectorXd & bVector() const
Accessor for the extended system vector (const version).
Definition Chi2Fitter.h:449
const Eigen::MatrixXd & aMatrix() const
Accessor for the extended system matrix (const version).
Definition Chi2Fitter.h:441

◆ computeGx2fDeltaParams()

Eigen::VectorXd MuonExperimental::computeGx2fDeltaParams ( const Gx2fSystem & extendedSystem)

Solve the gx2f system to get the delta parameters for the update.

This function computes the delta parameters for the GX2F Actor fitting process by solving the linear equation system [a] * delta = b. It uses the column-pivoting Householder QR decomposition for numerical stability.

Parameters
extendedSystemAll parameters of the current equation system
Returns
Delta parameters for the GX2F update

Definition at line 331 of file Chi2Fitter.cxx.

331 {
332 return extendedSystem.aMatrix().colPivHouseholderQr().solve(
333 extendedSystem.bVector());
334}

◆ fillGx2fSystem()

template<TrackProxyConcept track_proxy_t>
void MuonExperimental::fillGx2fSystem ( const track_proxy_t track,
Gx2fSystem & extendedSystem,
const std::unordered_map< GeometryIdentifier, Gx2fMaterialProperties > & materialMap,
const std::vector< std::size_t > & materialParamIndices,
std::vector< GeometryIdentifier > & geoIdVector,
const Logger & logger )

Fill the GX2F system with data from a track.

This function processes a track proxy and updates the aMatrix, bVector, and chi2 values for the GX2F fitting system. It considers material only if multiple scattering is enabled.

Template Parameters
track_proxy_tThe type of the track proxy
Parameters
trackA constant track proxy to inspect
extendedSystemAll parameters of the current equation system
multipleScatteringFlag to consider multiple scattering in the calculation
materialMapMap of geometry identifiers to scattering properties, containing scattering angles and validation status
loggerA logger instance

Invalid material state

Definition at line 582 of file Chi2Fitter.h.

587 {
588 std::vector<BoundMatrix> jacobianFromStart;
589 jacobianFromStart.emplace_back(BoundMatrix::Identity());
590 geoIdVector.reserve(track.nTrackStates());
591 std::vector<double> qOverPderiv;
592
593 bool foundELoss{false};
594 for (const auto& trackState : track.trackStates()) {
595 // Get and store geoId for the current surface
596 const GeometryIdentifier geoId = trackState.referenceSurface().geometryId();
597 ACTS_DEBUG("Start to investigate trackState on surface " << geoId);
598 const auto typeFlags = trackState.typeFlags();
599
600 // update all Jacobians from start for every track state
601 for (auto& jac : jacobianFromStart) {
602 jac = trackState.jacobian() * jac;
603 }
604
605 // Skip the hole states
606 if (!typeFlags.hasMeasurement() && !typeFlags.hasMaterial()) {
607 ACTS_DEBUG(" Skip state.");
608 continue;
609 }
610
611 // Handle measurement
612 if (typeFlags.hasMeasurement()) {
613 ACTS_DEBUG(" Handle measurement. ");
614
615 const auto measDim = trackState.calibratedSize();
616
617 if (measDim < 1 || 6 < measDim) {
618 ACTS_ERROR("Can not process state with measurement with "
619 << measDim << " dimensions.");
620 throw std::domain_error(
621 "Found measurement with less than 1 or more than 6 dimension(s).");
622 }
623
624 extendedSystem.ndf() += measDim;
625
626 visit_measurement(measDim, [&](auto N) {
627 addMeasurementToGx2fSums<N>(extendedSystem, jacobianFromStart,
628 materialParamIndices, qOverPderiv,
629 trackState, logger);
630 });
631 }
632
633 // Handle material
634 if (typeFlags.hasMaterial()) {
635 ACTS_DEBUG(" Handle material");
636 const auto materialMapId = materialMap.find(geoId);
637 if (materialMapId == materialMap.end()) {
638 ACTS_ERROR("No material properties found for surface " << geoId);
639 throw std::runtime_error("No material properties found for surface.");
640 }
642 if (materialMapId->second.nDim() == 0ul) {
643 continue;
644 }
645 if (materialMapId->second.energyLoss().isValid()) {
646 ACTS_VERBOSE("The material surface carries energy loss");
647 foundELoss = true;
648 }
649 const std::size_t deltaPosition =
650 materialParamIndices.at(geoIdVector.size());
651 geoIdVector.push_back(geoId);
652
653 materialMapId->second.contributionToGx2fSums(
654 extendedSystem, trackState.smoothed()[eBoundTheta], deltaPosition,
655 logger);
656
657 // after material surfaces, the measurements depend on the updated qoverp
658 // we need to scale the jacobian term for the qoverp row
659 if (foundELoss) {
660 ACTS_DEBUG(" Update Jacobian for q/p after material surface "
661 << geoId << " with ratio " << materialMapId->second.qOverPratio());
662 jacobianFromStart.front().row(eBoundQOverP) *=
663 materialMapId->second.qOverPratio();
664 }
665 // Add for this material a new Jacobian, starting from this surface.
666 jacobianFromStart.emplace_back(BoundMatrix::Identity());
667 qOverPderiv.push_back(materialMapId->second.qOverPderiv());
668 }
669 }
670}
void addMeasurementToGx2fSums(Gx2fSystem &extendedSystem, const std::vector< BoundMatrix > &jacobianFromStart, const std::vector< std::size_t > &materialIndices, const std::vector< double > &qOverPderiv, const track_state_t &trackState, const Logger &logger)
Process measurements and fill the aMatrix and bVector.
Definition Chi2Fitter.h:545
std::size_t ndf() const
Accessor for the number of degrees of freedom (const version).
Definition Chi2Fitter.h:457

◆ updateGx2fCovarianceParams()

void MuonExperimental::updateGx2fCovarianceParams ( BoundMatrix & fullCovariancePredicted,
Gx2fSystem & extendedSystem )

Calculate and update the covariance of the fitted parameters.

This function calculates the covariance of the fitted parameters using cov = inv([a]) It then updates the first square block of size ndfSystem. This ensures, that we only update the covariance for fitted parameters. (In case of no qop/time fit)

Parameters
fullCovariancePredictedThe covariance matrix to update
extendedSystemAll parameters of the current equation system

Definition at line 195 of file Chi2Fitter.cxx.

196 {
197 const std::size_t nDof = extendedSystem.findRequiredNdf();
198 // make invertible
199 for (std::size_t i = 0; i < extendedSystem.nDims(); ++i) {
200 if (extendedSystem.aMatrix()(i, i) == 0.) {
201 extendedSystem.aMatrix()(i, i) = 1.;
202 }
203 }
204
205 visit_measurement(nDof, [&](auto N) {
206 fullCovariancePredicted.topLeftCorner<N, N>() =
207 extendedSystem.aMatrix().inverse().topLeftCorner<N, N>();
208 });
209
210 return;
211}
constexpr std::size_t N
std::size_t findRequiredNdf()
Determines the minimum number of degrees of freedom required for the fit.
Definition Chi2Fitter.h:472

◆ updateGx2fParams()

void MuonExperimental::updateGx2fParams ( BoundTrackParameters & params,
const Eigen::VectorXd & deltaParamsExtended,
std::unordered_map< GeometryIdentifier, Gx2fMaterialProperties > & materialMap,
const std::vector< GeometryIdentifier > & geoIdVector )

Update parameters (and scattering angles if applicable).

Parameters
paramsParameters to be updated
deltaParamsExtendedDelta parameters for bound parameter and scattering angles
materialMapMap of geometry identifiers to scattering properties, containing all scattering angles and covariances
geoIdVectorVector of geometry identifiers corresponding to material surfaces

Definition at line 175 of file Chi2Fitter.cxx.

178 {
179 // update params
180 params.parameters() +=
181 deltaParamsExtended.topLeftCorner<eBoundSize, 1>().eval();
182
183 std::size_t deltaPosition{eBoundSize};
184 // update the scattering angles and energy loss.
185 for (const GeometryIdentifier& geoId : geoIdVector) {
186 const auto materialMapId = materialMap.find(geoId);
187 assert(materialMapId != materialMap.end() &&
188 "No material properties found for material surface.");
189
190 materialMapId->second.updateParameters(deltaParamsExtended, deltaPosition);
191 deltaPosition += materialMapId->second.nDim();
192 }
193}