LISTSERV mailing list manager LISTSERV 16.5

Help for HPS-SVN Archives


HPS-SVN Archives

HPS-SVN Archives


HPS-SVN@LISTSERV.SLAC.STANFORD.EDU


View:

Message:

[

First

|

Previous

|

Next

|

Last

]

By Topic:

[

First

|

Previous

|

Next

|

Last

]

By Author:

[

First

|

Previous

|

Next

|

Last

]

Font:

Proportional Font

LISTSERV Archives

LISTSERV Archives

HPS-SVN Home

HPS-SVN Home

HPS-SVN  November 2015

HPS-SVN November 2015

Subject:

r3992 - in /java/trunk/users/src/main/java/org/hps/users/phansson: STUtils.java StraightThroughAnalysisDriver.java

From:

[log in to unmask]

Reply-To:

Notification of commits to the hps svn repository <[log in to unmask]>

Date:

Thu, 26 Nov 2015 00:55:09 -0000

Content-Type:

text/plain

Parts/Attachments:

Parts/Attachments

text/plain (1682 lines)

Author: [log in to unmask]
Date: Wed Nov 25 16:55:06 2015
New Revision: 3992

Log:
not working

Added:
    java/trunk/users/src/main/java/org/hps/users/phansson/STUtils.java
    java/trunk/users/src/main/java/org/hps/users/phansson/StraightThroughAnalysisDriver.java

Added: java/trunk/users/src/main/java/org/hps/users/phansson/STUtils.java
 =============================================================================
