Skip to content

Commit

Permalink
feat: add helper and fusing infrastructure for cuboidal detectors (ac…
Browse files Browse the repository at this point in the history
…ts-project#2754)

This PR adds a new

`detail/CuboidalDetectorHelper.h/cpp`

for creating cuboid shape detectors.

Since it reuses some code from the cylindrical infrastructure, this is encapsulated into sub helpers to not be duplicated.


![CuboidalDetector00](https://github.com/acts-project/acts/assets/26623879/19fc7cb9-7189-4535-ada9-aa2fef33f7d4)

Blocked by:
- acts-project#2753 (merged)

This relaxes the Portal fusing to allow for two portals with same direction filled to be fused (necessary for box-2-box)
  • Loading branch information
asalzburger authored and LaraCalic committed Feb 10, 2024
1 parent cf0ad59 commit 4487c7c
Show file tree
Hide file tree
Showing 13 changed files with 1,035 additions and 126 deletions.
87 changes: 87 additions & 0 deletions Core/include/Acts/Detector/detail/CuboidalDetectorHelper.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// This file is part of the Acts project.
//
// Copyright (C) 2023 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 http://mozilla.org/MPL/2.0/.

#pragma once

#include "Acts/Definitions/Algebra.hpp"
#include "Acts/Definitions/Common.hpp"
#include "Acts/Detector/DetectorComponents.hpp"
#include "Acts/Detector/Portal.hpp"
#include "Acts/Geometry/GeometryContext.hpp"
#include "Acts/Utilities/BinningData.hpp"
#include "Acts/Utilities/Logger.hpp"

#include <array>
#include <limits>
#include <map>
#include <memory>
#include <vector>

namespace Acts {

namespace Experimental {

class DetectorVolume;
class Portal;

namespace detail {
namespace CuboidalDetectorHelper {

/// @brief Connect detector volumes given a binning value
///
/// @param gctx The geometry context
/// @param volumes the volumes
/// @param bValue the binning value (allowed are binX, binY, binZ)
/// @param selectedOnly switch only selected boundaries
/// @param logLevel is the screen logging level
///
/// @note a fair amount of consistency checking is done,
/// and exceptions are thrown if any of the tests fail
///
/// @return a proto container with the outside portals
DetectorComponent::PortalContainer connect(
const GeometryContext& gctx,
std::vector<std::shared_ptr<DetectorVolume>>& volumes, BinningValue bValue,
const std::vector<unsigned int>& selectedOnly = {},
Acts::Logging::Level logLevel = Acts::Logging::INFO);

/// @brief Connect containers given a binning value
///
/// @param gctx The geometry context
/// @param containers the containers
/// @param bValue the binning value (allowed are binX, binY, binZ)
/// @param selectedOnly switch only selected boundaries
/// @param logLevel is the screen logging level
///
/// @note not much checking is done anymore, as the DetectorComponent::PortalContainer
/// are assumed to come properly formed from the prior methods
///
/// @return a proto container with the outside portals
DetectorComponent::PortalContainer connect(
const GeometryContext& gctx,
const std::vector<DetectorComponent::PortalContainer>& containers,
BinningValue bValue, const std::vector<unsigned int>& selectedOnly = {},
Acts::Logging::Level logLevel = Acts::Logging::INFO);

/// @brief Helper method to extract r,z,phi boundaries for
/// eventual grid volume search
///
/// @param gctx the geometry context of the call
/// @param volumes the volumes at input
/// @param logLevel is the screen logging level
///
/// @return extracted boundary values
std::array<std::vector<ActsScalar>, 3u> xyzBoundaries(
const GeometryContext& gctx,
const std::vector<const DetectorVolume*>& volumes,
Acts::Logging::Level logLevel = Acts::Logging::INFO);

} // namespace CuboidalDetectorHelper
} // namespace detail
} // namespace Experimental
} // namespace Acts
58 changes: 58 additions & 0 deletions Core/include/Acts/Detector/detail/DetectorVolumeConsistency.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// This file is part of the Acts project.
//
// Copyright (C) 2023 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 http://mozilla.org/MPL/2.0/.

#pragma once

#include "Acts/Definitions/Common.hpp"
#include "Acts/Geometry/GeometryContext.hpp"
#include "Acts/Utilities/BinningData.hpp"

#include <memory>
#include <vector>

namespace Acts {
namespace Experimental {

class DetectorVolume;

namespace detail {
namespace DetectorVolumeConsistency {

/// @brief Helper method to check alignment of the volumes, this method checks
/// if the rotational part of the transform is identical
///
/// @param gctx the geometry context
/// @param volumes the input volumes to be checked
///
/// @note this is a strict matching that requires the rotation to be identical
///
/// @note throws exception if any of checks fails
void checkRotationAlignment(
const GeometryContext& gctx,
const std::vector<std::shared_ptr<Experimental::DetectorVolume>>& volumes);

/// @brief Helper method to check whether a set of volumes is lined up on
/// a given common axis definition
///
/// @param gctx the geometry context
/// @param volumes the input volumes to be checked
/// @param axisValue the alignment axist
///
/// @note this will call checkRotationAlignment first
/// @note throws exception if the volumes are not ordered
///
/// @return a vector with position differences (ordered)
std::vector<ActsScalar> checkCenterAlignment(
const GeometryContext& gctx,
const std::vector<std::shared_ptr<Experimental::DetectorVolume>>& volumes,
BinningValue axisValue);

} // namespace DetectorVolumeConsistency
} // namespace detail
} // namespace Experimental
} // namespace Acts
19 changes: 19 additions & 0 deletions Core/include/Acts/Detector/detail/PortalHelper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "Acts/Geometry/GeometryContext.hpp"
#include "Acts/Utilities/BinningType.hpp"

#include <map>
#include <memory>
#include <tuple>
#include <vector>
Expand Down Expand Up @@ -89,6 +90,24 @@ void attachDetectorVolumeUpdaters(
std::vector<std::shared_ptr<DetectorVolume>> attachedDetectorVolumes(
Portal& portal) noexcept(false);

/// @brief Method that strips out attached volumes from portals and
/// provides them back to the caller.
///
/// @param pContainers the portal containers to be resolved
/// @param sides the sides to be handled
/// @param selectedOnly the selected only volumes, e.g. for complex containers
/// to chose only outside skins,
/// @param logLevel the logging level
///
std::map<unsigned int,
std::vector<std::shared_ptr<Acts::Experimental::DetectorVolume>>>
stripSideVolumes(
const std::vector<std::map<unsigned int, std::shared_ptr<Portal>>>&
pContainers,
const std::vector<unsigned int>& sides,
const std::vector<unsigned int>& selectedOnly = {},
Acts::Logging::Level logLevel = Acts::Logging::INFO);

} // namespace PortalHelper
} // namespace detail
} // namespace Experimental
Expand Down
2 changes: 2 additions & 0 deletions Core/src/Detector/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ target_sources(
PRIVATE
detail/BlueprintHelper.cpp
detail/BlueprintDrawer.cpp
detail/CuboidalDetectorHelper.cpp
detail/CylindricalDetectorHelper.cpp
detail/DetectorVolumeConsistency.cpp
detail/PortalHelper.cpp
detail/ProtoMaterialHelper.cpp
detail/SupportHelper.cpp
Expand Down
46 changes: 26 additions & 20 deletions Core/src/Detector/Portal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,47 +69,53 @@ std::shared_ptr<Portal> Portal::fuse(std::shared_ptr<Portal>& aPortal,

if (noneConnected(*aPortal) || noneConnected(*bPortal)) {
throw std::invalid_argument(
"Portal: trying to fuse two portals where at least on has no links.");
"Portal: trying to fuse two portals where at least one has no links.");
}

// We checked they're not both empty, so one of them must be connected
Direction aDir = (aPortal->m_volumeUpdaters[0].connected())
// @TODO: There's no safety against fusing portals with different surfaces
// We model the fused portal after the aPortal
std::shared_ptr<Portal> fused = std::make_shared<Portal>(aPortal->m_surface);

// Get the connection directions
Direction getA = (aPortal->m_volumeUpdaters[0].connected())
? Direction::fromIndex(0)
: Direction::fromIndex(1);
Direction getB = (bPortal->m_volumeUpdaters[0].connected())
? Direction::fromIndex(0)
: Direction::fromIndex(1);
Direction bDir = aDir.invert();

// And now check other direction
if (!bPortal->m_volumeUpdaters[bDir.index()].connected()) {
throw std::runtime_error(
"Portal: trying to fuse portal (discard) with no links.");
}
// Modelling the fused portal after the aPortal, leaves B as inverted
Direction setA = getA;
Direction setB = setA.invert();

// Check if material is associated
const auto& aSurface = aPortal->surface();
const auto& bSurface = bPortal->surface();

// @TODO: There's no safety against fusing portals with different surfaces
std::shared_ptr<Portal> fused = std::make_shared<Portal>(aPortal->m_surface);

if (aSurface.surfaceMaterial() != nullptr &&
bSurface.surfaceMaterial() != nullptr) {
throw std::runtime_error(
"Portal: both surfaces have surface material, fusing will lead to "
"information loss.");
} else if (aSurface.surfaceMaterial() != nullptr) {
// We keep the aPortal modelling
fused->m_surface = aPortal->m_surface;
} else if (bSurface.surfaceMaterial() != nullptr) {
fused->m_surface = bPortal->m_surface;
// Remodel after the bPortal
setB = getB;
setA = setB.invert();
}

fused->m_volumeUpdaters[aDir.index()] =
std::move(aPortal->m_volumeUpdaters[aDir.index()]);
fused->m_attachedVolumes[aDir.index()] =
std::move(aPortal->m_attachedVolumes[aDir.index()]);
fused->m_volumeUpdaters[setA.index()] =
std::move(aPortal->m_volumeUpdaters[getA.index()]);
fused->m_attachedVolumes[setA.index()] =
std::move(aPortal->m_attachedVolumes[getA.index()]);

fused->m_volumeUpdaters[bDir.index()] =
std::move(bPortal->m_volumeUpdaters[bDir.index()]);
fused->m_attachedVolumes[bDir.index()] =
std::move(bPortal->m_attachedVolumes[bDir.index()]);
fused->m_volumeUpdaters[setB.index()] =
std::move(bPortal->m_volumeUpdaters[getB.index()]);
fused->m_attachedVolumes[setB.index()] =
std::move(bPortal->m_attachedVolumes[getB.index()]);

return fused;
}
Expand Down
Loading

0 comments on commit 4487c7c

Please sign in to comment.