//*LastUpdate : jsf-1-14  3-Feburary-2000  A.Miyamoto
//*-- Author  : Akiya Miyamoto  2-Feburary-2000

////////////////////////////////////////////////////////////////////////
//
// JSFGeoCFit
//
// (Description)
/*
C**********************************************************************
C* 
C*  -----------------------------------------------
C*  Subroutine UFGEOC( NTRK, LNxTRK, TRKINI, VTXINI,
C*                     CHIS, FITANS, NRET)
C*  -----------------------------------------------
C* 
C*(Function)
C*   Do geometrical constraint fit to the Track parameter.
C* 
C*(Input)
C*   NTRK    ; # of track.
C*   LNxTRK  ; Length of track parameter in I*4 unit.
C*             LNxTRK must be even number.
C*   TRKINI  ; Initial track parameter with TPC;Track_Parameter format.
C*   VTXINI  ; Initial vertex position.
C*             VTXINI(3) = ( Vx, Vy, Vz )
C* 
C*(Output)
C*   CHIS    ; Chi-square of Geofit.
C*   FITANS  ; R*4, R*8 mixed array of fit results, Should be decalred
C*            as REAL*4  FITANS(16, 0:NTRK) in the calling routine.
C*            Error matrix are saved in FITANS(5:14,0:NTRK) by REAL*8
C*            format.  To use Error matrix, declare as follows.
C*               REAL*4  FITANS(16,0:NTRK)
C*               REAL*8  DITANS( 8,0:NTRK)
C*               EQUIVALENCE (FITANS(1,0), DITANS(1,0))
C* 
C*       FITANS(1,i) = Vx (i=0) or Phi0(i^=0)
C*             (2,i) = Vy (i=0) or K   (i^=0)
C*             (3,i) = Vz (i=0) or Tanl(i^=0)
C*             (4,0) = -1, indicatting fitted vertex parameter.
C*                i) = Chi-square contribution of i-th track.
C*       DITANS(3,i) = Error matrix (1,1)  (k,l)
C*             (4,i) =              (2,1)     k=l=1  for Vx or Phi0
C*             (5,i) =              (3,1)        =2  for Vy orK
C*             (6,i) =              (2,2)        =3  for Vz of Tanl
C*             (7,i) =              (3,2)
C*             (8,i) =              (3,3)
C* 
C*   NRET  > 0 ; # of try, when fit converges
C*         =-1 ; Fit does not converge.
C*         =-2 ; Error during fit.
C*         =-3 ; Invalid error matrix.
C*         =-4 ; NTRK .GT. MFxTRK (50)
C* 
C*(Author)
C*  A. Miyamoto  24-Jun-1987
C* 
C**********************************************************************
C* 
   Converted to C++ By A.Miyamoto  2-Feburary-2000
*/
//
// (Update)
//  12-Jul-2000 A.Miyamoto  Remove memory leak in Initialize()
//
//$Id: JSFGeoCFit.cxx,v 1.3 2001/01/04 07:28:03 miyamoto Exp $
////////////////////////////////////////////////////////////////////////


#include "JSFGeoCFit.h"

ClassImp(JSFGeoCFit)

//____________________________________________________________
 JSFGeoCFit::JSFGeoCFit(Int_t ntrk, TClonesArray *trk, TVector3 vtxini)
{
  Initialize(ntrk, trk, JSF3DV(vtxini.X(),vtxini.Y(),vtxini.Z()));
}

//____________________________________________________________
 JSFGeoCFit::JSFGeoCFit(Int_t ntrk, TClonesArray *trk, JSF3DV vtxini)
{
  Initialize(ntrk, trk, vtxini);
}

//____________________________________________________________
 JSFGeoCFit::~JSFGeoCFit()
{

  if( fNtrk > 1 ) {
    for(Int_t i=0;i<fNtrk;i++){
      delete fTrkerr[i];
      delete fTrkpar[i];
    }
    delete [] fTrkerr;
    delete [] fTrkpar;
    delete fTrackChisq;
  }

}

