File indexing completed on 2026-07-26 08:22:17
0001
0002
0003
0004
0005
0006
0007
0008 #include <fstream>
0009 #include <stdexcept>
0010
0011 #include <boost/program_options.hpp>
0012
0013 #include "bfield_type.hpp"
0014 #include "traccc/definitions/common.hpp"
0015
0016
0017 #define TRACCC_INFO(x) \
0018 do { \
0019 std::cout << "INFO : " << x << std::endl; \
0020 } while (0)
0021 #define TRACCC_FATAL(x) \
0022 do { \
0023 std::cout << "FATAL : " << x << std::endl; \
0024 } while (0)
0025
0026 void parse_opts(int argc, char* argv[],
0027 boost::program_options::variables_map& vm) {
0028 boost::program_options::options_description opts("general options");
0029
0030 opts.add_options()("help", "produce help message")(
0031 "size,s",
0032 boost::program_options::value<std::string>()->required()->default_value(
0033 "big"),
0034 "size of bfield to generate [big or small]")(
0035 "output,o", boost::program_options::value<std::string>()->required(),
0036 "output magnetic field to write");
0037
0038 boost::program_options::parsed_options parsed =
0039 boost::program_options::command_line_parser(argc, argv)
0040 .options(opts)
0041 .run();
0042
0043 boost::program_options::store(parsed, vm);
0044
0045 if (vm.count("help")) {
0046 std::cout << opts << std::endl;
0047 std::exit(0);
0048 }
0049
0050 try {
0051 boost::program_options::notify(vm);
0052 } catch (boost::program_options::required_option& e) {
0053 TRACCC_FATAL(e.what());
0054 std::exit(1);
0055 }
0056 }
0057
0058 field_t create_bfield(bool small) {
0059 float minx = -10000.f;
0060 float maxx = 10000.f;
0061 float miny = -10000.f;
0062 float maxy = 10000.f;
0063 float minz = -15000.f;
0064 float maxz = 15000.f;
0065
0066 TRACCC_INFO("Field dimensions in x = [" << minx << ", " << maxx << "]");
0067 TRACCC_INFO("Field dimensions in y = [" << miny << ", " << maxy << "]");
0068 TRACCC_INFO("Field dimensions in z = [" << minz << ", " << maxz << "]");
0069
0070 std::size_t sx, sy, sz;
0071
0072 if (small) {
0073 sx = 2;
0074 sy = 2;
0075 sz = 2;
0076 } else {
0077 TRACCC_INFO("Assuming sample spacing of 100.0 in each dimension");
0078 sx = static_cast<std::size_t>(std::lround((maxx - minx) / 100.0)) + 1;
0079 sy = static_cast<std::size_t>(std::lround((maxy - miny) / 100.0)) + 1;
0080 sz = static_cast<std::size_t>(std::lround((maxz - minz) / 100.0)) + 1;
0081 }
0082
0083 TRACCC_INFO("Magnetic field size is " << sx << "x" << sy << "x" << sz);
0084
0085 TRACCC_INFO("Filling vector field...");
0086
0087 covfie::algebra::affine<3> translation =
0088 covfie::algebra::affine<3>::translation(-minx, -miny, -minz);
0089
0090 float sfx = static_cast<float>(sx - 1) / (maxx - minx);
0091 float sfy = static_cast<float>(sy - 1) / (maxy - miny);
0092 float sfz = static_cast<float>(sz - 1) / (maxz - minz);
0093
0094 covfie::algebra::affine<3> scaling =
0095 covfie::algebra::affine<3>::scaling(sfx, sfy, sfz);
0096
0097 field_t field(covfie::make_parameter_pack(
0098 field_t::backend_t::configuration_t(scaling * translation),
0099 field_t::backend_t::backend_t::configuration_t{},
0100 field_t::backend_t::backend_t::backend_t::configuration_t{sx, sy, sz}));
0101 field_t::view_t fv(field);
0102
0103 std::size_t n_points = 0;
0104
0105 for (std::size_t xi = 0; xi < sx; ++xi) {
0106 for (std::size_t yi = 0; yi < sy; ++yi) {
0107 for (std::size_t zi = 0; zi < sz; ++zi) {
0108 float xp = -minx + (static_cast<float>(xi) * sfx);
0109 float yp = -miny + (static_cast<float>(yi) * sfy);
0110 float zp = -minz + (static_cast<float>(zi) * sfz);
0111
0112 field_t::view_t::output_t& p = fv.at(xp, yp, zp);
0113
0114 p[0] = 0.f;
0115 p[1] = 0.f;
0116 p[2] = 1.99724f * traccc::unit<float>::T;
0117
0118 n_points++;
0119 }
0120 }
0121 }
0122
0123 TRACCC_INFO("Set " << n_points << " magnetic field points");
0124
0125 return field;
0126 }
0127
0128 int main(int argc, char** argv) {
0129 boost::program_options::variables_map vm;
0130 parse_opts(argc, argv, vm);
0131
0132 TRACCC_INFO("Welcome to the traccc magnetic field converter!");
0133 TRACCC_INFO("Starting creation of magnetic field...");
0134
0135 bool small;
0136
0137 if (vm["size"].as<std::string>() == "small") {
0138 small = true;
0139 } else if (vm["size"].as<std::string>() == "big") {
0140 small = false;
0141 } else {
0142 throw std::runtime_error("Size is neither \"big\" nor \"small\"");
0143 }
0144
0145 field_t fb = create_bfield(small);
0146
0147 TRACCC_INFO("Writing magnetic field to file \""
0148 << vm["output"].as<std::string>() << "\"...");
0149
0150 std::ofstream fs(vm["output"].as<std::string>(), std::ofstream::binary);
0151
0152 if (!fs.good()) {
0153 TRACCC_FATAL("Failed to open output file " << vm["output"].as<std::string>()
0154 << "!");
0155 std::exit(1);
0156 }
0157
0158 fb.dump(fs);
0159
0160 fs.close();
0161
0162 TRACCC_INFO("Conversion complete, goodbye!");
0163
0164 return 0;
0165 }