Namespaces | Classes | Typedefs | Functions | Variables
gar::rec Namespace Reference

Namespaces

 alg
 

Classes

class  CaloClusterCheater
 
class  CaloClustering
 
class  CaloHit
 
class  CaloStripSplitter
 
class  Cluster
 
class  CompressedHitFinder
 
class  dayoneconverter
 
class  dayonetrackfit
 
class  eveLoc
 
class  EventInit
 
class  Hit
 
class  IDNumberGen
 
class  PFParticle
 
class  Shower
 
class  SiPMHitFinder
 
class  tpccathodestitch
 
class  TPCCluster
 
class  TPCECALAssociation
 
class  TPCHitCluster
 
class  tpcpatrec2
 
class  tpcpatreccheat
 
class  tpctrackfit2
 
class  tpcvechitfinder2
 
class  Track
 
class  tracker1
 
class  TrackIoniz
 
class  TrackPar
 
class  TrackTrajectory
 
class  VecHit
 
class  Vee
 
class  veefinder1
 
class  Vertex
 
class  vertexfinder1
 

Typedefs

typedef size_t IDNumber
 
typedef int TrackEnd
 

Functions

float capprox (float x1, float y1, float x2, float y2, float x3, float y3, float &xc, float &yc)
 
void ouchef (double *x, double *y, int np, double &xcirccent, double &ycirccent, double &rcirc, double &chisq, int &ifail)
 
int initial_trackpar_estimate (const std::vector< gar::rec::TPCCluster > &TPCClusters, std::vector< int > &TPCClusterlist, float &curvature_init, float &lambda_init, float &phi_init, float &xpos, float &ypos, float &zpos, float &x_other_end, unsigned int initialtpnTPCClusters, int printlevel)
 
void sort_TPCClusters_along_track (const std::vector< gar::rec::TPCCluster > &TPCClusters, std::vector< int > &hlf, std::vector< int > &hlb, int printlevel, float &lengthforwards, float &lengthbackwards, float sorttransweight, float sortdistback)
 
void sort_TPCClusters_along_track2 (const std::vector< gar::rec::TPCCluster > &TPCClusters, std::vector< int > &hlf, std::vector< int > &hlb, int printlevel, float &lengthforwards, float &lengthbackwards, float dcut)
 
size_t ij2idxsort2 (size_t nclus, size_t i, size_t j)
 
void idx2ijsort2 (size_t nclus, size_t idx, size_t &i, size_t &j)
 
bool sort2_check_cyclic (std::vector< int > &link1, std::vector< int > &link2, int i, int j)
 
int fitVertex (std::vector< TrackPar > &tracks, std::vector< float > &xyz, float &chisquared, std::vector< std::vector< float > > &covmat, double &time, std::vector< TrackEnd > usebeg, std::vector< float > &doca)
 
std::ostream & operator<< (std::ostream &o, gar::rec::CaloHit const &h)
 
std::ostream & operator<< (std::ostream &o, gar::rec::Cluster const &h)
 
std::ostream & operator<< (std::ostream &o, gar::rec::Hit const &h)
 
std::ostream & operator<< (std::ostream &o, gar::rec::PFParticle const &h)
 
std::ostream & operator<< (std::ostream &o, gar::rec::TPCCluster const &h)
 
void FindDirectionFromTrackParameters (const float *tparms, const float thisXend, const float farXend, float *dir)
 
std::ostream & operator<< (std::ostream &o, gar::rec::VecHit const &h)
 

Variables

TrackEnd const TrackEndBeg = 1
 
TrackEnd const TrackEndEnd = 0
 

Typedef Documentation

typedef size_t gar::rec::IDNumber

Definition at line 71 of file IDNumberGen.h.

typedef int gar::rec::TrackEnd

Definition at line 32 of file Track.h.

Function Documentation

float gar::rec::capprox ( float  x1,
float  y1,
float  x2,
float  y2,
float  x3,
float  y3,
float &  xc,
float &  yc 
)

Definition at line 133 of file tracker2algs.cxx.

137 {
138  //-----------------------------------------------------------------
139  // Initial approximation of the track curvature -- copied from ALICE
140  // here x is y and y is z for us
141  //-----------------------------------------------------------------
142  x3 -=x1;
143  x2 -=x1;
144  y3 -=y1;
145  y2 -=y1;
146  //
147  float det = x3*y2-x2*y3;
148  if (TMath::Abs(det)<1e-10){
149  return 100;
150  }
151  //
152  float u = 0.5* (x2*(x2-x3)+y2*(y2-y3))/det;
153  float x0 = x3*0.5-y3*u;
154  float y0 = y3*0.5+x3*u;
155  float c2 = 1/TMath::Sqrt(x0*x0+y0*y0);
156  xc = x0 + x1;
157  yc = y0 + y1;
158  if (det<0) c2*=-1;
159  return c2;
160 }
const double e
void gar::rec::FindDirectionFromTrackParameters ( const float *  tparms,
const float  thisXend,
const float  farXend,
float *  dir 
)

Definition at line 269 of file Track.cxx.

270  {
271  // Direction is either +1 or -1 times d (position) / d(phi)
272  // from the track fit equations; the sign is determined by the
273  // x position of the far end.
274  dir[0] = TMath::Tan(tparms[4]);
275  dir[1] = TMath::Sin(tparms[3]);
276  dir[2] = TMath::Cos(tparms[3]);
277 
278  int sigh = +1;
279  if ( dir[0]>0 && farXend<thisXend ) sigh = -1;
280  if ( dir[0]<0 && farXend>thisXend ) sigh = -1;
281  float norm = sigh * TMath::Sqrt( 1.0 + dir[0]*dir[0]);
282 
283  dir[0] /= norm;
284  dir[1] /= norm;
285  dir[2] /= norm;
286  }
string dir
auto norm(Vector const &v)
Return norm of the specified vector.
int gar::rec::fitVertex ( std::vector< TrackPar > &  tracks,
std::vector< float > &  xyz,
float &  chisquared,
std::vector< std::vector< float > > &  covmat,
double &  time,
std::vector< TrackEnd usebeg,
std::vector< float > &  doca 
)

Definition at line 8 of file vertex1algs.cxx.