//____________________________________________________________
 void JSFGeoCFit::Initialize(Int_t ntrk, TClonesArray *trk, JSF3DV vtxini)
{
/*
C**********************************************************************
C* 
C*  --------------------------------------------------------=========
C*  Subroutine UFGEOI( NTRK, LNxTRK, TRKINI, DRKINI, VTXINI, X, NRET)
C*  --------------------------------------------------------=========
C* 
C*(Function)
C*   Called from PGFTRK to store initial parameter for the geometrical
C*   constraint fit to the buffer.
C* 
C*(Input)
C*   NTRK    ; # of track.
C*   LNxTRK  ; Length of track parameter in I*4 unit.
C*   TRKINI  ; Initial track parameter with TPC;Track_Parameter format.
C*   DRKINI  ; Track parameter by Real*8 format.
C*   VTXINI  ; Initial position of the vertex.
C* 
C*(Output)
C*   X       ; Parameter array ( Inital values are set.)
C*   NRET    ; Return code.
C*          = 0 when normal return
C*          < 0 when failed to invert matrix.
C* 
C*(Author)
C*  A. Miyamoto  24-Jun-1987
C* 
C**********************************************************************
C* 
*/

//C  
//C =====< Entry Point >=================================================
//C  

  fNtrk=ntrk;
  fNpar=3*(ntrk+1);
  fNDF = 5*fNtrk -fNpar;
  fDD.ResizeTo(fNpar,fNpar);
  fA.ResizeTo(fNpar,1);
  fTrackChisq = new Double_t[ntrk];

//
// ---------------------------------------------------------------------
// Save input track parameter and it's error
// ---------------------------------------------------------------------
//  
  fTrkpar = new JSFHelixParameter*[ntrk];
#if __ROOT_FULLVERSION__ < 30000
  fTrkerr = new JSFDMatrix*[ntrk];
#else
  fTrkerr = new TMatrixD*[ntrk];
#endif

  Int_t i=0;
  for(i=0;i<ntrk;i++){
    JSFHelicalTrack *t=(JSFHelicalTrack*)trk->UncheckedAt(i);
    
    JSF3DV dif=t->GetHelixParameter().pivot-vtxini;
    if( dif.X()*dif.X()+dif.Y()*dif.Y()+dif.Z()*dif.Z() > 1.E-12 ) {
      t->MovePivot(vtxini);
    }
    if(i==0) fPTOR=t->GetAlpha();
    fTrkpar[i]=new JSFHelixParameter(t->GetHelixParameter());

#if __ROOT_FULLVERSION__ < 30000
    JSFDMatrix em(5,5);
#else
    TMatrixD em(5,5);
#endif
    Double_t *err=t->GetHelixErrorMatrix();
    Int_t j,k;
    Int_t ip=0;
    for(j=0;j<5;j++)  for(k=0;k<=j;k++) { 
      em(j,k)=err[ip];  em(k,j)=err[ip++]; 
    }	
    em.Invert();
#if __ROOT_FULLVERSION__ < 30000
    fTrkerr[i]=new JSFDMatrix(em);
#else
    fTrkerr[i]=new TMatrixD(em);
#endif

  }

//C  
//C ---------------------------------------------------------------------
//C (3) Prepare Initial parameter array.
//C ---------------------------------------------------------------------
//C  

  fA(0,0)=vtxini.X();
  fA(1,0)=vtxini.Y();
  fA(2,0)=vtxini.Z();

  Int_t ip=3;
  JSFHelixParameter *h;
  for(i=0;i<fNtrk;i++){
    h=fTrkpar[i];
    Double_t drho=fPTOR/h->kappa;
    Double_t dxc=h->pivot.x + (drho+h->dr)*TMath::Cos(h->phi0);
    Double_t dyc=h->pivot.y + (drho+h->dr)*TMath::Sin(h->phi0);
    if( drho < 0.0 ) 
      fA(ip,0)=TMath::ATan2( -(dyc-fA(1,0)), -(dxc-fA(0,0)) );
    else 
      fA(ip,0)=TMath::ATan2(  (dyc-fA(1,0)),  (dxc-fA(0,0)) );
    fA(ip+1,0)=h->kappa;
    fA(ip+2,0)=h->tanl;
    ip+=3;
  }

//C  
//C ---------------------------------------------------------------------
//C (5) Return to Caller.
//C ---------------------------------------------------------------------
//C  


}


