23 #include <boost/program_options.hpp> 
   25 namespace po = boost::program_options;
 
   40 namespace ActsExamples {
 
   46   opt.add_options()(
"bf-map", po::value<std::string>()->default_value(
""),
 
   47                     "Set this string to point to the bfield source file." 
   48                     "That can either be a '.txt', a '.csv' or a '.root' file. " 
   49                     "Omit for a constant magnetic field.")(
 
   50       "bf-name", po::value<std::string>()->default_value(
"bField"),
 
   51       "In case your field map file is given in root format, please specify " 
   53       "name of the TTree.")(
 
   54       "bf-gridpoints", po::value<size_t>()->default_value(100000),
 
   55       "Estimate of number of grid points, " 
   56       "needed for allocation, only for txt and csv files.")(
 
   57       "bf-lscalor", po::value<double>()->default_value(1.),
 
   58       "The default unit for the grid " 
   59       "points is mm. In case the grid points of your field map has another " 
   60       "unit, please set  the scalor to mm.")(
 
   61       "bf-bscalor", po::value<double>()->default_value(1.),
 
   62       "The default unit for the magnetic field values is Tesla. In case the " 
   63       "grid points of your field map has another unit, please set  the " 
   66       "bf-rz", po::value<bool>()->default_value(
false),
 
   67       "Please set this flag to true, if your grid points and your " 
   68       "magnetic field values are given in 'rz'. The default is 'xyz'.")(
 
   69       "bf-foctant", po::value<bool>()->default_value(
false),
 
   70       "Please set this flag to true, if your field map is only given for the " 
   71       "first octant/quadrant and should be symmetrically created for all " 
   73       "octants/quadrants.")(
 
   75       po::value<read_range>()->multitoken()->default_value({0., 0., 0.}),
 
   76       "In case no magnetic field map is handed over. A constant magnetic " 
   77       "field will be created automatically. The values can be set with this " 
   78       "options. Please hand over the coordinates in cartesian coordinates: " 
   79       "{Bx,By,Bz} in Tesla.")(
 
   80       "bf-context-scalable", po::value<bool>()->default_value(
false),
 
   81       "This is for testing the event dependent magnetic field scaling.");
 
   86   std::string bfieldmap = 
"constfield";
 
   88   enum BFieldMapType { constant = 0, root = 1, text = 2 };
 
   90   std::shared_ptr<InterpolatedBFieldMap2D> map2D = 
nullptr;
 
   91   std::shared_ptr<InterpolatedBFieldMap3D> map3D = 
nullptr;
 
   92   std::shared_ptr<Acts::ConstantBField> mapConst = 
nullptr;
 
   93   std::shared_ptr<ActsExamples::BField::ScalableBField> mapScale = 
nullptr;
 
   95   int bfieldmaptype = constant;
 
   96   if (vm.count(
"bf-map") && vm[
"bf-map"].template as<std::string>() != 
"") {
 
   97     bfieldmap = vm[
"bf-map"].template as<std::string>();
 
   98     std::cout << 
"- read in magnetic field map: " 
   99               << vm[
"bf-map"].template as<std::string>() << std::endl;
 
  100     if (bfieldmap.find(
".root") != std::string::npos) {
 
  101       std::cout << 
"- root format for magnetic field detected" << std::endl;
 
  102       bfieldmaptype = root;
 
  103     } 
else if (bfieldmap.find(
".txt") != std::string::npos ||
 
  104                bfieldmap.find(
".csv") != std::string::npos) {
 
  105       std::cout << 
"- txt format for magnetic field detected" << std::endl;
 
  106       bfieldmaptype = text;
 
  108       std::cout << 
"- magnetic field format could not be detected";
 
  109       std::cout << 
" use '.root', '.txt', or '.csv'." << std::endl;
 
  110       throw std::runtime_error(
"Invalid BField options");
 
  113   if (bfieldmaptype == text && vm.count(
"bf-gridpoints")) {
 
  114     std::cout << 
"- number of points set to: " 
  115               << vm[
"bf-gridpoints"].template as<size_t>() << std::endl;
 
  118   if (bfieldmaptype != constant && vm.count(
"bf-lscalor")) {
 
  119     lscalor = vm[
"bf-lscalor"].template as<double>();
 
  120     std::cout << 
"- length scalor to mm set to: " << lscalor << std::endl;
 
  123   if (vm.count(
"bf-bscalor")) {
 
  124     bscalor = vm[
"bf-bscalor"].template as<double>();
 
  125     std::cout << 
"- BField (scalor to/in) Tesla set to: " << bscalor
 
  128   if (bfieldmaptype != constant && vm[
"bf-rz"].
template as<bool>())
 
  129     std::cout << 
"- BField map is given in 'rz' coordiantes." << std::endl;
 
  130   else if (bfieldmaptype != constant)
 
  131     std::cout << 
"- BField map is given in 'xyz' coordiantes." << std::endl;
 
  133   if (bfieldmaptype != constant && vm[
"bf-foctant"].
template as<bool>()) {
 
  135         << 
"- Only the first octant/quadrant is given, bField map will be " 
  136            "symmetrically created for all other octants/quadrants" 
  145   if (bfieldmaptype == root) {
 
  146     if (vm[
"bf-rz"].
template as<bool>()) {
 
  148           [](std::array<size_t, 2> binsRZ, std::array<size_t, 2> nBinsRZ) {
 
  149             return (binsRZ.at(1) * nBinsRZ.at(0) + binsRZ.at(0));
 
  151           vm[
"bf-map"].template as<std::string>(),
 
  152           vm[
"bf-name"].
template as<std::string>(), lengthUnit, BFieldUnit,
 
  153           vm[
"bf-foctant"].template as<bool>());
 
  157       config2D.
scale = bscalor;
 
  159       return std::make_shared<InterpolatedBFieldMap2D>(std::move(config2D));
 
  163           [](std::array<size_t, 3> binsXYZ, std::array<size_t, 3> nBinsXYZ) {
 
  164             return (binsXYZ.at(0) * (nBinsXYZ.at(1) * nBinsXYZ.at(2)) +
 
  165                     binsXYZ.at(1) * nBinsXYZ.at(2) + binsXYZ.at(2));
 
  167           vm[
"bf-map"].template as<std::string>(),
 
  168           vm[
"bf-name"].
template as<std::string>(), lengthUnit, BFieldUnit,
 
  169           vm[
"bf-foctant"].template as<bool>());
 
  173       config3D.
scale = bscalor;
 
  175       return std::make_shared<InterpolatedBFieldMap3D>(std::move(config3D));
 
  177   } 
else if (bfieldmaptype == text) {
 
  178     if (vm[
"bf-rz"].
template as<bool>()) {
 
  180           [](std::array<size_t, 2> binsRZ, std::array<size_t, 2> nBinsRZ) {
 
  181             return (binsRZ.at(1) * nBinsRZ.at(0) + binsRZ.at(0));
 
  183           vm[
"bf-map"].template as<std::string>(), lengthUnit, BFieldUnit,
 
  184           vm[
"bf-gridpoints"].
template as<size_t>(),
 
  185           vm[
"bf-foctant"].template as<bool>());
 
  189       config2D.
scale = bscalor;
 
  191       return std::make_shared<InterpolatedBFieldMap2D>(std::move(config2D));
 
  195           [](std::array<size_t, 3> binsXYZ, std::array<size_t, 3> nBinsXYZ) {
 
  196             return (binsXYZ.at(0) * (nBinsXYZ.at(1) * nBinsXYZ.at(2)) +
 
  197                     binsXYZ.at(1) * nBinsXYZ.at(2) + binsXYZ.at(2));
 
  199           vm[
"bf-map"].template as<std::string>(), lengthUnit, BFieldUnit,
 
  200           vm[
"bf-gridpoints"].
template as<size_t>(),
 
  201           vm[
"bf-foctant"].template as<bool>());
 
  205       config3D.
scale = bscalor;
 
  207       return std::make_shared<InterpolatedBFieldMap3D>(std::move(config3D));
 
  212     auto bFieldValues = vm[
"bf-values"].template as<read_range>();
 
  213     if (bFieldValues.size() != 3) {
 
  214       throw std::invalid_argument(
 
  215           "- The values handed over for the constant magnetic field " 
  216           "have wrong dimension. Needs to have 3 dimension. Please " 
  217           "hand over the coordinates in cartesian coordinates: " 
  218           "{Bx,By,Bz} in Tesla.");
 
  220     if (vm[
"bf-context-scalable"].
template as<bool>()) {
 
  222       return std::make_shared<ActsExamples::BField::ScalableBField>(
 
  228       return std::make_shared<Acts::ConstantBField>(