File indexing completed on 2025-08-05 08:09:34
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 <stdexcept>
0022 #include <utility>
0023
0024 namespace Acts::Experimental {
0025 class DetectorVolume;
0026 }
0027
0028 Acts::Experimental::CuboidalContainerBuilder::CuboidalContainerBuilder(
0029 const Acts::Experimental::CuboidalContainerBuilder::Config& cfg,
0030 std::unique_ptr<const Acts::Logger> logger)
0031 : IDetectorComponentBuilder(), m_cfg(cfg), m_logger(std::move(logger)) {
0032
0033 if (m_cfg.builders.empty()) {
0034 throw std::invalid_argument(
0035 "CuboidalContainerBuilder: no sub builders provided.");
0036 }
0037
0038 if (m_cfg.binning != Acts::binX && m_cfg.binning != Acts::binY &&
0039 m_cfg.binning != Acts::binZ) {
0040 throw std::invalid_argument(
0041 "CuboidalContainerBuilder: Invalid binning value. Only Acts::binX, "
0042 "Acts::binY, Acts::binZ are supported.");
0043 }
0044 }
0045
0046 Acts::Experimental::CuboidalContainerBuilder::CuboidalContainerBuilder(
0047 const Acts::Experimental::Blueprint::Node& bpNode,
0048 Acts::Logging::Level logLevel)
0049 : IDetectorComponentBuilder(),
0050 m_logger(getDefaultLogger(bpNode.name + "_cont", logLevel)) {
0051 if (bpNode.boundsType != VolumeBounds::BoundsType::eCuboid) {
0052 throw std::invalid_argument(
0053 "CuboidalContainerBuilder: boundary type must be cuboid - for "
0054 "building from a blueprint node.");
0055 }
0056
0057 std::vector<std::shared_ptr<const IDetectorComponentBuilder>> builders;
0058 for (const auto& child : bpNode.children) {
0059 if (child->isLeaf()) {
0060
0061 VolumeStructureBuilder::Config vsCfg;
0062 vsCfg.transform = child->transform;
0063 vsCfg.boundsType = child->boundsType;
0064 vsCfg.boundValues = child->boundaryValues;
0065 vsCfg.auxiliary = "*** acts auto-generated shape builder ***";
0066 auto vsBuilder = std::make_shared<VolumeStructureBuilder>(
0067 vsCfg, getDefaultLogger(child->name + "_shape", logLevel));
0068
0069 DetectorVolumeBuilder::Config dvCfg;
0070 dvCfg.name = child->name;
0071 dvCfg.externalsBuilder = vsBuilder;
0072 dvCfg.internalsBuilder = child->internalsBuilder;
0073 dvCfg.auxiliary = "*** acts auto-generated volume builder ***";
0074
0075 m_cfg.builders.push_back(std::make_shared<DetectorVolumeBuilder>(
0076 dvCfg, getDefaultLogger(child->name, logLevel)));
0077 } else {
0078
0079 m_cfg.builders.push_back(
0080 std::make_shared<CuboidalContainerBuilder>(*child, logLevel));
0081 }
0082 }
0083
0084 if (m_cfg.builders.empty()) {
0085 throw std::invalid_argument(
0086 "CuboidalContainerBuilder: no sub builders provided.");
0087 }
0088 if (bpNode.binning.size() != 1) {
0089 throw std::invalid_argument(
0090 "CuboidalContainerBuilder: >1D binning is not supported for cuboid "
0091 "containers.");
0092 }
0093 m_cfg.binning = bpNode.binning.at(0);
0094
0095 if (m_cfg.binning != Acts::binX && m_cfg.binning != Acts::binY &&
0096 m_cfg.binning != Acts::binZ) {
0097 throw std::invalid_argument(
0098 "CuboidalContainerBuilder: Invalid binning value. Only Acts::binX, "
0099 "Acts::binY, Acts::binZ are supported.");
0100 }
0101
0102 m_cfg.auxiliary = "*** acts auto-generated from proxy ***";
0103 m_cfg.geoIdGenerator = bpNode.geoIdGenerator;
0104 m_cfg.rootVolumeFinderBuilder = bpNode.rootVolumeFinderBuilder;
0105 }
0106
0107 Acts::Experimental::DetectorComponent
0108 Acts::Experimental::CuboidalContainerBuilder::construct(
0109 const GeometryContext& gctx) const {
0110
0111 DetectorComponent::PortalContainer rContainer;
0112 bool atNavigationLevel = true;
0113
0114
0115 std::vector<DetectorComponent> components;
0116 ACTS_DEBUG("Building container from " << m_cfg.builders.size()
0117 << " components.");
0118
0119
0120
0121 std::vector<std::shared_ptr<DetectorVolume>> volumes;
0122 std::vector<DetectorComponent::PortalContainer> containers;
0123 std::vector<std::shared_ptr<DetectorVolume>> rootVolumes;
0124
0125 std::for_each(
0126 m_cfg.builders.begin(), m_cfg.builders.end(), [&](const auto& builder) {
0127 auto [cVolumes, cContainer, cRoots] = builder->construct(gctx);
0128 atNavigationLevel = (atNavigationLevel && cVolumes.size() == 1u);
0129 ACTS_VERBOSE("Number of volumes: " << cVolumes.size());
0130
0131 volumes.insert(volumes.end(), cVolumes.begin(), cVolumes.end());
0132 containers.push_back(cContainer);
0133 rootVolumes.insert(rootVolumes.end(), cRoots.volumes.begin(),
0134 cRoots.volumes.end());
0135 });
0136
0137
0138 if (atNavigationLevel) {
0139 ACTS_VERBOSE(
0140 "Component volumes are at navigation level: connecting volumes.");
0141
0142 rContainer = Acts::Experimental::detail::CuboidalDetectorHelper::connect(
0143 gctx, volumes, m_cfg.binning, {}, logger().level());
0144
0145 } else {
0146 ACTS_VERBOSE("Components contain sub containers: connect containers.");
0147
0148 rContainer = Acts::Experimental::detail::CuboidalDetectorHelper::connect(
0149 gctx, containers, m_cfg.binning, {}, logger().level());
0150 }
0151 ACTS_VERBOSE("Number of root volumes: " << rootVolumes.size());
0152
0153
0154 if (m_cfg.geoIdGenerator != nullptr) {
0155 ACTS_DEBUG("Assigning geometry ids to the detector");
0156 auto cache = m_cfg.geoIdGenerator->generateCache();
0157 if (m_cfg.geoIdReverseGen) {
0158 std::for_each(rootVolumes.rbegin(), rootVolumes.rend(), [&](auto& v) {
0159 m_cfg.geoIdGenerator->assignGeometryId(cache, *v);
0160 ACTS_VERBOSE("-> Assigning geometry id to volume " << v->name());
0161 });
0162 } else {
0163 std::for_each(rootVolumes.begin(), rootVolumes.end(), [&](auto& v) {
0164 m_cfg.geoIdGenerator->assignGeometryId(cache, *v);
0165 ACTS_VERBOSE("-> Assigning geometry id to volume " << v->name());
0166 });
0167 }
0168 }
0169
0170
0171 if (m_cfg.rootVolumeFinderBuilder) {
0172
0173 return Acts::Experimental::DetectorComponent{
0174 volumes, rContainer,
0175 RootDetectorVolumes{
0176 rootVolumes,
0177 m_cfg.rootVolumeFinderBuilder->construct(gctx, rootVolumes)}};
0178 }
0179
0180
0181 return Acts::Experimental::DetectorComponent{
0182 volumes, rContainer, RootDetectorVolumes{rootVolumes, tryRootVolumes()}};
0183 }