LArSoft  v07_13_02
Liquid Argon Software toolkit - http://larsoft.org/
pma::PMAlgVertexing Class Reference

#include "PMAlgVertexing.h"

Classes

struct  Config
 

Public Member Functions

 PMAlgVertexing (const Config &config)
 
void reconfigure (const Config &config)
 
 PMAlgVertexing (const fhicl::ParameterSet &pset)
 
virtual ~PMAlgVertexing (void)
 
void reset (void)
 
size_t run (pma::TrkCandidateColl &trk_input)
 
size_t run (pma::TrkCandidateColl &trk_input, const std::vector< TVector3 > &vtx_input)
 
std::vector< std::pair< TVector3, std::vector< std::pair< size_t, bool > > > > getVertices (const pma::TrkCandidateColl &tracks, bool onlyBranching=false) const
 
std::vector< std::pair< TVector3, size_t > > getKinks (const pma::TrkCandidateColl &tracks) const
 

Private Member Functions

bool has (const std::vector< size_t > &v, size_t idx) const
 
std::vector< pma::VtxCandidatefirstPassCandidates (void)
 
std::vector< pma::VtxCandidatesecondPassCandidates (void)
 
size_t makeVertices (std::vector< pma::VtxCandidate > &candidates)
 
std::vector< std::pair< double, double > > getdQdx (const pma::Track3D &trk) const
 Get dQ/dx sequence to detect various features. More...
 
double convolute (size_t idx, size_t len, double *adc, double const *shape) const
 Get convolution value. More...
 
bool isSingleParticle (pma::Track3D *trk1, pma::Track3D *trk2) const
 Check if colinear in 3D and dQ/dx with no significant step. More...
 
void mergeBrokenTracks (pma::TrkCandidateColl &trk_input) const
 
void splitMergedTracks (pma::TrkCandidateColl &trk_input) const
 Split track and add vertex and reoptimize when dQ/dx step detected. More...
 
void findKinksOnTracks (pma::TrkCandidateColl &trk_input) const
 Remove penalty on the angle if kink detected and reopt track. More...
 
void cleanTracks (void)
 
void sortTracks (const pma::TrkCandidateColl &trk_input)
 
void collectTracks (pma::TrkCandidateColl &result)
 

Private Attributes

pma::TrkCandidateColl fOutTracks
 
pma::TrkCandidateColl fShortTracks
 
pma::TrkCandidateColl fEmTracks
 
pma::TrkCandidateColl fExcludedTracks
 
double fMinTrackLength
 
bool fFindKinks
 
double fKinkMinDeg
 
double fKinkMinStd
 

Detailed Description

Definition at line 29 of file PMAlgVertexing.h.

Constructor & Destructor Documentation

pma::PMAlgVertexing::PMAlgVertexing ( const Config config)

Definition at line 14 of file PMAlgVertexing.cxx.

References reconfigure().

15 {
16  this->reconfigure(config);
17 }
void reconfigure(const Config &config)
pma::PMAlgVertexing::PMAlgVertexing ( const fhicl::ParameterSet pset)
inline

Definition at line 61 of file PMAlgVertexing.h.

References ~PMAlgVertexing().

61  :
63  {}
PMAlgVertexing(const Config &config)
pma::PMAlgVertexing::~PMAlgVertexing ( void  )
virtual

Definition at line 29 of file PMAlgVertexing.cxx.

References cleanTracks().

Referenced by PMAlgVertexing().

30 {
31  cleanTracks();
32 }

Member Function Documentation

void pma::PMAlgVertexing::cleanTracks ( void  )
private

Definition at line 35 of file PMAlgVertexing.cxx.

References pma::TrkCandidateColl::clear(), fEmTracks, fExcludedTracks, fOutTracks, fShortTracks, and pma::TrkCandidateColl::tracks().

Referenced by reset(), sortTracks(), and ~PMAlgVertexing().

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 }
pma::TrkCandidateColl fEmTracks
pma::TrkCandidateColl fShortTracks
std::vector< TrkCandidate > const & tracks(void) const
pma::TrkCandidateColl fOutTracks
pma::TrkCandidateColl fExcludedTracks
void pma::PMAlgVertexing::collectTracks ( pma::TrkCandidateColl result)
private

Definition at line 51 of file PMAlgVertexing.cxx.

References pma::TrkCandidateColl::clear(), fEmTracks, fExcludedTracks, fOutTracks, fShortTracks, pma::TrkCandidateColl::push_back(), pma::TrkCandidateColl::size(), and pma::TrkCandidateColl::tracks().

