Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-10-31 08:16:21

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 #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 /// @brief Class to accumulate and average track lookup tables
0023 ///
0024 /// @tparam Grid type for track parameters accumulation
0025 ///
0026 /// This class is used to accumulate track parameters in
0027 /// reference layer grids and average them to create a lookup
0028 /// table for track parameter estimation in seeding
0029 ///
0030 /// @note Geometry context is left to be handled by the user
0031 /// outside of accumulation
0032 template <detail::TrackParamsGrid grid_t>
0033 class TrackParamsLookupAccumulator {
0034  public:
0035   /// Type alias for track parameter lookup grid
0036   using LookupGrid = grid_t;
0037   /// Type alias for track parameters type
0038   using TrackParameters = typename std::pointer_traits<
0039       typename grid_t::value_type::first_type>::element_type;
0040 
0041   /// @brief Constructor
0042   /// @param grid Grid to use for track parameter lookup accumulation
0043   explicit TrackParamsLookupAccumulator(grid_t grid)
0044       : m_grid(std::move(grid)) {}
0045 
0046   /// @brief Add track parameters to the accumulator
0047   ///
0048   /// @param ipTrackParameters Track parameters at the IP
0049   /// @param refTrackParameters Track parameters at the reference layer
0050   /// @param position Local position of the track hit on the reference layer
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   /// @brief Finalize the lookup table
0076   ///
0077   /// @return Grid with the bin track parameters averaged
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   /// @brief Add two track parameters
0116   ///
0117   /// @param a First track parameter in the sum
0118   /// @param b Second track parameter in the sum
0119   ///
0120   /// @return Sum of track parameters a + b
0121   ///
0122   /// @note Covariances of the track parameters
0123   /// are not added and instead assumed to be
0124   /// generated by the same random process for
0125   /// both a and b, making its averaging redundant
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     // Assume track parameters being i.i.d.
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   /// Grids to accumulate IP and reference
0171   /// layer track parameters
0172   LookupGrid m_grid;
0173 
0174   /// Mutex for protecting grid access
0175   std::mutex m_gridMutex;
0176 
0177   /// Map to keep the accumulation count
0178   /// in the occupied grid bins
0179   std::map<std::array<std::size_t, LookupGrid::DIM>, std::size_t> m_countGrid;
0180 };
0181 
0182 }  // namespace Acts