11 #ifndef LARCOREALG_GEOMETRY_PARTITIONS_H 12 #define LARCOREALG_GEOMETRY_PARTITIONS_H 26 #include <type_traits> 59 template <
typename Stream>
60 void dumpArea(Stream&& out)
const { std::forward<Stream>(out) <<
area(); }
71 template <AreaOwner::AreaRangeMember_t Range>
96 template <
typename Data>
99 template <
typename Stream>
101 Stream&& out, Data
const* data,
102 std::string
indent =
"", std::string firstIndent =
"" 124 template <
typename Stream,
typename Data>
126 Stream&& out, Data
const* data,
127 std::string
indent =
"", std::string firstIndent =
"" 155 std::string describeArea
156 (std::string
indent, std::string firstIndent)
const;
187 template <
typename Data>
217 virtual Data_t* atPoint(
double w,
double d)
const = 0;
221 (std::string
indent, std::string firstIndent)
const 222 {
return doDescribe(indent, firstIndent); }
225 std::string
describe(std::string indent =
"")
const 226 {
return describe(indent, indent); }
245 template <
typename Pred>
249 std::size_t
nParts()
const {
return parts().size(); }
259 virtual std::string doDescribe
260 (std::string indent, std::string firstIndent)
const 265 template <
typename Pred>
266 static void walk(
Partition_t const* start, Pred&& pred);
274 template <
typename Data>
285 :
Base_t(area), myData(myData)
293 {
return Base_t::contains(w, d)? myData:
nullptr; }
299 virtual std::string doDescribe
300 (std::string indent, std::string firstIndent)
const override;
307 template <
typename Data>
314 using Base_t::Base_t;
321 template <
typename Data>
334 virtual Data_t* atPoint(
double w,
double d)
const override;
340 std::size_t
size()
const {
return parts().size(); }
363 :
Base_t(area, defData), myParts(
std::move(subpartitions))
367 virtual Partition_t const* findPart(
double w,
double d)
const = 0;
370 virtual std::string doDescribe
371 (std::string indent, std::string firstIndent)
const override;
374 virtual std::string describeIntro()
const;
395 template <
typename Data,
typename Sorter>
427 Data_t* defData =
nullptr,
430 :
Base_t(area, std::move(subpartitions), defData), sorter(sorter)
438 Partition_t const* findPartWithKey(
double key)
const;
448 template<
typename Data, PartitionBase::AreaRangeMember_t Range>
450 <Data, details::PartitionSorterByAreaRangeLower<Range>>
463 template <
typename Data>
475 virtual typename Base_t::Partition_t
const* findPart
476 (
double ,
double d)
const override 477 {
return Base_t::findPartWithKey(d); }
481 virtual std::string describeIntro()
const override;
488 template <
typename Data>
500 virtual typename Base_t::Partition_t
const* findPart
501 (
double w,
double )
const override 502 {
return Base_t::findPartWithKey(w); }
506 virtual std::string describeIntro()
const override;
513 template <
typename Data>
541 unsigned int nDepthPartitions,
unsigned int nWidthPartitions,
550 unsigned int nDepthPartitions,
Data_t* defData =
nullptr 563 auto part(std::size_t iDepth, std::size_t iWidth) ->decltype(
auto)
564 {
return Base_t::parts()[iDepth * nWidthParts() + iWidth]; }
565 auto part(std::size_t iDepth, std::size_t iWidth)
const ->decltype(
auto)
566 {
return Base_t::parts()[iDepth * nWidthParts() + iWidth]; }
569 virtual Partition_t const* findPart(
double w,
double d)
const override;
572 std::vector<double> computeWidthSeps
573 (
unsigned int nD,
unsigned int nW)
const;
575 std::vector<double> computeDepthSeps
576 (
unsigned int nD,
unsigned int nW)
const;
579 virtual std::string doDescribe
580 (std::string indent, std::string firstIndent)
const override;
584 typename BeginIter,
typename EndIter
586 static std::vector<double> detectSeparators(
587 BeginIter b, EndIter
e,
588 std::size_t
const nGroups,
589 std::size_t
const startDelta,
590 std::size_t
const stride
606 (std::string, std::string firstIndent)
const 608 std::ostringstream sstr;
609 sstr << firstIndent <<
"partition covers ";
627 template <
typename T,
typename =
void>
630 template <
typename Part>
635 <std::is_base_of<PartitionBase, std::decay_t<Part>>::value>
637 :
public std::true_type
641 template <
typename T>
647 template <
typename,
typename =
void>
650 template <
typename PartPtr>
655 <is_partition_type_v<decltype(*std::declval<PartPtr>())>>
657 :
public std::true_type
661 template <
typename T>
667 template <
typename,
typename =
void>
670 template <
typename Iter>
675 <is_partition_ptr_v<std::decay_t<typename Iter::value_type>>>
677 :
public std::true_type
685 template <AreaOwner::AreaRangeMember_t Range>
687 static constexpr
auto range = Range;
690 double operator() (
double lower)
const {
return lower; }
692 {
return (*
this)(r.
lower); }
694 {
return (*
this)(area.*range); }
696 {
return (*
this)(area.
area()); }
698 {
return (*
this)(*ptr); }
706 template <PartitionBase::AreaRangeMember_t Range>
715 using Base_t::operator();
718 {
return Base_t::operator()(part.
area()); }
724 {
return operator()(*part); }
730 template <PartitionBase::AreaRangeMember_t Range>
736 static constexpr
auto range = Range;
738 template <
typename T>
742 using Key_t = decltype(Sorter_t::key(std::declval<PartitionBase>()));
747 template <
typename A,
typename B>
748 bool operator() (A
const& a,
B const& b)
const 749 {
return sortKey(key(a), key(b)); }
765 template <
typename Data>
766 template <
typename Stream>
768 Stream&& out, Data
const* data,
769 std::string indent , std::string firstIndent
773 std::string typeName = lar::debug::demangle<Data>();
775 out << typeName <<
"[" << ((
void*) data) <<
"]";
778 out <<
"no '" << typeName <<
"' data";
783 template <
typename Stream,
typename Data>
785 Stream&& out, Data
const* data,
786 std::string indent , std::string firstIndent
790 (std::forward<Stream>(out), data, indent, firstIndent);
797 template <
typename Data>
802 template <
typename Data>
803 template <
typename Pred>
809 for (
auto const& subPart: start->
parts())
810 subPart->walk(std::forward<Pred>(pred));
818 template <
typename Data>
820 (std::string indent, std::string firstIndent)
const 822 std::string msg = Base_t::doDescribe(indent, firstIndent);
824 std::ostringstream sstr;
840 template <
typename Data>
844 if (!Base_t::contains(w, d))
return nullptr;
846 auto part = findPart(w, d);
847 return part?
part->atPoint(w, d): Base_t::data();
852 template <
typename Data>
854 (std::string indent, std::string firstIndent)
const 856 std::string msg = firstIndent + describeIntro();
857 if (Base_t::data()) {
858 std::ostringstream sstr;
864 for (
auto const&
part: parts()) {
865 msg +=
"\n" + indent +
" * ";
866 msg +=
part->describe(indent +
" ",
"");
874 template <
typename Data>
883 template <
typename Data,
typename Sorter>
887 auto pbegin = Base_t::parts().cbegin();
888 auto iPart = std::upper_bound(pbegin, Base_t::parts().cend(), key, sorter);
889 return (iPart == pbegin)?
nullptr: (--iPart)->
get();
894 template <
typename Data,
typename Sorter>
901 std::sort(Base_t::myParts.
begin(), Base_t::myParts.
end(), sorter);
909 template <
typename Data>
911 std::ostringstream sstr;
913 << Base_t::size() <<
" partitions along depth covering " << Base_t::area();
921 template <
typename Data>
923 std::ostringstream sstr;
925 << Base_t::size() <<
" partitions along width covering " << Base_t::area();
933 template <
typename Data>
937 unsigned int nDepthPartitions,
unsigned int nWidthPartitions,
940 :
Base_t(area,
std::move(subpartitions), defData)
941 , widthSeps(computeWidthSeps(nDepthPartitions, nWidthPartitions))
942 , depthSeps(computeDepthSeps(nDepthPartitions, nWidthPartitions))
944 assert(nWidthPartitions * nDepthPartitions ==
Base_t::size());
948 template <
typename Data>
952 unsigned int nDepthPartitions,
Data_t* defData
955 area,
std::move(subpartitions), nDepthPartitions,
956 (nDepthPartitions? subpartitions.
size()/nDepthPartitions: 0),
963 template <
typename Data>
965 (std::string indent, std::string firstIndent)
const 967 std::ostringstream sstr;
974 for (std::size_t iDepth = 0; iDepth <
nDepthParts(); ++iDepth) {
975 for (std::size_t iWidth = 0; iWidth <
nWidthParts(); ++iWidth) {
976 sstr <<
"\n" << indent <<
" [" << iDepth <<
"][" << iWidth <<
"] " 977 <<
part(iDepth, iWidth)->describe(indent +
" ",
"");
986 template <
typename Data>
991 if (iWidth ==
widthSeps.cbegin())
return nullptr;
993 if (iDepth ==
depthSeps.cbegin())
return nullptr;
995 std::distance(
depthSeps.cbegin(), iDepth) - 1U,
996 std::distance(
widthSeps.cbegin(), iWidth) - 1U
1002 template <
typename Data>
1004 (
unsigned int,
unsigned int nW)
const 1006 return detectSeparators<&Area_t::width>
1011 template <
typename Data>
1013 (
unsigned int nD,
unsigned int nW)
const 1015 return detectSeparators<&Area_t::depth>
1020 template <
typename Data>
1023 typename BeginIter,
typename EndIter
1026 BeginIter b, EndIter
e,
1027 std::size_t
const nGroups,
1028 std::size_t
const startDelta,
1029 std::size_t
const stride
1060 "Begin iterator does not point to a pointer to partition type");
1064 std::size_t
const nParts = std::distance(b, e);
1065 std::size_t
const nPartsInGroup = nParts / nGroups;
1068 = [b](std::size_t index){
return std::next(b, index)->get(); };
1070 std::vector<double> seps(nGroups);
1071 for (
size_t g = 0; g < nGroups; ++g) {
1073 double& sep = seps[g];
1076 std::size_t index = g * startDelta;
1077 sep = lowerBound(
part(index));
1079 std::size_t
const iend = index + nPartsInGroup * stride;
1080 while ((index += stride) < iend) {
1081 double const l = lowerBound(
part(index));
1082 if (sep > l) sep = l;
1092 #endif // LARCOREALG_GEOMETRY_PARTITIONS_H Partition_t const * findPartWithKey(double key) const
Returns the only partition which could contain the specified key.
AreaOwner(Area_t const &area)
Constructor: sets the covered area and no subpartitions.
Trait type evaluating true if T is iterator to some PartitionBase.
PartitionBase(Area_t const &area)
Constructor: sets the covered area and no subpartitions.
PartitionContainer(Area_t const &area, Subpartitions_t &&subpartitions, Data_t *defData=nullptr)
Constructor: sets the partition.
A basic interface for objects owning an area.
void describePartitionData(Stream &&out, Data const *data, std::string indent="", std::string firstIndent="")
Describes a data object for Partition::describe() method.
auto part(std::size_t iDepth, std::size_t iWidth) const -> decltype(auto)
std::vector< double > computeDepthSeps(unsigned int nD, unsigned int nW) const
Computes and returns width separation levels proper for depthSeps.
constexpr bool is_partition_type_v
Constant true if T is derived from PartitionBase.
static Key_t key(Key_t k)
static auto key(T const &obj)
Partition of area along the width dimension.
virtual std::string doDescribe(std::string indent, std::string firstIndent) const override
Describes this and each of the subpartitions.
void initParts()
Performs initialization on the specified subpartition list.
virtual Data_t * atPoint(double w, double d) const override
Returns stored datum only if point is covered, nullptr otherwise.
bool contains(Data_t w, Data_t d) const
Returns whether the specified point is in the area.
Class providing custom dump for data contained in the partition.
std::vector< double > depthSeps
Separators for depth dimension.
virtual Data_t * data() const
Returns the datum directly stored (nullptr if none).
Ordering class to sort partition by specified range (lower boundary).
std::vector< double > widthSeps
Separators for width dimension.
AreaOwner::AreaRangeMember_t AreaRangeMember_t
bool contains(double w, double d) const
Returns whether the specified point is covered by this object.
std::vector< double > computeWidthSeps(unsigned int nD, unsigned int nW) const
Computes and returns width separation levels proper for widthSeps.
std::string describe(std::string indent="") const
Returns a description of the partition.
Partition(Area_t const &area)
Constructor: sets the covered area and no subpartitions.
Trait type evaluating true if T is derived from PartitionBase.
Non-template definitions and data for Partition class hierarchy.
std::vector< std::unique_ptr< Partition_t const >> Subpartitions_t
Type of list of subpartitions. It needs to preserve polymorphism.
Base element of a partitioned structure.
virtual Subpartitions_t const & parts() const
Returns a list of all subpartitions.
Partition of area along the depth dimension.
Area_t myArea
Covered area.
std::string describe(cet::exempt_ptr< fhicl::ConfigurationTable const > pb, std::string const &prefix)
virtual std::string doDescribe(std::string indent, std::string firstIndent) const override
Returns a description of the partition.
Partition of area along a area range dimension (width or depth).
lar::util::simple_geo::Rectangle< double > Area_t
Type of area covered by the partition.
std::vector< evd::details::RawDigitInfo_t >::const_iterator begin(RawDigitCacheDataClass const &cache)
std::string indent(std::size_t const i)
Area_t const & area() const
Returns the covered area.
PartitionWithData(Area_t const &area, Data_t *myData)
Constructor: sets the covered area and the contained datum.
std::size_t size() const
Returns the number of contained subpartitions.
void walk(Pred &&pred) const
Applies pred to all partitions.
virtual Subpartitions_t const & parts() const override
Returns a list of the subpartitions owned.
virtual Partition_t const * findPart(double w, double d) const override
Returns the only partition which could contain the specified depth.
Sorter Sorter_t
Type of sorter being used.
Range< Data_t > Range_t
Type for dimension boundaries.
static Subpartitions_t const NoSubparts
Subpartitions (if any).
Subpartitions_t myParts
List of subpartitions.
Data_t * myData
The contained datum.
void dumpArea(Stream &&out) const
Output the owned area into an output stream.
std::size_t nWidthParts() const
Number of partitions on width direction.
virtual Data_t * data() const override
Returns the datum directly stored (nullptr if none).
static bool sortKey(Key_t a, Key_t b)
virtual Data_t * atPoint(double w, double d) const override
Returns stored datum only if point is covered, nullptr otherwise.
Unpartitioned element ("leaf") of a partitioned area.
Partition divided in subpartitions (abstract).
decltype(Sorter_t::key(std::declval< PartitionBase >())) Key_t
Type of sorting key. In short: double.
auto part(std::size_t iDepth, std::size_t iWidth) -> decltype(auto)
std::string value(boost::any const &)
Data Data_t
Type of data stored in the partition.
SortedPartition(Area_t const &area, Subpartitions_t &&subpartitions, Data_t *defData=nullptr, Sorter_t sorter={})
Constructor: sets the partition.
Functions to help debugging by instrumenting code.
std::string to_string(Flag_t< Storage > const flag)
Convert a flag into a stream (shows its index).
constexpr bool is_partition_ptr_v
Constant true if T is pointer to some PartitionBase.
Sorter_t sorter
Object used for sorting and binary search.
static std::vector< double > detectSeparators(BeginIter b, EndIter e, std::size_t const nGroups, std::size_t const startDelta, std::size_t const stride)
Some simple functions to represent geometry entities.
Partition of area sorted across a dimension.
virtual std::string describeIntro() const
Introduction to the description of the subpartitions.
std::size_t nDepthParts() const
A container of partitions organised in a width/depth rectangular grid.
Trait type evaluating true if T is pointer to some PartitionBase.
virtual std::string doDescribe(std::string indent, std::string firstIndent) const override
Prints the information about the partition grid.
std::vector< evd::details::RawDigitInfo_t >::const_iterator end(RawDigitCacheDataClass const &cache)
std::size_t nParts() const
Returns the number of subparts in the partition (0 if simple element).
virtual std::string describeIntro() const override
std::string describeArea(std::string indent, std::string firstIndent) const
Returns a description of the partition area.
Data_t lower
Starting coordinate.
Namespace collecting geometry-related classes utilities.
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.
Partition also containing data directly.
PartitionDataDescriber(Stream &&out, Data const *data, std::string indent="", std::string firstIndent="")
Constructor; see describePartitionData() for argument description.
typename Partition_t::Data_t Data_t
Type of contained data.
virtual std::string describeIntro() const override
Area_t::Range_t(Area_t::*) AreaRangeMember_t
Type of pointer to Area_t data member of type Range_t.