Construction

Todo

Not complete yet

Blueprint tracking geometry construction

class BlueprintNode

Base class for all nodes in the blueprint tree.

This class defines the three-phase construction process. The three phases are

  1. Build: Construct volume representation + compute final sizing

  2. Connect: Create and connect portals at volume boundaries

  3. Finalize: Register portals with volumes + create acceleration structures

During the build phase, the build method of all nodes in the tree are called recursively. Some nodes, like Acts::CylinderContainerBlueprintNode, will take action on the volumes returns from its children, and perform sizing to connect them. See the Acts::CylinderContainerBlueprintNode and Acts::CylinderVolumeStack documentation for details on how the sizing is carried out.

Subclassed by Acts::Blueprint, Acts::CylinderContainerBlueprintNode, Acts::MaterialDesignatorBlueprintNode, Acts::StaticBlueprintNode

Construction methods

These methods constitute the primary interface of the node that participates in the geometry construction.

virtual Volume &build(const BlueprintOptions &options, const GeometryContext &gctx, const Logger &logger = Acts::getDummyLogger()) = 0

This method is called during the build phase of the blueprint tree construction.

It returns a single Acts::Volume which represents transform and bounds of the entire subtree. This does not have to correspond to the final Acts::TrackingVolume, some node types will produce temporary volume representations. Lifetime of the returned volume is managed by the source node! Nodes higher in the hierarchy will issue resizes down the tree hierarchy. This is not done through a direct hierarchy, but coordinated by the respective node type, by internally consulting its children.

Note

Generally, you should not need to to call this method directly. The construction should usually be done through the special Acts::Blueprint class.

Parameters:
  • options – The global construction options

  • gctx – The geometry context for construction (usually nominal)

  • logger – The logger to use for output during construction

Returns:

The volume used for communicating transform and size up the hierarchy

virtual PortalShellBase &connect(const BlueprintOptions &options, const GeometryContext &gctx, const Logger &logger = Acts::getDummyLogger()) = 0

This method is called during the connect phase.

This phase handles the creation and connection of portals (instances of Acts::PortalLinkBase). After the build-phase has completed, the volume sizes are final. Each node will consult its fully sized volume to produce boundary surfaces. Each boundary surface is then turned into a Acts::TrivialPortalLink, which in turn produces a one-sided portal (see Acts::Portal documentation)

Some nodes (like Acts::CylinderContainerBlueprintNode) will take action on their children, and unify the connected portals.

After a node’s processing has completed, it returns a reference to a Acts::PortalShellBase, which represents a set of portals in a specific geometry arrangement. The returned object lifetime is managed by the returning node.

Parameters:
  • options – The global construction options

  • gctx – The geometry context for construction (usually nominal)

  • logger – The logger to use for output during construction

virtual void finalize(const BlueprintOptions &options, const GeometryContext &gctx, TrackingVolume &parent, const Logger &logger = Acts::getDummyLogger()) = 0

This method is called during the finalize phase.

This phase handles:

  • Registering portals into their final volumes

  • Registering volumes into their parents

  • Creating navigation policies

  • (In future) Handle geometry identification assignment

At the end of this phase, each node will have transferred any temporary resources created during the build, that need to be retained, into the final Acts::TrackingGeometry, and can be safely destroyed.

Note

The parent for volumes, portals, etc to be registered in is passed in as an argument, rather than being implicitly determined from the parent node. This is done so that nodes can remove themselves from the final volume hierarchy, like container nodes or the Acts::MaterialDesignatorBlueprintNode.

Parameters:
  • options – The global construction options

  • gctx – The geometry context for construction (usually nominal)

  • parent – The parent volume to register in

  • logger – The logger to use for output during construction

Convenience methods

These methods are meant to make the construction of a blueprint tree in code more ergonomic.

They usually take an optional callback parameter. The primary use for this parameter is structural, as it facilitates introducing scopes to indicate in code that objects are nested.

