Print

Print


Author: [log in to unmask]
Date: Wed Nov 25 13:26:06 2015
New Revision: 3989

Log:
cleanup

Modified:
    java/trunk/tracking/src/main/java/org/hps/recon/tracking/gbl/GBLRefitterDriver.java
    java/trunk/tracking/src/main/java/org/hps/recon/tracking/gbl/GblUtils.java
    java/trunk/tracking/src/main/java/org/hps/recon/tracking/gbl/HpsGblRefitter.java
    java/trunk/tracking/src/main/java/org/hps/recon/tracking/gbl/MakeGblTracks.java

Modified: java/trunk/tracking/src/main/java/org/hps/recon/tracking/gbl/GBLRefitterDriver.java
 =============================================================================
--- java/trunk/tracking/src/main/java/org/hps/recon/tracking/gbl/GBLRefitterDriver.java	(original)
+++ java/trunk/tracking/src/main/java/org/hps/recon/tracking/gbl/GBLRefitterDriver.java	Wed Nov 25 13:26:06 2015
@@ -69,7 +69,7 @@
 
         Map<Track, Track> inputToRefitted = new HashMap<Track, Track>();
         for (Track track : tracks) {
-            Pair<Track, GBLKinkData> newTrack = GblUtils.refitTrack(TrackUtils.getHTF(track), TrackUtils.getStripHits(track, hitToStrips, hitToRotated), track.getTrackerHits(), 5, _scattering, bfield);
+            Pair<Track, GBLKinkData> newTrack = MakeGblTracks.refitTrack(TrackUtils.getHTF(track), TrackUtils.getStripHits(track, hitToStrips, hitToRotated), track.getTrackerHits(), 5, _scattering, bfield);
             refittedTracks.add(newTrack.getFirst());
             inputToRefitted.put(track, newTrack.getFirst());
         }
@@ -106,7 +106,7 @@
                         }
                     }
 
-                    Pair<Track, GBLKinkData> mergedTrack = GblUtils.refitTrack(TrackUtils.getHTF(track), TrackUtils.getStripHits(track, hitToStrips, hitToRotated), allHth, 5, _scattering, bfield);
+                    Pair<Track, GBLKinkData> mergedTrack = MakeGblTracks.refitTrack(TrackUtils.getHTF(track), TrackUtils.getStripHits(track, hitToStrips, hitToRotated), allHth, 5, _scattering, bfield);
                     mergedTracks.add(mergedTrack.getFirst());
 //                    System.out.format("%f %f %f\n", fit.get_chi2(), inputToRefitted.get(track).getChi2(), inputToRefitted.get(otherTrack).getChi2());
 //                mergedTrackToTrackList.put(mergedTrack, new ArrayList<Track>());

Modified: java/trunk/tracking/src/main/java/org/hps/recon/tracking/gbl/GblUtils.java
 =============================================================================
--- java/trunk/tracking/src/main/java/org/hps/recon/tracking/gbl/GblUtils.java	(original)
+++ java/trunk/tracking/src/main/java/org/hps/recon/tracking/gbl/GblUtils.java	Wed Nov 25 13:26:06 2015
@@ -1,35 +1,11 @@
 package org.hps.recon.tracking.gbl;
 
 import hep.physics.matrix.BasicMatrix;
-import hep.physics.vec.BasicHep3Vector;
-import hep.physics.vec.Hep3Matrix;
-import hep.physics.vec.Hep3Vector;
-import hep.physics.vec.VecOp;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-import org.apache.commons.math3.util.Pair;
-import org.hps.recon.tracking.CoordinateTransformations;
 import org.hps.recon.tracking.MaterialSupervisor;
 import org.hps.recon.tracking.MultipleScattering;
-import org.hps.recon.tracking.TrackUtils;
-import org.lcsim.constants.Constants;
 import org.lcsim.detector.IDetectorElement;
-import org.lcsim.detector.ITransform3D;
-import org.lcsim.detector.tracker.silicon.ChargeCarrier;
-import org.lcsim.detector.tracker.silicon.HpsSiSensor;
-import org.lcsim.detector.tracker.silicon.SiSensor;
-import org.lcsim.detector.tracker.silicon.SiSensorElectrodes;
-import org.lcsim.event.RawTrackerHit;
-import org.lcsim.event.Track;
-import org.lcsim.event.TrackerHit;
 import org.lcsim.fit.helicaltrack.HelicalTrackFit;
-import org.lcsim.fit.helicaltrack.HelicalTrackStrip;
 import org.lcsim.fit.helicaltrack.HelixUtils;
