Functions | |
| void | PredictXY (const double *x1, const double *sig1, const double *x2, const double *sig2, double *x3, double *sig3) |
| Predicts what XY position of a straight line would be if points x1 and x2 are on a straight line. | |
| double | FitLineFromWires (int n, const double *u, const double *w, const double *z, const double *cosA, const double *sinA, double z1, double z2, double par[4], double parErr[4]) |
| Fits a straight line to a set of wires. | |
| double | FitCurvedTrack (int n, const double *u, const double *w, const double *z, const double *cosA, const double *sinA, double z0, const double *lambdaX, const double *lambdaY, double par[5], double parErr[5]) |
| This function does a non-iterative fit of particle momentum by assuming that integral of integral of Bdl over the particle flight path is known a priori. | |
| double | FitCurvedTrack (int n, const double *u, const double *w, const double *z, const double *cosA, const double *sinA, double z0, const double *lambda, double par[5], double parErr[5]) |
| This function does a non-iterative fit of particle momentum by assuming that integral of integral of Bdl over the particle flight path is known a priori. | |
| bool | CalcLambda (double z0, double lx[][4], double ly[][4], double *par, int minCham, int maxCham) |
| This function calculates coefficients lambda for wire plane z-positions. | |
| void TrkRUtil::PredictXY | ( | const double * | x1, | |
| const double * | sig1, | |||
| const double * | x2, | |||
| const double * | sig2, | |||
| double * | x3, | |||
| double * | sig3 | |||
| ) |
Predicts what XY position of a straight line would be if points x1 and x2 are on a straight line.
We write the slope in each coordinate as a=(x1-x2)/(z1-z2) x3 = a*(z-z1) + x1=(x1*(z-z2)-x2*(z-z1))/(z1-z2); sig3^2 = ((z-z2)/(z1-z2))^2*sig1^2 + ((z-z1)/(z1-z2))^2*sig2^2
Definition at line 29 of file TrkRUtil.cxx.
Referenced by TrkSegBuilder::AddPoint(), AlignBC::FillNt(), TrackSeg::GetXY(), main(), ResolveDAF(), and TrkSegBuilder::TryFit().
00032 { 00033 // First compute x position 00034 double zDiff = 1/(x1[2] - x2[2]); 00035 double zDiff1 = (x3[2] - x1[2]) * zDiff; 00036 double zDiff2 = (x3[2] - x2[2]) * zDiff; 00037 00038 for (int i = 0; i < 2; ++i) { 00039 x3[i] = x1[i]*zDiff2 - x2[i]*zDiff1; 00040 if (sig3) sig3[i] = sqrt(pow(zDiff2*sig1[i], 2) + 00041 pow(zDiff1*sig2[i], 2)); 00042 } 00043 }
| double TrkRUtil::FitLineFromWires | ( | int | n, | |
| const double * | u, | |||
| const double * | w, | |||
| const double * | z, | |||
| const double * | cosA, | |||
| const double * | sinA, | |||
| double | z1, | |||
| double | z2, | |||
| double | par[4], | |||
| double | parErr[4] | |||
| ) |
Fits a straight line to a set of wires.
The line should be given by 4 parameters: point (x1, y2) at z1 and point (x2, y2) at z2. Array par will be returned as (x1, y2, x2, y2) The function will return chi squared of the fit.
| n | - number of chamber wires | |
| u | - position of every wire in its coordinate (see GChamGeo) | |
| w | - weight of every wire | |
| z | - z position of every wire | |
| cosA | - cosine of the wire angle w.r.t. vertical | |
| sinA | - sine of the wire angle w.r.t. vertical | |
| z1 | - position of the first point on the track | |
| z2 | - position of the last point on the track | |
| par | - returned fit parameters | |
| parErr | - returned fit parameter errors |
Definition at line 61 of file TrkRUtil.cxx.
References ok.
Referenced by AlignChamZNoBF::ComputeChi2F(), TrackBeamPart::FillDiffHisto(), TrackSeg::Fit(), TrkSegFitter::FitTrack(), main(), TrkSegBuilder::MakeTrack(), ResolveDAF(), ResolveDumb(), and TrkSegBuilder::TryFit().
00066 { 00067 const int nParam = 4; 00068 if (n < nParam) { 00069 cout << "TrkRUtil::FitLineFromWires() will not work with less " 00070 << " than " << nParam << " points" << endl; 00071 return 1e9; 00072 } 00073 double mat[nParam * nParam]; 00074 memset(mat, 0, sizeof(mat)); 00075 double vec[nParam] = {0, 0, 0, 0}; 00076 00077 // Calculate matrix elements, matrix is symmetric, so off-diagonal 00078 // elements need to be calculated only once 00079 double dz = 1/ (z1 - z2); 00080 double dz1, dz2; 00081 double c[nParam]; 00082 double chi2 = 0; 00083 for (int pt = 0; pt < n; ++pt) { 00084 dz1 = (z[pt] - z1) * dz; 00085 dz2 = (z[pt] - z2) * dz; 00086 chi2 += w[pt] * u[pt] * u[pt]; 00087 00088 // Initialize geometric constants 00089 c[0] = dz2 * cosA[pt]; 00090 c[1] = - dz2 * sinA[pt]; 00091 c[2] = - dz1 * cosA[pt]; 00092 c[3] = dz1 * sinA[pt]; 00093 00094 for (int i = 0; i < nParam; ++i) { 00095 vec[i] += w[pt] * u[pt] * c[i]; 00096 00097 for (int j = i; j < nParam; ++j) { 00098 mat[i * nParam + j] += w[pt] * c[i] * c[j]; 00099 if (i != j) mat[j * nParam + i] = mat[i * nParam + j]; 00100 } 00101 } 00102 } 00103 00104 Bool_t ok = true; 00105 00106 for (int j = 0; j < nParam; ++j) { 00107 if (mat[j * nParam + j] < 0) { 00108 ok = false; 00109 break; 00110 } 00111 } 00112 00113 if (!ok) { 00114 cout << "TrkRUtil::FitLineFromWires() : got a goofy matrix" << endl; 00115 for (int j = 0; j < nParam; ++j) { 00116 for (int k = 0; k < nParam; ++k) cout << mat[j * nParam + k] << " "; 00117 cout << endl; 00118 } 00119 cout << " **** From " << z1 << " to " << z2 << " **** " << endl; 00120 for (int i = 0; i < n; ++i) { 00121 cout << i << ": w=" << w[i] << ", u=" << u[i] << ", z=" << z[i] 00122 << ", cos=" << cosA[i] << ", sin=" << sinA[i] << endl; 00123 } 00124 cout << "***********************************************" << endl; 00125 } 00126 00127 // Define matrices so as to make ROOT invert the matrix for us 00128 TMatrixDSym matrix(nParam, mat); 00129 TVectorD v(nParam, vec); 00130 TDecompLU lu(matrix); 00131 if (!lu.Decompose() || !lu.Solve(v)) { 00132 cout << __FILE__ << ":" << __LINE__ << " error Solving matrix" 00133 << endl; 00134 for (int i = 0; i < 4; ++i) { 00135 par[i] = 1e9; 00136 if (parErr) parErr[i] = 1e9; 00137 } 00138 return 1e9; 00139 } 00140 if (parErr) { 00141 TMatrixD matInv(nParam, nParam); 00142 lu.Invert(matInv); 00143 00144 for (int i = 0; i < nParam; ++i) { 00145 parErr[i] = matInv[i][i]; 00146 if (parErr[i] < 0) { 00147 cout << "TrkRUtil::FitLineFromWires(): parErr[" << i << "]: " 00148 << parErr[i] << " this shouldn't happen. Matrix" << endl; 00149 for (int j = 0; j < nParam; ++j) { 00150 for (int k = 0; k < nParam; ++k) cout << mat[j * nParam + k] << " "; 00151 cout << endl; 00152 } 00153 cout << " **** From " << z1 << " to " << z2 << " **** " << endl; 00154 for (int j = 0; j < n; ++j) { 00155 cout << j << ": w=" << w[j] << ", u=" << u[j] << ", z=" << z[j] 00156 << ", cos=" << cosA[j] << ", sin=" << sinA[j] << endl; 00157 } 00158 cout << "***********************************************" << endl; 00159 parErr[i] = 0; 00160 } 00161 else parErr[i] = sqrt(parErr[i]); 00162 } 00163 } 00164 00165 // Calculate chi squared 00166 for (int i = 0; i < nParam; ++i) { 00167 par[i] = v[i]; 00168 chi2 -= vec[i] * par[i]; 00169 } 00170 00171 // Check for floating point errors 00172 if (chi2 < 0) return 0; 00173 00174 return chi2; 00175 }
| double TrkRUtil::FitCurvedTrack | ( | int | n, | |
| const double * | u, | |||
| const double * | w, | |||
| const double * | z, | |||
| const double * | cosA, | |||
| const double * | sinA, | |||
| double | z0, | |||
| const double * | lambdaX, | |||
| const double * | lambdaY, | |||
| double | par[5], | |||
| double | parErr[5] | |||
| ) |
This function does a non-iterative fit of particle momentum by assuming that integral of integral of Bdl over the particle flight path is known a priori.
| n | - number of measurement points | |
| u | - measurement value in respective coordinate | |
| w | - weight of the measurement | |
| z | - z position of the measurement | |
| cosA | - cosine of the wire angle w.r.t. vertical | |
| sinA | - sine of the wire angle w.r.t. vertical | |
| z0 | - z coordinate where momentum direction is fitted | |
| lambdaBx | - x-displacement from straight line projection | |
| lambdaBy | - y-displacement from straight line projection | |
| par | - returned fit parameters: x, y, px, py, q/p at z=z0 | |
| parErr | - returned fit parameter errors |
Definition at line 248 of file TrkRUtil.cxx.
References FitLine().
Referenced by TrkCandBuilder::AddBC(), ChamFCN(), AlignChamZ::ComputeChi2F(), TrackBeamPart::ComputeF(), AlignRotB::ComputeF(), AlignTPCDrift2::ComputeTrkChi2(), TrackBeamPart::FillDiffHisto(), Fit(), TrkCand::Fit(), SPTrk::Fit(), AlignRotB::Fit(), AlignChamZ::Fit(), AlignChamW0::Fit(), FitEqualWeights(), FitMSC(), main(), TrkCandBuilder::MakeTrack(), and TrkCandBuilder::TryBCFit().
00255 { 00256 const int nParam = 5; 00257 if (n < nParam) { 00258 cout << "TrkRUtil::FitCurvedTrack() will not work with " 00259 << n << " points; need at least " << nParam << endl; 00260 return 1e9; 00261 } 00262 double mat[nParam * nParam]; 00263 memset(mat, 0, sizeof(mat)); 00264 double vec[nParam] = {0, 0, 0, 0, 0}; 00265 00266 double chi2 = 0; 00267 double c[nParam]; // Geometric constants for each parameter 00268 00269 double minZ = z[0]; 00270 double maxZ = z[0]; 00271 double maxLam = 0; 00272 00273 const double kScale[nParam] = {1, 1, 1e-2, 1e-2, 1e-2}; 00274 00275 for (int pt = 0; pt < n; ++pt) { 00276 if (z[pt] < minZ) minZ = z[pt]; 00277 else if (z[pt] > maxZ) maxZ = z[pt]; 00278 00279 // Initialize geometric constants 00280 c[0] = cosA[pt] * kScale[0]; 00281 c[1] = -sinA[pt] * kScale[1]; 00282 c[2] = cosA[pt] * (z[pt] - z0) * kScale[2]; 00283 c[3] = -sinA[pt] * (z[pt] - z0) * kScale[3]; 00284 c[4] = (lambdaX[pt] * cosA[pt] - lambdaY[pt] * sinA[pt]) * kScale[4]; 00285 if (fabs(c[4]) > maxLam) maxLam = fabs(c[4]); 00286 00287 chi2 += w[pt] * u[pt] * u[pt]; 00288 00289 for (int i = 0; i < nParam; ++i) { 00290 vec[i] += w[pt] * u[pt] * c[i]; 00291 00292 for (int j = i; j < nParam; ++j) { 00293 mat[i * nParam + j] += w[pt] * c[i] * c[j]; 00294 if (i != j) mat[j * nParam + i] = mat[i * nParam + j]; 00295 } 00296 } 00297 } 00298 00299 double maxEnt = 0, minEnt = 1e15; 00300 for (int i = 0; i < 25; ++i) { 00301 if (fabs(maxEnt) < fabs(mat[i])) maxEnt = mat[i]; 00302 if (fabs(minEnt) > fabs(mat[i])) minEnt = mat[i]; 00303 } 00304 00305 if (maxLam < 1e-6) return FitLine(chi2, mat, vec, par, parErr); 00306 00307 // Use ROOT linear algebra to solve matrix inversion 00308 TMatrixDSym matrix(nParam, mat); 00309 TVectorD v(nParam, vec); 00310 TDecompLU lu(matrix); 00311 if (!lu.Decompose()) return FitLine(chi2, mat, vec, par, parErr); 00312 double d1, d2; 00313 lu.Det(d1, d2); 00314 if (d1 <= 0) { 00315 // cout << "TrkRUtil.cxx:" << __LINE__ 00316 // << " -- Determinant is less than 0" << endl; 00317 return FitLine(chi2, mat, vec, par, parErr); 00318 } 00319 if (!lu.Solve(v)) { 00320 for (int i = 0; i < nParam; ++i) par[i] = -1e9; 00321 return 1e9; 00322 } 00323 00324 bool goodres = true; 00325 00326 if (parErr) { 00327 TMatrixD matInv(nParam, nParam); 00328 lu.Invert(matInv); 00329 00330 for (int i = 0; i < nParam; ++i) { 00331 parErr[i] = matInv[i][i] * kScale[i]; 00332 if (parErr[i] < 0) { 00333 cout << __FILE__ << ":" << __LINE__ << " parErr[" << i << "]: " 00334 << parErr[i] << " this shouldn't happen!" << endl; 00335 parErr[i] = 0; 00336 goodres = false; 00337 } 00338 else parErr[i] = sqrt(parErr[i]); 00339 00340 } 00341 if (!goodres) { 00342 cout << "Matrix:\n"; 00343 for (int i = 0; i < 25; ++i) { 00344 printf(" %+.4e, ", mat[i]); 00345 if (i % 5 == 4) cout << "\n"; 00346 } 00347 cout << "Vector: "; 00348 for (int i = 0; i < 5; ++i) printf("%+.4e, ", vec[i]); 00349 cout << endl; 00350 00351 cout << "Solution: "; 00352 for (int i = 0; i < 5; ++i) printf("%+.4e, ", v[i]); 00353 cout << endl; 00354 00355 cout << "Data [" << n << "]\n"; 00356 for (int i = 0; i < n; ++i) { 00357 printf("%+.3e: %+.3e %+.2f %+.2f %+.3e %+.3e\n", 00358 z[i], u[i], cosA[i], sinA[i], lambdaX[i], lambdaY[i]); 00359 } 00360 } 00361 } 00362 00363 for (int i = 0; i < nParam; ++i) { 00364 par[i] = v[i]; 00365 chi2 -= vec[i] * par[i]; 00366 par[i] *= kScale[i]; 00367 } 00368 if (chi2 < 0) return 0; 00369 return chi2; 00370 00371 }
| double TrkRUtil::FitCurvedTrack | ( | int | n, | |
| const double * | u, | |||
| const double * | w, | |||
| const double * | z, | |||
| const double * | cosA, | |||
| const double * | sinA, | |||
| double | z0, | |||
| const double * | lambda, | |||
| double | par[5], | |||
| double | parErr[5] | |||
| ) |
This function does a non-iterative fit of particle momentum by assuming that integral of integral of Bdl over the particle flight path is known a priori.
| n | - number of measurement points | |
| u | - measurement value in respective coordinate | |
| w | - weight of the measurement | |
| z | - z position of the measurement | |
| cosA | - cosine of the wire angle w.r.t. vertical | |
| sinA | - sine of the wire angle w.r.t. vertical | |
| z0 | - z coordinate where momentum direction is fitted | |
| lambda | - displacement from straight-line projection in that wire direction | |
| par | - returned fit parameters: x, y, px, py, q/p at z=z0 | |
| parErr | - returned fit parameter errors |
Definition at line 390 of file TrkRUtil.cxx.
References FitLine().
00396 { 00397 const int nParam = 5; 00398 if (n < nParam) { 00399 cout << "TrkRUtil::FitCurvedTrack() will not work with " 00400 << n << " points; need at least " << nParam << endl; 00401 return 1e9; 00402 } 00403 double mat[nParam * nParam]; 00404 memset(mat, 0, sizeof(mat)); 00405 double vec[nParam] = {0, 0, 0, 0, 0}; 00406 00407 double chi2 = 0; 00408 double c[nParam]; // Geometric constants for each parameter 00409 00410 double minZ = z[0]; 00411 double maxZ = z[0]; 00412 double maxLam = 0; 00413 00414 for (int pt = 0; pt < n; ++pt) { 00415 if (z[pt] < minZ) minZ = z[pt]; 00416 else if (z[pt] > maxZ) maxZ = z[pt]; 00417 00418 // Initialize geometric constants 00419 c[0] = cosA[pt]; 00420 c[1] = -sinA[pt]; 00421 c[2] = cosA[pt] * (z[pt] - z0); 00422 c[3] = -sinA[pt] * (z[pt] - z0); 00423 c[4] = lambda[pt]; 00424 if (fabs(c[4]) > maxLam) maxLam = fabs(c[4]); 00425 00426 chi2 += w[pt] * u[pt] * u[pt]; 00427 00428 for (int i = 0; i < nParam; ++i) { 00429 vec[i] += w[pt] * u[pt] * c[i]; 00430 00431 for (int j = i; j < nParam; ++j) { 00432 mat[i * nParam + j] += w[pt] * c[i] * c[j]; 00433 if (i != j) mat[j * nParam + i] = mat[i * nParam + j]; 00434 } 00435 } 00436 } 00437 00438 if (maxLam < 1e-6) return FitLine(chi2, mat, vec, par, parErr); 00439 00440 // Use ROOT linear algebra to solve matrix inversion 00441 TMatrixDSym matrix(nParam, mat); 00442 TVectorD v(nParam, vec); 00443 TDecompLU lu(matrix); 00444 if (!lu.Decompose() || !lu.Solve(v)) { 00445 for (int i = 0; i < nParam; ++i) par[i] = -1e9; 00446 return 1e9; 00447 } 00448 00449 if (parErr) { 00450 TMatrixD matInv(nParam, nParam); 00451 lu.Invert(matInv); 00452 00453 for (int i = 0; i < nParam; ++i) { 00454 parErr[i] = matInv[i][i]; 00455 if (parErr[i] < 0) { 00456 cout << __FILE__ << ":" << __LINE__ << " parErr[" << i << "]: " 00457 << parErr[i] << " this shouldn't happen!" << endl; 00458 parErr[i] = 0; 00459 } 00460 else parErr[i] = sqrt(parErr[i]); 00461 00462 } 00463 } 00464 00465 for (int i = 0; i < nParam; ++i) { 00466 par[i] = v[i]; 00467 chi2 -= vec[i] * par[i]; 00468 } 00469 if (chi2 < 0) return 0; 00470 return chi2; 00471 00472 }
| bool TrkRUtil::CalcLambda | ( | double | z0, | |
| double | lx[][4], | |||
| double | ly[][4], | |||
| double * | par = 0, |
|||
| int | minCham = 0, |
|||
| int | maxCham = 8 | |||
| ) |
This function calculates coefficients lambda for wire plane z-positions.
These coefficients are needed for track template and can be thought of as integral of integral of Bdl or equivalent displacement from straight-line trajectory for 1 GeV/c particle. The values are stored for each plane of each wire chamber.
Definition at line 482 of file TrkRUtil.cxx.
References geo, SwimMIPP::GetXY(), GMIPPGeo::Instance(), kNPlane, mom, p, and SwimMIPP::Swim().
Referenced by ChamFCN(), AlignChamZ::ComputeChi2F(), TrackBeamPart::ComputeF(), AlignRotB::ComputeF(), AlignChamZ::ComputeF(), AlignChamZ::EndRun(), TrackBeamPart::FillDiffHisto(), Fit(), AlignRotB::Fit(), AlignChamZ::Fit(), AlignChamW0::Fit(), FitEqualWeights(), FitMSC(), TrkCand::Init(), main(), TrkCandBuilder::MakeTrack(), TrackBeamPart::NewRun(), and TrkCandBuilder::TryBCFit().
00485 { 00486 static SwimMIPP swim; 00487 00488 double mom = 120; 00489 if (par) { 00490 if (fabs(par[4]) < 1e-3) par[4] = 1e-3; 00491 mom = 1 / par[4]; 00492 } 00493 00494 if (!par) swim.Swim(1, 120, 0, 0, z0, 0, 0); 00495 else swim.Swim(z0, par); 00496 00497 for (int c = minCham; c <= maxCham; ++c) { 00498 GChamGeo& geo = GMIPPGeo::Instance().Cham(c); 00499 for (int p = 0; p < kNPlane; ++p) { 00500 // Get (x,y) coordinate prediction at chamber plane 00501 if (!swim.GetXY(geo.Z(p + 1), &lx[c][p], &ly[c][p])) return false; 00502 00503 if (par) { 00504 // Subtract initial parameters if we have them 00505 lx[c][p] -= par[0] + par[2] * (geo.Z(p + 1) - z0); 00506 ly[c][p] -= par[1] + par[3] * (geo.Z(p + 1) - z0); 00507 } 00508 // Multiply by momentum to obtain coefficients necessary for 00509 // track template fitting 00510 lx[c][p] *= mom; 00511 ly[c][p] *= mom; 00512 } 00513 } 00514 return true; 00515 }
1.4.7