Warning, file /include/Acts/Detector/KdtSurfacesProvider.hpp was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Detector/detail/ReferenceGenerators.hpp"
0013 #include "Acts/Detector/interface/ISurfacesProvider.hpp"
0014 #include "Acts/Surfaces/Surface.hpp"
0015 #include "Acts/Utilities/BinningData.hpp"
0016 #include "Acts/Utilities/KDTree.hpp"
0017
0018 #include <array>
0019 #include <stdexcept>
0020 #include <tuple>
0021 #include <vector>
0022
0023 namespace Acts::Experimental {
0024
0025
0026
0027
0028
0029
0030 template <std::size_t kDIM = 2u, std::size_t bSize = 100u,
0031 typename reference_generator =
0032 detail::PolyhedronReferenceGenerator<1u, false>>
0033 class KdtSurfaces {
0034 public:
0035
0036 using KDTS =
0037 KDTree<kDIM, std::shared_ptr<Surface>, ActsScalar, std::array, bSize>;
0038
0039
0040 using Query = std::array<ActsScalar, kDIM>;
0041
0042
0043 using Entry = std::pair<Query, std::shared_ptr<Surface>>;
0044
0045
0046
0047
0048
0049
0050
0051 KdtSurfaces(const GeometryContext& gctx,
0052 const std::vector<std::shared_ptr<Surface>>& surfaces,
0053 const std::array<BinningValue, kDIM>& casts,
0054 const reference_generator& rgen =
0055 detail::PolyhedronReferenceGenerator<1u, false>{})
0056 : m_kdt(nullptr), m_casts(casts), m_rGenerator(rgen) {
0057
0058 if (kDIM == 0u) {
0059 throw std::invalid_argument(
0060 "KdtSurfaces: dimension and/or cast rules are incorrect.");
0061 }
0062
0063 std::vector<Entry> kdtEntries;
0064 kdtEntries.reserve(surfaces.size());
0065 for (auto& s : surfaces) {
0066
0067 const auto references = m_rGenerator.references(gctx, *s);
0068 std::vector<Query> castedReferences;
0069 castedReferences.reserve(references.size());
0070 for (const auto& r : references) {
0071
0072 Query rc = {};
0073 fillCasts(r, rc, std::make_integer_sequence<std::size_t, kDIM>{});
0074 castedReferences.push_back(rc);
0075 }
0076
0077 kdtEntries.push_back({cog(castedReferences), s});
0078 }
0079
0080 m_kdt = std::make_unique<KDTS>(std::move(kdtEntries));
0081 }
0082
0083
0084
0085
0086
0087
0088 std::vector<std::shared_ptr<Surface>> surfaces(
0089 const RangeXD<kDIM, ActsScalar>& range) const {
0090
0091 std::vector<std::shared_ptr<Surface>> surfacePtrs;
0092 auto surfaceQuery = m_kdt->rangeSearchWithKey(range);
0093 std::for_each(surfaceQuery.begin(), surfaceQuery.end(),
0094 [&](auto& surf) { surfacePtrs.push_back(surf.second); });
0095 return surfacePtrs;
0096 }
0097
0098
0099
0100
0101
0102
0103 std::vector<std::shared_ptr<Surface>> surfaces(const Extent& extent) const {
0104 RangeXD<kDIM, ActsScalar> qRange;
0105 for (auto [ibv, v] : enumerate(m_casts)) {
0106 qRange[ibv] = extent.range(v);
0107 }
0108 return surfaces(qRange);
0109 }
0110
0111 private:
0112
0113 std::unique_ptr<KDTS> m_kdt = nullptr;
0114
0115
0116 std::array<BinningValue, kDIM> m_casts = {};
0117
0118
0119 reference_generator m_rGenerator;
0120
0121
0122
0123
0124 template <typename Array, std::size_t... idx>
0125 void fillCasts(const Vector3& position, Array& a,
0126 std::index_sequence<idx...> ) const {
0127 ((a[idx] = VectorHelpers::cast(position, m_casts[idx])), ...);
0128 }
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141 Query cog(const std::vector<Query>& cQueries) const {
0142
0143 if (cQueries.size() == 1) {
0144 return cQueries.front();
0145 }
0146
0147 Query c{};
0148 float weight = 1. / cQueries.size();
0149 for (auto& q : cQueries) {
0150 std::transform(c.begin(), c.end(), q.begin(), c.begin(),
0151 std::plus<ActsScalar>());
0152 }
0153 std::for_each(c.begin(), c.end(), [&](auto& v) { v *= weight; });
0154 return c;
0155 }
0156 };
0157
0158
0159
0160
0161
0162 template <std::size_t kDIM = 2u, std::size_t bSize = 100u,
0163 typename reference_generator =
0164 detail::PolyhedronReferenceGenerator<1u, false>>
0165 class KdtSurfacesProvider : public ISurfacesProvider {
0166 public:
0167
0168
0169
0170
0171
0172 KdtSurfacesProvider(
0173 std::shared_ptr<KdtSurfaces<kDIM, bSize, reference_generator>> kdts,
0174 const Extent& kregion)
0175 : m_kdt(std::move(kdts)), m_region(kregion) {
0176
0177 if (m_kdt == nullptr) {
0178 throw std::invalid_argument(
0179 "KdtSurfacesProvider: no KDTree structure provided.");
0180 }
0181 }
0182
0183
0184 std::vector<std::shared_ptr<Surface>> surfaces(
0185 [[maybe_unused]] const GeometryContext& gctx) const final {
0186 return m_kdt->surfaces(m_region);
0187 }
0188
0189 private:
0190 std::shared_ptr<KdtSurfaces<kDIM, bSize, reference_generator>> m_kdt =
0191 nullptr;
0192
0193 Extent m_region;
0194 };
0195
0196 }