Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:11:05

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   using LookupGrid = grid_t;
0036   using TrackParameters = typename std::pointer_traits<
0037       typename grid_t::value_type::first_type>::element_type;
0038 
0039   /// @brief Constructor
0040   explicit TrackParamsLookupAccumulator(grid_t grid)
0041       : m_grid(std::move(grid)) {}
0042 
0043   /// @brief Add track parameters to the accumulator
0044   ///
0045   /// @param ipTrackParameters Track parameters at the IP
0046   /// @param refTrackParameters Track parameters at the reference layer
0047   /// @param position Local position of the track hit on the reference layer
0048   void addTrack(const TrackParameters& ipTrackParameters,
0049                 const TrackParameters& refTrackParameters,
0050                 const Vector2& position) {
0051     std::lock_guard<std::mutex> lock(m_gridMutex);
0052 
0053     auto bin = m_grid.localBinsFromPosition(position);
0054 
0055     if (m_countGrid[bin] == 0) {
0056       m_grid.atLocalBins(bin).first =
0057           std::make_shared<TrackParameters>(ipTrackParameters);
0058       m_grid.atLocalBins(bin).second =
0059           std::make_shared<TrackParameters>(refTrackParameters);
0060 
0061       m_countGrid.at(bin)++;
0062       return;
0063     }
0064 
0065     *m_grid.atLocalBins(bin).first =
0066         addTrackParameters(*m_grid.atLocalBins(bin).first, ipTrackParameters);
0067     *m_grid.atLocalBins(bin).second =
0068         addTrackParameters(*m_grid.atLocalBins(bin).second, refTrackParameters);
0069     m_countGrid.at(bin)++;
0070   }
0071 
0072   /// @brief Finalize the lookup table
0073   ///
0074   /// @return Grid with the bin track parameters averaged
0075   LookupGrid finalizeLookup() {
0076     auto meanTrack = [&](const TrackParameters& track, std::size_t count) {
0077       if constexpr (detail::isGenericBoundTrackParams<TrackParameters>) {
0078         Acts::GeometryContext gctx;
0079 
0080         auto res = TrackParameters::create(
0081             track.referenceSurface().getSharedPtr(), gctx,
0082             track.fourPosition(gctx) / count, track.momentum().normalized(),
0083             count * track.charge() / track.momentum().norm(),
0084             track.covariance(), track.particleHypothesis());
0085 
0086         if (!res.ok()) {
0087           throw std::invalid_argument("Bound track grid finalization failed");
0088         }
0089         return res.value();
0090       } else {
0091         return TrackParameters(track.fourPosition() / count,
0092                                track.momentum().normalized(),
0093                                count * track.charge() / track.momentum().norm(),
0094                                track.covariance(), track.particleHypothesis());
0095       }
0096     };
0097 
0098     for (auto [bin, count] : m_countGrid) {
0099       if (count == 0) {
0100         continue;
0101       }
0102       *m_grid.atLocalBins(bin).first =
0103           meanTrack(*m_grid.atLocalBins(bin).first, count);
0104       *m_grid.atLocalBins(bin).second =
0105           meanTrack(*m_grid.atLocalBins(bin).second, count);
0106     }
0107 
0108     return m_grid;
0109   }
0110 
0111  private:
0112   /// @brief Add two track parameters
0113   ///
0114   /// @param a First track parameter in the sum
0115   /// @param b Second track parameter in the sum
0116   ///
0117   /// @return Sum of track parameters a + b
0118   ///
0119   /// @note Covariances of the track parameters
0120   /// are not added and instead assumed to be
0121   /// generated by the same random process for
0122   /// both a and b, making its averaging redundant
0123   TrackParameters addTrackParameters(const TrackParameters& a,
0124                                      const TrackParameters& b) {
0125     if (a.particleHypothesis() != b.particleHypothesis()) {
0126       throw std::invalid_argument(
0127           "Cannot accumulate track parameters with different particle "
0128           "hypotheses");
0129     }
0130     if (a.charge() != b.charge()) {
0131       throw std::invalid_argument(
0132           "Cannot accumulate track parameters with different charges");
0133     }
0134     if constexpr (detail::isGenericBoundTrackParams<TrackParameters>) {
0135       if (a.referenceSurface() != b.referenceSurface()) {
0136         throw std::invalid_argument(
0137             "Cannot accumulate bound track parameters with different reference "
0138             "surfaces");
0139       }
0140     }
0141 
0142     Acts::Vector3 momentum = a.momentum() + b.momentum();
0143 
0144     // Assume track parameters being i.i.d.
0145     if constexpr (detail::isGenericBoundTrackParams<TrackParameters>) {
0146       Acts::GeometryContext gctx;
0147 
0148       Acts::Vector4 fourPosition = a.fourPosition(gctx) + b.fourPosition(gctx);
0149 
0150       auto res = TrackParameters::create(
0151           a.referenceSurface().getSharedPtr(), gctx, fourPosition,
0152           momentum.normalized(), a.charge() / momentum.norm(), a.covariance(),
0153           a.particleHypothesis());
0154 
0155       if (!res.ok()) {
0156         throw std::runtime_error("Invalid bound track parameters");
0157       }
0158       return res.value();
0159     } else {
0160       Acts::Vector4 fourPosition = a.fourPosition() + b.fourPosition();
0161       return TrackParameters(fourPosition, momentum.normalized(),
0162                              a.charge() / momentum.norm(), a.covariance(),
0163                              a.particleHypothesis());
0164     }
0165   }
0166 
0167   /// Grids to accumulate IP and reference
0168   /// layer track parameters
0169   LookupGrid m_grid;
0170 
0171   /// Mutex for protecting grid access
0172   std::mutex m_gridMutex;
0173 
0174   /// Map to keep the accumulation count
0175   /// in the occupied grid bins
0176   std::map<std::array<std::size_t, LookupGrid::DIM>, std::size_t> m_countGrid;
0177 };
0178 
0179 }  // namespace Acts