|
|
|||
File indexing completed on 2025-12-16 09:20:19
0001 #pragma once 0002 0003 #include "PHField.h" 0004 0005 #if defined(__GNUC__) && !defined(__clang__) 0006 #pragma GCC diagnostic push 0007 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" 0008 #include <Eigen/Dense> 0009 #pragma GCC diagnostic pop 0010 #else 0011 #include <Eigen/Dense> 0012 #endif 0013 0014 #include <array> 0015 #include <deque> 0016 #include <iostream> 0017 #include <limits> 0018 #include <map> 0019 #include <mutex> 0020 #include <optional> 0021 #include <string> 0022 #include <thread> 0023 0024 //! Provides a best-fit cubic approximation of the Field 0025 //! In 3D cartesian coordinates 0026 class PHFieldInterpolated : public PHField 0027 { 0028 public: 0029 typedef Eigen::Vector3i Indices_t; 0030 typedef Eigen::Vector3f Point_t; 0031 typedef Eigen::Vector3f Field_t; 0032 0033 //! constructor 0034 explicit PHFieldInterpolated () = default; 0035 0036 //! destructor 0037 ~PHFieldInterpolated () override = default; 0038 0039 //! access field value 0040 //! Follow the convention of G4ElectroMagneticField 0041 //! @param[in] pointer to double[4] representing (x, y, z, t), where field is to be evaluated (in Geant4/CLHEP units) (cm) 0042 //! @param[out] pointer to double[3] representing (b_x, b_y, b_z), mutated to contain the value of the field (in Geant4/CLHEP units) (T) 0043 void GetFieldValue (double const*, double*) const override; 0044 0045 //! Returns an O(3) best fit interpolation of the field at the point, updating the cached interpolated parameters as needed 0046 //! Thread-safe top-level access 0047 Field_t get_interpolated (Point_t const&) const; 0048 0049 //! Loads the fieldmap from a ROOT file, expects specific contents 0050 void load_fieldmap ( 0051 std::string const& = "/cvmfs/sphenix.sdcc.bnl.gov/alma9.2-gcc-14.2.0/release/release_ana/ana.499/share/calibrations/Field/Map/sphenix3dtrackingmapxyz.root", 0052 const float& = 1.0 0053 ); 0054 0055 //! prints class info based on verbosity level 0056 //! thread-safe 0057 void print(std::ostream& = std::cout) const; 0058 0059 //! prints the cached Taylor coefficients 0060 //! thread-safe 0061 void print_coefficients(std::ostream& = std::cout) const; 0062 0063 private: 0064 0065 // Threads using the class get their own cache 0066 struct InterpolationCache { 0067 0068 //! Tracks how "important" this cache is 0069 //! When a thread accesses this class, its corresponding cache is moved to the front of the queue 0070 //! Instances at the end of the "queue" are culled 0071 //! Maximal value allows idential logic to shuffle indexes for existing or new thread accesses 0072 std::size_t m_queue_index{std::numeric_limits<std::size_t>::max()}; 0073 0074 //! The indices of the left-down-back corner of the cell that the interpolation is cached for 0075 //! Initialized out-of-bounds so the coefficients are always computed on first call 0076 Indices_t m_buffered_indices = {-1, -1, -1}; 0077 0078 //! The point about which the field is currently interpolated 0079 Point_t m_center; 0080 0081 //! The 20 coefficients for an O(3) Taylor expansion of a function in 3D 0082 //! (one per component of the magnetic field) 0083 std::array<Eigen::VectorXf, 3> m_coefficients; 0084 }; 0085 0086 //! Returns the 20 element row of a design matrix for position point about the stored value m_center 0087 static Eigen::VectorXf get_design_vector (Point_t const&, InterpolationCache const&); 0088 0089 //! Returns a mutable reference to the interpolation information cached for the calling thread 0090 InterpolationCache& get_cache () const; 0091 0092 //! Caches the interpolation for the cell containing given point 0093 //! Should really be a member funciton of InterpolationCache 0094 void cache_interpolation (Point_t const&, InterpolationCache&) const; 0095 0096 //! Gets the 3D grid indices from a 1D deque index 0097 Indices_t get_indices (std::size_t const&) const; 0098 //! Gets the 1D deque index from 3D grid indices 0099 std::size_t get_index (Indices_t const&) const; 0100 0101 //! return the 3D grid indices of the left-down-back corner of the grid cell containing point 0102 Indices_t get_indices (Point_t const&) const; 0103 //! return point at the left-down-back corner of the grid cell at the given 3D grid indices 0104 Point_t get_point (Indices_t const&) const; 0105 0106 //! return field at given 1D deque index 0107 Field_t get_field (std::size_t const& index) const { return m_field.at(index); } 0108 //! return field at the left-down-back corner of the grid cell at given 3D grid indices 0109 Field_t get_field (Indices_t const& indices) const { return get_field(get_index(indices)); } 0110 //! return the field at the left-down-back corner of the grid cell containing point 0111 Field_t get_field (Point_t const& point) const { return get_field(get_indices(point)); } 0112 0113 //! throw if the 3D grid indices are not in the grid and would give an invalid index 0114 void validate_indices (Indices_t const&) const; 0115 //! throw if the point lies outside the grid and would give an invalid index 0116 void validate_point (Point_t const&) const; 0117 0118 //! The most threads will we accomodate before pruning the cache map between calls 0119 static std::size_t const MAX_THREADS = 8; 0120 0121 Indices_t m_N; // Number of points along an axis 0122 Point_t m_D; // Grid spacing of an axis 0123 Point_t m_min; // Minimum value of an axis 0124 Point_t m_max; // Maximum value of an axis 0125 0126 //! The entire fieldmap, loaded into memory (yikes) 0127 //! deque for O(1) access, without requiring contiguous allocation 0128 std::deque<Field_t> m_field; 0129 0130 // Map of thread ids to caches 0131 typedef std::map<std::thread::id, InterpolationCache> map_t; 0132 mutable map_t m_caches; 0133 0134 // mutex for access 0135 mutable std::mutex m_mutex; 0136 };
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|