11 #include "fhiclcpp/ParameterSet.h"
22 namespace lar_cluster3d
47 double referenceTicks,
52 firstWire = hitVec.front()->getHits()[planeToCheck]->WireID().Wire;
53 lastWire = hitVec.back()->getHits()[planeToCheck]->WireID().Wire;
55 double maxDeltaTicks = referenceTicks - hitVec.front()->getHits()[planeToCheck]->getTimeTicks();
56 double minDeltaTicks = referenceTicks - hitVec.back()->getHits()[planeToCheck]->getTimeTicks();
58 if (minDeltaTicks > maxDeltaTicks) std::swap(maxDeltaTicks, minDeltaTicks);
60 double bestDeltaTicks = 1000000.;
63 if (hitVec.size() > 1)
70 double nextBestDeltaTicks = bestDeltaTicks;
72 for(
const auto& hitPair : hitVec)
74 int curWire = hitPair->getHits()[planeToCheck]->WireID().Wire;
75 double deltaTicks = referenceTicks - hitPair->getHits()[planeToCheck]->getTimeTicks();
77 maxDeltaTicks = std::max(maxDeltaTicks, deltaTicks);
78 minDeltaTicks = std::min(minDeltaTicks, deltaTicks);
80 if (bestDeltaTicks > fabs(deltaTicks))
83 nextBestDeltaTicks = bestDeltaTicks;
84 bestDeltaTicks = fabs(deltaTicks);
86 else if (nextBestDeltaTicks > fabs(deltaTicks))
88 nextBestDeltaTicks = fabs(deltaTicks);
93 if (fabs(curWire - lastWire) > 2000)
95 if (referenceWire <= lastWire)
break;
99 maxDeltaTicks = deltaTicks;
100 minDeltaTicks = deltaTicks;
101 bestDeltaTicks = fabs(deltaTicks);
102 nextBestDeltaTicks = bestDeltaTicks;
108 bestDeltaTicks = nextBestDeltaTicks;
113 if (minDeltaTicks * maxDeltaTicks > 0. && bestDeltaTicks > 30.) bestDeltaTicks = 0.;
115 return bestDeltaTicks;
125 for(
const auto leftHit : left->
getHits())
127 if (leftHit->WireID().Plane ==
m_plane)
129 for(
const auto rightHit : right->
getHits())
131 if (rightHit->WireID().Plane ==
m_plane)
133 return leftHit->WireID().Wire < rightHit->WireID().Wire;
149 return left.second < right.second;
160 typedef std::map<const reco::ClusterHit2D*, std::vector<const reco::ClusterHit3D*> > Hit2DtoHit3DMapU;
162 Hit2DtoHit3DMapU hit2DToHit3DMap[3];
164 for(
const auto& hitPair : hitPairList)
170 unsigned status = hitPair->getStatusBits();
172 if ((status & 0x7) != 0x7)
continue;
174 for(
const auto& hit2D : hitPair->getHits())
176 size_t plane = hit2D->WireID().Plane;
178 hit2DToHit3DMap[plane][hit2D].push_back(hitPair);
183 for(
size_t idx = 0; idx < 3; idx++)
185 for(
auto& mapPair : hit2DToHit3DMap[idx])
187 size_t numHitPairs = mapPair.second.size();
188 int planeToCheck = (idx + 1) % 3;
190 if (numHitPairs > 1) std::sort(mapPair.second.begin(), mapPair.second.end(),
OrderHitsAlongWire(planeToCheck));
195 int nSkeletonPoints(0);
198 for(
const auto& hitPair : hitPairList)
204 if ((hitPair->getStatusBits() & 0x7) != 7)
continue;
218 size_t numHitPairs[3] = {0, 0, 0};
219 int deltaWires[3] = {0, 0, 0};
220 double planeDeltaT[3] = {0., 0., 0.};
221 double bestDeltaTicks[3] = {0., 0., 0.};
222 int wireNumByPlane[3] = {int(hitPair->getHits()[0]->WireID().Wire),
223 int(hitPair->getHits()[1]->WireID().Wire),
224 int(hitPair->getHits()[2]->WireID().Wire)};
226 size_t bestPlaneIdx(0);
229 for(
size_t planeIdx = 0; planeIdx < 3; planeIdx++)
234 std::vector<const reco::ClusterHit3D*>& hitVec(hit2DToHit3DMap[planeIdx][hit2D]);
236 numHitPairs[planeIdx] = hitVec.size();
238 if (numHitPairs[planeIdx] > 1)
240 int planeToCheck = (planeIdx + 1) % 3;
246 wireNumByPlane[planeToCheck],
251 int deltaFirst = wireNumByPlane[planeToCheck] - firstWire;
252 int deltaLast = wireNumByPlane[planeToCheck] - lastWire;
257 deltaWires[planeIdx] = deltaFirst + deltaLast;
258 numHitPairs[planeIdx] = lastWire - firstWire + 1;
259 planeDeltaT[planeIdx] = fabs(hit2DTimeTicks - hitPair->getHits()[planeToCheck]->getTimeTicks());
264 if (numHitPairs[planeIdx] < numHitPairs[bestPlaneIdx])
266 bestPlaneIdx = planeIdx;
271 if (bestPlaneIdx < 3 && numHitPairs[bestPlaneIdx] > 0)
274 int maxBestWires = 0.05 * numHitPairs[bestPlaneIdx] + 1;
279 if (fabs(deltaWires[bestPlaneIdx]) < maxBestWires + 1)
291 int nextBestIdx = (bestPlaneIdx + 1) % 3;
293 for(
size_t idx = 0; idx < 3; idx++)
295 if (idx == bestPlaneIdx)
continue;
297 if (numHitPairs[idx] < numHitPairs[nextBestIdx]) nextBestIdx = idx;
302 std::cout <<
"***** invalid next best plane: " << nextBestIdx <<
" *******" << std::endl;
306 if (planeDeltaT[bestPlaneIdx] < 1.01*bestDeltaTicks[bestPlaneIdx] && planeDeltaT[nextBestIdx] < 6.01*bestDeltaTicks[nextBestIdx])
316 return nSkeletonPoints;
332 typedef std::map<const reco::ClusterHit2D*, std::vector<const reco::ClusterHit3D*> > Hit2DtoHit3DMap;
335 Hit2DtoHit3DMap hit2DToHit3DMap[3];
338 unsigned int nSkeletonHits(0);
341 for(
const auto& hitPair : skeletonHitList)
349 for(
const auto& hit2D : hitPair->getHits())
351 size_t plane = hit2D->WireID().Plane;
353 hit2DToHit3DMap[plane][hit2D].push_back(hitPair);
358 if (!nSkeletonHits)
return;
362 for(
size_t idx = 0; idx < 3; idx++)
364 for(
auto& mapPair : hit2DToHit3DMap[idx])
366 size_t numHitPairs = mapPair.second.size();
367 int planeToCheck = (idx + 1) % 3;
369 if (numHitPairs > 1) std::sort(mapPair.second.begin(), mapPair.second.end(),
OrderHitsAlongWire(planeToCheck));
380 reco::HitPairListPtr::iterator hitPairItr = skeletonHitList.begin();
382 for(
int bestPlaneVecIdx = 0; bestPlaneVecIdx < 2; bestPlaneVecIdx++)
384 std::list<reco::ClusterHit3D> tempHitPairList;
387 std::map<const reco::ClusterHit3D*, const reco::ClusterHit3D*> hit3DToHit3DMap;
389 while(hitPairItr != skeletonHitList.end())
393 std::vector<std::pair<size_t,size_t> > bestPlaneVec;
395 for(
const auto& hit2D : hit3D->
getHits())
397 bestPlaneVec.push_back(std::pair<size_t,size_t>(hit2D->WireID().Plane,hit2DToHit3DMap[hit2D->WireID().Plane][hit2D].size()));
400 std::sort(bestPlaneVec.begin(), bestPlaneVec.end(),
OrderBestPlanes());
402 size_t bestPlaneIdx = bestPlaneVec[bestPlaneVecIdx].first;
403 size_t bestPlaneCnt = bestPlaneVec[bestPlaneVecIdx].second;
405 if (bestPlaneCnt > 5)
continue;
407 std::vector<const reco::ClusterHit3D*>& hit3DVec = hit2DToHit3DMap[bestPlaneIdx][hit3D->
getHits()[bestPlaneIdx]];
409 Eigen::Vector3f avePosition(hit3D->
getPosition()[0],0.,0.);
411 for(
const auto& tempHit3D : hit3DVec)
413 avePosition[1] += tempHit3D->getPosition()[1];
414 avePosition[2] += tempHit3D->getPosition()[2];
417 avePosition[1] *= 1./double(hit3DVec.size());
418 avePosition[2] *= 1./double(hit3DVec.size());
436 tempHitPairListPtr.push_back(&tempHitPairList.back());
438 hit3DToHit3DMap[tempHitPairListPtr.back()] = hit3D;
441 for(
const auto& pair : hit3DToHit3DMap)
443 pair.second->
setPosition(pair.first->getPosition());
float getTimeTicks() const
const Eigen::Vector3f getPosition() const
Hit is an "edge" hit.
const std::vector< float > getHitDelTSigVec() const
float getTotalCharge() const
Hit has been rejected for any reason.
float getSigmaPeakTime() const
float getOverlapFraction() const
unsigned int getStatusBits() const
void GetSkeletonHits(const reco::HitPairListPtr &inputHitList, reco::HitPairListPtr &skeletonHitList) const
Return the skeleton hits from the input list.
float getDocaToAxis() const
SkeletonAlg(fhicl::ParameterSet const &pset)
Constructor.
void reconfigure(fhicl::ParameterSet const &pset)
a handler for the case where the algorithm control parameters are to be reset
OrderHitsAlongWire(int plane=0)
float getAvePeakTime() const
float getChargeAsymmetry() const
int FindMedialSkeleton(reco::HitPairListPtr &hitPairList) const
This is intended to find the medial skeleton given a list of input hit pairs.
double m_minimumDeltaTicks
void AverageSkeletonPositions(reco::HitPairListPtr &skeletonHitList) const
Modifies the position of input skeleton hits by averaging along the "best" wire direction.
std::list< const reco::ClusterHit3D * > HitPairListPtr
bool operator()(const reco::ClusterHit3D *left, const reco::ClusterHit3D *right)
Definition of data types for geometry description.
double m_maximumDeltaTicks
double FindFirstAndLastWires(std::vector< const reco::ClusterHit3D * > &hitVec, int planeToCheck, int referenceWire, double referenceTicks, int &firstWire, int &lastWire) const
A function to find the bounding wires in a given view.
bool operator()(const std::pair< size_t, size_t > &left, const std::pair< size_t, size_t > &right)
Header file to define the interface to the SkeletonAlg.
~SkeletonAlg()
Destructor.
const std::vector< geo::WireID > & getWireIDs() const
float getArclenToPoca() const
float getDeltaPeakTime() const
Skeleton hit position averaged.
float getHitChiSquare() const
Hit is a "skeleton" hit.
const ClusterHit2DVec & getHits() const
void setPosition(const Eigen::Vector3f &pos) const
BEGIN_PROLOG could also be cout