LArSoft  v07_13_02
Liquid Argon Software toolkit - http://larsoft.org/
PMAlgVertexing.cxx
Go to the documentation of this file.
1 // Class: PMAlgVertexing
3 // Author: D.Stefan (Dorota.Stefan@ncbj.gov.pl) and R.Sulej (Robert.Sulej@cern.ch), August 2015
5 
7 
9 
11 
12 #include "TMath.h"
13 
15 {
16  this->reconfigure(config);
17 }
18 
20 {
22 
23  fFindKinks = config.FindKinks();
24  fKinkMinDeg = config.KinkMinDeg();
25  fKinkMinStd = config.KinkMinStd();
26 }
27 // ------------------------------------------------------
28 
30 {
31  cleanTracks();
32 }
33 // ------------------------------------------------------
34 
36 {
37  for (auto & t : fOutTracks.tracks()) t.DeleteTrack();
38  fOutTracks.clear();
39 
40  for (auto & t : fShortTracks.tracks()) t.DeleteTrack();
42 
43  for (auto & t : fEmTracks.tracks()) t.DeleteTrack();
44  fEmTracks.clear();
45 
46  for (auto & t : fExcludedTracks.tracks()) t.DeleteTrack();
48 }
49 // ------------------------------------------------------
50 
52 {
53  mf::LogVerbatim("pma::PMAlgVertexing") << "clean input: " << result.size() << std::endl;
54  for (auto & t : result.tracks()) t.DeleteTrack();
55  result.clear();
56 
57  mf::LogVerbatim("pma::PMAlgVertexing") << "fill input from out: " << fOutTracks.size() << std::endl;
58  for (auto const & t : fOutTracks.tracks()) result.push_back(t);
59  fOutTracks.clear();
60 
61  mf::LogVerbatim("pma::PMAlgVertexing") << "fill input from short: " << fShortTracks.size() << std::endl;
62  for (auto const & t : fShortTracks.tracks()) result.push_back(t);
64 
65  mf::LogVerbatim("pma::PMAlgVertexing") << "fill input from em: " << fEmTracks.size() << std::endl;
66  for (auto const & t : fEmTracks.tracks()) result.push_back(t);
67  fEmTracks.clear();
68 
69  mf::LogVerbatim("pma::PMAlgVertexing") << "copy back excluded tracks: " << fExcludedTracks.size() << std::endl;
70  for (auto const & t : fExcludedTracks.tracks()) result.push_back(t);
72 }
73 // ------------------------------------------------------
74 
76 {
77  cleanTracks();
78 
79  for (auto const & t : trk_input.tracks())
80  {
81  pma::Track3D* copy = new pma::Track3D(*(t.Track()));
82  int key = t.Key();
83 
84  if ((t.Track()->GetT0() != 0) || // do not create vertices on cosmic muons, now track with any non-zero t0 is a muon,
85  (t.Track()->HasTagFlag(pma::Track3D::kCosmic))) // tag for track recognized as a cosmic ray is starting to be used
86  {
87  fExcludedTracks.tracks().emplace_back(copy, key);
88  continue;
89  }
90 
91  double l = t.Track()->Length();
92 
93  if (t.Track()->GetTag() == pma::Track3D::kEmLike)
94  {
95  if (l > 2 * fMinTrackLength) fOutTracks.tracks().emplace_back(copy, key);
96  else fEmTracks.tracks().emplace_back(copy, key);
97  }
98  else
99  {
100  if (l > fMinTrackLength) fOutTracks.tracks().emplace_back(copy, key);
101  else fEmTracks.tracks().emplace_back(copy, key);
102  }
103  }
104  mf::LogVerbatim("pma::PMAlgVertexing") << "long tracks: " << fOutTracks.size() << std::endl;
105  mf::LogVerbatim("pma::PMAlgVertexing") << "em and short tracks: " << fEmTracks.size() << std::endl;
106  mf::LogVerbatim("pma::PMAlgVertexing") << "excluded cosmic tracks: " << fExcludedTracks.size() << std::endl;
107 }
108 // ------------------------------------------------------
109 
110 std::vector< pma::VtxCandidate > pma::PMAlgVertexing::firstPassCandidates(void)
111 {
112  std::vector< pma::VtxCandidate > candidates;
113  for (size_t t = 0; t < fOutTracks.size() - 1; t++)
114  {
115  for (size_t u = t + 1; u < fOutTracks.size(); u++)
116  {
117  pma::VtxCandidate candidate;
118  if (!candidate.Add(fOutTracks[t])) break; // no segments with length > thr
119 
120  // **************************** try Mse2D / or only Mse ************************************
121  if (candidate.Add(fOutTracks[u]) && (sqrt(candidate.Mse()) < 1.0))
122  //if (candidate.Add(fOutTracks[u]) && (sqrt(candidate.Mse()) < 2.0) && (candidate.Mse2D() < 1.0))
123  {
124  candidates.push_back(candidate);
125  }
126  }
127  }
128  return candidates;
129 }
130 
131 std::vector< pma::VtxCandidate > pma::PMAlgVertexing::secondPassCandidates(void)
132 {
133  std::vector< pma::VtxCandidate > candidates;
134  for (size_t t = 0; t < fOutTracks.size(); t++)
135  if (fOutTracks[t].Track()->Length() > fMinTrackLength)
136  {
137  for (size_t u = 0; u < fEmTracks.size(); u++)
138  {
139  pma::VtxCandidate candidate;
140  if (!candidate.Add(fOutTracks[t])) break; // no segments with length > thr
141 
142  if (fOutTracks[t].Track() == fEmTracks[u].Track()) continue;
143 
144  if (candidate.Add(fEmTracks[u]) && (sqrt(candidate.Mse()) < 1.0))
145  {
146  candidates.push_back(candidate);
147  }
148  }
149  }
150  return candidates;
151 }
152 
153 size_t pma::PMAlgVertexing::makeVertices(std::vector< pma::VtxCandidate >& candidates)
154 {
155  bool merged = true;
156  while (merged && (candidates.size() > 1))
157  {
158  size_t k_best, l_best, k = 0;
159  while (k < candidates.size() - 1)
160  {
161  size_t l = k + 1;
162  while (l < candidates.size())
163  {
164  if (candidates[l].Has(candidates[k]))
165  {
166  candidates[k] = candidates[l];
167  candidates.erase(candidates.begin() + l);
168  }
169  else if (candidates[k].Has(candidates[l]))
170  {
171  candidates.erase(candidates.begin() + l);
172  }
173  else l++;
174  }
175  k++;
176  }
177 
178  merged = false;
179  double d_thr = 1.0; // 1.0 = max weighted dist. threshold
180  double d, dmin = d_thr;
181 
182  k = 0;
183  while (k < candidates.size() - 1)
184  {
185  size_t l = k + 1;
186  while (l < candidates.size())
187  {
188  d = candidates[k].Test(candidates[l]);
189  if (d < dmin) { dmin = d; k_best = k; l_best = l; }
190  l++;
191  }
192  k++;
193  }
194  if ((dmin < d_thr) && candidates[k_best].MergeWith(candidates[l_best]))
195  {
196  candidates.erase(candidates.begin() + l_best);
197  merged = true;
198  }
199  }
200 
201  mf::LogVerbatim("pma::PMAlgVertexing") << "*** Vtx candidates: " << candidates.size();
202  std::vector< pma::VtxCandidate > toJoin;
203  bool select = true;
204  while (select)
205  {
206  int s, nmax = 0, c_best = -1;
207  double a, amax = 0.0;
208 
209  for (size_t v = 0; v < candidates.size(); v++)
210  {
211  if (candidates[v].HasLoops()) continue;
212 
213  bool maybeCorrelated = false;
214  for (size_t u = 0; u < toJoin.size(); u++)
215  if (toJoin[u].IsAttached(candidates[v]) || // connected with tracks or close centers
216  (pma::Dist2(toJoin[u].Center(), candidates[v].Center()) < 15.0*15.0))
217  {
218  maybeCorrelated = true; break;
219  }
220  if (maybeCorrelated) continue;
221 
222  s = (int)candidates[v].Size(2 * fMinTrackLength);
223  a = candidates[v].MaxAngle(1.0);
224 
225  if ((s > nmax) || ((s == nmax) && (a > amax)))
226  {
227  nmax = s; amax = a; c_best = v;
228  }
229 /*
230  mf::LogVerbatim("pma::PMAlgVertexing")
231  << "center x:" << candidates[v].Center().X()
232  << " y:" << candidates[v].Center().Y()
233  << " z:" << candidates[v].Center().Z();
234 
235  for (size_t i = 0; i < candidates[v].Size(); i++)
236  mf::LogVerbatim("pma::PMAlgVertexing")
237  << " trk:" << i << " "
238  << candidates[v].Track(i).first->size();
239 
240  mf::LogVerbatim("pma::PMAlgVertexing")
241  << " dist 3D:" << sqrt(candidates[v].Mse())
242  << " 2D:" << sqrt(candidates[v].Mse2D())
243  << " max ang:" << a;
244 */
245  }
246  if (c_best >= 0)
247  {
248  toJoin.push_back(candidates[c_best]);
249  candidates.erase(candidates.begin() + c_best);
250  }
251  else select = false;
252  }
253  mf::LogVerbatim("pma::PMAlgVertexing") << "*** Vtx selected to join: " << toJoin.size();
254 
255  size_t njoined = 0;
256  for (auto & c : toJoin)
257  {
258  if (c.JoinTracks(fOutTracks, fEmTracks)) njoined++;
259  }
260 
261  return njoined;
262 }
263 // ------------------------------------------------------
264 
266 {
267  if (fFindKinks) findKinksOnTracks(trk_input);
268 
269  if (trk_input.size() < 2)
270  {
271  mf::LogWarning("pma::PMAlgVertexing") << "need min two source tracks!";
272  return 0;
273  }
274 
275  sortTracks(trk_input); // copy input and split by tag/size
276 
277  size_t nvtx = 0;
278  mf::LogVerbatim("pma::PMAlgVertexing") << "Pass #1:";
279  //std::cout << "Pass #1:" << std::endl;
280  if (fOutTracks.size() > 1)
281  {
282  size_t nfound = 0;
283  do
284  {
285  auto candidates = firstPassCandidates();
286  if (candidates.size())
287  {
288  nfound = makeVertices(candidates);
289  nvtx += nfound;
290  }
291  else nfound = 0;
292  }
293  while (nfound > 0);
294  mf::LogVerbatim("pma::PMAlgVertexing") << " " << nvtx << " vertices.";
295  //std::cout << " " << nvtx << " vertices." << std::endl;
296  }
297  else mf::LogVerbatim("pma::PMAlgVertexing") << " ...short tracks only.";
298 
299  mf::LogVerbatim("pma::PMAlgVertexing") << "Pass #2:";
300  //std::cout << "Pass #2:" << std::endl;
301  if (fOutTracks.size() && fEmTracks.size())
302  {
303  size_t nfound = 1; // just to start
304  while (nfound && fEmTracks.size())
305  {
306  auto candidates = secondPassCandidates();
307  if (candidates.size())
308  {
309  nfound = makeVertices(candidates);
310  nvtx += nfound;
311  }
312  else nfound = 0;
313  }
314  mf::LogVerbatim("pma::PMAlgVertexing") << " " << nvtx << " vertices.";
315  //std::cout << " " << nvtx << " vertices." << std::endl;
316  }
317  else mf::LogVerbatim("pma::PMAlgVertexing") << " ...no tracks.";
318 
319  collectTracks(trk_input);
320 
321  mergeBrokenTracks(trk_input);
322 
323  return nvtx;
324 }
325 // ------------------------------------------------------
326 
328  pma::TrkCandidateColl& trk_input,
329  const std::vector< TVector3 >& vtx_input)
330 {
331  sortTracks(trk_input); // copy input and split by tag/size
332 
333  // ....
334 
335  //collectTracks(trk_input); // return output in place of (deleted) input
336 
337  return 0;
338 }
339 // ------------------------------------------------------
340 
341 std::vector< std::pair<double, double> > pma::PMAlgVertexing::getdQdx(
342  const pma::Track3D& trk) const
343 {
344  std::vector< std::pair<double, double> > result;
345 
346  unsigned int view = geo::kZ;
347  unsigned int nhits = trk.NHits(view);
348  unsigned int max = nhits;
349 
350  nhits = trk.NHits(geo::kV);
351  if (nhits > max) { max = nhits; view = geo::kV; }
352 
353  nhits = trk.NHits(geo::kU);
354  if (nhits > max) { max = nhits; view = geo::kU; }
355 
356  if (max >= 16)
357  {
358  std::map< size_t, std::vector<double> > dqdx;
359  trk.GetRawdEdxSequence(dqdx, view);
360 
361  for (size_t i = 0; i < trk.size(); i++)
362  {
363  auto it = dqdx.find(i);
364  if (it != dqdx.end())
365  {
366  if (it->second[6] > 0.0) // dx > 0
367  {
368  double dvalue = it->second[5] / it->second[6];
369  result.emplace_back(std::pair<double, double>(dvalue, it->second[7]));
370  }
371  }
372  }
373  }
374 
375  return result;
376 }
377 // ------------------------------------------------------
378 
379 double pma::PMAlgVertexing::convolute(size_t idx, size_t len, double* adc, double const* shape) const
380 {
381  size_t half = len >> 1;
382  double v, mean = 0.0, stdev = 0.0;
383  for (size_t i = 0; i < len; i++)
384  {
385  v = adc[idx - half + i];
386  mean += v; stdev += v * v;
387  }
388  mean /= len;
389  stdev /= len;
390  stdev -= mean;
391 
392  double sum = 0.0;
393  for (size_t i = 0; i < len; i++)
394  sum += (adc[idx - half + i] - mean) * shape[i];
395 
396  return sum / sqrt(stdev);
397 }
398 
400 {
401  const double minCos = 0.996194698; // 5 deg (is it ok?)
402  double segCos = trk1->Segments().back()->GetDirection3D().Dot( trk2->Segments().front()->GetDirection3D() );
403  if (segCos < minCos)
404  {
405  mf::LogVerbatim("pma::PMAlgVertexing") << " has large angle, cos: " << segCos;
406  return false;
407  }
408 
409  const size_t stepShapeLen = 16;
410  const size_t stepShapeHalf = stepShapeLen >> 1;
411  const double stepShape[stepShapeLen] =
412  { -1., -1., -1., -1., -1., -1., -1., -1.,
413  1., 1., 1., 1., 1., 1., 1., 1. };
414 
415  auto dqdx1 = getdQdx(*trk1); if (dqdx1.size() < stepShapeHalf) return false;
416  auto dqdx2 = getdQdx(*trk2); if (dqdx2.size() < stepShapeHalf) return false;
417 
418  const size_t adcLen = stepShapeLen + 2; // 1 sample before/after to check convolution at 3 points in total
419  const size_t adcHalf = adcLen >> 1;
420 
421  double dqdx[adcLen];
422  for (size_t i = 0; i < adcLen; i++) dqdx[i] = 0.0;
423 
424  bool has_m = true;
425  for (int i = adcHalf - 1, j = dqdx1.size() - 1; i >= 0; i--, j--)
426  {
427  if (j >= 0) dqdx[i] = dqdx1[j].first;
428  else { dqdx[i] = dqdx[i+1]; has_m = false; }
429  }
430  bool has_p = true;
431  for (size_t i = adcHalf, j = 0; i < adcLen; i++, j++)
432  {
433  if (j < dqdx2.size()) dqdx[i] = dqdx2[j].first;
434  else { dqdx[i] = dqdx[i-1]; has_p = false; }
435  }
436 
437  double sum_m = 0.0; if (has_m) sum_m = convolute(adcHalf - 1, stepShapeLen, dqdx, stepShape);
438  double sum_0 = convolute(adcHalf, stepShapeLen, dqdx, stepShape);
439  double sum_p = 0.0; if (has_p) sum_p = convolute(adcHalf + 1, stepShapeLen, dqdx, stepShape);
440 
441  const double convMin = 0.8;
442  if ((fabs(sum_m) >= convMin) ||
443  (fabs(sum_0) >= convMin) ||
444  (fabs(sum_p) >= convMin))
445  {
446  mf::LogVerbatim("pma::PMAlgVertexing") << " has step in conv.values: "
447  << sum_m << ", " << sum_0 << ", " << sum_p;
448  return false;
449  }
450  else
451  {
452  mf::LogVerbatim("pma::PMAlgVertexing") << " single particle, conv.values: "
453  << sum_m << ", " << sum_0 << ", " << sum_p;
454  return true;
455  }
456 }
457 
459 {
460  if (trk_input.size() < 2) return;
461 
462  mf::LogVerbatim("pma::PMAlgVertexing") << "Find and merge tracks broken by vertices.";
463  bool merged = true;
464  while (merged)
465  {
466  merged = false;
467  for (size_t t = 0; t < trk_input.size(); t++)
468  {
469  pma::Track3D* trk1 = trk_input[t].Track();
470  pma::Track3D* trk2 = 0;
471 
472  pma::Node3D* node = trk1->Nodes().front();
473  if (node->Prev())
474  {
475  pma::Segment3D* seg = static_cast< pma::Segment3D* >(node->Prev());
476  trk2 = seg->Parent();
477  if ((trk1 != trk2) && isSingleParticle(trk2, trk1)) // note: reverse order
478  {
479  //merged = true;
480  break;
481  }
482  }
483 
484  trk2 = 0;
485  double c, maxc = 0.0;
486  pma::Vector3D dir1 = trk1->Segments().back()->GetDirection3D();
487  node = trk1->Nodes().back();
488  for (size_t n = 0; n < node->NextCount(); n++)
489  {
490  pma::Segment3D* seg = static_cast< pma::Segment3D* >(node->Next(n));
491  pma::Track3D* tst = seg->Parent();
492  if (tst != trk1) // should always be true: the last node of trk1 is tested
493  {
494  c = dir1.Dot( tst->Segments().front()->GetDirection3D() );
495  if (c > maxc) { maxc = c; trk2 = tst; }
496  }
497  }
498  if ((trk2) && isSingleParticle(trk1, trk2))
499  {
500  //merged = true;
501  break;
502  }
503  }
504  }
505  mf::LogVerbatim("pma::PMAlgVertexing") << "-------- done --------";
506 }
507 // ------------------------------------------------------
508 
510 {
511  if (trk_input.size() < 1) return;
512 
513  mf::LogVerbatim("pma::PMAlgVertexing") << "Find missed vtx by dQ/dx steps along merged tracks.";
514  size_t t = 0;
515  while (t < trk_input.size())
516  {
517  t++;
518  }
519  mf::LogVerbatim("pma::PMAlgVertexing") << "-------- done --------";
520 }
521 // ------------------------------------------------------
522 
524 {
525  if (trk_input.size() < 1) return;
526 
527  mf::LogVerbatim("pma::PMAlgVertexing") << "Find kinks on tracks, reopt with no penalty on angle where kinks.";
528  for (size_t t = 0; t < trk_input.size(); ++t)
529  {
530  pma::Track3D* trk = trk_input[t].Track();
531  if (trk->Nodes().size() < 5) continue;
532 
533  trk->Optimize(0, 1.0e-5, false);
534 
535  std::vector<size_t> tested_nodes;
536  bool kinkFound = true;
537  while (kinkFound)
538  {
539  int kinkIdx = -1, nnodes = 0;
540  double mean = 0.0, stdev = 0.0, min = 1.0, max_a = 0.0;
541  for (size_t n = 1; n < trk->Nodes().size() - 1; ++n)
542  {
543  auto const & node = *(trk->Nodes()[n]);
544 
545  if (node.IsVertex() || node.IsTPCEdge()) continue;
546  nnodes++;
547 
548  double c = -node.SegmentCosTransverse();
549  double a = 180.0 * (1 - std::acos(node.SegmentCosTransverse()) / TMath::Pi());
550  mean += c; stdev += c * c;
551  if ((c < min) && !has(tested_nodes, n))
552  {
553  if ((n > 1) && (n < trk->Nodes().size() - 2)) kinkIdx = n;
554  min = c; max_a = a;
555  }
556  }
557 
558  kinkFound = false;
559  if ((nnodes > 2) && (kinkIdx > 0) && (max_a > fKinkMinDeg))
560  {
561  mean /= nnodes; stdev /= nnodes;
562  stdev -= mean * mean;
563 
564  double thr = 1.0 - fKinkMinStd * stdev;
565  if (min < thr)
566  {
567  mf::LogVerbatim("pma::PMAlgVertexing") << " kink a: " << max_a << "deg";
568  trk->Nodes()[kinkIdx]->SetVertex(true);
569  tested_nodes.push_back(kinkIdx);
570  kinkFound = true;
571 
572  trk->Optimize(0, 1.0e-5, false, false);
573  double c = -trk->Nodes()[kinkIdx]->SegmentCosTransverse();
574  double a = 180.0 * (1 - std::acos(trk->Nodes()[kinkIdx]->SegmentCosTransverse()) / TMath::Pi());
575 
576  if ((a <= fKinkMinDeg) || (c >= thr)) // not a significant kink after precise optimization
577  {
578  mf::LogVerbatim("pma::PMAlgVertexing") << " -> tag removed after reopt";
579  trk->Nodes()[kinkIdx]->SetVertex(false); // kinkIdx is saved in tested_nodes to avoid inf loop
580  }
581  }
582  }
583  }
584 
585  mf::LogVerbatim("pma::PMAlgVertexing") << "-------- done --------";
586  }
587 }
588 // ------------------------------------------------------
589 
590 std::vector< std::pair< TVector3, std::vector< std::pair< size_t, bool > > > >
591 pma::PMAlgVertexing::getVertices(const pma::TrkCandidateColl & tracks, bool onlyBranching) const
592 {
593  std::vector< std::pair< TVector3, std::vector< std::pair< size_t, bool > > > > vsel;
594  std::vector< pma::Node3D const * > bnodes;
595 
596  for (size_t t = 0; t < tracks.size(); ++t)
597  {
598  pma::Track3D const * trk = tracks[t].Track();
599  pma::Node3D const * firstNode = trk->Nodes().front();
600  if (!(onlyBranching || firstNode->IsBranching()))
601  {
602  std::vector< std::pair< size_t, bool > > tidx;
603  tidx.emplace_back(std::pair< size_t, bool >(t, true));
604  vsel.emplace_back(std::pair< TVector3, std::vector< std::pair< size_t, bool > > >(trk->front()->Point3D(), tidx));
605  }
606 
607  bool pri = true;
608  for (auto node : trk->Nodes())
609  if (node->IsBranching())
610  {
611  bool found = false;
612  for (size_t n = 0; n < bnodes.size(); n++)
613  if (node == bnodes[n])
614  {
615  vsel[n].second.emplace_back(std::pair< size_t, bool >(t, pri));
616  found = true; break;
617  }
618  if (!found)
619  {
620  std::vector< std::pair< size_t, bool > > tidx;
621  tidx.emplace_back(std::pair< size_t, bool >(t, pri));
622  vsel.emplace_back(std::pair< TVector3, std::vector< std::pair< size_t, bool > > >(node->Point3D(), tidx));
623  bnodes.push_back(node);
624  }
625  pri = false;
626  }
627  }
628 
629  return vsel;
630 }
631 // ------------------------------------------------------
632 
633 std::vector< std::pair< TVector3, size_t > >
635 {
636  std::vector< std::pair< TVector3, size_t > > ksel;
637  for (size_t t = 0; t < tracks.size(); ++t)
638  {
639  pma::Track3D const * trk = tracks[t].Track();
640  for (size_t n = 1; n < trk->Nodes().size() - 1; ++n)
641  {
642  pma::Node3D const * node = trk->Nodes()[n];
643  if (!node->IsBranching() && node->IsVertex())
644  {
645  ksel.emplace_back(std::pair< TVector3, size_t >(node->Point3D(), t));
646  }
647  }
648  }
649  return ksel;
650 }
651 // ------------------------------------------------------
652 
653 
pma::TrkCandidateColl fEmTracks
Float_t s
Definition: plot.C:23
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
pma::TrkCandidateColl fShortTracks
bool IsVertex(void) const
Check fIsVertex flag.
Definition: PmaNode3D.h:54
double Dist2(const TVector2 &v1, const TVector2 &v2)
Definition: Utilities.cxx:19
std::vector< std::pair< TVector3, size_t > > getKinks(const pma::TrkCandidateColl &tracks) const
Planes which measure V.
Definition: geo_types.h:77
TVector3 const & Point3D(void) const
Definition: PmaNode3D.h:33
void collectTracks(pma::TrkCandidateColl &result)
std::vector< pma::Node3D * > const & Nodes(void) const
Definition: PmaTrack3D.h:232
void reconfigure(const Config &config)
virtual unsigned int NextCount(void) const
Definition: SortedObjects.h:84
Planes which measure Z direction.
Definition: geo_types.h:79
fhicl::Atom< double > MinTrackLength
std::vector< TrkCandidate > const & tracks(void) const
std::vector< std::pair< TVector3, std::vector< std::pair< size_t, bool > > > > getVertices(const pma::TrkCandidateColl &tracks, bool onlyBranching=false) const
std::vector< pma::Segment3D * > const & Segments(void) const
Definition: PmaTrack3D.h:227
recob::tracking::Vector_t Vector3D
Definition: Utilities.h:29
PMAlgVertexing(const Config &config)
double Mse(void) const
void findKinksOnTracks(pma::TrkCandidateColl &trk_input) const
Remove penalty on the angle if kink detected and reopt track.
size_t size(void) const
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:265
Planes which measure U.
Definition: geo_types.h:76
Int_t max
Definition: plot.C:27
unsigned int NHits(unsigned int view) const
Definition: PmaTrack3D.cxx:406
fhicl::Atom< bool > FindKinks
std::vector< std::pair< double, double > > getdQdx(const pma::Track3D &trk) const
Get dQ/dx sequence to detect various features.
Float_t d
Definition: plot.C:237
pma::TrkCandidateColl fOutTracks
double Optimize(int nNodes=-1, double eps=0.01, bool selAllHits=true, bool setAllNodes=true, size_t selSegHits=0, size_t selVtxHits=0)
Main optimization method.
fhicl::Atom< double > KinkMinStd
pma::TrkCandidateColl fExcludedTracks
bool IsBranching(void) const
Belongs to more than one track?
Definition: PmaNode3D.cxx:379
size_t makeVertices(std::vector< pma::VtxCandidate > &candidates)
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.
double convolute(size_t idx, size_t len, double *adc, double const *shape) const
Get convolution value.
virtual pma::SortedObjectBase * Next(unsigned int index=0) const
Definition: SortedObjects.h:79
bool Add(const pma::TrkCandidate &trk)
Int_t min
Definition: plot.C:26
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
void sortTracks(const pma::TrkCandidateColl &trk_input)
double GetRawdEdxSequence(std::map< size_t, std::vector< double > > &dedx, unsigned int view=geo::kZ, unsigned int skip=0, bool inclDisabled=false) const
Definition: PmaTrack3D.cxx:990
virtual ~PMAlgVertexing(void)
Char_t n[5]
TrackCollectionProxyElement< TrackCollProxy > Track
Proxy to an element of a proxy collection of recob::Track objects.
Definition: Track.h:1035
bool isSingleParticle(pma::Track3D *trk1, pma::Track3D *trk2) const
Check if colinear in 3D and dQ/dx with no significant step.
std::vector< pma::VtxCandidate > secondPassCandidates(void)
void splitMergedTracks(pma::TrkCandidateColl &trk_input) const
Split track and add vertex and reoptimize when dQ/dx step detected.
virtual pma::SortedObjectBase * Prev(void) const
Definition: SortedObjects.h:44
fhicl::Atom< double > KinkMinDeg
Float_t e
Definition: plot.C:34
size_t size() const
Definition: PmaTrack3D.h:76
size_t run(pma::TrkCandidateColl &trk_input)
pma::Track3D * Parent(void) const
Definition: PmaSegment3D.h:64
pma::Hit3D *& front()
Definition: PmaTrack3D.h:72
std::vector< pma::VtxCandidate > firstPassCandidates(void)
void push_back(const TrkCandidate &trk)
bool has(const std::vector< size_t > &v, size_t idx) const
void mergeBrokenTracks(pma::TrkCandidateColl &trk_input) const