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