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>(