File indexing completed on 2025-12-11 09:40:04
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include "Acts/Definitions/Direction.hpp"
0012 #include "Acts/Definitions/Units.hpp"
0013 #include "Acts/EventData/SpacePointContainer2.hpp"
0014 #include "Acts/Utilities/Delegate.hpp"
0015 #include "Acts/Utilities/detail/ContainerIterator.hpp"
0016
0017 #include <cstdint>
0018 #include <vector>
0019
0020 namespace Acts {
0021
0022
0023
0024
0025
0026 class DoubletsForMiddleSp {
0027 public:
0028
0029 using Index = std::uint32_t;
0030
0031 using IndexRange = std::pair<Index, Index>;
0032
0033 using IndexSubset = std::span<const Index>;
0034
0035
0036
0037 [[nodiscard]] bool empty() const { return m_spacePoints.empty(); }
0038
0039
0040 [[nodiscard]] Index size() const {
0041 return static_cast<Index>(m_spacePoints.size());
0042 }
0043
0044
0045 void clear() {
0046 m_spacePoints.clear();
0047 m_cotTheta.clear();
0048 m_er_iDeltaR.clear();
0049 m_uv.clear();
0050 m_xy.clear();
0051 }
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062 void emplace_back(SpacePointIndex2 sp, float cotTheta, float iDeltaR,
0063 float er, float u, float v, float x, float y) {
0064 m_spacePoints.push_back(sp);
0065 m_cotTheta.push_back(cotTheta);
0066 m_er_iDeltaR.push_back({er, iDeltaR});
0067 m_uv.push_back({u, v});
0068 m_xy.push_back({x, y});
0069 }
0070
0071
0072
0073 const std::vector<SpacePointIndex2>& spacePoints() const {
0074 return m_spacePoints;
0075 }
0076
0077
0078 const std::vector<float>& cotTheta() const { return m_cotTheta; }
0079
0080 struct IndexAndCotTheta {
0081 Index index{};
0082 float cotTheta{};
0083 };
0084
0085
0086 using IndexAndCotThetaSubset = std::span<const IndexAndCotTheta>;
0087
0088
0089
0090
0091 void sortByCotTheta(const IndexRange& range,
0092 std::vector<IndexAndCotTheta>& indexAndCotTheta) const {
0093 indexAndCotTheta.clear();
0094 indexAndCotTheta.reserve(range.second - range.first);
0095 for (Index i = range.first; i < range.second; ++i) {
0096 indexAndCotTheta.emplace_back(i, m_cotTheta[i]);
0097 }
0098 std::ranges::sort(indexAndCotTheta, {}, [](const IndexAndCotTheta& item) {
0099 return item.cotTheta;
0100 });
0101 }
0102
0103 class Proxy {
0104 public:
0105 Proxy(const DoubletsForMiddleSp* container, Index index)
0106 : m_container(container), m_index(index) {}
0107
0108 const DoubletsForMiddleSp& container() const { return *m_container; }
0109 Index index() const { return m_index; }
0110
0111 SpacePointIndex2 spacePointIndex() const {
0112 return m_container->m_spacePoints[m_index];
0113 }
0114
0115 float cotTheta() const { return m_container->m_cotTheta[m_index]; }
0116 float er() const { return m_container->m_er_iDeltaR[m_index][0]; }
0117 float iDeltaR() const { return m_container->m_er_iDeltaR[m_index][1]; }
0118 float u() const { return m_container->m_uv[m_index][0]; }
0119 float v() const { return m_container->m_uv[m_index][1]; }
0120 float x() const { return m_container->m_xy[m_index][0]; }
0121 float y() const { return m_container->m_xy[m_index][1]; }
0122
0123 private:
0124 const DoubletsForMiddleSp* m_container{};
0125 Index m_index{};
0126 };
0127
0128
0129 class Proxy2 : public Proxy {
0130 public:
0131
0132
0133
0134 Proxy2(const DoubletsForMiddleSp* container,
0135 IndexAndCotTheta indexAndCotTheta)
0136 : Proxy(container, indexAndCotTheta.index),
0137 m_cotTheta(indexAndCotTheta.cotTheta) {}
0138
0139
0140
0141 float cotTheta() const { return m_cotTheta; }
0142
0143 private:
0144 float m_cotTheta{};
0145 };
0146
0147
0148
0149
0150 Proxy operator[](Index index) const { return Proxy(this, index); }
0151
0152
0153
0154 Proxy2 operator[](IndexAndCotTheta indexAndCotTheta) const {
0155 return Proxy2(this, indexAndCotTheta);
0156 }
0157
0158
0159 using const_iterator =
0160 detail::ContainerIterator<DoubletsForMiddleSp, Proxy, Index, true>;
0161
0162
0163
0164 const_iterator begin() const { return const_iterator(*this, 0); }
0165
0166
0167 const_iterator end() const { return const_iterator(*this, size()); }
0168
0169 class Range : public detail::ContainerRange<Range, Range, DoubletsForMiddleSp,
0170 Index, true> {
0171 public:
0172 using Base =
0173 detail::ContainerRange<Range, Range, DoubletsForMiddleSp, Index, true>;
0174
0175 using Base::Base;
0176 };
0177
0178
0179
0180 Range range() const noexcept { return Range(*this, {0, size()}); }
0181
0182
0183
0184 Range range(const IndexRange& range) const noexcept {
0185 return Range(*this, range);
0186 }
0187
0188 class Subset
0189 : public detail::ContainerSubset<Subset, Subset, DoubletsForMiddleSp,
0190 Proxy, Index, true> {
0191 public:
0192 using Base = detail::ContainerSubset<Subset, Subset, DoubletsForMiddleSp,
0193 Proxy, Index, true>;
0194
0195 using Base::Base;
0196 };
0197 class Subset2
0198 : public detail::ContainerSubset<Subset2, Subset2, DoubletsForMiddleSp,
0199 Proxy2, IndexAndCotTheta, true> {
0200 public:
0201 using Base = detail::ContainerSubset<Subset2, Subset2, DoubletsForMiddleSp,
0202 Proxy2, IndexAndCotTheta, true>;
0203
0204 using Base::Base;
0205 };
0206
0207
0208
0209
0210 Subset subset(const IndexSubset& subset) const noexcept {
0211 return Subset(*this, subset);
0212 }
0213
0214
0215
0216 Subset2 subset(const IndexAndCotThetaSubset& subset) const noexcept {
0217 return Subset2(*this, subset);
0218 }
0219
0220 private:
0221 std::vector<SpacePointIndex2> m_spacePoints;
0222
0223
0224 std::vector<float> m_cotTheta;
0225 std::vector<std::array<float, 2>> m_er_iDeltaR;
0226 std::vector<std::array<float, 2>> m_uv;
0227 std::vector<std::array<float, 2>> m_xy;
0228 };
0229
0230 struct MiddleSpInfo {
0231
0232 float uIP{};
0233
0234 float uIP2{};
0235
0236 float cosPhiM{};
0237
0238 float sinPhiM{};
0239 };
0240
0241
0242
0243
0244
0245
0246
0247
0248 class DoubletSeedFinder {
0249 public:
0250
0251
0252
0253 struct Config {
0254
0255 bool spacePointsSortedByRadius = false;
0256
0257
0258
0259 Direction candidateDirection = Direction::Forward();
0260
0261
0262 float deltaRMin = 5 * UnitConstants::mm;
0263
0264 float deltaRMax = 270 * UnitConstants::mm;
0265
0266
0267 float deltaZMin = -std::numeric_limits<float>::infinity();
0268
0269 float deltaZMax = std::numeric_limits<float>::infinity();
0270
0271
0272 float impactMax = 20 * UnitConstants::mm;
0273
0274
0275
0276 bool interactionPointCut = false;
0277
0278
0279
0280 float collisionRegionMin = -150 * UnitConstants::mm;
0281
0282 float collisionRegionMax = +150 * UnitConstants::mm;
0283
0284
0285
0286 float cotThetaMax = 10.01788;
0287
0288
0289
0290
0291
0292
0293 float minPt = 400 * UnitConstants::MeV;
0294
0295
0296 float helixCutTolerance = 1;
0297
0298
0299
0300 using ExperimentCuts =
0301 Delegate<bool(const ConstSpacePointProxy2& ,
0302 const ConstSpacePointProxy2& ,
0303 float , bool )>;
0304
0305
0306 ExperimentCuts experimentCuts;
0307 };
0308
0309
0310 struct DerivedConfig : public Config {
0311
0312
0313
0314 DerivedConfig(const Config& config, float bFieldInZ);
0315
0316
0317 float bFieldInZ = std::numeric_limits<float>::quiet_NaN();
0318
0319
0320 float minHelixDiameter2 = std::numeric_limits<float>::quiet_NaN();
0321 };
0322
0323
0324
0325
0326
0327 static MiddleSpInfo computeMiddleSpInfo(const ConstSpacePointProxy2& spM);
0328
0329
0330
0331
0332 static std::unique_ptr<DoubletSeedFinder> create(const DerivedConfig& config);
0333
0334 virtual ~DoubletSeedFinder() = default;
0335
0336
0337
0338 virtual const DerivedConfig& config() const = 0;
0339
0340
0341
0342
0343
0344
0345
0346
0347
0348 virtual void createDoublets(
0349 const ConstSpacePointProxy2& middleSp, const MiddleSpInfo& middleSpInfo,
0350 SpacePointContainer2::ConstSubset& candidateSps,
0351 DoubletsForMiddleSp& compatibleDoublets) const = 0;
0352
0353
0354
0355
0356
0357
0358
0359
0360
0361 virtual void createDoublets(
0362 const ConstSpacePointProxy2& middleSp, const MiddleSpInfo& middleSpInfo,
0363 SpacePointContainer2::ConstRange& candidateSps,
0364 DoubletsForMiddleSp& compatibleDoublets) const = 0;
0365 };
0366
0367 }