9 #include "art/Utilities/ToolMacros.h"
10 #include "fhiclcpp/ParameterSet.h"
22 namespace lar_cluster3d {
42 void configure(
const fhicl::ParameterSet&)
override;
67 double minUniqueFrac = 0.,
68 double maxLostFrac=1.)
const override;
100 m_pcaAlg(pset.
get<fhicl::ParameterSet>(
"PrincipalComponentsAlg"))
134 if (!clusterParametersList.empty())
139 clusterParametersList.sort();
142 while(!clusterParametersList.empty() && clusterParametersList.back().getHitPairListPtr().size() <
m_clusterMinHits) clusterParametersList.pop_back();
148 reco::ClusterParametersList::iterator clusterItr = clusterParametersList.begin();
186 while(clusterItr != clusterParametersList.end())
196 else clusterItr = clusterParametersList.erase(clusterItr);
211 using HitCountMap = std::unordered_map<const reco::ClusterHit2D*,int>;
212 using PlaneHitCountMapVec = std::vector<HitCountMap>;
214 PlaneHitCountMapVec totalPlaneHitCountMapVec(3);
215 PlaneHitCountMapVec sharedPlaneHitCountMapVec(3);
216 PlaneHitCountMapVec uniquePlaneHitCountMapVec(3);
221 for(
const auto& hit2D : hit3D->getHits())
223 if (!hit2D)
continue;
225 size_t hitPlane = hit2D->WireID().Plane;
227 totalPlaneHitCountMapVec[hitPlane][hit2D]++;
229 reco::Hit2DToClusterMap::const_iterator hit2DToClusIter = hit2DToClusterMap.find(hit2D);
231 if (hit2DToClusIter != hit2DToClusterMap.end())
233 sharedPlaneHitCountMapVec[hitPlane][hit2D]++;
235 else uniquePlaneHitCountMapVec[hitPlane][hit2D]++;
240 std::vector<float> uniqueFractionVec(3,0.);
242 for(
size_t idx = 0; idx < 3; idx++)
244 if (!totalPlaneHitCountMapVec[idx].
empty()) uniqueFractionVec[idx] = float(uniquePlaneHitCountMapVec[idx].
size()) / float(totalPlaneHitCountMapVec[idx].
size());
247 float overallFraction = uniqueFractionVec[0] * uniqueFractionVec[1] * uniqueFractionVec[2];
248 float maxFraction = *std::max_element(uniqueFractionVec.begin(),uniqueFractionVec.end());
250 if (maxFraction > 0.9 || overallFraction > 0.2) keepThisCluster =
true;
258 std::unordered_set<const reco::ClusterHit2D*> hitSet;
263 for(
const auto& hit2D : hit3D->getHits())
265 if (!hit2D)
continue;
267 hit2DToClusterMap[hit2D][&clusterParams].insert(hit3D);
268 hitSet.insert(hit2D);
282 for(
const auto& hit2D : hitSet)
294 double minUniqueFrac,
295 double maxLostFrac)
const
314 std::set<const reco::ClusterHit2D*> hitSet;
318 std::vector<size_t> planeHit2DVec;
319 std::vector<size_t> planeUniqueHit2DVec;
321 planeHit2DVec.resize(3);
322 planeUniqueHit2DVec.resize(3);
328 for(
const auto& hitMapPair : hit2DToHit3DListMap)
330 size_t plane = hitMapPair.first->WireID().Plane;
332 planeHit2DVec[plane] += hitMapPair.second.size();
333 if (!(hitMapPair.first->getStatusBits() &
reco::ClusterHit2D::USED)) planeUniqueHit2DVec[plane] += hitMapPair.second.size();
338 int numUniqueHits(0);
341 std::vector<float> uniqueHitFracVec(3,0.);
342 int nPlanesWithHits(0);
343 int nPlanesWithUniqueHits(0);
345 size_t minPlaneCnt = planeUniqueHit2DVec[0];
348 for(
int idx = 0; idx < 3; idx++)
351 numTotalHits += planeHit2DVec[idx];
352 numUniqueHits += planeUniqueHit2DVec[idx];
354 if (planeHit2DVec[idx] > 0) nPlanesWithHits++;
355 if (planeUniqueHit2DVec[idx] > 0) nPlanesWithUniqueHits++;
358 uniqueHitFracVec[idx] = float(planeUniqueHit2DVec[idx]) / std::max(
float(planeHit2DVec[idx]),
float(1.));
361 if (planeHit2DVec[idx] < minPlaneCnt)
363 minPlaneCnt = planeHit2DVec[idx];
371 if (numUniqueHits > 0.25 * numTotalHits && nPlanesWithHits > 1 && nPlanesWithUniqueHits > 1)
374 std::sort(uniqueHitFracVec.begin(),uniqueHitFracVec.end());
376 float acceptRatio = 0.;
378 if(uniqueHitFracVec[0] * uniqueHitFracVec[1] > 0.25) acceptRatio = 1.;
380 float uniqueFraction = uniqueHitFracVec[0] * uniqueHitFracVec[1] * uniqueHitFracVec[2];
383 if (uniqueFraction > 0.6 && acceptRatio > 0.)
392 for(
auto& pair : hit2DToHit3DListMap)
395 if (pair.second.empty())
397 std::cout <<
"<<<<<< no matching 3D hits for reco hit in final hit processing >>>>>>" << std::endl;
402 size_t hitPlane = pair.first->WireID().Plane;
405 if (hitPlane != minPlane && pair.second.size() > 2)
411 pair.second.sort([](
const auto&
left,
const auto&
right){
return left->getHitChiSquare() <
right->getHitChiSquare();});
418 float cutDeltaTSig = std::min(2.0,std::max(0.5,
double(pair.second.front()->getHitChiSquare())));
426 reco::HitPairListPtr::iterator firstBadHitItr = std::find_if(pair.second.begin(),pair.second.end(),[cutDeltaTSig](
const auto& hitPtr){
return hitPtr->getHitChiSquare() > cutDeltaTSig;});
441 std::copy(firstBadHitItr,pair.second.end(),std::back_inserter(rejectCandList));
446 for(
const auto& hit3D : rejectCandList)
448 bool rejectThisHit(
true);
449 std::vector<std::pair<reco::HitPairListPtr&,reco::HitPairListPtr::iterator>> deleteVec;
451 for(
const auto& hit2D : hit3D->getHits())
454 if (!hit2D)
continue;
459 if (removeHitList.size() < 2)
462 rejectThisHit =
false;
466 reco::HitPairListPtr::iterator removeItr = std::find(removeHitList.begin(),removeHitList.end(),hit3D);
468 if (removeItr != removeHitList.end()) deleteVec.emplace_back(removeHitList,removeItr);
474 for(
auto& rejectPair : deleteVec) rejectPair.first.erase(rejectPair.second);
476 usedHitPairList.push_back(hit3D);
481 hitSet.insert(pair.first);
485 if (!usedHitPairList.empty())
490 for(
const auto& hit3D : usedHitPairList)
492 if (hit3D == lastHit3D)
continue;
494 reco::HitPairListPtr::iterator hit3DItr = std::find(hitPairVector.begin(),hitPairVector.end(),hit3D);
496 if (hit3DItr != hitPairVector.end())
502 hitPairVector.erase(hit3DItr);
509 edgeMap.erase(edgeMap.find(hit3D));
528 for(
const auto& hit2D : hitSet)
545 for(
const auto& hit3D : usedHitPairList)
547 for(
const auto& hit2D : hit3D->getHits())
549 if (!hit2D)
continue;
551 reco::Hit2DToClusterMap::iterator hitToClusMapItr = hit2DToClusterMap.find(hit2D);
554 if (hitToClusMapItr == hit2DToClusterMap.end())
556 std::cout <<
"*********** COULD NOT FIND ENTRY FOR 2D HIT! **************" << std::endl;
562 reco::ClusterToHitPairSetMap::iterator clusToHit3DMapItr = hitToClusMapItr->second.find(&clusterParams);
565 if (clusToHit3DMapItr == hitToClusMapItr->second.end())
567 std::cout <<
"************ DUCK! THE SKY HAS FALLEN!! *********" << std::endl;
572 if (clusToHit3DMapItr->second.size() > 1)
574 reco::HitPairSetPtr::iterator hit3DItr = clusToHit3DMapItr->second.find(hit3D);
576 clusToHit3DMapItr->second.erase(hit3DItr);
579 hitToClusMapItr->second.erase(clusToHit3DMapItr);
bool keepThisCluster(reco::ClusterParameters &, const reco::Hit2DToClusterMap &) const
Is a cluster "good" and worth keeping?
void configure(const fhicl::ParameterSet &) override
ClusterParamsBuilder(fhicl::ParameterSet const &pset)
Constructor.
virtual ~ClusterParamsBuilder()
Destructor.
void PCAAnalysis_3D(const reco::HitPairListPtr &hitPairList, reco::PrincipalComponents &pca, bool skeletonOnly=false) const
void BuildClusterInfo(reco::ClusterParametersList &clusterParametersList) const override
Given the results of running DBScan, format the clusters so that they can be easily transferred back ...
PrincipalComponentsAlg m_pcaAlg
reco::PrincipalComponents & getSkeletonPCA()
void FillClusterParams(reco::ClusterParameters &, reco::Hit2DToClusterMap &, double minUniqueFrac=0., double maxLostFrac=1.) const override
Fill the cluster parameters (expose to outside world for case of splitting/merging clusters) ...
reco::Hit2DToHit3DListMap & getHit2DToHit3DListMap()
std::size_t size(FixedBins< T, C > const &) noexcept
Hit has been rejected for any reason.
reco::Hit3DToEdgeMap & getHit3DToEdgeMap()
reco::HitPairListPtr & getHitPairListPtr()
reco::PlaneToClusterParamsMap & getClusterParams()
void removeUsedHitsFromMap(reco::ClusterParameters &, reco::HitPairListPtr &, reco::Hit2DToClusterMap &) const
size_t m_clusterMinHits
Data members to follow.
reco::PrincipalComponents & getFullPCA()
ClusterParamsBuilder class definiton.
void storeThisCluster(reco::ClusterParameters &, reco::Hit2DToClusterMap &) const
std::unordered_map< const reco::ClusterHit2D *, reco::HitPairListPtr > Hit2DToHit3DListMap
double m_clusterMinUniqueFraction
std::list< const reco::ClusterHit3D * > HitPairListPtr
void UpdateParameters(const reco::ClusterHit2D *hit)
Definition of data types for geometry description.
This header file defines the interface to a principal components analysis designed to be used within ...
std::unordered_map< const reco::ClusterHit2D *, ClusterToHitPairSetMap > Hit2DToClusterMap
ClusterParamsBuilder class definiton.
std::unordered_map< const reco::ClusterHit3D *, reco::EdgeList > Hit3DToEdgeMap
double m_clusterMaxLostFraction
bool empty(FixedBins< T, C > const &) noexcept
BEGIN_PROLOG could also be cout
std::list< ClusterParameters > ClusterParametersList
void setStatusBit(unsigned bits) const