87 const Eigen::Vector3f&,
88 const Eigen::Vector3f&,
89 const Eigen::Vector3f&,
91 Eigen::Vector3f&)
const;
93 using Point = std::tuple<float,float,const reco::ClusterHit3D*>;
156 int countClusters(0);
163 while(clusterParametersListItr != clusterParametersList.end())
168 std::cout <<
"**> Looking at Cluster " << countClusters++ <<
std::endl;
184 std::cout <<
">>>>>>>>>>> Reclustered to " << reclusteredParameters.size() <<
" Clusters <<<<<<<<<<<<<<<" <<
std::endl;
187 if (!reclusteredParameters.empty())
190 for (
auto&
cluster : reclusteredParameters)
192 std::cout <<
"****> Calling breakIntoTinyBits" <<
std::endl;
197 std::cout <<
"****> Broke Cluster with " <<
cluster.getHitPairListPtr().size() <<
" into " <<
cluster.daughterList().size() <<
" sub clusters";
198 for(
auto& clus :
cluster.daughterList()) std::cout <<
", " << clus.getHitPairListPtr().size();
208 clusterParametersListItr++;
213 theClockBuildClusters.
stop();
247 std::cout << indent <<
">>> breakIntoTinyBits with " << clusterToBreak.
getHitPairListPtr().size() <<
" input hits " <<
std::endl;
254 bool storeCurrentCluster(
true);
269 clusHitPairVector.sort([](
const auto&
left,
const auto&
right){
return left->getArclenToPoca() <
right->getArclenToPoca();});
273 std::vector<const reco::ClusterHit3D*> vertexHitVec;
275 std::cout << indent <<
"+> Breaking cluster, convex hull has " << bestEdgeList.size() <<
" edges to work with" <<
std::endl;
277 for(
const auto& edge : bestEdgeList)
279 vertexHitVec.push_back(std::get<0>(edge));
280 vertexHitVec.push_back(std::get<1>(edge));
284 std::sort(vertexHitVec.begin(),vertexHitVec.end(),[](
const auto&
left,
const auto&
right){
return left->getArclenToPoca() <
right->getArclenToPoca();});
287 using Hit3DItrPair = std::pair<reco::HitPairListPtr::iterator,reco::HitPairListPtr::iterator>;
288 using VertexPairList = std::list<Hit3DItrPair>;
290 VertexPairList vertexPairList;
293 for(
const auto& hit3D : vertexHitVec)
297 if (vertexItr == clusHitPairVector.end())
299 std::cout << indent <<
">>>>>>>>>>>>>>>>> Hit not found in input list, cannot happen? <<<<<<<<<<<<<<<<<<<" <<
std::endl;
303 std::cout << indent <<
"+> -- Distance from first to current vertex point: " <<
std::distance(firstHitItr,vertexItr) <<
" first: " << *firstHitItr <<
", vertex: " << *vertexItr;
306 if (
std::distance(firstHitItr,vertexItr) > minimumClusterSize)
308 vertexPairList.emplace_back(Hit3DItrPair(firstHitItr,vertexItr));
309 firstHitItr = vertexItr;
311 std::cout <<
" ++ made pair ";
320 std::cout << indent <<
"+> loop over vertices done, remant distance: " <<
std::distance(firstHitItr,clusHitPairVector.end()) <<
std::endl;
323 if (!vertexPairList.empty() &&
std::distance(firstHitItr,clusHitPairVector.end()) < minimumClusterSize)
324 vertexPairList.back().second = clusHitPairVector.end();
326 vertexPairList.emplace_back(Hit3DItrPair(firstHitItr,clusHitPairVector.end()));
329 std::cout << indent <<
"+> ---> breaking cluster into " << vertexPairList.size() <<
" subclusters" <<
std::endl;
331 if (vertexPairList.size() > 1)
333 storeCurrentCluster =
false;
336 for(
auto& hit3DItrPair : vertexPairList)
341 std::cout << indent <<
"+> -- building new cluster, size: " <<
std::distance(hit3DItrPair.first,hit3DItrPair.second) <<
std::endl;
344 hitPairListPtr.resize(
std::distance(hit3DItrPair.first,hit3DItrPair.second));
347 std::copy(hit3DItrPair.first,hit3DItrPair.second,hitPairListPtr.begin());
358 std::cout << indent <<
"+> -- >> cluster has a valid Full PCA" <<
std::endl;
365 if (fullPrimaryVec.dot(newPrimaryVec) < 0.)
367 for(
size_t vecIdx = 0; vecIdx < 3; vecIdx++) newFullPCA.
flipAxis(vecIdx);
373 positionItr =
breakIntoTinyBits(clusterParams, positionItr, outputClusterList, level+4);
380 if (storeCurrentCluster)
385 std::set<const reco::ClusterHit2D*> hitSet;
390 for(
const auto& hit2D : hit3D->getHits())
392 if (hit2D) hitSet.insert(hit2D);
397 for(
const auto& hit2D : hitSet)
403 std::cout << indent <<
"*********>>> storing new subcluster of size " << clusterToBreak.
getHitPairListPtr().size() <<
std::endl;
405 positionItr = outputClusterList.insert(positionItr,clusterToBreak);
410 else if (inputPositionItr == positionItr) std::cout << indent <<
"***** DID NOT STORE A CLUSTER *****" <<
std::endl;
431 using Point = std::tuple<float,float,const reco::ClusterHit3D*>;
438 Eigen::Vector3f pcaToHitVec(hit3D->getPosition()[0] - pcaCenter(0),
439 hit3D->getPosition()[1] - pcaCenter(1),
440 hit3D->getPosition()[2] - pcaCenter(2));
443 pointList.emplace_back(
dcel2d::Point(pcaToHit(1),pcaToHit(2),hit3D));
447 pointList.sort([](
const auto&
left,
const auto&
right){
return (
std::abs(std::get<0>(
left) - std::get<0>(
right)) > std::numeric_limits<float>::epsilon()) ? std::get<0>(
left) < std::get<0>(
right) : std::get<1>(
left) < std::get<1>(
right);});
450 std::vector<ConvexHull> convexHullVec;
451 std::vector<PointList> rejectedListVec;
452 bool increaseDepth(pointList.size() > 5);
458 convexHullVec.push_back(
ConvexHull(pointList));
461 const ConvexHull& convexHull = convexHullVec.back();
462 PointList& rejectedList = rejectedListVec.back();
465 increaseDepth =
false;
469 std::cout << indent <<
"-> built convex hull, 3D hits: " << pointList.size() <<
" with " << convexHullPoints.size() <<
" vertices" <<
", area: " << convexHull.
getConvexHullArea() <<
std::endl;
470 std::cout << indent <<
"-> -Points:";
471 for(
const auto& point : convexHullPoints)
472 std::cout <<
" (" << std::get<0>(point) <<
"," << std::get<1>(point) <<
")";
477 for(
auto& point : convexHullPoints)
479 pointList.remove(point);
480 rejectedList.emplace_back(point);
489 while(!convexHullVec.empty() && convexHullVec.back().getConvexHullArea() < 0.5)
491 convexHullVec.pop_back();
492 rejectedListVec.pop_back();
496 if (!convexHullVec.empty())
498 size_t nRejectedTotal(0);
501 for(
const auto& rejectedList : rejectedListVec)
503 nRejectedTotal += rejectedList.size();
505 for(
const auto& rejectedPoint : rejectedList)
507 std::cout << indent <<
"-> -- Point is " << convexHullVec.back().findNearestDistance(rejectedPoint) <<
" from nearest edge" <<
std::endl;
509 if (convexHullVec.back().findNearestDistance(rejectedPoint) > 0.5)
510 hitPairListPtr.remove(std::get<2>(rejectedPoint));
514 std::cout << indent <<
"-> Removed " << nRejectedTotal <<
" leaving " << pointList.size() <<
"/" << hitPairListPtr.size() <<
" points" <<
std::endl;
520 Point lastPoint = convexHullVec.back().getConvexHull().front();
522 for(
auto& curPoint : convexHullVec.back().getConvexHull())
524 if (curPoint == lastPoint)
continue;
529 float distBetweenPoints = (curPoint3D->getPosition()[0] - lastPoint3D->
getPosition()[0]) * (curPoint3D->getPosition()[0] - lastPoint3D->
getPosition()[0])
530 + (curPoint3D->getPosition()[1] - lastPoint3D->
getPosition()[1]) * (curPoint3D->getPosition()[1] - lastPoint3D->
getPosition()[1])
531 + (curPoint3D->getPosition()[2] - lastPoint3D->
getPosition()[2]) * (curPoint3D->getPosition()[2] - lastPoint3D->
getPosition()[2]);
533 distBetweenPoints = std::sqrt(distBetweenPoints);
537 edgeMap[lastPoint3D].push_back(edge);
538 edgeMap[curPoint3D].push_back(edge);
539 bestEdgeList.emplace_back(edge);
541 lastPoint = curPoint;
562 Eigen::Vector3f pcaToHitVec(hit3D->getPosition()[0] - pcaCenter(0),
563 hit3D->getPosition()[1] - pcaCenter(1),
564 hit3D->getPosition()[2] - pcaCenter(2));
567 pointList.emplace_back(
dcel2d::Point(pcaToHit(1),pcaToHit(2),hit3D));
571 pointList.sort([](
const auto&
left,
const auto&
right){
return (
std::abs(std::get<0>(
left) - std::get<0>(
right)) > std::numeric_limits<float>::epsilon()) ? std::get<0>(
left) < std::get<0>(
right) : std::get<1>(
left) < std::get<1>(
right);});
587 for(
auto&
vertex : vertexList)
589 Eigen::Vector3f coords = rotationMatrixInv *
vertex.getCoords();
613 dcel2d::Point lastPoint = voronoiDiagram.getConvexHull().front();
618 for(
auto& curPoint : voronoiDiagram.getConvexHull())
620 if (curPoint == lastPoint)
continue;
625 float distBetweenPoints = (curPoint3D->getPosition()[0] - lastPoint3D->
getPosition()[0]) * (curPoint3D->getPosition()[0] - lastPoint3D->
getPosition()[0])
626 + (curPoint3D->getPosition()[1] - lastPoint3D->
getPosition()[1]) * (curPoint3D->getPosition()[1] - lastPoint3D->
getPosition()[1])
627 + (curPoint3D->getPosition()[2] - lastPoint3D->
getPosition()[2]) * (curPoint3D->getPosition()[2] - lastPoint3D->
getPosition()[2]);
629 distBetweenPoints = std::sqrt(distBetweenPoints);
633 edgeMap[lastPoint3D].push_back(edge);
634 edgeMap[curPoint3D].push_back(edge);
635 bestEdgeList.emplace_back(edge);
637 lastPoint = curPoint;
640 std::cout <<
"****> vertexList containted " << vertexList.size() <<
" vertices" <<
std::endl;
647 const Eigen::Vector3f& u0,
648 const Eigen::Vector3f& P1,
649 const Eigen::Vector3f& u1,
650 Eigen::Vector3f& poca0,
651 Eigen::Vector3f& poca1)
const 654 Eigen::Vector3f w0 = P0 - P1;
660 float den(a * c -
b *
b);
662 float arcLen0 = (b *
e - c *
d) / den;
663 float arcLen1 = (a *
e - b *
d) / den;
665 poca0 = P0 + arcLen0 * u0;
666 poca1 = P1 + arcLen1 * u1;
668 return (poca0 - poca1).norm();
void PCAAnalysis_calc3DDocas(const reco::HitPairListPtr &hitPairVector, const reco::PrincipalComponents &pca) const
void PCAAnalysis_3D(const reco::HitPairListPtr &hitPairList, reco::PrincipalComponents &pca, bool skeletonOnly=false) const
void cluster(In first, In last, Out result, Pred *pred)
void flipAxis(size_t axis)
const Eigen::Vector3f getPosition() const
void configure(fhicl::ParameterSet const &pset) override
reco::PrincipalComponents & getSkeletonPCA()
~ClusterPathFinder()
Destructor.
std::unique_ptr< lar_cluster3d::IClusterAlg > m_clusterAlg
Algorithm to do 3D space point clustering.
reco::EdgeList & getBestEdgeList()
float closestApproach(const Eigen::Vector3f &, const Eigen::Vector3f &, const Eigen::Vector3f &, const Eigen::Vector3f &, Eigen::Vector3f &, Eigen::Vector3f &) const
reco::Hit3DToEdgeMap & getHit3DToEdgeMap()
reco::HitPairListPtr & getHitPairListPtr()
Cluster finding and building.
std::pair< MinMaxPoints, MinMaxPoints > MinMaxPointPair
float getTimeToExecute() const override
If monitoring, recover the time to execute a particular function.
IClusterModAlg interface class definiton.
ClusterParametersList & daughterList()
Implements a ConvexHull for use in clustering.
std::list< EdgeTuple > EdgeList
void buildConvexHull(reco::ClusterParameters &clusterParameters, int level=0) const
std::list< Point > PointList
void initializeHistograms(art::TFileDirectory &) override
Interface for initializing histograms if they are desired Note that the idea is to put hisgtograms in...
VoronoiDiagram class definiton.
reco::PrincipalComponents & getFullPCA()
std::tuple< double, double, const reco::ClusterHit3D * > Point
Definitions used by the VoronoiDiagram algorithm.
void buildVoronoiDiagram(const dcel2d::PointList &)
Given an input set of 2D points construct a 2D voronoi diagram.
T get(std::string const &key) const
const Eigen::Vector3f & getAvePosition() const
size_t m_minTinyClusterSize
Minimum size for a "tiny" cluster.
std::tuple< const reco::ClusterHit3D *, const reco::ClusterHit3D *, double > EdgeTuple
std::list< const reco::ClusterHit3D * > HitPairListPtr
void UpdateParameters(const reco::ClusterHit2D *hit)
float getConvexHullArea() const
recover the area of the convex hull
This provides an art tool interface definition for 3D Cluster algorithms.
double distance(double x1, double y1, double z1, double x2, double y2, double z2)
static int max(int a, int b)
const PointList & getConvexHull() const
recover the list of convex hull vertices
reco::ClusterParametersList::iterator breakIntoTinyBits(reco::ClusterParameters &cluster, reco::ClusterParametersList::iterator positionItr, reco::ClusterParametersList &outputClusterList, int level=0) const
Use PCA to try to find path in cluster.
std::pair< Point, Point > MinMaxPoints
ConvexHull class definiton.
bool m_enableMonitoring
Data members to follow.
void buildVoronoiDiagram(reco::ClusterParameters &clusterParameters, int level=0) const
PrincipalComponentsAlg m_pcaAlg
dcel2d::FaceList & getFaceList()
MaybeLogger_< ELseverityLevel::ELsev_success, false > LogDebug
This provides an art tool interface definition for 3D Cluster algorithms.
void ModifyClusters(reco::ClusterParametersList &) const override
Scan an input collection of clusters and modify those according to the specific implementing algorith...
std::list< Point > PointList
std::unordered_map< const reco::ClusterHit3D *, reco::EdgeList > Hit3DToEdgeMap
double accumulated_real_time() const
auto const & get(AssnsNode< L, R, D > const &r)
ClusterPathFinder(const fhicl::ParameterSet &)
Constructor.
dcel2d::HalfEdgeList & getHalfEdgeList()
std::list< Vertex > VertexList
std::list< ClusterParameters > ClusterParametersList
const EigenVectors & getEigenVectors() const
QTextStream & endl(QTextStream &s)
dcel2d::VertexList & getVertexList()