LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
PmaSegment3D.cxx
Go to the documentation of this file.
1 
11 #include <math.h>
12 
13 #include "Math/GenVector/DisplacementVector2D.h"
17 
19 
21  : SortedObjectBase(vstart, vstop), fParent(trk)
22 {
23  if (vstart->TPC() == vstop->TPC()) fTPC = vstart->TPC();
24  if (vstart->Cryo() == vstop->Cryo()) fCryo = vstart->Cryo();
25 }
26 
27 double pma::Segment3D::GetDistance2To(const TVector3& p3d) const
28 {
29  pma::Node3D* v0 = static_cast<pma::Node3D*>(prev);
30  pma::Node3D* v1 = static_cast<pma::Node3D*>(next);
31  return GetDist2(p3d, v0->Point3D(), v1->Point3D());
32 }
33 
34 double pma::Segment3D::GetDistance2To(const TVector2& p2d, unsigned int view) const
35 {
36  pma::Node3D* v0 = static_cast<pma::Node3D*>(prev);
37  pma::Node3D* v1 = static_cast<pma::Node3D*>(next);
38  return GetDist2(p2d, v0->Projection2D(view), v1->Projection2D(view));
39 }
40 
41 double pma::Segment3D::SumDist2Hits(void) const
42 {
43  pma::Node3D* v0 = static_cast<pma::Node3D*>(prev);
44  pma::Node3D* v1 = static_cast<pma::Node3D*>(next);
45 
46  double sum = 0.0F;
47  for (auto h : fAssignedHits) {
48  if (h->IsEnabled()) {
49  unsigned int view = h->View2D();
50 
51  sum += OptFactor(view) * h->GetSigmaFactor() // alpha_i * (hit_amp / hit_max_amp)
52  * GetDist2(h->Point2D(), v0->Projection2D(view), v1->Projection2D(view));
53  }
54  }
55  return sum;
56 }
57 
59 {
60  pma::Node3D* v0 = static_cast<pma::Node3D*>(prev);
61  pma::Node3D* v1 = static_cast<pma::Node3D*>(next);
62  pma::Vector3D dir(v1->Point3D().X() - v0->Point3D().X(),
63  v1->Point3D().Y() - v0->Point3D().Y(),
64  v1->Point3D().Z() - v0->Point3D().Z());
65  return dir.Unit();
66 }
67 
68 TVector3 pma::Segment3D::GetProjection(const TVector2& p, unsigned int view) const
69 {
70  pma::Node3D* vStart = static_cast<pma::Node3D*>(prev);
71  pma::Node3D* vStop = static_cast<pma::Node3D*>(next);
72 
73  TVector2 v0(p);
74  v0 -= vStart->Projection2D(view);
75 
76  TVector2 v1(vStop->Projection2D(view));
77  v1 -= vStart->Projection2D(view);
78 
79  TVector3 v3d(vStop->Point3D());
80  v3d -= vStart->Point3D();
81 
82  TVector3 v3dStart(vStart->Point3D());
83  TVector3 v3dStop(vStop->Point3D());
84 
85  double v0Norm = v0.Mod();
86  double v1Norm = v1.Mod();
87 
88  TVector3 result(0, 0, 0);
89  if (v1Norm > 1.0E-6) // 0.01mm
90  {
91  double mag = v0Norm * v1Norm;
92  double cosine = 0.0;
93  if (mag != 0.0) cosine = v0 * v1 / mag;
94  double b = v0Norm * cosine / v1Norm;
95 
96  if (b < 1.0) {
97  result = v3dStart;
98  if (b > 0.0) result += (v3d * b);
99  }
100  else
101  result = v3dStop;
102  }
103  else // segment 2D projection is almost a point
104  {
105  mf::LogWarning("pma::Segment3D") << "Short segment projection.";
106 
107  result = v3dStart;
108  result += v3dStop;
109  result *= 0.5;
110  }
111  return result;
112 }
113 
114 TVector3 pma::Segment3D::GetUnconstrainedProj3D(const TVector2& p2d, unsigned int view) const
115 {
116  pma::Node3D* vStart = static_cast<pma::Node3D*>(prev);
117  pma::Node3D* vStop = static_cast<pma::Node3D*>(next);
118 
119  TVector2 v0(p2d);
120  v0 -= vStart->Projection2D(view);
121 
122  TVector2 v1(vStop->Projection2D(view));
123  v1 -= vStart->Projection2D(view);
124 
125  TVector3 v3d(vStop->Point3D());
126  v3d -= vStart->Point3D();
127 
128  double v0Norm = v0.Mod();
129  double v1Norm = v1.Mod();
130  if (v1Norm > 1.0E-6) // 0.01mm
131  {
132  double mag = v0Norm * v1Norm;
133  double cosine = 0.0;
134  if (mag != 0.0) cosine = v0 * v1 / mag;
135  double b = v0Norm * cosine / v1Norm;
136 
137  return vStart->Point3D() + (v3d * b);
138  }
139  else // segment 2D projection is almost a point
140  {
141  v3d = vStart->Point3D();
142  v3d += vStop->Point3D();
143  v3d *= 0.5;
144 
145  return v3d;
146  }
147 }
148 
150 {
151  pma::Node3D* vStart = static_cast<pma::Node3D*>(prev);
152  pma::Node3D* vStop = static_cast<pma::Node3D*>(next);
153 
154  auto const& pointStart = vStart->Point3D();
155  auto const& pointStop = vStop->Point3D();
156 
157  auto const& projStart = vStart->Projection2D(h.View2D());
158  auto const& projStop = vStop->Projection2D(h.View2D());
159 
160  pma::Vector2D v0(h.Point2D().X() - projStart.X(), h.Point2D().Y() - projStart.Y());
161 
162  pma::Vector2D v1(projStop.X() - projStart.X(), projStop.Y() - projStart.Y());
163 
164  pma::Vector3D v3d(
165  pointStop.X() - pointStart.X(), pointStop.Y() - pointStart.Y(), pointStop.Z() - pointStart.Z());
166 
167  double v0Norm = sqrt(v0.Mag2());
168  double v1Norm = sqrt(v1.Mag2());
169  if (v1Norm > 1.0E-6) // 0.01mm
170  {
171  double mag = v0Norm * v1Norm;
172  double cosine = 0.0;
173  if (mag != 0.0) cosine = v0.Dot(v1) / mag;
174  double b = v0Norm * cosine / v1Norm;
175 
176  pma::Vector2D p(projStart.X(), projStart.Y());
177  p += (v1 * b);
178  v3d *= b;
179 
180  h.SetProjection(p.X(), p.Y(), (float)b);
181  h.SetPoint3D(pointStart.X() + v3d.X(), pointStart.Y() + v3d.Y(), pointStart.Z() + v3d.Z());
182  }
183  else // segment 2D projection is almost a point
184  {
185  h.SetProjection(
186  0.5 * (projStart.X() + projStop.X()), 0.5 * (projStart.Y() + projStop.Y()), 0.0F);
187 
188  h.SetPoint3D(0.5 * (pointStart.X() + pointStop.X()),
189  0.5 * (pointStart.Y() + pointStop.Y()),
190  0.5 * (pointStart.Z() + pointStop.Z()));
191  }
192 }
193 
194 double pma::Segment3D::Length2(void) const
195 {
196  if (prev && next)
197  return pma::Dist2(((pma::Node3D*)prev)->Point3D(), ((pma::Node3D*)next)->Point3D());
198  else {
199  mf::LogError("pma::Segment3D") << "Segment endpoints not set.";
200  return 0.0;
201  }
202 }
203 
204 double pma::Segment3D::GetDist2(const TVector3& psrc, const TVector3& p0, const TVector3& p1)
205 {
206  pma::Vector3D v0(psrc.X() - p0.X(), psrc.Y() - p0.Y(), psrc.Z() - p0.Z());
207  pma::Vector3D v1(p1.X() - p0.X(), p1.Y() - p0.Y(), p1.Z() - p0.Z());
208  pma::Vector3D v2(psrc.X() - p1.X(), psrc.Y() - p1.Y(), psrc.Z() - p1.Z());
209 
210  double v1Norm2 = v1.Mag2();
211  if (v1Norm2 >= 1.0E-6) // >= 0.01mm
212  {
213  double v0v1 = v0.Dot(v1);
214  double v2v1 = v2.Dot(v1);
215  double v0Norm2 = v0.Mag2();
216  double v2Norm2 = v2.Mag2();
217 
218  double result = 0.0;
219  if ((v0v1 > 0.0) && (v2v1 < 0.0)) {
220  double cosine01_square = 0.0;
221  double mag01_square = v0Norm2 * v1Norm2;
222  if (mag01_square != 0.0) cosine01_square = v0v1 * v0v1 / mag01_square;
223 
224  result = (1.0 - cosine01_square) * v0Norm2;
225  }
226  else // increase distance to prefer hit assigned to the vertex, not segment
227  {
228  if (v0v1 <= 0.0)
229  result = 1.0001 * v0Norm2;
230  else
231  result = 1.0001 * v2Norm2;
232  }
233 
234  if (result >= 0.0)
235  return result;
236  else
237  return 0.0;
238  }
239  else // short segment or its projection
240  {
241  double dx = 0.5 * (p0.X() + p1.X()) - psrc.X();
242  double dy = 0.5 * (p0.Y() + p1.Y()) - psrc.Y();
243  double dz = 0.5 * (p0.Z() + p1.Z()) - psrc.Z();
244  return dx * dx + dy * dy + dz * dz;
245  }
246 }
247 
248 double pma::Segment3D::GetDist2(const TVector2& psrc, const TVector2& p0, const TVector2& p1)
249 {
250  pma::Vector2D v0(psrc.X() - p0.X(), psrc.Y() - p0.Y());
251  pma::Vector2D v1(p1.X() - p0.X(), p1.Y() - p0.Y());
252  pma::Vector2D v2(psrc.X() - p1.X(), psrc.Y() - p1.Y());
253 
254  double v1Norm2 = v1.Mag2();
255  if (v1Norm2 >= 1.0E-6) // >= 0.01mm
256  {
257  double v0v1 = v0.Dot(v1);
258  double v2v1 = v2.Dot(v1);
259  double v0Norm2 = v0.Mag2();
260  double v2Norm2 = v2.Mag2();
261 
262  double result = 0.0;
263  if ((v0v1 > 0.0) && (v2v1 < 0.0)) {
264  double cosine01_square = 0.0;
265  double mag01_square = v0Norm2 * v1Norm2;
266  if (mag01_square != 0.0) cosine01_square = v0v1 * v0v1 / mag01_square;
267 
268  result = (1.0 - cosine01_square) * v0Norm2;
269  }
270  else // increase distance to prefer hit assigned to the vertex, not segment
271  {
272  if (v0v1 <= 0.0)
273  result = 1.0001 * v0Norm2;
274  else
275  result = 1.0001 * v2Norm2;
276  }
277  if (result >= 0.0)
278  return result;
279  else
280  return 0.0;
281  }
282  else // short segment or its projection
283  {
284  double dx = 0.5 * (p0.X() + p1.X()) - psrc.X();
285  double dy = 0.5 * (p0.Y() + p1.Y()) - psrc.Y();
286  return dx * dx + dy * dy;
287  }
288 }
TVector3 const & Point3D() const
Definition: PmaNode3D.h:44
TVector2 const & Projection2D(unsigned int view) const
Definition: PmaNode3D.h:50
TVector2 const & Point2D() const noexcept
Definition: PmaHit3D.h:55
double Dist2(const TVector2 &v1, const TVector2 &v2)
Definition: Utilities.cxx:39
Implementation of the Projection Matching Algorithm.
pma::SortedObjectBase * prev
Definition: SortedObjects.h:54
::fhicl::TupleAs< Point(::geo::Length_t,::geo::Length_t,::geo::Length_t)> Point3D
Atom object for reading a 3D point or vector (centimeters).
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
double Length2(void) const override
recob::tracking::Vector_t Vector3D
Definition: Utilities.h:34
int TPC(void) const
TPC index or -1 if out of any TPC.
Definition: PmaElement3D.h:35
Float_t E
Definition: plot.C:20
TVector3 GetProjection(const TVector2 &p, unsigned int view) const
Get 3D projection of a 2D point from the view.
Implementation of the Projection Matching Algorithm.
void SetProjection(const TVector2 &p, float b)
Definition: PmaHit3D.h:75
std::vector< pma::Hit3D * > fAssignedHits
Definition: PmaElement3D.h:122
unsigned int View2D() const noexcept
Definition: PmaHit3D.h:60
int Cryo(void) const
Cryostat index or -1 if out of any cryostat.
Definition: PmaElement3D.h:37
Implementation of the Projection Matching Algorithm.
TDirectory * dir
Definition: macro.C:5
pma::Vector3D GetDirection3D(void) const override
Get 3D direction cosines of this segment.
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
void SetPoint3D(const TVector3 &p3d)
Definition: PmaHit3D.h:52
ROOT::Math::DisplacementVector2D< ROOT::Math::Cartesian2D< double > > Vector2D
Definition: Utilities.h:33
pma::SortedObjectBase * next
Definition: SortedObjects.h:53
double GetDistance2To(const TVector3 &p3d) const override
Distance [cm] from the 3D segment to the point 3D.
TVector3 GetUnconstrainedProj3D(const TVector2 &p2d, unsigned int view) const override
double SumDist2Hits(void) const override
Double_t sum
Definition: plot.C:31
void SetProjection(pma::Hit3D &h) const override
Set hit 3D position and its 2D projection to the vertex.
static float OptFactor(unsigned int view)
Definition: PmaElement3D.h:112
static double GetDist2(const TVector3 &psrc, const TVector3 &p0, const TVector3 &p1)