File indexing completed on 2026-07-17 07:49:36
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include "Acts/EventData/BoundTrackParameters.hpp"
0012 #include "Acts/Geometry/GeometryContext.hpp"
0013 #include "Acts/MagneticField/MagneticFieldContext.hpp"
0014 #include "Acts/Material/interface/IAssignmentFinder.hpp"
0015 #include "Acts/Propagator/ActorList.hpp"
0016 #include "Acts/Propagator/StandardAborters.hpp"
0017 #include "Acts/Propagator/SurfaceCollector.hpp"
0018 #include "Acts/Surfaces/Surface.hpp"
0019 #include "Acts/Utilities/Logger.hpp"
0020 #include "Acts/Utilities/VectorHelpers.hpp"
0021
0022 #include <map>
0023 #include <utility>
0024 #include <vector>
0025
0026 namespace Acts {
0027
0028
0029
0030
0031 struct MaterialSurfaceIdentifier {
0032
0033
0034
0035 bool operator()(const Surface& sf) const { return sf.hasMaterial(); }
0036 };
0037
0038
0039 struct InteractionVolumeCollector {
0040
0041
0042
0043
0044 struct this_result {
0045
0046 std::map<GeometryIdentifier, IAssignmentFinder::VolumeAssignment> collected;
0047 };
0048
0049
0050 using result_type = this_result;
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066 template <typename propagator_state_t, typename stepper_t,
0067 typename navigator_t>
0068 Result<void> act(propagator_state_t& state, const stepper_t& stepper,
0069 const navigator_t& navigator, result_type& result,
0070 const Logger& ) const {
0071
0072 auto currentVolume = navigator.currentVolume(state.navigation);
0073
0074
0075 if (currentVolume != nullptr) {
0076 auto collIt = result.collected.find(currentVolume->geometryId());
0077
0078 if (collIt == result.collected.end() && currentVolume->hasMaterial()) {
0079 Vector3 entryPosition = stepper.position(state.stepping);
0080 Vector3 exitPosition = entryPosition;
0081 IAssignmentFinder::VolumeAssignment vAssignment{
0082 InteractionVolume(currentVolume), entryPosition, exitPosition};
0083 result.collected.emplace(currentVolume->geometryId(), vAssignment);
0084 } else if (collIt != result.collected.end()) {
0085
0086 (collIt->second).exit = stepper.position(state.stepping);
0087 }
0088 }
0089 return Result<void>::success();
0090 }
0091 };
0092
0093
0094
0095
0096
0097
0098
0099
0100 template <typename propagator_t>
0101 class PropagatorMaterialAssigner : public IAssignmentFinder {
0102 public:
0103
0104
0105 explicit PropagatorMaterialAssigner(propagator_t propagator)
0106 : m_propagator(std::move(propagator)) {}
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117 std::pair<std::vector<IAssignmentFinder::SurfaceAssignment>,
0118 std::vector<IAssignmentFinder::VolumeAssignment>>
0119 assignmentCandidates(const GeometryContext& gctx,
0120 const MagneticFieldContext& mctx,
0121 const Vector3& position,
0122 const Vector3& direction) const final {
0123
0124 std::pair<std::vector<IAssignmentFinder::SurfaceAssignment>,
0125 std::vector<IAssignmentFinder::VolumeAssignment>>
0126 candidates;
0127
0128 using VectorHelpers::makeVector4;
0129
0130 BoundTrackParameters start = BoundTrackParameters::createCurvilinear(
0131 makeVector4(position, 0), direction, 1, std::nullopt,
0132 ParticleHypothesis::geantino());
0133
0134
0135 using MaterialSurfaceCollector =
0136 SurfaceCollector<MaterialSurfaceIdentifier>;
0137 using ActorList = ActorList<MaterialSurfaceCollector,
0138 InteractionVolumeCollector, EndOfWorldReached>;
0139 using PropagatorOptions =
0140 typename propagator_t::template Options<ActorList>;
0141
0142 PropagatorOptions options(gctx, mctx);
0143
0144 const auto& result = m_propagator.propagate(start, options, false).value();
0145
0146
0147 auto scResult =
0148 result.template get<MaterialSurfaceCollector::result_type>();
0149 auto mappingSurfaces = scResult.collected;
0150
0151 for (auto& mSurface : mappingSurfaces) {
0152 candidates.first.push_back(IAssignmentFinder::SurfaceAssignment{
0153 mSurface.surface, mSurface.position, direction});
0154 }
0155
0156
0157 auto vcResult =
0158 result.template get<InteractionVolumeCollector::result_type>();
0159 for (const auto& [geoId, vIntersection] : vcResult.collected) {
0160 candidates.second.push_back(vIntersection);
0161 }
0162
0163
0164 return candidates;
0165 }
0166
0167 private:
0168 propagator_t m_propagator;
0169 };
0170
0171 }