Print

Print


Commit in lcsim/src/org/lcsim/contrib/uiowa/structural/likelihood on MAIN
MiscUtilities.java+67-141.3 -> 1.4
TrackToTrackIntermediateHits.java+64-31.1 -> 1.2
+131-17
2 modified files
Partially implemented the intermediate hit finder. Ultimately, it should extrapolate tracks through a series of layers, finding the cell ID in each and checking for a hit.

lcsim/src/org/lcsim/contrib/uiowa/structural/likelihood
MiscUtilities.java 1.3 -> 1.4
diff -u -r1.3 -r1.4
--- MiscUtilities.java	18 Oct 2005 17:42:14 -0000	1.3
+++ MiscUtilities.java	18 Oct 2005 22:32:57 -0000	1.4
@@ -116,23 +116,76 @@
 		double pointR = Math.sqrt(point.x()*point.x() + point.y()*point.y());
 		double pointZ = point.z();
 		if (pointR > innerR && pointR < outerR && pointZ > minZ && pointZ < maxZ) {
-		    // Yes.
-		    if (subdet.isCalorimeter()) {
-			//System.out.println("DEBUG: Point in calorimeter: "+point+" is inside system '"+name+"' which is of class '"+subdet.getClass().getName()+"'");
-			if (subdet.isLayered()) {
-			    Layering layers = subdet.getLayering();
-			}
-			return subdet;
-		    } else {
-			//System.out.println("DEBUG: Point not in calorimeter: "+point+" is inside system '"+name+"' which is of class '"+subdet.getClass().getName()+"'");
-			return subdet;
-		    }
+		    return subdet;
 		}
-	    } else {
-		//System.out.println("DEBUG: Subdetector '"+name+"' of class '"+subdet.getClass().getName()+"' is not cylindrical.");
 	    }
 	}
 
-	return null; // dummy
+	return null; // Couldn't find a cylindrical detector containing this point
+    }
+
+    static protected org.lcsim.geometry.layer.Layer findLayer(Hep3Vector point, org.lcsim.geometry.Detector det)
+    {
+	org.lcsim.geometry.Subdetector subdet = MiscUtilities.findComponent(point, det);
+	if (subdet == null) {
+	    // Point doesn't fall inside a cylindrical subdetector
+	    return null;
+	}
+	if ( ! (subdet instanceof CylindricalSubdetector) ) {
+	    throw new AssertionError("Asked to find layer info for subdetector "+subdet+" of class "+subdet.getClass().getName()+", which is not a cylinder");
+	}
+	if (!subdet.isLayered()) {
+	    throw new AssertionError("Asked to find layer info for subdetector "+subdet+" of class "+subdet.getClass().getName()+", which is not layered");
+	}
+	CylindricalSubdetector cylinder = (CylindricalSubdetector) (subdet);
+	Layering layers = subdet.getLayering();
+	// Barrel: Spans from -DeltaZ/2 to +DeltaZ/2
+	// Endcap: Spans from +z to +z+DeltaZ or from -z to -Z-Deltaz
+	boolean isEndcap = (cylinder.getZMin() * cylinder.getZMax() > 0.0);
+	// Now, if this is a barrel-type detector, the layers are at constant r and go outwards in steps of z.
+	//     If this is an endcap-type detector, the layers are at constant z and go outwards in steps of r.
+	double longitudinalCoord = 0.0;
+	double sign = 1.0;
+	if (isEndcap) {
+	    longitudinalCoord = Math.sqrt(point.x()*point.x() + point.y()*point.y());
+	} else {
+	    longitudinalCoord = point.z();
+	    if (longitudinalCoord<0.0) {
+		sign = -1.0;
+	    }
+	}
+	// Which layer are we in?
+	// Note that we have to be careful about the sign in the case where z<0...
+	int numLayers = layers.getLayerCount();
+	org.lcsim.geometry.layer.Layer matchingLayer = null;
+	for (int iLayer=0; iLayer<numLayers; iLayer++) {
+	    double layerAbsMin = sign*layers.getDistanceToLayer(iLayer);
+	    double layerAbsMax = layerAbsMin + layers.getLayer(iLayer).getThickness();
+	    if (sign*longitudinalCoord>=layerAbsMin && sign*longitudinalCoord<layerAbsMax) {
+		matchingLayer = layers.getLayer(iLayer);
+		break;
+	    }
+	}
+	// OK, we've found the layer (or not). Do some sanity checks:
+	// Total thickness must match sum of thicknesses, and layer distances
+	// must be monotonic increasing:
+	for (int iLayer=0; iLayer<numLayers-1; iLayer++) {
+	    double thickness = layers.getLayer(iLayer).getThickness();
+	    double thisLayerAbsMin = sign*layers.getDistanceToLayer(iLayer);
+	    double thisLayerAbsMax = thisLayerAbsMin + thickness;
+	    double nextLayerAbsMin = sign*layers.getDistanceToLayer(iLayer+1);
+	    if (thisLayerAbsMin > thisLayerAbsMax) {
+		throw new AssertionError("Layer "+iLayer+" min = "+thisLayerAbsMin+" and layer "+iLayer+" max = "+thisLayerAbsMax+" -- not allowed.");
+	    }
+	    if (thisLayerAbsMax > nextLayerAbsMin) {
+		throw new AssertionError("Layer "+(iLayer+1)+" min = "+nextLayerAbsMin+" and layer "+iLayer+" max = "+thisLayerAbsMax+" -- not allowed.");
+	    }
+	    // Check that there are no holes:
+	    double gap = (nextLayerAbsMin - thisLayerAbsMax);
+	    if ( Math.abs(gap) > 0.001) {
+		throw new AssertionError("Layer "+iLayer+" max = "+thisLayerAbsMax+" and layer "+iLayer+" min = "+nextLayerAbsMin+" so gap = "+gap+" -- not allowed.");
+	    }
+	}
+	return matchingLayer;
     }
 }

