EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
InterpolatedBFieldMap.hpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file InterpolatedBFieldMap.hpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2016-2018 CERN for the benefit of the Acts project
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
7 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 
9 #pragma once
10 
15 
16 #include <functional>
17 #include <optional>
18 #include <vector>
19 
20 namespace Acts {
21 
30 template <typename G>
32  public:
33  using Grid_t = G;
34  using FieldType = typename Grid_t::value_type;
35  static constexpr size_t DIM_POS = Grid_t::DIM;
36 
41  struct FieldCell {
43  static constexpr unsigned int N = 1 << DIM_POS;
44 
45  public:
57  FieldCell(std::function<ActsVectorD<DIM_POS>(const Vector3D&)> transformPos,
58  std::array<double, DIM_POS> lowerLeft,
59  std::array<double, DIM_POS> upperRight,
60  std::array<Vector3D, N> fieldValues)
61  : m_transformPos(std::move(transformPos)),
62  m_lowerLeft(std::move(lowerLeft)),
63  m_upperRight(std::move(upperRight)),
64  m_fieldValues(std::move(fieldValues)) {}
65 
73  // defined in Interpolation.hpp
76  }
77 
83  bool isInside(const Vector3D& position) const {
84  const auto& gridCoordinates = m_transformPos(position);
85  for (unsigned int i = 0; i < DIM_POS; ++i) {
86  if (gridCoordinates[i] < m_lowerLeft.at(i) ||
87  gridCoordinates[i] >= m_upperRight.at(i)) {
88  return false;
89  }
90  }
91  return true;
92  }
93 
94  private:
96  std::function<ActsVectorD<DIM_POS>(const Vector3D&)> m_transformPos;
97 
99  std::array<double, DIM_POS> m_lowerLeft;
100 
102  std::array<double, DIM_POS> m_upperRight;
103 
108  std::array<Vector3D, N> m_fieldValues;
109  };
110 
120  std::function<ActsVectorD<DIM_POS>(const Vector3D&)> transformPos,
121  std::function<Vector3D(const FieldType&, const Vector3D&)>
122  transformBField,
123  Grid_t grid)
124  : m_transformPos(std::move(transformPos)),
125  m_transformBField(std::move(transformBField)),
126  m_grid(std::move(grid)) {}
127 
136  return m_transformBField(m_grid.interpolate(m_transformPos(position)),
137  position);
138  }
139 
148  const auto& gridPosition = m_transformPos(position);
149  const auto& indices = m_grid.localBinsFromPosition(gridPosition);
150  const auto& lowerLeft = m_grid.lowerLeftBinEdge(indices);
151  const auto& upperRight = m_grid.upperRightBinEdge(indices);
152 
153  // loop through all corner points
154  constexpr size_t nCorners = 1 << DIM_POS;
155  std::array<Vector3D, nCorners> neighbors;
156  const auto& cornerIndices = m_grid.closestPointsIndices(gridPosition);
157 
158  size_t i = 0;
159  for (size_t index : cornerIndices) {
160  neighbors.at(i++) = m_transformBField(m_grid.at(index), position);
161  }
162 
163  return FieldCell(m_transformPos, lowerLeft, upperRight,
164  std::move(neighbors));
165  }
166 
170  std::vector<size_t> getNBins() const {
171  auto nBinsArray = m_grid.numLocalBins();
172  return std::vector<size_t>(nBinsArray.begin(), nBinsArray.end());
173  }
174 
178  std::vector<double> getMin() const {
179  auto minArray = m_grid.minPosition();
180  return std::vector<double>(minArray.begin(), minArray.end());
181  }
182 
186  std::vector<double> getMax() const {
187  auto maxArray = m_grid.maxPosition();
188  return std::vector<double>(maxArray.begin(), maxArray.end());
189  }
190 
196  bool isInside(const Vector3D& position) const {
197  return m_grid.isInside(m_transformPos(position));
198  }
199 
203  const Grid_t& getGrid() const { return m_grid; }
204 
205  private:
207  std::function<ActsVectorD<DIM_POS>(const Vector3D&)> m_transformPos;
211  std::function<Vector3D(const FieldType&, const Vector3D&)> m_transformBField;
214 };
215 
231 template <typename Mapper_t>
233  public:
235  struct Config {
236  Config(Mapper_t m) : mapper(m) {}
237 
242  double scale = 1.;
243 
249  Mapper_t mapper;
250  };
251 
252  struct Cache {
256  Cache(std::reference_wrapper<const MagneticFieldContext> /*mcfg*/) {}
257 
258  std::optional<typename Mapper_t::FieldCell> fieldCell;
259  bool initialized = false;
260  };
261 
265  InterpolatedBFieldMap(Config config) : m_config(std::move(config)) {}
266 
270  Config getConfiguration() const { return m_config; }
271 
278  return m_config.mapper.getField(position);
279  }
280 
288  Vector3D getField(const Vector3D& position, Cache& cache) const {
289  if (!cache.fieldCell || !(*cache.fieldCell).isInside(position)) {
290  cache.fieldCell = getFieldCell(position);
291  }
292  return (*cache.fieldCell).getField(position);
293  }
294 
304  ActsMatrixD<3, 3>& /*derivative*/) const {
305  return m_config.mapper.getField(position);
306  }
307 
319  ActsMatrixD<3, 3>& /*derivative*/,
320  Cache& /*cache*/) const {
321  return m_config.mapper.getField(position);
322  }
323 
327  double getScale() const { return m_config.scale; }
328 
332  Mapper_t getMapper() const { return m_config.mapper; }
333 
339  bool isInside(const Vector3D& position) const {
340  return m_config.mapper.isInside(position);
341  }
342 
347 
348  private:
356  typename Mapper_t::FieldCell getFieldCell(const Vector3D& position) const {
357  return m_config.mapper.getFieldCell(position);
358  }
359 
362 };
363 
364 } // namespace Acts