LArSoft  v10_04_05
Liquid Argon Software toolkit - https://larsoft.org/
GeometryIDmapper.h
Go to the documentation of this file.
1 
9 #ifndef LARCOREALG_GEOMETRY_GEOMETRYIDMAPPER_H
10 #define LARCOREALG_GEOMETRY_GEOMETRYIDMAPPER_H
11 
12 // LArSoft libraries
14 
15 // C/C++ standard libraries
16 #include <algorithm> // std::copy()
17 #include <array>
18 #include <cassert>
19 #include <cstdlib> // std::size_t
20 #include <initializer_list>
21 #include <type_traits> // std::index_sequence
22 
23 namespace geo {
24 
25  template <typename IDType, typename Index = std::size_t>
26  class GeoIDmapper;
27 
28  template <typename Index = std::size_t>
29  class TPCIDmapper;
30 
31  template <typename Index = std::size_t>
33 
34  // ---------------------------------------------------------------------------
35  namespace details {
36 
38  template <std::size_t N, typename T>
39  auto initializerListToArray(std::initializer_list<T> values);
40 
41  } // namespace details
42  // ---------------------------------------------------------------------------
43 
44 } // namespace geo
45 
46 // --- BEGIN Geometry ID mappers -----------------------------------------------
50 
72 template <typename IDType, typename Index /* = std::size_t */>
73 class geo::GeoIDmapper {
74 
75 public:
76  using ID_t = IDType;
77  using index_type = Index;
78 
85  GeoIDmapper();
86 
95  GeoIDmapper(std::initializer_list<unsigned int> dims);
96 
97  // --- BEGIN Indexer status query --------------------------------------------
100 
102  index_type size() const;
103 
105  bool empty() const;
106 
108  template <std::size_t Level>
109  unsigned int dimSize() const;
110 
112  static constexpr unsigned int dimensions();
113 
115  template <typename GeoID = ID_t>
116  bool hasElement(GeoID const& id) const;
117 
119  template <typename GeoID = ID_t>
120  GeoID firstID() const;
121 
123  template <typename GeoID = ID_t>
124  GeoID lastID() const;
125 
127  // --- END Indexer status query ----------------------------------------------
128 
129  // --- BEGIN Mapping transformations -----------------------------------------
132 
134  index_type index(ID_t const& id) const;
135 
137  ID_t ID(index_type const index) const;
138 
140  index_type operator()(ID_t const& id) const;
141 
143  ID_t operator()(index_type const index) const;
144 
146  // --- END Mapping transformations -------------------------------------------
147 
148  // --- BEGIN Mapping modification --------------------------------------------
151 
160  void resize(std::initializer_list<unsigned int> dims);
161 
168  template <typename OIDType, typename OIndex>
169  void resizeAs(GeoIDmapper<OIDType, OIndex> const& other);
170 
177  void clear();
178 
180  // --- END Mapping modification ----------------------------------------------
181 
182 private:
184  using Dimensions_t = std::array<unsigned int, dimensions()>;
185 
187  Dimensions_t fN = zeroDimensions();
188 
189  template <std::size_t Level, typename GeoID>
190  index_type indexLevel(GeoID const& id) const;
191 
205  template <std::size_t Level, std::size_t N>
206  void fillID(std::array<unsigned int, N>& id, index_type index) const;
207 
209  template <std::size_t Level, typename GeoID>
210  bool hasElementLevel(GeoID const& id) const;
211 
213  index_type computeSize() const;
214 
216  template <typename OIDType, typename OIndex, std::size_t... Indices>
217  void resizeAsImpl(GeoIDmapper<OIDType, OIndex> const& other, std::index_sequence<Indices...>);
218 
221  template <std::size_t Level, typename Dims>
222  static index_type sizeLevel(Dims const& dimSizes);
223 
226  {
227  Dimensions_t dims;
228  dims.fill(0);
229  return dims;
230  }
231 
233  template <typename Value, typename Upper>
234  static bool bounded(Value v, Upper upper)
235  {
236  return (v >= 0) && (static_cast<index_type>(v) < upper);
237  }
238 
239 }; // class geo::GeoIDmapper<>
240 
249 template <typename Index /* = std::size_t */>
250 class geo::TPCIDmapper : public geo::GeoIDmapper<geo::TPCID, Index> {
251 
254 
255 public:
256  // import types
257  using ID_t = typename BaseMapper_t::ID_t;
259 
260  // import all constructors from `geo::GeoIDmapper`
261  using BaseMapper_t::BaseMapper_t;
262 
270  TPCIDmapper(unsigned int nCryo, unsigned int nTPCs) : BaseMapper_t({nCryo, nTPCs}) {}
271 
272  // --- BEGIN Mapping modification --------------------------------------------
275 
276  using BaseMapper_t::resize;
277 
286  void resize(unsigned int nCryo, unsigned int nTPCs) { BaseMapper_t::resize({nCryo, nTPCs}); }
287 
289  // --- END Mapping modification ----------------------------------------------
290 
291  // --- BEGIN Mapping status query --------------------------------------------
294 
296  bool hasCryostat(CryostatID const& cryoid) const { return BaseMapper_t::hasElement(cryoid); }
297 
299  bool hasTPC(TPCID const& tpcid) const { return BaseMapper_t::hasElement(tpcid); }
300 
302  // --- END Mapping status query ----------------------------------------------
303 
304 }; // geo::TPCIDmapper<>
305 
314 template <typename Index /* = std::size_t */>
315 class geo::PlaneIDmapper : public geo::GeoIDmapper<geo::PlaneID, Index> {
316 
319 
320 public:
321  // import types
322  using ID_t = typename BaseMapper_t::ID_t;
324 
325  // import all constructors from `geo::GeoIDmapper`
326  using BaseMapper_t::BaseMapper_t;
327 
337  PlaneIDmapper(unsigned int nCryo, unsigned int nTPCs, unsigned int nPlanes)
338  : BaseMapper_t({nCryo, nTPCs, nPlanes})
339  {}
340 
341  // --- BEGIN Mapping modification --------------------------------------------
344 
345  using BaseMapper_t::resize;
346 
357  void resize(unsigned int nCryo, unsigned int nTPCs, unsigned int nPlanes)
358  {
359  BaseMapper_t::resize({nCryo, nTPCs, nPlanes});
360  }
361 
363  // --- END Mapping modification ----------------------------------------------
364 
365  // --- BEGIN Mapping status query --------------------------------------------
368 
370  bool hasCryostat(CryostatID const& cryoid) const { return BaseMapper_t::hasElement(cryoid); }
371 
373  bool hasTPC(TPCID const& tpcid) const { return BaseMapper_t::hasElement(tpcid); }
374 
376  bool hasPlane(PlaneID const& planeid) const { return BaseMapper_t::hasElement(planeid); }
377 
379  // --- END Mapping status query ----------------------------------------------
380 
381 }; // geo::PlaneIDmapper<>
382 
384 // --- END Geometry ID mappers -------------------------------------------------
385 //------------------------------------------------------------------------------
386 
387 //------------------------------------------------------------------------------
388 //--- Template implementation
389 //------------------------------------------------------------------------------
390 template <std::size_t N, typename T>
391 auto geo::details::initializerListToArray(std::initializer_list<T> values)
392 {
393  std::array<T, N> data{}; // <- initializing to quiet the compiler
394  std::copy(values.begin(), values.end(), data.begin());
395  return data;
396 }
397 
398 //------------------------------------------------------------------------------
399 //--- geo::GeoIDmapper
400 //------------------------------------------------------------------------------
401 template <typename IDType, typename Index>
403 {
404  fN.fill(0U);
405 }
406 
407 //------------------------------------------------------------------------------
408 template <typename IDType, typename Index>
409 geo::GeoIDmapper<IDType, Index>::GeoIDmapper(std::initializer_list<unsigned int> dims)
410  : fN(details::initializerListToArray<dimensions()>(dims))
411 {
412  assert(dims.size() == dimensions()); // can't be static
413 }
414 
415 //------------------------------------------------------------------------------
416 template <typename IDType, typename Index>
418 {
419  return computeSize();
420 }
421 
422 //------------------------------------------------------------------------------
423 template <typename IDType, typename Index>
425 {
426  return size() == index_type{0};
427 }
428 
429 //------------------------------------------------------------------------------
430 template <typename IDType, typename Index>
431 template <std::size_t Level>
433 {
434  if constexpr (Level >= dimensions())
435  return 0U; // technically it would be 1...
436  else
437  return fN[Level];
438 }
439 
440 //------------------------------------------------------------------------------
441 template <typename IDType, typename Index>
443 {
444  return IDType::Level + 1;
445 }
446 
447 //------------------------------------------------------------------------------
448 template <typename IDType, typename Index>
449 template <typename GeoID>
451 {
452  return hasElementLevel<GeoID::Level>(id);
453 }
454 
455 //------------------------------------------------------------------------------
456 template <typename IDType, typename Index>
457 template <typename GeoID /* = ID_t */>
459 {
460  if constexpr (GeoID::Level == 0)
461  return GeoID(0U);
462  else
463  return GeoID(firstID<typename GeoID::ParentID_t>(), 0U);
464 }
465 
466 //------------------------------------------------------------------------------
467 template <typename IDType, typename Index>
468 template <typename GeoID /* = ID_t */>
470 {
471  if constexpr (GeoID::Level == 0)
472  return GeoID(fN[GeoID::Level] - 1U);
473  else
474  return GeoID(lastID<typename GeoID::ParentID_t>(), fN[GeoID::Level] - 1U);
475 }
476 
477 //------------------------------------------------------------------------------
478 template <typename IDType, typename Index>
480 {
481  return indexLevel<ID_t::Level>(id);
482 }
483 
484 //------------------------------------------------------------------------------
485 template <typename IDType, typename Index>
487 {
488  std::array<unsigned int, ID_t::Level + 1u> numbers;
489  fillID<ID_t::Level>(numbers, index);
490  auto id = std::make_from_tuple<ID_t>(numbers);
491  id.setValidity(id.Cryostat < fN[0u]);
492  return id;
493 }
494 
495 //------------------------------------------------------------------------------
496 template <typename IDType, typename Index>
498 {
499  return index(id);
500 }
501 
502 //------------------------------------------------------------------------------
503 template <typename IDType, typename Index>
505 {
506  return ID(index);
507 }
508 
509 //------------------------------------------------------------------------------
510 template <typename IDType, typename Index>
511 void geo::GeoIDmapper<IDType, Index>::resize(std::initializer_list<unsigned int> dims)
512 {
513  fN = details::initializerListToArray<dimensions()>(dims);
514 }
515 
516 //------------------------------------------------------------------------------
517 template <typename IDType, typename Index>
518 template <typename OIDType, typename OIndex>
520 {
521  resizeAsImpl(other, std::make_index_sequence<dimensions()>{});
522 }
523 
524 //------------------------------------------------------------------------------
525 template <typename IDType, typename Index>
527 {
528  fN.fill(0U);
529 }
530 
531 //------------------------------------------------------------------------------
532 template <typename IDType, typename Index>
533 template <std::size_t Level, typename GeoID>
535 {
536  if constexpr (Level == 0)
537  return id.template getIndex<0U>();
538  else {
539  return indexLevel<(Level - 1U)>(id) * fN[Level] + id.template getIndex<Level>();
540  }
541 }
542 
543 //------------------------------------------------------------------------------
544 template <typename IDType, typename Index>
545 template <std::size_t Level, std::size_t N>
546 void geo::GeoIDmapper<IDType, Index>::fillID(std::array<unsigned int, N>& numbers,
547  index_type index) const
548 {
549  if constexpr (Level == 0) { numbers[0] = index; }
550  else {
551  numbers[Level] = index % fN[Level];
552  fillID<Level - 1U>(numbers, index / fN[Level]);
553  }
554 }
555 
556 //------------------------------------------------------------------------------
557 template <typename IDType, typename Index>
558 template <std::size_t Level, typename GeoID>
560 {
561  if (!bounded(id.template getIndex<Level>(), fN[Level])) return false;
562  if constexpr (Level == 0U)
563  return true;
564  else
565  return hasElementLevel<(Level - 1U)>(id);
566 }
567 
568 //------------------------------------------------------------------------------
569 template <typename IDType, typename Index>
571 {
572  return sizeLevel<0U>(fN);
573 }
574 
575 //------------------------------------------------------------------------------
576 template <typename IDType, typename Index>
577 template <typename OIDType, typename OIndex, std::size_t... Indices>
579  std::index_sequence<Indices...>)
580 {
581  // Clang 5.0.1 does not understand `other.dimensions()` is constexpr
583  "Can't resize a deeper mapping to a shallower one.");
584  resize({other.template dimSize<Indices>()...});
585 }
586 
587 //------------------------------------------------------------------------------
588 template <typename IDType, typename Index>
589 template <std::size_t Level, typename Dims>
591 {
592  if constexpr (Level >= dimensions())
593  return 1U;
594  else
595  return sizeLevel<(Level + 1U)>(dimSizes) * dimSizes[Level];
596 }
597 
598 //------------------------------------------------------------------------------
599 
600 #endif // LARCOREALG_GEOMETRY_GEOMETRYIDMAPPER_H
void resizeAs(GeoIDmapper< OIDType, OIndex > const &other)
Resizes the mapping to reflect the one from another mapping.
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 hasTPC(TPCID const &tpcid) const
Returns whether this mapping covers the specified TPC.
void resizeAsImpl(GeoIDmapper< OIDType, OIndex > const &other, std::index_sequence< Indices... >)
Implementation for resizeAs().
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.
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:364
bool hasCryostat(CryostatID const &cryoid) const
Returns whether this mapping covers the specified cryostat.
bool hasTPC(TPCID const &tpcid) const
Returns whether this mapping covers the specified TPC.
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 hasPlane(PlaneID const &planeid) const
Returns whether this mapping covers the specified plane.
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.
bool hasCryostat(CryostatID const &cryoid) const
Returns whether this mapping covers the specified cryostat.
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:306
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.
ROOT libraries.
void fillID(std::array< unsigned int, N > &id, index_type index) const
Fills the specified ID with its index.
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:187
void clear()
Sets all dimension sizes to 0.
Class managing the mapping between geometry/readout ID and flat index.