File indexing completed on 2025-12-15 09:24:01
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include "Acts/Definitions/Units.hpp"
0012 #include "Acts/Geometry/TrackingVolume.hpp"
0013 #include "Acts/Material/MaterialInteraction.hpp"
0014 #include "Acts/Material/MaterialSlab.hpp"
0015 #include "Acts/Propagator/Propagator.hpp"
0016 #include "Acts/Propagator/detail/PointwiseMaterialInteraction.hpp"
0017 #include "Acts/Propagator/detail/VolumeMaterialInteraction.hpp"
0018 #include "Acts/Surfaces/Surface.hpp"
0019
0020 #include <sstream>
0021
0022 namespace Acts {
0023
0024
0025
0026
0027 struct MaterialInteractor {
0028
0029 bool multipleScattering = true;
0030
0031 bool energyLoss = true;
0032
0033 bool recordInteractions = false;
0034
0035 NoiseUpdateMode noiseUpdateMode = NoiseUpdateMode::addNoise;
0036
0037
0038 using result_type = RecordedMaterial;
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057 template <typename propagator_state_t, typename stepper_t,
0058 typename navigator_t>
0059 void act(propagator_state_t& state, const stepper_t& stepper,
0060 const navigator_t& navigator, result_type& result,
0061 const Logger& logger) const {
0062 if (state.stage == PropagatorStage::postPropagation) {
0063 return;
0064 }
0065
0066
0067 if (!(multipleScattering || energyLoss || recordInteractions)) {
0068 return;
0069 }
0070
0071
0072
0073
0074
0075 const Surface* surface = navigator.currentSurface(state.navigation);
0076
0077
0078 if (surface && surface->surfaceMaterial()) {
0079 ACTS_VERBOSE("MaterialInteractor | " << "Found material on surface "
0080 << surface->geometryId());
0081
0082
0083 detail::PointwiseMaterialInteraction interaction(surface, state, stepper);
0084
0085
0086
0087 if (interaction.evaluateMaterialSlab(state, navigator)) {
0088
0089 interaction.evaluatePointwiseMaterialInteraction(multipleScattering,
0090 energyLoss);
0091
0092 if (energyLoss) {
0093 using namespace UnitLiterals;
0094 ACTS_VERBOSE("MaterialInteractor | "
0095 << interaction.slab << " absPdg=" << interaction.absPdg
0096 << " mass=" << interaction.mass / 1_MeV << "MeV"
0097 << " momentum=" << interaction.momentum / 1_GeV << "GeV"
0098 << " energyloss=" << interaction.Eloss / 1_MeV << "MeV");
0099 }
0100
0101
0102
0103 if (interaction.performCovarianceTransport) {
0104 stepper.transportCovarianceToCurvilinear(state.stepping);
0105 }
0106
0107 interaction.updateState(state, stepper, noiseUpdateMode);
0108
0109
0110 recordResult(interaction, result);
0111 }
0112 }
0113
0114
0115
0116
0117 if (!result.materialInteractions.empty() &&
0118 !result.materialInteractions.back().volume.empty() &&
0119 result.materialInteractions.back().updatedVolumeStep == false) {
0120 updateResult(state, stepper, result);
0121 }
0122
0123 auto volume = navigator.currentVolume(state.navigation);
0124
0125
0126 if (volume && volume->volumeMaterial()) {
0127 ACTS_VERBOSE("MaterialInteractor | " << "Found material in volume "
0128 << volume->geometryId());
0129
0130
0131 detail::VolumeMaterialInteraction interaction(volume, state, stepper);
0132
0133
0134 if (interaction.evaluateMaterialSlab(state, navigator)) {
0135
0136 recordResult(interaction, result);
0137 }
0138 }
0139 }
0140
0141 private:
0142
0143
0144
0145
0146 void recordResult(const detail::PointwiseMaterialInteraction& interaction,
0147 result_type& result) const {
0148 result.materialInX0 += interaction.slab.thicknessInX0();
0149 result.materialInL0 += interaction.slab.thicknessInL0();
0150
0151
0152 if (!recordInteractions) {
0153 return;
0154 }
0155
0156 MaterialInteraction mi;
0157 mi.position = interaction.pos;
0158 mi.time = interaction.time;
0159 mi.direction = interaction.dir;
0160 mi.deltaP = interaction.nextP - interaction.momentum;
0161 mi.sigmaPhi2 = interaction.variancePhi;
0162 mi.sigmaTheta2 = interaction.varianceTheta;
0163 mi.sigmaQoP2 = interaction.varianceQoverP;
0164 mi.surface = interaction.surface;
0165 mi.volume = InteractionVolume();
0166 mi.pathCorrection = interaction.pathCorrection;
0167 mi.materialSlab = interaction.slab;
0168 result.materialInteractions.push_back(std::move(mi));
0169 }
0170
0171
0172
0173
0174
0175 void recordResult(const detail::VolumeMaterialInteraction& interaction,
0176 result_type& result) const {
0177
0178 if (!recordInteractions) {
0179 return;
0180 }
0181
0182 MaterialInteraction mi;
0183 mi.position = interaction.pos;
0184 mi.time = interaction.time;
0185 mi.direction = interaction.dir;
0186 mi.surface = nullptr;
0187 mi.volume = interaction.volume;
0188 mi.pathCorrection = interaction.pathCorrection;
0189 mi.materialSlab = interaction.slab;
0190 result.materialInteractions.push_back(std::move(mi));
0191 }
0192
0193
0194
0195
0196
0197
0198 template <typename propagator_state_t, typename stepper_t>
0199 void updateResult(propagator_state_t& state, const stepper_t& stepper,
0200 result_type& result) const {
0201
0202 if (!recordInteractions) {
0203 return;
0204 }
0205
0206 Vector3 shift = stepper.position(state.stepping) -
0207 result.materialInteractions.back().position;
0208 double momentum = stepper.direction(state.stepping).norm();
0209 result.materialInteractions.back().deltaP =
0210 momentum - result.materialInteractions.back().direction.norm();
0211 result.materialInteractions.back().materialSlab.scaleThickness(
0212 shift.norm());
0213 result.materialInteractions.back().updatedVolumeStep = true;
0214 result.materialInX0 +=
0215 result.materialInteractions.back().materialSlab.thicknessInX0();
0216 result.materialInL0 +=
0217 result.materialInteractions.back().materialSlab.thicknessInL0();
0218 }
0219 };
0220
0221 }