Referenced by run().

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 }
pma::TrkCandidateColl fEmTracks
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
pma::TrkCandidateColl fShortTracks
std::vector< TrkCandidate > const & tracks(void) const
size_t size(void) const
pma::TrkCandidateColl fOutTracks
pma::TrkCandidateColl fExcludedTracks
void push_back(const TrkCandidate &trk)
double pma::PMAlgVertexing::convolute ( size_t  idx,
size_t  len,
double *  adc,
double const *  shape 
) const
private

Get convolution value.

Definition at line 379 of file PMAlgVertexing.cxx.

References pmtana::mean().

Referenced by has(), and isSingleParticle().

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 }
double mean(const std::vector< short > &wf, size_t start, size_t nsample)
Definition: UtilFunc.cxx:15
void pma::PMAlgVertexing::findKinksOnTracks ( pma::TrkCandidateColl trk_input) const
private

Remove penalty on the angle if kink detected and reopt track.

Definition at line 523 of file PMAlgVertexing.cxx.

References e, fKinkMinDeg, fKinkMinStd, has(), pmtana::mean(), min, n, pma::Track3D::Nodes(), pma::Track3D::Optimize(), and pma::TrkCandidateColl::size().

Referenced by has(), and run().

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 }
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
std::vector< pma::Node3D * > const & Nodes(void) const
Definition: PmaTrack3D.h:232
size_t size(void) const
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.
double mean(const std::vector< short > &wf, size_t start, size_t nsample)
Definition: UtilFunc.cxx:15
Int_t min
Definition: plot.C:26
Char_t n[5]
Float_t e
Definition: plot.C:34
bool has(const std::vector< size_t > &v, size_t idx) const
std::vector< pma::VtxCandidate > pma::PMAlgVertexing::firstPassCandidates ( void  )
private

Definition at line 110 of file PMAlgVertexing.cxx.

References pma::VtxCandidate::Add(), fOutTracks, pma::VtxCandidate::Mse(), and pma::TrkCandidateColl::size().

Referenced by has(), and run().

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 }
double Mse(void) const
size_t size(void) const
pma::TrkCandidateColl fOutTracks
bool Add(const pma::TrkCandidate &trk)
std::vector< std::pair< double, double > > pma::PMAlgVertexing::getdQdx ( const pma::Track3D trk) const
private

Get dQ/dx sequence to detect various features.

Definition at line 341 of file PMAlgVertexing.cxx.

References pma::Track3D::GetRawdEdxSequence(), geo::kU, geo::kV, geo::kZ, max, pma::Track3D::NHits(), and pma::Track3D::size().

Referenced by has(), and isSingleParticle().

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 }
Planes which measure V.
Definition: geo_types.h:77
Planes which measure Z direction.
Definition: geo_types.h:79
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
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
size_t size() const
Definition: PmaTrack3D.h:76
std::vector< std::pair< TVector3, size_t > > pma::PMAlgVertexing::getKinks ( const pma::TrkCandidateColl tracks) const

Definition at line 634 of file PMAlgVertexing.cxx.

References pma::Node3D::IsBranching(), pma::Node3D::IsVertex(), n, pma::Track3D::Nodes(), pma::Node3D::Point3D(), and pma::TrkCandidateColl::size().

Referenced by pma::PMAlgTrackingBase::getKinks(), and reset().

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 }
bool IsVertex(void) const
Check fIsVertex flag.
Definition: PmaNode3D.h:54
TVector3 const & Point3D(void) const
Definition: PmaNode3D.h:33
std::vector< pma::Node3D * > const & Nodes(void) const
Definition: PmaTrack3D.h:232
size_t size(void) const
bool IsBranching(void) const
Belongs to more than one track?
Definition: PmaNode3D.cxx:379
Char_t n[5]
std::vector< std::pair< TVector3, std::vector< std::pair< size_t, bool > > > > pma::PMAlgVertexing::getVertices ( const pma::TrkCandidateColl tracks,
bool  onlyBranching = false 
) const

Definition at line 591 of file PMAlgVertexing.cxx.

References pma::Track3D::front(), pma::Node3D::IsBranching(), n, pma::Track3D::Nodes(), pma::Hit3D::Point3D(), pma::TrkCandidateColl::size(), and lar::dump::vector().

Referenced by pma::PMAlgTrackingBase::getVertices(), and reset().

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 }
std::vector< pma::Node3D * > const & Nodes(void) const
Definition: PmaTrack3D.h:232
size_t size(void) const
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:265
bool IsBranching(void) const
Belongs to more than one track?
Definition: PmaNode3D.cxx:379
TVector3 const & Point3D(void) const
Definition: PmaHit3D.h:48
Char_t n[5]
pma::Hit3D *& front()
Definition: PmaTrack3D.h:72
bool pma::PMAlgVertexing::has ( const std::vector< size_t > &  v,
size_t  idx 
) const
inlineprivate

