Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 22 additions & 1 deletion Core/include/Acts/Geometry/LayerBlueprintNode.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,30 @@ class LayerBlueprintNode final : public StaticBlueprintNode {
LayerBlueprintNode& setSurfaces(
std::vector<std::shared_ptr<Surface>> surfaces);

/// Register a set of surface placemen with the layer node. The surfaces that
/// are not yet registered with the layer are also registered
/// @param placements The list of placements to be registered with the layer
/// @note This will clear any previously registered proto layer
/// @return Reference to this node for chaining
LayerBlueprintNode& setPlacements(
std::vector<std::shared_ptr<SurfacePlacementBase>> placements);

/// Register a new surface with the layer
/// @note This will clear any previously registered proto layer
/// @param surface Pointer to the surface tobe appended
/// @return Reference to this node for chaining
LayerBlueprintNode& addSurface(std::shared_ptr<Surface> surface);

/// Register a new placement with the layer
/// @note This will clear any previously registered proto layer
/// @param placement Pointer to be placement to be appended
/// @return Reference to this node for chaining
LayerBlueprintNode& addPlacement(
std::shared_ptr<SurfacePlacementBase> placement);

/// Access the registered surfaces.
/// @return The registered surfaces
const std::vector<std::shared_ptr<Surface>>& surfaces() const;
std::vector<std::shared_ptr<Surface>> surfaces() const;

/// Register a proto layer with the layer node.
/// @param protoLayer The proto layer to register
Expand Down
2 changes: 2 additions & 0 deletions Core/include/Acts/Geometry/TrackingGeometry.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,8 @@ class TrackingGeometry {
// lookup containers
std::unordered_map<GeometryIdentifier, const TrackingVolume*> m_volumesById;
std::unordered_map<GeometryIdentifier, const Surface*> m_surfacesById;
using PlacementOwnPtr = TrackingVolume::PlacementOwnPtr;
std::vector<PlacementOwnPtr> m_placements;
};

} // namespace Acts
35 changes: 32 additions & 3 deletions Core/include/Acts/Geometry/TrackingVolume.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ class TrackingVolume;
struct GeometryIdentifierHook;
class Portal;
class INavigationPolicy;

/// Interface types of the Gen1 geometry model
/// @note This interface is being replaced, and is subject to removal
/// @{
Expand Down Expand Up @@ -127,6 +126,18 @@ class TrackingVolume : public Volume {
std::shared_ptr<VolumeBounds> volbounds,
const std::string& volumeName = "undefined");

/// Constructor for an aligned container volumes where the tracking volume
/// also takes (temporary) ownership of the placement. This constructor is
/// only memory safe if the volume is appended to the tracking geometry tree
/// or if the placement does not own the placement
/// @param placement is the shared_ptr to the volume placement object
/// dynamically positioning the volume in space
/// @param volbounds is the description of the volume boundaries
/// @param volumeName is a string identifier
TrackingVolume(std::shared_ptr<VolumePlacementBase> placement,
std::shared_ptr<VolumeBounds> volBounds,
const std::string& volumeName = "undefined");

