Print

Print


Author: [log in to unmask]
Date: Tue Sep  1 13:02:05 2015
New Revision: 3483

Log:
add the track extrapolator using the field map to TrackUtils.  This method takes in the track, the field map, and where to extrapolate to.   

Modified:
    java/trunk/tracking/src/main/java/org/hps/recon/tracking/TrackUtils.java

Modified: java/trunk/tracking/src/main/java/org/hps/recon/tracking/TrackUtils.java
 =============================================================================
--- java/trunk/tracking/src/main/java/org/hps/recon/tracking/TrackUtils.java	(original)
+++ java/trunk/tracking/src/main/java/org/hps/recon/tracking/TrackUtils.java	Tue Sep  1 13:02:05 2015
@@ -14,6 +14,7 @@
 import java.util.Set;
 import org.hps.recon.tracking.EventQuality.Quality;
 import org.hps.recon.tracking.gbl.HelicalTrackStripGbl;
+import static org.lcsim.constants.Constants.fieldConversion;
 import org.lcsim.detector.ITransform3D;
 import org.lcsim.detector.solids.Box;
 import org.lcsim.detector.solids.Point3D;
@@ -29,6 +30,7 @@
 import org.lcsim.event.TrackState;
 import org.lcsim.event.TrackerHit;
 import org.lcsim.event.base.BaseRelationalTable;
+import org.lcsim.event.base.BaseTrackState;
 import org.lcsim.fit.helicaltrack.HelicalTrackFit;
 import org.lcsim.fit.helicaltrack.HelicalTrackHit;
 import org.lcsim.fit.helicaltrack.HelicalTrackStrip;
@@ -37,10 +39,15 @@
 import org.lcsim.fit.helicaltrack.HitUtils;
 import org.lcsim.fit.helicaltrack.MultipleScatter;
 import org.lcsim.geometry.Detector;
+import org.lcsim.geometry.FieldMap;
 import org.lcsim.geometry.subdetector.BarrelEndcapFlag;
 import org.lcsim.recon.tracking.seedtracker.SeedCandidate;
 import org.lcsim.recon.tracking.seedtracker.SeedTrack;
+import org.lcsim.spacegeom.CartesianVector;
+import org.lcsim.spacegeom.SpaceVector;
 import org.lcsim.util.swim.Helix;
