ParallelDataProxyMaker.h
Go to the documentation of this file.
1 /**
2  * @file lardata/RecoBaseProxy/ProxyBase/ParallelDataProxyMaker.h
3  * @brief Infrastructure for the addition of parallel data to a proxy.
4  * @author Gianluca Petrillo (petrillo@fnal.gov)
5  * @date July 27, 2017
6  * @see lardata/RecoBaseProxy/ProxyBase.h
7  *
8  * This library is header-only.
9  */
10 
11 #ifndef LARDATA_RECOBASEPROXY_PROXYBASE_PARALLELDATAPROXYMAKER_H
12 #define LARDATA_RECOBASEPROXY_PROXYBASE_PARALLELDATAPROXYMAKER_H
13 
14 // LArSoft libraries
17 #include "larcorealg/CoreUtils/ContainerMeta.h" // util::collection_value_t, ...
18 
19 // framework libraries
21 
22 // C/C++ standard
23 #include <vector>
24 #include <utility> // std::forward()
25 
26 
27 
28 namespace proxy {
29 
30 
31  // -- BEGIN Parallel data infrastructure -------------------------------------
32  /**
33  * @defgroup LArSoftProxiesParallelData Parallel data infrastructure
34  * @ingroup LArSoftProxyCustom
35  * @brief Infrastructure for support of parallel data structures.
36  *
37  * This infrastructure provides support for merging to a proxy data products
38  * fulfilling the
39  * @ref LArSoftProxyDefinitionParallelData "parallel data product"
40  * requirements.
41  *
42  * The typical pattern is to read and merge a parallel data product with
43  * `withParallelData()`. In alternative, a proxy can be augmented with any
44  * existing collection, using `wrapParallelData()`.
45  *
46  * @{
47  */
48 
49  /**
50  * @brief Creates an parallel data wrapper for the specified types.
51  * @tparam Main type of main datum (element)
52  * @tparam AuxColl type of the parallel data collection
53  * @tparam Aux type of the parallel data element
54  * @tparam AuxTag tag labelling the parallel data collection
55  *
56  * Usually, `AuxTag` is also the type of datum (element) in the parallel
57  * collection.
58  *
59  * This class works as a base class for `ParallelDataProxyMaker` so that
60  * the specializations of the latter can still inherit from this one if they
61  * its facilities.
62  */
63  template <
64  typename Main,
65  typename AuxColl,
66  typename Aux,
67  typename AuxTag = util::collection_value_t<AuxColl>
68  >
70 
71  /// Tag labelling the associated data we are going to produce.
72  using data_tag = AuxTag;
73 
74  /// Type of the main datum.
75  using main_element_t = Main;
76 
77  /// Type of the auxiliary data product.
78  using aux_collection_t = AuxColl;
79 
80  /// Type of the auxiliary datum.
81  using aux_element_t = Aux;
82 
83  /// Type of associated data proxy being created.
86 
87  /**
88  * @brief Create a parallel data proxy collection using main collection tag.
89  * @tparam Event type of the event to read data from
90  * @tparam Handle type of handle to the main data product
91  * @tparam MainArgs _(unused)_ any type convertible to `art::InputTag`
92  * @param event the event to read data from
93  * @param mainHandle _(unused)_ handle to the main collection data product
94  * @param mainArgs an object describing the main data product
95  * @return a parallel data proxy object
96  *
97  * The returned object exposes a random access container interface, with
98  * data indexed by the index of the corresponding object in the main
99  * collection.
100  *
101  * The `mainArgs` object is of an arbitrary type that must be convertible
102  * by explicit type cast into a `art::InputTag`; that input tag will be
103  * used to fetch the parallel data collection.
104  */
105  template<typename Event, typename Handle, typename MainArgs>
106  static auto make
107  (Event const& event, Handle&& mainHandle, MainArgs const& mainArgs)
108  {
109  return createFromTag
110  (event, std::forward<Handle>(mainHandle), art::InputTag(mainArgs));
111  }
112 
113  /**
114  * @brief Create a parallel data proxy collection using the specified tag.
115  * @tparam Event type of the event to read data from
116  * @tparam Handle type of handle to the main data product
117  * @tparam MainArgs (_unused_) any type convertible to `art::InputTag`
118  * @param event the event to read associations from
119  * @param mainHandle (_unused_) handle to the main collection data product
120  * @param auxInputTag the tag of the data to be read
121  * @return a parallel data proxy object
122  *
123  * The returned object exposes a random access container interface, with
124  * data indexed by the index of the corresponding object in the main
125  * collection.
126  */
127  template<typename Event, typename Handle, typename MainArgs>
128  static auto make(
129  Event const& event, Handle&& mainHandle,
130  MainArgs const&, art::InputTag const& auxInputTag
131  )
132  {
133  return
134  createFromTag(event, std::forward<Handle>(mainHandle), auxInputTag);
135  }
136 
137  /**
138  * @brief Create a parallel data proxy collection using the specified tag.
139  * @tparam Event (_unused_) type of the event to read data from
140  * @tparam Handle (_unused_) type of handle to the main data product
141  * @tparam MainArgs (_unused_) any type convertible to `art::InputTag`
142  * @param auxColl the collection to be wrapped
143  * @return a parallel data proxy object
144  *
145  * The returned object exposes a random access container interface, with
146  * data indexed by the index of the corresponding object in the main
147  * collection.
148  */
149  template<typename Event, typename Handle, typename MainArgs>
150  static auto make
151  (Event const&, Handle&&, MainArgs const&, aux_collection_t const& auxColl)
152  {
153  return makeParallelDataFrom<aux_collection_t, aux_element_t, data_tag>
154  (auxColl);
155  }
156 
157 
158  private:
159  template<typename Event, typename Handle>
160  static auto createFromTag
161  (Event const& event, Handle&&, art::InputTag const& auxInputTag)
162  {
163  return makeParallelDataFrom<aux_collection_t, aux_element_t, data_tag>
164  (event, auxInputTag);
165  }
166 
167  }; // struct ParallelDataProxyMakerBase<>
168 
169 
170  //--------------------------------------------------------------------------
171  /**
172  * @brief Creates an associated data wrapper for the specified types.
173  * @tparam Main type of main datum (element) to associate from ("left")
174  * @tparam Aux type of datum (element) to associate to ("right")
175  * @tparam CollProxy type of proxy this associated data works for
176  * @tparam Tag tag for the association proxy to be created
177  * @tparam AuxColl type of the auxiliary data (default: `std::vector<Aux>`)
178  * @see `withParallelDataAs()`, `wrapParallelDataAs()`
179  *
180  * This class is (indirectly) called when using `proxy::withParallelData()`
181  * in `getCollection()`.
182  * Its task is to supervise the creation of the proxy to the auxiliary data
183  * parallel to the main data type.
184  * The interface required by `withParallelData()` includes:
185  * * a static `make()` method creating and returning the auxiliary data
186  * proxy with arguments an event, the main data product handle, a template
187  * argument representing the main collection information, and all the
188  * arguments required for the creation of the associated proxy (coming from
189  * `withParallelData()`); equivalent to the signature:
190  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
191  * template <typename Event, typename Handle, typename MainArg, typename... Args>
192  * auto make(Event const&, Handle&&, MainArg const&, Args&&...);
193  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
194  *
195  * This class can be specialized (see `withParallelData()` for an example).
196  * The default implementation just wraps a one-to-many
197  * `std::vector<Aux>` data product fulfilling "parallel data product"
198  * requirement (see the "Definitions" section in `ProxyBase.h` documentation).
199  *
200  * The last template argument is designed for specialization of auxiliary data
201  * in the context of a specific proxy type.
202  */
203  template<
204  typename Main, typename Aux, typename CollProxy, typename Tag = Aux,
205  typename AuxColl = std::vector<Aux>
206  >
208  : public ParallelDataProxyMakerBase<Main, AuxColl, Aux, Tag>
209  {
210  //
211  // Note that this implementation is here only to document how to derive
212  // a ParallelDataProxyMaker (specialization) from
213  // ParallelDataProxyMakerBase. It's just mirroring the base class.
214  //
216 
217  public:
218 
219  /// Type of the main datum.
220  using typename base_t::main_element_t;
221 
222  /// Type of the auxiliary data product.
223  using typename base_t::aux_collection_t;
224 
225  /// Type of the auxiliary datum.
226  using typename base_t::aux_element_t;
227 
228  /// Type of collection data proxy being created.
229  using typename base_t::aux_collection_proxy_t;
230 
231 
232  /**
233  * @brief Create a association proxy collection using main collection tag.
234  * @tparam Event type of the event to read associations from
235  * @tparam Handle type of data product handle
236  * @tparam MainArgs any type convertible to `art::InputTag`
237  * @tparam Args optional single type (`art::InputTag` required)
238  * @param event the event to read associations from
239  * @param mainHandle handle of the main collection data product
240  * @param margs an object describing the main data product
241  * @param args input tag for parallel data, if different from main
242  * @return an auxiliary data proxy object
243  *
244  * The returned object exposes a random access container interface, with
245  * data indexed by the index of the corresponding object in the main
246  * collection.
247  *
248  * This implementation requires `margs` object to be convertible
249  * by explicit type cast into a `art::InputTag`; that input tag will be
250  * used to fetch the association.
251  */
252  template
253  <typename Event, typename Handle, typename MainArgs, typename... Args>
254  static auto make(
255  Event const& event, Handle&& mainHandle, MainArgs const& margs,
256  Args&&... args
257  )
258  {
259  return base_t::make(
260  event,
261  std::forward<Handle>(mainHandle),
262  margs,
263  std::forward<Args>(args)...
264  );
265  }
266 
267  }; // struct ParallelDataProxyMaker<>
268 
269 
270  /// @}
271  // -- END Parallel data infrastructure ---------------------------------------
272 
273 
274  //----------------------------------------------------------------------------
275  namespace details {
276 
277  //--------------------------------------------------------------------------
278  //--- stuff for parallel data collection (a form of auxiliary data)
279  //--------------------------------------------------------------------------
280  template <typename Aux, typename AuxTag, typename AuxColl = void>
282  template <typename CollProxy>
284  <typename CollProxy::main_element_t, Aux, CollProxy, AuxTag, AuxColl>;
285  }; // struct ParallelDataProxyMakerWrapper<Aux, AuxTag, AuxColl>
286 
287  template <typename Aux, typename AuxTag>
288  struct ParallelDataProxyMakerWrapper<Aux, AuxTag, void> {
289  template <typename CollProxy>
291  <typename CollProxy::main_element_t, Aux, CollProxy, AuxTag>;
292  }; // struct ParallelDataProxyMakerWrapper<Aux, AuxTag>
293 
294 
295  } // namespace details
296 
297 
298 } // namespace proxy
299 
300 
301 #endif // LARDATA_RECOBASEPROXY_PROXYBASE_PARALLELDATAPROXYMAKER_H
Object to draft parallel data interface.
Definition: ParallelData.h:82
Helper functions to create proxy::ParallelData objects.
Creates an associated data wrapper for the specified types.
Definition: tag.cpp:4
static auto make(Event const &event, Handle &&mainHandle, MainArgs const &margs, Args &&...args)
Create a association proxy collection using main collection tag.
Auxiliary data from parallel data products.
static QCString args
Definition: declinfo.cpp:674
AuxColl aux_collection_t
Type of the auxiliary data product.
Creates an parallel data wrapper for the specified types.
unique_ptr< InputSource > make(ParameterSet const &conf, InputSourceDescription &desc)
static auto createFromTag(Event const &event, Handle &&, art::InputTag const &auxInputTag)
Definition: types.h:32
static auto make(Event const &event, Handle &&mainHandle, MainArgs const &mainArgs)
Create a parallel data proxy collection using main collection tag.
static auto make(Event const &event, Handle &&mainHandle, MainArgs const &, art::InputTag const &auxInputTag)
Create a parallel data proxy collection using the specified tag.
typename collection_value_type< Coll >::type collection_value_t
Type contained in the collection Coll.
Definition: ContainerMeta.h:65
C++ metaprogramming utilities for dealing with containers.
Event finding and building.