6#include "Acts/Definitions/TrackParametrization.hpp"
7#include "Acts/Definitions/Units.hpp"
9using namespace Acts::UnitLiterals;
16 Acts::Matrix<eBoundSize, 2> m = Acts::Matrix<eBoundSize, 2>::Zero();
17 m(eBoundPhi, 0) = 1.0;
18 m(eBoundTheta, 1) = 1.0;
26 Acts::Matrix<eBoundSize, 3> m = Acts::Matrix<eBoundSize, 3>::Zero();
27 m(eBoundPhi, 0) = 1.0;
28 m(eBoundTheta, 1) = 1.0;
29 m(eBoundQOverP, 2) = 1.0;
34 Acts::Matrix<eBoundSize, 1> m = Acts::Matrix<eBoundSize, 1>::Zero();
35 m(eBoundQOverP, 0) = 1.0;
40 const Eigen::VectorXd& deltaParamsExtended,
const std::size_t stateIdx) {
42 m_scatPhi += deltaParamsExtended[stateIdx];
46 const std::size_t eLossIdx = stateIdx + (
nDim() - 1ul);
52 BoundTrackParameters& trackPars) {
54 trackPars.parameters()[eBoundPhi] +=
deltaPhi();
55 trackPars.parameters()[eBoundTheta] +=
deltaTheta();
58 const ParticleHypothesis& hypot = trackPars.particleHypothesis();
60 fastHypot(hypot.mass(), trackPars.absoluteMomentum()) -
m_lostEnergy;
61 const double qOverPBefore = trackPars.parameters()[eBoundQOverP];
63 (hypot.mass() < nextE) ? fastCathetus(nextE, hypot.mass()) : 0;
65 if (pAfter <= Acts::s_epsilon) {
78 trackPars.parameters()[eBoundQOverP] =
79 hypot.qOverP(pAfter, trackPars.charge());
89 Acts::square(trackPars.parameters()[eBoundQOverP] / qOverPBefore);
94 Gx2fSystem& extendedSystem,
const double theta,
const std::size_t stateIdx,
95 const Logger&
logger)
const {
97 const double invCovTheta = Acts::square(1. /
m_scatterer.sigma());
98 const double sinThetaLoc = std::sin(
theta);
99 const double invCovPhi = invCovTheta * Acts::square(sinThetaLoc);
102 extendedSystem.
aMatrix()(stateIdx, stateIdx) += invCovPhi;
104 extendedSystem.
chi2() += invCovPhi * Acts::square(
deltaPhi());
107 extendedSystem.
aMatrix()(stateIdx + 1, stateIdx + 1) += invCovTheta;
109 extendedSystem.
chi2() += invCovTheta * Acts::square(
deltaTheta());
110 ACTS_VERBOSE(
"Scattering contributions in contributionToGx2fSums:\n"
111 <<
" index: " << stateIdx <<
"-" << (stateIdx + 1) <<
" \n"
112 <<
" invCov: " << invCovPhi <<
"\n"
113 <<
" sinThetaLoc: " << sinThetaLoc <<
"\n"
115 <<
" scattering angle: " <<
deltaPhi() <<
"\n"
116 <<
" aMatrix contribution: " << invCovPhi <<
"\n"
117 <<
" bVector contribution: " << invCovPhi *
deltaPhi()
119 <<
" chi2sum contribution: "
120 << invCovPhi * Acts::square(
deltaPhi()) <<
"\n"
122 <<
" scattering angle: " <<
deltaTheta() <<
"\n"
123 <<
" aMatrix contribution: " << invCovTheta <<
"\n"
124 <<
" bVector contribution: "
126 <<
" chi2sum contribution: "
131 const std::size_t eLossIdx = stateIdx + (
nDim() - 1ul);
132 extendedSystem.
aMatrix()(eLossIdx, eLossIdx) +=
133 Acts::square(1. /
m_eloss.lostSigma());
134 extendedSystem.
bVector()(eLossIdx, 0) -=
135 Acts::square(1. /
m_eloss.lostSigma()) *
137 extendedSystem.
chi2() += Acts::square(
141 constexpr double Nepsilon = Acts::square(1. / 10._keV);
144 "Add penalty term to the chi2 to push the energy loss above zero");
147 extendedSystem.
aMatrix()(eLossIdx, eLossIdx) += Nepsilon;
149 ACTS_VERBOSE(
"Energy loss contributions in contributionToGx2fSums:\n"
150 <<
" index: " << eLossIdx <<
" \n"
151 <<
" measured loss: " <<
m_eloss.lostEnergy() <<
"+-"
152 << (
m_eloss.lostSigma()) <<
", \n"
153 <<
" currently estimated loss: " <<
m_lostEnergy <<
"\n"
154 <<
" --> chi2 contribution: "
158 <<
" --> aMatrix contribution: "
159 << Acts::square(1. /
m_eloss.lostSigma()) <<
"\n"
160 <<
" --> bVector contribution: "
161 << Acts::square(1. /
m_eloss.lostSigma()) *
168 const CalibrationContext&,
176 BoundTrackParameters& params,
const Eigen::VectorXd& deltaParamsExtended,
177 std::unordered_map<GeometryIdentifier, Gx2fMaterialProperties>& materialMap,
178 const std::vector<GeometryIdentifier>& geoIdVector) {
180 params.parameters() +=
181 deltaParamsExtended.topLeftCorner<eBoundSize, 1>().eval();
183 std::size_t deltaPosition{eBoundSize};
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.");
190 materialMapId->second.updateParameters(deltaParamsExtended, deltaPosition);
191 deltaPosition += materialMapId->second.nDim();
199 for (std::size_t i = 0; i < extendedSystem.
nDims(); ++i) {
200 if (extendedSystem.
aMatrix()(i, i) == 0.) {
201 extendedSystem.
aMatrix()(i, i) = 1.;
205 visit_measurement(nDof, [&](
auto N) {
206 fullCovariancePredicted.topLeftCorner<N, N>() =
207 extendedSystem.
aMatrix().inverse().topLeftCorner<N, N>();
215 const std::vector<BoundMatrix>& jacobianFromStart,
216 const std::vector<std::size_t>& materialIndices,
218 const Eigen::MatrixXd& covarianceMeasurement,
const BoundVector& predicted,
219 const Eigen::VectorXd& measurement,
const Eigen::MatrixXd& projector,
223 const auto safeInvCovMeasurement = safeInverse(covarianceMeasurement);
224 if (!safeInvCovMeasurement) {
225 ACTS_WARNING(
"addMeasurementToGx2fSums: safeInvCovMeasurement failed.");
226 ACTS_VERBOSE(
" covarianceMeasurement:\n" << covarianceMeasurement);
229 ACTS_VERBOSE(
"Jacobian size: " << jacobianFromStart.size());
233 Eigen::MatrixXd extendedJacobian =
234 Eigen::MatrixXd::Zero(eBoundSize, extendedSystem.
nDims());
237 extendedJacobian.topLeftCorner<eBoundSize, eBoundSize>() =
238 jacobianFromStart[0];
244 for (std::size_t matSurface = 1; matSurface < jacobianFromStart.size();
246 const BoundMatrix& jac = jacobianFromStart[matSurface];
250 const std::size_t deltaPosition = materialIndices.at(matSurface - 1);
251 ACTS_DEBUG(
"Update material jacobian " << deltaPosition <<
", "
252 << extendedSystem.
nDims());
256 const std::size_t matDim = materialIndices.at(matSurface) - deltaPosition;
263 proj(eBoundQOverP, 0) =
qOverPderiv.at(matSurface - 1);
264 extendedJacobian.block<eBoundSize, 1>(0, deltaPosition) = jac * proj;
268 extendedJacobian.block<eBoundSize, 2>(0, deltaPosition) =
273 proj(eBoundQOverP, 2) =
qOverPderiv.at(matSurface - 1);
274 extendedJacobian.block<eBoundSize, 3>(0, deltaPosition) = jac * proj;
278 ACTS_ERROR(
"Invalid material dimension: "
279 << matDim <<
" - this should be 1, 2, or 3.");
280 throw std::domain_error(
"Invalid material dimension.");
284 const Eigen::MatrixXd projJacobian = projector * extendedJacobian;
286 const Eigen::VectorXd projPredicted = projector * predicted;
288 const Eigen::VectorXd residual = measurement - projPredicted;
291 extendedSystem.
chi2() +=
292 (residual.transpose() * (*safeInvCovMeasurement) * residual)(0, 0);
295 (projJacobian.transpose() * (*safeInvCovMeasurement) * projJacobian)
299 (residual.transpose() * (*safeInvCovMeasurement) * projJacobian)
304 "Contributions in addMeasurementToGx2fSums:\n"
305 <<
" predicted: " << predicted.transpose() <<
"\n"
306 <<
" measurement: " << measurement.transpose() <<
"\n"
307 <<
" covarianceMeasurement:\n"
308 << covarianceMeasurement <<
"\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)
321 <<
" bVector contribution: "
322 << (residual.transpose() * (*safeInvCovMeasurement) * projJacobian).eval()
324 <<
" chi2sum contribution: "
325 << (residual.transpose() * (*safeInvCovMeasurement) * residual)(0, 0)
327 <<
" safeInvCovMeasurement:\n"
328 << (*safeInvCovMeasurement));
332 return extendedSystem.
aMatrix().colPivHouseholderQr().solve(
Scalar theta() const
theta method
void updateGx2fParams(BoundTrackParameters ¶ms, const Eigen::VectorXd &deltaParamsExtended, std::unordered_map< GeometryIdentifier, Gx2fMaterialProperties > &materialMap, const std::vector< GeometryIdentifier > &geoIdVector)
Update parameters (and scattering angles if applicable).
Eigen::VectorXd computeGx2fDeltaParams(const Gx2fSystem &extendedSystem)
Solve the gx2f system to get the delta parameters for the update.
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.
void updateGx2fCovarianceParams(BoundMatrix &fullCovariancePredicted, Gx2fSystem &extendedSystem)
Calculate and update the covariance of the fitted parameters.
static Root::TMsgLogger logger("iLumiCalc")
const Acts::Matrix< eBoundSize, 2 > phiThetaProjector
const Acts::Matrix< eBoundSize, 3 > phiThetaQOverPProjector
const Acts::Matrix< eBoundSize, 1 > qOverPProjector
Auxiliary struct to include the measured energy loss at a surface.
ELossAtSurface()=default
Default constructor to construct an invalid energy loss.
static ELossAtSurface invalidELoss(const GeometryContext &geoContext, const CalibrationContext &calibContext, const Vector3 &pos, const Vector3 &dir, const Surface &matSurface)
Function that satisfies the eLossAccumulator delegate pattern and the produces an invalid energy loss...
double m_scatPhi
Fitted delta phi scattering.
constexpr double qOverPderiv() const
ELossAtSurface m_eloss
Description of the energy loss.
void updateParameters(const Eigen::VectorXd &deltaParamsExtended, const std::size_t firstParamIdx)
constexpr std::size_t nDim() const
Number of dimensions from the material scatterer.
double m_lostEnergy
Fitted parameters.
double m_scatTheta
Fitted delta theta scattering.
double m_qOverPderiv
qOverP derivative with respect to eloss
void contributionToGx2fSums(Gx2fSystem &extendedSystem, const double theta, const std::size_t firstParamIdx, const Logger &logger) const
ScatteringAtSurface m_scatterer
Description of the scattering angles.
constexpr double deltaPhi() const
constexpr double deltaTheta() const
void updateTrackParameters(BoundTrackParameters &trackPars)
Update the track parameters with the scattering angles and.
A container to manage all properties of a gx2f system.
double chi2() const
Accessor for the accumulated chi-squared value (const version).
std::size_t findRequiredNdf()
Determines the minimum number of degrees of freedom required for the fit.
std::size_t nDims() const
Accessor for the number of dimensions of the extended system.
const Eigen::VectorXd & bVector() const
Accessor for the extended system vector (const version).
const Eigen::MatrixXd & aMatrix() const
Accessor for the extended system matrix (const version).