+import org.lcsim.util.swim.Line;
+import org.lcsim.util.swim.Trajectory;
 
 /**
  * Assorted helper functions for the track and helix objects in lcsim. Re-use as
@@ -148,17 +155,14 @@
         //WTrack wtrack = new WTrack(helfit, -1.0*bfield); //
         Hep3Vector B = new BasicHep3Vector(0, 0, 1);
         WTrack wtrack = new WTrack(helfit, bfield); //
-        if (initial_s != 0) {
+        if (initial_s != 0)
             wtrack.setTrackParameters(wtrack.getHelixParametersAtPathLength(initial_s, B));
-        }
-        if (debug) {
+        if (debug)
             System.out.printf("getHelixPlaneIntercept:find intercept between plane defined by point on plane %s, unit vec %s, bfield %.3f, h=%s and WTrack \n%s \n", point_on_plane.toString(), unit_vec_normal_to_plane.toString(), bfield, B.toString(), wtrack.toString());
-        }
         try {
             Hep3Vector intercept_point = wtrack.getHelixAndPlaneIntercept(point_on_plane, unit_vec_normal_to_plane, B);
-            if (debug) {
+            if (debug)
                 System.out.printf("getHelixPlaneIntercept: found intercept point at %s\n", intercept_point.toString());
-            }
             return intercept_point;
         } catch (RuntimeException e) {
             return null;
@@ -225,6 +229,8 @@
      * Extrapolate track to given position.
      *
      * @param helix - to be extrapolated
+     * @param z
+     * @param useMap
      * @param track - position along the x-axis of the helix in lcsim
      * coordiantes
      * @return
@@ -278,11 +284,11 @@
         double magnetZ = detector.getConstants().get("dipoleMagnetPositionZ").getValue();
         double magnetDownstreamEdge = magnetZ + magnetLength / 2;
         double magnetUpstreamEdge = magnetZ - magnetLength / 2;
-        if (z >= magnetDownstreamEdge) {
+        if (z >= magnetDownstreamEdge)
             trackPosition = extrapolateHelixToXPlane(track, magnetDownstreamEdge);
-        } else if (z <= magnetUpstreamEdge) {
+        else if (z <= magnetUpstreamEdge)
             trackPosition = extrapolateHelixToXPlane(track, magnetUpstreamEdge);
-        } else {
+        else {
             Hep3Vector detVecTracking = extrapolateHelixToXPlane(track, z);
             // System.out.printf("detVec %s\n", detVecTracking.toString());
             return new BasicHep3Vector(detVecTracking.y(), detVecTracking.z(), detVecTracking.x());
@@ -349,9 +355,8 @@
             // Check if we are on the plane
             d = VecOp.dot(VecOp.sub(pos, origin), normal);
             dx += -1.0 * d / 2.0;
-            if (debug) {
+            if (debug)
                 System.out.printf("%d d %.10f pos [%.10f %.10f %.10f] dx %.10f\n", nIter, d, pos.x(), pos.y(), pos.z(), dx);
-            }
             nIter += 1;
         }
         return pos;
@@ -378,12 +383,10 @@
         double sinPhi = (xc - x) / R;
         double phi_at_x = Math.asin(sinPhi);
         double dphi_at_x = phi_at_x - phi0;
-        if (dphi_at_x > Math.PI) {
+        if (dphi_at_x > Math.PI)
             dphi_at_x -= 2.0 * Math.PI;
-        }
-        if (dphi_at_x < -Math.PI) {
+        if (dphi_at_x < -Math.PI)
             dphi_at_x += 2.0 * Math.PI;
-        }
         double s_at_x = -1.0 * dphi_at_x * R;
         double y = dca * Math.cos(phi0) - R * Math.cos(phi0) + R * Math.cos(phi_at_x);
         double z = z0 + s_at_x * slope;
@@ -391,9 +394,8 @@
         // System.out.printf("pos %s xc %f phi_at_x %f dphi_at_x %f s_at_x %f\n",
         // pos.toString(),xc,phi_at_x,dphi_at_x,s_at_x);
         Hep3Vector posXCheck = TrackUtils.extrapolateHelixToXPlane(helix, x);
-        if (VecOp.sub(pos, posXCheck).magnitude() > 0.0000001) {
+        if (VecOp.sub(pos, posXCheck).magnitude() > 0.0000001)
             throw new RuntimeException(String.format("ERROR the helix propagation equations do not agree? (%f,%f,%f) vs (%f,%f,%f) in HelixUtils", pos.x(), pos.y(), pos.z(), posXCheck.x(), posXCheck.y(), posXCheck.z()));
-        }
         return pos;
     }
 
@@ -413,49 +415,42 @@
 
         Box sensorSolid = (Box) sensor.getGeometry().getLogicalVolume().getSolid();
         Polygon3D sensorFace = sensorSolid.getFacesNormalTo(new BasicHep3Vector(0, 0, 1)).get(0);
-        if (debug) {
+        if (debug)
             System.out.println("sensorContainsTrack:  Track Position: " + trackPosition.toString());
-        }
 
         List<Point3D> vertices = new ArrayList<Point3D>();
-        for (int index = 0; index < 4; index++) {
+        for (int index = 0; index < 4; index++)
             vertices.add(new Point3D());
-        }
-        for (Point3D vertex : sensorFace.getVertices()) {
+        for (Point3D vertex : sensorFace.getVertices())
             if (vertex.y() < 0 && vertex.x() > 0) {
                 localToGlobal.transform(vertex);
                 // vertices.set(0, new Point3D(vertex.y() + sensorPos.x(), vertex.x() +
                 // sensorPos.y(), vertex.z() + sensorPos.z()));
                 vertices.set(0, new Point3D(vertex.x(), vertex.y(), vertex.z()));
-                if (debug) {
-                    System.out.println("sensorContainsTrack:  Vertex 1 Position: " + vertices.get(0).toString()); // System.out.println("sensorContainsTrack:  Transformed Vertex 1 Position: " +
-                }                // localToGlobal.transformed(vertex).toString());
+                if (debug)
+                    System.out.println("sensorContainsTrack:  Vertex 1 Position: " + vertices.get(0).toString()); // System.out.println("sensorContainsTrack:  Transformed Vertex 1 Position: " +                // localToGlobal.transformed(vertex).toString());
             } else if (vertex.y() > 0 && vertex.x() > 0) {
                 localToGlobal.transform(vertex);
                 // vertices.set(1, new Point3D(vertex.y() + sensorPos.x(), vertex.x() +
                 // sensorPos.y(), vertex.z() + sensorPos.z()));
                 vertices.set(1, new Point3D(vertex.x(), vertex.y(), vertex.z()));
-                if (debug) {
-                    System.out.println("sensorContainsTrack:  Vertex 2 Position: " + vertices.get(1).toString()); // System.out.println("sensorContainsTrack:  Transformed Vertex 2 Position: " +
-                }                // localToGlobal.transformed(vertex).toString());
+                if (debug)
+                    System.out.println("sensorContainsTrack:  Vertex 2 Position: " + vertices.get(1).toString()); // System.out.println("sensorContainsTrack:  Transformed Vertex 2 Position: " +                // localToGlobal.transformed(vertex).toString());
             } else if (vertex.y() > 0 && vertex.x() < 0) {
                 localToGlobal.transform(vertex);
                 // vertices.set(2, new Point3D(vertex.y() + sensorPos.x(), vertex.x() +
                 // sensorPos.y(), vertex.z() + sensorPos.z()));
                 vertices.set(2, new Point3D(vertex.x(), vertex.y(), vertex.z()));
-                if (debug) {
-                    System.out.println("sensorContainsTrack:  Vertex 3 Position: " + vertices.get(2).toString()); // System.out.println("sensorContainsTrack:  Transformed Vertex 3 Position: " +
-                }                // localToGlobal.transformed(vertex).toString());
+                if (debug)
+                    System.out.println("sensorContainsTrack:  Vertex 3 Position: " + vertices.get(2).toString()); // System.out.println("sensorContainsTrack:  Transformed Vertex 3 Position: " +                // localToGlobal.transformed(vertex).toString());
             } else if (vertex.y() < 0 && vertex.x() < 0) {
                 localToGlobal.transform(vertex);
                 // vertices.set(3, new Point3D(vertex.y() + sensorPos.x(), vertex.x() +
                 // sensorPos.y(), vertex.z() + sensorPos.z()));
                 vertices.set(3, new Point3D(vertex.x(), vertex.y(), vertex.z()));
-                if (debug) {
-                    System.out.println("sensorContainsTrack:  Vertex 4 Position: " + vertices.get(3).toString()); // System.out.println("sensorContainsTrack:  Transformed Vertex 4 Position: " +
-                }                // localToGlobal.transformed(vertex).toString());
+                if (debug)
+                    System.out.println("sensorContainsTrack:  Vertex 4 Position: " + vertices.get(3).toString()); // System.out.println("sensorContainsTrack:  Transformed Vertex 4 Position: " +                // localToGlobal.transformed(vertex).toString());
             }
-        }
 
         double area1 = TrackUtils.findTriangleArea(vertices.get(0).x(), vertices.get(0).y(), vertices.get(1).x(), vertices.get(1).y(), trackPosition.y(), trackPosition.z());
         double area2 = TrackUtils.findTriangleArea(vertices.get(1).x(), vertices.get(1).y(), vertices.get(2).x(), vertices.get(2).y(), trackPosition.y(), trackPosition.z());
@@ -556,10 +551,9 @@
         boolean debug = false;
         boolean includeMS = true;
 
-        if (debug) {
+        if (debug)
             System.out.printf("calculateLocalTrackHitResiduals: for strip on sensor %s \n",
                     ((RawTrackerHit) strip.getStrip().rawhits().get(0)).getDetectorElement().getName());
-        }
 
         Hep3Vector u = strip.u();
         Hep3Vector corigin = strip.origin();
@@ -604,10 +598,9 @@
         double wmeas = 0;
         double wError = 10.0 / Math.sqrt(12); // 0.001;
 
-        if (debug) {
+        if (debug)
             System.out.printf("calculateLocalTrackHitResiduals: vdiffTrk %s vdiff %s umc %f umeas %f du %f\n",
                     vdiffTrk.toString(), vdiff.toString(), umc, umeas, umeas - umc);
-        }
 
         Map<String, Double> res = new HashMap<String, Double>();
         res.put("ures", umeas - umc);
@@ -629,11 +622,10 @@
             HelicalTrackHit hth = (HelicalTrackHit) hit;
             //===> if (SvtUtils.getInstance().isTopLayer((SiSensor) ((RawTrackerHit) hth.getRawHits().get(0)).getDetectorElement())) {
             HpsSiSensor sensor = ((HpsSiSensor) ((RawTrackerHit) hth.getRawHits().get(0)).getDetectorElement());
-            if (sensor.isTopLayer()) {
+            if (sensor.isTopLayer())
                 n[0] = n[0] + 1;
-            } else {
+            else
                 n[1] = n[1] + 1;
-            }
         }
         return n;
     }
@@ -648,13 +640,12 @@
 
     public static int isTopOrBottomTrack(Track track, int minhits) {
         int nhits[] = getHitsInTopBottom(track);
-        if (nhits[0] >= minhits && nhits[1] == 0) {
+        if (nhits[0] >= minhits && nhits[1] == 0)
             return 1;
-        } else if (nhits[1] >= minhits && nhits[0] == 0) {
+        else if (nhits[1] >= minhits && nhits[0] == 0)
             return 0;
-        } else {
+        else
             return -1;
-        }
     }
 
     public static boolean hasTopBotHit(Track track) {
@@ -669,9 +660,8 @@
             for (TrackerHit loop_hit : hitsOnTrack) {
                 HelicalTrackHit loop_hth = (HelicalTrackHit) loop_hit;
                 if (hth.equals(loop_hth)) // System.out.printf("share hit at layer %d at %s (%s) with track w/ chi2=%f\n",hth.Layer(),hth.getCorrectedPosition().toString(),loop_hth.getCorrectedPosition().toString(),track.getChi2());
-                {
+
                     return true;
-                }
             }
         }
         return false;
@@ -684,19 +674,16 @@
         for (Track t : tracklist) {
             // System.out.printf("add track with chi2=%f and px=%f ?\n",t.getChi2(),t.getTrackStates().get(0).getMomentum()[0]);
             if (t.equals(track)) // System.out.printf("NOPE\n");
-            {
+
                 continue;
-            }
             // System.out.printf("YEPP\n");
             tracks.add(t);
         }
         List<TrackerHit> hitsOnTrack = track.getTrackerHits();
         int n_shared = 0;
-        for (TrackerHit hit : hitsOnTrack) {
-            if (isSharedHit(hit, tracks)) {
+        for (TrackerHit hit : hitsOnTrack)
+            if (isSharedHit(hit, tracks))
                 ++n_shared;
-            }
-        }
         return n_shared;
     }
 
@@ -716,21 +703,16 @@
     public static int passTrackSelections(Track track, List<Track> tracklist, EventQuality.Quality trk_quality) {
         int cuts[] = {0};
         if (trk_quality.compareTo(Quality.NONE) != 0) {
-            if (track.getTrackStates().get(0).getMomentum()[0] < EventQuality.instance().getCutValue(EventQuality.Cut.PZ, trk_quality)) {
+            if (track.getTrackStates().get(0).getMomentum()[0] < EventQuality.instance().getCutValue(EventQuality.Cut.PZ, trk_quality))
                 cut(cuts, EventQuality.Cut.PZ);
-            }
-            if (track.getChi2() >= EventQuality.instance().getCutValue(EventQuality.Cut.CHI2, trk_quality)) {
+            if (track.getChi2() >= EventQuality.instance().getCutValue(EventQuality.Cut.CHI2, trk_quality))
                 cut(cuts, EventQuality.Cut.CHI2);
-            }
-            if (numberOfSharedHits(track, tracklist) > ((int) Math.round(EventQuality.instance().getCutValue(EventQuality.Cut.SHAREDHIT, trk_quality)))) {
+            if (numberOfSharedHits(track, tracklist) > ((int) Math.round(EventQuality.instance().getCutValue(EventQuality.Cut.SHAREDHIT, trk_quality))))
                 cut(cuts, EventQuality.Cut.SHAREDHIT);
-            }
-            if (hasTopBotHit(track)) {
+            if (hasTopBotHit(track))
                 cut(cuts, EventQuality.Cut.TOPBOTHIT);
-            }
-            if (track.getTrackerHits().size() < ((int) Math.round(EventQuality.instance().getCutValue(EventQuality.Cut.NHITS, trk_quality)))) {
+            if (track.getTrackerHits().size() < ((int) Math.round(EventQuality.instance().getCutValue(EventQuality.Cut.NHITS, trk_quality))))
                 cut(cuts, EventQuality.Cut.NHITS);
-            }
         }
         return cuts[0];
     }
@@ -759,9 +741,8 @@
         Hep3Vector org = CoordinateTransformations.transformVectorToTracking(mcp.getOrigin());
         Hep3Vector p = CoordinateTransformations.transformVectorToTracking(mcp.getMomentum());
 
-        if (debug) {
+        if (debug)
             System.out.printf("mcp org %s mc p %s (trans)\n", org.toString(), p.toString());
-        }
 
         // Move to x=0 if needed
         double targetX = BeamlineConstants.DIPOLE_EDGELOW_TESTRUN;
@@ -772,17 +753,15 @@
             double y = delta_x * dydx + org.y();
             double z = delta_x * dzdx + org.z();
             double x = org.x() + delta_x;
-            if (Math.abs(x - targetX) > 1e-8) {
+            if (Math.abs(x - targetX) > 1e-8)
                 throw new RuntimeException("Error: origin is not zero!");
-            }
             org = new BasicHep3Vector(x, y, z);
             // System.out.printf("org %s p %s -> org %s\n",
             // old.toString(),p.toString(),org.toString());
         }
 
-        if (debug) {
+        if (debug)
             System.out.printf("mcp org %s mc p %s (trans2)\n", org.toString(), p.toString());
-        }
 
         HelixParamCalculator helixParamCalculator = new HelixParamCalculator(p, org, -1 * ((int) mcp.getCharge()), Bz);
         double par[] = new double[5];
@@ -798,19 +777,17 @@
     }
 
     public static HelicalTrackFit getHTF(Track track) {
-        if (track.getClass().isInstance(SeedTrack.class)) {
+        if (track.getClass().isInstance(SeedTrack.class))
             return ((SeedTrack) track).getSeedCandidate().getHelix();
-        } else {
+        else
             return getHTF(track.getTrackStates().get(0).getParameters());
-        }
     }
 
     public static HelicalTrackFit getHTF(double par[]) {
         // need to have matrix that makes sense? Really?
         SymmetricMatrix cov = new SymmetricMatrix(5);
-        for (int i = 0; i < cov.getNRows(); ++i) {
+        for (int i = 0; i < cov.getNRows(); ++i)
             cov.setElement(i, i, 1.);
-        }
         HelicalTrackFit htf = new HelicalTrackFit(par, cov, new double[2], new int[2], null, null);
         return htf;
     }
@@ -823,9 +800,8 @@
         if (useFringe) {
             // broken because you need ot provide the Field Map to get this...
 //            pos1 = hpstrk1.getPositionAtZMap(100.0, zVal, 5.0)[0];            
-        } else {
+        } else
             pos1 = TrackUtils.extrapolateTrack(trk1, zVal);
-        }
         // System.out.printf("%s: Position1 at edge of fringe %s\n",this.getClass().getSimpleName(),pos1.toString());
         Helix traj = (Helix) hpstrk1.getTrajectory();
         if (traj == null) {
@@ -843,22 +819,19 @@
 
         Map<MCParticle, Integer> particlesOnTrack = new HashMap<MCParticle, Integer>();
 
-        if (debug) {
+        if (debug)
             System.out.printf("getMatchedTruthParticle: getmatched mc particle from %d tracker hits on the track \n", track.getTrackerHits().size());
-        }
 
         for (TrackerHit hit : track.getTrackerHits()) {
             List<MCParticle> mcps = ((HelicalTrackHit) hit).getMCParticles();
-            if (mcps == null) {
+            if (mcps == null)
                 System.out.printf("getMatchedTruthParticle: warning, this hit (layer %d pos=%s) has no mc particles.\n", ((HelicalTrackHit) hit).Layer(), ((HelicalTrackHit) hit).getCorrectedPosition().toString());
-            } else {
-                if (debug) {
+            else {
+                if (debug)
                     System.out.printf("getMatchedTruthParticle: this hit (layer %d pos=%s) has %d mc particles.\n", ((HelicalTrackHit) hit).Layer(), ((HelicalTrackHit) hit).getCorrectedPosition().toString(), mcps.size());
-                }
                 for (MCParticle mcp : mcps) {
-                    if (!particlesOnTrack.containsKey(mcp)) {
+                    if (!particlesOnTrack.containsKey(mcp))
                         particlesOnTrack.put(mcp, 0);
-                    }
                     int c = particlesOnTrack.get(mcp);
                     particlesOnTrack.put(mcp, c + 1);
                 }
@@ -867,26 +840,21 @@
         if (debug) {
             System.out.printf("Track p=[ %f, %f, %f] \n", track.getTrackStates().get(0).getMomentum()[0], track.getTrackStates().get(0).getMomentum()[1], track.getTrackStates().get(0).getMomentum()[1]);
             System.out.printf("Found %d particles\n", particlesOnTrack.size());
-            for (Map.Entry<MCParticle, Integer> entry : particlesOnTrack.entrySet()) {
+            for (Map.Entry<MCParticle, Integer> entry : particlesOnTrack.entrySet())
                 System.out.printf("%d hits assigned to %d p=%s \n", entry.getValue(), entry.getKey().getPDGID(), entry.getKey().getMomentum().toString());
-            }
         }
         Map.Entry<MCParticle, Integer> maxEntry = null;
-        for (Map.Entry<MCParticle, Integer> entry : particlesOnTrack.entrySet()) {
-            if (maxEntry == null || entry.getValue().compareTo(maxEntry.getValue()) > 0) {
-                maxEntry = entry; //if ( maxEntry != null ) {
-            }        //    if(entry.getValue().compareTo(maxEntry.getValue()) < 0) continue;
-        }        //}
+        for (Map.Entry<MCParticle, Integer> entry : particlesOnTrack.entrySet())
+            if (maxEntry == null || entry.getValue().compareTo(maxEntry.getValue()) > 0)
+                maxEntry = entry; //if ( maxEntry != null ) { //    if(entry.getValue().compareTo(maxEntry.getValue()) < 0) continue;        //}
         //maxEntry = entry;
-        if (debug) {
-            if (maxEntry != null) {
+        if (debug)
+            if (maxEntry != null)
                 System.out.printf("Matched particle with pdgId=%d and mom %s to track with charge %d and momentum [%f %f %f]\n",
                         maxEntry.getKey().getPDGID(), maxEntry.getKey().getMomentum().toString(),
                         track.getCharge(), track.getTrackStates().get(0).getMomentum()[0], track.getTrackStates().get(0).getMomentum()[1], track.getTrackStates().get(0).getMomentum()[2]);
-            } else {
+            else
                 System.out.printf("No truth particle found on this track\n");
-            }
-        }
         return maxEntry == null ? null : maxEntry.getKey();
     }
 
@@ -910,9 +878,8 @@
         //  now get the hits and make them helicaltrackhits
         List<TrackerHit> rth = track.getTrackerHits();
         List<HelicalTrackHit> hth = new ArrayList<>();
-        for (TrackerHit hit : rth) {
+        for (TrackerHit hit : rth)
             hth.add(makeHelicalTrackHitFromTrackerHit(hit));
-        }
 //        SeedCandidate(List<HelicalTrackHit> , SeedStrategy strategy, HelicalTrackFit helix, double bfield) ;
         SeedCandidate scand = new SeedCandidate(hth, null, htf, 0.24);
         SeedTrack st = new SeedTrack();
@@ -942,11 +909,9 @@
     public static RelationalTable getHitToStripsTable(EventHeader event) {
         RelationalTable hitToStrips = new BaseRelationalTable(RelationalTable.Mode.MANY_TO_MANY, RelationalTable.Weighting.UNWEIGHTED);
         List<LCRelation> hitrelations = event.get(LCRelation.class, "HelicalTrackHitRelations");
-        for (LCRelation relation : hitrelations) {
-            if (relation != null && relation.getFrom() != null && relation.getTo() != null) {
+        for (LCRelation relation : hitrelations)
+            if (relation != null && relation.getFrom() != null && relation.getTo() != null)
                 hitToStrips.add(relation.getFrom(), relation.getTo());
-            }
-        }
 
         return hitToStrips;
     }
@@ -955,11 +920,9 @@
 
         RelationalTable hitToRotated = new BaseRelationalTable(RelationalTable.Mode.ONE_TO_ONE, RelationalTable.Weighting.UNWEIGHTED);
         List<LCRelation> rotaterelations = event.get(LCRelation.class, "RotatedHelicalTrackHitRelations");
-        for (LCRelation relation : rotaterelations) {
-            if (relation != null && relation.getFrom() != null && relation.getTo() != null) {
+        for (LCRelation relation : rotaterelations)
+            if (relation != null && relation.getFrom() != null && relation.getTo() != null)
                 hitToRotated.add(relation.getFrom(), relation.getTo());
-            }
-        }
         return hitToRotated;
     }
 
@@ -979,16 +942,12 @@
 
     public static boolean hasSharedStrips(Track track1, Track track2, RelationalTable hitToStrips, RelationalTable hitToRotated) {
         Set<TrackerHit> track1hits = new HashSet<TrackerHit>();
-        for (TrackerHit hit : track1.getTrackerHits()) {
+        for (TrackerHit hit : track1.getTrackerHits())
             track1hits.addAll(hitToStrips.allFrom(hitToRotated.from(hit)));
-        }
-        for (TrackerHit hit : track2.getTrackerHits()) {
-            for (TrackerHit hts : (Set<TrackerHit>) hitToStrips.allFrom(hitToRotated.from(hit))) {
-                if (track1hits.contains(hts)) {
+        for (TrackerHit hit : track2.getTrackerHits())
+            for (TrackerHit hts : (Set<TrackerHit>) hitToStrips.allFrom(hitToRotated.from(hit)))
+                if (track1hits.contains(hts))
                     return true;
-                }
-            }
-        }
         return false;
     }
 
@@ -1009,8 +968,8 @@
      */
     public static double getIsolation(TrackerHit strip, TrackerHit otherStrip, RelationalTable hitToStrips, RelationalTable hitToRotated) {
         double nearestDistance = 99999999.0;
-        for (TrackerHit cross : (Set<TrackerHit>) hitToStrips.allTo(otherStrip)) {
-            for (TrackerHit crossStrip : (Set<TrackerHit>) hitToStrips.allFrom(cross)) {
+        for (TrackerHit cross : (Set<TrackerHit>) hitToStrips.allTo(otherStrip))
+            for (TrackerHit crossStrip : (Set<TrackerHit>) hitToStrips.allFrom(cross))
                 if (crossStrip != strip && crossStrip != otherStrip) {
                     int stripMin = Integer.MAX_VALUE;
                     int stripMax = Integer.MIN_VALUE;
@@ -1026,27 +985,22 @@
                         crossMin = Math.min(crossMin, hitStrip);
                         crossMax = Math.max(crossMax, hitStrip);
                     }
-                    if (stripMin - crossMax <= 1 && crossMin - stripMax <= 1) {
+                    if (stripMin - crossMax <= 1 && crossMin - stripMax <= 1)
                         continue; //adjacent strips don't count
-                    }
                     Hep3Vector stripPosition = new BasicHep3Vector(strip.getPosition());
                     Hep3Vector crossStripPosition = new BasicHep3Vector(crossStrip.getPosition());
                     double distance = VecOp.sub(stripPosition, crossStripPosition).magnitude();
-                    if (Math.abs(stripPosition.y()) > Math.abs(crossStripPosition.y())) {
+                    if (Math.abs(stripPosition.y()) > Math.abs(crossStripPosition.y()))
                         distance = -distance;
-                    }
 //                    System.out.format("%s, %s, %s, %f\n", stripPosition, crossStripPosition, VecOp.sub(stripPosition, crossStripPosition), distance);
 //                    if (distance<=0.0601) continue; //hack to avoid counting adjacent strips that didn't get clustered together
 //                    if (distance<0.1) System.out.format("%d, %d, %f\n",strip.getRawHits().size(),crossStrip.getRawHits().size(), distance);
 //                    if (distance < 0.1) {
 //                        System.out.format("%s, %s, %s, %f\n", stripPosition, crossStripPosition, VecOp.sub(stripPosition, crossStripPosition), distance);
 //                    }
-                    if (Math.abs(distance) < Math.abs(nearestDistance)) {
+                    if (Math.abs(distance) < Math.abs(nearestDistance))
                         nearestDistance = distance;
-                    }
                 }
-            }
-        }
         return nearestDistance;
     }
 