Blueprint::Config cfg;
auto root = std::make_unique<Blueprint>(cfg);
root->addStaticVolume(
    base, std::make_shared<CylinderVolumeBounds>(50_mm, 400_mm, 1000_mm),
    "PixelWrapper", [&](auto& wrapper) {
        // This scope can be used to equip `wrapper`
    });

Alternatively, they can also be used without a callback, as the newly created node is also returned by reference:

auto& wrapper = root->addStaticVolume(
    base, std::make_shared<CylinderVolumeBounds>(50_mm, 400_mm, 1000_mm),
    "PixelWrapper");

In both cases, it’s not necessary to register the newly created node with a parent node.

StaticBlueprintNode &addStaticVolume(std::unique_ptr<TrackingVolume> volume, const std::function<void(StaticBlueprintNode &cylinder)> &callback = {})

This method creates a new Acts::StaticBlueprintNode wrapping volume and adds it to this node as a child.

Parameters:
  • volume – The volume to add

  • callback – An optional callback that receives the node as an argument

Returns:

A reference to the created node

StaticBlueprintNode &addStaticVolume(const Transform3 &transform, std::shared_ptr<VolumeBounds> volumeBounds, const std::string &volumeName = "undefined", const std::function<void(StaticBlueprintNode &cylinder)> &callback = {})

Alternative overload for creating a Acts::StaticBlueprintNode.

This overload will invoke the constructor of Acts::TrackingVolume and use that volume to create the node.

Parameters:
  • transform – The transform of the volume

  • volumeBounds – The bounds of the volume

  • volumeName – The name of the volume

  • callback – An optional callback that receives the node as an argument

CylinderContainerBlueprintNode &addCylinderContainer(const std::string &name, AxisDirection direction, const std::function<void(CylinderContainerBlueprintNode &cylinder)> &callback = {})

Convenience method for creating a Acts::CylinderContainerBlueprintNode.

Parameters:
  • name – The name of the container node. This name is only reflected in the node tree for debugging, as no extra volumes is created for the container.

  • direction – The direction of the stack configuration. See Acts::CylinderVolumeStack for details.

  • callback – An optional callback that receives the node as an argument

MaterialDesignatorBlueprintNode &addMaterial(const std::string &name, const std::function<void(MaterialDesignatorBlueprintNode &material)> &callback = {})

Convenience method for creating a Acts::MaterialDesignatorBlueprintNode.

Parameters:
  • name – The name of the material designator node. Used for debugging the node tree only.

  • callback – An optional callback that receives the node as an argument

LayerBlueprintNode &addLayer(const std::string &name, const std::function<void(LayerBlueprintNode &layer)> &callback = {})

Convenience method for creating a Acts::LayerBlueprintNode.

Parameters:
  • name – The name of the layer node.

  • callback – An optional callback that receives the node as an argument

Public Types

using ChildRange = detail::TransformRange<detail::ConstDereference, const std::vector<std::shared_ptr<BlueprintNode>>>

A range-like object that allows range based for loops and index access.

This type’s iterators and accessors return const references when dereferenced.

using MutableChildRange = detail::TransformRange<detail::Dereference, std::vector<std::shared_ptr<BlueprintNode>>>

A range-like object that allows range based for loops and index access.

This type’s iterators and accessors return mutable references when dereferenced.

Public Functions

virtual ~BlueprintNode() = default

Virtual destructor to ensure correct cleanup.

BlueprintNode &addChild(std::shared_ptr<BlueprintNode> child)

Register a child to this node.

Warning

This method throws if adding the child would create a cycle in the blueprint tree!

Parameters:

child – The child node to add

Returns:

A reference this node (not the child!)

virtual void addToGraphviz(std::ostream &os) const

Method that writes a representatiohn of this node only to graphviz.

This should generally not be called on its own, but through the BlueprintNode::graphviz method.

Parameters:

os – The stream to print to

MutableChildRange children()

Return a MutableChildRange to the children of this node.

Returns:

A range-like object to the children

ChildRange children() const

Return a ChildRange to the children of this node.

Returns:

A range-like object to the children

