7 #include "marlin/Global.h" 8 #include <gear/BField.h> 9 #include <gearimpl/Vector3D.h> 11 #include "EVENT/LCIO.h" 13 #include "EVENT/TrackerHit.h" 37 const double qp = -bc.r();
38 const double q = qp * qbyp;
41 ajac[3][2] = ds * sqrt(t1[0] * t1[0] + t1[1] * t1[1]);
47 const double cosl1 = sqrt(t1[0] * t1[0] + t1[1] * t1[1]);
49 const double cosl2 = sqrt(t2[0] * t2[0] + t2[1] * t2[1]);
50 const double cosl2Inv = 1. / cosl2;
52 Vector3D hn(bc.unit());
54 const double pav = 1.0 / qbyp;
56 const double theta = q * ds;
57 const double sint = sin(theta);
58 const double cost = cos(theta);
59 const double gamma = hn.dot(t2);
60 Vector3D an1 = hn.cross(t1);
61 Vector3D an2 = hn.cross(t2);
63 const double au1 = 1. / t1.trans();
64 Vector3D u1(-au1 * t1[1], au1 * t1[0], 0.);
65 Vector3D v1(-t1[2] * u1[1], t1[2] * u1[0], t1[0] * u1[1] - t1[1] * u1[0]);
67 const double au2 = 1. / t2.trans();
68 Vector3D u2(-au2 * t2[1], au2 * t2[0], 0.);
69 Vector3D v2(-t2[2] * u2[1], t2[2] * u2[0], t2[0] * u2[1] - t2[1] * u2[0]);
71 const double anv = -hn.dot(u2);
72 const double anu = hn.dot(v2);
73 const double omcost = 1. - cost;
74 const double tmsint = theta - sint;
76 Vector3D dx(-(gamma * tmsint * hn[0] + sint * t1[0] + omcost * an1[0]) / q,
77 -(gamma * tmsint * hn[1] + sint * t1[1] + omcost * an1[1]) / q,
78 -(gamma * tmsint * hn[2] + sint * t1[2] + omcost * an1[2]) / q);
80 Vector3D hu1 = hn.cross(u1);
82 Vector3D hv1 = hn.cross(v1);
84 const double u1u2 = u1.dot(u2), u1v2 = u1.dot(v2), v1u2 = v1.dot(u2), v1v2 = v1.dot(v2);
85 const double hu1u2 = hu1.dot(u2), hu1v2 = hu1.dot(v2), hv1u2 = hv1.dot(u2), hv1v2 = hv1.dot(v2);
86 const double hnu1 = hn.dot(u1), hnv1 = hn.dot(v1), hnu2 = hn.dot(u2), hnv2 = hn.dot(v2);
87 const double t2u1 = t2.dot(u1), t2v1 = t2.dot(v1);
88 const double t2dx = t2.dot(dx), u2dx = u2.dot(dx), v2dx = v2.dot(dx);
89 const double an2u1 = an2.dot(u1), an2v1 = an2.dot(v1);
94 ajac[1][0] = -qp * anv * t2dx;
95 ajac[1][1] = cost * v1v2 + sint * hv1v2 + omcost * hnv1 * hnv2 + anv * (-sint * t2v1 + omcost * an2v1 - gamma * tmsint * hnv1);
97 * (cost * u1v2 + sint * hu1v2 + omcost * hnu1 * hnv2 + anv * (-sint * t2u1 + omcost * an2u1 - gamma * tmsint * hnu1));
98 ajac[1][3] = -q * anv * t2u1;
99 ajac[1][4] = -q * anv * t2v1;
101 ajac[2][0] = -qp * anu * t2dx * cosl2Inv;
102 ajac[2][1] = cosl2Inv
103 * (cost * v1u2 + sint * hv1u2 + omcost * hnv1 * hnu2 + anu * (-sint * t2v1 + omcost * an2v1 - gamma * tmsint * hnv1));
104 ajac[2][2] = cosl2Inv * cosl1
105 * (cost * u1u2 + sint * hu1u2 + omcost * hnu1 * hnu2 + anu * (-sint * t2u1 + omcost * an2u1 - gamma * tmsint * hnu1));
106 ajac[2][3] = -q * anu * t2u1 * cosl2Inv;
107 ajac[2][4] = -q * anu * t2v1 * cosl2Inv;
109 ajac[3][0] = pav * u2dx;
110 ajac[3][1] = (sint * v1u2 + omcost * hv1u2 + tmsint * hnu2 * hnv1) / q;
111 ajac[3][2] = (sint * u1u2 + omcost * hu1u2 + tmsint * hnu2 * hnu1) * cosl1 / q;
115 ajac[4][0] = pav * v2dx;
116 ajac[4][1] = (sint * v1v2 + omcost * hv1v2 + tmsint * hnv2 * hnv1) / q;
117 ajac[4][2] = (sint * u1v2 + omcost * hu1v2 + tmsint * hnv2 * hnu1) * cosl1 / q;
125 simpleHelix::simpleHelix(
const double rinv,
const double phi0,
const double dca,
const double dzds,
const double z0,
126 const double* refPoint,
const double Bzc) :
127 _xref(refPoint[0]), _yref(refPoint[1]), _zref(refPoint[2]), _bzc(Bzc), _rinv(rinv), _phi0(phi0), _dca(dca), _dzds(dzds), _z0(
128 z0), _xRelCenter(-(1. - _dca * _rinv) * sin(_phi0)), _yRelCenter((1. - _dca * _rinv) * cos(_phi0)), _eps(1.0e-6) {
140 std::cout <<
" simpleHelix " <<
_rinv <<
", " <<
_phi0 <<
", " <<
_dca <<
", " <<
_dzds <<
", " <<
_z0 << std::endl;
142 std::cout <<
" ref. point " <<
_xref <<
", " <<
_yref <<
", " <<
_zref << std::endl;
154 const double xLoc = position[0] -
_xref;
155 const double yLoc = position[1] -
_yref;
161 double dphi = atan2(dx, -dy) -
_phi0;
162 if (abs(dphi) > M_PI) dphi -= (dphi > 0.) ? 2.0 * M_PI : -2.0 * M_PI;
168 const double tanl =
_dzds;
169 const double cosl = 1. / sqrt(1. + tanl * tanl);
171 direction[1] = cosl * tanl;
208 double& phi,
double& lambda)
const {
209 const double xLoc = point[0] -
_xref;
210 const double yLoc = point[1] -
_yref;
211 const double zLoc = point[2] -
_zref;
214 if (measPhi ==
_phi0)
return false;
216 const double cosb = sin(measPhi -
_phi0);
217 const double sinb = cos(measPhi -
_phi0);
218 sArc = (sin(measPhi) * xLoc - cos(measPhi) * yLoc -
_dca * sinb) / cosb;
225 const double ex = cos(measPhi);
226 const double ey = sin(measPhi);
227 const double A = ex * dx + ey * dy;
228 const double B = dx * dx + dy * dy - 1.0;
230 if (A * A < B)
return false;
232 const double cosb = A * sqrt(1.0 - B / (A * A));
234 xyPos = (A - cosb) / _rinv;
235 const double dxSec = (xLoc + ex * xyPos) * _rinv -
_xRelCenter;
236 const double dySec = (yLoc + ey * xyPos) * _rinv -
_yRelCenter;
237 phi = atan2(dxSec, -dySec);
238 double dphi = phi -
_phi0;
239 if (abs(dphi) > M_PI) dphi -= dphi > 0. ? 2.0 * M_PI : -2.0 * M_PI;
243 lambda = atan(
_dzds);
257 Vector3D bFieldc(0., 0.,
_bzc);
259 const double cosl = 1. / sqrt(1. +
_dzds *
_dzds);
260 const double sinl = cosl *
_dzds;
261 const double phi2 = phi1 + ds * cosl *
_rinv;
262 Vector3D dir1(cosl * cos(phi1), cosl * sin(phi1), sinl);
263 Vector3D dir2(cosl * cos(phi2), cosl * sin(phi2), sinl);
265 const double qbyp = (_rinv != 0.) ? -cosl * _rinv /
_bzc : 0.;
278 const double cosl = 1. / sqrt(1. +
_dzds *
_dzds);
281 ajac[2][0] = -
_bzc * ds;
282 ajac[3][0] = -0.5 *
_bzc * ds * ds * cosl;
283 ajac[3][2] = ds * cosl;
297 const double cosPhi = cos(
_phi0);
298 const double sinPhi = sin(
_phi0);
299 const double tanLambda =
_dzds;
300 const double cosLambda = 1. / sqrt(1. + tanLambda * tanLambda);
301 const double sinLambda = cosLambda *
_dzds;
302 Vector3D T(cosPhi * cosLambda, sinPhi * cosLambda, sinLambda);
303 Vector3D U(-sinPhi, cosPhi, 0.);
304 Vector3D V(-cosPhi * sinLambda, -sinPhi * sinLambda, cosLambda);
307 Vector3D J(sinPhi, -cosPhi, 0.);
308 Vector3D K(0., 0., 1.);
309 Vector3D I = J.cross(K);
312 Vector3D H(0., 0., 1.);
313 Vector3D aN = H.cross(T);
315 const double ui = U.dot(I), anv = aN.dot(V), ti = T.dot(I);
316 const double vi = V.dot(I), anu = aN.dot(U), vk = V.dot(K);
318 TMatrixD cl2perjacobian(5, 5);
319 cl2perjacobian.UnitMatrix();
321 const double Q =
_rinv * cosLambda;
322 cl2perjacobian[0][0] = -
_bzc / cosLambda;
323 cl2perjacobian[0][1] = Q * tanLambda / cosLambda;
324 cl2perjacobian[0][3] = -Q * Q * tanLambda * ui * anv / cosLambda / ti;
325 cl2perjacobian[0][4] = -Q * Q * tanLambda * vi * anv / cosLambda / ti;
326 cl2perjacobian[1][1] = -1.;
327 cl2perjacobian[1][3] = Q * ui * anv / ti;
328 cl2perjacobian[1][4] = Q * vi * anv / ti;
329 cl2perjacobian[2][3] = -Q * ui * anu / cosLambda / ti;
330 cl2perjacobian[2][4] = -Q * vi * anu / cosLambda / ti;
331 cl2perjacobian[3][3] = vk / ti;
332 cl2perjacobian[4][4] = -1. / ti;
334 return cl2perjacobian;
346 TMatrixD per2ILDjacobian(5, 5);
347 per2ILDjacobian.UnitMatrix();
349 per2ILDjacobian[0][0] = -1.;
350 per2ILDjacobian[1][1] = -(1. +
_dzds *
_dzds);
351 per2ILDjacobian[3][3] = -1.;
353 return per2ILDjacobian;
365 TMatrixD per2LCIOjacobian(5, 5);
367 per2LCIOjacobian[0][3] = -1.;
368 per2LCIOjacobian[1][2] = 1.;
369 per2LCIOjacobian[2][0] = -1.;
370 per2LCIOjacobian[3][4] = 1.;
371 per2LCIOjacobian[4][1] = -(1. +
_dzds *
_dzds);
373 return per2LCIOjacobian;
385 TMatrixD hlx2LCIOjacobian(5, 5);
387 hlx2LCIOjacobian[0][2] = -1.;
388 hlx2LCIOjacobian[1][1] = 1.;
389 hlx2LCIOjacobian[2][0] = -1.;
390 hlx2LCIOjacobian[3][4] = 1.;
391 hlx2LCIOjacobian[4][3] = 1.;
393 return hlx2LCIOjacobian;
403 void simpleHelix::moveTo(
const double newRefX,
const double newRefY,
const double newRefZ,
double* newPar) {
404 const double dx =
_xref - newRefX;
405 const double dy =
_yref - newRefY;
406 const double dz =
_zref - newRefZ;
411 newPar[4] =
_z0 + dz;
413 const double cosphi = cos(
_phi0);
414 const double sinphi = sin(
_phi0);
416 const double dp = dx * sinphi - dy * cosphi +
_dca;
417 const double dl = dx * cosphi + dy * sinphi;
418 const double sa = 2. * dp -
_rinv * (dp * dp + dl * dl);
419 const double sb = -
_rinv * dx + u * sinphi;
420 const double sc =
_rinv * dy + u * cosphi;
421 const double sd = sqrt(1. -
_rinv * sa);
425 newPar[4] -= dl *
_dzds;
427 newPar[1] = atan2(sb, sc);
428 newPar[2] = sa / (1. + sd);
429 double dphi = newPar[1] -
_phi0;
430 if (abs(dphi) > M_PI) dphi -= (dphi > 0.) ? 2.0 * M_PI : -2.0 * M_PI;
445 TMatrixDSym& newCov) {
446 const double dx =
_xref - posX;
447 const double dy =
_yref - posY;
448 const double dz =
_zref - posZ;
450 const double cosphi = cos(
_phi0);
451 const double sinphi = sin(
_phi0);
453 const double dp = dx * sinphi - dy * cosphi +
_dca;
454 const double dl = dx * cosphi + dy * sinphi;
455 const double sa = 2. * dp -
_rinv * (dp * dp + dl * dl);
456 const double sb = -
_rinv * dx + u * sinphi;
457 const double sc =
_rinv * dy + u * cosphi;
458 const double sd = sqrt(1. -
_rinv * sa);
466 newPar[3] =
_z0 + sArc *
_dzds + dz;
469 newPar[1] = atan2(sb, sc);
470 newPar[2] = sa / (1. + sd);
472 double dphi = newPar[1] -
_phi0;
473 if (abs(dphi) > M_PI) dphi -= (dphi > 0.) ? 2.0 * M_PI : -2.0 * M_PI;
475 newPar[4] =
_z0 + sArc *
_dzds + dz;
478 int nPar = (
_rinv == 0.) ? 4 : 5;
479 TMatrixD aJac(nPar, nPar);
481 if ((dx * dx + dy * dy) *
_rinv *
_rinv < _eps * _eps) {
485 const double fc = 1. / (sb * sb + sc * sc);
486 const double fl = 0.5 * sa / (sd * (1. + sd) * (1. + sd));
487 const double fm = -
_rinv * fl + 1. / (sd * (1. + sd));
488 aJac[1][0] = -fc * dl;
489 aJac[1][1] = fc * u * (1. -
_rinv * dp);
491 aJac[2][0] = -fm * (dp * dp + dl * dl) + fl * sa;
492 aJac[2][1] = 2. * fm * u * dl;
493 aJac[2][2] = 2. * fm * (1. -
_rinv * dp);
494 aJac[4][0] =
_dzds * (aJac[1][0] - sArc) /
_rinv;
495 aJac[4][1] =
_dzds * (aJac[1][1] - 1.) /
_rinv;
501 newCov.Similarity(aJac);
511 _bfac(bScale * 0.0002998), _offset(3), _rotation(3, 3), _rotInv(3, 3) {
513 const double cosPhi = cos(parameters[1]);
514 const double sinPhi = sin(parameters[1]);
515 const double cosLambda = 1. / sqrt(1. + parameters[3] * parameters[3]);
516 _trackDir = cosLambda * Vector3D(cosPhi, sinPhi, parameters[3]);
518 double pca[] = { refPoint[0] + sinPhi * parameters[2], refPoint[1] - cosPhi * parameters[2], refPoint[2] + parameters[4] };
536 Vector3D n = h.cross(t).unit();
537 Vector3D p = n.cross(h);
539 for (
int i = 0; i < 3; ++i) {
548 const double gamma = h.dot(t);
549 const double alpha = sqrt(1. - gamma * gamma);
564 TVectorD localDir(3);
569 TVectorD globalDir(
_rotInv * localDir);
570 for (
int i = 0; i < 3; ++i)
578 cout <<
" localHelix, Q/P = " <<
_qbyp << endl;
582 cout <<
" rotation " << endl;
602 double relPos[] = { point[0] -
_offset[0], point[1] - _offset[1], point[2] - _offset[2] };
604 double deltaW = startHelix.getArcLengthXY(relPos) /
_cosLambda;
605 aJac = startHelix.analyticalHelixJacobian(0., deltaW);
607 for (
int i = 0; i < 3; ++i)
611 const double maxStep = abs(mstep);
613 double sArc, newPos[3], step;
614 TVectorD localPos(3);
622 sArc = startHelix.getArcLengthXY(localPos.GetMatrixArray());
626 startHelix.getPosAtArcLength(step *
_cosLambda, newPos);
629 Vector3D newBc =
getBFieldc(newGlobalPos.GetMatrixArray());
631 _bFieldc = 0.5 * (_bFieldc + newBc);
638 sArc = startHelix.getArcLengthXY(localPos.GetMatrixArray());
639 step = abs(sArc / _cosLambda) > maxStep ? (sArc > 0. ? maxStep : -maxStep) : sArc / _cosLambda;
641 startHelix.getPosAtArcLength(step * _cosLambda,
_localRef);
668 globalPar[1] = atan2(_trackDir[1], _trackDir[0]);
670 globalPar[3] = _trackDir[2] / cosLambda;
681 Vector3D bfield = marlin::Global::GEAR->getBField().at(Vector3D(pos));
682 return _bfac * bfield;
692 _curved(flag), _npar((flag) ? 3 : 2), _xRef(xr), _yRef(yr), _parameters(_npar), _covariance(_npar) {
706 double xl = x -
_xRef;
707 double yl = y -
_yRef;
715 double r2 = xl * xl + yl * yl;
728 EVENT::TrackerHitVec inputHitVec = seedTrack->getTrackerHits();
729 for (
unsigned int iHit = 0; iHit < inputHitVec.size(); iHit++) {
730 this->
simpleFitXY::addPoint(inputHitVec[iHit]->getPosition()[0], inputHitVec[iHit]->getPosition()[1], 1);
753 double cxx = axx - ax * ax;
754 double cyy = ayy - ay * ay;
755 double cxy = axy - ax * ay;
756 double cxr = axr - ax * ar;
757 double cyr = ayr - ay * ar;
758 double crr = arr - ar * ar;
762 q1 = crr * cxy - cxr * cyr;
763 q2 = crr * (cxx - cyy) - cxr * cxr + cyr * cyr;
768 double phi = 0.5 * atan2(2. * q1, q2);
769 double sinphi = sin(phi);
770 double cosphi = cos(phi);
772 if (cosphi * (ax +
_xRef) + sinphi * (ay +
_yRef) < 0.) {
774 phi -= (phi > 0.) ? M_PI : -M_PI;
779 double kappa = (sinphi * cxr - cosphi * cyr) / crr;
780 double delta = -kappa * ar + sinphi * ax - cosphi * ay;
782 double rho = -2. * kappa / sqrt(1. - 4. * delta * kappa);
783 double d = 2. * delta / (1. + sqrt(1. - 4. * delta * kappa));
788 double u = 1. - rho * d;
789 Chi2 =
_sw * u * u * (sinphi * sinphi * cxx - 2. * sinphi * cosphi * cxy + cosphi * cosphi * cyy - kappa * kappa * crr);
792 double sa = sinphi *
_sx - cosphi *
_sy;
793 double sb = cosphi *
_sx + sinphi *
_sy;
794 double sc = (sinphi * sinphi - cosphi * cosphi) *
_sxy + sinphi * cosphi * (
_sxx -
_syy);
795 double sd = sinphi *
_sxr - cosphi *
_syr;
796 double saa = sinphi * sinphi *
_sxx - 2. * sinphi * cosphi *
_sxy + cosphi * cosphi *
_syy;
799 _covariance[1][0] = _covariance[0][1];
800 _covariance[1][1] = u * u * (cosphi * cosphi *
_sxx + 2. * cosphi * sinphi *
_sxy + sinphi * sinphi *
_syy);
801 _covariance[0][2] = rho * (-0.5 * sd + d * saa) - 0.5 * u *
_sr + 0.5 * d * ((3 * u - 1.) * sa - u * d *
_sw);
802 _covariance[2][0] = _covariance[0][2];
803 _covariance[1][2] = -u * (rho * sc + u * sb);
804 _covariance[2][1] = _covariance[1][2];
805 _covariance[2][2] = rho * (rho * saa + 2 * u * sa) + u * u *
_sw;
808 double d = sinphi * ax - cosphi * ay;
812 Chi2 =
_sw * (sinphi * sinphi * cxx - 2. * sinphi * cosphi * cxy + cosphi * cosphi * cyy);
816 _covariance[0][1] = -(cosphi *
_sx + sinphi *
_sy);
817 _covariance[1][0] = _covariance[0][1];
818 _covariance[1][1] =
_sw;
879 aMat[0][1] = aMat[1][0] =
_sx;
void calcLocal()
Calculate local parameters.
int fit(double &, int &)
Perform fit.
double _sxx
weighted sum(x*x)
double _sx
weighted sum(x)
double _sy
weighted sum(z)
TMatrixD localHelixAnalyticalJacobian(double ds, double qbyp, Vector3D &t1, Vector3D &t2, Vector3D &bc)
Get analytical helix propagator (in constant magnetic field)
gear::Vector3D _bFieldc
B-field.
double _srr
weighted sum(r*r*r*r)
simpleHelix getSimpleHelix() const
Get simple helix.
const double _z0
Z position at distance of closest approach.
simpleHelix(const double, const double, const double, const double, const double, const double *, const double)
Constructor.
TMatrixD analyticalHelixJacobian(const double, const double) const
Get analytical helix propagator (in constant solenoidal magnetic field)
TMatrixD propagateTo(const double *, const double)
Propagate stepwise (close) to point.
void moveTo(const double, const double, const double, double *)
Change reference point.
const double _eps
cut off for straight line approximation (|relevent scale / R| < _eps)
void dump() const
Dump helix.
TMatrixD _rotation
rotation to local system
double _localRef[3]
local reference point
TMatrixD _rotInv
rotation from local system
double _syy
weighted sum(z*z)
double _syr
weighted sum(y*r*r)
TMatrixD perigeeToLCIOJacobian() const
Get transformation from helix to LCIO track parameters (at reference point)
double _localPar[5]
local helix parameter
void dump() const
Dump helix.
gear::Vector3D _trackDir
(global) track direction
double _sy
weighted sum(y)
TMatrixDSym getCov() const
Get covariance matrix.
int _numPoints
number of points (hits) used
void getPosAtArcLength(const double, double *) const
Get position (on helix) at arc length.
const double _phi0
flight direction at point of closest approach (in XY)
const double _yRef
Y of reference point.
const double _yref
Y of reference point.
double _qbyp
Q/P = const !
bool getExpectedPlanePos(const double *, const double, double &, double &, double &, double &, double &) const
Get expected position (and direction) in plane.
void calcGlobal()
Calculate global parameters.
double _sxy
weighted sum(s*z)
void addPoint(double, double, double)
Add point.
const double _xref
X of reference point.
simpleFitZS()
Constructor for simple fit in ZS.
TVectorD _parameters
parameter vector
double _syy
weighted sum(y*y)
const double _yRelCenter
XY circle parameter: Y position of center / R.
void getStateAt(const double, const double, const double, TMatrixDSym &, TVectorD &, TMatrixDSym &)
Get state (parameters, covariance matrix) at point.
TMatrixD simplifiedHelixJacobian(const double, const double) const
Get simplified helix propagator (in constant solenoidal magnetic field)
gear::Vector3D getBFieldc(const double *) const
Get magnetic field (*c).
void getZSDirection(double *) const
Get ZS direction (cosLambda, sinLambda).
double _cosLambda
(local) cos(lambda)
int fit(double &, int &)
Perform fit.
double _sr
weighted sum(r*r)
double _sx
weighted sum(s)
const double _dca
distance of closest approach in (XY)
const double _xRelCenter
XY circle parameter: X position of center / R.
double _sxx
weighted sum(s*s)
TMatrixD curvilinearToPerigeeJacobian() const
Get transformation from curivilinear to perigee track parameters (at reference point) ...
TVectorD _parameters
parameter vector
void addTrack(EVENT::Track const *)
add a complete Track.
localHelix(const double *, const double *, const double)
Constructor.
const bool _curved
flag for curved (circle) track
TMatrixDSym _covariance
covariance matrix
const int _npar
number of track parameters (3: circle, 2: line)
TMatrixD perigeeToILDJacobian() const
Get transformation from perigee to L3/ILD track parameters (at reference point)
const double _xRef
X of reference point.
TVectorD getPar() const
Get parameters vector.
void addPoint(double, double, double)
Add point.
double _sxr
weighted sum(x*r*r)
const double _bzc
Z component of magnetic field (*c)
double _bfac
c * scaling factor (0/1) for magnetic field
TMatrixDSym getCov() const
Get covariance matrix.
const int _npar
number of track parameters (2)
TVectorD _offset
offset of local system
double getArcLengthXY(const double *) const
Get (2D) arc length for given point.
TMatrixDSym _covariance
covariance matrix
TMatrixD helixToLCIOJacobian() const
Get transformation from helix to LCIO track parameters (at reference point)
TVectorD getPar() const
Get parameters vector.
int _numPoints
number of points (hits) used
simpleFitXY(bool, double, double)
Constructor for simple fit in XY.
double _sxy
weighted sum(x*y)
const double _zref
Z of reference point.