Juggler
Juggling algorithms and event processing using gaudi framework
GeometryContainers.hpp
Go to the documentation of this file.
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2017-2020 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 #include "Acts/Geometry/GeometryIdentifier.hpp"
14 #include "Acts/Surfaces/Surface.hpp"
15 
16 #include <algorithm>
17 #include <cstddef>
18 #include <utility>
19 
20 #include <boost/container/flat_map.hpp>
21 #include <boost/container/flat_set.hpp>
22 
23 namespace Jug {
24 namespace detail {
25 // extract the geometry identifier from a variety of types
26 struct GeometryIdGetter {
27  // explicit geometry identifier are just forwarded
28  constexpr Acts::GeometryIdentifier operator()(Acts::GeometryIdentifier geometryId) const {
29  return geometryId;
30  }
31  // encoded geometry ids are converted back to geometry identifiers.
32  constexpr Acts::GeometryIdentifier operator()(Acts::GeometryIdentifier::Value encoded) const {
33  return Acts::GeometryIdentifier(encoded);
34  }
35  // support elements in map-like structures.
36  template <typename T>
37  constexpr Acts::GeometryIdentifier operator()(
38  const std::pair<Acts::GeometryIdentifier, T>& mapItem) const {
39  return mapItem.first;
40  }
41  // support elements that implement `.geometryId()`.
42  template <typename T>
43  inline auto operator()(const T& thing) const
44  -> decltype(thing.geometryId(), Acts::GeometryIdentifier()) {
45  return thing.geometryId();
46  }
47  // support reference_wrappers around such types as well
48  template <typename T>
49  inline auto operator()(std::reference_wrapper<T> thing) const
50  -> decltype(thing.get().geometryId(), Acts::GeometryIdentifier()) {
51  return thing.get().geometryId();
52  }
53 };
54 
55 struct CompareGeometryId {
56  // indicate that comparisons between keys and full objects are allowed.
57  using is_transparent = void;
58  // compare two elements using the automatic key extraction.
59  template <typename Left, typename Right>
60  constexpr bool operator()(Left&& lhs, Right&& rhs) const {
61  return GeometryIdGetter()(lhs) < GeometryIdGetter()(rhs);
62  }
63 };
64 } // namespace detail
65 
66 /// Store elements that know their detector geometry id, e.g. simulation hits.
67 ///
68 /// @tparam T type to be stored, must be compatible with `CompareGeometryId`
69 ///
70 /// The container stores an arbitrary number of elements for any geometry
71 /// id. Elements can be retrieved via the geometry id; elements can be selected
72 /// for a specific geometry id or for a larger range, e.g. a volume or a layer
73 /// within the geometry hierachy using the helper functions below. Elements can
74 /// also be accessed by index that uniquely identifies each element regardless
75 /// of geometry id.
76 template <typename T>
77 using GeometryIdMultiset =
78  boost::container::flat_multiset<T, detail::CompareGeometryId>;
79 
80 /// Store elements indexed by an geometry id.
81 ///
82 /// @tparam T type to be stored
83 ///
84 /// The behaviour is the same as for the `GeometryIdMultiset` except that the
85 /// stored elements do not know their geometry id themself. When iterating
86 /// the iterator elements behave as for the `std::map`, i.e.
87 ///
88 /// for (const auto& entry: elements) {
89 /// auto id = entry.first; // geometry id
90 /// const auto& el = entry.second; // stored element
91 /// }
92 ///
93 template <typename T>
94 using GeometryIdMultimap = GeometryIdMultiset<std::pair<Acts::GeometryIdentifier, T>>;
95 
96 /// Select all elements within the given volume.
97 template <typename T>
98 inline Range<typename GeometryIdMultiset<T>::const_iterator> selectVolume(
99  const GeometryIdMultiset<T>& container, Acts::GeometryIdentifier::Value volume) {
100  auto cmp = Acts::GeometryIdentifier().setVolume(volume);
101  auto beg = std::lower_bound(container.begin(), container.end(), cmp,
102  detail::CompareGeometryId{});
103  // WARNING overflows to volume==0 if the input volume is the last one
104  cmp = Acts::GeometryIdentifier().setVolume(volume + 1u);
105  // optimize search by using the lower bound as start point. also handles
106  // volume overflows since the geo id would be located before the start of
107  // the upper edge search window.
108  auto end =
109  std::lower_bound(beg, container.end(), cmp, detail::CompareGeometryId{});
110  return makeRange(beg, end);
111 }
112 template <typename T>
113 inline auto selectVolume(const GeometryIdMultiset<T>& container,
114  Acts::GeometryIdentifier id) {
115  return selectVolume(container, id.volume());
116 }
117 
118 /// Select all elements within the given layer.
119 template <typename T>
120 inline Range<typename GeometryIdMultiset<T>::const_iterator> selectLayer(
121  const GeometryIdMultiset<T>& container, Acts::GeometryIdentifier::Value volume,
122  Acts::GeometryIdentifier::Value layer) {
123  auto cmp = Acts::GeometryIdentifier().setVolume(volume).setLayer(layer);
124  auto beg = std::lower_bound(container.begin(), container.end(), cmp,
125  detail::CompareGeometryId{});
126  // WARNING resets to layer==0 if the input layer is the last one
127  cmp = Acts::GeometryIdentifier().setVolume(volume).setLayer(layer + 1u);
128  // optimize search by using the lower bound as start point. also handles
129  // volume overflows since the geo id would be located before the start of
130  // the upper edge search window.
131  auto end =
132  std::lower_bound(beg, container.end(), cmp, detail::CompareGeometryId{});
133  return makeRange(beg, end);
134 }
135 template <typename T>
136 inline auto selectLayer(const GeometryIdMultiset<T>& container,
137  Acts::GeometryIdentifier id) {
138  return selectLayer(container, id.volume(), id.layer());
139 }
140 
141 /// Select all elements for the given module / sensitive surface.
142 template <typename T>
143 inline Range<typename GeometryIdMultiset<T>::const_iterator> selectModule(
144  const GeometryIdMultiset<T>& container, Acts::GeometryIdentifier geoId) {
145  // module is the lowest level and defines a single geometry id value
146  return makeRange(container.equal_range(geoId));
147 }
148 template <typename T>
149 inline auto selectModule(const GeometryIdMultiset<T>& container,
150  Acts::GeometryIdentifier::Value volume,
151  Acts::GeometryIdentifier::Value layer,
152  Acts::GeometryIdentifier::Value module) {
153  return selectModule(
154  container,
155  Acts::GeometryIdentifier().setVolume(volume).setLayer(layer).setSensitive(
156  module));
157 }
158 
159 /// Iterate over groups of elements belonging to each module/ sensitive surface.
160 template <typename T>
161 inline GroupBy<typename GeometryIdMultiset<T>::const_iterator,
162  detail::GeometryIdGetter>
163 groupByModule(const GeometryIdMultiset<T>& container) {
164  return makeGroupBy(container, detail::GeometryIdGetter());
165 }
166 
167 /// The accessor for the GeometryIdMultiset container
168 ///
169 /// It wraps up a few lookup methods to be used in the Combinatorial Kalman
170 /// Filter
171 template <typename T>
174  using Key = Acts::GeometryIdentifier;
177 
178  // pointer to the container
179  const Container* container = nullptr;
180 
181  // get the range of elements with requested geoId
182  std::pair<Iterator, Iterator> range(const Acts::Surface& surface) const {
183  assert(container != nullptr);
184  return container->equal_range(surface.geometryId());
185  }
186 };
187 
188 } // namespace FW
Jug::selectVolume
Range< typename GeometryIdMultiset< T >::const_iterator > selectVolume(const GeometryIdMultiset< T > &container, Acts::GeometryIdentifier::Value volume)
Select all elements within the given volume.
Definition: GeometryContainers.hpp:91
Jug::GeometryIdMultisetAccessor::Key
Acts::GeometryIdentifier Key
Definition: GeometryContainers.hpp:174
Jug::detail::GeometryIdGetter::operator()
constexpr Acts::GeometryIdentifier operator()(Acts::GeometryIdentifier geometryId) const
Definition: GeometryContainers.hpp:28
Jug::GeometryIdMultiset
boost::container::flat_multiset< T, detail::CompareGeometryId > GeometryIdMultiset
Definition: GeometryContainers.hpp:71
Jug::makeGroupBy
auto makeGroupBy(const Container &container, KeyGetter keyGetter) -> GroupBy< decltype(std::begin(container)), KeyGetter >
Construct the group-by proxy for a container.
Definition: GroupBy.hpp:136
Jug::GeometryIdMultisetAccessor::container
const Container * container
Definition: GeometryContainers.hpp:179
Jug::detail::GeometryIdGetter::operator()
auto operator()(const T &thing) const -> decltype(thing.geometryId(), Acts::GeometryIdentifier())
Definition: GeometryContainers.hpp:43
Jug::detail::CompareGeometryId::is_transparent
void is_transparent
Definition: GeometryContainers.hpp:50
Jug::selectLayer
Range< typename GeometryIdMultiset< T >::const_iterator > selectLayer(const GeometryIdMultiset< T > &container, Acts::GeometryIdentifier::Value volume, Acts::GeometryIdentifier::Value layer)
Select all elements within the given layer.
Definition: GeometryContainers.hpp:113
Jug::GeometryIdMultimap
GeometryIdMultiset< std::pair< Acts::GeometryIdentifier, T > > GeometryIdMultimap
Definition: GeometryContainers.hpp:87
Jug::detail::GeometryIdGetter::operator()
constexpr Acts::GeometryIdentifier operator()(Acts::GeometryIdentifier::Value encoded) const
Definition: GeometryContainers.hpp:32
Jug::GeometryIdMultisetAccessor::range
std::pair< Iterator, Iterator > range(const Acts::Surface &surface) const
Definition: GeometryContainers.hpp:182
GroupBy.hpp
Range.hpp
Jug::GeometryIdMultisetAccessor::Iterator
typename GeometryIdMultiset< T >::const_iterator Iterator
Definition: GeometryContainers.hpp:176
Jug
Definition: DD4hepBField.h:22
Jug::GeometryIdMultisetAccessor::Value
typename GeometryIdMultiset< T >::value_type Value
Definition: GeometryContainers.hpp:175
Jug::detail::CompareGeometryId::operator()
constexpr bool operator()(Left &&lhs, Right &&rhs) const
Definition: GeometryContainers.hpp:60
Jug::makeRange
Range< Iterator > makeRange(Iterator begin, Iterator end)
Definition: Range.hpp:47
Jug::detail::GeometryIdGetter::operator()
constexpr Acts::GeometryIdentifier operator()(const std::pair< Acts::GeometryIdentifier, T > &mapItem) const
Definition: GeometryContainers.hpp:37
Jug::detail::GeometryIdGetter::operator()
auto operator()(std::reference_wrapper< T > thing) const -> decltype(thing.get().geometryId(), Acts::GeometryIdentifier())
Definition: GeometryContainers.hpp:49
Jug::GeometryIdMultisetAccessor::Container
GeometryIdMultiset< T > Container
Definition: GeometryContainers.hpp:173
Jug::selectModule
Range< typename GeometryIdMultiset< T >::const_iterator > selectModule(const GeometryIdMultiset< T > &container, Acts::GeometryIdentifier geoId)
Select all elements for the given module / sensitive surface.
Definition: GeometryContainers.hpp:136
Jug::detail::GeometryIdGetter
Definition: GeometryContainers.hpp:25
Jug::groupByModule
GroupBy< typename GeometryIdMultiset< T >::const_iterator, detail::GeometryIdGetter > groupByModule(const GeometryIdMultiset< T > &container)
Iterate over groups of elements belonging to each module/ sensitive surface.
Definition: GeometryContainers.hpp:156
Jug::GeometryIdMultisetAccessor
Definition: GeometryContainers.hpp:172