--- java/trunk/users/src/main/java/org/hps/users/phansson/STUtils.java	(added)
+++ java/trunk/users/src/main/java/org/hps/users/phansson/STUtils.java	Wed Nov 25 16:55:06 2015
@@ -0,0 +1,806 @@
+/**
+ * 
+ */
+package org.hps.users.phansson;
+
+import hep.physics.vec.BasicHep3Matrix;
+import hep.physics.vec.BasicHep3Vector;
+import hep.physics.vec.Hep3Matrix;
+import hep.physics.vec.Hep3Vector;
+import hep.physics.vec.VecOp;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Logger;
+
+import org.apache.commons.math3.stat.regression.SimpleRegression;
+import org.hps.users.phansson.STUtils.STStereoTrack.VIEW;
+import org.lcsim.detector.ITransform3D;
+import org.lcsim.detector.tracker.silicon.HpsSiSensor;
+import org.lcsim.event.EventHeader;
+import org.lcsim.event.RawTrackerHit;
+import org.lcsim.fit.helicaltrack.HelicalTrackCross;
+import org.lcsim.fit.helicaltrack.HitUtils;
+import org.lcsim.fit.line.SlopeInterceptLineFit;
+import org.lcsim.fit.line.SlopeInterceptLineFitter;
+import org.lcsim.recon.tracking.digitization.sisim.SiTrackerHitStrip1D;
+import org.lcsim.recon.tracking.digitization.sisim.TrackerHitType.CoordinateSystem;
+
+/**
+ * Class with static utilities for straight through tracking.
+ * 
+ * @author Per Hansson Adrian <[log in to unmask]>
+ *
+ */
+public class STUtils {
+    
+    public final static Logger logger = Logger.getLogger(STUtils.class.getSimpleName());
+
+    
+    /**
+     * Private constructor to avoid instantiation.
+     */
+    private STUtils() {
+    }
+
+
+    abstract static class STBaseTrack {
+        protected List<STUtils.STTrackFit> fit = new ArrayList<STUtils.STTrackFit>();
+        protected abstract double getIntercept();
+        protected abstract double getSlope();
+        protected abstract double getPath(double dz);
+        public double predict(double zHit) {
+            checkFit();
+            return getFit().predict(zHit);
+        }
+        public STUtils.STTrackFit getFit() {
+            return getFit(0);
+        }
+        public STUtils.STTrackFit getFit(int i) {
+            if(i<fit.size()) 
+                return fit.get(i);
+            else 
+                return null;
+        }
+        public void addFit(STUtils.STTrackFit fit) {
+            this.fit.add(fit);
+        }
+        protected void checkFit() {
+            if(getFit() == null) throw new RuntimeException("This track has no fit");
+        }
+        public abstract boolean isTop();
+        public abstract String toString();
+        public abstract List<double[]> getPointList();
+        public void clearFit() {
+            fit.clear();
+        }
+    
+    
+    }
+
+    static class STTrack extends STBaseTrack {
+        private List<SiTrackerHitStrip1D> hits = new ArrayList<SiTrackerHitStrip1D>();
+        
+        public STTrack() {}
+        
+        public void setHits(List<SiTrackerHitStrip1D> hits) {
+           this.hits = hits;
+        }
+    
+        public List<SiTrackerHitStrip1D> getHits() {
+            return hits;
+        }
+    
+        public double getIntercept() {
+           checkFit();
+           return getFit().intercept();
+        }
+    
+        public double getSlope() {
+            checkFit();
+            return getFit().slope();
+        }
+        
+        protected double getPath(double dz) {
+            double slope = getSlope();
+            double dy = slope*dz;
+            return Math.sqrt( dz*dz + dy*dy );
+        }
+    
+        public boolean isTop() {
+            if(hits.size()==0) throw new RuntimeException("need hits to determine half.");
+            return ((HpsSiSensor) hits.get(0).getRawHits().get(0).getDetectorElement()).isTopLayer();
+        }
+        
+        public List<double[]> getPointList() {
+            List<double[]> l = new ArrayList<double[]>();
+            for(SiTrackerHitStrip1D hit : hits) {
+                l.add( new double[]{hit.getPositionAsVector().z(), hit.getPositionAsVector().y()});
+            }
+            return l;
+        }
+    
+        public String toString() {
+            String s = "STTrack: \n";
+            s+= String.valueOf(hits.size()) + " hits:\n";
+            for(SiTrackerHitStrip1D hit : hits) {
+                s += hit.getPositionAsVector().toString() + "(" + hit.getRawHits().get(0).getDetectorElement().getName() + ")\n";
+            }
+            s += fit.toString();
+            return s;
+        }
+        
+    }
+
+    
+    
+    static class STStereoTrack {
+        protected static enum VIEW { YZ,XZ };
+        private List<STUtils.StereoPair> hits = new ArrayList<STUtils.StereoPair>();
+        protected STTrackFit fit[] = {null,null};
+        
+        public STStereoTrack() {
+        }
+        
+        void checkView(VIEW view) {
+            if(!view.equals(VIEW.YZ) && !view.equals(VIEW.XZ)) throw new RuntimeException("This view is not valid.");
+        }
+        
+        public double[] predict(double z) {
+            checkFit(VIEW.XZ);
+            checkFit(VIEW.YZ);
+            double p[] = new double[2];
+            double s = getSignedPathLength(this, z, VIEW.YZ);
+            p[VIEW.YZ.ordinal()] = predict(z, VIEW.YZ);
+            p[VIEW.XZ.ordinal()] = predict(s, VIEW.XZ);
+            return p;
+        }
+
+        private double predict(double z, VIEW view) {
+            checkView(view);
+            return getFit(view).predict(z);
+        }
+
+        public STTrackFit getFit(VIEW view) {
+            return fit[view.ordinal()];
+        }
+        
+        public void setFit(STTrackFit f, VIEW view) {
+            fit[view.ordinal()] = f;
+        }
+        
+        protected void checkFit(VIEW view) {
+            if(getFit(view) == null) throw new RuntimeException("This track has no fit");
+        }
+
+        public void clearFit() {
+            clearFit(VIEW.XZ);
+            clearFit(VIEW.YZ);
+        }
+
+        public void clearFit(VIEW view) {
+            fit[view.ordinal()] = null;
+        }
+    
+        /**
+         * Track direction. Assumes track moves in positive z.
+         * @return track direction.
+         */
+        public Hep3Vector getDirection() {
+            double dxdz = getFit(VIEW.XZ).slope();
+            double dydz = getFit(VIEW.YZ).slope();
+            double dzdz = 1- Math.sqrt( dxdz*dxdz + dydz*dydz);
+            return new BasicHep3Vector(dxdz, dydz, dzdz);
+        }
+    
+        public List<StereoPair> getHits() {
+            return hits;
+        }
+
+        protected double[] getIntercept() {
+            double[] p = new double[2];
+            p[VIEW.XZ.ordinal()] = getIntercept(VIEW.XZ);
+            p[VIEW.YZ.ordinal()] = getIntercept(VIEW.YZ);
+            return p;
+        }
+    
+        private double getIntercept(VIEW view) {
+            checkView(view);
+            return getFit(view).intercept();
+        }
+
+        protected double[] getSlope() {
+            double[] p = new double[2];
+            p[VIEW.XZ.ordinal()] = getSlope(VIEW.XZ);
+            p[VIEW.YZ.ordinal()] = getSlope(VIEW.YZ);
+            return p;
+        }
+    
+        private double getSlope(VIEW view) {
+            checkView(view);
+            return getFit(view).slope();
+        }
+
+        public void setHits(List<STUtils.StereoPair> seedHits) {
+            hits = seedHits;
+        }
+        
+        public boolean isTop() {
+            if(hits.size()==0) throw new RuntimeException("need hits to determine half.");
+            return ((HpsSiSensor) hits.get(0).getAxial().getRawHits().get(0).getDetectorElement()).isTopLayer();
+        }
+    
+        /**
+         * Get list of points that would be used in a simple univariate regression. 
+         * Note that one {@link VIEW} uses the path length.
+         * @param view - {@link VIEW} to be obtained
+         * @return {@link List} of points for this track. 
+         */
+        public List<double[]> getPointList(VIEW view) {
+            checkView(view);
+            List<double[]> l = new ArrayList<double[]>();
+            for(StereoPair hit : hits) {
+                Hep3Vector p = hit.getPosition();
+                // get the path length
+                // in one view this is simple the z-position.
+                double s = view.compareTo(VIEW.YZ) == 0 ? p.z() : getSignedPathLength(this, p.z(), VIEW.YZ);
+                double y = view.equals(VIEW.YZ) ? p.y() : p.x();
+                l.add( new double[]{s, y} );
+            }
+            return l;
+        }
+
+        public String toString() {
+            StringBuffer sb = new StringBuffer("STStereoTrack:\n");
+            sb.append(hits.size() + " stereo hits.\n");
+            for(int i=0;i<2;++i) {
+                VIEW v = VIEW.values()[i];
+                sb.append("View " + v.name() + ": \n");
+                for(double[] xy : getPointList(v))
+                    sb.append(xy[0] + ", " + xy[1] + "\n");
+                if(getFit(v)!=null) sb.append(getFit(v).toString());
+            }
+            return sb.toString();
+        }
+
+
+       
+    }
+
+    static class StereoPair {
+        SiTrackerHitStrip1D axialCluster;
+        SiTrackerHitStrip1D stereoCluster;
+        Hep3Vector position = null;
+        public StereoPair(SiTrackerHitStrip1D axial, SiTrackerHitStrip1D stereo, Hep3Vector origin) {
+            this.axialCluster = axial;
+            this.stereoCluster = stereo;
+            this.position = STUtils.getStereoHitPositionFromReference(origin, getAxial(), getStereo());
+        }
+        public void updatePosition(Hep3Vector trackDirection) {
+            position = STUtils.getPosition(trackDirection, axialCluster, stereoCluster);
+            
+        }
+        public SiTrackerHitStrip1D getStereo() {
+            return stereoCluster;
+        }
+        public SiTrackerHitStrip1D getAxial() {
+           return axialCluster;
+        }
+        public Hep3Vector getPosition() {
+            return position;
+        }
+        public static boolean passCuts(StereoPair pair) {
+           //find intersection with sensor
+            return true;
+        }
+        
+    }
+
+    static class STTrackFit extends SlopeInterceptLineFit {
+        private String type;
+        public STTrackFit(String type, SlopeInterceptLineFit fit) {
+            super(fit.slope(), fit.intercept(), fit.slopeUncertainty(),fit.interceptUncertainty(),fit.covariance(),fit.chisquared(),fit.ndf());
+            this.type = type;
+        }
+        public STTrackFit(String type, double slope, double intercept, double slopeUncertainty, double interceptUncertainty, double sigAB, double chisq, int ndf) {
+            super(slope, intercept,slopeUncertainty,interceptUncertainty,sigAB,chisq,ndf);
+            this.type = type;
+        }
+        public double predict(double zHit) {
+            return intercept() + slope() * zHit;
+        }
+        public String getType() {
+            return type;
+        }
+        public String toString() {
+            String s = "STTrackFit " + getType() + ": " + super.toString();
+            return s;
+        }
+    }
+
+    static abstract class STTrackFitter {
+        private STTrackFit fit = null;
+        public STTrackFitter() {}
+        abstract String getType();
+        abstract public void fit(STTrack track);
+        abstract public void fit(List<double[]> xyList);
+        protected void setFit(STTrackFit fit) {
+            this.fit = fit;
+        }
+        public STTrackFit getFit() { return fit; }
+        void clear() {
+            fit = null;
+        }
+        abstract public void setErrY(double err_y);
+            
+    }
+
+    static class RegressionFit extends STTrackFitter {
+        private static final String TYPE = "SimpleRegression";
+        public void fit(List<double[]> xyList) {
+            clear();
+            SimpleRegression regression = new SimpleRegression();
+            for(double[] hit : xyList) {
+                regression.addData(hit[0], hit[1]);
+            }
+            setFit(new STTrackFit(TYPE,regression.getSlope(), regression.getIntercept(), regression.getSlopeStdErr(), regression.getInterceptStdErr(), regression.getR(), 0.0, (int) (regression.getN()-2)));
+        }
+        public void fit(STTrack track) {
+            fit(track.getPointList());
+        }
+        String getType() {
+            return TYPE;
+        }
+        public void setErrY(double err_y) {
+        }
+    }
+
+    private static class LineFit extends STTrackFitter {
+        private static final String TYPE = "LineFit";
+        private double errY = 6e-3;
+        String getType() {
+            return TYPE;
+        }
+        public void setErrY(double err_y) {
+            this.errY = err_y;
+        }
+        public void fit(STTrack track) {
+            fit(track.getPointList());
+        }
+        @Override
+        public void fit(List<double[]> xyList) {
+            int n = xyList.size();
+            double[] x = new double[n];
+            double[] y = new double[n];
+            double[] sigma_y = new double[n];
+            for(int i=0; i<n; ++i ) {
+                x[i] = xyList.get(i)[0];
+                y[i] = xyList.get(i)[1];
+                sigma_y[i] = errY;
+            }            
+            SlopeInterceptLineFitter fitter = new SlopeInterceptLineFitter();
+            fitter.fit(x, y, sigma_y, n);
+            setFit( new STTrackFit(TYPE, fitter.getFit()) );
+        }
+    
+    }
+
+
+    static Hep3Vector getOrigin(SiTrackerHitStrip1D stripCluster) {
+        SiTrackerHitStrip1D local = stripCluster.getTransformedHit(CoordinateSystem.SENSOR);
+        ITransform3D trans = local.getLocalToGlobal();
+        return trans.transformed(StraightThroughAnalysisDriver.origo);
+    }
+
+    static Hep3Vector getNormal(SiTrackerHitStrip1D s2) {
+        Hep3Vector u2 = s2.getMeasuredCoordinate();
+        Hep3Vector v2 = s2.getUnmeasuredCoordinate();
+        return  VecOp.cross(u2, v2);
+    }
+
+    /**
+     * Basically an adaptation of what's in {@link HelicalTrackCross}.
+     * @param origin
+     * @param strip1
+     * @param strip2
+     * @return
+     */
+    static Hep3Vector getStereoHitPositionFromReference(Hep3Vector origin, SiTrackerHitStrip1D strip1, SiTrackerHitStrip1D strip2) {
+        SiTrackerHitStrip1D s1 = strip1;
+        SiTrackerHitStrip1D s2 = strip2;
+        // sort in direction of track
+        // TODO do I need to sort these?
+        if(s1.getPositionAsVector().z() > s2.getPositionAsVector().z()) { s1 = strip2; s2 = strip1; }
+    
+        StraightThroughAnalysisDriver.logger.finest("Calculate stereo hit position assuming track from " + origin.toString());
+        
+        // Get origin of sensors
+        Hep3Vector o1 = getOrigin(s1);
+        Hep3Vector o2 = getOrigin(s2);
+        
+        // Get sensor orientation
+        Hep3Vector u1 = s1.getMeasuredCoordinate();
+        Hep3Vector v1 = s1.getUnmeasuredCoordinate();
+        Hep3Vector w1 = getNormal(s1);
+        Hep3Vector u2 = s2.getMeasuredCoordinate();
+        Hep3Vector v2 = s2.getUnmeasuredCoordinate();
+        Hep3Vector w2 = getNormal(s2);
+    
+        // update origin calculation with displaced origin
+        o1 = VecOp.sub(o1, origin);
+        o2 = VecOp.sub(o2, origin);
+    
+        // For this to work the normal needs to point along track i.e. along z for both sensors
+        // so rotate coordinate system pi around u axis in this case
+        if(VecOp.dot(w1, o1) < 0) {
+           v1 = VecOp.mult(-1.0, v1);
+           w1 = VecOp.cross(u1, v1);
+        }
+        if(VecOp.dot(w2, o2) < 0) {
+            v2 = VecOp.mult(-1.0, v2);
+            w2 = VecOp.cross(u2, v2);
+         }
+        
+        
+        StraightThroughAnalysisDriver.logger.finest("o1 " + o1.toString());
+        StraightThroughAnalysisDriver.logger.finest("u1 " + u1.toString());
+        StraightThroughAnalysisDriver.logger.finest("v1 " + v1.toString());
+        StraightThroughAnalysisDriver.logger.finest("w1 " + w1.toString());
+        StraightThroughAnalysisDriver.logger.finest("o2 " + o2.toString());
+        StraightThroughAnalysisDriver.logger.finest("u2 " + u2.toString());
+        StraightThroughAnalysisDriver.logger.finest("v2 " + v2.toString());
+        StraightThroughAnalysisDriver.logger.finest("w2 " + w2.toString());
+    
+        
+        // Get the measured strip position on each sensor (basically origin + mult(umeas,u))
+        Hep3Vector p1 = s1.getPositionAsVector();
+        Hep3Vector p2 = s2.getPositionAsVector();
+        StraightThroughAnalysisDriver.logger.finest("p1 " + p1.toString());
+        StraightThroughAnalysisDriver.logger.finest("p2 " + p2.toString());
+    
+        // sin(stereo angle)
+        double sinAlpha = VecOp.dot(v1, u2); 
+        StraightThroughAnalysisDriver.logger.finest("sinAlpha " + sinAlpha);
+        
+        // check
+        if(Math.abs( VecOp.dot(o1, w1)) < 0.0001) throw new RuntimeException("o1 and w1 are orthogonal: o1 " + o1.toString() + " w1 " + w1.toString());
+        
+        // calculate effective distance along z
+        double gamma = VecOp.dot(o2, w2) / VecOp.dot(o1, w1);
+        StraightThroughAnalysisDriver.logger.finest("gamma " + gamma);
+    
+        // Get the vector between the two strip (center) positions
+        Hep3Vector dp = VecOp.sub(p2, VecOp.mult(gamma, p1));
+        StraightThroughAnalysisDriver.logger.finest("dp " + dp.toString());
+        
+        // Get the projection onto u2 and scale with stereo angle to get un-measured coordinate
+        double p1_v = VecOp.dot(dp, u2) / (gamma * sinAlpha);
+        StraightThroughAnalysisDriver.logger.finest("p1_v " + p1_v);
+        
+        // calculate the position of the hit on the strip
+        Hep3Vector r1 = VecOp.add(p1, VecOp.mult(p1_v, v1));
+        StraightThroughAnalysisDriver.logger.finest("r1 " + r1.toString());
+        
+        // Take the final position as the half-way between the sensors
+        Hep3Vector p = VecOp.mult( 0.5 * ( 1 + gamma ), r1);
+    
+        StraightThroughAnalysisDriver.logger.finest("p " + p.toString());
+    
+        
+        return p;
+        
+    }
+
+    /**
+     * Basically the same as what's in {@link HitUtils}.
+     * @param origin
+     * @param strip1
+     * @param strip2
+     * @return
+     */
+    static Hep3Vector getPosition(Hep3Vector t, SiTrackerHitStrip1D strip1, SiTrackerHitStrip1D strip2) {
+        SiTrackerHitStrip1D s1 = strip1;
+        SiTrackerHitStrip1D s2 = strip2;
+        // sort in direction of track
+        // TODO do I need to sort these?
+        if(s1.getPositionAsVector().z() > s2.getPositionAsVector().z()) { s1 = strip2; s2 = strip1; }
+    
+        StraightThroughAnalysisDriver.logger.finest("Calculate stereo hit position assuming track direction " + t.toString());
+        
+        // Get origin of sensors
+        Hep3Vector o1 = getOrigin(s1);
+        Hep3Vector o2 = getOrigin(s2);
+        
+        // Get sensor orientation
+        Hep3Vector u1 = s1.getMeasuredCoordinate();
+        Hep3Vector v1 = s1.getUnmeasuredCoordinate();
+        Hep3Vector w1 = getNormal(s1);
+        Hep3Vector u2 = s2.getMeasuredCoordinate();
+        Hep3Vector v2 = s2.getUnmeasuredCoordinate();
+        Hep3Vector w2 = getNormal(s2);
+    
+        // For this to work the normal needs to point along track i.e. along z for both sensors
+        // so rotate coordinate system pi around u axis in this case
+        if(VecOp.dot(w1, o1) < 0) {
+           v1 = VecOp.mult(-1.0, v1);
+           w1 = VecOp.cross(u1, v1);
+        }
+        if(VecOp.dot(w2, o2) < 0) {
+            v2 = VecOp.mult(-1.0, v2);
+            w2 = VecOp.cross(u2, v2);
+         }
+        
+        
+        StraightThroughAnalysisDriver.logger.finest("o1 " + o1.toString());
+        StraightThroughAnalysisDriver.logger.finest("u1 " + u1.toString());
+        StraightThroughAnalysisDriver.logger.finest("v1 " + v1.toString());
+        StraightThroughAnalysisDriver.logger.finest("w1 " + w1.toString());
+        StraightThroughAnalysisDriver.logger.finest("o2 " + o2.toString());
+        StraightThroughAnalysisDriver.logger.finest("u2 " + u2.toString());
+        StraightThroughAnalysisDriver.logger.finest("v2 " + v2.toString());
+        StraightThroughAnalysisDriver.logger.finest("w2 " + w2.toString());
+    
+        
+        // Get the measured strip position on each sensor (basically origin + mult(umeas,u))
+        Hep3Vector p1 = s1.getPositionAsVector();
+        Hep3Vector p2 = s2.getPositionAsVector();
+        StraightThroughAnalysisDriver.logger.finest("p1 " + p1.toString());
+        StraightThroughAnalysisDriver.logger.finest("p2 " + p2.toString());
+    
+        // sin(stereo angle)
+        double sinAlpha = VecOp.dot(v1, u2); 
+        StraightThroughAnalysisDriver.logger.finest("sinAlpha " + sinAlpha);
+        
+        // check
+        if(Math.abs( VecOp.dot(o1, w1)) < 0.0001) throw new RuntimeException("o1 and w1 are orthogonal: o1 " + o1.toString() + " w1 " + w1.toString());
+        
+        // calculate the distance between the sensors
+        double gamma = VecOp.dot( w1, VecOp.sub(o2, o1)) / VecOp.dot(w1, t);
+        StraightThroughAnalysisDriver.logger.finest("gamma " + gamma);
+    
+        // Get the vector along the track direction
+        Hep3Vector tgamma = VecOp.mult(gamma, t);
+        StraightThroughAnalysisDriver.logger.finest("tgamma " + tgamma.toString());
+        
+        // Get the vector taking you from the midpoint of strip1 in the direction of the track
+        Hep3Vector p1Prime = VecOp.add(p1, tgamma);
+        StraightThroughAnalysisDriver.logger.finest("p1Prime " + p1Prime.toString());
+        
+        // Get the vector between the predicted and measured center values on strip2
+        Hep3Vector dp = VecOp.sub(p2, p1Prime);
+        StraightThroughAnalysisDriver.logger.finest("dp " + dp.toString());
+        
+        // Get the projection onto u2 and scale with stereo angle to get un-measured coordinate
+        double p1_v = VecOp.dot(dp, u2) / (sinAlpha);
+        StraightThroughAnalysisDriver.logger.finest("p1_v " + p1_v + " (u2="+u2.toString()+")");
+        
+        // calculate the position of the hit on the strip
+        Hep3Vector r1 = VecOp.add(p1, VecOp.mult(p1_v, v1));
+        StraightThroughAnalysisDriver.logger.finest("r1 " + r1.toString() + "(v1="+v1.toString()+")");
+        
+        // Take the final position as the half-way between the sensors
+        Hep3Vector p = VecOp.add(r1, VecOp.mult( 0.5 * gamma, t) );
+    
+        StraightThroughAnalysisDriver.logger.finest("p " + p.toString());
+    
+        
+        return p;
+        
+    }
+
+    /**
+     * Fit the {@link STStereoTrack} track with the supplied {@link STTrackFitter} and add the fit to the track.
+     * @param regressionFitter
+     * @param track
+     */
+    public static void fit(STTrackFitter regressionFitter, STStereoTrack track) {
+        track.clearFit();
+        regressionFitter.fit(track.getPointList(STStereoTrack.VIEW.YZ));
+        track.setFit(regressionFitter.getFit(), STStereoTrack.VIEW.YZ);
+
+        regressionFitter.fit(track.getPointList(STStereoTrack.VIEW.XZ));
+        track.setFit(regressionFitter.getFit(), STStereoTrack.VIEW.XZ);
+        
+    }
+    
+    public static double getSignedPathLength(STStereoTrack track, double z, STStereoTrack.VIEW view) {
+        double slope = track.getSlope(view);
+        double dy = slope*z;
+        return z > 0 ? Math.sqrt( z*z + dy*dy ) : -1*Math.sqrt( z*z + dy*dy );
+    }
+    
+    
+    
+    
+    public static void printGBL(PrintWriter printWriter, EventHeader event, List<STStereoTrack> tracks) {
+        printWriter.printf("New Event %d %f", event.getEventNumber(), 0.0);
+        printWriter.println();
+        for(int iTrack=0; iTrack<tracks.size(); ++iTrack) {
+            
+            STStereoTrack track = tracks.get(iTrack);
+            
+            printWriter.printf("New Track %d", iTrack);
+            printWriter.println();
+            
+            double[] perPars = getPerPars(track);
+            printWriter.printf("Track perPar (x0 y0 dxdz dydz) %.12f %.12f %.12f %.12f", perPars[0],perPars[1],perPars[2],perPars[3]);
+            printWriter.println();
+            
+            double[] clPars = getCLPars(track);
+            printWriter.printf("Track clPar (xT yT dxTdz dyTdz) %.12f %.12f %.12f %.12f", clPars[0],clPars[1],clPars[2],clPars[3]);
+            printWriter.println();
+            
+            Hep3Matrix clPrj = curvilinearProjectionMatrix(track.getDirection());
+            StringBuffer sb = new StringBuffer();
+            for(int i=0;i!=3;++i) 
+                for(int j=0;j!=3;++j) 
+                    sb.append(String.format("%.8f ", clPrj.e(i, j)));
+            printWriter.printf("Track clPrj %s", sb.toString());
+            printWriter.println();
+            
+            //List<SiTrackerHitStrip1D> stripHits = new ArrayList<SiTrackerHitStrip1D>();
+            int iStrip = 0;
+            for(StereoPair pair : track.getHits()) {
+                SiTrackerHitStrip1D strips[] = new SiTrackerHitStrip1D[2];
+                if(pair.getAxial().getPosition()[2] < pair.getStereo().getPosition()[2]) {
+                    strips[0] = pair.getAxial();
+                    strips[1] = pair.getStereo();
+                } else {
+                    strips[1] = pair.getAxial();
+                    strips[0] = pair.getStereo();
+                }
+                for(int i=0; i<strips.length;++i) {
+                    SiTrackerHitStrip1D strip = strips[i];
+                    HpsSiSensor sensor = (HpsSiSensor) ((RawTrackerHit) strip.getRawHits().get(0)).getDetectorElement();
+                    printWriter.printf("New Strip id layer %d %d %s", iStrip, sensor.getMillepedeId(), sensor.getName() );
+                    printWriter.println();
+                    iStrip++;
+                }
+            }
+            
+            
+        }
+        
+    }
+    
+    
+    
+    
+    public static double[] getPerPars(STStereoTrack track) {
+        double intercept[] = track.getIntercept();
+        double slope[] = track.getSlope();
+        return new double[]{
+                intercept[VIEW.XZ.ordinal()],
+                intercept[VIEW.YZ.ordinal()],
+                slope[VIEW.XZ.ordinal()],
+                slope[VIEW.YZ.ordinal()]};
+    }
+    
+    
+    /**
+     * Computes projection matrix from the ST variables x0,y0,z0
+     * to the curvilinear xT,yT,zT variables.
+     *
+     * @param track - {@link STStereoTrack}
+     * @return 3x3 projection matrix
+     */
+    static Hep3Matrix curvilinearProjectionMatrix(Hep3Vector dir) {
+        
+        Hep3Vector X = new BasicHep3Vector(1, 0, 0);
+        Hep3Vector Y = new BasicHep3Vector(0, 1, 0);
+        Hep3Vector Z = new BasicHep3Vector(0, 0, 1);
+        
+        // build the curvilinear unit vectors: UVT
+        Hep3Vector T = dir;
+        Hep3Vector J = VecOp.mult(1. / VecOp.cross(T, Z).magnitude(), VecOp.cross(T, Z));
+        Hep3Vector U = VecOp.mult(-1, J);
+        Hep3Vector V = VecOp.cross(T, U);
+        Hep3Vector K = Z;
+        Hep3Vector I = VecOp.cross(J, K);
+
+        logger.info("U " + U.toString());
+        logger.info("V " + V.toString());
+        logger.info("T " + T.toString());
+        logger.info("X " + X.toString());
+        logger.info("Y " + Y.toString());
+        logger.info("Z " + Z.toString());
+        BasicHep3Matrix trans = new BasicHep3Matrix();
+        trans.setElement(0, 0, VecOp.dot(X, U));
+        trans.setElement(0, 1, VecOp.dot(Y, U));
+        trans.setElement(0, 2, VecOp.dot(Z, U));
+        trans.setElement(1, 0, VecOp.dot(X, V));
+        trans.setElement(1, 1, VecOp.dot(Y, V));
+        trans.setElement(1, 2, VecOp.dot(Z, V));
+        trans.setElement(2, 0, VecOp.dot(X, T));
+        trans.setElement(2, 1, VecOp.dot(Y, T));
+        trans.setElement(2, 2, VecOp.dot(Z, T));
+        
+        
+        
+        return trans;
+
+    }
+
+    
+    /**
+     * Computes projection matrix from the ST variables x0,y0,z0
+     * to the curvilinear xT,yT,zT variables.
+     *
+     * @param track - {@link STStereoTrack}
+     * @return 3x3 projection matrix
+     */
+    static Hep3Vector curvilinearProjection(double x0, double y0, Hep3Vector dir) {
+        final double z0 = 0; 
+        Hep3Vector v = new BasicHep3Vector(x0, y0, z0);
+        Hep3Matrix trans = curvilinearProjectionMatrix(dir);
+        Hep3Vector vnew = VecOp.mult(trans, v);
+
+        StringBuffer sb = new StringBuffer();
+        sb.append("Convert v " + v.toString() + " in ST x,y,z to curvilinear frame xT,yT,zT with prjection matrix:\n");
+        for(int i=0;i!=3;++i) {
+            sb.append("\n");
+            for(int j=0;j!=3;++j) {
+                sb.append(trans.e(i, j) + "  ");
+            }
+        }
+        sb.append("New vector is " + vnew.toString() + " in curvilinear frame xT,yT,zT");
+        logger.info(sb.toString());
+        
+        return vnew;
+
+    }
+    
+    /**
+     * 
+     * Get curvilinear track parameter. 
+     */
+    public static double[] getCLPars(STStereoTrack track) {
+        return getCLPars(track.getIntercept(VIEW.XZ), track.getIntercept(VIEW.YZ), track.getSlope(VIEW.XZ), track.getSlope(VIEW.YZ));
+    }
+    
+    public static double[] getCLPars(double x0, double y0, double dxdz, double dydz) {
+        // track direction
+        Hep3Vector dir = new BasicHep3Vector(dxdz, dydz, 1 - Math.sqrt(dxdz*dxdz + dydz*dydz));
+        
+        final double z0 = 0;
+        Hep3Vector v = new BasicHep3Vector(x0, y0, z0);
+        Hep3Matrix trans = curvilinearProjectionMatrix(dir);
+        Hep3Vector vnew = VecOp.mult(trans, v);
+
+        // for readability
+        double xT = vnew.x();
+        double yT = vnew.y();
+        //double zT = vnew.z();
+
+        final double dzdz = 1.0;
+        Hep3Vector dxyz_dv = new BasicHep3Vector(dxdz, dydz, dzdz);
+        Hep3Vector dxyzT_dv = VecOp.mult(trans, dxyz_dv);
+
+        // for readability
+        double xT_prime = dxyzT_dv.x();
+        double yT_prime = dxyzT_dv.y();
+        //double zT_prime = dxyzT_dv.z();
+
+        double clPars[] = new double[]{xT,yT,xT_prime,yT_prime};
+        
+        logger.info("getCLPars: \n(x0,y0,z0) " + v.toString() + "\n(xT,yT,zT) " + vnew.toString() + "\nd/dz(x,y,z) " + dxyz_dv.toString() + "\nd/dz(xT,yT,zT) " + dxyzT_dv.toString()  );
+        StringBuffer sb = new StringBuffer();
+        for(int i=0;i!=3;++i) {
+            sb.append("\n");
+            for(int j=0;j!=3;++j) {
+                sb.append(trans.e(i, j) + "  ");
+            }
+        }
+        logger.info("using CL prj matrix:\n" + sb.toString() + "\n and track direction "+ dir.toString());
+        
+        return clPars;
+    }
+
+    
+    
+    
+
+    
+    
+}

