Commit in lcsim/src/org/lcsim/recon/cluster/structural/likelihood on MAIN
TrackToTrackDOCA.java+31-51.1 -> 1.2
TrackToTrackPOCAInCalorimeter.java+26-121.1 -> 1.2
TrackToTrackSmallestDistanceToPOCA.java+24-21.1 -> 1.2
+81-19
3 modified files
Structural PFA: Handle the special case of parallel tracks better. Added some documentation.

lcsim/src/org/lcsim/recon/cluster/structural/likelihood
TrackToTrackDOCA.java 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- TrackToTrackDOCA.java	1 Mar 2006 02:45:58 -0000	1.1
+++ TrackToTrackDOCA.java	29 Mar 2007 19:12:12 -0000	1.2
@@ -7,6 +7,8 @@
 import hep.physics.vec.Hep3Vector;
 import hep.physics.vec.VecOp;
 
+import org.lcsim.spacegeom.SpacePoint;
+
 /**
   * This quantity calculates the distance of closest approach (DOCA)
   * of two track-like clusters. The clusters are treated as straight
@@ -14,6 +16,12 @@
   *
   * Note that here the DOCA is the distance from one track to the
   * other, not the distance from each track to the POCA.
+  * 
+  * This evaluator requires that each track segment cluster has at least
+  * four hits (otherwise the direction is not so meaningful).
+  *
+  * @author Mat Charles <[log in to unmask]>
+  * @version $Id: TrackToTrackDOCA.java,v 1.2 2007/03/29 19:12:12 mcharles Exp $
   */
 
 public class TrackToTrackDOCA implements StructuralLikelihoodQuantity
@@ -40,11 +48,29 @@
 	Line line2 = MiscUtilities.makeLine(track2);
 
 	double[] distancesAlongLinesToPOCAs = Line.getPOCAOfLines(line1, line2);
-	
-	Hep3Vector poca1 = line1.getPointAtDistance(distancesAlongLinesToPOCAs[0]);
-	Hep3Vector poca2 = line2.getPointAtDistance(distancesAlongLinesToPOCAs[1]);
-	double doca = VecOp.sub(poca1,poca2).magnitude();
-	return doca;
+	if (distancesAlongLinesToPOCAs == null) {
+	    // Lines are parallel!
+	    // Find a point on each line
+	    SpacePoint pointOnLine1 = line1.getPointAtDistance(0.0);
+	    SpacePoint pointOnLine2 = line2.getPointAtDistance(0.0);
+	    double distanceBetweenPoints = SpacePoint.distance(pointOnLine1, pointOnLine2);
+	    // Find dot product of displacement vector with line direction
+	    double displacement_x = pointOnLine2.x() - pointOnLine1.x();
+	    double displacement_y = pointOnLine2.y() - pointOnLine1.y();
+	    double displacement_z = pointOnLine2.z() - pointOnLine1.z();
+	    double direction_x = line1.getDirection().x();
+	    double direction_y = line1.getDirection().y();
+	    double direction_z = line1.getDirection().z();
+	    double dotProduct = displacement_x*direction_x + displacement_y*direction_y + displacement_z*direction_z;
+	    // Subtract in quadrature to get perpendicular distance (DOCA)
+	    double doca = distanceBetweenPoints*distanceBetweenPoints - dotProduct*dotProduct;
+	    return doca;
+	} else {
+	    Hep3Vector poca1 = line1.getPointAtDistance(distancesAlongLinesToPOCAs[0]);
+	    Hep3Vector poca2 = line2.getPointAtDistance(distancesAlongLinesToPOCAs[1]);
+	    double doca = VecOp.sub(poca1,poca2).magnitude();
+	    return doca;
+	}
     }
 
     

lcsim/src/org/lcsim/recon/cluster/structural/likelihood
TrackToTrackPOCAInCalorimeter.java 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- TrackToTrackPOCAInCalorimeter.java	1 Mar 2006 02:45:58 -0000	1.1
+++ TrackToTrackPOCAInCalorimeter.java	29 Mar 2007 19:12:12 -0000	1.2
@@ -12,14 +12,23 @@
 
 /**
   * This quantity indicates whether the point of closest approach (POCA) of two track-like clusters
-  * is within the calorimeter. In the current implementation, the tracks are treated
+  * is within the calorimeter (return value 1) or not (return value 0). In the current implementation, the tracks are treated
   * as straight lines; their position and direction are determined from the energy
   * tensory of the cluster. 
   *
+  * This evaluator requires that each track segment cluster has at least
+  * four hits (otherwise the direction is not so meaningful).
+  *
+  * If the track segments are parallel, the POCA is not well-defined. In this
+  * case, the evaluator returns 1.
+  *
   * The implementation uses geometry information derived from EventHeader. The
   * method setEventInfo() MUST be called before evaluate() so that the geometry
   * information can be cached. In general, setEventInfo() SHOULD be called
   * at the start of every event.
+  * 
+  * @author Mat Charles <[log in to unmask]>
+  * @version $Id: TrackToTrackPOCAInCalorimeter.java,v 1.2 2007/03/29 19:12:12 mcharles Exp $
   */
 
 public class TrackToTrackPOCAInCalorimeter implements StructuralLikelihoodQuantityWithEventInfo
