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
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
279  (recob::SpacePoint const& spacePoint, recob::PointCharge const& charge);
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!).
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!).
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.
Reconstruction base classes.
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::string string
Definition: nybbler.cc:12
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.
std::string fInstanceName
Instance name of all the data products.
Coord add(Coord c1, Coord c2)
Definition: restypedef.cpp:23
std::unique_ptr< art::PtrMaker< recob::SpacePoint > > fSpacePointPtrMaker
Space point pointer maker.
Information about charge reconstructed in the active volume.
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
Definition: StdUtils.h:92
art::Ptr< recob::PointCharge > lastChargePtr() const
Returns an art pointer to the inserted charge (no check!).
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().
Creates a collection of space points with associated charge.
std::unique_ptr< std::vector< recob::PointCharge > > fCharges
Charge data.
Definition: types.h:32
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.
vector< vector< double > > clear
int bool
Definition: qglobal.h:345
Event finding and building.
std::unique_ptr< art::PtrMaker< recob::PointCharge > > fChargePtrMaker
Charge pointer maker.
Charge reconstructed in the active volume.
Definition: PointCharge.h:31