Commit in lcsim/src/org/lcsim/fit/helicaltrack on MAIN
HelicalTrackCross.java-11.8 -> 1.9
HelicalTrackHit.java+11.15 -> 1.16
HelicalTrackHitDriver.java+64-161.34 -> 1.35
HitUtils.java+4-31.9 -> 1.10
StereoHitMaker.java+160-541.7 -> 1.8
+229-74
5 modified files
Speed up creation of stereo hits

lcsim/src/org/lcsim/fit/helicaltrack
HelicalTrackCross.java 1.8 -> 1.9
diff -u -r1.8 -r1.9
--- HelicalTrackCross.java	4 Sep 2008 17:22:08 -0000	1.8
+++ HelicalTrackCross.java	21 May 2009 21:48:15 -0000	1.9
@@ -34,7 +34,6 @@
 public class HelicalTrackCross extends HelicalTrackHit {
     private HelicalTrackStrip _strip1;
     private HelicalTrackStrip _strip2;
-    private double _eps = 1.0e-6;
     private static int _type = 3;
     
     /**

lcsim/src/org/lcsim/fit/helicaltrack
HelicalTrackHit.java 1.15 -> 1.16
diff -u -r1.15 -r1.16
--- HelicalTrackHit.java	2 Oct 2008 17:13:38 -0000	1.15
+++ HelicalTrackHit.java	21 May 2009 21:48:15 -0000	1.16
@@ -52,6 +52,7 @@
     private double _dr;
     private double _chisq;
     protected static final double _eps = 1e-6;
+
     public HelicalTrackHit(Hep3Vector pos, SymmetricMatrix cov, double dEdx, double time, int type,
             List rawhits, String detname, int layer, BarrelEndcapFlag beflag) {
         _pos = pos;

lcsim/src/org/lcsim/fit/helicaltrack
HelicalTrackHitDriver.java 1.34 -> 1.35
diff -u -r1.34 -r1.35
--- HelicalTrackHitDriver.java	24 Apr 2009 01:25:10 -0000	1.34
+++ HelicalTrackHitDriver.java	21 May 2009 21:48:15 -0000	1.35
@@ -14,9 +14,11 @@
 
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 
+import java.util.Set;
 import org.lcsim.recon.tracking.digitization.sisim.SiTrackerHit;
 import org.lcsim.recon.tracking.digitization.sisim.SiTrackerHitStrip1D;
 import org.lcsim.recon.tracking.digitization.sisim.TrackerHitType.CoordinateSystem;
@@ -26,11 +28,9 @@
 import org.lcsim.recon.tracking.vsegment.geom.sensortypes.Cylinder;
 import org.lcsim.recon.tracking.vsegment.hit.DigiTrackerHit;
 import org.lcsim.recon.tracking.vsegment.hit.TrackerCluster;
-import org.lcsim.recon.tracking.vsegment.hitmaking.OldTrackerHit;
-import org.lcsim.detector.DetectorElementStore;
 import org.lcsim.detector.IDetectorElement;
-import org.lcsim.detector.IDetectorElementContainer;
 import org.lcsim.detector.ITransform3D;
+import org.lcsim.detector.tracker.silicon.SiSensor;
 import org.lcsim.detector.tracker.silicon.SiTrackerModule;
 import org.lcsim.digisim.MyLCRelation;
 import org.lcsim.event.EventHeader;
@@ -216,24 +216,51 @@
                 helhits.add(hit);
             }
         }
-        
+
+        //  Loop over the collections of hits produced by the sisim digitization code
         for (String colname : _digcol) {
-            
+
+            //  Get the list of SiTrackerHits for this collection
             List<SiTrackerHit> hitlist = (List<SiTrackerHit>) event.get(colname);
-            List<HelicalTrackStrip> strips = new ArrayList<HelicalTrackStrip>();
-            
+
+            //  Create collections for modules, strip hits by sensor, and hit cross references
+            Set<SiTrackerModule> modules = new HashSet<SiTrackerModule>();
+            Map<SiSensor, List<HelicalTrackStrip>> sensormap = new HashMap<SiSensor, List<HelicalTrackStrip>>();
             Map<HelicalTrackStrip, SiTrackerHitStrip1D> stripmap = new HashMap<HelicalTrackStrip, SiTrackerHitStrip1D>();
+
+            //  Loop over the SiTrackerHits in this collection
             for (SiTrackerHit hit : hitlist) {
                 
                 if (hit instanceof SiTrackerHitStrip1D) {
                     //determine if the hit is stereoed or not
                     SiTrackerHitStrip1D h = (SiTrackerHitStrip1D) hit;
-                    SiTrackerModule m = (SiTrackerModule) hit.getSensor().getParent();
                     
-                    if (m.getChildren().size()==2) {//stereo hit
+                    //  Get the sensor and parent modules
+                    SiSensor sensor = h.getSensor();
+                    SiTrackerModule m = (SiTrackerModule) sensor.getParent();
+
+                    //  Check if we have a stereo hit (i.e., the module has 2 children)
+                    if (m.getChildren().size()==2) {
+                        
+                        //  Add the module to the set of modules containing stereo hits
+                        modules.add(m);
+
+                        //  Create a HelicalTrackStrip for this hit
                         HelicalTrackStrip strip = makeDigiStrip(h);
-                        strips.add(strip);
-                        stripmap.put(strip,h);
+
+                        //  Get the list of strips for this module - create a new list if one doesn't already exist
+                        List<HelicalTrackStrip> modhits = sensormap.get(sensor);
+                        if (modhits == null) {
+                            modhits = new ArrayList<HelicalTrackStrip>();
+                            sensormap.put(sensor, modhits);
+                        }
+                        
+                        //  Add the strip to the list of strips on this sensor
+                        modhits.add(strip);
+                        
+                        //  Map a reference back to the hit needed to create the stereo hit LC relations
+                        stripmap.put(strip, h);
+
                     } else {
                         //System.out.println("trying to make an axial hit???");
                         HelicalTrackHit dah = makeDigiAxialHit(h);
@@ -248,11 +275,22 @@
                     hitrelations.add(new MyLCRelation(hit3d, hit));
                 }
             }
-            
-            //generate Stereo hits
-            List<HelicalTrackCross> stereohits = _crosser.MakeHits(strips);
-            
-            
+            //  Now create the stereo hits
+            //  Create a list of stereo hits
+            List<HelicalTrackCross> stereohits = new ArrayList<HelicalTrackCross>();
+
+            //  Loop over the modules with hits
+            for (SiTrackerModule m : modules) {
+
+                //  Make sure we have 2 sensors, and get the sensors for this module
+                if (m.getChildren().size() != 2) continue;
+                SiSensor sensor1 = (SiSensor) m.getChildren().get(0);
+                SiSensor sensor2 = (SiSensor) m.getChildren().get(1);
+
+                //  Form the stereo hits and add them to our hit list
+                stereohits.addAll(_crosser.MakeHits(sensormap.get(sensor1), sensormap.get(sensor2)));
+            }
+
             helhits.addAll(stereohits);
             
             //add LCRelation for strip hits
@@ -312,6 +350,16 @@
         _mcrelname = mcrelname;
         return;
     }
+
+    public void setMaxSeperation(double maxsep) {
+        _crosser.setMaxSeparation(maxsep);
+        return;
+    }
+
+    public void setTolerance(double tolerance) {
+        _crosser.setTolerance(tolerance);
+        return;
+    }
     
     private HelicalTrackHit MakeAxialHit(org.lcsim.recon.tracking.vsegment.hit.TrackerHit hit) {
         HelicalTrackStrip strip = MakeStrip(hit);

lcsim/src/org/lcsim/fit/helicaltrack
HitUtils.java 1.9 -> 1.10
diff -u -r1.9 -r1.10
--- HitUtils.java	1 Apr 2009 20:55:58 -0000	1.9
+++ HitUtils.java	21 May 2009 21:48:15 -0000	1.10
@@ -139,9 +139,6 @@
         //  gamma = Origin2 . w_hat / Origin1 . w_hat
         double gamma = VecOp.dot(strip2.origin(), strip2.w()) / NonZeroDotProduct(strip1.origin(), strip1.w());
         
-        //  Calculate the seperation between the sensor planes
-        double separation = VecOp.dot(strip1.w(), VecOp.sub(strip2.origin(), strip1.origin()));
-        
         //  Calculate v1hat . u2hat, which is equivalent to sin(alpha) where alpha is the stereo angle
         double salpha = VecOp.dot(strip1.v(), strip2.u());
         
@@ -151,8 +148,12 @@
         
         //  dp = (p2 - gamma * p1)
         Hep3Vector dp = VecOp.sub(p2, VecOp.mult(gamma, p1));
+
         //  Unmeasured coordinate v1:  v1 = (dp . u2_hat) / (gamma * sin(alpha))
         double v1 = VecOp.dot(dp, strip2.u()) / (gamma * salpha);
+        if (v1 < strip1.vmin()) v1 = strip1.vmin();
+        if (v1 > strip1.vmax()) v1 = strip1.vmax();
+
         //  Position of hit on strip 1:  r1 = p1 + v1 * v1_hat
         Hep3Vector r1 = VecOp.add(p1, VecOp.mult(v1, strip1.v()));
         //  Take position to be the midpoint of r1 and r2: r = 0.5 * (1 + gamma) * r1

lcsim/src/org/lcsim/fit/helicaltrack
StereoHitMaker.java 1.7 -> 1.8
diff -u -r1.7 -r1.8
--- StereoHitMaker.java	20 Feb 2009 22:45:10 -0000	1.7
+++ StereoHitMaker.java	21 May 2009 21:48:15 -0000	1.8
@@ -4,7 +4,6 @@
  * Created on June 22, 2008, 9:45 PM
  *
  */
-
 package org.lcsim.fit.helicaltrack;
 
 import hep.physics.vec.Hep3Vector;
@@ -16,94 +15,201 @@
 import org.lcsim.event.MCParticle;
 
 /**
+ * This class forms stereo hits (HelicalTrackCross) from pairs of hits in
+ * parallel sensor layers.
  *
- * @author partridge
+ * @author Richard Partridge
  * @version 1.0
  */
 public class StereoHitMaker {
+
     private double _tolerance;
     private double _maxsep;
     private double _eps = 1.0e-6;
-    
+
     /**
-     * Creates a new instance of StereoHitMaker
+     * Creates a new instance of StereoHitMaker with default parameters:
+     *
+     * MaxSeparation = 10 mm
+     * Tolerance = 2
      */
     public StereoHitMaker() {
         this(2., 10.);
     }
-    
+
+    /**
+     * Fully qualified constructor for StereoHitMaker.
+     *
+     * The tolerance is a dimensionless parameter characterizes the maximum
+     * angle between a track and the sensor for high efficiency.  A tolerance
+     * near unity will allow hits to be found even for steeply inclined tracks.
+     *
+     * The maximum separation sets the maximum distance between sensor planes
+     * when forming paired hits.
+     *
+     * @param tolerance dimensionless tolerance parameter
+     * @param maxsep maximum separation between sensor planes (units are mm)
+     */
     public StereoHitMaker(double tolerance, double maxsep) {
         _tolerance = tolerance;
         _maxsep = maxsep;
     }
-    
+
+    /**
+     * Create cross hits from two lists of HelicalTrackStrip hits.  The cross
+     * hits are found by making pairs of hits, taking one hit from each list,
+     * that are compatible with forming crosses.
+     *
+     * @param slist1 list of HelicalTrackStrips in first sensor plane
+     * @param slist2 list of HelicalTrackStrips in second sensor plane
+     * @return list of HelicalTrackCross hits
+     */
+    public List<HelicalTrackCross> MakeHits(List<HelicalTrackStrip> slist1, List<HelicalTrackStrip> slist2) {
+
+        //  Make a list of the cross hits that are found
+        List<HelicalTrackCross> crosscol = new ArrayList<HelicalTrackCross>();
+
+        if (slist1 == null || slist2 == null) return crosscol;
+
+        //  Loop over pairs of hits taking one hit from each collection
+        for (HelicalTrackStrip strip1 : slist1) {
+            for (HelicalTrackStrip strip2 : slist2) {
+
+                //  Try to make a cross - if successful, add it to the collection
+                HelicalTrackCross cross = MakeHit(strip1, strip2);
+                if (cross != null) crosscol.add(cross);
+            }
+        }
+
+        //  Done making cross hits
+        return crosscol;
+    }
+
+    /**
+     * Create cross hits from a list of HelicalTrackStrip hits.  Each pair of
+     * hits is checked for consistency with forming a cross hit.  Pairs are
+     * only formed from strips with the same detector name, layer number, and
+     * BarrelEndcapFlag.
+     *
+     * @param stripcol list of HelicalTrackStrips
+     * @return list of HelicalTrackCross hits
+     */
     public List<HelicalTrackCross> MakeHits(List<HelicalTrackStrip> stripcol) {
-        
+
         //  Make a list of the cross hits that are found
         List<HelicalTrackCross> crosscol = new ArrayList<HelicalTrackCross>();
-        
-        //  Loop over all strip pairs
+
+        //  Make sure we have at least 2 strips
         int nstrip = stripcol.size();
         if (nstrip < 2) return crosscol;
-        for (int i = 0; i < nstrip - 1; i++) {
+
+        //  Loop over all pairs of strips
+        for (int i = 0; i < nstrip - 1; i++)
             for (int j = i + 1; j < nstrip; j++) {
                 HelicalTrackStrip strip1 = stripcol.get(i);
                 HelicalTrackStrip strip2 = stripcol.get(j);
-              
+
                 //  Check that these strips are in the same detector and layer
-                if (!strip1.detector().equals(strip2.detector())) continue;
                 if (strip1.layer() != strip2.layer()) continue;
                 if (strip1.BarrelEndcapFlag() != strip2.BarrelEndcapFlag()) continue;
+                if (!strip1.detector().equals(strip2.detector())) continue;
 
-                //  Locate the center of the hit strips and the difference in these positions
-                Hep3Vector p1 = VecOp.add(strip1.origin(), VecOp.mult(strip1.umeas(), strip1.u()));
-                Hep3Vector p2 = VecOp.add(strip2.origin(), VecOp.mult(strip2.umeas(), strip2.u()));
-                Hep3Vector dp = VecOp.sub(p1, p2);
-
-
-                //  Check that the sensors planes are parallel to each other
-                if (VecOp.cross(strip1.w(), strip2.w()).magnitude() > _eps) continue;
-
-                //  Check that the sensor seperation meets requirements
-                double seperation = Math.abs(VecOp.dot(dp, strip1.w()));
-                if (seperation > _maxsep) continue;
-                
-                //  Check that the strips aren't colinear
-                double salpha = VecOp.dot(strip1.v(), strip2.u());
-                if (Math.abs(salpha) < _eps) continue;
-
-                //  Check if we can form a cross within tolerances
-                double v1 = VecOp.dot(dp, strip2.u()) / salpha;
-
-                double vtol = Math.abs(seperation * _tolerance / salpha);
-                if (v1 > strip1.vmax() + vtol ) continue;
-                if (v1 < strip1.vmin() - vtol) continue;
-                double v2 = VecOp.dot(dp, strip1.u()) / salpha;
-                if (v2 > strip2.vmax() + vtol) continue;
-                if (v2 < strip2.vmin() - vtol) continue;
-
-                //  Strip pair passes all requirements, make a new cross and add it to the collection
-                HelicalTrackCross cross = new HelicalTrackCross(strip1, strip2);
-                crosscol.add(cross);
-                
-                // Add any matching MC hits to the cross
-                for (MCParticle mcp : strip1.MCParticles()) {
-                    if (strip2.MCParticles().contains(mcp)) {
-                        cross.addMCParticle(mcp);
-                    }
-                }
+                //  Try to make a cross - if successful, add it to the collection
+                HelicalTrackCross cross = MakeHit(strip1, strip2);
+                if (cross != null) crosscol.add(cross);
             }
-        }
+
+        //  Done making crosses
         return crosscol;
     }
-    
+
+    /**
+     * Set the maximum separation between sensor planes in the direction normal
+     * to the sensor.
+     *
+     * @param maxsep maximum sensor seperation (units are mm)
+     */
     public void setMaxSeparation(double maxsep) {
         _maxsep = maxsep;
-        return;
     }
-    
+
+    /**
+     * Set the tolerance parameter, which is a dimensionless parameter
+     * that characterizes the maximum angle between a track and the sensor for
+     * high efficiency.  A tolerance near unity will allow hits to be found
+     * even for steeply inclined tracks.
+     *
+     * @param tolerance tolerance parameter
+     */
     public void setTolerance(double tolerance) {
         _tolerance = tolerance;
-        return;
+    }
+
+    /**
+     * Try to form a cross hit from two HelicalTrackStrips.  Returns null
+     * if these two strips don't form a valid cross.
+     * 
+     * @param strip1 first strip
+     * @param strip2 second strip
+     * @return cross hit (or null if a valid cross hit cannot be made)
+     */
+    private HelicalTrackCross MakeHit(HelicalTrackStrip strip1, HelicalTrackStrip strip2) {
+
+        //  Check if we can make a valid hit from this cross
+        if (!CheckCross(strip1, strip2)) return null;
+
+        //  Strip pair passes all requirements, make a new cross
+        HelicalTrackCross cross = new HelicalTrackCross(strip1, strip2);
+
+        // Add any matching MC hits to the cross
+        for (MCParticle mcp : strip1.MCParticles()) {
+            if (strip2.MCParticles().contains(mcp)) cross.addMCParticle(mcp);
+        }
+
+        //  Done making a new cross hit
+        return cross;
+    }
+
+    /**
+     * Check a pair of hits to see if we can make a valid cross hit.  Checks
+     * include requiring the sensors to be parallel with a separation less than
+     * the maximum separation, that the two strips are not collinear, and
+     * that the intersection assuming a normal trajectory gives unmeasured
+     * coordinates that are consistent with the strip limits (or if outside
+     * the strip limits, are within the allowed tolerance).
+     *
+     * @param strip1 first strip
+     * @param strip2 second strip
+     * @return
+     */
+    private boolean CheckCross(HelicalTrackStrip strip1, HelicalTrackStrip strip2) {
+
+        //  Check that the sensors planes are parallel to each other
+        if (VecOp.cross(strip1.w(), strip2.w()).magnitude() > _eps) return false;
+
+        //  Check that the strips aren't colinear
+        double salpha = VecOp.dot(strip1.v(), strip2.u());
+        if (Math.abs(salpha) < _eps) return false;
+
+        //  Locate the center of the hit strips and the difference in these positions
+        Hep3Vector p1 = VecOp.add(strip1.origin(), VecOp.mult(strip1.umeas(), strip1.u()));
+        Hep3Vector p2 = VecOp.add(strip2.origin(), VecOp.mult(strip2.umeas(), strip2.u()));
+        Hep3Vector dp = VecOp.sub(p1, p2);
+
+        //  Check that the sensor separation meets requirements
+        double separation = Math.abs(VecOp.dot(dp, strip1.w()));
+        if (separation > _maxsep) return false;
+
+        //  Check if we can form a cross within tolerances
+        double v1 = VecOp.dot(dp, strip2.u()) / salpha;
+        double vtol = Math.abs(separation * _tolerance / salpha);
+        if (v1 > strip1.vmax() + vtol) return false;
+        if (v1 < strip1.vmin() - vtol) return false;
+        double v2 = VecOp.dot(dp, strip1.u()) / salpha;
+        if (v2 > strip2.vmax() + vtol) return false;
+        if (v2 < strip2.vmin() - vtol) return false;
+
+        //  Passed all tests - OK to make stereo hit from this strip pair
+        return true;
     }
 }
\ No newline at end of file
CVSspam 0.2.8