Print

Print


Commit in lcsim/src/org/lcsim/recon/vertexing/billoir on MAIN
Perigee.java+39added 1.1
Vertex.java+63added 1.1
VertexFitter.java+864added 1.1
package.html+9added 1.1
+975
4 added files
First release of Billoir vertex fit.
Very much a work in progress.

lcsim/src/org/lcsim/recon/vertexing/billoir
Perigee.java added at 1.1
diff -N Perigee.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ Perigee.java	14 Oct 2005 23:29:42 -0000	1.1
@@ -0,0 +1,39 @@
+package org.lcsim.recon.vertexing.billoir;
+public class Perigee
+{
+    //attributes
+    
+    private double[] _par;
+    //                          0 : epsilon (impact par. in xy projection, with sign)
+    //                          1 : z coordinate
+    //                          2 : theta angle
+    //                          3 : phi angle
+    //                          4 : 1/r (r = radius of curvature, with sign)
+    private double[] _cov;           // cov(0:15) :  covariance matrix of par (in lower diagonal form)
+    private double[] _wgt;           // wgt(0:15) :  weight matrix of par (inverse of cov)
+    
+    public Perigee( double[] par, double[] cov, double[] wgt)
+    {
+        _par = new double[5];
+        System.arraycopy(par,0,_par,0,5);
+        _cov = new double[15];
+        System.arraycopy(cov,0,_cov,0,15);
+        _wgt = new double[15];
+        System.arraycopy(wgt,0,_wgt,0,15);
+    }
+    
+    public double[] par()
+    {
+        return _par;
+    }
+    
+    public double[] cov()
+    {
+        return _cov;
+    }
+    
+    public double[] wgt()
+    {
+        return _wgt;
+    }
+}
\ No newline at end of file

lcsim/src/org/lcsim/recon/vertexing/billoir
Vertex.java added at 1.1
diff -N Vertex.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ Vertex.java	14 Oct 2005 23:29:42 -0000	1.1
@@ -0,0 +1,63 @@
+package org.lcsim.recon.vertexing.billoir;
+//Testing...
+// A class encapsulating the behavior of a vertex constructed
+// from tracks. It is written to be independent of any other
+// packages and therefore makes extensive use of arrays and
+// internal methods. It is not object-oriented in any way.
+// But it should work.
+//
+public class Vertex
+{
+    int _ntrk;       // the number of tracks used in this fit
+    double[] _xyzf; //the vertex position in Cartesian coordinates
+    double[] _vcov;   // packed covariance matrix on _xyzf
+    
+    double[][] _parf; // the fitted parameters at the vertex
+    // 0: theta
+    // 1: phi
+    // 2: 1/R
+    double[][] _tcov; // covariance matrix on _parf
+    
+    double _chi2;      // chisquared of vertex fit;
+    double[] _chi2tr;  // chisquared contribution of each track
+    
+    
+//default constructor
+    public Vertex()
+    {
+        _ntrk = 0;
+        _xyzf = new double[3];
+        _parf = new double[3][0];
+        _vcov = new double[6];
+        _tcov = new double[6][0];
+        _chi2 = 0.;
+        _chi2tr = new double[0];
+    }
+    // constructor
+    public Vertex( int ntrk, double[] xyz, double[][] parf, double[] vcov,
+            double[][] tcov, double chi2, double[] chi2tr)
+    {
+        _ntrk = ntrk;
+        _xyzf = xyz;
+        _parf = parf;
+        _vcov = vcov;
+        _tcov = tcov;
+        _chi2 = chi2;
+        _chi2tr = chi2tr;
+    }
+    
+    public String toString()
+    {
+        StringBuffer sb = new StringBuffer( "Vertex at : \nx= "+_xyzf[0]+" +/- "+Math.sqrt(_vcov[0])+
+                "\ny= "+_xyzf[1]+" +/- "+Math.sqrt(_vcov[2])+
+                "\nz= "+_xyzf[2]+" +/- "+Math.sqrt(_vcov[5])+
+                "\nchi2 = "+_chi2);
+        for (int i = 0;i < _ntrk ; ++i )
+        {
+            sb.append("\n chi2["+i+"]= "+_chi2tr[i]);
+        }
+        return sb.toString();
+        
+    }
+    
+}
\ No newline at end of file

