7#include "Acts/Definitions/Algebra.hpp"
8#include "Acts/MagneticField/BFieldMapUtils.hpp"
9#include "Acts/MagneticField/InterpolatedBFieldMap.hpp"
10#include "Acts/MagneticField/MagneticFieldContext.hpp"
11#include "Acts/Utilities/AxisFwd.hpp"
12#include "Acts/Utilities/Grid.hpp"
13#include "Acts/Utilities/Interpolation.hpp"
14#include "Acts/Utilities/Result.hpp"
16static const double DIPOLE_OFFSET = 400.;
18using InterpolatedMagneticField3 = Acts::InterpolatedBFieldMap<
19 Acts::Grid<Acts::Vector3, Acts::Axis<Acts::AxisType::Equidistant>,
20 Acts::Axis<Acts::AxisType::Equidistant>,
21 Acts::Axis<Acts::AxisType::Equidistant>>>;
23using GenericTransformPos = std::function<Acts::Vector3(
const Acts::Vector3&)>;
24using GenericTransformBField =
25 std::function<Acts::Vector3(
const Acts::Vector3&,
const Acts::Vector3&)>;
34Acts::Vector3 default_transformPos(
const Acts::Vector3& pos);
42Acts::Vector3 default_transformBField(
const Acts::Vector3& field,
43 const Acts::Vector3& );
45void testField(
const std::shared_ptr<Acts::MagneticFieldProvider> bfield,
46 const Acts::Vector3& eval_pos,
47 const Acts::MagneticFieldContext& bctx);
54size_t localToGlobalBin_xyz(std::array<size_t, 3> bins,
55 std::array<size_t, 3> sizes);
57inline InterpolatedMagneticField3 rotateFieldMapXYZ(
58 const std::function<
size_t(std::array<size_t, 3> binsXYZ,
59 std::array<size_t, 3> nBinsXYZ)>&
61 std::vector<double> xPos, std::vector<double> yPos,
62 std::vector<double> zPos, std::vector<Acts::Vector3> bField,
63 double lengthUnit,
double BFieldUnit,
bool firstOctant,
64 GenericTransformPos transformPosition,
65 GenericTransformBField transformMagneticField) {
68 std::sort(xPos.begin(), xPos.end());
69 std::sort(yPos.begin(), yPos.end());
70 std::sort(zPos.begin(), zPos.end());
73 xPos.erase(std::unique(xPos.begin(), xPos.end()), xPos.end());
74 yPos.erase(std::unique(yPos.begin(), yPos.end()), yPos.end());
75 zPos.erase(std::unique(zPos.begin(), zPos.end()), zPos.end());
81 size_t nBinsX = xPos.size();
82 size_t nBinsY = yPos.size();
83 size_t nBinsZ = zPos.size();
86 auto minMaxX = std::minmax_element(xPos.begin(), xPos.end());
87 auto minMaxY = std::minmax_element(yPos.begin(), yPos.end());
88 auto minMaxZ = std::minmax_element(zPos.begin(), zPos.end());
91 double xMin = *minMaxX.first;
92 double yMin = *minMaxY.first;
93 double zMin = *minMaxZ.first;
95 double xMax = *minMaxX.second;
96 double yMax = *minMaxY.second;
97 double zMax = *minMaxZ.second;
100 double stepZ = std::fabs(zMax - zMin) / (nBinsZ - 1);
101 double stepY = std::fabs(yMax - yMin) / (nBinsY - 1);
102 double stepX = std::fabs(xMax - xMin) / (nBinsX - 1);
109 xMin = -*minMaxX.second;
110 yMin = -*minMaxY.second;
111 zMin = -*minMaxZ.second;
112 nBinsX = 2 * nBinsX - 1;
113 nBinsY = 2 * nBinsY - 1;
114 nBinsZ = 2 * nBinsZ - 1;
116 Acts::Axis<Acts::AxisType::Equidistant> xAxis(xMin * lengthUnit,
117 xMax * lengthUnit, nBinsX);
118 Acts::Axis<Acts::AxisType::Equidistant> yAxis(yMin * lengthUnit,
119 yMax * lengthUnit, nBinsY);
120 Acts::Axis<Acts::AxisType::Equidistant> zAxis(zMin * lengthUnit,
121 zMax * lengthUnit, nBinsZ);
124 Acts::Grid<Acts::Vector3, Acts::Axis<Acts::AxisType::Equidistant>,
125 Acts::Axis<Acts::AxisType::Equidistant>,
126 Acts::Axis<Acts::AxisType::Equidistant>>;
128 std::make_tuple(std::move(xAxis), std::move(yAxis), std::move(zAxis)));
131 for (
size_t i = 1; i <= nBinsX; ++i) {
132 for (
size_t j = 1; j <= nBinsY; ++j) {
133 for (
size_t k = 1; k <= nBinsZ; ++k) {
134 Grid_t::index_t indices = {{i, j, k}};
135 std::array<size_t, 3> nIndices = {
136 {xPos.size(), yPos.size(), zPos.size()}};
141 size_t m = std::abs(
int(i) - (
int(xPos.size())));
142 size_t n = std::abs(
int(j) - (
int(yPos.size())));
143 size_t l = std::abs(
int(k) - (
int(zPos.size())));
144 Grid_t::index_t indicesFirstOctant = {{m, n, l}};
146 grid.atLocalBins(indices) =
147 bField.at(localToGlobalBin(indicesFirstOctant, nIndices)) *
154 grid.atLocalBins(indices) =
155 bField.at(localToGlobalBin({{i - 1, j - 1, k - 1}}, nIndices)) *
161 grid.setExteriorBins(Acts::Vector3::Zero());
197 return Acts::InterpolatedBFieldMap<Grid_t>(
198 {transformPosition, transformMagneticField, std::move(grid)});
206inline InterpolatedMagneticField3 makeMagneticFieldMapXyzFromText(
207 std::function<
size_t(std::array<size_t, 3> binsXYZ,
208 std::array<size_t, 3> nBinsXYZ)>
210 GenericTransformPos transformPosition,
211 GenericTransformBField transformMagneticField,
212 const std::string& fieldMapFile, Acts::ActsScalar lengthUnit,
213 Acts::ActsScalar BFieldUnit,
bool firstOctant,
bool rotateAxes) {
216 std::vector<double> xPos;
217 std::vector<double> yPos;
218 std::vector<double> zPos;
220 std::vector<Acts::Vector3> bField;
222 constexpr size_t kDefaultSize = 1 << 15;
224 xPos.reserve(kDefaultSize);
225 yPos.reserve(kDefaultSize);
226 zPos.reserve(kDefaultSize);
227 bField.reserve(kDefaultSize);
229 std::ifstream map_file(fieldMapFile.c_str(), std::ios::in);
231 double x = 0., y = 0., z = 0.;
232 double bx = 0., by = 0., bz = 0.;
234 bool headerFound =
false;
236 while (std::getline(map_file, line)) {
237 if (line.empty() || line[0] ==
'%' || line[0] ==
'#' || line[0] ==
' ' ||
238 line.find_first_not_of(
' ') == std::string::npos || !headerFound) {
239 if (line.find(
"Header") != std::string::npos) headerFound =
true;
242 std::istringstream tmp(line);
243 tmp >> x >> y >> z >> bx >> by >> bz;
248 bField.push_back(Acts::Vector3(bx, by, bz));
253 std::cout <<
"MAP LOADING ERROR:: line containing the word 'Header' not "
258 xPos.shrink_to_fit();
259 yPos.shrink_to_fit();
260 zPos.shrink_to_fit();
261 bField.shrink_to_fit();
264 return rotateFieldMapXYZ(localToGlobalBin, xPos, yPos, zPos, bField,
265 lengthUnit, BFieldUnit, firstOctant,
266 transformPosition, transformMagneticField);
268 return Acts::fieldMapXYZ(localToGlobalBin, xPos, yPos, zPos, bField,
269 lengthUnit, BFieldUnit, firstOctant);
272inline InterpolatedMagneticField3 loadDefaultBField(
273 const std::string& fieldMapFile, GenericTransformPos transformPosition,
274 GenericTransformBField transformMagneticField) {
279 return makeMagneticFieldMapXyzFromText(
280 std::move(localToGlobalBin_xyz), transformPosition,
281 transformMagneticField, fieldMapFile,
282 1. * Acts::UnitConstants::mm,
283 1000. * Acts::UnitConstants::T,