LArSoft  v07_13_02
Liquid Argon Software toolkit - http://larsoft.org/
PmaSegment3D.cxx
Go to the documentation of this file.
1 
13 
15 
17  SortedObjectBase(vstart, vstop),
18  fParent(trk)
19 {
20  if (vstart->TPC() == vstop->TPC()) fTPC = vstart->TPC();
21  if (vstart->Cryo() == vstop->Cryo()) fCryo = vstart->Cryo();
22 }
23 
24 double pma::Segment3D::GetDistance2To(const TVector3& p3d) const
25 {
26  pma::Node3D* v0 = static_cast< pma::Node3D* >(prev);
27  pma::Node3D* v1 = static_cast< pma::Node3D* >(next);
28  return GetDist2(p3d, v0->Point3D(), v1->Point3D());
29 }
30 
31 double pma::Segment3D::GetDistance2To(const TVector2& p2d, unsigned int view) const
32 {
33  pma::Node3D* v0 = static_cast< pma::Node3D* >(prev);
34  pma::Node3D* v1 = static_cast< pma::Node3D* >(next);
35  return GetDist2(p2d, v0->Projection2D(view), v1->Projection2D(view));
36 }
37 
38 double pma::Segment3D::SumDist2Hits(void) const
39 {
40  pma::Node3D* v0 = static_cast< pma::Node3D* >(prev);
41  pma::Node3D* v1 = static_cast< pma::Node3D* >(next);
42 
43  double sum = 0.0F;
44  for (auto h : fAssignedHits)
45  {
46  if (h->IsEnabled())
47  {
48  unsigned int view = h->View2D();
49 
50  sum += OptFactor(view) * h->GetSigmaFactor() // alpha_i * (hit_amp / hit_max_amp)
51  * GetDist2(h->Point2D(), v0->Projection2D(view), v1->Projection2D(view));
52  }
53  }
54  return sum;
55 }
56 
58 {
59  pma::Node3D* v0 = static_cast< pma::Node3D* >(prev);
60  pma::Node3D* v1 = static_cast< pma::Node3D* >(next);
62  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  {
98  result = v3dStart;
99  if (b > 0.0) result += (v3d * b);
100  }
101  else 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(
161  h.Point2D().X() - projStart.X(),
162  h.Point2D().Y() - projStart.Y());
163 
164  pma::Vector2D v1(
165  projStop.X() - projStart.X(),
166  projStop.Y() - projStart.Y());
167 
168  pma::Vector3D v3d(
169  pointStop.X() - pointStart.X(),
170  pointStop.Y() - pointStart.Y(),
171  pointStop.Z() - pointStart.Z());
172 
173  double v0Norm = sqrt(v0.Mag2());
174  double v1Norm = sqrt(v1.Mag2());
175  if (v1Norm > 1.0E-6) // 0.01mm
176  {
177  double mag = v0Norm * v1Norm;
178  double cosine = 0.0;
179  if (mag != 0.0) cosine = v0.Dot(v1) / mag;
180  double b = v0Norm * cosine / v1Norm;
181 
182  pma::Vector2D p(projStart.X(), projStart.Y());
183  p += (v1 * b);
184  v3d *= b;
185 
186  h.SetProjection(p.X(), p.Y(), (float)b);
187  h.SetPoint3D(
188  pointStart.X() + v3d.X(),
189  pointStart.Y() + v3d.Y(),
190  pointStart.Z() + v3d.Z());
191  }
192  else // segment 2D projection is almost a point
193  {
194  h.SetProjection(
195  0.5 * (projStart.X() + projStop.X()),
196  0.5 * (projStart.Y() + projStop.Y()), 0.0F);
197 
198  h.SetPoint3D(
199  0.5 * (pointStart.X() + pointStop.X()),
200  0.5 * (pointStart.Y() + pointStop.Y()),
201  0.5 * (pointStart.Z() + pointStop.Z()));
202  }
203 }
204 
205 double pma::Segment3D::Length2(void) const
206 {
207  if (prev && next)
208  return pma::Dist2( ((pma::Node3D*)prev)->Point3D(), ((pma::Node3D*)next)->Point3D() );
209  else
210  {
211  mf::LogError("pma::Segment3D") << "Segment endpoints not set.";
212  return 0.0;
213  }
214 }
215 
216 
217 double pma::Segment3D::GetDist2(const TVector3& psrc, const TVector3& p0, const TVector3& p1)
218 {
219  pma::Vector3D v0(psrc.X() - p0.X(), psrc.Y() - p0.Y(), psrc.Z() - p0.Z());
220  pma::Vector3D v1(p1.X() - p0.X(), p1.Y() - p0.Y(), p1.Z() - p0.Z());
221  pma::Vector3D v2(psrc.X() - p1.X(), psrc.Y() - p1.Y(), psrc.Z() - p1.Z());
222 
223  double v1Norm2 = v1.Mag2();
224  if (v1Norm2 >= 1.0E-6) // >= 0.01mm
225  {
226  double v0v1 = v0.Dot(v1);
227  double v2v1 = v2.Dot(v1);
228  double v0Norm2 = v0.Mag2();
229  double v2Norm2 = v2.Mag2();
230 
231  double result = 0.0;
232  if ((v0v1 > 0.0) && (v2v1 < 0.0))
233  {
234  double cosine01_square = 0.0;
235  double mag01_square = v0Norm2 * v1Norm2;
236  if (mag01_square != 0.0) cosine01_square = v0v1 * v0v1 / mag01_square;
237 
238  result = (1.0 - cosine01_square) * v0Norm2;
239  }
240  else // increase distance to prefer hit assigned to the vertex, not segment
241  {
242  if (v0v1 <= 0.0) result = 1.0001 * v0Norm2;
243  else result = 1.0001 * v2Norm2;
244  }
245 
246  if (result >= 0.0) return result;
247  else return 0.0;
248  }
249  else // short segment or its projection
250  {
251  double dx = 0.5 * (p0.X() + p1.X()) - psrc.X();
252  double dy = 0.5 * (p0.Y() + p1.Y()) - psrc.Y();
253  double dz = 0.5 * (p0.Z() + p1.Z()) - psrc.Z();
254  return dx * dx + dy * dy + dz * dz;
255  }
256 }
257 
258 double pma::Segment3D::GetDist2(const TVector2& psrc, const TVector2& p0, const TVector2& p1)
259 {
260  pma::Vector2D v0(psrc.X() - p0.X(), psrc.Y() - p0.Y());
261  pma::Vector2D v1(p1.X() - p0.X(), p1.Y() - p0.Y());
262  pma::Vector2D v2(psrc.X() - p1.X(), psrc.Y() - p1.Y());
263 
264  double v1Norm2 = v1.Mag2();
265  if (v1Norm2 >= 1.0E-6) // >= 0.01mm
266  {
267  double v0v1 = v0.Dot(v1);
268  double v2v1 = v2.Dot(v1);
269  double v0Norm2 = v0.Mag2();
270  double v2Norm2 = v2.Mag2();
271 
272  double result = 0.0;
273  if ((v0v1 > 0.0) && (v2v1 < 0.0))
274  {
275  double cosine01_square = 0.0;
276  double mag01_square = v0Norm2 * v1Norm2;
277  if (mag01_square != 0.0) cosine01_square = v0v1 * v0v1 / mag01_square;
278 
279  result = (1.0 - cosine01_square) * v0Norm2;
280  }
281  else // increase distance to prefer hit assigned to the vertex, not segment
282  {
283  if (v0v1 <= 0.0) result = 1.0001 * v0Norm2;
284  else result = 1.0001 * v2Norm2;
285  }
286  if (result >= 0.0) return result;
287  else return 0.0;
288  }
289  else // short segment or its projection
290  {
291  double dx = 0.5 * (p0.X() + p1.X()) - psrc.X();
292  double dy = 0.5 * (p0.Y() + p1.Y()) - psrc.Y();
293  return dx * dx + dy * dy;
294  }
295 }
296 
TVector2 const & Projection2D(unsigned int view) const
Definition: PmaNode3D.h:39
Float_t E
Definition: plot.C:23
unsigned int View2D(void) const
Definition: PmaHit3D.h:58
double Dist2(const TVector2 &v1, const TVector2 &v2)
Definition: Utilities.cxx:19
TVector3 const & Point3D(void) const
Definition: PmaNode3D.h:33
Implementation of the Projection Matching Algorithm.
::fhicl::TupleAs< Point(::geo::Length_t,::geo::Length_t,::geo::Length_t)> Point3D
Atom object for reading a 3D point or vector (centimeters).
pma::SortedObjectBase * prev
Definition: SortedObjects.h:54
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
double Length2(void) const override
recob::tracking::Vector_t Vector3D
Definition: Utilities.h:29
int TPC(void) const
TPC index or -1 if out of any TPC.
Definition: PmaElement3D.h:31
TVector3 GetProjection(const TVector2 &p, unsigned int view) const
Get 3D projection of a 2D point from the view.
ROOT::Math::DisplacementVector2D< ROOT::Math::Cartesian2D< double > > Vector2D
Definition: Utilities.h:28
std::vector< pma::Hit3D * > fAssignedHits
Definition: PmaElement3D.h:113
void SetProjection(const TVector2 &p, float b)
Definition: PmaHit3D.h:73
TVector2 const & Point2D(void) const
Definition: PmaHit3D.h:53
int Cryo(void) const
Cryostat index or -1 if out of any cryostat.
Definition: PmaElement3D.h:33
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:50
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
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:103
static double GetDist2(const TVector3 &psrc, const TVector3 &p0, const TVector3 &p1)