File indexing completed on 2025-08-05 08:09:37
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/Surface.hpp"
0016
0017 #include <algorithm>
0018 #include <functional>
0019 #include <iterator>
0020 #include <vector>
0021
0022 Acts::Layer::Layer(std::unique_ptr<SurfaceArray> surfaceArray, double thickness,
0023 std::unique_ptr<ApproachDescriptor> ades, LayerType laytyp)
0024 : m_nextLayers(NextLayers(nullptr, nullptr)),
0025 m_surfaceArray(surfaceArray.release()),
0026 m_layerThickness(thickness),
0027 m_approachDescriptor(nullptr),
0028 m_representingVolume(nullptr),
0029 m_layerType(laytyp),
0030 m_ssRepresentingSurface(1) {
0031 if (ades) {
0032 ades->registerLayer(*this);
0033 m_approachDescriptor = std::move(ades);
0034 m_ssApproachSurfaces = 1;
0035 }
0036
0037 if (m_surfaceArray) {
0038 m_ssSensitiveSurfaces = 1;
0039 }
0040 }
0041
0042 const Acts::ApproachDescriptor* Acts::Layer::approachDescriptor() const {
0043 return m_approachDescriptor.get();
0044 }
0045
0046 Acts::ApproachDescriptor* Acts::Layer::approachDescriptor() {
0047 return const_cast<ApproachDescriptor*>(m_approachDescriptor.get());
0048 }
0049
0050 void Acts::Layer::closeGeometry(const IMaterialDecorator* materialDecorator,
0051 const GeometryIdentifier& layerID,
0052 const GeometryIdentifierHook& hook,
0053 const Logger& logger) {
0054
0055 assignGeometryId(layerID);
0056
0057 Surface* rSurface = const_cast<Surface*>(&surfaceRepresentation());
0058 if (materialDecorator != nullptr) {
0059 materialDecorator->decorate(*rSurface);
0060 }
0061 ACTS_DEBUG("layerID: " << layerID);
0062
0063 rSurface->assignGeometryId(layerID);
0064
0065
0066 if (surfaceRepresentation().surfaceMaterial() != nullptr) {
0067 m_ssRepresentingSurface = 2;
0068 }
0069
0070 if (m_approachDescriptor) {
0071
0072 m_ssApproachSurfaces = 1;
0073
0074 GeometryIdentifier::Value iasurface = 0;
0075 for (auto& aSurface : m_approachDescriptor->containedSurfaces()) {
0076 auto asurfaceID = GeometryIdentifier(layerID).setApproach(++iasurface);
0077 auto mutableASurface = const_cast<Surface*>(aSurface);
0078 mutableASurface->assignGeometryId(asurfaceID);
0079 if (materialDecorator != nullptr) {
0080 materialDecorator->decorate(*mutableASurface);
0081 }
0082
0083 if (aSurface->surfaceMaterial() != nullptr) {
0084 m_ssApproachSurfaces = 2;
0085 }
0086 }
0087 }
0088
0089 if (m_surfaceArray) {
0090
0091 m_ssSensitiveSurfaces = 1;
0092
0093 GeometryIdentifier::Value issurface = 0;
0094 for (auto& sSurface : m_surfaceArray->surfaces()) {
0095 auto ssurfaceID = GeometryIdentifier(layerID).setSensitive(++issurface);
0096 ssurfaceID = hook.decorateIdentifier(ssurfaceID, *sSurface);
0097 auto mutableSSurface = const_cast<Surface*>(sSurface);
0098 mutableSSurface->assignGeometryId(ssurfaceID);
0099 if (materialDecorator != nullptr) {
0100 materialDecorator->decorate(*mutableSSurface);
0101 }
0102
0103 if (sSurface->surfaceMaterial() != nullptr) {
0104 m_ssSensitiveSurfaces = 2;
0105 }
0106 }
0107 }
0108 }
0109
0110 boost::container::small_vector<Acts::SurfaceIntersection, 10>
0111 Acts::Layer::compatibleSurfaces(
0112 const GeometryContext& gctx, const Vector3& position,
0113 const Vector3& direction, const NavigationOptions<Surface>& options) const {
0114
0115 boost::container::small_vector<SurfaceIntersection, 10> sIntersections;
0116
0117
0118 if (!m_surfaceArray || !m_approachDescriptor) {
0119 return sIntersections;
0120 }
0121
0122
0123
0124
0125 double nearLimit = options.nearLimit;
0126 double farLimit = options.farLimit;
0127 if (options.endObject != nullptr) {
0128
0129
0130 SurfaceIntersection endInter =
0131 options.endObject
0132 ->intersect(gctx, position, direction, BoundaryCheck(true))
0133 .closest();
0134
0135
0136
0137
0138 if (endInter) {
0139 farLimit = endInter.pathLength();
0140 } else {
0141 return sIntersections;
0142 }
0143 } else {
0144
0145
0146
0147
0148 double pCorrection =
0149 surfaceRepresentation().pathCorrection(gctx, position, direction);
0150 farLimit = 1.5 * thickness() * pCorrection;
0151 }
0152
0153
0154 auto acceptSurface = [&options](const Surface& sf,
0155 bool sensitive = false) -> bool {
0156
0157 if (sensitive && options.resolveSensitive) {
0158 return true;
0159 }
0160
0161 if (options.resolveMaterial && sf.surfaceMaterial() != nullptr) {
0162 return true;
0163 }
0164
0165 return options.resolvePassive;
0166 };
0167
0168
0169
0170 auto processSurface = [&](const Surface& sf, bool sensitive = false) {
0171
0172 if (options.startObject == &sf || options.endObject == &sf) {
0173 return;
0174 }
0175
0176 if (!acceptSurface(sf, sensitive)) {
0177 return;
0178 }
0179 bool boundaryCheck = options.boundaryCheck.isEnabled();
0180 if (std::find(options.externalSurfaces.begin(),
0181 options.externalSurfaces.end(),
0182 sf.geometryId()) != options.externalSurfaces.end()) {
0183 boundaryCheck = false;
0184 }
0185
0186 SurfaceMultiIntersection sfmi =
0187 sf.intersect(gctx, position, direction, BoundaryCheck(boundaryCheck));
0188 for (const auto& sfi : sfmi.split()) {
0189
0190 if (sfi &&
0191 detail::checkIntersection(sfi.intersection(), nearLimit, farLimit)) {
0192 sIntersections.push_back(sfi);
0193 }
0194 }
0195 };
0196
0197
0198
0199
0200
0201
0202 if (m_approachDescriptor &&
0203 (options.resolveMaterial || options.resolvePassive)) {
0204
0205 const std::vector<const Surface*>& approachSurfaces =
0206 m_approachDescriptor->containedSurfaces();
0207
0208
0209
0210 for (auto& aSurface : approachSurfaces) {
0211 processSurface(*aSurface);
0212 }
0213 }
0214
0215
0216
0217
0218 if (m_surfaceArray && (options.resolveMaterial || options.resolvePassive ||
0219 options.resolveSensitive)) {
0220
0221 const std::vector<const Surface*>& sensitiveSurfaces =
0222 m_surfaceArray->neighbors(position);
0223
0224
0225
0226 for (auto& sSurface : sensitiveSurfaces) {
0227 processSurface(*sSurface, true);
0228 }
0229 }
0230
0231
0232
0233
0234 const Surface* layerSurface = &surfaceRepresentation();
0235 processSurface(*layerSurface);
0236
0237
0238 std::sort(
0239 sIntersections.begin(), sIntersections.end(),
0240 [](const auto& a, const auto& b) { return a.object() < b.object(); });
0241
0242
0243 auto it = std::unique(
0244 sIntersections.begin(), sIntersections.end(),
0245 [](const SurfaceIntersection& a, const SurfaceIntersection& b) -> bool {
0246 return a.object() == b.object();
0247 });
0248
0249
0250 sIntersections.resize(std::distance(sIntersections.begin(), it),
0251 SurfaceIntersection::invalid());
0252
0253
0254 std::sort(sIntersections.begin(), sIntersections.end(),
0255 SurfaceIntersection::pathLengthOrder);
0256
0257 return sIntersections;
0258 }
0259
0260 Acts::SurfaceIntersection Acts::Layer::surfaceOnApproach(
0261 const GeometryContext& gctx, const Vector3& position,
0262 const Vector3& direction, const NavigationOptions<Layer>& options) const {
0263
0264
0265
0266
0267
0268 bool resolvePS = options.resolveSensitive || options.resolvePassive;
0269 bool resolveMS = options.resolveMaterial &&
0270 (m_ssSensitiveSurfaces > 1 || m_ssApproachSurfaces > 1 ||
0271 (surfaceRepresentation().surfaceMaterial() != nullptr));
0272
0273
0274 double nearLimit = options.nearLimit;
0275 double farLimit = options.farLimit;
0276
0277
0278 auto findValidIntersection =
0279 [&](const SurfaceMultiIntersection& sfmi) -> SurfaceIntersection {
0280 for (const auto& sfi : sfmi.split()) {
0281 if (sfi &&
0282 detail::checkIntersection(sfi.intersection(), nearLimit, farLimit)) {
0283 return sfi;
0284 }
0285 }
0286
0287
0288 return SurfaceIntersection::invalid();
0289 };
0290
0291
0292 if (m_approachDescriptor && (resolvePS || resolveMS)) {
0293 SurfaceIntersection aSurface = m_approachDescriptor->approachSurface(
0294 gctx, position, direction, options.boundaryCheck, nearLimit, farLimit);
0295 return aSurface;
0296 }
0297
0298
0299 const Surface& rSurface = surfaceRepresentation();
0300 auto sIntersection =
0301 rSurface.intersect(gctx, position, direction, options.boundaryCheck);
0302 return findValidIntersection(sIntersection);
0303 }