void clearChildren()

Remove all children from this node.

std::size_t depth() const

Return the depth of this node in the blueprint tree.

A depth of zero means this node does not have a parent.

Returns:

The depth of this node

void graphviz(std::ostream &os) const

Print the node tree starting from this node to graphviz format.

Parameters:

os – The stream to print to

virtual const std::string &name() const = 0

Get the name of this node.

Friends

inline friend std::ostream &operator<<(std::ostream &os, const BlueprintNode &node)

Print a representation of this node to the stream.

Parameters:
  • os – The stream to print to

  • node – The node to print

Returns:

The output stream

class Blueprint : public Acts::BlueprintNode

This class is the top-level entry point to build a tracking geometry using the blueprint building mechanism.

It forms the root of a tree of nodes where each node performs a portion of the construction. This top-level class has the main construction methods that execute the construction of the geometry.

           +---------------+  +-----------+
           |               |  |           |
           |     Root      |  |           v
           |               |  |   +---------------+
           +---------------+  |   |               |
                   |          |   |    Child 1    |
        +----------+          |   |               |
        v          +----------+   +---------------+
+---------------+                         |
|               |          +--------------+
|    Child 2    |          v         +----------+
|               |     .---------.    |          |
+---------------+    /           \   |          v
                    (  Proc node  )  |  +---------------+
                     `.         ,'   |  |               |
                       `-------'     |  |    Child 3    |
                           |         |  |               |
                           |         |  +---------------+
                           +---------+

The construction phases are documented in BlueprintNode, which is the base class for all nodes in the tree.

Note

This class inherits from BlueprintNode, but hides the main blueprint construction phase overloads. The Blueprint class is only ever intended to be the top-level node, and not anywhere else in the tree.

Public Functions

explicit Blueprint(const Config &config)

Constructor from a config object.

Parameters:

config – The configuration object

std::unique_ptr<TrackingGeometry> construct(const BlueprintOptions &options, const GeometryContext &gctx, const Logger &logger = Acts::getDummyLogger())

Construct the tracking geometry from the blueprint tree.

Parameters:
  • options – The construction options, see BlueprintOptions

  • gctx – The geometry context for construction. In almost all cases, this should be the nominal geometry context

  • logger – The logger to use for output during construction

struct Config

Public Members

ExtentEnvelope envelope = ExtentEnvelope::Zero()

Determine how much envelope space to produce from the highest volume in the geometry hierarchy and the world volume.

GeometryIdentifierHook geometryIdentifierHook = {}

The geometry identifier hook, passed through the TrackingGeometry constructor.

This will be superseded by a more integrated approach to the identification scheme

Container nodes

class CylinderContainerBlueprintNode : public Acts::BlueprintNode

This class handles the case of wrapping a set of cylinder-shaped children and stacking them in a configured direction.

The stacking is done using CylinderVolumeStack. The container does not result in an extra volume in the hierarchy, as all input volumes and any gap volumes produced are directly registered in the volume of the parent of this node.

Note

This node assumes all children produce only cylinder volumes! It throws if this is not the case.

Public Functions

CylinderContainerBlueprintNode(const std::string &name, AxisDirection direction, VolumeAttachmentStrategy attachmentStrategy = VolumeAttachmentStrategy::Midpoint, VolumeResizeStrategy resizeStrategy = VolumeResizeStrategy::Expand)

Main constructor for the cylinder container node.

Note

The parameters are passed through to CylinderVolumeStack, see documentation of that class for more information

Parameters:
  • name – The name of the node (for debug only)

  • direction – The stacking direction

  • attachmentStrategy – The attachment strategy for the stack

  • resizeStrategy – The resize strategy

VolumeAttachmentStrategy attachmentStrategy() const

Accessor to the attachment strategy.

Returns:

The attachment strategy

virtual Volume &build(const BlueprintOptions &options, const GeometryContext &gctx, const Logger &logger = Acts::getDummyLogger()) override

This participates in the construction of the geometry via the blueprint tree.