@@ -1071,4 +1025,167 @@
         }
         return isolations;
     }
+
+    /**
+     * iteratively extrapolates a track to a specified value of z using the full
+     * field map.
+     *
+     * @param track
+     * @param start = value to start extrapolation (use analytic=constant field
+     * calculation up to here)
+     * @param zFinal = value to extrapolate to
+     * @param step = step size
+     * @param bmap = the field map
+     * @param debugOk
+     * @return
+     */
+    public TrackState extrapolateTrackUsingFieldMap(Track track, double start, double zFinal, double step, FieldMap bmap, boolean debugOk) {
+        Trajectory _trajectory;
+        double startFringe = start;
+        HelicalTrackFit helix = getHTF(track);
+
+        // if looking upstream, we'll be propagating backwards
+        if (zFinal < 0)
+            step = -step;
+        if (debugOk)
+            System.out.println(track.toString());
+
+        double sStartFringe = HelixUtils.PathToXPlane(helix, startFringe, 1000.0, 1).get(0);
+        if (debugOk)
+            System.out.println("path to end of fringe = " + sStartFringe + "; zFinal = " + zFinal);
+        double xtmp = startFringe;
+        double ytmp = HelixUtils.PointOnHelix(helix, sStartFringe).y();
+        double ztmp = HelixUtils.PointOnHelix(helix, sStartFringe).z();
+        double Rorig = helix.R();
+        double xCtmp = helix.xc();
+        double yCtmp = helix.yc();
+        double q = Math.signum(helix.curvature());
+        double phitmp = calculatePhi(xtmp, ytmp, xCtmp, yCtmp, q);
+        if (debugOk) {
+            System.out.println("\nOriginal xtmp = " + xtmp + "; ytmp = " + ytmp + "; ztmp = " + ztmp + "; phitmp = " + phitmp);
+
+            System.out.println("nOriginal Rorig = " + Rorig + "; xCtmp = " + xCtmp + "; yCtmp = " + yCtmp);
+        }
+        if (debugOk)
+            System.out.println("Original Direction at Fringe: " + HelixUtils.Direction(helix, startFringe).toString());
+        double Rtmp = Rorig;
+        // now start stepping through the fringe field
+        Hep3Vector r0Tmp = HelixUtils.PointOnHelix(helix, sStartFringe);
+        org.lcsim.spacegeom.SpacePoint r0 = new org.lcsim.spacegeom.SpacePoint(r0Tmp);
+        Hep3Vector bMid = bmap.getField(new BasicHep3Vector(0, 0, 500.0));
+        double pTot = helix.p(bMid.y());//50 cm ~ middle of dipole
+        Hep3Vector dirOrig = HelixUtils.Direction(helix, sStartFringe);
+        Hep3Vector p0 = VecOp.mult(pTot, dirOrig);
+        Hep3Vector dirTmp = dirOrig;
+        org.lcsim.spacegeom.SpacePoint rTmp = r0;
+        Hep3Vector pTmp = p0;
+        double pXOrig = p0.x();
+        double pXTmp = pXOrig;
+        double totalS = sStartFringe;
+        double myBField = bMid.y();
+        // follow trajectory while: in fringe field, before end point, and we don't have a looper
+        while (Math.signum(step) * xtmp < Math.signum(step) * zFinal && Math.signum(pXOrig * pXTmp) > 0) {
+            if (debugOk) {
+                System.out.println("New step in Fringe Field");
+                System.out.println("rTmp = " + rTmp.toString());
+                System.out.println("pTmp = " + pTmp.toString());
+                System.out.println("OriginalHelix pos = " + HelixUtils.PointOnHelix(helix, totalS));
+                System.out.println("OriginalHelix Momentum = " + VecOp.mult(pTot, HelixUtils.Direction(helix, totalS)));
+            }
+
+            myBField = bmap.getField(new BasicHep3Vector(rTmp.y(), rTmp.z(), rTmp.x())).y(); // note weird co ordinates for track vs det   
+            if (debugOk)
+                System.out.println("rTmp.x() = " + rTmp.x() + " field = " + myBField);
+            _trajectory = getTrajectory(pTmp, rTmp, q, myBField);
+            rTmp = _trajectory.getPointAtDistance(step);
+            pTmp = VecOp.mult(pTot, _trajectory.getUnitTangentAtLength(step));
+            pXTmp = pTmp.x();
+            xtmp = rTmp.x();
+            if (debugOk) {
+                System.out.println("##############   done...    #############");
+
+                System.out.println("\n");
+            }
+            totalS += step;
+        }
+        myBField = bmap.getField(new BasicHep3Vector(rTmp.y(), rTmp.z(), rTmp.x())).y(); // note weird co ordinates for track vs det   
+        _trajectory = getTrajectory(pTmp, rTmp, q, myBField);
+        // Go with finer granularity in the end
+        rTmp = _trajectory.getPointAtDistance(0);
+        xtmp = rTmp.x();
+        pTmp = VecOp.mult(pTot, _trajectory.getUnitTangentAtLength(step));
+        pXTmp = pTmp.x();
+        step = step / 10.0;
+
+        while (Math.signum(step) * xtmp < Math.signum(step) * zFinal && Math.signum(pXOrig * pXTmp) > 0) {
+            if (debugOk) {
+                System.out.println("New step in Fringe Field");
+                System.out.println("rTmp = " + rTmp.toString());
+                System.out.println("pTmp = " + pTmp.toString());
+                System.out.println("OriginalHelix pos = " + HelixUtils.PointOnHelix(helix, totalS));
+                System.out.println("OriginalHelix Momentum = " + VecOp.mult(pTot, HelixUtils.Direction(helix, totalS)));
+            }
+
+            myBField = bmap.getField(new BasicHep3Vector(rTmp.y(), rTmp.z(), rTmp.x())).y(); // note weird co ordinates for track vs det   
+
+            if (debugOk)
+                System.out.println("rTmp.x() = " + rTmp.x() + " field = " + myBField);
+            _trajectory = getTrajectory(pTmp, rTmp, q, myBField);
+            rTmp = _trajectory.getPointAtDistance(step);
+            pTmp = VecOp.mult(pTot, _trajectory.getUnitTangentAtLength(step));
+            pXTmp = pTmp.x();
+            xtmp = rTmp.x();
+            if (debugOk) {
+                System.out.println("##############   done...    #############");
+                System.out.println("\n");
+            }
+            totalS += step;
+        }
+
+        // ok, done with field.
+        //store the helical track parameters at rTmp
+        double pars[] = {Math.sqrt(rTmp.x() * rTmp.x() + rTmp.y() * rTmp.y()),
+            calculatePhi(pTmp.x(), pTmp.y()),
+            calculateCurvature(pTmp.magnitude(), q, myBField),
+            calculateLambda(pTmp.z(), pTmp.magnitude()),
+            rTmp.z()};
+        Hep3Vector pointInTrking = new BasicHep3Vector(rTmp.x(), rTmp.y(), rTmp.z());
+
+        if (debugOk)
+            System.out.println("Position xfinal (tracking) :  x = " + zFinal + "; y = " + pointInTrking.y() + "; z = " + pointInTrking.z());
+        BaseTrackState ts = new BaseTrackState(pars, myBField);
+        ts.setReferencePoint(pointInTrking.v());
+        ts.setLocation(TrackState.AtCalorimeter);
+        return ts;
+    }
+
+    public double calculatePhi(double x, double y, double xc, double yc, double sign) {
+        return Math.atan2(y - yc, x - xc) - sign * Math.PI / 2;
+    }
+
+    public double calculatePhi(double px, double py) {
+        return Math.atan2(py, px);
+    }
+
+    public double calculateLambda(double pz, double p) {
+        return Math.atan2(pz, p);
+    }
+
+    public double calculateCurvature(double p, double q, double B) {
+        return q * B / p;
+    }
+
+    public Trajectory getTrajectory(Hep3Vector p0, org.lcsim.spacegeom.SpacePoint r0, double q, double B) {
+        SpaceVector p = new CartesianVector(p0.v());
+        double phi = Math.atan2(p.y(), p.x());
+        double lambda = Math.atan2(p.z(), p.rxy());
+        double field = B * fieldConversion;
+
+        if (q != 0 && field != 0) {
+            double radius = p.rxy() / (q * field);
+            return new Helix(r0, radius, phi, lambda);
+        } else
+            return new Line(r0, phi, lambda);
+    }
+
 }