File indexing completed on 2025-01-18 09:10:55
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Definitions/Common.hpp"
0013 #include "Acts/Definitions/Direction.hpp"
0014 #include "Acts/Definitions/PdgParticle.hpp"
0015 #include "Acts/Definitions/TrackParametrization.hpp"
0016 #include "Acts/Definitions/Units.hpp"
0017 #include "Acts/Material/ISurfaceMaterial.hpp"
0018 #include "Acts/Material/MaterialSlab.hpp"
0019 #include "Acts/Surfaces/Surface.hpp"
0020 #include "Acts/Utilities/MathHelpers.hpp"
0021
0022 #include <algorithm>
0023 #include <cmath>
0024
0025 namespace Acts::detail {
0026
0027
0028 struct PointwiseMaterialInteraction {
0029
0030 const Surface* surface = nullptr;
0031
0032
0033 const Vector3 pos = Vector3(0., 0., 0);
0034
0035 const double time = 0.0;
0036
0037 const Vector3 dir = Vector3(0., 0., 0);
0038
0039 const float qOverP = 0.0;
0040
0041 const float absQ = 0.0;
0042
0043 const float momentum = 0.0;
0044
0045 const float mass = 0.0;
0046
0047 const PdgParticle absPdg = PdgParticle::eInvalid;
0048
0049 const bool performCovarianceTransport = false;
0050
0051 const Direction navDir;
0052
0053
0054 MaterialSlab slab = MaterialSlab(0.);
0055
0056 double pathCorrection = 0.;
0057
0058 double variancePhi = 0.;
0059
0060 double varianceTheta = 0.;
0061
0062 double varianceQoverP = 0.;
0063
0064 double Eloss = 0.;
0065
0066 double nextP = 0.;
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076 template <typename propagator_state_t, typename stepper_t>
0077 PointwiseMaterialInteraction(const Surface* sSurface,
0078 const propagator_state_t& state,
0079 const stepper_t& stepper)
0080 : surface(sSurface),
0081 pos(stepper.position(state.stepping)),
0082 time(stepper.time(state.stepping)),
0083 dir(stepper.direction(state.stepping)),
0084 qOverP(stepper.qOverP(state.stepping)),
0085 absQ(stepper.particleHypothesis(state.stepping).absoluteCharge()),
0086 momentum(stepper.absoluteMomentum(state.stepping)),
0087 mass(stepper.particleHypothesis(state.stepping).mass()),
0088 absPdg(stepper.particleHypothesis(state.stepping).absolutePdg()),
0089 performCovarianceTransport(state.stepping.covTransport),
0090 navDir(state.options.direction) {}
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103 template <typename propagator_state_t, typename navigator_t>
0104 bool evaluateMaterialSlab(
0105 const propagator_state_t& state, const navigator_t& navigator,
0106 MaterialUpdateStage updateStage = MaterialUpdateStage::FullUpdate) {
0107
0108 if (surface == navigator.startSurface(state.navigation)) {
0109 updateStage = MaterialUpdateStage::PostUpdate;
0110
0111 } else if (surface == navigator.targetSurface(state.navigation)) {
0112 updateStage = MaterialUpdateStage::PreUpdate;
0113 }
0114
0115
0116 slab = navigator.currentSurface(state.navigation)
0117 ->surfaceMaterial()
0118 ->materialSlab(pos, navDir, updateStage);
0119
0120
0121 pathCorrection = surface->pathCorrection(state.geoContext, pos, dir);
0122 slab.scaleThickness(pathCorrection);
0123
0124
0125 return slab.isValid();
0126 }
0127
0128
0129
0130
0131
0132
0133 void evaluatePointwiseMaterialInteraction(bool multipleScattering,
0134 bool energyLoss);
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144 template <typename propagator_state_t, typename stepper_t>
0145 void updateState(propagator_state_t& state, const stepper_t& stepper,
0146 NoiseUpdateMode updateMode = addNoise) {
0147 const auto& particleHypothesis = stepper.particleHypothesis(state.stepping);
0148
0149
0150 const auto nextE = fastHypot(mass, momentum) - Eloss * navDir;
0151
0152 nextP = (mass < nextE) ? std::sqrt(nextE * nextE - mass * mass) : 0;
0153
0154
0155
0156 static constexpr double minP = 10 * Acts::UnitConstants::MeV;
0157 nextP = std::max(minP, nextP);
0158 const double nextQOverP =
0159 std::copysign(particleHypothesis.qOverP(nextP, absQ), qOverP);
0160
0161 stepper.update(state.stepping, pos, dir, nextQOverP, time);
0162 state.stepping.cov(eBoundPhi, eBoundPhi) = updateVariance(
0163 state.stepping.cov(eBoundPhi, eBoundPhi), variancePhi, updateMode);
0164 state.stepping.cov(eBoundTheta, eBoundTheta) =
0165 updateVariance(state.stepping.cov(eBoundTheta, eBoundTheta),
0166 varianceTheta, updateMode);
0167 state.stepping.cov(eBoundQOverP, eBoundQOverP) =
0168 updateVariance(state.stepping.cov(eBoundQOverP, eBoundQOverP),
0169 varianceQoverP, updateMode);
0170 }
0171
0172 private:
0173
0174
0175
0176
0177
0178 void covarianceContributions(bool multipleScattering, bool energyLoss);
0179
0180
0181
0182
0183
0184
0185
0186
0187 double updateVariance(double variance, double change,
0188 NoiseUpdateMode updateMode = addNoise) const;
0189 };
0190
0191 }