22 added files
lcsim/src/org/lcsim/contrib/onoprien/util/swim
diff -N AbstractIntersection.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ AbstractIntersection.java 5 Nov 2008 03:32:51 -0000 1.1
@@ -0,0 +1,63 @@
+package org.lcsim.contrib.onoprien.util.swim;
+
+import hep.physics.vec.Hep3Vector;
+import org.lcsim.units.clhep.SystemOfUnits;
+
+/**
+ * Abstract class that provides a skeletal implementation of the {@link Intersection}
+ * interface to minimize the effort required to implement this interface.
+ *
+ * @author D. Onoprienko
+ * @version $Id: AbstractIntersection.java,v 1.1 2008/11/05 03:32:51 onoprien Exp $
+ */
+abstract public class AbstractIntersection implements Intersection {
+
+ /**
+ * Precision with which the path length to an intersection is calculated.
+ * <i>Intersections closer to each other than this distance will be merged.
+ * <b>This behavior is currently disabled.</b></i>
+ * Default value: 0.1 micrometer.
+ */
+ public static double pathLengthTolerance = .1 * SystemOfUnits.micrometer;
+
+// -- Constructors : ----------------------------------------------------------
+
+ public AbstractIntersection() {
+ }
+
+ public AbstractIntersection(Trajectory trajectory, Surface surface) {
+ _trajectory = trajectory;
+ _surface = surface;
+ }
+
+// -- Stepping through intersection points : ----------------------------------
+
+ public void stepForward() {
+ step(1);
+ }
+
+ public void stepBack() {
+ step(-1);
+ }
+
+// -- Trajectory parameters at the next intersection point : ------------------
+
+ public Hep3Vector getPoint() {
+ return _trajectory.getPoint(getPathLength());
+ }
+
+ public Hep3Vector getDirection() {
+ return _trajectory.getDirection(getPathLength());
+ }
+
+// -- Access to intersecting objects : ----------------------------------------
+
+ public Trajectory getTrajectory() {return _trajectory;}
+
+ public Surface getSurface() {return _surface;}
+
+// -- Private parts : ---------------------------------------------------------
+
+ protected Trajectory _trajectory;
+ protected Surface _surface;
+}
lcsim/src/org/lcsim/contrib/onoprien/util/swim
diff -N AbstractSurface.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ AbstractSurface.java 5 Nov 2008 03:32:51 -0000 1.1
@@ -0,0 +1,22 @@
+package org.lcsim.contrib.onoprien.util.swim;
+
+/**
+ * Abstract class that provides a skeletal implementation of the {@link Surface}
+ * interface to minimize the effort required to implement this interface.
+ *
+ * @author D. Onoprienko
+ * @version $Id: AbstractSurface.java,v 1.1 2008/11/05 03:32:51 onoprien Exp $
+ */
+abstract public class AbstractSurface implements Surface {
+
+ /**
+ * Default implementation provided by this class throws <tt>UnsupportedOperationException</tt>
+ * with a diagnostic message. Concrete subclasses must override to return intersection
+ * of the specified trajectory with this surface.
+ */
+ public Intersection intersect(Trajectory trajectory) {
+ throw new UnsupportedOperationException("No idea how to find intersection of "
+ + this.getClass().getName() + " with " + trajectory.getClass().getName() + " - please implement");
+ }
+
+}
lcsim/src/org/lcsim/contrib/onoprien/util/swim
diff -N AbstractTrajectory.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ AbstractTrajectory.java 5 Nov 2008 03:32:51 -0000 1.1
@@ -0,0 +1,68 @@
+package org.lcsim.contrib.onoprien.util.swim;
+
+import hep.physics.vec.Hep3Vector;
+
+/**
+ * Abstract class that provides a skeletal implementation of the {@link Trajectory}
+ * interface to minimize the effort required to implement this interface.
+ * <p>
+ * This class also declares a few additional methods (<tt>getLengthToZPlane</tt>,
+ * <tt>getLengthToZCylinder</tt>) that can be implemented by concrete trajectory
+ * classes to facilitate finding intersections with surfaces. Default implementation
+ * provided by this class throws <tt>UnsupportedOperationException</tt>.
+ *
+ * @author D. Onoprienko
+ * @version $Id: AbstractTrajectory.java,v 1.1 2008/11/05 03:32:51 onoprien Exp $
+ */
+abstract public class AbstractTrajectory implements Trajectory {
+
+// -- Implementing Trajectory : -----------------------------------------------
+
+ /**
+ * Returns the position of the origin of the trajectory.
+ * Implemented by forwarding the call to {@link #getPoint(double)} with zero argument.
+ * Concrete subclasses can override.
+ */
+ public Hep3Vector getPoint() {
+ return getPoint(0.);
+ }
+
+ /**
+ * Returns direction unit vector at the origin.
+ * Implemented by forwarding the call to {@link #getDirection(double)} with zero argument.
+ * Concrete subclasses can override.
+ */
+ public Hep3Vector getDirection() {
+ return getDirection(0.);
+ }
+
+ /**
+ * Returns intersection of this trajectory with the specified surface.
+ * Implemented by forwarding the call to {@link Surface#intersect(Surface)}.
+ * Concrete subclasses can override.
+ */
+ public Intersection intersect(Surface surface) {
+ return surface.intersect(this);
+ }
+
+// -- Get trajectory parameters : ---------------------------------------------
+
+ /**
+ * Returns the value of a parameter that describes the shape of this trajectory.
+ * The parameter is identified by enum constant that belongs to a particular representation.
+ */
+ public <T extends Enum<T>> double getParameter(T parameter) {
+ ParVector<T> v = getParameters(parameter.getClass());
+ return v.get(parameter);
+ }
+
+ /**
+ * Returns an element of a covariance matrix of parameters that describe the shape of this trajectory.
+ * The parameter is identified by enum constant that belongs to a particular representation.
+ */
+ public <T extends Enum<T>> double getCovElement(T parameter1, T parameter2) {
+ ParCovMatrix<T> m = getCovMatrix(parameter1.getClass());
+ return m.get(parameter1, parameter2);
+ }
+
+}
lcsim/src/org/lcsim/contrib/onoprien/util/swim
diff -N Helix.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ Helix.java 5 Nov 2008 03:32:51 -0000 1.1
@@ -0,0 +1,344 @@
+package org.lcsim.contrib.onoprien.util.swim;
+
+import java.util.*;
+
+import hep.physics.matrix.SymmetricMatrix;
+import hep.physics.vec.Hep3Vector;
+
+import org.lcsim.contrib.onoprien.util.ConstHep3Vector;
+
+/**
+ * Helical {@link Trajectory} with its axis parallel to Z.
+ *
+ * @author D. Onoprienko
+ * @version $Id: Helix.java,v 1.1 2008/11/05 03:32:51 onoprien Exp $
+ */
+public class Helix extends AbstractTrajectory {
+
+ /**
+ * Emumeration of helix parameters in C-representation.
+ */
+ public enum CRep {
+ /** D0 (signed impact parameter in XY plane). */
+ D0,
+ /** Phi0. */
+ PHI0,
+ /** Omega (signed curvature). */
+ OMEGA,
+ /** Z0. */
+ Z0,
+ /** Tangent of the dip angle. */
+ LAMBDA
+ }
+
+ /**
+ * Emumeration of helix parameters in W-representation.
+ */
+ public enum WRep {
+ /** X of the helix origin. */
+ X,
+ /** Y of the helix origin. */
+ Y,
+ /** Z of the helix origin. */
+ Z,
+ /** X component of the unit vector in the direction of the helix at its origin. */
+ DX,
+ /** Y component of the unit vector in the direction of the helix at its origin. */
+ DY,
+ /** Z component of the unit vector in the direction of the helix at its origin. */
+ DZ,
+ /** Amplitude of the transverse component of the unit vector in the direction of
+ * the helix at its origin, devided by the helix radius. */
+ RO
+ }
+
+// -- Constructors : ----------------------------------------------------------
+
+ public Helix(Hep3Vector origin, Hep3Vector direction, double curvature) {
+
+ if (origin instanceof ConstHep3Vector) {
+ _orig = (ConstHep3Vector) origin;
+ } else {
+ _orig = new ConstHep3Vector(origin);
+ }
+
+ double mag = direction.magnitude();
+ _dir = new ConstHep3Vector(direction.x()/mag, direction.y()/mag, direction.z()/mag);
+
+ _ro = - curvature * Math.hypot(_dir.x(), _dir.y());
+ }
+
+ public Helix(ParVector<CRep> parameters, Hep3Vector referencePoint) {
+ _ref = new ConstHep3Vector(referencePoint);
+ _parC = new ParVector<CRep>(parameters);
+ repCtoW();
+ }
+
+ public Helix(ParVector<WRep> parameters) {
+ _orig = new ConstHep3Vector(parameters.get(WRep.X), parameters.get(WRep.Y), parameters.get(WRep.Z));
+ _dir = new ConstHep3Vector(parameters.get(WRep.DX), parameters.get(WRep.DY), parameters.get(WRep.DZ));
+ _ro = parameters.get(WRep.RO);
+ }
+
+ public Helix(Helix helix) {
+ _orig = helix._orig;
+ _dir = helix._dir;
+ _ro = helix._ro;
+ _ref = helix._ref;
+ }
+
+// -- Get helix parameters : --------------------------------------------------
+
+ /**
+ * Returns helix parameters in the requested representation.
+ *
+ * @param representation Enum class that defines helix parameters representation.
+ * Currently either {@link CRep} or {@link WRep}.
+ */
+ public <T extends Enum<T>> ParVector<T> getParameters(Class<T> representation) {
+ if (CRep.class.isAssignableFrom(representation)) {
+ if (_parC == null) repWtoC();
+ return (ParVector) _parC;
+ } else if (WRep.class.isAssignableFrom(representation)) {
+ return new ParVector<T>(representation, _orig.x(),_orig.y(),_orig.z(),_dir.x(),_dir.y(),_dir.z(),_ro);
+ } else {
+ throw new IllegalArgumentException();
+ }
+ }
+
+ /**
+ * Returns covariance matrix for helix parameters in the requested representation.
+ *
+ * @param representation Enum class that defines helix parameters representation.
+ * Currently either {@link CRep} or {@link WRep}.
+ */
+ public <T extends Enum<T>> ParCovMatrix<T> getCovMatrix(Class<T> representation) {
+ throw new UnsupportedOperationException("Covariance matrix operations are not yet implemented"); // FIXME
+ }
+
+ public double getZPeriod() {
+ return Math.abs(_dir.z()*TWOPI / _ro);
+ }
+
+ public double getLengthPeriod() {
+ return Math.abs(TWOPI / _ro);
+ }
+
+ /**
+ * Returns reference point used to calculate helix parameters in C-representation.
+ */
+ public ConstHep3Vector getReferencePoint() {
+ return (_ref == null) ? _orig : _ref ;
+ }
+
+ /**
+ * Sets the reference point for C-representation of the helix parameters.
+ * Once set by this method, the reference point will not be affected by calls to {@link #swim}.
+ * Calling this method with <tt>null</tt> vector resets the reference point to
+ * the origin of this trajectory, and allows subsequent calls to {@link #swim} to
+ * modify it.
+ */
+ public void setReferencePoint(Hep3Vector referencePoint) {
+ if (referencePoint == null) {
+ _ref = null;
+ } else {
+ _ref = new ConstHep3Vector(referencePoint);
+ }
+ _parC = null;
+ }
+
+// -- Position at the given point : -------------------------------------------
+
+ /**
+ * Returns the position of the origin of the trajectory.
+ */
+ public ConstHep3Vector getPoint() {
+ return _orig;
+ }
+
+ /**
+ * Returns the position at given path length along the trajectory.
+ */
+ public ConstHep3Vector getPoint(double pathLength) {
+ double nx = _dir.x()/_ro;
+ double ny = _dir.y()/_ro;
+ double x, y, z;
+ if (Double.isInfinite(nx) || Double.isInfinite(ny)) {
+ x = _orig.x() + _dir.x() * pathLength;
+ y = _orig.y() + _dir.y() * pathLength;
+ } else {
+ double sin = Math.sin(_ro*pathLength);
+ double cos1 = 1. - Math.cos(_ro*pathLength);
+ x = _orig.x() + nx * sin - ny * cos1;
+ y = _orig.y() + ny * sin + nx * cos1;
+ }
+ z = _orig.z() + _dir.z() * pathLength;
+ return new ConstHep3Vector(x,y,z);
+ }
+
+// -- Direction at the given point : ------------------------------------------
+
+ /**
+ * Returns the direction unit vector at the origin.
+ */
+ public ConstHep3Vector getDirection() {
+ return _dir;
+ }
+
+ /**
+ * Returns the direction unit vector at given path length along the trajectory.
+ */
+ public ConstHep3Vector getDirection(double pathLength) {
+ double sin = Math.sin(_ro*pathLength);
+ double cos = Math.cos(_ro*pathLength);
+ double dx = _dir.x() * cos - _dir.y() * sin;
+ double dy = _dir.y() * cos + _dir.x() * sin;
+ return new ConstHep3Vector(dx, dy, _dir.z());
+ }
+
+// -- Intersections : ---------------------------------------------------------
+
+ public Intersection intersect(Surface surface) {
+ if (surface instanceof Poca) {
+ return intersect((Poca) surface);
+ } else if (surface instanceof PocaXY) {
+ return intersect((PocaXY) surface);
+ } else if (surface instanceof ZPlane) {
+ return intersect((ZPlane) surface);
+ } else if (surface instanceof ZCylinder) {
+ return intersect((ZCylinder) surface);
+ } else {
+ return surface.intersect(this);
+ }
+ }
+
+ public Intersection intersect(Poca poca) {
+ Hep3Vector point = poca.getPoint();
+ double s = 0; // FIXME
+ return new IntersectionSingle(s, this, poca);
+ }
+
+ public Intersection intersect(PocaXY poca) {
+ Hep3Vector point = poca.getPoint();
+ double s = 0; // FIXME
+ return new IntersectionSingle(s, this, poca);
+ }
+
+ public Intersection intersect(ZPlane zPlane) {
+ double s = getLengthToZ(zPlane._z);
+ return (Double.isInfinite(s)) ? new IntersectionNone(this, zPlane) : new IntersectionSingle(s, this, zPlane) ;
+ }
+
+ public Intersection intersect(ZDisk zDisk) {
+ double s = getLengthToZ(zDisk._z);
+ if (Double.isInfinite(s)) return new IntersectionNone(this, zDisk);
+ Hep3Vector pos = getPoint(s);
+ double x = pos.x();
+ double y = pos.y();
+ double r2 = x*x + y*y;
+ return (r2 > zDisk._rMin2 && r2 < zDisk._rMax2) ? new IntersectionSingle(s, this, zDisk) : new IntersectionNone(this, zDisk);
+ }
+
+ public Intersection intersectZCylinder(ZCylinder zCylinder) { // FIXME
+
+ double ro2 = _ro*_ro;
+ double a1 = 1. - _dir.z()*_dir.z() - _ro*(_orig.x()*_dir.y() + _orig.y()*_dir.x());
+ double a2 = _orig.x()*_dir.x() - _orig.y()*_dir.y();
+ double deltaR = _orig.x()*_orig.x() + _orig.y()*_orig.y() - zCylinder._r*zCylinder._r;
+ double a12 = a1*a1 + ro2*a2*a2;
+ double d = 4.*a2*a2 - 4.*deltaR*a1 - ro2*deltaR*deltaR;
+ if (d < 0.) return new IntersectionNone(this, zCylinder);
+ d = Math.sqrt(d);
+
+ double cos1 = 1. - (ro2* (2.*a2*a2 - deltaR*a1 + a2*d) ) / (2.*a12);
+ double cos2 = 1. - (ro2* (2.*a2*a2 - deltaR*a1 - a2*d) ) / (2.*a12);
+
+ double sin1 = (- _ro* (2.*a1*a2 + ro2*deltaR*a2 + a1*d)) / (2.*a12);
+ double sin2 = (- _ro* (2.*a1*a2 + ro2*deltaR*a2 - a1*d)) / (2.*a12);
+
+ double s1 = getLength(sin1, cos1);
+ double s2 = getLength(sin2, cos2);
+
+ double[] s;
+ if (Double.isNaN(s1)) {
+ if (Double.isNaN(s2)) {
+ return new IntersectionNone(this, zCylinder);
+ } else {
+ s = new double[]{s2};
+ }
+ } else {
+ if (Double.isNaN(s2) || s1==s2) {
+ s = new double[]{s1};
+ } else {
+ s = new double[]{s1,s2};
+ }
+ }
+ s1 = getLengthToZ(zCylinder.getMinZ());
+ s2 = getLengthToZ(zCylinder.getMaxZ());
+ return new IntersectionPeriodicBound(false, s1, s2, s, getLengthPeriod(), this, zCylinder);
+ }
+
+// -- Modifying the trajectory : ----------------------------------------------
+
+ /**
+ * Reverse the direction of the trajectory.
+ */
+ public void reverse() {
+ throw new UnsupportedOperationException(); // FIXME
+ }
+
+ /**
+ * Moves the origin by the specified path length along the trajectory.
+ * Returns <tt>null</tt> if an attemt to move the origin by the requested length would place
+ * it beyond the boundary of this trajectory.
+ * Unless the reference point that defines C-representation of helix parameters has
+ * been set explicitly in a constructor or through a call to {@link #setReferencePoint(Hep3Vector)}
+ * method, the new origin also becomes the new reference point.
+ */
+ public boolean swim(double pathLength) {
+ throw new UnsupportedOperationException(); // FIXME
+ }
+
+// -- Helper methods : --------------------------------------------------------
+
+ double getLength(double sin, double cos) {
+ double ros = Math.acos(cos);
+ if (sin < 0.) {
+ ros = - ros;
+ }
+ return ros/_ro;
+ }
+
+ /** Returns path length to Z plane specified by the argument. */
+ double getLengthToZ(double z) {
+ return (z - _orig.z()) / _dir.z();
+ }
+
+ private void repWtoC() {
+ throw new UnsupportedOperationException(); // FIXME
+ }
+
+ private void repCtoW() {
+ throw new UnsupportedOperationException(); // FIXME
+ }
+
+// -- Private parts : ---------------------------------------------------------
+
+ // W-representation :
+
+ ConstHep3Vector _orig;
+ ConstHep3Vector _dir;
+ double _ro;
+ SymmetricMatrix _covW;
+
+ // C-representation :
+
+ ConstHep3Vector _ref; // Ref.point
+ ParVector<CRep> _parC; // D0, Phi0, Omega, Z0, Tan Lambda at XY POCA to ref.point
+ SymmetricMatrix _covC;
+
+ static private final double TWOPI = 2. * Math.PI;
+
+
+
+}
lcsim/src/org/lcsim/contrib/onoprien/util/swim
diff -N Intersection.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ Intersection.java 5 Nov 2008 03:32:51 -0000 1.1
@@ -0,0 +1,72 @@
+package org.lcsim.contrib.onoprien.util.swim;
+
+import java.util.NoSuchElementException;
+
+import hep.physics.vec.Hep3Vector;
+
+/**
+ * An intersection between a trajectory and a surface.
+ * <p>
+ * The intersection consists of zero or more intersection points ordered along the
+ * trajectory direction, and the <tt>Intersection</tt>
+ * object provides a way to iterate over them. Each instance of this class has a cursor
+ * that is always positioned between two intersection points. In an <tt>Intersection</tt>
+ * consisting of <tt>n</tt> points, there are <tt>n+1</tt> valid cursor positions corresponding
+ * to <tt>n+1</tt> gaps between points, including the gap before the first point and the gap
+ * after the last point. The cursor can be moved by calling <tt>step(int)</tt>,
+ * <tt>stepForward()</tt>, and <tt>stepBack()</tt> methods. <tt>hasPrevious()</tt> and
+ * <tt>hasNext()</tt> methods check whether thare is an intersection point upstream and
+ * downstream from the cursor. <tt>getPathLength()</tt>, <tt>getPoint()</tt>, and
+ * <tt>getDirection()</tt> methods return trajectory parameters at the point downstream
+ * from the cursor. An attempt to move the cursor beyond the ends of the point list, or to
+ * obtain trajectory parameters when the cursor is downstream from the last intersection point,
+ * throws {@link NoSuchElementException}.
+ * <p>
+ * When the <tt>Intersection</tt> is first created, its cursor is positioned before the first
+ * intersection point downstream (along the trajectory direction) from the trajectory origin.
+ * Therefore, an immediate call to <tt>getPathLength()</tt> will return the path length to
+ * that point, or throw <tt>NoSuchElementException</tt> if there are no intersections downstream
+ * from the origin.
+ *
+ * @author D. Onoprienko
+ * @version $Id: Intersection.java,v 1.1 2008/11/05 03:32:51 onoprien Exp $
+ */
+public interface Intersection {
+
+// -- Number of intersection points : -----------------------------------------
+
+ /**
+ * Returns the number of intersection points.
+ * If the number is infinite, returns <tt>-1</tt>.
+ */
+ public int size();
+
+// -- Stepping through intersection points : ----------------------------------
+
+ public void step(int steps);
+
+ public void stepForward();
+
+ public void stepBack();
+
+ public boolean hasNext();
+
+ public boolean hasPrevious();
+
+// -- Trajectory parameters at the next intersection point : ------------------
+
+ public double getPathLength();
+
+ public Hep3Vector getPoint();
+
+ public Hep3Vector getDirection();
+
+// -- Access to intersecting objects : ----------------------------------------
+
+ /** Returns the trajectory this intersection belongs to. */
+ public Trajectory getTrajectory();
+
+ /** Returns the surface this intersection belongs to. */
+ public Surface getSurface();
+
+}
lcsim/src/org/lcsim/contrib/onoprien/util/swim
diff -N IntersectionHelixZ.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ IntersectionHelixZ.java 5 Nov 2008 03:32:51 -0000 1.1
@@ -0,0 +1,137 @@
+package org.lcsim.contrib.onoprien.util.swim;
+
+import java.util.*;
+
+import hep.physics.vec.Hep3Vector;
+
+import org.lcsim.contrib.onoprien.util.ConstHep3Vector;
+
+/**
+ * Specialized implementation of {@link Intersection} interface suitable for use when
+ * locations of intersection points are periodic along the path length of the trajectory,
+ * possibly bounded to certain path length interval, and swimming the trajectory by a
+ * period changes only Z coordinate. This is typically used for intersecting {@Helix} with
+ * a surface parallel to Z axis.
+ *
+ * @author D. Onoprienko
+ * @version $Id: IntersectionHelixZ.java,v 1.1 2008/11/05 03:32:51 onoprien Exp $
+ */
+public class IntersectionHelixZ extends IntersectionPeriodicBound {
+
+// -- Constructors : ----------------------------------------------------------
+
+ /**
+ * Fast constructor.
+ * Arrays passed to this constructor will be owned by this <tt>Intersection</tt> object.
+ * They are assumed to contain consecutive intersections in increasing path
+ * length order, though not necessarily corresponding to the allowed Z interval.
+ */
+ public IntersectionHelixZ(double zMin, double zMax,
+ double[] pathLengths, ConstHep3Vector[] points, ConstHep3Vector[] directions,
+ Helix helix, Surface surface) {
+
+ super(helix, surface);
+ _path = pathLengths;
+ _pos = points;
+ _dir = directions;
+ init(zMin, zMax, helix);
+ }
+
+ /**
+ * Slow constructor.
+ * Arrays passed to this constructor will be copied and re-ordered if necessary.
+ */
+ public IntersectionHelixZ(double zMin, double zMax,
+ double[] pathLengths, Hep3Vector[] points, Hep3Vector[] directions,
+ Helix helix, Surface surface) {
+
+ super(helix, surface);
+
+ // Set periods in path length and Z
+
+ _pathPeriod = helix.getLengthPeriod();
+ _zPeriod = helix.getZPeriod();
+
+ // Move all solutions to withing period from _pathLength[0]
+
+ int n = pathLengths.length;
+ double[] s = new double[n];
+ ConstHep3Vector[] pos = new ConstHep3Vector[n];
+ double sMin = pathLengths[0];
+ for (int i=1; i<n; i++) if (pathLengths[i] < sMin) sMin = pathLengths[i];
+ for (int i=0; i<n; i++) {
+ int period = (int) Math.floor((pathLengths[i]-sMin) / _pathPeriod);
+ Hep3Vector point = points[i];
+ if (period != 0) {
+ s[i] = pathLengths[i] - period * _pathPeriod;
+ pos[i] = new ConstHep3Vector(point.x(), point.y(), point.z() - period*_zPeriod);
+ } else {
+ s[i] = pathLengths[i];
+ pos[i] = (point instanceof ConstHep3Vector) ? (ConstHep3Vector)point : new ConstHep3Vector(point) ;
+ }
+ }
+
+ // Order solutions
+
+ SortedMap<Double, Integer> map = new TreeMap<Double, Integer>();
+ for (int i=0; i<n; i++) map.put(s[i], i);
+ _path = new double[n];
+ _pos = new ConstHep3Vector[n];
+ _dir = new ConstHep3Vector[n];
+ int newIndex = 0;
+ for (Map.Entry<Double, Integer> entry : map.entrySet()) {
+ double path = entry.getKey();
+ int oldIndex = entry.getValue();
+ _path[newIndex] = path;
+ _pos[newIndex] = pos[oldIndex];
+ Hep3Vector dir = directions[oldIndex];
+ _dir[newIndex] = (dir instanceof ConstHep3Vector) ? (ConstHep3Vector)dir : new ConstHep3Vector(dir);
+ }
+
+ // Final initialization
+
+ init(zMin, zMax, helix);
+ }
+
+ protected void init(double zMin, double zMax, Helix helix) {
+ double sMin = helix.getLengthToZ(zMin);
+ double sMax = helix.getLengthToZ(zMax);
+ if (sMin > sMax) {
+ double temp = sMin;
+ sMin = sMax;
+ sMax = temp;
+ }
+ super.init(sMin, sMax);
+ }
+
+// -- Trajectory parameters at the next intersection point : ------------------
+
+ public ConstHep3Vector getPoint() {
+ if (hasNext()) {
+ if (_index.iPeriod == 0) {
+ return _pos[_index.iNext];
+ } else {
+ return new ConstHep3Vector(_pos[_index.iNext].x(),
+ _pos[_index.iNext].y(),
+ _pos[_index.iNext].z() + _index.iPeriod * _zPeriod);
+ }
+ } else {
+ throw new NoSuchElementException();
+ }
+ }
+
+ public ConstHep3Vector getDirection() {
+ if (hasNext()) {
+ return _dir[_index.iNext];
+ } else {
+ throw new NoSuchElementException();
+ }
+ }
+
+// -- Private parts : ---------------------------------------------------------
+
+ ConstHep3Vector[] _dir;
+ ConstHep3Vector[] _pos;
+ double _zPeriod;
+
+}
lcsim/src/org/lcsim/contrib/onoprien/util/swim
diff -N IntersectionMultiple.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ IntersectionMultiple.java 5 Nov 2008 03:32:51 -0000 1.1
@@ -0,0 +1,69 @@
+package org.lcsim.contrib.onoprien.util.swim;
+
+import java.util.*;
+
+/**
+ * An implementation of {@link Intersection} interface suitable for use when there is
+ * a finite number of intersection points, and their locations along the path length of
+ * the trajectory need to be explicitly specified to the constructor.
+ *
+ * @author D. Onoprienko
+ * @version $Id: IntersectionMultiple.java,v 1.1 2008/11/05 03:32:51 onoprien Exp $
+ */
+public class IntersectionMultiple extends AbstractIntersection {
+
+// -- Constructors : ----------------------------------------------------------
+
+ protected IntersectionMultiple() {
+ super();
+ }
+
+ public IntersectionMultiple(double[] pathLengths, Trajectory trajectory, Surface surface) {
+ super(trajectory, surface);
+ _next = 0;
+ Arrays.sort(pathLengths);
+ _path = pathLengths;
+ while (_next < pathLengths.length && pathLengths[_next] <= 0.) _next++;
+ }
+
+// -- Number of intersection points : -----------------------------------------
+
+ public int size() {return _path.length;}
+
+// -- Stepping through intersection points : ----------------------------------
+
+ public void step(int steps) {
+ int i = _next + steps;
+ if (i < 0 || i > _path.length) {
+ throw new NoSuchElementException();
+ } else {
+ _next = i;
+ }
+ }
+
+ public boolean hasNext() {
+ return _next < _path.length;
+ }
+
+ public boolean hasPrevious() {
+ return _next > 0;
+ }
+
+
+// -- Trajectory parameters at the next intersection point : ------------------
+
+ public double getPathLength() {
+ if (_next < _path.length) {
+ return _path[_next];
+ } else {
+ throw new NoSuchElementException();
+ }
+ }
+
+
+// -- Private parts : ---------------------------------------------------------
+
+ protected double[] _path;
+ protected int _next;
+
+}
lcsim/src/org/lcsim/contrib/onoprien/util/swim
diff -N IntersectionNone.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ IntersectionNone.java 5 Nov 2008 03:32:51 -0000 1.1
@@ -0,0 +1,50 @@
+package org.lcsim.contrib.onoprien.util.swim;
+
+import java.util.NoSuchElementException;
+
+import hep.physics.vec.Hep3Vector;
+
+/**
+ * An implementation of {@link Intersection} interface suitable for use when the trajectory
+ * and the surface have no intersection points.
+ *
+ * @author D. Onoprienko
+ * @version $Id: IntersectionNone.java,v 1.1 2008/11/05 03:32:51 onoprien Exp $
+ */
+public class IntersectionNone extends AbstractIntersection {
+
+// -- Constructors : ----------------------------------------------------------
+
+ public IntersectionNone() {
+ super();
+ }
+
+ public IntersectionNone(Trajectory trajectory, Surface surface) {
+ super(trajectory, surface);
+ }
+
+// -- Number of intersection points : -----------------------------------------
+
+ public int size() {return 0;}
+
+// -- Stepping through intersection points : ----------------------------------
+
+ public void step(int steps) {throw new NoSuchElementException();}
+
+ public void stepForward() {throw new NoSuchElementException();}
+
+ public void stepBack() {throw new NoSuchElementException();}
+
+ public boolean hasNext() {return false;}
+
+ public boolean hasPrevious() {return false;}
+
+// -- Trajectory parameters at the next intersection point : ------------------
+
+ public double getPathLength() {throw new NoSuchElementException();}
+
+ public Hep3Vector getPoint() {throw new NoSuchElementException();}
+
+ public Hep3Vector getDirection() {throw new NoSuchElementException();}
+
+}
lcsim/src/org/lcsim/contrib/onoprien/util/swim
diff -N IntersectionPeriodic.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ IntersectionPeriodic.java 5 Nov 2008 03:32:51 -0000 1.1
@@ -0,0 +1,177 @@
+package org.lcsim.contrib.onoprien.util.swim;
+
+import java.util.*;
+
+/**
+ * Specialized implementation of {@link Intersection} interface suitable for use when
+ * locations of intersection points are periodic along the path length of the trajectory.
+ *
+ * @author D. Onoprienko
+ * @version $Id: IntersectionPeriodic.java,v 1.1 2008/11/05 03:32:51 onoprien Exp $
+ */
+public class IntersectionPeriodic extends AbstractIntersection {
+
+// -- Constructors : ----------------------------------------------------------
+
+ /** Default constructor for use by superclasses. */
+ protected IntersectionPeriodic() {
+ super();
+ }
+
+ /** Empty constructor for use by superclasses. */
+ protected IntersectionPeriodic(Trajectory trajectory, Surface surface) {
+ super(trajectory, surface);
+ }
+
+ /**
+ * Main constructor.
+ *
+ * @param fast If <tt>true</tt>, the <tt>pathLengths</tt> array will be used "as is"
+ * and owned by this <tt>Intersection</tt> object. If <tt>false</tt>, the
+ * array will be copied, ordered, and its elements will be shifted to make
+ * sure they do not differ by more then <tt>period</tt>.
+ * @param pathLengths An array containing a set of unique path lengths to intersection points
+ * (those that cannot be obtained from each other by shifting by several periods).
+ */
+ public IntersectionPeriodic(boolean fast, double[] pathLengths, double period, Trajectory trajectory, Surface surface) {
+ super(trajectory, surface);
+ _pathPeriod = period;
+ if (fast) {
+ _path = pathLengths;
+ } else {
+ int n = pathLengths.length;
+ _path = new double[n];
+ double sMin = pathLengths[0];
+ for (int i=0; i<n; i++) {
+ _path[i] = pathLengths[i];
+ if (pathLengths[i] < sMin) sMin = pathLengths[i];
+ }
+ for (int i=0; i<n; i++) {
+ int iPeriod = (int) Math.floor((_path[i]-sMin) / _pathPeriod);
+ _path[i] = _path[i] - iPeriod * _pathPeriod;
+ }
+ Arrays.sort(_path);
+ }
+ _index = new Index();
+ _index.iSetBeforeGT(0.);
+ }
+
+// -- Number of intersection points : -----------------------------------------
+
+ public int size() {return -1;}
+
+// -- Stepping through intersection points : ----------------------------------
+
+ public void step(int steps) {
+ _index.iStep(steps);
+ }
+
+ public void stepForward() {
+ _index.iStepForward();
+ }
+
+ public void stepBack() {
+ _index.iStepBack();
+ }
+
+ public boolean hasNext() {return true;}
+
+ public boolean hasPrevious() {return true;}
+
+// -- Trajectory parameters at the next intersection point : ------------------
+
+ public double getPathLength() {
+ return _index.iGetPathLength();
+ }
+
+// -- Private parts : ---------------------------------------------------------
+
+ protected double[] _path;
+ protected double _pathPeriod;
+ protected Index _index;
+
+// -- Index class : -----------------------------------------------------------
+
+ /** Class that represents a pointer to a particular intersection point. */
+ protected class Index implements Comparable<Index> {
+
+ Index() {
+ iPeriod = 0;
+ iNext = 0;
+ }
+
+ Index(int period, int next) {
+ iPeriod = period;
+ iNext = next;
+ }
+
+ Index(Index index) {
+ iPeriod = index.iPeriod;
+ iNext = index.iNext;
+ }
+
+ public void iStep(int steps) {
+ int i = iNext + steps;
+ iPeriod += i / _path.length;
+ iNext = i % _path.length;
+ if (iNext < 0) {
+ iNext += _path.length;
+ iPeriod--;
+ }
+ }
+
+ public void iStepForward() {
+ if (++iNext == _path.length) {
+ iNext = 0;
+ iPeriod++;
+ }
+ }
+
+ public void iStepBack() {
+ if (--iNext < 0) {
+ iNext = _path.length - 1;
+ iPeriod--;
+ }
+ }
+
+ public double iGetPathLength() {
+ return _path[iNext] + iPeriod * _pathPeriod;
+ }
+
+ public int iSubtract(Index index) {
+ return (iPeriod - index.iPeriod) * _path.length + (iNext - index.iNext);
+ }
+
+ public int compareTo(Index index) {
+ return (iPeriod == index.iPeriod) ? (iNext - index.iNext) : (iPeriod - index.iPeriod) ;
+ }
+
+ /**
+ * Sets the index to point to the first intersection point with the path length
+ * greater than the one specified by the argument.
+ */
+ public void iSetBeforeGT(double s) {
+ iPeriod = (int) (Math.ceil( (s - _path[_path.length-1]) / _pathPeriod) );
+ iNext = 0;
+ while (iGetPathLength() <= s) {
+ iStepForward();
+ }
+ }
+
+ /**
+ * Sets the index to point to the first intersection point with the path length
+ * greater or equal to the one specified by the argument.
+ */
+ public void iSetBeforeGE(double s) {
+ iPeriod = (int) (Math.ceil( (s - _path[_path.length-1]) / _pathPeriod) );
+ iNext = 0;
+ while (iGetPathLength() < s) {
+ iStepForward();
+ }
+ }
+
+ int iPeriod;
+ int iNext;
+ }
+
+}
lcsim/src/org/lcsim/contrib/onoprien/util/swim
diff -N IntersectionPeriodicBound.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ IntersectionPeriodicBound.java 5 Nov 2008 03:32:51 -0000 1.1
@@ -0,0 +1,115 @@
+package org.lcsim.contrib.onoprien.util.swim;
+
+import java.util.*;
+
+/**
+ * Specialized implementation of {@link Intersection} interface suitable for use when
+ * locations of intersection points are periodic along the path length of the trajectory,
+ * but bounded to certain path length interval.
+ *
+ * @author D. Onoprienko
+ * @version $Id: IntersectionPeriodicBound.java,v 1.1 2008/11/05 03:32:51 onoprien Exp $
+ */
+public class IntersectionPeriodicBound extends IntersectionPeriodic {
+
+// -- Constructors : ----------------------------------------------------------
+
+ /** Default constructor for use by superclasses. */
+ protected IntersectionPeriodicBound() {
+ super();
+ }
+
+ /** Empty constructor for use by superclasses. */
+ protected IntersectionPeriodicBound(Trajectory trajectory, Surface surface) {
+ super(trajectory, surface);
+ }
+
+ /**
+ * Main constructor.
+ *
+ * @param fast If <tt>true</tt>, the <tt>pathLengths</tt> array will be used "as is"
+ * and owned by this <tt>Intersection</tt> object. If <tt>false</tt>, the
+ * array will be copied, ordered, and its elements will be shifted to make
+ * sure they do not differ by more then <tt>period</tt>. The order of bounds will
+ * also be checked.
+ * @param pathLengths An array containing a set of unique path lengths to intersection points
+ * (those that cannot be obtained from each other by shifting by several periods).
+ */
+ public IntersectionPeriodicBound(boolean fast, double pathLengthMin, double pathLengthMax,
+ double[] pathLengths, double period, Trajectory trajectory, Surface surface) {
+ super(fast, pathLengths, period, trajectory, surface);
+ if (pathLengthMin < pathLengthMax) {
+ init(pathLengthMin, pathLengthMax);
+ } else {
+ init(pathLengthMax, pathLengthMin);
+ }
+ }
+
+ protected void init(double pathLengthMin, double pathLengthMax) {
+ _min = new Index();
+ _min.iSetBeforeGT(pathLengthMin);
+ _max = new Index();
+ _max.iSetBeforeGE(pathLengthMax);
+ if (_index.compareTo(_min) < 0) {
+ _index = new Index(_min);
+ } else if (_index.compareTo(_max) > 0) {
+ _index = new Index(_max);
+ }
+ }
+
+// -- Number of intersection points : -----------------------------------------
+
+ public int size() {
+ return _max.iSubtract(_min);
+ }
+
+// -- Stepping through intersection points : ----------------------------------
+
+ public void step(int steps) {
+ Index newIndex = new Index(_index);
+ newIndex.iStep(steps);
+ if (newIndex.compareTo(_min) < 0 || newIndex.compareTo(_max) > 0) {
+ throw new NoSuchElementException();
+ } else {
+ _index = newIndex;
+ }
+ }
+
+ public void stepForward() {
+ if (hasNext()) {
+ _index.iStepForward();
+ } else {
+ throw new NoSuchElementException();
+ }
+ }
+
+ public void stepBack() {
+ if (hasPrevious()) {
+ _index.iStepBack();
+ } else {
+ throw new NoSuchElementException();
+ }
+ }
+
+ public boolean hasNext() {
+ return _index.compareTo(_max) < 0 ;
+ }
+
+ public boolean hasPrevious() {
+ return _index.compareTo(_min) > 0 ;
+ }
+
+// -- Trajectory parameters at the next intersection point : ------------------
+
+ public double getPathLength() {
+ if (hasNext()) {
+ return _index.iGetPathLength();
+ } else {
+ throw new NoSuchElementException();
+ }
+ }
+
+// -- Private parts : ---------------------------------------------------------
+
+ protected Index _min, _max;
+}
lcsim/src/org/lcsim/contrib/onoprien/util/swim
diff -N IntersectionSingle.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ IntersectionSingle.java 5 Nov 2008 03:32:51 -0000 1.1
@@ -0,0 +1,80 @@
+package org.lcsim.contrib.onoprien.util.swim;
+
+import java.util.NoSuchElementException;
+
+/**
+ * An implementation of {@link Intersection} interface suitable for use when there
+ * is a single intersection point.
+ *
+ * @author D. Onoprienko
+ * @version $Id: IntersectionSingle.java,v 1.1 2008/11/05 03:32:51 onoprien Exp $
+ */
+public class IntersectionSingle extends AbstractIntersection {
+
+// -- Constructors : ----------------------------------------------------------
+
+ protected IntersectionSingle() {
+ super();
+ }
+
+ public IntersectionSingle(double pathLength, Trajectory trajectory, Surface surface) {
+ super(trajectory, surface);
+ _path = pathLength;
+ _hasNext = pathLength > 0.;
+ }
+
+
+// -- Number of intersection points : -----------------------------------------
+
+ public int size() {return 1;}
+
+
+// -- Stepping through intersection points : ----------------------------------
+
+ public void step(int steps) {
+ if (steps == 1) {
+ stepForward();
+ } else if (steps == -1) {
+ stepBack();
+ } else if (steps != 0) {
+ throw new NoSuchElementException();
+ }
+ }
+
+ public void stepForward() {
+ if (_hasNext) {
+ _hasNext = false;
+ } else {
+ throw new NoSuchElementException();
+ }
+ }
+
+ public void stepBack() {
+ if (_hasNext) {
+ throw new NoSuchElementException();
+ } else {
+ _hasNext = true;
+ }
+ }
+
+ public boolean hasNext() {return _hasNext;}
+
+ public boolean hasPrevious() {return ! _hasNext;}
+
+
+// -- Trajectory parameters at the next intersection point : ------------------
+
+ public double getPathLength() {
+ if (_hasNext) {
+ return _path;
+ } else {
+ throw new NoSuchElementException();
+ }
+ }
+
+
+// -- Private parts : ---------------------------------------------------------
+
+ protected double _path;
+ protected boolean _hasNext;
+}
lcsim/src/org/lcsim/contrib/onoprien/util/swim
diff -N Line.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ Line.java 5 Nov 2008 03:32:51 -0000 1.1
@@ -0,0 +1,222 @@
+package org.lcsim.contrib.onoprien.util.swim;
+
+import hep.physics.vec.Hep3Vector;
+
+import org.lcsim.contrib.onoprien.util.ConstHep3Vector;
+
+/**
+ * Straight line {@link Trajectory}.
+ *
+ * @author D. Onoprienko
+ * @version $Id: Line.java,v 1.1 2008/11/05 03:32:51 onoprien Exp $
+ */
+public class Line extends AbstractTrajectory {
+
+ /**
+ * Emumeration of line parameters in W-representation.
+ */
+ public enum WRep {
+ /** X of the line origin. */
+ X,
+ /** Y of the line origin. */
+ Y,
+ /** Z of the line origin. */
+ Z,
+ /** X component of the unit vector in the direction of the line at its origin. */
+ DX,
+ /** Y component of the unit vector in the direction of the line at its origin. */
+ DY,
+ /** Z component of the unit vector in the direction of the line at its origin. */
+ DZ
+ }
+
+// -- Constructors : ----------------------------------------------------------
+
+ /**
+ * Construct from origin and direction.
+ * The direction vector does not have to be normalized.
+ */
+ public Line(Hep3Vector origin, Hep3Vector direction) {
+ _orig = new ConstHep3Vector(origin);
+ double mag = direction.magnitude();
+ _dir = new ConstHep3Vector(direction.x()/mag, direction.y()/mag, direction.z()/mag);
+ }
+
+ /**
+ * Construct from origin and direction.
+ * The direction vector does not have to be normalized.
+ */
+ public Line(ConstHep3Vector origin, Hep3Vector direction) {
+ _orig = origin;
+ double mag = direction.magnitude();
+ _dir = new ConstHep3Vector(direction.x()/mag, direction.y()/mag, direction.z()/mag);
+ }
+
+ /**
+ * Copy constructor.
+ */
+ public Line(Line line) {
+ _orig = line._orig;
+ _dir = line._dir;
+ }
+
+// -- Get line parameters : ---------------------------------------------------
+
+ /**
+ * Returns helix parameters in the requested representation.
+ *
+ * @param representation Enum class that defines helix parameters representation.
+ * Currently either {@link CRep} or {@link WRep}.
+ */
+ public <T extends Enum<T>> ParVector<T> getParameters(Class<T> representation) {
+ if (WRep.class.isAssignableFrom(representation)) {
+ return new ParVector<T>(representation, _orig.x(),_orig.y(),_orig.z(),_dir.x(),_dir.y(),_dir.z());
+ } else {
+ throw new IllegalArgumentException();
+ }
+ }
+
+ /**
+ * Returns covariance matrix for helix parameters in the requested representation.
+ *
+ * @param representation Enum class that defines helix parameters representation.
+ * Currently either {@link CRep} or {@link WRep}.
+ */
+ public <T extends Enum<T>> ParCovMatrix<T> getCovMatrix(Class<T> representation) {
+ throw new UnsupportedOperationException("Covariance matrix operations are not yet implemented"); // FIXME
+ }
+
+// -- Position at the given point : -------------------------------------------
+
+ /**
+ * Returns the position of the origin of the trajectory.
+ */
+ public Hep3Vector getPoint() {
+ return _orig;
+ }
+
+ /**
+ * Returns the position at given path length along the trajectory.
+ */
+ public Hep3Vector getPoint(double pathLength) {
+ return new ConstHep3Vector(_orig.x() + pathLength * _dir.x(),
+ _orig.y() + pathLength * _dir.y(),
+ _orig.z() + pathLength * _dir.z());
+ }
+
+// -- Direction at the given point : ------------------------------------------
+
+ /**
+ * Returns the direction unit vector at the origin.
+ */
+ public Hep3Vector getDirection() {
+ return _dir;
+ }
+
+ /**
+ * Returns the direction unit vector at given path length along the trajectory.
+ */
+ public Hep3Vector getDirection(double pathLength) {
+ return _dir;
+ }
+
+// -- Modifying the trajectory : ----------------------------------------------
+
+ /**
+ * Reverse the direction of the trajectory.
+ */
+ public void reverse() {
+ _dir = new ConstHep3Vector(- _dir.x(), - _dir.y(), - _dir.z());
+ }
+
+ /**
+ * Move the origin by the given path length along the trajectory.
+ */
+ public boolean swim(double pathLength) {
+ _orig = new ConstHep3Vector(_orig.x() + pathLength * _dir.x(),
+ _orig.y() + pathLength * _dir.y(),
+ _orig.z() + pathLength * _dir.z());
+ return true;
+ }
+
+// -- Intersections : ---------------------------------------------------------
+
+ public Intersection intersect(Surface surface) {
+ if (surface instanceof Poca) {
+ return intersect((Poca) surface);
+ } else if (surface instanceof PocaXY) {
+ return intersect((PocaXY) surface);
+ } else if (surface instanceof ZPlane) {
+ return intersect((ZPlane) surface);
+ } else if (surface instanceof ZCylinder) {
+ return intersect((ZCylinder) surface);
+ } else {
+ return surface.intersect(this);
+ }
+ }
+
+ public Intersection intersect(Poca poca) {
+ Hep3Vector point = poca.getPoint();
+ double s = (point.x()-_orig.x())*_dir.x() + (point.y()-_orig.y())*_dir.y() + (point.z()-_orig.z())*_dir.z();
+ return new IntersectionSingle(s, this, poca);
+ }
+
+ public Intersection intersect(PocaXY poca) {
+ ConstHep3Vector point = poca.getPoint();
+ double s = ((point.x()-_orig.x())*_dir.x() + (point.y()-_orig.y())*_dir.y()) / (_dir.x()*_dir.x() + _dir.y()*_dir.y());
+ if (Double.isInfinite(s)) s = (point.z() - _orig.z()) / _dir.z();
+ return new IntersectionSingle(s, this, poca) ;
+ }
+
+ public Intersection intersect(ZPlane zPlane) {
+ double s = (zPlane._z - _orig.z()) / _dir.z();
+ return (Double.isInfinite(s)) ? new IntersectionNone(this, zPlane) : new IntersectionSingle(s, this, zPlane) ;
+ }
+
+ public Intersection intersect(ZDisk zDisk) {
+ double s = (zDisk._z - _orig.z()) / _dir.z();
+ if (Double.isInfinite(s)) return new IntersectionNone(this, zDisk);
+ Hep3Vector pos = getPoint(s);
+ double x = pos.x();
+ double y = pos.y();
+ double r2 = x*x + y*y;
+ return (r2 > zDisk._rMin2 && r2 < zDisk._rMax2) ? new IntersectionSingle(s, this, zDisk) : new IntersectionNone(this, zDisk);
+ }
+
+ public Intersection intersectZCylinder(ZCylinder zCylinder) {
+ double d2 = _dir.x() * _dir.x() + _dir.y() * _dir.y();
+ if (d2 == 0.) return new IntersectionNone(this, zCylinder);
+ double b = _orig.x() * _dir.x() + _orig.y() * _dir.y();
+ double discr = b*b - d2 * (_orig.x() * _orig.x() + _orig.y() * _orig.y() - zCylinder._r * zCylinder._r);
+ if ((discr < 0.) || Double.isNaN(discr) || Double.isInfinite(discr)) {
+ return new IntersectionNone(this, zCylinder);
+ } else {
+ discr = Math.sqrt(discr);
+ double[] ss = new double[] { (-b - discr) / d2, (-b + discr) / d2};
+ boolean[] good = new boolean[2];
+ for (int i=0; i<2; i++) {
+ double s = ss[i];
+ if (Double.isInfinite(s)) {
+ good[i] = false;
+ } else {
+ double z = getPoint(s).z();
+ good[i] = z > zCylinder._zMin && z < zCylinder._zMax;
+ }
+ }
+ if (good[0] && good[1]) {
+ return new IntersectionMultiple(ss, this, zCylinder);
+ } else if (! (good[0] || good[1])) {
+ return new IntersectionNone(this, zCylinder);
+ } else {
+ double s = (good[0] ? ss[0] : ss[1]);
+ return new IntersectionSingle(s, this, zCylinder);
+ }
+ }
+ }
+
+// -- Private parts : ---------------------------------------------------------
+
+ private ConstHep3Vector _orig;
+ private ConstHep3Vector _dir;
+
+}
lcsim/src/org/lcsim/contrib/onoprien/util/swim
diff -N ParCovMatrix.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ParCovMatrix.java 5 Nov 2008 03:32:51 -0000 1.1
@@ -0,0 +1,56 @@
+package org.lcsim.contrib.onoprien.util.swim;
+
+import hep.physics.matrix.SymmetricMatrix;
+
+/**
+ * An instance of this class represents a covariance matrix of parameters that define a trajectory,
+ * in a particular representation. The representation is described by enum that contains
+ * constants identifying the parameters (for example, {@link Helix} parameters can be
+ * described in {@link Helix.CRep} and {@link Helix.WRep} representations).
+ *
+ * @author D. Onoprienko
+ * @version $Id: ParCovMatrix.java,v 1.1 2008/11/05 03:32:51 onoprien Exp $
+ */
+public class ParCovMatrix<T extends Enum<T>> extends SymmetricMatrix {
+
+// -- Constructors : ----------------------------------------------------------
+
+ public ParCovMatrix(Class<T> representation) {
+ super(representation.getEnumConstants().length);
+ _rep = representation;
+ }
+
+ public ParCovMatrix(Class<T> representation, double[] initialValues, boolean isLower) {
+ super(representation.getEnumConstants().length, initialValues, isLower);
+ _rep = representation;
+ }
+
+ public ParCovMatrix(ParCovMatrix<T> covMatrix) {
+ super(covMatrix);
+ _rep = covMatrix._rep;
+ }
+
+// -- Getters : ---------------------------------------------------------------
+
+ public double get(T parameter) {
+ return diagonal(parameter.ordinal());
+ }
+
+ public double get(T parameter1, T parameter2) {
+ return e(parameter1.ordinal(), parameter2.ordinal());
+ }
+
+// -- Setters : ---------------------------------------------------------------
+
+ public void set(T parameter, double value) {
+ setElement(parameter.ordinal(), parameter.ordinal(), value);
+ }
+
+ public void set(T parameter1, T parameter2, double value) {
+ setElement(parameter1.ordinal(), parameter2.ordinal(), value);
+ }
+
+// -- Private parts : ---------------------------------------------------------
+
+ private Class<T> _rep;
+}
lcsim/src/org/lcsim/contrib/onoprien/util/swim
diff -N ParVector.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ParVector.java 5 Nov 2008 03:32:51 -0000 1.1
@@ -0,0 +1,49 @@
+package org.lcsim.contrib.onoprien.util.swim;
+
+/**
+ * An instance of this class represents a vector of parameters that define a trajectory,
+ * in a particular representation. The representation is described by enum that contains
+ * constants identifying the parameters (for example, {@link Helix} parameters can be
+ * described in {@link Helix.CRep} and {@link Helix.WRep} representations).
+ *
+ * @author D. Onoprienko
+ * @version $Id: ParVector.java,v 1.1 2008/11/05 03:32:51 onoprien Exp $
+ */
+public class ParVector<T extends Enum<T>> {
+
+// -- Constructors : ----------------------------------------------------------
+
+ public ParVector(Class<T> representation) {
+ _rep = representation;
+ _pars = new double[_rep.getEnumConstants().length];
+ }
+
+ public ParVector(Class<T> representation, double... values) {
+ _rep = representation;
+ int n = _rep.getEnumConstants().length;
+ if (values.length != n) throw new IllegalArgumentException();
+ _pars = values;
+ }
+
+ public ParVector(ParVector parVector) {
+ _rep = parVector._rep;
+ _pars = (double[]) parVector._pars.clone();
+ }
+
+// -- Getters : ---------------------------------------------------------------
+
+ public double get(T parameter) {
+ return _pars[parameter.ordinal()];
+ }
+
+// -- Setters : ---------------------------------------------------------------
+
+ public void set(T parameter, double value) {
+ _pars[parameter.ordinal()] = value;
+ }
+
+// -- Private parts : ---------------------------------------------------------
+
+ private Class<T> _rep;
+ private double[] _pars;
+}
lcsim/src/org/lcsim/contrib/onoprien/util/swim
diff -N Poca.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ Poca.java 5 Nov 2008 03:32:51 -0000 1.1
@@ -0,0 +1,59 @@
+package org.lcsim.contrib.onoprien.util.swim;
+
+import hep.physics.vec.Hep3Vector;
+
+import org.lcsim.contrib.onoprien.util.ConstHep3Vector;
+
+/**
+ * {@link Surface} that represents point of closest approach to the point supplied to
+ * its constructor.
+ *
+ * @author D. Onoprienko
+ * @version $Id: Poca.java,v 1.1 2008/11/05 03:32:51 onoprien Exp $
+ */
+public class Poca extends AbstractSurface {
+
+// -- Constructors : ----------------------------------------------------------
+
+ public Poca(Hep3Vector point) {
+ if (point instanceof ConstHep3Vector) {
+ _point = (ConstHep3Vector) point;
+ } else {
+ _point = new ConstHep3Vector(point.v());
+ }
+ }
+
+ public Poca(double[] point) {
+ _point = new ConstHep3Vector(point);
+ }
+
+ public Poca(double x, double y, double z) {
+ _point = new ConstHep3Vector(x,y,z);
+ }
+
+// -- Getters : ---------------------------------------------------------------
+
+ public ConstHep3Vector getPoint() {
+ return _point;
+ }
+
+// -- Implementing Surface : --------------------------------------------------
+
+ /**
+ * Returns intersection of the specified trajectory with this surface.
+ */
+ public Intersection intersect(Trajectory trajectory) {
+ if (trajectory instanceof Line) {
+ return ((Line)trajectory).intersect(this);
+ } else if (trajectory instanceof Helix) {
+ return ((Helix)trajectory).intersect(this);
+ } else {
+ return super.intersect(trajectory);
+ }
+ }
+
+// -- Private parts : ---------------------------------------------------------
+
+ private ConstHep3Vector _point;
+
+}
lcsim/src/org/lcsim/contrib/onoprien/util/swim
diff -N PocaXY.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ PocaXY.java 5 Nov 2008 03:32:51 -0000 1.1
@@ -0,0 +1,58 @@
+package org.lcsim.contrib.onoprien.util.swim;
+
+import hep.physics.vec.Hep3Vector;
+
+import org.lcsim.contrib.onoprien.util.ConstHep3Vector;
+
+/**
+ * {@link Surface} that represents point of closest approach in XY plane to the
+ * point supplied to its constructor.
+ *
+ * @author D. Onoprienko
+ * @version $Id: PocaXY.java,v 1.1 2008/11/05 03:32:51 onoprien Exp $
+ */
+public class PocaXY extends AbstractSurface {
+
+// -- Constructors : ----------------------------------------------------------
+
+ public PocaXY(Hep3Vector point) {
+ if (point instanceof ConstHep3Vector) {
+ _point = (ConstHep3Vector) point;
+ } else {
+ _point = new ConstHep3Vector(point.v());
+ }
+ }
+
+ public PocaXY(double[] point) {
+ _point = new ConstHep3Vector(point);
+ }
+
+ public PocaXY(double x, double y, double z) {
+ _point = new ConstHep3Vector(x,y,z);
+ }
+
+// -- Getters : ---------------------------------------------------------------
+
+ public ConstHep3Vector getPoint() {
+ return _point;
+ }
+
+// -- Implementing Surface : --------------------------------------------------
+
+ /**
+ * Returns intersection of the specified trajectory with this surface.
+ */
+ public Intersection intersect(Trajectory trajectory) {
+ if (trajectory instanceof Line) {
+ return ((Line)trajectory).intersect(this);
+ } else if (trajectory instanceof Helix) {
+ return ((Helix)trajectory).intersect(this);
+ } else {
+ return super.intersect(trajectory);
+ }
+ }
+
+// -- Private parts : ---------------------------------------------------------
+
+ private ConstHep3Vector _point;
+}
lcsim/src/org/lcsim/contrib/onoprien/util/swim
diff -N Surface.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ Surface.java 5 Nov 2008 03:32:51 -0000 1.1
@@ -0,0 +1,18 @@
+package org.lcsim.contrib.onoprien.util.swim;
+
+import hep.physics.vec.Hep3Vector;
+
+/**
+ * A surface in space.
+ *
+ * @author D. Onoprienko
+ * @version $Id: Surface.java,v 1.1 2008/11/05 03:32:51 onoprien Exp $
+ */
+public interface Surface {
+
+ /**
+ * Returns intersection of the specified trajectory with this surface.
+ */
+ public Intersection intersect(Trajectory trajectory);
+
+}
lcsim/src/org/lcsim/contrib/onoprien/util/swim
diff -N Trajectory.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ Trajectory.java 5 Nov 2008 03:32:51 -0000 1.1
@@ -0,0 +1,95 @@
+package org.lcsim.contrib.onoprien.util.swim;
+
+import hep.physics.vec.Hep3Vector;
+
+/**
+ * A trajectory in space.
+ * Trajectory is characterized by its shape, origin, and direction.
+ *
+ * @author D. Onoprienko
+ * @version $Id: Trajectory.java,v 1.1 2008/11/05 03:32:51 onoprien Exp $
+ */
+public interface Trajectory {
+
+// -- Position and direction at the given point : -----------------------------
+
+ /**
+ * Returns the position of the origin of the trajectory.
+ */
+ public Hep3Vector getPoint();
+
+ /**
+ * Returns the position at given path length along the trajectory.
+ * Returns <tt>null</tt> if the requested point does not exist on this trajectory.
+ */
+ public Hep3Vector getPoint(double pathLength);
+
+ /**
+ * Returns direction unit vector at the origin.
+ */
+ public Hep3Vector getDirection();
+
+ /**
+ * Returns direction unit vector at given path length along the trajectory.
+ * Returns <tt>null</tt> if the requested point does not exist on this trajectory.
+ */
+ public Hep3Vector getDirection(double pathLength);
+
+// -- Get trajectory parameters : ---------------------------------------------
+
+ /**
+ * Returns a vector of parameters that define the shape of this trajectory.
+ * Throws <tt>IllegalArgumentException</tt> if the requested representation is not
+ * applicable to this concrete trajectory class.
+ *
+ * @param representation Enum that defines a particular representation of the trajectory
+ * parameters. For example, {@link Helix} parameters can be
+ * returned in {@link Helix.CRep} and {@link Helix.WRep} representations.
+ */
+ public <T extends Enum<T>> ParVector<T> getParameters(Class<T> representation);
+
+ /**
+ * Returns the value of a parameter that describes the shape of this trajectory.
+ * The parameter is identified by enum constant that belongs to a particular representation.
+ */
+ public <T extends Enum<T>> double getParameter(T parameter);
+
+ /**
+ * Returns a covariance matrix of parameters that define the shape of this trajectory.
+ * Throws <tt>IllegalArgumentException</tt> if the requested representation is not
+ * applicable to this concrete trajectory class.
+ *
+ * @param representation Enum that defines a particular representation of the trajectory
+ * parameters. For example, {@link Helix} parameters can be
+ * returned in {@link Helix.CRep} and {@link Helix.WRep} representations.
+ */
+ public <T extends Enum<T>> ParCovMatrix<T> getCovMatrix(Class<T> representation);
+
+ /**
+ * Returns an element of a covariance matrix of parameters that describe the shape of this trajectory.
+ * The parameter is identified by enum constant that belongs to a particular representation.
+ */
+ public <T extends Enum<T>> double getCovElement(T parameter1, T parameter2);
+
+// -- Find intersection with a surface : --------------------------------------
+
+ /**
+ * Returns intersection of this trajectory with the specified surface.
+ */
+ public Intersection intersect(Surface surface);
+
+
+// -- Modifying the trajectory : ----------------------------------------------
+
+ /**
+ * Reverse the direction of the trajectory.
+ */
+ public void reverse();
+
+ /**
+ * Move the origin by the given path length along the trajectory.
+ * Returns <tt>false</tt> if the requested point does not exist on this trajectory.
+ */
+ public boolean swim(double pathLength);
+
+}
lcsim/src/org/lcsim/contrib/onoprien/util/swim
diff -N ZCylinder.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ZCylinder.java 5 Nov 2008 03:32:51 -0000 1.1
@@ -0,0 +1,56 @@
+package org.lcsim.contrib.onoprien.util.swim;
+
+import org.lcsim.contrib.onoprien.util.ConstHep3Vector;
+
+/**
+ * {@link Surface} that represents a bounded cylinder parallel to and centered at Z axis.
+ * This surface is characterized by radius, low Z bound, and high Z bound.
+ *
+ * @author D. Onoprienko
+ * @version $Id: ZCylinder.java,v 1.1 2008/11/05 03:32:51 onoprien Exp $
+ */
+public class ZCylinder extends AbstractSurface {
+
+// -- Constructors : ----------------------------------------------------------
+
+ public ZCylinder(double radius, double zMin, double zMax) {
+ }
+
+// -- Getters : ---------------------------------------------------------------
+
+ /** Returns radius of this cylinder. */
+ public double getRadius() {
+ return _r;
+ }
+
+ /** Returns minimum Z of this cylinder. */
+ public double getMinZ() {
+ return _zMin;
+ }
+
+ /** Returns minimum Z of this cylinder. */
+ public double getMaxZ() {
+ return _zMax;
+ }
+
+// -- Implementing Surface : --------------------------------------------------
+
+ /**
+ * Returns intersection of the specified trajectory with this surface.
+ */
+ public Intersection intersect(Trajectory trajectory) {
+ if (trajectory instanceof Line) {
+ return ((Line)trajectory).intersect(this);
+ } else if (trajectory instanceof Helix) {
+ return ((Helix)trajectory).intersect(this);
+ } else {
+ return super.intersect(trajectory);
+ }
+ }
+
+// -- Private parts : ---------------------------------------------------------
+
+ double _r;
+ double _zMin, _zMax;
+
+}
lcsim/src/org/lcsim/contrib/onoprien/util/swim
diff -N ZDisk.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ZDisk.java 5 Nov 2008 03:32:51 -0000 1.1
@@ -0,0 +1,57 @@
+package org.lcsim.contrib.onoprien.util.swim;
+
+import hep.physics.vec.Hep3Vector;
+
+/**
+ * {@link Surface} that represents a disk centered around Z axis and perpendicular to it.
+ *
+ * @author D. Onoprienko
+ * @version $Id: ZDisk.java,v 1.1 2008/11/05 03:32:51 onoprien Exp $
+ */
+public class ZDisk extends AbstractSurface {
+
+// -- Constructors : ----------------------------------------------------------
+
+ public ZDisk(double z, double radiusMin, double radiusMax) {
+ _z = z;
+ _rMin2 = radiusMin * radiusMin;
+ _rMax2 = radiusMax * radiusMax;
+ }
+
+// -- Getters : ---------------------------------------------------------------
+
+ /** Returns Z coordinate of this disk. */
+ public double getZ() {
+ return _z;
+ }
+
+ /** Returns inner radius of this disk. */
+ public double getMinRadius() {
+ return Math.sqrt(_rMin2);
+ }
+
+ /** Returns outer radius of this disk. */
+ public double getMaxRadius() {
+ return Math.sqrt(_rMax2);
+ }
+
+// -- Implementing Surface : --------------------------------------------------
+
+ /**
+ * Returns intersection of the specified trajectory with this surface.
+ */
+ public Intersection intersect(Trajectory trajectory) {
+ if (trajectory instanceof Line) {
+ return ((Line)trajectory).intersect(this);
+ } else if (trajectory instanceof Helix) {
+ return ((Helix)trajectory).intersect(this);
+ } else {
+ return super.intersect(trajectory);
+ }
+ }
+
+// -- Private parts : ---------------------------------------------------------
+
+ double _z;
+ double _rMin2, _rMax2;
+}
lcsim/src/org/lcsim/contrib/onoprien/util/swim
diff -N ZPlane.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ZPlane.java 5 Nov 2008 03:32:51 -0000 1.1
@@ -0,0 +1,42 @@
+package org.lcsim.contrib.onoprien.util.swim;
+
+/**
+ * {@link Surface} that represents a plane perpendicular to Z axis.
+ *
+ * @author D. Onoprienko
+ * @version $Id: ZPlane.java,v 1.1 2008/11/05 03:32:51 onoprien Exp $
+ */
+public class ZPlane extends AbstractSurface {
+
+// -- Constructors : ----------------------------------------------------------
+
+ public ZPlane(double z) {
+ _z = z;
+ }
+
+// -- Getters : ---------------------------------------------------------------
+
+ /** Returns Z coordinate of this plane. */
+ public double getZ() {
+ return _z;
+ }
+
+// -- Implementing Surface : --------------------------------------------------
+
+ /**
+ * Returns intersection of the specified trajectory with this surface.
+ */
+ public Intersection intersect(Trajectory trajectory) {
+ if (trajectory instanceof Line) {
+ return ((Line)trajectory).intersect(this);
+ } else if (trajectory instanceof Helix) {
+ return ((Helix)trajectory).intersect(this);
+ } else {
+ return super.intersect(trajectory);
+ }
+ }
+
+// -- Private parts : ---------------------------------------------------------
+
+ double _z;
+}
lcsim/src/org/lcsim/contrib/onoprien/util/swim
diff -N package-info.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ package-info.java 5 Nov 2008 03:32:51 -0000 1.1
@@ -0,0 +1,6 @@
+/**
+ * Classes for representing trajectories and surfaces, finding their
+ * intersections, and propagating parameters and their covariance matrices along trajectories.
+ */
+package org.lcsim.contrib.onoprien.util.swim;
+
CVSspam 0.2.8