Commit in hps-java/src/main/java/org/lcsim/hps/users/phansson on MAIN | |||
AlignmentUtils.java | +320 | -11 | 1.8 -> 1.9 |
Fixed formula for phi. Fixed product rule error for dfx_dR and dfy_dR. Fixed dphi range to be valid in path length calc. Added Numerical ders (five-point, Newton, finite difference) for local ders.
diff -u -r1.8 -r1.9 --- AlignmentUtils.java 23 Oct 2012 01:52:23 -0000 1.8 +++ AlignmentUtils.java 24 Oct 2012 06:45:52 -0000 1.9 @@ -5,8 +5,11 @@
package org.lcsim.hps.users.phansson; import hep.physics.matrix.BasicMatrix;
+import hep.physics.matrix.MatrixOp; +import hep.physics.vec.BasicHep3Vector; +import hep.physics.vec.Hep3Vector; +import hep.physics.vec.VecOp;
import org.lcsim.fit.helicaltrack.HelicalTrackFit;
-import org.lcsim.fit.helicaltrack.HelicalTrackStrip;
import org.lcsim.fit.helicaltrack.HelixUtils; /**
@@ -15,6 +18,8 @@
*/ public class AlignmentUtils {
+ + private boolean _debug;
public AlignmentUtils() { _debug = false;
@@ -25,6 +30,8 @@
public void setDebug(boolean debug) { _debug = debug; }
+ +
public BasicMatrix calculateLocalHelixDerivatives(HelicalTrackFit trk, double xint) { // Calculate the derivative w.r.t. to the track parameters (in order/index):
@@ -76,7 +83,16 @@
}
-
+ private BasicMatrix FillMatrix(double[][] array, int nrow, int ncol) { + BasicMatrix retMat = new BasicMatrix(nrow, ncol); + for (int i = 0; i < nrow; i++) { + for (int j = 0; j < ncol; j++) { + retMat.setElement(i, j, array[i][j]); + } + } + return retMat; + } +
@@ -97,7 +113,7 @@
return (R-d0)*Math.cos(phi0) - R*Math.cos(phi)*dphi_dphi0(x,d0,phi0,R); } public double dx_dR(double x, double xr, double yr, double d0, double phi0, double R, double phi) {
- return Math.sin(phi0) - R*Math.cos(phi)*dphi_dR(x,d0,phi0,R);
+ return Math.sin(phi0) - R*Math.cos(phi)*dphi_dR(x,d0,phi0,R) - Math.sin(phi);
} //-----------------------------------
@@ -119,7 +135,7 @@
return (R-d0)*Math.sin(phi0) - R*Math.sin(phi)*this.dphi_dphi0(x, d0, phi0, R); } public double dy_dR(double x, double d0, double phi0, double R, double phi) {
- return -Math.cos(phi0) - R*Math.sin(phi)*this.dphi_dR(x, d0, phi0, R);
+ return -Math.cos(phi0) - R*Math.sin(phi)*this.dphi_dR(x, d0, phi0, R) + Math.cos(phi);
}
@@ -152,8 +168,8 @@
// Derivatives of phi w.r.t. track parameters public double dphi_dd0(double x,double d0, double phi0, double R) {
- double num = Math.sin(phi0); - double den = R*Math.sqrt(Math.pow(x+(d0-R)*Math.sin(phi0), 2)/Math.pow(R,2));
+ double num = -1*Math.sin(phi0); + double den = R*Math.sqrt( 1 - Math.pow(x+(d0-R)*Math.sin(phi0), 2)/Math.pow(R,2));
return num/den; }
@@ -164,14 +180,14 @@
return 0; } public double dphi_dphi0(double x,double d0, double phi0, double R) {
- double num = (d0-R)*Math.sin(phi0); - double den = R*Math.sqrt(1-Math.pow(x+(d0-R)*Math.sin(phi0),2)/Math.pow(R, 2));
+ double num = -1*(d0-R)*Math.cos(phi0); + double den = R*Math.sqrt( 1 - Math.pow(x+(d0-R)*Math.sin(phi0),2)/Math.pow(R, 2));
return num/den; } public double dphi_dR(double x,double d0, double phi0, double R) {
- double num = -x-d0*Math.sin(phi0); - double den = Math.pow(R, 2)*Math.sqrt(1-Math.pow(x+(d0-R)*Math.sin(phi0),2)/Math.pow(R, 2));
+ double num = x + d0*Math.sin(phi0); + double den = Math.pow(R, 2)*Math.sqrt( 1 - Math.pow(x+(d0-R)*Math.sin(phi0),2)/Math.pow(R, 2));
return num/den; }
@@ -539,9 +555,302 @@
return Math.signum(val); }
+ + + /** + * + * Nested class that contains the numerical derivatives + * Nested class to increase encapsulation and save this for future cross-checks + */ + + + + public class NumDerivatives { + + private double _eps = 1e-9; + private int _type = 0; //0=five point stencil, 1=finite difference, 2=Newton difference quotient + public NumDerivatives() {} + public NumDerivatives(double eps, int type) { + _eps = eps; + _type = type; + } + public void setEpsilon(double eps) { + _eps = eps; + } + public void setType(int type) { + _type = type; + } + public BasicMatrix calculateLocalHelixDerivatives(HelicalTrackFit trk, double xint) { + + double d0 = trk.dca(); + double z0 = trk.z0(); + double R = trk.R(); + double phi0 = trk.phi0(); + double slope = trk.slope(); + double s = HelixUtils.PathToXPlane(trk, xint, 0, 0).get(0); + double phi = -s/R + phi0; + + BasicMatrix dfdq = new BasicMatrix(3,5); //3-dim,ntrackparams + + Hep3Vector df_dd0 = df_dd0(trk, xint, d0, z0, phi0, R, slope); + Hep3Vector df_dz0 = df_dz0(trk, xint, d0, z0, phi0, R, slope); + Hep3Vector df_dslope = df_dslope(trk, xint, d0, z0, phi0, R, slope); + Hep3Vector df_dphi0 = df_dphi0(trk, xint, d0, z0, phi0, R, slope); + Hep3Vector df_dR = df_dR(trk, xint, d0, z0, phi0, R, slope); + + dfdq.setElement(0, 0, df_dd0.x()); + dfdq.setElement(0, 1, df_dz0.x()); + dfdq.setElement(0, 2, df_dslope.x()); + dfdq.setElement(0, 3, df_dphi0.x()); + dfdq.setElement(0, 4, df_dR.x()); + + dfdq.setElement(1, 0, df_dd0.y()); + dfdq.setElement(1, 1, df_dz0.y()); + dfdq.setElement(1, 2, df_dslope.y()); + dfdq.setElement(1, 3, df_dphi0.y()); + dfdq.setElement(1, 4, df_dR.y()); + + dfdq.setElement(2, 0, df_dd0.z()); + dfdq.setElement(2, 1, df_dz0.z()); + dfdq.setElement(2, 2, df_dslope.z()); + dfdq.setElement(2, 3, df_dphi0.z()); + dfdq.setElement(2, 4, df_dR.z()); + + return dfdq; + + } + public Hep3Vector getNumDer(Hep3Vector f2h, Hep3Vector fh, Hep3Vector f, Hep3Vector fmh, Hep3Vector fm2h) { + double[] ders = new double[3]; + for(int i=0;i<3;++i) { + ders[i] = getNumDer(f2h.v()[i], fh.v()[i], f.v()[i], fmh.v()[i], fm2h.v()[i]); + } + return new BasicHep3Vector(ders); + } + public double getNumDer(double f2h, double fh, double f, double fmh, double fm2h) { + double d = 0; + try { + switch (_type) { + case 0: + d = getFivePointStencilValue(f2h, fh, fmh, fm2h); + break; + case 1: + d = this.getFiniteDifference(fh, fmh); + break; + case 2: + d = this.getFiniteDifferenceNewton(fh, f); + break; + default: + throw new RuntimeException(this.getClass().getSimpleName() + ": error wrong numder type " + _type); + } + } catch (RuntimeException e) { + System.out.println("Error " + e); + } + return d; + } + public double getFivePointStencilValue(double f2h, double fh, double fmh, double fm2h) { + return 1/(12*_eps)*(-f2h + 8*fh - 8*fmh + fm2h); + } + public double getFiniteDifference(double fh, double fmh) { + return 1/(2*_eps)*(fh - fmh); + } + public double getFiniteDifferenceNewton(double fh, double f) { + return 1/(_eps)*(fh - f); + } + public double phiHelix(double xint, double d0, double phi0, double R) { + return Math.asin(1/R*((R-d0)*Math.sin(phi0) - xint)); + } + public Hep3Vector pointOnHelix(double xint, double d0, double z0, double phi0, double R, double slope) { + return this.pointOnHelix(null, xint, d0, z0, phi0, R, slope); + } + public Hep3Vector pointOnHelix(HelicalTrackFit trk, double xint, double d0, double z0, double phi0, double R, double slope) { + double phi = phiHelix(xint,d0,phi0,R); + double dphi = phi-phi0; + //Make sure dphi is in the valid range -pi,+pi + if(dphi>Math.PI) dphi -= 2.0*Math.PI; + if(dphi<-Math.PI) dphi += 2.0*Math.PI; + + double xc = (R-d0)*Math.sin(phi0); + double yc = -1*(R-d0)*Math.cos(phi0); + double x = xc - R*Math.sin(phi); + double y = yc + R*Math.cos(phi); + double s = -R*dphi; + double z = z0 + s*slope; + Hep3Vector p = new BasicHep3Vector(x,y,z); + System.out.printf("PointOnHelix s=%.3f dphi=%.3f d0=%.3f R=%.2f phi0=%.3f phi=%.3f (xc=%.3f,yc=%.3f)\n",s,dphi,d0,R,phi0,phi,xc,yc); + if(trk!=null) { + double s_tmp = HelixUtils.PathToXPlane(trk, xint, 0, 0).get(0); + Hep3Vector p_tmp = HelixUtils.PointOnHelix(trk, s_tmp); + Hep3Vector diff = VecOp.sub(p, p_tmp); + System.out.printf(this.getClass().getSimpleName()+": diff=%s p=%s p_tmp=%s\n",diff.toString(),p.toString(),p_tmp.toString()); + } + return p; + } + + public Hep3Vector df_dd0(HelicalTrackFit trk, double xint, double d0, double z0, double phi0, double R, double slope) { + Hep3Vector f = pointOnHelix(trk, xint, d0, z0, phi0, R, slope); + Hep3Vector fh = pointOnHelix(xint, d0+_eps, z0, phi0, R, slope); + Hep3Vector fmh = pointOnHelix(xint, d0-_eps, z0, phi0, R, slope); + Hep3Vector f2h = pointOnHelix(xint, d0+2*_eps, z0, phi0, R, slope); + Hep3Vector fm2h = pointOnHelix(xint, d0-2*_eps, z0, phi0, R, slope); + Hep3Vector df = this.getNumDer(f2h, fh, f, fmh, fm2h); + return df; + } + public Hep3Vector df_dz0(HelicalTrackFit trk, double xint, double d0, double z0, double phi0, double R, double slope) { + Hep3Vector f = pointOnHelix( trk, xint, d0, z0, phi0, R, slope); + Hep3Vector fh = pointOnHelix(xint, d0, z0+_eps, phi0, R, slope); + Hep3Vector fmh = pointOnHelix(xint, d0, z0-_eps, phi0, R, slope); + Hep3Vector f2h = pointOnHelix(xint, d0, z0+2*_eps, phi0, R, slope); + Hep3Vector fm2h = pointOnHelix(xint, d0, z0-2*_eps, phi0, R, slope); + Hep3Vector df = this.getNumDer(f2h, fh, f, fmh, fm2h); + return df; + } + public Hep3Vector df_dslope(HelicalTrackFit trk, double xint, double d0, double z0, double phi0, double R, double slope) { + Hep3Vector f = pointOnHelix( trk, xint, d0, z0, phi0, R, slope); + Hep3Vector fh = pointOnHelix(xint, d0, z0, phi0, R, slope+_eps); + Hep3Vector fmh = pointOnHelix(xint, d0, z0, phi0, R, slope-_eps); + Hep3Vector f2h = pointOnHelix(xint, d0, z0, phi0, R, slope+2*_eps); + Hep3Vector fm2h = pointOnHelix(xint, d0, z0, phi0, R, slope-2*_eps); + Hep3Vector df = this.getNumDer(f2h, fh, f, fmh, fm2h); + return df; + } + public Hep3Vector df_dphi0(HelicalTrackFit trk, double xint, double d0, double z0, double phi0, double R, double slope) { + Hep3Vector f = pointOnHelix( trk, xint, d0, z0, phi0, R, slope); + Hep3Vector fh = pointOnHelix(xint, d0, z0, phi0+_eps, R, slope); + Hep3Vector fmh = pointOnHelix(xint, d0, z0, phi0-_eps, R, slope); + Hep3Vector f2h = pointOnHelix(xint, d0, z0, phi0+2*_eps, R, slope); + Hep3Vector fm2h = pointOnHelix(xint, d0, z0, phi0-2*_eps, R, slope); + Hep3Vector df = this.getNumDer(f2h, fh, f, fmh, fm2h); + return df; + } + public Hep3Vector df_dR(HelicalTrackFit trk, double xint, double d0, double z0, double phi0, double R, double slope) { + Hep3Vector f = pointOnHelix( trk, xint, d0, z0, phi0, R, slope); + Hep3Vector fh = pointOnHelix(xint, d0, z0, phi0, R+_eps, slope); + Hep3Vector fmh = pointOnHelix(xint, d0, z0, phi0, R-_eps, slope); + Hep3Vector f2h = pointOnHelix(xint, d0, z0, phi0, R+2*_eps, slope); + Hep3Vector fm2h = pointOnHelix(xint, d0, z0, phi0, R-2*_eps, slope); + Hep3Vector df = this.getNumDer(f2h, fh, f, fmh, fm2h); + return df; + } + + + + + } + + + + + + + + + +
//-------------------------------------------
- private boolean _debug;
+ + + + /** + * + * Nested class to increase encapsulation and save this for future cross-checks + */ + public class OldAlignmentUtils { + public OldAlignmentUtils() {} + public BasicMatrix calculateLocalHelixDerivatives(HelicalTrackFit trk,double xint) { + //get track parameters. + double d0 = trk.dca(); + double z0 = trk.z0(); + double slope = trk.slope(); + double phi0 = trk.phi0(); + double R = trk.R(); + //strip origin is defined in the tracking coordinate system (x=beamline) + double s = HelixUtils.PathToXPlane(trk, xint, 0, 0).get(0); + double phi = -s/R + phi0; + double[][] dfdq = new double[3][5]; + //dx/dq + //these are wrong for X, but for now it doesn't matter + dfdq[0][0] = Math.sin(phi0); + dfdq[0][1] = 0; + dfdq[0][2] = 0; + dfdq[0][3] = d0 * Math.cos(phi0) + R * Math.sin(phi0) - s * Math.cos(phi0); + dfdq[0][4] = (phi - phi0) * Math.cos(phi0); + double[] mydydq = dydq(R, d0, phi0, xint, s); + double[] mydzdq = dzdq(R, d0, phi0, xint, slope, s); + for (int i = 0; i < 5; i++) { + dfdq[1][i] = mydydq[i]; + dfdq[2][i] = mydzdq[i]; + } + + BasicMatrix dfdqGlobal = FillMatrix(dfdq, 3, 5); + return dfdqGlobal; + } + private double[] dydq(double R, double d0, double phi0, double xint, double s) { + double[] dy = new double[5]; + // dy[0] = Math.cos(phi0) + Cot(phi0 - s / R) * Csc(phi0 - s / R) * dsdd0(R, d0, phi0, xint); + dy[0] = Math.cos(phi0) - Sec(phi0 - s / R) * Math.tan(phi0 - s / R) * dsdd0(R, d0, phi0, xint); + dy[1] = 0; + dy[2] = 0; + // dy[3] = (-(d0 - R)) * Math.sin(phi0) - R * Cot(phi0 - s / R) * Csc(phi0 - s / R) * (1 - dsdphi(R, d0, phi0, xint) / R); + dy[3] = (-(d0 - R)) * Math.sin(phi0) + Sec(phi0 - s / R) * Math.tan(phi0 - s / R) * (R - dsdphi(R, d0, phi0, xint)); + // dy[4] = -Math.cos(phi0) + Csc(phi0 - s / R) - R * Cot(phi0 - s / R) * Csc(phi0 - s / R) * (s / (R * R) - dsdR(R, d0, phi0, xint) / R); + dy[4] = -Math.cos(phi0) + Sec(phi0 - s / R) + (1 / R) * Sec(phi0 - s / R) * Math.tan(phi0 - s / R) * (s - R * dsdR(R, d0, phi0, xint)); + return dy; + } + private double[] dzdq(double R, double d0, double phi0, double xint, double slope, double s) { + double[] dz = new double[5]; + dz[0] = slope * dsdd0(R, d0, phi0, xint); + dz[1] = 1; + dz[2] = s; + dz[3] = slope * dsdphi(R, d0, phi0, xint); + dz[4] = slope * dsdR(R, d0, phi0, xint); + return dz; + } + + private double dsdphi(double R, double d0, double phi0, double xint) { + double sqrtTerm = Math.sqrt(R * R - Math.pow(((d0 - R) * Math.sin(phi0) + xint), 2)); + double rsign = Math.signum(R); + double dsdphi = R * (sqrtTerm + rsign * d0 * Math.cos(phi0) - rsign * R * Math.cos(phi0)) / sqrtTerm; + // if (_DEBUG) + // System.out.println("xint = " + xint + "; dsdphi = " + dsdphi); + return dsdphi; + } + + private double dsdd0(double R, double d0, double phi0, double xint) { + double sqrtTerm = Math.sqrt(R * R - Math.pow(((d0 - R) * Math.sin(phi0) + xint), 2)); + double rsign = Math.signum(R); + double dsdd0 = rsign * (R * Math.sin(phi0)) / sqrtTerm; + // if (_DEBUG) + // System.out.println("xint = " + xint + "; dsdd0 = " + dsdd0); + return dsdd0; + } + + private double dsdR(double R, double d0, double phi0, double xint) { + double sqrtTerm = Math.sqrt(R * R - Math.pow(((d0 - R) * Math.sin(phi0) + xint), 2)); + + double rsign = Math.signum(R); + double dsdr = (1 / sqrtTerm) * ((-rsign * xint) + (-rsign) * d0 * Math.sin(phi0) + + Math.atan2(R * Math.cos(phi0), (-R) * Math.sin(phi0)) + * sqrtTerm + - Math.atan2(rsign * sqrtTerm, xint + (d0 - R) * Math.sin(phi0)) + * sqrtTerm); + + + // if (_DEBUG) + // System.out.println("xint = " + xint + "; dsdr = " + dsdr); + return dsdr;
+ } + + private double Sec(double val) { + return 1 / Math.cos(val); + } + + + + } + + +
}
Use REPLY-ALL to reply to list
To unsubscribe from the LCD-CVS list, click the following link:
https://listserv.slac.stanford.edu/cgi-bin/wa?SUBED1=LCD-CVS&A=1