25 std::array<size_t, 2> nBinsRZ)>&
27 std::vector<double> rPos, std::vector<double> zPos,
28 std::vector<Acts::Vector2D>
bField,
double lengthUnit,
29 double BFieldUnit,
bool firstQuadrant) {
32 std::sort(rPos.begin(), rPos.end());
33 std::sort(zPos.begin(), zPos.end());
35 rPos.erase(std::unique(rPos.begin(), rPos.end()), rPos.end());
36 zPos.erase(std::unique(zPos.begin(), zPos.end()), zPos.end());
40 size_t nBinsR = rPos.size();
41 size_t nBinsZ = zPos.size();
44 auto minMaxR = std::minmax_element(rPos.begin(), rPos.end());
45 auto minMaxZ = std::minmax_element(zPos.begin(), zPos.end());
46 double rMin = *minMaxR.first;
47 double zMin = *minMaxZ.first;
48 double rMax = *minMaxR.second;
49 double zMax = *minMaxZ.second;
52 double stepZ = std::fabs(zMax - zMin) / (nBinsZ - 1);
53 double stepR = std::fabs(rMax - rMin) / (nBinsR - 1);
57 zMin = -(*minMaxZ.second);
58 nBinsZ = 2. * nBinsZ - 1;
70 Acts::detail::EquidistantAxis>;
71 Grid_t grid(std::make_tuple(std::move(rAxis), std::move(zAxis)));
74 for (
size_t i = 1; i <=
nBinsR; ++i) {
75 for (
size_t j = 1; j <=
nBinsZ; ++j) {
76 std::array<size_t, 2> nIndices = {{rPos.size(), zPos.size()}};
77 Grid_t::index_t indices = {{i, j}};
82 size_t n =
std::abs(
int(j) -
int(zPos.size()));
83 Grid_t::index_t indicesFirstQuadrant = {{i - 1, n}};
85 grid.atLocalBins(indices) =
86 bField.at(localToGlobalBin(indicesFirstQuadrant, nIndices)) *
92 grid.atLocalBins(indices) =
93 bField.at(localToGlobalBin({{i - 1, j - 1}}, nIndices)) *
98 grid.setExteriorBins(Acts::Vector2D::Zero());
108 auto transformBField = [](
const Acts::Vector2D& field,
110 double r_sin_theta_2 =
pos.x() *
pos.x() +
pos.y() *
pos.y();
111 double cos_phi, sin_phi;
113 double inv_r_sin_theta = 1. / sqrt(r_sin_theta_2);
114 cos_phi =
pos.x() * inv_r_sin_theta;
115 sin_phi =
pos.y() * inv_r_sin_theta;
120 return Acts::Vector3D(field.x() * cos_phi, field.x() * sin_phi, field.y());
133 const std::function<
size_t(std::array<size_t, 3> binsXYZ,
134 std::array<size_t, 3> nBinsXYZ)>&
136 std::vector<double> xPos, std::vector<double> yPos,
137 std::vector<double> zPos, std::vector<Acts::Vector3D>
bField,
138 double lengthUnit,
double BFieldUnit,
bool firstOctant) {
141 std::sort(xPos.begin(), xPos.end());
142 std::sort(yPos.begin(), yPos.end());
143 std::sort(zPos.begin(), zPos.end());
145 xPos.erase(std::unique(xPos.begin(), xPos.end()), xPos.end());
146 yPos.erase(std::unique(yPos.begin(), yPos.end()), yPos.end());
147 zPos.erase(std::unique(zPos.begin(), zPos.end()), zPos.end());
148 xPos.shrink_to_fit();
149 yPos.shrink_to_fit();
150 zPos.shrink_to_fit();
152 size_t nBinsX = xPos.size();
153 size_t nBinsY = yPos.size();
154 size_t nBinsZ = zPos.size();
157 auto minMaxX = std::minmax_element(xPos.begin(), xPos.end());
158 auto minMaxY = std::minmax_element(yPos.begin(), yPos.end());
159 auto minMaxZ = std::minmax_element(zPos.begin(), zPos.end());
162 double xMin = *minMaxX.first;
163 double yMin = *minMaxY.first;
164 double zMin = *minMaxZ.first;
166 double xMax = *minMaxX.second;
167 double yMax = *minMaxY.second;
168 double zMax = *minMaxZ.second;
171 double stepZ = std::fabs(zMax - zMin) / (nBinsZ - 1);
172 double stepY = std::fabs(yMax - yMin) / (nBinsY - 1);
173 double stepX = std::fabs(xMax - xMin) / (nBinsX - 1);
180 xMin = -*minMaxX.second;
181 yMin = -*minMaxY.second;
182 zMin = -*minMaxZ.second;
183 nBinsX = 2 * nBinsX - 1;
184 nBinsY = 2 * nBinsY - 1;
185 nBinsZ = 2 * nBinsZ - 1;
187 Acts::detail::EquidistantAxis xAxis(xMin * lengthUnit, xMax * lengthUnit,
189 Acts::detail::EquidistantAxis yAxis(yMin * lengthUnit, yMax * lengthUnit,
191 Acts::detail::EquidistantAxis zAxis(zMin * lengthUnit, zMax * lengthUnit,
197 Acts::detail::EquidistantAxis>;
199 std::make_tuple(std::move(xAxis), std::move(yAxis), std::move(zAxis)));
202 for (
size_t i = 1; i <= nBinsX; ++i) {
203 for (
size_t j = 1; j <= nBinsY; ++j) {
205 Grid_t::index_t indices = {{i, j,
k}};
206 std::array<size_t, 3> nIndices = {
207 {xPos.size(), yPos.size(), zPos.size()}};
212 size_t m =
std::abs(
int(i) - (
int(xPos.size())));
213 size_t n =
std::abs(
int(j) - (
int(yPos.size())));
214 size_t l =
std::abs(
int(
k) - (
int(zPos.size())));
215 Grid_t::index_t indicesFirstOctant = {{
m,
n, l}};
217 grid.atLocalBins(indices) =
218 bField.at(localToGlobalBin(indicesFirstOctant, nIndices)) *
225 grid.atLocalBins(indices) =
226 bField.at(localToGlobalBin({{i - 1, j - 1,
k - 1}}, nIndices)) *
232 grid.setExteriorBins(Acts::Vector3D::Zero());
236 auto transformPos = [](
const Acts::Vector3D&
pos) {
return pos; };
240 auto transformBField = [](
const Acts::Vector3D& field,
241 const Acts::Vector3D& ) {
return field; };
251 Acts::detail::EquidistantAxis>>
253 std::pair<double, double> zlim,
254 std::pair<size_t, size_t> nbins,
256 double rMin, rMax, zMin, zMax;
257 std::tie(rMin, rMax) = rlim;
258 std::tie(zMin, zMax) = zlim;
261 std::tie(nBinsR, nBinsZ) = nbins;
263 double stepZ =
std::abs(zMax - zMin) / (nBinsZ - 1);
264 double stepR =
std::abs(rMax - rMin) / (nBinsR - 1);
270 Acts::detail::EquidistantAxis rAxis(rMin, rMax, nBinsR);
271 Acts::detail::EquidistantAxis zAxis(zMin, zMax, nBinsZ);
276 Acts::detail::EquidistantAxis>;
277 Grid_t grid(std::make_tuple(std::move(rAxis), std::move(zAxis)));
281 auto transformPos = [](
const Acts::Vector3D&
pos) {
287 auto transformBField = [](
const Acts::Vector2D& bfield,
288 const Acts::Vector3D&
pos) {
289 double r_sin_theta_2 =
pos.x() *
pos.x() +
pos.y() *
pos.y();
290 double cos_phi, sin_phi;
292 double inv_r_sin_theta = 1. / sqrt(r_sin_theta_2);
293 cos_phi =
pos.x() * inv_r_sin_theta;
294 sin_phi =
pos.y() * inv_r_sin_theta;
305 for (
size_t i = 0; i <= nBinsR + 1; i++) {
306 for (
size_t j = 0; j <= nBinsZ + 1; j++) {
307 Grid_t::index_t index({i, j});
308 if (i == 0 || j == 0 || i == nBinsR + 1 || j == nBinsZ + 1) {
313 Grid_t::point_t lowerLeft = grid.lowerLeftBinEdge(index);
316 grid.atLocalBins(index) = B;