Project
Loading...
Searching...
No Matches
GroupedCombinations.h
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
12#ifndef FRAMEWORK_GROUPEDCOMBINATIONS_H
13#define FRAMEWORK_GROUPEDCOMBINATIONS_H
14
17#include "Framework/Pack.h"
19#include <optional>
20
21namespace o2::framework
22{
23
24// Create an instance of a tuple interleaved from given tuples
25template <typename... T1s, typename... T2s, std::size_t... Is>
26auto interleaveTuplesImpl(std::tuple<T1s...>& t1, std::tuple<T2s...>& t2, std::index_sequence<Is...>)
27{
28 return std::tuple_cat(std::make_tuple(std::get<Is>(t1), std::get<Is>(t2))...);
29}
30
31template <typename... T1s, typename... T2s>
32auto interleaveTuples(std::tuple<T1s...>& t1, std::tuple<T2s...>& t2)
33{
34 return interleaveTuplesImpl(t1, t2, std::index_sequence_for<T1s...>());
35}
36
37template <typename T, typename G>
38using is_index_to_g_t = typename std::conditional<o2::soa::is_binding_compatible_v<G, typename T::binding_t>(), std::true_type, std::false_type>::type;
39
40template <typename G, typename A>
42{
43 using external_index_columns_pack = typename A::external_index_columns_t;
44 using selected_indices_t = selected_pack_multicondition<is_index_to_g_t, pack<G>, external_index_columns_pack>;
45 static_assert(pack_size(selected_indices_t{}) == 1, "No matching index column from associated to grouping");
46 using index_column_t = pack_head_t<selected_indices_t>;
47 return expressions::BindingNode{index_column_t::mLabel, o2::framework::TypeIdHelpers::uniqueId<typename index_column_t::column_t>(), expressions::selectArrowType<typename index_column_t::type>()};
48}
49
50template <typename T1, typename GroupingPolicy, typename BP, typename G, typename... As>
51 requires(sizeof...(As) > 0)
54 using g_t = G;
56
58
60 public:
64 using iterator_category = std::forward_iterator_tag;
65
66 GroupedIterator(const GroupingPolicy& groupingPolicy, SliceCache* cache_)
67 : GroupingPolicy(groupingPolicy), mIndexColumns{getMatchingIndexNode<G, As>()...}, cache{cache_}
68 {
69 }
70 template <typename... T2s>
71 GroupedIterator(const GroupingPolicy& groupingPolicy, const G& grouping, const std::tuple<T2s...>& associated, SliceCache* cache_)
72 : GroupingPolicy(groupingPolicy),
73 mGrouping{std::make_shared<G>(std::vector{grouping.asArrowTableRef()})},
74 mAssociated{std::make_shared<std::tuple<As...>>(std::make_tuple(std::get<has_type_at<As>(pack<T2s...>{})>(associated)...))},
75 mIndexColumns{getMatchingIndexNode<G, As>()...},
76 cache{cache_}
77 {
78 if constexpr (soa::is_filtered_table<std::decay_t<G>>) {
79 mGrouping = std::make_shared<G>(std::vector{grouping.asArrowTableRef()}, grouping.getSelectedRows());
80 } else {
81 mGrouping = std::make_shared<G>(std::vector{grouping.asArrowTableRef()});
82 }
83 setMultipleGroupingTables<sizeof...(As)>(grouping);
84 if (!this->mIsEnd) {
85 setCurrentGroupedCombination();
86 }
87 }
88
91 ~GroupedIterator() = default;
92
93 template <typename... T2s>
94 void setTables(const G& grouping, const std::tuple<T2s...>& associated)
95 {
97 mGrouping = std::make_shared<G>(std::vector{grouping.asArrowTableRef()}, grouping.getSelectedRows());
98 } else {
99 mGrouping = std::make_shared<G>(std::vector{grouping.asArrowTableRef()});
100 }
101 mAssociated = std::make_shared<std::tuple<As...>>(std::make_tuple(std::get<has_type_at_v<As>(pack<T2s...>{})>(associated)...));
102 setMultipleGroupingTables<sizeof...(As)>(grouping);
103 if (!this->mIsEnd) {
104 setCurrentGroupedCombination();
105 }
106 }
107
108 template <std::size_t N, typename T, typename... Args>
109 void setMultipleGroupingTables(const T& param, const Args&... args)
110 {
111 if constexpr (N == 1) {
112 GroupingPolicy::setTables(param, args...);
113 } else {
114 setMultipleGroupingTables<N - 1>(param, param, args...);
115 }
116 }
117
119 {
120 GroupingPolicy::moveToEnd();
121 }
122
123 // prefix increment
125 {
126 if (!this->mIsEnd) {
127 this->addOne();
128 setCurrentGroupedCombination();
129 }
130 return *this;
131 }
132 // postfix increment
134 {
135 GroupedIterator copy(*this);
136 operator++();
137 return copy;
138 }
139 // return reference
141 {
142 return *mCurrentGrouped;
143 }
144 bool operator==(const GroupedIterator& rh) const
145 {
146 return (this->mIsEnd && rh.mIsEnd) || (this->mCurrent == rh.mCurrent);
147 }
148 bool operator!=(const GroupedIterator& rh) const
149 {
150 return !(*this == rh);
151 }
152
153 private:
154 std::tuple<As...> getAssociatedTables()
155 {
156 return doGetAssociatedTables(std::make_index_sequence<sizeof...(As)>());
157 }
158
159 template <std::size_t... Is>
160 std::tuple<As...> doGetAssociatedTables(std::index_sequence<Is...>)
161 {
162 return std::make_tuple(getAssociatedTable<Is>()...);
163 }
164
165 template <std::size_t I>
166 auto getAssociatedTable()
167 {
168 uint64_t ind = *std::get<0>(std::get<I>(this->mCurrent).getIndices());
169 if (std::get<I>(*mAssociated).size() == 0) {
170 return std::get<I>(*mAssociated);
171 }
172 return std::get<I>(*mAssociated).sliceByCached(mIndexColumns[I], ind, *cache);
173 }
174
175 void setCurrentGroupedCombination()
176 {
177 if (!this->mIsEnd) {
178 auto& currentGrouping = GroupingPolicy::mCurrent;
179 mSlices.emplace(getAssociatedTables());
180 mCurrentGrouped.emplace(interleaveTuples(currentGrouping, *mSlices));
181 }
182 }
183
184 std::array<expressions::BindingNode, sizeof...(As)> mIndexColumns;
185 std::shared_ptr<G> mGrouping;
186 std::shared_ptr<std::tuple<As...>> mAssociated;
187 std::optional<std::tuple<As...>> mSlices;
188 std::optional<GroupedIteratorType> mCurrentGrouped;
189 SliceCache* cache = nullptr;
190 };
191
194
196 {
197 return iterator(mBegin);
198 }
199 inline iterator end()
200 {
201 return iterator(mEnd);
202 }
203 inline const_iterator begin() const
204 {
205 return iterator(mBegin);
206 }
207 inline const_iterator end() const
208 {
209 return iterator(mEnd);
210 }
211
212 GroupedCombinationsGenerator(const BP& binningPolicy, int catNeighbours, const T1& outsider, SliceCache* cache)
213 : mBegin(GroupingPolicy(binningPolicy, catNeighbours, outsider), cache),
214 mEnd(GroupingPolicy(binningPolicy, catNeighbours, outsider), cache) {}
215 template <typename... T2s>
216 GroupedCombinationsGenerator(const BP& binningPolicy, int catNeighbours, const T1& outsider, const G& grouping, const std::tuple<T2s...>& associated, SliceCache* cache)
217 : GroupedCombinationsGenerator(binningPolicy, catNeighbours, outsider, cache)
218 {
219 setTables(grouping, associated);
220 }
224
225 template <typename... T2s>
226 void setTables(const G& grouping, const std::tuple<T2s...>& associated)
227 {
228 mBegin.setTables(grouping, associated);
229 mEnd.setTables(grouping, associated);
230 mEnd.moveToEnd();
231 }
232
233 private:
234 iterator mBegin;
235 iterator mEnd;
236};
237
238template <typename T>
239concept is_combinations_generator = requires(T t, typename T::g_t const& g, pack_to_tuple_t<typename T::associated_pack_t>& a) {
240 typename T::GroupedIterator;
241 t.setTables(g, a);
242 { t.begin() } -> std::same_as<typename T::iterator>;
243 { t.end() } -> std::same_as<typename T::iterator>;
244};
245
246// Aliases for 2-particle correlations
247// 'Pair' and 'Triple' can be used for same kind pair/triple, too, just specify the same type twice
248template <typename G, typename A1, typename A2, typename BP, typename T1 = int, typename GroupingPolicy = o2::soa::CombinationsBlockStrictlyUpperSameIndexPolicy<BP, T1, G, G>>
250template <typename G, typename A, typename BP, typename T1 = int, typename GroupingPolicy = o2::soa::CombinationsBlockStrictlyUpperSameIndexPolicy<BP, T1, G, G>>
252
253// Aliases for 3-particle correlations
254template <typename G, typename A1, typename A2, typename A3, typename BP, typename T1 = int, typename GroupingPolicy = o2::soa::CombinationsBlockStrictlyUpperSameIndexPolicy<BP, T1, G, G, G>>
256template <typename G, typename A, typename BP, typename T1 = int, typename GroupingPolicy = o2::soa::CombinationsBlockStrictlyUpperSameIndexPolicy<BP, T1, G, G, G>>
258
259} // namespace o2::framework
260#endif // FRAMEWORK_GROUPEDCOMBINATIONS_H_
Timeframe settings Average distance in cm of events merged into Randomize distance around average distance of merged events Simulate correct bunch interactions instead of placing only the average number of events A value[n] sets TFlen for[n] collisions in Number of bunches per trainsort Number of bunch trains Instantaneous interaction rate Do not simulate border Total number of collisions to be placed in the interior of all time Do not select random but walk over array of events in stride steps h Event generator settings h configStandalone Use CPU for GPU Force usage of the specified GPU device no CPU fallback Continue processing after an error First event to Number of events to Number of iterations to Number of iterations to Number of initial iterations excluded from const char Directory with events to Events directory is and not inside events Show standalone event Run event generator maximum time bin of continuous for triggered for automatic continuous for automatic continuous triggered uint64_t
GLboolean GLboolean g
Definition glcorearb.h:1233
GLint GLint GLsizei GLint GLenum GLenum type
Definition glcorearb.h:275
GLenum GLfloat param
Definition glcorearb.h:271
GLboolean GLboolean GLboolean GLboolean a
Definition glcorearb.h:1233
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat t1
Definition glcorearb.h:5034
Defining ITS Vertex explicitly as messageable.
Definition Cartesian.h:288
auto interleaveTuplesImpl(std::tuple< T1s... > &t1, std::tuple< T2s... > &t2, std::index_sequence< Is... >)
decltype(interleave_pack(P1{}, P2{})) interleaved_pack_t
Definition Pack.h:99
decltype(sequence_to_pack< T >(std::make_index_sequence< N >())) repeated_type_pack_t
Definition Pack.h:352
typename std::conditional< o2::soa::is_binding_compatible_v< G, typename T::binding_t >(), std::true_type, std::false_type >::type is_index_to_g_t
std::decay_t< decltype(select_pack< Condition >(pack<>{}, Pack{}, CondPack{}))> selected_pack_multicondition
Definition Pack.h:181
expressions::BindingNode getMatchingIndexNode()
auto interleaveTuples(std::tuple< T1s... > &t1, std::tuple< T2s... > &t2)
constexpr std::size_t pack_size(pack< Ts... > const &)
template function to determine number of types in a pack
Definition Pack.h:28
typename pack_element< 0, T >::type pack_head_t
Definition Pack.h:59
decltype(pack_to_tuple(P{})) pack_to_tuple_t
Definition Pack.h:343
GroupedIterator(const GroupingPolicy &groupingPolicy, SliceCache *cache_)
void setTables(const G &grouping, const std::tuple< T2s... > &associated)
void setMultipleGroupingTables(const T &param, const Args &... args)
GroupedIterator & operator=(GroupedIterator const &)=default
GroupedIterator(const GroupingPolicy &groupingPolicy, const G &grouping, const std::tuple< T2s... > &associated, SliceCache *cache_)
GroupedCombinationsGenerator(const BP &binningPolicy, int catNeighbours, const T1 &outsider, const G &grouping, const std::tuple< T2s... > &associated, SliceCache *cache)
GroupedCombinationsGenerator(GroupedCombinationsGenerator const &)=default
GroupedCombinationsGenerator & operator=(GroupedCombinationsGenerator const &)=default
GroupedCombinationsGenerator(const BP &binningPolicy, int catNeighbours, const T1 &outsider, SliceCache *cache)
void setTables(const G &grouping, const std::tuple< T2s... > &associated)
pack_to_tuple_t< interleaved_pack_t< repeated_type_pack_t< typename G::iterator, sizeof...(As)>, pack< As... > > > GroupedIteratorType
An expression tree node corresponding to a column binding.