LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
Partitions.h
Go to the documentation of this file.
1 
11 #ifndef LARCOREALG_GEOMETRY_PARTITIONS_H
12 #define LARCOREALG_GEOMETRY_PARTITIONS_H
13 
14 // LArSoft libraries
15 #include "larcorealg/CoreUtils/DebugUtils.h" // lar::debug::demangle(), ...
16 #include "larcorealg/Geometry/SimpleGeo.h" // lar::util::simple_geo::Rectangle
17 
18 // C/C++ standard libraries
19 #include <algorithm> // std::upper_bound()
20 #include <cassert>
21 #include <cstdlib> // std::size_t
22 #include <iterator> // std::next(), ...
23 #include <memory> // std::unique_ptr<>
24 #include <sstream>
25 #include <string>
26 #include <type_traits> // std::declval(), std::true_type...
27 #include <utility> // std::move(), std::forward()
28 #include <vector>
29 
30 namespace geo {
31 
33  namespace part {
34 
35  //-------------------------------------------------------------------------
37  class AreaOwner {
38 
39  public:
42 
45 
47  AreaOwner(Area_t const& area) : myArea(area) {}
48 
50  bool contains(double w, double d) const { return area().contains(w, d); }
51 
53  Area_t const& area() const { return myArea; }
54 
56  template <typename Stream>
57  void dumpArea(Stream&& out) const
58  {
59  std::forward<Stream>(out) << area();
60  }
61 
62  private:
64 
65  }; // class AreaOwner
66 
67  namespace details {
68 
70  template <AreaOwner::AreaRangeMember_t Range>
72 
73  } // namespace details
74 
75  //*************************************************************************
76  //*** Fundamental classes
77  //-------------------------------------------------------------------------
78 
95  template <typename Data>
98  template <typename Stream>
99  PartitionDataDescriber(Stream&& out,
100  Data const* data,
101  std::string indent = "",
102  std::string firstIndent = "");
103  }; // struct PartitionDataDescriber<>
104 
123  template <typename Stream, typename Data>
124  void describePartitionData(Stream&& out,
125  Data const* data,
126  std::string indent = "",
127  std::string firstIndent = "");
128 
129  //--------------------------------------------------------------------------
140  class PartitionBase : public AreaOwner {
141 
142  public:
143  // imported types
146 
148  PartitionBase(Area_t const& area) : AreaOwner(area) {}
149 
150  protected:
152  std::string describeArea(std::string indent, std::string firstIndent) const;
153 
154  }; // class PartitionBase
155 
156  //--------------------------------------------------------------------------
182  template <typename Data>
183  class Partition : public PartitionBase {
184 
185  public:
186  using Data_t = Data;
189 
191  using Subpartitions_t = std::vector<std::unique_ptr<Partition_t const>>;
192 
194  Partition(Area_t const& area) : PartitionBase(area) {}
195 
197  virtual ~Partition() = default;
198 
200  virtual Data_t* data() const { return nullptr; }
201 
212  virtual Data_t* atPoint(double w, double d) const = 0;
213 
215  std::string describe(std::string indent, std::string firstIndent) const
216  {
217  return doDescribe(indent, firstIndent);
218  }
219 
221  std::string describe(std::string indent = "") const { return describe(indent, indent); }
222 
240  template <typename Pred>
241  void walk(Pred&& pred) const
242  {
243  walk(this, pred);
244  }
245 
247  std::size_t nParts() const { return parts().size(); }
248 
249  protected:
251 
253  virtual Subpartitions_t const& parts() const { return NoSubparts; }
254 
256  virtual std::string doDescribe(std::string indent, std::string firstIndent) const
257  {
258  return PartitionBase::describeArea(indent, firstIndent);
259  }
260 
263  template <typename Pred>
264  static void walk(Partition_t const* start, Pred&& pred);
265 
266  }; // class Partition<>
267 
268  //**************************************************************************
269  //*** Partition class hierarchy
270  //--------------------------------------------------------------------------
272  template <typename Data>
273  class PartitionWithData : public Partition<Data> {
274 
275  public:
278  using Data_t = typename Partition_t::Data_t;
279  using Area_t = typename Partition_t::Area_t;
280 
282  PartitionWithData(Area_t const& area, Data_t* myData) : Base_t(area), myData(myData) {}
283 
285  virtual Data_t* data() const override { return myData; }
286 
288  virtual Data_t* atPoint(double w, double d) const override
289  {
290  return Base_t::contains(w, d) ? myData : nullptr;
291  }
292 
293  private:
295 
297  virtual std::string doDescribe(std::string indent, std::string firstIndent) const override;
298 
299  }; // class PartitionWithData
300 
301  //--------------------------------------------------------------------------
303  template <typename Data>
304  class PartitionElement : public PartitionWithData<Data> {
305 
306  public:
308 
309  // Import constructors
310  using Base_t::Base_t;
311 
312  }; // class PartitionElement
313 
314  //--------------------------------------------------------------------------
316  template <typename Data>
317  class PartitionContainer : public PartitionWithData<Data> {
318 
319  public:
322 
323  // inherited types
324  using Data_t = typename Partition_t::Data_t;
325  using Area_t = typename Partition_t::Area_t;
327 
329  virtual Data_t* atPoint(double w, double d) const override;
330 
331  protected:
333 
335  std::size_t size() const { return parts().size(); }
336 
338  virtual Subpartitions_t const& parts() const override { return myParts; }
339 
354  Subpartitions_t&& subpartitions,
355  Data_t* defData = nullptr)
356  : Base_t(area, defData), myParts(std::move(subpartitions))
357  {}
358 
360  virtual Partition_t const* findPart(double w, double d) const = 0;
361 
363  virtual std::string doDescribe(std::string indent, std::string firstIndent) const override;
364 
366  virtual std::string describeIntro() const;
367 
368  }; // class PartitionContainer<>
369 
370  //--------------------------------------------------------------------------
386  template <typename Data, typename Sorter>
387  class SortedPartition : public PartitionContainer<Data> {
388 
389  public:
392  using Sorter_t = Sorter;
393 
394  // inherited data types
395  using Data_t = typename Partition_t::Data_t;
396  using Area_t = typename Partition_t::Area_t;
398 
416  Subpartitions_t&& subpartitions,
417  Data_t* defData = nullptr,
418  Sorter_t sorter = {})
419  : Base_t(area, std::move(subpartitions), defData), sorter(sorter)
420  {
421  initParts();
422  }
423 
424  protected:
426 
428  Partition_t const* findPartWithKey(double key) const;
429 
431  void initParts();
432 
433  }; // class SortedPartition<>
434 
435  //--------------------------------------------------------------------------
437  template <typename Data, PartitionBase::AreaRangeMember_t Range>
439  : public SortedPartition<Data, details::PartitionSorterByAreaRangeLower<Range>> {
440  public:
443  using Base_t::Base_t; // import inherited constructors
444 
445  }; // class PartitionSortedByRange
446 
447  //--------------------------------------------------------------------------
449  template <typename Data>
450  class DepthPartition : public PartitionSortedByRange<Data, &PartitionBase::Area_t::depth> {
451  public:
454 
455  using Base_t::Base_t; // import inherited constructors
456 
458  virtual typename Base_t::Partition_t const* findPart(double /* w */, double d) const override
459  {
460  return Base_t::findPartWithKey(d);
461  }
462 
463  private:
464  virtual std::string describeIntro() const override;
465 
466  }; // class DepthPartition
467 
468  //--------------------------------------------------------------------------
470  template <typename Data>
471  class WidthPartition : public PartitionSortedByRange<Data, &PartitionBase::Area_t::width> {
472  public:
475 
476  using Base_t::Base_t; // inherited constructors
477 
479  virtual typename Base_t::Partition_t const* findPart(double w, double /* d */) const override
480  {
481  return Base_t::findPartWithKey(w);
482  }
483 
484  private:
485  virtual std::string describeIntro() const override;
486 
487  }; // class WidthPartition
488 
489  //--------------------------------------------------------------------------
491  template <typename Data>
492  class GridPartition : public PartitionContainer<Data> {
493  public:
496 
497  // Inherited types
498  using Data_t = typename Partition_t::Data_t;
499  using Area_t = typename Partition_t::Area_t;
501 
516  GridPartition(Area_t const& area,
517  Subpartitions_t&& subpartitions,
518  unsigned int nDepthPartitions,
519  unsigned int nWidthPartitions,
520  Data_t* defData = nullptr);
521 
524  GridPartition(Area_t const& area,
525  Subpartitions_t&& subpartitions,
526  unsigned int nDepthPartitions,
527  Data_t* defData = nullptr);
528 
529  private:
530  std::vector<double> widthSeps;
531  std::vector<double> depthSeps;
532 
534  std::size_t nWidthParts() const { return widthSeps.size(); }
536  std::size_t nDepthParts() const { return depthSeps.size(); }
537 
538  auto part(std::size_t iDepth, std::size_t iWidth) -> decltype(auto)
539  {
540  return Base_t::parts()[iDepth * nWidthParts() + iWidth];
541  }
542  auto part(std::size_t iDepth, std::size_t iWidth) const -> decltype(auto)
543  {
544  return Base_t::parts()[iDepth * nWidthParts() + iWidth];
545  }
546 
548  virtual Partition_t const* findPart(double w, double d) const override;
549 
551  std::vector<double> computeWidthSeps(unsigned int nD, unsigned int nW) const;
553  std::vector<double> computeDepthSeps(unsigned int nD, unsigned int nW) const;
554 
556  virtual std::string doDescribe(std::string indent, std::string firstIndent) const override;
557 
558  template <PartitionBase::AreaRangeMember_t Range, typename BeginIter, typename EndIter>
559  static std::vector<double> detectSeparators(BeginIter b,
560  EndIter e,
561  std::size_t const nGroups,
562  std::size_t const startDelta,
563  std::size_t const stride);
564 
565  }; // class GridPartition<>
566 
567  //--------------------------------------------------------------------------
568 
569  } // namespace part
570 } // namespace geo
571 
572 //******************************************************************************
573 //*** inline implementation
574 //******************************************************************************
575 inline std::string geo::part::PartitionBase::describeArea(std::string,
576  std::string firstIndent) const
577 {
578  std::ostringstream sstr;
579  sstr << firstIndent << "partition covers ";
580  dumpArea(sstr);
581  return sstr.str();
582 } // geo::part::PartitionBase::describeArea()
583 
584 //******************************************************************************
585 //*** template implementation
586 //******************************************************************************
587 
588 namespace geo {
589  namespace part {
590  namespace details {
591 
592  //------------------------------------------------------------------------
593  //--- some metaprogramming utilities
594  //------------------------------------------------------------------------
596  template <typename T, typename = void>
597  struct is_partition_type : public std::false_type {};
598 
599  template <typename Part>
601  Part,
602  std::enable_if_t<std::is_base_of<PartitionBase, std::decay_t<Part>>::value>>
603  : public std::true_type {};
604 
606  template <typename T>
608 
609  //------------------------------------------------------------------------
611  template <typename, typename = void>
612  struct is_partition_ptr : public std::false_type {};
613 
614  template <typename PartPtr>
616  PartPtr,
617  std::enable_if_t<is_partition_type_v<decltype(*std::declval<PartPtr>())>>>
618  : public std::true_type {};
619 
621  template <typename T>
623 
624  //------------------------------------------------------------------------
626  template <typename, typename = void>
627  struct is_partition_ptr_iterator : public std::false_type {};
628 
629  template <typename Iter>
631  Iter,
632  std::enable_if_t<is_partition_ptr_v<std::decay_t<typename Iter::value_type>>>>
633  : public std::true_type {};
634 
635  //------------------------------------------------------------------------
636  //--- Sorting objects
637  //------------------------------------------------------------------------
639  template <AreaOwner::AreaRangeMember_t Range>
641  static constexpr auto range = Range;
643 
644  double operator()(double lower) const { return lower; }
645  double operator()(Area_t::Range_t const& r) const { return (*this)(r.lower); }
646  double operator()(Area_t const& area) const { return (*this)(area.*range); }
647  double operator()(AreaOwner const& area) const { return (*this)(area.area()); }
648  double operator()(AreaOwner const* ptr) const { return (*this)(*ptr); }
649 
650  }; // struct RangeLowerBoundExtractor<>
651 
652  //------------------------------------------------------------------------
655  template <PartitionBase::AreaRangeMember_t Range>
658  using Area_t = typename Base_t::Area_t;
659 
661 
662  using Base_t::operator(); // import inherited versions
663 
664  auto operator()(Partition_t const& part) { return Base_t::operator()(part.area()); }
665  template <typename PartPtr,
667  auto operator()(PartPtr const& part)
668  {
669  return operator()(*part);
670  }
671 
672  }; // struct PartitionRangeLowerBoundExtractor<>
673 
674  //------------------------------------------------------------------------
675  template <PartitionBase::AreaRangeMember_t Range>
678 
680 
681  static constexpr auto range = Range;
682 
683  template <typename T>
684  static auto key(T const& obj)
685  {
686  return KeyExtractor_t()(obj);
687  }
688 
690  using Key_t = decltype(Sorter_t::key(std::declval<PartitionBase>()));
691 
692  static Key_t key(Key_t k) { return k; } // shortcut
693  static bool sortKey(Key_t a, Key_t b) { return a < b; }
694 
695  template <typename A, typename B>
696  bool operator()(A const& a, B const& b) const
697  {
698  return sortKey(key(a), key(b));
699  }
700 
701  }; // struct PartitionSorterByAreaRangeLower
702 
703  //------------------------------------------------------------------------
704 
705  } // namespace details
706  } // namespace part
707 } // namespace geo
708 
709 //------------------------------------------------------------------------------
710 //--- partition data description
711 //---
712 
713 template <typename Data>
714 template <typename Stream>
716  Data const* data,
717  std::string indent /* = "" */,
718  std::string firstIndent /* = "" */
719 )
720 {
721  out << firstIndent;
722  std::string typeName = lar::debug::demangle<Data>();
723  if (data) { out << typeName << "[" << ((void*)data) << "]"; }
724  else {
725  out << "no '" << typeName << "' data";
726  }
727 } // geo::part::PartitionDataDescriber::PartitionDataDescriber()
728 
729 template <typename Stream, typename Data>
731  Data const* data,
732  std::string indent /* = "" */,
733  std::string firstIndent /* = "" */
734 )
735 {
736  geo::part::PartitionDataDescriber<Data>(std::forward<Stream>(out), data, indent, firstIndent);
737 } // geo::part::describePartitionData()
738 
739 //------------------------------------------------------------------------------
740 //--- geo::part::Partition
741 //---
742 template <typename Data>
744 
745 //------------------------------------------------------------------------------
746 template <typename Data>
747 template <typename Pred>
748 void geo::part::Partition<Data>::walk(Partition_t const* start, Pred&& pred)
749 {
750  if (!start) return;
751  pred(*start);
752 
753  // recursive implementation
754  for (auto const& subPart : start->parts())
755  subPart->walk(std::forward<Pred>(pred));
756 
757 } // geo::part::Partition<Data>::walk()
758 
759 //------------------------------------------------------------------------------
760 //--- geo::part::PartitionWithData
761 //---
762 template <typename Data>
764  std::string firstIndent) const
765 {
766  std::string msg = Base_t::doDescribe(indent, firstIndent);
767  if (data()) {
768  std::ostringstream sstr;
769  sstr << ": ";
770  describePartitionData(sstr, data(), indent);
771  msg += sstr.str();
772  }
773  else {
774  msg += " (no data)";
775  }
776  return msg;
777 } // geo::part::PartitionWithData<Data>::doDescribe()
778 
779 //------------------------------------------------------------------------------
780 //--- geo::part::PartitionContainer
781 //---
782 //------------------------------------------------------------------------------
783 template <typename Data>
785 {
786  if (!Base_t::contains(w, d)) return nullptr; // not our point at all
787  // it's ours; see if it belongs to a subpart
788  auto part = findPart(w, d);
789  return part ? part->atPoint(w, d) : Base_t::data();
790 } // geo::part::PartitionContainer<Data>::atPoint()
791 
792 //------------------------------------------------------------------------------
793 template <typename Data>
795  std::string firstIndent) const
796 {
797  std::string msg = firstIndent + describeIntro();
798  if (Base_t::data()) {
799  std::ostringstream sstr;
800  sstr << ", and ";
801  describePartitionData(sstr, Base_t::data(), indent, "");
802  msg += sstr.str();
803  }
804 
805  for (auto const& part : parts()) {
806  msg += "\n" + indent + " * ";
807  msg += part->describe(indent + " ", "");
808  }
809 
810  return msg;
811 } // geo::part::PartitionContainer<Data>::doDescribe()
812 
813 //------------------------------------------------------------------------------
814 template <typename Data>
816 {
817  return std::to_string(parts().size()) + " subpartitions";
818 } // geo::part::PartitionContainer<Data>::describeIntro()
819 
820 //------------------------------------------------------------------------------
821 //--- geo::part::SortedPartition
822 //---
823 template <typename Data, typename Sorter>
825  -> Partition_t const*
826 {
827  auto pbegin = Base_t::parts().cbegin();
828  auto iPart = std::upper_bound(pbegin, Base_t::parts().cend(), key, sorter);
829  return (iPart == pbegin) ? nullptr : (--iPart)->get();
830 } // geo::part::SortedPartition<>::findPartWithKey()
831 
832 //------------------------------------------------------------------------------
833 template <typename Data, typename Sorter>
835 {
836  /*
837  * Initialization tasks:
838  * - ensure that the parts are sorted by increasing depth
839  *
840  */
841  std::sort(Base_t::myParts.begin(), Base_t::myParts.end(), sorter);
842 
843 } // geo::part::SortedPartition<>::initParts()
844 
845 //------------------------------------------------------------------------------
846 //--- geo::part::DepthPartition
847 //---
848 template <typename Data>
850 {
851  std::ostringstream sstr;
852  sstr << Base_t::size() << " partitions along depth covering " << Base_t::area();
853  return sstr.str();
854 } // geo::part::DepthPartition<Data>::describeIntro()
855 
856 //------------------------------------------------------------------------------
857 //--- geo::part::WidthPartition
858 //---
859 template <typename Data>
861 {
862  std::ostringstream sstr;
863  sstr << Base_t::size() << " partitions along width covering " << Base_t::area();
864  return sstr.str();
865 } // geo::part::WidthPartition<Data>::describeIntro()
866 
867 //------------------------------------------------------------------------------
868 //--- geo::part::GridPartition
869 //---
870 template <typename Data>
872  Subpartitions_t&& subpartitions,
873  unsigned int nDepthPartitions,
874  unsigned int nWidthPartitions,
875  Data_t* defData /* = nullptr */
876  )
877  : Base_t(area, std::move(subpartitions), defData)
878  , widthSeps(computeWidthSeps(nDepthPartitions, nWidthPartitions))
879  , depthSeps(computeDepthSeps(nDepthPartitions, nWidthPartitions))
880 {
881  assert(nWidthPartitions * nDepthPartitions == Base_t::size());
882 } // geo::part::GridPartition<Data>::GridPartition()
883 
884 template <typename Data>
886  Subpartitions_t&& subpartitions,
887  unsigned int nDepthPartitions,
888  Data_t* defData /* = nullptr */
889  )
890  : GridPartition(area,
891  std::move(subpartitions),
892  nDepthPartitions,
893  (nDepthPartitions ? subpartitions.size() / nDepthPartitions : 0),
894  defData)
895 {}
896 
897 //------------------------------------------------------------------------------
898 template <typename Data>
900  std::string firstIndent) const
901 {
902  std::ostringstream sstr;
903  sstr << firstIndent << Base_t::describeIntro() << " in a (WxD) = " << nWidthParts() << " x "
904  << nDepthParts() << " grid";
905  if (Base_t::data()) {
906  sstr << ", and ";
907  describePartitionData(sstr, Base_t::data(), indent, "");
908  }
909  for (std::size_t iDepth = 0; iDepth < nDepthParts(); ++iDepth) {
910  for (std::size_t iWidth = 0; iWidth < nWidthParts(); ++iWidth) {
911  sstr << "\n"
912  << indent << " [" << iDepth << "][" << iWidth << "] "
913  << part(iDepth, iWidth)->describe(indent + " ", "");
914  } // for width
915  } // for depth
916 
917  return sstr.str();
918 } // geo::part::GridPartition<Data>::doDescribe()
919 
920 //------------------------------------------------------------------------------
921 template <typename Data>
922 auto geo::part::GridPartition<Data>::findPart(double w, double d) const -> Partition_t const*
923 {
924  auto const iWidth = std::upper_bound(widthSeps.cbegin(), widthSeps.cend(), w);
925  if (iWidth == widthSeps.cbegin()) return nullptr;
926  auto const iDepth = std::upper_bound(depthSeps.cbegin(), depthSeps.cend(), d);
927  if (iDepth == depthSeps.cbegin()) return nullptr;
928  return part(std::distance(depthSeps.cbegin(), iDepth) - 1U,
929  std::distance(widthSeps.cbegin(), iWidth) - 1U)
930  .get();
931 } // geo::part::GridPartition<Data>::findPart()
932 
933 //------------------------------------------------------------------------------
934 template <typename Data>
935 std::vector<double> geo::part::GridPartition<Data>::computeWidthSeps(unsigned int,
936  unsigned int nW) const
937 {
938  return detectSeparators<&Area_t::width>(
939  Base_t::parts().cbegin(), Base_t::parts().cend(), nW, 1U, nW);
940 } // geo::part::GridPartition<Data>::computeWidthSeps()
941 
942 template <typename Data>
943 std::vector<double> geo::part::GridPartition<Data>::computeDepthSeps(unsigned int nD,
944  unsigned int nW) const
945 {
946  return detectSeparators<&Area_t::depth>(
947  Base_t::parts().cbegin(), Base_t::parts().cend(), nD, nW, 1U);
948 } // geo::part::GridPartition<Data>::computeDepthSeps()
949 
950 template <typename Data>
951 template <geo::part::AreaOwner::AreaRangeMember_t Range, typename BeginIter, typename EndIter>
952 std::vector<double> geo::part::GridPartition<Data>::detectSeparators(BeginIter b,
953  EndIter e,
954  std::size_t const nGroups,
955  std::size_t const startDelta,
956  std::size_t const stride)
957 {
958  /*
959  * The iterators are better be random access.
960  * The range [b,e[ is considered to be a 2D table stored row after row.
961  * This function can operate on rows or columns, given the proper arguments.
962  *
963  * The full range is split in nGroups "groups" (e.g. rows or columns).
964  * Each group g starts at the element g x startDelta.
965  * All members of that group are stride elements far from each other.
966  *
967  * Be the table of size (d x w).
968  * To process data row by row:
969  * - the group is a row
970  * - the number of groups is the number of rows: nGroups = d
971  * - each group will have (d x w)/nGroups = w elements
972  * - the start offset is the number of group times the size of it:
973  * startDelta = w
974  * - the elements are contiguous: stride = 1
975  *
976  * To process data column by column:
977  * - the group is a column
978  * - the number of groups is the number of columns: nGroups = w
979  * - each group will have (d x w)/nGroups = d elements
980  * - the start offset matches the number of group: startDelta = 1
981  * - the elements are separated by a full row: stride = w
982  *
983  */
984  // the separator is on the lower bound of selected range of the partition area
985 
987  "Begin iterator does not point to a pointer to partition type");
988 
990 
991  std::size_t const nParts = std::distance(b, e);
992  std::size_t const nPartsInGroup = nParts / nGroups;
993 
994  auto const part = [b](std::size_t index) { return std::next(b, index)->get(); };
995 
996  std::vector<double> seps(nGroups);
997  for (size_t g = 0; g < nGroups; ++g) {
998 
999  double& sep = seps[g];
1000 
1001  // indices of an element in the previous and next group, respectively
1002  std::size_t index = g * startDelta;
1003  sep = lowerBound(part(index));
1004 
1005  std::size_t const iend = index + nPartsInGroup * stride;
1006  while ((index += stride) < iend) {
1007  double const l = lowerBound(part(index));
1008  if (sep > l) sep = l;
1009  } // while (element)
1010 
1011  } // while (groups)
1012  return seps;
1013 } // geo::part::GridPartition<Data>::detectSeparators()
1014 
1015 //******************************************************************************
1016 
1017 #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:824
AreaOwner(Area_t const &area)
Constructor: sets the covered area and no subpartitions.
Definition: Partitions.h:47
Trait type evaluating true if T is iterator to some PartitionBase.
Definition: Partitions.h:627
PartitionBase(Area_t const &area)
Constructor: sets the covered area and no subpartitions.
Definition: Partitions.h:148
PartitionContainer(Area_t const &area, Subpartitions_t &&subpartitions, Data_t *defData=nullptr)
Constructor: sets the partition.
Definition: Partitions.h:353
A basic interface for objects owning an area.
Definition: Partitions.h:37
void describePartitionData(Stream &&out, Data const *data, std::string indent="", std::string firstIndent="")
Describes a data object for Partition::describe() method.
Definition: Partitions.h:730
std::vector< double > computeDepthSeps(unsigned int nD, unsigned int nW) const
Computes and returns width separation levels proper for depthSeps.
Definition: Partitions.h:943
constexpr bool is_partition_type_v
Constant true if T is derived from PartitionBase.
Definition: Partitions.h:607
auto part(std::size_t iDepth, std::size_t iWidth) -> decltype(auto)
Definition: Partitions.h:538
AreaOwner::Area_t Area_t
Definition: Partitions.h:144
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:471
virtual std::string doDescribe(std::string indent, std::string firstIndent) const override
Describes this and each of the subpartitions.
Definition: Partitions.h:794
void initParts()
Performs initialization on the specified subpartition list.
Definition: Partitions.h:834
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:458
virtual Data_t * atPoint(double w, double d) const override
Returns stored datum only if point is covered, nullptr otherwise.
Definition: Partitions.h:784
double operator()(Area_t::Range_t const &r) const
Definition: Partitions.h:645
bool contains(Data_t w, Data_t d) const
Returns whether the specified point is in the area.
Definition: SimpleGeo.h:442
double operator()(AreaOwner const *ptr) const
Definition: Partitions.h:648
STL namespace.
Class providing custom dump for data contained in the partition.
Definition: Partitions.h:96
std::vector< double > depthSeps
Separators for depth dimension.
Definition: Partitions.h:531
virtual Data_t * data() const
Returns the datum directly stored (nullptr if none).
Definition: Partitions.h:200
Ordering class to sort partition by specified range (lower boundary).
Definition: Partitions.h:71
bool operator()(A const &a, B const &b) const
Definition: Partitions.h:696
std::vector< double > widthSeps
Separators for width dimension.
Definition: Partitions.h:530
virtual std::string doDescribe(std::string indent, std::string firstIndent) const
Returns a description of the partition.
Definition: Partitions.h:256
bool contains(double w, double d) const
Returns whether the specified point is covered by this object.
Definition: Partitions.h:50
std::vector< double > computeWidthSeps(unsigned int nD, unsigned int nW) const
Computes and returns width separation levels proper for widthSeps.
Definition: Partitions.h:935
std::string describe(std::string indent="") const
Returns a description of the partition.
Definition: Partitions.h:221
Partition(Area_t const &area)
Constructor: sets the covered area and no subpartitions.
Definition: Partitions.h:194
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:597
Non-template definitions and data for Partition class hierarchy.
Definition: Partitions.h:140
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:646
std::vector< std::unique_ptr< Partition_t const >> Subpartitions_t
Type of list of subpartitions. It needs to preserve polymorphism.
Definition: Partitions.h:191
Base element of a partitioned structure.
Definition: Partitions.h:183
virtual Subpartitions_t const & parts() const
Returns a list of all subpartitions.
Definition: Partitions.h:253
TString part[npart]
Definition: Style.C:32
Partition of area along the depth dimension.
Definition: Partitions.h:450
Area_t myArea
Covered area.
Definition: Partitions.h:63
double operator()(double lower) const
Definition: Partitions.h:644
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:763
Partition of area along a area range dimension (width or depth).
Definition: Partitions.h:438
lar::util::simple_geo::Rectangle< double > Area_t
Type of area covered by the partition.
Definition: Partitions.h:41
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:53
PartitionWithData(Area_t const &area, Data_t *myData)
Constructor: sets the covered area and the contained datum.
Definition: Partitions.h:282
std::size_t size() const
Returns the number of contained subpartitions.
Definition: Partitions.h:335
void walk(Pred &&pred) const
Applies pred to all partitions.
Definition: Partitions.h:241
virtual Subpartitions_t const & parts() const override
Returns a list of the subpartitions owned.
Definition: Partitions.h:338
virtual Partition_t const * findPart(double w, double d) const override
Returns the only partition which could contain the specified depth.
Definition: Partitions.h:922
Range< Data_t > Range_t
Type for dimension boundaries.
Definition: SimpleGeo.h:427
static Subpartitions_t const NoSubparts
Subpartitions (if any).
Definition: Partitions.h:250
Subpartitions_t myParts
List of subpartitions.
Definition: Partitions.h:332
Data_t * myData
The contained datum.
Definition: Partitions.h:294
void dumpArea(Stream &&out) const
Output the owned area into an output stream.
Definition: Partitions.h:57
Class extracting the lower bound of the specified range of an area.
Definition: Partitions.h:640
std::string describe(std::string indent, std::string firstIndent) const
Returns a description of the partition.
Definition: Partitions.h:215
double value
Definition: spectrum.C:18
std::size_t nWidthParts() const
Number of partitions on width direction.
Definition: Partitions.h:534
virtual Data_t * data() const override
Returns the datum directly stored (nullptr if none).
Definition: Partitions.h:285
auto part(std::size_t iDepth, std::size_t iWidth) const -> decltype(auto)
Definition: Partitions.h:542
virtual Data_t * atPoint(double w, double d) const override
Returns stored datum only if point is covered, nullptr otherwise.
Definition: Partitions.h:288
Unpartitioned element ("leaf") of a partitioned area.
Definition: Partitions.h:304
Partition divided in subpartitions (abstract).
Definition: Partitions.h:317
decltype(Sorter_t::key(std::declval< PartitionBase >())) Key_t
Type of sorting key. In short: double.
Definition: Partitions.h:690
Data Data_t
Type of data stored in the partition.
Definition: Partitions.h:186
SortedPartition(Area_t const &area, Subpartitions_t &&subpartitions, Data_t *defData=nullptr, Sorter_t sorter={})
Constructor: sets the partition.
Definition: Partitions.h:415
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:622
Sorter_t sorter
Object used for sorting and binary search.
Definition: Partitions.h:425
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:952
Some simple functions to represent geometry entities.
Partition of area sorted across a dimension.
Definition: Partitions.h:387
virtual std::string describeIntro() const
Introduction to the description of the subpartitions.
Definition: Partitions.h:815
std::size_t nDepthParts() const
Definition: Partitions.h:536
A container of partitions organised in a width/depth rectangular grid.
Definition: Partitions.h:492
Trait type evaluating true if T is pointer to some PartitionBase.
Definition: Partitions.h:612
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:479
virtual std::string doDescribe(std::string indent, std::string firstIndent) const override
Prints the information about the partition grid.
Definition: Partitions.h:899
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:247
virtual std::string describeIntro() const override
Introduction to the description of the subpartitions.
Definition: Partitions.h:849
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:575
Data_t lower
Starting coordinate.
Definition: SimpleGeo.h:358
Namespace collecting geometry-related classes utilities.
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:871
Partition also containing data directly.
Definition: Partitions.h:273
PartitionDataDescriber(Stream &&out, Data const *data, std::string indent="", std::string firstIndent="")
Constructor; see describePartitionData() for argument description.
Definition: Partitions.h:715
typename Partition_t::Data_t Data_t
Type of contained data.
Definition: Partitions.h:278
virtual std::string describeIntro() const override
Introduction to the description of the subpartitions.
Definition: Partitions.h:860
Area_t::Range_t(Area_t::*) AreaRangeMember_t
Type of pointer to Area_t data member of type Range_t.
Definition: Partitions.h:44
double operator()(AreaOwner const &area) const
Definition: Partitions.h:647