File indexing completed on 2025-01-18 09:11:46
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include "Acts/Geometry/GeometryIdentifier.hpp"
0012 #include "ActsExamples/Utilities/GroupBy.hpp"
0013 #include "ActsExamples/Utilities/Range.hpp"
0014
0015 #include <algorithm>
0016 #include <cassert>
0017 #include <utility>
0018
0019 #include <boost/bimap.hpp>
0020 #include <boost/container/flat_map.hpp>
0021 #include <boost/container/flat_set.hpp>
0022
0023 namespace ActsExamples {
0024 namespace detail {
0025
0026
0027 struct GeometryIdGetter {
0028
0029 constexpr Acts::GeometryIdentifier operator()(
0030 Acts::GeometryIdentifier geometryId) const {
0031 return geometryId;
0032 }
0033
0034 constexpr Acts::GeometryIdentifier operator()(
0035 Acts::GeometryIdentifier::Value encoded) const {
0036 return Acts::GeometryIdentifier(encoded);
0037 }
0038
0039 template <typename T>
0040 constexpr Acts::GeometryIdentifier operator()(
0041 const std::pair<Acts::GeometryIdentifier, T>& mapItem) const {
0042 return mapItem.first;
0043 }
0044
0045 template <typename T>
0046 inline auto operator()(const T& thing) const
0047 -> decltype(thing.geometryId(), Acts::GeometryIdentifier()) {
0048 return thing.geometryId();
0049 }
0050
0051 template <typename T>
0052 inline auto operator()(std::reference_wrapper<T> thing) const
0053 -> decltype(thing.get().geometryId(), Acts::GeometryIdentifier()) {
0054 return thing.get().geometryId();
0055 }
0056 };
0057
0058 struct CompareGeometryId {
0059
0060 using is_transparent = void;
0061
0062 template <typename Left, typename Right>
0063 constexpr bool operator()(Left&& lhs, Right&& rhs) const {
0064 return GeometryIdGetter()(lhs) < GeometryIdGetter()(rhs);
0065 }
0066 };
0067
0068 }
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080 template <typename T>
0081 using GeometryIdMultiset =
0082 boost::container::flat_multiset<T, detail::CompareGeometryId>;
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097 template <typename T>
0098 using GeometryIdMultimap =
0099 GeometryIdMultiset<std::pair<Acts::GeometryIdentifier, T>>;
0100
0101
0102 template <typename T>
0103 inline Range<typename GeometryIdMultiset<T>::const_iterator> selectVolume(
0104 const GeometryIdMultiset<T>& container,
0105 Acts::GeometryIdentifier::Value volume) {
0106 auto cmp = Acts::GeometryIdentifier().setVolume(volume);
0107 auto beg = std::lower_bound(container.begin(), container.end(), cmp,
0108 detail::CompareGeometryId{});
0109
0110 cmp = Acts::GeometryIdentifier().setVolume(volume + 1u);
0111
0112
0113
0114 auto end =
0115 std::lower_bound(beg, container.end(), cmp, detail::CompareGeometryId{});
0116 return makeRange(beg, end);
0117 }
0118
0119
0120 template <typename T>
0121 inline auto selectVolume(const GeometryIdMultiset<T>& container,
0122 Acts::GeometryIdentifier id) {
0123 return selectVolume(container, id.volume());
0124 }
0125
0126
0127 template <typename T>
0128 inline Range<typename GeometryIdMultiset<T>::const_iterator> selectLayer(
0129 const GeometryIdMultiset<T>& container,
0130 Acts::GeometryIdentifier::Value volume,
0131 Acts::GeometryIdentifier::Value layer) {
0132 auto cmp = Acts::GeometryIdentifier().setVolume(volume).setLayer(layer);
0133 auto beg = std::lower_bound(container.begin(), container.end(), cmp,
0134 detail::CompareGeometryId{});
0135
0136 cmp = Acts::GeometryIdentifier().setVolume(volume).setLayer(layer + 1u);
0137
0138
0139
0140 auto end =
0141 std::lower_bound(beg, container.end(), cmp, detail::CompareGeometryId{});
0142 return makeRange(beg, end);
0143 }
0144
0145
0146 template <typename T>
0147 inline auto selectLayer(const GeometryIdMultiset<T>& container,
0148 Acts::GeometryIdentifier id) {
0149 return selectLayer(container, id.volume(), id.layer());
0150 }
0151
0152
0153 template <typename T>
0154 inline Range<typename GeometryIdMultiset<T>::const_iterator> selectModule(
0155 const GeometryIdMultiset<T>& container, Acts::GeometryIdentifier geoId) {
0156
0157 return makeRange(container.equal_range(geoId));
0158 }
0159
0160
0161 template <typename T>
0162 inline auto selectModule(const GeometryIdMultiset<T>& container,
0163 Acts::GeometryIdentifier::Value volume,
0164 Acts::GeometryIdentifier::Value layer,
0165 Acts::GeometryIdentifier::Value sensitive) {
0166 return selectModule(
0167 container,
0168 Acts::GeometryIdentifier().setVolume(volume).setLayer(layer).setSensitive(
0169 sensitive));
0170 }
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188 template <typename T>
0189 inline Range<typename GeometryIdMultiset<T>::const_iterator>
0190 selectLowestNonZeroGeometryObject(const GeometryIdMultiset<T>& container,
0191 Acts::GeometryIdentifier geoId) {
0192 assert((geoId.boundary() == 0u) && "Boundary component must be zero");
0193 assert((geoId.approach() == 0u) && "Approach component must be zero");
0194
0195 if (geoId.sensitive() != 0u) {
0196 return selectModule(container, geoId);
0197 } else if (geoId.layer() != 0u) {
0198 return selectLayer(container, geoId);
0199 } else if (geoId.volume() != 0u) {
0200 return selectVolume(container, geoId);
0201 } else {
0202 return makeRange(container.begin(), container.end());
0203 }
0204 }
0205
0206
0207 template <typename T>
0208 inline GroupBy<typename GeometryIdMultiset<T>::const_iterator,
0209 detail::GeometryIdGetter>
0210 groupByModule(const GeometryIdMultiset<T>& container) {
0211 return makeGroupBy(container, detail::GeometryIdGetter());
0212 }
0213
0214
0215
0216
0217
0218 template <typename T>
0219 struct GeometryIdMultisetAccessor {
0220 using Container = GeometryIdMultiset<T>;
0221 using Key = Acts::GeometryIdentifier;
0222 using Value = typename GeometryIdMultiset<T>::value_type;
0223 using Iterator = typename GeometryIdMultiset<T>::const_iterator;
0224
0225
0226 const Container* container = nullptr;
0227 };
0228
0229
0230
0231 using GeometryIdMapActsAthena =
0232 boost::bimap<std::uint64_t, Acts::GeometryIdentifier>;
0233
0234 }