Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Intersection.hpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file Intersection.hpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2016-2023 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 
9 #pragma once
10 
13 
14 #include <algorithm>
15 #include <array>
16 #include <cstddef>
17 #include <cstdint>
18 #include <limits>
19 
20 #include <boost/container/static_vector.hpp>
21 
22 namespace Acts {
23 
25 enum class IntersectionStatus : int {
26  missed = 0,
27  unreachable = 0,
28  reachable = 1,
29  onSurface = 2
30 };
31 
33 inline std::ostream& operator<<(std::ostream& os, IntersectionStatus status) {
34  constexpr static std::array<const char*, 3> names = {
35  {"missed/unreachable", "reachable", "onSurface"}};
36 
37  os << names[static_cast<std::size_t>(status)];
38  return os;
39 }
40 
44 template <unsigned int DIM>
45 class Intersection {
46  public:
51 
57  constexpr Intersection(const Position& position, double pathLength,
58  Status status)
59  : m_position(position), m_pathLength(pathLength), m_status(status) {}
60 
62  constexpr explicit operator bool() const {
63  return m_status != Status::missed;
64  }
65 
66  constexpr const Position& position() const { return m_position; }
67 
68  constexpr ActsScalar pathLength() const { return m_pathLength; }
69 
70  constexpr Status status() const { return m_status; }
71 
72  constexpr static Intersection invalid() { return Intersection(); }
73 
76  constexpr static bool forwardOrder(const Intersection& aIntersection,
77  const Intersection& bIntersection) {
78  auto a = aIntersection.pathLength();
79  auto b = bIntersection.pathLength();
80  return a < b;
81  }
82 
85  constexpr static bool closestOrder(const Intersection& aIntersection,
86  const Intersection& bIntersection) {
87  if ((aIntersection.status() == Status::unreachable) &&
88  (bIntersection.status() != Status::unreachable)) {
89  return false;
90  }
91  if ((aIntersection.status() != Status::unreachable) &&
92  (bIntersection.status() == Status::unreachable)) {
93  return true;
94  }
95  // both are reachable or onSurface now
96  auto a = aIntersection.pathLength();
97  auto b = bIntersection.pathLength();
98  return std::abs(a) < std::abs(b);
99  }
100 
101  private:
103  Position m_position = Position::Zero();
105  ActsScalar m_pathLength = std::numeric_limits<double>::infinity();
107  Status m_status = Status::unreachable;
108 
109  constexpr Intersection() = default;
110 };
111 
114 
115 static constexpr std::uint8_t s_maximumNumberOfIntersections = 2;
116 using MultiIntersection3D =
117  boost::container::static_vector<Intersection3D,
119 
121 template <typename object_t, typename representation_t = object_t>
123  public:
129  template <typename T = representation_t,
132  const object_t* object, std::uint8_t index = 0)
133  : m_intersection(intersection),
134  m_object(object),
135  m_representation(object),
136  m_index(index) {}
137 
145  const object_t* object,
146  const representation_t* representation,
147  std::uint8_t index = 0)
148  : m_intersection(intersection),
149  m_object(object),
150  m_representation(representation),
151  m_index(index) {}
152 
154  constexpr explicit operator bool() const {
155  return m_intersection.operator bool();
156  }
157 
158  constexpr const Intersection3D& intersection() const {
159  return m_intersection;
160  }
161 
162  constexpr const Intersection3D::Position& position() const {
163  return m_intersection.position();
164  }
165 
166  constexpr ActsScalar pathLength() const {
167  return m_intersection.pathLength();
168  }
169 
170  constexpr Intersection3D::Status status() const {
171  return m_intersection.status();
172  }
173 
174  constexpr const object_t* object() const { return m_object; }
175 
176  constexpr const representation_t* representation() const {
177  return m_representation;
178  }
179 
180  constexpr std::uint8_t index() const { return m_index; }
181 
182  constexpr static ObjectIntersection invalid() { return ObjectIntersection(); }
183 
184  constexpr static bool forwardOrder(const ObjectIntersection& aIntersection,
185  const ObjectIntersection& bIntersection) {
186  return Intersection3D::forwardOrder(aIntersection.intersection(),
187  bIntersection.intersection());
188  }
189 
190  constexpr static bool closestOrder(const ObjectIntersection& aIntersection,
191  const ObjectIntersection& bIntersection) {
192  return Intersection3D::closestOrder(aIntersection.intersection(),
193  bIntersection.intersection());
194  }
195 
196  private:
200  const object_t* m_object = nullptr;
202  const representation_t* m_representation = nullptr;
204  std::uint8_t m_index = 0;
205 
206  constexpr ObjectIntersection() = default;
207 };
208 
210 template <typename object_t, typename representation_t = object_t>
212  public:
213  using SplitIntersections = boost::container::static_vector<
216 
221  template <typename T = representation_t,
223  constexpr ObjectMultiIntersection(const MultiIntersection3D& intersections,
224  const object_t* object)
225  : m_intersections(intersections),
226  m_object(object),
227  m_representation(object) {}
228 
234  constexpr ObjectMultiIntersection(const MultiIntersection3D& intersections,
235  const object_t* object,
236  const representation_t* representation)
237  : m_intersections(intersections),
238  m_object(object),
239  m_representation(representation) {}
240 
242  std::uint8_t index) const {
243  return {m_intersections[index], m_object, m_representation, index};
244  }
245 
246  constexpr std::size_t size() const { return m_intersections.size(); }
247 
248  constexpr const object_t* object() const { return m_object; }
249 
250  constexpr const representation_t* representation() const {
251  return m_representation;
252  }
253 
254  constexpr SplitIntersections split() const {
255  SplitIntersections result;
256  for (std::size_t i = 0; i < size(); ++i) {
257  result.push_back(operator[](i));
258  }
259  return result;
260  }
261 
263  auto splitIntersections = split();
264  return *std::min_element(
265  splitIntersections.begin(), splitIntersections.end(),
267  }
268 
269  private:
273  const object_t* m_object = nullptr;
275  const representation_t* m_representation = nullptr;
276 };
277 
278 namespace detail {
279 
293 template <typename intersection_t, typename logger_t = std::false_type>
294 bool checkIntersection(const intersection_t& intersection, double pLimit,
295  double oLimit, double tolerance,
296  const Logger& logger = getDummyLogger()) {
297  const double cLimit = intersection.pathLength();
298 
299  ACTS_VERBOSE(" -> pLimit, oLimit, cLimit: " << pLimit << ", " << oLimit
300  << ", " << cLimit);
301 
302  const bool coCriterion = cLimit > oLimit;
303  const bool cpCriterion = std::abs(cLimit) < std::abs(pLimit) + tolerance;
304 
305  const bool accept = coCriterion and cpCriterion;
306 
307  if (accept) {
308  ACTS_VERBOSE("Intersection is WITHIN limit");
309  } else {
310  ACTS_VERBOSE("Intersection is OUTSIDE limit because: ");
311  if (not coCriterion) {
312  ACTS_VERBOSE("- intersection path length "
313  << cLimit << " <= overstep limit " << oLimit);
314  }
315  if (not cpCriterion) {
316  ACTS_VERBOSE("- intersection path length "
317  << std::abs(cLimit) << " is over the path limit "
318  << (std::abs(pLimit) + tolerance)
319  << " (including tolerance of " << tolerance << ")");
320  }
321  }
322 
323  return accept;
324 }
325 
326 } // namespace detail
327 
328 } // namespace Acts