Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Adding cuboid portal shell #4047

Open
wants to merge 19 commits into
base: main
Choose a base branch
from
160 changes: 160 additions & 0 deletions Core/include/Acts/Geometry/CuboidPortalShell.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
// This file is part of the ACTS project.
//
// Copyright (C) 2016 CERN for the benefit of the ACTS project
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

#pragma once

#include "Acts/Definitions/Algebra.hpp"
#include "Acts/Geometry/CuboidVolumeBounds.hpp"
#include "Acts/Geometry/PortalShell.hpp"
#include "Acts/Geometry/TrackingVolume.hpp"
#include "Acts/Utilities/AxisDefinitions.hpp"
#include "Acts/Utilities/Logger.hpp"

#include <array>
#include <memory>
#include <vector>

namespace Acts {

/// @class CuboidPortalShell
/// Base class for cuboid shaped portal shells, e.g. shells for cuboid
/// volumes
class CuboidPortalShell : public PortalShellBase {
public:
using Face = CuboidVolumeBounds::Face;

using enum CuboidVolumeBounds::Face;

/// Retrieve the portal associated to the given face. Can be nullptr if unset.
/// @param face The face to retrieve the portal for
/// @return The portal associated to the face
virtual Portal* portal(Face face) = 0;

/// Retrieve a shared_ptr for the portal associated to the given face. Can be
/// nullptr if unset.
/// @param face The face to retrieve the portal for
/// @return The portal associated to the face
virtual std::shared_ptr<Portal> portalPtr(Face face) = 0;

/// Set the portal associated to the given face.
/// @param portal The portal to set
/// @param face The face to set the portal
virtual void setPortal(std::shared_ptr<Portal> portal, Face face) = 0;

/// @copydoc PortalShellBase::fill
void fill(TrackingVolume& volume) override;

virtual const Transform3& transform() const = 0;
};

/// Output stream operator for the CuboidPortalShell::Face enum
/// @param os The output stream
/// @param face The face to output
/// @return The output stream
std::ostream& operator<<(std::ostream& os, CuboidPortalShell::Face face);

/// @class SingleCuboidPortalShell
/// This class describes a cuboid shell containing a single volume.
class SingleCuboidPortalShell : public CuboidPortalShell {
public:
/// Construct a single cuboid portal shell for the given volume
/// @param volume The volume to create the shell for
explicit SingleCuboidPortalShell(TrackingVolume& volume);

/// @copydoc PortalShellBase::size
std::size_t size() const final;

/// @copydoc CuboidPortalShell::portal
Portal* portal(Face face) final;

/// @copydoc CuboidPortalShell::portalPtr
std::shared_ptr<Portal> portalPtr(Face face) final;

/// @copydoc CuboidPortalShell::setPortal
void setPortal(std::shared_ptr<Portal> portal, Face face) final;

/// @copydoc PortalShellBase::applyToVolume
void applyToVolume() override;

/// @copydoc PortalShellBase::isValid
bool isValid() const override;

/// @copydoc PortalShellBase::label
std::string label() const override;

const Transform3& transform() const override {
return m_volume->transform();
};

private:
std::array<std::shared_ptr<Portal>, 6> m_portals{};

TrackingVolume* m_volume;
};

/// @class CuboidStackPortalShell
/// This class describes a cuboid shell containing multiple volumes.
class CuboidStackPortalShell : public CuboidPortalShell {
public:
/// Construct the portal shell stack from the given shells
/// @param gctx The geometry context
/// @param shells The shells to stack
/// @note The shells must be ordered in the given direction
/// @param axis The stacking direction (along x/y/z axis) in local stack coordinates
/// @param logger A logging instance for debugging
CuboidStackPortalShell(const GeometryContext& gctx,
std::vector<CuboidPortalShell*> shells,
AxisDirection axis,
const Logger& logger = getDummyLogger());

/// @copydoc PortalShellBase::size
std::size_t size() const final;

/// @copydoc CuboidPortalShell::portal
Portal* portal(Face face) final;

/// @copydoc CuboidPortalShell::portalPtr
std::shared_ptr<Portal> portalPtr(Face face) final;

/// @copydoc CuboidPortalShell::setPortal
void setPortal(std::shared_ptr<Portal> portal, Face face) final;

void applyToVolume() override {
// No-op, because it's a composite portal shell
}

/// @copydoc PortalShellBase::isValid
bool isValid() const final;

/// @copydoc PortalShellBase::label
std::string label() const final;

/// Return the stack's group transform
const Transform3& transform() const override;

private:
void stackShell(const GeometryContext& gctx, const Logger& logger);

/// Shell stacking direction in global coordinates
Vector3 m_direction;
ssdetlab marked this conversation as resolved.
Show resolved Hide resolved

/// Shell stacking direction in local stack coordinates
AxisDirection m_axis;

/// The cuboid face positioned first along the stacking direction
CuboidVolumeBounds::Face m_frontFace = NegativeYZPlane;
/// The cuboid face positioned last along the stacking direction
CuboidVolumeBounds::Face m_backFace = PositiveYZPlane;
/// The cuboid faces parallel to the stacking direction
std::array<CuboidVolumeBounds::Face, 4> m_sideFaces{
NegativeXYPlane, PositiveXYPlane, NegativeZXPlane, PositiveZXPlane};

std::vector<CuboidPortalShell*> m_shells;
};

} // namespace Acts
25 changes: 24 additions & 1 deletion Core/include/Acts/Geometry/CuboidVolumeBounds.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#pragma once

