Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
AnnulusBoundsBenchmark.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file AnnulusBoundsBenchmark.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2017-2018 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 
14 
15 #include <algorithm>
16 #include <chrono>
17 #include <fstream>
18 #include <functional>
19 #include <iostream>
20 #include <random>
21 #include <vector>
22 
23 using namespace Acts;
24 
25 int main(int /*argc*/, char** /*argv[]*/) {
26  std::mt19937 rng(42);
27  std::uniform_real_distribution<double> xDist(-2, 20);
28  std::uniform_real_distribution<double> yDist(-2, 20);
29 
30  std::ofstream os{"annulus.csv"};
31  os << "x,y,inside_abs,inside_tol0,inside_tol1,inside_tol01,inside_cov"
32  << std::endl;
33 
34  // === PROBLEM DATA ===
35 
36  // bounds definition
37  double minRadius = 7.2;
38  double maxRadius = 12.0;
39  double minPhi = 0.74195;
40  double maxPhi = 1.33970;
41  Vector2 offset(-2., 2.);
42  AnnulusBounds aBounds(minRadius, maxRadius, minPhi, maxPhi, offset);
43 
44  // helper to convert to expected local frame
45  auto toStripFrame = [&](const Vector2& xy) -> Vector2 {
46  auto shifted = xy + offset;
47  double r = VectorHelpers::perp(shifted);
48  double phi = VectorHelpers::phi(shifted);
49  return Vector2(r, phi);
50  };
51 
52  auto random_point = [&]() -> Vector2 { return {xDist(rng), yDist(rng)}; };
53 
54  // for covariance based check, set up one;
56  cov << 1.0, 0, 0, 0.05;
57 
58  BoundaryCheck bcAbs{true};
59  BoundaryCheck bcTol0{true, false, 1.0, 0};
60  BoundaryCheck bcTol1{false, true, 0, 0.2};
61  BoundaryCheck bcTol01{true, true, 1.0, 0.2};
62  BoundaryCheck bcCov{cov, 1};
63 
64  // visualization to make sense of things
65  for (size_t i = 0; i < 10000; i++) {
66  const Vector2 loc{xDist(rng), yDist(rng)};
67  auto locPC = toStripFrame(loc);
68  bool isInsideAbs = aBounds.inside(locPC, bcAbs);
69  bool isInsideTol0 = aBounds.inside(locPC, bcTol0);
70  bool isInsideTol1 = aBounds.inside(locPC, bcTol1);
71  bool isInsideTol01 = aBounds.inside(locPC, bcTol01);
72 
73  bool isInsideCov = aBounds.inside(locPC, bcCov);
74 
75  os << loc.x() << "," << loc.y() << "," << isInsideAbs << "," << isInsideTol0
76  << "," << isInsideTol1 << "," << isInsideTol01 << "," << isInsideCov
77  << std::endl;
78  }
79 
80  std::vector<std::tuple<Vector2, bool, std::string>> testPoints{{
81  {{7.0, 6.0}, true, "center"},
82  {{3.0, 1.0}, false, "radial far out low"},
83  {{5.0, 4.0}, false, "radial close out low"},
84  {{6.0, 5.0}, true, "radial close in low"},
85  {{8.5, 7.5}, true, "radial close in high"},
86  {{10.0, 9.0}, false, "radial close out high"},
87  {{15.0, 15.0}, false, "radial far out high"},
88  {{0.0, 11.0}, false, "angular far out left"},
89  {{4.0, 9.0}, false, "angular close out left"},
90  {{5.0, 8.5}, true, "angular close in left"},
91  {{9.0, 5.0}, true, "angular close in right"},
92  {{9.5, 4.5}, false, "angular close out right"},
93  {{11.0, 0.0}, false, "angular far out right"},
94  {{2.0, 4.0}, false, "quad low left"},
95  {{5.0, 14.0}, false, "quad high left"},
96  {{13.0, 6.0}, false, "quad high right"},
97  {{7.0, 1.0}, false, "quad low right"},
98  }};
99 
100  // === BENCHMARKS ===
101 
102  // Number of benchmark runs
103  constexpr int NTESTS = 5'000;
104 
105  // Some checks are much slower, so we tune down benchmark iterations
106  constexpr int NTESTS_SLOW = NTESTS / 10;
107 
108  // We use this to switch between iteration counts
109  enum class Mode { FastOutside, SlowOutside };
110 
111  // Benchmark output display
112  auto print_bench_header = [](const std::string& check_name) {
113  std::cout << check_name << ":" << std::endl;
114  };
115  auto print_bench_result = [](const std::string& bench_name,
116  const Acts::Test::MicroBenchmarkResult& res) {
117  std::cout << "- " << bench_name << ": " << res << std::endl;
118  };
119 
120  // Benchmark runner
121  auto run_bench = [&](auto&& iteration, int num_iters,
122  const std::string& bench_name) {
123  auto bench_result = Acts::Test::microBenchmark(iteration, num_iters);
124  print_bench_result(bench_name, bench_result);
125  };
126 
127  auto run_bench_with_inputs = [&](auto&& iterationWithArg, auto&& inputs,
128  const std::string& bench_name) {
129  auto bench_result = Acts::Test::microBenchmark(iterationWithArg, inputs);
130  print_bench_result(bench_name, bench_result);
131  };
132  auto run_all_benches = [&](const BoundaryCheck& check,
133  const std::string& check_name, const Mode mode) {
134  // Announce a set of benchmarks
135  print_bench_header(check_name);
136 
137  // Pre-determined "interesting" test points
138  int num_inside_points = 0;
139  int num_outside_points = 0;
140  switch (mode) {
141  case Mode::FastOutside:
142  num_inside_points = NTESTS;
143  num_outside_points = NTESTS;
144  break;
145  case Mode::SlowOutside:
146  num_inside_points = NTESTS;
147  num_outside_points = NTESTS_SLOW;
148  };
149 
150  for (const auto& [loc, inside, label] : testPoints) {
151  const auto locPC = toStripFrame(loc);
152  run_bench([&] { return aBounds.inside(locPC, check); },
153  inside ? num_inside_points : num_outside_points, label);
154  }
155 
156  // Pre-rolled random points
157  std::vector<Vector2> points(num_outside_points);
158  std::generate(points.begin(), points.end(),
159  [&] { return toStripFrame(random_point()); });
160  run_bench_with_inputs(
161  [&](const auto& point) { return aBounds.inside(point, check); }, points,
162  "Random");
163  };
164 
165  // Benchmark scenarios
166  run_all_benches(bcAbs, "Absolute", Mode::FastOutside);
167  run_all_benches(bcTol0, "Tolerance 0", Mode::FastOutside);
168  run_all_benches(bcTol1, "Tolerance 1", Mode::FastOutside);
169  run_all_benches(bcTol01, "Tolerance 01", Mode::FastOutside);
170  run_all_benches(bcCov, "Covariance", Mode::SlowOutside);
171 
172  return 0;
173 }