Back to home page

EIC code displayed by LXR

 
 

    


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 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 CERN for the benefit of the ACTS project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
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 }  // namespace Acts::Experimental
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   // Check if builders are present
0034   if (m_cfg.builders.empty()) {
0035     throw std::invalid_argument(
0036         "CuboidalContainerBuilder: no sub builders provided.");
0037   }
0038   // Check if binning value is correctly chosen
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       // Volume structure
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       // Detector volume builder
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       // Add the builder
0079       m_cfg.builders.push_back(std::make_shared<DetectorVolumeBuilder>(
0080           dvCfg, getDefaultLogger(child->name, logLevel)));
0081     } else {
0082       // This evokes the recursive stepping down the tree
0083       m_cfg.builders.push_back(
0084           std::make_shared<CuboidalContainerBuilder>(*child, logLevel));
0085     }
0086   }
0087   // Check if builders are present
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   // Check if binning value is correctly chosen
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   // Return container object
0118   DetectorComponent::PortalContainer rContainer;
0119   bool atNavigationLevel = true;
0120 
0121   // Create the indivudal components, collect for both outcomes
0122   std::vector<DetectorComponent> components;
0123   ACTS_DEBUG("Building container from " << m_cfg.builders.size()
0124                                         << " components.");
0125   // Check through the component volumes - if every builder only
0126   // built exactly one volume, you are at pure navigation level
0127   // Collect the volumes
0128   std::vector<std::shared_ptr<DetectorVolume>> volumes;
0129   std::vector<DetectorComponent::PortalContainer> containers;
0130   std::vector<std::shared_ptr<DetectorVolume>> rootVolumes;
0131   // Run through the builders
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     // Collect individual components, volumes, containers, roots
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   // Navigation level detected, connect volumes (cleaner and faster than
0143   // connect containers)
0144   if (atNavigationLevel) {
0145     ACTS_VERBOSE(
0146         "Component volumes are at navigation level: connecting volumes.");
0147     // Connect volumes
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     // Connect containers
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   // Geometry Id generation
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   // Check if a root volume finder is provided
0177   if (m_cfg.rootVolumeFinderBuilder) {
0178     // Return the container
0179     return Acts::Experimental::DetectorComponent{
0180         volumes, rContainer,
0181         RootDetectorVolumes{
0182             rootVolumes,
0183             m_cfg.rootVolumeFinderBuilder->construct(gctx, rootVolumes)}};
0184   }
0185 
0186   // Return the container
0187   return Acts::Experimental::DetectorComponent{
0188       volumes, rContainer, RootDetectorVolumes{rootVolumes, tryRootVolumes()}};
0189 }