PmaVtxCandidate.cxx
Go to the documentation of this file.
1 /**
2  * @file PmaVtxCandidate.cxx
3  *
4  * @author D.Stefan and R.Sulej
5  *
6  * @brief Vertex finding helper for the Projection Matching Algorithm
7  *
8  * Candidate for 3D vertex. Used to test intersections and join tracks in vertices.
9  * See PmaTrack3D.h file for details.
10  */
11 
18 
20 
22 
23 #include "TMath.h"
24 
25 bool
27 {
28  for (const auto& t : fAssigned)
29  if (trk == t.first.Track()) return true;
30  return false;
31 }
32 
33 bool
35 {
36  for (const auto& t : other.fAssigned)
37  if (!Has(t.first.Track())) return false;
38  return true;
39 }
40 
41 bool
43 {
44  pma::Track3D const* rootTrk = trk->GetRoot();
45  if (!rootTrk) throw cet::exception("pma::VtxCandidate") << "Broken track.";
46 
47  for (const auto& t : fAssigned) {
48  pma::Track3D const* rootAssn = t.first.Track()->GetRoot();
49  if (!rootAssn) throw cet::exception("pma::VtxCandidate") << "Broken track.";
50 
51  if (rootTrk->IsAttachedTo(rootAssn)) return true;
52  }
53  return false;
54 }
55 
56 bool
58 {
59  for (const auto& t : other.fAssigned)
60  if (IsAttached(t.first.Track())) return true;
61  return false;
62 }
63 
64 bool
66 {
67  for (size_t t = 0; t < fAssigned.size(); t++) {
68  pma::Track3D const* trk_t = fAssigned[t].first.Track()->GetRoot();
69  if (!trk_t) throw cet::exception("pma::VtxCandidate") << "Broken track.";
70 
71  for (size_t u = 0; u < fAssigned.size(); u++)
72  if (t != u) {
73  pma::Track3D const* trk_u = fAssigned[u].first.Track()->GetRoot();
74  if (!trk_u) throw cet::exception("pma::VtxCandidate") << "Broken track.";
75 
76  if (trk_t->IsAttachedTo(trk_u)) return true;
77  }
78  }
79  return false;
80 }
81 
82 size_t
83 pma::VtxCandidate::Size(double minLength) const
84 {
85  size_t n = 0;
86  for (auto const& c : fAssigned)
87  if (c.first.Track()->Length() > minLength) n++;
88  return n;
89 }
90 
91 bool
93 {
94  if (IsAttached(trk.Track())) return false;
95 
96  fAssigned.emplace_back(trk, 0);
97 
98  double d, d_best;
99  double mse, min_mse = kMaxDistToTrack * kMaxDistToTrack;
100  if (fAssigned.size() > 2) {
101  size_t n_best = 0;
102  d_best = kMaxDistToTrack;
103  for (size_t n = 0; n < trk.Track()->Nodes().size() - 1; n++) {
104  pma::Segment3D* seg = trk.Track()->NextSegment(trk.Track()->Nodes()[n]);
105  if (seg->Length() < fSegMinLength) continue;
106 
107  fAssigned.back().second = n;
108 
109  mse = Compute();
110  if (mse < min_mse) {
111  d = sqrt(seg->GetDistance2To(fCenter));
112  if (d < d_best) {
113  min_mse = mse;
114  n_best = n;
115  d_best = d;
116  }
117  }
118  }
119 
120  if (d_best < kMaxDistToTrack) {
121  fAssigned.back().second = n_best;
122  fMse = Compute();
123  fMse2D = ComputeMse2D();
124  return true;
125  }
126  else {
127  fAssigned.pop_back();
128  fMse = Compute();
129  fMse2D = ComputeMse2D();
130  return false;
131  }
132  }
133  else if (fAssigned.size() == 2) {
134  pma::Track3D* p0 = fAssigned.front().first.Track();
135 
136  size_t n_best = 0, m_best = 0;
137  d_best = kMaxDistToTrack;
138 
139  double lm, ln, l_best = 0;
140  for (size_t m = 0; m < p0->Nodes().size() - 1; m++) {
141  pma::Segment3D* seg_m = p0->NextSegment(p0->Nodes()[m]);
142  lm = seg_m->Length();
143  if (lm < fSegMinLength) continue;
144 
145  fAssigned.front().second = m;
146 
147  for (size_t n = 0; n < trk.Track()->Nodes().size() - 1; n++) {
148  pma::Segment3D* seg_n = trk.Track()->NextSegment(trk.Track()->Nodes()[n]);
149  ln = seg_n->Length();
150  if (ln < fSegMinLength) continue;
151 
152  fAssigned.back().second = n;
153 
154  mse = Compute(); // std::cout << mse << std::endl;
155 
156  d = sqrt(ComputeMse2D());
157 
158  if (d < d_best) {
159  double d_dist = (d_best - d) / d_best;
160  if (lm + ln > 0.8 * d_dist * l_best) // take closer if not much shorter
161  {
162  min_mse = mse;
163  n_best = n;
164  m_best = m;
165  d_best = d;
166  l_best = lm + ln;
167  }
168  }
169  }
170  }
171 
172  if (d_best < kMaxDistToTrack) {
173  fAssigned.front().second = m_best;
174  fAssigned.back().second = n_best;
175  fMse = Compute();
176 
177  fMse2D = ComputeMse2D();
178 
179  return true;
180  }
181  else {
182  fAssigned.pop_back();
183  fCenter.SetXYZ(0., 0., 0.);
184  fMse = 0;
185  fMse2D = 0;
186  return false;
187  }
188  }
189  else {
190  for (size_t n = 0; n < trk.Track()->Nodes().size() - 1; n++) {
191  pma::Segment3D* seg = trk.Track()->NextSegment(trk.Track()->Nodes()[n]);
192  if (seg->Length() >= fSegMinLength) { return true; }
193  }
194  fAssigned.pop_back();
195  fCenter.SetXYZ(0., 0., 0.);
196  fMse = 0;
197  fMse2D = 0;
198  return false;
199  }
200 }
201 
202 double
204 {
206 
207  double mse = 0.0;
208  TVector2 center2d;
209  for (const auto& t : fAssigned) {
210  pma::Track3D* trk = t.first.Track();
211  pma::Segment3D* seg = trk->NextSegment(trk->Nodes()[t.second]);
212 
213  int tpc = trk->Nodes()[t.second]->TPC();
214  int cryo = trk->Nodes()[t.second]->Cryo();
215 
216  size_t k = 0;
217  double m = 0.0;
218  if (geom->TPC(tpc, cryo).HasPlane(geo::kU)) {
219  center2d = GetProjectionToPlane(fCenter, geo::kU, tpc, cryo);
220  m += seg->GetDistance2To(center2d, geo::kU);
221  k++;
222  }
223  if (geom->TPC(tpc, cryo).HasPlane(geo::kV)) {
224  center2d = GetProjectionToPlane(fCenter, geo::kV, tpc, cryo);
225  m += seg->GetDistance2To(center2d, geo::kV);
226  k++;
227  }
228  if (geom->TPC(tpc, cryo).HasPlane(geo::kZ)) {
229  center2d = GetProjectionToPlane(fCenter, geo::kZ, tpc, cryo);
230  m += seg->GetDistance2To(center2d, geo::kZ);
231  k++;
232  }
233  mse += m / (double)k;
234  }
235 
236  return mse / fAssigned.size();
237 }
238 
239 double
241 {
242  double dx = fCenter[0] - other.fCenter[0];
243  double dy = fCenter[1] - other.fCenter[1];
244  double dz = fCenter[2] - other.fCenter[2];
245  double dw = fErr[0] * other.fErr[0] * dx * dx + fErr[1] * other.fErr[1] * dy * dy +
246  fErr[2] * other.fErr[2] * dz * dz;
247  return sqrt(dw);
248 }
249 
250 double
251 pma::VtxCandidate::MaxAngle(double minLength) const
252 {
253  TVector3 dir_i;
254  size_t max_l_idx = 0;
255  double l, max_l = 0.0;
256  for (size_t i = 0; i < fAssigned.size() - 1; i++) {
257  l = fAssigned[i].first.Track()->Length();
258  if (l > max_l) {
259  max_l = l;
260  max_l_idx = i;
261  pma::Track3D* trk_i = fAssigned[i].first.Track();
262  pma::Node3D* vtx_i0 = trk_i->Nodes()[fAssigned[i].second];
263  pma::Node3D* vtx_i1 = trk_i->Nodes()[fAssigned[i].second + 1];
264  dir_i = vtx_i1->Point3D() - vtx_i0->Point3D();
265  dir_i *= 1.0 / dir_i.Mag();
266  }
267  }
268 
269  double a, min = 1.0;
270  for (size_t j = 0; j < fAssigned.size(); j++)
271  if ((j != max_l_idx) && (fAssigned[j].first.Track()->Length() > minLength)) {
272  pma::Track3D* trk_j = fAssigned[j].first.Track();
273  pma::Node3D* vtx_j0 = trk_j->Nodes()[fAssigned[j].second];
274  pma::Node3D* vtx_j1 = trk_j->Nodes()[fAssigned[j].second + 1];
275  TVector3 dir_j = vtx_j1->Point3D() - vtx_j0->Point3D();
276  dir_j *= 1.0 / dir_j.Mag();
277  a = fabs(dir_i * dir_j);
278  if (a < min) min = a;
279  }
280 
281  return 180.0 * acos(min) / TMath::Pi();
282 }
283 
284 bool
286 {
287  double d = sqrt(pma::Dist2(fCenter, other.fCenter));
288  if (d > 10.0) {
289  mf::LogVerbatim("pma::VtxCandidate") << "too far..";
290  return false;
291  }
292 
293  double dw = Test(other);
294 
295  size_t ntrk = 0;
296  for (const auto& t : other.fAssigned) {
297  if (IsAttached(t.first.Track())) {
298  mf::LogVerbatim("pma::VtxCandidate") << "already attached..";
299  return false;
300  }
301  if (!Has(t.first.Track())) {
302  fAssigned.push_back(t);
303  ntrk++;
304  }
305  }
306  if (ntrk) {
307  double mse0 = fMse, mse1 = other.fMse;
308  mf::LogVerbatim("pma::VtxCandidate")
309  << "try: " << d << " mse0:" << sqrt(mse0) << " mse1:" << sqrt(mse1);
310  //std::cout << "try: " << d << " mse0:" << sqrt(mse0) << " mse1:" << sqrt(mse1) << std::endl;
311 
312  double mse = Compute();
313  mf::LogVerbatim("pma::VtxCandidate")
314  << "out: " << Size() << " mse:" << sqrt(mse) << " dw:" << dw;
315  //std::cout << "out: " << Size() << " mse:" << sqrt(mse) << " dw:" << dw << std::endl;
316 
317  if (mse < 1.0) // kMaxDistToTrack * kMaxDistToTrack)
318  {
319  fMse = mse;
320  fMse2D = ComputeMse2D();
321  return true;
322  }
323  else {
324  mf::LogVerbatim("pma::VtxCandidate") << "high mse..";
325  while (ntrk--) {
326  fAssigned.pop_back();
327  }
328  fMse = Compute();
329  fMse2D = ComputeMse2D();
330  return false;
331  }
332  }
333  else {
334  mf::LogVerbatim("pma::VtxCandidate") << "no tracks..";
335  return false;
336  }
337 }
338 
339 double
341 {
342  std::vector<pma::Segment3D*> segments;
343  std::vector<std::pair<TVector3, TVector3>> lines;
344  std::vector<double> weights;
345  for (const auto& v : fAssigned) {
346  pma::Track3D* trk = v.first.Track();
347  int vIdx = v.second;
348 
349  pma::Node3D* vtx1 = trk->Nodes()[vIdx];
350  pma::Segment3D* seg = trk->NextSegment(vtx1);
351  double segLength = seg->Length();
352  if (segLength >= fSegMinLength) {
353  pma::Node3D* vtx2 = static_cast<pma::Node3D*>(seg->Next(0));
354 
355  std::pair<TVector3, TVector3> endpoints(vtx1->Point3D(), vtx2->Point3D());
356  double dy = endpoints.first.Y() - endpoints.second.Y();
357  double fy_norm = asin(fabs(dy) / segLength) / (0.5 * TMath::Pi());
358  double w = 1.0 - pow(fy_norm - 1.0, 12);
359  if (w < 0.3) w = 0.3;
360 
361  lines.push_back(endpoints);
362  segments.push_back(seg);
363  weights.push_back(w);
364  }
365  }
366 
367  fCenter.SetXYZ(0., 0., 0.);
368  fErr.SetXYZ(0., 0., 0.);
369 
370  TVector3 result;
371  double resultMse = pma::SolveLeastSquares3D(lines, result);
372  if (resultMse < 0.0) {
373  mf::LogWarning("pma::VtxCandidate") << "Cannot compute crossing point.";
374  return 1.0E+6;
375  }
376 
377  TVector3 pproj;
378  //double dx, dy, dz
379  double wsum = 0.0;
380  for (size_t s = 0; s < segments.size(); s++) {
381  pma::Node3D* vprev = static_cast<pma::Node3D*>(segments[s]->Prev());
382  pma::Node3D* vnext = static_cast<pma::Node3D*>(segments[s]->Next(0));
383 
384  pproj = pma::GetProjectionToSegment(result, vprev->Point3D(), vnext->Point3D());
385 
386  //dx = weights[s] * (result.X() - pproj.X());
387  //dy = result.Y() - pproj.Y();
388  //dz = result.Z() - pproj.Z();
389 
390  fErr[0] += weights[s] * weights[s];
391  fErr[1] += 1.0;
392  fErr[2] += 1.0;
393 
394  fCenter[0] += weights[s] * pproj.X();
395  fCenter[1] += pproj.Y();
396  fCenter[2] += pproj.Z();
397  wsum += weights[s];
398  }
399  fCenter[0] /= wsum;
400  fCenter[1] /= segments.size();
401  fCenter[2] /= segments.size();
402 
403  fErr *= 1.0 / segments.size();
404  fErr[0] = sqrt(fErr[0]);
405  fErr[1] = sqrt(fErr[1]);
406  fErr[2] = sqrt(fErr[2]);
407 
408  return resultMse;
409 }
410 
411 bool
415 {
416  if (tracksJoined) {
417  mf::LogError("pma::VtxCandidate") << "Tracks already attached to the vertex.";
418  return false;
419  }
420  tracksJoined = true;
421 
422  mf::LogVerbatim("pma::VtxCandidate")
423  << "JoinTracks (" << fAssigned.size() << ") at:"
424  << " vx:" << fCenter.X() << " vy:" << fCenter.Y() << " vz:" << fCenter.Z();
425 
426  for (auto const& c : fAssigned) {
427  size_t t = 0;
428  while (t < src.size()) {
429  if (c.first.Track() == src[t].Track()) { // move from "src" to "tracks"
430  tracks.push_back(src[t]);
431  src.erase_at(t);
432  break;
433  }
434  else
435  t++;
436  }
437  }
438  // all involved tracks are in the same container, so:
439  tracks.setTreeIds();
440  for (auto& c : fAssigned) // update ids
441  for (auto const& t : tracks.tracks())
442  if (c.first.Track() == t.Track()) {
443  c.first.SetTreeId(t.TreeId());
444  break;
445  }
446 
447  // backup in case of fitting problems
448  std::vector<int> treeIds;
449  pma::TrkCandidateColl backupTracks;
450 
451  pma::Node3D* vtxCenter = 0;
452  bool hasInnerCenter = false;
453  size_t nOK = 0;
454  for (size_t i = 0; i < fAssigned.size(); i++) {
455  mf::LogVerbatim("pma::VtxCandidate") << "----------> track #" << i;
456 
457  pma::Track3D* trk = fAssigned[i].first.Track();
458  int key = fAssigned[i].first.Key();
459  int tid = fAssigned[i].first.TreeId();
460  size_t idx = fAssigned[i].second;
461 
462  mf::LogVerbatim("pma::VtxCandidate") << " track tid:" << tid << ", size:" << trk->size()
463  << " (nodes:" << trk->Nodes().size() << ")";
464 
465  if (!has(treeIds, tid)) // backup in case of fitting problems
466  {
467  treeIds.push_back(tid);
468  int rootIdx = tracks.getCandidateIndex(trk->GetRoot());
469  if (rootIdx >= 0)
470  tracks.getTreeCopy(backupTracks, rootIdx);
471  else
472  mf::LogError("pma::VtxCandidate") << "Root of the tree not found in tracks collection.";
473  }
474 
475  TVector3 p0(trk->Nodes()[idx]->Point3D());
476  TVector3 p1(trk->Nodes()[idx + 1]->Point3D());
477 
478  int tpc0 = trk->Nodes()[idx]->TPC();
479  int tpc1 = trk->Nodes()[idx + 1]->TPC();
480 
481  int cryo0 = trk->Nodes()[idx]->Cryo();
482  int cryo1 = trk->Nodes()[idx + 1]->Cryo();
483 
484  double d0 = sqrt(pma::Dist2(p0, fCenter));
485  double d1 = sqrt(pma::Dist2(p1, fCenter));
486  double ds = sqrt(pma::Dist2(p0, p1));
487  double f = pma::GetSegmentProjVector(fCenter, p0, p1);
488  TVector3 proj = pma::GetProjectionToSegment(fCenter, p0, p1);
489 
490  if ((idx == 0) && (f * ds <= kMinDistToNode)) {
491  if (i == 0) {
492  mf::LogVerbatim("pma::VtxCandidate") << " new at front";
493  vtxCenter = trk->Nodes().front();
494  vtxCenter->SetPoint3D(fCenter);
495  nOK++;
496  }
497  else {
498  mf::LogVerbatim("pma::VtxCandidate") << " front to center";
499  if (trk->AttachTo(vtxCenter)) nOK++;
500  }
501  }
502  else if ((idx + 2 == trk->Nodes().size()) && ((1.0 - f) * ds <= kMinDistToNode)) {
503  if (i == 0) {
504  if (trk->CanFlip()) {
505  mf::LogVerbatim("pma::VtxCandidate") << " flip trk to make new center";
506  trk->Flip();
507  vtxCenter = trk->Nodes().front();
508  }
509  else {
510  mf::LogVerbatim("pma::VtxCandidate") << " new center at the endpoint";
511  vtxCenter = trk->Nodes().back();
512  }
513  vtxCenter->SetPoint3D(fCenter);
514  nOK++;
515  }
516  else {
517  if (vtxCenter->Prev() && trk->CanFlip()) {
518  mf::LogVerbatim("pma::VtxCandidate") << " flip trk to attach to inner";
519  trk->Flip();
520  if (trk->AttachTo(vtxCenter)) nOK++;
521  }
522  else {
523  mf::LogVerbatim("pma::VtxCandidate") << " endpoint to center";
524  if (trk->AttachBackTo(vtxCenter)) nOK++;
525  }
526  }
527  }
528  else {
529  bool canFlipPrev = true;
530  if (vtxCenter && vtxCenter->Prev()) {
531  pma::Segment3D* seg = static_cast<pma::Segment3D*>(vtxCenter->Prev());
532  if (seg->Parent()->NextSegment(vtxCenter))
533  canFlipPrev = false;
534  else
535  canFlipPrev = seg->Parent()->CanFlip();
536  }
537 
538  if (hasInnerCenter || !canFlipPrev) {
539  mf::LogVerbatim("pma::VtxCandidate") << " split track";
540 
541  if ((f >= 0.0F) && (f <= 1.0) && (f * ds > kMinDistToNode) &&
542  ((1.0 - f) * ds > kMinDistToNode)) {
543  mf::LogVerbatim("pma::VtxCandidate") << " add center inside segment";
544 
545  int tpc, cryo;
546  if (f < 0.5) {
547  tpc = tpc0;
548  cryo = cryo0;
549  }
550  else {
551  tpc = tpc1;
552  cryo = cryo1;
553  }
554 
555  trk->InsertNode(detProp, fCenter, ++idx, tpc, cryo);
556  }
557  else {
558  if (d1 < d0) {
559  mf::LogVerbatim("pma::VtxCandidate") << " add center at end of segment";
560  ++idx;
561  }
562  else {
563  mf::LogVerbatim("pma::VtxCandidate") << " center at start of segment - no action";
564  }
565  }
566 
567  pma::Track3D* t0 = trk->Split(detProp, idx); // makes both tracks attached to each other
568 
569  if (t0) {
570  mf::LogVerbatim("pma::VtxCandidate")
571  << " trk size:" << trk->size() << " (nodes:" << trk->Nodes().size() << ")";
572 
573  trk->MakeProjection();
574 
575  mf::LogVerbatim("pma::VtxCandidate")
576  << " t0 size:" << t0->size() << " (nodes:" << t0->Nodes().size() << ")";
577 
578  t0->MakeProjection();
579 
580  tracks.tracks().emplace_back(t0, key, tid);
581  if (i == 0) {
582  mf::LogVerbatim("pma::VtxCandidate") << " center at trk0 back";
583  vtxCenter = trk->Nodes().front();
584  nOK += 2;
585  }
586  else {
587  mf::LogVerbatim("pma::VtxCandidate") << " attach trk to trk0";
588  if (trk->AttachTo(vtxCenter)) nOK += 2;
589  }
590  }
591  mf::LogVerbatim("pma::VtxCandidate") << " done";
592  }
593  else {
594  mf::LogVerbatim("pma::VtxCandidate") << " inner center";
595  hasInnerCenter = true;
596 
597  if ((f >= 0.0F) && (f <= 1.0) && (f * ds > kMinDistToNode) &&
598  ((1.0 - f) * ds > kMinDistToNode)) {
599  mf::LogVerbatim("pma::VtxCandidate") << " add center inside segment";
600 
601  int tpc, cryo;
602  if (f < 0.5) {
603  tpc = tpc0;
604  cryo = cryo0;
605  }
606  else {
607  tpc = tpc1;
608  cryo = cryo1;
609  }
610 
611  trk->InsertNode(detProp, fCenter, ++idx, tpc, cryo);
612  }
613  else {
614  if (d1 < d0) {
615  mf::LogVerbatim("pma::VtxCandidate") << " add center at end of segment";
616  ++idx;
617  }
618  else {
619  mf::LogVerbatim("pma::VtxCandidate") << " center at start of segment - no action";
620  }
621  }
622 
623  pma::Node3D* innerCenter = trk->Nodes()[idx];
624  if (i > 0) // already has vtxCenter
625  {
626  // prepare for prev...
627  pma::Track3D* rootBranch = 0;
628  pma::Segment3D* seg = static_cast<pma::Segment3D*>(vtxCenter->Prev());
629  if (seg) {
630  rootBranch = seg->Parent();
631  rootBranch->Flip();
632  }
633 
634  // ...but nexts reattached first, then...
635  auto branches = vtxCenter->GetBranches();
636 
637  for (size_t j = 0; j < branches.size(); ++j) {
638  if (branches[j]->AttachTo(innerCenter, true)) {}
639  }
640  vtxCenter = innerCenter; // vtxCenter is deleted after full reattach
641  }
642  else {
643  vtxCenter = innerCenter; // vtx from inner center
644  } // set vtxCenter on i == 0
645 
646  nOK++;
647 
648  mf::LogVerbatim("pma::VtxCandidate") << " done";
649  }
650  }
651  }
652 
653  bool result = false;
654  if (vtxCenter) {
655  pma::Segment3D* rootSeg = 0;
656  if (vtxCenter->NextCount())
657  rootSeg = static_cast<pma::Segment3D*>(vtxCenter->Next(0));
658  else if (vtxCenter->Prev())
659  rootSeg = static_cast<pma::Segment3D*>(vtxCenter->Prev());
660  else
661  throw cet::exception("pma::VtxCandidate") << "Vertex with no segments attached.";
662 
663  pma::Track3D* rootTrk = rootSeg->Parent()->GetRoot();
664  if (!rootTrk) rootTrk = rootSeg->Parent();
665 
666  std::vector<pma::Track3D const*> branchesToRemove; // change to a more simple check
667  bool noLoops = rootTrk->GetBranches(branchesToRemove); // if there are loops
668 
669  bool tuneOK = true;
670  if (noLoops && (nOK > 1)) {
671  fAssigned.clear();
672  fCenter = vtxCenter->Point3D();
673  fMse = 0.0;
674  fMse2D = 0.0;
675 
676  double g = rootTrk->TuneFullTree();
677 
678  if (g > -2.0) // -1.0: high value of g; -2.0: inf. value of g.
679  {
680  result = true; // all OK, new vertex added
681  }
682  else {
683  tuneOK = false; // inf. g, remove tracks
684  }
685  }
686 
687  if (noLoops && tuneOK) {
688  mf::LogVerbatim("pma::VtxCandidate") << "remove backup tracks";
689  for (auto& c : backupTracks.tracks())
690  c.DeleteTrack();
691  }
692  else {
693  mf::LogVerbatim("pma::VtxCandidate") << "restore tracks from backup....";
694  for (int tid : treeIds) {
695  size_t t = 0;
696  while (t < tracks.size()) {
697  if (tracks[t].TreeId() == tid) {
698  tracks[t].DeleteTrack();
699  tracks.erase_at(t);
700  }
701  else
702  t++;
703  }
704  }
705  for (const auto& c : backupTracks.tracks())
706  tracks.push_back(c);
707  mf::LogVerbatim("pma::VtxCandidate") << " done";
708  }
709  }
710  else
711  mf::LogError("pma::VtxCandidate") << "Cannot create common vertex";
712 
713  return result;
714 }
void MakeProjection()
Vertex finding helper for the Projection Matching Algorithm.
code to link reconstructed objects back to the MC truth information
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
bool HasPlane(unsigned int iplane) const
Returns whether a plane with index iplane is present in this TPC.
Definition: TPCGeo.h:175
TVector3 const & Point3D() const
Definition: PmaNode3D.h:45
size_t size() const
bool Has(pma::Track3D *trk) const
double SolveLeastSquares3D(const std::vector< std::pair< TVector3, TVector3 >> &lines, TVector3 &result)
Definition: Utilities.cxx:165
pma::Track3D * getTreeCopy(pma::TrkCandidateColl &dst, size_t trkIdx, bool isRoot=true)
bool AttachTo(pma::Node3D *vStart, bool noFlip=false)
static constexpr double g
Definition: Units.h:144
static QCString result
Implementation of the Projection Matching Algorithm.
bool IsAttachedTo(pma::Track3D const *trk) const
double Dist2(const TVector2 &v1, const TVector2 &v2)
Definition: Utilities.cxx:37
double Test(const VtxCandidate &other) const
Planes which measure V.
Definition: geo_types.h:130
bool JoinTracks(detinfo::DetectorPropertiesData const &detProp, pma::TrkCandidateColl &tracks, pma::TrkCandidateColl &src)
void erase_at(size_t pos)
Implementation of the Projection Matching Algorithm.
constexpr T pow(T x)
Definition: pow.h:72
bool GetBranches(std::vector< pma::Track3D const * > &branches, bool skipFirst=false) const
std::vector< std::pair< pma::TrkCandidate, size_t > > fAssigned
virtual unsigned int NextCount(void) const
Definition: SortedObjects.h:84
std::vector< pma::Track3D * > GetBranches() const
Definition: PmaNode3D.cxx:463
Planes which measure Z direction.
Definition: geo_types.h:132
Implementation of the Projection Matching Algorithm.
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
static QStrList * l
Definition: config.cpp:1044
double TuneFullTree(double eps=0.001, double gmax=50.0)
art framework interface to geometry description
bool Has(const VtxCandidate &other) const
size_t Size() const
pma::Track3D * Split(detinfo::DetectorPropertiesData const &detProp, size_t idx, bool try_start_at_idx=true)
Planes which measure U.
Definition: geo_types.h:129
bool CanFlip() const
Check if the track can be flipped without breaking any other track.
Definition: PmaTrack3D.cxx:653
def key(type, name=None)
Definition: graph.py:13
TVector2 GetProjectionToSegment(const TVector2 &p, const TVector2 &p0, const TVector2 &p1)
Definition: Utilities.cxx:149
pma::Track3D * GetRoot()
std::void_t< T > n
const double a
static constexpr double kMinDistToNode
int getCandidateIndex(pma::Track3D const *candidate) const
bool SetPoint3D(const TVector3 &p3d)
Definition: PmaNode3D.cxx:167
static constexpr double kMaxDistToTrack
Definition of data types for geometry description.
double MaxAngle(double minLength=0.0) const
void InsertNode(detinfo::DetectorPropertiesData const &detProp, TVector3 const &p3d, size_t at_idx, unsigned int tpc, unsigned int cryo)
bool MergeWith(const VtxCandidate &other)
Definition: tracks.py:1
Implementation of the Projection Matching Algorithm.
virtual pma::SortedObjectBase * Next(unsigned int index=0) const
Definition: SortedObjects.h:79
bool Add(const pma::TrkCandidate &trk)
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
Definition: statistics.h:55
double GetSegmentProjVector(const TVector2 &p, const TVector2 &p0, const TVector2 &p1)
Definition: Utilities.cxx:117
TVector2 GetProjectionToPlane(const TVector3 &p, unsigned int plane, unsigned int tpc, unsigned int cryo)
Definition: Utilities.cxx:270
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
bool IsAttached(pma::Track3D *trk) const
double GetDistance2To(const TVector3 &p3d) const override
Distance [cm] from the 3D segment to the point 3D.
TPCGeo const & TPC(unsigned int const tpc=0, unsigned int const cstat=0) const
Returns the specified TPC.
std::vector< pma::Node3D * > const & Nodes() const noexcept
Definition: PmaTrack3D.h:335
virtual pma::SortedObjectBase * Prev(void) const
Definition: SortedObjects.h:44
bool Flip(const detinfo::DetectorPropertiesData &detProp, std::vector< pma::Track3D * > &allTracks)
Definition: PmaTrack3D.cxx:533
size_t size() const
Definition: PmaTrack3D.h:108
pma::Track3D * Track() const
pma::Track3D * Parent(void) const
Definition: PmaSegment3D.h:68
virtual pma::SortedObjectBase * Next(unsigned int index=0) const
Definition: SortedObjects.h:45
bool AttachBackTo(pma::Node3D *vStart)
bool HasLoops() const
static QCString * s
Definition: config.cpp:1042
pma::Segment3D * NextSegment(pma::Node3D *vtx) const
double Length(void) const
Definition: PmaElement3D.h:52
void push_back(const TrkCandidate &trk)
std::vector< TrkCandidate > const & tracks() const
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
bool has(const std::vector< int > &v, int id) const