The steps are approximately as follows:

  1. Collect all child volumes

  2. Package them into a Acts::CylinderVolumeStack, which performs sizing and/or gap creation

  3. Return the Acts::CylinderVolumeStack as a volume up the tree

Parameters:
  • options – The global blueprint options

  • gctx – The geometry context (nominal usually)

  • logger – The logger to use

Returns:

The combined Acts::CylinderVolumeStack

virtual CylinderStackPortalShell &connect(const BlueprintOptions &options, const GeometryContext &gctx, const Logger &logger = Acts::getDummyLogger()) override

This participates in the construction of the geometry via the blueprint tree.

The steps are approximately as follows:

  1. Walk through all volumes that were created by the build phase

  2. Check if they are: real child volumes or gap volumes

    • If gap volume: produce a Acts::TrackingVolume, and wrap it in a single use shell

    • If child volume: locate the right child node it came from, call connect and collect the returned shell

  3. Produce a combined Acts::CylinderStackPortalShell from all the shells

  4. Return that shell representation

Parameters:
  • options – The global blueprint options

  • gctx – The geometry context (nominal usually)

  • logger – The logger to use

Returns:

The combined Acts::CylinderStackPortalShell

AxisDirection direction() const

Accessor to the stacking direction.

Returns:

The stacking direction

virtual void finalize(const BlueprintOptions &options, const GeometryContext &gctx, TrackingVolume &parent, const Logger &logger) override

This participates in the construction of the geometry via the blueprint tree.

The steps are approximately as follows:

  1. Register portals created for gap volumes, as they’re not handled by dedicated nodes

  2. Register gap volumes in the parent volume

  3. Create a configured Acts::INavigationPolicy for the gap

  4. Call finalize on all children while passing through parent.

Parameters:
  • options – The global blueprint options

  • gctx – The geometry context (nominal usually)

  • parent – The parent volume

  • logger – The logger to use

virtual const std::string &name() const override

Get the name of this node.

VolumeResizeStrategy resizeStrategy() const

Accessor to the resize strategy.

Returns:

The resize strategy

CylinderContainerBlueprintNode &setAttachmentStrategy(VolumeAttachmentStrategy attachmentStrategy)

Setter for the attachment strategy.

Parameters:

attachmentStrategy – The attachment strategy

Returns:

This node for chaining

CylinderContainerBlueprintNode &setDirection(AxisDirection direction)

Setter for the stacking direction.

Parameters:

direction – The stacking direction

Returns:

This node for chaining

CylinderContainerBlueprintNode &setResizeStrategy(VolumeResizeStrategy resizeStrategy)

Setter for the resize strategy.

Parameters:

resizeStrategy – The resize strategy

Returns:

This node for chaining

Material nodes

class MaterialDesignatorBlueprintNode : public Acts::BlueprintNode

This node type registers material proxies into its child volume during the blueprint construction.

It is configured ahead of time which volume faces to mark up, and how do to so.

Note

This node can only have a single child. This is not an error during tree building, but during geometry construction.

Note

This currently only supports a cylinder volume child

Public Types

using BinningConfig = std::variant<std::vector<std::tuple<CylinderVolumeBounds::Face, Experimental::ProtoBinning, Experimental::ProtoBinning>>>

Public Functions

inline explicit MaterialDesignatorBlueprintNode(const std::string &name)

Main constructor for the material designator node.

Parameters:

name – The name of the node (for debug only)

const std::optional<BinningConfig> &binning() const

Retrieve the binning configuration.

Returns:

The binning configuration

virtual Volume &build(const BlueprintOptions &options, const GeometryContext &gctx, const Logger &logger = Acts::getDummyLogger()) override

This method participates in the geometry construction.

It checks that this node only has a single child, is correctly configured, and forwards the call.

Parameters:
  • options – The global blueprint options

  • gctx – The geometry context (nominal usually)

  • logger – The logger to use

Returns:

The child volume

virtual PortalShellBase &connect(const BlueprintOptions &options, const GeometryContext &gctx, const Logger &logger = Acts::getDummyLogger()) override