#include "Acts/Definitions/Algebra.hpp"
#include "Acts/Geometry/BoundarySurfaceFace.hpp"
#include "Acts/Geometry/Volume.hpp"
#include "Acts/Geometry/VolumeBounds.hpp"
#include "Acts/Utilities/AxisDefinitions.hpp"
Expand Down Expand Up @@ -58,6 +59,18 @@ class CuboidVolumeBounds : public VolumeBounds {
eSize
};

/// Enum describing the possible faces of a cuboid volume
/// @note These values are synchronized with the BoundarySurfaceFace enum.
/// Once Gen1 is removed, this can be changed.
enum class Face : unsigned int {
NegativeXYPlane = BoundarySurfaceFace::negativeFaceXY,
PositiveXYPlane = BoundarySurfaceFace::positiveFaceXY,
NegativeYZPlane = BoundarySurfaceFace::negativeFaceYZ,
PositiveYZPlane = BoundarySurfaceFace::positiveFaceYZ,
NegativeZXPlane = BoundarySurfaceFace::negativeFaceZX,
PositiveZXPlane = BoundarySurfaceFace::positiveFaceZX
};

CuboidVolumeBounds() = delete;

/// Constructor - the box boundaries
Expand Down Expand Up @@ -156,7 +169,17 @@ class CuboidVolumeBounds : public VolumeBounds {
/// Convert axis direction to a corresponding bound value
/// in local coordinate convention
/// @param direction the axis direction to convert
static BoundValues fromAxisDirection(AxisDirection direction);
static BoundValues boundsFromAxisDirection(AxisDirection direction);

/// Convert axis direction to a set of corresponding cuboid faces
/// in local coordinate convention
/// @param direction the axis direction to convert
/// @return A tuple of cuboid faces with the following ordering convention:
/// (1) negative face orthogonal to the axis direction
/// (2) positive face orthogonal to the axis direction
/// (3) list of side faces parallel to the axis direction
static std::tuple<Face, Face, std::array<Face, 4>> facesFromAxisDirection(
AxisDirection direction);

/// Output Method for std::ostream
///
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
#pragma once

#include "Acts/Geometry/BlueprintNode.hpp"
#include "Acts/Geometry/CylinderPortalShell.hpp"
#include "Acts/Geometry/CylinderVolumeStack.hpp"
#include "Acts/Geometry/PortalShell.hpp"
#include "Acts/Geometry/VolumeAttachmentStrategy.hpp"
#include "Acts/Geometry/VolumeResizeStrategy.hpp"
#include "Acts/Utilities/AxisDefinitions.hpp"
Expand Down
174 changes: 174 additions & 0 deletions Core/include/Acts/Geometry/CylinderPortalShell.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
// This file is part of the ACTS project.
//
// Copyright (C) 2016 CERN for the benefit of the ACTS project
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

#pragma once

#include "Acts/Geometry/CylinderVolumeBounds.hpp"
#include "Acts/Geometry/PortalShell.hpp"
#include "Acts/Utilities/AxisDefinitions.hpp"
#include "Acts/Utilities/Logger.hpp"

#include <array>
#include <memory>

namespace Acts {

/// @class CylinderPortalShell
/// Base class for cylinder shaped portal shells, e.g. shells for cylinder
/// volumes
class CylinderPortalShell : public PortalShellBase {
public:
using Face = CylinderVolumeBounds::Face;

using enum CylinderVolumeBounds::Face;

/// Retrieve the portal associated to the given face. Can be nullptr if unset.
/// @param face The face to retrieve the portal for
/// @return The portal associated to the face
virtual Portal* portal(Face face) = 0;

/// Retrieve a shared_ptr for the portal associated to the given face. Can be
/// nullptr if unset.
/// @param face The face to retrieve the portal for
/// @return The portal associated to the face
virtual std::shared_ptr<Portal> portalPtr(Face face) = 0;

/// Set the portal associated to the given face.
/// @param portal The portal to set
/// @param face The face to set the portal
virtual void setPortal(std::shared_ptr<Portal> portal, Face face) = 0;

/// @copydoc PortalShellBase::fill
void fill(TrackingVolume& volume) override;
};

/// Output stream operator for the CylinderPortalShell::Face enum
/// @param os The output stream
/// @param face The face to output
/// @return The output stream
std::ostream& operator<<(std::ostream& os, CylinderPortalShell::Face face);

/// @class SingleCylinderPortalShell
/// This class describes a cylinder shell containing a single volume. The
/// available faces depend on the configuration of the cylinder volume bounds.
/// If a phi sector is configured, the shell will have corresponding portal
/// slots. If the inner radius is non-zero, the shell will have an inner
/// cylinder portal slot.
class SingleCylinderPortalShell : public CylinderPortalShell {
public:
using Base = CylinderPortalShell;

/// Construct a single cylinder portal shell for the given volume
/// @param volume The volume to create the shell for
explicit SingleCylinderPortalShell(TrackingVolume& volume);

/// @copydoc PortalShellBase::size
std::size_t size() const final;

/// @copydoc CylinderPortalShell::portal
Portal* portal(Face face) final;

/// @copydoc CylinderPortalShell::portalPtr
std::shared_ptr<Portal> portalPtr(Face face) final;

/// @copydoc CylinderPortalShell::setPortal
void setPortal(std::shared_ptr<Portal> portal, Face face) final;

/// @copydoc PortalShellBase::applyToVolume
void applyToVolume() override;

/// @copydoc PortalShellBase::isValid
bool isValid() const override;

/// @copydoc PortalShellBase::label
std::string label() const override;

private:
std::array<std::shared_ptr<Portal>, 6> m_portals{};

TrackingVolume* m_volume;
};

/// @class CylinderStackPortalShell
/// This class describes a cylinder shell containing multiple volumes. The
/// available faces depend on the configuration of the cylinder volume bounds.
/// @note The stack shell currently does not support phi sectors
/// The stack can be oriented along the (local) z or r direction, which drives
/// the stacking. Depending on the direction, portals on the shells of children
/// are merged or fused. Subsequently, portal access respects shared portals
/// between shells. Below is an illustration of a stack in the r direction:
///
/// Fused +-----------------+
/// portals ----+ | |
/// | | v OuterCylinder
/// | +------+------+
/// | | | |
/// | | | |<--+
/// +--+---+ v | |
/// +---+---------+ |
/// | | | | Shared portal
/// | | |<--+--- (grid)
/// | v | | PositiveDisc
/// +-------------+ |
/// r ^ | | |
/// | | |<--+
/// | | |
/// | +-------------+ InnerCylinder
/// +-----> ^ (if rMin>0)
/// z | |
/// +-----------------+
///
/// @note The shells must be ordered in the given direction
/// Depending on the stack direction, the portal lookup will return different
/// portals. In the illustration above, the `PositiveDisc` portal is shared
/// among all shells, while the `OuterCylinder` and `InnerCylinder` portals are
/// looked up from the innermost and outermost shell in the r direction.
class CylinderStackPortalShell : public CylinderPortalShell {
public:
using SingleShell = SingleCylinderPortalShell;

/// Construct the portal shell stack from the given shells
/// @param gctx The geometry context
/// @param shells The shells to stack
/// @note The shells must be ordered in the given direction
/// @param direction The stacking direction
/// @param logger A logging instance for debugging
CylinderStackPortalShell(const GeometryContext& gctx,
std::vector<CylinderPortalShell*> shells,
AxisDirection direction,
const Logger& logger = getDummyLogger());

/// @copydoc PortalShellBase::size
std::size_t size() const final;

/// @copydoc CylinderPortalShell::portal
Portal* portal(Face face) final;

/// @copydoc CylinderPortalShell::portalPtr
std::shared_ptr<Portal> portalPtr(Face face) final;

/// @copydoc CylinderPortalShell::setPortal
void setPortal(std::shared_ptr<Portal> portal, Face face) final;

void applyToVolume() override {
// No-op, because it's a composite portal shell
}

/// @copydoc PortalShellBase::isValid
bool isValid() const override;

/// @copydoc PortalShellBase::label
std::string label() const override;

private:
AxisDirection m_direction;
std::vector<CylinderPortalShell*> m_shells;
bool m_hasInnerCylinder{true};
};

} // namespace Acts
ssdetlab marked this conversation as resolved.
Show resolved Hide resolved
Loading
Loading