Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-07-26 08:22:17

0001 /** TRACCC library, part of the ACTS project (R&D line)
0002  *
0003  * (c) 2025 CERN for the benefit of the ACTS project
0004  *
0005  * Mozilla Public License Version 2.0
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 // TODO: Remove this when we have logging
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 }