File indexing completed on 2025-01-18 09:11:23
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "Acts/Geometry/Layer.hpp"
0010
0011 #include "Acts/Definitions/Direction.hpp"
0012 #include "Acts/Definitions/Tolerance.hpp"
0013 #include "Acts/Material/IMaterialDecorator.hpp"
0014 #include "Acts/Propagator/Navigator.hpp"
0015 #include "Acts/Surfaces/BoundaryTolerance.hpp"
0016 #include "Acts/Surfaces/Surface.hpp"
0017 #include "Acts/Utilities/Helpers.hpp"
0018 #include "Acts/Utilities/Intersection.hpp"
0019
0020 #include <algorithm>
0021 #include <functional>
0022 #include <iterator>
0023 #include <vector>
0024
0025 Acts::Layer::Layer(std::unique_ptr<SurfaceArray> surfaceArray, double thickness,
0026 std::unique_ptr<ApproachDescriptor> ades, LayerType laytyp)
0027 : m_nextLayers(NextLayers(nullptr, nullptr)),
0028 m_surfaceArray(surfaceArray.release()),
0029 m_layerThickness(thickness),
0030 m_approachDescriptor(nullptr),
0031 m_representingVolume(nullptr),
0032 m_layerType(laytyp),
0033 m_ssRepresentingSurface(1) {
0034 if (ades) {
0035 ades->registerLayer(*this);
0036 m_approachDescriptor = std::move(ades);
0037 m_ssApproachSurfaces = 1;
0038 }
0039
0040 if (m_surfaceArray) {
0041 m_ssSensitiveSurfaces = 1;
0042 }
0043 }
0044
0045 const Acts::ApproachDescriptor* Acts::Layer::approachDescriptor() const {
0046 return m_approachDescriptor.get();
0047 }
0048
0049 Acts::ApproachDescriptor* Acts::Layer::approachDescriptor() {
0050 return const_cast<ApproachDescriptor*>(m_approachDescriptor.get());
0051 }
0052
0053 void Acts::Layer::closeGeometry(const IMaterialDecorator* materialDecorator,
0054 const GeometryIdentifier& layerID,
0055 const GeometryIdentifierHook& hook,
0056 const Logger& logger) {
0057
0058 assignGeometryId(layerID);
0059
0060 Surface* rSurface = const_cast<Surface*>(&surfaceRepresentation());
0061 if (materialDecorator != nullptr) {
0062 materialDecorator->decorate(*rSurface);
0063 }
0064 ACTS_DEBUG("layerID: " << layerID);
0065
0066 rSurface->assignGeometryId(layerID);
0067
0068
0069 if (surfaceRepresentation().surfaceMaterial() != nullptr) {
0070 m_ssRepresentingSurface = 2;
0071 }
0072
0073 if (m_approachDescriptor) {
0074
0075 m_ssApproachSurfaces = 1;
0076
0077 GeometryIdentifier::Value iasurface = 0;
0078 for (auto& aSurface : m_approachDescriptor->containedSurfaces()) {
0079 auto asurfaceID = GeometryIdentifier(layerID).setApproach(++iasurface);
0080 auto mutableASurface = const_cast<Surface*>(aSurface);
0081 mutableASurface->assignGeometryId(asurfaceID);
0082 if (materialDecorator != nullptr) {
0083 materialDecorator->decorate(*mutableASurface);
0084 }
0085
0086 if (aSurface->surfaceMaterial() != nullptr) {
0087 m_ssApproachSurfaces = 2;
0088 }
0089 }
0090 }
0091
0092 if (m_surfaceArray) {
0093
0094 m_ssSensitiveSurfaces = 1;
0095
0096 GeometryIdentifier::Value issurface = 0;
0097 for (auto& sSurface : m_surfaceArray->surfaces()) {
0098 auto ssurfaceID = GeometryIdentifier(layerID).setSensitive(++issurface);
0099 ssurfaceID = hook.decorateIdentifier(ssurfaceID, *sSurface);
0100 auto mutableSSurface = const_cast<Surface*>(sSurface);
0101 mutableSSurface->assignGeometryId(ssurfaceID);
0102 if (materialDecorator != nullptr) {
0103 materialDecorator->decorate(*mutableSSurface);
0104 }
0105
0106 if (sSurface->surfaceMaterial() != nullptr) {
0107 m_ssSensitiveSurfaces = 2;
0108 }
0109 }
0110 }
0111 }
0112
0113 boost::container::small_vector<Acts::SurfaceIntersection, 10>
0114 Acts::Layer::compatibleSurfaces(
0115 const GeometryContext& gctx, const Vector3& position,
0116 const Vector3& direction, const NavigationOptions<Surface>& options) const {
0117
0118 boost::container::small_vector<SurfaceIntersection, 10> sIntersections;
0119
0120
0121 if (!m_surfaceArray || !m_approachDescriptor) {
0122 return sIntersections;
0123 }
0124
0125 double nearLimit = options.nearLimit;
0126 double farLimit = options.farLimit;
0127
0128 auto isUnique = [&](const SurfaceIntersection& b) {
0129 return std::ranges::none_of(sIntersections, [&b](const auto& a) {
0130 return a.object() == b.object() && a.index() == b.index();
0131 });
0132 };
0133
0134
0135 auto acceptSurface = [&options](const Surface& sf,
0136 bool sensitive = false) -> bool {
0137
0138 if (sensitive && options.resolveSensitive) {
0139 return true;
0140 }
0141
0142 if (options.resolveMaterial && sf.surfaceMaterial() != nullptr) {
0143 return true;
0144 }
0145
0146 return options.resolvePassive;
0147 };
0148
0149
0150
0151 auto processSurface = [&](const Surface& sf, bool sensitive = false) {
0152
0153 if (options.startObject == &sf) {
0154 return;
0155 }
0156
0157 if (!acceptSurface(sf, sensitive)) {
0158 return;
0159 }
0160 BoundaryTolerance boundaryTolerance = options.boundaryTolerance;
0161 if (rangeContainsValue(options.externalSurfaces, sf.geometryId())) {
0162 boundaryTolerance = BoundaryTolerance::Infinite();
0163 }
0164
0165 SurfaceIntersection sfi =
0166 sf.intersect(gctx, position, direction, boundaryTolerance).closest();
0167 if (sfi.isValid() &&
0168 detail::checkPathLength(sfi.pathLength(), nearLimit, farLimit) &&
0169 isUnique(sfi)) {
0170 sIntersections.push_back(sfi);
0171 }
0172 };
0173
0174
0175
0176
0177
0178
0179 if (m_approachDescriptor &&
0180 (options.resolveMaterial || options.resolvePassive)) {
0181
0182 const std::vector<const Surface*>& approachSurfaces =
0183 m_approachDescriptor->containedSurfaces();
0184
0185
0186
0187 for (auto& aSurface : approachSurfaces) {
0188 processSurface(*aSurface);
0189 }
0190 }
0191
0192
0193
0194
0195 if (m_surfaceArray && (options.resolveMaterial || options.resolvePassive ||
0196 options.resolveSensitive)) {
0197
0198 const std::vector<const Surface*>& sensitiveSurfaces =
0199 m_surfaceArray->neighbors(position);
0200
0201
0202
0203 for (auto& sSurface : sensitiveSurfaces) {
0204 processSurface(*sSurface, true);
0205 }
0206 }
0207
0208
0209
0210
0211 const Surface* layerSurface = &surfaceRepresentation();
0212 processSurface(*layerSurface);
0213
0214 return sIntersections;
0215 }
0216
0217 Acts::SurfaceIntersection Acts::Layer::surfaceOnApproach(
0218 const GeometryContext& gctx, const Vector3& position,
0219 const Vector3& direction, const NavigationOptions<Layer>& options) const {
0220
0221
0222
0223
0224
0225 bool resolvePS = options.resolveSensitive || options.resolvePassive;
0226 bool resolveMS = options.resolveMaterial &&
0227 (m_ssSensitiveSurfaces > 1 || m_ssApproachSurfaces > 1 ||
0228 (surfaceRepresentation().surfaceMaterial() != nullptr));
0229
0230
0231 double nearLimit = options.nearLimit;
0232 double farLimit = options.farLimit;
0233
0234
0235 auto findValidIntersection =
0236 [&](const SurfaceMultiIntersection& sfmi) -> SurfaceIntersection {
0237 for (const auto& sfi : sfmi.split()) {
0238 if (sfi.isValid() &&
0239 detail::checkPathLength(sfi.pathLength(), nearLimit, farLimit)) {
0240 return sfi;
0241 }
0242 }
0243
0244
0245 return SurfaceIntersection::invalid();
0246 };
0247
0248
0249 if (m_approachDescriptor && (resolvePS || resolveMS)) {
0250 SurfaceIntersection aSurface = m_approachDescriptor->approachSurface(
0251 gctx, position, direction, options.boundaryTolerance, nearLimit,
0252 farLimit);
0253 return aSurface;
0254 }
0255
0256
0257 const Surface& rSurface = surfaceRepresentation();
0258 auto sIntersection =
0259 rSurface.intersect(gctx, position, direction, options.boundaryTolerance);
0260 return findValidIntersection(sIntersection);
0261 }