16 {
17  // find the ends of the tracks that are closest to the other tracks' ends
18  // pick the end that minimizes the sums of the min(dist) to the other tracks' endpoints
19 
20  // todo -- iterate on this as the tracks are helices and not lines -- move to close point on track and re-do linear extrapolation
21 
22  if (tracks.size() < 2) return(1); // need at least two tracks to make a vertex
23 
24  // find the average time of the tracks
25 
26  time = 0;
27  for (size_t i=0; i<tracks.size(); ++i)
28  {
29  time += tracks.at(i).getTime();
30  }
31  if (tracks.size() > 0)
32  {
33  time /= tracks.size();
34  }
35 
36  xyz.resize(3);
37  covmat.resize(9);
38 
39  std::vector<TVectorF> dir;
40  std::vector<TVectorF> p;
41 
42  for (size_t itrack = 0; itrack < tracks.size(); ++itrack)
43  {
44  TVector3 trackbeg = tracks.at(itrack).getXYZBeg();
45  TVector3 trackend = tracks.at(itrack).getXYZEnd();
46  float phi=0;
47  float si=0;
48  if (usebeg.at(itrack)==TrackEndBeg)
49  {
50  float tmppos[3] = {(float) trackbeg.X(), (float) trackbeg.Y(), (float) trackbeg.Z()};
51  p.emplace_back(3,tmppos);
52  phi = tracks.at(itrack).getTrackParametersBegin()[3];
53  si = TMath::Tan(tracks.at(itrack).getTrackParametersBegin()[4]);
54  }
55  else
56  {
57  float tmppos[3] = {(float) trackend.X(), (float) trackend.Y(), (float) trackend.Z()};
58  p.emplace_back(3,tmppos);
59  phi = tracks.at(itrack).getTrackParametersEnd()[3];
60  si = TMath::Tan(tracks.at(itrack).getTrackParametersEnd()[4]);
61  }
62  TVectorF dtmp(3);
63  dtmp[0] = si;
64  dtmp[1] = TMath::Sin(phi);
65  dtmp[2] = TMath::Cos(phi);
66  float norminv = 1.0/TMath::Sqrt(dtmp.Norm2Sqr());
67  dtmp *= norminv;
68  dir.push_back(dtmp);
69  }
70 
71  TMatrixF I(3,3);
72  I[0][0] = 1;
73  I[1][1] = 1;
74  I[2][2] = 1;
75 
76  TMatrixF A(3,3);
77  TMatrixF VVT(3,3);
78  TMatrixF IMVVT(3,3);
79  TVectorF vsum(3);
80  vsum.Zero();
81  A *= 0;
82 
83  for (size_t itrack=0; itrack < tracks.size(); ++itrack)
84  {
85  for (size_t i=0; i<3; ++i)
86  {
87  for (size_t j=0; j<3; ++j)
88  {
89  VVT[i][j] = dir.at(itrack)[i]*dir.at(itrack)[j];
90  }
91  }
92  IMVVT = I - VVT;
93  A += IMVVT;
94  vsum += IMVVT*p.at(itrack);
95  }
96  double det;
97  A.Invert(&det);
98  if (det == 0) return(1);
99  TVectorF xyzsol = A*vsum;
100  xyz.at(0) = xyzsol[0];
101  xyz.at(1) = xyzsol[1];
102  xyz.at(2) = xyzsol[2];
103 
104  chisquared = 0;
105  //std::cout << "in vertexfit ntracks: " << tracks.size() << std::endl;
106  for (size_t itrack=0; itrack < tracks.size(); ++itrack)
107  {
108 
109  TVector3 dir3(dir.at(itrack)[0],dir.at(itrack)[1],dir.at(itrack)[2]);
110  TVectorF diff = xyzsol - p.at(itrack);
111  TVector3 diff3(diff[0],diff[1],diff[2]);
112  double dctmp = (diff3.Cross(dir3)).Mag2();
113  doca.push_back(dctmp);
114  chisquared += dctmp*dctmp; // todo -- include track errors in chisquared calc
115  }
116 
117  // to iterate -- extrapolate helical tracks to the closest point to the first found vertex and
118  // run the fitter again
119 
120  // to do: figure out what the vertex covariance matrix is
121 
122  covmat.clear();
123  for (size_t i=0;i<3;++i)
124  {
125  std::vector<float> cmr;
126  for (size_t j=0; j<3; ++j)
127  {
128  cmr.push_back(0);
129  }
130  covmat.push_back(cmr);
131  }
132  return 0;
133 
134 }
string dir
p
Definition: test.py:223
TrackEnd const TrackEndBeg
Definition: Track.h:33
#define A
Definition: memgrp.cpp:38
void gar::rec::idx2ijsort2 ( size_t  nclus,
size_t  idx,
size_t &  i,
size_t &  j 
)

Definition at line 627 of file tracker2algs.cxx.

628 {
629  if (n<2)
630  {
631  i=0;
632  j=0;
633  return;
634  }
635  if (k > n*(n-1)/2)
636  {
637  throw cet::exception("gar::rec::idx2ijsort2: k too big. ") << k << " " << n;
638  }
639  i = n - 2 - TMath::Floor(TMath::Sqrt( (double) (-8*k + 4*n*(n-1)-7) )/2.0 - 0.5);
640  j = k + i + 1 - n*(n-1)/2 + (n-i)*((n-i)-1)/2;
641 }
std::void_t< T > n
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
size_t gar::rec::ij2idxsort2 ( size_t  nclus,
size_t  i,
size_t  j 
)

Definition at line 609 of file tracker2algs.cxx.

610 {
611  if (i_in >= n)
612  {
613  throw cet::exception("gar::rec::ij2idxsort2 i_in >= n");
614  }
615  if (j_in >= n)
616  {
617  throw cet::exception("gar::rec::ij2idxsort2 j_in >= n");
618  }
619  size_t i = TMath::Min(i_in,j_in);
620  size_t j = TMath::Max(i_in,j_in);
621  size_t k = (n*(n-1)/2) - (n-i)*((n-i)-1)/2 + j - i - 1;
622  return k;
623 }
std::void_t< T > n
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
int gar::rec::initial_trackpar_estimate ( const std::vector< gar::rec::TPCCluster > &  TPCClusters,
std::vector< int > &  TPCClusterlist,
float &  curvature_init,
float &  lambda_init,
float &  phi_init,
float &  xpos,
float &  ypos,
float &  zpos,
float &  x_other_end,
unsigned int  initialtpnTPCClusters,
int  printlevel 
)

