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 
15 #include <algorithm>
16 #include <cstddef>
17 #include <utility>
18 
19 #include <boost/container/flat_map.hpp>
20 #include <boost/container/flat_set.hpp>
21 
22 namespace Jug {
23 namespace detail {
24 // extract the geometry identifier from a variety of types
26  // explicit geometry identifier are just forwarded
27  constexpr Acts::GeometryIdentifier operator()(Acts::GeometryIdentifier geometryId) const {
28  return geometryId;
29  }
30  // encoded geometry ids are converted back to geometry identifiers.
31  constexpr Acts::GeometryIdentifier operator()(Acts::GeometryIdentifier::Value encoded) const {
32  return Acts::GeometryIdentifier(encoded);
33  }
34  // support elements in map-like structures.
35  template <typename T>
36  constexpr Acts::GeometryIdentifier operator()(
37  const std::pair<Acts::GeometryIdentifier, T>& mapItem) const {
38  return mapItem.first;
39  }
40  // support elements that implement `.geometryId()`.
41  template <typename T>
42  inline auto operator()(const T& thing) const
43  -> decltype(thing.geometryId(), Acts::GeometryIdentifier()) {
44  return thing.geometryId();
45  }
46 };
47 
49  // indicate that comparisons between keys and full objects are allowed.
50  using is_transparent = void;
51  // compare two elements using the automatic key extraction.
52  template <typename Left, typename Right>
53  constexpr bool operator()(Left&& lhs, Right&& rhs) const {
54  return GeometryIdGetter()(lhs) < GeometryIdGetter()(rhs);
55  }
56 };
57 } // namespace detail
58 
59 /// Store elements that know their detector geometry id, e.g. simulation hits.
60 ///
61 /// @tparam T type to be stored, must be compatible with `CompareGeometryId`
62 ///
63 /// The container stores an arbitrary number of elements for any geometry
64 /// id. Elements can be retrieved via the geometry id; elements can be selected
65 /// for a specific geometry id or for a larger range, e.g. a volume or a layer
66 /// within the geometry hierachy using the helper functions below. Elements can
67 /// also be accessed by index that uniquely identifies each element regardless
68 /// of geometry id.
69 template <typename T>
71  boost::container::flat_multiset<T, detail::CompareGeometryId>;
72 
73 /// Store elements indexed by an geometry id.
74 ///
75 /// @tparam T type to be stored
76 ///
77 /// The behaviour is the same as for the `GeometryIdMultiset` except that the
78 /// stored elements do not know their geometry id themself. When iterating
79 /// the iterator elements behave as for the `std::map`, i.e.
80 ///
81 /// for (const auto& entry: elements) {
82 /// auto id = entry.first; // geometry id
83 /// const auto& el = entry.second; // stored element
84 /// }
85 ///
86 template <typename T>
88 
89 /// Select all elements within the given volume.
90 template <typename T>
92  const GeometryIdMultiset<T>& container, Acts::GeometryIdentifier::Value volume) {
93  auto cmp = Acts::GeometryIdentifier().setVolume(volume);
94  auto beg = std::lower_bound(container.begin(), container.end(), cmp,
96  // WARNING overflows to volume==0 if the input volume is the last one
97  cmp = Acts::GeometryIdentifier().setVolume(volume + 1u);
98  // optimize search by using the lower bound as start point. also handles
99  // volume overflows since the geo id would be located before the start of
100  // the upper edge search window.
101  auto end =
102  std::lower_bound(beg, container.end(), cmp, detail::CompareGeometryId{});
103  return makeRange(beg, end);
104 }
105 template <typename T>
106 inline auto selectVolume(const GeometryIdMultiset<T>& container,
107  Acts::GeometryIdentifier id) {
108  return selectVolume(container, id.volume());
109 }
110 
111 /// Select all elements within the given layer.
112 template <typename T>
114  const GeometryIdMultiset<T>& container, Acts::GeometryIdentifier::Value volume,
115  Acts::GeometryIdentifier::Value layer) {
116  auto cmp = Acts::GeometryIdentifier().setVolume(volume).setLayer(layer);
117  auto beg = std::lower_bound(container.begin(), container.end(), cmp,
119  // WARNING resets to layer==0 if the input layer is the last one
120  cmp = Acts::GeometryIdentifier().setVolume(volume).setLayer(layer + 1u);
121  // optimize search by using the lower bound as start point. also handles
122  // volume overflows since the geo id would be located before the start of
123  // the upper edge search window.
124  auto end =
125  std::lower_bound(beg, container.end(), cmp, detail::CompareGeometryId{});
126  return makeRange(beg, end);
127 }
128 template <typename T>
129 inline auto selectLayer(const GeometryIdMultiset<T>& container,
130  Acts::GeometryIdentifier id) {
131  return selectLayer(container, id.volume(), id.layer());
132 }
133 
134 /// Select all elements for the given module / sensitive surface.
135 template <typename T>
137  const GeometryIdMultiset<T>& container, Acts::GeometryIdentifier geoId) {
138  // module is the lowest level and defines a single geometry id value
139  return makeRange(container.equal_range(geoId));
140 }
141 template <typename T>
142 inline auto selectModule(const GeometryIdMultiset<T>& container,
143  Acts::GeometryIdentifier::Value volume,
144  Acts::GeometryIdentifier::Value layer,
145  Acts::GeometryIdentifier::Value module) {
146  return selectModule(
147  container,
148  Acts::GeometryIdentifier().setVolume(volume).setLayer(layer).setSensitive(
149  module));
150 }
151 
152 /// Iterate over groups of elements belonging to each module/ sensitive surface.
153 template <typename T>
154 inline GroupBy<typename GeometryIdMultiset<T>::const_iterator,
155  detail::GeometryIdGetter>
157  return makeGroupBy(container, detail::GeometryIdGetter());
158 }
159 
160 } // 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::detail::GeometryIdGetter::operator()
constexpr Acts::GeometryIdentifier operator()(Acts::GeometryIdentifier geometryId) const
Definition: GeometryContainers.hpp:27
Jug::GeometryIdMultiset
boost::container::flat_multiset< T, detail::CompareGeometryId > GeometryIdMultiset
Definition: GeometryContainers.hpp:71
GroupBy.hpp
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::detail::GeometryIdGetter::operator()
auto operator()(const T &thing) const -> decltype(thing.geometryId(), Acts::GeometryIdentifier())
Definition: GeometryContainers.hpp:42
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:31
Jug::detail::CompareGeometryId
Definition: GeometryContainers.hpp:48
Jug
Definition: DD4hepBField.h:22
Jug::detail::CompareGeometryId::operator()
constexpr bool operator()(Left &&lhs, Right &&rhs) const
Definition: GeometryContainers.hpp:53
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:36
Jug::Range
Definition: Range.hpp:27
Range.hpp
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