-import org.lcsim.recon.tracking.digitization.sisim.SiTrackerHitStrip1D;
-import org.lcsim.recon.tracking.digitization.sisim.TrackerHitType;
 import org.lcsim.recon.tracking.seedtracker.ScatterAngle;
 
 /**
@@ -129,216 +105,4 @@
             throw new UnsupportedOperationException("Should not happen. This problem is only solved with the MaterialSupervisor.");
         }
     }
-
-    /**
-     * Do a GBL fit to an arbitrary set of strip hits, with a starting value of
-     * the helix parameters.
-     *
-     * @param helix Initial helix parameters. Only track parameters are used
-     * (not covariance)
-     * @param stripHits Strip hits to be used for the GBL fit. Does not need to
-     * be in sorted order.
-     * @param hth Stereo hits for the track's hit list (these are not used in
-     * the GBL fit). Does not need to be in sorted order.
-     * @param nIterations Number of times to iterate the GBL fit.
-     * @param scattering Multiple scattering manager.
-     * @param bfield B-field
-     * @return The refitted track.
-     */
-    public static Pair<Track, GBLKinkData> refitTrack(HelicalTrackFit helix, Collection<TrackerHit> stripHits, Collection<TrackerHit> hth, int nIterations, MultipleScattering scattering, double bfield) {
-        List<TrackerHit> allHthList = sortHits(hth);
-        List<TrackerHit> sortedStripHits = sortHits(stripHits);
-        FittedGblTrajectory fit = GblUtils.doGBLFit(helix, sortedStripHits, scattering, bfield, 0);
-        for (int i = 0; i < nIterations; i++) {
-            Pair<Track, GBLKinkData> newTrack = MakeGblTracks.makeCorrectedTrack(fit, helix, allHthList, 0, bfield);
-            helix = TrackUtils.getHTF(newTrack.getFirst());
-            fit = GblUtils.doGBLFit(helix, sortedStripHits, scattering, bfield, 0);
-        }
-        Pair<Track, GBLKinkData> mergedTrack = MakeGblTracks.makeCorrectedTrack(fit, helix, allHthList, 0, bfield);
-        return mergedTrack;
-    }
-
-    public static FittedGblTrajectory doGBLFit(HelicalTrackFit htf, List<TrackerHit> stripHits, MultipleScattering _scattering, double bfield, int debug) {
-        List<GBLStripClusterData> stripData = makeStripData(htf, stripHits, _scattering, bfield, debug);
-        double bfac = Constants.fieldConversion * bfield;
-
-        FittedGblTrajectory fit = HpsGblRefitter.fit(stripData, bfac, debug > 0);
-        return fit;
-    }
-
-    public static List<GBLStripClusterData> makeStripData(HelicalTrackFit htf, List<TrackerHit> stripHits, MultipleScattering _scattering, double _B, int _debug) {
-        List<GBLStripClusterData> stripClusterDataList = new ArrayList<GBLStripClusterData>();
-
-        // Find scatter points along the path
-        MultipleScattering.ScatterPoints scatters = _scattering.FindHPSScatterPoints(htf);
-
-        if (_debug > 0) {
-            System.out.printf("perPar covariance matrix\n%s\n", htf.covariance().toString());
-        }
-
-        for (TrackerHit stripHit : stripHits) {
-            HelicalTrackStripGbl strip;
-            if (stripHit instanceof SiTrackerHitStrip1D) {
-                strip = new HelicalTrackStripGbl(makeDigiStrip((SiTrackerHitStrip1D) stripHit), true);
-            } else {
-                SiTrackerHitStrip1D newHit = new SiTrackerHitStrip1D(stripHit);
-                strip = new HelicalTrackStripGbl(makeDigiStrip(newHit), true);
-            }
-
-            // find Millepede layer definition from DetectorElement
-            HpsSiSensor sensor = (HpsSiSensor) ((RawTrackerHit) stripHit.getRawHits().get(0)).getDetectorElement();
-
-            int millepedeId = sensor.getMillepedeId();
-
-            if (_debug > 0) {
-                System.out.printf("layer %d millepede %d (DE=\"%s\", origin %s) \n", strip.layer(), millepedeId, sensor.getName(), strip.origin().toString());
-            }
-
-            //Center of the sensor
-            Hep3Vector origin = strip.origin();
-
-            //Find intercept point with sensor in tracking frame
-            Hep3Vector trkpos = TrackUtils.getHelixPlaneIntercept(htf, strip, Math.abs(_B));
-            if (trkpos == null) {
-                if (_debug > 0) {
-                    System.out.println("Can't find track intercept; use sensor origin");
-                }
-                trkpos = strip.origin();
-            }
-            if (_debug > 0) {
-                System.out.printf("trkpos at intercept [%.10f %.10f %.10f]\n", trkpos.x(), trkpos.y(), trkpos.z());
-            }
-
-            //GBLDATA
-            GBLStripClusterData stripData = new GBLStripClusterData(millepedeId);
-            //Add to output list
-            stripClusterDataList.add(stripData);
-
-            //path length to intercept
-            double s = HelixUtils.PathToXPlane(htf, trkpos.x(), 0, 0).get(0);
-            double s3D = s / Math.cos(Math.atan(htf.slope()));
-
-            //GBLDATA
-            stripData.setPath(s);
-            stripData.setPath3D(s3D);
-
-            //GBLDATA
-            stripData.setU(strip.u());
-            stripData.setV(strip.v());
-            stripData.setW(strip.w());
-
-            //Print track direction at intercept
-            Hep3Vector tDir = HelixUtils.Direction(htf, s);
-            double phi = htf.phi0() - s / htf.R();
-            double lambda = Math.atan(htf.slope());
-
-            //GBLDATA
-            stripData.setTrackDir(tDir);
-            stripData.setTrackPhi(phi);
-            stripData.setTrackLambda(lambda);
-
-            //Print residual in measurement system
-            // start by find the distance vector between the center and the track position
-            Hep3Vector vdiffTrk = VecOp.sub(trkpos, origin);
-
-            // then find the rotation from tracking to measurement frame
-            Hep3Matrix trkToStripRot = getTrackToStripRotation(sensor);
-
-            // then rotate that vector into the measurement frame to get the predicted measurement position
-            Hep3Vector trkpos_meas = VecOp.mult(trkToStripRot, vdiffTrk);
-
-            //GBLDATA
-            stripData.setMeas(strip.umeas());
-            stripData.setTrackPos(trkpos_meas);
-            stripData.setMeasErr(strip.du());
-
-            if (_debug > 1) {
-                System.out.printf("rotation matrix to meas frame\n%s\n", VecOp.toString(trkToStripRot));
-                System.out.printf("tPosGlobal %s origin %s\n", trkpos.toString(), origin.toString());
-                System.out.printf("tDiff %s\n", vdiffTrk.toString());
-                System.out.printf("tPosMeas %s\n", trkpos_meas.toString());
-            }
-
-            if (_debug > 0) {
-                System.out.printf("layer %d millePedeId %d uRes %.10f\n", strip.layer(), millepedeId, stripData.getMeas() - stripData.getTrackPos().x());
-            }
-
-            // find scattering angle
-            MultipleScattering.ScatterPoint scatter = scatters.getScatterPoint(((RawTrackerHit) strip.getStrip().rawhits().get(0)).getDetectorElement());
-            double scatAngle;
-
-            if (scatter != null) {
-                scatAngle = scatter.getScatterAngle().Angle();
-            } else {
-                if (_debug > 0) {
-                    System.out.printf("WARNING cannot find scatter for detector %s with strip cluster at %s\n", ((RawTrackerHit) strip.getStrip().rawhits().get(0)).getDetectorElement().getName(), strip.origin().toString());
-                }
-                scatAngle = GblUtils.estimateScatter(sensor, htf, _scattering, _B);
-            }
-
-            //GBLDATA
-            stripData.setScatterAngle(scatAngle);
-        }
-        return stripClusterDataList;
-    }
-
-    private static Hep3Matrix getTrackToStripRotation(SiSensor sensor) {
-        // This function transforms the hit to the sensor coordinates
-
-        // Transform from JLab frame to sensor frame (done through the RawTrackerHit)
-        SiSensorElectrodes electrodes = sensor.getReadoutElectrodes(ChargeCarrier.HOLE);
-        ITransform3D detToStrip = electrodes.getGlobalToLocal();
-        // Get rotation matrix
-        Hep3Matrix detToStripMatrix = detToStrip.getRotation().getRotationMatrix();
-        // Transformation between the JLAB and tracking coordinate systems
-        Hep3Matrix detToTrackMatrix = CoordinateTransformations.getMatrix();
-
-        return VecOp.mult(detToStripMatrix, VecOp.inverse(detToTrackMatrix));
-    }
-
-    private static HelicalTrackStrip makeDigiStrip(SiTrackerHitStrip1D h) {
-        SiTrackerHitStrip1D local = h.getTransformedHit(TrackerHitType.CoordinateSystem.SENSOR);
-        SiTrackerHitStrip1D global = h.getTransformedHit(TrackerHitType.CoordinateSystem.GLOBAL);
-
-        ITransform3D trans = local.getLocalToGlobal();
-        Hep3Vector org = trans.transformed(new BasicHep3Vector(0., 0., 0.));
-        Hep3Vector u = global.getMeasuredCoordinate();
-        Hep3Vector v = global.getUnmeasuredCoordinate();
-
-        //rotate to tracking frame
-        Hep3Vector neworigin = CoordinateTransformations.transformVectorToTracking(org);
-        Hep3Vector newu = CoordinateTransformations.transformVectorToTracking(u);
-        Hep3Vector newv = CoordinateTransformations.transformVectorToTracking(v);
-
-        double umeas = local.getPosition()[0];
-        double vmin = VecOp.dot(local.getUnmeasuredCoordinate(), local.getHitSegment().getStartPoint());
-        double vmax = VecOp.dot(local.getUnmeasuredCoordinate(), local.getHitSegment().getEndPoint());
-        double du = Math.sqrt(local.getCovarianceAsMatrix().diagonal(0));
-
-        //don't fill fields we don't use
-//        IDetectorElement de = h.getSensor();
-//        String det = getName(de);
-//        int lyr = getLayer(de);
-//        BarrelEndcapFlag be = getBarrelEndcapFlag(de);
-        double dEdx = h.getdEdx();
-        double time = h.getTime();
-        List<RawTrackerHit> rawhits = h.getRawHits();
-        HelicalTrackStrip strip = new HelicalTrackStrip(neworigin, newu, newv, umeas, du, vmin, vmax, dEdx, time, rawhits, null, -1, null);
-
-        return strip;
-    }
-
-    private static List<TrackerHit> sortHits(Collection<TrackerHit> hits) {
-        List<TrackerHit> hitList = new ArrayList<TrackerHit>(hits);
-        Collections.sort(hitList, new LayerComparator());
-        return hitList;
-    }
-
-    private static class LayerComparator implements Comparator<TrackerHit> {
-
-        @Override
-        public int compare(TrackerHit o1, TrackerHit o2) {
-            return Integer.compare(TrackUtils.getLayer(o1), TrackUtils.getLayer(o2));
-        }
-    }
 }