Definition at line 8 of file tracker2algs.cxx.

19 {
20 
21  size_t nTPCClusters = TPCClusterlist.size();
22  size_t firstTPCCluster = 0;
23  size_t farTPCCluster = TMath::Min(nTPCClusters-1, (size_t) initialtpnTPCClusters);;
24  size_t intTPCCluster = farTPCCluster/2;
25  size_t lastTPCCluster = nTPCClusters-1;
26 
27  float trackbeg[3] = {TPCClusters[TPCClusterlist[firstTPCCluster]].Position()[0],
28  TPCClusters[TPCClusterlist[firstTPCCluster]].Position()[1],
29  TPCClusters[TPCClusterlist[firstTPCCluster]].Position()[2]};
30 
31  float tp1[3] = {TPCClusters[TPCClusterlist[intTPCCluster]].Position()[0],
32  TPCClusters[TPCClusterlist[intTPCCluster]].Position()[1],
33  TPCClusters[TPCClusterlist[intTPCCluster]].Position()[2]};
34 
35  float tp2[3] = {TPCClusters[TPCClusterlist[farTPCCluster]].Position()[0],
36  TPCClusters[TPCClusterlist[farTPCCluster]].Position()[1],
37  TPCClusters[TPCClusterlist[farTPCCluster]].Position()[2]};
38 
39  if (printlevel>1)
40  {
41  std::cout << "TPCCluster Dump in initial_trackpar_estimate: " << std::endl;
42  for (size_t i=0;i<nTPCClusters;++i)
43  {
44  size_t ihf = i;
45  std::cout << i << " : " <<
46  TPCClusters[TPCClusterlist[ihf]].Position()[0] << " " <<
47  TPCClusters[TPCClusterlist[ihf]].Position()[1] << " " <<
48  TPCClusters[TPCClusterlist[ihf]].Position()[2] << std::endl;
49  }
50  }
51  if (printlevel>0)
52  {
53  std::cout << "first TPCCluster: " << firstTPCCluster << ", inter TPCCluster: " << intTPCCluster << " " << " far TPCCluster: " << farTPCCluster << std::endl;
54  std::cout << "in the TPCCluster list: " << TPCClusterlist[firstTPCCluster] << " " << TPCClusterlist[intTPCCluster] << " " << TPCClusterlist[farTPCCluster] << std::endl;
55  std::cout << "First TPCCluster x, y, z: " << trackbeg[0] << " " << trackbeg[1] << " " << trackbeg[2] << std::endl;
56  std::cout << "Inter TPCCluster x, y, z: " << tp1[0] << " " << tp1[1] << " " << tp1[2] << std::endl;
57  std::cout << "Far TPCCluster x, y, z: " << tp2[0] << " " << tp2[1] << " " << tp2[2] << std::endl;
58  }
59 
60  xpos = trackbeg[0];
61  ypos = trackbeg[1];
62  zpos = trackbeg[2];
63  x_other_end = TPCClusters[TPCClusterlist[lastTPCCluster]].Position()[0];
64 
65 
66  float ycc=0;
67  float zcc=0;
68  curvature_init = gar::rec::capprox(trackbeg[1],trackbeg[2],tp1[1],tp1[2],tp2[1],tp2[2],ycc,zcc);
69  //std::cout << " inputs to trackpar circ fit (y,z): " << trackbeg[1] << " " << trackbeg[2] << " : "
70  // << tp1[1] << " " << tp1[2] << " : " << tp2[1] << " " << tp2[2] << std::endl;
71  //std::cout << "curvature output: " << curvature_init << std::endl;
72 
73  // redo calc with a circle fit to all points, not just three
74 
75  double dycc=0;
76  double dzcc=0;
77  double drcc=0;
78  double dchisq=0;
79  int ifail=0;
80  std::vector<double> dtpcclusy;
81  std::vector<double> dtpcclusz;
82  for (size_t i=0;i<nTPCClusters; ++i)
83  {
84  dtpcclusy.push_back(TPCClusters[TPCClusterlist[i]].Position()[1]);
85  dtpcclusz.push_back(TPCClusters[TPCClusterlist[i]].Position()[2]);
86  }
87  int ict = nTPCClusters;
88  ouchef(dtpcclusy.data(),dtpcclusz.data(),ict,dycc,dzcc,drcc,dchisq,ifail);
89  if (ifail == 0 && drcc != 0)
90  {
91  ycc = dycc;
92  zcc = dzcc;
93  if (curvature_init < 0) drcc = -std::abs(drcc);
94  //if (ict > 3)
95  // {
96  // std::cout << "updating curvature " << ict << " " << curvature_init << " with " << 1.0/drcc << std::endl;
97  // }
98  curvature_init = 1.0/drcc;
99  }
100 
101 
102  phi_init = TMath::ATan2( trackbeg[2] - zcc, ycc - trackbeg[1] );
103  float phi2 = phi_init;
104  if (curvature_init<0) phi_init += TMath::Pi();
105  float radius_init = 10000;
106  if (curvature_init != 0) radius_init = 1.0/curvature_init;
107 
108  float dx1 = tp2[0] - xpos;
109  if (dx1 != 0)
110  {
111  float dphi2 = TMath::ATan2(tp2[2]-zcc,ycc-tp2[1])-phi2;
112  if (dphi2 > TMath::Pi()) dphi2 -= 2.0*TMath::Pi();
113  if (dphi2 < -TMath::Pi()) dphi2 += 2.0*TMath::Pi();
114  lambda_init = TMath::ATan(1.0/((radius_init/dx1)*dphi2));
115  }
116  else
117  {
118  //std::cout << "initial track par estimate failure" << std::endl;
119  lambda_init = 0;
120  return 1;
121  } // got fMinNumTPCClusters all at exactly the same value of x (they were sorted). Reject track.
122 
123  if (printlevel>0)
124  {
125  std::cout << "phi calc: dz, dy " << tp2[2]-trackbeg[2] << " " << tp2[1]-trackbeg[1] << std::endl;
126  std::cout << "initial curvature, phi, lambda: " << curvature_init << " " << phi_init << " " << lambda_init << std::endl;
127  }
128  return 0;
129 
130 }
void ouchef(double *x, double *y, int np, double &xcirccent, double &ycirccent, double &rcirc, double &chisq, int &ifail)
TH3F * xpos
Definition: doAna.cpp:29
float capprox(float x1, float y1, float x2, float y2, float x3, float y3, float &xc, float &yc)
TH3F * ypos
Definition: doAna.cpp:30
T abs(T value)
TH3F * zpos
Definition: doAna.cpp:31
QTextStream & endl(QTextStream &s)
std::ostream& gar::rec::operator<< ( std::ostream &  o,
gar::rec::VecHit const &  h 
)

