Print

Print


Commit in trf/src/main/java/org/lcsim/recon/tracking/trfzp on MAIN
PropZZRK.java+751added 1.1
Runge-Kutta Propagator

trf/src/main/java/org/lcsim/recon/tracking/trfzp
PropZZRK.java added at 1.1
diff -N PropZZRK.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ PropZZRK.java	28 Aug 2013 22:27:04 -0000	1.1
@@ -0,0 +1,751 @@
+package org.lcsim.recon.tracking.trfzp;
+
+import org.lcsim.recon.tracking.magfield.AbstractMagneticField;
+import org.lcsim.recon.tracking.trfbase.*;
+
+import static java.lang.Math.sqrt;
+import static java.lang.Math.abs;
+import static java.lang.Math.max;
+import static java.lang.Math.pow;
+import org.lcsim.recon.tracking.spacegeom.CartesianPoint;
+import org.lcsim.recon.tracking.spacegeom.SpacePointTensor;
+import org.lcsim.recon.tracking.spacegeom.SpacePointVector;
+import org.lcsim.recon.tracking.trfutil.Assert;
+import org.lcsim.recon.tracking.trfutil.TRFMath;
+
+/**
+ *
+ * @author Norman A Graf
+ *
+ * @version $Id:
+ */
+public class PropZZRK extends PropDirected
+{
+
+    private AbstractMagneticField _bfield;
+    // Assign track parameter indices.
+    private static final int IX = SurfZPlane.IX;
+    private static final int IY = SurfZPlane.IY;
+    private static final int IDXDZ = SurfZPlane.IDXDZ;
+    private static final int IDYDZ = SurfZPlane.IDYDZ;
+    private static final int IQP = SurfZPlane.IQP;
+    private double _precision;
+    private double _derivprec;
+
+    public PropZZRK(AbstractMagneticField bfield, double precision, double derivprecision)
+    {
+        _bfield = bfield;
+        _precision = precision;
+        _derivprec = derivprecision;
+        assert (_precision > 0. && _precision <= 0.01);
+        assert (_derivprec > 0. && _derivprec <= 0.1);
+    }
+    
+    public PropZZRK(AbstractMagneticField bfield)
+    {
+        _precision = 1.e-7;
+        _derivprec = 1.e-7;
+        _bfield = bfield;
+    }
+
+    @Override
+    public Propagator newPropagator()
+    {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    // Equations of motion in terms of track parameters x, y, dxdz, dydz,
+    // curvature (q/p), and path length and the magnetic field.
+    double[] motion(double[] par, double z, double crv, double sign_dz,
+                    AbstractMagneticField bfield)
+    {
+
+        double[] result = new double[par.length];
+        boolean deriv = par.length > 5;
+
+        // Extract track parameters.
+
+        double x = par[0];
+        double y = par[1];
+        double xv = par[2];
+        double yv = par[3];
+        double s = par[4];
+
+        // Declare derivative matrix.
+
+        double dxdx0 = 0.;
+        double dxdy0 = 0.;
+        double dxdxv0 = 0.;
+        double dxdyv0 = 0.;
+        double dxdcrv = 0.;
+
+        double dydx0 = 0.;
+        double dydy0 = 0.;
+        double dydxv0 = 0.;
+        double dydyv0 = 0.;
+        double dydcrv = 0.;
+
+        double dxvdx0 = 0.;
+        double dxvdy0 = 0.;
+        double dxvdxv0 = 0.;
+        double dxvdyv0 = 0.;
+        double dxvdcrv = 0.;
+
+        double dyvdx0 = 0.;
+        double dyvdy0 = 0.;
+        double dyvdxv0 = 0.;
+        double dyvdyv0 = 0.;
+        double dyvdcrv = 0.;
+
+        if (deriv) {
+
+            // Extract derivative matrix.
+
+            dxdx0 = par[5];
+            dxdy0 = par[6];
+            dxdxv0 = par[7];
+            dxdyv0 = par[8];
+            dxdcrv = par[9];
+
+            dydx0 = par[10];
+            dydy0 = par[11];
+            dydxv0 = par[12];
+            dydyv0 = par[13];
+            dydcrv = par[14];
+
+            dxvdx0 = par[15];
+            dxvdy0 = par[16];
+            dxvdxv0 = par[17];
+            dxvdyv0 = par[18];
+            dxvdcrv = par[19];
+
+            dyvdx0 = par[20];
+            dyvdy0 = par[21];
+            dyvdxv0 = par[22];
+            dyvdyv0 = par[23];
+            dyvdcrv = par[24];
+        }
+        double dmax = 1.e30;
+        if (!(xv < dmax && xv > -dmax)) {
+            throw new RuntimeException("Floating point exception");
+        }
+        if (!(yv < dmax && yv > -dmax)) {
+            throw new RuntimeException("Floating point exception");
+        }
+        double dsdz2 = 1. + xv * xv + yv * yv;
+        double dsdz = sign_dz * sqrt(dsdz2);
+
+        // Get Cartesian components of magnetic field & derivatives.
+
+        double bx = 0.;
+        double by = 0.;
+        double bz = 0.;
+        double dbxdx = 0.;
+        double dbxdy = 0.;
+        double dbydx = 0.;
+        double dbydy = 0.;
+        double dbzdx = 0.;
+        double dbzdy = 0.;
+        SpacePointVector bf;
+        if (deriv) {
+            SpacePointTensor t = new SpacePointTensor();
+            bf = bfield.field(new CartesianPoint(x, y, z), t);
+            dbxdx = t.t_x_x();
+            dbxdy = t.t_x_y();
+            dbydx = t.t_y_x();
+            dbydy = t.t_y_y();
+            dbzdx = t.t_z_x();
+            dbzdy = t.t_z_y();
+        } else {
+            bf = bfield.field(new CartesianPoint(x, y, z));
+        }
+        bx = bf.v_x();
+        by = bf.v_y();
+        bz = bf.v_z();
+
+        // dx/dz.
+
+        result[0] = xv;
+
+        // dy/dz.
+
+        result[1] = yv;
+
+        // dxv/dz.
+
+        double dxvdz_nocrv = TRFMath.BFAC * dsdz * (xv * yv * bx - (1. + xv * xv) * by + yv * bz);
+        result[2] = dxvdz_nocrv * crv;
+
+        // dyv/dz.
+
+        double dyvdz_nocrv = TRFMath.BFAC * dsdz * ((1. + yv * yv) * bx - xv * yv * by - xv * bz);
+        result[3] = dyvdz_nocrv * crv;
+
+        // ds/dz.
+
+        result[4] = dsdz;
+
+        if (deriv) {
+
+            // d(dx/d x0)/dz.
+
+            result[5] = dxvdx0;
+
+            // d(dx/d y0)/dz.
+
+            result[6] = dxvdy0;
+
+            // d(dx/d xv0)/dz.
+
+            result[7] = dxvdxv0;
+
+            // d(dx/d yv0)/dz.
+
+            result[8] = dxvdyv0;
+
+            // d(dx/d crv)/dz.
+
+            result[9] = dxvdcrv;
+
+            // d(dy/d x0)/dz.
+
+            result[10] = dyvdx0;
+
+            // d(dy/d y0)/dz.
+
+            result[11] = dyvdy0;
+
+            // d(dy/d xv0)/dz.
+
+            result[12] = dyvdxv0;
+
+            // d(dy/d yv0)/dz.
+
+            result[13] = dyvdyv0;
+
+            // d(dy/d crv)/dz.
+
+            result[14] = dyvdcrv;
+
+            // d(d xv/d x0)/dz.
+
+            result[15] = result[2] * (xv * dxvdx0 + yv * dyvdx0) / dsdz2
+                    + TRFMath.BFAC * crv * dsdz
+                    * (dxvdx0 * yv * bx + xv * dyvdx0 * bx + xv * yv * (dbxdx * dxdx0 + dbxdy * dydx0)
+                    - 2. * xv * dxvdx0 * by - (1. + xv * xv) * (dbydx * dxdx0 + dbydy * dydx0)
+                    + dyvdx0 * bz + yv * (dbzdx * dxdx0 + dbzdy * dydx0));
+
+            // d(d xv/d y0)/dz.
+
+            result[16] = result[2] * (xv * dxvdy0 + yv * dyvdy0) / dsdz2
+                    + TRFMath.BFAC * crv * dsdz
+                    * (dxvdy0 * yv * bx + xv * dyvdy0 * bx + xv * yv * (dbxdx * dxdy0 + dbxdy * dydy0)
+                    - 2. * xv * dxvdy0 * by - (1. + xv * xv) * (dbydx * dxdy0 + dbydy * dydy0)
+                    + dyvdy0 * bz + yv * (dbzdx * dxdy0 + dbzdy * dydy0));
+
+            // d(d xv/d xv0)/dz.
+
+            result[17] = result[2] * (xv * dxvdxv0 + yv * dyvdxv0) / dsdz2
+                    + TRFMath.BFAC * crv * dsdz
+                    * (dxvdxv0 * yv * bx + xv * dyvdxv0 * bx + xv * yv * (dbxdx * dxdxv0 + dbxdy * dydxv0)
+                    - 2. * xv * dxvdxv0 * by - (1. + xv * xv) * (dbydx * dxdxv0 + dbydy * dydxv0)
+                    + dyvdxv0 * bz + yv * (dbzdx * dxdxv0 + dbzdy * dydxv0));
+
+            // d(d xv/d yv0)/dz.
+
+            result[18] = result[2] * (xv * dxvdyv0 + yv * dyvdyv0) / dsdz2
+                    + TRFMath.BFAC * crv * dsdz
+                    * (dxvdyv0 * yv * bx + xv * dyvdyv0 * bx + xv * yv * (dbxdx * dxdyv0 + dbxdy * dydyv0)
+                    - 2. * xv * dxvdyv0 * by - (1. + xv * xv) * (dbydx * dxdyv0 + dbydy * dydyv0)
+                    + dyvdyv0 * bz + yv * (dbzdx * dxdyv0 + dbzdy * dydyv0));
+
+            // d(d xv/d crv)/dz.
+
+            result[19] = dxvdz_nocrv * (1. + crv * (xv * dxvdcrv + yv * dyvdcrv) / dsdz2)
+                    + TRFMath.BFAC * crv * dsdz
+                    * (dxvdcrv * yv * bx + xv * dyvdcrv * bx + xv * yv * (dbxdx * dxdcrv + dbxdy * dydcrv)
+                    - 2. * xv * dxvdcrv * by - (1. + xv * xv) * (dbydx * dxdcrv + dbydy * dydcrv)
+                    + dyvdcrv * bz + yv * (dbzdx * dxdcrv + dbzdy * dydcrv));
+
+
+            // d(d yv/d x0)/dr
+
+            result[20] = result[3] * (xv * dxvdx0 + yv * dyvdx0) / dsdz2
+                    + TRFMath.BFAC * crv * dsdz
+                    * (2. * yv * dyvdx0 * bx + (1. + yv * yv) * (dbxdx * dxdx0 + dbxdy * dydx0)
+                    - dxvdx0 * yv * by - xv * dyvdx0 * by - xv * yv * (dbydx * dxdx0 + dbydy * dydx0)
+                    - dxvdx0 * bz - xv * (dbzdx * dxdx0 + dbzdy * dydx0));
+
+            // d(d yv/d y0)/dr
+
+            result[21] = result[3] * (xv * dxvdy0 + yv * dyvdy0) / dsdz2
+                    + TRFMath.BFAC * crv * dsdz
+                    * (2. * yv * dyvdy0 * bx + (1. + yv * yv) * (dbxdx * dxdy0 + dbxdy * dydy0)
+                    - dxvdy0 * yv * by - xv * dyvdy0 * by - xv * yv * (dbydx * dxdy0 + dbydy * dydy0)
+                    - dxvdy0 * bz - xv * (dbzdx * dxdy0 + dbzdy * dydy0));
+
+            // d(d yv/d xv0)/dr
+
+            result[22] = result[3] * (xv * dxvdxv0 + yv * dyvdxv0) / dsdz2
+                    + TRFMath.BFAC * crv * dsdz
+                    * (2. * yv * dyvdxv0 * bx + (1. + yv * yv) * (dbxdx * dxdxv0 + dbxdy * dydxv0)
+                    - dxvdxv0 * yv * by - xv * dyvdxv0 * by - xv * yv * (dbydx * dxdxv0 + dbydy * dydxv0)
+                    - dxvdxv0 * bz - xv * (dbzdx * dxdxv0 + dbzdy * dydxv0));
+
+            // d(d yv/d yv0/dr
+
+            result[23] = result[3] * (xv * dxvdyv0 + yv * dyvdyv0) / dsdz2
+                    + TRFMath.BFAC * crv * dsdz
+                    * (2. * yv * dyvdyv0 * bx + (1. + yv * yv) * (dbxdx * dxdyv0 + dbxdy * dydyv0)
+                    - dxvdyv0 * yv * by - xv * dyvdyv0 * by - xv * yv * (dbydx * dxdyv0 + dbydy * dydyv0)
+                    - dxvdyv0 * bz - xv * (dbzdx * dxdyv0 + dbzdy * dydyv0));
+
+            // d(d yv/d crv)/dr
+
+            result[24] = dyvdz_nocrv * (1. + crv * (xv * dxvdcrv + yv * dyvdcrv) / dsdz2)
+                    + TRFMath.BFAC * crv * dsdz
+                    * (2. * yv * dyvdcrv * bx + (1. + yv * yv) * (dbxdx * dxdcrv + dbxdy * dydcrv)
+                    - dxvdcrv * yv * by - xv * dyvdcrv * by - xv * yv * (dbydx * dxdcrv + dbydy * dydcrv)
+                    - dxvdcrv * bz - xv * (dbzdx * dxdcrv + dbzdy * dydcrv));
+        }
+        return result;
+    }
+
+    // Function to evolve track paramters using a single fourth order 
+    // Runge-Kutta step from z1 to z2.
+    void rk4(double[] par, double[] z, double h, double crv, double sign_dz,
+             AbstractMagneticField bfield, double[] k1, boolean reuse)
+    {
+        int size = par.length;
+        double[] k2 = new double[size];
+        double[] k3 = new double[size];
+        double[] k4 = new double[size];
+        if (!reuse) //    k1 = h * motion(par, z[0], crv, sign_dz, bfield);
+        //    k2 = h * motion(par + 0.5*k1, z + 0.5*h, crv, sign_dz, bfield);
+        //    k3 = h * motion(par + 0.5*k2, z + 0.5*h, crv, sign_dz, bfield);
+        //    k4 = h * motion(par + k3, z + h, crv, sign_dz, bfield);
+        {
+            scale(motion(par, z[0], crv, sign_dz, bfield), h, k1);
+        }
+        scale(motion(add(par, 0.5, k1), z[0] + 0.5 * h, crv, sign_dz, bfield), h, k2);
+        scale(motion(add(par, 0.5, k2), z[0] + 0.5 * h, crv, sign_dz, bfield), h, k3);
+        scale(motion(add(par, 1.0, k3), z[0] + h, crv, sign_dz, bfield), h, k4);
+//        par += (1. / 6.) * (k1 + 2. * k2 + 2. * k3 + k4);
+        sum(k1, k2, k3, k4, par);
+        z[0] += h;
+        double dmax = 1.e30;
+        for (int i = 0; i < par.length; ++i) {
+            double x = par[i];
+            if (!(x < dmax && x > -dmax)) {
+                throw new RuntimeException("Floating point exception");
+            }
+        }
+    }
+
+    // Function to calculate the relative difference between two sets
+    // of track parameters.  The result is scaled so that a difference
+    // of less than one is "good."
+    double pardiff(double[] par1, double[] par2,
+                   double derivscale)
+    {
+        int n = par1.length;
+        assert (par2.length == n);
+        double epsmax = 0.;
+        for (int i = 0; i < n; ++i) {
+            double p1 = par1[i];
+            double p2 = par2[i];
+            double eps = abs(p2 - p1) / max(max(abs(p1), abs(p2)), 10.);
+            if (i >= 5) {
+                eps *= derivscale;
+            }
+            if (eps > epsmax) {
+                epsmax = eps;
+            }
+        }
+        return epsmax;
+    }
+
+    // Function to evolve track parameters using fourth order Runge-Kutta
+    // with a variable step size.  The starting step size is as specified,
+    // which may be reduced until the error is estimated to be small enough.
+    // The z coordinate is updated to reflect the actual step size.  The 
+    // estimated next step size is returned as the value of the function.
+    double rkv(double[] par, double[] z, double h, double crv, double sign_dz,
+               AbstractMagneticField bfield, double precision,
+               double derivprec)
+    {
+
+        double derivscale = precision / derivprec;
+
+        // Calculate the minimum allowed step, which is the lesser of 
+        // either 1 cm or the initial step.
+
+        double hmin = abs(h) / h;
+        if (abs(hmin) > abs(h)) {
+            hmin = h;
+        }
+        double hnext = h;
+        for (;;) {
+
+            // Reduce the target precision for short steps to control the 
+            // accumulation of roundoff error.
+
+            double maxdiff = precision * sqrt(0.1 * abs(h));
+            double[] par1 = new double[par.length];
+            System.arraycopy(par,0,par1,0,par.length);
+            double[] par2 = new double[par.length];
+            System.arraycopy(par,0,par2,0,par.length);;
+            
+
+            // Try step using h.
+
+            double[] z1 = new double[1];
+            z1[0] = z[0];
+            double[] k1 = new double[par.length];
+            rk4(par1, z1, h, crv, sign_dz, bfield, k1, false);
+
+            // In short hop situations, quit here.
+
+            if (abs(hmin) <= 0.01) {
+                System.arraycopy(par1, 0, par, 0, par1.length);
+                z[0] = z1[0];
+                break;
+            }
+
+            // Try two steps using hh.
+
+            double[] z2 = new double[1];
+            z2[0] = z[0];
+            double hh = 0.5 * h;
+//      k1 = 0.5 * k1;
+            for (int i = 0; i < k1.length; ++i) {
+                k1[i] = 0.5 * k1[i];
+            }
+            rk4(par2, z2, hh, crv, sign_dz, bfield, k1, true);
+            rk4(par2, z2, hh, crv, sign_dz, bfield, k1, false);
+
+            // Calculate difference and get the next step size.
+
+            double eps = pardiff(par1, par2, derivscale);
+            if (eps <= maxdiff || abs(h) <= abs(hmin)) {
+
+                // Check for catastrophic loss of accuracy.
+
+                //	if(eps > 100000.*maxdiff)
+                //	  throw new RuntimeException("Catastrophic loss of accuracy");
+
+                // Current step is accurate enough.  Adjust the step size.
+                // and return current propagation.
+
+                if (eps != 0) {
+                    hnext = 0.8 * h * pow(maxdiff / eps, 0.25);
+                    if (abs(hnext) > 4. * abs(h)) {
+                        hnext = 4. * h;
+                    }
+                } else {
+                    hnext = 4. * h;
+                }
+//                par = (16. / 15.) * par2 - (1. / 15.) * par1;
+                subtract(par, par2, par1);
+                z[0] = z1[0];
+                break;
+            } else {
+
+                // Not accurate enough.  Shrink the step size and try again.
+                // Don't let the step get too small.
+
+                hnext = 0.8 * h * pow(maxdiff / eps, 0.25);
+                if (abs(hnext) < abs(hmin)) {
+                    hnext = hmin;
+                }
+                h = hnext;
+            }
+        }
+
+        // Final check on minimum step size.
+
+        if (abs(hnext) < abs(hmin)) {
+            hnext = hmin;
+        }
+        return hnext;
+    }
+//
+    // This routine uses adaptive step size control to make the specified
+    // step using one or several steps.
+
+    void rka(double[] par, double[] z, double h, double crv, double sign_dz,
+             AbstractMagneticField bfield, double precision,
+             double derivprec)
+    {
+        assert (h != 0);
+        double htry = h;
+        double hnext;
+        double z2 = z[0] + h;
+        while (h > 0 && z[0] < z2 || h < 0 && z[0] > z2) {
+            double hmax = abs(z2 - z[0]);
+            if (abs(htry) > hmax) {
+                htry = z2 - z[0];
+            }
+            hnext = rkv(par, z, htry, crv, sign_dz, bfield, precision, derivprec);
+            assert (hnext * htry > 0);
+            assert (z[0] + hnext != z[0]);
+            htry = hnext;
+        }
+    }
+
+// 
+    private void scale(double[] a, double s, double[] b)
+    {
+        for (int i = 0; i < a.length; i++) {
+            b[i] = a[i] * s;
+        }
+    }
+
+    private double[] add(double[] a, double s, double[] b)
+    {
+        double[] f = new double[a.length];
+        for (int i = 0; i < a.length; i++) {
+            f[i] = a[i] + s * b[i];
+        }
+        return f;
+    }
+
+    private void sum(double[] k1, double[] k2, double[] k3, double[] k4, double[] p)
+    {
+        for (int i = 0; i < p.length; ++i) {
+            p[i] += (1. / 6.) * (k1[i] + 2. * k2[i] + 2. * k3[i] + k4[i]);
+        }
+    }
+
+    private void subtract(double[] par, double[] par2, double[] par1)
+    {
+        for (int i = 0; i < par.length; ++i) {
+            par[i] = (16. / 15.) * par2[i] - (1. / 15.) * par1[i];
+        }
+    }
+
+// Propagator interface here
+// Propagate a track without error in the specified direction.
+//
+// The track parameters for a z-plane are:
+// x y dx/dz dy/dz curvature=q/p
+//
+// If pder is nonzero, return the derivative matrix there.
+    public PropStat vecDirProp(VTrack trv, Surface srf, PropDir dir,
+                               TrackDerivative deriv)
+    {
+
+        // construct return status
+        PropStat pstat = new PropStat();
+
+        // fetch the originating surface.
+        Surface srf1 = trv.surface();
+
+        // Check origin is a z plane.
+        Assert.assertTrue(srf1.pureType().equals(SurfZPlane.staticType()));
+        if (!srf1.pureType().equals(SurfZPlane.staticType())) {
+            return pstat;
+        }
+
+        SurfZPlane sz1 = (SurfZPlane) srf1;
+
+        // Check destination is a z plane.
+        Assert.assertTrue(srf.pureType().equals(SurfZPlane.staticType()));
+        if (!srf.pureType().equals(SurfZPlane.staticType())) {
+            return pstat;
+        }
+        SurfZPlane sz2 = (SurfZPlane) srf;
+
+        // Separate the move status from the direction.
+        PropDir rdir = dir; // need to check constness
+        boolean move = Propagator.reduceDirection(rdir);
+
+        // This flag indicates the new surface is only a short hop away.
+        boolean short_hop = false;
+
+        // If surfaces are the same and move is not set, then we leave the
+        // track where it is.
+        if (srf.pureEqual(srf1) && !move) {
+            if (deriv != null) {
+                deriv.setIdentity();
+            }
+            pstat.setSame();
+            return pstat;
+        }
+
+        // Fetch the z coordinates.
+        int iz = SurfZPlane.ZPOS;
+        double z1 = sz1.parameter(iz);
+        double z2 = sz2.parameter(iz);
+
+        // Fetch the starting track vector.
+        TrackVector vec = trv.vector();
+        double x1 = vec.get(IX);                   // x
+        double y1 = vec.get(IY);                   // y
+        double xv1 = vec.get(IDXDZ);               // dx/dz
+        double yv1 = vec.get(IDYDZ);               // dy/dz
+        double crv = vec.get(IQP);                 // q/p
+        double sign_dz = 0.;
+        if (trv.isForward()) {
+            sign_dz = 1.;
+        } else if (trv.isBackward()) {
+            sign_dz = -1.;
+        }
+        if (sign_dz == 0.) {
+            return pstat;
+        }
+
+        // Check the consistency of the initial and final z positions, the track 
+        // direction and the propagation direction.  Four of the eight possible
+        // forward/backward combinations are illegal.  
+
+        if (z2 == z1) {
+            if (move) {
+                System.out.println("PropZZRK: Invalid move");
+                return pstat;
+            }
+        } else if (z2 > z1) {
+            if (rdir == PropDir.FORWARD && trv.isBackward()
+                    || rdir == PropDir.BACKWARD && trv.isForward()) {
+                System.out.println("PropZZRK: Wrong direction");
+                return pstat;
+            }
+        } else {  // z2 < z1
+            if (rdir == PropDir.FORWARD && trv.isForward()
+                    || rdir == PropDir.BACKWARD && trv.isBackward()) {
+                System.out.println("PropZZRK: Wrong direction");
+                return pstat;
+            }
+        }
+
+        // We have all non-trivial mathematical operations in a try block
+        // so we can catch floating point exceptions.
+
+        {
+
+            // Fill initial parameter vector.
+
+            int size = 5;
+            if (deriv != null) {
+                size = 25;
+            }
+            double[] par = new double[size];
+            par[0] = x1;       // x
+            par[1] = y1;       // y
+            par[2] = xv1;      // dx/dz
+            par[3] = yv1;      // dy/dz
+            par[4] = 0.;       // Path length.
+            if (deriv != null) {
+                par[5] = 1.;     // d x / d x0
+                par[11] = 1.;    // d y / d y0
+                par[17] = 1.;    // d xv / d xv0
+                par[23] = 1.;    // d yv / d yv0
+            }
+
+            // Propagate parameter vector.
+
+            double[] z = new double[1];
+            z[0] = z1;
+            double h = z2 - z1;
+            if (abs(h) < 1.e-10) {
+                z[0] = z2;
+            } else {
+                rka(par, z, h, crv, sign_dz, _bfield, _precision, _derivprec);
+            }
+
+            // Calculate final parameters and put them back into vec.
+
+            double dmax = 1.e30;
+            double x2 = par[0];
+            double y2 = par[1];
+            double xv2 = par[2];
+            double yv2 = par[3];
+            double s = par[4];
+            vec.set(IX, x2);
+            vec.set(IY, y2);
+            vec.set(IDXDZ, xv2);
+            vec.set(IDYDZ, yv2);
+            vec.set(IQP, crv);
+            if (!(x2 < dmax && x2 > -dmax)) {
+                throw new RuntimeException("Floating point exception");
+            }
+            if (!(y2 < dmax && y2 > -dmax)) {
+                throw new RuntimeException("Floating point exception");
+            }
+            if (!(xv2 < dmax && xv2 > -dmax)) {
+                throw new RuntimeException("Floating point exception");
+            }
+            if (!(yv2 < dmax && yv2 > -dmax)) {
+                throw new RuntimeException("Floating point exception");
+            }
+            if (!(s < dmax && s > -dmax)) {
+                throw new RuntimeException("Floating point exception");
+            }
+            if (deriv != null) {
+
+                // Calculate final derivative matrix.
+
+
+                deriv.set(0, 0, par[5]);                // dx / d x0
+                deriv.set(0, 1, par[6]);                // dx / d y0
+                deriv.set(0, 2, par[7]);                // dx / d xv0
+                deriv.set(0, 3, par[8]);                // dx / d yv0
+                deriv.set(0, 4, par[9]);                // dx / d crv
+                deriv.set(1, 0, par[10]);               // dy / d x0
+                deriv.set(1, 1, par[11]);               // dy / d y0
+                deriv.set(1, 2, par[12]);               // dy / d xv0
+                deriv.set(1, 3, par[13]);               // dy / d yv0
+                deriv.set(1, 4, par[14]);               // dy / d crv
+                deriv.set(2, 0, par[15]);               // d xv / d x0
+                deriv.set(2, 1, par[16]);               // d xv / d y0
+                deriv.set(2, 2, par[17]);               // d xv / d xv0
+                deriv.set(2, 3, par[18]);               // d xv / d yv0
+                deriv.set(2, 4, par[19]);               // d xv / d crv
+                deriv.set(3, 0, par[20]);               // d yv / d x0
+                deriv.set(3, 1, par[21]);               // d yv / d y0
+                deriv.set(3, 2, par[22]);               // d yv / d xv0
+                deriv.set(3, 3, par[23]);               // d yv / d yv0
+                deriv.set(3, 4, par[24]);               // d yv / d crv
+                deriv.set(4, 0, 0.);                    // d crv / d x0
+                deriv.set(4, 1, 0.);                    // d crv / d y0
+                deriv.set(4, 2, 0.);                    // d crv / d xv0
+                deriv.set(4, 3, 0.);                    // d crv / d yv0
+                deriv.set(4, 4, 1.);                    // d crv / d crv
+                for (int i = 0; i < 4; ++i) {
+                    for (int j = 0; j < 5; ++j) {
+                        double x = deriv.get(i, j);
+                        if (!(x < dmax && x > -dmax)) {
+                            throw new RuntimeException("Floating point exception");
+                        }
+                    }
+                }
+            }
+
+            // Update trv
+            boolean forward = trv.isForward();
+            boolean backward = trv.isBackward();
+            assert (forward || backward);
+            assert (!(forward && backward));
+            trv.setSurface(srf.newPureSurface());
+            trv.setVector(vec);
+            if (forward) {
+                trv.setForward();
+            } else if (backward) {
+                trv.setBackward();
+            }
+
+            // Set the return status.
+            pstat.setPathDistance(s);
+        }
+        return pstat;
+    }
+    
+    public String toString()
+    {
+        StringBuffer sb = new StringBuffer( "Z Plane RK propagation with magnetic field: \n");
+         sb.append(" "+_bfield+"\n");
+	 sb.append(" precision = " + _precision);
+	 sb.append(", derivprec = " + _derivprec+"\n");
+         return sb.toString();
+    }
+}
CVSspam 0.2.12


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