LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
GeometryIDmapper.h
Go to the documentation of this file.
1 
11 #ifndef LARCOREALG_GEOMETRY_GEOMETRYIDMAPPER_H
12 #define LARCOREALG_GEOMETRY_GEOMETRYIDMAPPER_H
13 
14 // LArSoft libraries
16 
17 // C/C++ standard libraries
18 #include <algorithm> // std::copy()
19 #include <array>
20 #include <cassert>
21 #include <cstdlib> // std::size_t
22 #include <initializer_list>
23 #include <type_traits> // std::index_sequence
24 
25 namespace geo {
26 
27  template <typename IDType, typename Index = std::size_t>
28  class GeoIDmapper;
29 
30  template <typename Index = std::size_t>
31  class TPCIDmapper;
32 
33  template <typename Index = std::size_t>
35 
36  // ---------------------------------------------------------------------------
37  namespace details {
38 
40  template <std::size_t N, typename T>
41  auto initializerListToArray(std::initializer_list<T> values);
42 
43  } // namespace details
44  // ---------------------------------------------------------------------------
45 
46 } // namespace geo
47 
48 // --- BEGIN Geometry ID mappers -----------------------------------------------
52 
74 template <typename IDType, typename Index /* = std::size_t */>
75 class geo::GeoIDmapper {
76 
77 public:
78  using ID_t = IDType;
79  using index_type = Index;
80 
87  GeoIDmapper();
88 
97  GeoIDmapper(std::initializer_list<unsigned int> dims);
98 
99  // --- BEGIN Indexer status query --------------------------------------------
102 
104  index_type size() const;
105 
107  bool empty() const;
108 
110  template <std::size_t Level>
111  unsigned int dimSize() const;
112 
114  static constexpr unsigned int dimensions();
115 
117  template <typename GeoID = ID_t>
118  bool hasElement(GeoID const& id) const;
119 
121  template <typename GeoID = ID_t>
122  GeoID firstID() const;
123 
125  template <typename GeoID = ID_t>
126  GeoID lastID() const;
127 
129  // --- END Indexer status query ----------------------------------------------
130 
131  // --- BEGIN Mapping transformations -----------------------------------------
134 
136  index_type index(ID_t const& id) const;
137 
139  ID_t ID(index_type const index) const;
140 
142  index_type operator()(ID_t const& id) const;
143 
145  ID_t operator()(index_type const index) const;
146 
148  // --- END Mapping transformations -------------------------------------------
149 
150  // --- BEGIN Mapping modification --------------------------------------------
153 
162  void resize(std::initializer_list<unsigned int> dims);
163 
170  template <typename OIDType, typename OIndex>
171  void resizeAs(geo::GeoIDmapper<OIDType, OIndex> const& other);
172 
179  void clear();
180 
182  // --- END Mapping modification ----------------------------------------------
183 
184 private:
186  using Dimensions_t = std::array<unsigned int, dimensions()>;
187 
189  Dimensions_t fN = zeroDimensions();
190 
191  template <std::size_t Level, typename GeoID>
192  index_type indexLevel(GeoID const& id) const;
193 
207  template <std::size_t Level, typename GeoID>
208  void fillID(GeoID& id, index_type index) const;
209 
211  template <std::size_t Level, typename GeoID>
212  bool hasElementLevel(GeoID const& id) const;
213 
215  index_type computeSize() const;
216 
218  template <typename OIDType, typename OIndex, std::size_t... Indices>
219  void resizeAsImpl(geo::GeoIDmapper<OIDType, OIndex> const& other,
220  std::index_sequence<Indices...>);
221 
224  template <std::size_t Level, typename Dims>
225  static index_type sizeLevel(Dims const& dimSizes);
226 
229  {
230  Dimensions_t dims;
231  dims.fill(0);
232  return dims;
233  }
234 
236  template <typename Value, typename Upper>
237  static bool bounded(Value v, Upper upper)
238  {
239  return (v >= 0) && (static_cast<index_type>(v) < upper);
240  }
241 
242 }; // class geo::GeoIDmapper<>
243 
252 template <typename Index /* = std::size_t */>
253 class geo::TPCIDmapper : public geo::GeoIDmapper<geo::TPCID, Index> {
254 
257 
258 public:
259  // import types
260  using ID_t = typename BaseMapper_t::ID_t;
262 
263  // import all constructors from `geo::GeoIDmapper`
264  using BaseMapper_t::BaseMapper_t;
265 
273  TPCIDmapper(unsigned int nCryo, unsigned int nTPCs) : BaseMapper_t({nCryo, nTPCs}) {}
274 
275  // --- BEGIN Mapping modification --------------------------------------------
278 
279  using BaseMapper_t::resize;
280 
289  void resize(unsigned int nCryo, unsigned int nTPCs) { BaseMapper_t::resize({nCryo, nTPCs}); }
290 
292  // --- END Mapping modification ----------------------------------------------
293 
294  // --- BEGIN Mapping status query --------------------------------------------
297 
299  bool hasCryostat(geo::CryostatID const& cryoid) const { return BaseMapper_t::hasElement(cryoid); }
300 
302  bool hasTPC(geo::TPCID const& tpcid) const { return BaseMapper_t::hasElement(tpcid); }
303 
305  // --- END Mapping status query ----------------------------------------------
306 
307 }; // geo::TPCIDmapper<>
308 
317 template <typename Index /* = std::size_t */>
318 class geo::PlaneIDmapper : public geo::GeoIDmapper<geo::PlaneID, Index> {
319 
322 
323 public:
324  // import types
325  using ID_t = typename BaseMapper_t::ID_t;
327 
328  // import all constructors from `geo::GeoIDmapper`
329  using BaseMapper_t::BaseMapper_t;
330 
340  PlaneIDmapper(unsigned int nCryo, unsigned int nTPCs, unsigned int nPlanes)
341  : BaseMapper_t({nCryo, nTPCs, nPlanes})
342  {}
343 
344  // --- BEGIN Mapping modification --------------------------------------------
347 
348  using BaseMapper_t::resize;
349 
360  void resize(unsigned int nCryo, unsigned int nTPCs, unsigned int nPlanes)
361  {
362  BaseMapper_t::resize({nCryo, nTPCs, nPlanes});
363  }
364 
366  // --- END Mapping modification ----------------------------------------------
367 
368  // --- BEGIN Mapping status query --------------------------------------------
371 
373  bool hasCryostat(geo::CryostatID const& cryoid) const { return BaseMapper_t::hasElement(cryoid); }
374 
376  bool hasTPC(geo::TPCID const& tpcid) const { return BaseMapper_t::hasElement(tpcid); }
377 
379  bool hasPlane(geo::PlaneID const& planeid) const { return BaseMapper_t::hasElement(planeid); }
380 
382  // --- END Mapping status query ----------------------------------------------
383 
384 }; // geo::PlaneIDmapper<>
385 
387 // --- END Geometry ID mappers -------------------------------------------------
388 //------------------------------------------------------------------------------
389 
390 //------------------------------------------------------------------------------
391 //--- Template implementation
392 //------------------------------------------------------------------------------
393 template <std::size_t N, typename T>
394 auto geo::details::initializerListToArray(std::initializer_list<T> values)
395 {
396  std::array<T, N> data;
397  std::copy(values.begin(), values.end(), data.begin());
398  return data;
399 } // geo::details::initializerListToArray()
400 
401 //------------------------------------------------------------------------------
402 //--- geo::GeoIDmapper
403 //------------------------------------------------------------------------------
404 template <typename IDType, typename Index>
406 {
407  fN.fill(0U);
408 }
409 
410 //------------------------------------------------------------------------------
411 template <typename IDType, typename Index>
412 geo::GeoIDmapper<IDType, Index>::GeoIDmapper(std::initializer_list<unsigned int> dims)
413  : fN(details::initializerListToArray<dimensions()>(dims))
414 {
415  assert(dims.size() == dimensions()); // can't be static
416 }
417 
418 //------------------------------------------------------------------------------
419 template <typename IDType, typename Index>
421 {
422  return computeSize();
423 }
424 
425 //------------------------------------------------------------------------------
426 template <typename IDType, typename Index>
428 {
429  return size() == index_type{0};
430 }
431 
432 //------------------------------------------------------------------------------
433 template <typename IDType, typename Index>
434 template <std::size_t Level>
436 {
437  if constexpr (Level >= dimensions())
438  return 0U; // technically it would be 1...
439  else
440  return fN[Level];
441 } // geo::GeoIDmapper<>::dimSize()
442 
443 //------------------------------------------------------------------------------
444 template <typename IDType, typename Index>
446 {
447  return IDType::Level + 1;
448 }
449 
450 //------------------------------------------------------------------------------
451 template <typename IDType, typename Index>
452 template <typename GeoID>
454 {
455  return hasElementLevel<GeoID::Level>(id);
456 }
457 
458 //------------------------------------------------------------------------------
459 template <typename IDType, typename Index>
460 template <typename GeoID /* = ID_t */>
462 {
463  if constexpr (GeoID::Level == 0)
464  return GeoID(0U);
465  else
466  return GeoID(firstID<typename GeoID::ParentID_t>(), 0U);
467 } // geo::GeoIDmapper<>::firstID()
468 
469 //------------------------------------------------------------------------------
470 template <typename IDType, typename Index>
471 template <typename GeoID /* = ID_t */>
473 {
474  if constexpr (GeoID::Level == 0)
475  return GeoID(fN[GeoID::Level] - 1U);
476  else
477  return GeoID(lastID<typename GeoID::ParentID_t>(), fN[GeoID::Level] - 1U);
478 } // geo::GeoIDmapper<>::lastID()
479 
480 //------------------------------------------------------------------------------
481 template <typename IDType, typename Index>
483 {
484  return indexLevel<ID_t::Level>(id);
485 }
486 
487 //------------------------------------------------------------------------------
488 template <typename IDType, typename Index>
490 {
491  ID_t ID;
492  fillID<ID_t::Level>(ID, index);
493  return ID;
494 } // geo::GeoIDmapper<>::ID()
495 
496 //------------------------------------------------------------------------------
497 template <typename IDType, typename Index>
499 {
500  return index(id);
501 }
502 
503 //------------------------------------------------------------------------------
504 template <typename IDType, typename Index>
506 {
507  return ID(index);
508 }
509 
510 //------------------------------------------------------------------------------
511 template <typename IDType, typename Index>
512 void geo::GeoIDmapper<IDType, Index>::resize(std::initializer_list<unsigned int> dims)
513 {
514  fN = details::initializerListToArray<dimensions()>(dims);
515 } // geo::GeoIDmapper<>::resize()
516 
517 //------------------------------------------------------------------------------
518 template <typename IDType, typename Index>
519 template <typename OIDType, typename OIndex>
521 {
522  resizeAsImpl(other, std::make_index_sequence<dimensions()>{});
523 } // geo::GeoIDmapper<>::resizeAs()
524 
525 //------------------------------------------------------------------------------
526 template <typename IDType, typename Index>
528 {
529  fN.fill(0U);
530 } // geo::GeoIDmapper<>::clear()
531 
532 //------------------------------------------------------------------------------
533 template <typename IDType, typename Index>
534 template <std::size_t Level, typename GeoID>
536 {
537  if constexpr (Level == 0)
538  return id.template getIndex<0U>();
539  else {
540  return indexLevel<(Level - 1U)>(id) * fN[Level] + id.template getIndex<Level>();
541  }
542 } // geo::GeoIDmapper<>::indexLevel()
543 
544 //------------------------------------------------------------------------------
545 template <typename IDType, typename Index>
546 template <std::size_t Level, typename GeoID>
548 {
549  if constexpr (Level == 0) {
550  id.template writeIndex<0U>() = index;
551  id.setValidity(index < fN[0U]);
552  }
553  else {
554  id.template writeIndex<Level>() = index % fN[Level];
555  fillID<(Level - 1U)>(id, index / fN[Level]);
556  }
557 } // geo::GeoIDmapper<>::fillID()
558 
559 //------------------------------------------------------------------------------
560 template <typename IDType, typename Index>
561 template <std::size_t Level, typename GeoID>
563 {
564  if (!bounded(id.template getIndex<Level>(), fN[Level])) return false;
565  if constexpr (Level == 0U)
566  return true;
567  else
568  return hasElementLevel<(Level - 1U)>(id);
569 } // geo::GeoIDmapper<>::hasElementLevel()
570 
571 //------------------------------------------------------------------------------
572 template <typename IDType, typename Index>
574 {
575  return sizeLevel<0U>(fN);
576 }
577 
578 //------------------------------------------------------------------------------
579 template <typename IDType, typename Index>
580 template <typename OIDType, typename OIndex, std::size_t... Indices>
582  std::index_sequence<Indices...>)
583 {
584  // Clang 5.0.1 does not understand `other.dimensions()` is constexpr
586  "Can't resize a deeper mapping to a shallower one.");
587  resize({other.template dimSize<Indices>()...});
588 } // geo::GeoIDmapper<>::resizeAsImpl()
589 
590 //------------------------------------------------------------------------------
591 template <typename IDType, typename Index>
592 template <std::size_t Level, typename Dims>
594 {
595  if constexpr (Level >= dimensions())
596  return 1U;
597  else
598  return sizeLevel<(Level + 1U)>(dimSizes) * dimSizes[Level];
599 } // geo::GeoIDmapper<>::sizeLevel()
600 
601 //------------------------------------------------------------------------------
602 
603 #endif // LARCOREALG_GEOMETRY_GEOMETRYIDMAPPER_H
bool hasTPC(geo::TPCID const &tpcid) const
Returns whether this mapping covers the specified TPC.
void fillID(GeoID &id, index_type index) const
Fills the specified ID with its index.
void resize(unsigned int nCryo, unsigned int nTPCs)
Prepares the mapping for the specified sizes.
ID_t ID(index_type const index) const
Returns the ID corresponding to the specified linear index.
bool hasElementLevel(GeoID const &id) const
Returns whether all levels of id up to Level are within range.
bool hasCryostat(geo::CryostatID const &cryoid) const
Returns whether this mapping covers the specified cryostat.
index_type size() const
Returns the number of elements in the mapping.
index_type operator()(ID_t const &id) const
Returns the linear index corresponding to the specified ID.
void resizeAs(geo::GeoIDmapper< OIDType, OIndex > const &other)
Resizes the mapping to reflect the one from another mapping.
void resizeAsImpl(geo::GeoIDmapper< OIDType, OIndex > const &other, std::index_sequence< Indices... >)
Implementation for resizeAs().
GeoID firstID() const
Returns the ID of the first element with GeoID type.
The data type to uniquely identify a Plane.
Definition: geo_types.h:463
void resize(unsigned int nCryo, unsigned int nTPCs, unsigned int nPlanes)
Prepares the mapping for the specified sizes.
Level
Definition: Level.h:13
static bool bounded(Value v, Upper upper)
Returns whether the specified value is between 0 and the upper limit.
index_type computeSize() const
Computes the expected size of this mapping.
PlaneIDmapper(unsigned int nCryo, unsigned int nTPCs, unsigned int nPlanes)
Prepares the mapping with the specified sizes.
index_type indexLevel(GeoID const &id) const
bool hasCryostat(geo::CryostatID const &cryoid) const
Returns whether this mapping covers the specified cryostat.
Dimensions_t fN
Number of maximum entries per ID level.
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
Definition: StdUtils.h:101
static index_type sizeLevel(Dims const &dimSizes)
decltype(auto) values(Coll &&coll)
Range-for loop helper iterating across the values of the specified collection.
static constexpr unsigned int dimensions()
Dimensions of the ID of this mapping.
TPCIDmapper(unsigned int nCryo, unsigned int nTPCs)
Prepares the mapping with the specified sizes.
unsigned int dimSize() const
Dimensions of the Level dimension of this mapping.
auto initializerListToArray(std::initializer_list< T > values)
Returns a STL array of size N filled with values from the argument.
The data type to uniquely identify a TPC.
Definition: geo_types.h:381
GeoIDmapper()
Default constructor: all dimensions empty.
Definition of data types for geometry description.
Mapping for TPC identifiers.
GeoID lastID() const
Returns the ID of the last covered element with GeoID type.
bool hasElement(GeoID const &id) const
Returns whether this mapping hosts data for the specified ID.
bool empty() const
Returns whether the mapping has no elements (false by assumptions).
std::array< unsigned int, dimensions()> Dimensions_t
< Type of dimension sizes.
IDType ID_t
Type used as ID for this mapping.
static Dimensions_t zeroDimensions()
Initializer with zero size for each of the dimensions.
Index index_type
Type of flat index.
void resize(std::initializer_list< unsigned int > dims)
Resizes the mapping to accommodate the specified dimension sizes.
Mapping for sensitive plane identifiers.
index_type index(ID_t const &id) const
Returns the linear index corresponding to the specified ID.
bool hasPlane(geo::PlaneID const &planeid) const
Returns whether this mapping covers the specified plane.
Namespace collecting geometry-related classes utilities.
bool hasTPC(geo::TPCID const &tpcid) const
Returns whether this mapping covers the specified TPC.
vec_iX clear()
decltype(auto) constexpr empty(T &&obj)
ADL-aware version of std::empty.
Definition: StdUtils.h:109
The data type to uniquely identify a cryostat.
Definition: geo_types.h:192
void clear()
Sets all dimension sizes to 0.
Class managing the mapping between geometry/readout ID and flat index.