Definition at line 39 of file VecHit.cxx.

40  {
41 
42  o << "Vector Hit "
43  << "\n\tposition = ("
44  << h.Position()[0]
45  << ", "
46  << h.Position()[1]
47  << ", "
48  << h.Position()[2]
49  << ")"
50  << "\tdirection = ("
51  << h.Direction()[0]
52  << ", "
53  << h.Direction()[1]
54  << ", "
55  << h.Direction()[2]
56  << ")"
57  << "\tLength = " << h.Length();
58 
59  return o;
60  }
std::ostream& gar::rec::operator<< ( std::ostream &  o,
gar::rec::Cluster const &  h 
)

Definition at line 75 of file Cluster.cxx.

76  {
77  o << "Cluster "
78  << "\n\tEnergy = "
79  << h.Energy()
80  << "\n\tTime = "
81  << h.Time()
82  << "\n\tPID = "
83  << h.ParticleID()
84  << "\n\tID number = "
85  << h.getIDNumber()
86  << "\n\tMain EigenVector = ("
87  << h.EigenVectors()[0] << ", " << h.EigenVectors()[1] << ", " << h.EigenVectors()[2] << ")"
88  << "\n\tPosition = "
89  << h.Position()[0] << ", " << h.Position()[1] << ", " << h.Position()[2] << ")";
90 
91  return o;
92  }
std::ostream& gar::rec::operator<< ( std::ostream &  o,
gar::rec::CaloHit const &  h 
)

Definition at line 98 of file CaloHit.cxx.

99  {
100 
101  o << "CaloHit "
102  << "\n\tID number = "
103  << h.getIDNumber()
104  << "\n\tposition = ("
105  << h.Position()[0]
106  << ", "
107  << h.Position()[1]
108  << ", "
109  << h.Position()[2]
110  << ")"
111  << "\n\tenergy = "
112  << h.Energy()
113  << "\n\t time: "
114  << h.Time().first << " " << h.Time().second
115  << " cellID: "
116  << h.CellID();
117 
118  return o;
119  }
std::ostream& gar::rec::operator<< ( std::ostream &  o,
gar::rec::PFParticle const &  h 
)

Definition at line 106 of file PFParticle.cxx.

107  {
108  o << "Reconstructed Particle "
109  << "\n\tType = "
110  << h.Type()
111  << "\n\tEnergy = "
112  << h.Energy()
113  << "\n\tMomentum = "
114  << h.Momentum()[0] << ", " << h.Momentum()[1] << ", " << h.Momentum()[2] << ")"
115  << "\n\tPID = "
116  << h.Pdg() << ", goodness " << h.GoodnessOfPdg()
117  << "\n\tMass = "
118  << h.Mass()
119  << "\n\tID number = "
120  << h.getIDNumber()
121  << "\n\tPosition = "
122  << h.Position()[0] << ", " << h.Position()[1] << ", " << h.Position()[2] << ")";
123 
124  return o;
125  }
std::ostream& gar::rec::operator<< ( std::ostream &  o,
gar::rec::TPCCluster const &  h 
)

Definition at line 106 of file TPCCluster.cxx.

107  {
108  const float* cov;
109  cov = h.CovMatPacked();
110  o << "TPCCluster "
111  << "\n\tID number = "
112  << h.getIDNumber()
113  << "\n\tposition = ("
114  << h.Position()[0]
115  << ", "
116  << h.Position()[1]
117  << ", "
118  << h.Position()[2]
119  << ")"
120  << "\n\tcovariance matrix = \n\t"
121  << cov[0] << "\t" << cov[1] << "\t" << cov[2] << "\n"
122  << "\t\t" << cov[3] << "\t" << cov[4] << "\n"
123  << "\t\t\t" << cov[5]
124  << "\n\tsignal = "
125  << h.Signal()
126  << "\n\tdrift direction rms = "
127  << h.RMS()
128  << "\n\tstart time: "
129  << h.StartTime()
130  << "\n\tend time: "
131  << h.EndTime();
132 
133  return o;
134  }
std::ostream& gar::rec::operator<< ( std::ostream &  o,
gar::rec::Hit const &  h 
)

Definition at line 128 of file Hit.cxx.

129  {
130 
131  o << "Hit on channel "
132  << h.Channel()
133  << "\n\tposition = ("
134  << h.Position()[0]
135  << ", "
136  << h.Position()[1]
137  << ", "
138  << h.Position()[2]
139  << ")"
140  << "\n\tsignal = "
141  << h.Signal()
142  << "\n\tstart time: "
143  << h.StartTime()
144  << " end time: "
145  << h.EndTime();
146 
147  return o;
148  }
void gar::rec::ouchef ( double *  x,
double *  y,
int  np,
double &  xcirccent,
double &  ycirccent,
double &  rcirc,
double &  chisq,
int &  ifail 
)

Definition at line 643 of file tracker2algs.cxx.

645 {
646 
647  // converted from the original Fortran by T. Junk and de-OPALified -- apologies for the gotos
648 
649  // SUBROUTINE OUCHEF(X,Y,NP,XCIRCCENT,YCIRCCENT,RCIRC,CHISQ,IFAIL)
650  // *
651  // *...OUCHEF circle fit by linear regression method
652  // *.
653  // *. OUCHEF(X,Y,NP,XCIRCCENT,YCIRCCENT,RCIRC,CHISQ,IFAIL)
654  // *.
655  // *. INPUT
656  // *. X(.) x coordinates of points
657  // *. Y(.) y coordinates of points
658  // *. NP number of points
659  // *.
660  // *. OUTPUT
661  // *. XMED, YMED center of circle
662  // *. R radius of circle
663  // *. CHISQ residual sum of squares : to be a chi**2 ,it should
664  // *. be divided by (NP-3)*(mean residual)**2
665  // *.
666  // *. IFAIL error flag : 0 OK
667  // *. 1 less than 3 points
668  // *. 2 no convergence
669  // *. 5 number of points exceeding
670  // *. arrays dimensions -> fit performed
671  // *. with allowed maximum (NPTMAX)
672  // *.
673  // *. AUTHOR : N.Chernov, G.Ososkov
674  // *.
675  // *. written by N. Chernov and G. Ososkov, Dubna,
676  // *. reference: computer physics communications vol 33, p329
677  // *. adapted slightly by F. James, March, 1986
678  // *. further adapted slightly by M.Hansroul May,1989
679  // *.
680  // *. CALLED : any
681  // *.
682  // *. CREATED : 31 May 1989
683  // *. LAST MOD : 11 January 1996
684  // *.
685  // *. Modification Log.:
686  // *. 11-jan-96 M.Hansroul preset chisq to 9999.
687  // *. 12-oct-95 M.Hansroul clean up
688  // *. 12-jul-93 M.Hansroul protection against huge d0
689  // *. put OUATG2 in line
690  // *. 31-May-89 M.Hansroul use OPAL output parameters
691  // *.*********************************************************************
692 
693  const double eps = 1.0e-10;
694  const int itmax=20;
695  const int nptmax=1000;
696  //const double twopi=8.0*atan(1.0);
697  //const double piby2=2.0*atan(1.0);
698 
699  int nptlim=0;
700  int npf=0;
701  int n=0;
702  int ihalf=0;
703  int i=0;
704  int iter=0;
705  int iswap=0;
706  //double sfi0=0;
707  //double cfi0=0;
708  double xmid=0;
709  double ymid=0;
710  double *xf;
711  double *yf;
712  double vlf[2];
713  double vmf[2];
714  //double vlm[2];
715 
716  double alf=0;
717  double alm=0;
718  double a0=0;
719  double a1=0;
720  double a2=0;
721  double a22=0;
722  double bem=0;
723  double bet=0;
724  double cur=0;
725  double cu2=0;
726  double dd=0;
727  double den=0;
728  double det=0;
729  double dy=0;
730  double d2=0;
731  double f=0;
732  double fact=0;
733  double fg=0;
734  double f1=0;
735  double g=0;
736  double gam=0;
737  double gam0=0;
738  double gmm=0;
739  double g1=0;
740  double h=0;
741  double h2=0;
742  double p2=0;
743  double q2=0;
744  double rm=0;
745  double rn=0;
746  double xa=0;
747  double xb=0;
748  double xd=0;
749  double xi=0;
750  double xm=0;
751  double xx=0;
752  double xy=0;
753  double x1=0;
754  double x2=0;
755  double ya=0;
756  double yb=0;
757  double yd=0;
758  double yi=0;
759  double ym=0;
760  double yy=0;
761  double y1=0;
762  double y2=0;
763  double xcd=0;
764  double ycd=0;
765  //double xcycsq=0;
766  //double rcd;
767 
768  //* -----------------------------------------------------------------
769  //* xmid,ymid = centre of fitted circle of radius radfit
770  //* chisq = residual sum of squares per point
771  //* alf,bet,gam,cur = internal parameters of the circle
772 
773  ifail = 0;
774  chisq = 9999.;
775 
776  nptlim = np;
777  if (nptlim>nptmax)
778  {
779  nptlim = nptmax;
780  ifail = 5;
781  return;
782  }
783 
784  npf = nptlim + 1;
785  label_12:
786  npf = npf - 1;
787  if (npf < 2)
788  {
789  ifail = 1;
790  return;
791  }
792  vlf[0] = x[npf-1] - x[0];
793  vlf[1] = y[npf-1] - y[0];
794 
795  //* get a point near the middle
796 
797  ihalf = (npf+1)/2;
798 
799  vmf[0] = x[ihalf-1] - x[0];
800  vmf[1] = y[ihalf-1] - y[0];
801  //vlm[0] = x[npf-1] - x[ihalf-1];
802  //vlm[1] = y[npf-1] - y[ihalf-1];
803 
804  //* check for more than half a cicle of points
805 
806  if (vlf[0]*vmf[0] + vlf[1]*vmf[1] < 0.) goto label_12;
807 
808  //* if the track is nearer to the y axis
809  //* interchange x and y
810 
811  if (fabs(y[npf-1] - y[0]) > fabs(x[npf-1]-x[0]))
812  {
813  yf = x;
814  xf = y;
815  iswap = 1;
816  }
817  else
818  {
819  xf = x;
820  yf = y;
821  iswap = 0;
822  }
823 
824  n = npf;
825  rn = 1./((float) n);
826  xm = 0.;
827  ym = 0.;
828  for (i=0;i<n;++i)
829  {
830  xm = xm + xf[i];
831  ym = ym + yf[i];
832  }
833 
834  xm = xm * rn;
835  ym = ym * rn;
836  x2 = 0.;
837  y2 = 0.;
838  xy = 0.;
839  xd = 0.;
840  yd = 0.;
841  d2 = 0.;
842  for (i=0; i<n; ++i)
843  {
844  xi = xf[i] - xm;
845  yi = yf[i] - ym;
846  xx = xi*xi;
847  yy = yi*yi;
848  x2 = x2 + xx;
849  y2 = y2 + yy;
850  xy = xy + xi*yi;
851  dd = xx + yy;
852  xd = xd + xi*dd;
853  yd = yd + yi*dd;
854  d2 = d2 + dd*dd;
855  }
856 
857  x2 = x2*rn;
858  y2 = y2*rn;
859  xy = xy*rn;
860  d2 = d2*rn;
861  xd = xd*rn;
862  yd = yd*rn;
863  f = 3.*x2 + y2;
864  g = 3.*y2 + x2;
865  fg = f*g;
866  h = xy + xy;
867  h2 = h*h;
868  p2 = xd*xd;
869  q2 = yd*yd;
870  gam0 = x2 + y2;
871  fact = gam0*gam0;
872  a2 = (fg-h2-d2)/fact;
873  fact = fact*gam0;
874  a1 = (d2*(f+g) - 2.*(p2+q2))/fact;
875  fact = fact*gam0;
876  a0 = (d2*(h2-fg) + 2.*(p2*g + q2*f) - 4.*xd*yd*h)/fact;
877  a22 = a2 + a2;
878  yb = 1.0e30;
879  iter = 0;
880  xa = 1.;
881  //* main iteration
882  label_3:
883  ya = a0 + xa*(a1 + xa*(a2 + xa*(xa-4.0)));
884  if (fabs(ya) > fabs(yb)) goto label_4;
885  if (iter >= itmax) goto label_4;
886  dy = a1 + xa*(a22 + xa*(4.*xa - 12.));
887  xb = xa - ya/dy;
888  if (fabs(xa-xb) <= eps) goto label_5;
889  xa = xb;
890  yb = ya;
891  iter = iter + 1;
892  goto label_3;
893 
894  label_4:
895  ifail = 2;
896  //* print 99, iter
897  //* 99 format (' circle - no convergence after',i4,' iterations.')
898  xb = 1.;
899 
900  label_5:
901  gam = gam0*xb;
902  f1 = f - gam;
903  g1 = g - gam;
904  x1 = xd*g1 - yd*h;
905  y1 = yd*f1 - xd*h;
906  det = f1*g1 - h2;
907  den = 1./sqrt(x1*x1 + y1*y1 + gam*det*det);
908  cur = det*den;
909  alf = -(xm*det + x1)*den;
910  bet = -(ym*det + y1)*den;
911  rm = xm*xm + ym*ym;
912  gam = ((rm-gam)*det + 2.*(xm*x1 + ym*y1))*den*0.5;
913  alm = alf + cur*xm;
914  bem = bet + cur*ym;
915 
916  gmm = gam + alf*xm + bet*ym + 0.5*cur*rm;
917  chisq = ((0.5*cur)*(0.5*cur)*d2 + cur*(alm*xd + bem*yd + gmm*gam0)
918  + alm*alm*x2 + bem*bem*y2 + 2.*alm*bem*xy + gmm*gmm) /rn;
919  cu2 = 0.;
920  if (cur != 0.)
921  {
922  cu2 = 1./cur;
923  xcd = -alf*cu2;
924  ycd = -bet*cu2;
925  //rcd = fabs(cu2);
926  xmid = xcd;
927  ymid = ycd;
928  xcirccent = xmid;
929  ycirccent = ymid;
930  if (iswap == 1)
931  {
932  xcirccent = ymid;
933  ycirccent = xmid;
934  }
935  rcirc = cu2;
936  }
937  else
938  {
939  rcirc = 1e6;
940  }
941 
942  return;
943 }
static constexpr double g
Definition: Units.h:144
#define a0
#define a2
std::void_t< T > n
list x
Definition: train.py:276
#define a1
bool gar::rec::sort2_check_cyclic ( std::vector< int > &  link1,
std::vector< int > &  link2,
int  i,
int  j 
)

