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.
336  item_iterator item_begin();
337 
338  /// Returns an item iterator to past the end of the data.
339  item_iterator item_end();
340 
341  /// Returns a item constant iterator to the beginning of the data.
342  item_const_iterator item_begin() const;
343 
344  /// Returns a item constant iterator to past the end of the data.
345  item_const_iterator item_end() const;
346 
347  /// Returns a item constant iterator to the beginning of the data.
348  item_const_iterator item_cbegin() const;
349 
350  /// Returns a item constant iterator to past the end of the data.
351  item_const_iterator item_cend() const;
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  */
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  */
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 
1030  using value_type = typename Container_t::value_type ;
1031  using reference = typename Container_t::reference ;
1032  using const_reference = typename Container_t::const_reference ;
1033  using pointer = typename Container_t::pointer ;
1034  using const_pointer = typename Container_t::const_pointer ;
1035  using iterator = typename Container_t::iterator ;
1037  using reverse_iterator = typename Container_t::reverse_iterator ;
1038  using const_reverse_iterator = typename Container_t::const_reverse_iterator;
1039  using difference_type = typename Container_t::difference_type ;
1040  using size_type = typename Container_t::size_type ;
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.
end
while True: pbar.update(maxval-len(onlies[E][S])) #print iS, "/", len(onlies[E][S]) found = False for...
intermediate_table::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.
void resize(unsigned int nCryo, unsigned int nTPCs, T const &defValue)
Prepares the container initializing all its data.
Mapper_t const & mapper() const
Returns the mapper object used to convert ID&#39;s and container positions.
Item iterator for geo::GeoIDdataContainer class.
BaseIterator_t const & start() const
Returns the iterator to the begin element.
GeoID firstID() const
Returns the ID of the first element with GeoID type.
decltype(auto) constexpr cend(T &&obj)
ADL-aware version of std::cend.
Definition: StdUtils.h:87
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.
std::string string
Definition: nybbler.cc:12
unsigned int ID
void resizeAs(geo::GeoIDmapper< OIDType, OIndex > const &other)
Resizes the mapping to reflect the one from another mapping.
iterator_adaptor_::reference dereference() const
bool hasCryostat(geo::CryostatID const &cryoid) const
Returns whether this container hosts data for the specified cryostat.
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.
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.
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).
typename Container_t::reverse_iterator reverse_iterator
STL namespace.
ExtraData_t fData
Data for extended features of this iterator.
intermediate_table::const_iterator const_iterator
ID_t ID() const
Returns the ID corresponding to the current element.
size_type index_type
Type used internally (so far) for indexing.
bool hasPlane(geo::PlaneID const &planeid) const
Returns whether this container hosts data for the specified plane.
Container with one element per geometry wire plane.
typename Container_t::const_reverse_iterator const_reverse_iterator
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.
Simple class with a begin and an end.
Definition: span.h:125
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.
void resize(Vector< T > &vec1, Index n1, const V &val)
void resize(unsigned int nCryo, unsigned int nTPCs)
Prepares the container with default-constructed data.
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 resize(unsigned int nCryo, unsigned int nTPCs, unsigned int nPlanes, T const &defValue)
Prepares the container initializing all its data.
void reset()
Sets all the elements to a default-constructed value_type.
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
Definition: StdUtils.h:92
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.
QTextStream & reset(QTextStream &s)
typename Mapper_t::ID_t ID_t
Type used as ID for this container.
size_type size() const
Returns the number of elements in the container.
bool hasCryostat(geo::CryostatID const &cryoid) const
Returns whether this container hosts data for the specified cryostat.
typename Container_t::difference_type difference_type
reference operator[](index_type index)
Returns the element for the specified index.
typename Container_t::size_type size_type
typename Mapper_t::index_type Index_t
Type of index in the container mapping.
typename Container_t::const_reference const_reference
GeoIDdataContainerIterator(Mapper_t const &mapper, BaseIterator_t const &start, BaseIterator_t const &current)
Constructor: points to data pointed by current.
item_iterator item_begin()
Returns an item iterator to the beginning of the data.
static Entry * current
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.
GeoIDIteratorClass GeoIDiterator_t
Type of wrapped iterator.
bool hasTPC(geo::TPCID const &tpcid) const
Returns whether this container hosts data for the specified TPC.
item_iterator item_end()
Returns an item iterator to past the end of the data.
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).
void resize(unsigned int nCryo, unsigned int nTPCs, unsigned int nPlanes)
Prepares the container with default-constructed data.
def fill(s)
Definition: translator.py:93
GeoContainerData(size_type size, value_type const &defValue)
typename Container_t::value_type value_type
typename Container_t::iterator BaseIter_t
Type of iterator to the data.
BaseIterator_t const & current() const
Returns the iterator to the current element.
typename Container_t::const_iterator BaseConstIter_t
Type of constant iterator to the data.
void resize(unsigned int nCryo, unsigned int nTPCsets)
Prepares the mapping for the specified sizes.
typename Container_t::const_iterator const_iterator
decltype(auto) constexpr cbegin(T &&obj)
ADL-aware version of std::cbegin.
Definition: StdUtils.h:82
bool hasTPC(geo::TPCID const &tpcid) const
Returns whether this container hosts data for the specified TPC.
typename BaseMapper_t::ID_t ID_t
PlaneDataContainer(unsigned int nCryo, unsigned int nTPCs, unsigned int nPlanes, T const &defValue)
Prepares the container with copies of the specified default value.
Mapper_t const & mapper() const
Returns the mapping of the container being iterated.
size_type index(ID_t const &id) const
Returns the internal index of the specified ID in the storage area.
vector< vector< double > > clear
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
Definition: StdUtils.h:72
Index_t index() const
Returns the index of the current element.
void resize(size_type size)
Prepares the container with default-constructed data.
size_type size() const
Returns the number of elements in the container.
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.
BaseIterator_t start
Iterator to the first element.
LArSoft geometry interface.
Definition: ChannelGeo.h:16
unsigned int dimSize() const
Dimensions of the Level dimension of this container.
typename Mapper_t::ID_t ID_t
Type of the ID in this iterator.
typename GeoIDdataContainerItemIterator::iterator_adaptor_ iterator_adaptor_
void clear()
Makes the container empty, with no usable storage space.
GeoIDdataContainer()=default
Default constructor: container has no room at all.
Container_t fData
Data storage area.
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.
GeoIDmapperClass Mapper_t
< Type of mapping of the container this class iterates.
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.
decltype(auto) constexpr empty(T &&obj)
ADL-aware version of std::empty.
Definition: StdUtils.h:97
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
Mapper_t const * mapper
Mapping of the container being iterated.
void clear()
Sets all dimension sizes to 0.