Definition at line 89 of file PMAlgVertexing.h.

References convolute(), findKinksOnTracks(), firstPassCandidates(), getdQdx(), isSingleParticle(), makeVertices(), mergeBrokenTracks(), secondPassCandidates(), and splitMergedTracks().

Referenced by findKinksOnTracks().

90  {
91  for (auto c : v) if (c == idx) return true;
92  return false;
93  }
bool pma::PMAlgVertexing::isSingleParticle ( pma::Track3D trk1,
pma::Track3D trk2 
) const
private

Check if colinear in 3D and dQ/dx with no significant step.

Definition at line 399 of file PMAlgVertexing.cxx.

References convolute(), getdQdx(), and pma::Track3D::Segments().

Referenced by has(), and mergeBrokenTracks().

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 }
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
std::vector< pma::Segment3D * > const & Segments(void) const
Definition: PmaTrack3D.h:227
std::vector< std::pair< double, double > > getdQdx(const pma::Track3D &trk) const
Get dQ/dx sequence to detect various features.
double convolute(size_t idx, size_t len, double *adc, double const *shape) const
Get convolution value.
size_t pma::PMAlgVertexing::makeVertices ( std::vector< pma::VtxCandidate > &  candidates)
private

Definition at line 153 of file PMAlgVertexing.cxx.

References d, pma::Dist2(), fEmTracks, fMinTrackLength, fOutTracks, and s.

Referenced by has(), and run().

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 }
pma::TrkCandidateColl fEmTracks
Float_t s
Definition: plot.C:23
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
double Dist2(const TVector2 &v1, const TVector2 &v2)
Definition: Utilities.cxx:19
Float_t d
Definition: plot.C:237
pma::TrkCandidateColl fOutTracks
void pma::PMAlgVertexing::mergeBrokenTracks ( pma::TrkCandidateColl trk_input) const
private

Find elastic scattering vertices on tracks, merge back tracks that were split during vertex finding. 3D angle between two tracks and dQ/dx is checked.

Definition at line 458 of file PMAlgVertexing.cxx.

References isSingleParticle(), n, pma::SortedBranchBase::Next(), pma::SortedBranchBase::NextCount(), pma::Track3D::Nodes(), pma::Segment3D::Parent(), pma::SortedObjectBase::Prev(), pma::Track3D::Segments(), and pma::TrkCandidateColl::size().

Referenced by has(), and run().

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 }
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
std::vector< pma::Node3D * > const & Nodes(void) const
Definition: PmaTrack3D.h:232
virtual unsigned int NextCount(void) const
Definition: SortedObjects.h:84
std::vector< pma::Segment3D * > const & Segments(void) const
Definition: PmaTrack3D.h:227
recob::tracking::Vector_t Vector3D
Definition: Utilities.h:29
size_t size(void) const
virtual pma::SortedObjectBase * Next(unsigned int index=0) const
Definition: SortedObjects.h:79
Char_t n[5]
bool isSingleParticle(pma::Track3D *trk1, pma::Track3D *trk2) const
Check if colinear in 3D and dQ/dx with no significant step.
virtual pma::SortedObjectBase * Prev(void) const
Definition: SortedObjects.h:44
pma::Track3D * Parent(void) const
Definition: PmaSegment3D.h:64
void pma::PMAlgVertexing::reconfigure ( const Config config)

Definition at line 19 of file PMAlgVertexing.cxx.

References fFindKinks, pma::PMAlgVertexing::Config::FindKinks, fKinkMinDeg, fKinkMinStd, fMinTrackLength, pma::PMAlgVertexing::Config::KinkMinDeg, pma::PMAlgVertexing::Config::KinkMinStd, and pma::PMAlgVertexing::Config::MinTrackLength.

Referenced by PMAlgVertexing().

20 {
21  fMinTrackLength = config.MinTrackLength();
22 
23  fFindKinks = config.FindKinks();
24  fKinkMinDeg = config.KinkMinDeg();
25  fKinkMinStd = config.KinkMinStd();
26 }
void pma::PMAlgVertexing::reset ( void  )
inline

Definition at line 67 of file PMAlgVertexing.h.

References cleanTracks(), getKinks(), getVertices(), and run().

67 { cleanTracks(); }
size_t pma::PMAlgVertexing::run ( pma::TrkCandidateColl trk_input)

Copy input tracks, find 3D vertices, connect tracks, break them or flip if needed, reoptimize track structures. Result is returned as a collection of new tracks, that replaces content of trk_input (old tracks are deleted). Vertices can be accessed with getVertices function.

Definition at line 265 of file PMAlgVertexing.cxx.

