ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SimpleTrack3D.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file SimpleTrack3D.cpp
1 #include "SimpleTrack3D.h"
2 
3 #include <Eigen/Core> // for MatrixXf, Product, Transpose
4 #include <Eigen/Dense>
5 
6 #include <cfloat>
7 #include <climits>
8 #include <cmath> // for sqrt
9 #include <memory> // for allocator_traits<>::value...
10 
11 using namespace std;
12 using namespace Eigen;
13 
15  : hits(std::vector<SimpleHit3D> ()),
16  phi(FLT_MAX),
17  d(FLT_MAX),
18  kappa(FLT_MAX),
19  dzdl(FLT_MAX),
20  z0(FLT_MAX),
21  index(UINT_MAX),
22  vertex_id(UINT_MAX)
23 {
24 
25 }
26 
28  hits.clear();
29  cluster_ids.clear();
30 }
31 
33 /*
34  cout << "SimpleTrack3D: "
35  << "id: " << index
36  << "(phi,d,kappa,dzdl,z0) = (" << phi << "," << d << "," << kappa <<","<<dzdl<<","<<z0 << ") "
37  << endl;
38 */
39  std::vector<float> chi2_hit;
40  chi2_hit.clear();
41  std::vector<float> xy_res;
42  std::vector<float> xy_res_inv;
43  std::vector<float> z_res;
44  std::vector<float> z_res_inv;
45 
46  for (unsigned int i = 0; i < hits.size(); i++) {
47 
48  float ex = (2.0*sqrt(hits[i].get_size(0,0))) * scale;
49  float ey = (2.0*sqrt(hits[i].get_size(1,1))) * scale;
50  float ez = (2.0*sqrt(hits[i].get_size(2,2))) * scale;
51 
52  if (hits[i].get_layer() < 0) {
53  ex = 0.0001 * scale;
54  ey = 0.0001 * scale;
55  ez = 0.0001 * scale;
56  }
57 
58  xy_res.push_back(sqrt( ex * ex + ey * ey ));
59  xy_res_inv.push_back(1. / xy_res.back());
60  z_res.push_back( ez );
61  z_res_inv.push_back(1. / z_res.back());
62  }
63 
64  chi2_hit.resize(hits.size(), 0.);
65 
66  MatrixXf y = MatrixXf::Zero(hits.size(), 1);
67  for (unsigned int i = 0; i <hits.size(); i++) {
68  y(i, 0) = (pow(hits[i].get_x(), 2) + pow(hits[i].get_y(), 2));
69  y(i, 0) *= xy_res_inv[i];
70  }
71 
72  MatrixXf X = MatrixXf::Zero(hits.size(), 3);
73  for (unsigned int i = 0; i < hits.size(); i++) {
74  X(i, 0) = hits[i].get_x();
75  X(i, 1) = hits[i].get_y();
76  X(i, 2) = -1.;
77  X(i, 0) *= xy_res_inv[i];
78  X(i, 1) *= xy_res_inv[i];
79  X(i, 2) *= xy_res_inv[i];
80  }
81 
82  MatrixXf Xt = X.transpose();
83 
84  MatrixXf prod = Xt * X;
85 
86  MatrixXf Xty = Xt * y;
87  MatrixXf beta = prod.ldlt().solve(Xty);
88 
89  float cx = beta(0, 0) * 0.5;
90  float cy = beta(1, 0) * 0.5;
91  float r = sqrt(cx * cx + cy * cy - beta(2, 0));
92 
93  phi = atan2(cy, cx);
94  d = sqrt(cx * cx + cy * cy) - r;
95  kappa = 1. / r;
96 
97  MatrixXf diff = y - (X * beta);
98  MatrixXf chi2 = (diff.transpose()) * diff;
99 
100  float dx = d * cos(phi);
101  float dy = d * sin(phi);
102 
103  MatrixXf y2 = MatrixXf::Zero(hits.size(), 1);
104  for (unsigned int i = 0; i < hits.size(); i++) {
105  y2(i, 0) = hits[i].get_z();
106  y2(i, 0) *= z_res_inv[i];
107  }
108 
109  MatrixXf X2 = MatrixXf::Zero(hits.size(), 2);
110  for (unsigned int i = 0; i < hits.size(); i++) {
111  float D = sqrt(pow(dx - hits[i].get_x(), 2) + pow(dy - hits[i].get_y(), 2));
112  float s = 0.0;
113 
114  if (0.5 * kappa * D > 0.1) {
115  float v = 0.5 * kappa * D;
116  if (v >= 0.999999) {
117  v = 0.999999;
118  }
119  s = 2. * asin(v) / kappa;
120  } else {
121  float temp1 = kappa * D * 0.5;
122  temp1 *= temp1;
123  float temp2 = D * 0.5;
124  s += 2. * temp2;
125  temp2 *= temp1;
126  s += temp2 / 3.;
127  temp2 *= temp1;
128  s += (3. / 20.) * temp2;
129  temp2 *= temp1;
130  s += (5. / 56.) * temp2;
131  }
132 
133  X2(i, 0) = s;
134  X2(i, 1) = 1.0;
135 
136  X2(i, 0) *= z_res_inv[i];
137  X2(i, 1) *= z_res_inv[i];
138  }
139 
140  MatrixXf Xt2 = X2.transpose();
141  MatrixXf prod2 = Xt2 * X2;
142 
143  MatrixXf Xty2 = Xt2 * y2;
144  MatrixXf beta2 = prod2.ldlt().solve(Xty2);
145 
146  MatrixXf diff2 = y2 - (X2 * beta2);
147  MatrixXf chi2_z = (diff2.transpose()) * diff2;
148 
149  z0 = beta2(1, 0);
150  dzdl = beta2(0, 0) / sqrt(1. + beta2(0, 0) * beta2(0, 0));
151 
152 
153  if (kappa != 0.) {
154  r = 1. / kappa;
155  } else {
156  r = 1.0e10;
157  }
158 
159  cx = (d + r) * cos(phi);
160  cy = (d + r) * sin(phi);
161 
162  float chi2_tot = 0.;
163  for (unsigned int h = 0; h < hits.size(); h++) {
164  float dx1 = hits[h].get_x() - cx;
165  float dy1 = hits[h].get_y() - cy;
166 
167  float dx2 = hits[h].get_x() + cx;
168  float dy2 = hits[h].get_y() + cy;
169 
170  float xydiff1 = sqrt(dx1 * dx1 + dy1 * dy1) - r;
171  float xydiff2 = sqrt(dx2 * dx2 + dy2 * dy2) - r;
172  float xydiff = xydiff2;
173  if (fabs(xydiff1) < fabs(xydiff2)) {
174  xydiff = xydiff1;
175  }
176 
177  float ls_xy = xy_res[h];
178 
179  chi2_hit[h] = 0.;
180  chi2_hit[h] += xydiff * xydiff / (ls_xy * ls_xy);
181  chi2_hit[h] += diff2(h, 0) * diff2(h, 0);
182 
183  chi2_tot += chi2_hit[h];
184  }
185 
186  unsigned int deg_of_freedom = 2 * hits.size() - 5;
187 
188  return (chi2_tot) / ((float)(deg_of_freedom));
189 
190 }
191