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