References collectTracks(), fEmTracks, fFindKinks, findKinksOnTracks(), firstPassCandidates(), fOutTracks, makeVertices(), mergeBrokenTracks(), secondPassCandidates(), pma::TrkCandidateColl::size(), and sortTracks().

Referenced by pma::PMAlgFitter::build(), pma::PMAlgTracker::build(), and reset().

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 }
pma::TrkCandidateColl fEmTracks
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
void collectTracks(pma::TrkCandidateColl &result)
void findKinksOnTracks(pma::TrkCandidateColl &trk_input) const
Remove penalty on the angle if kink detected and reopt track.
size_t size(void) const
pma::TrkCandidateColl fOutTracks
size_t makeVertices(std::vector< pma::VtxCandidate > &candidates)
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
void sortTracks(const pma::TrkCandidateColl &trk_input)
std::vector< pma::VtxCandidate > secondPassCandidates(void)
std::vector< pma::VtxCandidate > firstPassCandidates(void)
void mergeBrokenTracks(pma::TrkCandidateColl &trk_input) const
size_t pma::PMAlgVertexing::run ( pma::TrkCandidateColl trk_input,
const std::vector< TVector3 > &  vtx_input 
)

Copy input tracks, use provided 3D vertices to connect tracks, break tracks or flip if needed, reoptimize track structures. Result is returned as a collection of new tracks, that replaces content of trk_input (old tracks are deleted). Input vertices that were actually associated to tracks are copied to the output collection (use getVertices function).

Definition at line 327 of file PMAlgVertexing.cxx.

References sortTracks().

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 }
void sortTracks(const pma::TrkCandidateColl &trk_input)
std::vector< pma::VtxCandidate > pma::PMAlgVertexing::secondPassCandidates ( void  )
private

Definition at line 131 of file PMAlgVertexing.cxx.

References pma::VtxCandidate::Add(), fEmTracks, fMinTrackLength, fOutTracks, pma::VtxCandidate::Mse(), and pma::TrkCandidateColl::size().

Referenced by has(), and run().

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 }
pma::TrkCandidateColl fEmTracks
double Mse(void) const
size_t size(void) const
pma::TrkCandidateColl fOutTracks
bool Add(const pma::TrkCandidate &trk)
TrackCollectionProxyElement< TrackCollProxy > Track
Proxy to an element of a proxy collection of recob::Track objects.
Definition: Track.h:1035
void pma::PMAlgVertexing::sortTracks ( const pma::TrkCandidateColl trk_input)
private

Definition at line 75 of file PMAlgVertexing.cxx.

References cleanTracks(), fEmTracks, fExcludedTracks, fMinTrackLength, fOutTracks, pma::Track3D::kCosmic, pma::Track3D::kEmLike, pma::TrkCandidateColl::size(), and pma::TrkCandidateColl::tracks().

Referenced by run().

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 }
pma::TrkCandidateColl fEmTracks
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
std::vector< TrkCandidate > const & tracks(void) const
size_t size(void) const
pma::TrkCandidateColl fOutTracks
pma::TrkCandidateColl fExcludedTracks
void pma::PMAlgVertexing::splitMergedTracks ( pma::TrkCandidateColl trk_input) const
private

Split track and add vertex and reoptimize when dQ/dx step detected.

Definition at line 509 of file PMAlgVertexing.cxx.

References pma::TrkCandidateColl::size().

Referenced by has().

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 }
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
size_t size(void) const

Member Data Documentation

pma::TrkCandidateColl pma::PMAlgVertexing::fEmTracks
private
pma::TrkCandidateColl pma::PMAlgVertexing::fExcludedTracks
private

Definition at line 119 of file PMAlgVertexing.h.

Referenced by cleanTracks(), collectTracks(), and sortTracks().

bool pma::PMAlgVertexing::fFindKinks
private

Definition at line 129 of file PMAlgVertexing.h.

Referenced by reconfigure(), and run().

double pma::PMAlgVertexing::fKinkMinDeg
private

Definition at line 130 of file PMAlgVertexing.h.

Referenced by findKinksOnTracks(), and reconfigure().

double pma::PMAlgVertexing::fKinkMinStd
private

Definition at line 131 of file PMAlgVertexing.h.

Referenced by findKinksOnTracks(), and reconfigure().

double pma::PMAlgVertexing::fMinTrackLength
private

Definition at line 127 of file PMAlgVertexing.h.

Referenced by makeVertices(), reconfigure(), secondPassCandidates(), and sortTracks().

pma::TrkCandidateColl pma::PMAlgVertexing::fOutTracks
private
pma::TrkCandidateColl pma::PMAlgVertexing::fShortTracks
private

Definition at line 118 of file PMAlgVertexing.h.

Referenced by cleanTracks(), and collectTracks().


The documentation for this class was generated from the following files: