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