Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:11:18

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/DetectorVolumeBuilder.hpp"
0010 
0011 #include "Acts/Detector/DetectorVolume.hpp"
0012 #include "Acts/Detector/detail/ProtoMaterialHelper.hpp"
0013 #include "Acts/Detector/interface/IExternalStructureBuilder.hpp"
0014 #include "Acts/Detector/interface/IGeometryIdGenerator.hpp"
0015 #include "Acts/Detector/interface/IInternalStructureBuilder.hpp"
0016 #include "Acts/Geometry/VolumeBounds.hpp"
0017 #include "Acts/Navigation/DetectorVolumeFinders.hpp"
0018 #include "Acts/Navigation/InternalNavigation.hpp"
0019 #include "Acts/Utilities/Enumerate.hpp"
0020 
0021 #include <iterator>
0022 #include <map>
0023 #include <stdexcept>
0024 #include <utility>
0025 #include <vector>
0026 
0027 Acts::Experimental::DetectorVolumeBuilder::DetectorVolumeBuilder(
0028     const Acts::Experimental::DetectorVolumeBuilder::Config& cfg,
0029     std::unique_ptr<const Acts::Logger> mlogger)
0030     : IDetectorComponentBuilder(), m_cfg(cfg), m_logger(std::move(mlogger)) {
0031   if (m_cfg.externalsBuilder == nullptr) {
0032     throw std::invalid_argument(
0033         "DetectorVolumeBuilder: no external structure builder defined.");
0034   }
0035 }
0036 
0037 Acts::Experimental::DetectorComponent
0038 Acts::Experimental::DetectorVolumeBuilder::construct(
0039     const GeometryContext& gctx) const {
0040   // The outgoing root volumes
0041   std::vector<std::shared_ptr<DetectorVolume>> rootVolumes;
0042   // Screen printout of the auxiliary information
0043   if (!m_cfg.auxiliary.empty()) {
0044     ACTS_DEBUG(m_cfg.auxiliary);
0045   }
0046   ACTS_DEBUG("Building a volume with name '" << m_cfg.name << "'.");
0047 
0048   // Get transform and bounds from the volume
0049   auto [transform, bounds, portalGenerator] =
0050       m_cfg.externalsBuilder->construct(gctx);
0051 
0052   // Although only a single volume, describe it as a
0053   // container shell for further processing
0054   DetectorComponent::PortalContainer portalContainer;
0055   // The detector volume to be constructed
0056   std::shared_ptr<DetectorVolume> dVolume = nullptr;
0057   // If there are no internals, the volume is fully defined
0058   if (m_cfg.internalsBuilder == nullptr) {
0059     ACTS_VERBOSE("No internal structure present.");
0060     // Construct the DetectorVolume
0061     dVolume = DetectorVolumeFactory::construct(
0062         portalGenerator, gctx, m_cfg.name, transform, std::move(bounds),
0063         tryAllPortals());
0064   } else {
0065     // Internal structure is present
0066     ACTS_VERBOSE("Internal structure is being built.");
0067     auto [surfaces, volumes, surfacesUpdater, volumeUpdater] =
0068         m_cfg.internalsBuilder->construct(gctx);
0069 
0070     // Add the internally created volumes as root volumes
0071     if (m_cfg.addInternalsToRoot) {
0072       for (const auto& v : volumes) {
0073         rootVolumes.push_back(v);
0074       }
0075     }
0076     // Construct the DetectorVolume
0077     dVolume = DetectorVolumeFactory::construct(
0078         portalGenerator, gctx, m_cfg.name, transform, std::move(bounds),
0079         surfaces, volumes, std::move(volumeUpdater),
0080         std::move(surfacesUpdater));
0081   }
0082   // All portals are defined and build the current shell
0083   for (const auto& [ip, p] : enumerate(dVolume->portalPtrs())) {
0084     portalContainer[ip] = p;
0085   }
0086 
0087   // Assign the geometry ids if configured to do so
0088   if (m_cfg.geoIdGenerator != nullptr) {
0089     ACTS_DEBUG("Assigning geometry ids to the detector volume");
0090     auto cache = m_cfg.geoIdGenerator->generateCache();
0091     m_cfg.geoIdGenerator->assignGeometryId(cache, *dVolume);
0092   }
0093 
0094   // Assign the proto material if configured to do so
0095   for (const auto& [ip, bDescription] : m_cfg.portalMaterialBinning) {
0096     if (portalContainer.contains(ip)) {
0097       auto bd = detail::ProtoMaterialHelper::attachProtoMaterial(
0098           gctx, portalContainer[ip]->surface(), bDescription);
0099       ACTS_VERBOSE("-> Assigning proto material to portal " << ip << " with "
0100                                                             << bd.toString());
0101     }
0102   }
0103 
0104   // Add to the root volume collection if configured
0105   rootVolumes.push_back(dVolume);
0106   // The newly built volume is the single produced volume
0107   return Acts::Experimental::DetectorComponent{
0108       {dVolume},
0109       portalContainer,
0110       RootDetectorVolumes{rootVolumes, tryRootVolumes()}};
0111 }