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;
+ }
+
+
+
+
+}
|