Changes in external/TrackCovariance/VertexFit.cc [127644a:82db145] in git
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
external/TrackCovariance/VertexFit.cc
r127644a r82db145 8 8 // Constructors 9 9 // 10 // Empty 10 // 11 // Empty construction (to be used when adding tracks later with AddTrk() ) 11 12 VertexFit::VertexFit() 12 13 { 13 14 fNtr = 0; 15 fRold = -1.0; 14 16 fVtxDone = kFALSE; 15 17 fVtxCst = kFALSE; 16 18 fxCst.ResizeTo(3); 17 fCovCst.ResizeTo(3, 3);19 fCovCst.ResizeTo(3, 3); 18 20 fXv.ResizeTo(3); 19 fcovXv.ResizeTo(3,3); 20 } 21 // Parameters and covariances 21 fcovXv.ResizeTo(3, 3); 22 } 23 // 24 // Build from list of parameters and covariances 22 25 VertexFit::VertexFit(Int_t Ntr, TVectorD** trkPar, TMatrixDSym** trkCov) 23 26 { 24 27 fNtr = Ntr; 28 fRold = -1.0; 25 29 fVtxDone = kFALSE; 26 30 fVtxCst = kFALSE; 27 31 fxCst.ResizeTo(3); 28 fCovCst.ResizeTo(3, 3);32 fCovCst.ResizeTo(3, 3); 29 33 fXv.ResizeTo(3); 30 fcovXv.ResizeTo(3,3); 31 // 32 fPar = trkPar; 33 fCov = trkCov; 34 fChi2List.ResizeTo(Ntr); 35 // 36 ffi = new Double_t[Ntr]; // Fit phases 37 fx0i = new TVectorD* [Ntr]; // Track expansion points 38 for (Int_t i = 0; i < Ntr; i++) fx0i[i] = new TVectorD(3); 39 fai = new TVectorD * [Ntr]; // dx/dphi 40 for (Int_t i = 0; i < Ntr; i++) fai[i] = new TVectorD(3); 41 fa2i = new Double_t[Ntr]; // a'Wa 42 fDi = new TMatrixDSym*[Ntr]; // W-WBW 43 for (Int_t i = 0; i < Ntr; i++) fDi[i] = new TMatrixDSym(3); 44 fWi = new TMatrixDSym * [Ntr]; // (ACA')^-1 45 for (Int_t i = 0; i < Ntr; i++) fWi[i] = new TMatrixDSym(3); 46 fWinvi = new TMatrixDSym * [Ntr]; // ACA' 47 for (Int_t i = 0; i < Ntr; i++) fWinvi[i] = new TMatrixDSym(3); 48 49 } 50 // ObsTrk list 34 fcovXv.ResizeTo(3, 3); 35 // 36 for (Int_t i = 0; i < fNtr; i++) 37 { 38 TVectorD pr = *trkPar[i]; 39 fPar.push_back(new TVectorD(pr)); 40 TMatrixDSym cv = *trkCov[i]; 41 fCov.push_back(new TMatrixDSym(cv)); 42 } 43 fChi2List.ResizeTo(fNtr); 44 // 45 } 46 // 47 // Build from ObsTrk list of tracks 51 48 VertexFit::VertexFit(Int_t Ntr, ObsTrk** track) 52 49 { 53 50 fNtr = Ntr; 51 fRold = -1.0; 54 52 fVtxDone = kFALSE; 55 53 fVtxCst = kFALSE; 56 54 fxCst.ResizeTo(3); 57 fCovCst.ResizeTo(3, 3);55 fCovCst.ResizeTo(3, 3); 58 56 fXv.ResizeTo(3); 59 fcovXv.ResizeTo(3,3); 60 // 61 fPar = new TVectorD*[Ntr]; 62 fCov = new TMatrixDSym*[Ntr]; 63 fChi2List.ResizeTo(Ntr); 64 for (Int_t i = 0; i < Ntr; i++) 65 { 66 fPar[i] = new TVectorD(track[i]->GetObsPar()); 67 //std::cout << "fPar = " << std::endl; fPar[i]->Print(); 68 fCov[i] = new TMatrixDSym(track[i]->GetCov()); 69 //std::cout << "fCov = " << std::endl; fCov[i]->Print(); 70 } 71 // 72 ffi = new Double_t[Ntr]; // Fit phases 73 fx0i = new TVectorD * [Ntr]; // Track expansion points 74 for (Int_t i = 0; i < Ntr; i++) fx0i[i] = new TVectorD(3); 75 fai = new TVectorD * [Ntr]; // dx/dphi 76 for (Int_t i = 0; i < Ntr; i++) fai[i] = new TVectorD(3); 77 fa2i = new Double_t[Ntr]; // a'Wa 78 fDi = new TMatrixDSym * [Ntr]; // W-WBW 79 for (Int_t i = 0; i < Ntr; i++) fDi[i] = new TMatrixDSym(3); 80 fWi = new TMatrixDSym * [Ntr]; // (ACA')^-1 81 for (Int_t i = 0; i < Ntr; i++) fWi[i] = new TMatrixDSym(3); 82 fWinvi = new TMatrixDSym * [Ntr]; // ACA' 83 for (Int_t i = 0; i < Ntr; i++) fWinvi[i] = new TMatrixDSym(3); 84 85 //std::cout << "VertexFit constructor executed" << std::endl; 57 fcovXv.ResizeTo(3, 3); 58 // 59 fChi2List.ResizeTo(fNtr); 60 for (Int_t i = 0; i < fNtr; i++) 61 { 62 fPar.push_back(new TVectorD(track[i]->GetObsPar())); 63 fCov.push_back(new TMatrixDSym(track[i]->GetCov())); 64 } 86 65 } 87 66 // 88 67 // Destructor 68 // 69 void VertexFit::ResetWrkArrays() 70 { 71 Int_t N = (Int_t)ffi.size(); 72 for (Int_t i = 0; i < N; i++) 73 { 74 if (fx0i[i]) { fx0i[i]->Clear(); delete fx0i[i]; } 75 if (fai[i]) { fai[i]->Clear(); delete fai[i]; } 76 if (fDi[i]) { fDi[i]->Clear(); delete fDi[i]; } 77 if (fWi[i]) { fWi[i]->Clear(); delete fWi[i]; } 78 if (fWinvi[i]){ fWinvi[i]->Clear(); delete fWinvi[i]; } 79 } 80 fa2i.clear(); 81 fx0i.clear(); 82 fai.clear(); 83 fDi.clear(); 84 fWi.clear(); 85 fWinvi.clear(); 86 } 89 87 VertexFit::~VertexFit() 90 88 { 91 fxCst.Clear(); 92 fCovCst.Clear(); 93 fXv.Clear(); 94 fcovXv.Clear(); 95 fChi2List.Clear(); 96 // 97 for (Int_t i= 0; i < fNtr; i++) 98 { 99 fPar[i]->Clear(); 100 fCov[i]->Clear(); 101 // 102 fx0i[i]->Clear(); delete fx0i[i]; 103 fai[i]->Clear(); delete fai[i]; 104 fDi[i]->Clear(); delete fDi[i]; 105 fWi[i]->Clear(); delete fWi[i]; 106 fWinvi[i]->Clear(); delete fWinvi[i]; 107 } 89 fxCst.Clear(); 90 fCovCst.Clear(); 91 fXv.Clear(); 92 fcovXv.Clear(); 93 fChi2List.Clear(); 94 // 95 for (Int_t i = 0; i < fNtr; i++) 96 { 97 fPar[i]->Clear(); delete fPar[i]; 98 fCov[i]->Clear(); delete fCov[i]; 99 } 100 fPar.clear(); 101 fCov.clear(); 102 // 103 ResetWrkArrays(); 104 ffi.clear(); 108 105 fNtr = 0; 109 delete[] fPar; 110 delete[] fCov; 111 delete[] ffi; 112 delete[] fa2i; 113 delete[] fx0i; 114 delete[] fai; 115 delete[] fDi; 116 delete[] fWi; 117 delete[] fWinvi; 118 } 119 // 120 Double_t VertexFit::FastRv1(TVectorD p1, TVectorD p2) 121 { 122 // 123 // Find radius of intersection between two tracks in the transverse plane 106 } 107 // 108 Double_t VertexFit::FastRv(TVectorD p1, TVectorD p2) 109 { 110 // 111 // Find radius of minimum distance between two tracks 124 112 // 125 113 // p = (D,phi, C, z0, ct) … … 127 115 // Define arrays 128 116 // 129 Double_t r1 = 1.0 / p1(2); 130 Double_t r2 = 1.0 / p2(2); 117 Double_t C1 = p1(2); 118 Double_t C2 = p2(2); 119 Double_t ph1 = p1(1); 120 Double_t ph2 = p2(1); 131 121 TVectorD x0 = Fill_x0(p1); 132 122 TVectorD y0 = Fill_x0(p2); 133 123 TVectorD n = Fill_a(p1, 0.0); 134 n *= r1;124 n *= (2*C1); 135 125 TVectorD k = Fill_a(p2, 0.0); 136 k *= r2;126 k *= (2*C2); 137 127 // 138 128 // Setup and solve linear system … … 148 138 H(1, 1) = nn; 149 139 TVectorD c(2); 150 c(0) = 0; for (Int_t i = 0; i < 3; i++)c(0) += 140 c(0) = 0; for (Int_t i = 0; i < 3; i++)c(0) += n(i) * (y0(i) - x0(i)); 151 141 c(1) = 0; for (Int_t i = 0; i < 3; i++)c(1) += -k(i) * (y0(i) - x0(i)); 152 142 TVectorD smin = (H * c); … … 155 145 TVectorD X = x0 + smin(0) * n; 156 146 TVectorD Y = y0 + smin(1) * k; 157 Double_t R1 = TMath::Sqrt(X(0) * X(0) + X(1) * X(1)); 158 Double_t R2 = TMath::Sqrt(Y(0) * Y(0) + Y(1) * Y(1)); 159 // 160 return 0.5*(R1+R2); 161 } 162 Double_t VertexFit::FastRv(TVectorD p1, TVectorD p2) 163 { 164 // 165 // Find radius of minimum distance 166 // 167 // p = (D,phi, C) 168 // 169 // Solving matrix 170 TMatrixDSym H(2); 171 H(0, 0) = -TMath::Cos(p2(1)); 172 H(0, 1) = TMath::Cos(p1(1)); 173 H(1, 0) = -TMath::Sin(p2(1)); 174 H(1, 1) = TMath::Sin(p1(1)); 175 Double_t Det = TMath::Sin(p2(1) - p1(1)); 176 H *= 1.0 / Det; 177 // 178 // Convergence parameters 179 Int_t Ntry = 0; 180 Int_t NtryMax = 100; 181 Double_t eps = 1000.; 182 Double_t epsMin = 1.0e-6; 183 // 184 // Vertex finding loop 185 // 186 TVectorD cterm(2); 187 cterm(0) = p1(0); 188 cterm(1) = p2(0); 189 TVectorD xv(2); 190 Double_t R = 1000.; 191 while (eps > epsMin) 192 { 193 xv = H * cterm; 194 Ntry++; 195 if (Ntry > NtryMax) 147 // 148 // Higher order corrections 149 X(0) += -C1 * smin(0) * smin(0) * TMath::Sin(ph1); 150 X(1) += C1 * smin(0) * smin(0) * TMath::Cos(ph1); 151 Y(0) += -C2 * smin(1) * smin(1) * TMath::Sin(ph2); 152 Y(1) += C2 * smin(1) * smin(1) * TMath::Cos(ph2); 153 // 154 TVectorD Xavg = 0.5 * (X + Y); 155 // 156 // 157 return TMath::Sqrt(Xavg(0)*Xavg(0)+Xavg(1)*Xavg(1)); 158 } 159 // 160 // Starting radius determination 161 Double_t VertexFit::StartRadius() 162 { 163 // 164 // Maximum impact parameter 165 Double_t Rd = 0; 166 for (Int_t i = 0; i < fNtr; i++) 167 { 168 TVectorD par = *fPar[i]; 169 Double_t Dabs = TMath::Abs(par(0)); 170 if (Dabs > Rd)Rd = Dabs; 171 } 172 //----------------------------- 173 // 174 // Find track pair with phi difference closest to pi/2 175 Int_t isel = 0; Int_t jsel = 0; // selected track indices 176 Double_t dSinMax = 0.0; // Max phi difference 177 for (Int_t i = 0; i < fNtr - 1; i++) 178 { 179 TVectorD pari = *fPar[i]; 180 Double_t phi1 = pari(1); 181 182 for (Int_t j = i + 1; j < fNtr; j++) 196 183 { 197 std::cout << "FastRv: maximum number of iteration reached" << std::endl; 198 break; 184 TVectorD parj = *fPar[j]; 185 Double_t phi2 = parj(1); 186 Double_t Sindphi = TMath::Abs(TMath::Sin(phi2 - phi1)); 187 if (Sindphi > dSinMax) 188 { 189 isel = i; jsel = j; 190 dSinMax = Sindphi; 191 } 199 192 } 200 Double_t Rnew = TMath::Sqrt(xv(0) * xv(0) + xv(1) * xv(1)); 201 eps = Rnew - R; 202 R = Rnew; 203 cterm(0) = p1(2) * R * R; 204 cterm(1) = p2(2) * R * R; 205 } 193 } 194 // 195 //------------------------------------------ 196 // 197 // Find radius of minimum distrance between tracks 198 TVectorD p1 = *fPar[isel]; 199 TVectorD p2 = *fPar[jsel]; 200 Double_t R = FastRv(p1, p2); 201 // 202 R = 0.9 * R + 0.1 * Rd; // Protect for overshoot 206 203 // 207 204 return R; 208 205 } 209 210 TMatrixDSym VertexFit::RegInv3(TMatrixDSym &Smat0) 211 { 212 // 213 // Regularized inversion of symmetric 3x3 matrix with positive diagonal elements 214 // 215 TMatrixDSym Smat = Smat0; 216 Int_t N = Smat.GetNrows(); 217 if (N != 3) 218 { 219 std::cout << "RegInv3 called with matrix size != 3. Abort & return standard inversion." << std::endl; 220 return Smat.Invert(); 221 } 222 TMatrixDSym D(N); D.Zero(); 223 Bool_t dZero = kTRUE; // No elements less or equal 0 on the diagonal 224 for (Int_t i = 0; i < N; i++) if (Smat(i, i) <= 0.0)dZero = kFALSE; 225 if (dZero) 226 { 227 for (Int_t i = 0; i < N; i++) D(i, i) = 1.0 / TMath::Sqrt(Smat(i, i)); 228 TMatrixDSym RegMat = Smat.Similarity(D); 229 TMatrixDSym Q(2); 230 for (Int_t i = 0; i < 2; i++) 206 // 207 // Regularized symmetric matrix inversion 208 // 209 TMatrixDSym VertexFit::RegInv(TMatrixDSym& Min) 210 { 211 TMatrixDSym M = Min; // Decouple from input 212 Int_t N = M.GetNrows(); // Matrix size 213 TMatrixDSym D(N); D.Zero(); // Normaliztion matrix 214 TMatrixDSym R(N); // Normarized matrix 215 TMatrixDSym Rinv(N); // Inverse of R 216 TMatrixDSym Minv(N); // Inverse of M 217 // 218 // Check for 0's and normalize 219 for (Int_t i = 0; i < N; i++) 220 { 221 if (M(i, i) != 0.0) D(i, i) = 1. / TMath::Sqrt(TMath::Abs(M(i, i))); 222 else D(i, i) = 1.0; 223 } 224 R = M.Similarity(D); 225 // 226 // Recursive algorithms stops when N = 2 227 // 228 //**************** 229 // case N = 2 *** 230 //**************** 231 if (N == 2) 232 { 233 Double_t det = R(0, 0) * R(1, 1) - R(0, 1) * R(1, 0); 234 if (det == 0) 231 235 { 232 for (Int_t j = 0; j < 2; j++)Q(i, j) = RegMat(i, j); 236 std::cout << "VertexFit::RegInv: null determinant for N = 2" << std::endl; 237 Rinv.Zero(); // Return null matrix 233 238 } 234 Double_t Det = 1 - Q(0, 1)*Q(1, 0); 235 TMatrixDSym H(2); 236 H = Q; 237 H(0, 1) = -Q(0, 1); 238 H(1, 0) = -Q(1, 0); 239 TVectorD p(2); 240 p(0) = RegMat(0, 2); 241 p(1) = RegMat(1, 2); 242 Double_t pHp = H.Similarity(p); 243 Double_t h = pHp-Det; 244 // 245 TMatrixDSym pp(2); pp.Rank1Update(p); 246 TMatrixDSym F = (h*H) - pp.Similarity(H); 247 F *= 1.0 / Det; 248 TVectorD b = H*p; 249 TMatrixDSym InvReg(3); 250 for (Int_t i = 0; i < 2; i++) 239 else 251 240 { 252 InvReg(i, 2) = b(i); 253 InvReg(2, i) = b(i); 254 for (Int_t j = 0; j < 2; j++) InvReg(i, j) = F(i, j); 241 // invert matrix 242 Rinv(0, 0) = R(1, 1); 243 Rinv(0, 1) = -R(0, 1); 244 Rinv(1, 0) = Rinv(0, 1); 245 Rinv(1, 1) = R(0, 0); 246 Rinv *= 1. / det; 255 247 } 256 InvReg(2, 2) = -Det; 257 // 258 InvReg *= 1.0 / h; 259 // 260 // 261 return InvReg.Similarity(D); 262 } 248 } 249 //**************** 250 // case N > 2 *** 251 //**************** 263 252 else 264 253 { 265 std::cout << "RegInv3: found negative elements in diagonal. Return standard inversion." << std::endl; 266 return Smat.Invert(); 267 } 254 // Break up matrix 255 TMatrixDSym Q = R.GetSub(0, N - 2, 0, N - 2); // Upper left 256 TVectorD p(N - 1); 257 for (Int_t i = 0; i < N - 1; i++)p(i) = R(N - 1, i); 258 Double_t q = R(N - 1, N - 1); 259 //Invert pieces and re-assemble 260 TMatrixDSym Ainv(N - 1); 261 TMatrixDSym A(N - 1); 262 if (TMath::Abs(q) > 1.0e-15) 263 { 264 // Case |q| > 0 265 Ainv.Rank1Update(p, -1.0 / q); 266 Ainv += Q; 267 A = RegInv(Ainv); // Recursive call 268 TMatrixDSub(Rinv, 0, N - 2, 0, N - 2) = A; 269 // 270 TVectorD b = (-1.0 / q) * (A * p); 271 for (Int_t i = 0; i < N - 1; i++) 272 { 273 Rinv(N - 1, i) = b(i); 274 Rinv(i, N - 1) = b(i); 275 } 276 // 277 Double_t pdotb = 0.; 278 for (Int_t i = 0; i < N - 1; i++)pdotb += p(i) * b(i); 279 Double_t c = (1.0 - pdotb) / q; 280 Rinv(N - 1, N - 1) = c; 281 } 282 else 283 { 284 // case q = 0 285 TMatrixDSym Qinv = RegInv(Q); // Recursive call 286 Double_t a = Qinv.Similarity(p); 287 Double_t c = -1.0 / a; 288 Rinv(N - 1, N - 1) = c; 289 // 290 TVectorD b = (1.0 / a) * (Qinv * p); 291 for (Int_t i = 0; i < N - 1; i++) 292 { 293 Rinv(N - 1, i) = b(i); 294 Rinv(i, N - 1) = b(i); 295 } 296 // 297 A.Rank1Update(p, -1 / a); 298 A += Q; 299 A.Similarity(Qinv); 300 TMatrixDSub(Rinv, 0, N - 2, 0, N - 2) = A; 301 } 302 } 303 Minv = Rinv.Similarity(D); 304 return Minv; 268 305 } 269 306 // … … 273 310 { 274 311 // 275 // Derivative of track 3D position vector with respect to track parameters at constant phase 312 // Derivative of track 3D position vector with respect to track parameters at constant phase 276 313 // 277 314 // par = vector of track parameters … … 294 331 A(2, 0) = 0.0; 295 332 // phi0 296 A(0, 1) = -D *TMath::Cos(p0) + (TMath::Cos(phi + p0) - TMath::Cos(p0)) / (2 * C);297 A(1, 1) = -D *TMath::Sin(p0) + (TMath::Sin(phi + p0) - TMath::Sin(p0)) / (2 * C);333 A(0, 1) = -D * TMath::Cos(p0) + (TMath::Cos(phi + p0) - TMath::Cos(p0)) / (2 * C); 334 A(1, 1) = -D * TMath::Sin(p0) + (TMath::Sin(phi + p0) - TMath::Sin(p0)) / (2 * C); 298 335 A(2, 1) = 0.0; 299 336 // C 300 A(0, 2) = -(TMath::Sin(phi + p0) - TMath::Sin(p0)) / (2 * C *C);301 A(1, 2) = (TMath::Cos(phi + p0) - TMath::Cos(p0)) / (2 * C *C);302 A(2, 2) = -ct *phi / (2 * C*C);337 A(0, 2) = -(TMath::Sin(phi + p0) - TMath::Sin(p0)) / (2 * C * C); 338 A(1, 2) = (TMath::Cos(phi + p0) - TMath::Cos(p0)) / (2 * C * C); 339 A(2, 2) = -ct * phi / (2 * C * C); 303 340 // z0 304 341 A(0, 3) = 0.0; … … 353 390 Double_t ct = par(4); 354 391 // 355 x0(0) = -D * TMath::Sin(p0);356 x0(1) = D *TMath::Cos(p0);392 x0(0) = -D * TMath::Sin(p0); 393 x0(1) = D * TMath::Cos(p0); 357 394 x0(2) = z0; 358 395 // … … 378 415 x(0) = x0(0) + (TMath::Sin(phi + p0) - TMath::Sin(p0)) / (2 * C); 379 416 x(1) = x0(1) - (TMath::Cos(phi + p0) - TMath::Cos(p0)) / (2 * C); 380 x(2) = x0(2) + ct *phi / (2 * C);417 x(2) = x0(2) + ct * phi / (2 * C); 381 418 // 382 419 return x; 383 420 } 384 421 // 385 void VertexFit::VertexFinder() 386 { 387 // 388 // Vertex fit (units are meters) 422 void VertexFit::UpdateTrkArrays(Int_t i) 423 { 424 // 425 // Get track parameters and their covariance 426 TVectorD par = *fPar[i]; 427 TMatrixDSym Cov = *fCov[i]; 428 // 429 // Fill all track related work arrays arrays 430 Double_t fs = ffi[i]; // Get phase 431 TVectorD xs = Fill_x(par, fs); 432 fx0i.push_back(new TVectorD(xs)); // Start helix position 433 // 434 TMatrixD A = Fill_A(par, fs); // A = dx/da = derivatives wrt track parameters 435 TMatrixDSym Winv = Cov.Similarity(A); // W^-1 = A*C*A' 436 fWinvi.push_back(new TMatrixDSym(Winv)); // Store W^-1 matrix 437 // 438 TMatrixDSym W = RegInv(Winv); // W = (A*C*A')^-1 439 fWi.push_back(new TMatrixDSym(W)); // Store W matrix 440 // 441 TVectorD a = Fill_a(par, fs); // a = dx/ds = derivatives wrt phase 442 fai.push_back(new TVectorD(a)); // Store a 443 // 444 Double_t a2 = W.Similarity(a); 445 fa2i.push_back(a2); // Store a2 446 // 447 // Build D matrix 448 TMatrixDSym B(3); 449 B.Rank1Update(a, -1. / a2); 450 B.Similarity(W); 451 TMatrixDSym Ds = W + B; // D matrix 452 fDi.push_back(new TMatrixDSym(Ds)); // Store D matrix 453 } 454 // 455 void VertexFit::VertexFitter() 456 { 457 //std::cout << "VertexFitter: just in" << std::endl; 458 if (fNtr < 2) 459 { 460 std::cout << "VertexFit::VertexFitter - Method called with less than 2 tracks - Aborting " << std::endl; 461 std::exit(1); 462 } 463 // 464 // Vertex fit 389 465 // 390 466 // Initial variable definitions 391 467 TVectorD x(3); 392 468 TMatrixDSym covX(3); 393 TVectorD x0(3); for (Int_t v = 0; v < 3; v++)x0(v) = 100.; // set to large value394 469 Double_t Chi2 = 0; 395 // 396 // Stored quantities 397 Double_t *fi = new Double_t[fNtr]; // Phases 398 TVectorD **x0i = new TVectorD*[fNtr]; // Track expansion point 399 TVectorD **ai = new TVectorD*[fNtr]; // dx/dphi 400 Double_t *a2i = new Double_t[fNtr]; // a'Wa 401 TMatrixDSym **Di = new TMatrixDSym*[fNtr]; // W-WBW 402 TMatrixDSym **Wi = new TMatrixDSym*[fNtr]; // (ACA')^-1 403 TMatrixDSym **Winvi = new TMatrixDSym*[fNtr]; // ACA' 404 // 405 // vertex radius approximation 406 // Maximum impact parameter 407 Double_t Rd = 0; 408 for (Int_t i = 0; i < fNtr; i++) 409 { 410 //ObsTrk* t = tracks[i]; 411 TVectorD par = *fPar[i]; 412 Double_t Dabs = TMath::Abs(par(0)); 413 if (Dabs > Rd)Rd = Dabs; 414 } 415 // 416 // Find track pair with largest phi difference 417 Int_t isel=0; Int_t jsel=0; // selected track indices 418 Double_t dphiMax = 0.0; // Max phi difference 419 for (Int_t i = 0; i < fNtr-1; i++) 420 { 421 //ObsTrk* ti = tracks[i]; 422 TVectorD pari = *fPar[i]; 423 Double_t phi1 = pari(1); 424 425 for (Int_t j = i+1; j < fNtr; j++) 426 { 427 //ObsTrk* tj = tracks[j]; 428 TVectorD parj = *fPar[j]; 429 Double_t phi2 = parj(1); 430 Double_t dphi = TMath::Abs(phi2 - phi1); 431 if (dphi > TMath::Pi())dphi = TMath::TwoPi() - dphi; 432 if (dphi > dphiMax) 433 { 434 isel = i; jsel = j; 435 dphiMax = dphi; 436 } 437 } 438 } 439 // 440 // 441 //ObsTrk* t1 = tracks[isel]; 442 TVectorD p1 = *fPar[isel]; 443 //ObsTrk* t2 = tracks[jsel]; 444 TVectorD p2 = *fPar[jsel]; 445 Double_t R = FastRv1(p1, p2); 446 if (R > 1.0) R = Rd; 447 R = 0.9*R + 0.1*Rd; 448 // 449 //std::cout << "VertexFinder: fast R = " << R << std::endl; 470 TVectorD x0 = fXv; // If previous fit done 471 if (fRold < 0.0)for (Int_t i = 0; i < 3; i++)x0(i) = 1000.; // Set to arbitrary large value if not 472 // 473 // Starting vertex radius approximation 474 // 475 Double_t R = fRold; // Use previous fit if available 476 if (R < 0.0) R = StartRadius(); // Rough vertex estimate 450 477 // 451 478 // Iteration properties … … 456 483 Double_t epsi = 1000.; 457 484 // 485 // Iteration loop 458 486 while (epsi > eps && Ntry < TryMax) // Iterate until found vertex is stable 459 487 { 488 // Initialize arrays 460 489 x.Zero(); 461 490 TVectorD cterm(3); TMatrixDSym H(3); TMatrixDSym DW1D(3); 462 covX.Zero(); // Reset vertex covariance491 covX.Zero(); // Reset vertex covariance 463 492 cterm.Zero(); // Reset constant term 464 493 H.Zero(); // Reset H matrix 465 494 DW1D.Zero(); 466 495 // 467 //std::cout << "VertexFinder: start loop on tracks" << std::endl; 496 // Reset work arrays 497 // 498 ResetWrkArrays(); 499 // 500 // Start loop on tracks 501 // 468 502 for (Int_t i = 0; i < fNtr; i++) 469 503 { 470 504 // Get track helix parameters and their covariance matrix 471 //ObsTrk *t = tracks[i];472 505 TVectorD par = *fPar[i]; 473 506 TMatrixDSym Cov = *fCov[i]; 507 // 508 // For first iteration only 474 509 Double_t fs; 475 510 if (Ntry <= 0) // Initialize all phases on first pass … … 477 512 Double_t D = par(0); 478 513 Double_t C = par(2); 479 Double_t arg = TMath::Max(1.0e-6, (R *R - D*D) / (1 + 2 * C*D));480 fs = 2 * TMath::ASin(C *TMath::Sqrt(arg));481 f i[i] = fs;514 Double_t arg = TMath::Max(1.0e-6, (R * R - D * D) / (1 + 2 * C * D)); 515 fs = 2 * TMath::ASin(C * TMath::Sqrt(arg)); 516 ffi.push_back(fs); 482 517 } 483 518 // 484 // Starting values 485 // 486 fs = fi[i]; // Get phase 487 //std::cout << "VertexFinder: phase fs set" << std::endl; 488 TVectorD xs = Fill_x(par, fs); 489 //std::cout << "VertexFinder: position xs set" << std::endl; 490 x0i[i] = new TVectorD(xs); // Start helix position 491 //std::cout << "VertexFinder: position x0i stored" << std::endl; 492 // W matrix = (A*C*A')^-1; W^-1 = A*C*A' 493 TMatrixD A = Fill_A(par, fs); // A = dx/da = derivatives wrt track parameters 494 //std::cout << "VertexFinder: derivatives A set" << std::endl; 495 TMatrixDSym Winv = Cov.Similarity(A); // W^-1 = A*C*A' 496 Winvi[i] = new TMatrixDSym(Winv); // Store W^-1 matrix 497 //std::cout << "VertexFinder: Winvi stored" << std::endl; 498 TMatrixDSym W = RegInv3(Winv); // W = (A*C*A')^-1 499 Wi[i] = new TMatrixDSym(W); // Store W matrix 500 //std::cout << "VertexFinder: Wi stored" << std::endl; 501 TVectorD a = Fill_a(par, fs); // a = dx/ds = derivatives wrt phase 502 //std::cout << "VertexFinder: derivatives a set" << std::endl; 503 ai[i] = new TVectorD(a); // Store a 504 //std::cout << "VertexFinder: derivatives a stored" << std::endl; 505 Double_t a2 = W.Similarity(a); 506 a2i[i] = a2; // Store a2 507 // Build D matrix 508 TMatrixDSym B(3); 509 B.Rank1Update(a, 1.0); 510 B *= -1. / a2; 511 B.Similarity(W); 512 TMatrixDSym Ds = W+B; // D matrix 513 Di[i] = new TMatrixDSym(Ds); // Store D matrix 514 //std::cout << "VertexFinder: matrix Di stored" << std::endl; 519 // Update track related arrays 520 // 521 UpdateTrkArrays(i); 522 TMatrixDSym Ds = *fDi[i]; 523 TMatrixDSym Winv = *fWinvi[i]; 515 524 TMatrixDSym DsW1Ds = Winv.Similarity(Ds); // Service matrix to calculate covX 525 // 526 // Update global arrays 516 527 DW1D += DsW1Ds; 517 528 // Update hessian 518 529 H += Ds; 519 530 // update constant term 531 TVectorD xs = *fx0i[i]; 520 532 cterm += Ds * xs; 521 533 } // End loop on tracks 522 534 // 523 535 // update vertex position 524 TMatrixDSym H1 = RegInv 3(H);525 x = H1 *cterm;526 // std::cout << "VertexFinder: x vertex set" << std::endl;536 TMatrixDSym H1 = RegInv(H); 537 x = H1 * cterm; 538 // 527 539 // Update vertex covariance 528 540 covX = DW1D.Similarity(H1); 529 // std::cout << "VertexFinder: cov vertex set" << std::endl;541 // 530 542 // Update phases and chi^2 531 543 Chi2 = 0.0; 532 544 for (Int_t i = 0; i < fNtr; i++) 533 545 { 534 TVectorD lambda = (* Di[i])*(*x0i[i] - x);535 TMatrixDSym Wm1 = * Winvi[i];546 TVectorD lambda = (*fDi[i]) * (*fx0i[i] - x); 547 TMatrixDSym Wm1 = *fWinvi[i]; 536 548 fChi2List(i) = Wm1.Similarity(lambda); 537 549 Chi2 += fChi2List(i); 538 TVectorD a = * ai[i];539 TVectorD b = (* Wi[i])*(x - *x0i[i]);540 for (Int_t j = 0; j < 3; j++)f i[i] += a(j)*b(j) /a2i[i];550 TVectorD a = *fai[i]; 551 TVectorD b = (*fWi[i]) * (x - (*fx0i[i])); 552 for (Int_t j = 0; j < 3; j++)ffi[i] += a(j) * b(j) / fa2i[i]; 541 553 } 542 543 //std::cout << "VertexFinder: end chi2 calculation" << std::endl;544 554 // 545 555 TVectorD dx = x - x0; 546 556 x0 = x; 547 557 // update vertex stability 548 TMatrixDSym Hess = RegInv 3(covX);558 TMatrixDSym Hess = RegInv(covX); 549 559 epsi = Hess.Similarity(dx); 550 560 Ntry++; … … 552 562 // Store result 553 563 // 554 fXv = x; // Vertex position564 fXv = x; // Vertex position 555 565 fcovXv = covX; // Vertex covariance 556 566 fChi2 = Chi2; // Vertex fit Chi2 557 // 558 // Store intermediate data 559 // 560 561 //std::cout << "VertexFinder: before store intermediate data" << std::endl; 562 for (Int_t i = 0; i < fNtr; i++) 563 { 564 //std::cout << "VertexFinder: inside store intermediate data" << std::endl; 565 //std::cout << "i = " << i << ", fi[i] = " << fi[i] << std::endl; 566 //std::cout << "i = " << i << ", ffi[i] = " << ffi[i] << std::endl; 567 ffi[i] = fi[i]; // Fit phases 568 //std::cout << "VertexFinder: fi stored" << std::endl; 569 fx0i[i] = x0i[i]; // Track expansion points 570 //std::cout << "VertexFinder: x0i stored" << std::endl; 571 fai[i] = ai[i]; // dx/dphi 572 //std::cout << "VertexFinder: ai stored" << std::endl; 573 fa2i[i] = a2i[i]; // a'Wa 574 //std::cout << "VertexFinder: a2i stored" << std::endl; 575 fDi[i] = Di[i]; // W-WBW 576 //std::cout << "VertexFinder: Di stored" << std::endl; 577 fWi[i] = Wi[i]; // (ACA')^-1 578 //std::cout << "VertexFinder: Wi stored" << std::endl; 579 fWinvi[i] = Winvi[i]; // ACA' 580 //std::cout << "VertexFinder: Winvi stored" << std::endl; 581 } 582 //std::cout << "Iteration " << Ntry << " completed - Before cleanup" << std::endl; 583 // 584 // Cleanup 585 // 586 for (Int_t i = 0; i < fNtr; i++) 587 { 588 x0i[i]->Clear(); 589 Winvi[i]->Clear(); 590 Wi[i]->Clear(); 591 ai[i]->Clear(); 592 Di[i]->Clear(); 593 594 delete x0i[i]; 595 delete Winvi[i]; 596 delete Wi[i]; 597 delete ai[i]; 598 delete Di[i]; 599 } 600 601 //std::cout << "Iteration " << Ntry << " completed - After cleanup" << std::endl; 602 } 603 // 604 fVtxDone = kTRUE; // Set fitting completion flag 605 // 606 delete[] fi; // Phases 607 delete[] x0i; // Track expansion point 608 delete[] ai; // dx/dphi 609 delete[] a2i; // a'Wa 610 delete[] Di; // W-WBW 611 delete[] Wi; // (ACA')^-1 612 delete[] Winvi; // ACA' 613 } 614 // 567 } // end of iteration loop 568 // 569 fVtxDone = kTRUE; // Set fit completion flag 570 fRold = TMath::Sqrt(fXv(0)*fXv(0) + fXv(1)*fXv(1)); // Store fit radius 571 // 572 } 573 // 574 // Return fit vertex 615 575 TVectorD VertexFit::GetVtx() 616 576 { 617 //std::cout << "GetVtx: flag set to " << fVtxDone << std::endl; 618 if (!fVtxDone)VertexFinder(); 577 if (!fVtxDone) VertexFitter(); 619 578 return fXv; 620 579 } 621 580 // 581 // Return fit vertex covariance 622 582 TMatrixDSym VertexFit::GetVtxCov() 623 583 { 624 if (!fVtxDone) VertexFinder();584 if (!fVtxDone) VertexFitter(); 625 585 return fcovXv; 626 586 } 627 587 // 588 // Return fit vertex chi2 628 589 Double_t VertexFit::GetVtxChi2() 629 590 { 630 if (!fVtxDone) VertexFinder();591 if (!fVtxDone) VertexFitter(); 631 592 return fChi2; 632 593 } 633 594 // 595 // Return array of chi2 contributions from each track 634 596 TVectorD VertexFit::GetVtxChi2List() 635 597 { 636 if (!fVtxDone) VertexFinder();598 if (!fVtxDone) VertexFitter(); 637 599 return fChi2List; 638 600 } … … 644 606 } 645 607 // 646 void VertexFit::AddTrk(TVectorD par, TMatrixDSym Cov) // Add track to input list 647 { 648 std::cout << "VertexFit::AddTrk: Not implemented yet" << std::endl; 649 } 650 void VertexFit::RemoveTrk(Int_t iTrk) // Remove iTrk track 651 { 652 std::cout << "VertexFit::RemoveTrk: Not implemented yet" << std::endl; 653 } 608 // Adding tracks one by one 609 void VertexFit::AddTrk(TVectorD *par, TMatrixDSym *Cov) // Add track to input list 610 { 611 fNtr++; 612 fChi2List.ResizeTo(fNtr); // Resize chi2 array 613 fPar.push_back(par); // add new track 614 fCov.push_back(Cov); 615 // 616 // Reset previous vertex temp arrays 617 ResetWrkArrays(); 618 ffi.clear(); 619 fVtxDone = kFALSE; // Reset vertex done flag 620 } 621 // 622 // Removing tracks one by one 623 void VertexFit::RemoveTrk(Int_t iTrk) // Remove iTrk track 624 { 625 fNtr--; 626 fChi2List.Clear(); 627 fChi2List.ResizeTo(fNtr); // Resize chi2 array 628 fPar.erase(fPar.begin() + iTrk); // Remove track 629 fCov.erase(fCov.begin() + iTrk); 630 // 631 // Reset previous vertex temp arrays 632 ResetWrkArrays(); 633 ffi.clear(); 634 fVtxDone = kFALSE; // Reset vertex done flag 635 }
Note:
See TracChangeset
for help on using the changeset viewer.