File indexing completed on 2025-01-18 09:11:18
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::AxisDirection::AxisX &&
0039 m_cfg.binning != Acts::AxisDirection::AxisY &&
0040 m_cfg.binning != Acts::AxisDirection::AxisZ) {
0041 throw std::invalid_argument(
0042 "CuboidalContainerBuilder: Invalid binning value. Only "
0043 "Acts::AxisDirection::AxisX, "
0044 "Acts::AxisDirection::AxisY, Acts::AxisDirection::AxisZ are "
0045 "supported.");
0046 }
0047 }
0048
0049 Acts::Experimental::CuboidalContainerBuilder::CuboidalContainerBuilder(
0050 const Acts::Experimental::Blueprint::Node& bpNode,
0051 Acts::Logging::Level logLevel)
0052 : IDetectorComponentBuilder(),
0053 m_logger(getDefaultLogger(bpNode.name + "_cont", logLevel)) {
0054 if (bpNode.boundsType != VolumeBounds::BoundsType::eCuboid) {
0055 throw std::invalid_argument(
0056 "CuboidalContainerBuilder: boundary type must be cuboid - for "
0057 "building from a blueprint node.");
0058 }
0059
0060 std::vector<std::shared_ptr<const IDetectorComponentBuilder>> builders;
0061 for (const auto& child : bpNode.children) {
0062 if (child->isLeaf()) {
0063
0064 VolumeStructureBuilder::Config vsCfg;
0065 vsCfg.transform = child->transform;
0066 vsCfg.boundsType = child->boundsType;
0067 vsCfg.boundValues = child->boundaryValues;
0068 vsCfg.auxiliary = "*** acts auto-generated shape builder ***";
0069 auto vsBuilder = std::make_shared<VolumeStructureBuilder>(
0070 vsCfg, getDefaultLogger(child->name + "_shape", logLevel));
0071
0072 DetectorVolumeBuilder::Config dvCfg;
0073 dvCfg.name = child->name;
0074 dvCfg.externalsBuilder = vsBuilder;
0075 dvCfg.internalsBuilder = child->internalsBuilder;
0076 dvCfg.auxiliary = "*** acts auto-generated volume builder ***";
0077
0078 m_cfg.builders.push_back(std::make_shared<DetectorVolumeBuilder>(
0079 dvCfg, getDefaultLogger(child->name, logLevel)));
0080 } else {
0081
0082 m_cfg.builders.push_back(
0083 std::make_shared<CuboidalContainerBuilder>(*child, logLevel));
0084 }
0085 }
0086
0087 if (m_cfg.builders.empty()) {
0088 throw std::invalid_argument(
0089 "CuboidalContainerBuilder: no sub builders provided.");
0090 }
0091 if (bpNode.binning.size() != 1) {
0092 throw std::invalid_argument(
0093 "CuboidalContainerBuilder: >1D binning is not supported for cuboid "
0094 "containers.");
0095 }
0096 m_cfg.binning = bpNode.binning.at(0);
0097
0098 if (m_cfg.binning != Acts::AxisDirection::AxisX &&
0099 m_cfg.binning != Acts::AxisDirection::AxisY &&
0100 m_cfg.binning != Acts::AxisDirection::AxisZ) {
0101 throw std::invalid_argument(
0102 "CuboidalContainerBuilder: Invalid binning value. Only "
0103 "Acts::AxisDirection::AxisX, "
0104 "Acts::AxisDirection::AxisY, Acts::AxisDirection::AxisZ are "
0105 "supported.");
0106 }
0107
0108 m_cfg.auxiliary = "*** acts auto-generated from proxy ***";
0109 m_cfg.geoIdGenerator = bpNode.geoIdGenerator;
0110 m_cfg.rootVolumeFinderBuilder = bpNode.rootVolumeFinderBuilder;
0111 }
0112
0113 Acts::Experimental::DetectorComponent
0114 Acts::Experimental::CuboidalContainerBuilder::construct(
0115 const GeometryContext& gctx) const {
0116
0117 DetectorComponent::PortalContainer rContainer;
0118 bool atNavigationLevel = true;
0119
0120
0121 std::vector<DetectorComponent> components;
0122 ACTS_DEBUG("Building container from " << m_cfg.builders.size()
0123 << " components.");
0124
0125
0126
0127 std::vector<std::shared_ptr<DetectorVolume>> volumes;
0128 std::vector<DetectorComponent::PortalContainer> containers;
0129 std::vector<std::shared_ptr<DetectorVolume>> rootVolumes;
0130
0131 std::for_each(
0132 m_cfg.builders.begin(), m_cfg.builders.end(), [&](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::for_each(rootVolumes.rbegin(), rootVolumes.rend(), [&](auto& v) {
0165 m_cfg.geoIdGenerator->assignGeometryId(cache, *v);
0166 ACTS_VERBOSE("-> Assigning geometry id to volume " << v->name());
0167 });
0168 } else {
0169 std::for_each(rootVolumes.begin(), rootVolumes.end(), [&](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 }