This method participates in the geometry construction.

It receives the populated portal shell from its only child and attaches material proxies by consulting the configuration stored in the node.

Note

Currently, this node will unconditionally attach Acts::ProtoGridSurfaceMaterial

Parameters:
  • options – The global blueprint options

  • gctx – The geometry context (nominal usually)

  • logger – The logger to use

Returns:

The portal shell with material proxies attached

virtual void finalize(const BlueprintOptions &options, const GeometryContext &gctx, TrackingVolume &parent, const Logger &logger) override

This method participates in the geometry construction.

Passes through the call to its only child.

Parameters:
  • options – The global blueprint options

  • gctx – The geometry context (nominal usually)

  • parent – The parent volume

  • logger – The logger to use during construction

virtual const std::string &name() const override

Get the name of this node.

MaterialDesignatorBlueprintNode &setBinning(BinningConfig binning)

Set the binning configuration.

Parameters:

binning – The binning configuration

virtual void toStream(std::ostream &os) const override

Virtual method to determine stream representation.

Note

This method is called by the stream operator.

Geometry identification specification

Layers and other nodes

class StaticBlueprintNode : public Acts::BlueprintNode

The static blueprint node wraps a single already-constructred TrackingVolume.

The node will present this volume to its hierarchy. The volume is given as mutable, and will be potentially enlarged in order to connect to neighboring volumes.

  • In case the volume already has child volumes, they will be retained.

  • In case the volume already has a registered navigation policy, it will be overwritten with the one configured on this node, regardless of content.

Subclassed by Acts::LayerBlueprintNode

Public Functions

explicit StaticBlueprintNode(std::unique_ptr<TrackingVolume> volume)

Construct the static node from an existing volume.

Parameters:

volume – The volume to wrap

virtual Volume &build(const BlueprintOptions &options, const GeometryContext &gctx, const Logger &logger = Acts::getDummyLogger()) override

This method is called during the build phase of the blueprint tree construction.

It returns a single Acts::Volume which represents transform and bounds of the entire subtree. This does not have to correspond to the final Acts::TrackingVolume, some node types will produce temporary volume representations. Lifetime of the returned volume is managed by the source node! Nodes higher in the hierarchy will issue resizes down the tree hierarchy. This is not done through a direct hierarchy, but coordinated by the respective node type, by internally consulting its children.

Note

Generally, you should not need to to call this method directly. The construction should usually be done through the special Acts::Blueprint class.

Parameters:
  • options – The global construction options

  • gctx – The geometry context for construction (usually nominal)

  • logger – The logger to use for output during construction

Returns:

The volume used for communicating transform and size up the hierarchy Build-phase of the blueprint construction. Returns the wrapped volume for sizing.

virtual PortalShellBase &connect(const BlueprintOptions &options, const GeometryContext &gctx, const Logger &logger = Acts::getDummyLogger()) override

This method is called during the connect phase.

This phase handles the creation and connection of portals (instances of Acts::PortalLinkBase). After the build-phase has completed, the volume sizes are final. Each node will consult its fully sized volume to produce boundary surfaces. Each boundary surface is then turned into a Acts::TrivialPortalLink, which in turn produces a one-sided portal (see Acts::Portal documentation)

Some nodes (like Acts::CylinderContainerBlueprintNode) will take action on their children, and unify the connected portals.

After a node’s processing has completed, it returns a reference to a Acts::PortalShellBase, which represents a set of portals in a specific geometry arrangement. The returned object lifetime is managed by the returning node.

Parameters:
  • options – The global construction options

  • gctx – The geometry context for construction (usually nominal)

  • logger – The logger to use for output during construction

virtual void finalize(const BlueprintOptions &options, const GeometryContext &gctx, TrackingVolume &parent, const Logger &logger = Acts::getDummyLogger()) override

This method is called during the finalize phase.

This phase handles:

  • Registering portals into their final volumes

  • Registering volumes into their parents

  • Creating navigation policies

  • (In future) Handle geometry identification assignment

