Warning, file /acts/Core/src/Detector/CuboidalContainerBuilder.cpp was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "Acts/Detector/CuboidalContainerBuilder.hpp"
0010
0011 #include "Acts/Detector/DetectorComponents.hpp"
0012 #include "Acts/Detector/DetectorVolumeBuilder.hpp"
0013 #include "Acts/Detector/VolumeStructureBuilder.hpp"
0014 #include "Acts/Detector/detail/CuboidalDetectorHelper.hpp"
0015 #include "Acts/Detector/interface/IGeometryIdGenerator.hpp"
0016 #include "Acts/Detector/interface/IRootVolumeFinderBuilder.hpp"
0017 #include "Acts/Navigation/DetectorVolumeFinders.hpp"
0018
0019 #include <algorithm>
0020 #include <ostream>
0021 #include <ranges>
0022 #include <stdexcept>
0023 #include <utility>
0024
0025 namespace Acts::Experimental {
0026 class DetectorVolume;
0027 }
0028
0029 Acts::Experimental::CuboidalContainerBuilder::CuboidalContainerBuilder(
0030 const Acts::Experimental::CuboidalContainerBuilder::Config& cfg,
0031 std::unique_ptr<const Acts::Logger> logger)
0032 : IDetectorComponentBuilder(), m_cfg(cfg), m_logger(std::move(logger)) {
0033
0034 if (m_cfg.builders.empty()) {
0035 throw std::invalid_argument(
0036 "CuboidalContainerBuilder: no sub builders provided.");
0037 }
0038
0039 if (m_cfg.binning != Acts::AxisDirection::AxisX &&
0040 m_cfg.binning != Acts::AxisDirection::AxisY &&
0041 m_cfg.binning != Acts::AxisDirection::AxisZ) {
0042 throw std::invalid_argument(
0043 "CuboidalContainerBuilder: Invalid binning value. Only "
0044 "Acts::AxisDirection::AxisX, "
0045 "Acts::AxisDirection::AxisY, Acts::AxisDirection::AxisZ are "
0046 "supported.");
0047 }
0048 }
0049
0050 Acts::Experimental::CuboidalContainerBuilder::CuboidalContainerBuilder(
0051 const Acts::Experimental::Gen2Blueprint::Node& bpNode,
0052 Acts::Logging::Level logLevel)
0053 : IDetectorComponentBuilder(),
0054 m_logger(getDefaultLogger(bpNode.name + "_cont", logLevel)) {
0055 if (bpNode.boundsType != VolumeBounds::BoundsType::eCuboid) {
0056 throw std::invalid_argument(
0057 "CuboidalContainerBuilder: boundary type must be cuboid - for "
0058 "building from a blueprint node.");
0059 }
0060
0061 std::vector<std::shared_ptr<const IDetectorComponentBuilder>> builders;
0062 for (const auto& child : bpNode.children) {
0063 if (child->isLeaf()) {
0064
0065 VolumeStructureBuilder::Config vsCfg;
0066 vsCfg.transform = child->transform;
0067 vsCfg.boundsType = child->boundsType;
0068 vsCfg.boundValues = child->boundaryValues;
0069 vsCfg.auxiliary = "*** acts auto-generated shape builder ***";
0070 auto vsBuilder = std::make_shared<VolumeStructureBuilder>(
0071 vsCfg, getDefaultLogger(child->name + "_shape", logLevel));
0072
0073 DetectorVolumeBuilder::Config dvCfg;
0074 dvCfg.name = child->name;
0075 dvCfg.externalsBuilder = vsBuilder;
0076 dvCfg.internalsBuilder = child->internalsBuilder;
0077 dvCfg.auxiliary = "*** acts auto-generated volume builder ***";
0078
0079 m_cfg.builders.push_back(std::make_shared<DetectorVolumeBuilder>(
0080 dvCfg, getDefaultLogger(child->name, logLevel)));
0081 } else {
0082
0083 m_cfg.builders.push_back(
0084 std::make_shared<CuboidalContainerBuilder>(*child, logLevel));
0085 }
0086 }
0087
0088 if (m_cfg.builders.empty()) {
0089 throw std::invalid_argument(
0090 "CuboidalContainerBuilder: no sub builders provided.");
0091 }
0092 if (bpNode.binning.size() != 1) {
0093 throw std::invalid_argument(
0094 "CuboidalContainerBuilder: >1D binning is not supported for cuboid "
0095 "containers.");
0096 }
0097 m_cfg.binning = bpNode.binning.at(0);
0098
0099 if (m_cfg.binning != Acts::AxisDirection::AxisX &&
0100 m_cfg.binning != Acts::AxisDirection::AxisY &&
0101 m_cfg.binning != Acts::AxisDirection::AxisZ) {
0102 throw std::invalid_argument(
0103 "CuboidalContainerBuilder: Invalid binning value. Only "
0104 "Acts::AxisDirection::AxisX, "
0105 "Acts::AxisDirection::AxisY, Acts::AxisDirection::AxisZ are "
0106 "supported.");
0107 }
0108
0109 m_cfg.auxiliary = "*** acts auto-generated from proxy ***";
0110 m_cfg.geoIdGenerator = bpNode.geoIdGenerator;
0111 m_cfg.rootVolumeFinderBuilder = bpNode.rootVolumeFinderBuilder;
0112 }
0113
0114 Acts::Experimental::DetectorComponent
0115 Acts::Experimental::CuboidalContainerBuilder::construct(
0116 const GeometryContext& gctx) const {
0117
0118 DetectorComponent::PortalContainer rContainer;
0119 bool atNavigationLevel = true;
0120
0121
0122 std::vector<DetectorComponent> components;
0123 ACTS_DEBUG("Building container from " << m_cfg.builders.size()
0124 << " components.");
0125
0126
0127
0128 std::vector<std::shared_ptr<DetectorVolume>> volumes;
0129 std::vector<DetectorComponent::PortalContainer> containers;
0130 std::vector<std::shared_ptr<DetectorVolume>> rootVolumes;
0131
0132 std::ranges::for_each(m_cfg.builders, [&](const auto& builder) {
0133 auto [cVolumes, cContainer, cRoots] = builder->construct(gctx);
0134 atNavigationLevel = (atNavigationLevel && cVolumes.size() == 1u);
0135 ACTS_VERBOSE("Number of volumes: " << cVolumes.size());
0136
0137 volumes.insert(volumes.end(), cVolumes.begin(), cVolumes.end());
0138 containers.push_back(cContainer);
0139 rootVolumes.insert(rootVolumes.end(), cRoots.volumes.begin(),
0140 cRoots.volumes.end());
0141 });
0142
0143
0144 if (atNavigationLevel) {
0145 ACTS_VERBOSE(
0146 "Component volumes are at navigation level: connecting volumes.");
0147
0148 rContainer = Acts::Experimental::detail::CuboidalDetectorHelper::connect(
0149 gctx, volumes, m_cfg.binning, {}, logger().level());
0150
0151 } else {
0152 ACTS_VERBOSE("Components contain sub containers: connect containers.");
0153
0154 rContainer = Acts::Experimental::detail::CuboidalDetectorHelper::connect(
0155 gctx, containers, m_cfg.binning, {}, logger().level());
0156 }
0157 ACTS_VERBOSE("Number of root volumes: " << rootVolumes.size());
0158
0159
0160 if (m_cfg.geoIdGenerator != nullptr) {
0161 ACTS_DEBUG("Assigning geometry ids to the detector");
0162 auto cache = m_cfg.geoIdGenerator->generateCache();
0163 if (m_cfg.geoIdReverseGen) {
0164 std::ranges::for_each(rootVolumes, [&](auto& v) {
0165 m_cfg.geoIdGenerator->assignGeometryId(cache, *v);
0166 ACTS_VERBOSE("-> Assigning geometry id to volume " << v->name());
0167 });
0168 } else {
0169 std::ranges::for_each(rootVolumes, [&](auto& v) {
0170 m_cfg.geoIdGenerator->assignGeometryId(cache, *v);
0171 ACTS_VERBOSE("-> Assigning geometry id to volume " << v->name());
0172 });
0173 }
0174 }
0175
0176
0177 if (m_cfg.rootVolumeFinderBuilder) {
0178
0179 return Acts::Experimental::DetectorComponent{
0180 volumes, rContainer,
0181 RootDetectorVolumes{
0182 rootVolumes,
0183 m_cfg.rootVolumeFinderBuilder->construct(gctx, rootVolumes)}};
0184 }
0185
0186
0187 return Acts::Experimental::DetectorComponent{
0188 volumes, rContainer, RootDetectorVolumes{rootVolumes, tryRootVolumes()}};
0189 }