Added: java/trunk/users/src/main/java/org/hps/users/phansson/StraightThroughAnalysisDriver.java
 =============================================================================
--- java/trunk/users/src/main/java/org/hps/users/phansson/StraightThroughAnalysisDriver.java	(added)
+++ java/trunk/users/src/main/java/org/hps/users/phansson/StraightThroughAnalysisDriver.java	Wed Nov 25 16:55:06 2015
@@ -0,0 +1,853 @@
+/**
+ * 
+ */
+package org.hps.users.phansson;
+
+import hep.aida.IAnalysisFactory;
+import hep.aida.IFitResult;
+import hep.aida.IHistogram1D;
+import hep.aida.IHistogram2D;
+import hep.aida.IHistogramFactory;
+import hep.aida.IPlotter;
+import hep.aida.IPlotterFactory;
+import hep.aida.IPlotterStyle;
+import hep.aida.ref.rootwriter.RootFileStore;
+import hep.physics.vec.BasicHep3Vector;
+import hep.physics.vec.Hep3Vector;
+import hep.physics.vec.VecOp;
+
+import java.io.BufferedWriter;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.hps.monitoring.drivers.svt.SvtPlotUtils;
+import org.hps.users.phansson.STUtils.STStereoTrack;
+import org.lcsim.detector.converter.compact.subdetector.HpsTracker2;
+import org.lcsim.detector.converter.compact.subdetector.SvtStereoLayer;
+import org.lcsim.detector.tracker.silicon.HpsSiSensor;
+import org.lcsim.event.EventHeader;
+import org.lcsim.geometry.Detector;
+import org.lcsim.geometry.compact.converter.HPSTrackerBuilder;
+import org.lcsim.recon.tracking.digitization.sisim.SiTrackerHitStrip1D;
+import org.lcsim.recon.tracking.digitization.sisim.TrackerHitType.CoordinateSystem;
+import org.lcsim.util.Driver;
+import org.lcsim.util.aida.AIDA;
+
+/**
+ * @author Per Hansson Adrian <[log in to unmask]>
+ *
+ */
+public class StraightThroughAnalysisDriver extends Driver {
+
+    final static Logger logger = Logger.getLogger(StraightThroughAnalysisDriver.class.getSimpleName());
+    private String stripClusterCollectionName = "StripClusterer_SiTrackerHitStrip1D";
+    private List<HpsSiSensor> sensors = null;
+    private IHistogram1D hitCount;
+    private IHistogram1D topHitCount;
+    private IHistogram1D botHitCount;
+    private Map<String,IHistogram2D> stereoHitPositionsXY = new HashMap<String, IHistogram2D>();
+    private Map<String,IHistogram1D> sensorHitResGlobal = new HashMap<String, IHistogram1D>();
+    private Map<String,IHistogram1D>  sensorStereoHitYZResGlobal = new HashMap<String, IHistogram1D>();
+    private Map<String,IHistogram1D>  sensorStereoHitXZResGlobal = new HashMap<String, IHistogram1D>();
+    private Map<String,IHistogram1D> sensorHitPositions = new HashMap<String, IHistogram1D>();
+    private Map<String,IHistogram1D> sensorHitCounts = new HashMap<String, IHistogram1D>();
+    private Map<String,IHistogram1D> sensorHitTimes = new HashMap<String, IHistogram1D>();
+    private Map<String,int[]> sensorHitCountMap = new HashMap<String,int[]>();
+    private static AIDA aida = AIDA.defaultInstance();
+    static final Hep3Vector origo = new BasicHep3Vector(0, 0, 0);
+    private static final Hep3Vector origoStraightThroughs = new BasicHep3Vector(0, 0, 0);
+
+    private final IAnalysisFactory af = aida.analysisFactory();
+    private final IHistogramFactory hf = af.createHistogramFactory(aida.tree());
+    private final IPlotterFactory pf = af.createPlotterFactory("Factory");
+    private Map<String,IPlotter> plotters = new HashMap<String, IPlotter>();
+    private String rootFileName = "";
+    private int runNumber = -1;
+    private IHistogram1D trackAxialHitCount[];
+    private IHistogram1D trackAxialSlope[];
+    private IHistogram1D trackAxialIntercept[];
+    private IHistogram1D trackAxialCount[];
+    private IHistogram2D trackAxialExtraPolation[];
+    private IHistogram2D trackExtraPolationY[];
+    private IHistogram2D trackExtraPolationX[];
+    private IHistogram1D stereoHitCount[];
+    private IHistogram1D trackHitCount[];
+    private IHistogram1D trackSlope[][];
+    private IHistogram1D trackIntercept[][];
+    private IHistogram1D trackCount[];
+    private IHistogram2D[] fitUpdateIteration;
+
+
+    private boolean selectTime = true;
+    private double timeMax = 8.0;
+    private double timeMin = -8.0;
+    private int minHitsAxialTrack = 6;
+    private int minHitsStereoTrack = 6;
+    private STUtils.STTrackFitter regressionFitter  = new STUtils.RegressionFit();
+    //private STTrackFitter regressionFitter  = new LineFit();
+    private final double startPointZ = 1500.0;
+    private final double endPointZ = -3000.0;
+    private final int nPointsZ = 100;
+    private final double[] wirePosition = {-67.23, 0.0, -2337.1};
+    private String subdetectorName = "Tracker";
+    private List<SvtStereoLayer> stereoLayers;
+
+    private String outputFilename = "";
+    private PrintWriter gblPrintWriter = null;
+    
+
+    
+    /**
+     * 
+     */
+    public StraightThroughAnalysisDriver() {
+        logger.setLevel(Level.INFO);
+        STUtils.logger.setLevel(logger.getLevel());
+    }
+
+  
+    private static double getTheta0(double beta,double p,double X0) {
+        return 13.6/beta/p*Math.sqrt(X0)*(1 + 0.038*Math.log(X0));
+    }
+    protected void detectorChanged(Detector detector) {
+
+        if(!outputFilename.isEmpty()) {
+            try {
+                gblPrintWriter = new PrintWriter( new BufferedWriter(new FileWriter(outputFilename)));
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+            logger.info("Created a GBL filewriter for to file \"" + outputFilename + "\"");
+        }
+
+        // find the stereo layers for this detector
+        stereoLayers = ((HpsTracker2) detector.getSubdetector(subdetectorName).getDetectorElement()).getStereoPairs();
+        StringBuffer sb = new StringBuffer("Found " + stereoLayers.size() + " stereo layers:");
+        for(SvtStereoLayer sl : stereoLayers) sb.append(sl.getLayerNumber() + ": " + sl.getAxialSensor().getName()+ " - " + sl.getStereoSensor().getName() + "\n");
+        logger.info(sb.toString());
+
+        //
+        double beta = 1.0;
+        double p = 1.05;
+        double X0 = 0.007; // per stereo pair
+        double theta0 = getTheta0(beta, p, X0);
+        double msErrY = 100.0*theta0;
+        regressionFitter.setErrY(msErrY);
+        
+        
+        // Get the HpsSiSensor objects from the geometry
+        sensors = detector.getSubdetector("Tracker").getDetectorElement().findDescendants(HpsSiSensor.class);
+        aida.tree().cd("/");
+        plotters.put("Sensor hit position", af.createPlotterFactory().create("Sensor hit positions"));
+        plotters.get("Sensor hit position").setStyle(this.getDefaultPlotterStyle("Hit y (mm)","Entries"));
+        plotters.get("Sensor hit position").createRegions(6, 6);
+        plotters.put("Sensor hit res", af.createPlotterFactory().create("Sensor hit res"));
+        //plotters.get("Sensor hit res").setStyle(this.getDefaultPlotterStyle("Hit y res global (mm)","Entries"));
+        plotters.get("Sensor hit res").createRegions(3, 6);
+        plotters.put("Sensor stereo YZ hit res", af.createPlotterFactory().create("Sensor stereo YZ hit res"));
+        plotters.get("Sensor stereo YZ hit res").setStyle(this.getDefaultPlotterStyle("Stereo hit y res global (mm)","Entries"));
+        plotters.get("Sensor stereo YZ hit res").createRegions(3, 6);
+        plotters.put("Sensor stereo XZ hit res", af.createPlotterFactory().create("Sensor stereo XZ hit res"));
+        plotters.get("Sensor stereo XZ hit res").setStyle(this.getDefaultPlotterStyle("Stereo hit x res global (mm)","Entries"));
+        plotters.get("Sensor stereo XZ hit res").createRegions(3, 6);
+        plotters.put("Sensor hit times", af.createPlotterFactory().create("Sensor hit times"));
+        plotters.get("Sensor hit times").setStyle(this.getDefaultPlotterStyle("Hit time (ns)","Entries"));
+        plotters.get("Sensor hit times").createRegions(6, 6);
+        plotters.put("Sensor cluster counts", af.createPlotterFactory().create("Sensor cluster counts"));
+        plotters.get("Sensor cluster counts").setStyle(this.getDefaultPlotterStyle("Cluster multiplicity","Entries"));
+        plotters.get("Sensor cluster counts").createRegions(6, 6);
+        plotters.put("Cluster counts", af.createPlotterFactory().create("Cluster counts"));
+        plotters.get("Cluster counts").setStyle(this.getDefaultPlotterStyle("Cluster multiplicity","Entries"));
+        plotters.get("Cluster counts").createRegions(2,2);
+        plotters.put("Track axial extrapolation", af.createPlotterFactory().create("Track axial extrapolation"));
+        plotters.get("Track axial extrapolation").setStyle(this.getDefaultPlotterStyle("Z (mm)","Y (mm)"));
+        plotters.get("Track axial extrapolation").createRegions(2,3);
+        plotters.put("Track extrapolation Y", af.createPlotterFactory().create("Track extrapolation Y"));
+        plotters.get("Track extrapolation Y").setStyle(this.getDefaultPlotterStyle("Z (mm)","Y (mm)"));
+        plotters.get("Track extrapolation Y").createRegions(2,3);
+        plotters.put("Track extrapolation X", af.createPlotterFactory().create("Track extrapolation X"));
+        plotters.get("Track extrapolation X").setStyle(this.getDefaultPlotterStyle("Z (mm)","X (mm)"));
+        plotters.get("Track extrapolation X").createRegions(2,3);
+        plotters.put("Stereo hit position", af.createPlotterFactory().create("Stereo hit positions"));
+        plotters.get("Stereo hit position").setStyle(this.getDefaultPlotterStyle("Hit x (mm)","Hit y (mm)"));
+        plotters.get("Stereo hit position").createRegions(3, 6);
+        plotters.put("Stereo hit count", af.createPlotterFactory().create("Stereo hit count"));
+        plotters.get("Stereo hit count").createRegions(1, 2);
+        plotters.put("Fit update iterations", af.createPlotterFactory().create("Fit update iterations"));
+        plotters.get("Fit update iterations").setStyle(this.getDefaultPlotterStyle("Iterations","Average hit update magnitude (mm)"));
+        plotters.get("Fit update iterations").createRegions(1, 2);
+
+        topHitCount = hf.createHistogram1D("Top hit count", 21,-0.5, 20.5);
+        botHitCount = hf.createHistogram1D("Bottom hit count", 21,-0.5, 20.5);
+        hitCount = hf.createHistogram1D("Hit count", 21, -0.5, 20.5);
+        trackAxialHitCount = new IHistogram1D[2];
+        trackAxialCount = new IHistogram1D[2];
+        trackAxialSlope = new IHistogram1D[2];
+        trackAxialIntercept = new IHistogram1D[2];
+        trackAxialExtraPolation = new IHistogram2D[5];
+        trackExtraPolationY = new IHistogram2D[5];
+        trackExtraPolationX = new IHistogram2D[5];
+        stereoHitCount = new IHistogram1D[2];
+        trackHitCount = new IHistogram1D[2];
+        trackCount = new IHistogram1D[2];
+        trackSlope = new IHistogram1D[2][];
+        trackIntercept = new IHistogram1D[2][];
+        fitUpdateIteration = new IHistogram2D[2];
+        
+
+        for(int i=0;i<2;++i) {
+            String half = i==0 ? "top" : "bottom";
+            
+            trackHitCount[i]= hf.createHistogram1D("Track " + half + " hit multiplicity", 11, -0.5, 10.5);
+            trackCount[i] = hf.createHistogram1D("Track " + half + " multiplicity", 11, -0.5, 10.5);
+            trackSlope[i] = new IHistogram1D[2];
+            trackIntercept[i] = new IHistogram1D[2];
+            trackSlope[i][STUtils.STStereoTrack.VIEW.YZ.ordinal()] = hf.createHistogram1D("Track " + half +" " + STUtils.STStereoTrack.VIEW.YZ.name()  + " slope", 50, -0.05, 0.05);
+            trackSlope[i][STUtils.STStereoTrack.VIEW.XZ.ordinal()] = hf.createHistogram1D("Track " + half +" " + STUtils.STStereoTrack.VIEW.XZ.name()  + " slope", 50, -0.1, 0.1);
+            if(i==0) {
+                trackIntercept[i][STUtils.STStereoTrack.VIEW.YZ.ordinal()] = hf.createHistogram1D("Track " + half +" " + STUtils.STStereoTrack.VIEW.YZ.name()  + " intecept", 50, 0, 50);
+                trackIntercept[i][STUtils.STStereoTrack.VIEW.XZ.ordinal()] = hf.createHistogram1D("Track " + half +" " + STUtils.STStereoTrack.VIEW.XZ.name()  + " intecept", 50, -80, 0);
+                trackAxialIntercept[i] = hf.createHistogram1D("Track axial " + half +" intercept", 50, 0, 50);
+            } else {
+                trackIntercept[i][STUtils.STStereoTrack.VIEW.YZ.ordinal()] = hf.createHistogram1D("Track " + half +" " + STUtils.STStereoTrack.VIEW.YZ.name()  + " intecept", 50, -50, 0);
+                trackIntercept[i][STUtils.STStereoTrack.VIEW.XZ.ordinal()] = hf.createHistogram1D("Track " + half +" " + STUtils.STStereoTrack.VIEW.XZ.name()  + " intecept", 50, -50, 50);
+                trackAxialIntercept[i] = hf.createHistogram1D("Track axial " + half +" intercept", 50, -50, 0);
+            }
+            trackAxialHitCount[i] = hf.createHistogram1D("Track axial " + half +" hit multiplicity", 11, -0.5, 10.5);
+            trackAxialCount[i] = hf.createHistogram1D("Track axial " + half +" multiplicity", 2, -0.5, 1.5);
+            trackAxialSlope[i] = hf.createHistogram1D("Track axial " + half +" slope", 50, -0.05, 0.05);
+            trackAxialExtraPolation[i] = hf.createHistogram2D("Track axial " + half +" extrapolation", nPointsZ, endPointZ, startPointZ,50,-80,80);
+            trackExtraPolationY[i] = hf.createHistogram2D("Track " + half +" extrapolation Y", nPointsZ, endPointZ, startPointZ,50,-80,80);
+            trackExtraPolationX[i] = hf.createHistogram2D("Track " + half +" extrapolation X", nPointsZ, endPointZ, startPointZ,50,-100,60);
+            stereoHitCount[i] = hf.createHistogram1D("Stereo hit count " + half, 11, -0.5, 10.5);
+            
+            fitUpdateIteration[i] = hf.createHistogram2D("Fit update" + half, 6, -0.5, 6.5,50,0,20);
+            
+            plotters.get("Fit update iterations").region(i).plot(fitUpdateIteration[i]);
+            
+            plotters.put("Track " + half +" axial", af.createPlotterFactory().create("Track " + half +" axial"));
+            //plotters.get("Track " + half +" axial").setStyle(this.getDefaultPlotterStyle("","Entries",true));
+            plotters.get("Track " + half +" axial").createRegions(2,2);
+
+            plotters.get("Track " + half +" axial").region(0).plot(trackAxialHitCount[i]);
+            plotters.get("Track " + half +" axial").region(1).plot(trackAxialCount[i]);
+            plotters.get("Track " + half +" axial").region(2).plot(trackAxialSlope[i]);
+            plotters.get("Track " + half +" axial").region(3).plot(trackAxialIntercept[i]);
+
+
+
+            plotters.put("Track " + half, af.createPlotterFactory().create("Track " + half));
+            //plotters.get("Track " + half +" axial").setStyle(this.getDefaultPlotterStyle("","Entries",true));
+            plotters.get("Track " + half).createRegions(3,2);
+            plotters.get("Track " + half).region(0).plot(trackHitCount[i]);
+            plotters.get("Track " + half).region(1).plot(trackCount[i]);
+            plotters.get("Track " + half).region(2).plot(trackSlope[i][STUtils.STStereoTrack.VIEW.YZ.ordinal()]);
+            plotters.get("Track " + half).region(3).plot(trackIntercept[i][STUtils.STStereoTrack.VIEW.YZ.ordinal()]);
+            plotters.get("Track " + half).region(4).plot(trackSlope[i][STUtils.STStereoTrack.VIEW.XZ.ordinal()]);
+            plotters.get("Track " + half).region(5).plot(trackIntercept[i][STUtils.STStereoTrack.VIEW.XZ.ordinal()]);
+            
+            plotters.get("Stereo hit count").region(i).plot(stereoHitCount[i]);
+            
+            plotters.get("Track axial extrapolation").region(i).plot(trackAxialExtraPolation[i]);
+            plotters.get("Track extrapolation Y").region(i).plot(trackExtraPolationY[i]);
+            plotters.get("Track extrapolation X").region(i).plot(trackExtraPolationX[i]);
+            
+        }
+        
+        trackAxialExtraPolation[2] = hf.createHistogram2D("Track axial extrapolation", nPointsZ, endPointZ, startPointZ,50,-80,80);
+        plotters.get("Track axial extrapolation").region(2).plot(trackAxialExtraPolation[2]);
+        trackAxialExtraPolation[3] = hf.createHistogram2D("Track axial extrapolation wires", nPointsZ, wirePosition[2]-350, wirePosition[2]+350,50,-20,20);
+        plotters.get("Track axial extrapolation").region(3).plot(trackAxialExtraPolation[3]);
+        trackAxialExtraPolation[4] = hf.createHistogram2D("Track axial extrapolation rndm", nPointsZ, -200.0, 200.0,50,-60,60);
+        plotters.get("Track axial extrapolation").region(4).plot(trackAxialExtraPolation[4]);
+
+        trackExtraPolationY[2] = hf.createHistogram2D("Track extrapolation Y", nPointsZ, endPointZ, startPointZ,50,-80,80);
+        plotters.get("Track extrapolation Y").region(2).plot(trackExtraPolationY[2]);
+        trackExtraPolationY[3] = hf.createHistogram2D("Track extrapolation Y wires", nPointsZ, wirePosition[2]-350, wirePosition[2]+350,50,-20,20);
+        plotters.get("Track extrapolation Y").region(3).plot(trackExtraPolationY[3]);
+        trackExtraPolationY[4] = hf.createHistogram2D("Track extrapolation Y rndm", nPointsZ, -200.0, 200.0,50,-60,60);
+        plotters.get("Track extrapolation Y").region(4).plot(trackExtraPolationY[4]);
+
+        trackExtraPolationX[2] = hf.createHistogram2D("Track extrapolation X", nPointsZ, endPointZ, startPointZ,50,-100,60);
+        plotters.get("Track extrapolation X").region(2).plot(trackExtraPolationX[2]);
+        trackExtraPolationX[3] = hf.createHistogram2D("Track extrapolation X wires", nPointsZ, wirePosition[2]-350, wirePosition[2]+350,50,-80,-20);
+        plotters.get("Track extrapolation X").region(3).plot(trackExtraPolationX[3]);
+        trackExtraPolationX[4] = hf.createHistogram2D("Track extrapolation X rndm", nPointsZ, -200.0, 200.0,50,-60,0);
+        plotters.get("Track extrapolation X").region(4).plot(trackExtraPolationX[4]);
+
+        plotters.get("Cluster counts").region(0).plot(hitCount);
+        plotters.get("Cluster counts").region(1).plot(topHitCount);
+        plotters.get("Cluster counts").region(2).plot(botHitCount);
+        
+        
+        for(HpsSiSensor sensor : sensors) {
+            
+            if(sensor.isBottomLayer()) {
+                sensorHitPositions.put(sensor.getName(), hf.createHistogram1D(sensor.getName() + "_hitpos1D", 50, -60, 0));
+                if(sensor.isAxial()) {
+                    stereoHitPositionsXY.put(sensor.getName(), hf.createHistogram2D(sensor.getName() + "_stereohitpos2D", 50, -100, 1000,50,-60,0));
+                    plotters.get("Stereo hit position").region(SvtPlotUtils.computePlotterRegionAxialOnly(sensor)).plot(stereoHitPositionsXY.get(sensor.getName()));
+                }
+            }
+            else{
+                sensorHitPositions.put(sensor.getName(), hf.createHistogram1D(sensor.getName() + "_hitpos1D", 50, 0, 60));
+                if(sensor.isAxial()) {
+                    stereoHitPositionsXY.put(sensor.getName(), hf.createHistogram2D(sensor.getName() + "_stereohitpos2D", 50, -100, 100,50,0,60));
+                    plotters.get("Stereo hit position").region(SvtPlotUtils.computePlotterRegionAxialOnly(sensor)).plot(stereoHitPositionsXY.get(sensor.getName()));
+                }
+            }
+            sensorHitCounts.put(sensor.getName(), hf.createHistogram1D(sensor.getName() + "_hitcount", 11, -0.5, 10.5));
+            sensorHitTimes.put(sensor.getName(), hf.createHistogram1D(sensor.getName() + "_hittime", 50, -100, 100));
+            sensorHitCountMap.put(sensor.getName(), new int[1]);
+            sensorHitCountMap.get(sensor.getName())[0] = 0;
+
+            if(sensor.isAxial()) {
+                sensorHitResGlobal.put(sensor.getName(), hf.createHistogram1D(sensor.getName() + "_hitresglobal", 50, -0.7, 0.7));
+                plotters.get("Sensor hit res").region(SvtPlotUtils.computePlotterRegionAxialOnly(sensor)).plot(sensorHitResGlobal.get(sensor.getName()));
+                plotters.get("Sensor hit res").region(0).style().dataStyle().showInStatisticsBox(true);
+                sensorStereoHitYZResGlobal.put(sensor.getName(), hf.createHistogram1D(sensor.getName() + "_stereohityzresglobal", 50, -1, 1));
+                plotters.get("Sensor stereo YZ hit res").region(SvtPlotUtils.computePlotterRegionAxialOnly(sensor)).plot(sensorStereoHitYZResGlobal.get(sensor.getName()));
+                plotters.get("Sensor stereo YZ hit res").region(0).style().dataStyle().showInStatisticsBox(true);
+                sensorStereoHitXZResGlobal.put(sensor.getName(), hf.createHistogram1D(sensor.getName() + "_stereohitxzresglobal", 50, -1, 1));
+                plotters.get("Sensor stereo XZ hit res").region(SvtPlotUtils.computePlotterRegionAxialOnly(sensor)).plot(sensorStereoHitXZResGlobal.get(sensor.getName()));
+                plotters.get("Sensor stereo XZ hit res").region(0).style().dataStyle().showInStatisticsBox(true);
+
+            
+            }
+            
+            plotters.get("Sensor hit position").region(SvtPlotUtils.computePlotterRegion(sensor)).plot(sensorHitPositions.get(sensor.getName()));
+            plotters.get("Sensor hit times").region(SvtPlotUtils.computePlotterRegion(sensor)).plot(sensorHitTimes.get(sensor.getName()));
+            plotters.get("Sensor cluster counts").region(SvtPlotUtils.computePlotterRegion(sensor)).plot(sensorHitCounts.get(sensor.getName()));
+            
+        }
+
+        for(IPlotter plotter : plotters.values())
+            plotter.show();
+    }
+    
+    
+    protected void resetCounts() {
+        //reset hit counts
+        for(HpsSiSensor sensor : sensors) {
+            sensorHitCountMap.get(sensor.getName())[0] = 0;
+        }
+    }
+    protected void process(EventHeader event) {
+    
+        logger.fine("Process event");
+        
+        if (runNumber  == -1) {
+            runNumber = event.getRunNumber();
+        }
+        
+        //Find all strip clusters in the events
+        List<SiTrackerHitStrip1D> stripClusters = new ArrayList<SiTrackerHitStrip1D>();
+        if(event.hasCollection(SiTrackerHitStrip1D.class, stripClusterCollectionName)) {
+            stripClusters = event.get(SiTrackerHitStrip1D.class, stripClusterCollectionName);
+        }
+        
+        logger.fine("Found " + stripClusters.size() + " strip clusters in the event");
+    
+        resetCounts();
+        
+        List<SiTrackerHitStrip1D> topHits= new ArrayList<SiTrackerHitStrip1D>(); 
+        List<SiTrackerHitStrip1D> botHits= new ArrayList<SiTrackerHitStrip1D>(); 
+        
+        // Create a map of axial hits
+        List<Map<Integer, List<SiTrackerHitStrip1D>>> axialHitsPerLayer = new ArrayList<Map<Integer, List<SiTrackerHitStrip1D>>>();
+        axialHitsPerLayer.add(new HashMap<Integer, List<SiTrackerHitStrip1D>>());
+        axialHitsPerLayer.add(new HashMap<Integer, List<SiTrackerHitStrip1D>>());
+        
+        // Create a map of stereo hits
+        List<Map<Integer, List<SiTrackerHitStrip1D>>> stereoHitsPerLayer = new ArrayList<Map<Integer, List<SiTrackerHitStrip1D>>>();
+        stereoHitsPerLayer.add(new HashMap<Integer, List<SiTrackerHitStrip1D>>());
+        stereoHitsPerLayer.add(new HashMap<Integer, List<SiTrackerHitStrip1D>>());
+        
+        
+        for(SiTrackerHitStrip1D cluster : stripClusters) {
+            SiTrackerHitStrip1D cluster_global = cluster.getTransformedHit(CoordinateSystem.GLOBAL);
+            HpsSiSensor sensor = (HpsSiSensor) cluster.getRawHits().get(0).getDetectorElement();
+            int layer = HPSTrackerBuilder.getLayerFromVolumeName(sensor.getName());
+            sensorHitPositions.get(sensor.getName()).fill(cluster_global.getPositionAsVector().y());
+            sensorHitTimes.get(sensor.getName()).fill(cluster.getTime());
+            logger.fine("cluster position " + cluster_global.getPositionAsVector().toString());
+            sensorHitCountMap.get(sensor.getName())[0]++;
+
+            if(sensor.isTopLayer()) {
+                topHits.add(cluster);
+            } else {
+                botHits.add(cluster);
+            }
+            //hit time selection
+            if(!selectTime || (cluster.getTime() < timeMax && cluster.getTime()>timeMin)) { 
+
+                // look at axials and stereo separately
+                if(sensor.isAxial()) {
+
+                    Map<Integer, List<SiTrackerHitStrip1D>> hitsPerLayer;
+                    if(sensor.isTopLayer()) {
+                        hitsPerLayer = axialHitsPerLayer.get(0);
+                    } else {
+                        hitsPerLayer = axialHitsPerLayer.get(1);
+                    }
+
+                    List<SiTrackerHitStrip1D> hits;
+                    hits = hitsPerLayer.get(layer);
+                    if(hits == null) {
+                        hits = new ArrayList<SiTrackerHitStrip1D>();
+                        hitsPerLayer.put(layer, hits);
+                    }
+                    hits.add(cluster);
+
+                } else {
+                    
+                    // look at stereos
+
+                    Map<Integer, List<SiTrackerHitStrip1D>> hitsPerLayer;
+                    if(sensor.isTopLayer()) {
+                        hitsPerLayer = stereoHitsPerLayer.get(0);
+                    } else {
+                        hitsPerLayer = stereoHitsPerLayer.get(1);
+                    }
+
+                    List<SiTrackerHitStrip1D> hits;
+                    hits = hitsPerLayer.get(layer);
+                    if(hits == null) {
+                        hits = new ArrayList<SiTrackerHitStrip1D>();
+                        hitsPerLayer.put(layer, hits);
+                    }
+                    hits.add(cluster);
+
+                }
+
+            }
+            
+        }
+        
+        //count hits
+        hitCount.fill(stripClusters.size());
+        topHitCount.fill(topHits.size());
+        botHitCount.fill(botHits.size());
+  
+        // fill hit positions
+        for(HpsSiSensor sensor : sensors) 
+            sensorHitCounts.get(sensor.getName()).fill(sensorHitCountMap.get(sensor.getName())[0] );
+
+        
+        // Pattern recognition for axial hits - yeah!
+        List< List<SiTrackerHitStrip1D>> axialSeedHits = new ArrayList<List<SiTrackerHitStrip1D>>();
+        for(int ihalf=0; ihalf<2; ++ihalf) {
+            List<SiTrackerHitStrip1D> seedHits = new ArrayList<SiTrackerHitStrip1D>();
+            for(int layer : axialHitsPerLayer.get(ihalf).keySet()) {
+                // single hit on the sensor
+                if( axialHitsPerLayer.get(ihalf).get(layer).size() == 1 )
+                    seedHits.add(axialHitsPerLayer.get(ihalf).get(layer).get(0));
+            }
+            axialSeedHits.add(seedHits);
+        }
+        
+        // Pattern recognition for stereo hits - yeah!
+        List< List<SiTrackerHitStrip1D>> stereoSeedHits = new ArrayList<List<SiTrackerHitStrip1D>>();
+        for(int ihalf=0; ihalf<2; ++ihalf) {
+            List<SiTrackerHitStrip1D> seedHits = new ArrayList<SiTrackerHitStrip1D>();
+            for(int layer : stereoHitsPerLayer.get(ihalf).keySet()) {
+                // single hit on the sensor
+                if( stereoHitsPerLayer.get(ihalf).get(layer).size() == 1 )
+                    seedHits.add(stereoHitsPerLayer.get(ihalf).get(layer).get(0));
+            }
+            stereoSeedHits.add(seedHits);
+        }
+        
+
+        // try to make stereo hits
+        
+        
+        List< List<STUtils.StereoPair> > stereoPairs  = new ArrayList< List<STUtils.StereoPair>>();
+        
+        
+        
+        for(int ihalf=0; ihalf<2; ++ihalf) {
+            List<STUtils.StereoPair> stereoPairCandidates = new ArrayList< STUtils.StereoPair>();
+            List<SiTrackerHitStrip1D> aSeedHits = axialSeedHits.get(ihalf);
+            for(SiTrackerHitStrip1D axialSeedHit : aSeedHits) {
+
+                // find the stereo sensor and its hit from the pre-compiled stereo pair list
+                HpsSiSensor stereoSensor = null;
+                SiTrackerHitStrip1D stereoSeedHit = null;
+                
+                HpsSiSensor axialSensor = (HpsSiSensor) axialSeedHit.getRawHits().get(0).getDetectorElement();
+                logger.fine("Look for stereo sensor to \"" + axialSensor.getName() + "\"");
+                
+                for(SvtStereoLayer stereoLayer : stereoLayers) {
+                    if(stereoLayer.getAxialSensor().getName().equals(axialSensor.getName())) {
+                        stereoSensor = stereoLayer.getStereoSensor();
+                        break;
+                    }
+                }
+                
+                // make sure it was found
+                if(stereoSensor == null) throw new RuntimeException("Couldn't find stereo sensor to \"" + axialSensor.getName() + "\"");
+                
+                logger.fine("Found stereo sensor \"" + stereoSensor.getName() + "\"");
+                
+                // find the hit
+                // this only works for single hits per sensor
+                for(List<SiTrackerHitStrip1D> sSeedHits : stereoSeedHits) {
+                    for(SiTrackerHitStrip1D stereoSeedHitCandidate : sSeedHits) {
+                        HpsSiSensor sensor = (HpsSiSensor) stereoSeedHitCandidate.getRawHits().get(0).getDetectorElement();
+                        if(sensor.getName().equals(stereoSensor.getName())) {
+                            logger.fine("Found stereo hit at " + stereoSeedHitCandidate.getPositionAsVector().toString() + " at sensor \"" + stereoSensor.getName() + "\"");
+                            stereoSeedHit = stereoSeedHitCandidate;
+                            break; // ok, this only works for single hits per sensor
+                        }
+                    }
+                }
+                
+                // Check if we found a candidate pair
+                if(stereoSeedHit != null) {
+                    STUtils.StereoPair pair = new STUtils.StereoPair(axialSeedHit,stereoSeedHit,origoStraightThroughs);
+                    if(STUtils.StereoPair.passCuts(pair))
+                        stereoPairCandidates.add( pair );
+                }
+            }
+            stereoPairs.add(stereoPairCandidates);
+        }
+
+        
+       
+        // loop over the stereo pairs
+        for(int ihalf=0; ihalf<2; ++ihalf) {
+            List< STUtils.StereoPair > pairs = stereoPairs.get(ihalf);
+            
+            logger.fine("Found " + pairs.size() + " stereo candidates for " + (ihalf == 0 ? "top" : "bottom"));
+            
+            // Fill count
+            stereoHitCount[ihalf].fill(pairs.size());
+
+            // Plot the position of the hits
+            for(STUtils.StereoPair pair : pairs) {
+                Hep3Vector p = pair.getPosition();
+                stereoHitPositionsXY.get(pair.getAxial().getRawHits().get(0).getDetectorElement().getName()).fill(p.x(),p.y());
+                logger.fine(p.toString() + " from " + pair.getAxial().getPositionAsVector().toString() + "  " + pair.getStereo().getPositionAsVector().toString() 
+                        + " ("+pair.getAxial().getRawHits().get(0).getDetectorElement().getName() +" and "+pair.getStereo().getRawHits().get(0).getDetectorElement().getName()+")");
+            }
+        }
+        
+        
+        // add hits to axial tracks and fit them
+        List<STUtils.STTrack> axialTracks = new ArrayList<STUtils.STTrack>();
+        for(List<SiTrackerHitStrip1D> seedHits : axialSeedHits) {
+            
+            if(seedHits.size() < minHitsAxialTrack) 
+                continue;
+
+            STUtils.STTrack track = new STUtils.STTrack();
+            track.setHits(seedHits);
+            
+            logger.fine("Fit axial track");
+            regressionFitter.fit(track);
+            track.addFit(regressionFitter.getFit());
+            
+            axialTracks.add(track);
+        }
+
+        // add stereo hits to tracks and fit them with simple regression in 1D
+        List<STUtils.STStereoTrack> stereoTracks = new ArrayList<STUtils.STStereoTrack>();
+        for(List<STUtils.StereoPair> seedHits : stereoPairs) {
+            
+            if(seedHits.size() < minHitsStereoTrack) 
+                continue;
+
+            STUtils.STStereoTrack track = new STUtils.STStereoTrack();
+            track.setHits(seedHits);
+            
+            STUtils.fit(regressionFitter, track);
+
+            //            logger.fine("Fit stereo track in YZ");
+//            regressionFitter.fit(track.getPointList(STStereoTrack.VIEW.YZ,null));
+//            track.setFit(regressionFitter.getFit(), STStereoTrack.VIEW.YZ);
+//            logger.fine("Fit stereo track in XZ");
+//            regressionFitter.fit(track.getPointList(STStereoTrack.VIEW.XZ,STStereoTrack.VIEW.YZ));
+//            track.setFit(regressionFitter.getFit(), STStereoTrack.VIEW.XZ);
+            
+            stereoTracks.add(track);
+        }
+        
+        
+        
+        // Loop over the axial tracks
+        int nTracksAxial[] = {0,0};
+        for(STUtils.STTrack track : axialTracks) {
+            
+            for(SiTrackerHitStrip1D hit : track.getHits()) {
+                double yhit = hit.getPositionAsVector().y();
+                double zHit = hit.getPositionAsVector().z();
+                double yPred = track.predict(zHit);
+                double resGlobal = yhit - yPred;
+                sensorHitResGlobal.get(hit.getRawHits().get(0).getDetectorElement().getName()).fill(resGlobal);
+            }
+            
+            logger.fine(track.toString());
+
+            if(track.isTop()) {
+                nTracksAxial[0]++;
+                trackAxialHitCount[0].fill(track.getHits().size());
+                trackAxialSlope[0].fill(track.getSlope());
+                trackAxialIntercept[0].fill(track.getIntercept());
+            }
+            else {
+                nTracksAxial[1]++;
+                trackAxialHitCount[1].fill(track.getHits().size());
+                trackAxialSlope[1].fill(track.getSlope());
+                trackAxialIntercept[1].fill(track.getIntercept());
+            }
+         }   
+        trackAxialCount[0].fill(nTracksAxial[0]);
+        trackAxialCount[1].fill(nTracksAxial[1]);
+        
+        
+        
+        // Loop over the stereo tracks
+        int nTracks[] = {0,0};
+        for(STUtils.STStereoTrack track : stereoTracks) {
+
+            int half = track.isTop() ? 0 : 1;
+            
+            // update the hit positions with the fit
+            double delta = 9999.9;
+            int idelta = 0;
+            while(delta>0.05) {
+                logger.fine(idelta + ": delta " + delta);
+                delta = 0.0;
+                for(STUtils.StereoPair pair : track.getHits()) {
+                    Hep3Vector p = new BasicHep3Vector(pair.getPosition().v());
+                    Hep3Vector trackDirection = track.getDirection();
+                    logger.fine("updatePosition " + p.toString() + " with track dir " + trackDirection.toString());
+                    pair.updatePosition(trackDirection);
+                    Hep3Vector pnew = pair.getPosition();
+                    logger.fine("new position " + pnew.toString());
+                    delta += VecOp.sub(p, pnew).magnitude();
+                }
+                delta = delta / track.getHits().size();
+                idelta++;
+
+                fitUpdateIteration[half].fill(idelta,delta);
+
+                // Re-fit the track after the update
+                STUtils.fit(regressionFitter,track);
+//                track.clearFit();
+//                logger.fine("Fit stereo track in YZ");
+//                regressionFitter.fit(track.getPointList(STStereoTrack.VIEW.YZ,null));
+//                track.setFit(regressionFitter.getFit(), STStereoTrack.VIEW.YZ);
+//                logger.fine("Fit stereo track in XZ");
+//                regressionFitter.fit(track.getPointList(STStereoTrack.VIEW.XZ,STStereoTrack.VIEW.YZ));
+//                track.setFit(regressionFitter.getFit(), STStereoTrack.VIEW.XZ);
+                
+            }
+            logger.fine("finished update position after " + idelta + "iterations with delta " + delta);
+            
+            
+            for(STUtils.StereoPair hit : track.getHits()) {
+                double yhit = hit.getPosition().y();
+                double xhit = hit.getPosition().x();
+                double zHit = hit.getPosition().z();
+                double xyPred[] = track.predict(zHit);
+                double resGlobalY = yhit - xyPred[STStereoTrack.VIEW.YZ.ordinal()];
+                double resGlobalX = xhit - xyPred[STStereoTrack.VIEW.XZ.ordinal()];;
+                sensorStereoHitYZResGlobal.get(hit.getAxial().getRawHits().get(0).getDetectorElement().getName()).fill(resGlobalY);
+                sensorStereoHitXZResGlobal.get(hit.getAxial().getRawHits().get(0).getDetectorElement().getName()).fill(resGlobalX);
+            }
+
+            logger.fine(track.toString());
+
+            nTracks[half]++;
+            trackHitCount[half].fill(track.getHits().size());
+            for(int v=0;v<2;++v) {
+                STUtils.STStereoTrack.VIEW view = STUtils.STStereoTrack.VIEW.values()[v];
+                trackSlope[half][v].fill(track.getSlope()[view.ordinal()]);
+                trackIntercept[half][v].fill(track.getIntercept()[view.ordinal()]);
+            }
+        }   
+        trackCount[0].fill(nTracks[0]);
+        trackCount[1].fill(nTracks[1]);
+
+
+        
+        
+        //predict where these axial tracks go upstream in Y
+        double zIter,yIter,start,end;
+        for(STUtils.STTrack track : axialTracks) {
+            int half = track.isTop() ? 0 : 1;
+            for(int i = 0; i < (nPointsZ+1); ++i) {
+                zIter = startPointZ - i*(startPointZ - endPointZ)/(double)nPointsZ; 
+                yIter = track.predict(zIter);
+                trackAxialExtraPolation[half].fill(zIter,yIter);
+                trackAxialExtraPolation[2].fill(zIter,yIter);
+            }
+            start = wirePosition[2] + 350.0;
+            end = wirePosition[2] - 350.0;
+            for(int i = 0; i < (nPointsZ+1); ++i) {
+                zIter = start - i*(start - end)/(double)nPointsZ; 
+                yIter = track.predict(zIter);
+                trackAxialExtraPolation[3].fill(zIter,yIter);
+            }
+            start = 200.0;
+            end = -200.0;
+            for(int i = 0; i < (nPointsZ+1); ++i) {
+                zIter = start - i*(start - end)/(double)nPointsZ; 
+                yIter = track.predict(zIter);
+                trackAxialExtraPolation[4].fill(zIter,yIter);
+            }
+        }
+
+        
+      //predict where the stereo tracks go upstream in X-Y
+        double xyIter[];
+        for(STStereoTrack track : stereoTracks) {
+            int half = track.isTop() ? 0 : 1;
+            for(int i = 0; i < (nPointsZ+1); ++i) {
+                zIter = startPointZ - i*(startPointZ - endPointZ)/(double)nPointsZ; 
+                xyIter = track.predict(zIter);
+                trackExtraPolationY[half].fill(zIter,xyIter[STStereoTrack.VIEW.YZ.ordinal()]);
+                trackExtraPolationY[2].fill(zIter,xyIter[STStereoTrack.VIEW.YZ.ordinal()]);
+                trackExtraPolationX[half].fill(zIter,xyIter[STStereoTrack.VIEW.XZ.ordinal()]);
+                trackExtraPolationX[2].fill(zIter,xyIter[STStereoTrack.VIEW.XZ.ordinal()]);
+            }
+            start = wirePosition[2] + 350.0;
+            end = wirePosition[2] - 350.0;
+            for(int i = 0; i < (nPointsZ+1); ++i) {
+                zIter = start - i*(start - end)/(double)nPointsZ; 
+                xyIter = track.predict(zIter);
+                trackExtraPolationY[3].fill(zIter,xyIter[STStereoTrack.VIEW.YZ.ordinal()]);
+                trackExtraPolationX[3].fill(zIter,xyIter[STStereoTrack.VIEW.XZ.ordinal()]);
+            }
+            start = 200.0;
+            end = -200.0;
+            for(int i = 0; i < (nPointsZ+1); ++i) {
+                zIter = start - i*(start - end)/(double)nPointsZ; 
+                xyIter = track.predict(zIter);
+                trackExtraPolationY[4].fill(zIter,xyIter[STStereoTrack.VIEW.YZ.ordinal()]);
+                trackExtraPolationX[4].fill(zIter,xyIter[STStereoTrack.VIEW.XZ.ordinal()]);
+            }
+        }
+
+
+        // GBL interface
+        if(gblPrintWriter != null) {
+            STUtils.printGBL(gblPrintWriter, event, stereoTracks);
+        }
+
+
+    }
+    
+    
+    protected void endOfData() {
+        
+        rootFileName = outputFilename + "_hitrecon.root";
+        RootFileStore rootFileStore = new RootFileStore(rootFileName);
+        try {
+            rootFileStore.open();
+            rootFileStore.add(aida.tree());
+            rootFileStore.close();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        
+        if(gblPrintWriter != null) gblPrintWriter.close();
+        
+    }
+
+    
+    private void updateFits() {
+        for(HpsSiSensor sensor : sensors) {
+            IHistogram1D h = sensorHitResGlobal.get(sensor.getName());
+            if(h != null) {
+                if( h.entries() > 20) {
+                    IFitResult f = SvtPlotUtils.performGaussianFit(h);
+                    if(f != null) {
+                        SvtPlotUtils.plot(plotters.get("Sensor hit res"), f.fittedFunction(), null, SvtPlotUtils.computePlotterRegionAxialOnly(sensor));
+                    }
+                }
+            }
+//            if(sensor.isAxial()) {
+//                sensorHitResGlobal.put(sensor.getName(), hf.createHistogram1D(sensor.getName() + "_hitresglobal", 50, -1.5, 1.5));
+//                plotters.get("Sensor hit res").region(SvtPlotUtils.computePlotterRegionAxialOnly(sensor)).plot(sensorHitResGlobal.get(sensor.getName()));
+//                plotters.get("Sensor hit res").region(0).style().dataStyle().showInStatisticsBox(true);
+//            }
+            
+        }
+        
+    }
+
+    protected IPlotterStyle getMinPlotterStyle(String xAxisTitle, String yAxisTitle) {
+        // Create a default style
+        IPlotterStyle style = this.pf.createPlotterStyle();
+
+        // Set the style of the X axis
+        if(!xAxisTitle.isEmpty()) style.xAxisStyle().setLabel(xAxisTitle);
+        style.xAxisStyle().labelStyle().setFontSize(14);
+        style.xAxisStyle().setVisible(true);
+
+        // Set the style of the Y axis
+        if(!yAxisTitle.isEmpty()) style.yAxisStyle().setLabel(yAxisTitle);
+        style.yAxisStyle().labelStyle().setFontSize(14);
+        style.yAxisStyle().setVisible(true);
+
+        // Turn off the histogram grid 
+        style.gridStyle().setVisible(false);
+        
+        // Turn off legend
+        style.legendBoxStyle().setVisible(false);
+        
+        style.setParameter("hist2DStyle", "colorMap");
+        style.dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow");
+        style.dataStyle().fillStyle().setColor("yellow");
+        style.dataStyle().errorBarStyle().setVisible(false);
+        
+        return style;
+    }
+    
+    protected IPlotterStyle getDefaultPlotterStyle(String xAxisTitle, String yAxisTitle) {
+        // Create a default style
+        IPlotterStyle style = this.pf.createPlotterStyle();
+
+        style.dataBoxStyle().setVisible(true);
+
+        // Set the style of the X axis
+        if(!xAxisTitle.isEmpty()) style.xAxisStyle().setLabel(xAxisTitle);
+        style.xAxisStyle().labelStyle().setFontSize(14);
+        style.xAxisStyle().setVisible(true);
+
+        // Set the style of the Y axis
+        if(!yAxisTitle.isEmpty()) style.yAxisStyle().setLabel(yAxisTitle);
+        style.yAxisStyle().labelStyle().setFontSize(14);
+        style.yAxisStyle().setVisible(true);
+
+        // Turn off the histogram grid 
+        style.gridStyle().setVisible(false);
+        
+        style.setParameter("hist2DStyle", "colorMap");
+        style.dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow");
+        style.dataStyle().fillStyle().setColor("yellow");
+        style.dataStyle().errorBarStyle().setVisible(false);
+        
+        return style;
+    }
+
+
+
+    public void setOutputFilename(String gblOutputFilename) {
+        this.outputFilename = gblOutputFilename;
+    }
+    
+   
+    
+    
+}

Top of Message | Previous Page | Permalink

Advanced Options


Options

Log In

Log In

Get Password

Get Password


Search Archives

Search Archives


Subscribe or Unsubscribe

Subscribe or Unsubscribe


Archives

November 2017
August 2017
July 2017
January 2017
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
December 2013
November 2013

ATOM RSS1 RSS2



LISTSERV.SLAC.STANFORD.EDU

Secured by F-Secure Anti-Virus CataList Email List Search Powered by the LISTSERV Email List Manager

Privacy Notice, Security Notice and Terms of Use