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