File indexing completed on 2024-06-26 07:06:33
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include "JugReco/Utilities/GroupBy.hpp"
0012 #include "JugReco/Utilities/Range.hpp"
0013 #include "Acts/Geometry/GeometryIdentifier.hpp"
0014
0015 #include <algorithm>
0016 #include <cstddef>
0017 #include <utility>
0018
0019 #include <boost/container/flat_map.hpp>
0020 #include <boost/container/flat_set.hpp>
0021
0022 namespace Jug {
0023 namespace detail {
0024
0025 struct GeometryIdGetter {
0026
0027 constexpr Acts::GeometryIdentifier operator()(Acts::GeometryIdentifier geometryId) const {
0028 return geometryId;
0029 }
0030
0031 constexpr Acts::GeometryIdentifier operator()(Acts::GeometryIdentifier::Value encoded) const {
0032 return Acts::GeometryIdentifier(encoded);
0033 }
0034
0035 template <typename T>
0036 constexpr Acts::GeometryIdentifier operator()(
0037 const std::pair<Acts::GeometryIdentifier, T>& mapItem) const {
0038 return mapItem.first;
0039 }
0040
0041 template <typename T>
0042 inline auto operator()(const T& thing) const
0043 -> decltype(thing.geometryId(), Acts::GeometryIdentifier()) {
0044 return thing.geometryId();
0045 }
0046 };
0047
0048 struct CompareGeometryId {
0049
0050 using is_transparent = void;
0051
0052 template <typename Left, typename Right>
0053 constexpr bool operator()(Left&& lhs, Right&& rhs) const {
0054 return GeometryIdGetter()(lhs) < GeometryIdGetter()(rhs);
0055 }
0056 };
0057 }
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069 template <typename T>
0070 using GeometryIdMultiset =
0071 boost::container::flat_multiset<T, detail::CompareGeometryId>;
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086 template <typename T>
0087 using GeometryIdMultimap = GeometryIdMultiset<std::pair<Acts::GeometryIdentifier, T>>;
0088
0089
0090 template <typename T>
0091 inline Range<typename GeometryIdMultiset<T>::const_iterator> selectVolume(
0092 const GeometryIdMultiset<T>& container, Acts::GeometryIdentifier::Value volume) {
0093 auto cmp = Acts::GeometryIdentifier().setVolume(volume);
0094 auto beg = std::lower_bound(container.begin(), container.end(), cmp,
0095 detail::CompareGeometryId{});
0096
0097 cmp = Acts::GeometryIdentifier().setVolume(volume + 1u);
0098
0099
0100
0101 auto end =
0102 std::lower_bound(beg, container.end(), cmp, detail::CompareGeometryId{});
0103 return makeRange(beg, end);
0104 }
0105 template <typename T>
0106 inline auto selectVolume(const GeometryIdMultiset<T>& container,
0107 Acts::GeometryIdentifier id) {
0108 return selectVolume(container, id.volume());
0109 }
0110
0111
0112 template <typename T>
0113 inline Range<typename GeometryIdMultiset<T>::const_iterator> selectLayer(
0114 const GeometryIdMultiset<T>& container, Acts::GeometryIdentifier::Value volume,
0115 Acts::GeometryIdentifier::Value layer) {
0116 auto cmp = Acts::GeometryIdentifier().setVolume(volume).setLayer(layer);
0117 auto beg = std::lower_bound(container.begin(), container.end(), cmp,
0118 detail::CompareGeometryId{});
0119
0120 cmp = Acts::GeometryIdentifier().setVolume(volume).setLayer(layer + 1u);
0121
0122
0123
0124 auto end =
0125 std::lower_bound(beg, container.end(), cmp, detail::CompareGeometryId{});
0126 return makeRange(beg, end);
0127 }
0128 template <typename T>
0129 inline auto selectLayer(const GeometryIdMultiset<T>& container,
0130 Acts::GeometryIdentifier id) {
0131 return selectLayer(container, id.volume(), id.layer());
0132 }
0133
0134
0135 template <typename T>
0136 inline Range<typename GeometryIdMultiset<T>::const_iterator> selectModule(
0137 const GeometryIdMultiset<T>& container, Acts::GeometryIdentifier geoId) {
0138
0139 return makeRange(container.equal_range(geoId));
0140 }
0141 template <typename T>
0142 inline auto selectModule(const GeometryIdMultiset<T>& container,
0143 Acts::GeometryIdentifier::Value volume,
0144 Acts::GeometryIdentifier::Value layer,
0145 Acts::GeometryIdentifier::Value module) {
0146 return selectModule(
0147 container,
0148 Acts::GeometryIdentifier().setVolume(volume).setLayer(layer).setSensitive(
0149 module));
0150 }
0151
0152
0153 template <typename T>
0154 inline GroupBy<typename GeometryIdMultiset<T>::const_iterator,
0155 detail::GeometryIdGetter>
0156 groupByModule(const GeometryIdMultiset<T>& container) {
0157 return makeGroupBy(container, detail::GeometryIdGetter());
0158 }
0159
0160 }