6 modified files
lcsim/src/org/lcsim/contrib/KFFitter
diff -u -r1.1 -r1.2
--- History 13 Dec 2006 22:45:11 -0000 1.1
+++ History 1 Feb 2007 22:29:34 -0000 1.2
@@ -3,11 +3,36 @@
## Please summarize changes to the KFFitter code here.
## Most recent first please.
+01 February 2007 Fred Blanc V01-01-00
+ - using the track fit parameters (d0,phi0,omega,z0,s) at all stages of the
+ propagation and filtering.
+ - added effects of:
+ 1) multiple scattering: add MS error matrix to track covariance matrix before filtering
+ 2) energy loss: subtract or add dE/dx at the end of the filtering step
+ - calculate the seed track using the first 3 hits on a track
+
13 December 2006 Fred Blanc V01-00-00
- Create KFFitter package. Included files:
- SODFittedCir.java
+ KFConstants.java stores a list of constants
+ KFFitterDriver.java main driver
+ KFMain.java used to run on the command line
+ java org.lcsim.contrib.KFFitter.KFMain <data file> <number of events to run>
+ KFMatrix.java unused (using Jama instead)
+ KFPoint.java defines a point in space and its error matrix
+ KFSite.java defines a Kalman site and handles the filtering of propagates track
+ KFSites can be a measurement and/or a material site
+ KFTrack.java contains a list of KFSites.
+ handles the swimming trough list of KFSites
+ KFTrackParameters.java defines the track parametrization and its error matrix
+ Supports three parameterizations:
+ 1) fit parameters: d0, phi0, omega, z0, tanl (+ path length)
+ 2) point parameters: x, y, z, px, py, pz
+ 3) helix parameters: xc, yc, rc, z0, tanl
+
- KFFitterDriver.java is the main driver
+ - Track parameterization is transformed to the r,phi,z,px,py,pz for
+ the filtering stage (this will changes in a coming version)
- Example code is given in test/TestKFF.java
- The default functionality is: 1) loop over tracks reconstructed
with the SODTrackFinder package, 2) apply the Kalman Filter
lcsim/src/org/lcsim/contrib/KFFitter
diff -u -r1.2 -r1.3
--- KFFitterDriver.java 30 Jan 2007 17:01:58 -0000 1.2
+++ KFFitterDriver.java 1 Feb 2007 22:29:34 -0000 1.3
@@ -47,6 +47,7 @@
// create new KFTrack and initialize it to the SODTrack fit parameters
KFTrack track = new KFTrack();
track.defineSeedTrack(SODtrk);
+ //track.defineSeedTrack(); // For testing purpose
List<SimTrackerHit> hits = (List<SimTrackerHit>) SODtrk.getHits();
int nbHits = hits.size();
@@ -64,6 +65,7 @@
if(chi2<100.) { // run fitter only if good track seed
for ( SimTrackerHit hit : hits ) {
track.addHit(hit); // assign hits to KFTrack
+ //track.addHitDebug(hit); // assign hits to KFTrack
}
System.out.print("Driver: track params before fit = ");
track.getTrackParameters().printFitParams();
lcsim/src/org/lcsim/contrib/KFFitter
diff -u -r1.2 -r1.3
--- KFPoint.java 30 Jan 2007 17:01:58 -0000 1.2
+++ KFPoint.java 1 Feb 2007 22:29:34 -0000 1.3
@@ -32,8 +32,6 @@
_zErr = 0.0005;
if(_r>10.){_zErr = 1000.;}
- _zErr = 1e+6; // fix me
-
//System.out.print("KFPoint: phi, rphiErr = ");
//System.out.print(_phi); System.out.print(" ");
//System.out.println(_rphiErr);
lcsim/src/org/lcsim/contrib/KFFitter
diff -u -r1.2 -r1.3
--- KFSite.java 30 Jan 2007 17:01:58 -0000 1.2
+++ KFSite.java 1 Feb 2007 22:29:34 -0000 1.3
@@ -45,13 +45,40 @@
}
+ public void setLocation(double x, double y, double z)
+ {
+ // ************************
+ // For testing purpose only
+ // ************************
+ System.out.println(" ************************");
+ System.out.println("KFSite: setLocation ** DEBUG MODE **");
+ System.out.println(" ************************");
+
+ _siteLocation.makePoint(x,y,z);
+
+ System.out.print("KFSite: Add Pt at coord = ");
+ System.out.print(x); System.out.print(" ");
+ System.out.print(y); System.out.print(" ");
+ System.out.println(z);
+
+ _PhiZErrorMatrix = _siteLocation.getPhiZErrorMatrix();
+
+ _PhiZErrorMatrixInverse = _PhiZErrorMatrix.inverse();
+
+ System.out.println("KFSite: PhiZ cov matrix:");
+ _PhiZErrorMatrix.print(12,10);
+
+ //System.out.println("KFSite: PhiZ cov matrix inverted:");
+ //_PhiZErrorMatrixInverse.print(12,10);
+ }
+
public KFTrackParameters filter(KFTrackParameters trk)
{
double[] tpp = trk.getFitParameters();
Matrix stateVect = new Matrix(tpp,5);
System.out.println("KFSite: initial stateVect:");
- stateVect.print(15,10);
+ stateVect.print(15,12);
double d0 = tpp[0];
double phi0 = tpp[1];
@@ -66,7 +93,7 @@
Matrix Q = new Matrix(5,5,0.);
- if(_materialSite) {
+ if(_materialSite && _applyMSCorrection) {
//add here process noise due to dE/dx and scattering effects
// Consider 3 unit vectors:
@@ -98,7 +125,7 @@
int chg = trk.getCharge();
double pt = Math.sqrt(px*px+py*py);
- double p = Math.sqrt(px*px+py*py+pz*pz);
+ double p = Math.sqrt(px*px+py*py+pz*pz);
double pxt1p = Math.cos(sctVar)*px - Math.sin(sctVar)*py*p/pt;
double pyt1p = Math.cos(sctVar)*py + Math.sin(sctVar)*px*p/pt;
@@ -142,7 +169,7 @@
SCTderiv.print(15,12);
// 2. Average scattering angle
- double mass = 0.13957; // assume pion hypothesis
+ double mass = _cst.pionMass(); // assume pion hypothesis
double beta = p/Math.sqrt(p*p+mass*mass); // use particle momentum
double sctRMS = (0.0136/(beta*p))*Math.sqrt(_radThickness)*(1+0.038*Math.log(_radThickness));
@@ -220,7 +247,11 @@
System.out.println("KFSite: trkCovInverse:");
trkCovInverse.print(15,12);
- double[] mp = {_siteLocation.getPhi(),_siteLocation.getZ()};
+ double[] ptParam = trk.getPointParameters();
+ double refPhi = Math.atan2(ptParam[1],ptParam[0]);
+ double refZ = ptParam[2];
+ double[] mp = {_siteLocation.getPhi()-refPhi,_siteLocation.getZ()-refZ};
+ //double[] mp = {_siteLocation.getPhi(),_siteLocation.getZ()};
Matrix measVect = new Matrix(mp,2);
System.out.println("KFSite: measVect:");
@@ -239,13 +270,16 @@
System.out.println("KFSite: Filtered Cov:");
filteredCov.print(15,12);
- Matrix tmp1 = trkCovInverse.times(stateVect);
+ //Matrix tmp1 = trkCovInverse.times(stateVect);
+ //Matrix tmp2 = HT.times(_PhiZErrorMatrixInverse).times(measVect);
+ //Matrix tmp3 = tmp1.plus(tmp2);
+ Matrix tmp1 = filteredCovInv.times(stateVect);
Matrix tmp2 = HT.times(_PhiZErrorMatrixInverse).times(measVect);
Matrix tmp3 = tmp1.plus(tmp2);
Matrix filteredTrkPar = filteredCov.times(tmp3);
System.out.println("KFSite: Filtered State Vector:");
- filteredTrkPar.print(6,6);
+ filteredTrkPar.print(15,12);
double[][] par = filteredTrkPar.getArrayCopy();
d0 = par[0][0];
@@ -262,13 +296,21 @@
tmpTrk.setTrackFitParameters(d0,phi0,omega,z0,tanl,l);
tmpTrk.setPointToRadius(_siteLocation.getR());
double tmpPtot = tmpTrk.getPtot();
- double dEdx = dEdx(tmpPtot);
- System.out.print("KFSite: Ptot = "); System.out.println(tmpPtot);
- System.out.print("KFSite: dEdx = "); System.out.println(dEdx);
-
- double tmpEtot = Math.sqrt(_cst.pionMass()*_cst.pionMass()+tmpPtot*tmpPtot);
- double tmpEtotCorr = tmpEtot+0.01*dEdx; // (fix me) change sign depending on fit direction
- double ratioCorr = tmpEtotCorr/tmpEtot;
+ double ratioCorr = 1.;
+ if(_applyDEDXCorrection) {
+ double dEdx = dEdx(tmpPtot);
+ System.out.print("KFSite: Ptot = "); System.out.println(tmpPtot);
+ System.out.print("KFSite: dEdx = "); System.out.println(dEdx);
+
+ double tmpEtot = Math.sqrt(_cst.pionMass()*_cst.pionMass()+tmpPtot*tmpPtot);
+ double tmpEtotCorr = tmpEtot;
+ if(_fitOutward) {
+ tmpEtotCorr -= _thickness*dEdx; // apply energy _loss_ when fitting inside-out
+ } else {
+ tmpEtotCorr += _thickness*dEdx; // apply energy _gain_ when fitting outside-in
+ }
+ ratioCorr = tmpEtotCorr/tmpEtot;
+ }
double[] tmpPar = tmpTrk.getPointParameters();
int tmpCh = tmpTrk.getCharge();
@@ -301,32 +343,45 @@
public KFPoint getSiteLocation() {return _siteLocation;}
+ public void setFitOutward() {_fitOutward = true;}
+ public void setFitInward() {_fitOutward = false;}
+
public void isMeasurementSite(boolean bool) {_measurementSite=bool;}
- public void isMaterialSite(boolean bool,double thickness) {
+ public void isMaterialSite(boolean bool,double rT, double t) {
_materialSite=bool;
- _radThickness = thickness;
+ _radThickness = rT;
+ _thickness = t;
}
public void isBFieldDiscontinuitySite(boolean bool) {_BFieldDiscontinuitySite=bool;}
+ public void applyMSCorrection(boolean bool) {_applyMSCorrection=bool;}
+ public void applyDEDXCorrection(boolean bool) {
+ System.out.print("KFSite: Setting dedx bool from: ");
+ System.out.print(_applyDEDXCorrection);
+ System.out.print(" to ");
+ _applyDEDXCorrection=bool;
+ System.out.println(_applyDEDXCorrection);
+ }
+
private double dEdx(double p)
{
double dedx = 0.0;
- double rho = 2.33; // g/cm^3 (Si)
- double Z = 14.; // Si
- double A = 28.0855; // Si
+ double rho = 2.3296; // g/cm^3 (Si)
+ double Z = 14.; // (Si)
+ double A = 28.0855; // g/mol (Si)
double beta = p/Math.sqrt(p*p+_cst.pionMass()*_cst.pionMass());
double gamma = 1./Math.sqrt(1-beta*beta);
double eta = beta*gamma;
- double s = 0.510998/_cst.pionMass();
- double Wmax = 2.*0.510998*eta*eta/(1.+2.*s*Math.sqrt(1+eta*eta)+s*s);
- double I = 172.;
+ double s = 0.000510998/_cst.pionMass();
+ double Wmax = 2.*0.000510998*eta*eta/(1.+2.*s*Math.sqrt(1+eta*eta)+s*s);
+ double I = 0.000000172;
- double frac = 2.*0.510998*eta*eta*Wmax/(I*I);
+ double frac = 2.*0.000510998*eta*eta*Wmax/(I*I);
double delta = 0.;
double C = 0.;
- dedx = -0.1535*rho*(Z/A)*(Math.log(frac)-2*beta*beta-delta-2*C/Z)/(beta*beta);
+ dedx = 0.0001535*rho*(Z/A)*(Math.log(frac)-2*beta*beta-delta-2*C/Z)/(beta*beta);
return dedx;
}
@@ -345,7 +400,13 @@
private boolean _materialSite = false;
private boolean _BFieldDiscontinuitySite = false;
+ private boolean _applyMSCorrection = true;
+ private boolean _applyDEDXCorrection = true;
+
+ private boolean _fitOutward = true;
+
private double _radThickness = 0.;
+ private double _thickness = 0.;
private KFConstants _cst = new KFConstants();
}
lcsim/src/org/lcsim/contrib/KFFitter
diff -u -r1.2 -r1.3
--- KFTrack.java 30 Jan 2007 17:01:58 -0000 1.2
+++ KFTrack.java 1 Feb 2007 22:29:34 -0000 1.3
@@ -27,9 +27,51 @@
kfhit.isMeasurementSite(true);
double radius = kfhit.getSiteLocation().getR();
double radThickness = 0.00107;
+ if (radius>10.) {radThickness = 0.00532;}
+ double thickness = 0.01;
+ if (radius>10.) {thickness = 0.03;}
+ kfhit.isMaterialSite(true,radThickness,thickness);
+
+ kfhit.applyMSCorrection(true);
+ kfhit.applyDEDXCorrection(true);
+
+ _siteList.add(kfhit);
+ //System.out.print("KFTrack: read back radius = ");
+ //System.out.println(kfhit.getSiteLocation().getR());
+
+ }
+
+ public void addHitDebug(SimTrackerHit hit)
+ {
+
+ System.out.println(" ************************");
+ System.out.println("KFTrack: addHitDebug ** DEBUG MODE **");
+ System.out.println(" ************************");
+
+
+ double[] pos = hit.getPoint();
+ // convert to cm
+ for(int i=0; i<3; i++) {pos[i]*=0.1;}
+ double radius = Math.sqrt(pos[0]*pos[0]+pos[1]*pos[1]);
+
+ KFTrackParameters seedExtrap = _seedTrack.makePredictionAtRadius(radius);
+ double[] p = seedExtrap.getPointParameters();
+
+ // define site for this hit
+ KFSite kfhit = new KFSite();
+ kfhit.setLocation(p[0],p[1],p[2]);
+
+ kfhit.isMeasurementSite(true);
+ double radThickness = 0.00107;
if (radius>10.) {radThickness=0.00532;}
- kfhit.isMaterialSite(true,radThickness);
+ double thickness = 0.01;
+ if (radius>10.) {thickness = 0.03;}
+ kfhit.isMaterialSite(false,radThickness,thickness);
_siteList.add(kfhit);
+
+ kfhit.applyMSCorrection(false);
+ kfhit.applyDEDXCorrection(false);
+
//System.out.print("KFTrack: read back radius = ");
//System.out.println(kfhit.getSiteLocation().getR());
@@ -85,27 +127,91 @@
}
+ public void defineSeedTrack()
+ {
+ // ************************
+ // For testing purpose only
+ // ************************
+
+ System.out.println(" ************************");
+ System.out.println("KFTrack: defineSeedTrack ** DEBUG MODE **");
+ System.out.println(" ************************");
+
+ // load track parameters d0,omega,...
+ double d = 0.;
+ double phi = 0;
+ //double omega = 0.00300; // 5GeV
+ //double omega = 0.00075; // 20GeV
+ double omega = 0.00015; // 100GeV
+ double z = 0.;
+ double s = 0.;
+
+ double l = 0.0; // path length set to zero (=POCA)
+
+ System.out.print("KFTrack: define track par = ");
+ System.out.print(d); System.out.print(" ");
+ System.out.print(phi); System.out.print(" ");
+ System.out.print(omega); System.out.print(" ");
+ System.out.print(z); System.out.print(" ");
+ System.out.println(s);
+
+ _seedTrack.setTrackFitParameters(d,phi,omega,z,s,l);
+
+ }
+
public void fit()
{
// sort list of hits by distance from origin
sortSiteList();
+ int initChg = _seedTrack.getCharge();
+ // initialize track param correlation matrix
+ double[][] cor = new double[5][5];
+ cor[0][0] = 1.; // d0
+ cor[0][1] = cor[1][0] = initChg*0.6; // d0 - phi0
+ cor[0][2] = cor[2][0] = -initChg*0.3; // d0 - omega
+ cor[1][1] = 1.; // phi0
+ cor[1][2] = cor[2][1] = -0.8; // phi0 - omega
+ cor[2][2] = 1.; // omega
+ cor[3][3] = 1.; // z0
+ cor[3][4] = cor[4][3] = -initChg*0.9; // z0 - tanl
+ cor[4][4] = 1.; // tanl
+ Matrix initCor = new Matrix(cor);
+
// initialize track param covariance matrix
double[][] diag = new double[5][5];
diag[0][0] = 10.; // d0
diag[1][1] = 1.; // phi0
diag[2][2] = 100.; // omega
- diag[3][3] = 10.; // z0
- diag[4][4] = 10.; // tanl
- Matrix initCov = new Matrix(diag);
+ diag[3][3] = 100.; // z0
+ diag[4][4] = 100.; // tanl
+ Matrix initDiag = new Matrix(diag);
+
+ //Matrix initCov = new Matrix();
+ Matrix initCov = initDiag.times(initCor).times(initDiag);
System.out.println("KFTrack: init cov matrix");
initCov.print(6,2);
System.out.print("KFTrack: ");
_seedTrack.printFitParams();
+ ListIterator hits = _orderedSiteList.listIterator();
+
+ //***************
+ // Fit inside-out
+ //***************
+ System.out.println("KFTrack: Fitting Track outward");
+
+ // Determine seed track parameters from 3 innermost hits
+ KFTrackParameters inOutSeedTrk =
+ seedTrkFromHits(_seedTrack.getCharge(),
+ (KFSite)_orderedSiteList.get(0),
+ (KFSite)_orderedSiteList.get(1),
+ (KFSite)_orderedSiteList.get(2));
+
// initialize track parameters for outward fit
- KFTrackParameters currentTrackOut = new KFTrackParameters(_seedTrack);
+ //KFTrackParameters currentTrackOut = new KFTrackParameters(_seedTrack);
+ KFTrackParameters currentTrackOut = new KFTrackParameters(inOutSeedTrk);
// determine track params at fixed small radius
//_seedTrack.setPointToPOCA();
double refRadius = 1.0;
@@ -115,24 +221,6 @@
// initialize error matrix
currentTrackOut.setErrorMatrix(initCov);
-
- // initialize track parameters for inward fit
- KFTrackParameters currentTrackIn = new KFTrackParameters(_seedTrack);
- // determine track params at fixed small radius
- refRadius = 130.0;
- currentTrackIn.setPointToRadius(refRadius);
- System.out.print("KFTrack: set radius to 130 : ");
- currentTrackIn.printFitParams();
- // initialize error matrix
- currentTrackIn.setErrorMatrix(initCov);
-
- ListIterator hits = _orderedSiteList.listIterator();
-
- //***************
- // Fit inside-out
- //***************
- System.out.println("KFTrack: Fitting Track outward");
-
for (; hits.hasNext();){
KFSite hit = (KFSite)hits.next();
@@ -153,6 +241,7 @@
predictedTrack.printPointParams();
// filter predicted track parameters with hit at radius R
+ hit.setFitOutward();
currentTrackOut = hit.filter(predictedTrack);
// record track parameters in KFSite
@@ -164,6 +253,25 @@
//***************
System.out.println("KFTrack: Fitting Track inward");
+ // Determine seed track parameters from 3 outtermost hits
+ //int hitListSize = _orderedSiteList.size();
+ //KFTrackParameters outInSeedTrk =
+ // seedTrkFromHits(_seedTrack.getCharge(),
+ // (KFSite)_orderedSiteList.get(hitListSize-1),
+ // (KFSite)_orderedSiteList.get(hitListSize-2),
+ // (KFSite)_orderedSiteList.get(hitListSize-3));
+ //KFTrackParameters currentTrackIn = new KFTrackParameters(outInSeedTrk);
+
+ // initialize track parameters for inward fit
+ KFTrackParameters currentTrackIn = new KFTrackParameters(currentTrackOut);
+ // determine track params at fixed small radius
+ refRadius = 130.0;
+ currentTrackIn.setPointToRadius(refRadius);
+ System.out.print("KFTrack: set radius to 130 : ");
+ currentTrackIn.printFitParams();
+ // initialize error matrix
+ currentTrackIn.setErrorMatrix(initCov);
+
for (; hits.hasPrevious();){
KFSite hit = (KFSite)hits.previous();
@@ -183,6 +291,7 @@
predictedTrack.printFitParams();
// filter predicted track parameters with hit at radius R
+ hit.setFitInward();
currentTrackIn = hit.filter(predictedTrack);
// record track parameters in KFSite
@@ -191,8 +300,76 @@
}
_fittedPtAtPOCA = currentTrackIn.getPt();
- System.out.print("KFTrack: Final fitted pt = ");
+ System.out.print("KFTrack: Final fitted pt = ");
System.out.println(_fittedPtAtPOCA);
+ System.out.print("KFTrack: Final fitted par = ");
+ currentTrackIn.printFitParams();
+ System.out.print("KFTrack: Final cov matrix = ");
+ currentTrackIn.getErrorMatrix().print(15,12);
+ Matrix cov = currentTrackIn.getErrorMatrix();
+ double[][] covArray = cov.getArrayCopy();
+ double[] error = new double[5];
+ for(int c=0; c<5; c++) {error[c] = Math.sqrt(covArray[c][c]);}
+ for(int a=0; a<5; a++) {
+ for(int b=0; b<5; b++) {
+ covArray[a][b] /= error[a]*error[b];
+ }
+ }
+ Matrix corMat = new Matrix(covArray);
+ System.out.print("KFTrack: Final corrlation matrix = ");
+ corMat.print(15,12);
+ }
+
+ private KFTrackParameters seedTrkFromHits(int q, KFSite p1, KFSite p2, KFSite p3)
+ {
+ double x1 = p1.getSiteLocation().getX();
+ double y1 = p1.getSiteLocation().getY();
+ double z1 = p1.getSiteLocation().getZ();
+ double x2 = p2.getSiteLocation().getX();
+ double y2 = p2.getSiteLocation().getY();
+ double z2 = p2.getSiteLocation().getZ();
+ double x3 = p3.getSiteLocation().getX();
+ double y3 = p3.getSiteLocation().getY();
+
+ double r1 = Math.sqrt(x1*x1+y1*y1);
+ double r2 = Math.sqrt(x2*x2+y2*y2);
+
+ System.out.println("KFTrack: hit coordinates = ");
+ System.out.print(x1); System.out.print(" ");
+ System.out.print(y1); System.out.print(" ");
+ System.out.print(z1); System.out.print(" ");
+ System.out.println(r1);
+ System.out.print(x2); System.out.print(" ");
+ System.out.print(y2); System.out.print(" ");
+ System.out.print(z2); System.out.print(" ");
+ System.out.println(r2);
+ System.out.print(x3); System.out.print(" ");
+ System.out.print(y3); System.out.print(" ");
+ System.out.println(Math.sqrt(x3*x3+y3*y3));
+
+ double denom = (x1-x2)*(y3-y2)-(x2-x3)*(y2-y1);
+ double alpha = 0.5*((x1-x3)*(x2-x3)+(y1-y3)*(y2-y3))/denom;
+ double beta = 0.5*((x1-x3)*(x1-x2)+(y1-y3)*(y1-y2))/denom;
+
+ double xc = 0.5*(x1+x2)+alpha*(y2-y1);
+ double yc = 0.5*(y1+y2)+beta*(x1-x2);
+
+ double r0 = Math.sqrt(xc*xc+yc*yc);
+ double rc = Math.sqrt((xc-x1)*(xc-x1)+(yc-y1)*(yc-y1));
+
+ double d0 = r0-rc;
+ double phi0 = Math.atan2(q*xc,-q*yc);
+ double omega = -q/rc;
+
+ double s = (z2-z1)/(r2-r1);
+ double z0 = z1+(Math.abs(d0)-r1)*s;
+
+ double l = 0.;
+
+ KFTrackParameters seedTrk = new KFTrackParameters();
+ seedTrk.setTrackFitParameters(d0,phi0,omega,z0,s,l);
+
+ return seedTrk;
}
public KFTrackParameters getTrackParameters() { return _seedTrack; }
lcsim/src/org/lcsim/contrib/KFFitter
diff -u -r1.2 -r1.3
--- KFTrackParameters.java 30 Jan 2007 17:01:58 -0000 1.2
+++ KFTrackParameters.java 1 Feb 2007 22:29:34 -0000 1.3
@@ -142,7 +142,7 @@
_yc = _y-_charge*_px/_cst.pointThreeTimesB();
_r0 = Math.sqrt(_xc*_xc+_yc*_yc);
_rc = Math.sqrt((_x-_xc)*(_x-_xc)+(_y-_yc)*(_y-_yc));
- _pt = Math.sqrt(_px*_px+_py*_py); // = _rc/_cst.pointThreeTimesB();
+ _pt = Math.sqrt(_px*_px+_py*_py); // = _rc*_cst.pointThreeTimesB();
_s = _pz/_pt;
_z0 = _z+Math.atan2(_y*_xc-_x*_yc,_r0*_r0-_x*_xc-_y*_yc)*_pz/_cst.pointThreeTimesB();
CVSspam 0.2.8