11 #include <Geant4/G4SystemOfUnits.hh>
13 #include <TMatrixFfwd.h>
15 #include <TMatrixTUtils.h>
19 #define LogDebug(exp) std::cout << "DEBUG: " << __FILE__ << ": " << __LINE__ << ": " << exp
21 #define LogDebug(exp) (void)0
24 #define LogError(exp) if(Verbosity()>0) std::cout << "ERROR: " << __FILE__ << ": " << __LINE__ << ": " << exp
25 #define LogWarning(exp) if(Verbosity()>0) std::cout << "WARNING: " << __FILE__ << ": " << __LINE__ << ": " << exp
27 using keylist = std::vector<TrkrDefs::cluskey>;
33 template<
class T>
inline constexpr
T square(
const T&
x ) {
return x*
x; }
40 if(
Verbosity()>0) std::cout <<
"WARNING: " << name <<
" is NaN for seed " << num <<
". Aborting this seed.\n";
42 return std::isnan(val);
48 double p[4] = {x*
cm,y*
cm,z*
cm,0.*cm};
51 return bfield[2]/tesla;
63 TMatrixF localErr(3,3);
65 double clusRadius = sqrt(global[0]*global[0] + global[1]*global[1]);
72 localErr[1][1] = para_errors.first;
76 localErr[2][2] = para_errors.second;
78 float clusphi = atan2(global(1), global(0));
80 ROT[0][0] = cos(clusphi);
81 ROT[0][1] = -sin(clusphi);
83 ROT[1][0] = sin(clusphi);
84 ROT[1][1] = cos(clusphi);
93 err = ROT * localErr * ROT_T;
103 std::vector<TrackSeed_v1> seeds_vector;
104 std::vector<Eigen::Matrix<double,6,6>> alice_seeds_vector;
108 for(
auto trackKeyChain:trackSeedKeyLists )
110 if(trackKeyChain.size()<2)
continue;
115 const auto& globalpos = globalPositions.at(trackKeyChain.at(0));
116 double x0 = globalpos(0);
117 double y0 = globalpos(1);
118 double z0 = globalpos(2);;
119 LogDebug(
"Initial (x,y,z): (" << x0 <<
"," << y0 <<
"," << z0 <<
")" << std::endl);
121 double alice_x0 = sqrt(x0*x0+y0*y0);
123 double alice_z0 = z0;
127 trackSeed.
SetX(alice_x0);
128 trackSeed.
SetY(alice_y0);
129 trackSeed.
SetZ(alice_z0);
134 double alice_x = sqrt(x0*x0+y0*y0);
136 double trackCartesian_x = 0.;
137 double trackCartesian_y = 0.;
138 double trackCartesian_z = 0.;
140 const auto& secondpos = globalPositions.at(trackKeyChain.at(1));
142 const double second_x = secondpos(0);
143 const double second_y = secondpos(1);
144 const double second_z = secondpos(2);
145 const double first_phi = atan2(y0,x0);
146 const double second_alice_x = second_x*std::cos(first_phi)+second_y*std::sin(first_phi);
147 const double delta_alice_x = second_alice_x - alice_x0;
149 const double second_alice_y = -second_x*std::sin(first_phi)+second_y*std::cos(first_phi);
150 const double init_SinPhi = second_alice_y / std::sqrt(
square(delta_alice_x) +
square(second_alice_y));
151 const double delta_z = second_z - z0;
152 const double init_DzDs = -delta_z / std::sqrt(
square(delta_alice_x) +
square(second_alice_y));
154 LogDebug(
"Set initial SinPhi to " << init_SinPhi << std::endl);
156 LogDebug(
"Set initial DzDs to " << init_DzDs << std::endl);
159 std::vector<std::pair<double,double>> pts;
162 const auto& clpos = globalPositions.at(key);
163 return std::make_pair(clpos(0),clpos(1));
167 if(
Verbosity()>1) std::cout <<
"circle fit parameters: R=" << R <<
", X0=" << x_center <<
", Y0=" << y_center << std::endl;
171 if( std::isnan(R) )
continue;
173 double init_QPt = 1./(0.3*R/100.*
get_Bz(x0,y0,z0));
175 double phi_first = atan2(y0,x0);
176 if(
Verbosity()>1) std::cout <<
"phi_first: " << phi_first << std::endl;
177 double phi_second = atan2(second_y,second_x);
178 if(
Verbosity()>1) std::cout <<
"phi_second: " << phi_second << std::endl;
179 double dphi = phi_second - phi_first;
180 if(
Verbosity()>1) std::cout <<
"dphi: " << dphi << std::endl;
181 if(dphi>M_PI) dphi = 2*M_PI -
dphi;
182 if(dphi<-M_PI) dphi = 2*M_PI +
dphi;
183 if(
Verbosity()>1) std::cout <<
"corrected dphi: " << dphi << std::endl;
184 if(dphi<0) init_QPt = -1*init_QPt;
185 LogDebug(
"initial QPt: " << init_QPt << std::endl);
186 trackSeed.
SetQPt(init_QPt);
192 LogDebug(std::endl << std::endl <<
"------------------------" << std::endl <<
"seed size: " << trackKeyChain.size() << std::endl << std::endl << std::endl);
196 std::vector<double> cx;
197 std::vector<double> cy;
198 std::vector<double> cz;
199 std::vector<double> tx;
200 std::vector<double> ty;
201 std::vector<double> tz;
202 std::vector<double> xerr;
203 std::vector<double> yerr;
204 std::vector<double> zerr;
205 std::vector<double>
layer;
206 std::vector<double> xsize;
207 std::vector<double> ysize;
209 std::vector<double> phierr;
210 std::vector<double>
zsize;
211 for(
auto clusterkey =
std::next(trackKeyChain.begin()); clusterkey != trackKeyChain.end(); ++clusterkey)
213 if(std::isnan(trackSeed.
GetX()) ||
214 std::isnan(trackSeed.
GetY()) ||
215 std::isnan(trackSeed.
GetZ()))
continue;
216 LogDebug(
"-------------------------------------------------------------" << std::endl);
217 LogDebug(
"cluster " << cluster_ctr <<
" -> " << cluster_ctr + 1 << std::endl);
218 LogDebug(
"this cluster (x,y,z) = (" << x <<
"," << y <<
"," << z <<
")" << std::endl);
222 const auto& nextpos = globalPositions.at(*clusterkey);
225 double nextCluster_x = nextpos(0);
226 double nextCluster_xerr = sqrt(
getClusterError(nextCluster,*clusterkey,nextpos,0,0));
227 double nextCluster_y = nextpos(1);
228 double nextCluster_yerr = sqrt(
getClusterError(nextCluster,*clusterkey,nextpos,1,1));
229 double nextCluster_z = nextpos(2);
230 double nextCluster_zerr = sqrt(
getClusterError(nextCluster,*clusterkey,nextpos,2,2));
232 double newPhi = atan2(nextCluster_y,nextCluster_x);
233 LogDebug(
"new phi = " << newPhi << std::endl);
234 double oldPhi = atan2(y,x);
235 LogDebug(
"old phi = " << oldPhi << std::endl);
236 double alpha = newPhi - oldPhi;
237 LogDebug(
"alpha = " << alpha << std::endl);
240 LogWarning(
"Rotate failed! Aborting for this seed...\n");
244 double nextAlice_x = nextCluster_x*cos(newPhi)+nextCluster_y*sin(newPhi);
245 LogDebug(
"track coordinates (ALICE) after rotation: (" << trackSeed.
GetX() <<
"," << trackSeed.
GetY() <<
"," << trackSeed.
GetZ() <<
")" << std::endl);
246 LogDebug(
"Transporting from " << alice_x <<
" to " << nextAlice_x <<
"...");
247 double track_x = trackSeed.
GetX()*cos(newPhi)-trackSeed.
GetY()*sin(newPhi);
248 double track_y = trackSeed.
GetX()*sin(newPhi)+trackSeed.
GetY()*cos(newPhi);
249 double track_z = trackSeed.
GetZ();
252 LogWarning(
"Transport failed! Aborting for this seed...\n");
258 LogWarning(
"Rotate failed! Aborting for this seed...\n");
264 LogWarning(
"Transport failed! Aborting for this seed...\n");
271 double predicted_alice_x = trackSeed.
GetX();
272 LogDebug(
"new track ALICE x = " << trackSeed.
GetX() << std::endl);
273 double predicted_alice_y = trackSeed.
GetY();
274 LogDebug(
"new track ALICE y = " << trackSeed.
GetY() << std::endl);
275 double predicted_z = trackSeed.
GetZ();
276 LogDebug(
"new track z = " << trackSeed.
GetZ() << std::endl);
277 double cos_phi = x/sqrt(x*x+y*y);
278 LogDebug(
"cos_phi = " << cos_phi << std::endl);
279 double sin_phi = y/sqrt(x*x+y*y);
280 LogDebug(
"sin phi = " << sin_phi << std::endl);
281 trackCartesian_x = predicted_alice_x*cos_phi-predicted_alice_y*sin_phi;
282 trackCartesian_y = predicted_alice_x*sin_phi+predicted_alice_y*cos_phi;
283 trackCartesian_z = predicted_z;
284 LogDebug(
"Track transported to (x,y,z) = (" << trackCartesian_x <<
"," << trackCartesian_y <<
"," << trackCartesian_z <<
")" << std::endl);
285 LogDebug(
"Track position ALICE Y error: " << sqrt(trackSeed.
GetCov(0)) << std::endl);
286 LogDebug(
"Track position x error: " << sqrt(trackSeed.
GetCov(0))*sin_phi << std::endl);
287 LogDebug(
"Track position y error: " << sqrt(trackSeed.
GetCov(0))*cos_phi << std::endl);
288 LogDebug(
"Track position z error: " << sqrt(trackSeed.
GetCov(5)) << std::endl);
289 LogDebug(
"Next cluster is at (x,y,z) = (" << nextCluster_x <<
"," << nextCluster_y <<
"," << nextCluster_z <<
")" << std::endl);
290 LogDebug(
"Cluster errors: (" << nextCluster_xerr <<
", " << nextCluster_yerr <<
", " << nextCluster_zerr <<
")" << std::endl);
291 LogDebug(
"track coordinates (ALICE) after rotation: (" << trackSeed.
GetX() <<
"," << trackSeed.
GetY() <<
"," << trackSeed.
GetZ() <<
")" << std::endl);
294 double nextCluster_alice_y = -nextCluster_x*sin(newPhi)+nextCluster_y*cos(newPhi);
295 LogDebug(
"next cluster ALICE y = " << nextCluster_alice_y << std::endl);
296 double y2_error =
getClusterError(nextCluster,*clusterkey,nextpos,0,0)*sin(newPhi)*sin(newPhi)+2*
getClusterError(nextCluster,*clusterkey,nextpos,0,1)*cos(newPhi)*sin(newPhi)+
getClusterError(nextCluster,*clusterkey,nextpos,1,1)*cos(newPhi)*cos(newPhi);
297 double z2_error =
getClusterError(nextCluster,*clusterkey,nextpos,2,2);
305 if(!trackSeed.
Filter(nextCluster_alice_y,nextCluster_z,y2_error,z2_error,
_max_sin_phi))
307 LogError(
"Kalman filter failed for seed " << nseeds <<
"! Aborting for this seed..." << std::endl);
312 double track_pt = 1./trackSeed.
GetQPt();
313 double track_pY = track_pt*trackSeed.
GetSinPhi();
314 double track_pX = sqrt(track_pt*track_pt-track_pY*track_pY);
315 double track_px = track_pX*cos(newPhi)-track_pY*sin(newPhi);
316 double track_py = track_pX*sin(newPhi)+track_pY*cos(newPhi);
317 double track_pz = -track_pt*trackSeed.
GetDzDs();
320 LogDebug(
"track pt = " << track_pt <<
" +- " << track_pterr << std::endl);
321 LogDebug(
"track ALICE p = (" << track_pX <<
", " << track_pY <<
", " << track_pz <<
")" << std::endl);
322 LogDebug(
"track p = (" << track_px <<
", " << track_py <<
", " << track_pz <<
")" << std::endl);
327 alice_x = nextAlice_x;
334 float nextclusrad = std::sqrt(nextCluster_x*nextCluster_x +
335 nextCluster_y*nextCluster_y);
336 float nextclusphierr = nextCluster->
getRPhiError() / nextclusrad;;
338 cx.push_back(nextCluster_x);
339 cy.push_back(nextCluster_y);
340 cz.push_back(nextCluster_z);
341 tx.push_back(trackCartesian_x);
342 ty.push_back(trackCartesian_y);
343 tz.push_back(trackCartesian_z);
344 xerr.push_back(nextCluster_xerr);
345 yerr.push_back(nextCluster_yerr);
346 zerr.push_back(nextCluster_zerr);
348 phierr.push_back(nextclusphierr);
354 double track_phi = atan2(y,x);
356 double track_pt = fabs(1./trackSeed.
GetQPt());
358 double track_pY = track_pt*trackSeed.
GetSinPhi();
359 double track_pX = sqrt(track_pt*track_pt-track_pY*track_pY);
360 double track_px = track_pX*cos(track_phi)-track_pY*sin(track_phi);
361 double track_py = track_pX*sin(track_phi)+track_pY*cos(track_phi);
362 double track_pz = track_pt*trackSeed.
GetDzDs();
366 if(trackKeyChain.size()<10) track_pt = fabs(1./init_QPt);
367 LogDebug(
"track pt = " << track_pt <<
" +- " << track_pterr << std::endl);
368 LogDebug(
"track ALICE p = (" << track_pX <<
", " << track_pY <<
", " << track_pz <<
")" << std::endl);
369 LogDebug(
"track p = (" << track_px <<
", " << track_py <<
", " << track_pz <<
")" << std::endl);
384 if(
checknan(track_pt,
"pT",nseeds))
continue;
386 if(
checknan(track_pterr,
"pT err",nseeds))
continue;
387 LogDebug(
"Track pterr = " << track_pterr << std::endl);
388 double track_x = trackSeed.
GetX()*cos(track_phi)-trackSeed.
GetY()*sin(track_phi);
389 double track_y = trackSeed.
GetX()*sin(track_phi)+trackSeed.
GetY()*cos(track_phi);
390 double track_z = trackSeed.
GetZ();
391 if(
checknan(track_z,
"z",nseeds))
continue;
392 double track_zerr = sqrt(trackSeed.
GetErr2Z());
393 if(
checknan(track_zerr,
"zerr",nseeds))
continue;
395 const auto& lclusterglob = globalPositions.at(trackKeyChain.back());
396 const float lclusterrad = sqrt(lclusterglob(0)*lclusterglob(0) + lclusterglob(1)*lclusterglob(1));
397 double last_cluster_phierr = lcluster->getRPhiError() / lclusterrad;;
400 double track_phierr = sqrt(pow(last_cluster_phierr,2)+(pow(trackSeed.
GetX(),2)*trackSeed.
GetErr2Y()) /
401 pow(pow(trackSeed.
GetX(),2)+pow(trackSeed.
GetY(),2),2));
402 if(
checknan(track_phierr,
"phierr",nseeds))
continue;
403 LogDebug(
"Track phi = " << atan2(track_py,track_px) << std::endl);
404 LogDebug(
"Track phierr = " << track_phierr << std::endl);
406 if(
checknan(track_curvature,
"curvature",nseeds))
continue;
408 if(
checknan(track_curverr,
"curvature error",nseeds))
continue;
411 for (
unsigned int j = 0;
j < trackKeyChain.size(); ++
j)
416 int track_charge = 0;
420 double s = sin(track_phi);
421 double c = cos(track_phi);
432 double d = trackSeed.
GetDzDs();
433 if(
checknan(d,
"ALICE dz/ds",nseeds))
continue;
445 bool cov_nan =
false;
446 for(
int i=0;
i<15;
i++)
450 if(cov_nan)
continue;
452 Eigen::Matrix<double,5,5> ecov;
488 Eigen::Matrix<double,6,5>
J;
509 J(3,2) = -track_pt*(p*c/sqrt(1-p*p)+
s);
511 J(3,4) = track_pt*track_pt*track_charge*(p*s-c*sqrt(1-p*p));
515 J(4,2) = track_pt*(c-p*s/sqrt(1-p*p));
517 J(4,4) = -track_pt*track_pt*track_charge*(p*c+s*sqrt(1-p*p));
523 J(5,4) = -track_pt*track_pt*track_charge*d;
539 Eigen::Matrix<double,6,6> scov = J*ecov*J.transpose();
608 seeds_vector.push_back(track);
609 alice_seeds_vector.push_back(scov);
610 trackChi2.push_back(trackSeed.
GetChi2() / trackSeed.
GetNDF());
617 if(
Verbosity()>0) std::cout <<
"number of seeds: " << nseeds <<
"\n";
619 return std::make_pair(seeds_vector, alice_seeds_vector);
626 Eigen::LLT<Eigen::Matrix<double,6,6>> chDec(cov);
628 return (chDec.info() != Eigen::NumericalIssue);
633 Eigen::Matrix<double,6,6> repaircov =
cov;
635 Eigen::SelfAdjointEigenSolver<Eigen::Matrix<double,6,6>> solver(repaircov);
636 Eigen::Matrix<double,6,1>
D = solver.eigenvalues();
637 Eigen::Matrix<double,6,6>
Q = solver.eigenvectors();
638 Eigen::Matrix<double,6,1> Dp = D.cwiseMax(1
e-15);
639 Eigen::Matrix<double,6,6>
Z = Q*Dp.asDiagonal()*Q.transpose();
653 std::vector<double> residues;
654 std::transform( points.begin(), points.end(), std::back_inserter( residues ), [
R,
X0,
Y0](
const std::pair<double,double>&
point )
667 std::vector<double> residues;
669 std::transform( points.begin(), points.end(), std::back_inserter( residues ), [
A,B](
const std::pair<double,double>&
point )