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