Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-08 08:10:08

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/MultiWireStructureBuilder.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/IndexedSurfacesGenerator.hpp"
0015 #include "Acts/Detector/detail/ReferenceGenerators.hpp"
0016 #include "Acts/Detector/interface/IExternalStructureBuilder.hpp"
0017 #include "Acts/Detector/interface/IInternalStructureBuilder.hpp"
0018 #include "Acts/Geometry/GeometryContext.hpp"
0019 #include "Acts/Geometry/VolumeBounds.hpp"
0020 #include "Acts/Navigation/DetectorVolumeFinders.hpp"
0021 #include "Acts/Navigation/InternalNavigation.hpp"
0022 #include "Acts/Utilities/Axis.hpp"
0023 #include "Acts/Utilities/Grid.hpp"
0024 #include "Acts/Utilities/Logger.hpp"
0025 
0026 #include <algorithm>
0027 #include <functional>
0028 #include <iostream>
0029 #include <string>
0030 #include <vector>
0031 
0032 class MultiWireInternalStructureBuilder
0033     : public Acts::Experimental::IInternalStructureBuilder {
0034  public:
0035   struct Config {
0036     /// The internal surfaces
0037     std::vector<std::shared_ptr<Acts::Surface>> iSurfaces;
0038 
0039     /// Definition of Binning
0040     std::vector<std::tuple<Acts::DirectedProtoAxis, std::size_t>> binning;
0041 
0042     /// Extra information, mainly for screen output
0043     std::string auxiliary = "";
0044 
0045     /// The transform into the local binning schema
0046     Acts::Transform3 transform = Acts::Transform3::Identity();
0047   };
0048 
0049   // Constructor
0050   explicit MultiWireInternalStructureBuilder(
0051       const Config& cfg,
0052       std::unique_ptr<const Acts::Logger> mlogger = Acts::getDefaultLogger(
0053           "MUltiWireInternalBuilder", Acts::Logging::INFO))
0054       : Acts::Experimental::IInternalStructureBuilder(),
0055         m_cfg(cfg),
0056         m_logger(std::move(mlogger)) {}
0057 
0058   Acts::Experimental::InternalStructure construct(
0059       const Acts::GeometryContext& gctx) const final {
0060     if (!m_cfg.auxiliary.empty()) {
0061       ACTS_DEBUG(m_cfg.auxiliary);
0062     }
0063 
0064     Acts::Experimental::ExternalNavigationDelegate internalVolumeUpdater =
0065         Acts::Experimental::tryNoVolumes();
0066 
0067     if (m_cfg.binning.size() < 2) {
0068       throw std::runtime_error(
0069           "MultiWireStructureBuilder: At least 2 binning axes required");
0070     }
0071 
0072     auto [protoAxisA, expansionA] = m_cfg.binning.at(0);
0073     auto [protoAxisB, expansionB] = m_cfg.binning.at(1);
0074 
0075     const auto& iaxisA = protoAxisA.getAxis();
0076     const auto& iaxisB = protoAxisB.getAxis();
0077     // Binning needs to be equidistant
0078     if (iaxisA.getType() != Acts::AxisType::Equidistant ||
0079         iaxisB.getType() != Acts::AxisType::Equidistant) {
0080       throw std::runtime_error(
0081           "MultiWireStructureBuilder: Binning axes need to be equidistant");
0082     }
0083 
0084     Acts::Axis<Acts::AxisType::Equidistant, Acts::AxisBoundaryType::Bound>
0085         axisA(iaxisA.getBinEdges().front(), iaxisA.getBinEdges().back(),
0086               iaxisA.getNBins());
0087 
0088     Acts::Axis<Acts::AxisType::Equidistant, Acts::AxisBoundaryType::Bound>
0089         axisB(iaxisB.getBinEdges().front(), iaxisB.getBinEdges().back(),
0090               iaxisB.getNBins());
0091 
0092     Acts::Grid<std::vector<std::size_t>, decltype(axisA), decltype(axisB)> grid(
0093         axisA, axisB);
0094 
0095     // Prepare the indexed updator
0096     std::array<Acts::AxisDirection, 2u> axisDirs = {
0097         protoAxisA.getAxisDirection(), protoAxisB.getAxisDirection()};
0098     Acts::Experimental::MultiLayerSurfacesNavigation<decltype(grid)>
0099         indexedSurfaces(std::move(grid), axisDirs, m_cfg.transform);
0100 
0101     std::vector<std::size_t> fillExpansion = {expansionA, expansionB};
0102 
0103     Acts::Experimental::detail::CenterReferenceGenerator rGenerator;
0104     Acts::Experimental::detail::IndexedGridFiller filler{fillExpansion};
0105     filler.fill(gctx, indexedSurfaces, m_cfg.iSurfaces, rGenerator, {});
0106 
0107     Acts::Experimental::InternalNavigationDelegate sfCandidatesUpdater;
0108 
0109     // The portal delegate
0110     Acts::Experimental::AllPortalsNavigation allPortals;
0111 
0112     // The chained delegate: indexed surfaces and all portals
0113     using DelegateType =
0114         Acts::Experimental::IndexedSurfacesAllPortalsNavigation<
0115             decltype(grid), Acts::Experimental::MultiLayerSurfacesNavigation>;
0116     auto indexedSurfacesAllPortals = std::make_unique<const DelegateType>(
0117         std::tie(allPortals, indexedSurfaces));
0118 
0119     // Create the delegate and connect it
0120     sfCandidatesUpdater.connect<&DelegateType::update>(
0121         std::move(indexedSurfacesAllPortals));
0122 
0123     return {m_cfg.iSurfaces,
0124             {},
0125             std::move(sfCandidatesUpdater),
0126             std::move(internalVolumeUpdater)};
0127   }
0128 
0129  private:
0130   /// Configuration object
0131   Config m_cfg;
0132 
0133   /// Private access method to the logger
0134   const Acts::Logger& logger() const { return *m_logger; }
0135 
0136   /// logging instance
0137   std::unique_ptr<const Acts::Logger> m_logger;
0138 };
0139 
0140 Acts::Experimental::MultiWireStructureBuilder::MultiWireStructureBuilder(
0141     const Acts::Experimental::MultiWireStructureBuilder::Config& config,
0142     std::unique_ptr<const Acts::Logger> logger)
0143     : mCfg(config), mLogger(std::move(logger)) {
0144   // check if the surfaces are set
0145   if (mCfg.mlSurfaces.empty()) {
0146     throw std::invalid_argument(
0147         "MultiWireStructureBuilder: No surfaces are given");
0148   } else if (mCfg.mlBinning.size() != 2u) {
0149     throw ::std::invalid_argument(
0150         "MultiWireStructureBuilder: Invalid binning provided");
0151   }
0152 }
0153 
0154 Acts::Experimental::DetectorComponent
0155 Acts::Experimental::MultiWireStructureBuilder::construct(
0156     const Acts::GeometryContext& gctx) {
0157   // Configure the external structure builder for the internal structure
0158   Acts::Experimental::VolumeStructureBuilder::Config vsConfig;
0159   vsConfig.boundsType = Acts::VolumeBounds::eTrapezoid;
0160   vsConfig.transform = mCfg.transform;
0161   vsConfig.boundValues = mCfg.mlBounds;
0162   vsConfig.auxiliary = "Construct External Structure";
0163 
0164   // Configure the internal structure builder for the internal structure
0165   MultiWireInternalStructureBuilder::Config iConfig;
0166   iConfig.iSurfaces = mCfg.mlSurfaces;
0167   iConfig.binning = mCfg.mlBinning;
0168   iConfig.transform = mCfg.transform.inverse();
0169   iConfig.auxiliary = "Construct Internal Structure";
0170 
0171   Acts::Experimental::DetectorVolumeBuilder::Config dvConfig;
0172   dvConfig.auxiliary = "Construct Detector Volume";
0173   dvConfig.name = mCfg.name;
0174   dvConfig.internalsBuilder =
0175       std::make_shared<MultiWireInternalStructureBuilder>(
0176           iConfig,
0177           Acts::getDefaultLogger("MultiWire Internal Structure Builder",
0178                                  Acts::Logging::VERBOSE));
0179   dvConfig.externalsBuilder =
0180       std::make_shared<Acts::Experimental::VolumeStructureBuilder>(
0181           vsConfig, Acts::getDefaultLogger("VolumeStructureBuilder",
0182                                            Acts::Logging::VERBOSE));
0183   auto dvBuilder = std::make_shared<Acts::Experimental::DetectorVolumeBuilder>(
0184       dvConfig,
0185       Acts::getDefaultLogger("DetectorVolumeBuilder", Acts::Logging::VERBOSE));
0186 
0187   auto dvComponent = dvBuilder->construct(gctx);
0188 
0189   return dvComponent;
0190 }