File indexing completed on 2025-01-18 09:12:56
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <boost/test/data/test_case.hpp>
0010 #include <boost/test/unit_test.hpp>
0011
0012 #include "Acts/Definitions/Algebra.hpp"
0013 #include "Acts/MagneticField/BFieldMapUtils.hpp"
0014 #include "Acts/MagneticField/InterpolatedBFieldMap.hpp"
0015 #include "Acts/Tests/CommonHelpers/FloatComparisons.hpp"
0016 #include "Acts/Utilities/Result.hpp"
0017 #include "Acts/Utilities/VectorHelpers.hpp"
0018
0019 #include <array>
0020 #include <cstddef>
0021 #include <random>
0022 #include <vector>
0023
0024 namespace bdata = boost::unit_test::data;
0025
0026 using Acts::VectorHelpers::perp;
0027
0028 using namespace Acts::detail;
0029
0030 namespace Acts::Test {
0031
0032 BOOST_AUTO_TEST_CASE(bfield_creation) {
0033
0034 std::vector<double> rPos = {0., 1., 2., 3.};
0035 std::vector<double> xPos = {0., 1., 2., 3.};
0036 std::vector<double> yPos = {0., 1., 2., 3.};
0037 std::vector<double> zPos = {0., 1., 2., 3.};
0038
0039
0040 std::vector<Acts::Vector2> bField_rz;
0041 for (int i = 0; i < 27; i++) {
0042 bField_rz.push_back(Acts::Vector2(i, i));
0043 }
0044
0045 auto localToGlobalBin_rz = [](std::array<std::size_t, 2> binsRZ,
0046 std::array<std::size_t, 2> nBinsRZ) {
0047 return (binsRZ.at(1) * nBinsRZ.at(0) + binsRZ.at(0));
0048 };
0049
0050 auto map_rz =
0051 Acts::fieldMapRZ(localToGlobalBin_rz, rPos, zPos, bField_rz, 1, 1, false);
0052
0053 std::vector<std::size_t> nBins_rz = {rPos.size(), zPos.size()};
0054 std::vector<double> minima_rz = {0., 0.};
0055 std::vector<double> maxima_rz = {3., 3.};
0056 BOOST_CHECK(map_rz.getNBins() == nBins_rz);
0057
0058
0059 BOOST_CHECK(map_rz.getMin() == minima_rz);
0060
0061
0062 BOOST_CHECK(map_rz.getMax() == maxima_rz);
0063
0064 auto localToGlobalBin_xyz = [](std::array<std::size_t, 3> binsXYZ,
0065 std::array<std::size_t, 3> nBinsXYZ) {
0066 return (binsXYZ.at(0) * (nBinsXYZ.at(1) * nBinsXYZ.at(2)) +
0067 binsXYZ.at(1) * nBinsXYZ.at(2) + binsXYZ.at(2));
0068 };
0069
0070 rPos = {0., 1., 2., 3.};
0071 xPos = {0., 1., 2., 3.};
0072 yPos = {0., 1., 2., 3.};
0073 zPos = {0., 1., 2., 3.};
0074
0075
0076 std::vector<Acts::Vector3> bField_xyz;
0077 for (int i = 0; i < 81; i++) {
0078 bField_xyz.push_back(Acts::Vector3(i, i, i));
0079 }
0080
0081
0082 auto map_xyz = Acts::fieldMapXYZ(localToGlobalBin_xyz, xPos, yPos, zPos,
0083 bField_xyz, 1, 1, false);
0084
0085 std::vector<std::size_t> nBins_xyz = {xPos.size(), yPos.size(), zPos.size()};
0086 std::vector<double> minima_xyz = {0., 0., 0.};
0087 std::vector<double> maxima_xyz = {3., 3., 3.};
0088 BOOST_CHECK(map_xyz.getNBins() == nBins_xyz);
0089
0090
0091 BOOST_CHECK(map_xyz.getMin() == minima_xyz);
0092
0093
0094 BOOST_CHECK(map_xyz.getMax() == maxima_xyz);
0095
0096
0097 Acts::Vector3 pos0_rz(0., 0., 0.);
0098 Acts::Vector3 pos1_rz(1., 0., 1.);
0099 Acts::Vector3 pos2_rz(0., 2., 2.);
0100 auto value0_rz = map_rz.getField(pos0_rz).value();
0101 auto value1_rz = map_rz.getField(pos1_rz).value();
0102 auto value2_rz = map_rz.getField(pos2_rz).value();
0103
0104 auto b0_rz =
0105 bField_rz.at(localToGlobalBin_rz({{0, 0}}, {{rPos.size(), zPos.size()}}));
0106 auto b1_rz =
0107 bField_rz.at(localToGlobalBin_rz({{1, 1}}, {{rPos.size(), zPos.size()}}));
0108 auto b2_rz =
0109 bField_rz.at(localToGlobalBin_rz({{2, 2}}, {{rPos.size(), zPos.size()}}));
0110 Acts::Vector3 bField0_rz(b0_rz.x(), 0., b0_rz.y());
0111 Acts::Vector3 bField1_rz(b1_rz.x(), 0., b1_rz.y());
0112 Acts::Vector3 bField2_rz(0., b2_rz.x(), b2_rz.y());
0113
0114
0115 CHECK_CLOSE_ABS(perp(value0_rz), perp(bField0_rz), 1e-9);
0116 CHECK_CLOSE_ABS(value0_rz.z(), bField0_rz.z(), 1e-9);
0117 CHECK_CLOSE_ABS(perp(value1_rz), perp(bField1_rz), 1e-9);
0118 CHECK_CLOSE_ABS(value1_rz.z(), bField1_rz.z(), 1e-9);
0119 CHECK_CLOSE_ABS(perp(value2_rz), perp(bField2_rz), 1e-9);
0120 CHECK_CLOSE_ABS(value2_rz.z(), bField2_rz.z(), 1e-9);
0121
0122
0123 Acts::Vector3 pos0_xyz(0., 0., 0.);
0124 Acts::Vector3 pos1_xyz(1., 1., 1.);
0125 Acts::Vector3 pos2_xyz(2., 2., 2.);
0126 auto value0_xyz = map_xyz.getField(pos0_xyz).value();
0127 auto value1_xyz = map_xyz.getField(pos1_xyz).value();
0128 auto value2_xyz = map_xyz.getField(pos2_xyz).value();
0129
0130 auto b0_xyz = bField_xyz.at(localToGlobalBin_xyz(
0131 {{0, 0, 0}}, {{xPos.size(), yPos.size(), zPos.size()}}));
0132 auto b1_xyz = bField_xyz.at(localToGlobalBin_xyz(
0133 {{1, 1, 1}}, {{xPos.size(), yPos.size(), zPos.size()}}));
0134 auto b2_xyz = bField_xyz.at(localToGlobalBin_xyz(
0135 {{2, 2, 2}}, {{xPos.size(), yPos.size(), zPos.size()}}));
0136
0137 BOOST_CHECK_EQUAL(value0_xyz, b0_xyz);
0138 BOOST_CHECK_EQUAL(value1_xyz, b1_xyz);
0139 BOOST_CHECK_EQUAL(value2_xyz, b2_xyz);
0140
0141
0142
0143 CHECK_CLOSE_ABS(value0_xyz, b0_xyz, 1e-9);
0144 CHECK_CLOSE_ABS(value1_xyz, b1_xyz, 1e-9);
0145 CHECK_CLOSE_ABS(value2_xyz, b2_xyz, 1e-9);
0146 }
0147
0148 BOOST_AUTO_TEST_CASE(bfield_symmetry) {
0149
0150 std::vector<double> rPos = {0., 1., 2.};
0151 std::vector<double> xPos = {0., 1., 2.};
0152 std::vector<double> yPos = {0., 1., 2.};
0153 std::vector<double> zPos = {0., 1., 2.};
0154
0155 std::vector<Acts::Vector2> bField_rz;
0156 for (int i = 0; i < 9; i++) {
0157 bField_rz.push_back(Acts::Vector2(i, i));
0158 }
0159
0160 auto map_rz = Acts::fieldMapRZ(
0161 [](std::array<std::size_t, 2> binsRZ,
0162 std::array<std::size_t, 2> nBinsRZ) {
0163 return (binsRZ.at(1) * nBinsRZ.at(0) + binsRZ.at(0));
0164 },
0165 rPos, zPos, bField_rz, 1, 1, true);
0166
0167
0168 std::vector<std::size_t> nBins_rz = {rPos.size(), 2 * zPos.size() - 1};
0169 std::vector<double> minima_rz = {0., -2.};
0170 std::vector<double> maxima_rz = {2., 2.};
0171 BOOST_CHECK(map_rz.getNBins() == nBins_rz);
0172 auto vec = map_rz.getNBins();
0173 auto vec0 = map_rz.getMin();
0174
0175
0176 BOOST_CHECK(map_rz.getMin() == minima_rz);
0177
0178
0179 BOOST_CHECK(map_rz.getMax() == maxima_rz);
0180
0181
0182 std::vector<Acts::Vector3> bField_xyz;
0183 for (int i = 0; i < 27; i++) {
0184 bField_xyz.push_back(Acts::Vector3(i, i, i));
0185 }
0186
0187 auto map_xyz = Acts::fieldMapXYZ(
0188 [](std::array<std::size_t, 3> binsXYZ,
0189 std::array<std::size_t, 3> nBinsXYZ) {
0190 return (binsXYZ.at(0) * (nBinsXYZ.at(1) * nBinsXYZ.at(2)) +
0191 binsXYZ.at(1) * nBinsXYZ.at(2) + binsXYZ.at(2));
0192 },
0193 xPos, yPos, zPos, bField_xyz, 1, 1, true);
0194
0195
0196 std::vector<std::size_t> nBins_xyz = {
0197 2 * xPos.size() - 1, 2 * yPos.size() - 1, 2 * zPos.size() - 1};
0198 std::vector<double> minima_xyz = {-2., -2., -2.};
0199 std::vector<double> maxima_xyz = {2., 2., 2.};
0200 BOOST_CHECK(map_xyz.getNBins() == nBins_xyz);
0201
0202
0203 BOOST_CHECK(map_xyz.getMin() == minima_xyz);
0204
0205
0206 BOOST_CHECK(map_xyz.getMax() == maxima_xyz);
0207
0208 Acts::Vector3 pos0(1.2, 1.3, 1.4);
0209 Acts::Vector3 pos1(1.2, 1.3, -1.4);
0210 Acts::Vector3 pos2(-1.2, 1.3, 1.4);
0211 Acts::Vector3 pos3(1.2, -1.3, 1.4);
0212 Acts::Vector3 pos4(-1.2, -1.3, 1.4);
0213
0214 auto value0_rz = map_rz.getField(pos0).value();
0215 auto value1_rz = map_rz.getField(pos1).value();
0216 auto value2_rz = map_rz.getField(pos2).value();
0217 auto value3_rz = map_rz.getField(pos3).value();
0218 auto value4_rz = map_rz.getField(pos4).value();
0219
0220 auto value0_xyz = map_xyz.getField(pos0).value();
0221 auto value1_xyz = map_xyz.getField(pos1).value();
0222 auto value2_xyz = map_xyz.getField(pos2).value();
0223 auto value3_xyz = map_xyz.getField(pos3).value();
0224 auto value4_xyz = map_xyz.getField(pos4).value();
0225
0226
0227 CHECK_CLOSE_REL(perp(value0_rz), perp(value1_rz), 1e-10);
0228 CHECK_CLOSE_REL(value0_rz.z(), value1_rz.z(), 1e-10);
0229 CHECK_CLOSE_REL(perp(value0_rz), perp(value2_rz), 1e-10);
0230 CHECK_CLOSE_REL(value0_rz.z(), value2_rz.z(), 1e-10);
0231 CHECK_CLOSE_REL(perp(value0_rz), perp(value3_rz), 1e-10);
0232 CHECK_CLOSE_REL(value0_rz.z(), value3_rz.z(), 1e-10);
0233 CHECK_CLOSE_REL(perp(value0_rz), perp(value4_rz), 1e-10);
0234 CHECK_CLOSE_REL(value0_rz.z(), value4_rz.z(), 1e-10);
0235
0236
0237
0238 CHECK_CLOSE_REL(value0_xyz, value1_xyz, 1e-10);
0239 CHECK_CLOSE_REL(value0_xyz, value2_xyz, 1e-10);
0240 CHECK_CLOSE_REL(value0_xyz, value3_xyz, 1e-10);
0241 CHECK_CLOSE_REL(value0_xyz, value4_xyz, 1e-10);
0242 }
0243
0244
0245 BOOST_DATA_TEST_CASE(
0246 bfield_symmetry_random,
0247 bdata::random((bdata::engine = std::mt19937(), bdata::seed = 0,
0248 bdata::distribution =
0249 std::uniform_real_distribution<double>(-10., 10.))) ^
0250 bdata::random((bdata::engine = std::mt19937(), bdata::seed = 0,
0251 bdata::distribution =
0252 std::uniform_real_distribution<double>(-10., 10.))) ^
0253 bdata::random((bdata::engine = std::mt19937(), bdata::seed = 0,
0254 bdata::distribution =
0255 std::uniform_real_distribution<double>(-20., 20.))) ^
0256 bdata::xrange(10),
0257 x, y, z, index) {
0258 (void)index;
0259
0260 std::vector<double> rPos;
0261 std::vector<double> xPos;
0262 std::vector<double> yPos;
0263 std::vector<double> zPos;
0264 double maxR = 20.;
0265 double maxZ = 30.;
0266 double maxBr = 10.;
0267 double maxBz = 20.;
0268 std::size_t nBins = 10;
0269 double stepR = maxR / nBins;
0270 double stepZ = maxZ / nBins;
0271 double bStepR = maxBr / nBins;
0272 double bStepZ = maxBz / nBins;
0273
0274 for (std::size_t i = 0; i < nBins; i++) {
0275 rPos.push_back(i * stepR);
0276 xPos.push_back(i * stepR);
0277 yPos.push_back(i * stepR);
0278 zPos.push_back(i * stepZ);
0279 }
0280
0281 std::vector<Acts::Vector2> bField_rz;
0282 for (std::size_t i = 0; i < nBins * nBins; i++) {
0283 bField_rz.push_back(Acts::Vector2(i * bStepR, i * bStepZ));
0284 }
0285
0286 auto map_rz = Acts::fieldMapRZ(
0287 [](std::array<std::size_t, 2> binsRZ,
0288 std::array<std::size_t, 2> nBinsRZ) {
0289 return (binsRZ.at(1) * nBinsRZ.at(0) + binsRZ.at(0));
0290 },
0291 rPos, zPos, bField_rz, 1, 1, true);
0292
0293
0294 std::vector<std::size_t> nBins_rz = {rPos.size(), 2 * zPos.size() - 1};
0295 std::vector<double> minima_rz = {0., -((nBins - 1) * stepZ)};
0296 std::vector<double> maxima_rz = {(nBins - 1) * stepR, (nBins - 1) * stepZ};
0297 BOOST_CHECK(map_rz.getNBins() == nBins_rz);
0298
0299
0300 CHECK_CLOSE_ABS(map_rz.getMin(), minima_rz, 1e-10);
0301
0302
0303 CHECK_CLOSE_ABS(map_rz.getMax(), maxima_rz, 1e-10);
0304
0305
0306 std::vector<Acts::Vector3> bField_xyz;
0307 for (std::size_t i = 0; i < nBins * nBins * nBins; i++) {
0308 bField_xyz.push_back(Acts::Vector3(i * bStepR, i * bStepR, i * bStepZ));
0309 }
0310
0311 auto map_xyz = Acts::fieldMapXYZ(
0312 [](std::array<std::size_t, 3> binsXYZ,
0313 std::array<std::size_t, 3> nBinsXYZ) {
0314 return (binsXYZ.at(0) * (nBinsXYZ.at(1) * nBinsXYZ.at(2)) +
0315 binsXYZ.at(1) * nBinsXYZ.at(2) + binsXYZ.at(2));
0316 },
0317 xPos, yPos, zPos, bField_xyz, 1, 1, true);
0318
0319 std::vector<std::size_t> nBins_xyz = {
0320 2 * xPos.size() - 1, 2 * yPos.size() - 1, 2 * zPos.size() - 1};
0321 std::vector<double> minima_xyz = {
0322 -((nBins - 1) * stepR), -((nBins - 1) * stepR), -((nBins - 1) * stepZ)};
0323 std::vector<double> maxima_xyz = {(nBins - 1) * stepR, (nBins - 1) * stepR,
0324 (nBins - 1) * stepZ};
0325 BOOST_CHECK(map_xyz.getNBins() == nBins_xyz);
0326
0327
0328 CHECK_CLOSE_REL(map_xyz.getMin(), minima_xyz, 1e-10);
0329
0330
0331 CHECK_CLOSE_REL(map_xyz.getMax(), maxima_xyz, 1e-10);
0332
0333 Acts::Vector3 pos0(x, y, z);
0334 Acts::Vector3 pos1(x, y, -z);
0335 Acts::Vector3 pos2(-x, y, z);
0336 Acts::Vector3 pos3(x, -y, z);
0337 Acts::Vector3 pos4(-x, -y, z);
0338
0339 auto value0_rz = map_rz.getField(pos0).value();
0340 auto value1_rz = map_rz.getField(pos1).value();
0341 auto value2_rz = map_rz.getField(pos2).value();
0342 auto value3_rz = map_rz.getField(pos3).value();
0343 auto value4_rz = map_rz.getField(pos4).value();
0344
0345
0346 CHECK_CLOSE_REL(perp(value0_rz), perp(value1_rz), 1e-10);
0347 CHECK_CLOSE_REL(value0_rz.z(), value1_rz.z(), 1e-10);
0348 CHECK_CLOSE_REL(perp(value0_rz), perp(value2_rz), 1e-10);
0349 CHECK_CLOSE_REL(value0_rz.z(), value2_rz.z(), 1e-10);
0350 CHECK_CLOSE_REL(perp(value0_rz), perp(value3_rz), 1e-10);
0351 CHECK_CLOSE_REL(value0_rz.z(), value3_rz.z(), 1e-10);
0352 CHECK_CLOSE_REL(perp(value0_rz), perp(value4_rz), 1e-10);
0353 CHECK_CLOSE_REL(value0_rz.z(), value4_rz.z(), 1e-10);
0354
0355 auto value0_xyz = map_xyz.getField(pos0).value();
0356 auto value1_xyz = map_xyz.getField(pos1).value();
0357 auto value2_xyz = map_xyz.getField(pos2).value();
0358 auto value3_xyz = map_xyz.getField(pos3).value();
0359 auto value4_xyz = map_xyz.getField(pos4).value();
0360
0361
0362
0363 CHECK_CLOSE_REL(value0_xyz, value1_xyz, 1e-10);
0364 CHECK_CLOSE_REL(value0_xyz, value2_xyz, 1e-10);
0365 CHECK_CLOSE_REL(value0_xyz, value3_xyz, 1e-10);
0366 CHECK_CLOSE_REL(value0_xyz, value4_xyz, 1e-10);
0367 }
0368
0369 }