26 fTpcGeo(
art::ServiceHandle<
geo::Geometry>()->TPC(0, 0)),
41 pma::Node3D::Node3D(
const TVector3& p3d,
unsigned int tpc,
unsigned int cryo,
bool vtx,
double xshift) :
48 unsigned int lastPlane =
geo::kZ;
51 auto const *detprop = lar::providerFrom<detinfo::DetectorPropertiesService>();
52 fMinX = detprop->ConvertTicksToX(0, lastPlane, tpc, cryo);
53 fMaxX = detprop->ConvertTicksToX(detprop->NumberTimeSamples() - 1, lastPlane, tpc, cryo);
68 if (d < dmin) dmin =
d;
71 if (d < dmin) dmin =
d;
73 if (d < dmin) dmin =
d;
76 if (d < dmin) dmin =
d;
78 if (d < dmin) dmin =
d;
85 if (((
fMinX - margin) <= p3d.X()) && (p3d.X() <= (
fMaxX + margin)) &&
86 ((
fMinY - margin) <= p3d.Y()) && (p3d.Y() <= (
fMaxY + margin)) &&
87 ((
fMinZ - margin) <= p3d.Z()) && (p3d.Z() <= (
fMaxZ + margin)))
return true;
93 if (((
fMinX - margin) <= p3d.X()) && (p3d.X() <= (
fMaxX + margin)) &&
94 ((
fMinY - margin) <= p3d.Y()) && (p3d.Y() <= (
fMaxY + margin)) &&
95 ((
fMinZ - margin) <= p3d.Z()) && (p3d.Z() <= (
fMaxZ + margin)))
return true;
101 bool trimmed =
false;
150 unsigned int view = h->View2D();
153 h->GetSigmaFactor() *
165 else {
throw cet::exception(
"Node3D") <<
"Isolated vertex." << std::endl; }
168 else {
throw cet::exception(
"Node3D") <<
"Corrupted vertex." << std::endl; }
207 double v0Norm = v0.Mod();
208 double v1Norm = v1.Mod();
209 double mag = v0Norm * v1Norm;
211 if (mag != 0.0) cosine = v0 * v1 / mag;
221 mag = v0Norm * vN.Mod();
222 double cosineN = 0.0;
223 if (mag != 0.0) cosineN = v0 * vN / mag;
234 float b = (float)(v0Norm * cosine / v1Norm);
256 if (
next &&
prev)
return 0.25 * l * l;
268 double mag = sqrt(v1.Mag2() * v2.Mag2());
270 if (mag != 0.0) cosine = v1.Dot(v2) / mag;
275 mf::LogError(
"pma::Node3D") <<
"pma::Node3D::SegmentCos(): neighbours not initialized.";
288 double mag = sqrt(v1.Mag2() * v2.Mag2());
290 if (mag != 0.0) cosine = v1.Dot(v2) / mag;
295 mf::LogError(
"pma::Node3D") <<
"pma::Node3D::SegmentCosZX(): neighbours not initialized.";
308 double mag = sqrt(v1.Mag2() * v2.Mag2());
310 if (mag != 0.0) cosine = v1.Dot(v2) / mag;
315 mf::LogError(
"pma::Node3D") <<
"pma::Node3D::SegmentCosZY(): neighbours not initialized.";
328 double dy = vStop.X() - vStart.X();
329 double dz = vStop.Z() - vStart.Z();
330 double len2 = dy * dy + dz * dz;
331 double cosine2 = 0.0;
332 if (len2 > 0.0) cosine2 = dz * dz / len2;
362 unsigned int nseg = 1;
382 if (nnext > 1)
return true;
401 if ((segPrev->
TPC() < 0) || (segNext->
TPC() < 0))
return true;
408 std::vector< pma::Track3D* > branches;
415 branches.push_back(seg->
Parent());
431 if ((segPrev->
TPC() < 0) || (segNext->
TPC() < 0)) scale = 0.5;
435 double lAsymmFactor = 0.0;
438 double lPrev = segPrev->
Length();
439 double lNext = segNext->
Length();
440 double lSum = lPrev + lNext;
443 double lAsymm = (1.0 - segCos) * (lPrev - lNext) / lSum;
444 lAsymmFactor = 0.05 * lAsymm * lAsymm;
449 else return scale * (1.0 + segCos + lAsymmFactor) *
Length2();
453 double pi_result = 0.0;
454 unsigned int nSeg = 0;
461 if (prevVtx->
Prev()) nSeg++;
473 mf::LogWarning(
"pma::Node3D") <<
"pma::Node3D::Pi(): an isolated vertex?";
476 if (nSeg == 1) pi_result = endSegWeight * seg->
Length2();
483 unsigned int nseg = 1;
484 double penalty =
Pi(endSegWeight,
true);
487 for (
unsigned int i = 0; i <
NextCount(); i++)
490 penalty += v->
Pi(endSegWeight,
false); nseg++;
495 penalty += v->
Pi(endSegWeight,
false); nseg++;
497 return penalty / nseg;
506 for (
unsigned int i = 0; i <
NextCount(); i++)
518 if (!nhits)
return 0.0;
519 else return mse / nhits;
529 double l1 = 0.0, l2 = 0.0, minLength2 = 0.0;
543 if ((l1 > 0.01) && (l1 < l2)) minLength2 = l1;
544 else if ((l2 > 0.01) && (l2 < l1)) minLength2 = l2;
545 else minLength2 = 0.01;
547 double dxi = 0.001 * sqrt(minLength2);
549 if (dxi < 6.0
E-37)
return 0.0;
558 gpoint[0] =
tmp[0] + dxi;
563 gpoint[0] =
tmp[0] - dxi;
573 gpoint[1] =
tmp[1] + dxi;
578 gpoint[1] =
tmp[1] - dxi;
588 gpoint[2] =
tmp[2] + dxi;
594 gpoint[2] =
tmp[2] - dxi;
604 if (
fGradient.Mag2() < 6.0E-37)
return 0.0;
611 unsigned int steps = 0;
612 double t,
t1,
t2, t3, g, g0, g1, g2, g3, p1, p2;
613 double eps = 6.0E-37, zero_tol = 1.0E-15;
617 if (g < zero_tol)
return 0.0;
637 if (g3 < g2)
return (g0 - g3) / g3;
643 if (g3 < zero_tol)
return 0.0;
657 t2 = (t1 * g3 + t3 * g1) / (g1 + g3);
660 t2 = 0.05 * t3 + 0.95 *
t2;
674 if (g2 < g0)
return (g0 - g2) / g2;
678 return (g0 - g1) / g1;
683 return (g0 - g3) / g3;
689 if (g2 < zero_tol)
return 0.0;
696 while (fabs(t1 - t3) > tol)
699 if ((fabs(t2 - t1) < eps) || (fabs(t2 - t3) < eps))
701 if ((fabs(g2 - g1) < eps) && (fabs(g2 - g3) < eps))
704 p1 = (t2 -
t1) * (g2 - g3);
705 p2 = (t2 - t3) * (g2 - g1);
706 if (fabs(p1 - p2) < eps)
break;
708 t = t2 + ((t2 -
t1) * p1 - (t2 - t3) * p2) / (2 * (p2 - p1));
709 if ((t <= t1) || (t >= t3))
710 t = (t1 * g3 + t3 * g1) / (g1 + g3);
718 if ((g < g0) && (g < g1) && (g < g3))
return (g0 - g) / g;
719 else if ((g1 < g0) && (g1 < g3))
722 return (g0 - g1) / g1;
727 return (g0 - g3) / g3;
733 if (g < zero_tol)
return 0.0;
738 if (fabs(t - t2) < 0.2 * tol)
break;
741 if (t < t2) { t3 =
t2; g3 = g2; }
742 else { t1 =
t2; g1 = g2; }
747 if (t < t2) { t1 = t; g1 = g; }
748 else { t3 = t; g3 = g; }
761 if (dg > 0.01) dg =
StepWithGradient(0.03F, 0.0001F, penaltyValue, endSegWeight);
762 if (dg > 0.0) dg =
StepWithGradient(0.03F, 0.0001F, penaltyValue, endSegWeight);
776 std::vector< pma::Track3D* > to_check;
781 if (seg->
Parent() != trk) to_check.push_back(seg->
Parent());
783 for (
unsigned int i = 0; i <
NextCount(); i++)
786 if (seg->
Parent() != trk) to_check.push_back(seg->
Parent());
793 for (
size_t t = 0; t < to_check.size(); t++)
809 for (
size_t t = 0; (t < to_check.size()) && !found; t++)
810 for (
size_t i = 0; i < to_check[t]->size(); i++)
size_t NPrecalcEnabledHits(void) const
bool HasPlane(unsigned int iplane) const
Returns whether a plane with index iplane is present in this TPC.
TVector2 const & Projection2D(unsigned int view) const
double Penalty(float endSegWeight) const
Implementation of the Projection Matching Algorithm.
unsigned int View2D(void) const
double Dist2(const TVector2 &v1, const TVector2 &v2)
TVector3 const & Point3D(void) const
unsigned int Nplanes() const
Number of planes in this tpc.
void ClearAssigned(pma::Track3D *trk=0) override
pma::SortedObjectBase * prev
double GetDistance2To(const TVector3 &p3d) const override
Distance [cm] from the 3D point to the point 3D.
virtual unsigned int NextCount(void) const
void Optimize(float penaltyValue, float endSegWeight)
Planes which measure Z direction.
double SegmentCosWirePlane(void) const
bool LimitPoint3D(void)
Returns true if node position was trimmed to its TPC volume + fMargin.
double GetDistToWall(void) const
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
double Length2(void) const override
double PiInWirePlane(void) const
pma::Vector3D GetDirection3D(void) const override
Get 3D direction cosines of the next segment, or pevious segment if this is the last node...
recob::tracking::Vector_t Vector3D
static bool fGradFixed[3]
double PenaltyInWirePlane(void) const
virtual pma::Vector3D GetDirection3D(void) const =0
Get 3D direction cosines corresponding to this element.
int TPC(void) const
TPC index or -1 if out of any TPC.
virtual unsigned int NextCount(void) const
double EndPtCos2Transverse(void) const
std::vector< TVector3 * > fAssignedPoints
bool SetPoint3D(const TVector3 &p3d)
double MinZ() const
Returns the world z coordinate of the start of the box.
double StepWithGradient(float alfa, float tol, float penalty, float weight)
ROOT::Math::DisplacementVector2D< ROOT::Math::Cartesian2D< double > > Vector2D
std::vector< pma::Hit3D * > fAssignedHits
bool SameTPC(const TVector3 &p3d, float margin=0.0F) const
Check if p3d is in the same TPC as the node.
void SetProjection(const TVector2 &p, float b)
TVector2 const & Point2D(void) const
bool IsBranching(void) const
Belongs to more than one track?
double SumDist2(void) const
Detector simulation of raw signals on wires.
double MaxY() const
Returns the world y coordinate of the end of the box.
std::vector< pma::Track3D * > GetBranches(void) const
double MakeGradient(float penaltyValue, float endSegWeight)
double SumDist2Hits(void) const override
Implementation of the Projection Matching Algorithm.
double SegmentCos(void) const
Cosine of 3D angle between connected segments.
virtual pma::SortedObjectBase * Next(unsigned int index=0) const
Encapsulate the construction of a single detector plane.
double GetObjFunction(float penaltyValue, float endSegWeight) const
Objective function minimized during oprimization.
double MaxZ() const
Returns the world z coordinate of the end of the box.
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
void SetPoint3D(const TVector3 &p3d)
pma::SortedObjectBase * next
geo::TPCGeo const & fTpcGeo
PlaneGeo const & Plane(geo::View_t view) const
Return the plane in the tpc with View_t view.
double Length2(void) const override
virtual pma::SortedObjectBase * Prev(void) const
bool IsTPCEdge(void) const
Is the first/last in this TPC?
Namespace collecting geometry-related classes utilities.
void SetProjection(pma::Hit3D &h) const override
Set hit 3D position and its 2D projection to the vertex.
double MinY() const
Returns the world y coordinate of the start of the box.
pma::Track3D * Parent(void) const
double Pi(float endSegWeight, bool doAsymm) const
virtual pma::SortedObjectBase * Next(unsigned int index=0) const
double PlaneCoordinate(geo::Point_t const &point) const
Returns the coordinate of the point on the plane.
double Length(void) const
cet::coded_exception< error, detail::translate > exception
static float OptFactor(unsigned int view)
Encapsulate the construction of a single detector plane.
double SegmentCosTransverse(void) const