Main Page
Related Pages
Modules
Namespaces
Classes
Files
Examples
File List
File Members
canvas
canvas
Persistency
Common
AssnsAlgorithms.h
Go to the documentation of this file.
1
/**
2
* @file ForEachAssociatedGroup.h
3
* @brief Helper functions to access associations in order
4
*
5
* No additional linking is required to use these functions.
6
*
7
* Provided functions:
8
*
9
* * `art::for_each_group()` executing the provided function on each
10
* of the elements associated to the same object, for each object
11
*
12
* * `art::for_each_group_with_left()` executing the provided function
13
* on each of the elements associated to the same object, for each
14
* object, while also providing a reference to the object.
15
*/
16
17
#ifndef canvas_Persistency_Common_AssnsAlgorithms_h
18
#define canvas_Persistency_Common_AssnsAlgorithms_h
19
20
#include "
canvas/Persistency/Common/Assns.h
"
21
22
// range library
23
#include "range/v3/algorithm/for_each.hpp"
24
#include "range/v3/view/all.hpp"
25
#include "range/v3/view/group_by.hpp"
26
#include "range/v3/view/map.hpp"
27
#include "range/v3/view/transform.hpp"
28
29
// C/C++ standard libraries
30
#include <iterator>
// std::next()
31
32
namespace
art
{
33
/**
34
* @brief Helper functions to access associations in order
35
* @tparam A type of association being read
36
* @tparam F type of functor to be called on each associated group
37
* @param assns the association being read
38
* @param func functor to be called on each associated group
39
*
40
* This function takes two input arguments, a constant reference to
41
* the association data product itself (`assns`), and the function
42
* (`func`) to be operated on each of the group of associated objects.
43
* This function represents the association data product as
44
* a range of ranges representing the right hand side in the
45
* collection, hence the function provided as the second argument
46
* should assume that it will be operating on a range of art::Ptr
47
* to the associated data products grouped by the data product
48
* they are associated with.
49
*
50
* Example: assuming that a module with input tag stored in `fTrackTag` has
51
* created associations of each track to its hits, the total charge for each
52
* track can be extracted by:
53
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
54
* auto assns = art::getValidHandle<art::Assns<recob::Track, recob::Hit>>
55
* (fTrackTag);
56
*
57
* std::vector<double> totalCharge;
58
* art::for_each_group(*assns,
59
* [&totalCharge](auto hits)
60
* {
61
* double total = 0.;
62
* for (auto iHit = begin(hits); iHit != end(hits); ++iHit)
63
* total += (*iHit)->Integral();
64
* totalCharge.push_back(total);
65
* }
66
* );
67
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
68
* A number of important points need to be realised about this example:
69
*
70
* * the requirements of this function translate, for this example, into:
71
* * at the creation of the associations data product, for each track the
72
* _complete_ sequence of hits must be associated, one hit after the
73
* other (via `addSingle`); if the order of the hits is relevant (it is
74
* not in this specific example), hits must be associated in that order
75
* * each track must have at least one associated hit;
76
* * the original association has to be stored with `recob::Track` as
77
* _left_ key and `recob::Hit` as _right_ key;
78
* * we use here a lambda function as `func`; any object
79
* behaving as a function and able to accept the range of hits as its only
80
* argument will work just as well;
81
* * `func` will be called once for every track (but if a track has no
82
* associated hit, that track will be skipped, and if a track appears in
83
* more than one association sequence, like in (T1,H1) (T1,H2) (T2,H4)
84
* (T1,H3), then that track will appear as many times);
85
* * `func` does not return any value: the results are accumulated in a new
86
* sequence;
87
* * `func` receives a range of _art_ pointers (`art::Ptr<recob::Hit>`) which
88
* needs to be navigated with the `begin()`/`end()` free functions (don't
89
* specify their namespace: C++ will figure out!); double dereferencing
90
* is needed: the first (`*iHit`) will turn the range iterator into the
91
* pointed `art::Ptr<recob::Hit>`, and the second (`(...)->Integral()`)
92
* accesses the `recob::Hit` pointed by the _art_ pointer;
93
* * `func` does not know which track the hits are associated to, and it
94
* assumes that the first sequence of hits is associated to the first track
95
* (so that its total charge will be available in `totalCharge[0]`), the
96
* second sequence to the second track (`totalCharge[1]`) and so on.
97
*
98
* Therefore, for a `assns` sequence like
99
*
100
* (T1,H1) (T1,H2) (T2,H4) (T2,H6) (T1,H5)
101
*
102
* the function `for_each_group()` will execute two calls:
103
*
104
* func({ H1, H2 })
105
* func({ H4, H6, H5 })
106
*
107
* dealing with the hits associated to `T1` first, and `T2` next.
108
*/
109
template
<
typename
A,
typename
B,
typename
D,
typename
F>
110
void
111
for_each_group
(
art::Assns<A, B, D>
const
& assns, F
func
)
112
{
113
ranges::for_each(assns |
ranges::views::all
|
114
ranges::views::group_by
([](
auto
a1
,
auto
a2
) {
115
return
a1
.first ==
a2
.first;
116
}) |
117
ranges::views::transform([](
auto
pairs) {
118
return
pairs |
ranges::views::values
;
119
}),
120
func);
121
}
122
123
/*
124
* @brief Helper functions to access associations in order
125
* @tparam A type of association being read
126
* @tparam F type of functor to be called on each LHS and associated RHS
127
* @param assns the association being read
128
* @param func functor to be called on each LHS and associated RHS
129
*
130
* This function performs the following:
131
* -- takes an association collection as the first argument
132
* -- calls the provided callable object
133
* For example, given an art::Assns<L, R>, it will transform this
134
* collection to a form that supports calling a function with two arguments
135
* (auto const & left, auto rights)
136
* The provided callable is invoked for each unique left.
137
*
138
*/
139
template
<
typename
A,
typename
B,
typename
D,
typename
F>
140
void
141
for_each_group_with_left
(
art::Assns<A, B, D>
const
& assns, F
func
)
142
{
143
for_each_pair
(assns, [&func](
auto
rng
) {
144
auto
rights =
rng
|
ranges::views::values
;
145
auto
lefts =
rng
|
ranges::views::keys
;
146
auto
const
&
left
= **
ranges::begin
(lefts);
147
func
(
left
, rights);
148
});
149
}
150
151
template
<
typename
A,
typename
B,
typename
D,
typename
F>
152
void
153
for_each_pair
(
art::Assns<A, B, D>
const
& assns, F
func
)
154
{
155
ranges::for_each(assns |
ranges::views::all
|
156
ranges::views::group_by
(
157
[](
auto
a1
,
auto
a2
) {
return
a1
.first ==
a2
.first; }),
158
func);
159
}
160
161
}
// namespace art
162
163
#endif
/* canvas_Persistency_Common_AssnsAlgorithms_h */
164
165
// Local Variables:
166
// mode: c++
167
// End:
Assns.h
ValidateOpDetSimulation.keys
keys
Definition:
ValidateOpDetSimulation.py:135
test_gpu_visible.rng
rng
Definition:
test_gpu_visible.py:9
art::Assns
Definition:
Assns.h:102
a2
#define a2
Definition:
HoughBaseAlg.cxx:64
art::for_each_group_with_left
void for_each_group_with_left(art::Assns< A, B, D > const &assns, F func)
Definition:
AssnsAlgorithms.h:141
values
Q_UINT16 values[128]
Definition:
qtextcodec.cpp:1352
art::left
constexpr auto const & left(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
Definition:
AssnsIter.h:94
all
static QInternalList< QTextCodec > * all
Definition:
qtextcodec.cpp:63
art::for_each_group
void for_each_group(art::Assns< A, B, D > const &assns, F func)
Helper functions to access associations in order.
Definition:
AssnsAlgorithms.h:111
art::for_each_pair
void for_each_pair(art::Assns< A, B, D > const &assns, F func)
Definition:
AssnsAlgorithms.h:153
docstring.func
def func()
Definition:
docstring.py:7
art
Definition:
BasicOptionsHandler.h:9
wirecell.sigproc.response.group_by
def group_by(rflist, field)
Definition:
__init__.py:162
util::begin
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
Definition:
StdUtils.h:72
a1
#define a1
Definition:
HoughBaseAlg.cxx:63
Generated by
1.8.11