Modified: java/trunk/tracking/src/main/java/org/hps/recon/tracking/gbl/HpsGblRefitter.java
 =============================================================================
--- java/trunk/tracking/src/main/java/org/hps/recon/tracking/gbl/HpsGblRefitter.java	(original)
+++ java/trunk/tracking/src/main/java/org/hps/recon/tracking/gbl/HpsGblRefitter.java	Wed Nov 25 13:26:06 2015
@@ -14,8 +14,10 @@
 import java.util.logging.Formatter;
 import java.util.logging.Level;
 import java.util.logging.Logger;
+import org.apache.commons.math3.util.Pair;
 
 import org.hps.recon.tracking.TrackUtils;
+import static org.hps.recon.tracking.gbl.MakeGblTracks.makeCorrectedTrack;
 import org.hps.recon.tracking.gbl.matrix.Matrix;
 import org.hps.recon.tracking.gbl.matrix.SymMatrix;
 import org.hps.recon.tracking.gbl.matrix.Vector;
@@ -25,8 +27,12 @@
 import org.lcsim.event.GenericObject;
 import org.lcsim.event.LCRelation;
 import org.lcsim.event.Track;
+import org.lcsim.event.base.BaseLCRelation;
 import org.lcsim.geometry.Detector;
 import org.lcsim.geometry.compact.converter.MilleParameter;