lcsim/src/org/lcsim/contrib/uiowa/structural/likelihood
TrackToTrackIntermediateHits.java 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- TrackToTrackIntermediateHits.java	29 Sep 2005 21:04:50 -0000	1.1
+++ TrackToTrackIntermediateHits.java	18 Oct 2005 22:32:57 -0000	1.2
@@ -1,10 +1,15 @@
 package structural.likelihood; // package org.lcsim.recon.cluster.structural.likelihood;
 
+import java.util.Set;
+import java.util.HashSet;
+
+import org.lcsim.event.CalorimeterHit;
+import org.lcsim.event.Cluster;
 import org.lcsim.util.swim.Trajectory;
 import org.lcsim.util.swim.Line;
-import org.lcsim.event.Cluster;
 import hep.physics.vec.BasicHep3Vector;
 import hep.physics.vec.Hep3Vector;
+import hep.physics.vec.VecOp;
 
 abstract public class TrackToTrackIntermediateHits implements StructuralLikelihoodQuantity
 {
@@ -15,9 +20,65 @@
     transient protected IntermediateHitFinder.InfoLookForHits m_infoParallel = null;
 
     // Figure out if tracks are parallel
-    protected boolean areTracksParallel(Cluster clus1, Cluster clus2) 
+    protected boolean areTracksParallel(Cluster track1, Cluster track2) 
     {
-	throw new AssertionError("Not implemented");
+	// First step: Are these guys nearly the same?
+        // They are if:
+        //   1) Their directions are nearly the same:
+        //        dot product of directions > 0.95
+        //   2) They are close to each other
+        //        DOCA < 1.0
+        //   3) They are ~ disjoint in layer
+        //        "Overlap" = hits from both MIPs in the same layer in the same detector component
+        //        Require < 2 overlaps.
+	
+        // Obtain basic quantities:
+	Line line1 = MiscUtilities.makeLine(track1);
+	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();
+	Hep3Vector dir1 = line1.getDirection();
+	Hep3Vector dir2 = line2.getDirection();
+	double dotProduct = VecOp.dot(dir1, dir2);
+
+        // Check if direction/proximity/disjoint criteria are met:
+        boolean tracksAreParallel = (dotProduct > 0.95);
+        boolean tracksMeet = (doca < 1.0);
+        int numOverlaps = countOverlaps(track1, track2);
+        boolean disjoint = (numOverlaps < 2);
+        
+        return (tracksAreParallel && tracksMeet && disjoint);
+    }
+
+    /**
+     * Count the number of distinct layers in which both
+     * clusters have a hit.
+     */
+    protected int countOverlaps(Cluster clus1, Cluster clus2) 
+    {
+	Set<org.lcsim.geometry.layer.Layer> overlapLayers = new HashSet<org.lcsim.geometry.layer.Layer>();
+	// For each pair of hits, check if they come from the same subdetector and have the same
+	// layer index:
+	for (CalorimeterHit hit1 : clus1.getCalorimeterHits()) {
+	    org.lcsim.geometry.Subdetector subdet1 = hit1.getSubdetector();
+	    hit1.getIDDecoder().setID(hit1.getCellID());
+	    int layer1 = hit1.getIDDecoder().getLayer();
+	    for (CalorimeterHit hit2 : clus2.getCalorimeterHits()) {
+		org.lcsim.geometry.Subdetector subdet2 = hit2.getSubdetector();
+		hit2.getIDDecoder().setID(hit2.getCellID());
+		int layer2 = hit2.getIDDecoder().getLayer();
+		if (layer1==layer2 && subdet1==subdet2) {
+		    // Overlap
+		    org.lcsim.geometry.layer.Layer layerObject = subdet1.getLayering().getLayer(layer1);
+		    overlapLayers.add(layerObject);
+		}
+	    }
+	}
+
+        // How many distinct layers have overlaps?
+        return overlapLayers.size();
     }
 
     // Make info for divergent (non-parallel) tracks
CVSspam 0.2.8