LArSoft  v06_85_00
Liquid Argon Software toolkit - http://larsoft.org/
Utilities.cxx
Go to the documentation of this file.
1 
14 
16 
18 
19 double pma::Dist2(const TVector2 & v1, const TVector2 & v2)
20 {
21  double dx = v1.X() - v2.X(), dy = v1.Y() - v2.Y();
22  return dx * dx + dy * dy;
23 }
24 double pma::Dist2(const Vector2D & v1, const Vector2D & v2)
25 {
26  double dx = v1.X() - v2.X(), dy = v1.Y() - v2.Y();
27  return dx * dx + dy * dy;
28 }
29 
30 double pma::Dist2(const TVector3 & v1, const TVector3 & v2)
31 {
32  double dx = v1.X() - v2.X(), dy = v1.Y() - v2.Y(), dz = v1.Z() - v2.Z();
33  return dx * dx + dy * dy + dz * dz;
34 }
35 double pma::Dist2(const Vector3D & v1, const Vector3D & v2)
36 {
37  double dx = v1.X() - v2.X(), dy = v1.Y() - v2.Y(), dz = v1.Z() - v2.Z();
38  return dx * dx + dy * dy + dz * dz;
39 }
40 
41 size_t pma::GetHitsCount(const std::vector< pma::Hit3D* >& hits, unsigned int view)
42 {
43  size_t n = 0;
44  for (auto const& hit : hits)
45  if ((view == geo::kUnknown) || (view == hit->View2D())) n++;
46  return n;
47 }
48 
49 double pma::GetSummedADC(const std::vector< pma::Hit3D* >& hits, unsigned int view)
50 {
51  double sum = 0.0;
52  for (auto const& hit : hits)
53  if ((view == geo::kUnknown) || (view == hit->View2D()))
54  sum += hit->SummedADC();
55  return sum;
56 }
57 
58 double pma::GetSummedAmpl(const std::vector< pma::Hit3D* >& hits, unsigned int view)
59 {
60  double sum = 0.0;
61  for (auto const& hit : hits)
62  if ((view == geo::kUnknown) || (view == hit->View2D()))
63  sum += hit->GetAmplitude();
64  return sum;
65 }
66 
67 double pma::GetHitsRadius3D(const std::vector< pma::Hit3D* >& hits, bool exact)
68 {
69  if (!exact && (hits.size() < 5)) return 0.0;
70 
71  if (hits.size() == 0) return 0.0;
72 
73  TVector3 mean(0, 0, 0);
74  for (size_t i = 0; i < hits.size(); i++)
75  {
76  mean += hits[i]->Point3D();
77  }
78  mean *= (1.0 / hits.size());
79 
80  double r2, max_r2 = pma::Dist2(hits.front()->Point3D(), mean);
81  for (size_t i = 1; i < hits.size(); i++)
82  {
83  r2 = pma::Dist2(hits[i]->Point3D(), mean);
84  if (r2 > max_r2) max_r2 = r2;
85  }
86  return sqrt(max_r2);
87 }
88 
89 double pma::GetHitsRadius2D(const std::vector< pma::Hit3D* >& hits, bool exact)
90 {
91  if (!exact && (hits.size() < 5)) return 0.0;
92 
93  if (hits.size() == 0) return 0.0;
94 
95  TVector2 mean(0, 0);
96  for (size_t i = 0; i < hits.size(); i++)
97  {
98  mean += hits[i]->Point2D();
99  }
100  mean *= (1.0 / hits.size());
101 
102  double r2, max_r2 = pma::Dist2(hits.front()->Point2D(), mean);
103  for (size_t i = 1; i < hits.size(); i++)
104  {
105  r2 = pma::Dist2(hits[i]->Point2D(), mean);
106  if (r2 > max_r2) max_r2 = r2;
107  }
108  return sqrt(max_r2);
109 }
110 
111 double pma::GetSegmentProjVector(const TVector2& p, const TVector2& p0, const TVector2& p1)
112 {
113  TVector2 v0(p); v0 -= p0;
114  TVector2 v1(p1); v1 -= p0;
115 
116  double v0Norm = v0.Mod();
117  double v1Norm = v1.Mod();
118  double mag = v0Norm * v1Norm;
119  double cosine = 0.0;
120  if (mag != 0.0) cosine = v0 * v1 / mag;
121 
122  return v0Norm * cosine / v1Norm;
123 }
124 
126 {
127  pma::Vector2D v0(p); v0 -= p0;
128  pma::Vector2D v1(p1); v1 -= p0;
129 
130  double v0Norm = v0.R();
131  double v1Norm = v1.R();
132  double mag = v0Norm * v1Norm;
133  double cosine = 0.0;
134  if (mag != 0.0) cosine = v0.Dot(v1) / mag;
135 
136  return v0Norm * cosine / v1Norm;
137 }
138 
139 double pma::GetSegmentProjVector(const TVector3& p, const TVector3& p0, const TVector3& p1)
140 {
141  TVector3 v0(p); v0 -= p0;
142  TVector3 v1(p1); v1 -= p0;
143 
144  double v0Norm = v0.Mag();
145  double v1Norm = v1.Mag();
146  double mag = v0Norm * v1Norm;
147  double cosine = 0.0;
148  if (mag != 0.0) cosine = v0 * v1 / mag;
149 
150  return v0Norm * cosine / v1Norm;
151 }
152 
154 {
155  pma::Vector3D v0(p); v0 -= p0;
156  pma::Vector3D v1(p1); v1 -= p0;
157 
158  double v0Norm = v0.R();
159  double v1Norm = v1.R();
160  double mag = v0Norm * v1Norm;
161  double cosine = 0.0;
162  if (mag != 0.0) cosine = v0.Dot(v1) / mag;
163 
164  return v0Norm * cosine / v1Norm;
165 }
166 
167 TVector2 pma::GetProjectionToSegment(const TVector2& p, const TVector2& p0, const TVector2& p1)
168 {
169  TVector2 v1(p1); v1 -= p0;
170 
171  double b = GetSegmentProjVector(p, p0, p1);
172  TVector2 r(p0);
173  r += (v1 * b);
174  return r;
175 }
176 
177 TVector3 pma::GetProjectionToSegment(const TVector3& p, const TVector3& p0, const TVector3& p1)
178 {
179  TVector3 v1(p1); v1 -= p0;
180 
181  double b = GetSegmentProjVector(p, p0, p1);
182  TVector3 r(p0);
183  r += (v1 * b);
184  return r;
185 }
186 
187 double pma::SolveLeastSquares3D(const std::vector< std::pair<TVector3, TVector3> >& lines, TVector3& result)
188 {
189  // RS: please, ask me if you need examples/explanation of formulas as they
190  // are not easy to derive from the code solely; I have Mathcad sources that
191  // were used to test the solving method, weighting, etc.
192 
193  result.SetXYZ(0., 0., 0.);
194  if (lines.size() < 2)
195  {
196  mf::LogError("pma::SolveLeastSquares3D") << "Need min. two lines.";
197  return -1.0;
198  }
199 
200  double m;
201  std::vector< TVectorT<double> > U, P;
202  for (size_t v = 0; v < lines.size(); v++)
203  {
204  TVector3 point = lines[v].first;
205  TVector3 dir = lines[v].second;
206  dir -= point; m = dir.Mag();
207  if (m > 0.0)
208  {
209  dir *= 1.0 / m;
210 
211  P.push_back(TVectorT<double>(3));
212  P.back()[0] = point.X(); P.back()[1] = point.Y(); P.back()[2] = point.Z();
213 
214  U.push_back(TVectorT<double>(3));
215  U.back()[0] = dir.X(); U.back()[1] = dir.Y(); U.back()[2] = dir.Z();
216  }
217  else mf::LogWarning("pma::SolveLeastSquares3D") << "Line undefined.";
218  }
219  if (P.size() < 2)
220  {
221  mf::LogError("pma::SolveLeastSquares3D") << "Need min. two lines.";
222  return -1.0;
223  }
224 
225  TVectorT<double> x(3), y(3), w(3);
226  TMatrixT<double> A(3, 3);
227  double ur, uc, pc;
228  double s_uc2[3], s_ur_uc[3];
229  double s_p_uc2[3], s_p_ur_uc[3];
230 
231  w[0] = 1.0; w[1] = 1.0; w[2] = 1.0;
232  for (size_t r = 0; r < 3; r++)
233  {
234  y[r] = 0.0;
235  for (size_t c = 0; c < 3; c++)
236  {
237  s_uc2[c] = 0.0; s_ur_uc[c] = 0.0;
238  s_p_uc2[c] = 0.0; s_p_ur_uc[c] = 0.0;
239 
240  for (size_t v = 0; v < P.size(); v++)
241  {
242  //w[1] = fWeights[v]; // to remember that individual coordinates can be supressed...
243  //w[2] = fWeights[v];
244 
245  ur = U[v][r];
246  uc = U[v][c];
247  pc = P[v][c];
248 
249  s_uc2[c] += w[r] * w[c] * (1 - uc * uc);
250  s_p_uc2[c] += w[r] * w[r] * pc * (1 - uc * uc);
251 
252  s_ur_uc[c] += w[r] * w[c] * ur * uc;
253  s_p_ur_uc[c] += w[r] * w[r] * pc * ur * uc;
254  }
255 
256  if (r == c)
257  {
258  y[r] += s_p_uc2[c];
259  A(r, c) = s_uc2[c];
260  }
261  else
262  {
263  y[r] -= s_p_ur_uc[c];
264  A(r, c) = -s_ur_uc[c];
265  }
266  }
267  }
268  try { x = A.InvertFast() * y; }
269  catch (...)
270  {
271  result.SetXYZ(0., 0., 0.); return 1.0e12;
272  }
273 
274  result.SetXYZ(x[0], x[1], x[2]);
275 
276  TVector3 pproj;
277  double dx, dy, dz, mse = 0.0;
278  for (size_t v = 0; v < lines.size(); v++)
279  {
280  pproj = pma::GetProjectionToSegment(result, lines[v].first, lines[v].second);
281 
282  dx = result.X() - pproj.X(); // dx, dy, dz and the result point can be weighted
283  dy = result.Y() - pproj.Y(); // here (linearly) by each line uncertainty
284  dz = result.Z() - pproj.Z();
285 
286  mse += dx * dx + dy * dy + dz * dz;
287  }
288  return mse / lines.size();
289 }
290 
291 TVector2 pma::GetProjectionToPlane(const TVector3& p, unsigned int plane, unsigned int tpc, unsigned int cryo)
292 {
294 
295  return TVector2(geom->TPC(tpc, cryo).Plane(plane).PlaneCoordinate(p), p.X());
296 }
297 
298 TVector2 pma::GetVectorProjectionToPlane(const TVector3& v, unsigned int plane, unsigned int tpc, unsigned int cryo)
299 {
300  TVector3 v0_3d(0., 0., 0.);
301  TVector2 v0_2d = GetProjectionToPlane(v0_3d, plane, tpc, cryo);
302  TVector2 v1_2d = GetProjectionToPlane(v, plane, tpc, cryo);
303 
304  return v1_2d - v0_2d;
305 }
306 
307 TVector2 pma::WireDriftToCm(unsigned int wire, float drift, unsigned int plane, unsigned int tpc, unsigned int cryo)
308 {
310  const detinfo::DetectorProperties* detprop = lar::providerFrom<detinfo::DetectorPropertiesService>();
311 
312  return TVector2(
313  geom->TPC(tpc, cryo).Plane(plane).WirePitch() * wire,
314  detprop->ConvertTicksToX(drift, plane, tpc, cryo)
315  );
316 }
317 
318 TVector2 pma::CmToWireDrift(float xw, float yd, unsigned int plane, unsigned int tpc, unsigned int cryo)
319 {
321  const detinfo::DetectorProperties* detprop = lar::providerFrom<detinfo::DetectorPropertiesService>();
322 
323  return TVector2(
324  xw / geom->TPC(tpc, cryo).Plane(plane).WirePitch(),
325  detprop->ConvertXToTicks(yd, plane, tpc, cryo)
326  );
327 }
328 
330 {
331  if (h1 && h2) return h1->fSegFraction < h2->fSegFraction;
332  else return false;
333 }
334 
336 {
337  if (h1 && h2) return h1->GetDist2ToProj() < h2->GetDist2ToProj();
338  else return false;
339 }
340 
342 {
343  pma::Track3D* trk1 = t1.Track();
344  pma::Track3D* trk2 = t2.Track();
345  if (trk1 && trk2)
346  {
347  double l1 = pma::Dist2(trk1->front()->Point3D(), trk1->back()->Point3D());
348  double l2 = pma::Dist2(trk2->front()->Point3D(), trk2->back()->Point3D());
349  return l1 > l2;
350  }
351  else return false;
352 }
353 
354 pma::bSegmentProjLess::bSegmentProjLess(const TVector3& s0, const TVector3& s1) :
355  segStart(s0), segStop(s1)
356 {
357  if (s0 == s1) mf::LogError("pma::bSegmentProjLess") << "Vectors equal!";
358 }
359 
Float_t x
Definition: compare.C:6
double GetSummedAmpl(const std::vector< pma::Hit3D * > &hits, unsigned int view=geo::kUnknown)
Definition: Utilities.cxx:58
TTree * t1
Definition: plottest35.C:26
double GetHitsRadius2D(const std::vector< pma::Hit3D * > &hits, bool exact=false)
Definition: Utilities.cxx:89
double Dist2(const TVector2 &v1, const TVector2 &v2)
Definition: Utilities.cxx:19
Unknown view.
Definition: geo_types.h:83
Float_t y
Definition: compare.C:6
::fhicl::TupleAs< Point(::geo::Length_t,::geo::Length_t,::geo::Length_t)> Point3D
Atom object for reading a 3D point or vector (centimeters).
float fSegFraction
Definition: PmaHit3D.h:98
bool operator()(pma::Hit3D *h1, pma::Hit3D *h2)
Definition: Utilities.cxx:335
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
double GetHitsRadius3D(const std::vector< pma::Hit3D * > &hits, bool exact=false)
Definition: Utilities.cxx:67
recob::tracking::Vector_t Vector3D
Definition: Utilities.h:29
virtual double ConvertXToTicks(double X, int p, int t, int c) const =0
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:265
bSegmentProjLess(const TVector3 &s0, const TVector3 &s1)
Definition: Utilities.cxx:354
void hits()
Definition: readHits.C:15
size_t GetHitsCount(const std::vector< pma::Hit3D * > &hits, unsigned int view)
Definition: Utilities.cxx:41
TVector2 GetProjectionToSegment(const TVector2 &p, const TVector2 &p0, const TVector2 &p1)
Definition: Utilities.cxx:167
double GetDist2ToProj(void) const
Definition: PmaHit3D.cxx:83
pma::Hit3D *& back()
Definition: PmaTrack3D.h:74
ROOT::Math::DisplacementVector2D< ROOT::Math::Cartesian2D< double > > Vector2D
Definition: Utilities.h:28
TVector2 GetVectorProjectionToPlane(const TVector3 &v, unsigned int plane, unsigned int tpc, unsigned int cryo)
Definition: Utilities.cxx:298
double SolveLeastSquares3D(const std::vector< std::pair< TVector3, TVector3 > > &lines, TVector3 &result)
Definition: Utilities.cxx:187
Detector simulation of raw signals on wires.
TTree * t2
Definition: plottest35.C:36
TH1F * h2
Definition: plot.C:46
Track finding helper for the Projection Matching Algorithm.
virtual double ConvertTicksToX(double ticks, int p, int t, int c) const =0
TVector3 const & Point3D(void) const
Definition: PmaHit3D.h:48
double mean(const std::vector< short > &wf, size_t start, size_t nsample)
Definition: UtilFunc.cxx:15
Implementation of the Projection Matching Algorithm.
bool operator()(pma::Hit3D *h1, pma::Hit3D *h2)
Definition: Utilities.cxx:329
TDirectory * dir
Definition: macro.C:5
double GetSegmentProjVector(const TVector2 &p, const TVector2 &p0, const TVector2 &p1)
Definition: Utilities.cxx:111
TVector2 WireDriftToCm(unsigned int wire, float drift, unsigned int plane, unsigned int tpc, unsigned int cryo)
Definition: Utilities.cxx:307
TVector2 GetProjectionToPlane(const TVector3 &p, unsigned int plane, unsigned int tpc, unsigned int cryo)
Definition: Utilities.cxx:291
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
TH1F * h1
Definition: plot.C:43
TVector2 CmToWireDrift(float xw, float yd, unsigned int plane, unsigned int tpc, unsigned int cryo)
Definition: Utilities.cxx:318
Char_t n[5]
TPCGeo const & TPC(unsigned int const tpc=0, unsigned int const cstat=0) const
Returns the specified TPC.
double GetSummedADC(const std::vector< pma::Hit3D * > &hits, unsigned int view=geo::kUnknown)
Definition: Utilities.cxx:49
PlaneGeo const & Plane(geo::View_t view) const
Return the plane in the tpc with View_t view.
Definition: TPCGeo.cxx:298
Float_t w
Definition: plot.C:23
pma::Hit3D *& front()
Definition: PmaTrack3D.h:72
double PlaneCoordinate(geo::Point_t const &point) const
Returns the coordinate of the point on the plane.
Definition: PlaneGeo.h:704
bool operator()(const pma::TrkCandidate &t1, const pma::TrkCandidate &t2)
Definition: Utilities.cxx:341
double WirePitch() const
Return the wire pitch (in centimeters). It is assumed constant.
Definition: PlaneGeo.h:367
pma::Track3D * Track(void) const