At the end of this phase, each node will have transferred any temporary resources created during the build, that need to be retained, into the final Acts::TrackingGeometry, and can be safely destroyed.

Note

The parent for volumes, portals, etc to be registered in is passed in as an argument, rather than being implicitly determined from the parent node. This is done so that nodes can remove themselves from the final volume hierarchy, like container nodes or the Acts::MaterialDesignatorBlueprintNode.

Parameters:
  • options – The global construction options

  • gctx – The geometry context for construction (usually nominal)

  • parent – The parent volume to register in

  • logger – The logger to use for output during construction

virtual const std::string &name() const override

Get the name of this node.

It is automatically taken from the wrapped volume

Returns:

The name of the volume

const NavigationPolicyFactory *navigationPolicyFactory() const
virtual StaticBlueprintNode &setNavigationPolicyFactory(std::shared_ptr<NavigationPolicyFactory> navigationPolicyFactory)
class LayerBlueprintNode : public Acts::StaticBlueprintNode

The layer node is essentially an auto-sizing wrapper around a set of surfaces.

The layer volume is created to wrap around the surfaces registered with this node. The orientation of the resulting volume defaults to the identity matrix. If another orientation is desired, this can be set with the Acts::LayerBlueprintNode::setTransform. See Acts::ProtoLayer for details on the auto-sizing from surfaces.

Note

This implementation is preliminary and will likely change in the future. It defers most of the functionality to Acts::StaticBlueprintNode, after the initial volume creation is completed.

Public Types

enum class LayerType

Enum that lists out the supported layer types.

Values:

enumerator Cylinder

A cylinder layer.

enumerator Disc

A disc layer.

enumerator Plane

A plane layer.

Note

This is not yet implemented

Public Functions

inline explicit LayerBlueprintNode(const std::string &name)

Constructor for a layer node.

Parameters:

name – The name of the layer

virtual Volume &build(const BlueprintOptions &options, const GeometryContext &gctx, const Logger &logger = Acts::getDummyLogger()) override

This function participates in the geometry construction.

It will:

  1. Analyze the surfaces provided and produce a wrapping volume

  2. Register the surfaces with the volume

  3. Return the volume

Note

At least one surfaces needs to be registered via Acts::LayerBlueprintNode::setSurfaces before geometry construction.

const ExtentEnvelope &envelope() const

Access the envelope of the layer node.

Returns:

The envelope

const LayerType &layerType() const

Access the layer type of the layer node.

Returns:

The layer type

virtual const std::string &name() const override

Get the name of this node.

LayerBlueprintNode &setEnvelope(const ExtentEnvelope &envelope)

Set the envelope of the layer node.

This configures the amount of space to add around the contained surfaces.

Parameters:

envelope – The envelope to set

Returns:

Reference to this node for chaining

LayerBlueprintNode &setLayerType(LayerType layerType)

Set the layer type of the layer node.

Parameters:

layerType – The layer type to set

Returns:

Reference to this node for chaining

LayerBlueprintNode &setSurfaces(std::vector<std::shared_ptr<Surface>> surfaces)

Register a set of surfaces with the layer node.

Parameters:

surfaces – The surfaces to register

Returns:

Reference to this node for chaining

LayerBlueprintNode &setTransform(const Transform3 &transform)

Set the transformation of the layer node.

This can be used to specifically orient the resulting layer volume.

Parameters:

transform – The transformation to set

Returns:

Reference to this node for chaining

const std::vector<std::shared_ptr<Surface>> &surfaces() const

Access the registered surfaces.

Returns:

The registered surfaces

const Transform3 &transform() const

Access the transformation of the layer node.

Returns:

The transformation

Friends

inline friend std::ostream &operator<<(std::ostream &os, LayerBlueprintNode::LayerType type)

Output operator for the layer type enum.

Parameters:
  • os – The output stream

  • type – The layer type

API

C++ API Example

Python API Examples

Plugin usage

Extension capabilities