LArSoft  v10_04_05
Liquid Argon Software toolkit - https://larsoft.org/
Partitions.h
Go to the documentation of this file.
1 
9 #ifndef LARCOREALG_GEOMETRY_PARTITIONS_H
10 #define LARCOREALG_GEOMETRY_PARTITIONS_H
11 
12 // LArSoft libraries
13 #include "larcorealg/CoreUtils/DebugUtils.h" // lar::debug::demangle(), ...
14 #include "larcorealg/Geometry/SimpleGeo.h" // lar::util::simple_geo::Rectangle
15 
16 // C/C++ standard libraries
17 #include <algorithm> // std::upper_bound()
18 #include <cassert>
19 #include <cstdlib> // std::size_t
20 #include <iterator> // std::next(), ...
21 #include <memory> // std::unique_ptr<>
22 #include <sstream>
23 #include <string>
24 #include <type_traits> // std::declval(), std::true_type...
25 #include <utility> // std::move(), std::forward()
26 #include <vector>
27 
29 namespace geo::part {
30 
31  //-------------------------------------------------------------------------
33  class AreaOwner {
34  public:
37 
40 
42  AreaOwner(Area_t const& area) : myArea(area) {}
43 
45  bool contains(double w, double d) const { return area().contains(w, d); }
46 
48  Area_t const& area() const { return myArea; }
49 
51  template <typename Stream>
52  void dumpArea(Stream&& out) const
53  {
54  std::forward<Stream>(out) << area();
55  }
56 
57  private:
59 
60  }; // class AreaOwner
61 
62  namespace details {
63 
65  template <AreaOwner::AreaRangeMember_t Range>
67 
68  } // namespace details
69 
70  //*************************************************************************
71  //*** Fundamental classes
72  //-------------------------------------------------------------------------
73 
90  template <typename Data>
93  template <typename Stream>
94  PartitionDataDescriber(Stream&& out,
95  Data const* data,
96  std::string indent = "",
97  std::string firstIndent = "");
98  }; // struct PartitionDataDescriber<>
99 
118  template <typename Stream, typename Data>
119  void describePartitionData(Stream&& out,
120  Data const* data,
121  std::string indent = "",
122  std::string firstIndent = "");
123 
124  //--------------------------------------------------------------------------
133  class PartitionBase : public AreaOwner {
134  public:
135  // imported types
138 
140  PartitionBase(Area_t const& area) : AreaOwner(area) {}
141 
142  protected:
144  std::string describeArea(std::string indent, std::string firstIndent) const;
145 
146  }; // class PartitionBase
147 
148  //--------------------------------------------------------------------------
172  template <typename Data>
173  class Partition : public PartitionBase {
174  public:
175  using Data_t = Data;
178 
180  using Subpartitions_t = std::vector<std::unique_ptr<Partition_t const>>;
181 
183  Partition(Area_t const& area) : PartitionBase(area) {}
184 
186  virtual ~Partition() = default;
187 
189  virtual Data_t* data() const { return nullptr; }
190 
201  virtual Data_t* atPoint(double w, double d) const = 0;
202 
204  std::string describe(std::string indent, std::string firstIndent) const
205  {
206  return doDescribe(indent, firstIndent);
207  }
208 
210  std::string describe(std::string indent = "") const { return describe(indent, indent); }
211 
227  template <typename Pred>
228  void walk(Pred&& pred) const
229  {
230  walk(this, pred);
231  }
232 
234  std::size_t nParts() const { return parts().size(); }
235 
236  protected:
238 
240  virtual Subpartitions_t const& parts() const { return NoSubparts; }
241 
243  virtual std::string doDescribe(std::string indent, std::string firstIndent) const
244  {
245  return PartitionBase::describeArea(indent, firstIndent);
246  }
247 
249  template <typename Pred>
250  static void walk(Partition_t const* start, Pred&& pred);
251 
252  }; // class Partition<>
253 
254  //**************************************************************************
255  //*** Partition class hierarchy
256  //--------------------------------------------------------------------------
258  template <typename Data>
259  class PartitionWithData : public Partition<Data> {
260 
261  public:
264  using Data_t = typename Partition_t::Data_t;
265  using Area_t = typename Partition_t::Area_t;
266 
268  PartitionWithData(Area_t const& area, Data_t* myData) : Base_t(area), myData(myData) {}
269 
271  virtual Data_t* data() const override { return myData; }
272 
274  virtual Data_t* atPoint(double w, double d) const override
275  {
276  return Base_t::contains(w, d) ? myData : nullptr;
277  }
278 
279  private:
281 
283  virtual std::string doDescribe(std::string indent, std::string firstIndent) const override;
284 
285  }; // class PartitionWithData
286 
287  //--------------------------------------------------------------------------
289  template <typename Data>
290  class PartitionElement : public PartitionWithData<Data> {
291  public:
293 
294  // Import constructors
295  using Base_t::Base_t;
296  };
297 
298  //--------------------------------------------------------------------------
300  template <typename Data>
301  class PartitionContainer : public PartitionWithData<Data> {
302  public:
305 
306  // inherited types
307  using Data_t = typename Partition_t::Data_t;
308  using Area_t = typename Partition_t::Area_t;
310 
312  virtual Data_t* atPoint(double w, double d) const override;
313 
314  protected:
316 
318  std::size_t size() const { return parts().size(); }
319 
321  virtual Subpartitions_t const& parts() const override { return myParts; }
322 
337  Subpartitions_t&& subpartitions,
338  Data_t* defData = nullptr)
339  : Base_t(area, defData), myParts(std::move(subpartitions))
340  {}
341 
343  virtual Partition_t const* findPart(double w, double d) const = 0;
344 
346  virtual std::string doDescribe(std::string indent, std::string firstIndent) const override;
347 
349  virtual std::string describeIntro() const;
350 
351  }; // class PartitionContainer<>
352 
353  //--------------------------------------------------------------------------
368  template <typename Data, typename Sorter>
369  class SortedPartition : public PartitionContainer<Data> {
370  public:
373  using Sorter_t = Sorter;
374 
375  // inherited data types
376  using Data_t = typename Partition_t::Data_t;
377  using Area_t = typename Partition_t::Area_t;
379 
397  Subpartitions_t&& subpartitions,
398  Data_t* defData = nullptr,
399  Sorter_t sorter = {})
400  : Base_t(area, std::move(subpartitions), defData), sorter(sorter)
401  {
402  initParts();
403  }
404 
405  protected:
407 
409  Partition_t const* findPartWithKey(double key) const;
410 
412  void initParts();
413 
414  }; // class SortedPartition<>
415 
416  //--------------------------------------------------------------------------
418  template <typename Data, PartitionBase::AreaRangeMember_t Range>
420  : public SortedPartition<Data, details::PartitionSorterByAreaRangeLower<Range>> {
421  public:
423  using Base_t::Base_t; // import inherited constructors
424  };
425 
426  //--------------------------------------------------------------------------
428  template <typename Data>
429  class DepthPartition : public PartitionSortedByRange<Data, &PartitionBase::Area_t::depth> {
430  public:
432 
433  using Base_t::Base_t; // import inherited constructors
434 
436  virtual typename Base_t::Partition_t const* findPart(double /* w */, double d) const override
437  {
438  return Base_t::findPartWithKey(d);
439  }
440 
441  private:
442  virtual std::string describeIntro() const override;
443 
444  }; // class DepthPartition
445 
446  //--------------------------------------------------------------------------
448  template <typename Data>
449  class WidthPartition : public PartitionSortedByRange<Data, &PartitionBase::Area_t::width> {
450  public:
453 
454  using Base_t::Base_t; // inherited constructors
455 
457  virtual typename Base_t::Partition_t const* findPart(double w, double /* d */) const override
458  {
459  return Base_t::findPartWithKey(w);
460  }
461 
462  private:
463  virtual std::string describeIntro() const override;
464 
465  }; // class WidthPartition
466 
467  //--------------------------------------------------------------------------
469  template <typename Data>
470  class GridPartition : public PartitionContainer<Data> {
471  public:
474 
475  // Inherited types
476  using Data_t = typename Partition_t::Data_t;
477  using Area_t = typename Partition_t::Area_t;
479 
494  GridPartition(Area_t const& area,
495  Subpartitions_t&& subpartitions,
496  unsigned int nDepthPartitions,
497  unsigned int nWidthPartitions,
498  Data_t* defData = nullptr);
499 
501  GridPartition(Area_t const& area,
502  Subpartitions_t&& subpartitions,
503  unsigned int nDepthPartitions,
504  Data_t* defData = nullptr);
505 
506  private:
507  std::vector<double> widthSeps;
508  std::vector<double> depthSeps;
509 
511  std::size_t nWidthParts() const { return widthSeps.size(); }
513  std::size_t nDepthParts() const { return depthSeps.size(); }
514 
515  auto part(std::size_t iDepth, std::size_t iWidth) -> decltype(auto)
516  {
517  return Base_t::parts()[iDepth * nWidthParts() + iWidth];
518  }
519  auto part(std::size_t iDepth, std::size_t iWidth) const -> decltype(auto)
520  {
521  return Base_t::parts()[iDepth * nWidthParts() + iWidth];
522  }
523 
525  virtual Partition_t const* findPart(double w, double d) const override;
526 
528  std::vector<double> computeWidthSeps(unsigned int nD, unsigned int nW) const;
530  std::vector<double> computeDepthSeps(unsigned int nD, unsigned int nW) const;
531 
533  virtual std::string doDescribe(std::string indent, std::string firstIndent) const override;
534 
535  template <PartitionBase::AreaRangeMember_t Range, typename BeginIter, typename EndIter>
536  static std::vector<double> detectSeparators(BeginIter b,
537  EndIter e,
538  std::size_t const nGroups,
539  std::size_t const startDelta,
540  std::size_t const stride);
541 
542  }; // class GridPartition<>
543 
544  //--------------------------------------------------------------------------
545 
546 } // namespace geo::part
547 
548 //******************************************************************************
549 //*** inline implementation
550 //******************************************************************************
551 inline std::string geo::part::PartitionBase::describeArea(std::string,
552  std::string firstIndent) const
553 {
554  std::ostringstream sstr;
555  sstr << firstIndent << "partition covers ";
556  dumpArea(sstr);
557  return sstr.str();
558 }
559 
560 //******************************************************************************
561 //*** template implementation
562 //******************************************************************************
563 
564 namespace geo::part::details {
565 
566  //------------------------------------------------------------------------
567  //--- some metaprogramming utilities
568  //------------------------------------------------------------------------
570  template <typename T, typename = void>
571  struct is_partition_type : public std::false_type {};
572 
573  template <typename Part>
575  Part,
576  std::enable_if_t<std::is_base_of<PartitionBase, std::decay_t<Part>>::value>>
577  : public std::true_type {};
578 
580  template <typename T>
582 
583  //------------------------------------------------------------------------
585  template <typename, typename = void>
586  struct is_partition_ptr : public std::false_type {};
587 
588  template <typename PartPtr>
589  struct is_partition_ptr<PartPtr,
590  std::enable_if_t<is_partition_type_v<decltype(*std::declval<PartPtr>())>>>
591  : public std::true_type {};
592 
594  template <typename T>
596 
597  //------------------------------------------------------------------------
599  template <typename, typename = void>
600  struct is_partition_ptr_iterator : public std::false_type {};
601 
602  template <typename Iter>
604  Iter,
605  std::enable_if_t<is_partition_ptr_v<std::decay_t<typename Iter::value_type>>>>
606  : public std::true_type {};
607 
608  //------------------------------------------------------------------------
609  //--- Sorting objects
610  //------------------------------------------------------------------------
612  template <AreaOwner::AreaRangeMember_t Range>
614  static constexpr auto range = Range;
616 
617  double operator()(double lower) const { return lower; }
618  double operator()(Area_t::Range_t const& r) const { return (*this)(r.lower); }
619  double operator()(Area_t const& area) const { return (*this)(area.*range); }
620  double operator()(AreaOwner const& area) const { return (*this)(area.area()); }
621  double operator()(AreaOwner const* ptr) const { return (*this)(*ptr); }
622  };
623 
624  //------------------------------------------------------------------------
626  template <PartitionBase::AreaRangeMember_t Range>
629  using Area_t = typename Base_t::Area_t;
630 
632 
633  using Base_t::operator(); // import inherited versions
634 
635  auto operator()(Partition_t const& part) { return Base_t::operator()(part.area()); }
636  template <typename PartPtr,
638  auto operator()(PartPtr const& part)
639  {
640  return operator()(*part);
641  }
642  };
643 
644  //------------------------------------------------------------------------
645  template <PartitionBase::AreaRangeMember_t Range>
648 
650 
651  static constexpr auto range = Range;
652 
653  template <typename T>
654  static auto key(T const& obj)
655  {
656  return KeyExtractor_t()(obj);
657  }
658 
660  using Key_t = decltype(Sorter_t::key(std::declval<PartitionBase>()));
661 
662  static Key_t key(Key_t k) { return k; } // shortcut
663  static bool sortKey(Key_t a, Key_t b) { return a < b; }
664 
665  template <typename A, typename B>
666  bool operator()(A const& a, B const& b) const
667  {
668  return sortKey(key(a), key(b));
669  }
670  };
671 
672  //------------------------------------------------------------------------
673 
674 } // namespace geo::part::details
675 
676 //------------------------------------------------------------------------------
677 //--- partition data description
678 //---
679 
680 template <typename Data>
681 template <typename Stream>
683  Data const* data,
684  std::string indent /* = "" */,
685  std::string firstIndent /* = "" */
686 )
687 {
688  out << firstIndent;
689  std::string typeName = lar::debug::demangle<Data>();
690  if (data) { out << typeName << "[" << ((void*)data) << "]"; }
691  else {
692  out << "no '" << typeName << "' data";
693  }
694 }
695 
696 template <typename Stream, typename Data>
698  Data const* data,
699  std::string indent /* = "" */,
700  std::string firstIndent /* = "" */
701 )
702 {
703  PartitionDataDescriber<Data>(std::forward<Stream>(out), data, indent, firstIndent);
704 }
705 
706 //------------------------------------------------------------------------------
707 //--- geo::part::Partition
708 //---
709 template <typename Data>
711 
712 //------------------------------------------------------------------------------
713 template <typename Data>
714 template <typename Pred>
715 void geo::part::Partition<Data>::walk(Partition_t const* start, Pred&& pred)
716 {
717  if (!start) return;
718  pred(*start);
719 
720  // recursive implementation
721  for (auto const& subPart : start->parts())
722  subPart->walk(std::forward<Pred>(pred));
723 }
724 
725 //------------------------------------------------------------------------------
726 //--- geo::part::PartitionWithData
727 //---
728 template <typename Data>
730  std::string firstIndent) const
731 {
732  std::string msg = Base_t::doDescribe(indent, firstIndent);
733  if (data()) {
734  std::ostringstream sstr;
735  sstr << ": ";
736  describePartitionData(sstr, data(), indent);
737  msg += sstr.str();
738  }
739  else {
740  msg += " (no data)";
741  }
742  return msg;
743 }
744 
745 //------------------------------------------------------------------------------
746 //--- geo::part::PartitionContainer
747 //---
748 //------------------------------------------------------------------------------
749 template <typename Data>
751 {
752  if (!Base_t::contains(w, d)) return nullptr; // not our point at all
753  // it's ours; see if it belongs to a subpart
754  auto part = findPart(w, d);
755  return part ? part->atPoint(w, d) : Base_t::data();
756 }
757 
758 //------------------------------------------------------------------------------
759 template <typename Data>
761  std::string firstIndent) const
762 {
763  std::string msg = firstIndent + describeIntro();
764  if (Base_t::data()) {
765  std::ostringstream sstr;
766  sstr << ", and ";
767  describePartitionData(sstr, Base_t::data(), indent, "");
768  msg += sstr.str();
769  }
770 
771  for (auto const& part : parts()) {
772  msg += "\n" + indent + " * ";
773  msg += part->describe(indent + " ", "");
774  }
775 
776  return msg;
777 }
778 
779 //------------------------------------------------------------------------------
780 template <typename Data>
782 {
783  return std::to_string(parts().size()) + " subpartitions";
784 }
785 
786 //------------------------------------------------------------------------------
787 //--- geo::part::SortedPartition
788 //---
789 template <typename Data, typename Sorter>
791  -> Partition_t const*
792 {
793  auto pbegin = Base_t::parts().cbegin();
794  auto iPart = std::upper_bound(pbegin, Base_t::parts().cend(), key, sorter);
795  return (iPart == pbegin) ? nullptr : (--iPart)->get();
796 }
797 
798 //------------------------------------------------------------------------------
799 template <typename Data, typename Sorter>
801 {
802  /*
803  * Initialization tasks:
804  * - ensure that the parts are sorted by increasing depth
805  */
806  std::sort(Base_t::myParts.begin(), Base_t::myParts.end(), sorter);
807 }
808 
809 //------------------------------------------------------------------------------
810 //--- geo::part::DepthPartition
811 //---
812 template <typename Data>
814 {
815  std::ostringstream sstr;
816  sstr << Base_t::size() << " partitions along depth covering " << Base_t::area();
817  return sstr.str();
818 }
819 
820 //------------------------------------------------------------------------------
821 //--- geo::part::WidthPartition
822 //---
823 template <typename Data>
825 {
826  std::ostringstream sstr;
827  sstr << Base_t::size() << " partitions along width covering " << Base_t::area();
828  return sstr.str();
829 }
830 
831 //------------------------------------------------------------------------------
832 //--- geo::part::GridPartition
833 //---
834 template <typename Data>
836  Subpartitions_t&& subpartitions,
837  unsigned int nDepthPartitions,
838  unsigned int nWidthPartitions,
839  Data_t* defData /* = nullptr */
840  )
841  : Base_t(area, std::move(subpartitions), defData)
842  , widthSeps(computeWidthSeps(nDepthPartitions, nWidthPartitions))
843  , depthSeps(computeDepthSeps(nDepthPartitions, nWidthPartitions))
844 {
845  assert(nWidthPartitions * nDepthPartitions == Base_t::size());
846 }
847 
848 template <typename Data>
850  Subpartitions_t&& subpartitions,
851  unsigned int nDepthPartitions,
852  Data_t* defData /* = nullptr */
853  )
854  : GridPartition(area,
855  std::move(subpartitions),
856  nDepthPartitions,
857  (nDepthPartitions ? subpartitions.size() / nDepthPartitions : 0),
858  defData)
859 {}
860 
861 //------------------------------------------------------------------------------
862 template <typename Data>
864  std::string firstIndent) const
865 {
866  std::ostringstream sstr;
867  sstr << firstIndent << Base_t::describeIntro() << " in a (WxD) = " << nWidthParts() << " x "
868  << nDepthParts() << " grid";
869  if (Base_t::data()) {
870  sstr << ", and ";
871  describePartitionData(sstr, Base_t::data(), indent, "");
872  }
873  for (std::size_t iDepth = 0; iDepth < nDepthParts(); ++iDepth) {
874  for (std::size_t iWidth = 0; iWidth < nWidthParts(); ++iWidth) {
875  sstr << "\n"
876  << indent << " [" << iDepth << "][" << iWidth << "] "
877  << part(iDepth, iWidth)->describe(indent + " ", "");
878  } // for width
879  } // for depth
880  return sstr.str();
881 }
882 
883 //------------------------------------------------------------------------------
884 template <typename Data>
885 auto geo::part::GridPartition<Data>::findPart(double w, double d) const -> Partition_t const*
886 {
887  auto const iWidth = std::upper_bound(widthSeps.cbegin(), widthSeps.cend(), w);
888  if (iWidth == widthSeps.cbegin()) return nullptr;
889  auto const iDepth = std::upper_bound(depthSeps.cbegin(), depthSeps.cend(), d);
890  if (iDepth == depthSeps.cbegin()) return nullptr;
891  return part(std::distance(depthSeps.cbegin(), iDepth) - 1U,
892  std::distance(widthSeps.cbegin(), iWidth) - 1U)
893  .get();
894 }
895 
896 //------------------------------------------------------------------------------
897 template <typename Data>
898 std::vector<double> geo::part::GridPartition<Data>::computeWidthSeps(unsigned int,
899  unsigned int nW) const
900 {
901  return detectSeparators<&Area_t::width>(
902  Base_t::parts().cbegin(), Base_t::parts().cend(), nW, 1U, nW);
903 }
904 
905 template <typename Data>
906 std::vector<double> geo::part::GridPartition<Data>::computeDepthSeps(unsigned int nD,
907  unsigned int nW) const
908 {
909  return detectSeparators<&Area_t::depth>(
910  Base_t::parts().cbegin(), Base_t::parts().cend(), nD, nW, 1U);
911 }
912 
913 template <typename Data>
914 template <geo::part::AreaOwner::AreaRangeMember_t Range, typename BeginIter, typename EndIter>
915 std::vector<double> geo::part::GridPartition<Data>::detectSeparators(BeginIter b,
916  EndIter e,
917  std::size_t const nGroups,
918  std::size_t const startDelta,
919  std::size_t const stride)
920 {
921  /*
922  * The iterators are better be random access.
923  * The range [b,e[ is considered to be a 2D table stored row after row.
924  * This function can operate on rows or columns, given the proper arguments.
925  *
926  * The full range is split in nGroups "groups" (e.g. rows or columns).
927  * Each group g starts at the element g x startDelta.
928  * All members of that group are stride elements far from each other.
929  *
930  * Be the table of size (d x w).
931  * To process data row by row:
932  * - the group is a row
933  * - the number of groups is the number of rows: nGroups = d
934  * - each group will have (d x w)/nGroups = w elements
935  * - the start offset is the number of group times the size of it:
936  * startDelta = w
937  * - the elements are contiguous: stride = 1
938  *
939  * To process data column by column:
940  * - the group is a column
941  * - the number of groups is the number of columns: nGroups = w
942  * - each group will have (d x w)/nGroups = d elements
943  * - the start offset matches the number of group: startDelta = 1
944  * - the elements are separated by a full row: stride = w
945  *
946  */
947  // the separator is on the lower bound of selected range of the partition area
948 
950  "Begin iterator does not point to a pointer to partition type");
951 
953 
954  std::size_t const nParts = std::distance(b, e);
955  std::size_t const nPartsInGroup = nParts / nGroups;
956 
957  auto const part = [b](std::size_t index) { return std::next(b, index)->get(); };
958 
959  std::vector<double> seps(nGroups);
960  for (size_t g = 0; g < nGroups; ++g) {
961 
962  double& sep = seps[g];
963 
964  // indices of an element in the previous and next group, respectively
965  std::size_t index = g * startDelta;
966  sep = lowerBound(part(index));
967 
968  std::size_t const iend = index + nPartsInGroup * stride;
969  while ((index += stride) < iend) {
970  double const l = lowerBound(part(index));
971  if (sep > l) sep = l;
972  } // while (element)
973 
974  } // while (groups)
975  return seps;
976 }
977 
978 //******************************************************************************
979 
980 #endif // LARCOREALG_GEOMETRY_PARTITIONS_H
TRandom r
Definition: spectrum.C:23
Partition_t const * findPartWithKey(double key) const
Returns the only partition which could contain the specified key.
Definition: Partitions.h:790
AreaOwner(Area_t const &area)
Constructor: sets the covered area and no subpartitions.
Definition: Partitions.h:42
Trait type evaluating true if T is iterator to some PartitionBase.
Definition: Partitions.h:600
PartitionBase(Area_t const &area)
Constructor: sets the covered area and no subpartitions.
Definition: Partitions.h:140
PartitionContainer(Area_t const &area, Subpartitions_t &&subpartitions, Data_t *defData=nullptr)
Constructor: sets the partition.
Definition: Partitions.h:336
A basic interface for objects owning an area.
Definition: Partitions.h:33
void describePartitionData(Stream &&out, Data const *data, std::string indent="", std::string firstIndent="")
Describes a data object for Partition::describe() method.
Definition: Partitions.h:697
Partition-related utilities.
Definition: Partitions.h:29
auto part(std::size_t iDepth, std::size_t iWidth) -> decltype(auto)
Definition: Partitions.h:515
std::vector< double > computeDepthSeps(unsigned int nD, unsigned int nW) const
Computes and returns width separation levels proper for depthSeps.
Definition: Partitions.h:906
constexpr bool is_partition_type_v
Constant true if T is derived from PartitionBase.
Definition: Partitions.h:581
AreaOwner::Area_t Area_t
Definition: Partitions.h:136
decltype(auto) constexpr cend(T &&obj)
ADL-aware version of std::cend.
Definition: StdUtils.h:93
Partition of area along the width dimension.
Definition: Partitions.h:449
virtual std::string doDescribe(std::string indent, std::string firstIndent) const override
Describes this and each of the subpartitions.
Definition: Partitions.h:760
void initParts()
Performs initialization on the specified subpartition list.
Definition: Partitions.h:800
virtual Base_t::Partition_t const * findPart(double, double d) const override
Returns the only partition which could contain the specified depth.
Definition: Partitions.h:436
virtual Data_t * atPoint(double w, double d) const override
Returns stored datum only if point is covered, nullptr otherwise.
Definition: Partitions.h:750
Class extracting the lower bound of the specified range of a partition area.
Definition: Partitions.h:627
double operator()(Area_t::Range_t const &r) const
Definition: Partitions.h:618
bool contains(Data_t w, Data_t d) const
Returns whether the specified point is in the area.
Definition: SimpleGeo.h:441
double operator()(AreaOwner const *ptr) const
Definition: Partitions.h:621
STL namespace.
Class providing custom dump for data contained in the partition.
Definition: Partitions.h:91
std::vector< double > depthSeps
Separators for depth dimension.
Definition: Partitions.h:508
virtual Data_t * data() const
Returns the datum directly stored (nullptr if none).
Definition: Partitions.h:189
Ordering class to sort partition by specified range (lower boundary).
Definition: Partitions.h:66
bool operator()(A const &a, B const &b) const
Definition: Partitions.h:666
std::vector< double > widthSeps
Separators for width dimension.
Definition: Partitions.h:507
virtual std::string doDescribe(std::string indent, std::string firstIndent) const
Returns a description of the partition.
Definition: Partitions.h:243
bool contains(double w, double d) const
Returns whether the specified point is covered by this object.
Definition: Partitions.h:45
std::vector< double > computeWidthSeps(unsigned int nD, unsigned int nW) const
Computes and returns width separation levels proper for widthSeps.
Definition: Partitions.h:898
std::string describe(std::string indent="") const
Returns a description of the partition.
Definition: Partitions.h:210
Partition(Area_t const &area)
Constructor: sets the covered area and no subpartitions.
Definition: Partitions.h:183
decltype(auto) constexpr end(T &&obj)
ADL-aware version of std::end.
Definition: StdUtils.h:77
Trait type evaluating true if T is derived from PartitionBase.
Definition: Partitions.h:571
Non-template definitions and data for Partition class hierarchy.
Definition: Partitions.h:133
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
Definition: StdUtils.h:101
double operator()(Area_t const &area) const
Definition: Partitions.h:619
std::vector< std::unique_ptr< Partition_t const >> Subpartitions_t
Type of list of subpartitions. It needs to preserve polymorphism.
Definition: Partitions.h:180
Base element of a partitioned structure.
Definition: Partitions.h:173
virtual Subpartitions_t const & parts() const
Returns a list of all subpartitions.
Definition: Partitions.h:240
TString part[npart]
Definition: Style.C:32
Partition of area along the depth dimension.
Definition: Partitions.h:429
Area_t myArea
Covered area.
Definition: Partitions.h:58
double operator()(double lower) const
Definition: Partitions.h:617
decltype(auto) constexpr to_string(T &&obj)
ADL-aware version of std::to_string.
virtual std::string doDescribe(std::string indent, std::string firstIndent) const override
Returns a description of the partition.
Definition: Partitions.h:729
Partition of area along a area range dimension (width or depth).
Definition: Partitions.h:419
lar::util::simple_geo::Rectangle< double > Area_t
Type of area covered by the partition.
Definition: Partitions.h:36
std::string indent(std::size_t const i)
Float_t d
Definition: plot.C:235
Area_t const & area() const
Returns the covered area.
Definition: Partitions.h:48
PartitionWithData(Area_t const &area, Data_t *myData)
Constructor: sets the covered area and the contained datum.
Definition: Partitions.h:268
std::size_t size() const
Returns the number of contained subpartitions.
Definition: Partitions.h:318
void walk(Pred &&pred) const
Applies pred to all partitions.
Definition: Partitions.h:228
virtual Subpartitions_t const & parts() const override
Returns a list of the subpartitions owned.
Definition: Partitions.h:321
virtual Partition_t const * findPart(double w, double d) const override
Returns the only partition which could contain the specified depth.
Definition: Partitions.h:885
Range< Data_t > Range_t
Type for dimension boundaries.
Definition: SimpleGeo.h:426
static Subpartitions_t const NoSubparts
Subpartitions (if any).
Definition: Partitions.h:237
Subpartitions_t myParts
List of subpartitions.
Definition: Partitions.h:315
Data_t * myData
The contained datum.
Definition: Partitions.h:280
void dumpArea(Stream &&out) const
Output the owned area into an output stream.
Definition: Partitions.h:52
Class extracting the lower bound of the specified range of an area.
Definition: Partitions.h:613
std::string describe(std::string indent, std::string firstIndent) const
Returns a description of the partition.
Definition: Partitions.h:204
double value
Definition: spectrum.C:18
std::size_t nWidthParts() const
Number of partitions on width direction.
Definition: Partitions.h:511
virtual Data_t * data() const override
Returns the datum directly stored (nullptr if none).
Definition: Partitions.h:271
virtual Data_t * atPoint(double w, double d) const override
Returns stored datum only if point is covered, nullptr otherwise.
Definition: Partitions.h:274
Unpartitioned element ("leaf") of a partitioned area.
Definition: Partitions.h:290
Partition divided in subpartitions (abstract).
Definition: Partitions.h:301
auto part(std::size_t iDepth, std::size_t iWidth) const -> decltype(auto)
Definition: Partitions.h:519
decltype(Sorter_t::key(std::declval< PartitionBase >())) Key_t
Type of sorting key. In short: double.
Definition: Partitions.h:660
Data Data_t
Type of data stored in the partition.
Definition: Partitions.h:175
SortedPartition(Area_t const &area, Subpartitions_t &&subpartitions, Data_t *defData=nullptr, Sorter_t sorter={})
Constructor: sets the partition.
Definition: Partitions.h:396
Functions to help debugging by instrumenting code.
constexpr bool is_partition_ptr_v
Constant true if T is pointer to some PartitionBase.
Definition: Partitions.h:595
Sorter_t sorter
Object used for sorting and binary search.
Definition: Partitions.h:406
static std::vector< double > detectSeparators(BeginIter b, EndIter e, std::size_t const nGroups, std::size_t const startDelta, std::size_t const stride)
Definition: Partitions.h:915
Some simple functions to represent geometry entitiesThis library is simple and header-only.
Partition of area sorted across a dimension.
Definition: Partitions.h:369
virtual std::string describeIntro() const
Introduction to the description of the subpartitions.
Definition: Partitions.h:781
std::size_t nDepthParts() const
Definition: Partitions.h:513
A container of partitions organised in a width/depth rectangular grid.
Definition: Partitions.h:470
Trait type evaluating true if T is pointer to some PartitionBase.
Definition: Partitions.h:586
virtual Base_t::Partition_t const * findPart(double w, double) const override
Returns the only partition which could contain the specified depth.
Definition: Partitions.h:457
virtual std::string doDescribe(std::string indent, std::string firstIndent) const override
Prints the information about the partition grid.
Definition: Partitions.h:863
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
Definition: StdUtils.h:69
std::size_t nParts() const
Returns the number of subparts in the partition (0 if simple element).
Definition: Partitions.h:234
virtual std::string describeIntro() const override
Introduction to the description of the subpartitions.
Definition: Partitions.h:813
Float_t e
Definition: plot.C:35
std::string describeArea(std::string indent, std::string firstIndent) const
Returns a description of the partition area.
Definition: Partitions.h:551
Data_t lower
Starting coordinate.
Definition: SimpleGeo.h:357
Float_t w
Definition: plot.C:20
GridPartition(Area_t const &area, Subpartitions_t &&subpartitions, unsigned int nDepthPartitions, unsigned int nWidthPartitions, Data_t *defData=nullptr)
Creates a partition with a grid of subpartitions.
Definition: Partitions.h:835
Partition also containing data directly.
Definition: Partitions.h:259
PartitionDataDescriber(Stream &&out, Data const *data, std::string indent="", std::string firstIndent="")
Constructor; see describePartitionData() for argument description.
Definition: Partitions.h:682
typename Partition_t::Data_t Data_t
Type of contained data.
Definition: Partitions.h:264
virtual std::string describeIntro() const override
Introduction to the description of the subpartitions.
Definition: Partitions.h:824
Area_t::Range_t(Area_t::*) AreaRangeMember_t
Type of pointer to Area_t data member of type Range_t.
Definition: Partitions.h:39
double operator()(AreaOwner const &area) const
Definition: Partitions.h:620