File indexing completed on 2025-01-18 09:11:25
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "Acts/Geometry/TrackingVolume.hpp"
0010
0011 #include "Acts/Definitions/Direction.hpp"
0012 #include "Acts/Geometry/GeometryIdentifier.hpp"
0013 #include "Acts/Geometry/GlueVolumesDescriptor.hpp"
0014 #include "Acts/Geometry/Portal.hpp"
0015 #include "Acts/Geometry/VolumeBounds.hpp"
0016 #include "Acts/Material/IMaterialDecorator.hpp"
0017 #include "Acts/Material/IVolumeMaterial.hpp"
0018 #include "Acts/Material/ProtoVolumeMaterial.hpp"
0019 #include "Acts/Navigation/INavigationPolicy.hpp"
0020 #include "Acts/Navigation/NavigationStream.hpp"
0021 #include "Acts/Propagator/Navigator.hpp"
0022 #include "Acts/Surfaces/RegularSurface.hpp"
0023 #include "Acts/Surfaces/Surface.hpp"
0024 #include "Acts/Utilities/BinningType.hpp"
0025 #include "Acts/Utilities/Intersection.hpp"
0026
0027 #include <algorithm>
0028 #include <memory>
0029 #include <ostream>
0030 #include <string>
0031 #include <utility>
0032
0033 #include <boost/container/small_vector.hpp>
0034
0035 namespace Acts {
0036
0037
0038 TrackingVolume::TrackingVolume(
0039 const Transform3& transform, std::shared_ptr<VolumeBounds> volumeBounds,
0040 std::shared_ptr<const IVolumeMaterial> volumeMaterial,
0041 std::unique_ptr<const LayerArray> staticLayerArray,
0042 std::shared_ptr<const TrackingVolumeArray> containedVolumeArray,
0043 MutableTrackingVolumeVector denseVolumeVector,
0044 const std::string& volumeName)
0045 : Volume(transform, std::move(volumeBounds)),
0046 m_confinedLayers(std::move(staticLayerArray)),
0047 m_confinedVolumes(std::move(containedVolumeArray)),
0048 m_confinedDenseVolumes({}),
0049 m_volumeMaterial(std::move(volumeMaterial)),
0050 m_name(volumeName) {
0051 createBoundarySurfaces();
0052 interlinkLayers();
0053 connectDenseBoundarySurfaces(denseVolumeVector);
0054
0055 DelegateChainBuilder{m_navigationDelegate}
0056 .add<&INavigationPolicy::noopInitializeCandidates>()
0057 .store(m_navigationDelegate);
0058 }
0059
0060 TrackingVolume::TrackingVolume(Volume& volume, const std::string& volumeName)
0061 : TrackingVolume(volume.transform(), volume.volumeBoundsPtr(), nullptr,
0062 nullptr, nullptr, MutableTrackingVolumeVector{},
0063 volumeName) {}
0064
0065 TrackingVolume::TrackingVolume(const Transform3& transform,
0066 std::shared_ptr<VolumeBounds> volbounds,
0067 const std::string& volumeName)
0068 : TrackingVolume(transform, std::move(volbounds), nullptr, nullptr, nullptr,
0069 {}, volumeName) {}
0070
0071 TrackingVolume::~TrackingVolume() = default;
0072 TrackingVolume::TrackingVolume(TrackingVolume&&) noexcept = default;
0073 TrackingVolume& TrackingVolume::operator=(TrackingVolume&&) noexcept = default;
0074
0075 const TrackingVolume* TrackingVolume::lowestTrackingVolume(
0076 const GeometryContext& gctx, const Vector3& position,
0077 const double tol) const {
0078 if (!inside(position, tol)) {
0079 return nullptr;
0080 }
0081
0082
0083 if (m_confinedVolumes) {
0084 const TrackingVolume* volume = m_confinedVolumes->object(position).get();
0085 if (volume != nullptr) {
0086 return volume->lowestTrackingVolume(gctx, position, tol);
0087 }
0088 }
0089
0090
0091 if (!m_confinedDenseVolumes.empty()) {
0092 for (auto& denseVolume : m_confinedDenseVolumes) {
0093 if (denseVolume->inside(position, tol)) {
0094 return denseVolume.get();
0095 }
0096 }
0097 }
0098
0099
0100 for (const auto& volume : volumes()) {
0101 if (volume.inside(position, tol)) {
0102 return volume.lowestTrackingVolume(gctx, position, tol);
0103 }
0104 }
0105
0106
0107 return this;
0108 }
0109
0110 const TrackingVolumeBoundaries& TrackingVolume::boundarySurfaces() const {
0111 return (m_boundarySurfaces);
0112 }
0113
0114 void TrackingVolume::connectDenseBoundarySurfaces(
0115 MutableTrackingVolumeVector& confinedDenseVolumes) {
0116 if (!confinedDenseVolumes.empty()) {
0117 Direction dir = Direction::Positive();
0118
0119 for (auto& confDenseVol : confinedDenseVolumes) {
0120
0121 auto& boundSur = confDenseVol->boundarySurfaces();
0122 for (std::size_t i = 0; i < boundSur.size(); i++) {
0123
0124
0125 if (boundSur.at(i) == nullptr) {
0126 continue;
0127 }
0128
0129
0130
0131 auto mutableBs =
0132 std::const_pointer_cast<BoundarySurfaceT<TrackingVolume>>(
0133 boundSur.at(i));
0134 if (mutableBs->m_oppositeVolume != nullptr &&
0135 mutableBs->m_alongVolume == nullptr) {
0136 dir = Direction::Positive();
0137 mutableBs->attachVolume(this, dir);
0138 } else {
0139 if (mutableBs->m_oppositeVolume == nullptr &&
0140 mutableBs->m_alongVolume != nullptr) {
0141 dir = Direction::Negative();
0142 mutableBs->attachVolume(this, dir);
0143 }
0144 }
0145
0146
0147 confDenseVol->updateBoundarySurface(static_cast<BoundarySurfaceFace>(i),
0148 mutableBs);
0149 }
0150
0151 m_confinedDenseVolumes.push_back(std::move(confDenseVol));
0152 }
0153 }
0154 }
0155
0156 void TrackingVolume::createBoundarySurfaces() {
0157 using Boundary = BoundarySurfaceT<TrackingVolume>;
0158
0159
0160 auto orientedSurfaces = Volume::volumeBounds().orientedSurfaces(m_transform);
0161
0162 m_boundarySurfaces.reserve(orientedSurfaces.size());
0163 for (auto& osf : orientedSurfaces) {
0164 TrackingVolume* opposite = nullptr;
0165 TrackingVolume* along = nullptr;
0166 if (osf.direction == Direction::OppositeNormal()) {
0167 opposite = this;
0168 } else {
0169 along = this;
0170 }
0171 m_boundarySurfaces.push_back(std::make_shared<const Boundary>(
0172 std::move(osf.surface), opposite, along));
0173 }
0174 }
0175
0176 void TrackingVolume::glueTrackingVolume(const GeometryContext& gctx,
0177 BoundarySurfaceFace bsfMine,
0178 TrackingVolume* neighbor,
0179 BoundarySurfaceFace bsfNeighbor) {
0180
0181
0182 Vector3 bPosition(referencePosition(gctx, AxisDirection::AxisR));
0183 Vector3 distance = Vector3(
0184 neighbor->referencePosition(gctx, AxisDirection::AxisR) - bPosition);
0185
0186 std::shared_ptr<const BoundarySurfaceT<TrackingVolume>> bSurfaceMine =
0187 boundarySurfaces().at(bsfMine);
0188
0189
0190
0191
0192 Vector3 nvector =
0193 bSurfaceMine->surfaceRepresentation().normal(gctx, bPosition);
0194
0195 Direction dir = Direction::fromScalar(nvector.dot(distance));
0196
0197
0198 if ((m_glueVolumeDescriptor == nullptr) ||
0199 m_glueVolumeDescriptor->glueVolumes(bsfMine) == nullptr) {
0200
0201 auto mutableBSurfaceMine =
0202 std::const_pointer_cast<BoundarySurfaceT<TrackingVolume>>(bSurfaceMine);
0203 mutableBSurfaceMine->attachVolume(neighbor, dir);
0204
0205 const Surface& neighborSurface =
0206 neighbor->m_boundarySurfaces.at(bsfNeighbor)->surfaceRepresentation();
0207 auto neighborMaterial = neighborSurface.surfaceMaterialSharedPtr();
0208 const Surface& mySurface = bSurfaceMine->surfaceRepresentation();
0209 auto myMaterial = mySurface.surfaceMaterialSharedPtr();
0210
0211 if (myMaterial == nullptr && neighborMaterial != nullptr) {
0212 Surface* myMutbableSurface = const_cast<Surface*>(&mySurface);
0213 myMutbableSurface->assignSurfaceMaterial(neighborMaterial);
0214 }
0215
0216 (neighbor->m_boundarySurfaces).at(bsfNeighbor) = bSurfaceMine;
0217 }
0218 }
0219
0220 void TrackingVolume::glueTrackingVolumes(
0221 const GeometryContext& gctx, BoundarySurfaceFace bsfMine,
0222 const std::shared_ptr<TrackingVolumeArray>& neighbors,
0223 BoundarySurfaceFace bsfNeighbor) {
0224
0225
0226 std::shared_ptr<const TrackingVolume> nRefVolume =
0227 neighbors->arrayObjects().at(0);
0228
0229 Vector3 bPosition(referencePosition(gctx, AxisDirection::AxisR));
0230 Vector3 distance(nRefVolume->referencePosition(gctx, AxisDirection::AxisR) -
0231 bPosition);
0232
0233 std::shared_ptr<const BoundarySurfaceT<TrackingVolume>> bSurfaceMine =
0234 boundarySurfaces().at(bsfMine);
0235
0236
0237
0238
0239 Vector3 nvector =
0240 bSurfaceMine->surfaceRepresentation().normal(gctx, bPosition);
0241
0242 Direction dir = Direction::fromScalar(nvector.dot(distance));
0243
0244
0245 if ((m_glueVolumeDescriptor == nullptr) ||
0246 !m_glueVolumeDescriptor->glueVolumes(bsfMine)) {
0247
0248 auto mutableBSurfaceMine =
0249 std::const_pointer_cast<BoundarySurfaceT<TrackingVolume>>(bSurfaceMine);
0250 mutableBSurfaceMine->attachVolumeArray(neighbors, dir);
0251
0252 for (auto& nVolume : neighbors->arrayObjects()) {
0253 auto mutableNVolume = std::const_pointer_cast<TrackingVolume>(nVolume);
0254 (mutableNVolume->m_boundarySurfaces).at(bsfNeighbor) = bSurfaceMine;
0255 }
0256 }
0257 }
0258
0259 void TrackingVolume::assignBoundaryMaterial(
0260 std::shared_ptr<const ISurfaceMaterial> surfaceMaterial,
0261 BoundarySurfaceFace bsFace) {
0262 auto bSurface = m_boundarySurfaces.at(bsFace);
0263 RegularSurface* surface =
0264 const_cast<RegularSurface*>(&bSurface->surfaceRepresentation());
0265 surface->assignSurfaceMaterial(std::move(surfaceMaterial));
0266 }
0267
0268 void TrackingVolume::updateBoundarySurface(
0269 BoundarySurfaceFace bsf,
0270 std::shared_ptr<const BoundarySurfaceT<TrackingVolume>> bs,
0271 bool checkmaterial) {
0272 if (checkmaterial) {
0273 auto cMaterialPtr = m_boundarySurfaces.at(bsf)
0274 ->surfaceRepresentation()
0275 .surfaceMaterialSharedPtr();
0276 auto bsMaterial = bs->surfaceRepresentation().surfaceMaterial();
0277 if (cMaterialPtr != nullptr && bsMaterial == nullptr) {
0278 RegularSurface* surface =
0279 const_cast<RegularSurface*>(&bs->surfaceRepresentation());
0280 surface->assignSurfaceMaterial(cMaterialPtr);
0281 }
0282 }
0283 m_boundarySurfaces.at(bsf) = std::move(bs);
0284 }
0285
0286 void TrackingVolume::registerGlueVolumeDescriptor(
0287 std::unique_ptr<GlueVolumesDescriptor> gvd) {
0288 m_glueVolumeDescriptor = std::move(gvd);
0289 }
0290
0291 GlueVolumesDescriptor& TrackingVolume::glueVolumesDescriptor() {
0292 if (m_glueVolumeDescriptor == nullptr) {
0293 m_glueVolumeDescriptor = std::make_unique<GlueVolumesDescriptor>();
0294 }
0295 return *m_glueVolumeDescriptor;
0296 }
0297
0298 void TrackingVolume::synchronizeLayers(double envelope) const {
0299
0300
0301
0302
0303 if (m_confinedLayers) {
0304
0305
0306
0307 for (auto& clayIter : m_confinedLayers->arrayObjects()) {
0308 if (clayIter) {
0309
0310
0311
0312
0313
0314
0315 }
0316
0317
0318 }
0319 }
0320
0321
0322 if (m_confinedVolumes) {
0323
0324
0325
0326 for (auto& cVolumesIter : m_confinedVolumes->arrayObjects()) {
0327 cVolumesIter->synchronizeLayers(envelope);
0328 }
0329 }
0330 }
0331
0332 void TrackingVolume::interlinkLayers() {
0333 if (m_confinedLayers) {
0334 auto& layers = m_confinedLayers->arrayObjects();
0335
0336
0337
0338 const Layer* lastLayer = nullptr;
0339 for (auto& layerPtr : layers) {
0340
0341 Layer& mutableLayer = *(std::const_pointer_cast<Layer>(layerPtr));
0342
0343 mutableLayer.m_nextLayerUtility = m_confinedLayers->binUtility();
0344 mutableLayer.m_nextLayers.first = lastLayer;
0345
0346 mutableLayer.encloseTrackingVolume(*this);
0347
0348 lastLayer = &mutableLayer;
0349 }
0350
0351 lastLayer = nullptr;
0352 for (auto layerIter = layers.rbegin(); layerIter != layers.rend();
0353 ++layerIter) {
0354
0355 Layer& mutableLayer = *(std::const_pointer_cast<Layer>(*layerIter));
0356 mutableLayer.m_nextLayers.second = lastLayer;
0357 lastLayer = &mutableLayer;
0358 }
0359 }
0360 }
0361
0362 void TrackingVolume::closeGeometry(
0363 const IMaterialDecorator* materialDecorator,
0364 std::unordered_map<GeometryIdentifier, const TrackingVolume*>& volumeMap,
0365 std::size_t& vol, const GeometryIdentifierHook& hook,
0366 const Logger& logger) {
0367 if (m_confinedVolumes && !volumes().empty()) {
0368 ACTS_ERROR(
0369 "TrackingVolume::closeGeometry: Volume "
0370 << volumeName()
0371 << " has both confined volumes and volumes. This is not supported.");
0372 throw std::invalid_argument("Volume has both confined volumes and volumes");
0373 }
0374
0375 if (m_confinedLayers && !surfaces().empty()) {
0376 ACTS_ERROR(
0377 "TrackingVolume::closeGeometry: Volume "
0378 << volumeName()
0379 << " has both confined layers and surfaces. This is not supported.");
0380 throw std::invalid_argument("Volume has both confined layers and surfaces");
0381 }
0382
0383
0384 auto volumeID = GeometryIdentifier().setVolume(++vol);
0385
0386 auto thisVolume = const_cast<TrackingVolume*>(this);
0387 thisVolume->assignGeometryId(volumeID);
0388 ACTS_DEBUG("volumeID: " << volumeID << ", name: " << volumeName());
0389
0390 volumeMap[volumeID] = thisVolume;
0391
0392
0393 if (materialDecorator != nullptr) {
0394 materialDecorator->decorate(*thisVolume);
0395 }
0396 if (thisVolume->volumeMaterial() == nullptr &&
0397 thisVolume->motherVolume() != nullptr &&
0398 thisVolume->motherVolume()->volumeMaterial() != nullptr) {
0399 auto protoMaterial = dynamic_cast<const ProtoVolumeMaterial*>(
0400 thisVolume->motherVolume()->volumeMaterial());
0401 if (protoMaterial == nullptr) {
0402 thisVolume->assignVolumeMaterial(
0403 thisVolume->motherVolume()->volumeMaterialPtr());
0404 }
0405 }
0406
0407 this->assignGeometryId(volumeID);
0408
0409 GeometryIdentifier::Value iboundary = 0;
0410
0411 for (auto& bSurfIter : boundarySurfaces()) {
0412
0413 auto& bSurface = bSurfIter->surfaceRepresentation();
0414
0415 iboundary++;
0416 auto boundaryID = GeometryIdentifier(volumeID).setBoundary(iboundary);
0417
0418 auto& mutableBSurface = *(const_cast<RegularSurface*>(&bSurface));
0419 mutableBSurface.assignGeometryId(boundaryID);
0420
0421 if (materialDecorator != nullptr) {
0422 materialDecorator->decorate(mutableBSurface);
0423 }
0424 }
0425
0426
0427 if (!m_confinedVolumes) {
0428
0429 if (m_confinedLayers) {
0430 GeometryIdentifier::Value ilayer = 0;
0431
0432 for (auto& layerPtr : m_confinedLayers->arrayObjects()) {
0433
0434 ilayer++;
0435 auto layerID = GeometryIdentifier(volumeID).setLayer(ilayer);
0436
0437 auto mutableLayerPtr = std::const_pointer_cast<Layer>(layerPtr);
0438 mutableLayerPtr->closeGeometry(materialDecorator, layerID, hook,
0439 logger);
0440 }
0441 }
0442 } else {
0443
0444
0445 for (auto& volumesIter : m_confinedVolumes->arrayObjects()) {
0446 auto mutableVolumesIter =
0447 std::const_pointer_cast<TrackingVolume>(volumesIter);
0448 mutableVolumesIter->setMotherVolume(this);
0449 mutableVolumesIter->closeGeometry(materialDecorator, volumeMap, vol, hook,
0450 logger);
0451 }
0452 }
0453
0454 if (!m_confinedDenseVolumes.empty()) {
0455 for (auto& volumesIter : m_confinedDenseVolumes) {
0456 auto mutableVolumesIter =
0457 std::const_pointer_cast<TrackingVolume>(volumesIter);
0458 mutableVolumesIter->setMotherVolume(this);
0459 mutableVolumesIter->closeGeometry(materialDecorator, volumeMap, vol, hook,
0460 logger);
0461 }
0462 }
0463
0464 GeometryIdentifier::Value iportal = 0;
0465 for (auto& portal : portals()) {
0466 iportal++;
0467 auto portalId = GeometryIdentifier(volumeID).setBoundary(iportal);
0468 assert(portal.isValid() && "Invalid portal encountered during closing");
0469
0470 portal.surface().assignGeometryId(portalId);
0471 }
0472
0473 GeometryIdentifier::Value isensitive = 0;
0474
0475 for (auto& surface : surfaces()) {
0476 if (surface.associatedDetectorElement() == nullptr) {
0477 continue;
0478 }
0479 isensitive++;
0480 auto sensitiveId = GeometryIdentifier(volumeID).setSensitive(isensitive);
0481 surface.assignGeometryId(sensitiveId);
0482 }
0483
0484 for (auto& volume : volumes()) {
0485 volume.closeGeometry(materialDecorator, volumeMap, vol, hook, logger);
0486 }
0487 }
0488
0489
0490 boost::container::small_vector<BoundaryIntersection, 4>
0491 TrackingVolume::compatibleBoundaries(const GeometryContext& gctx,
0492 const Vector3& position,
0493 const Vector3& direction,
0494 const NavigationOptions<Surface>& options,
0495 const Logger& logger) const {
0496 ACTS_VERBOSE("Finding compatibleBoundaries");
0497
0498 boost::container::small_vector<BoundaryIntersection, 4> intersections;
0499
0500
0501 double nearLimit = options.nearLimit;
0502 double farLimit = options.farLimit;
0503
0504
0505 auto checkIntersection =
0506 [&](SurfaceMultiIntersection& candidates,
0507 const BoundarySurface* boundary) -> BoundaryIntersection {
0508 for (const auto& intersection : candidates.split()) {
0509 if (!intersection.isValid()) {
0510 continue;
0511 }
0512
0513 ACTS_VERBOSE("Check intersection with surface "
0514 << boundary->surfaceRepresentation().geometryId());
0515 if (detail::checkPathLength(intersection.pathLength(), nearLimit,
0516 farLimit, logger)) {
0517 return BoundaryIntersection(intersection, boundary);
0518 }
0519 }
0520
0521 ACTS_VERBOSE("No intersection accepted");
0522 return BoundaryIntersection(SurfaceIntersection::invalid(), nullptr);
0523 };
0524
0525
0526 auto processBoundaries =
0527 [&](const TrackingVolumeBoundaries& boundaries) -> void {
0528
0529 for (auto& boundary : boundaries) {
0530
0531 const auto& surface = boundary->surfaceRepresentation();
0532 ACTS_VERBOSE("Consider boundary surface " << surface.geometryId());
0533
0534
0535
0536
0537 if (&surface == options.startObject) {
0538 ACTS_VERBOSE(" - Surface is excluded surface");
0539 continue;
0540 }
0541
0542 auto candidates = surface.intersect(gctx, position, direction,
0543 options.boundaryTolerance);
0544
0545 auto intersection = checkIntersection(candidates, boundary.get());
0546 if (intersection.first.isValid()) {
0547 ACTS_VERBOSE(" - Proceed with surface");
0548 intersections.push_back(intersection);
0549 } else {
0550 ACTS_VERBOSE(" - Surface intersecion invalid");
0551 }
0552 }
0553 };
0554
0555
0556 const auto& surfaces = boundarySurfaces();
0557 ACTS_VERBOSE("Volume reports " << surfaces.size() << " boundary surfaces");
0558 processBoundaries(surfaces);
0559
0560
0561 auto confinedDenseVolumes = denseVolumes();
0562 ACTS_VERBOSE("Volume reports " << confinedDenseVolumes.size()
0563 << " confined dense volumes");
0564 for (const auto& volume : confinedDenseVolumes) {
0565 const auto& surfacesConfined = volume->boundarySurfaces();
0566 ACTS_VERBOSE(" -> " << surfacesConfined.size() << " boundary surfaces");
0567 processBoundaries(surfacesConfined);
0568 }
0569
0570 return intersections;
0571 }
0572
0573 boost::container::small_vector<LayerIntersection, 10>
0574 TrackingVolume::compatibleLayers(
0575 const GeometryContext& gctx, const Vector3& position,
0576 const Vector3& direction, const NavigationOptions<Layer>& options) const {
0577
0578 boost::container::small_vector<LayerIntersection, 10> lIntersections;
0579
0580
0581 if (m_confinedLayers == nullptr) {
0582 return {};
0583 }
0584
0585
0586 const Layer* tLayer = options.startObject != nullptr
0587 ? static_cast<const Layer*>(options.startObject)
0588 : associatedLayer(gctx, position);
0589 while (tLayer != nullptr) {
0590
0591
0592
0593
0594
0595 if (tLayer != options.startObject && tLayer->resolve(options)) {
0596
0597
0598 auto atIntersection =
0599 tLayer->surfaceOnApproach(gctx, position, direction, options);
0600
0601 if (atIntersection.isValid()) {
0602
0603 lIntersections.push_back(LayerIntersection(atIntersection, tLayer));
0604 }
0605 }
0606
0607 tLayer = (tLayer == options.endObject)
0608 ? nullptr
0609 : tLayer->nextLayer(gctx, position, direction);
0610 }
0611
0612
0613
0614
0615 auto min = std::min_element(
0616 lIntersections.begin(), lIntersections.end(),
0617 [](const LayerIntersection& a, const LayerIntersection& b) {
0618 return a.first.pathLength() < b.first.pathLength();
0619 });
0620 std::rotate(lIntersections.begin(), min, lIntersections.end());
0621 lIntersections.resize(std::distance(min, lIntersections.end()),
0622 {SurfaceIntersection::invalid(), nullptr});
0623
0624 return lIntersections;
0625 }
0626
0627 const std::string& TrackingVolume::volumeName() const {
0628 return m_name;
0629 }
0630
0631 void TrackingVolume::setVolumeName(const std::string& volumeName) {
0632 m_name = volumeName;
0633 }
0634
0635 const IVolumeMaterial* TrackingVolume::volumeMaterial() const {
0636 return m_volumeMaterial.get();
0637 }
0638
0639 const std::shared_ptr<const IVolumeMaterial>&
0640 TrackingVolume::volumeMaterialPtr() const {
0641 return m_volumeMaterial;
0642 }
0643
0644 void TrackingVolume::assignVolumeMaterial(
0645 std::shared_ptr<const IVolumeMaterial> material) {
0646 m_volumeMaterial = std::move(material);
0647 }
0648
0649 const LayerArray* TrackingVolume::confinedLayers() const {
0650 return m_confinedLayers.get();
0651 }
0652
0653 const MutableTrackingVolumeVector TrackingVolume::denseVolumes() const {
0654 return m_confinedDenseVolumes;
0655 }
0656
0657 std::shared_ptr<const TrackingVolumeArray> TrackingVolume::confinedVolumes()
0658 const {
0659 return m_confinedVolumes;
0660 }
0661
0662 const TrackingVolume* TrackingVolume::motherVolume() const {
0663 return m_motherVolume;
0664 }
0665
0666 TrackingVolume* TrackingVolume::motherVolume() {
0667 return m_motherVolume;
0668 }
0669
0670 void TrackingVolume::setMotherVolume(TrackingVolume* mvol) {
0671 m_motherVolume = mvol;
0672 }
0673
0674 const Acts::Layer* TrackingVolume::associatedLayer(
0675 const GeometryContext& , const Vector3& position) const {
0676
0677 if (m_confinedLayers != nullptr) {
0678 return (m_confinedLayers->object(position).get());
0679 }
0680
0681
0682 return nullptr;
0683 }
0684
0685 TrackingVolume::VolumeRange TrackingVolume::volumes() const {
0686 return VolumeRange{m_volumes};
0687 }
0688
0689 TrackingVolume::MutableVolumeRange TrackingVolume::volumes() {
0690 return MutableVolumeRange{m_volumes};
0691 }
0692
0693 TrackingVolume& TrackingVolume::addVolume(
0694 std::unique_ptr<TrackingVolume> volume) {
0695 if (volume->motherVolume() != nullptr) {
0696 throw std::invalid_argument("Volume already has a mother volume");
0697 }
0698
0699 volume->setMotherVolume(this);
0700 m_volumes.push_back(std::move(volume));
0701 return *m_volumes.back();
0702 }
0703
0704 TrackingVolume::PortalRange TrackingVolume::portals() const {
0705 return PortalRange{m_portals};
0706 }
0707
0708 TrackingVolume::MutablePortalRange TrackingVolume::portals() {
0709 return MutablePortalRange{m_portals};
0710 }
0711
0712 void TrackingVolume::addPortal(std::shared_ptr<Portal> portal) {
0713 if (portal == nullptr) {
0714 throw std::invalid_argument("Portal is nullptr");
0715 }
0716 m_portals.push_back(std::move(portal));
0717 }
0718
0719 TrackingVolume::SurfaceRange TrackingVolume::surfaces() const {
0720 return SurfaceRange{m_surfaces};
0721 }
0722
0723 TrackingVolume::MutableSurfaceRange TrackingVolume::surfaces() {
0724 return MutableSurfaceRange{m_surfaces};
0725 }
0726
0727 void TrackingVolume::addSurface(std::shared_ptr<Surface> surface) {
0728 if (surface == nullptr) {
0729 throw std::invalid_argument("Surface is nullptr");
0730 }
0731 m_surfaces.push_back(std::move(surface));
0732 }
0733
0734 void TrackingVolume::visualize(IVisualization3D& helper,
0735 const GeometryContext& gctx,
0736 const ViewConfig& viewConfig,
0737 const ViewConfig& portalViewConfig,
0738 const ViewConfig& sensitiveViewConfig) const {
0739 helper.object(volumeName());
0740 Volume::visualize(helper, gctx, viewConfig);
0741
0742 if (!surfaces().empty()) {
0743 helper.object(volumeName() + "_sensitives");
0744 }
0745 for (const auto& surface : surfaces()) {
0746 surface.visualize(helper, gctx, sensitiveViewConfig);
0747 }
0748
0749 for (const auto& portal : portals()) {
0750 portal.surface().visualize(helper, gctx, portalViewConfig);
0751 }
0752
0753 for (const auto& child : volumes()) {
0754 child.visualize(helper, gctx, viewConfig, portalViewConfig,
0755 sensitiveViewConfig);
0756 }
0757 }
0758
0759 void TrackingVolume::setNavigationPolicy(
0760 std::unique_ptr<INavigationPolicy> policy) {
0761 if (policy == nullptr) {
0762 throw std::invalid_argument("Navigation policy is nullptr");
0763 }
0764
0765 m_navigationPolicy = std::move(policy);
0766 m_navigationPolicy->connect(m_navigationDelegate);
0767 }
0768
0769 void TrackingVolume::initializeNavigationCandidates(
0770 const NavigationArguments& args, AppendOnlyNavigationStream& stream,
0771 const Logger& logger) const {
0772 m_navigationDelegate(args, stream, logger);
0773 }
0774
0775 }