/// Constructor for a container Volume
/// - vacuum filled volume either as a for other tracking volumes
///
Expand Down Expand Up @@ -339,7 +350,10 @@ class TrackingVolume : public Volume {
using PortalRange =
detail::TransformRange<detail::ConstDereference,
const std::vector<std::shared_ptr<Portal>>>;

/// Abrivation of the shared ptr variant holding the placements
using PlacementOwnPtr =
std::variant<std::shared_ptr<const VolumePlacementBase>,
std::shared_ptr<const SurfacePlacementBase>>;
/// Return all portals registered under this tracking volume
/// @return the range of portals
PortalRange portals() const;
Expand Down Expand Up @@ -371,7 +385,11 @@ class TrackingVolume : public Volume {

/// Add a surface to this tracking volume
/// @param surface The surface to add
void addSurface(std::shared_ptr<Surface> surface);
/// @param placement Optional pointer to the surface placement associated with the surface
/// @note The volume takes shared ownership of the placement
void addSurface(
std::shared_ptr<Surface> surface,
std::shared_ptr<const SurfacePlacementBase> placement = nullptr);

/// Add a child volume to this tracking volume
/// @param volume The volume to add
Expand Down Expand Up @@ -554,6 +572,12 @@ class TrackingVolume : public Volume {
AppendOnlyNavigationStream& stream,
const Logger& logger) const;

/// Pass over a (Volume / Surface) placement to share owner ship
/// with the volume
/// @param placement: Pointer to the placement to be managed by the
/// tracking volume
void cachePlacement(PlacementOwnPtr placement);

private:
void connectDenseBoundarySurfaces(
MutableTrackingVolumeVector& confinedDenseVolumes);
Expand All @@ -570,6 +594,10 @@ class TrackingVolume : public Volume {
/// @param envelope is the clearance between volume boundary and layer
void synchronizeLayers(double envelope = 1.) const;

/// Return the garbage container into which the placements are pushed. If the
/// volume does not have a mother it's the volume itself otherwise the mother
std::vector<PlacementOwnPtr>& cachedPlacements();

// the boundary surfaces
std::vector<TrackingVolumeBoundaryPtr> m_boundarySurfaces;

Expand Down Expand Up @@ -600,6 +628,7 @@ class TrackingVolume : public Volume {
std::vector<std::unique_ptr<TrackingVolume>> m_volumes;
std::vector<std::shared_ptr<Portal>> m_portals;
std::vector<std::shared_ptr<Surface>> m_surfaces;
std::vector<PlacementOwnPtr> m_placements;

std::unique_ptr<INavigationPolicy> m_navigationPolicy;

Expand Down
86 changes: 74 additions & 12 deletions Core/src/Geometry/LayerBlueprintNode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@

std::string m_name;

std::vector<std::shared_ptr<Surface>> m_surfaces{};
using LayerNodePtr = std::variant<std::shared_ptr<Surface>,
std::shared_ptr<SurfacePlacementBase>>;

std::vector<LayerNodePtr> m_nodes{};

/// If a proto layer is already given externally, this node will not perform
/// sizing from surfaces
Expand Down Expand Up @@ -57,21 +60,20 @@
Volume& LayerBlueprintNode::build(const BlueprintOptions& options,
const GeometryContext& gctx,
const Logger& logger) {
if (impl().m_surfaces.empty()) {
if (impl().m_nodes.empty()) {
ACTS_ERROR("LayerBlueprintNode: no surfaces provided");
throw std::invalid_argument("LayerBlueprintNode: no surfaces provided");
}

ACTS_DEBUG(prefix() << "Building Layer " << name() << " from "
<< impl().m_surfaces.size() << " surfaces");
<< impl().m_nodes.size() << " nodes");
ACTS_VERBOSE(prefix() << " -> layer type: " << impl().m_layerType);
ACTS_VERBOSE(prefix() << " -> transform:\n" << impl().m_transform.matrix());

Extent extent;

if (!impl().m_protoLayer.has_value()) {
impl().m_protoLayer.emplace(gctx, impl().m_surfaces,
impl().m_transform.inverse());
impl().m_protoLayer.emplace(gctx, surfaces(), impl().m_transform.inverse());
ACTS_VERBOSE(prefix() << "Built proto layer: "
<< impl().m_protoLayer.value());
} else {
Expand All @@ -86,10 +88,20 @@
buildVolume(extent, logger);
assert(m_volume != nullptr && "Volume not built from proto layer");

for (auto& surface : impl().m_surfaces) {
for (auto& surface : surfaces()) {

Check warning on line 91 in Core/src/Geometry/LayerBlueprintNode.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Make the type of this variable a reference-to-const. The current type of "surface" is "class std::shared_ptr<class Acts::Surface> &".

See more on https://sonarcloud.io/project/issues?id=acts-project_acts&issues=AZ1y1uLFibOnsipywi1T&open=AZ1y1uLFibOnsipywi1T&pullRequest=5322
m_volume->addSurface(surface);
}

auto visitor = overloaded{
[](const std::shared_ptr<Surface>&) {

},

Check failure on line 98 in Core/src/Geometry/LayerBlueprintNode.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Add a nested comment explaining why this method is empty, or complete the implementation.

See more on https://sonarcloud.io/project/issues?id=acts-project_acts&issues=AZ1y1uLFibOnsipywi1U&open=AZ1y1uLFibOnsipywi1U&pullRequest=5322
[this](const std::shared_ptr<SurfacePlacementBase>& placement) {
m_volume->cachePlacement(placement);
}};
for (auto& node : impl().m_nodes) {
std::visit(visitor, node);
}
return StaticBlueprintNode::build(options, gctx, logger);
}

Expand Down Expand Up @@ -148,23 +160,73 @@

LayerBlueprintNode& LayerBlueprintNode::setSurfaces(
std::vector<std::shared_ptr<Surface>> surfaces) {
impl().m_surfaces = std::move(surfaces);
impl().m_nodes.reserve(impl().m_nodes.size() + surfaces.size());
for (auto& surface : surfaces) {
impl().m_nodes.emplace_back(std::move(surface));
}
impl().m_protoLayer.reset();
return *this;
}

const std::vector<std::shared_ptr<Surface>>& LayerBlueprintNode::surfaces()
const {
return impl().m_surfaces;
LayerBlueprintNode& LayerBlueprintNode::setPlacements(
std::vector<std::shared_ptr<SurfacePlacementBase>> placements) {
impl().m_nodes.reserve(impl().m_nodes.size() + placements.size());
for (auto& placement : placements) {
impl().m_nodes.emplace_back(std::move(placement));
}
impl().m_protoLayer.reset();

return *this;
}

/// Register a new surface with the layer
/// @note This will clear any previously registered proto layer
/// @return Reference to this node for chaining
LayerBlueprintNode& LayerBlueprintNode::addSurface(
std::shared_ptr<Surface> surface) {
impl().m_nodes.emplace_back(std::move(surface));
return *this;
}

/// Register a new placement with the layer
/// @note This will clear any previously registered proto layer
/// @return Reference to this node for chaining
LayerBlueprintNode& LayerBlueprintNode::addPlacement(
std::shared_ptr<SurfacePlacementBase> placement) {
impl().m_nodes.emplace_back(std::move(placement));
return *this;
}

std::vector<std::shared_ptr<Surface>> LayerBlueprintNode::surfaces() const {
std::vector<std::shared_ptr<Surface>> surfaces{};
surfaces.reserve(impl().m_nodes.size());
auto visitor = overloaded{
[&surfaces](const std::shared_ptr<Surface>& surface) {
surfaces.emplace_back(surface);
},
[&surfaces](const std::shared_ptr<SurfacePlacementBase>& placement) {
surfaces.emplace_back(placement->surface().getSharedPtr());
}};
for (const auto& node : impl().m_nodes) {
std::visit(visitor, node);
}
auto nonUniqueRange = std::ranges::unique(
surfaces.begin(), surfaces.end(),
[](const std::shared_ptr<Surface>& a, const std::shared_ptr<Surface>& b) {
return a == b;
});

Check warning on line 217 in Core/src/Geometry/LayerBlueprintNode.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Replace with the version of "std::ranges::unique" that takes a range.

See more on https://sonarcloud.io/project/issues?id=acts-project_acts&issues=AZ1y1uLFibOnsipywi1V&open=AZ1y1uLFibOnsipywi1V&pullRequest=5322
surfaces.erase(nonUniqueRange.begin(), nonUniqueRange.end());

return surfaces;
}

LayerBlueprintNode& LayerBlueprintNode::setProtoLayer(
std::optional<MutableProtoLayer> protoLayer) {
impl().m_protoLayer = std::move(protoLayer);
impl().m_surfaces.clear();
impl().m_nodes.clear();
// also take ownership of the surfaces now
for (auto& surface : impl().m_protoLayer.value().surfaces()) {
impl().m_surfaces.push_back(surface->getSharedPtr());
impl().m_nodes.emplace_back(surface->getSharedPtr());
}
return *this;
}
Expand Down
5 changes: 5 additions & 0 deletions Core/src/Geometry/TrackingGeometry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,11 @@ TrackingGeometry::TrackingGeometry(
ACTS_DEBUG("Closing tracking geometry with Gen1 assignment");
Gen1GeometryClosureVisitor visitor{logger, materialDecorator, hook};
apply(visitor);
m_placements.insert(
m_placements.end(),
std::make_move_iterator(highestVolume->m_placements.begin()),
std::make_move_iterator(highestVolume->m_placements.end()));
highestVolume->m_placements.clear();
}

GeometryIdMapVisitor mapVisitor{logger};
Expand Down
32 changes: 31 additions & 1 deletion Core/src/Geometry/TrackingVolume.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,16 @@ TrackingVolume::TrackingVolume(VolumePlacementBase& placement,
m_navigationDelegate.connect<&INavigationPolicy::noopInitializeCandidates>();
}

TrackingVolume::TrackingVolume(std::shared_ptr<VolumePlacementBase> placement,
std::shared_ptr<VolumeBounds> volBounds,
const std::string& volumeName)
: TrackingVolume(*placement, std::move(volBounds), volumeName) {
if (placement == nullptr) {
throw std::invalid_argument("The passed placement must not be a nullptr");
}
m_placements.emplace_back(placement);
}

TrackingVolume::~TrackingVolume() = default;
TrackingVolume::TrackingVolume(TrackingVolume&&) noexcept = default;
TrackingVolume& TrackingVolume::operator=(TrackingVolume&&) noexcept = default;
Expand Down Expand Up @@ -562,10 +572,25 @@ TrackingVolume& TrackingVolume::addVolume(
}

volume->setMotherVolume(this);
// Take over the ownership of all placements hold
auto& placements = cachedPlacements();
placements.insert(placements.end(),
std::make_move_iterator(volume->m_placements.begin()),
std::make_move_iterator(volume->m_placements.end()));
volume->m_placements.clear();
m_volumes.push_back(std::move(volume));
return *m_volumes.back();
}

void TrackingVolume::cachePlacement(PlacementOwnPtr placement) {
cachedPlacements().emplace_back(std::move(placement));
}
std::vector<TrackingVolume::PlacementOwnPtr>&
TrackingVolume::cachedPlacements() {
return m_motherVolume == nullptr ? m_placements
: m_motherVolume->cachedPlacements();
}

TrackingVolume::PortalRange TrackingVolume::portals() const {
return PortalRange{m_portals};
}
Expand All @@ -589,11 +614,16 @@ TrackingVolume::MutableSurfaceRange TrackingVolume::surfaces() {
return MutableSurfaceRange{m_surfaces};
}

void TrackingVolume::addSurface(std::shared_ptr<Surface> surface) {
void TrackingVolume::addSurface(
std::shared_ptr<Surface> surface,
std::shared_ptr<const SurfacePlacementBase> placement) {
if (surface == nullptr) {
throw std::invalid_argument("Surface is nullptr");
}
m_surfaces.push_back(std::move(surface));
if (placement != nullptr) {
cachePlacement(std::move(placement));
}
}

void TrackingVolume::visualize(IVisualization3D& helper,
Expand Down
Loading