-
Notifications
You must be signed in to change notification settings - Fork 157
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: introduce external volume structure builder (#2148)
After the inclusion of the - `LayerStructureBuilder` which builds intrinsic layer structures of `DetectorVolume` objects - `CylindricalContainerBuilder` which connects cylindrical `DetectorVolume` objects this adds the last missing piece for describing cylindrical detector geometries: - `VolumeStructurBuilder` which helps to define the external volume structure of a `DetectorVolume`. To harmonise this accordingly, the `GenericCuboidBounds` are slightly adapted in order to have the same look and feel as all the other `VolumeBounds` derivates.
- Loading branch information
1 parent
1074d34
commit f8d0446
Showing
11 changed files
with
656 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
// 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/Detector/DetectorComponents.hpp" | ||
#include "Acts/Detector/interface/IExternalStructureBuilder.hpp" | ||
#include "Acts/Geometry/Extent.hpp" | ||
#include "Acts/Geometry/GeometryContext.hpp" | ||
#include "Acts/Geometry/VolumeBounds.hpp" | ||
#include "Acts/Utilities/Logger.hpp" | ||
|
||
#include <optional> | ||
|
||
namespace Acts { | ||
namespace Experimental { | ||
|
||
/// This class provides the external detector volume structure, configured | ||
/// either from: | ||
/// - a volume extent | ||
/// - from an array with volume bounds identification | ||
/// | ||
class VolumeStructureBuilder : public IExternalStructureBuilder { | ||
public: | ||
/// Nexted configuration struct | ||
struct Config { | ||
/// A defined volume bound type | ||
VolumeBounds::BoundsType boundsType = VolumeBounds::BoundsType::eOther; | ||
/// The values (if already defined) | ||
std::vector<ActsScalar> boundValues = {}; | ||
/// The optional extent to feed into the values | ||
std::optional<Extent> extent = std::nullopt; | ||
}; | ||
|
||
/// Constructor | ||
/// | ||
/// @param cfg is the configuration struct | ||
/// @param logger logging instance for screen output | ||
VolumeStructureBuilder(const Config& cfg, | ||
std::unique_ptr<const Logger> logger = | ||
getDefaultLogger("VolumeStructureBuilder", | ||
Logging::INFO)); | ||
|
||
/// The interface definition for internal structure creation | ||
/// | ||
/// @param gctx the geometry context at the creation of the internal structure | ||
/// | ||
/// @return a consistent set of detector volume internals | ||
ExternalStructure construct(const GeometryContext& gctx) const final; | ||
|
||
private: | ||
/// configuration object | ||
Config m_cfg; | ||
|
||
/// Private access method to the logger | ||
const Logger& logger() const { return *m_logger; } | ||
|
||
/// logging instance | ||
std::unique_ptr<const Logger> m_logger; | ||
}; | ||
|
||
} // namespace Experimental | ||
} // namespace Acts |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,4 +12,5 @@ target_sources( | |
Portal.cpp | ||
PortalGenerators.cpp | ||
ProtoDetector.cpp | ||
VolumeStructureBuilder.cpp | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,176 @@ | ||
// 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/. | ||
|
||
#include "Acts/Detector/VolumeStructureBuilder.hpp" | ||
|
||
#include "Acts/Detector/PortalGenerators.hpp" | ||
#include "Acts/Geometry/ConeVolumeBounds.hpp" | ||
#include "Acts/Geometry/CuboidVolumeBounds.hpp" | ||
#include "Acts/Geometry/CutoutCylinderVolumeBounds.hpp" | ||
#include "Acts/Geometry/CylinderVolumeBounds.hpp" | ||
#include "Acts/Geometry/GenericCuboidVolumeBounds.hpp" | ||
#include "Acts/Geometry/TrapezoidVolumeBounds.hpp" | ||
#include "Acts/Utilities/Enumerate.hpp" | ||
#include "Acts/Utilities/Helpers.hpp" | ||
|
||
Acts::Experimental::VolumeStructureBuilder::VolumeStructureBuilder( | ||
const Acts::Experimental::VolumeStructureBuilder::Config& cfg, | ||
std::unique_ptr<const Acts::Logger> logger) | ||
: IExternalStructureBuilder(), m_cfg(cfg), m_logger(std::move(logger)) { | ||
// Sanity cross-checks | ||
if (m_cfg.boundValues.empty() and not m_cfg.extent.has_value()) { | ||
throw std::invalid_argument( | ||
"VolumeStructureBuilder: no extent nor boundary values given"); | ||
} | ||
// Check for the bounds type | ||
if (m_cfg.boundsType == VolumeBounds::BoundsType::eOther) { | ||
throw std::invalid_argument( | ||
"VolumeStructureBuilder: no known volume bounds type provided."); | ||
} | ||
} | ||
|
||
Acts::Experimental::ExternalStructure | ||
Acts::Experimental::VolumeStructureBuilder::construct( | ||
[[maybe_unused]] const Acts::GeometryContext& gctx) const { | ||
// The volume bounds to be constructed | ||
std::unique_ptr<VolumeBounds> volumeBounds = nullptr; | ||
|
||
// The transform of the volume, default: identity | ||
auto transform = Transform3::Identity(); | ||
std::vector<ActsScalar> boundValues = m_cfg.boundValues; | ||
|
||
// This code dispatches into the dedicated volume types | ||
switch (m_cfg.boundsType) { | ||
case VolumeBounds::BoundsType::eCone: { | ||
ACTS_VERBOSE("Building conical volume bounds."); | ||
// Cone translation - only pre-defined values | ||
if (boundValues.size() < 5u) { | ||
throw std::runtime_error( | ||
"VolumeStructureBuilder: parameters for cone volume bounds need to " | ||
"be fully provided, they can not be estimated from an Extent " | ||
"object. It needs at least 5 parameters, while " + | ||
std::to_string(boundValues.size()) + " where given"); | ||
} | ||
auto bArray = to_array<ConeVolumeBounds::BoundValues::eSize, ActsScalar>( | ||
boundValues); | ||
volumeBounds = std::make_unique<ConeVolumeBounds>(bArray); | ||
} break; | ||
case VolumeBounds::BoundsType::eCuboid: { | ||
ACTS_VERBOSE("Building cuboid volume bounds."); | ||
// Cuboid translation - either parameters / or extent | ||
if (boundValues.empty() and m_cfg.extent.has_value()) { | ||
ACTS_VERBOSE("Cuboid: estimate parameters from Extent."); | ||
const auto& vExtent = m_cfg.extent.value(); | ||
if (vExtent.constrains(binX) and vExtent.constrains(binY) and | ||
vExtent.constrains(binZ)) { | ||
transform.pretranslate(Vector3(vExtent.medium(binX), | ||
vExtent.medium(binY), | ||
vExtent.medium(binZ))); | ||
boundValues = {0.5 * vExtent.interval(binX), | ||
0.5 * vExtent.interval(binY), | ||
0.5 * vExtent.interval(binZ)}; | ||
|
||
} else { | ||
throw std::runtime_error( | ||
"VolumeStructureBuilder: translation to cuboid does not work as " | ||
"the extent does not constrain all necessary value."); | ||
} | ||
} else if (boundValues.size() < 3u) { | ||
throw std::runtime_error( | ||
"VolumeStructureBuilder: parameters for cuboid volume bounds need " | ||
"to be fully provided, it needs exaclty 3 parameters, while " + | ||
std::to_string(boundValues.size()) + " where given"); | ||
} | ||
auto bArray = | ||
to_array<CuboidVolumeBounds::BoundValues::eSize>(boundValues); | ||
volumeBounds = std::make_unique<CuboidVolumeBounds>(bArray); | ||
} break; | ||
case VolumeBounds::BoundsType::eCutoutCylinder: { | ||
ACTS_VERBOSE("Building cutout cylindrical volume bounds."); | ||
// Cutout cylinder translation - only parameters | ||
if (boundValues.size() < 5u) { | ||
throw std::runtime_error( | ||
"VolumeStructureBuilder: parameters for cutout cylinder volume " | ||
"bounds need to be fully provided, they can not be estimated from " | ||
"an Extent object. It needs exaclty 3 parameters, while " + | ||
std::to_string(boundValues.size()) + " where given"); | ||
} | ||
auto bArray = | ||
to_array<CutoutCylinderVolumeBounds::BoundValues::eSize>(boundValues); | ||
volumeBounds = std::make_unique<CutoutCylinderVolumeBounds>(bArray); | ||
} break; | ||
case VolumeBounds::BoundsType::eCylinder: { | ||
ACTS_VERBOSE("Building cylindrical volume bounds."); | ||
// Cylinder translation - either parameters / or extent | ||
if (boundValues.empty() and m_cfg.extent.has_value()) { | ||
ACTS_VERBOSE("Cylinder: estimate parameters from Extent."); | ||
const auto& vExtent = m_cfg.extent.value(); | ||
if (vExtent.constrains(binR) and vExtent.constrains(binZ)) { | ||
transform.pretranslate(Vector3(0., 0., vExtent.medium(binZ))); | ||
boundValues = {vExtent.min(binR), vExtent.max(binR), | ||
0.5 * vExtent.interval(binZ)}; | ||
if (vExtent.constrains(binPhi)) { | ||
boundValues.push_back(0.5 * vExtent.interval(binPhi)); | ||
boundValues.push_back(vExtent.medium(binPhi)); | ||
} | ||
} else { | ||
throw std::runtime_error( | ||
"VolumeStructureBuilder: translation to cuboid does not work as " | ||
"the extent does not constrain all necessary values."); | ||
} | ||
} else if (boundValues.size() < 3u) { | ||
throw std::runtime_error( | ||
"VolumeStructureBuilder: parameters for cylinder volume " | ||
"bounds need to be fully provided, it needs at least 3 parameters, " | ||
"while " + | ||
std::to_string(boundValues.size()) + " where given"); | ||
} | ||
// Check if phi has been constraint, otherwise fill it with full coverage | ||
if (boundValues.size() == 3u) { | ||
boundValues.push_back(M_PI); | ||
boundValues.push_back(0.); | ||
} | ||
auto bArray = | ||
to_array<CylinderVolumeBounds::BoundValues::eSize>(boundValues); | ||
volumeBounds = std::make_unique<CylinderVolumeBounds>(bArray); | ||
} break; | ||
case VolumeBounds::BoundsType::eGenericCuboid: { | ||
ACTS_VERBOSE("Building generic cuboid volume bounds."); | ||
// Generic cuboid translation - parameters only | ||
if (boundValues.size() < GenericCuboidVolumeBounds::BoundValues::eSize) { | ||
throw std::runtime_error( | ||
"VolumeStructureBuilder: parameters for generic cuboid volume " | ||
"bounds need to be provided, they can not be estimated from an " | ||
"Extent object. It needs exactly 24 parameters, while " + | ||
std::to_string(boundValues.size()) + " where given"); | ||
} | ||
auto bArray = | ||
to_array<GenericCuboidVolumeBounds::BoundValues::eSize>(boundValues); | ||
volumeBounds = std::make_unique<GenericCuboidVolumeBounds>(bArray); | ||
} break; | ||
case VolumeBounds::BoundsType::eTrapezoid: { | ||
ACTS_VERBOSE("Building trapezoid volume bounds."); | ||
// Trapezoid translation - parameters only | ||
if (boundValues.size() < 4u) { | ||
throw std::runtime_error( | ||
"VolumeStructureBuilder: parameters for trapezoid volume bounds " | ||
"need to be provided, they can not be estimated from an Extent " | ||
"object. It needs at least 4 parameters, while " + | ||
std::to_string(boundValues.size()) + " where given"); | ||
} | ||
auto bArray = | ||
to_array<TrapezoidVolumeBounds::BoundValues::eSize>(boundValues); | ||
volumeBounds = std::make_unique<TrapezoidVolumeBounds>(bArray); | ||
} break; | ||
default: | ||
break; | ||
} | ||
// Return the transform, the volume bounds, and some default portal | ||
// generators | ||
return {transform, std::move(volumeBounds), defaultPortalGenerator()}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.