Skip to content

Commit 425168b

Browse files
committed
feat: Add portal tagging blueprint node
1 parent 03125e8 commit 425168b

13 files changed

Lines changed: 679 additions & 1 deletion

Core/include/Acts/Geometry/BlueprintNode.hpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ class PortalShellBase;
3333
namespace Experimental {
3434

3535
class MaterialDesignatorBlueprintNode;
36+
class PortalDesignatorBlueprintNode;
3637
class StaticBlueprintNode;
3738
class LayerBlueprintNode;
3839
class GeometryIdentifierBlueprintNode;
@@ -231,6 +232,16 @@ class BlueprintNode {
231232
const std::function<void(MaterialDesignatorBlueprintNode& material)>&
232233
callback = {});
233234

235+
/// Convenience method for creating a @ref Acts::Experimental::PortalDesignatorBlueprintNode.
236+
/// @param name The name of the portal designator node. Used for debugging
237+
/// the node tree only.
238+
/// @param callback An optional callback that receives the node as an argument
239+
/// @return Reference to the newly created portal designator blueprint node
240+
PortalDesignatorBlueprintNode& addPortalDesignator(
241+
const std::string& name,
242+
const std::function<void(PortalDesignatorBlueprintNode& portals)>&
243+
callback = {});
244+
234245
/// Convenience method for creating a @ref Acts::Experimental::LayerBlueprintNode.
235246
/// @param name The name of the layer node.
236247
/// @param callback An optional callback that receives the node as an argument

Core/include/Acts/Geometry/Portal.hpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616

1717
#include <exception>
1818
#include <memory>
19+
#include <span>
1920
#include <string>
21+
#include <vector>
2022

2123
namespace Acts {
2224

@@ -255,6 +257,16 @@ class Portal {
255257
/// @return The portal surface
256258
RegularSurface& surface();
257259

260+
/// Add a string tag to this portal. Tags are used to look the portal up from
261+
/// the final @ref Acts::TrackingGeometry (e.g. the portal connecting the
262+
/// tracker and the calorimeter).
263+
/// @param tag The tag to add
264+
void addTag(std::string tag);
265+
266+
/// Access the tags assigned to this portal.
267+
/// @return A view of the tags assigned to this portal
268+
std::span<const std::string> tags() const;
269+
258270
private:
259271
/// Helper to check surface equivalence without checking material status. This
260272
/// is needed because we allow fusing portals with surfaces that are
@@ -272,6 +284,8 @@ class Portal {
272284

273285
std::unique_ptr<PortalLinkBase> m_alongNormal;
274286
std::unique_ptr<PortalLinkBase> m_oppositeNormal;
287+
288+
std::vector<std::string> m_tags;
275289
};
276290

277291
} // namespace Acts
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
// This file is part of the ACTS project.
2+
//
3+
// Copyright (C) 2016 CERN for the benefit of the ACTS project
4+
//
5+
// This Source Code Form is subject to the terms of the Mozilla Public
6+
// License, v. 2.0. If a copy of the MPL was not distributed with this
7+
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
8+
9+
#pragma once
10+
11+
#include "Acts/Geometry/BlueprintNode.hpp"
12+
#include "Acts/Geometry/CuboidVolumeBounds.hpp"
13+
#include "Acts/Geometry/CylinderVolumeBounds.hpp"
14+
15+
namespace Acts {
16+
17+
namespace Experimental {
18+
19+
namespace detail {
20+
class PortalDesignatorBlueprintNodeImpl;
21+
}
22+
23+
/// This node type assigns string tags to specific portal faces of its child
24+
/// volume during the blueprint construction. The tags can be used to look up
25+
/// the corresponding portals from the final @ref Acts::TrackingGeometry, e.g.
26+
/// "the portal connecting the tracker and the calorimeter".
27+
///
28+
/// Tagging happens in the *finalize* phase, after all portal merging and
29+
/// fusing has completed, so the tagged portal is the final, shared portal that
30+
/// ends up in the geometry. The position of this node in the blueprint tree
31+
/// determines which face is meant, which makes the lookup robust against volume
32+
/// subdivision and portal ordering.
33+
/// @note This node can only have a single child. This is not an error during
34+
/// tree building, but during geometry construction.
35+
class PortalDesignatorBlueprintNode final : public BlueprintNode {
36+
public:
37+
/// Main constructor for the portal designator node.
38+
/// @param name The name of the node (for debug only)
39+
explicit PortalDesignatorBlueprintNode(const std::string& name);
40+
41+
~PortalDesignatorBlueprintNode() override;
42+
43+
/// @copydoc BlueprintNode::name
44+
const std::string& name() const override;
45+
46+
/// @copydoc BlueprintNode::toStream
47+
void toStream(std::ostream& os) const override;
48+
49+
/// This method participates in the geometry construction.
50+
/// It checks that this node only has a single child and forwards the call.
51+
/// @param options The global blueprint options
52+
/// @param gctx The geometry context (nominal usually)
53+
/// @param logger The logger to use
54+
/// @return The child volume
55+
Volume& build(const BlueprintOptions& options, const GeometryContext& gctx,
56+
const Logger& logger = Acts::getDummyLogger()) override;
57+
58+
/// This method participates in the geometry construction.
59+
/// It captures the populated portal shell from its only child so the tags can
60+
/// be applied in the finalize phase (after all merging/fusing), and forwards
61+
/// the call.
62+
/// @param options The global blueprint options
63+
/// @param gctx The geometry context (nominal usually)
64+
/// @param logger The logger to use
65+
/// @return The portal shell of the child
66+
PortalShellBase& connect(
67+
const BlueprintOptions& options, const GeometryContext& gctx,
68+
const Logger& logger = Acts::getDummyLogger()) override;
69+
70+
/// This method participates in the geometry construction.
71+
/// It applies the configured tags to the (now final) portals of the captured
72+
/// shell, then passes the call through to its only child.
73+
/// @param options The global blueprint options
74+
/// @param gctx The geometry context (nominal usually)
75+
/// @param parent The parent volume
76+
/// @param logger The logger to use during construction
77+
void finalize(const BlueprintOptions& options, const GeometryContext& gctx,
78+
TrackingVolume& parent, const Logger& logger) override;
79+
80+
/// Tag a cylinder face with a string label.
81+
/// @note This method can be called multiple times to tag different faces.
82+
/// @param face The face of the cylinder to tag
83+
/// @param label The tag to assign to the portal at that face
84+
/// @return The portal designator node
85+
/// @note If this node has previously been configured with a different volume
86+
/// shape, this will throw an exception during geometry construction.
87+
PortalDesignatorBlueprintNode& tagFace(CylinderVolumeBounds::Face face,
88+
const std::string& label);
89+
90+
/// Tag a cuboid face with a string label.
91+
/// @note This method can be called multiple times to tag different faces.
92+
/// @param face The face of the cuboid to tag
93+
/// @param label The tag to assign to the portal at that face
94+
/// @return The portal designator node
95+
/// @note If this node has previously been configured with a different volume
96+
/// shape, this will throw an exception during geometry construction.
97+
PortalDesignatorBlueprintNode& tagFace(CuboidVolumeBounds::Face face,
98+
const std::string& label);
99+
100+
private:
101+
/// @copydoc BlueprintNode::addToGraphviz
102+
void addToGraphviz(std::ostream& os) const override;
103+
104+
detail::PortalDesignatorBlueprintNodeImpl& impl();
105+
const detail::PortalDesignatorBlueprintNodeImpl& impl() const;
106+
107+
std::unique_ptr<detail::PortalDesignatorBlueprintNodeImpl> m_impl;
108+
};
109+
110+
} // namespace Experimental
111+
} // namespace Acts

Core/include/Acts/Geometry/TrackingGeometry.hpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,16 @@
1818
#include "Acts/Utilities/Logger.hpp"
1919

2020
#include <memory>
21+
#include <string>
22+
#include <string_view>
2123
#include <unordered_map>
2224
#include <utility>
2325

2426
namespace Acts {
2527

2628
class Layer;
2729
class Surface;
30+
class Portal;
2831
class PerigeeSurface;
2932
class IMaterialDecorator;
3033
class TrackingVolume;
@@ -190,6 +193,14 @@ class TrackingGeometry {
190193
/// @retval pointer to the found surface otherwise.
191194
const Surface* findSurface(GeometryIdentifier id) const;
192195

196+
/// Search for a portal that was tagged with the given label during the
197+
/// blueprint construction (see @ref Acts::Experimental::PortalDesignatorBlueprintNode).
198+
///
199+
/// @param tag the tag assigned to the portal
200+
/// @retval nullptr if no portal carries the tag
201+
/// @retval pointer to the tagged portal otherwise.
202+
const Portal* findPortal(std::string_view tag) const;
203+
193204
/// Access to the GeometryIdentifier - Surface association map
194205
/// @return Const reference to the geometry ID to surface map
195206
const std::unordered_map<GeometryIdentifier, const Surface*>&
@@ -219,6 +230,7 @@ class TrackingGeometry {
219230
// lookup containers
220231
std::unordered_map<GeometryIdentifier, const TrackingVolume*> m_volumesById;
221232
std::unordered_map<GeometryIdentifier, const Surface*> m_surfacesById;
233+
std::unordered_map<std::string, const Portal*> m_portalsByTag;
222234
};
223235

224236
} // namespace Acts

Core/src/Geometry/BlueprintNode.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "Acts/Geometry/GeometryIdentifierBlueprintNode.hpp"
1414
#include "Acts/Geometry/LayerBlueprintNode.hpp"
1515
#include "Acts/Geometry/MaterialDesignatorBlueprintNode.hpp"
16+
#include "Acts/Geometry/PortalDesignatorBlueprintNode.hpp"
1617
#include "Acts/Geometry/StaticBlueprintNode.hpp"
1718
#include "Acts/Navigation/INavigationPolicy.hpp"
1819
#include "Acts/Navigation/TryAllNavigationPolicy.hpp"
@@ -149,6 +150,18 @@ MaterialDesignatorBlueprintNode& BlueprintNode::addMaterial(
149150
return *material;
150151
}
151152

153+
PortalDesignatorBlueprintNode& BlueprintNode::addPortalDesignator(
154+
const std::string& name,
155+
const std::function<void(PortalDesignatorBlueprintNode& portals)>&
156+
callback) {
157+
auto portals = std::make_shared<PortalDesignatorBlueprintNode>(name);
158+
addChild(portals);
159+
if (callback) {
160+
callback(*portals);
161+
}
162+
return *portals;
163+
}
164+
152165
LayerBlueprintNode& BlueprintNode::addLayer(
153166
const std::string& name,
154167
const std::function<void(LayerBlueprintNode& layer)>& callback) {

Core/src/Geometry/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ target_sources(
5656
LayerBlueprintNode.cpp
5757
IndexGrid.cpp
5858
MaterialDesignatorBlueprintNode.cpp
59+
PortalDesignatorBlueprintNode.cpp
5960
VolumeAttachmentStrategy.cpp
6061
VolumeResizeStrategy.cpp
6162
GeometryIdentifierBlueprintNode.cpp

Core/src/Geometry/Portal.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "Acts/Surfaces/RegularSurface.hpp"
2020
#include "Acts/Utilities/Zip.hpp"
2121

22+
#include <algorithm>
2223
#include <cstdlib>
2324
#include <memory>
2425
#include <sstream>
@@ -184,6 +185,21 @@ RegularSurface& Portal::surface() {
184185
return *m_surface;
185186
}
186187

188+
void Portal::addTag(std::string tag) {
189+
if (std::ranges::find(m_tags, tag) != m_tags.end()) {
190+
throw std::invalid_argument("Portal already has tag: " + tag);
191+
}
192+
m_tags.push_back(std::move(tag));
193+
}
194+
195+
std::span<const std::string> Portal::tags() const {
196+
return m_tags;
197+
}
198+
199+
// Note: tags are intentionally *not* propagated through merge/fuse. These
200+
// operations build new portals, and portal tagging is a post-stacking operation
201+
// (applied in the finalize phase of the blueprint construction, after all
202+
// merging and fusing has happened), so there is nothing to carry over here.
187203
Portal Portal::merge(const GeometryContext& gctx, Portal& aPortal,
188204
Portal& bPortal, AxisDirection direction,
189205
const Logger& logger,

0 commit comments

Comments
 (0)