/* Vertex fitting code */ #include #include #include #include #include #include #include "VertexFit.h" // // Constructors // // // Empty construction (to be used when adding tracks later with AddTrk() ) VertexFit::VertexFit() { fNtr = 0; fRold = -1.0; fVtxDone = kFALSE; fVtxCst = kFALSE; fxCst.ResizeTo(3); fCovCst.ResizeTo(3, 3); fCovCstInv.ResizeTo(3, 3); fXv.ResizeTo(3); fcovXv.ResizeTo(3, 3); } // // Build from list of parameters and covariances VertexFit::VertexFit(Int_t Ntr, TVectorD** trkPar, TMatrixDSym** trkCov) { fNtr = Ntr; fRold = -1.0; fVtxDone = kFALSE; fVtxCst = kFALSE; fxCst.ResizeTo(3); fCovCst.ResizeTo(3, 3); fCovCstInv.ResizeTo(3, 3); fXv.ResizeTo(3); fcovXv.ResizeTo(3, 3); // for (Int_t i = 0; i < fNtr; i++) { fPar.push_back(new TVectorD(*trkPar[i])); fParNew.push_back(new TVectorD(*trkPar[i])); fCov.push_back(new TMatrixDSym(*trkCov[i])); fCovNew.push_back(new TMatrixDSym(*trkCov[i])); } fChi2List.ResizeTo(fNtr); // } // // Build from ObsTrk list of tracks VertexFit::VertexFit(Int_t Ntr, ObsTrk** track) { fNtr = Ntr; fRold = -1.0; fVtxDone = kFALSE; fVtxCst = kFALSE; fxCst.ResizeTo(3); fCovCst.ResizeTo(3, 3); fCovCstInv.ResizeTo(3, 3); fXv.ResizeTo(3); fcovXv.ResizeTo(3, 3); // fChi2List.ResizeTo(fNtr); for (Int_t i = 0; i < fNtr; i++) { fPar.push_back(new TVectorD(track[i]->GetObsPar())); fParNew.push_back(new TVectorD(track[i]->GetObsPar())); fCov.push_back(new TMatrixDSym(track[i]->GetCov())); fCovNew.push_back(new TMatrixDSym(track[i]->GetCov())); } } // // Destructor // void VertexFit::ResetWrkArrays() { Int_t N = (Int_t)fdi.size(); if(N > 0){ for (Int_t i = 0; i < N; i++) { if (fx0i[i]) { fx0i[i]->Clear(); delete fx0i[i]; } if (fai[i]) { fai[i]->Clear(); delete fai[i]; } if (fdi[i]) { fdi[i]->Clear(); delete fdi[i]; } if (fAti[i]) { fAti[i]->Clear(); delete fAti[i]; } if (fDi[i]) { fDi[i]->Clear(); delete fDi[i]; } if (fWi[i]) { fWi[i]->Clear(); delete fWi[i]; } if (fWinvi[i]){ fWinvi[i]->Clear(); delete fWinvi[i]; } } fa2i.clear(); fx0i.clear(); fai.clear(); fdi.clear(); fAti.clear(); fDi.clear(); fWi.clear(); fWinvi.clear(); } } VertexFit::~VertexFit() { fxCst.Clear(); fCovCst.Clear(); fCovCstInv.Clear(); fXv.Clear(); fcovXv.Clear(); fChi2List.Clear(); // for (Int_t i = 0; i < fNtr; i++) { fPar[i]->Clear(); delete fPar[i]; fParNew[i]->Clear(); delete fParNew[i]; fCov[i]->Clear(); delete fCov[i]; fCovNew[i]->Clear(); delete fCovNew[i]; } fPar.clear(); fParNew.clear(); fCov.clear(); fCovNew.clear(); // ResetWrkArrays(); ffi.clear(); fNtr = 0; } // // // TVectorD VertexFit::Fill_x0(TVectorD par) { // // Calculate track 3D position at R = |D| (minimum approach to z-axis) // TVectorD x0(3); // // Decode input arrays // Double_t D = par(0); Double_t p0 = par(1); Double_t C = par(2); Double_t z0 = par(3); Double_t ct = par(4); // x0(0) = -D * TMath::Sin(p0); x0(1) = D * TMath::Cos(p0); x0(2) = z0; // return x0; } // TVectorD VertexFit::Fill_x(TVectorD par, Double_t phi) { // // Calculate track 3D position for a given phase, phi // TVectorD x(3); // // Decode input arrays // Double_t D = par(0); Double_t p0 = par(1); Double_t C = par(2); Double_t z0 = par(3); Double_t ct = par(4); // TVectorD x0 = Fill_x0(par); x(0) = x0(0) + (TMath::Sin(phi + p0) - TMath::Sin(p0)) / (2 * C); x(1) = x0(1) - (TMath::Cos(phi + p0) - TMath::Cos(p0)) / (2 * C); x(2) = x0(2) + ct * phi / (2 * C); // return x; } // void VertexFit::UpdateTrkArrays(Int_t i) { // // Get track parameters, covariance and phase Double_t fs = ffi[i]; // Get phase TVectorD par = *fParNew[i]; TMatrixDSym Cov = *fCov[i]; // // Fill all track related work arrays arrays TMatrixD A = derXdPar(par, fs); // A = dx/da = derivatives wrt track parameters TMatrixDSym Winv = Cov; Winv.Similarity(A); // W^-1 = A*C*A' TMatrixD At(TMatrixD::kTransposed, A); // A transposed fAti.push_back(new TMatrixD(At)); // Store A' fWinvi.push_back(new TMatrixDSym(Winv)); // Store W^-1 matrix // TVectorD xs = Fill_x(par, fs); fx0i.push_back(new TVectorD(xs)); // Start helix position // TVectorD di = A * (par - *fPar[i]); // x-shift fdi.push_back(new TVectorD(di)); // Store x-shift // TMatrixDSym W = RegInv(Winv); // W = (A*C*A')^-1 fWi.push_back(new TMatrixDSym(W)); // Store W matrix // TVectorD a = derXds(par, fs); // a = dx/ds = derivatives wrt phase fai.push_back(new TVectorD(a)); // Store a // Double_t a2 = W.Similarity(a); fa2i.push_back(a2); // Store a2 // // Build D matrix TMatrixDSym B(3); B.Rank1Update(a, -1. / a2); B.Similarity(W); TMatrixDSym Ds = W + B; // D matrix fDi.push_back(new TMatrixDSym(Ds)); // Store D matrix } // void VertexFit::VtxFitNoSteer() { // // Initialize // std::vector x0i; // Tracks at ma std::vector ni; // Track derivative wrt phase std::vector Ci; // Position error matrix at fixed phase std::vector wi; // Ci*ni // // Track loop for (Int_t i = 0; i < fNtr; i++) { Double_t s = 0.; TVectorD par = *fPar[i]; TMatrixDSym Cov = *fCov[i]; x0i.push_back(new TVectorD(Fill_x0(par))); ni.push_back(new TVectorD(derXds(par, s))); TMatrixD A = derXdPar(par, s); Ci.push_back(new TMatrixDSym(Cov.Similarity(A))); TMatrixDSym Cinv = RegInv(*Ci[i]); wi.push_back(new TVectorD(Cinv * (*ni[i]))); } //std::cout << "Vtx init completed. fNtr = "<Similarity(*wi[i])); TMatrixDSym Dd = Cinv - W; D += Dd; Dx += Dd * (*x0i[i]); } if(fVtxCst){ D += fCovCstInv; Dx += fCovCstInv*fxCst; } fXv = RegInv(D) * Dx; //std::cout << "Fast vertex (x, y, z) = "<Similarity(*wi[i]); ffi.push_back(si); //TVectorD xvi = Fill_x(*fPar[i],si); //std::cout << "Fast vertex "< eps && Ntry < TryMax) // Iterate until found vertex is stable { // Initialize arrays x.Zero(); TVectorD cterm(3); TMatrixDSym H(3); TMatrixDSym DW1D(3); covX.Zero(); // Reset vertex covariance cterm.Zero(); // Reset constant term H.Zero(); // Reset H matrix DW1D.Zero(); // // Reset work arrays // ResetWrkArrays(); // // Start loop on tracks // for (Int_t i = 0; i < fNtr; i++) { // Get track helix parameters and their covariance matrix TVectorD par = *fPar[i]; TMatrixDSym Cov = *fCov[i]; // // Update track related arrays // UpdateTrkArrays(i); TMatrixDSym Ds = *fDi[i]; TMatrixDSym Winv = *fWinvi[i]; TMatrixDSym DsW1Ds = Winv.Similarity(Ds); // Service matrix to calculate covX // // Update global arrays DW1D += DsW1Ds; // Update hessian H += Ds; // update constant term TVectorD xs = *fx0i[i] - *fdi[i]; //TVectorD xx0 = *fx0i[i]; //std::cout << "Iter. " << Ntry << ", trk " << i << ", xs= " // << xs(0) << ", " << xs(1) << ", " << xs(2)<< // ", ph0= "<