File indexing completed on 2025-07-08 08:10:08
0001
0002
0003
0004
0005
0006
0007
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
0037 std::vector<std::shared_ptr<Acts::Surface>> iSurfaces;
0038
0039
0040 std::vector<std::tuple<Acts::DirectedProtoAxis, std::size_t>> binning;
0041
0042
0043 std::string auxiliary = "";
0044
0045
0046 Acts::Transform3 transform = Acts::Transform3::Identity();
0047 };
0048
0049
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
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
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
0110 Acts::Experimental::AllPortalsNavigation allPortals;
0111
0112
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
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
0131 Config m_cfg;
0132
0133
0134 const Acts::Logger& logger() const { return *m_logger; }
0135
0136
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
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
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
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 }