//________________________________________________________________________
#if __ROOT_FULLVERSION__ < 30000
 void JSFGeoCFit::Derivative(Double_t &chis, JSFDMatrix &grad, JSFDMatrix &second)
#else
void JSFGeoCFit::Derivative(Double_t &chis, TMatrixD &grad, TMatrixD &second)
#endif
{
// Calculate chi-square, and derivatives.
/*
C**********************************************************************
C* 
C*  ------------------------------------==================
C*  Subroutine UFGEOK( NPAR, MXxPAR, X, CHIS, GRAD, SECOND)
C*  ------------------------------------==================
C* 
C*(Function)
C*   Calculate chi-squre, first derivative of Chi-square and
C*   2nd-derivative of the matrix.
C* 
C*(Input)
C*   NPAR   ; # of parameter
C*   MXxPAR ; Size of matrix second.
C*   X  ; Fitted parameter array.
C*      X(1) = Xv
C*       (2) = Yv
C*       (3) = Zv
C*       (4) = Phi0 of 1st track
C*       (5) = K    of 1st track
C*       (6) = Tanl of 1st track
C*       (4) = Phi0 of 2nd track
C* 
C*      Dimension of X is 3 + 3*NUMTRK
C* 
C*(Output)
C*   CHIS   ; Chi-square
C*   GRAD   ; First derivative of the chi-square.
C*   SECOND ; Second derivative of the chi-square.
C* 
C*(Author)
C*  A. Miyamoto  27-Jun-1987
C* 
C**********************************************************************
C* 
*/

//C*    DADP(i,1:6) : Derivative of i-th measured track parameter with
//C*                  respect to the Xv, Yv, Zv, Phi0, K, Tanl
//C*    DAE(i)      : Product of dA vector and error matrix.
//C*    DXDA(i,j)   : Derivative of the calculated position with respect
//C*                  to the track parameter, Xv, Yv, Zv, Phi0, K, Tanl

//C  
//C =====< Entry Point >=================================================
//C  

  chis = 0.0;
  Double_t xv   = fA(0,0);
  Double_t yv   = fA(1,0);
  Double_t zv   = fA(2,0);
  
  grad.Zero();
  second.Zero();
#if __ROOT_FULLVERSION__ < 30000
  JSFDMatrix da(5,1), dadp(6,5);
#else
  TMatrixD da(5,1), dadp(6,5);
#endif
  dadp.Zero();
  dadp(4,2)=1.0;
  dadp(2,3)=1.0;
  dadp(5,4)=1.0;

  //fA.Print();
//C  
//C ---------------------------------------------------------------------
//C (2) Track Loop
//C ---------------------------------------------------------------------
//C  

  Int_t itrk;
  for(itrk=0;itrk<fNtrk;itrk++){
    Int_t ip   = 3*itrk+3;
    Double_t a = fA(ip,0);
    Double_t b = fA(ip+1,0);
    Double_t c = fA(ip+2,0);

    JSFHelixParameter *h=fTrkpar[itrk];
    Double_t x0=h->pivot.x;
    Double_t y0=h->pivot.y;
    Double_t z0=h->pivot.z;
    Double_t rho=fPTOR/b;

    Double_t cosa=TMath::Cos(a);
    Double_t sina=TMath::Sin(a);
    Double_t xc  = xv + rho*cosa;
    Double_t yc  = yv + rho*sina;

    Double_t phi0=0;
    if( h->kappa > 0.0 ) phi0=TMath::ATan2( yc-y0, xc-x0);
    else phi0 = TMath::ATan2(y0-yc, x0-xc);
    
    Double_t cosp0 = TMath::Cos(phi0);
    Double_t sinp0 = TMath::Sin(phi0);
    Double_t xp0   = xv + rho*(cosa-cosp0);
    Double_t yp0   = yv + rho*(sina-sinp0);
    Double_t zp0   = zv - rho*c*(phi0-a);

    Double_t dr = (xp0-x0)*cosp0 + (yp0-y0)*sinp0;
    da(0,0) = h->dr - dr;
    da(1,0) = h->phi0 - phi0;
    da(2,0) = h->kappa - b;
    da(3,0) = h->dz - (zp0-z0);
    da(4,0) = h->tanl - c;

//C  
//C ... Calculate Chi-Square contribution of this track.
//C  
#if __ROOT_FULLVERSION__ < 30000
    JSFDMatrix *em = fTrkerr[itrk];
    JSFDMatrix prod(da,da.kTransposeMult,JSFDMatrix((*em),da.kMult,da));
#else
    TMatrixD *em = fTrkerr[itrk];
    TMatrixD prod(da,da.kTransposeMult,TMatrixD((*em),da.kMult,da));
#endif
    Double_t chi=prod(0,0);
    
    chis += chi;
    fTrackChisq[itrk]=chi;

//C  
//C (DADP(i,j)
//C       i = dr,Phi0,K,dZ,Tanl
//C       j = Xv,Yv,Zv,A,B,C
//C

    Double_t rhodri = 1/(rho+dr);
    Double_t rhob   = rho/b;

    dadp(0,0) =  cosp0 ;
    dadp(1,0) =  sinp0 ;
    dadp(3,0) =  rho* (       sinp0*cosa - cosp0*sina );
    dadp(4,0) =  rhob*( 1 - sinp0*sina - cosp0*cosa );
// 
    dadp(0,1) = -rhodri*sinp0;
    dadp(1,1) =  rhodri*cosp0;
    dadp(3,1) =  rho *rhodri*( sinp0*sina + cosp0*cosa);
    dadp(4,1) =  rhob*rhodri*( sinp0*cosa - cosp0*sina);
//c  
    dadp(0,3) =  rho*rhodri*c*sinp0;
    dadp(1,3) = -rho*rhodri*c*cosp0;
    dadp(3,3) =  rho*c*(  1.0 - dadp(3,1));
    dadp(4,3) =  rho*c*( (phi0-a)/b - dadp(4,1) );
    dadp(5,3) = -rho*(phi0-a);
//C  
//C (Derivative of chi-square.
//C  
#if __ROOT_FULLVERSION__ < 30000
    JSFDMatrix dae((*em),da.kMult,da);
#else
    TMatrixD dae((*em),da.kMult,da);
#endif
//C  
//C Derivatives with respect to A, B, C
//C  

#if __ROOT_FULLVERSION__ < 30000
    JSFDMatrix daedadp(dadp,dae.kMult,dae);
#else
    TMatrixD daedadp(dadp,dae.kMult,dae);
#endif
    Int_t i;
    for(i=0;i<3;i++){
      grad(i,0) -= daedadp(i,0);
      grad(ip+i,0) -= daedadp(i+3,0);
    }

#if __ROOT_FULLVERSION__ < 30000
    JSFDMatrix sm1(dadp,dadp.kMult,(*em));
    JSFDMatrix sm(dadp,dadp.kMult,JSFDMatrix(sm1.kTransposed,sm1));
#else
    TMatrixD sm1(dadp,dadp.kMult,(*em));
    TMatrixD sm(dadp,dadp.kMult,TMatrixD(sm1.kTransposed,sm1));
#endif
    Int_t j;
    for(i=0;i<3;i++) for(j=0;j<3;j++) {
      second(i,j)+=sm(i,j);
      second(i+ip,j)+=sm(i+3,j);
      second(i,j+ip)+=sm(i,j+3);
      second(i+ip,j+ip)+=sm(i+3,j+3);
    }

  }

}



ROOT page - Home page - Class index - Top of the page

This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.