All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ChargedSpacePointCreator.h
Go to the documentation of this file.
1 /**
2  * @file lardata/ArtDataHelper/ChargedSpacePointCreator.h
3  * @brief Helpers to create space points with associated charge.
4  * @author Gianluca Petrillo (petrillo@fnal.gov)
5  * @date December 21, 2017
6  * @see lardata/ArtDataHelper/ChargedSpacePointCreator.cpp
7  *
8  * The unit test for this utility is part of the `proxy::ChargedSpacePoints`
9  * unit test.
10  *
11  */
12 
13 #ifndef LARDATA_ARTDATAHELPER_CHARGEDSPACEPOINTCREATOR_H
14 #define LARDATA_ARTDATAHELPER_CHARGEDSPACEPOINTCREATOR_H
15 
16 // LArSoft libraries
19 
20 // framework libraries
21 #include "art/Persistency/Common/PtrMaker.h"
22 #include "canvas/Persistency/Common/Ptr.h"
23 
24 // C/C++ standard libraries
25 #include <vector>
26 #include <memory> // std::unique_ptr<>
27 #include <type_traits> // std::enable_if_t, ...
28 #include <cstdlib> // std::size_t
29 
30 namespace art { class Event; class ProducesCollector; }
31 
32 namespace recob {
33 
34  /**
35  * @brief Creates a collection of space points with associated charge.
36  *
37  * This class facilitates the creation of data products satisfying the
38  * requirements the `proxy::ChargedSpacePoints` proxy relies on.
39  * It will keep track of space points and reconstructed charge, and will put
40  * them into the event at the end.
41  *
42  * Requirements of the data products
43  * ==================================
44  *
45  * The requirements guaranteed by the output of this collection creator
46  * satisfy the `proxy::ChargedSpacePoints` proxy requirements.
47  * They are:
48  * * space points and charges stored in two separate data products
49  * * space points and charge in the same order, so that charge at position
50  * `i` is associated to space point at the same position `i`
51  * * one-to-one correspondence between each space point and its charge
52  * * association is implicit in the requirements above: no `art::Assns` data
53  * product is produced
54  *
55  *
56  * Usage
57  * ======
58  *
59  * The usage pattern is made of two main parts:
60  * # declaration of the data products, at producer construction time
61  * # production of the data products, event by event
62  *
63  * The second part happens within the context of the producer's `produce()`
64  * (or `filter()`, or equivalent) method, and it can be split into three
65  * stages:
66  * # construction of the collection creator, binding it to the current event
67  * # filling of the creator, usually in a loop
68  * # explicit transfer of the data products into the event
69  *
70  *
71  * Declaration of the data products
72  * ---------------------------------
73  *
74  * In the same fashion as data products must be declared to _art_ with a
75  * `produces()` call, the collection creator will have to perform an
76  * `equivalent step. This is achieved by calling the static `produces()`
77  * method from your module's constructor (see its documentation for an example).
78  *
79  *
80  * Construction of a collection creator object
81  * --------------------------------------------
82  *
83  * Collection creator objects are bound to a specific event and therefore
84  * can't be data members of the producer class. In the `produces()` method,
85  * we'll have:
86  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
87  * void MyProducer::produce(art::Event& event) {
88  *
89  * recob::ChargedSpacePointCollectionCreator spacePoints(event);
90  *
91  * // ...
92  *
93  * } // MyProducer::produce()
94  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
95  *
96  * If _art_ pointers to the data products are needed (e.g. to create
97  * associations), then the named-constructor idiom should be followed:
98  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
99  * void MyProducer::produce(art::Event& event) {
100  *
101  * auto spacePoints = recob::ChargedSpacePointCollectionCreator::forPtrs(event);
102  *
103  * // ...
104  *
105  * } // MyProducer::produce()
106  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
107  *
108  * In both cases, an instance name can be specified which will be used for all
109  * the managed data products (space points and reconstructed charge).
110  *
111  *
112  * Populating the collections
113  * ---------------------------
114  *
115  * The core of the usage of this object is feeding the objects to the data
116  * product collections. This is done using the `add()` member function.
117  * If the data objects already exist, they can be moved in instead of being
118  * copied. For example:
119  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
120  * void MyProducer::produce(art::Event& event) {
121  *
122  * recob::ChargedSpacePointCollectionCreator spacePoints(event);
123  *
124  * auto hitAssns
125  * = std::make_unique<art::Assns<recob::SpacePoint, recob::Hit>>();
126  *
127  * // some processing
128  *
129  * for (auto const& hitSet: hitSets) {
130  *
131  * recob::SpacePoint spacePoint;
132  * recob::PointCharge charge;
133  *
134  * fSpacePointChargeAlgo->run(hitSet, spacePoint, charge);
135  *
136  * // add the new space point and charge to the collection
137  * spacePoints.add(std::move(spacePoint), std::move(charge));
138  *
139  * // associate this space point with all the hits in the source set
140  * auto const& spacePointPtr = spacePoints.lastSpacePointPtr();
141  * for (art::Ptr<recob::Hit> const& hitPtr: hitSet)
142  * hitAssns.addSingle(spacePointPtr, hitPtr);
143  *
144  * } // for
145  *
146  * // ...
147  *
148  * } // MyProducer::produce()
149  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
150  *
151  * If your algorithm is creating a subcollection of space points and charges
152  * which are in the same order, a shortcut to a loop of `add()` is `addAll()`:
153  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
154  * void MyProducer::produce(art::Event& event) {
155  *
156  * recob::ChargedSpacePointCollectionCreator spacePoints(event);
157  *
158  * // some processing
159  *
160  * for (auto const& track: tracks) {
161  *
162  * std::vector<recob::SpacePoint> trackSpacePoints;
163  * std::vector<recob::PointCharge> trackCharges;
164  *
165  * fSpacePointChargeAlgo->run(track, trackSpacePoints, trackCharges);
166  *
167  * spacePoints.addAll
168  * (std::move(trackSpacePoints), std::move(trackCharges));
169  *
170  * } // for
171  *
172  * // ...
173  *
174  * } // MyProducer::produce()
175  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
176  *
177  *
178  *
179  * Operations on the collection
180  * -----------------------------
181  *
182  * While the collection creator object is designed to be just a single-use,
183  * single-pattern helper, there are a few operations that it allows:
184  *
185  * * query: the current number of space points (`size()`), whether there are
186  * any (`empty()`), and whether `put()` has been already called
187  * (`spent()`; see below)
188  * * deletion: it is possible to remove *all* the data so far collected;
189  * this may be useful in case of error, where the data product
190  * should be set in as default-constructed (which unfortunately
191  * in the case of space points _might_ be, albeit unlikely, a
192  * legal outcome)
193  * * if art::Ptr-creation has been enabled (by calling the static 'forPtrs(...)' function), _art_
194  * pointers can be created with `lastSpacePointPtr()`, `lastChargePtr()`, `spacePointPtr()`
195  * and `chargePtr()` to the elements of the future data products
196  *
197  *
198  * Insertion of the data products into the event
199  * ----------------------------------------------
200  *
201  * Again as in the standard producer pattern, where `Event::put()` needs to
202  * be called to finally move the data into _art_, the collection creator will
203  * need to be told to do the same:
204  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
205  * void MyProducer::produce(art::Event& event) {
206  *
207  * recob::ChargedSpacePointCollectionCreator spacePoints(event);
208  *
209  * auto hitAssns
210  * = std::make_unique<art::Assns<recob::SpacePoint, recob::Hit>>();
211  *
212  * // ... filling here ...
213  *
214  * spacePoints.put();
215  * event.put(std::move(hitAssns)); // other data products go the usual way
216  *
217  * } // MyProducer::produce()
218  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
219  * The instance name used in `put()` had been set at construction time.
220  *
221  * *After `put()` is called*, the object has served its purpose and *can't be
222  * used any further*. In this state, `spent()` method will return `true`.
223  *
224  */
226 
227  public:
228 
229  //--- BEGIN Constructors ---------------------------------------------------
230  /// @{
231  /// @name Constructors
232 
233  /**
234  * @brief Constructor binding this object to a specific _art_ event.
235  * @param event the _art_ event to bind to
236  * @param instanceName _(default: empty)_ instance name for all data
237  * products
238  *
239  * When the object is constructed with this constructor, the creation of
240  * _art_ pointers will not be enabled (`canMakePointers()` will return
241  * `false`).
242  */
244  (art::Event& event, std::string const& instanceName = {});
245 
246  /**
247  * @brief Static function binding a new object to a specific _art_ event.
248  * @param event the _art_ event to bind to
249  * @param instanceName _(default: empty)_ instance name for all data
250  * products
251  *
252  * This static function follows the named-constructor idiom,
253  * enabling the creation of _art_ pointers.
254  */
255  static ChargedSpacePointCollectionCreator forPtrs(art::Event& event,
256  std::string const& instanceName = {});
257 
258  /// @}
259  //--- END Constructors ---------------------------------------------------
260 
261 
262  //--- BEGIN Insertion and finish operations --------------------------------
263  /// @{
264  /// @name Insertion and finish operations
265 
266  //@{
267  /**
268  * @brief Inserts the specified space point and associated data into the
269  * collection.
270  * @param spacePoint the space point to be copied into the collection
271  * @param charge the charge to be copied into the collection
272  *
273  * The data is pushed as the new last element of the collection.
274  *
275  * Data is copied or moved depending on which variant of this method is
276  * used.
277  */
278  void add
280  void add(recob::SpacePoint&& spacePoint, recob::PointCharge&& charge);
281  //@}
282 
283  //@{
284  /**
285  * @brief Inserts all the space points and associated data from the vectors
286  * into the collection.
287  * @param spacePoints the space point to be copied into the collection
288  * @param charges the charges to be copied into the collection
289  * @throw cet::exception (category `ChargedSpacePointCollectionCreator`)
290  * if the input collections are inconsistent
291  *
292  * The data is pushed as the new last element of the collection.
293  *
294  * Data is copied or moved depending on which variant of this method is
295  * used.
296  *
297  * No exception safety is offered here.
298  */
299  void addAll(
300  std::vector<recob::SpacePoint>&& spacePoints,
301  std::vector<recob::PointCharge>&& charges
302  );
303  void addAll(
304  std::vector<recob::SpacePoint> const& spacePoints,
305  std::vector<recob::PointCharge> const& charges
306  );
307  //@}
308 
309  /**
310  * @brief Puts all data products into the event, leaving the creator
311  * `empty()`.
312  *
313  * The accumulated data is moved into the event.
314  *
315  * This is the last valid action of the object.
316  * After this, only `empty()`, `spent()` and the _art_ pointer makers
317  * (if enabled) are guaranteed to work.
318  */
319  void put();
320 
321 
322  /// @}
323  //--- END Insertion and finish operations --------------------------------
324 
325 
326  //--- BEGIN Queries and operations -----------------------------------------
327  /// @{
328  /// @name Queries and operations
329 
330  /// Returns whether there are currently no space points in the collection.
331  bool empty() const { return spent() || fSpacePoints->empty(); }
332 
333  /// Returns the number of space points currently in the collection.
334  std::size_t size() const { return spent()? 0U: fSpacePoints->size(); }
335 
336  /// Removes all data from the collection, making it `empty()`.
337  void clear();
338 
339  /// Returns whether `put()` has already been called.
340  bool spent() const { return !fSpacePoints; }
341 
342  /// Returns whether _art_ pointer making is enabled.
343  bool canMakePointers() const { return bool(fSpacePointPtrMaker); }
344 
345  ///@}
346  //--- END Queries and operations -------------------------------------------
347 
348 
349  //--- BEGIN Complimentary unchecked element access -------------------------
350  ///@{
351  ///@name Complimentary unchecked element access
352 
353  /// Returns the specified space point; undefined behaviour if not there.
354  recob::SpacePoint const& spacePoint(std::size_t i) const
355  { return fSpacePoints->operator[](i); }
356 
357  /// Returns the last inserted space point; undefined behaviour if `empty()`.
359  { return spacePoint(lastIndex()); }
360 
361  /// Returns an _art_ pointer to the specified space point (no check done!).
362  art::Ptr<recob::SpacePoint> spacePointPtr(std::size_t i) const;
363 
364  /// Returns an _art_ pointer to the last inserted space point (no check!).
365  art::Ptr<recob::SpacePoint> lastSpacePointPtr() const
366  { return spacePointPtr(lastIndex()); }
367 
368 
369  /// Returns the last inserted charge; undefined behaviour if `empty()`.
370  recob::PointCharge const& charge(std::size_t i) const
371  { return fCharges->operator[](i); }
372 
373  /// Returns the last inserted charge; undefined behaviour if `empty()`.
375  { return charge(lastIndex()); }
376 
377  /// Returns an _art_ pointer to the specified charge (no check done!).
378  art::Ptr<recob::PointCharge> chargePtr(std::size_t i) const;
379 
380  /// Returns an _art_ pointer to the inserted charge (no check!).
381  art::Ptr<recob::PointCharge> lastChargePtr() const
382  { return chargePtr(lastIndex()); }
383 
384  /// @}
385  //--- END Complimentary unchecked element access ---------------------------
386 
387 
388  //--- BEGIN Static constructor interface -----------------------------------
389  /// @{
390  /** @name Static constructor interface
391  *
392  * These methods take care of initialization that needs to take place on
393  * construction of the module.
394  */
395 
396  /**
397  * @brief Declares the data products being produced.
398  * @param producer the module producing the data products
399  * @param instanceName _(default: empty)_ name of instance of all data
400  * products
401  *
402  * Call this method in the constructor of `producer`, e.g.:
403  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
404  * MyProducer::MyProducer(Parameters const& config) {
405  *
406  * recob::ChargedSpacePointCollectionCreator::produces
407  * (producesCollector(), config().instanceName());
408  *
409  * } // MyProducer::MyProducer()
410  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
411  */
412  static void produces
413  (art::ProducesCollector& producesCollector, std::string const& instanceName = {});
414 
415  /// @}
416  //--- END Static constructor interface -------------------------------------
417 
418 
419  private:
420  art::Event& fEvent; ///< The event this object is bound to.
421 
422  std::string fInstanceName; ///< Instance name of all the data products.
423 
424  /// Space point data.
425  std::unique_ptr<std::vector<recob::SpacePoint>> fSpacePoints;
426  /// Space point pointer maker.
427  std::unique_ptr<art::PtrMaker<recob::SpacePoint>> fSpacePointPtrMaker;
428  /// Charge data.
429  std::unique_ptr<std::vector<recob::PointCharge>> fCharges;
430  /// Charge pointer maker.
431  std::unique_ptr<art::PtrMaker<recob::PointCharge>> fChargePtrMaker;
432 
433  /// Returns the index of the last element (undefined if empty).
434  std::size_t lastIndex() const { return size() - 1U; }
435 
436  }; // class ChargedSpacePointCollectionCreator
437 
438 } // namespace recob
439 
440 
441 //------------------------------------------------------------------------------
442 
443 #endif // LARDATA_ARTDATAHELPER_CHARGEDSPACEPOINTCREATOR_H
std::size_t size() const
Returns the number of space points currently in the collection.
art::Ptr< recob::SpacePoint > spacePointPtr(std::size_t i) const
Returns an art pointer to the specified space point (no check done!).
art::Event & fEvent
The event this object is bound to.
recob::PointCharge const & charge(std::size_t i) const
Returns the last inserted charge; undefined behaviour if empty().
std::size_t lastIndex() const
Returns the index of the last element (undefined if empty).
art::Ptr< recob::SpacePoint > lastSpacePointPtr() const
Returns an art pointer to the last inserted space point (no check!).
std::unique_ptr< std::vector< recob::SpacePoint > > fSpacePoints
Space point data.
static void produces(art::ProducesCollector &producesCollector, std::string const &instanceName={})
Declares the data products being produced.
std::string fInstanceName
Instance name of all the data products.
std::unique_ptr< art::PtrMaker< recob::SpacePoint > > fSpacePointPtrMaker
Space point pointer maker.
static constexpr bool
Information about charge reconstructed in the active volume.
art::Ptr< recob::PointCharge > lastChargePtr() const
Returns an art pointer to the inserted charge (no check!).
ChargedSpacePointCollectionCreator(art::Event &event, std::string const &instanceName={})
Constructor binding this object to a specific art event.
bool spent() const
Returns whether put() has already been called.
recob::PointCharge const & lastCharge() const
Returns the last inserted charge; undefined behaviour if empty().
bool empty() const
Returns whether there are currently no space points in the collection.
recob::SpacePoint const & lastSpacePoint() const
Returns the last inserted space point; undefined behaviour if empty().
static ChargedSpacePointCollectionCreator forPtrs(art::Event &event, std::string const &instanceName={})
Static function binding a new object to a specific art event.
Creates a collection of space points with associated charge.
art::Ptr< recob::PointCharge > chargePtr(std::size_t i) const
Returns an art pointer to the specified charge (no check done!).
std::unique_ptr< std::vector< recob::PointCharge > > fCharges
Charge data.
void addAll(std::vector< recob::SpacePoint > &&spacePoints, std::vector< recob::PointCharge > &&charges)
Inserts all the space points and associated data from the vectors into the collection.
bool canMakePointers() const
Returns whether art pointer making is enabled.
recob::SpacePoint const & spacePoint(std::size_t i) const
Returns the specified space point; undefined behaviour if not there.
void put()
Puts all data products into the event, leaving the creator empty().
void clear()
Removes all data from the collection, making it empty().
void add(recob::SpacePoint const &spacePoint, recob::PointCharge const &charge)
Inserts the specified space point and associated data into the collection.
std::unique_ptr< art::PtrMaker< recob::PointCharge > > fChargePtrMaker
Charge pointer maker.
Charge reconstructed in the active volume.
Definition: PointCharge.h:31