Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-06-21 08:08:59

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/Geometry/MultiWireVolumeBuilder.hpp"
0010 
0011 #include "Acts/Geometry/GeometryContext.hpp"
0012 #include "Acts/Geometry/NavigationPolicyFactory.hpp"
0013 #include "Acts/Geometry/TrapezoidPortalShell.hpp"
0014 #include "Acts/Geometry/TrapezoidVolumeBounds.hpp"
0015 #include "Acts/Navigation/InternalNavigation.hpp"
0016 #include "Acts/Navigation/MultiLayerNavigationPolicy.hpp"
0017 #include "Acts/Navigation/TryAllNavigationPolicy.hpp"
0018 #include "Acts/Surfaces/SurfaceArray.hpp"
0019 #include "Acts/Utilities/Helpers.hpp"
0020 #include "Acts/Utilities/StringHelpers.hpp"
0021 
0022 namespace Acts::Experimental {
0023 
0024 MultiWireVolumeBuilder::MultiWireVolumeBuilder(
0025     const Config& config, std::unique_ptr<const Logger> logger)
0026     : m_config(config), m_logger(std::move(logger)) {
0027   if (m_config.mlSurfaces.empty()) {
0028     throw std::invalid_argument(
0029         "MultiWireStructureBuilder: No surfaces are given");
0030   } else if (m_config.binning.size() != 2u) {
0031     throw ::std::invalid_argument(
0032         "MultiWireStructureBuilder: Invalid binning provided");
0033   }
0034 }
0035 
0036 std::unique_ptr<TrackingVolume> MultiWireVolumeBuilder::buildVolume(
0037     const GeometryContext& gctx) const {
0038   // Create the tracking volume
0039 
0040   ACTS_VERBOSE("Building a tracking volume with name "
0041                << m_config.name << " ,translation"
0042                << toString(m_config.transform.translation())
0043                << " and number of surfaces " << m_config.mlSurfaces.size());
0044 
0045   const auto& bounds =
0046       dynamic_pointer_cast<TrapezoidVolumeBounds>(m_config.bounds);
0047   if (bounds == nullptr) {
0048     throw std::runtime_error(
0049         "MultiWireVolumeBuilder: Invalid bounds - trapezoidal needed");
0050   }
0051 
0052   std::unique_ptr<TrackingVolume> trackingVolume =
0053       std::make_unique<TrackingVolume>(m_config.transform, bounds,
0054                                        m_config.name);
0055 
0056   SingleTrapezoidPortalShell portalShell(*trackingVolume);
0057   portalShell.applyToVolume();
0058 
0059   // Add the surfaces to the tracking volume
0060   for (auto& surface : m_config.mlSurfaces) {
0061     trackingVolume->addSurface(surface);
0062   }
0063 
0064   auto [protoAxisA, expansionA] = m_config.binning.at(0);
0065   auto [protoAxisB, expansionB] = m_config.binning.at(1);
0066 
0067   // Create the grid from the axis
0068   const auto& iaxisA = protoAxisA.getAxis();
0069   const auto& iaxisB = protoAxisB.getAxis();
0070   // Binning needs to be equidistant
0071   if (iaxisA.getType() != AxisType::Equidistant ||
0072       iaxisB.getType() != AxisType::Equidistant) {
0073     throw std::runtime_error(
0074         "MultiWireVolumeBuilder: Binning axes need to be equidistant");
0075   }
0076 
0077   Axis<AxisType::Equidistant, AxisBoundaryType::Bound> axisA(
0078       iaxisA.getBinEdges().front(), iaxisA.getBinEdges().back(),
0079       iaxisA.getNBins());
0080 
0081   Axis<AxisType::Equidistant, AxisBoundaryType::Bound> axisB(
0082       iaxisB.getBinEdges().front(), iaxisB.getBinEdges().back(),
0083       iaxisB.getNBins());
0084 
0085   Grid<std::vector<std::size_t>, decltype(axisA), decltype(axisB)> grid(axisA,
0086                                                                         axisB);
0087 
0088   // The indexed grid to be filled from the navigation policy
0089   IndexedSurfacesNavigation<decltype(grid)> indexedGrid(
0090       std::move(grid),
0091       {protoAxisA.getAxisDirection(), protoAxisB.getAxisDirection()});
0092 
0093   // Use TryAll Navigation Policy for the portals and acceleration structure
0094   // with indexed surfaces for the sensitives
0095 
0096   TryAllNavigationPolicy::Config tryAllConfig;
0097   tryAllConfig.portals = true;
0098   tryAllConfig.sensitives = false;
0099 
0100   TryAllNavigationPolicy tryAllPolicy(gctx, *trackingVolume, *m_logger,
0101                                       tryAllConfig);
0102 
0103   // Configure the navigation policy with the binning for the grid for the
0104   // sensitive surfaces
0105 
0106   MultiLayerNavigationPolicy::Config navConfig;
0107   navConfig.binExpansion = {expansionA, expansionB};
0108 
0109   std::unique_ptr<NavigationPolicyFactory> factory =
0110       NavigationPolicyFactory::make()
0111           .add<TryAllNavigationPolicy>(tryAllConfig)
0112           .add<MultiLayerNavigationPolicy>(navConfig, indexedGrid)
0113           .asUniquePtr();
0114 
0115   auto policyBase = factory->build(gctx, *trackingVolume, *m_logger);
0116 
0117   trackingVolume->setNavigationPolicy(std::move(policyBase));
0118 
0119   return trackingVolume;
0120 }
0121 
0122 }  // namespace Acts::Experimental