Definition at line 378 of file tracker2algs.cxx.

379 {
380  if (i == j) return true;
381 
382  int prev = i;
383  int next = (link1.at(i) == -1) ? link2.at(i) : link1.at(i);
384  while (next != -1)
385  {
386  if (next == j) return true;
387  int ptmp = next;
388  next = (link1.at(next) == prev) ? link2.at(next) : link1.at(next);
389  prev = ptmp;
390  }
391  return false;
392 }
void gar::rec::sort_TPCClusters_along_track ( const std::vector< gar::rec::TPCCluster > &  TPCClusters,
std::vector< int > &  hlf,
std::vector< int > &  hlb,
int  printlevel,
float &  lengthforwards,
float &  lengthbackwards,
float  sorttransweight,
float  sortdistback 
)

Definition at line 170 of file tracker2algs.cxx.

178 {
179 
180  // this sorting code appears in the patrec stage too, if only to make tracks that can be drawn
181  // on the event display
182 
183  // find candidate endpoints and sort TPCClusters
184 
185  float cmin[3]; // min x, y, and z coordinates over all TPCClusters
186  float cmax[3]; // max x, y, and z coordinates over all TPCClusters
187  size_t ihex[6]; // index of TPCCluster which gave the min or max ("extreme") 0-2: (min xyz) 3-5 (max xyz)
188 
189 
190  for (size_t iTPCCluster=0; iTPCCluster < TPCClusters.size(); ++iTPCCluster)
191  {
192  for (int i=0; i<3; ++i)
193  {
194  float c = TPCClusters[iTPCCluster].Position()[i];
195  if (iTPCCluster==0)
196  {
197  cmin[i] = c;
198  cmax[i] = c;
199  ihex[i] = 0;
200  ihex[i+3] = 0;
201  }
202  else
203  {
204  if (c<cmin[i])
205  {
206  cmin[i] = c;
207  ihex[i] = iTPCCluster;
208  }
209  if (c>cmax[i])
210  {
211  cmax[i] = c;
212  ihex[i+3] = iTPCCluster;
213  }
214  }
215  }
216  }
217  // now we have six TPCClusters that have the min and max x, y, and z values. Find out which of these six
218  // TPCClusters has the biggest sum of distances to all the other TPCClusters (the most extreme)
219  float sumdmax = 0;
220  size_t imax = 0;
221  for (size_t i=0; i<6; ++i)
222  {
223  float sumd = 0;
224  TVector3 poshc(TPCClusters[ihex[i]].Position());
225  for (size_t iTPCCluster=0; iTPCCluster<TPCClusters.size(); ++iTPCCluster)
226  {
227  TVector3 hp(TPCClusters[iTPCCluster].Position());
228  sumd += (poshc - hp).Mag();
229  }
230  if (sumd > sumdmax)
231  {
232  sumdmax = sumd;
233  imax = i;
234  }
235  }
236 
237  // Use this TPCCluster, indexed by ihex[imax] as a starting point
238  // For cases with less than dmindir length, sort TPCClusters in order of how
239  // far they are from the first TPCCluster. If longer, calculate a curdir vector
240  // and add hits that are a minimum step along curdir
241 
242  hlf.clear();
243  lengthforwards = 0;
244  hlf.push_back(ihex[imax]);
245  TVector3 lpos(TPCClusters[hlf[0]].Position());
246  TVector3 lastpos=lpos;
247  TVector3 cdpos=lpos; // position of the beginning of the direction vector
248  size_t cdposindex=0; // and its index in the hlf vector
249  TVector3 hpadd;
250  TVector3 curdir(0,0,0);
251  bool havecurdir = false;
252  float dmindir=10; // promote to a fcl parameter someday. Distance over which to compute curdir
253 
254  for (size_t inh=1;inh<TPCClusters.size();++inh)
255  {
256  float dmin=0;
257  int jmin=-1;
258  for (size_t jh=0;jh<TPCClusters.size();++jh)
259  {
260  bool found = false;
261  for (size_t kh=0;kh<hlf.size();++kh)
262  {
263  if (hlf[kh] == (int) jh)
264  {
265  found = true;
266  break;
267  }
268  }
269  if (found) continue; // skip if we've already assigned this TPCCluster on this track
270  TVector3 hpos(TPCClusters[jh].Position());
271 
272  float d=0;
273  if (havecurdir)
274  {
275  float dtmp = (hpos-lastpos).Dot(curdir);
276  if (dtmp<-2)
277  {
278  dtmp = -4 - dtmp;
279  }
280  d= dtmp + 0.1 * ((hpos-lastpos).Cross(curdir)).Mag();
281  }
282  else
283  {
284  d=(hpos-lpos).Mag();
285  }
286  if (jmin == -1)
287  {
288  jmin = jh;
289  dmin = d;
290  hpadd = hpos;
291  }
292  else
293  {
294  if (d<dmin)
295  {
296  jmin = jh;
297  dmin = d;
298  hpadd = hpos;
299  }
300  }
301  }
302  // std::cout << "dmin: " << dmin << std::endl;
303  hlf.push_back(jmin);
304  lengthforwards += (hpadd-lastpos).Mag(); // add up track length
305  lastpos = hpadd;
306  if ( (hpadd-cdpos).Mag() > dmindir)
307  {
308  TVector3 cdcand(TPCClusters[hlf[cdposindex]].Position());
309  size_t itctmp = cdposindex;
310  for (size_t itc=cdposindex+1; itc<hlf.size(); ++itc)
311  {
312  TVector3 cdcandt(TPCClusters[hlf[itc]].Position());
313  if ( (hpadd-cdcandt).Mag() < dmindir )
314  {
315  break;
316  }
317  else
318  {
319  itctmp = itc;
320  cdcand = cdcandt;
321  }
322  }
323  //std::cout << "Updated curdir: " << cdposindex << " " << itctmp << " " << curdir.X() << " " << curdir.Y() << " " << curdir.Z() << " ";
324  cdposindex = itctmp;
325  cdpos = cdcand;
326  curdir = hpadd - cdcand;
327  curdir *= (1.0/curdir.Mag());
328  //std::cout << "To: " << curdir.X() << " " << curdir.Y() << " " << curdir.Z() << std::endl;
329  havecurdir = true;
330  }
331  }
332 
333  if (printlevel>2)
334  {
335  for (size_t iTPCCluster=0; iTPCCluster<TPCClusters.size(); ++iTPCCluster)
336  {
337  printf("Sort compare: %5d %10.3f %10.3f %10.3f %5d %10.3f %10.3f %10.3f\n",
338  (int) iTPCCluster,
339  TPCClusters[iTPCCluster].Position()[0],
340  TPCClusters[iTPCCluster].Position()[1],
341  TPCClusters[iTPCCluster].Position()[2],
342  hlf[iTPCCluster],
343  TPCClusters[hlf[iTPCCluster]].Position()[0],
344  TPCClusters[hlf[iTPCCluster]].Position()[1],
345  TPCClusters[hlf[iTPCCluster]].Position()[2]);
346  }
347  }
348 
349  // now go backwards -- just invert the sort order
350 
351  hlb.clear();
352  for (size_t i=0; i< hlf.size(); ++i)
353  {
354  hlb.push_back(hlf[hlf.size()-1-i]); // just invert the order for the backward sort
355  }
356  lengthbackwards = lengthforwards;
357 
358  if (printlevel>2)
359  {
360  for (size_t iTPCCluster=0; iTPCCluster<TPCClusters.size(); ++iTPCCluster)
361  {
362  printf("Backward Sort compare: %5d %10.3f %10.3f %10.3f %5d %10.3f %10.3f %10.3f\n",
363  (int) iTPCCluster,
364  TPCClusters[iTPCCluster].Position()[0],
365  TPCClusters[iTPCCluster].Position()[1],
366  TPCClusters[iTPCCluster].Position()[2],
367  hlb[iTPCCluster],
368  TPCClusters[hlb[iTPCCluster]].Position()[0],
369  TPCClusters[hlb[iTPCCluster]].Position()[1],
370  TPCClusters[hlb[iTPCCluster]].Position()[2]);
371  }
372  }
373 }
int imax
Definition: tracks.py:195
void gar::rec::sort_TPCClusters_along_track2 ( const std::vector< gar::rec::TPCCluster > &  TPCClusters,
std::vector< int > &  hlf,
std::vector< int > &  hlb,
int  printlevel,
float &  lengthforwards,
float &  lengthbackwards,
float  dcut 
)

