Warning, file /include/Acts/Detector/DetectorVolume.hpp 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 #pragma once
0010
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Definitions/Common.hpp"
0013 #include "Acts/Detector/DetectorVolumeVisitorConcept.hpp"
0014 #include "Acts/Detector/Portal.hpp"
0015 #include "Acts/Detector/PortalGenerators.hpp"
0016 #include "Acts/Geometry/Extent.hpp"
0017 #include "Acts/Geometry/GeometryContext.hpp"
0018 #include "Acts/Geometry/GeometryIdentifier.hpp"
0019 #include "Acts/Geometry/VolumeBounds.hpp"
0020 #include "Acts/Material/IVolumeMaterial.hpp"
0021 #include "Acts/Navigation/NavigationDelegates.hpp"
0022 #include "Acts/Navigation/NavigationState.hpp"
0023 #include "Acts/Surfaces/BoundaryCheck.hpp"
0024 #include "Acts/Surfaces/SurfaceVisitorConcept.hpp"
0025 #include "Acts/Utilities/BoundingBox.hpp"
0026 #include "Acts/Utilities/Concepts.hpp"
0027 #include "Acts/Utilities/Delegate.hpp"
0028 #include "Acts/Utilities/Helpers.hpp"
0029
0030 #include <algorithm>
0031 #include <cstddef>
0032 #include <memory>
0033 #include <stdexcept>
0034 #include <string>
0035 #include <utility>
0036 #include <vector>
0037
0038 namespace Acts {
0039
0040 class Surface;
0041 class IVolumeMaterial;
0042 class VolumeBounds;
0043
0044 namespace Experimental {
0045
0046 class DetectorVolume;
0047 class Detector;
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062 class DetectorVolume : public std::enable_shared_from_this<DetectorVolume> {
0063 public:
0064 using BoundingBox =
0065 Acts::AxisAlignedBoundingBox<Acts::Experimental::DetectorVolume,
0066 Acts::ActsScalar, 3>;
0067
0068 friend class DetectorVolumeFactory;
0069
0070
0071
0072
0073
0074
0075
0076
0077 template <typename internal_type>
0078 struct ObjectStore {
0079
0080 std::vector<internal_type> internal = {};
0081
0082
0083 std::vector<const typename internal_type::element_type*> external = {};
0084
0085
0086
0087
0088 ObjectStore(std::vector<internal_type> objects)
0089 : internal(std::move(objects)) {
0090 external = unpack_shared_const_vector(internal);
0091 }
0092
0093 ObjectStore() = default;
0094 };
0095
0096 protected:
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111 DetectorVolume(const GeometryContext& gctx, std::string name,
0112 const Transform3& transform,
0113 std::shared_ptr<VolumeBounds> bounds,
0114 std::vector<std::shared_ptr<Surface>> surfaces,
0115 std::vector<std::shared_ptr<DetectorVolume>> volumes,
0116 ExternalNavigationDelegate externalNavigation,
0117 InternalNavigationDelegate internalNavigation) noexcept(false);
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130 DetectorVolume(const GeometryContext& gctx, std::string name,
0131 const Transform3& transform,
0132 std::shared_ptr<VolumeBounds> bounds,
0133 InternalNavigationDelegate internalNavigation) noexcept(false);
0134
0135
0136
0137
0138 static std::shared_ptr<DetectorVolume> makeShared(
0139 const GeometryContext& gctx, std::string name,
0140 const Transform3& transform, std::shared_ptr<VolumeBounds> bounds,
0141 std::vector<std::shared_ptr<Surface>> surfaces,
0142 std::vector<std::shared_ptr<DetectorVolume>> volumes,
0143 ExternalNavigationDelegate externalNavigation,
0144 InternalNavigationDelegate internalNavigation);
0145
0146
0147
0148
0149 static std::shared_ptr<DetectorVolume> makeShared(
0150 const GeometryContext& gctx, std::string name,
0151 const Transform3& transform, std::shared_ptr<VolumeBounds> bounds,
0152 InternalNavigationDelegate internalNavigation);
0153
0154 public:
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164 std::shared_ptr<DetectorVolume> getSharedPtr();
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175 std::shared_ptr<const DetectorVolume> getSharedPtr() const;
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185 const Transform3& transform(
0186 const GeometryContext& gctx = GeometryContext()) const;
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196 Vector3 center(const GeometryContext& gctx = GeometryContext()) const;
0197
0198
0199
0200
0201 const VolumeBounds& volumeBounds() const;
0202
0203
0204
0205
0206
0207
0208
0209 bool inside(const GeometryContext& gctx, const Vector3& position) const;
0210
0211
0212
0213
0214
0215
0216
0217
0218 bool exclusivelyInside(const GeometryContext& gctx,
0219 const Vector3& position) const;
0220
0221
0222
0223
0224
0225
0226
0227 Extent extent(const GeometryContext& gctx, std::size_t nseg = 1) const;
0228
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240 void updateNavigationState(const GeometryContext& gctx,
0241 NavigationState& nState) const;
0242
0243
0244
0245
0246 std::vector<std::shared_ptr<Portal>>& portalPtrs();
0247
0248
0249
0250
0251 std::vector<std::shared_ptr<Surface>>& surfacePtrs();
0252
0253
0254
0255
0256 std::vector<std::shared_ptr<DetectorVolume>>& volumePtrs();
0257
0258
0259
0260
0261
0262
0263
0264 const std::vector<const Portal*>& portals() const;
0265
0266
0267
0268
0269
0270
0271
0272
0273 const std::vector<const Surface*>& surfaces() const;
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283 const std::vector<const DetectorVolume*>& volumes() const;
0284
0285
0286 const ExternalNavigationDelegate& externalNavigation() const;
0287
0288
0289
0290
0291
0292
0293
0294 template <ACTS_CONCEPT(SurfaceVisitor) visitor_t>
0295 void visitSurfaces(visitor_t&& visitor) const {
0296 for (const auto& s : surfaces()) {
0297 visitor(s);
0298 }
0299 for (const auto& p : portals()) {
0300 p->visitSurface(std::forward<visitor_t>(visitor));
0301 }
0302 for (const auto& v : volumes()) {
0303 v->visitSurfaces(std::forward<visitor_t>(visitor));
0304 }
0305 }
0306
0307
0308
0309
0310
0311
0312
0313 template <ACTS_CONCEPT(MutableSurfaceVisitor) visitor_t>
0314 void visitMutableSurfaces(visitor_t&& visitor) {
0315 for (auto& s : surfacePtrs()) {
0316 visitor(s.get());
0317 }
0318 for (auto& p : portalPtrs()) {
0319 p->visitMutableSurface(std::forward<visitor_t>(visitor));
0320 }
0321 for (auto& v : volumePtrs()) {
0322 v->visitMutableSurfaces(std::forward<visitor_t>(visitor));
0323 }
0324 }
0325
0326
0327
0328
0329
0330
0331
0332
0333
0334
0335
0336 template <ACTS_CONCEPT(DetectorVolumeVisitor) visitor_t>
0337 void visitVolumes(visitor_t&& visitor) const {
0338 visitor(this);
0339 for (const auto& v : volumes()) {
0340 v->visitVolumes(std::forward<visitor_t>(visitor));
0341 }
0342 }
0343
0344
0345
0346
0347
0348
0349
0350
0351
0352
0353
0354 template <ACTS_CONCEPT(MutableDetectorVolumeVisitor) visitor_t>
0355 void visitMutableVolumes(visitor_t&& visitor) {
0356 visitor(this);
0357 for (auto& v : volumePtrs()) {
0358 v->visitMutableVolumes(std::forward<visitor_t>(visitor));
0359 }
0360 }
0361
0362
0363
0364
0365
0366
0367
0368
0369 void assignInternalNavigation(
0370 InternalNavigationDelegate internalNavigation,
0371 const std::vector<std::shared_ptr<Surface>>& surfaces = {},
0372 const std::vector<std::shared_ptr<DetectorVolume>>& volumes = {});
0373
0374
0375 const InternalNavigationDelegate& internalNavigation() const;
0376
0377
0378
0379
0380
0381
0382
0383 void updatePortal(std::shared_ptr<Portal> portal,
0384 unsigned int pIndex) noexcept(false);
0385
0386
0387 void closePortals();
0388
0389
0390
0391
0392
0393
0394
0395
0396 void assignVolumeMaterial(std::shared_ptr<const IVolumeMaterial> material);
0397
0398
0399 const IVolumeMaterial* volumeMaterial() const;
0400
0401
0402 const std::string& name() const;
0403
0404
0405 const GeometryIdentifier& geometryId() const;
0406
0407
0408
0409
0410
0411 void assignGeometryId(const GeometryIdentifier& geoID);
0412
0413
0414
0415 void assignDetector(const Detector& detector);
0416
0417
0418 const Detector* detector() const;
0419
0420 const BoundingBox& getBoundingBox() const;
0421
0422 private:
0423
0424
0425
0426
0427
0428
0429 void construct(const GeometryContext& gctx,
0430 const PortalGenerator& portalGenerator) noexcept(false);
0431
0432
0433
0434
0435
0436
0437
0438 bool checkContainment(const GeometryContext& gctx,
0439 std::size_t nseg = 1) const;
0440
0441
0442
0443 void createBoundingBox(const GeometryContext& gctx);
0444
0445
0446 std::string m_name = "Unnamed";
0447
0448
0449 Transform3 m_transform = Transform3::Identity();
0450
0451
0452 std::shared_ptr<VolumeBounds> m_bounds = nullptr;
0453
0454
0455 ObjectStore<std::shared_ptr<Portal>> m_portals;
0456
0457
0458 ObjectStore<std::shared_ptr<Surface>> m_surfaces;
0459
0460
0461 ObjectStore<std::shared_ptr<DetectorVolume>> m_volumes;
0462
0463
0464 std::shared_ptr<const BoundingBox> m_boundingBox;
0465
0466 ExternalNavigationDelegate m_externalNavigation;
0467
0468
0469 InternalNavigationDelegate m_internalNavigation;
0470
0471
0472 std::shared_ptr<const IVolumeMaterial> m_volumeMaterial = nullptr;
0473
0474
0475 GeometryIdentifier m_geometryId{0};
0476
0477
0478 const Detector* m_detector = nullptr;
0479 };
0480
0481
0482
0483
0484
0485
0486
0487 class DetectorVolumeFactory {
0488 public:
0489
0490 static std::shared_ptr<DetectorVolume> construct(
0491 const PortalGenerator& portalGenerator, const GeometryContext& gctx,
0492 const std::string& name, const Transform3& transform,
0493 std::shared_ptr<VolumeBounds> bounds,
0494 const std::vector<std::shared_ptr<Surface>>& surfaces,
0495 const std::vector<std::shared_ptr<DetectorVolume>>& volumes,
0496 ExternalNavigationDelegate externalNavigation,
0497 InternalNavigationDelegate internalNavigation, int nSeg = -1) {
0498 auto dVolume = DetectorVolume::makeShared(
0499 gctx, name, transform, std::move(bounds), surfaces, volumes,
0500 std::move(externalNavigation), std::move(internalNavigation));
0501 dVolume->construct(gctx, portalGenerator);
0502
0503
0504
0505
0506 if (nSeg > 0 && !dVolume->checkContainment(gctx, nSeg)) {
0507 throw std::invalid_argument(
0508 "DetectorVolume: surfaces or subvolumes are not contained by volume");
0509 }
0510 return dVolume;
0511 }
0512
0513
0514 static std::shared_ptr<DetectorVolume> construct(
0515 const PortalGenerator& portalGenerator, const GeometryContext& gctx,
0516 std::string name, const Transform3& transform,
0517 std::shared_ptr<VolumeBounds> bounds,
0518 InternalNavigationDelegate internalNavigation) {
0519 auto dVolume = DetectorVolume::makeShared(gctx, std::move(name), transform,
0520 std::move(bounds),
0521 std::move(internalNavigation));
0522 dVolume->construct(gctx, portalGenerator);
0523 return dVolume;
0524 }
0525 };
0526
0527
0528 struct AllPortalsExtractor {
0529
0530
0531
0532
0533
0534
0535 inline static const std::vector<const Portal*> extract(
0536 [[maybe_unused]] const GeometryContext& gctx,
0537 const NavigationState& nState) {
0538 if (nState.currentVolume == nullptr) {
0539 throw std::runtime_error(
0540 "AllPortalsExtractor: no detector volume given.");
0541 }
0542 return nState.currentVolume->portals();
0543 }
0544 };
0545
0546
0547 struct AllSurfacesExtractor {
0548
0549
0550
0551
0552
0553
0554
0555 inline static const std::vector<const Surface*> extract(
0556 [[maybe_unused]] const GeometryContext& gctx,
0557 const NavigationState& nState,
0558 [[maybe_unused]] const std::vector<std::size_t>& indices = {}) {
0559 if (nState.currentVolume == nullptr) {
0560 throw std::runtime_error(
0561 "AllSurfacesExtractor: no detector volume given.");
0562 }
0563 return nState.currentVolume->surfaces();
0564 }
0565 };
0566
0567
0568 struct IndexedSurfacesExtractor {
0569
0570
0571
0572
0573
0574
0575
0576
0577
0578 inline static const std::vector<const Surface*> extract(
0579 [[maybe_unused]] const GeometryContext& gctx,
0580 const NavigationState& nState, const std::vector<std::size_t>& indices) {
0581 if (nState.currentVolume == nullptr) {
0582 throw std::runtime_error(
0583 "IndexedSurfacesExtractor: no detector volume given.");
0584 }
0585
0586 const auto& surfaces = nState.currentVolume->surfaces();
0587
0588 std::vector<const Surface*> eSurfaces;
0589 eSurfaces.reserve(indices.size());
0590 std::for_each(indices.begin(), indices.end(),
0591 [&](const auto& i) { eSurfaces.push_back(surfaces[i]); });
0592 return eSurfaces;
0593 }
0594 };
0595
0596
0597 struct AllSubVolumesExtractor {
0598
0599
0600
0601
0602
0603
0604
0605 inline static const std::vector<const DetectorVolume*> extract(
0606 [[maybe_unused]] const GeometryContext& gctx,
0607 const NavigationState& nState,
0608 [[maybe_unused]] const std::vector<std::size_t>& indices = {}) {
0609 if (nState.currentVolume == nullptr) {
0610 throw std::runtime_error(
0611 "AllSubVolumesExtractor: no detector volume given.");
0612 }
0613 return nState.currentVolume->volumes();
0614 }
0615 };
0616
0617
0618 struct IndexedSubVolumesExtractor {
0619
0620
0621
0622
0623
0624
0625
0626 inline static const std::vector<const DetectorVolume*> extract(
0627 [[maybe_unused]] const GeometryContext& gctx,
0628 const NavigationState& nState, const std::vector<std::size_t>& indices) {
0629 if (nState.currentVolume == nullptr) {
0630 throw std::runtime_error(
0631 "AllSubVolumesExtractor: no detector volume given.");
0632 }
0633
0634 const auto& volumes = nState.currentVolume->volumes();
0635
0636 std::vector<const DetectorVolume*> eVolumes;
0637 eVolumes.reserve(indices.size());
0638 std::for_each(indices.begin(), indices.end(),
0639 [&](const auto& i) { eVolumes.push_back(volumes[i]); });
0640 return eVolumes;
0641 }
0642 };
0643
0644 }
0645 }