21 #include <unordered_set> 68 double )
const override;
133 if (!clusterParametersList.empty()) {
137 clusterParametersList.sort();
140 while (!clusterParametersList.empty() &&
142 clusterParametersList.pop_back();
186 while (clusterItr != clusterParametersList.end()) {
195 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(
217 PlaneHitCountMapVec uniquePlaneHitCountMapVec(
222 for (
const auto& hit2D : hit3D->getHits()) {
223 if (!hit2D)
continue;
225 size_t hitPlane = hit2D->WireID().Plane;
227 totalPlaneHitCountMapVec[hitPlane][hit2D]++;
231 if (hit2DToClusIter != hit2DToClusterMap.end()) {
232 sharedPlaneHitCountMapVec[hitPlane][hit2D]++;
235 uniquePlaneHitCountMapVec[hitPlane][hit2D]++;
240 std::vector<float> uniqueFractionVec(3, 0.);
242 for (
size_t idx = 0; idx < 3; idx++) {
243 if (!totalPlaneHitCountMapVec[idx].
empty())
244 uniqueFractionVec[idx] = float(uniquePlaneHitCountMapVec[idx].
size()) /
245 float(totalPlaneHitCountMapVec[idx].
size());
248 float overallFraction = uniqueFractionVec[0] * uniqueFractionVec[1] * uniqueFractionVec[2];
249 float maxFraction = *std::max_element(uniqueFractionVec.begin(), uniqueFractionVec.end());
251 if (maxFraction > 0.9 || overallFraction > 0.2) keepThisCluster =
true;
260 std::unordered_set<const reco::ClusterHit2D*> hitSet;
264 for (
const auto& hit2D : hit3D->getHits()) {
265 if (!hit2D)
continue;
267 hit2DToClusterMap[hit2D][&clusterParams].insert(hit3D);
268 hitSet.insert(hit2D);
281 for (
const auto& hit2D : hitSet) {
312 std::set<const reco::ClusterHit2D*> hitSet;
316 std::vector<size_t> planeHit2DVec;
317 std::vector<size_t> planeUniqueHit2DVec;
319 planeHit2DVec.resize(3);
320 planeUniqueHit2DVec.resize(3);
326 for (
const auto& hitMapPair : hit2DToHit3DListMap) {
327 size_t plane = hitMapPair.first->WireID().Plane;
329 planeHit2DVec[plane] += hitMapPair.second.size();
331 planeUniqueHit2DVec[plane] += hitMapPair.second.size();
336 int numUniqueHits(0);
339 std::vector<float> uniqueHitFracVec(3, 0.);
340 int nPlanesWithHits(0);
341 int nPlanesWithUniqueHits(0);
343 size_t minPlaneCnt = planeUniqueHit2DVec[0];
346 for (
int idx = 0; idx < 3; idx++) {
348 numTotalHits += planeHit2DVec[idx];
349 numUniqueHits += planeUniqueHit2DVec[idx];
351 if (planeHit2DVec[idx] > 0) nPlanesWithHits++;
352 if (planeUniqueHit2DVec[idx] > 0) nPlanesWithUniqueHits++;
355 uniqueHitFracVec[idx] =
356 float(planeUniqueHit2DVec[idx]) / std::max(
float(planeHit2DVec[idx]),
float(1.));
359 if (planeHit2DVec[idx] < minPlaneCnt) {
360 minPlaneCnt = planeHit2DVec[idx];
368 if (numUniqueHits > 0.25 * numTotalHits && nPlanesWithHits > 1 && nPlanesWithUniqueHits > 1) {
370 std::sort(uniqueHitFracVec.begin(), uniqueHitFracVec.end());
372 float acceptRatio = 0.;
374 if (uniqueHitFracVec[0] * uniqueHitFracVec[1] > 0.25) acceptRatio = 1.;
376 float uniqueFraction = uniqueHitFracVec[0] * uniqueHitFracVec[1] * uniqueHitFracVec[2];
379 if (uniqueFraction > 0.6 && acceptRatio > 0.) {
387 for (
auto& pair : hit2DToHit3DListMap) {
389 if (pair.second.empty()) {
390 std::cout <<
"<<<<<< no matching 3D hits for reco hit in final hit processing >>>>>>" 396 size_t hitPlane = pair.first->WireID().Plane;
399 if (hitPlane != minPlane && pair.second.size() > 2) {
404 pair.second.sort([](
const auto&
left,
const auto&
right) {
405 return left->getHitChiSquare() <
right->getHitChiSquare();
414 std::min(2.0, std::max(0.5,
double(pair.second.front()->getHitChiSquare())));
423 pair.second.begin(), pair.second.end(), [cutDeltaTSig](
const auto& hitPtr) {
424 return hitPtr->getHitChiSquare() > cutDeltaTSig;
440 std::copy(firstBadHitItr, pair.second.end(), std::back_inserter(rejectCandList));
445 for (
const auto& hit3D : rejectCandList) {
446 bool rejectThisHit(
true);
447 std::vector<std::pair<reco::HitPairListPtr&, reco::HitPairListPtr::iterator>>
450 for (
const auto& hit2D : hit3D->getHits()) {
452 if (!hit2D)
continue;
457 if (removeHitList.size() < 2) {
459 rejectThisHit =
false;
464 std::find(removeHitList.begin(), removeHitList.end(), hit3D);
466 if (removeItr != removeHitList.end())
467 deleteVec.emplace_back(removeHitList, removeItr);
472 for (
auto& rejectPair : deleteVec)
473 rejectPair.first.erase(rejectPair.second);
475 usedHitPairList.push_back(hit3D);
480 hitSet.insert(pair.first);
484 if (!usedHitPairList.empty()) {
488 for (
const auto& hit3D : usedHitPairList) {
489 if (hit3D == lastHit3D)
continue;
492 std::find(hitPairVector.begin(), hitPairVector.end(), hit3D);
494 if (hit3DItr != hitPairVector.end()) {
499 hitPairVector.erase(hit3DItr);
505 edgeMap.erase(edgeMap.find(hit3D));
523 for (
const auto& hit2D : hitSet) {
539 for (
const auto& hit3D : usedHitPairList) {
540 for (
const auto& hit2D : hit3D->getHits()) {
541 if (!hit2D)
continue;
546 if (hitToClusMapItr == hit2DToClusterMap.end()) {
547 std::cout <<
"*********** COULD NOT FIND ENTRY FOR 2D HIT! **************" << std::endl;
554 hitToClusMapItr->second.find(&clusterParams);
557 if (clusToHit3DMapItr == hitToClusMapItr->second.end()) {
558 std::cout <<
"************ DUCK! THE SKY HAS FALLEN!! *********" << std::endl;
563 if (clusToHit3DMapItr->second.size() > 1) {
566 clusToHit3DMapItr->second.erase(hit3DItr);
569 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.
constexpr auto const & right(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
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()
reco::Hit2DToHit3DListMap & getHit2DToHit3DListMap()
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
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
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 *, ClusterToHitPairSetMap > Hit2DToClusterMap
T get(std::string const &key) 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 ...
constexpr auto const & left(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
decltype(auto) get(T &&obj)
ADL-aware version of std::to_string.
ClusterParamsBuilder class definiton.
std::unordered_map< const reco::ClusterHit3D *, reco::EdgeList > Hit3DToEdgeMap
double m_clusterMaxLostFraction
void FillClusterParams(reco::ClusterParameters &, reco::Hit2DToClusterMap &, double, double) const override
Fill the cluster parameters (expose to outside world for case of splitting/merging clusters) ...
std::list< ClusterParameters > ClusterParametersList
decltype(auto) constexpr empty(T &&obj)
ADL-aware version of std::empty.