Fork me on GitHub

Ignore:
Timestamp:
Nov 29, 2021, 4:04:38 PM (3 years ago)
Author:
GitHub <noreply@…>
Branches:
master
Children:
0c0c9af
Parents:
9a7ea36 (diff), bd376e3 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
git-author:
Michele Selvaggi <michele.selvaggi@…> (11/29/21 16:04:38)
git-committer:
GitHub <noreply@…> (11/29/21 16:04:38)
Message:

Merge pull request #102 from fbedesch/master

Major update to handle highly displaced tracks

File:
1 edited

Legend:

Unmodified
Added
Removed
  • external/TrackCovariance/TrkUtil.cc

    r9a7ea36 r0b8551f  
    33#include <algorithm>
    44#include <TSpline.h>
     5#include <TDecompChol.h>
    56
    67// Constructor
     
    3334        fZmin = 0.0;                            // Lower                DCH z
    3435        fZmax = 0.0;                            // Higher       DCH z
     36}
     37//
     38// Distance between two lines
     39//
     40void TrkUtil::LineDistance(TVector3 x0, TVector3 y0, TVector3 dirx, TVector3 diry, Double_t &sx, Double_t &sy, Double_t &distance)
     41{
     42        TMatrixDSym M(2);
     43        M(0,0) = dirx.Mag2();
     44        M(1,1) = diry.Mag2();
     45        M(0,1) = -dirx.Dot(diry);
     46        M(1,0) = M(0,1);
     47        M.Invert();
     48        TVectorD c(2);
     49        c(0) = dirx.Dot(y0-x0);
     50        c(1) = diry.Dot(x0-y0);
     51        TVectorD st = M*c;
     52        //
     53        // Fill output
     54        sx = st(0);
     55        sy = st(1);
     56        //
     57        TVector3 x = x0+sx*dirx;
     58        TVector3 y = y0+sy*diry;
     59        TVector3 d = x-y;
     60        distance = d.Mag();
     61}
     62//
     63// Covariance smearing
     64//
     65TVectorD TrkUtil::CovSmear(TVectorD x, TMatrixDSym C)
     66{
     67        //
     68        // Check arrays
     69        //
     70        // Consistency of dimensions
     71        Int_t Nvec = x.GetNrows();
     72        Int_t Nmat = C.GetNrows();
     73        if (Nvec != Nmat || Nvec == 0)
     74        {
     75                std::cout << "TrkUtil::CovSmear: vector/matrix mismatch. Aborting." << std::endl;
     76                exit(EXIT_FAILURE);
     77        }
     78        // Positive diagonal elements
     79        for (Int_t i = 0; i < Nvec; i++)
     80        {
     81                if (C(i, i) <= 0.0)
     82                {
     83                        std::cout << "TrkUtil::CovSmear: covariance matrix has negative diagonal elements. Aborting." << std::endl;
     84                        exit(EXIT_FAILURE);
     85                }
     86        }
     87        //
     88        // Do a Choleski decomposition and random number extraction, with appropriate stabilization
     89        //
     90        TMatrixDSym CvN = C;
     91        TMatrixDSym DCv(Nvec); DCv.Zero();
     92        TMatrixDSym DCvInv(Nvec); DCvInv.Zero();
     93        for (Int_t id = 0; id < Nvec; id++)
     94        {
     95                Double_t dVal = TMath::Sqrt(C(id, id));
     96                DCv(id, id) = dVal;
     97                DCvInv(id, id) = 1.0 / dVal;
     98        }
     99        CvN.Similarity(DCvInv);                 // Normalize diagonal to 1
     100        TDecompChol Chl(CvN);
     101        Bool_t OK = Chl.Decompose();            // Choleski decomposition of normalized matrix
     102        if (!OK)
     103        {
     104                std::cout << "TrkUtil::CovSmear: covariance matrix is not positive definite. Aborting." << std::endl;
     105                exit(EXIT_FAILURE);
     106        }
     107        TMatrixD U = Chl.GetU();                        // Get Upper triangular matrix
     108        TMatrixD Ut(TMatrixD::kTransposed, U); // Transposed of U (lower triangular)
     109        TVectorD r(Nvec);
     110        for (Int_t i = 0; i < Nvec; i++)r(i) = gRandom->Gaus(0.0, 1.0);         // Array of normal random numbers
     111        TVectorD xOut = x + DCv * (Ut * r);     // Observed parameter vector
     112        //
     113        return xOut;
    35114}
    36115//
     
    48127        Double_t r2 = x(0) * x(0) + x(1) * x(1);
    49128        Double_t cross = x(0) * p(1) - x(1) * p(0);
    50         Double_t T = sqrt(pt * pt - 2 * a * cross + a * a * r2);
    51         Double_t phi0 = atan2((p(1) - a * x(0)) / T, (p(0) + a * x(1)) / T);    // Phi0
     129        Double_t T = TMath::Sqrt(pt * pt - 2 * a * cross + a * a * r2);
     130        Double_t phi0 = TMath::ATan2((p(1) - a * x(0)) / T, (p(0) + a * x(1)) / T);     // Phi0
    52131        Double_t D;                                                     // Impact parameter D
    53132        if (pt < 10.0) D = (T - pt) / a;
     
    58137        Par(2) = C;             // Store C
    59138        //Longitudinal parameters
    60         Double_t B = C * sqrt(TMath::Max(r2 - D * D, 0.0) / (1 + 2 * C * D));
    61         Double_t st = asin(B) / C;
     139        Double_t B = C * TMath::Sqrt(TMath::Max(r2 - D * D, 0.0) / (1 + 2 * C * D));
     140        Double_t st = TMath::ASin(B) / C;
    62141        Double_t ct = p(2) / pt;
    63142        Double_t z0;
     
    235314        //
    236315        return Cmm;
     316}//
     317// Regularized symmetric matrix inversion
     318//
     319TMatrixDSym TrkUtil::RegInv(TMatrixDSym& Min)
     320{
     321        TMatrixDSym M = Min;                            // Decouple from input
     322        Int_t N = M.GetNrows();                 // Matrix size
     323        TMatrixDSym D(N); D.Zero();             // Normaliztion matrix
     324        TMatrixDSym R(N);                               // Normarized matrix
     325        TMatrixDSym Rinv(N);                            // Inverse of R
     326        TMatrixDSym Minv(N);                            // Inverse of M
     327        //
     328        // Check for 0's and normalize
     329        for (Int_t i = 0; i < N; i++)
     330        {
     331                if (M(i, i) != 0.0) D(i, i) = 1. / TMath::Sqrt(TMath::Abs(M(i, i)));
     332                else D(i, i) = 1.0;
     333        }
     334        R = M.Similarity(D);
     335        //
     336        // Recursive algorithms stops when N = 2
     337        //
     338        //****************
     339        // case N = 2  ***
     340        //****************
     341        if (N == 2)
     342        {
     343                Double_t det = R(0, 0) * R(1, 1) - R(0, 1) * R(1, 0);
     344                if (det == 0)
     345                {
     346                        std::cout << "VertexFit::RegInv: null determinant for N = 2" << std::endl;
     347                        Rinv.Zero();    // Return null matrix
     348                }
     349                else
     350                {
     351                        // invert matrix
     352                        Rinv(0, 0) = R(1, 1);
     353                        Rinv(0, 1) = -R(0, 1);
     354                        Rinv(1, 0) = Rinv(0, 1);
     355                        Rinv(1, 1) = R(0, 0);
     356                        Rinv *= 1. / det;
     357                }
     358        }
     359        //****************
     360        // case N > 2  ***
     361        //****************
     362        else
     363        {
     364                // Break up matrix
     365                TMatrixDSym Q = R.GetSub(0, N - 2, 0, N - 2);   // Upper left
     366                TVectorD p(N - 1);
     367                for (Int_t i = 0; i < N - 1; i++)p(i) = R(N - 1, i);
     368                Double_t q = R(N - 1, N - 1);
     369                //Invert pieces and re-assemble
     370                TMatrixDSym Ainv(N - 1);
     371                TMatrixDSym A(N - 1);
     372                if (TMath::Abs(q) > 1.0e-15)
     373                {
     374                        // Case |q| > 0
     375                        Ainv.Rank1Update(p, -1.0 / q);
     376                        Ainv += Q;
     377                        A = RegInv(Ainv);               // Recursive call
     378                        TMatrixDSub(Rinv, 0, N - 2, 0, N - 2) = A;
     379                        //
     380                        TVectorD b = (-1.0 / q) * (A * p);
     381                        for (Int_t i = 0; i < N - 1; i++)
     382                        {
     383                                Rinv(N - 1, i) = b(i);
     384                                Rinv(i, N - 1) = b(i);
     385                        }
     386                        //
     387                        Double_t pdotb = 0.;
     388                        for (Int_t i = 0; i < N - 1; i++)pdotb += p(i) * b(i);
     389                        Double_t c = (1.0 - pdotb) / q;
     390                        Rinv(N - 1, N - 1) = c;
     391                }
     392                else
     393                {
     394                        // case q = 0
     395                        TMatrixDSym Qinv = RegInv(Q);           // Recursive call
     396                        Double_t a = Qinv.Similarity(p);
     397                        Double_t c = -1.0 / a;
     398                        Rinv(N - 1, N - 1) = c;
     399                        //
     400                        TVectorD b = (1.0 / a) * (Qinv * p);
     401                        for (Int_t i = 0; i < N - 1; i++)
     402                        {
     403                                Rinv(N - 1, i) = b(i);
     404                                Rinv(i, N - 1) = b(i);
     405                        }
     406                        //
     407                        A.Rank1Update(p, -1 / a);
     408                        A += Q;
     409                        A.Similarity(Qinv);
     410                        TMatrixDSub(Rinv, 0, N - 2, 0, N - 2) = A;
     411                }
     412        }
     413        Minv = Rinv.Similarity(D);
     414        return Minv;
     415}
     416//
     417// Track tracjectory
     418//
     419TVector3 TrkUtil::Xtrack(TVectorD par, Double_t s)
     420{
     421        //
     422        // unpack parameters
     423        Double_t D = par(0);
     424        Double_t p0 = par(1);
     425        Double_t C = par(2);
     426        Double_t z0 = par(3);
     427        Double_t ct = par(4);
     428        //
     429        Double_t x = -D * TMath::Sin(p0) + (TMath::Sin(s + p0) - TMath::Sin(p0)) / (2 * C);
     430        Double_t y =  D * TMath::Cos(p0) - (TMath::Cos(s + p0) - TMath::Cos(p0)) / (2 * C);     
     431        Double_t z = z0 + ct * s / (2 * C);
     432        //
     433        TVector3 Xt(x, y, z);
     434        return Xt;
     435}
     436//
     437// Track derivatives
     438//
     439// Constant radius
     440// R-Phi
     441TVectorD TrkUtil::derRphi_R(TVectorD par, Double_t R)
     442{
     443        TVectorD dRphi(5);      // return vector
     444        //
     445        // unpack parameters
     446        Double_t D = par(0);
     447        Double_t C = par(2);
     448        //
     449        Double_t s = 2 * TMath::ASin(C * TMath::Sqrt((R * R - D * D)/(1 + 2 * C * D)));
     450        TVector3 X = Xtrack(par, s);            // Intersection point
     451        TVector3 v(-X.y()/R, X.x()/R, 0.);      // measurement direction
     452        TMatrixD derX = derXdPar(par, s);       // dX/dp
     453        TVectorD derXs = derXds(par, s);        // dX/ds
     454        TVectorD ders = dsdPar_R(par, R);       // ds/dp       
     455        //
     456        for (Int_t i = 0; i < 5; i++)
     457        {
     458                dRphi(i) = 0.;
     459                for (Int_t j = 0; j < 3; j++)
     460                {
     461                        dRphi(i) += v(j) * (derX(j, i) + derXs(j) * ders(i));
     462                }
     463        }
     464        //
     465        return dRphi;
     466}
     467// z
     468TVectorD TrkUtil::derZ_R(TVectorD par, Double_t R)
     469{
     470
     471        TVectorD dZ(5); // return vector
     472        //
     473        // unpack parameters
     474        Double_t D = par(0);
     475        Double_t C = par(2);
     476        //
     477        Double_t s = 2 * TMath::ASin(C * TMath::Sqrt((R * R - D * D)/(1 + 2 * C * D))); // phase
     478        TVector3 v(0., 0., 1.);                         // measurement direction
     479        TMatrixD derX = derXdPar(par, s);       // dX/dp
     480        TVectorD derXs = derXds(par, s);        // dX/ds
     481        TVectorD ders = dsdPar_R(par, R);       // ds/dp       
     482        //
     483        for (Int_t i = 0; i < 5; i++)
     484        {
     485                dZ(i) = 0.;
     486                for (Int_t j = 0; j < 3; j++)
     487                {
     488                        dZ(i) += v(j) * (derX(j, i) + derXs(j) * ders(i));
     489                }
     490        }
     491        //
     492        return dZ;
     493}
     494//
     495// constant z
     496// R-Phi
     497TVectorD TrkUtil::derRphi_Z(TVectorD par, Double_t z)
     498{
     499        TVectorD dRphi(5);      // return vector
     500        //
     501        // unpack parameters
     502        Double_t C = par(2);
     503        Double_t z0 = par(3);
     504        Double_t ct = par(4);
     505        //
     506        Double_t s = 2 * C * (z - z0) / ct;
     507        TVector3 X = Xtrack(par, s);                    // Intersection point
     508        TVector3 v(-X.y() / X.Pt(), X.x() / X.Pt(), 0.);        // measurement direction
     509        TMatrixD derX = derXdPar(par, s);               // dX/dp
     510        TVectorD derXs = derXds(par, s);                // dX/ds
     511        TVectorD ders = dsdPar_z(par, z);               // ds/dp       
     512        //
     513        for (Int_t i = 0; i < 5; i++)
     514        {
     515                dRphi(i) = 0.;
     516                for (Int_t j = 0; j < 3; j++)
     517                {
     518                        dRphi(i) += v(j) * (derX(j, i) + derXs(j) * ders(i));
     519                }
     520        }
     521        //
     522        return dRphi;
     523
     524}
     525// R
     526TVectorD TrkUtil::derR_Z(TVectorD par, Double_t z)
     527{
     528        TVectorD dR(5); // return vector
     529        //
     530        // unpack parameters
     531        Double_t C = par(2);
     532        Double_t z0 = par(3);
     533        Double_t ct = par(4);
     534        //
     535        Double_t s = 2 * C * (z - z0) / ct;
     536        TVector3 X = Xtrack(par, s);                    // Intersection point
     537        TVector3 v(X.x() / X.Pt(), X.y() / X.Pt(), 0.); // measurement direction
     538        TMatrixD derX = derXdPar(par, s);               // dX/dp
     539        TVectorD derXs = derXds(par, s);                // dX/ds
     540        TVectorD ders = dsdPar_z(par, z);       // ds/dp       
     541        //
     542        for (Int_t i = 0; i < 5; i++)
     543        {
     544                dR(i) = 0.;
     545                for (Int_t j = 0; j < 3; j++)
     546                {
     547                        dR(i) += v(j) * (derX(j, i) + derXs(j) * ders(i));
     548                }
     549        }
     550        //
     551        return dR;
     552
     553}
     554//
     555// derivatives of track trajectory
     556//
     557// dX/dPar
     558TMatrixD TrkUtil::derXdPar(TVectorD par, Double_t s)
     559{
     560        TMatrixD dxdp(3, 5);    // return matrix
     561        //
     562        // unpack parameters
     563        Double_t D = par(0);
     564        Double_t p0 = par(1);
     565        Double_t C = par(2);
     566        Double_t z0 = par(3);
     567        Double_t ct = par(4);
     568        //
     569        // derivatives
     570        // dx/dD
     571        dxdp(0, 0) = -TMath::Sin(p0);
     572        dxdp(1, 0) =  TMath::Cos(p0);
     573        dxdp(2, 0) = 0.;
     574        // dx/dphi0
     575        dxdp(0, 1) = -D * TMath::Cos(p0) + (TMath::Cos(s + p0) - TMath::Cos(p0)) / (2 * C);
     576        dxdp(1, 1) = -D * TMath::Sin(p0) + (TMath::Sin(s + p0) - TMath::Sin(p0)) / (2 * C);
     577        dxdp(2, 1) = 0;
     578        // dx/dC
     579        dxdp(0, 2) = -(TMath::Sin(s + p0) - TMath::Sin(p0)) / (2 * C * C);
     580        dxdp(1, 2) =  (TMath::Cos(s + p0) - TMath::Cos(p0)) / (2 * C * C);
     581        dxdp(2, 2) = -ct * s / (2 * C * C);
     582        // dx/dz0
     583        dxdp(0, 3) = 0;
     584        dxdp(1, 3) = 0;
     585        dxdp(2, 3) = 1.;
     586        // dx/dCtg
     587        dxdp(0, 4) = 0;
     588        dxdp(1, 4) = 0;
     589        dxdp(2, 4) = s / (2 * C);
     590        //
     591        return dxdp;
     592}
     593//
     594// dX/ds
     595//
     596TVectorD TrkUtil::derXds(TVectorD par, Double_t s)
     597{
     598        TVectorD dxds(3);       // return vector
     599        //
     600        // unpack parameters
     601        Double_t p0 = par(1);
     602        Double_t C = par(2);
     603        Double_t ct = par(4);
     604        //
     605        // dX/ds
     606        dxds(0) = TMath::Cos(s + p0) / (2 * C);
     607        dxds(1) = TMath::Sin(s + p0) / (2 * C);
     608        dxds(2) = ct / (2 * C);
     609        //
     610        return dxds;
     611}
     612//
     613// derivative of trajectory phase s
     614//Constant R
     615TVectorD TrkUtil::dsdPar_R(TVectorD par, Double_t R)
     616{
     617        TVectorD dsdp(5);       // return vector
     618        //
     619        // unpack parameters
     620        Double_t D = par(0);
     621        Double_t p0 = par(1);
     622        Double_t C = par(2);
     623        //
     624        // derivatives
     625        Double_t opCD = 1. + 2 * C * D;
     626        Double_t A = C*TMath::Sqrt((R*R-D*D)/opCD);
     627        Double_t sqA0 = TMath::Sqrt(1. - A * A);
     628        Double_t dMin = 0.01;
     629        Double_t sqA = TMath::Max(dMin, sqA0);  // Protect against divergence
     630        //
     631        dsdp(0) = -2 * C * C * (D * (1. + C * D) + C * R * R) / (A * sqA * opCD * opCD);
     632        dsdp(1) = 0;
     633        dsdp(2) = 2 * A * (1 + C * D) / (C * sqA * opCD);
     634        dsdp(3) = 0;
     635        dsdp(4) = 0;
     636        //
     637        return dsdp;
     638}
     639// Constant z
     640TVectorD TrkUtil::dsdPar_z(TVectorD par, Double_t z)
     641{
     642        TVectorD dsdp(5);       // return vector
     643        //
     644        // unpack parameters
     645        Double_t C = par(2);
     646        Double_t z0 = par(3);
     647        Double_t ct = par(4);
     648        //
     649        // derivatives
     650        //
     651        dsdp(0) = 0;
     652        dsdp(1) = 0;
     653        dsdp(2) = 2*(z-z0)/ct;
     654        dsdp(3) = -2*C/ct;
     655        dsdp(4) = -2*C*(z-z0)/(ct*ct);
     656        //
     657        return dsdp;
    237658}
    238659//
Note: See TracChangeset for help on using the changeset viewer.