Back to home page

EIC code displayed by LXR

 
 

    


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

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/detail/PortalHelper.hpp"
0010 
0011 #include "Acts/Detector/Portal.hpp"
0012 #include "Acts/Navigation/NavigationDelegates.hpp"
0013 #include "Acts/Navigation/PortalNavigation.hpp"
0014 #include "Acts/Surfaces/Surface.hpp"
0015 #include "Acts/Utilities/Helpers.hpp"
0016 
0017 #include <array>
0018 #include <stdexcept>
0019 #include <utility>
0020 
0021 void Acts::Experimental::detail::PortalHelper::attachExternalNavigationDelegate(
0022     Portal& portal, const std::shared_ptr<DetectorVolume>& volume,
0023     const Direction& direction) {
0024   // Create a shared link instance & delegate
0025   auto volumeLinkImpl = std::make_unique<
0026       const Acts::Experimental::SingleDetectorVolumeNavigation>(volume.get());
0027   Acts::Experimental::ExternalNavigationDelegate volumeLink;
0028   volumeLink
0029       .connect<&Acts::Experimental::SingleDetectorVolumeNavigation::update>(
0030           std::move(volumeLinkImpl));
0031   // Update the volume link and the store
0032   portal.assignPortalNavigation(direction, std::move(volumeLink), {volume});
0033 }
0034 
0035 void Acts::Experimental::detail::PortalHelper::attachDetectorVolumesUpdater(
0036     const GeometryContext& gctx, Portal& portal,
0037     const std::vector<std::shared_ptr<DetectorVolume>>& volumes,
0038     const Direction& direction, const std::vector<double>& boundaries,
0039     const AxisDirection& binning) {
0040   // Check if the boundaries need a transform
0041   const auto pTransform = portal.surface().transform(gctx);
0042   // Creating a link to the mother
0043   auto volumes1D = std::make_unique<const BoundVolumesGrid1Navigation>(
0044       boundaries, binning, unpack_shared_const_vector(volumes),
0045       pTransform.inverse());
0046   ExternalNavigationDelegate dVolumeUpdater;
0047   dVolumeUpdater.connect<&BoundVolumesGrid1Navigation::update>(
0048       std::move(volumes1D));
0049   portal.assignPortalNavigation(direction, std::move(dVolumeUpdater), volumes);
0050 }
0051 
0052 void Acts::Experimental::detail::PortalHelper::
0053     attachExternalNavigationDelegates(
0054         const GeometryContext& gctx,
0055         const std::vector<std::shared_ptr<DetectorVolume>>& volumes,
0056         std::vector<PortalReplacement>& pReplacements) {
0057   // Unpack to navigation bare points
0058   auto cVolumes = unpack_shared_const_vector(volumes);
0059   // Set to the constructed portals (p), at index (i), in direction (d)
0060   // using boundaries and binning
0061   for (auto& [p, i, dir, boundaries, binning] : pReplacements) {
0062     // Check if the boundaries need a transform
0063     const auto pTransform = p->surface().transform(gctx);
0064     // Creating a link to the mother
0065     auto volumes1D = std::make_unique<const BoundVolumesGrid1Navigation>(
0066         boundaries, binning, cVolumes, pTransform.inverse());
0067     ExternalNavigationDelegate dVolumeUpdater;
0068     dVolumeUpdater.connect<&BoundVolumesGrid1Navigation::update>(
0069         std::move(volumes1D));
0070     p->assignPortalNavigation(dir, std::move(dVolumeUpdater), volumes);
0071   }
0072 }
0073 
0074 std::vector<std::shared_ptr<Acts::Experimental::DetectorVolume>>
0075 Acts::Experimental::detail::PortalHelper::attachedDetectorVolumes(
0076     Portal& portal) noexcept(false) {
0077   auto& attachedVolumes = portal.attachedDetectorVolumes();
0078   if (!attachedVolumes[0u].empty() && !attachedVolumes[1u].empty()) {
0079     throw std::invalid_argument(
0080         "PortalHelper: trying to get attachedVolumes from already populated "
0081         "portal.");
0082   }
0083   unsigned int iu = attachedVolumes[0u].empty() ? 1u : 0u;
0084   return attachedVolumes[iu];
0085 }
0086 
0087 std::map<unsigned int,
0088          std::vector<std::shared_ptr<Acts::Experimental::DetectorVolume>>>
0089 Acts::Experimental::detail::PortalHelper::stripSideVolumes(
0090     const std::vector<std::map<unsigned int, std::shared_ptr<Portal>>>&
0091         pContainers,
0092     const std::vector<unsigned int>& sides,
0093     const std::vector<unsigned int>& selectedOnly,
0094     Acts::Logging::Level logLevel) {
0095   ACTS_LOCAL_LOGGER(Acts::getDefaultLogger("::stripSideVolumes", logLevel));
0096 
0097   // These are the stripped off outside volumes
0098   std::map<unsigned int,
0099            std::vector<std::shared_ptr<Acts::Experimental::DetectorVolume>>>
0100       sideVolumes;
0101 
0102   // Principle sides and selected sides, make an intersection
0103   std::vector<unsigned int> selectedSides;
0104   if (!selectedOnly.empty()) {
0105     std::set_intersection(sides.begin(), sides.end(), selectedOnly.begin(),
0106                           selectedOnly.end(),
0107                           std::back_inserter(selectedSides));
0108   } else {
0109     selectedSides = sides;
0110   }
0111 
0112   // Loop through the containers
0113   for (const auto& pc : pContainers) {
0114     // Loop through the selected sides and check if they are contained
0115     for (const auto& s : selectedSides) {
0116       auto cSide = pc.find(s);
0117       if (cSide != pc.end()) {
0118         auto p = cSide->second;
0119         auto& sVolumes = sideVolumes[s];
0120         auto aVolumes =
0121             Acts::Experimental::detail::PortalHelper::attachedDetectorVolumes(
0122                 *p);
0123         sVolumes.insert(sVolumes.end(), aVolumes.begin(), aVolumes.end());
0124       }
0125     }
0126   }
0127   // return them
0128   return sideVolumes;
0129 }