Definition at line 399 of file tracker2algs.cxx.

406 {
407  size_t nclus = TPCClusters.size();
408  hlf.clear();
409  hlb.clear();
410  lengthforwards = 0;
411  lengthbackwards = 0;
412  if (nclus == 0) return;
413  if (nclus == 1)
414  {
415  hlf.push_back(0);
416  hlb.push_back(0);
417  return;
418  }
419 
420  size_t ndists = nclus*(nclus-1)/2;
421  std::vector<float> dists(ndists);
422  std::vector<int> dsi(ndists);
423  std::vector<int> link1(nclus,-1);
424  std::vector<int> link2(nclus,-1);
425  for (size_t i=0; i<nclus-1; ++i)
426  {
427  TVector3 iclus(TPCClusters.at(i).Position());
428  for (size_t j=i+1; j<nclus; ++j)
429  {
430  TVector3 jclus(TPCClusters.at(j).Position());
431  float d = (iclus-jclus).Mag();
432  dists.at(ij2idxsort2(nclus,i,j)) = d;
433  }
434  }
435  TMath::Sort( (int) ndists, dists.data(), dsi.data(), false );
436  //std::cout << "Dists sorting: " << std::endl;
437  //for (size_t i=0; i<ndists; ++i)
438  // {
439  // std::cout << i << " " << dists[i] << " " << dists[dsi[i]] << std::endl;
440  // }
441 
442  // greedy pairwise association -- may end up leaving some hits stranded
443 
444  for (size_t k=0; k<ndists; ++k)
445  {
446  size_t i = 0;
447  size_t j = 0;
448  size_t k2 = dsi.at(k);
449  if (dists.at(k2) > dcut) break;
450  idx2ijsort2(nclus,k2,i,j);
451  TVector3 iclus(TPCClusters.at(i).Position());
452  TVector3 jclus(TPCClusters.at(j).Position());
453 
454  if (link1.at(i) == -1)
455  {
456  if (link1.at(j) == -1)
457  {
458  link1.at(i) = j;
459  link1.at(j) = i;
460  }
461  else // already have a link on j'th cluster, add a second one only if it's on the other side
462  {
463  if (link2.at(j) == -1)
464  {
465  TVector3 j2clus(TPCClusters.at(link1.at(j)).Position());
466 
467  // old test on angle instead of cyclicness
468  //if ( (j2clus-jclus).Angle(iclus-jclus) > TMath::Pi()/2)
469 
470  if (!sort2_check_cyclic(link1,link2,j,i))
471  {
472  link1.at(i) = j;
473  link2.at(j) = i;
474  }
475  }
476  }
477  }
478  else
479  {
480  if (link2.at(i) == -1)
481  {
482  if (link1.at(j) == -1)
483  {
484  link2.at(i) = j;
485  link1.at(j) = i;
486  }
487  else // already have a link on j'th cluster, add a second one only if it's on the other side
488  {
489  if (link2.at(j) == -1)
490  {
491  TVector3 j2clus(TPCClusters.at(link1.at(j)).Position());
492 
493  // old test on angle instead of cyclicness
494  //if ( (j2clus-jclus).Angle(iclus-jclus) > TMath::Pi()/2)
495 
496  if (!sort2_check_cyclic(link1,link2,j,i))
497  {
498  link2.at(i) = j;
499  link2.at(j) = i;
500  }
501  }
502  }
503  }
504  }
505  }
506 
507  //std::cout << "sorting clusters and links" << std::endl;
508  //for (size_t i=0; i<nclus; ++i)
509  // {
510  // std::cout << i << " " << link1.at(i) << " " << link2.at(i) << " " <<
511  // TPCClusters.at(i).Position()[0] << " " <<
512  // TPCClusters.at(i).Position()[1] << " " <<
513  // TPCClusters.at(i).Position()[2] << std::endl;
514  //}
515 
516  std::vector<int> used(nclus,-1);
517  std::vector<std::vector<int> > clistv;
518 
519  // find the first tpc cluster with just one link
520 
521  int ifirst = -1;
522  for (size_t i=0; i<nclus; ++i)
523  {
524  int il1 = link1.at(i);
525  int il2 = link2.at(i);
526 
527  if ( (il1 == -1 && il2 != -1) || (il1 != -1 && il2 == -1) )
528  {
529  ifirst = i;
530  break;
531  }
532  }
533  // this can happen if all TPC clusters are singletons -- no links anywhere. Happens if
534  // there are no TPC clusters at all or just one.
535  if (ifirst == -1)
536  {
537  return;
538  }
539 
540  // follow the chains
541 
542  for (size_t i=ifirst; i<nclus; ++i)
543  {
544  if (used.at(i) == 1) continue;
545  std::vector<int> clist;
546  clist.push_back(i);
547  used.at(i) = 1;
548 
549  int idx = i;
550  int il1 = link1.at(idx);
551  int il2 = link2.at(idx);
552 
553  int u1 = -2;
554  if (il1 != -1) u1 = used.at(il1);
555  int u2 = -2;
556  if (il2 != -1) u2 = used.at(il2);
557 
558  while (u1 == -1 || u2 == -1)
559  {
560  idx = (u1 == -1) ? il1 : il2;
561  clist.push_back(idx);
562  used.at(idx) = 1;
563  il1 = link1.at(idx);
564  il2 = link2.at(idx);
565  u1 = -2;
566  if (il1 != -1) u1 = used.at(il1);
567  u2 = -2;
568  if (il2 != -1) u2 = used.at(il2);
569  }
570  clistv.push_back(clist);
571  }
572 
573  // temporary solution -- think about what to do. Report the longest chain
574 
575  size_t msize=0;
576  int ibest=-1;
577  for (size_t ichain=0; ichain<clistv.size(); ++ichain)
578  {
579  size_t cursize = clistv.at(ichain).size();
580  if (cursize > msize)
581  {
582  ibest = ichain;
583  msize = cursize;
584  }
585  }
586  if (ibest == -1) return;
587 
588  for (size_t i=0; i<clistv.at(ibest).size(); ++i)
589  {
590  hlf.push_back(clistv[ibest].at(i));
591  if (i>0)
592  {
593  TVector3 lastpoint(TPCClusters.at(hlf.at(i-1)).Position());
594  TVector3 curpoint(TPCClusters.at(hlf.at(i)).Position());
595  lengthforwards += (curpoint-lastpoint).Mag();
596  }
597  }
598  for (size_t i=0; i< hlf.size(); ++i)
599  {
600  hlb.push_back(hlf[hlf.size()-1-i]); // just invert the order for the backward sort
601  }
602  lengthbackwards = lengthforwards;
603 
604 }
bool sort2_check_cyclic(std::vector< int > &link1, std::vector< int > &link2, int i, int j)
size_t ij2idxsort2(size_t nclus, size_t i, size_t j)
void idx2ijsort2(size_t nclus, size_t idx, size_t &i, size_t &j)

Variable Documentation

TrackEnd const gar::rec::TrackEndBeg = 1

Definition at line 33 of file Track.h.

TrackEnd const gar::rec::TrackEndEnd = 0

Definition at line 33 of file Track.h.