All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GeometryDataContainers.h
Go to the documentation of this file.
1 /**
2  * @file larcorealg/Geometry/GeometryDataContainers.h
3  * @brief Containers to hold one datum per TPC or plane.
4  * @author Gianluca Petrillo (petrillo@fnal.gov)
5  * @date January 2nd, 2018
6  * @ingroup Geometry
7  *
8  * This is a header-only library.
9  */
10 
11 #ifndef LARCOREALG_GEOMETRY_GEOMETRYDATACONTAINERS_H
12 #define LARCOREALG_GEOMETRY_GEOMETRYDATACONTAINERS_H
13 
14 // LArSoft libraries
18 
19 // Boost libraries
20 #include <boost/iterator/iterator_adaptor.hpp>
21 #include <boost/iterator/transform_iterator.hpp>
22 
23 // C/C++ standard libraries
24 #include <vector>
25 #include <initializer_list>
26 #include <string>
27 #include <utility> // std::forward()
28 #include <algorithm> // std::fill(), std::for_each()
29 #include <stdexcept> // std::out_of_range
30 #include <cassert>
31 
32 
33 namespace geo {
34 
35  template <typename T, typename Mapper>
37 
38  template <typename T>
40 
41  template <typename T>
43 
44  // ---------------------------------------------------------------------------
45  namespace details {
46 
47  template <typename T>
49 
50  template <typename GeoIDdataContainerClass, typename BaseIterator>
52 
53  template <typename GeoIDIteratorClass>
55 
56  } // namespace details
57  // ---------------------------------------------------------------------------
58 
59 } // namespace geo
60 
61 
62 // --- BEGIN Geometry data containers ----------------------------------------
63 
64 /// @name Geometry data containers
65 /// @ingroup Geometry
66 /// @{
67 
68 /** **************************************************************************
69  * @brief Container with one element per geometry TPC.
70  * @tparam T type of the contained datum
71  * @see `geo::GeometryCore::makeTPCData`
72  *
73  * The container is of fixed size and can't be neither resized nor freed
74  * before destruction.
75  *
76  * This example creates a "map" of tracks starting on each TPC:
77  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
78  * auto const* geom = lar::providerFrom<geo::GeometryCore>();
79  * geo::TPCDataContainer<std::vector<recob::Track const*>> TracksPerTPC
80  * (geom->NCryostats(), geom->MaxTPCs());
81  *
82  * for (recob::Track const& track: tracks) {
83  * geo::TPCGeo const* tpc = geom->PositionToTPCptr(track.Start());
84  * if (tpc) TracksPerTPC[tpc->ID()].push_back(tpc);
85  * } // for
86  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
87  *
88  *
89  * Assumptions
90  * ============
91  *
92  * The following assumptions should be considered unchecked, and the behavior
93  * when they are violated undefined (but note that in debug mode some of them
94  * might be actually checked):
95  * * the container assumes the same number of TPCs in each cryostat. While
96  * this is not effectively a necessary condition, keep in mind that this
97  * container has no notion whether a given TPC actually exists in the
98  * geometry or not
99  * * at least one element is expected to be present
100  *
101  */
102 template <typename T, typename Mapper>
104 
105  using This_t = geo::GeoIDdataContainer<T, Mapper>; ///< Type of this class.
106 
107  /// Type of data container helper.
109 
110  /// Type of iterator to the data.
112 
113  /// Type of constant iterator to the data.
115 
116  /// Functor to extract an ID data member.
117  struct IDextractor {
118  template <typename Obj>
119  decltype(auto) operator()(Obj&& obj) const { return obj.ID(); }
120  }; // struct IDextractor
121 
122  public:
123 
124  /// Type of mapper between IDs and index.
125  using Mapper_t = Mapper;
126 
127  using ID_t = typename Mapper_t::ID_t; ///< Type used as ID for this container.
128 
129  /// @{
130  /// @name STL container types.
131 
135  using pointer = typename Container_t::pointer ;
139 // using reverse_iterator = typename Container_t::reverse_iterator ;
140 // using const_reverse_iterator = typename Container_t::const_reverse_iterator;
143 
144  /// Special iterator dereferencing to pairs ( ID, value ) (see `items()`).
146 
147  /// Special iterator dereferencing to pairs ( ID, value ) (see `items()`).
149 
150  /// @}
151 
152  /**
153  * @brief Default constructor: container has no room at all.
154  * @see `resize()`
155  *
156  * The object *must* be resized before being of any use.
157  */
158  GeoIDdataContainer() = default;
159 
160  /**
161  * @brief Prepares the container with default-constructed data.
162  * @param dims number of elements on all levels of the container
163  * @see `resize()`
164  *
165  * The size of each dimension is specified by the corresponding number,
166  * starting from the size of the outer dimension (cryostat).
167  *
168  * The container is sized to host data for all the elements.
169  * Each element in the container is default-constructed.
170  */
171  GeoIDdataContainer(std::initializer_list<unsigned int> dims);
172 
173  /**
174  * @brief Prepares the container initializing all its data.
175  * @param dims number of elements on all levels of the container
176  * @param defValue the value copied to fill all entries in the container
177  * @see `resize()`
178  *
179  * The size of each dimension is specified by the corresponding number,
180  * starting from the size of the outer dimension (cryostat).
181  *
182  * The container is sized to host data for all the elements.
183  * Each element in the container is constructed as copy of `defValue`.
184  */
186  std::initializer_list<unsigned int> dims,
187  value_type const& defValue
188  );
189 
190 
191  // --- BEGIN Container status query ----------------------------------------
192  /// @name Container status query
193  /// @{
194 
195  /// Returns the number of elements in the container.
196  size_type size() const;
197 
198  /// Returns the number of elements the container has memory for.
199  size_type capacity() const;
200 
201  /// Returns whether the container has no elements (`false` by assumptions).
202  bool empty() const;
203 
204  /// Dimensions of the `Level` dimension of this container.
205  template <std::size_t Level>
206  unsigned int dimSize() const;
207 
208  /// Dimensions of the ID of this container.
209  static constexpr unsigned int dimensions();
210 
211  /// Returns whether this container hosts data for the specified ID.
212  template <typename GeoID>
213  bool hasElement(GeoID const& id) const;
214 
215  /// Returns the ID of the first element with GeoID type.
216  template <typename GeoID = ID_t>
217  GeoID firstID() const;
218 
219  /// Returns the ID of the last covered element with GeoID type.
220  template <typename GeoID = ID_t>
221  GeoID lastID() const;
222 
223  /// Returns the mapper object used to convert ID's and container positions.
224  Mapper_t const& mapper() const;
225 
226  /// @}
227  // --- END Container status query ------------------------------------------
228 
229 
230  // --- BEGIN Element access ------------------------------------------------
231  /// @name Element access
232  /// @{
233 
234  /// Returns the element for the specified geometry element.
235 
236  reference operator[](ID_t const& id);
237 
238  /// Returns the element for the specified geometry element (read-only).
239  const_reference operator[](ID_t const& id) const;
240 
241  /// Returns the element for the specified geometry element.
242  /// @throw std::out_of_range if element `id` is not within the container range
243  reference at(ID_t const& id);
244 
245  /// Returns the element for the specified geometry element (read-only).
246  /// @throw std::out_of_range if element `id` is not within the container range
247  const_reference at (ID_t const& id) const;
248 
249 
250  /// Returns the element for the first ID (unchecked).
251  reference first();
252 
253  /// Returns the element for the first ID (unchecked).
254  const_reference first() const;
255 
256 
257  /// Returns the element for the last ID (unchecked).
258  reference last();
259 
260  /// Returns the element for the last ID (unchecked).
261  const_reference last() const;
262 
263  /// @}
264  // --- END Element access --------------------------------------------------
265 
266 
267  // --- BEGIN Iterators -----------------------------------------------------
268  /**
269  * @name Iterators
270  *
271  * Two types of iterators are provided:
272  *
273  * 1. "standard" iterators pointing to data values
274  * 2. "item" pseudo-iterators dereferencing to a (ID, value) pair
275  *
276  * Reverse iterators are not supported (yet?).
277  *
278  * Standard iterators
279  * -------------------
280  *
281  * The STL-like interface provides iterators that go through the entire range
282  * of allowed data, i.e. all the `size()` elements that are also reached
283  * via random access (`operator[]()`).
284  *
285  * These iterators have an interface extension: the data member `ID()` returns
286  * the ID of the element the iterator is pointing to. For example:
287  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
288  * auto iData = data.begin();
289  * auto const dend = data.end();
290  * while (iData != dend) {
291  * std::cout << "data[" << iData.ID() << "] = " << *iData << std::endl;
292  * ++iData;
293  * } // while
294  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
295  * Note that using the range-for loop, you don't get access to the iterator
296  * and therefore not even to the ID.
297  *
298  *
299  * Item iterators
300  * ---------------
301  *
302  * The item iterators are iterators adapted from the standard ones, which
303  * when dereferenced return a pair ( `ID_t`, `reference` ).
304  * They can be accessed with `item_begin()`, `item_end()` etc, and range-for
305  * loop can be obtained via `items()` member function:
306  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
307  * for (auto&& [ ID, value ]: data.items()) {
308  * std::cout << "data[" << ID << "] = " << value << std::endl;
309  * }
310  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
311  * (this loop has the same effect as the one in the example of the standard
312  * iterators, but it's more compact).
313  *
314  */
315  /// @{
316 
317  /// Returns an iterator to the beginning of the data.
318  iterator begin();
319 
320  /// Returns an iterator to past the end of the data.
321  iterator end();
322 
323  /// Returns a constant iterator to the beginning of the data.
324  const_iterator begin() const;
325 
326  /// Returns a constant iterator to past the end of the data.
327  const_iterator end() const;
328 
329  /// Returns a constant iterator to the beginning of the data.
330  const_iterator cbegin() const;
331 
332  /// Returns a constant iterator to past the end of the data.
333  const_iterator cend() const;
334 
335  /// Returns an item iterator to the beginning of the data.
337 
338  /// Returns an item iterator to past the end of the data.
340 
341  /// Returns a item constant iterator to the beginning of the data.
343 
344  /// Returns a item constant iterator to past the end of the data.
346 
347  /// Returns a item constant iterator to the beginning of the data.
349 
350  /// Returns a item constant iterator to past the end of the data.
352 
353  /// Returns an object suitable for a range-for loop with `item_iterator`.
354  auto items();
355 
356  /// Returns an object suitable for a range-for loop with `item_const_iterator`.
357  auto items() const;
358 
359  /// @}
360  // --- END Iterators -------------------------------------------------------
361 
362 
363  // --- BEGIN Data modification ---------------------------------------------
364  /**
365  * @name Data modification
366  *
367  * In general, each single element can be accessed and changed.
368  * In addition, this section includes methods acting on multiple elements
369  * at once.
370  */
371  /// @{
372 
373  /// Sets all elements to the specified `value` (copied).
374  void fill(value_type value);
375 
376  /// Sets all the elements to a default-constructed `value_type`.
377  void reset();
378 
379 
380  /**
381  * @brief Applies an operation on all elements.
382  * @tparam Op type of operation
383  * @param op Operation
384  * @return the operation object after operations took place
385  *
386  * The operation `op` is a unary functor, i.e. an object that supports the
387  * call to `op(value_type&)`.
388  *
389  * The return values of `op` calls are discarded.
390  */
391  template <typename Op>
392  Op apply(Op&& op);
393 
394  /**
395  * @brief Applies an operation on all elements.
396  * @tparam Op type of operation
397  * @param op Operation
398  * @return the operation object after operations took place
399  *
400  * The operation `op` is a unary functor, i.e. an object that supports the
401  * call to `op(value_type const&)`.
402  *
403  * The return values of `op` calls are discarded.
404  * Note that while the elements of this container can't be modified, the
405  * operation itself still can if not constant, and it is returned.
406  */
407  template <typename Op>
408  decltype(auto) apply(Op&& op) const;
409 
410  /// @}
411  // --- END Data modification -------------------------------------------------
412 
413 
414  // --- BEGIN Container modification ------------------------------------------
415  /// @name Container modification
416  /// @{
417 
418  /**
419  * @brief Prepares the container with default-constructed data.
420  * @param dims number of elements on all levels of the container
421  * @see `clear()`, `fill()`
422  *
423  * The size of each dimension is specified by the corresponding number,
424  * starting from the size of the outer dimension (cryostat).
425  *
426  * The container is sized to host data for all the elements.
427  * Each new element in the container is default-constructed.
428  * Existing data is not touched, but it may be rearranged in a
429  * non-straightforward way.
430  */
431  void resize(std::initializer_list<unsigned int> dims);
432 
433  /**
434  * @brief Prepares the container initializing all its data.
435  * @param dims number of elements on all levels of the container
436  * @param defValue the value copied to fill all entries in the container
437  * @see `clear()`, `fill()`
438  *
439  * The size of each dimension is specified by the corresponding number,
440  * starting from the size of the outer dimension (cryostat).
441  *
442  * The container is sized to host data for all the elements.
443  * Each new element in the container is constructed as copy of `defValue`.
444  * Existing data is not touched, but it may be rearranged in a
445  * non-straightforward way.
446  */
447  void resize
448  (std::initializer_list<unsigned int> dims, value_type const& defValue);
449 
450 
451  /**
452  * @brief Prepares the container with default-constructed data.
453  * @param other data collection to take dimensions from
454  *
455  * The size of each dimension is taken by the matching one in `other`.
456  *
457  * The container is sized to host data for all the elements.
458  * Each new element in the container is default-constructed.
459  * Existing data is not touched, but it may be rearranged in a
460  * non-straightforward way.
461  */
462  template <typename OT>
463  void resizeAs(geo::GeoIDdataContainer<OT, Mapper_t> const& other);
464 
465  /**
466  * @brief Prepares the container initializing all its data.
467  * @param other data collection to take dimensions from
468  * @param defValue the value copied to fill all entries in the container
469  *
470  * The size of each dimension is taken by the matching one in `other`.
471  *
472  * The container is sized to host data for all the elements.
473  * Each new element in the container is constructed as copy of `defValue`.
474  * Existing data is not touched, but it may be rearranged in a
475  * non-straightforward way.
476  */
477  template <typename OT>
478  void resizeAs(
479  geo::GeoIDdataContainer<OT, Mapper_t> const& other,
480  value_type const& defValue
481  );
482 
483  /**
484  * @brief Makes the container empty, with no usable storage space.
485  * @see `resize()`
486  *
487  * The container needs to be resized before it is useful again.
488  */
489  void clear();
490 
491 
492  /// @}
493  // --- END Container modification --------------------------------------------
494 
495 
496  private:
497 
498  Mapper_t fMapper; ///< Mapping of IDs to indices.
499 
500  Container_t fData; ///< Data storage.
501 
502 
503  /// Returns the internal index of the specified ID in the storage area.
504  size_type index(ID_t const& id) const;
505 
506  /// Returns the ID corresponding to a internal index in the storage area.
507  ID_t ID(size_type const index) const;
508 
509 
510 }; // class geo::GeoIDdataContainer<>
511 
512 
513 //------------------------------------------------------------------------------
514 /**
515  * @brief Container with one element per geometry TPC.
516  * @tparam T type of the contained datum
517  * @see `geo::GeometryCore::makeTPCData`
518  *
519  * The container is of fixed size and can't be neither resized nor freed
520  * before destruction.
521  *
522  * This example creates a "map" of tracks starting on each TPC:
523  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
524  * auto const* geom = lar::providerFrom<geo::GeometryCore>();
525  * geo::TPCDataContainer<std::vector<recob::Track const*>> TracksPerTPC
526  * (geom->NCryostats(), geom->MaxTPCs());
527  *
528  * for (recob::Track const& track: tracks) {
529  * geo::TPCGeo const* tpc = geom->PositionToTPCptr(track.Start());
530  * if (tpc) TracksPerTPC[tpc->ID()].push_back(tpc);
531  * } // for
532  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
533  *
534  *
535  * Assumptions
536  * ============
537  *
538  * The following assumptions should be considered unchecked, and the behavior
539  * when they are violated undefined (but note that in debug mode some of them
540  * might be actually checked):
541  * * the container assumes the same number of TPCs in each cryostat. While
542  * this is not effectively a necessary condition, keep in mind that this
543  * container has no notion whether a given TPC actually exists in the
544  * geometry or not
545  * * at least one element is expected to be present
546  *
547  */
548 template <typename T>
549 class geo::TPCDataContainer
550  : public geo::GeoIDdataContainer<T, geo::TPCIDmapper<>>
551 {
552 
554 
555  public:
556 
558 
559  /**
560  * @brief Default constructor: empty container.
561  * @see `resize()`
562  *
563  * The container starts with no room for any data.
564  * The only guarantee is that `empty()` is `true` and `size()` is `0`.
565  * Use `resize()` before anything else.
566  */
567  TPCDataContainer() = default;
568 
569  /**
570  * @brief Prepares the container with default-constructed data.
571  * @param nCryo number of cryostats
572  * @param nTPCs number of TPCs
573  *
574  * The container is sized to host data for `nCryo` cryostats, each with
575  * `nTPCs` TPCs. Each element in the container is default-constructed.
576  */
577  TPCDataContainer(unsigned int nCryo, unsigned int nTPCs)
578  : BaseContainer_t({ nCryo, nTPCs })
579  {}
580 
581  /**
582  * @brief Prepares the container with copies of the specified default value.
583  * @param nCryo number of cryostats
584  * @param nTPCs number of TPCs
585  * @param defValue the value to be replicated
586  *
587  * The container is sized to host data for `nCryo` cryostats, each with
588  * `nTPCs` TPCs. Each element in the container is a copy of defValue.
589  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
590  * auto const* geom = lar::providerFrom<geo::GeometryCore>();
591  * geo::TPCDataContainer<unsigned int> PlanesPerTPC
592  * (geom->NCryostats(), geom->MaxTPCs(), 3U);
593  * for (geo::TPCGeo const& TPC: geom->IterateTPC())
594  * assert(PlanesPerTPC[TPC.ID()] == TPC.Nplanes());
595  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
596  */
597  TPCDataContainer
598  (unsigned int nCryo, unsigned int nTPCs, value_type const& defValue)
599  : BaseContainer_t({ nCryo, nTPCs }, defValue)
600  {}
601 
602 
603  // --- BEGIN Container modification ------------------------------------------
604  /// @name Container modification
605  /// @{
606 
607  /**
608  * @brief Prepares the container with default-constructed data.
609  * @param nCryo number of cryostats
610  * @param nTPCs number of TPCs
611  * @see `clear()`, `fill()`
612  *
613  * The container is sized to host data for `nCryo` cryostats, each with
614  * `nTPCs` TPCs. Each element in the container is default-constructed.
615  *
616  * Existing data is not touched, but it may be rearranged in a
617  * non-straightforward way.
618  */
619  void resize(unsigned int nCryo, unsigned int nTPCs)
620  { BaseContainer_t::resize({ nCryo, nTPCs }); }
621 
622  /**
623  * @brief Prepares the container initializing all its data.
624  * @param nCryo number of cryostats
625  * @param nTPCs number of TPCs
626  * @param defValue the value copied to fill all entries in the container
627  * @see `clear()`, `fill()`
628  *
629  * The container is sized to host data for `nCryo` cryostats, each with
630  * `nTPCs` TPCs. Each element in the container is a copy of `defValue`.
631  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
632  * auto const* geom = lar::providerFrom<geo::GeometryCore>();
633  * geo::TPCDataContainer<unsigned int> countPerPlane
634  * countPerPlane.resize(geom->NCryostats(), geom->MaxTPCs(), 0U);
635  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
636  *
637  * Existing data is not touched, but it may be rearranged in a
638  * non-straightforward way.
639  */
640  void resize(unsigned int nCryo, unsigned int nTPCs, T const& defValue)
641  { BaseContainer_t::resize({ nCryo, nTPCs }, defValue); }
642 
643  /// @}
644  // --- END Container modification --------------------------------------------
645 
646 
647  // --- BEGIN Container status query ------------------------------------------
648  /// @name Container status query
649  /// @{
650 
651  /// Returns whether this container hosts data for the specified cryostat.
652  bool hasCryostat(geo::CryostatID const& cryoid) const
653  { return BaseContainer_t::hasElement(cryoid); }
654 
655  /// Returns whether this container hosts data for the specified TPC.
656  bool hasTPC(geo::TPCID const& tpcid) const
657  { return BaseContainer_t::hasElement(tpcid); }
658 
659  /// @}
660  // --- END Container status query --------------------------------------------
661 
662 
663 }; // class geo::details::TPCDataContainer<>
664 
665 
666 //------------------------------------------------------------------------------
667 /**
668  * @brief Container with one element per geometry wire plane.
669  * @tparam T type of the contained datum
670  * @see `geo::GeometryCore::makePlaneData`
671  *
672  * The container is of fixed size and can't be neither resized nor freed
673  * before destruction.
674  *
675  * This example creates a "map" of hits on each wire plane:
676  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
677  * auto const* geom = lar::providerFrom<geo::GeometryCore>();
678  * geo::PlaneDataContainer<std::vector<recob::Hit const*>> hitsPerPlane
679  * (geom->NCryostats(), geom->MaxTPCs(), geom->MaxPlanes());
680  *
681  * for (recob::Hit const& hit: hits) {
682  * if (hit.WireID()) hitsPerPlane[hit.WireID().planeID()].push_back(&hit);
683  * } // for
684  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
685  *
686  *
687  * Assumptions
688  * ============
689  *
690  * The following assumptions should be considered unchecked, and the behavior
691  * when they are violated undefined (but note that in debug mode some of them
692  * might be actually checked):
693  * * the container assumes the same number of planes in all TPCs, and of TPCs
694  * on all cryostats. While this is not effectively a necessary condition,
695  * keep in mind that this container has no notion whether a given plane or
696  * TPC actually exists in the geometry or not
697  * * at least one element is expected to be present
698  *
699  */
700 template <typename T>
702  : public geo::GeoIDdataContainer<T, geo::PlaneIDmapper<>>
703 {
704 
705  /// Base class.
707 
708  public:
709 
710  /**
711  * @brief Default constructor: empty container.
712  * @see `resize()`
713  *
714  * The container starts with no room for any data.
715  * The only guarantee is that `empty()` is `true` and `size()` is `0`.
716  * Use `resize()` before anything else.
717  */
718  PlaneDataContainer() = default;
719 
720  /**
721  * @brief Prepares the container with default-constructed data.
722  * @param nCryo number of cryostats
723  * @param nTPCs number of TPCs per cryostat
724  * @param nPlanes number of planes per TPC
725  *
726  * The container is sized to host data for `nCryo` cryostats, each with
727  * `nTPCs` TPCs, each one with `nPlanes` wire planes. Each element in the
728  * container is default-constructed.
729  */
731  (unsigned int nCryo, unsigned int nTPCs, unsigned int nPlanes)
732  : BaseContainer_t({ nCryo, nTPCs, nPlanes })
733  {}
734 
735  /**
736  * @brief Prepares the container with copies of the specified default value.
737  * @param nCryo number of cryostats
738  * @param nTPCs number of TPCs
739  * @param nPlanes number of planes per TPC
740  * @param defValue the value to be replicated
741  *
742  * The container is sized to host data for `nCryo` cryostats, each with
743  * `nTPCs` TPCs, and each of them with `nPlanes` planes. Each element in
744  * the container is a copy of `defValue`.
745  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
746  * auto const* geom = lar::providerFrom<geo::GeometryCore>();
747  * geo::PlaneDataContainer<unsigned int> countPerPlane
748  * (geom->NCryostats(), geom->MaxTPCs(), geom->MaxPlanes(), 0U);
749  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
750  */
751  PlaneDataContainer(
752  unsigned int nCryo, unsigned int nTPCs, unsigned int nPlanes,
753  T const& defValue
754  )
755  : BaseContainer_t{ { nCryo, nTPCs, nPlanes }, defValue }
756  {}
757 
758 
759  // --- BEGIN Container modification ------------------------------------------
760  /// @name Container modification
761  /// @{
762 
763  /**
764  * @brief Prepares the container with default-constructed data.
765  * @param nCryo number of cryostats
766  * @param nTPCs number of TPCs
767  * @param nPlanes number of planes per TPC
768  * @see `clear()`, `fill()`
769  *
770  * The container is sized to host data for `nCryo` cryostats, each with
771  * `nTPCs` TPCs, each one with `nPlanes` wire planes. Each element in the
772  * container is default-constructed.
773  *
774  * Existing data is not touched, but it may be rearranged in a
775  * non-straightforward way.
776  */
777  void resize(unsigned int nCryo, unsigned int nTPCs, unsigned int nPlanes)
778  { BaseContainer_t::resize({ nCryo, nTPCs, nPlanes }); }
779 
780  /**
781  * @brief Prepares the container initializing all its data.
782  * @param nCryo number of cryostats
783  * @param nTPCs number of TPCs
784  * @param nPlanes number of planes per TPC
785  * @param defValue the value copied to fill all entries in the container
786  * @see `clear()`, `fill()`
787  *
788  * The container is sized to host data for `nCryo` cryostats, each with
789  * `nTPCs` TPCs, and each of them with `nPlanes` planes. Each element in
790  * the container is a copy of `defValue`.
791  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
792  * auto const* geom = lar::providerFrom<geo::GeometryCore>();
793  * geo::PlaneDataContainer<unsigned int> countPerPlane
794  * countPerPlane.resize
795  * (geom->NCryostats(), geom->MaxTPCs(), geom->MaxPlanes(), 0U);
796  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
797  *
798  * Existing data is not touched, but it may be rearranged in a
799  * non-straightforward way.
800  */
801  void resize(
802  unsigned int nCryo, unsigned int nTPCs, unsigned int nPlanes,
803  T const& defValue
804  )
805  { BaseContainer_t::resize({ nCryo, nTPCs, nPlanes }, defValue); }
806 
807  /// @}
808  // --- END Container modification --------------------------------------------
809 
810 
811  // --- BEGIN Container status query ------------------------------------------
812  /// @name Container status query
813  /// @{
814 
815  /// Returns whether this container hosts data for the specified cryostat.
816  bool hasCryostat(geo::CryostatID const& cryoid) const
817  { return BaseContainer_t::hasElement(cryoid); }
818 
819  /// Returns whether this container hosts data for the specified TPC.
820  bool hasTPC(geo::TPCID const& tpcid) const
821  { return BaseContainer_t::hasElement(tpcid); }
822 
823  /// Returns whether this container hosts data for the specified plane.
824  bool hasPlane(geo::PlaneID const& planeid) const
825  { return BaseContainer_t::hasElement(planeid); }
826 
827  /// @}
828  // --- END Container status query --------------------------------------------
829 
830 
831 }; // class geo::PlaneDataContainer
832 
833 
834 //------------------------------------------------------------------------------
835 /**
836  * @brief Iterator for `geo::GeoIDdataContainer` class.
837  * @tparam GeoIDdataContainerClass type of the class being iterated
838  * @tparam BaseIterator type of iterator to the actual data
839  *
840  * @note These iterators haven't been extensively tested. Caveat emptor...
841  */
842 template <typename GeoIDmapperClass, typename BaseIterator>
844  : public boost::iterator_adaptor<
845  geo::details::GeoIDdataContainerIterator<GeoIDmapperClass, BaseIterator>
846  , BaseIterator
847  >
848 {
849 
850  ///< Type of mapping of the container this class iterates.
851  using Mapper_t = GeoIDmapperClass;
852 
853  using BaseIterator_t = BaseIterator; ///< Type of iterator to the actual data.
854 
855  /// Type of index in the container mapping.
856  using Index_t = typename Mapper_t::index_type;
857 
858  struct ExtraData_t {
859 
860  /// Mapping of the container being iterated.
861  Mapper_t const* mapper = nullptr;
862 
863  BaseIterator_t start; ///< Iterator to the first element.
864 
865  }; // struct ExtraData_t
866 
867  ExtraData_t fData; ///< Data for extended features of this iterator.
868 
869  /// Returns the iterator to the current element.
870  BaseIterator_t const& current() const
871  { return GeoIDdataContainerIterator::iterator_adaptor_::base(); }
873  { return GeoIDdataContainerIterator::iterator_adaptor_::base(); }
874 
875  /// Returns the iterator to the begin element.
876  BaseIterator_t const& start() const { return fData.start; }
877 
878  /// Returns the mapping of the container being iterated.
879  Mapper_t const& mapper() const
880  { assert(fData.mapper); return *(fData.mapper); }
881 
882  /// Returns the index of the current element
883  Index_t index() const { return static_cast<Index_t>(current() - start()); }
884 
885  public:
886 
887  using ID_t = typename Mapper_t::ID_t; ///< Type of the ID in this iterator.
888 
889 
890  /// Default constructor: undefined status.
891  GeoIDdataContainerIterator() = default;
892 
893  /// Constructor: points to data pointed by `current`.
895  Mapper_t const& mapper,
896  BaseIterator_t const& start,
897  BaseIterator_t const& current
898  )
899  : GeoIDdataContainerIterator::iterator_adaptor_(current)
900  , fData{ &mapper, start }
901  {}
902 
903  /// Generalized copy constructor, only if argument iterator can be converted.
904  template <typename OBaseIterator>
907  std::enable_if_t<std::is_convertible_v<OBaseIterator, BaseIterator_t>>
908  = nullptr
909  )
910  : GeoIDdataContainerIterator::iterator_adaptor_(other.base())
911  , fData(other.fData)
912  {}
913 
914  /// Returns the ID corresponding to the current element.
915  ID_t ID() const { return mapper().ID(index()); }
916 
917  private:
918 // friend class boost::iterator_core_access;
919 
920  // there might be some need for other interoperability methods (comparison?)
921 
922 }; // geo::details::GeoIDdataContainerIterator
923 
924 
925 
926 /**
927  * @brief Item iterator for `geo::GeoIDdataContainer` class.
928  * @tparam GeoIDIteratorClass type of iterator being wrapped
929  *
930  * This iterator is just a wrapper.
931  *
932  * @note These iterators haven't been extensively tested. Caveat emptor...
933  */
934 template <typename GeoIDIteratorClass>
936  : public boost::iterator_adaptor<
937  geo::details::GeoIDdataContainerItemIterator<GeoIDIteratorClass>
938  , GeoIDIteratorClass
939  , std::pair<
940  typename GeoIDIteratorClass::ID_t,
941  typename GeoIDIteratorClass::reference
942  > // Value
943  , boost::use_default // Category
944  , std::pair<
945  typename GeoIDIteratorClass::ID_t,
946  typename GeoIDIteratorClass::reference
947  > // Reference
948  >
949 {
950  /*
951  * Implementation notes:
952  * * boost::transform_iterator can't be used to wrap
953  * `geo::GeoIDdataContainerIterator` because it acts on the value of
954  * the wrapped iterator, while we need to extract information from
955  * the iterator itself (its `ID()` data member)
956  * * we need to specify the type of reference the iterator returns,
957  * because... it's not a reference; this is not really a STL random
958  * access iterator since it dereferences to a temporary value (rvalue)
959  * like an input iterator can; but for the rest it's a full blown random
960  * access iterator (same stuff as the infamous `std::vector<bool>`)
961  *
962  */
963 
964  using GeoIDiterator_t = GeoIDIteratorClass; ///< Type of wrapped iterator.
965 
966  using iterator_adaptor_
968 
969  public:
970 
971  /// Type of the ID in this iterator.
972  using ID_t = typename GeoIDiterator_t::ID_t;
973 
974 
975  /// Default constructor: undefined status.
976  GeoIDdataContainerItemIterator() = default;
977 
978  /// Constructor: points to data pointed by `current`.
980  : iterator_adaptor_(iter)
981  {}
982 
983  /// Generalized copy constructor, only if argument iterator can be converted.
984  template <typename OGeoIDIteratorClass>
987  std::enable_if_t<std::is_convertible_v<OGeoIDIteratorClass, GeoIDiterator_t>>
988  = nullptr
989  )
990  : iterator_adaptor_(other.base())
991  {}
992 
993 
994  private:
995  friend class boost::iterator_core_access;
996 
997  using iterator_adaptor_::base;
998 
999  typename iterator_adaptor_::reference dereference() const
1000  { return { base().ID(), *base() }; }
1001 
1002  // there might be some need for other interoperability methods (comparison?)
1003 
1004 }; // geo::details::GeoIDdataContainerItemIterator
1005 
1006 
1007 
1008 /// @}
1009 // --- END Geometry data containers --------------------------------------------
1010 //------------------------------------------------------------------------------
1011 
1012 
1013 
1014 //------------------------------------------------------------------------------
1015 //--- Template implementation
1016 //------------------------------------------------------------------------------
1017 //--- geo::details::GeoContainerData
1018 //------------------------------------------------------------------------------
1019 template <typename T>
1021 
1022  using Container_t = std::vector<T>;
1023 
1024  public:
1025 
1026  // --- BEGIN STL container types ---------------------------------------------
1027  /// @{
1028  /// @name STL container types.
1029 
1033  using pointer = typename Container_t::pointer ;
1035  using iterator = typename Container_t::iterator ;
1041 
1042  /// @}
1043  // --- END STL container types -----------------------------------------------
1044 
1045 
1046  using index_type = size_type; ///< Type used internally (so far) for indexing.
1047 
1048  // --- BEGIN Constructors ----------------------------------------------------
1049 
1050  /// Default constructor with empty container. Good for nothing.
1051  GeoContainerData() = default;
1052 
1053  /// Prepares the container with default-constructed data.
1055 
1056  // Prepares the container with copies of the specified default value.
1058  : fData(size, defValue) {}
1059 
1060  // --- END Constructors ------------------------------------------------------
1061 
1062 
1063  // --- BEGIN Container status query ------------------------------------------
1064  /// @name Container status query
1065  /// @{
1066 
1067  /// Returns the number of elements in the container.
1068  size_type size() const { return fData.size(); }
1069 
1070  /// Returns the number of elements the container has memory for.
1071  size_type capacity() const { return fData.capacity(); }
1072 
1073  /// Returns whether the container has no elements (`false` by assumptions).
1074  bool empty() const { return fData.empty(); }
1075 
1076  /// @}
1077  // --- END Container status query --------------------------------------------
1078 
1079 
1080  // --- BEGIN Data modification -----------------------------------------------
1081  /**
1082  * @name Data modification
1083  *
1084  * In general, each single element can be accessed and changed.
1085  * In addition, this section includes methods acting on multiple elements
1086  * at once.
1087  */
1088  /// @{
1089 
1090  /// Sets all elements to the specified `value` (copied).
1092  { std::fill(fData.begin(), fData.end(), value); }
1093 
1094  /// Sets all the elements to a default-constructed `value_type`.
1095  void reset() { fill(value_type{}); }
1096 
1097  /**
1098  * @brief Applies an operation on all elements.
1099  * @tparam Op type of operation
1100  * @param op Operation
1101  * @return the operation object after operations took place
1102  *
1103  * The operation `op` is a unary functor, i.e. an object that supports the
1104  * call to `op(value_type&)`.
1105  *
1106  * The return values of `op` calls are discarded.
1107  */
1108  template <typename Op>
1109  Op apply(Op&& op)
1110  { for (auto& data: fData) op(data); return op; }
1111 
1112  /**
1113  * @brief Applies an operation on all elements.
1114  * @tparam Op type of operation
1115  * @param op Operation
1116  * @return the operation object after operations took place
1117  *
1118  * The operation `op` is a unary functor, i.e. an object that supports the
1119  * call to `op(value_type const&)`.
1120  *
1121  * The return values of `op` calls are discarded.
1122  */
1123  template <typename Op>
1124  Op apply(Op&& op) const
1125  { for (auto const& data: fData) op(data); return op; }
1126 
1127 
1128  /// @}
1129  // --- END Element access ----------------------------------------------------
1130 
1131 
1132  // --- BEGIN Container modification ------------------------------------------
1133  /// @name Container modification
1134  /// @{
1135 
1136  /**
1137  * @brief Prepares the container with default-constructed data.
1138  * @param size number of elements in the container
1139  * @see `clear()`, `fill()`
1140  *
1141  * The container is sized to host data for all the elements.
1142  * Each new element in the container is default-constructed.
1143  * Existing data is not touched.
1144  */
1145  void resize(size_type size) { fData.resize(size); }
1146 
1147  /**
1148  * @brief Prepares the container with copies of the specified default value.
1149  * @param size number of elements in the container
1150  * @param defValue the value copied to fill all entries in the container
1151  * @see `clear()`, `fill()`
1152  *
1153  * The container is sized to host data for all the elements.
1154  * Each new element in the container is constructed as copy of `defValue`.
1155  * Existing data is not touched.
1156  */
1157  void resize(size_type size, value_type const& defValue)
1158  { fData.resize(size, defValue); }
1159 
1160  /**
1161  * @brief Makes the container empty, with no usable storage space.
1162  * @see `resize()`
1163  *
1164  * The container needs to be resized before it is useful again.
1165  */
1166  void clear() { fData.clear(); }
1167 
1168 
1169  /// @}
1170  // --- END Container modification --------------------------------------------
1171 
1172 
1173  // --- BEGIN Element access --------------------------------------------------
1174  /// @name Element access
1175  /// @{
1176 
1177  /// Returns the element for the specified index.
1179 
1180  /// Returns the element for the specified index (read-only).
1182 
1183  /// @}
1184  // --- END Element access ----------------------------------------------------
1185 
1186 
1187  // --- BEGIN Iterators -------------------------------------------------------
1188  /// @name Iterators
1189  /// @{
1190 
1191  iterator begin() { return fData.begin(); }
1192  iterator end() { return fData.end(); }
1193  const_iterator begin() const { return fData.begin(); }
1194  const_iterator end() const { return fData.end(); }
1195  const_iterator cbegin() const { return fData.cbegin(); }
1196  const_iterator cend() const { return fData.cend(); }
1197 
1198  reverse_iterator rbegin() { return fData.rbegin(); }
1199  reverse_iterator rend() { return fData.rend(); }
1200  const_reverse_iterator rbegin() const { return fData.rbegin(); }
1201  const_reverse_iterator rend() const { return fData.rend(); }
1202  const_reverse_iterator crbegin() const { return fData.crbegin(); }
1203  const_reverse_iterator crend() const { return fData.crend(); }
1204 
1205  /// @}
1206  // --- END Iterators ---------------------------------------------------------
1207 
1208 
1209  /// Returns whether the specified value is between `0` and the upper limit.
1210  template <typename Value, typename Upper>
1211  static bool bounded(Value v, Upper upper)
1212  { return (v >= 0) && (static_cast<size_type>(v) < upper); }
1213 
1214  private:
1215 
1216  Container_t fData; ///< Data storage area.
1217 
1218 }; // class geo::details::GeoContainerData
1219 
1220 
1221 //------------------------------------------------------------------------------
1222 //--- geo::GeoIDdataContainer
1223 //------------------------------------------------------------------------------
1224 template <typename T, typename Mapper>
1226  (std::initializer_list<unsigned int> dims)
1227  : fMapper(dims)
1228  , fData(fMapper.size())
1229 {
1230  assert(!fData.empty());
1231 }
1232 
1233 
1234 //------------------------------------------------------------------------------
1235 template <typename T, typename Mapper>
1237  (std::initializer_list<unsigned int> dims, value_type const& defValue)
1238  : fMapper(dims)
1239  , fData(fMapper.computeSize(), defValue)
1240 {
1241  assert(!fData.empty());
1242 }
1243 
1244 
1245 //------------------------------------------------------------------------------
1246 template <typename T, typename Mapper>
1248  { return fData.size(); }
1249 
1250 
1251 //------------------------------------------------------------------------------
1252 template <typename T, typename Mapper>
1254  { return fData.capacity(); }
1255 
1256 
1257 //------------------------------------------------------------------------------
1258 template <typename T, typename Mapper>
1260  { return fData.empty(); }
1261 
1262 
1263 //------------------------------------------------------------------------------
1264 template <typename T, typename Mapper>
1265 template <std::size_t Level>
1267  { return mapper().template dimSize<Level>(); }
1268 
1269 
1270 //------------------------------------------------------------------------------
1271 template <typename T, typename Mapper>
1273  { return Mapper_t::dimensions(); }
1274 
1275 
1276 //------------------------------------------------------------------------------
1277 template <typename T, typename Mapper>
1278 template <typename GeoID>
1280  { return mapper().template hasElement<GeoID>(id); }
1281 
1282 
1283 //------------------------------------------------------------------------------
1284 template <typename T, typename Mapper>
1285 template <typename GeoID /* = ID_t */>
1287  { return mapper().template firstID<GeoID>(); }
1288 
1289 
1290 //------------------------------------------------------------------------------
1291 template <typename T, typename Mapper>
1292 template <typename GeoID /* = ID_t */>
1294  { return mapper().template lastID<GeoID>(); }
1295 
1296 
1297 //------------------------------------------------------------------------------
1298 template <typename T, typename Mapper>
1300  { return fMapper; }
1301 
1302 
1303 //------------------------------------------------------------------------------
1304 template <typename T, typename Mapper>
1306  { return fData[mapper().index(id)]; }
1307 
1308 
1309 //------------------------------------------------------------------------------
1310 template <typename T, typename Mapper>
1312  -> const_reference
1313  { return fData[mapper().index(id)]; }
1314 
1315 
1316 //------------------------------------------------------------------------------
1317 template <typename T, typename Mapper>
1319  if (hasElement(id)) return operator[](id);
1320  throw std::out_of_range("No data for " + std::string(id));
1321 } // geo::GeoIDdataContainer<>::at()
1322 
1323 
1324 //------------------------------------------------------------------------------
1325 template <typename T, typename Mapper>
1327  -> const_reference
1328 {
1329  if (hasElement(id)) return operator[](id);
1330  throw std::out_of_range("No data for " + std::string(id));
1331 } // geo::GeoIDdataContainer<>::at() const
1332 
1333 
1334 //------------------------------------------------------------------------------
1335 template <typename T, typename Mapper>
1337  { return operator[](firstID()); }
1338 
1339 
1340 //------------------------------------------------------------------------------
1341 template <typename T, typename Mapper>
1343  { return operator[](firstID()); }
1344 
1345 
1346 //------------------------------------------------------------------------------
1347 template <typename T, typename Mapper>
1349  { return operator[](lastID()); }
1350 
1351 
1352 //------------------------------------------------------------------------------
1353 template <typename T, typename Mapper>
1355  { return operator[](lastID()); }
1356 
1357 
1358 //------------------------------------------------------------------------------
1359 template <typename T, typename Mapper>
1361  { return { mapper(), fData.begin(), fData.begin() }; }
1362 
1363 
1364 //------------------------------------------------------------------------------
1365 template <typename T, typename Mapper>
1367  { return { mapper(), fData.begin(), fData.end() }; }
1368 
1369 
1370 //------------------------------------------------------------------------------
1371 template <typename T, typename Mapper>
1373  { return { mapper(), fData.begin(), fData.begin() }; }
1374 
1375 
1376 //------------------------------------------------------------------------------
1377 template <typename T, typename Mapper>
1379  { return { mapper(), fData.begin(), fData.end() }; }
1380 
1381 
1382 //------------------------------------------------------------------------------
1383 template <typename T, typename Mapper>
1385  { return begin(); }
1386 
1387 
1388 //------------------------------------------------------------------------------
1389 template <typename T, typename Mapper>
1391  { return end(); }
1392 
1393 
1394 //------------------------------------------------------------------------------
1395 template <typename T, typename Mapper>
1397  { return { begin() }; }
1398 
1399 
1400 //------------------------------------------------------------------------------
1401 template <typename T, typename Mapper>
1403  { return { end() }; }
1404 
1405 
1406 //------------------------------------------------------------------------------
1407 template <typename T, typename Mapper>
1410  { return { begin() }; }
1411 
1412 
1413 //------------------------------------------------------------------------------
1414 template <typename T, typename Mapper>
1417  { return { end() }; }
1418 
1419 
1420 //------------------------------------------------------------------------------
1421 template <typename T, typename Mapper>
1424  { return item_begin(); }
1425 
1426 
1427 //------------------------------------------------------------------------------
1428 template <typename T, typename Mapper>
1431  { return item_end(); }
1432 
1433 
1434 //------------------------------------------------------------------------------
1435 template <typename T, typename Mapper>
1437  { return util::span{ item_begin(), item_end() }; }
1438 
1439 
1440 //------------------------------------------------------------------------------
1441 template <typename T, typename Mapper>
1443  { return util::span{ item_begin(), item_end() }; }
1444 
1445 
1446 //------------------------------------------------------------------------------
1447 template <typename T, typename Mapper>
1449  { fData.fill(value); }
1450 
1451 
1452 //------------------------------------------------------------------------------
1453 template <typename T, typename Mapper>
1455  { fData.reset(); }
1456 
1457 
1458 //------------------------------------------------------------------------------
1459 template <typename T, typename Mapper>
1460 template <typename Op>
1462  { return fData.apply(std::forward<Op>(op)); }
1463 
1464 
1465 //------------------------------------------------------------------------------
1466 template <typename T, typename Mapper>
1468  (std::initializer_list<unsigned int> dims)
1469 {
1470  fMapper.resize(dims);
1471  fData.resize(mapper().size());
1472 } // geo::GeoIDdataContainer<T, Mapper>::resize()
1473 
1474 
1475 //------------------------------------------------------------------------------
1476 template <typename T, typename Mapper>
1478  (std::initializer_list<unsigned int> dims, value_type const& defValue)
1479 {
1480  fMapper.resize(dims);
1481  fData.resize(mapper().size(), defValue);
1482 } // geo::GeoIDdataContainer<T, Mapper>::resize(value_type)
1483 
1484 
1485 //------------------------------------------------------------------------------
1486 template <typename T, typename Mapper>
1487 template <typename OT>
1490 {
1491  fMapper.resizeAs(other.mapper());
1492  fData.resize(mapper().size());
1493 } // geo::GeoIDdataContainer<T, Mapper>::resizeAs()
1494 
1495 
1496 //------------------------------------------------------------------------------
1497 template <typename T, typename Mapper>
1498 template <typename OT>
1500  (geo::GeoIDdataContainer<OT, Mapper_t> const& other, value_type const& defValue)
1501 {
1502  fMapper.resizeAs(other.mapper());
1503  fData.resize(mapper().size(), defValue);
1504 } // geo::GeoIDdataContainer<T, Mapper>::resizeAs(value_type)
1505 
1506 
1507 //------------------------------------------------------------------------------
1508 template <typename T, typename Mapper>
1510  fMapper.clear();
1511  fData.clear();
1512 } // geo::GeoIDdataContainer<>::clear()
1513 
1514 
1515 //------------------------------------------------------------------------------
1516 template <typename T, typename Mapper>
1517 template <typename Op>
1518 decltype(auto) geo::GeoIDdataContainer<T, Mapper>::apply(Op&& op) const
1519  { return fData.apply(std::forward<Op>(op)); }
1520 
1521 
1522 //------------------------------------------------------------------------------
1523 template <typename T, typename Mapper>
1525  -> size_type
1526  { return mapper().index(id); }
1527 
1528 
1529 //------------------------------------------------------------------------------
1530 template <typename T, typename Mapper>
1532  { return mapper().ID(index); }
1533 
1534 
1535 //------------------------------------------------------------------------------
1536 
1537 
1538 #endif // LARCOREALG_GEOMETRY_GEOMETRYDATACONTAINERS_H
void reset()
Sets all the elements to a default-constructed value_type.
typename Container_t::iterator iterator
Functor to extract an ID data member.
static bool bounded(Value v, Upper upper)
Returns whether the specified value is between 0 and the upper limit.
auto items()
Returns an object suitable for a range-for loop with item_iterator.
double std(const std::vector< short > &wf, const double ped_mean, size_t start, size_t nsample)
Definition: UtilFunc.cxx:42
Mapper_t const & mapper() const
Returns the mapper object used to convert ID&#39;s and container positions.
BaseIterator_t const & start() const
Returns the iterator to the begin element.
Item iterator for geo::GeoIDdataContainer class.
GeoID firstID() const
Returns the ID of the first element with GeoID type.
reference at(ID_t const &id)
An object with a begin and end iterator.
const_reverse_iterator crend() const
const_reverse_iterator crbegin() const
GeoID lastID() const
Returns the ID of the last covered element with GeoID type.
typename Container_t::const_pointer const_pointer
iterator end()
Returns an iterator to past the end of the data.
index_type size() const
Returns the number of elements in the mapping.
Iterator for geo::GeoIDdataContainer class.
void resizeAs(geo::GeoIDmapper< OIDType, OIndex > const &other)
Resizes the mapping to reflect the one from another mapping.
iterator_adaptor_::reference dereference() const
size_type capacity() const
Returns the number of elements the container has memory for.
GeoIDdataContainerItemIterator(GeoIDiterator_t const &iter)
Constructor: points to data pointed by current.
GeoIDmapperClass Mapper_t
&lt; Type of mapping of the container this class iterates.
size_type capacity() const
Returns the number of elements the container has memory for.
The data type to uniquely identify a Plane.
Definition: geo_types.h:472
Mapping between geometry/readout ID and flat index.
void resize(unsigned int nCryo, unsigned int nTPCs, unsigned int nPlanes)
Prepares the mapping for the specified sizes.
const_iterator cbegin() const
Returns a constant iterator to the beginning of the data.
TPCDataContainer(unsigned int nCryo, unsigned int nTPCs)
Prepares the container with default-constructed data.
reference last()
Returns the element for the last ID (unchecked).
Mapper_t const & mapper() const
Returns the mapping of the container being iterated.
Index_t index() const
Returns the index of the current element.
Container with one element per geometry wire plane.
bool empty() const
Returns whether the container has no elements (false by assumptions).
void resize(size_type size, value_type const &defValue)
Prepares the container with copies of the specified default value.
typename Mapper_t::ID_t ID_t
Type of the ID in this iterator.
Simple class with a begin and an end.
Definition: span.h:125
GeoIDdataContainerItemIterator(GeoIDdataContainerItemIterator< OGeoIDIteratorClass > const &other, std::enable_if_t< std::is_convertible_v< OGeoIDIteratorClass, GeoIDiterator_t >>=nullptr)
Generalized copy constructor, only if argument iterator can be converted.
Op apply(Op &&op) const
Applies an operation on all elements.
Container with one element per geometry TPC.
item_const_iterator item_cbegin() const
Returns a item constant iterator to the beginning of the data.
void reset()
Sets all the elements to a default-constructed value_type.
GeoContainerData(size_type size)
Prepares the container with default-constructed data.
ID_t ID(size_type const index) const
Returns the ID corresponding to a internal index in the storage area.
Container with one element per geometry TPC.
size_type size() const
Returns the number of elements in the container.
typename Container_t::difference_type difference_type
GeoIDdataContainerIterator(Mapper_t const &mapper, BaseIterator_t const &start, BaseIterator_t const &current)
Constructor: points to data pointed by current.
reference operator[](index_type index)
Returns the element for the specified index.
typename Container_t::size_type size_type
typename std::enable_if< B, T >::type enable_if_t
Definition: json.hpp:2191
typename Container_t::const_reference const_reference
item_iterator item_begin()
Returns an item iterator to the beginning of the data.
void fill(const art::PtrVector< recob::Hit > &hits, int only_plane)
typename Container_t::reference reference
The data type to uniquely identify a TPC.
Definition: geo_types.h:386
Definition of data types for geometry description.
const_reference operator[](index_type index) const
Returns the element for the specified index (read-only).
Mapping for TPC identifiers.
reference first()
Returns the element for the first ID (unchecked).
typename GeoIDiterator_t::ID_t ID_t
Type of the ID in this iterator.
const_reverse_iterator rend() const
reference operator[](ID_t const &id)
Returns the element for the specified geometry element.
Mapper Mapper_t
Type of mapper between IDs and index.
GeoIDIteratorClass GeoIDiterator_t
Type of wrapped iterator.
item_iterator item_end()
Returns an item iterator to past the end of the data.
typename Mapper_t::index_type Index_t
Type of index in the container mapping.
void clear()
Makes the container empty, with no usable storage space.
Op apply(Op &&op)
Applies an operation on all elements.
static constexpr unsigned int dimensions()
Dimensions of the ID of this container.
void fill(value_type value)
Sets all elements to the specified value (copied).
BaseIterator_t const & current() const
Returns the iterator to the current element.
GeoContainerData(size_type size, value_type const &defValue)
typename Container_t::value_type value_type
BaseIterator_t start
Iterator to the first element.
typename Container_t::const_iterator BaseConstIter_t
Type of constant iterator to the data.
typename Container_t::const_iterator const_iterator
BaseIterator BaseIterator_t
Type of iterator to the actual data.
size_t ID_t
Index used to identify Flash_t/QPointCollection_t uniquely in an event.
size_type index(ID_t const &id) const
Returns the internal index of the specified ID in the storage area.
temporary value
void resize(size_type size)
Prepares the container with default-constructed data.
size_type size() const
Returns the number of elements in the container.
ExtraData_t fData
Data for extended features of this iterator.
typename Container_t::pointer pointer
bool empty() const
Returns whether the container has no elements (false by assumptions).
void resizeAs(geo::GeoIDdataContainer< OT, Mapper_t > const &other)
Prepares the container with default-constructed data.
unsigned int dimSize() const
Dimensions of the Level dimension of this container.
typename GeoIDdataContainerItemIterator::iterator_adaptor_ iterator_adaptor_
void clear()
Makes the container empty, with no usable storage space.
ID_t ID() const
Returns the ID corresponding to the current element.
GeoIDdataContainer()=default
Default constructor: container has no room at all.
Mapper_t fMapper
Mapping of IDs to indices.
Container_t fData
Data storage area.
Container_t fData
Data storage.
const_iterator cend() const
Returns a constant iterator to past the end of the data.
Op apply(Op &&op)
Applies an operation on all elements.
GeoIDdataContainerIterator(GeoIDdataContainerIterator< Mapper_t, OBaseIterator > const &other, std::enable_if_t< std::is_convertible_v< OBaseIterator, BaseIterator_t >>=nullptr)
Generalized copy constructor, only if argument iterator can be converted.
item_const_iterator item_cend() const
Returns a item constant iterator to past the end of the data.
iterator begin()
Returns an iterator to the beginning of the data.
void resize(std::initializer_list< unsigned int > dims)
Prepares the container with default-constructed data.
void fill(value_type value)
Sets all elements to the specified value (copied).
bool hasElement(GeoID const &id) const
Returns whether this container hosts data for the specified ID.
The data type to uniquely identify a cryostat.
Definition: geo_types.h:190
const_reverse_iterator rbegin() const
std::vector< icarus::ICARUSChannelMapAlg::PlaneInfo_t > Container_t
void clear()
Sets all dimension sizes to 0.