File indexing completed on 2025-12-15 09:42:22
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include "Acts/EventData/detail/TrackParametersUtils.hpp"
0012 #include "Acts/Geometry/GeometryContext.hpp"
0013
0014 #include <map>
0015 #include <memory>
0016 #include <mutex>
0017 #include <stdexcept>
0018 #include <utility>
0019
0020 namespace Acts {
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032 template <detail::TrackParamsGrid grid_t>
0033 class TrackParamsLookupAccumulator {
0034 public:
0035
0036 using LookupGrid = grid_t;
0037
0038 using TrackParameters = typename std::pointer_traits<
0039 typename grid_t::value_type::first_type>::element_type;
0040
0041
0042
0043 explicit TrackParamsLookupAccumulator(grid_t grid)
0044 : m_grid(std::move(grid)) {}
0045
0046
0047
0048
0049
0050
0051 void addTrack(const TrackParameters& ipTrackParameters,
0052 const TrackParameters& refTrackParameters,
0053 const Vector2& position) {
0054 std::lock_guard<std::mutex> lock(m_gridMutex);
0055
0056 auto bin = m_grid.localBinsFromPosition(position);
0057
0058 if (m_countGrid[bin] == 0) {
0059 m_grid.atLocalBins(bin).first =
0060 std::make_shared<TrackParameters>(ipTrackParameters);
0061 m_grid.atLocalBins(bin).second =
0062 std::make_shared<TrackParameters>(refTrackParameters);
0063
0064 m_countGrid.at(bin)++;
0065 return;
0066 }
0067
0068 *m_grid.atLocalBins(bin).first =
0069 addTrackParameters(*m_grid.atLocalBins(bin).first, ipTrackParameters);
0070 *m_grid.atLocalBins(bin).second =
0071 addTrackParameters(*m_grid.atLocalBins(bin).second, refTrackParameters);
0072 m_countGrid.at(bin)++;
0073 }
0074
0075
0076
0077
0078 LookupGrid finalizeLookup() {
0079 auto meanTrack = [&](const TrackParameters& track, std::size_t count) {
0080 if constexpr (detail::isGenericBoundTrackParams<TrackParameters>) {
0081 Acts::GeometryContext gctx;
0082
0083 auto res = TrackParameters::create(
0084 gctx, track.referenceSurface().getSharedPtr(),
0085 track.fourPosition(gctx) / count, track.momentum().normalized(),
0086 count * track.charge() / track.momentum().norm(),
0087 track.covariance(), track.particleHypothesis());
0088
0089 if (!res.ok()) {
0090 throw std::invalid_argument("Bound track grid finalization failed");
0091 }
0092 return res.value();
0093 } else {
0094 return TrackParameters(track.fourPosition() / count,
0095 track.momentum().normalized(),
0096 count * track.charge() / track.momentum().norm(),
0097 track.covariance(), track.particleHypothesis());
0098 }
0099 };
0100
0101 for (auto [bin, count] : m_countGrid) {
0102 if (count == 0) {
0103 continue;
0104 }
0105 *m_grid.atLocalBins(bin).first =
0106 meanTrack(*m_grid.atLocalBins(bin).first, count);
0107 *m_grid.atLocalBins(bin).second =
0108 meanTrack(*m_grid.atLocalBins(bin).second, count);
0109 }
0110
0111 return m_grid;
0112 }
0113
0114 private:
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126 TrackParameters addTrackParameters(const TrackParameters& a,
0127 const TrackParameters& b) {
0128 if (a.particleHypothesis() != b.particleHypothesis()) {
0129 throw std::invalid_argument(
0130 "Cannot accumulate track parameters with different particle "
0131 "hypotheses");
0132 }
0133 if (a.charge() != b.charge()) {
0134 throw std::invalid_argument(
0135 "Cannot accumulate track parameters with different charges");
0136 }
0137 if constexpr (detail::isGenericBoundTrackParams<TrackParameters>) {
0138 if (a.referenceSurface() != b.referenceSurface()) {
0139 throw std::invalid_argument(
0140 "Cannot accumulate bound track parameters with different reference "
0141 "surfaces");
0142 }
0143 }
0144
0145 Acts::Vector3 momentum = a.momentum() + b.momentum();
0146
0147
0148 if constexpr (detail::isGenericBoundTrackParams<TrackParameters>) {
0149 Acts::GeometryContext gctx;
0150
0151 Acts::Vector4 fourPosition = a.fourPosition(gctx) + b.fourPosition(gctx);
0152
0153 auto res = TrackParameters::create(
0154 gctx, a.referenceSurface().getSharedPtr(), fourPosition,
0155 momentum.normalized(), a.charge() / momentum.norm(), a.covariance(),
0156 a.particleHypothesis());
0157
0158 if (!res.ok()) {
0159 throw std::runtime_error("Invalid bound track parameters");
0160 }
0161 return res.value();
0162 } else {
0163 Acts::Vector4 fourPosition = a.fourPosition() + b.fourPosition();
0164 return TrackParameters(fourPosition, momentum.normalized(),
0165 a.charge() / momentum.norm(), a.covariance(),
0166 a.particleHypothesis());
0167 }
0168 }
0169
0170
0171
0172 LookupGrid m_grid;
0173
0174
0175 std::mutex m_gridMutex;
0176
0177
0178
0179 std::map<std::array<std::size_t, LookupGrid::DIM>, std::size_t> m_countGrid;
0180 };
0181
0182 }