Fork me on GitHub

Ignore:
Timestamp:
Nov 29, 2021, 3:18:22 PM (3 years ago)
Author:
Franco BEDESCHI <bed@…>
Branches:
master
Children:
bd376e3
Parents:
9a7ea36
Message:

Major update to handle highly displaced tracks

File:
1 edited

Legend:

Unmodified
Added
Removed
  • external/TrackCovariance/SolTrack.cc

    r9a7ea36 rebf40fd  
    1 #include <iostream>
    21
     2#include "SolGeom.h"
     3#include "SolTrack.h"
    34#include <TString.h>
    45#include <TMath.h>
     
    78#include <TDecompChol.h>
    89#include <TMatrixDSymEigen.h>
    9 
    10 #include "SolGeom.h"
    11 #include "SolTrack.h"
    12 
    13 using namespace std;
    14 
     10#include <TGraph.h>
     11#include <iostream>
     12//
     13// Constructors
    1514SolTrack::SolTrack(Double_t *x, Double_t *p, SolGeom *G)
    1615{
    17   fG = G;
    18   // Store momentum
    19   fp[0] = p[0]; fp[1] = p[1]; fp[2] = p[2];
    20   Double_t px = p[0]; Double_t py = p[1]; Double_t pz = p[2];
    21   fx[0] = x[0]; fx[1] = x[1]; fx[2] = x[2];
    22   Double_t xx = x[0]; Double_t yy = x[1]; Double_t zz = x[2];
    23   // Store parameters
    24   Double_t pt = TMath::Sqrt(px*px + py*py);
    25   Double_t Charge = 1.0;            // Don't worry about charge for now
    26   Double_t a = -Charge*G->B()*0.2998;     // Normalized speed of light
    27   Double_t C = a / (2 * pt);          // pt in GeV, B in Tesla, C in meters
    28   Double_t r2 = xx*xx + yy*yy;
    29   Double_t cross = xx*py - yy*px;
    30   Double_t T = TMath::Sqrt(pt*pt - 2 * a*cross + a*a*r2);
    31   Double_t phi0 = TMath::ATan2((py - a*xx) / T, (px + a*yy) / T);
    32   Double_t D;
    33   if (pt < 10.0) D = (T - pt) / a;
    34   else D = (-2 * cross + a*r2) / (T + pt);
    35   Double_t B = C*TMath::Sqrt((r2 - D*D) / (1 + 2 * C*D));
    36   Double_t st = TMath::ASin(B) / C;
    37   Double_t ct = pz / pt;
    38   Double_t z0 = zz - ct*st;
    39   fpar[0] = D;
    40   fpar[1] = phi0;
    41   fpar[2] = C;
    42   fpar[3] = z0;
    43   fpar[4] = ct;
    44   // Init covariances
    45   fCov.ResizeTo(5, 5);
     16        // Set B field
     17        fG = G;                                 // Store geometry
     18        Double_t B = G->B();
     19        SetB(B);
     20        // Store momentum and position
     21        fp[0] = p[0]; fp[1] = p[1]; fp[2] = p[2];
     22        fx[0] = x[0]; fx[1] = x[1]; fx[2] = x[2];
     23        // Get generated parameters
     24        TVector3 xv(fx);
     25        TVector3 pv(fp);
     26        Double_t Charge = 1.0;                                          // Don't worry about charge for now
     27        TVectorD gPar = XPtoPar(xv, pv, Charge);
     28        // Store parameters
     29        fpar[0] = gPar(0);
     30        fpar[1] = gPar(1);
     31        fpar[2] = gPar(2);
     32        fpar[3] = gPar(3);
     33        fpar[4] = gPar(4);
     34        //cout << "SolTrack:: C = " << C << ", fpar[2] = " << fpar[2] << endl;
     35        //
     36        // Init covariances
     37        //
     38        fCov.ResizeTo(5, 5);
    4639}
    4740SolTrack::SolTrack(TVector3 x, TVector3 p, SolGeom* G)
    4841{
    49         fG = G;
     42        // set B field
     43        fG = G;                                 // Store geometry
     44        Double_t B = G->B();
     45        SetB(B);
    5046        // Store momentum
    5147        fp[0] = p(0); fp[1] = p(1); fp[2] = p(2);
    52         Double_t px = p(0); Double_t py = p(1); Double_t pz = p(2);
    5348        fx[0] = x(0); fx[1] = x(1); fx[2] = x(2);
    54         Double_t xx = x(0); Double_t yy = x(1); Double_t zz = x(2);
     49        // Get generated parameters
     50        Double_t Charge = 1.0;                                          // Don't worry about charge for now
     51        TVectorD gPar = XPtoPar(x, p, Charge);
    5552        // Store parameters
    56         Double_t pt = TMath::Sqrt(px * px + py * py);
    57         Double_t Charge = 1.0;                                          // Don't worry about charge for now
    58         Double_t a = -Charge * G->B() * 0.2998;                 // Normalized speed of light
    59         Double_t C = a / (2 * pt);                                      // pt in GeV, B in Tesla, C in meters
    60         Double_t r2 = xx * xx + yy * yy;
    61         Double_t cross = xx * py - yy * px;
    62         Double_t T = TMath::Sqrt(pt * pt - 2 * a * cross + a * a * r2);
    63         Double_t phi0 = TMath::ATan2((py - a * xx) / T, (px + a * yy) / T);
    64         Double_t D;
    65         if (pt < 10.0) D = (T - pt) / a;
    66         else D = (-2 * cross + a * r2) / (T + pt);
    67         Double_t B = C * TMath::Sqrt((r2 - D * D) / (1 + 2 * C * D));
    68         Double_t st = TMath::ASin(B) / C;
    69         Double_t ct = pz / pt;
    70         Double_t z0 = zz - ct * st;
     53        fpar[0] = gPar(0);
     54        fpar[1] = gPar(1);
     55        fpar[2] = gPar(2);
     56        fpar[3] = gPar(3);
     57        fpar[4] = gPar(4);
     58        //cout << "SolTrack:: C = " << C << ", fpar[2] = " << fpar[2] << endl;
     59        //
     60        // Init covariances
     61        //
     62        fCov.ResizeTo(5, 5);
     63}
     64//
     65SolTrack::SolTrack(Double_t D, Double_t phi0, Double_t C, Double_t z0, Double_t ct, SolGeom *G)
     66{
     67        fG = G;
     68        Double_t B = G->B();
     69        SetB(B);
     70        // Store parameters
    7171        fpar[0] = D;
    7272        fpar[1] = phi0;
     
    7474        fpar[3] = z0;
    7575        fpar[4] = ct;
    76         //cout << "SolTrack:: C = " << C << ", fpar[2] = " << fpar[2] << endl;
     76        // Store momentum
     77        Double_t pt = B * TrkUtil::cSpeed() / TMath::Abs(2 * C);
     78        Double_t px = pt*TMath::Cos(phi0);
     79        Double_t py = pt*TMath::Sin(phi0);
     80        Double_t pz = pt*ct;
     81        //
     82        fp[0] = px; fp[1] = py; fp[2] = pz;
     83        fx[0] = -D*TMath::Sin(phi0); fx[1] = D*TMath::Cos(phi0);  fx[2] = z0;
    7784        //
    7885        // Init covariances
    7986        //
    8087        fCov.ResizeTo(5, 5);
    81 }
    82 
    83 SolTrack::SolTrack(Double_t D, Double_t phi0, Double_t C, Double_t z0, Double_t ct, SolGeom *G)
    84 {
    85   fG = G;
    86   // Store parameters
    87   fpar[0] = D;
    88   fpar[1] = phi0;
    89   fpar[2] = C;
    90   fpar[3] = z0;
    91   fpar[4] = ct;
    92   // Store momentum
    93   Double_t pt = G->B()*0.2998 / TMath::Abs(2 * C);
    94   Double_t px = pt*TMath::Cos(phi0);
    95   Double_t py = pt*TMath::Sin(phi0);
    96   Double_t pz = pt*ct;
    97 
    98   fp[0] = px; fp[1] = py; fp[2] = pz;
    99   fx[0] = -D*TMath::Sin(phi0); fx[1] = D*TMath::Cos(phi0);  fx[2] = z0;
    100   // Init covariances
    101   fCov.ResizeTo(5, 5);
    10288}
    10389// Destructor
    10490SolTrack::~SolTrack()
    10591{
    106         delete[] & fp;
    107         delete[] & fpar;
    108   fCov.Clear();
    109 }
     92        fCov.Clear();
     93}
     94//
    11095// Calculate intersection with given layer
    11196Bool_t SolTrack::HitLayer(Int_t il, Double_t &R, Double_t &phi, Double_t &zz)
    11297{
    113   Double_t Di = D();
    114   Double_t phi0i = phi0();
    115   Double_t Ci = C();
    116   Double_t z0i = z0();
    117   Double_t cti = ct();
    118 
    119   R = 0; phi = 0; zz = 0;
    120 
    121   Bool_t val = kFALSE;
    122   if (fG->lTyp(il) == 1)      // Cylinder: layer at constant R
    123   {
    124     R = fG->lPos(il);
    125     Double_t argph = (Ci*R + (1 + Ci*Di)*Di / R) / (1. + 2.*Ci*Di);
    126     if (TMath::Abs(argph) < 1.0)
    127     {
    128       Double_t argz = Ci*TMath::Sqrt((R*R - Di*Di) / (1 + 2 * Ci*Di));
    129       if (TMath::Abs(argz) < 1.0)
    130       {
    131         zz = z0i + cti*TMath::ASin(argz) / Ci;
    132         if (zz > fG->lxMin(il) && zz < fG->lxMax(il))
    133         {
    134           phi = phi0i + TMath::ASin(argph);
    135           val = kTRUE;
    136         }
    137       }
    138     }
    139   }
    140   else if (fG->lTyp(il) == 2)   // disk: layer at constant z
    141   {
    142     zz = fG->lPos(il);
    143     Double_t arg = Ci*(zz - z0i) / cti;
    144     if (TMath::Abs(arg) < 1.0 && (zz - z0i) / cti > 0)
    145     {
    146       R = TMath::Sqrt(Di*Di + (1. + 2.*Ci*Di)*pow(TMath::Sin(arg), 2) / (Ci*Ci));
    147       if (R > fG->lxMin(il) && R < fG->lxMax(il))
    148       {
    149         Double_t arg1 = (Ci*R + (1 + Ci*Di)*Di / R) / (1. + 2.*Ci*Di);
    150         if (TMath::Abs(arg1) < 1.0)
    151         {
    152           phi = phi0i + TMath::ASin(arg1);
    153           val = kTRUE;
    154         }
    155       }
    156     }
    157   }
    158   //
    159   return val;
    160 }
     98        Double_t Di = D();
     99        Double_t phi0i = phi0();
     100        Double_t Ci = C();
     101        Double_t z0i = z0();
     102        Double_t cti = ct();
     103        //
     104        R = 0; phi = 0; zz = 0;
     105        Bool_t val = kFALSE;
     106        Double_t Rmin = TMath::Sqrt(fx[0] * fx[0] + fx[1] * fx[1]); // Smallest track radius
     107        if (Rmin < TMath::Abs(Di)) return val;
     108        //
     109        Double_t ArgzMin = Ci * TMath::Sqrt((Rmin * Rmin - Di * Di) / (1 + 2 * Ci * Di));
     110        Double_t stMin = TMath::ASin(ArgzMin) / Ci;                                     // Arc length at track origin
     111        //
     112        if (fG->lTyp(il) == 1)                  // Cylinder: layer at constant R
     113        {
     114                R = fG->lPos(il);
     115                Double_t argph = (Ci*R + (1 + Ci*Di)*Di / R) / (1. + 2.*Ci*Di);
     116                if (TMath::Abs(argph) < 1.0 && R > Rmin)
     117                {
     118                        Double_t argz = Ci*TMath::Sqrt((R*R - Di*Di) / (1 + 2 * Ci*Di));
     119                        if (TMath::Abs(argz) < 1.0)
     120                        {
     121                                zz = z0i + cti*TMath::ASin(argz) / Ci;
     122                                if (zz > fG->lxMin(il) && zz < fG->lxMax(il))
     123                                {
     124                                        phi = phi0i + TMath::ASin(argph);
     125                                        val = kTRUE;
     126                                }
     127                        }
     128                }
     129        }
     130        else if (fG->lTyp(il) == 2)             // disk: layer at constant z
     131        {
     132                zz = fG->lPos(il);
     133                Double_t st = (zz - z0i) / cti;
     134                if (TMath::Abs(Ci * st) < 1.0 && st > stMin)
     135                {
     136                        R = TMath::Sqrt(Di * Di + (1. + 2. * Ci * Di) * pow(TMath::Sin(Ci * st), 2) / (Ci * Ci));
     137                        if (R > fG->lxMin(il) && R < fG->lxMax(il))
     138                        {
     139                                Double_t arg1 = (Ci*R + (1 + Ci*Di)*Di / R) / (1. + 2.*Ci*Di);
     140                                if (TMath::Abs(arg1) < 1.0)
     141                                {
     142                                        phi = phi0i + TMath::ASin(arg1);
     143                                        val = kTRUE;
     144                                }
     145                        }
     146                }
     147        }
     148        //
     149        return val;
     150}
     151//
    161152// # of layers hit
    162153Int_t SolTrack::nHit()
    163154{
    164   Int_t kh = 0;
    165   Double_t R; Double_t phi; Double_t zz;
    166   for (Int_t i = 0; i < fG->Nl(); i++)
    167   if (HitLayer(i, R, phi, zz))kh++;
    168 
    169   return kh;
    170 }
    171 
     155        Int_t kh = 0;
     156        Double_t R; Double_t phi; Double_t zz;
     157        for (Int_t i = 0; i < fG->Nl(); i++)
     158        if (HitLayer(i, R, phi, zz))kh++;
     159        //
     160        return kh;
     161}
     162//
    172163// # of measurement layers hit
    173164Int_t SolTrack::nmHit()
     
    181172}
    182173//
    183 
    184 
    185174// List of layers hit with intersections
    186175Int_t SolTrack::HitList(Int_t *&ihh, Double_t *&rhh, Double_t *&zhh)
    187176{
    188   // Return lists of hits associated to a track including all scattering layers.
    189   // Return value is the total number of measurement hits
    190   // kmh = total number of measurement layers hit for given type
    191   // ihh = pointer to layer number
    192   // rhh = radius of hit
    193   // zhh = z of hit
    194 
    195   // ***** NB: double layers with stereo on lower layer not included
    196 
    197   Int_t kh = 0; // Number of layers hit
    198   Int_t kmh = 0; // Number of measurement layers of given type
    199   for (Int_t i = 0; i < fG->Nl(); i++)
    200   {
    201     Double_t R; Double_t phi; Double_t zz;
    202     if (HitLayer(i, R, phi, zz)) // Only barrel type layers
    203     {
    204       zhh[kh] = zz;
    205       rhh[kh] = R;
    206       ihh[kh] = i;
    207       if (fG->isMeasure(i))kmh++;
    208       kh++;
    209     }
    210   }
    211 
    212   return kmh;
    213 }
    214 
     177        //
     178        // Return lists of hits associated to a track including all scattering layers.
     179        // Return value is the total number of measurement hits
     180        // kmh = total number of measurement layers hit for given type
     181        // ihh = pointer to layer number
     182        // rhh = radius of hit
     183        // zhh = z of hit
     184        //
     185        // ***** NB: double layers with stereo on lower layer not included
     186        //
     187        Int_t kh = 0;   // Number of layers hit
     188        Int_t kmh = 0;  // Number of measurement layers of given type
     189        for (Int_t i = 0; i < fG->Nl(); i++)
     190        {
     191                Double_t R; Double_t phi; Double_t zz;
     192                if (HitLayer(i, R, phi, zz))
     193                {
     194                        zhh[kh] = zz;
     195                        rhh[kh] = R;
     196                        ihh[kh] = i;
     197                        if (fG->isMeasure(i))kmh++;
     198                        kh++;
     199                }
     200        }
     201        //
     202        return kmh;
     203}
     204//
    215205// List of XYZ measurements without any error
    216206Int_t SolTrack::HitListXYZ(Int_t *&ihh, Double_t *&Xh, Double_t *&Yh, Double_t *&Zh)
    217207{
    218208        //
    219         // Return lists of hits associated to a track for all measurement layers.
     209        // Return lists of hits associated to a track for all measurement layers. 
    220210        // Return value is the total number of measurement hits
    221211        // kmh = total number of measurement layers hit for given type
     
    244234}
    245235//
     236// Track plot
     237//
     238TGraph *SolTrack::TrkPlot()
     239{
     240        //
     241        // Fill list of layers hit
     242        //
     243        Int_t Nhit = nHit();                                    // Total number of layers hit
     244        //cout << "Nhit = " << Nhit << endl;
     245        Double_t *zh = new Double_t[Nhit];              // z of hit
     246        Double_t *rh = new Double_t[Nhit];              // r of hit
     247        Int_t    *ih = new Int_t   [Nhit];              // true index of layer
     248        Int_t kmh;                                                              // Number of measurement layers hit
     249        //
     250        kmh = HitList(ih, rh, zh);                              // hit layer list
     251        //for (Int_t j = 0; j < Nhit; j++) cout << "r = " << rh[j] << ", z = " << zh[j] << endl;
     252        Double_t *dh = new Double_t[Nhit];              // Hit distance from origin
     253        for(Int_t i=0; i<Nhit; i++)dh[i] = TMath::ASin(C() * TMath::Sqrt((rh[i] * rh[i] - D() * D()) / (1. + 2 * C() * D()))) / C();    // Arc length traveled;
     254        //
     255        Int_t *hord = new Int_t[Nhit];
     256        TMath::Sort(Nhit, dh, hord, kFALSE);            // Order by increasing phase
     257        Double_t *z = new Double_t[Nhit];               // z of ordered hit
     258        Double_t *r = new Double_t[Nhit];               // r of ordered hit
     259        for (Int_t i = 0; i < Nhit; i++)
     260        {
     261                z[i] = zh[hord[i]];
     262                r[i] = rh[hord[i]];
     263        }
     264        //cout << "After ordering" << endl;
     265        //for (Int_t j = 0; j < Nhit; j++) cout << "r = " << rh[j] << ", z = " << zh[j] << endl;
     266        TGraph *gr = new TGraph(Nhit, z, r);    // graph intersection with layers
     267        gr->SetMarkerStyle(kCircle);
     268        gr->SetMarkerColor(kMagenta);
     269        gr->SetMarkerSize(1);
     270        gr->SetLineColor(kMagenta);
     271        //
     272        // clean up
     273        //
     274        delete[] zh;
     275        delete[] rh;
     276        delete[] ih;
     277        delete[] hord;
     278        return gr;
     279}
     280//
    246281// Covariance matrix estimation
    247282//
     
    250285        //
    251286        //
    252         // Input flags:
     287        // Input flags: 
    253288        //                              Res = .TRUE. turn on resolution effects/Use standard resolutions
    254289        //                                        .FALSE. set all resolutions to 0
     
    265300        Int_t ntry = 0;
    266301        Int_t ntrymax = 0;
    267         Int_t Nhit = nHit();                                    // Total number of layers hit
     302        Int_t Nhit = nHit();                            // Total number of layers hit
    268303        Double_t *zhh = new Double_t[Nhit];             // z of hit
    269304        Double_t *rhh = new Double_t[Nhit];             // r of hit
    270305        Double_t *dhh = new Double_t[Nhit];             // distance of hit from origin
    271306        Int_t    *ihh = new Int_t[Nhit];                // true index of layer
    272         Int_t kmh;                                                              // Number of measurement layers hit
     307        Int_t kmh;                                      // Number of measurement layers hit
    273308        //
    274309        kmh = HitList(ihh, rhh, zhh);                   // hit layer list
    275         Int_t mTot = 0;                                                 // Total number of measurements
     310        Int_t mTot = 0;                                 // Total number of measurements
    276311        for (Int_t i = 0; i < Nhit; i++)
    277312        {
    278                 dhh[i] = TMath::Sqrt(rhh[i] * rhh[i] + zhh[i] * zhh[i]);
     313                Double_t rr = rhh[i];
     314                dhh[i] = TMath::ASin(C() * TMath::Sqrt((rr * rr - D() * D()) / (1. + 2 * C() * D()))) / C();    // Arc length traveled
    279315                if (fG->isMeasure(ihh[i])) mTot += fG->lND(ihh[i]);     // Count number of measurements
    280316        }
    281317        //
    282         // Order hit list by increasing distance from origin
     318        // Order hit list by increasing arc length
    283319        //
    284320        Int_t    *hord = new Int_t[Nhit];               // hit order by increasing distance from origin
    285         TMath::Sort(Nhit, dhh, hord, kFALSE);   // Order by increasing distance from origin
     321        TMath::Sort(Nhit, dhh, hord, kFALSE);           // Order by increasing distance from origin
    286322        Double_t *zh = new Double_t[Nhit];              // d-ordered z of hit
    287323        Double_t *rh = new Double_t[Nhit];              // d-ordered r of hit
     
    297333        // Store interdistances and multiple scattering angles
    298334        //
    299         Double_t sn2t = 1.0 / (1 + ct()*ct());                  //sin^2 theta of track
     335        Double_t sn2t = 1.0 / (1.0 + ct()*ct());                        //sin^2 theta of track
    300336        Double_t cs2t = 1.0 - sn2t;                                             //cos^2 theta
    301337        Double_t snt = TMath::Sqrt(sn2t);                               // sin theta
     
    306342        //
    307343        TMatrixDSym dik(Nhit);  dik.Zero();             // Distances between layers
    308         Double_t *thms = new Double_t[Nhit];    // Scattering angles/plane
    309         Double_t *cs = new Double_t[Nhit];              // Cosine of angle with layer normal
     344        Double_t *thms = new Double_t[Nhit];            // Scattering angles/plane
     345        Double_t* cs = new Double_t[Nhit];              // Cosine of angle with normal in transverse plane
     346        //
    310347        for (Int_t ii = 0; ii < Nhit; ii++)             // Hit layer loop
    311348        {
    312349                Int_t i = ih[ii];                                       // Get true layer number
     350                Int_t il = hord[ii];                                    // Unordered layer
    313351                Double_t B = C()*TMath::Sqrt((rh[ii] * rh[ii] - D()*D()) / (1 + 2 * C()*D()));
     352                //
    314353                Double_t pxi = px0*(1-2*B*B)-2*py0*B*TMath::Sqrt(1-B*B);                // Momentum at scattering layer
    315354                Double_t pyi = py0*(1-2*B*B)+2*px0*B*TMath::Sqrt(1-B*B);
    316355                Double_t pzi = pz0;
    317356                Double_t ArgRp = (rh[ii]*C() + (1 + C() * D())*D() / rh[ii]) / (1 + 2 * C()*D());
     357                //
    318358                Double_t phi = phi0() + TMath::ASin(ArgRp);
    319359                Double_t nx = TMath::Cos(phi);          // Barrel layer normal
    320360                Double_t ny = TMath::Sin(phi);
    321361                Double_t nz = 0.0;
    322                 if (fG->lTyp(i) == 2)                                                           // this is Z layer
     362                cs[ii] = TMath::Abs((pxi * nx + pyi * ny) / pt());
     363                //
     364                if (fG->lTyp(i) == 2)                   // this is Z layer
    323365                {
    324366                        nx = 0.0;
     
    326368                        nz = 1.0;
    327369                }
    328                 Double_t corr = (pxi*nx + pyi * ny + pzi * nz) / p();
    329                 cs[ii] = corr;
    330                 Double_t Rlf = fG->lTh(i) / (corr*fG->lX0(i));          // Rad. length fraction
     370                Double_t corr = TMath::Abs(pxi*nx + pyi * ny + pzi * nz) / p();
     371                Double_t Rlf = fG->lTh(i) / (corr*fG->lX0(i));                                  // Rad. length fraction
    331372                thms[ii] = 0.0136*TMath::Sqrt(Rlf)*(1.0 + 0.038*TMath::Log(Rlf)) / p();         // MS angle
    332373                if (!MS)thms[ii] = 0;
     
    334375                for (Int_t kk = 0; kk < ii; kk++)       // Fill distances between layers
    335376                {
    336                         //dik(ii, kk) = TMath::Sqrt(pow(rh[ii] - rh[kk], 2) + pow(zh[ii] - zh[kk], 2));
    337                         Double_t Ci = C();
    338                         dik(ii, kk) = (TMath::ASin(Ci*rh[ii])-TMath::ASin(Ci*rh[kk]))/(Ci*snt);
     377                        Int_t kl = hord[kk];            // Unordered layer
     378                        dik(ii, kk) = TMath::Abs(dhh[il] - dhh[kl])/snt;
    339379                        dik(kk, ii) = dik(ii, kk);
    340380                }
    341                 //
    342                 // Store momentum components for resolution correction cosines
    343                 //
    344                 Double_t *pRi = new Double_t[Nhit];
    345                 pRi[ii] = TMath::Abs(pxi * TMath::Cos(phi) + pyi * TMath::Sin(phi)); // Radial component
    346                 Double_t *pPhi = new Double_t[Nhit];
    347                 pPhi[ii] = TMath::Abs(pxi * TMath::Sin(phi) - pyi * TMath::Cos(phi)); // Phi component
    348381        }
    349382        //
    350383        // Fill measurement covariance
    351384        //
    352         Int_t *mTl = new Int_t[mTot];           // Pointer from measurement number to true layer number
     385        TVectorD tPar(5,fpar);
     386        //
    353387        TMatrixDSym Sm(mTot); Sm.Zero();        // Measurement covariance
    354         TMatrixD Rm(mTot, 5);                           // Derivative matrix
    355         Int_t im = 0;
     388        TMatrixD Rm(mTot, 5);                   // Derivative matrix
     389        Int_t im = 0;                                           // Initialize number of measurement counter
    356390        //
    357391        // Fill derivatives and error matrix with MS
    358392        //
    359         Double_t AngMax = 90.; Double_t AngMx = AngMax * TMath::Pi() / 180.;
    360         Double_t csMin = TMath::Cos(AngMx);     // Set maximum angle wrt normal
    361         //
    362393        for (Int_t ii = 0; ii < Nhit; ii++)
    363394        {
    364                 Int_t i = ih[ii];                                       // True layer number
     395                Int_t i = ih[ii];                               // True layer number
    365396                Int_t ityp  = fG->lTyp(i);                      // Layer type Barrel or Z
    366397                Int_t nmeai = fG->lND(i);                       // # measurements in layer
    367                 if (fG->isMeasure(i) && nmeai >0 && cs[ii] > csMin)
    368                 {
    369                         Double_t Di    = D();                           // Get true track parameters
    370                         Double_t phi0i = phi0();
    371                         Double_t Ci    = C();
    372                         Double_t z0i   = z0();
    373                         Double_t cti   = ct();
    374                         //
    375                         Double_t Ri    = rh[ii];
    376                         Double_t ArgRp = (Ri*Ci + (1 + Ci * Di)*Di / Ri) / (1 + 2 * Ci*Di);
    377                         Double_t ArgRz = Ci * TMath::Sqrt((Ri*Ri - Di * Di) / (1 + 2 * Ci*Di));
    378                         TVectorD dRphi(5); dRphi.Zero();                // R-phi derivatives @ const. R
    379                         TVectorD dRz(5); dRz.Zero();                    // z     derivatives @ const. R
    380                         //
    381                         // Derivative overflow protection
    382                         Double_t dMin = 0.8;
    383                         dRphi(0) = (1 - 2 * Ci*Ci*Ri*Ri) /
    384                                 TMath::Max(dMin,TMath::Sqrt(1 - ArgRp * ArgRp));        // D derivative
    385                         dRphi(1) = Ri;                                                                                                          // phi0 derivative
    386                         dRphi(2) = Ri * Ri /
    387                                 TMath::Max(dMin,TMath::Sqrt(1 - ArgRp * ArgRp));                                // C derivative
    388                         dRphi(3) = 0.0;                                                                                         // z0 derivative
    389                         dRphi(4) = 0.0;                                                                                         // cot(theta) derivative
    390                         //
    391                         dRz(0) = -cti * Di /
    392                                 (Ri*TMath::Max(dMin,TMath::Sqrt(1 - Ci * Ci*Ri*Ri)));   // D
    393                         dRz(1) = 0.0;                                                                                           // Phi0
    394                         dRz(2) = cti * (Ri*Ci / TMath::Sqrt(1-Ri*Ri*Ci*Ci) -            // C
    395                                 TMath::ASin(Ri*Ci)) / (Ci*Ci);
    396                         dRz(3) = 1.0;                                                                                           // Z0
    397                         dRz(4) = TMath::ASin(ArgRz) / Ci;                                                       // Cot(theta)
     398               
     399                if (fG->isMeasure(i))
     400                {
     401                        Double_t Ri = rh[ii];
     402                        Double_t zi = zh[ii];
    398403                        //
    399404                        for (Int_t nmi = 0; nmi < nmeai; nmi++)
    400405                        {
    401                                 mTl[im] = i;
    402                                 Double_t stri = 0;
    403                                 Double_t sig = 0;
     406                                Double_t stri = 0;                                              // Stereo angle
     407                                Double_t sig = 0;                                               // Layer resolution
     408                                // Constant R derivatives
     409                                TVectorD dRphi(5); dRphi.Zero();                // R-phi derivatives @ const. R
     410                                TVectorD dRz(5); dRz.Zero();                    // z     derivatives @ const. R
     411                                //
    404412                                if (nmi + 1 == 1)               // Upper layer measurements
    405413                                {
     
    407415                                        Double_t csa = TMath::Cos(stri);
    408416                                        Double_t ssa = TMath::Sin(stri);
     417                                        //
    409418                                        sig = fG->lSgU(i);      // Resolution
    410419                                        if (ityp == 1)          // Barrel type layer (Measure R-phi, stereo or z at const. R)
    411420                                        {
    412421                                                //
    413                                                 // Almost exact solution (CD<<1, D<<R)
     422                                                // Exact solution
     423                                                dRphi = derRphi_R(tPar, Ri);
     424                                                dRz   = derZ_R   (tPar, Ri);
     425                                                //
    414426                                                Rm(im, 0) = csa * dRphi(0) - ssa * dRz(0);      // D derivative
    415427                                                Rm(im, 1) = csa * dRphi(1) - ssa * dRz(1);      // phi0 derivative
    416428                                                Rm(im, 2) = csa * dRphi(2) - ssa * dRz(2);      // C derivative
    417429                                                Rm(im, 3) = csa * dRphi(3) - ssa * dRz(3);      // z0 derivative
    418                                                 Rm(im, 4) = csa * dRphi(4) - ssa * dRz(4);      // cot(theta) derivative
     430                                                Rm(im, 4) = csa * dRphi(4) - ssa * dRz(4);      // cot(theta) derivative       
    419431                                        }
    420                                         if (ityp == 2)          // Z type layer (Measure phi at const. Z)
     432                                        if (ityp == 2)          // Z type layer (Measure R-phi at const. Z)
    421433                                        {
    422                                                 Rm(im, 0) = 1.0;                                        // D derivative
    423                                                 Rm(im, 1) = rh[ii];                                     // phi0 derivative
    424                                                 Rm(im, 2) = rh[ii] * rh[ii];            // C derivative
    425                                                 Rm(im, 3) = 0;                                          // z0 derivative
    426                                                 Rm(im, 4) = 0;                                          // cot(theta) derivative
     434                                                TVectorD dRphz(5); dRphz.Zero();                // R-phi derivatives @ const. z
     435                                                dRphz = derRphi_Z(tPar, zi);
     436                                                //
     437                                                Rm(im, 0) = dRphz(0);                                   // D derivative
     438                                                Rm(im, 1) = dRphz(1);                                   // phi0 derivative
     439                                                Rm(im, 2) = dRphz(2);                                   // C derivative
     440                                                Rm(im, 3) = dRphz(3);                                   // z0 derivative
     441                                                Rm(im, 4) = dRphz(4);                                   // cot(theta) derivative
    427442                                        }
    428443                                }
     
    436451                                        {
    437452                                                //
    438                                                 // Almost exact solution (CD<<1, D<<R)
     453                                                // Exact solution
     454                                                dRphi = derRphi_R(tPar, Ri);
     455                                                dRz   = derZ_R   (tPar, Ri);
     456                                                //
    439457                                                Rm(im, 0) = csa * dRphi(0) - ssa * dRz(0);      // D derivative
    440458                                                Rm(im, 1) = csa * dRphi(1) - ssa * dRz(1);      // phi0 derivative
     
    445463                                        if (ityp == 2)                  // Z type layer (Measure R at const. z)
    446464                                        {
    447                                                 Rm(im, 0) = 0;                                                          // D derivative
    448                                                 Rm(im, 1) = 0;                                                          // phi0 derivative
    449                                                 Rm(im, 2) = 0;                                                          // C derivative
    450                                                 Rm(im, 3) = -1.0 / ct();                                        // z0 derivative
    451                                                 Rm(im, 4) = -rh[ii] / ct();                                     // cot(theta) derivative
     465                                                TVectorD dRRz(5); dRRz.Zero();                  // R     derivatives @ const. z
     466                                                dRRz = derR_Z(tPar, zi);
     467                                                //
     468                                                Rm(im, 0) = dRRz(0);                                    // D derivative
     469                                                Rm(im, 1) = dRRz(1);                                    // phi0 derivative
     470                                                Rm(im, 2) = dRRz(2);                                    // C derivative
     471                                                Rm(im, 3) = dRRz(3);                                    // z0 derivative
     472                                                Rm(im, 4) = dRRz(4);                                    // cot(theta) derivative
    452473                                        }
    453474                                }
     
    457478                                //
    458479                                Int_t km = 0;
     480                                Double_t CosMin = TMath::Sin(TMath::Pi() / 9.); // Protect for derivative explosion
    459481                                for (Int_t kk = 0; kk <= ii; kk++)
    460482                                {
    461                                         Int_t k = ih[kk];                                       // True layer number
    462                                         Int_t ktyp = fG->lTyp(k);                       // Layer type Barrel or
     483                                        Int_t k = ih[kk];                               // True layer number
     484                                        Int_t ktyp = fG->lTyp(k);                       // Layer type Barrel or disk
    463485                                        Int_t nmeak = fG->lND(k);                       // # measurements in layer
    464                                         if (fG->isMeasure(k) && nmeak > 0 &&cs[kk] > csMin)
     486                                        if (fG->isMeasure(k))
    465487                                        {
    466488                                                for (Int_t nmk = 0; nmk < nmeak; nmk++)
    467489                                                {
    468490                                                        Double_t strk = 0;
    469                                                         if (nmk + 1 == 1) strk = fG->lStU(k);   // Stereo angle
    470                                                         if (nmk + 1 == 2) strk = fG->lStL(k);   // Stereo angle
    471                                                         if (im == km && Res) Sm(im, km) += sig*sig;     // Detector resolution on diagonal
     491                                                        if (nmk + 1 == 1) strk = fG->lStU(k);   // Stereo angle upper
     492                                                        if (nmk + 1 == 2) strk = fG->lStL(k);   // Stereo angle lower
     493                                                        //if (im == km && Res) Sm(im, km) += sig*sig;   // Detector resolution on diagonal
     494                                                        if (im == km && Res) {
     495                                                                Double_t sg = sig;
     496                                                                if(TMath::Abs(strk) < TMath::Pi()/6. && cs[kk] < CosMin)
     497                                                                TMath::Min(1000.*sig,sg = sig/pow(cs[kk],4));
     498                                                                Sm(im, km) += sg * sg;  // Detector resolution on diagonal
     499                                                        }
    472500                                                        //
    473501                                                        // Loop on all layers below for MS contributions
    474                                                         for (Int_t jj = 0; jj < kk; jj++)
     502                                                        for (Int_t jj = 0; jj < kk; jj++)               
    475503                                                        {
    476504                                                                Double_t di = dik(ii, jj);
     
    482510                                                                if (ktyp == 1) msk = ms / snt;                  // Barrel
    483511                                                                else if (ktyp == 2) msk = ms / cst;             // Disk
    484                                                                 Double_t ci = TMath::Cos(stri); Double_t si = TMath::Sin(stri);
    485                                                                 Double_t ck = TMath::Cos(strk); Double_t sk = TMath::Sin(strk);
    486                                                                 Sm(im, km) += di*dk*(ci*ck*ms*ms + si*sk*msi*msk);                      // Ms contribution
     512                                                                Double_t ci = TMath::Abs(TMath::Cos(stri)); Double_t si = TMath::Abs(TMath::Sin(stri));
     513                                                                Double_t ck = TMath::Abs(TMath::Cos(strk)); Double_t sk = TMath::Abs(TMath::Sin(strk));
     514                                                                Sm(im, km) += di*dk*(ci*ck*ms*ms + si*sk*msi*msk);      // Ms contribution
    487515                                                        }
    488516                                                        //
     
    497525        }
    498526        Sm.ResizeTo(mTot, mTot);
     527        TMatrixDSym SmTemp = Sm;
    499528        Rm.ResizeTo(mTot, 5);
    500529        //
     
    506535        for (Int_t id = 0; id < mTot; id++) DSmInv(id, id) = 1.0 / TMath::Sqrt(Sm(id, id));
    507536        TMatrixDSym SmN = Sm.Similarity(DSmInv);        // Normalize diagonal to 1
    508         //SmN.Invert();
    509537        //
    510538        // Protected matrix inversions
    511539        //
    512         TDecompChol Chl(SmN);
     540        TDecompChol Chl(SmN,1.e-12);
    513541        TMatrixDSym SmNinv = SmN;
    514542        if (Chl.Decompose())
     
    519547        else
    520548        {
    521                 cout << "SolTrack::CovCalc: Error matrix not positive definite. Recovering ...." << endl;
     549                std::cout << "SolTrack::CovCalc: Error matrix not positive definite. Recovering ...." << std::endl;
     550                //cout << "pt = " << pt() << endl;
    522551                if (ntry < ntrymax)
    523552                {
     
    525554                        ntry++;
    526555                }
     556                //
    527557                TMatrixDSym rSmN = MakePosDef(SmN); SmN = rSmN;
    528558                TDecompChol rChl(SmN);
     
    533563        Sm = SmNinv.Similarity(DSmInv);                 // Error matrix inverted
    534564        TMatrixDSym H = Sm.SimilarityT(Rm);             // Calculate half Hessian
    535         // Normalize before inversion
    536565        const Int_t Npar = 5;
    537566        TMatrixDSym DHinv(Npar); DHinv.Zero();
     
    541570        Hnrm.Invert();
    542571        fCov = Hnrm.Similarity(DHinv);
    543 }
    544 
     572        //
     573        // debug
     574        //
     575        if(TMath::IsNaN(fCov(0,0)))
     576        {
     577                std::cout<<"SolTrack::CovCalc: NaN found in covariance matrix"<<std::endl;
     578        }
     579        //
     580        // Lots of cleanup to do
     581        delete[] zhh;
     582        delete[] rhh;
     583        delete[] dhh;
     584        delete[] ihh;
     585        delete[] hord;
     586        delete[] zh;
     587        delete[] rh;
     588        delete[] ih;
     589        delete[] cs;
     590        delete[] thms;
     591}
     592//
    545593// Force positive definitness in normalized matrix
    546594TMatrixDSym SolTrack::MakePosDef(TMatrixDSym NormMat)
     
    558606        if (Check)
    559607        {
    560                 cout << "SolTrack::MakePosDef: input matrix doesn ot have 1 on diagonal. Abort." << endl;
     608                std::cout << "SolTrack::MakePosDef: input matrix doesn ot have 1 on diagonal. Abort." << std::endl;
    561609                return rMatN;
    562610        }
     
    566614        TMatrixD U = Eign.GetEigenVectors();
    567615        TVectorD lambda = Eign.GetEigenValues();
     616        //cout << "Eigenvalues:"; lambda.Print();
     617        //cout << "Input matrix: "; NormMat.Print();
    568618        // Reset negative eigenvalues to small positive value
    569619        TMatrixDSym D(Size); D.Zero(); Double_t eps = 1.0e-13;
     
    587637                }
    588638        }
     639        //cout << "Rebuilt matrix: "; rMatN.Print();
    589640        return rMatN;
    590641}
Note: See TracChangeset for help on using the changeset viewer.