+import org.lcsim.lcio.LCIOConstants;
+import org.lcsim.recon.tracking.seedtracker.SeedCandidate;
+import org.lcsim.recon.tracking.seedtracker.SeedTrack;
 import org.lcsim.util.Driver;
 
 /**
@@ -40,21 +46,20 @@
 public class HpsGblRefitter extends Driver {
 
     static Formatter f = new BasicLogFormatter();
-    private static Logger LOGGER = Logger.getLogger(HpsGblRefitter.class.getPackage().getName());
+    private final static Logger LOGGER = Logger.getLogger(HpsGblRefitter.class.getPackage().getName());
     private boolean _debug = false;
     private final String trackCollectionName = "MatchedTracks";
     private final String track2GblTrackRelationName = "TrackToGBLTrack";
     private final String gblTrack2StripRelationName = "GBLTrackToStripData";
+    private final String outputTrackCollectionName = "GBLTracks";
 
     private MilleBinary mille;
     private String milleBinaryFileName = MilleBinary.DEFAULT_OUTPUT_FILE_NAME;
     private boolean writeMilleBinary = false;
 
-    private final MakeGblTracks _makeTracks;
-
     public void setDebug(boolean debug) {
         _debug = debug;
-        _makeTracks.setDebug(debug);
+        MakeGblTracks.setDebug(debug);
     }
 
     public void setMilleBinaryFileName(String filename) {
@@ -66,8 +71,7 @@
     }
 
     public HpsGblRefitter() {
-        _makeTracks = new MakeGblTracks();
-        _makeTracks.setDebug(_debug);
+        MakeGblTracks.setDebug(_debug);
         LOGGER.setLevel(Level.WARNING);
         //System.out.println("level " + LOGGER.getLevel().toString());
     }
@@ -179,7 +183,35 @@
         LOGGER.info(stripsGblMap.size() + " tracks in stripsGblMap");
         LOGGER.info(trackFits.size() + " fitted GBL tracks before adding to event");
 
-        _makeTracks.Process(event, trackFits, bfield);
+        List<Track> newTracks = new ArrayList<Track>();
+
+        List<GBLKinkData> kinkDataCollection = new ArrayList<GBLKinkData>();
+
+        List<LCRelation> kinkDataRelations = new ArrayList<LCRelation>();
+
+        LOGGER.info("adding " + trackFits.size() + " of fitted GBL tracks to the event");
+
+        for (FittedGblTrajectory fittedTraj : trackFits) {
+
+            SeedTrack seedTrack = (SeedTrack) fittedTraj.get_seed();
+            SeedCandidate trackseed = seedTrack.getSeedCandidate();
+
+            //  Create a new Track
+            Pair<Track, GBLKinkData> trk = makeCorrectedTrack(fittedTraj, trackseed.getHelix(), seedTrack.getTrackerHits(), seedTrack.getType(), bfield);
+
+            //  Add the track to the list of tracks
+            newTracks.add(trk.getFirst());
+            kinkDataCollection.add(trk.getSecond());
+            kinkDataRelations.add(new BaseLCRelation(trk.getSecond(), trk.getFirst()));
+        }
+
+        LOGGER.info("adding " + Integer.toString(newTracks.size()) + " Gbl tracks to event with " + event.get(Track.class, "MatchedTracks").size() + " matched tracks");
+
+        // Put the tracks back into the event and exit
+        int flag = 1 << LCIOConstants.TRBIT_HITS;
+        event.put(outputTrackCollectionName, newTracks, Track.class, flag);
+        event.put(GBLKinkData.DATA_COLLECTION, kinkDataCollection, GBLKinkData.class, 0);
+        event.put(GBLKinkData.DATA_RELATION_COLLECTION, kinkDataRelations, LCRelation.class, 0);
 
         if (_debug) {
             System.out.printf("%s: Done.\n", getClass().getSimpleName());

Modified: java/trunk/tracking/src/main/java/org/hps/recon/tracking/gbl/MakeGblTracks.java
 =============================================================================
--- java/trunk/tracking/src/main/java/org/hps/recon/tracking/gbl/MakeGblTracks.java	(original)
+++ java/trunk/tracking/src/main/java/org/hps/recon/tracking/gbl/MakeGblTracks.java	Wed Nov 25 13:26:06 2015
@@ -6,94 +6,58 @@
 import hep.physics.vec.Hep3Vector;
 import hep.physics.vec.VecOp;
 import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
 import java.util.List;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 import org.apache.commons.math3.util.Pair;
+import org.hps.recon.tracking.CoordinateTransformations;
+import org.hps.recon.tracking.MultipleScattering;
 import org.hps.recon.tracking.TrackType;
+import org.hps.recon.tracking.TrackUtils;
 import static org.hps.recon.tracking.gbl.GBLOutput.getPerToClPrj;
 import org.hps.recon.tracking.gbl.matrix.Matrix;
 import org.hps.recon.tracking.gbl.matrix.SymMatrix;
 import org.hps.recon.tracking.gbl.matrix.Vector;
 import org.lcsim.constants.Constants;
-import org.lcsim.event.EventHeader;
-import org.lcsim.event.LCRelation;
+import org.lcsim.detector.ITransform3D;
+import org.lcsim.detector.tracker.silicon.ChargeCarrier;
+import org.lcsim.detector.tracker.silicon.HpsSiSensor;
+import org.lcsim.detector.tracker.silicon.SiSensor;
+import org.lcsim.detector.tracker.silicon.SiSensorElectrodes;
+import org.lcsim.event.RawTrackerHit;
 import org.lcsim.event.Track;
 import org.lcsim.event.TrackState;
 import org.lcsim.event.TrackerHit;
-import org.lcsim.event.base.BaseLCRelation;
 import org.lcsim.event.base.BaseTrack;
 import org.lcsim.event.base.BaseTrackState;
 import org.lcsim.fit.helicaltrack.HelicalTrackFit;
-import org.lcsim.lcio.LCIOConstants;
-import org.lcsim.recon.tracking.seedtracker.SeedCandidate;
-import org.lcsim.recon.tracking.seedtracker.SeedTrack;
+import org.lcsim.fit.helicaltrack.HelicalTrackStrip;
+import org.lcsim.fit.helicaltrack.HelixUtils;
+import org.lcsim.recon.tracking.digitization.sisim.SiTrackerHitStrip1D;
+import org.lcsim.recon.tracking.digitization.sisim.TrackerHitType;
 
 /**
- * A class that creates track objects from fitted GBL trajectories and adds them
- * into the event.
+ * Utilities that create track objects from fitted GBL trajectories.
  *
  * @author Per Hansson Adrian <[log in to unmask]>
  *
  */
 public class MakeGblTracks {
 
-    private String _TrkCollectionName = "GBLTracks";
-    private static Logger LOGGER = Logger.getLogger(MakeGblTracks.class.getPackage().getName());
-
-    /**
-     * Creates a new instance of MakeTracks.
-     */
-    public MakeGblTracks() {
-    }
-
-    public void setDebug(boolean debug) {
+    private final static Logger LOGGER = Logger.getLogger(MakeGblTracks.class.getPackage().getName());
+
+    private MakeGblTracks() {
+    }
+
+    public static void setDebug(boolean debug) {
         if (debug) {
             LOGGER.setLevel(Level.INFO);
         } else {
             LOGGER.setLevel(Level.OFF);
         }
-    }
-
-    /**
-     * Process a Gbl track and store it into the event
-     *
-     * @param event event header
-     * @param track Gbl trajectory
-     * @param seed SeedTrack
-     * @param bfield magnetic field (used to turn curvature into momentum)
-     */
-    public void Process(EventHeader event, List<FittedGblTrajectory> gblTrajectories, double bfield) {
-
-        List<Track> tracks = new ArrayList<Track>();
-
-        List<GBLKinkData> kinkDataCollection = new ArrayList<GBLKinkData>();
-
-        List<LCRelation> kinkDataRelations = new ArrayList<LCRelation>();
-
-        LOGGER.info("adding " + gblTrajectories.size() + " of fitted GBL tracks to the event");
-
-        for (FittedGblTrajectory fittedTraj : gblTrajectories) {
-
-            SeedTrack seedTrack = (SeedTrack) fittedTraj.get_seed();
-            SeedCandidate trackseed = seedTrack.getSeedCandidate();
-
-            //  Create a new Track
-            Pair<Track, GBLKinkData> trk = makeCorrectedTrack(fittedTraj, trackseed.getHelix(), seedTrack.getTrackerHits(), seedTrack.getType(), bfield);
-
-            //  Add the track to the list of tracks
-            tracks.add(trk.getFirst());
-            kinkDataCollection.add(trk.getSecond());
-            kinkDataRelations.add(new BaseLCRelation(trk.getSecond(), trk.getFirst()));
-        }
-
-        LOGGER.info("adding " + Integer.toString(tracks.size()) + " Gbl tracks to event with " + event.get(Track.class, "MatchedTracks").size() + " matched tracks");
-
-        // Put the tracks back into the event and exit
-        int flag = 1 << LCIOConstants.TRBIT_HITS;
-        event.put(_TrkCollectionName, tracks, Track.class, flag);
-        event.put(GBLKinkData.DATA_COLLECTION, kinkDataCollection, GBLKinkData.class, 0);
-        event.put(GBLKinkData.DATA_RELATION_COLLECTION, kinkDataRelations, LCRelation.class, 0);
     }
 
     public static Pair<Track, GBLKinkData> makeCorrectedTrack(FittedGblTrajectory fittedTraj, HelicalTrackFit helix, List<TrackerHit> trackHits, int trackType, double bfield) {
@@ -319,8 +283,215 @@
         return new GBLKinkData(lambdaKinks, phiKinks);
     }
 
-    public void setTrkCollectionName(String name) {
-        _TrkCollectionName = name;
-    }
-
+    /**
+     * Do a GBL fit to an arbitrary set of strip hits, with a starting value of
+     * the helix parameters.
+     *
+     * @param helix Initial helix parameters. Only track parameters are used
+     * (not covariance)
+     * @param stripHits Strip hits to be used for the GBL fit. Does not need to
+     * be in sorted order.
+     * @param hth Stereo hits for the track's hit list (these are not used in
+     * the GBL fit). Does not need to be in sorted order.
+     * @param nIterations Number of times to iterate the GBL fit.
+     * @param scattering Multiple scattering manager.
+     * @param bfield B-field
+     * @return The refitted track.
+     */
+    public static Pair<Track, GBLKinkData> refitTrack(HelicalTrackFit helix, Collection<TrackerHit> stripHits, Collection<TrackerHit> hth, int nIterations, MultipleScattering scattering, double bfield) {
+        List<TrackerHit> allHthList = sortHits(hth);
+        List<TrackerHit> sortedStripHits = sortHits(stripHits);
+        FittedGblTrajectory fit = MakeGblTracks.doGBLFit(helix, sortedStripHits, scattering, bfield, 0);
+        for (int i = 0; i < nIterations; i++) {
+            Pair<Track, GBLKinkData> newTrack = MakeGblTracks.makeCorrectedTrack(fit, helix, allHthList, 0, bfield);
+            helix = TrackUtils.getHTF(newTrack.getFirst());
+            fit = MakeGblTracks.doGBLFit(helix, sortedStripHits, scattering, bfield, 0);
+        }
+        Pair<Track, GBLKinkData> mergedTrack = MakeGblTracks.makeCorrectedTrack(fit, helix, allHthList, 0, bfield);
+        return mergedTrack;
+    }
+
+    public static FittedGblTrajectory doGBLFit(HelicalTrackFit htf, List<TrackerHit> stripHits, MultipleScattering _scattering, double bfield, int debug) {
+        List<GBLStripClusterData> stripData = makeStripData(htf, stripHits, _scattering, bfield, debug);
+        double bfac = Constants.fieldConversion * bfield;
+
+        FittedGblTrajectory fit = HpsGblRefitter.fit(stripData, bfac, debug > 0);
+        return fit;
+    }
+
+    public static List<GBLStripClusterData> makeStripData(HelicalTrackFit htf, List<TrackerHit> stripHits, MultipleScattering _scattering, double _B, int _debug) {
+        List<GBLStripClusterData> stripClusterDataList = new ArrayList<GBLStripClusterData>();
+
+        // Find scatter points along the path
+        MultipleScattering.ScatterPoints scatters = _scattering.FindHPSScatterPoints(htf);
+
+        if (_debug > 0) {
+            System.out.printf("perPar covariance matrix\n%s\n", htf.covariance().toString());
+        }
+
+        for (TrackerHit stripHit : stripHits) {
+            HelicalTrackStripGbl strip;
+            if (stripHit instanceof SiTrackerHitStrip1D) {
+                strip = new HelicalTrackStripGbl(makeDigiStrip((SiTrackerHitStrip1D) stripHit), true);
+            } else {
+                SiTrackerHitStrip1D newHit = new SiTrackerHitStrip1D(stripHit);
+                strip = new HelicalTrackStripGbl(makeDigiStrip(newHit), true);
+            }
+
+            // find Millepede layer definition from DetectorElement
+            HpsSiSensor sensor = (HpsSiSensor) ((RawTrackerHit) stripHit.getRawHits().get(0)).getDetectorElement();
+
+            int millepedeId = sensor.getMillepedeId();
+
+            if (_debug > 0) {
+                System.out.printf("layer %d millepede %d (DE=\"%s\", origin %s) \n", strip.layer(), millepedeId, sensor.getName(), strip.origin().toString());
+            }
+
+            //Center of the sensor
+            Hep3Vector origin = strip.origin();
+
+            //Find intercept point with sensor in tracking frame
+            Hep3Vector trkpos = TrackUtils.getHelixPlaneIntercept(htf, strip, Math.abs(_B));
+            if (trkpos == null) {
+                if (_debug > 0) {
+                    System.out.println("Can't find track intercept; use sensor origin");
+                }
+                trkpos = strip.origin();
+            }
+            if (_debug > 0) {
+                System.out.printf("trkpos at intercept [%.10f %.10f %.10f]\n", trkpos.x(), trkpos.y(), trkpos.z());
+            }
+
+            //GBLDATA
+            GBLStripClusterData stripData = new GBLStripClusterData(millepedeId);
+            //Add to output list
+            stripClusterDataList.add(stripData);
+
+            //path length to intercept
+            double s = HelixUtils.PathToXPlane(htf, trkpos.x(), 0, 0).get(0);
+            double s3D = s / Math.cos(Math.atan(htf.slope()));
+
+            //GBLDATA
+            stripData.setPath(s);
+            stripData.setPath3D(s3D);
+
+            //GBLDATA
+            stripData.setU(strip.u());
+            stripData.setV(strip.v());
+            stripData.setW(strip.w());
+
+            //Print track direction at intercept
+            Hep3Vector tDir = HelixUtils.Direction(htf, s);
+            double phi = htf.phi0() - s / htf.R();
+            double lambda = Math.atan(htf.slope());
+
+            //GBLDATA
+            stripData.setTrackDir(tDir);
+            stripData.setTrackPhi(phi);
+            stripData.setTrackLambda(lambda);
+
+            //Print residual in measurement system
+            // start by find the distance vector between the center and the track position
+            Hep3Vector vdiffTrk = VecOp.sub(trkpos, origin);
+
+            // then find the rotation from tracking to measurement frame
+            Hep3Matrix trkToStripRot = getTrackToStripRotation(sensor);
+
+            // then rotate that vector into the measurement frame to get the predicted measurement position
+            Hep3Vector trkpos_meas = VecOp.mult(trkToStripRot, vdiffTrk);
+
+            //GBLDATA
+            stripData.setMeas(strip.umeas());
+            stripData.setTrackPos(trkpos_meas);
+            stripData.setMeasErr(strip.du());
+
+            if (_debug > 1) {
+                System.out.printf("rotation matrix to meas frame\n%s\n", VecOp.toString(trkToStripRot));
+                System.out.printf("tPosGlobal %s origin %s\n", trkpos.toString(), origin.toString());
+                System.out.printf("tDiff %s\n", vdiffTrk.toString());
+                System.out.printf("tPosMeas %s\n", trkpos_meas.toString());
+            }
+
+            if (_debug > 0) {
+                System.out.printf("layer %d millePedeId %d uRes %.10f\n", strip.layer(), millepedeId, stripData.getMeas() - stripData.getTrackPos().x());
+            }
+
+            // find scattering angle
+            MultipleScattering.ScatterPoint scatter = scatters.getScatterPoint(((RawTrackerHit) strip.getStrip().rawhits().get(0)).getDetectorElement());
+            double scatAngle;
+
+            if (scatter != null) {
+                scatAngle = scatter.getScatterAngle().Angle();
+            } else {
+                if (_debug > 0) {
+                    System.out.printf("WARNING cannot find scatter for detector %s with strip cluster at %s\n", ((RawTrackerHit) strip.getStrip().rawhits().get(0)).getDetectorElement().getName(), strip.origin().toString());
+                }
+                scatAngle = GblUtils.estimateScatter(sensor, htf, _scattering, _B);
+            }
+
+            //GBLDATA
+            stripData.setScatterAngle(scatAngle);
+        }
+        return stripClusterDataList;
+    }
+
+    private static Hep3Matrix getTrackToStripRotation(SiSensor sensor) {
+        // This function transforms the hit to the sensor coordinates
+
+        // Transform from JLab frame to sensor frame (done through the RawTrackerHit)
+        SiSensorElectrodes electrodes = sensor.getReadoutElectrodes(ChargeCarrier.HOLE);
+        ITransform3D detToStrip = electrodes.getGlobalToLocal();
+        // Get rotation matrix
+        Hep3Matrix detToStripMatrix = detToStrip.getRotation().getRotationMatrix();
+        // Transformation between the JLAB and tracking coordinate systems
+        Hep3Matrix detToTrackMatrix = CoordinateTransformations.getMatrix();
+
+        return VecOp.mult(detToStripMatrix, VecOp.inverse(detToTrackMatrix));
+    }
+
+    private static HelicalTrackStrip makeDigiStrip(SiTrackerHitStrip1D h) {
+        SiTrackerHitStrip1D local = h.getTransformedHit(TrackerHitType.CoordinateSystem.SENSOR);
+        SiTrackerHitStrip1D global = h.getTransformedHit(TrackerHitType.CoordinateSystem.GLOBAL);
+
+        ITransform3D trans = local.getLocalToGlobal();
+        Hep3Vector org = trans.transformed(new BasicHep3Vector(0., 0., 0.));
+        Hep3Vector u = global.getMeasuredCoordinate();
+        Hep3Vector v = global.getUnmeasuredCoordinate();
+
+        //rotate to tracking frame
+        Hep3Vector neworigin = CoordinateTransformations.transformVectorToTracking(org);
+        Hep3Vector newu = CoordinateTransformations.transformVectorToTracking(u);
+        Hep3Vector newv = CoordinateTransformations.transformVectorToTracking(v);
+
+        double umeas = local.getPosition()[0];
+        double vmin = VecOp.dot(local.getUnmeasuredCoordinate(), local.getHitSegment().getStartPoint());
+        double vmax = VecOp.dot(local.getUnmeasuredCoordinate(), local.getHitSegment().getEndPoint());
+        double du = Math.sqrt(local.getCovarianceAsMatrix().diagonal(0));
+
+        //don't fill fields we don't use
+//        IDetectorElement de = h.getSensor();
+//        String det = getName(de);
+//        int lyr = getLayer(de);
+//        BarrelEndcapFlag be = getBarrelEndcapFlag(de);
+        double dEdx = h.getdEdx();
+        double time = h.getTime();
+        List<RawTrackerHit> rawhits = h.getRawHits();
+        HelicalTrackStrip strip = new HelicalTrackStrip(neworigin, newu, newv, umeas, du, vmin, vmax, dEdx, time, rawhits, null, -1, null);
+
+        return strip;
+    }
+
+    private static List<TrackerHit> sortHits(Collection<TrackerHit> hits) {
+        List<TrackerHit> hitList = new ArrayList<TrackerHit>(hits);
+        Collections.sort(hitList, new LayerComparator());
+        return hitList;
+    }
+
+    private static class LayerComparator implements Comparator<TrackerHit> {
+
+        @Override
+        public int compare(TrackerHit o1, TrackerHit o2) {
+            return Integer.compare(TrackUtils.getLayer(o1), TrackUtils.getLayer(o2));
+        }
+    }
 }