Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-10-13 08:18:55

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 CERN for the benefit of the ACTS project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
0008 
0009 #include <boost/test/data/test_case.hpp>
0010 #include <boost/test/unit_test.hpp>
0011 
0012 #include "Acts/Definitions/Units.hpp"
0013 #include "Acts/MagneticField/TextMagneticFieldIo.hpp"
0014 #include "Acts/Utilities/Enumerate.hpp"
0015 #include "ActsTests/CommonHelpers/TemporaryDirectory.hpp"
0016 
0017 #include <fstream>
0018 
0019 namespace bdata = boost::unit_test::data;
0020 
0021 using namespace Acts;
0022 using namespace Acts::UnitLiterals;
0023 
0024 namespace ActsTests {
0025 
0026 BOOST_AUTO_TEST_SUITE(MagneticFieldSuite)
0027 
0028 BOOST_AUTO_TEST_CASE(InterpolatedBFieldMap_rz_from_text) {
0029   TemporaryDirectory tmp{};
0030 
0031   // This tests octant reading, different deliminators, different scales
0032   for (auto fieldScale : {1_T, 1_kGauss}) {
0033     for (auto [id, cdlm] : enumerate(std::vector<std::string>{";", ",", ""})) {
0034       for (auto fOctant : {true, false}) {
0035         std::string fieldName = "rz_magfield" + std::to_string(id) + "_" +
0036                                 std::to_string(static_cast<int>(fOctant)) +
0037                                 "fieldScale" + std::to_string(fieldScale) +
0038                                 ".csv";
0039 
0040         std::string dlm = cdlm.empty() ? " " : cdlm;
0041 
0042         // Write out a simple csv file with r,z,Br,Bz
0043         std::ofstream csvFile(tmp.path() / fieldName);
0044 
0045         // header should be ignored if indicated by %
0046         csvFile << "% r,z,Br,Bz\n";
0047         // header should be ignored if indicated by #
0048         csvFile << "# this is a B-Field file in r/z\n";
0049         // Empty line should be ignored
0050         csvFile << '\n';
0051 
0052         // Innermost r-bin
0053         if (!fOctant) {
0054           csvFile << "0." << dlm << "-2." << dlm << "0." << dlm << "0.2\n";
0055           csvFile << "0." << dlm << "-1." << dlm << "0.1" << dlm << "1.8\n";
0056         }
0057         csvFile << "0." << dlm << "0." << dlm << "0." << dlm << "2.0\n";
0058         csvFile << "0." << dlm << "1." << dlm << "0.1" << dlm << "1.8\n";
0059         csvFile << "0." << dlm << "2." << dlm << "0." << dlm << "0.2\n";
0060         // Middle r bin
0061         if (!fOctant) {
0062           csvFile << "0.5" << dlm << "-2." << dlm << "0." << dlm << "0.1\n";
0063           csvFile << "0.5" << dlm << "-1." << dlm << "0.2" << dlm << "1.7\n";
0064         }
0065         csvFile << "0.5" << dlm << "0." << dlm << "0.1" << dlm << "1.9\n";
0066         csvFile << "0.5" << dlm << "1." << dlm << "0.2" << dlm << "1.7\n";
0067         csvFile << "0.5" << dlm << "2." << dlm << "0." << dlm << "0.1\n";
0068         // Outer r bin
0069         if (!fOctant) {
0070           csvFile << "1." << dlm << "-2." << dlm << "0." << dlm << "0.\n";
0071           csvFile << "1." << dlm << "-1." << dlm << "0.1" << dlm << "1.5\n";
0072         }
0073         csvFile << "1." << dlm << "0." << dlm << "0.1" << dlm << "1.7\n";
0074         csvFile << "1." << dlm << "1." << dlm << "0.2" << dlm << "1.5\n";
0075         csvFile << "1." << dlm << "2." << dlm << "0." << dlm << "0.\n";
0076         csvFile.close();
0077 
0078         auto rzField = makeMagneticFieldMapRzFromText(
0079             [](std::array<std::size_t, 2> binsRZ,
0080                std::array<std::size_t, 2> nBinsRZ) {
0081               return (binsRZ.at(0) * nBinsRZ.at(1) + binsRZ.at(1));
0082             },
0083             tmp.path() / fieldName, 1_mm, fieldScale, fOctant, dlm);
0084 
0085         // Check that the bfield is two dimenstional
0086         auto nBins = rzField.getNBins();
0087         BOOST_CHECK_EQUAL(nBins.size(), 2u);
0088 
0089         // Check number of bins in r and z
0090         BOOST_CHECK_EQUAL(nBins.at(0), 3u);
0091         BOOST_CHECK_EQUAL(nBins.at(1), 5u);
0092 
0093         // Check that the bin edges are correct
0094         auto mins = rzField.getMin();
0095         auto maxs = rzField.getMax();
0096         BOOST_CHECK_EQUAL(mins.size(), 2u);
0097         BOOST_CHECK_EQUAL(maxs.size(), 2u);
0098 
0099         // Get the unchecked field in the middle
0100         auto centralField = rzField.getFieldUnchecked({0., .0, 0.0});
0101         BOOST_CHECK(centralField.isApprox(Vector3(0., 0., 2. * fieldScale)));
0102       }
0103     }
0104   }
0105 }
0106 
0107 BOOST_AUTO_TEST_CASE(InterpolatedBFieldMap_xyz_from_text) {
0108   TemporaryDirectory tmp{};
0109   // This tests octant reading, different deliminators, different scales
0110   for (auto fieldScale : {1_T, 1_kGauss}) {
0111     for (auto [id, cdlm] : enumerate(std::vector<std::string>{";", ",", ""})) {
0112       for (auto fOctant : {true, false}) {
0113         std::string fieldName = "xyz_magfield" + std::to_string(id) + "_" +
0114                                 std::to_string(static_cast<int>(fOctant)) +
0115                                 "fieldScale" + std::to_string(fieldScale) +
0116                                 ".csv";
0117 
0118         std::string dlm = cdlm.empty() ? " " : cdlm;
0119 
0120         // Write out a simple csv file with x,y,z,Bx,By,Bz
0121         std::ofstream csvFile(fieldName);
0122 
0123         // header should be ignored if indicated by %
0124         csvFile << "% x,y,z,Bx,By,Bz\n";
0125         // header should be ignored if indicated by #
0126         csvFile << "# this is a B-Field file in x/y/z\n";
0127         // Empty line should be ignored
0128         csvFile << '\n';
0129 
0130         std::vector<double> xvals = {0., 0.5, 1.};
0131         std::vector<double> yvals = {0., 1., 2.};
0132         std::vector<double> zvals = {0., 1., 2., 3.};
0133         if (!fOctant) {
0134           xvals = {-1., -0.5, 0., 0.5, 1.};
0135           yvals = {-2., -1., 0., 1., 2.};
0136           zvals = {-3., -2., -1., 0., 1., 2., 3.};
0137         }
0138         for (auto xv : xvals) {
0139           for (auto yv : yvals) {
0140             for (auto zv : zvals) {
0141               csvFile << xv << dlm << yv << dlm << zv << dlm << 0. << dlm << 0.
0142                       << dlm << 2.1 - std::abs(zv) * 0.1 << '\n';
0143             }
0144           }
0145         }
0146         csvFile.close();
0147 
0148         auto xyzField = makeMagneticFieldMapXyzFromText(
0149             [](std::array<std::size_t, 3> binsXYZ,
0150                std::array<std::size_t, 3> nBinsXYZ) {
0151               return (binsXYZ.at(0) * nBinsXYZ.at(1) * nBinsXYZ.at(2) +
0152                       binsXYZ.at(1) * nBinsXYZ.at(2) + binsXYZ.at(2));
0153             },
0154             fieldName, 1_mm, fieldScale, true, dlm);
0155 
0156         // Check that the bfield is three-dimenstional
0157         auto nBins = xyzField.getNBins();
0158         BOOST_CHECK_EQUAL(nBins.size(), 3u);
0159       }
0160     }
0161   }
0162 }
0163 
0164 BOOST_AUTO_TEST_SUITE_END()
0165 
0166 }  // namespace ActsTests