#include "SolGeom.h" #include "SolTrack.h" #include #include #include #include #include #include #include #include // // Constructors SolTrack::SolTrack(Double_t *x, Double_t *p, SolGeom *G) { // Set B field fG = G; // Store geometry Double_t B = G->B(); SetB(B); // Store momentum and position fp[0] = p[0]; fp[1] = p[1]; fp[2] = p[2]; fx[0] = x[0]; fx[1] = x[1]; fx[2] = x[2]; // Get generated parameters TVector3 xv(fx); TVector3 pv(fp); Double_t Charge = 1.0; // Don't worry about charge for now TVectorD gPar = XPtoPar(xv, pv, Charge); // Store parameters fpar[0] = gPar(0); fpar[1] = gPar(1); fpar[2] = gPar(2); fpar[3] = gPar(3); fpar[4] = gPar(4); //cout << "SolTrack:: C = " << C << ", fpar[2] = " << fpar[2] << endl; // // Init covariances // fCov.ResizeTo(5, 5); } SolTrack::SolTrack(TVector3 x, TVector3 p, SolGeom* G) { // set B field fG = G; // Store geometry Double_t B = G->B(); SetB(B); // Store momentum fp[0] = p(0); fp[1] = p(1); fp[2] = p(2); fx[0] = x(0); fx[1] = x(1); fx[2] = x(2); // Get generated parameters Double_t Charge = 1.0; // Don't worry about charge for now TVectorD gPar = XPtoPar(x, p, Charge); // Store parameters fpar[0] = gPar(0); fpar[1] = gPar(1); fpar[2] = gPar(2); fpar[3] = gPar(3); fpar[4] = gPar(4); //cout << "SolTrack:: C = " << C << ", fpar[2] = " << fpar[2] << endl; // // Init covariances // fCov.ResizeTo(5, 5); } // SolTrack::SolTrack(Double_t D, Double_t phi0, Double_t C, Double_t z0, Double_t ct, SolGeom *G) { fG = G; Double_t B = G->B(); SetB(B); // Store parameters fpar[0] = D; fpar[1] = phi0; fpar[2] = C; fpar[3] = z0; fpar[4] = ct; // Store momentum Double_t pt = B * TrkUtil::cSpeed() / TMath::Abs(2 * C); Double_t px = pt*TMath::Cos(phi0); Double_t py = pt*TMath::Sin(phi0); Double_t pz = pt*ct; // fp[0] = px; fp[1] = py; fp[2] = pz; fx[0] = -D*TMath::Sin(phi0); fx[1] = D*TMath::Cos(phi0); fx[2] = z0; // // Init covariances // fCov.ResizeTo(5, 5); } // Destructor SolTrack::~SolTrack() { fCov.Clear(); } // // Calculate intersection with given layer Bool_t SolTrack::HitLayer(Int_t il, Double_t &R, Double_t &phi, Double_t &zz) { Double_t Di = D(); Double_t phi0i = phi0(); Double_t Ci = C(); Double_t z0i = z0(); Double_t cti = ct(); // R = 0; phi = 0; zz = 0; Bool_t val = kFALSE; Double_t Rmin = TMath::Sqrt(fx[0] * fx[0] + fx[1] * fx[1]); // Smallest track radius if (Rmin < TMath::Abs(Di)) return val; // Double_t ArgzMin = Ci * TMath::Sqrt((Rmin * Rmin - Di * Di) / (1 + 2 * Ci * Di)); Double_t stMin = TMath::ASin(ArgzMin) / Ci; // Arc length at track origin // if (fG->lTyp(il) == 1) // Cylinder: layer at constant R { R = fG->lPos(il); Double_t argph = (Ci*R + (1 + Ci*Di)*Di / R) / (1. + 2.*Ci*Di); if (TMath::Abs(argph) < 1.0 && R > Rmin) { Double_t argz = Ci*TMath::Sqrt((R*R - Di*Di) / (1 + 2 * Ci*Di)); if (TMath::Abs(argz) < 1.0) { zz = z0i + cti*TMath::ASin(argz) / Ci; if (zz > fG->lxMin(il) && zz < fG->lxMax(il)) { phi = phi0i + TMath::ASin(argph); val = kTRUE; } } } } else if (fG->lTyp(il) == 2) // disk: layer at constant z { zz = fG->lPos(il); Double_t st = (zz - z0i) / cti; if (TMath::Abs(Ci * st) < 1.0 && st > stMin) { R = TMath::Sqrt(Di * Di + (1. + 2. * Ci * Di) * pow(TMath::Sin(Ci * st), 2) / (Ci * Ci)); if (R > fG->lxMin(il) && R < fG->lxMax(il)) { Double_t arg1 = (Ci*R + (1 + Ci*Di)*Di / R) / (1. + 2.*Ci*Di); if (TMath::Abs(arg1) < 1.0) { phi = phi0i + TMath::ASin(arg1); val = kTRUE; } } } } // return val; } // // # of layers hit Int_t SolTrack::nHit() { Int_t kh = 0; Double_t R; Double_t phi; Double_t zz; for (Int_t i = 0; i < fG->Nl(); i++) if (HitLayer(i, R, phi, zz))kh++; // return kh; } // // # of measurement layers hit Int_t SolTrack::nmHit() { Int_t kmh = 0; Double_t R; Double_t phi; Double_t zz; for (Int_t i = 0; i < fG->Nl(); i++) if (HitLayer(i, R, phi, zz))if (fG->isMeasure(i))kmh++; // return kmh; } // // List of layers hit with intersections Int_t SolTrack::HitList(Int_t *&ihh, Double_t *&rhh, Double_t *&zhh) { // // Return lists of hits associated to a track including all scattering layers. // Return value is the total number of measurement hits // kmh = total number of measurement layers hit for given type // ihh = pointer to layer number // rhh = radius of hit // zhh = z of hit // // ***** NB: double layers with stereo on lower layer not included // Int_t kh = 0; // Number of layers hit Int_t kmh = 0; // Number of measurement layers of given type for (Int_t i = 0; i < fG->Nl(); i++) { Double_t R; Double_t phi; Double_t zz; if (HitLayer(i, R, phi, zz)) { zhh[kh] = zz; rhh[kh] = R; ihh[kh] = i; if (fG->isMeasure(i))kmh++; kh++; } } // return kmh; } // // List of XYZ measurements without any error Int_t SolTrack::HitListXYZ(Int_t *&ihh, Double_t *&Xh, Double_t *&Yh, Double_t *&Zh) { // // Return lists of hits associated to a track for all measurement layers. // Return value is the total number of measurement hits // kmh = total number of measurement layers hit for given type // ihh = pointer to layer number // Xh, Yh, Zh = X, Y, Z of hit - No measurement error - No multiple scattering // // Int_t kmh = 0; // Number of measurement layers hit for (Int_t i = 0; i < fG->Nl(); i++) { Double_t R; Double_t phi; Double_t zz; if (HitLayer(i, R, phi, zz)) // Only barrel type layers { if (fG->isMeasure(i)) { ihh[kmh] = i; Xh[kmh] = R*cos(phi); Yh[kmh] = R*sin(phi); Zh[kmh] = zz; kmh++; } } } // return kmh; } // // Track plot // TGraph *SolTrack::TrkPlot() { // // Fill list of layers hit // Int_t Nhit = nHit(); // Total number of layers hit //cout << "Nhit = " << Nhit << endl; Double_t *zh = new Double_t[Nhit]; // z of hit Double_t *rh = new Double_t[Nhit]; // r of hit Int_t *ih = new Int_t [Nhit]; // true index of layer Int_t kmh; // Number of measurement layers hit // kmh = HitList(ih, rh, zh); // hit layer list //for (Int_t j = 0; j < Nhit; j++) cout << "r = " << rh[j] << ", z = " << zh[j] << endl; Double_t *dh = new Double_t[Nhit]; // Hit distance from origin for(Int_t i=0; i1.0E-15)Check = kTRUE; if (Check) { std::cout << "SolTrack::MakePosDef: input matrix doesn ot have 1 on diagonal. Abort." << std::endl; return rMatN; } // // Diagonalize matrix TMatrixDSymEigen Eign(NormMat); TMatrixD U = Eign.GetEigenVectors(); TVectorD lambda = Eign.GetEigenValues(); //cout << "Eigenvalues:"; lambda.Print(); //cout << "Input matrix: "; NormMat.Print(); // Reset negative eigenvalues to small positive value TMatrixDSym D(Size); D.Zero(); Double_t eps = 1.0e-13; for (Int_t i = 0; i < Size; i++) { D(i, i) = lambda(i); if (lambda(i) <= 0) D(i, i) = eps; } //Rebuild matrix TMatrixD Ut(TMatrixD::kTransposed, U); TMatrixD rMat = (U*D)*Ut; // Now it is positive defite // Restore all ones on diagonal for (Int_t i1 = 0; i1 < Size; i1++) { Double_t rn1 = TMath::Sqrt(rMat(i1, i1)); for (Int_t i2 = 0; i2 <= i1; i2++) { Double_t rn2 = TMath::Sqrt(rMat(i2, i2)); rMatN(i1, i2) = 0.5*(rMat(i1, i2) + rMat(i2, i1)) / (rn1*rn2); rMatN(i2, i1) = rMatN(i1, i2); } } //cout << "Rebuilt matrix: "; rMatN.Print(); return rMatN; }