lcsim/src/org/lcsim/recon/vertexing/billoir
VertexFitter.java added at 1.1
diff -N VertexFitter.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ VertexFitter.java	14 Oct 2005 23:29:42 -0000	1.1
@@ -0,0 +1,864 @@
+package org.lcsim.recon.vertexing.billoir;
+// Performs a Kalman fit to a list of tracks and returns
+// a Vertex object
+import static java.lang.Math.sin;
+import static java.lang.Math.cos;
+import static java.lang.Math.tan;
+import static java.lang.Math.atan;
+import static java.lang.Math.atan2;
+import static java.lang.Math.sqrt;
+import static java.lang.Math.PI;
+import static org.lcsim.recon.tracking.trfutil.TRFMath.fmod1;
+public class VertexFitter
+{
+    // the value of the magnetic field in the vicinity of the vertex
+    // default is a constant field along the z axis
+    private double _bField;
+    // constructor
+    public VertexFitter(double bField)
+    {
+        _bField = bField;
+    }
+    
+    // fitter
+    public Vertex fit(int ntrk, boolean fitwb, boolean[] invtx, double[][] par, double[][] wgt, double[] xyz)
+    {
+        return new Vertex();
+    }
+    
+    private double[] pxmi5(double[] wgt)
+    {
+        
+        //***********************************************************************
+        //*                                                                     *
+        //*                                                                     *
+        //*   inversion of a (5x5) symmetric positive matrix (cholesky method)  *
+        //*   internal computation in double precision                          *
+        //*   check on positivity (ierr=2 if wgt not positive)                  *
+        //*                                                                     *
+        //***********************************************************************
+        //*
+        double[] cov = new double[15];
+        double t11, t12, t13, t14, t15;
+        double t22, t23, t24, t25;
+        double t33, t34, t35;
+        double t44, t45;
+        double t55;
+        double s12, s13, s14, s15;
+        double s23, s24, s25;
+        double s34, s35;
+        double s45;
+        if(wgt[0]<0.) throw new IllegalArgumentException("Bad weight matrix!");
+        
+        t11=1./sqrt(wgt[0]);
+        s12=wgt[1]*t11;
+        s13=wgt[3]*t11;
+        s14=wgt[6]*t11;
+        s15=wgt[10]*t11;
+        //
+        t22=wgt[2]-s12*s12;
+        if(t22<0.) throw new IllegalArgumentException("Bad weight matrix!");
+        
+        t22=1./sqrt(t22);
+        s23=(wgt[4]-s12*s13)*t22;
+        s24=(wgt[7]-s12*s14)*t22;
+        s25=(wgt[11]-s12*s15)*t22;
+        //
+        t33=wgt[5]-s13*s13-s23*s23;
+        if(t33<0.) throw new IllegalArgumentException("Bad weight matrix!");
+        
+        t33=1./sqrt(t33);
+        s34=(wgt[8]-s13*s14-s23*s24)*t33;
+        s35=(wgt[12]-s13*s15-s23*s25)*t33;
+        //
+        t44=wgt[9]-s14*s14-s24*s24-s34*s34;
+        if(t44<0.) throw new IllegalArgumentException("Bad weight matrix!");
+        
+        t44=1./sqrt(t44);
+        s45=(wgt[13]-s14*s15-s24*s25-s34*s35)*t44;
+        //
+        t55=wgt[14]-s15*s15-s25*s25-s35*s35-s45*s45;
+        if(t55<0.) throw new IllegalArgumentException("Bad weight matrix!");
+        
+        t55=1./sqrt(t55);
+        //
+        t45=-t44*(s45*t55);
+        t34=-t33*(s34*t44);
+        t35=-t33*(s34*t45+s35*t55);
+        t23=-t22*(s23*t33);
+        t24=-t22*(s23*t34+s24*t44);
+        t25=-t22*(s23*t35+s24*t45+s25*t55);
+        t12=-t11*(s12*t22);
+        t13=-t11*(s12*t23+s13*t33);
+        t14=-t11*(s12*t24+s13*t34+s14*t44);
+        t15=-t11*(s12*t25+s13*t35+s14*t45+s15*t55);
+        //
+        cov[0]=t11*t11+t12*t12+t13*t13+t14*t14+t15*t15;
+        cov[1]=t12*t22+t13*t23+t14*t24+t15*t25;
+        cov[2]=t22*t22+t23*t23+t24*t24+t25*t25;
+        cov[3]=t13*t33+t14*t34+t15*t35;
+        cov[4]=t23*t33+t24*t34+t25*t35;
+        cov[5]=t33*t33+t34*t34+t35*t35;
+        cov[6]=t14*t44+t15*t45;
+        cov[7]=t24*t44+t25*t45;
+        cov[8]=t34*t44+t35*t45;
+        cov[9]=t44*t44+t45*t45;
+        cov[10]=t15*t55;
+        cov[11]=t25*t55;
+        cov[12]=t35*t55;
+        cov[13]=t45*t55;
+        cov[14]=t55*t55;
+        return cov;
+    }
+    
+    
+    private double fwdch2(double[] wgt,double d1,double d2,double d3,double d4,double d5)
+    {
+        //***********************************************************************
+        //*                                                                     *
+        //*   computation of dt*wgt*d                                           *
+        //*   wgt is a (5x5) symmetric matrix  ;  d is a 5-vector               *
+        //*                                                                     *
+        //***********************************************************************
+        //*
+        return wgt[0]*d1*d1+wgt[2]*d2*d2+wgt[5]*d3*d3+
+                wgt[9]*d4*d4+wgt[14]*d5*d5+
+                2*(d2* d1*wgt[1]+
+                d3*(d1*wgt[3]+d2*wgt[4])+
+                d4*(d1*wgt[6]+d2*wgt[7]+d3*wgt[8])+
+                d5*(d1*wgt[10]+d2*wgt[11]+d3*wgt[12]+d4*wgt[13]));
+    }
+    
+//	************************************************************************
+//	*                                                                      *
+//	subroutine perigee(rawdat,xb,yb,par,cov,wgt,ierr)
+    public Perigee perigee(double[] rawdat, double xb, double yb)
+    {
+//	*                                                                      *
+//	************************************************************************
+//  name        :  perigee
+//
+//  created     : 30-jun-1998 author : norman a. graf
+//                based on pxfxpe 7-jun-1989   author : p. billoir (cdf)
+//
+//  function    : compute from input data (with cylindrical or cartesian
+//                coordinates)
+//                the "perigee" parameters (point of closest approach to the
+//                reference axis) and the covariance matrix on them
+//                for error propagation, an approximation is made, assuming
+//                that the r coordinate of reference point is small w.r.t.
+//                the radius of curvature
+//                no account is taken for multiple scattering, so that the
+//                error matrix is underestimated if the data reference point
+//                is outside the beam pipe (except at high momentum)
+//
+//  references  : none
+//
+//  arguments   : input  : dat(1:21) :  tix array
+//                dat(1:3) : coord. of a point on the track
+//                  if "cylindrical" coord. :  r,r*phi,z
+//                  if "cartesian" coord. :  x,y,z
+//                dat(4:5) : theta, phi of the tangent at this point
+//                dat[5] : 1/p with geometrical sign
+//                dat(7:21) : covariance matrix on 5 "free" param. :
+//                  rphi,z,theta,phi,1/p if "cylind." coord. (r fixed)
+//                     x,y,theta,phi,1/p if "cartes." coord. (z fixed)
+//
+//                         xb,yb      :  coordinates of the reference axis
+//
+//                output : par(1:5)  :  "perigee" parameters
+//                          1 : epsilon (impact par. in xy projection, with sign)
+//                          2 : z coordinate
+//                          3 : theta angle
+//                          4 : phi angle
+//                          5 : 1/r (r = radius of curvature, with sign)
+//                         cov(1:15) :  covariance matrix of par
+//                         wgt(1:15) :  weight matrix of par (inverse of cov)
+//
+//  errors      :  ierr = 1 :  incorrect data in tkr array
+//                             (for example not cylindrical coordinates)
+//                        2 :  cov not positive (wgt not computed)
+//
+//************************************************************************
+//
+//
+// conversion from d0 cylindrical coordinates to mine...
+//
+        double sthet, sthet2, cthet, gamma;
+        double d0der11, d0der43, d0der45, d0der55;
+//	double[] rawdat = new double [21];
+//
+        double cosf,sinf,r0,rcosb,d11,d12,d21,d22,cov1,cov3,cov4,cov7,cov11;
+//   to define the magnetic field - values to be provided :
+        double consa = 0.003;
+        double bmag = _bField;
+        double consb = consa*bmag;
+        
+//   consa = velocity of light (here in gev/(cm.t) ; depends on units)
+//   bmag  = magnetic field along z axis
+//
+//
+        double[] par = new double[5];
+        double[] cov= new double[15];
+        double[] wgt= new double[15];
+        double sgn;
+        double[] dat = new double[21];
+//
+// local variables
+//__________________
+//
+        int ierr, ii;
+        double capphi,cotth,dphi,rdphi,rtrk,xc,x0,yc,y0;
+        double der1,der2,der11,der14,der15,der23,der45;
+//
+//
+// executable statements
+//________________________
+//
+        double twopi=2.*PI;
+        double halfpi=PI/2.;
+        
+        
+        int icypl = 1;
+//  icypl = 1 if "cylindrical" coordinates, 0 if "plane" coordinates
+//
+// convert here...
+//
+//
+//::: parameters r, rphi, z, theta, phi, 1/p
+//
+        dat[0]  = rawdat[0];               //r
+        dat[1]  = rawdat[0]*rawdat[1];     //r*phi
+        dat[2]  = rawdat[2];               //z
+        dat[3] = atan(1./rawdat[4]);       //theta
+        if(rawdat[4]<0) dat[3] = dat[3]+PI;
+        dat[4] = rawdat[1]+rawdat[3];      //phi (recall beta= phi(dir)-phi(pos) )
+        dat[5] = -rawdat[5]*sin(dat[3]);   //1/p (recall 1/pt = 1/(p*sin(theta))
+//
+//::: covariance matrix
+//::: there are seven terms in the conversion from
+//
+//      phi                     rphi
+//      z                       z
+//      alfa          to        theta
+//      cot(theta)              phi
+//      q/pt                    1/p
+//
+//     d0der14 =  1
+//     d0der22 =  1
+//     d0der34 = -1
+//
+        sthet  =  sin(dat[3]);
+        sthet2 =  sthet*sthet;
+        cthet  =  cos(dat[3]);
+        gamma  =  -rawdat[5]*cthet*sthet2;
+        
+        d0der11  =  rawdat[0];
+        d0der43  = -sthet2;
+        d0der45  = -rawdat[5]*cthet*sthet2;
+        d0der55  =  sthet;
+//
+        dat[6] =  rawdat[6]*rawdat[0]*rawdat[0];
+        dat[7] =  rawdat[7]*rawdat[0];
+        dat[8] =  rawdat[8];
+        dat[9] = -rawdat[12]*rawdat[0]*sthet2;
+        dat[10] = -rawdat[13]*sthet2;
+        dat[11] =  rawdat[15]*sthet2*sthet2;
+        dat[12] = (rawdat[6] - rawdat[9])*rawdat[0];
+        dat[13] =  rawdat[7] - rawdat[10];
+        dat[14] = (rawdat[14]-rawdat[12])*sthet2;
+        dat[15] =  rawdat[6] - 2*rawdat[9] + rawdat[11];
+        dat[16] = -(rawdat[16]*sthet + rawdat[12]*gamma)*rawdat[0];
+        dat[17] = -rawdat[17]*sthet - rawdat[13]*gamma;
+        dat[18] = (rawdat[19]*sthet + rawdat[15]*gamma)*sthet2;
+        dat[19] = (rawdat[14] - rawdat[12])*gamma +
+                (rawdat[18] -rawdat[16])*sthet;
+        dat[20] = (rawdat[15]*gamma + 2*rawdat[19]*sthet)*gamma +
+                rawdat[20]*sthet2;
+        
+//
+//  icypl = 1 if "cylindrical" coordinates, 0 if "plane" coordinates
+//
+        if ((icypl == 1 && dat[0] == 0.) ||
+                dat[3] == 0. || dat[5] == 0.)
+        {
+            System.out.println("******error in perigee*******");
+            throw new IllegalArgumentException("Choke!");
+        }
+        
+//
+//   now computation of "perigee" parameters
+//
+        capphi=dat[1]/dat[0];
+        if (icypl == 1)
+        {
+            x0=dat[0]*cos(capphi)-xb;
+            y0=dat[0]*sin(capphi)-yb;
+        }
+        else
+        {
+            x0 = dat[0]-xb;
+            y0 = dat[1]-yb;
+        }
+        rtrk= sin(dat[3])/(consb*dat[5]);
+        cosf = cos(dat[4]);
+        sinf = sin(dat[4]);
+        xc = x0-rtrk*sinf;
+        yc = y0+rtrk*cosf;
+//   epsilon (impact parameter in xy projection, with geometrical sign)
+        sgn = 1.;
+        if(rtrk<0.) sgn = -1.;
+        par[0]=rtrk-sgn*sqrt(xc*xc+yc*yc);
+//   phi at perigee (range 0,2*PI)
+        par[3]=atan2(yc,xc)+PI+sgn*halfpi;
+        if(par[3] <    0.) par[3]=par[3]+twopi;
+        if(par[3] > twopi) par[3]=par[3]-twopi;
+//   variation of phi from reference point of tkr to perigee (range -pi,+pi)
+        dphi=fmod1(par[3]-dat[4]+twopi+PI,twopi)-PI;
+        rdphi=rtrk*dphi;
+        cotth=1./tan(dat[3]);
+//   z of perigee
+        par[1]=dat[2]+cotth*rdphi;
+//   theta and 1/r at perigee (unchanged)
+        par[2]=dat[3];
+        par[4]=1./rtrk;
+//
+//   computation of covariance matrix
+//
+        for (ii = 0;ii<15; ++ii )
+        {
+            cov[ii] = dat[6+ii];
+        }
+//
+//   transformation from 1/p to 1/r = consb * (1/p) / sin(theta)
+//
+        der1=-cotth*par[4];
+        der2=par[4]/dat[5];
+        cov[14]=der1*der1*cov[5]+2*der1*der2*cov[12]+der2*der2*cov[14];
+        cov[10]=der1*cov[3]+der2*cov[10];
+        cov[11]=der1*cov[4]+der2*cov[11];
+        cov[12]=der1*cov[5]+der2*cov[12];
+        cov[13]=der1*cov[8]+der2*cov[13];
+//
+//   if cartesian coordinates transformation from (x,y) to (r*phi,z)
+//   (neglecting curvature effects )
+//
+        if (icypl == 0)
+        {
+            r0 = sqrt(dat[0]*dat[0]+dat[1]*dat[1]);
+            rcosb = dat[0]*cosf+dat[1]*sinf;
+            d11 = -r0*sinf/rcosb;
+            d12 = r0*cosf/rcosb;
+            d21 = -dat[0]*cotth/rcosb;
+            d22 = -dat[1]*cotth/rcosb;
+            cov1 = d11*d11*cov[0]+2*d11*d12*cov[1]+d12*d12*cov[2];
+            cov3 = d21*d21*cov[0]+2*d21*d22*cov[1]+d22*d22*cov[2];
+            cov[1]=d11*d21*cov[0]+(d12*d21+d11*d22)*cov[1]+d12*d22*cov[2];
+            cov[0] = cov1;
+            cov[2] = cov3;
+            cov4 = d11*cov[3]+d12*cov[4];
+            cov[4] = d21*cov[3]+d22*cov[4];
+            cov[3] = cov4;
+            cov7 = d11*cov[6]+d12*cov[7];
+            cov[7] = d21*cov[6]+d22*cov[7];
+            cov[6] = cov7;
+            cov11 = d11*cov[10]+d12*cov[11];
+            cov[11] = d21*cov[10]+d22*cov[11];
+            cov[10] = cov11;
+        }
+//
+//   transformation from (r*phi,z0,theta,phi0,1/r)
+//                  to (epsilon,zp,theta,phip,1/r)
+//
+//   approximation for derivatives d(epsilon)/d(r*phi), d(epsilon)/d(phi0),
+//   d(epsilon)/d(1/r), d(zp)/d(z0) and d(phip)/d(1/r)
+//   the other ones are exactly or approximately 1 (diagonal terms)
+//   or 0 (non-diagonal terms)
+//
+        der11 = rdphi/sqrt(x0*x0+y0*y0);
+        der14=-rdphi;
+        der15=-rdphi*rdphi/2.;
+        der23=-(1.+cotth*cotth)*rdphi;
+        der45=rdphi;
+//
+        cov[0]=der11*der11*cov[0]+2*der11*(der14*cov[6]+  der15*cov[10])
+        +der14*(der14*cov[9]+2*der15*cov[13])
+        +der15*der15*cov[14];
+        cov[1]=der11*(cov[1]+der23*cov[3])
+        +der14*(cov[7]+der23*cov[8])
+        +der15*(cov[11]+der23*cov[12]);
+        cov[2]=cov[2]+2*der23*cov[4]+der23*der23*cov[5];
+        cov[3]=der11*cov[3]+der14*cov[8]+der15*cov[12];
+        cov[4]=cov[4]+der23*cov[5];
+        cov[6]=der11*(cov[6]+der45*cov[10])
+        +der14*(cov[9]+der45*cov[13])
+        +der15*(cov[13]+der45*cov[14]);
+        cov[7]=       cov[7]+der23*cov[8]
+                +der45*(cov[11]+der23*cov[12]);
+        cov[8]=       cov[8]+der45*cov[12];
+        cov[9]=cov[9]+2*der45*cov[13]+der45*der45*cov[14];
+        cov[10]=der11*cov[10]+der14*cov[13]+der15*cov[14];
+        cov[11]=cov[11]+der23*cov[12];
+        cov[13]=cov[13]+der45*cov[14];
+//
+//   invert matrix cov to get wgt
+//
+        wgt = pxmi5(cov);
+//
+        return new Perigee(par, cov, wgt);
+        
+    }
+    private double[] pxmi3(double[] wgt)
+    {
+        //***********************************************************************
+        //*                                                                     *
+        //*                                                                     *
+        //*   inversion of a (3x3) symmetric positive matrix (cholesky method)  *
+        //*   internal computation in double precision                          *
+        //*   check on positivity (ierr=2 if wgt not positive)                  *
+        //*   cov (output) may overwrite wgt (input)                            *
+        //*                                                                     *
+        //***********************************************************************
+        //*
+        
+        double[] cov = new double[6];
+        double t11, t12, t13;
+        double t21, t22, t23;
+        double t33;
+        double s12, s13;
+        double s23;
+        
+        if(wgt[0]<0.) throw new IllegalArgumentException("Bad weight matrix!");
+        
+        t11=1./sqrt(wgt[0]);
+        s12=wgt[1]*t11;
+        s13=wgt[3]*t11;
+        //
+        t22=wgt[2]-s12*s12;
+        if(t22<0.) throw new IllegalArgumentException("Bad weight matrix!");
+        
+        t22=1./sqrt(t22);
+        s23=(wgt[4]-s12*s13)*t22;
+        //
+        t33=wgt[5]-s13*s13-s23*s23;
+        if(t33<0.) throw new IllegalArgumentException("Bad weight matrix!");
+        
+        t33=1./sqrt(t33);
+        //
+        t23=-t22*(s23*t33);
+        t12=-t11*(s12*t22);
+        t13=-t11*(s12*t23+s13*t33);
+        //
+        cov[0]=t11*t11+t12*t12+t13*t13;
+        cov[1]=t12*t22+t13*t23;
+        cov[2]=t22*t22+t23*t23;
+        cov[3]=t13*t33;
+        cov[4]=t23*t33;
+        cov[5]=t33*t33;
+        return cov;
+    }
+    
+    //************************************************************************
+    //*                                                                      *
+    public Vertex pxfvtx(int ntrk, boolean fitwb,
+            boolean[] invtx,double[][] par, double[][] wgt,
+            double[] xyz)
+    {
+        //*                                                                      *
+        //************************************************************************
+        //*  name        :  pxfvtx
+        //*
+        //*  created     :  5-jan-1989   author : p. billoir (cdf)
+        //*
+        //*  function    : perform a full vertex vertex fit with weighted mean
+        //*                of tracks considered as ellipsoids in 5d space of
+        //*                "perigee" parameters (epsilon,zp,theta,phi,1/r)
+        //*
+        //********  1-12-90 changes in pxfvtx routine :    p. billoir
+        //*    - to allow the use of the beam spot constraint (logical var. fitwb)
+        //*    - to know the contribution of individual tracks to the total chi2.
+        //*
+        //*  references  : none
+        //*
+        //*  arguments   : input  : ntrk             :  number of tracks
+        //*                            fitwb = .true. if we want the beam spot
+        //*                                           constraint
+        //*                            invtx(i)=.true. to use the track i in the
+        //*                                            vertex fit
+        //*                         par(1:5,1:ntrk)  :  "perigee" parameters
+        //*                          1 : epsilon (impact par. in xy projection, with sign)
+        //*                          2 : z coordinate
+        //*                          3 : theta angle
+        //*                          4 : phi angle
+        //*                          5 : 1/r (r = radius of curvature, with sign)
+        //*                         wgt(1:15,1:ntrk) :  weight matrix on par
+        //*                         xyz(1:3)  :  approximate coordinates of the vertex
+        //*
+        //*                output : xyzf(1:3) :  fitted coordinates of the vertex
+        //*                         parf(1:3,1:ntrk) : fitted parameters at the vertex
+        //*                          1 : theta
+        //*                          2 : phi
+        //*                          3 : 1/r
+        //*                         vcov(1:6) :  covariance matrix on xyz(vertex)
+        //*                         tcov(1:6,1:ntrk) :  covariance matrix on parf
+        //*                         chi2      :  chi2 of the fit
+        //*                            chi2tr(i)=contribution of track i to the
+        //*                                      total chi2
+        //*
+        //*  errors      :  ierr = 1 :  too many tracks (ntrk > ntrmax)
+        //*                 ierr = 2 :  covariance or weight matrix not positive
+        //*
+        //*************************************************************************
+        //*
+        //*
+        //*  "beam spot" description (common to be provided by the user)
+        //*  beamoy(1-3) are the mean beam spot positions in x,y and z.
+        //*  sigxbe,sigybe,sigzbe are the beam spread in x,y,z
+        //      common/pxcpro/beamoy[2],sigxbe,sigybe,sigzbe
+        //      double beamoy,sigxbe,sigybe,sigzbe
+        //*
+        // formal parameters
+        //*____________________
+        //*
+        //      int i,j,ierr,ntrk,ntrmax
+        //*
+        int ntrmax=1000;
+        
+        double[] xyzf = new double[3];
+        double[][] parf = new double[3][ntrk];
+        double[] vcov = new double[6];
+        double[][] tcov = new double[6][ntrk];
+        double chi2;
+        
+        //*
+        //* local variables
+        //*__________________
+        //*
+        double[] wa = new double[6];
+        double[][] wb = new double[9][ntrk];
+        double[][] wc = new double[6][ntrk];
+        double[][] wci = new double[6][ntrk];
+        double[][] wbci = new double[9][ntrk];
+        double[] tv = new double[3];
+        double[][] tt = new double[3][ntrk];
+        double[] dxyz = new double[3];
+        double[] phiv = new double[ntrk];
+        double[] eps = new double[ntrk];
+        double[] zp = new double[ntrk];
+        double[] deps = new double[ntrk];
+        double[] dzp = new double[ntrk];
+        double cotth,cosf,sinf,uu,vv,
+                d11,d12,d21,d22,d41,d42,e12,e13,e21,e22,e23,e43,
+                dw11,dw12,dw13,dw14,dw15,dw21,dw22,dw23,dw24,dw25,
+                dw31,dw32,dw33,dw34,dw35,ew11,ew12,ew13,ew14,ew15,
+                ew21,ew22,ew23,ew24,ew25,ew31,ew32,ew33,ew34,ew35,
+                chi2i,epsf,zpf,phif;
+        
+        double fwdch2;
+        double[] chi2tr = new double[ntrk];
+        
+        // needs to be set
+        double sigxbe = .1;
+        double sigybe = .1;
+        double sigzbe = .1;
+        double beamoy[] = {0.,0.,0.};
+        //
+        //*
+        //* executable statements
+        //*________________________
+        //*
+        
+        //*
+        //*   loop over the tracks
+        //*
+        chi2i=0.;
+        for (int i=0; i<ntrk; ++i)
+        {
+            if (invtx[i])
+            {
+                //*
+                //*  starting conditions :
+                //*  "perigee" parameters eps and zp if the trajectory goes through xyz
+                //*   and its theta,phi,1/r at perigee are equal to the values at input
+                //*
+                cotth=1./tan(par[2][i]);
+                uu=xyz[0]*cos(par[3][i])+xyz[1]*sin(par[3][i]);
+                vv=xyz[1]*cos(par[3][i])-xyz[0]*sin(par[3][i]);
+                eps[i]=-vv+.5*uu*uu*par[4][i];
+                zp[i]=xyz[2]-uu*cotth;
+                //*   phi at vertex with these parameters
+                phiv[i]=par[3][i]+uu*par[4][i];
+                cosf=cos(phiv[i]);
+                sinf=sin(phiv[i]);
+                //*
+                //*   contribution of this track to chi2 with initial values
+                //*
+                deps[i]=par[0][i]-eps[i];
+                dzp[i]=par[1][i]-zp[i];
+                chi2i=chi2i+wgt[0][i]*deps[i]*deps[i]+2*wgt[1][i]*deps[i]*dzp[i]+
+                        wgt[2][i]*dzp[i]*dzp[i];
+                //*
+                //*   derivatives (deriv1) of perigee param. w.r.t. x,y,z (vertex)
+                d11=sinf;
+                d12=-cosf;
+                d21=-cosf*cotth;
+                d22=-sinf*cotth;
+                d41=-cosf*par[4][i];
+                d42=-sinf*par[4][i];
+                //*
+                //*   matrix dw = (deriv1)t * weight
+                dw11 = d11*wgt[ 0][i] + d21*wgt[ 1][i] + d41*wgt[ 6][i];
+                dw12 = d11*wgt[ 1][i] + d21*wgt[ 2][i] + d41*wgt[ 7][i];
+                dw13 = d11*wgt[ 3][i] + d21*wgt[ 4][i] + d41*wgt[ 8][i];
+                dw14 = d11*wgt[ 6][i] + d21*wgt[ 7][i] + d41*wgt[9][i];
+                dw15 = d11*wgt[10][i] + d21*wgt[11][i] + d41*wgt[13][i];
+                dw21 = d12*wgt[ 0][i] + d22*wgt[ 1][i] + d42*wgt[ 6][i];
+                dw22 = d12*wgt[ 1][i] + d22*wgt[ 2][i] + d42*wgt[ 7][i];
+                dw23 = d12*wgt[ 3][i] + d22*wgt[ 4][i] + d42*wgt[ 8][i];
+                dw24 = d12*wgt[ 6][i] + d22*wgt[ 7][i] + d42*wgt[ 9][i];
+                dw25 = d12*wgt[10][i] + d22*wgt[11][i] + d42*wgt[13][i];
+                dw31 = wgt[ 1][i];
+                dw32 = wgt[ 2][i];
+                dw33 = wgt[ 4][i];
+                dw34 = wgt[ 7][i];
+                dw35 = wgt[11][i];
+                //*
+                //*  summation of  dw * dpar  to vector tv
+                tv[0] = tv[0] + dw11*deps[i] + dw12*dzp[i];
+                tv[1] = tv[1] + dw21*deps[i] + dw22*dzp[i];
+                tv[2] = tv[2] + dw31*deps[i] + dw32*dzp[i];
+                //*
+                //*   derivatives (deriv2) of perigee param. w.r.t. theta,phi,1/r (vertex)
+                e12=uu;
+                e13=-.5*uu*uu;
+                e21=-uu*(1.+cotth*cotth);
+                e22=-vv*cotth;
+                e23=uu*vv*cotth;
+                e43=-uu;
+                //*
+                //*   matrix ew = (deriv2)t * weight
+                ew11 = e21*wgt[ 1][i] + wgt[ 3][i];
+                ew12 = e21*wgt[ 2][i] + wgt[ 4][i];
+                ew13 = e21*wgt[ 4][i] + wgt[ 5][i];
+                ew14 = e21*wgt[ 7][i] + wgt[ 8][i];
+                ew15 = e21*wgt[11][i] + wgt[12][i];
+                ew21 = e12*wgt[ 0][i] + e22*wgt[ 1][i] + wgt[ 6][i];
+                ew22 = e12*wgt[ 1][i] + e22*wgt[ 2][i] + wgt[ 7][i];
+                ew23 = e12*wgt[ 3][i] + e22*wgt[ 4][i] + wgt[ 8][i];
+                ew24 = e12*wgt[ 6][i] + e22*wgt[ 7][i] + wgt[9][i];
+                ew25 = e12*wgt[10][i] + e22*wgt[11][i] + wgt[13][i];
+                ew31 = e13*wgt[ 0][i] + e23*wgt[ 1][i] + e43*wgt[ 6][i] + wgt[10][i];
+                ew32 = e13*wgt[ 1][i] + e23*wgt[ 2][i] + e43*wgt[ 7][i] + wgt[11][i];
+                ew33 = e13*wgt[ 3][i] + e23*wgt[ 4][i] + e43*wgt[ 8][i] + wgt[12][i];
+                ew34 = e13*wgt[ 6][i] + e23*wgt[ 7][i] + e43*wgt[9][i] + wgt[13][i];
+                ew35 = e13*wgt[10][i] + e23*wgt[11][i] + e43*wgt[13][i] + wgt[14][i];
+                //*
+                //*   computation of vector  tt = ew * dpar
+                tt[0][i] = ew11*deps[i] + ew12*dzp[i];
+                tt[1][i] = ew21*deps[i] + ew22*dzp[i];
+                tt[2][i] = ew31*deps[i] + ew32*dzp[i];
+                //*
+                //*   summation of  (deriv1)t * weight * (deriv1)  to  matrix wa
+                wa[0] = wa[0] + dw11*d11 + dw12*d21 + dw14*d41;
+                wa[1] = wa[1] + dw11*d12 + dw12*d22 + dw14*d42;
+                wa[2] = wa[2] + dw21*d12 + dw22*d22 + dw24*d42;
+                wa[3] = wa[3] + dw12;
+                wa[4] = wa[4] + dw22;
+                wa[5] = wa[5] + dw32;
+                //*
+                //*   computation of matrix  wb = (deriv1)t * weight * (deriv2)
+                wb[0][i] = dw12*e21 + dw13;
+                wb[1][i] = dw22*e21 + dw23;
+                wb[2][i] = dw32*e21 + dw33;
+                wb[3][i] = dw11*e12 + dw12*e22 + dw14;
+                wb[4][i] = dw21*e12 + dw22*e22 + dw24;
+                wb[5][i] = dw31*e12 + dw32*e22 + dw34;
+                wb[6][i] = dw11*e13 + dw12*e23 + dw14*e43 + dw15;
+                wb[7][i] = dw21*e13 + dw22*e23 + dw24*e43 + dw25;
+                wb[8][i] = dw31*e13 + dw32*e23 + dw34*e43 + dw35;
+                //*
+                //*   computation of matrix  wc = (deriv2)t * weight * (deriv2)
+                wc[0][i] = ew12*e21 + ew13;
+                wc[1][i] = ew22*e21 + ew23;
+                wc[3][i] = ew32*e21 + ew33;
+                wc[2][i] = ew21*e12 + ew22*e22 + ew24;
+                wc[4][i] = ew31*e12 + ew32*e22 + ew34;
+                wc[5][i] = ew31*e13 + ew32*e23 + ew34*e43 + ew35;
+                //*
+                //*   computation of matrices  wci = (wc)**(-1) and  wbci = wb * wci
+                
+                // Not very efficient here...
+                double[] tmp = new double[6];
+                for(int j = 0; j<6; ++j)
+                {
+                    tmp[j] = wc[j][i];
+                    System.out.println("tmp["+j+"]= "+tmp[j]);
+                }
+                double[] tmpinv = new double[6];
+                tmpinv = pxmi3(tmp);
+                for(int j = 0; j<6; ++j)
+                {
+                    wci[j][i] = tmpinv[j];
+                }
+                //         wci[0][i] = pxmi3(wc[0][i]);
+                
+                wbci[0][i] = wb[0][i]*wci[0][i] +wb[3][i]*wci[1][i] +wb[6][i]*wci[3][i];
+                wbci[1][i] = wb[1][i]*wci[0][i] +wb[4][i]*wci[1][i] +wb[7][i]*wci[3][i];
+                wbci[2][i] = wb[2][i]*wci[0][i] +wb[5][i]*wci[1][i] +wb[8][i]*wci[3][i];
+                wbci[3][i] = wb[0][i]*wci[1][i] +wb[3][i]*wci[2][i] +wb[6][i]*wci[4][i];
+                wbci[4][i] = wb[1][i]*wci[1][i] +wb[4][i]*wci[2][i] +wb[7][i]*wci[4][i];
+                wbci[5][i] = wb[2][i]*wci[1][i] +wb[5][i]*wci[2][i] +wb[8][i]*wci[4][i];
+                wbci[6][i] = wb[0][i]*wci[3][i] +wb[3][i]*wci[4][i] +wb[6][i]*wci[5][i];
+                wbci[7][i] = wb[1][i]*wci[3][i] +wb[4][i]*wci[4][i] +wb[7][i]*wci[5][i];
+                wbci[8][i] = wb[2][i]*wci[3][i] +wb[5][i]*wci[4][i] +wb[8][i]*wci[5][i];
+                //*
+                //*   subtraction of  wbci * (wb)t  from matrix wa
+                wa[0] = wa[0] - wbci[0][i]*wb[0][i] - wbci[3][i]*wb[3][i] - wbci[6][i]*wb[6][i];
+                wa[1] = wa[1] - wbci[0][i]*wb[1][i] - wbci[3][i]*wb[4][i] - wbci[6][i]*wb[7][i];
+                wa[2] = wa[2] - wbci[1][i]*wb[1][i] - wbci[4][i]*wb[4][i] - wbci[7][i]*wb[7][i];
+                wa[3] = wa[3] - wbci[0][i]*wb[2][i] - wbci[3][i]*wb[5][i] - wbci[6][i]*wb[8][i];
+                wa[4] = wa[4] - wbci[1][i]*wb[2][i] - wbci[4][i]*wb[5][i] - wbci[7][i]*wb[8][i];
+                wa[5] = wa[5] - wbci[2][i]*wb[2][i] - wbci[5][i]*wb[5][i] - wbci[8][i]*wb[8][i];
+                //*
+                //*   subtraction of  wbci * tt  from vector  tv
+                tv[0] = tv[0] - wbci[0][i]*tt[0][i] - wbci[3][i]*tt[1][i] - wbci[6][i]*tt[2][i];
+                tv[1] = tv[1] - wbci[1][i]*tt[0][i] - wbci[4][i]*tt[1][i] - wbci[7][i]*tt[2][i];
+                tv[2] = tv[2] - wbci[2][i]*tt[0][i] - wbci[5][i]*tt[1][i] - wbci[8][i]*tt[2][i];
+                //*
+            }// check on whether to use track
+        }// loop over tracks
+        
+        //    beam constraint
+        if (fitwb)
+        {
+            
+            wa[0] = wa[0] + 1./(sigxbe*sigxbe);
+            wa[2] = wa[2] + 1./(sigxbe*sigybe);
+            wa[5] = wa[5] + 1./(sigzbe*sigzbe);
+            tv[0]=tv[0]+(beamoy[0]-xyz[0])/(sigxbe*sigxbe);
+            tv[1]=tv[1]+(beamoy[1]-xyz[1])/(sigybe*sigybe);
+            tv[2]=tv[2]+(beamoy[2]-xyz[2])/(sigzbe*sigzbe);
+        }
+        //		*
+        //		*   solution of the linear system
+        //		*
+        //		*   covariance matrix on vertex
+        vcov = pxmi3(wa);
+        for (int ii = 0; ii < vcov.length ; ++ii )
+        {
+            System.out.println("vcov["+ii+"]= "+vcov[ii]);
+        }
+        //
+        //		*
+        //		*   corrections to vertex coordinates
+        dxyz[0] = vcov[0]*tv[0] + vcov[1]*tv[1] + vcov[3]*tv[2];
+        dxyz[1] = vcov[1]*tv[0] + vcov[2]*tv[1] + vcov[4]*tv[2];
+        dxyz[2] = vcov[3]*tv[0] + vcov[4]*tv[1] + vcov[5]*tv[2];
+        xyzf[0] = xyz[0] + dxyz[0];
+        xyzf[1] = xyz[1] + dxyz[1];
+        xyzf[2] = xyz[2] + dxyz[2];
+        //		*
+        //		*   corrections to track parameters and covariance matrices
+        //		*
+        for(int i = 0; i<ntrk;++i)
+        {
+            if (invtx[i])
+            {
+                //		*
+                //		*   variation on par is  wci * tt - (wbci)t * dxyz
+                parf[0][i] = par[2][i] + wci[0][i]*tt[0][i] + wci[1][i]*tt[1][i]
+                        + wci[3][i]*tt[2][i] - wbci[0][i]*dxyz[0] - wbci[1][i]*dxyz[1] -
+                        wbci[2][i]*dxyz[2];
+                parf[1][i] = phiv[i] + wci[1][i]*tt[0][i] + wci[2][i]*tt[1][i]
+                        + wci[4][i]*tt[2][i] - wbci[3][i]*dxyz[0] - wbci[4][i]*dxyz[1] -
+                        wbci[5][i]*dxyz[2];
+                parf[2][i] = par[4][i] + wci[3][i]*tt[0][i] + wci[4][i]*tt[1][i]
+                        + wci[5][i]*tt[2][i] - wbci[6][i]*dxyz[0] - wbci[7][i]*dxyz[1] -
+                        wbci[8][i]*dxyz[2];
+                //		*
+                //		*   covariance matrix of par is  wci + (wbci)t * vcov * wbci
+                tcov[0][i] = wci[0][i]
+                        + wbci[0][i] * (vcov[0]*wbci[0][i]+vcov[1]*wbci[1][i]+vcov[3]*wbci[2][i])
+                        + wbci[1][i] * (vcov[1]*wbci[0][i]+vcov[2]*wbci[1][i]+vcov[4]*wbci[2][i])
+                        + wbci[2][i] * (vcov[3]*wbci[0][i]+vcov[4]*wbci[1][i]+vcov[5]*wbci[2][i]);
+                
+                
+                
+                tcov[1][i] = wci[1][i]
+                        + wbci[0][i] * (vcov[0]*wbci[3][i]+vcov[1]*wbci[4][i]+vcov[3]*wbci[5][i])
+                        + wbci[1][i] * (vcov[1]*wbci[3][i]+vcov[2]*wbci[4][i]+vcov[4]*wbci[5][i])
+                        + wbci[2][i] * (vcov[3]*wbci[3][i]+vcov[4]*wbci[4][i]+vcov[5]*wbci[5][i]);
+                
+                
+                
+                tcov[2][i] = wci[2][i]
+                        + wbci[3][i] * (vcov[0]*wbci[3][i]+vcov[1]*wbci[4][i]+vcov[3]*wbci[5][i])
+                        + wbci[4][i] * (vcov[1]*wbci[3][i]+vcov[2]*wbci[4][i]+vcov[4]*wbci[5][i])
+                        + wbci[5][i] * (vcov[3]*wbci[3][i]+vcov[4]*wbci[4][i]+vcov[5]*wbci[5][i]);
+                
+                
+                
+                tcov[3][i] = wci[3][i]
+                        + wbci[0][i] * (vcov[0]*wbci[6][i]+vcov[1]*wbci[7][i]+vcov[3]*wbci[8][i])
+                        + wbci[1][i] * (vcov[1]*wbci[6][i]+vcov[2]*wbci[7][i]+vcov[4]*wbci[8][i])
+                        + wbci[2][i] * (vcov[3]*wbci[6][i]+vcov[4]*wbci[7][i]+vcov[5]*wbci[8][i]);
+                
+                
+                
+                tcov[4][i] = wci[4][i]
+                        + wbci[3][i] * (vcov[0]*wbci[6][i]+vcov[1]*wbci[7][i]+vcov[3]*wbci[8][i])
+                        + wbci[4][i] * (vcov[1]*wbci[6][i]+vcov[2]*wbci[7][i]+vcov[4]*wbci[8][i])
+                        + wbci[5][i] * (vcov[3]*wbci[6][i]+vcov[4]*wbci[7][i]+vcov[5]*wbci[8][i]);
+                
+                
+                
+                tcov[5][i] = wci[5][i]
+                        + wbci[6][i] * (vcov[0]*wbci[6][i]+vcov[1]*wbci[7][i]+vcov[3]*wbci[8][i])
+                        + wbci[7][i] * (vcov[1]*wbci[6][i]+vcov[2]*wbci[7][i]+vcov[4]*wbci[8][i])
+                        + wbci[8][i] * (vcov[3]*wbci[6][i]+vcov[4]*wbci[7][i]+vcov[5]*wbci[8][i]);
+                
+                
+                
+                //*
+            } // check on whether to use track
+        } // loop over tracks
+        
+        //		*
+        //		*   chi2 with fitted values
+        //		*
+        chi2=0.;
+        if(fitwb) chi2 = chi2
+                + ((xyzf[0]-beamoy[0])/sigxbe)*((xyzf[0]-beamoy[0])/sigxbe)
+                + ((xyzf[1]-beamoy[1])/sigybe)*((xyzf[1]-beamoy[1])/sigybe)
+                + ((xyzf[2]-beamoy[2])/sigzbe)*((xyzf[2]-beamoy[2])/sigzbe);
+        
+        for (int i = 0; i<ntrk; ++i)
+        {
+            if (invtx[i])
+            {
+                uu=xyzf[0]*cos(parf[1][i])+xyzf[1]*sin(parf[1][i]);
+                vv=xyzf[1]*cos(parf[1][i])-xyzf[0]*sin(parf[1][i]);
+                epsf=-vv-.5*uu*uu*parf[2][i];
+                zpf=xyzf[2]-uu/tan(parf[0][i]);
+                phif=parf[1][i]-uu*parf[2][i];
+                // not very efficient here...
+                double[] tmp = new double[15];
+                for(int j = 0; j<15; ++j)
+                {
+                    tmp[j] = wgt[j][i];
+                }
+                chi2tr[i]=fwdch2(tmp,
+                        epsf-par[0][i],
+                        zpf-par[1][i],
+                        parf[0][i]-par[2][i],
+                        phif-par[3][i],
+                        parf[2][i]-par[4][i]);
+                chi2=chi2+chi2tr[i];
+            }
+        }
+        System.out.println("chi2= "+chi2);
+        return new Vertex(ntrk, xyzf, parf, vcov, tcov, chi2, chi2tr);
+        
+    }
+    
+}
\ No newline at end of file

lcsim/src/org/lcsim/recon/vertexing/billoir
package.html added at 1.1
diff -N package.html
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ package.html	14 Oct 2005 23:29:43 -0000	1.1
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<html>
+  <body>
+  This package contains classes which implement vertex fitting
+  based on Billoir's method.
+  It is very much a work in progress.
+  </body>
+</html>
CVSspam 0.2.8