Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
BFieldAccessExample.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file BFieldAccessExample.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2017-2021 CERN for the benefit of the Acts project
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
7 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 
15 
16 #include <random>
17 #include <string>
18 
19 #include <boost/program_options.hpp>
20 
21 #if ((BOOST_VERSION / 100) % 1000) <= 71
22 // Boost <=1.71 and lower do not have progress_display.hpp as a replacement yet
23 #include <boost/progress.hpp>
25 #else
26 // Boost >=1.72 can use this as a replacement
27 #include <boost/timer/progress_display.hpp>
29 #endif
30 
37 
38 namespace po = boost::program_options;
39 
40 using UniformDist = std::uniform_real_distribution<double>;
41 using RandomEngine = std::mt19937;
42 
44  const Acts::MagneticFieldContext& bFieldContext,
45  size_t events, size_t theta_steps, double theta_0,
46  double theta_step, size_t phi_steps, double phi_0,
47  double phi_step, size_t access_steps, double access_step) {
48  std::cout << "[>>>] Start: step-wise access pattern ... " << std::endl;
49  // initialize the field cache
50  auto bCache = bField.makeCache(bFieldContext);
51  // boost display
52  size_t totalSteps = events * theta_steps * phi_steps * access_steps;
53  progress_display show_progress(totalSteps);
54  // the event loop
55  // loop over the events - @todo move to parallel for
56  for (size_t ievt = 0; ievt < events; ++ievt) {
57  for (size_t itheta = 0; itheta < theta_steps; ++itheta) {
58  double theta = theta_0 + itheta * theta_step;
59  for (size_t iphi = 0; iphi < phi_steps; ++iphi) {
60  double phi = phi_0 + iphi * phi_step;
61  // make a direction
62  Acts::Vector3 dir(cos(phi) * sin(theta), sin(phi) * sin(theta),
63  cos(theta));
64  // check for the current step
65  double currentStep = 0.;
66  // now step through the magnetic field
67  for (size_t istep = 0; istep < access_steps; ++istep) {
68  Acts::Vector3 position = currentStep * dir;
69  // access the field with the cell
70  auto field_from_cache = bField.getField(position, bCache);
71  (void)field_from_cache; // we don't use this explicitly
72  // increase the step
73  currentStep += access_step;
74  // show the progress bar
75  ++show_progress;
76  }
77  }
78  }
79  std::cout << "[<<<] End result: total steps:" << totalSteps << std::endl;
80  }
81 }
82 
84  const Acts::MagneticFieldContext& bFieldContext,
85  size_t totalSteps, double radius) {
86  std::cout << "[>>>] Start: random access pattern ... " << std::endl;
88  UniformDist xDist(-radius, radius);
89  UniformDist yDist(-radius, radius);
90  UniformDist zDist(-radius, radius);
91 
92  // initialize the field cache
93  auto bCache = bField.makeCache(bFieldContext);
94  progress_display show_progress(totalSteps);
95 
96  // the event loop
97  // loop over the events - @todo move to parallel for
98  for (size_t istep = 0; istep < totalSteps; ++istep) {
99  Acts::Vector3 position(xDist(rng), yDist(rng), zDist(rng));
100  // access the field with the cell
101  auto field_from_cache = bField.getField(position, bCache);
102  (void)field_from_cache; // we don't use this explicitly
103  // show the progress bar
104  ++show_progress;
105  }
106  std::cout << "[<<<] End result: total steps: " << totalSteps << std::endl;
107 }
108 
113 int main(int argc, char* argv[]) {
114  // Declare the supported program options.
118  desc.add_options()(
119  "bf-phi-range",
120  po::value<ActsExamples::Options::Reals<2>>()->default_value(
121  {{-M_PI, M_PI}}),
122  "range in which the phi parameter is generated.")(
123  "bf-theta-range",
124  po::value<ActsExamples::Options::Reals<2>>()->default_value({{0., M_PI}}),
125  "range in which the eta parameter is generated.")(
126  "bf-phisteps", po::value<size_t>()->default_value(1000),
127  "number of steps for the phi parameter.")(
128  "bf-thetasteps", po::value<size_t>()->default_value(100),
129  "number of steps for the eta parameter.")(
130  "bf-accesssteps", po::value<size_t>()->default_value(100),
131  "number of steps for magnetic field access.")(
132  "bf-tracklength", po::value<double>()->default_value(100.),
133  "track length in [mm] magnetic field access.");
134  auto vm = ActsExamples::Options::parse(desc, argc, argv);
135  if (vm.empty()) {
136  return EXIT_FAILURE;
137  }
138 
139  // A test magnetic field context
141 
142  // TODO
143  // Why does this need number-of-events? If it really does emulate
144  // per-event access patterns this should be switched to a proper
145  // Sequencer-based tool. Otherwise it should be removed.
148 
149  // Get the phi and eta range
150  auto phir = vm["bf-phi-range"].as<ActsExamples::Options::Reals<2>>();
151  auto thetar = vm["bf-theta-range"].as<ActsExamples::Options::Reals<2>>();
152  // Get the granularity
153  size_t phi_steps = vm["bf-phisteps"].as<size_t>();
154  size_t theta_steps = vm["bf-thetasteps"].as<size_t>();
155  // The defaults
156  size_t access_steps = vm["bf-accesssteps"].as<size_t>();
157  double track_length =
158  vm["bf-tracklength"].as<double>() * Acts::UnitConstants::mm;
159  // sort the ranges - and prepare the access grid
160  std::sort(phir.begin(), phir.end());
161  std::sort(thetar.begin(), thetar.end());
162  double phi_span = std::abs(phir[1] - phir[0]);
163  double phi_step = phi_span / phi_steps;
164  double theta_span = std::abs(thetar[1] - thetar[0]);
165  double theta_step = theta_span / theta_steps;
166  double access_step = track_length / access_steps;
167 
168  accessStepWise(*bField, magFieldContext, nEvents, theta_steps, thetar[0],
169  theta_step, phi_steps, phir[0], phi_step, access_steps,
170  access_step);
171 
172  accessRandom(*bField, magFieldContext,
173  nEvents * theta_steps * phi_steps * access_steps, track_length);
174  return EXIT_SUCCESS;
175 }