@@ -61,17 +70,22 @@
 
         // Find the POCA:
 	double[] distancesAlongLinesToPOCAs = Line.getPOCAOfLines(line1, line2);
-	Hep3Vector nearestPointOnLine1 = line1.getPointAtDistance(distancesAlongLinesToPOCAs[0]);
-	Hep3Vector nearestPointOnLine2 = line2.getPointAtDistance(distancesAlongLinesToPOCAs[1]);
-	// Find the mean of these two points -- that's the POCA
-	Hep3Vector poca = VecOp.mult(0.5, VecOp.add(nearestPointOnLine1, nearestPointOnLine2));
-
-        boolean pocaInCalorimeter = isPointInCalorimeter(poca);
-        if (pocaInCalorimeter) {
-            return 1.0;
-        } else {
-            return 0.0;
-        }
+	if (distancesAlongLinesToPOCAs == null) {
+	    // Lines are parallel!
+	    // Assume yes
+	    return 1.0;
+	} else {
+	    Hep3Vector nearestPointOnLine1 = line1.getPointAtDistance(distancesAlongLinesToPOCAs[0]);
+	    Hep3Vector nearestPointOnLine2 = line2.getPointAtDistance(distancesAlongLinesToPOCAs[1]);
+	    // Find the mean of these two points -- that's the POCA
+	    Hep3Vector poca = VecOp.mult(0.5, VecOp.add(nearestPointOnLine1, nearestPointOnLine2));
+	    boolean pocaInCalorimeter = isPointInCalorimeter(poca);
+	    if (pocaInCalorimeter) {
+		return 1.0;
+	    } else {
+		return 0.0;
+	    }
+	}
     }
  
     /**

lcsim/src/org/lcsim/recon/cluster/structural/likelihood
TrackToTrackSmallestDistanceToPOCA.java 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- TrackToTrackSmallestDistanceToPOCA.java	1 Mar 2006 02:45:59 -0000	1.1
+++ TrackToTrackSmallestDistanceToPOCA.java	29 Mar 2007 19:12:12 -0000	1.2
@@ -9,6 +9,23 @@
 import org.lcsim.recon.cluster.util.BasicCluster;
 import org.lcsim.util.swim.Line;
 
+/**
+ * A likelihood quantity used in the structural algorithm.
+ *
+ * For two track segment clusters within the calorimeter, we:
+ *   (1) Approximate them by straight lines
+ *   (2) Find the point of closest approach
+ *   (3) Return the shortest distance from a line to the POCA
+ * If the lines are parallel, the POCA is not well-defined, and we return
+ * half of the shortest hit-hit distance between the two segments instead.
+ *
+ * This evaluator requires that each track segment cluster has at least
+ * four hits (otherwise the direction is not so meaningful).
+ * 
+ * @author Mat Charles <[log in to unmask]>
+ * @version $Id: TrackToTrackSmallestDistanceToPOCA.java,v 1.2 2007/03/29 19:12:12 mcharles Exp $
+ */
+
 public class TrackToTrackSmallestDistanceToPOCA implements StructuralLikelihoodQuantity
 {
     public TrackToTrackSmallestDistanceToPOCA() {}
@@ -28,7 +45,12 @@
 	Line line2 = MiscUtilities.makeLine(track2);
 
 	double[] distancesAlongLinesToPOCAs = Line.getPOCAOfLines(line1, line2);
-
-	return Math.min(Math.abs(distancesAlongLinesToPOCAs[0]), Math.abs(distancesAlongLinesToPOCAs[1]));
+	if (distancesAlongLinesToPOCAs != null) {
+	    // Lines not parallel
+	    return Math.min(Math.abs(distancesAlongLinesToPOCAs[0]), Math.abs(distancesAlongLinesToPOCAs[1]));
+	} else {
+	    // Lines are parallel -- take shortest hit-hit distance
+	    return (0.5 * MiscUtilities.distance(track1, track2));
+	}
     }
 }
CVSspam 0.2.8