Print

Print


Commit in java/trunk/tracking/src/main/java/org/hps/recon/tracking/gbl on MAIN
GBLDriver.java+97added 391
GblPoint.java+22added 391
GblTrajectory.java+33added 391
GblUtils.java+89added 391
HpsGblFitter.java+472added 391
MilleBinary.java+5added 391
+718
6 added files
Adding placeholder classes

java/trunk/tracking/src/main/java/org/hps/recon/tracking/gbl
GBLDriver.java added at 391
--- java/trunk/tracking/src/main/java/org/hps/recon/tracking/gbl/GBLDriver.java	                        (rev 0)
+++ java/trunk/tracking/src/main/java/org/hps/recon/tracking/gbl/GBLDriver.java	2014-03-26 23:09:46 UTC (rev 391)
@@ -0,0 +1,97 @@
+package org.hps.recon.tracking.gbl;
+
+import hep.physics.vec.BasicHep3Vector;
+import hep.physics.vec.Hep3Vector;
+
+import java.util.List;
+
+import org.hps.recon.tracking.MaterialSupervisor;
+import org.hps.recon.tracking.MultipleScattering;
+import org.lcsim.event.EventHeader;
+import org.lcsim.event.Track;
+import org.lcsim.geometry.Detector;
+import org.lcsim.util.Driver;
+
+
+/**
+ * Run GBL track fit on existing seed tracks in the event.
+ * 
+ * @author phansson
+ *
+ */
+public class GBLDriver extends Driver {
+
+	private boolean _debug = false;
+	private boolean _isMC = false;
+	MaterialSupervisor _materialManager = null;
+	MultipleScattering _scattering = null;
+	private HpsGblFitter _gbl_fitter = null; 
+	private String milleBinaryName = "";
+	
+	public GBLDriver() {
+	}
+	
+	public void setDebug(boolean debug) {
+		_debug = debug;
+	}
+	
+	public void setMC(boolean mcflag) {
+		_isMC = mcflag;
+	}
+	
+	protected void detectorChanged(Detector det) {
+		 Hep3Vector bfield = det.getFieldMap().getField(new BasicHep3Vector(0., 0., 1.));
+		 _materialManager = new MaterialSupervisor();
+		 _scattering = new MultipleScattering(_materialManager);
+		 _materialManager.buildModel(det);
+		 _scattering.setBField(Math.abs(bfield.z())); // only absolute of B is needed as it's used for momentum calculation only
+		 _gbl_fitter = new HpsGblFitter(bfield.z(), _scattering, _isMC);
+		 if(!milleBinaryName.equalsIgnoreCase("")) {
+			 _gbl_fitter.setMilleBinary(new MilleBinary());
+		 }
+	}
+
+	protected void process(EventHeader event) {
+
+		List<Track> seedTracks = null;
+        if(event.hasCollection(Track.class,"MatchedTracks")) {        
+            seedTracks = event.get(Track.class, "MatchedTracks");
+             if(_debug) {
+                System.out.printf("%s: Event %d has %d tracks\n", this.getClass().getSimpleName(),event.getEventNumber(),seedTracks.size());
+             }
+        } else {
+        	 if(_debug) {
+                 System.out.printf("%s: No tracks in Event %d \n", this.getClass().getSimpleName(),event.getEventNumber());
+              }
+        	 return;
+        }
+	    
+        
+        for(int itrack = 0; itrack < seedTracks.size(); ++itrack) {
+
+        	if(_debug) {
+        		System.out.printf("%s: do the fit for track  %d \n", this.getClass().getSimpleName(),itrack);
+        	}
+
+        	// Reset
+        	_gbl_fitter.clear();
+        	
+        	// Run the GBL fit on this track
+        	int status = _gbl_fitter.Fit(seedTracks.get(itrack));
+        
+        	if(_debug) {
+        		System.out.printf("%s: fit status %d \n", this.getClass().getSimpleName(),status);
+        	}
+        
+        }
+        
+        
+        
+	}
+
+	protected void endOfData() {
+	}
+
+
+	
+}

java/trunk/tracking/src/main/java/org/hps/recon/tracking/gbl
GblPoint.java added at 391
--- java/trunk/tracking/src/main/java/org/hps/recon/tracking/gbl/GblPoint.java	                        (rev 0)
+++ java/trunk/tracking/src/main/java/org/hps/recon/tracking/gbl/GblPoint.java	2014-03-26 23:09:46 UTC (rev 391)
@@ -0,0 +1,22 @@
+package org.hps.recon.tracking.gbl;
+
+import hep.physics.matrix.BasicMatrix;
+import hep.physics.matrix.Matrix;
+
+public class GblPoint {
+
+	public GblPoint(BasicMatrix jacPointToPoint) {
+		// TODO Auto-generated constructor stub
+	}
+
+	public void addMeasurement(Matrix proL2m, BasicMatrix meas, BasicMatrix measPrec) {
+		// TODO Auto-generated method stub
+		
+	}
+
+	public void addScatterer(BasicMatrix scat, BasicMatrix scatPrec) {
+		// TODO Auto-generated method stub
+		
+	}
+
+}

java/trunk/tracking/src/main/java/org/hps/recon/tracking/gbl
GblTrajectory.java added at 391
--- java/trunk/tracking/src/main/java/org/hps/recon/tracking/gbl/GblTrajectory.java	                        (rev 0)
+++ java/trunk/tracking/src/main/java/org/hps/recon/tracking/gbl/GblTrajectory.java	2014-03-26 23:09:46 UTC (rev 391)
@@ -0,0 +1,33 @@
+package org.hps.recon.tracking.gbl;
+
+/**
+ * 
+ * 
+ * @author Per Hansson Adrian <[log in to unmask]>
+ *
+ */
+
+import java.util.List;
+
+public class GblTrajectory {
+
+	public GblTrajectory(List<GblPoint> listOfPoints) {
+		// TODO Auto-generated constructor stub
+	}
+
+	public boolean isValid() {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+	public void fit(double m_chi2, int m_ndf, int m_lost_weight) {
+		// TODO Auto-generated method stub
+		
+	}
+
+	public void milleOut(MilleBinary mille) {
+		// TODO Auto-generated method stub
+		
+	}
+
+}

java/trunk/tracking/src/main/java/org/hps/recon/tracking/gbl
GblUtils.java added at 391
--- java/trunk/tracking/src/main/java/org/hps/recon/tracking/gbl/GblUtils.java	                        (rev 0)
+++ java/trunk/tracking/src/main/java/org/hps/recon/tracking/gbl/GblUtils.java	2014-03-26 23:09:46 UTC (rev 391)
@@ -0,0 +1,89 @@
+package org.hps.recon.tracking.gbl;
+
+import hep.physics.matrix.BasicMatrix;
+
+/**
+ * A class providing various utilities related to GBL
+ * 
+ * @author Per Hansson Adrian <[log in to unmask]>
+ *
+ */
+
+public class GblUtils {
+	
+	private static GblUtils INSTANCE = null;
+	
+	private GblUtils() {
+	}
+	
+	public static GblUtils getInstance() {
+		if(INSTANCE == null) {
+			return new GblUtils();
+		} else {
+			return INSTANCE;
+		}
+	}
+	
+	
+	public BasicMatrix gblSimpleJacobianLambdaPhi(double ds,double cosl,double bfac) {
+		/*
+	     Simple jacobian: quadratic in arc length difference.
+	     using lambda phi as directions
+	    
+	    @param ds: arc length difference
+	    @type ds: float
+	    @param cosl: cos(lambda)
+	    @type cosl: float
+	    @param bfac: Bz*c
+	    @type bfac: float
+	    @return: jacobian to move by 'ds' on trajectory
+	    @rtype: matrix(float)
+	       ajac(1,1)= 1.0D0
+	       ajac(2,2)= 1.0D0
+	       ajac(3,1)=-DBLE(bfac*ds)
+	       ajac(3,3)= 1.0D0
+	       ajac(4,1)=-DBLE(0.5*bfac*ds*ds*cosl)
+	       ajac(4,3)= DBLE(ds*cosl)
+	       ajac(4,4)= 1.0D0
+	       ajac(5,2)= DBLE(ds)
+	       ajac(5,5)= 1.0D0
+	    '''
+	    jac = np.eye(5)
+	    jac[2, 0] = -bfac * ds
+	    jac[3, 0] = -0.5 * bfac * ds * ds * cosl
+	    jac[3, 2] = ds * cosl
+	    jac[4, 1] = ds  
+	    return jac
+	  */
+		BasicMatrix mat = unitMatrix(5,5);
+		mat.setElement(2, 0, -bfac * ds);
+		mat.setElement(3, 0, -0.5 * bfac * ds * ds * cosl);
+		mat.setElement(3, 2, ds * cosl);
+		mat.setElement(4, 1, ds);
+		return mat;
+	 }
+		
+	 public BasicMatrix unitMatrix(int rows, int cols) {
+		BasicMatrix mat = new BasicMatrix(rows,cols);
+		for(int row=0;row!=mat.getNRows();row++) {
+			for(int col=0;col!=mat.getNColumns();col++) {
+				if(row!=col) mat.setElement(row, col, 0);
+				else mat.setElement(row, col, 1);
+			}
+		}
+		return mat;
+	 }
+
+	 public BasicMatrix zeroMatrix(int rows, int cols) {
+		BasicMatrix mat = new BasicMatrix(rows,cols);
+		for(int row=0;row!=mat.getNRows();row++) {
+			for(int col=0;col!=mat.getNColumns();col++) {
+				mat.setElement(row, col, 0.);
+			}
+		}
+		return mat;
+	 }
+
+	
+
+}

java/trunk/tracking/src/main/java/org/hps/recon/tracking/gbl
HpsGblFitter.java added at 391
--- java/trunk/tracking/src/main/java/org/hps/recon/tracking/gbl/HpsGblFitter.java	                        (rev 0)
+++ java/trunk/tracking/src/main/java/org/hps/recon/tracking/gbl/HpsGblFitter.java	2014-03-26 23:09:46 UTC (rev 391)
@@ -0,0 +1,472 @@
+package org.hps.recon.tracking.gbl;
+
+import hep.physics.matrix.BasicMatrix;
+import hep.physics.matrix.Matrix;
+import hep.physics.matrix.MatrixOp;
+import hep.physics.vec.BasicHep3Vector;
+import hep.physics.vec.Hep3Matrix;
+import hep.physics.vec.Hep3Vector;
+import hep.physics.vec.VecOp;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.hps.recon.tracking.MaterialSupervisor;
+import org.hps.recon.tracking.MaterialSupervisor.DetectorPlane;
+import org.hps.recon.tracking.MaterialSupervisor.ScatteringDetectorVolume;
+import org.hps.recon.tracking.MultipleScattering;
+import org.hps.recon.tracking.MultipleScattering.ScatterPoint;
+import org.hps.recon.tracking.MultipleScattering.ScatterPoints;
+import org.hps.recon.tracking.TrackUtils;
+import org.hps.recon.tracking.TrackerHitUtils;
+import org.lcsim.constants.Constants;
+import org.lcsim.event.RawTrackerHit;
+import org.lcsim.event.Track;
+import org.lcsim.fit.helicaltrack.HelicalTrackCross;
+import org.lcsim.fit.helicaltrack.HelicalTrackFit;
+import org.lcsim.fit.helicaltrack.HelicalTrackHit;
+import org.lcsim.fit.helicaltrack.HelicalTrackStrip;
+import org.lcsim.fit.helicaltrack.HelixUtils;
+import org.lcsim.recon.tracking.seedtracker.ScatterAngle;
+import org.lcsim.recon.tracking.seedtracker.SeedCandidate;
+import org.lcsim.recon.tracking.seedtracker.SeedTrack;
+
+
+/**
+ * Class to running GBL on HPS track.
+ * 
+ * @author phansson
+ *
+ */
+public class HpsGblFitter {
+
+	
+	private boolean _debug = false;
+	private double _B = 0.;
+	private double _bfac = 0.;
+	private boolean isMC = false;
+	TrackerHitUtils _trackHitUtils = null;
+	MultipleScattering _scattering = null;
+	private double m_chi2 = -1.;
+	private int m_ndf = -1;
+	private int m_lost_weight = -1;
+	GblTrajectory _traj = null;
+	MilleBinary _mille = null;
+	
+
+	
+	public HpsGblFitter(double Bz, MultipleScattering scattering, boolean isMCFlag) {
+		isMC = isMCFlag;
+		_B = Bz;
+		_bfac = Bz * Constants.fieldConversion;
+		_trackHitUtils = new TrackerHitUtils();
+		_scattering = scattering;
+	}
+	
+	public void setMilleBinary(MilleBinary mille) {
+		_mille = mille;
+	}
+	
+	public void clear() {
+		m_chi2 = -1.;
+		m_ndf = -1;
+		m_lost_weight = -1;
+		_traj = null;
+	}
+
+	public int Fit(Track track) {
+		
+
+		// Check that things are setup
+		if(_B == 0.) {
+			System.out.printf("%s: B-field not set!\n", this.getClass().getSimpleName());
+			return -1;
+		}
+		if(_scattering == null) {
+			System.out.printf("%s: Multiple scattering calculator not set!\n", this.getClass().getSimpleName());
+			return -2;
+		}
+		
+		// Time the fits
+		//clock_t startTime = clock();
+
+		
+		
+		// path length along trajectory
+		double s = 0.;
+		// jacobian to transport errors between points along the path
+		BasicMatrix jacPointToPoint = GblUtils.getInstance().unitMatrix(5, 5);
+		// Option to use uncorrelated  MS errors
+		// This is similar to what is done in lcsim seedtracker
+		// The msCov below holds the MS errors
+		// This is for testing purposes only.
+		boolean useUncorrMS = false;
+		BasicMatrix msCov = GblUtils.getInstance().zeroMatrix(5, 5);
+		
+		// Vector of the strip clusters used for the GBL fit
+		List<GblPoint> listOfPoints = new ArrayList<GblPoint>();
+		
+		// Store the projection from local to measurement frame for each strip cluster
+		// need to use pointer for TMatrix here?
+		Map<Integer, Matrix> proL2m_list = new HashMap<Integer, Matrix>(); 
+		// Save the association between strip cluster and label	
+		Map<HelicalTrackStrip, Integer> stripLabelMap = new HashMap<HelicalTrackStrip, Integer>();
+		  
+		//start trajectory at refence point (s=0) - this point has no measurement
+		GblPoint ref_point = new GblPoint(jacPointToPoint);
+		listOfPoints.add(ref_point);
+		
+		//Create a list of all the strip clusters making up the track 
+		List<HelicalTrackStrip> stripClusters = new ArrayList<HelicalTrackStrip>();
+		SeedCandidate seed = ((SeedTrack) track).getSeedCandidate();
+		HelicalTrackFit htf = seed.getHelix();
+		List<HelicalTrackHit> stereoHits = seed.getHits();
+		for(int ihit = 0; ihit < stereoHits.size(); ++ihit) {
+			HelicalTrackCross cross = (HelicalTrackCross) stereoHits.get(ihit);
+			stripClusters.add(cross.getStrips().get(0));
+			stripClusters.add(cross.getStrips().get(1));
+		}
+		
+		// sort the clusters along path
+		// TODO use actual path length and not layer id!
+		//Collections.sort(stripClusters, new HelicalTrackStripComparer());
+		Collections.sort(stripClusters, new Comparator<HelicalTrackStrip>() {
+			public int compare(HelicalTrackStrip o1, HelicalTrackStrip o2) {
+				return o1.layer() < o2.layer() ? -1 : o1.layer() > o2.layer() ? 1 : 0;
+			}
+		});
+
+		if(_debug ) {
+			System.out.printf("%s: %d strip clusters:\n", stripClusters.size());
+			for(int istrip=0;istrip<stripClusters.size();++istrip) {
+				System.out.printf("%s: layer %d origin %s\n", stripClusters.get(istrip).layer(),stripClusters.get(istrip).origin().toString());
+			}
+		}
+
+		
+		// Find scatter points along the path of the track
+        ScatterPoints scatters = _scattering.FindHPSScatterPoints(htf);
+		
+		
+		if(_debug ) {
+			System.out.printf("%s: Process %d strip clusters\n", stripClusters.size());
+		}
+		for(int istrip=0;istrip<stripClusters.size();++istrip) {
+			
+			HelicalTrackStrip strip = stripClusters.get(istrip);
+			
+			if(_debug) {
+				System.out.printf("%s: layer %d origin %s\n", strip.layer(),strip.origin().toString());
+			}
+			
+			 //Find intercept point with sensor in tracking frame
+            Hep3Vector trkpos = TrackUtils.getHelixPlaneIntercept(htf, strip, Math.abs(_B));
+            if(_debug) {
+            	System.out.printf("trkpos at intercept [%.10f %.10f %.10f]\n",trkpos.x(),trkpos.y(),trkpos.z());
+            }
+            
+          //path length to intercept
+            double path = HelixUtils.PathToXPlane(htf,trkpos.x(),0,0).get(0); 
+            double path3D = path / Math.cos(Math.atan(htf.slope()));
+            
+		    
+		    // Path length step for this cluster
+		    double step = path3D - s;
+		    
+		    if( _debug ) {
+		      System.out.printf("%s: Path length step %f from %f to %f\n",this.getClass().getSimpleName(),step, s, path3D);
+		    }
+		    
+		    // Measurement direction (perpendicular and parallel to strip direction)
+		    BasicMatrix mDir = new BasicMatrix(2,3);
+		    mDir.setElement(0, 0, strip.u().x());
+		    mDir.setElement(0, 1, strip.u().y());
+		    mDir.setElement(0, 2, strip.u().z());
+		    mDir.setElement(1, 0, strip.v().x());
+		    mDir.setElement(1, 1, strip.v().y());
+		    mDir.setElement(1, 2, strip.v().z());
+		    
+		    Matrix mDirT = MatrixOp.transposed(mDir); //new BasicMatrix(MatrixOp.transposed(mDir));
+		    if(_debug) {
+		    	System.out.printf("%s: mDir \n%s\n",this.getClass().getSimpleName(),mDir.toString());
+		    	System.out.printf("%s: mDirT \n%s\n",this.getClass().getSimpleName(),mDirT.toString());
+		    }
+		    
+
+		    // Track direction 
+		    double sinLambda = Math.sin(Math.atan(htf.slope())); 
+		    double cosLambda = Math.sqrt(1.0 - sinLambda*sinLambda);
+		    double sinPhi = Math.sin(htf.phi0());
+		    double cosPhi = Math.sqrt(1.0 - sinPhi*sinPhi);
+		    
+		    // Track direction in curvilinear frame (U,V,T)
+		    // U = Z x T / |Z x T|, V = T x U
+		    BasicMatrix uvDir = new BasicMatrix(2,3);
+		    uvDir.setElement(0, 0, -sinPhi);
+		    uvDir.setElement(0, 1, cosPhi);
+		    uvDir.setElement(0, 2, 0.);
+		    uvDir.setElement(1, 0, -sinLambda * cosPhi);
+		    uvDir.setElement(1, 1, -sinLambda * sinPhi);
+		    uvDir.setElement(1, 2, cosLambda);
+		    
+		    if(_debug) {
+		    	System.out.printf("%s: uvDir \n%s\n",this.getClass().getSimpleName(),uvDir.toString());
+		    }
+
+		    // projection from  measurement to local (curvilinear uv) directions (duv/dm)
+		    Matrix proM2l = MatrixOp.mult(uvDir, mDirT); //uvDir * mDirT;
+		    
+		    //projection from local (curvilinear uv) to measurement directions (dm/duv)
+		    Matrix proL2m = MatrixOp.inverse(proM2l);
+		    
+		    //proL2m_list[strip->GetId()] = new TMatrixD(proL2m);
+
+			if(_debug) {
+				System.out.printf("%s: proM2l \n%s\n",this.getClass().getSimpleName(),proM2l.toString());
+				System.out.printf("%s: proL2m \n%s\n",this.getClass().getSimpleName(),proL2m.toString());
+			}
+			
+			// measurement/residual in the measurement system
+		    
+            // start by find the distance vector between the center and the track position
+            Hep3Vector vdiffTrk = VecOp.sub(trkpos, strip.origin());
+            
+            // then find the rotation from tracking to measurement frame
+            Hep3Matrix trkToStripRot = _trackHitUtils.getTrackToStripRotation(strip);
+            
+            // then rotate that vector into the measurement frame to get the predicted measurement position
+            Hep3Vector trkpos_meas = VecOp.mult(trkToStripRot, vdiffTrk);
+                            
+            // hit measurement and uncertainty in measurement frame
+            Hep3Vector m_meas = new BasicHep3Vector(strip.umeas(),0.,0.);
+            
+            // finally the residual
+            Hep3Vector res_meas = VecOp.sub(m_meas, trkpos_meas);
+            Hep3Vector res_err_meas = new BasicHep3Vector(strip.du(),(strip.vmax() - strip.vmin()) / Math.sqrt(12),10.0/Math.sqrt(12));
+
+            // Move to matrix objects instead of 3D vectors
+            // TODO use only one type
+            
+			// only 1D measurement in u-direction, set strip measurement direction to zero
+		    BasicMatrix meas = new BasicMatrix(0,2);
+		    meas.setElement(0, 0, res_meas.x());
+		    meas.setElement(0, 1, 0.);
+//			    //meas[0][0] += deltaU[iLayer] # misalignment
+
+		    BasicMatrix measErr = new BasicMatrix(0,2);
+		    measErr.setElement(0, 0, res_err_meas.x());
+		    measErr.setElement(0, 1, 0.);
+
+		    BasicMatrix measPrec = new BasicMatrix(0,2);
+		    measPrec.setElement(0, 0, 1.0/( measErr.e(0, 0) * measErr.e(0, 0)));
+		    measPrec.setElement(0, 1, 0.);
+		    if (_debug) {
+		    	System.out.printf("%s: meas \n%s\n",this.getClass().getSimpleName(),meas.toString());
+		    	System.out.printf("%s: measErr \n%s\n",this.getClass().getSimpleName(),measErr.toString());
+		    	System.out.printf("%s: measPrec \n%s\n",this.getClass().getSimpleName(),measPrec.toString());
+            }
+
+            //Find the Jacobian to be able to propagate the covariance matrix to this strip position
+            jacPointToPoint = GblUtils.getInstance().gblSimpleJacobianLambdaPhi(step, cosLambda, Math.abs(_bfac));
+            
+            if(_debug) {
+				System.out.printf("%s: jacPointToPoint \n%s\n",this.getClass().getSimpleName(),jacPointToPoint.toString());
+            }
+            
+          //propagate MS covariance matrix (in the curvilinear frame) to this strip position
+            //msCov = np.dot(jacPointToPoint, np.dot(msCov, jacPointToPoint.T))
+            //measMsCov = np.dot(proL2m, np.dot(msCov[3:, 3:], proL2m.T))
+//                if (m_debug) {
+//                  cout << "HpsGblFitter: " << " msCov at this point:" << endl;
+//                  msCov.Print();
+//                  //cout << "HpsGblFitter: " << "measMsCov at this point:" << endl;
+//                  //measMsCov.Print();
+//                }
+            
+            //Option to blow up measurement error according to multiple scattering
+            //if useUncorrMS:
+            //measPrec[0] = 1.0 / (measErr[0] ** 2 + measMsCov[0, 0])
+            //  if debug:
+            //print 'Adding measMsCov ', measMsCov[0,0]
+                
+            // point with independent measurement
+            GblPoint point = new GblPoint(jacPointToPoint);
+
+            //Add measurement to the point
+            point.addMeasurement(proL2m,meas,measPrec);
+
+            
+            //Add scatterer in curvilinear frame to the point
+            // no direction in this frame as it moves along the track
+            BasicMatrix scat = GblUtils.getInstance().zeroMatrix(0,2);
+
+            // find scattering angle
+            ScatterPoint scatter = scatters.getScatterPoint(((RawTrackerHit)strip.rawhits().get(0)).getDetectorElement());
+            double scatAngle;
+         
+            if(scatter != null) {
+            	scatAngle = scatter.getScatterAngle().Angle();
+            }	
+            else {
+                System.out.printf("%s: WARNING cannot find scatter for detector %s with strip cluster at %s\n",this.getClass(),((RawTrackerHit)strip.rawhits().get(0)).getDetectorElement().getName(),strip.origin().toString());
+                //can be edge case where helix is outside, but close to sensor, so use hack with the sensor origin closest to hit
+                //TODO check if this really makes sense to do
+                DetectorPlane closest = null;
+                double dx = 999999.9;
+                if(MaterialSupervisor.class.isInstance(_scattering.getMaterialManager())) {
+                    MaterialSupervisor matSup = (MaterialSupervisor)_scattering.getMaterialManager();
+                    for(ScatteringDetectorVolume vol : matSup.getMaterialVolumes()) {
+                        DetectorPlane plane = (DetectorPlane)vol;
+                        double dx_loop = Math.abs(strip.origin().x() - plane.origin().x());
+                        if(dx_loop<dx) {
+                            dx = dx_loop;
+                            closest = plane;
+                        }
+                    }
+                    if(closest==null) {
+                        throw new RuntimeException("cannot find any plane that is close to strip!");
+                    } else {
+                        // find scatterlength
+                        double s_closest = HelixUtils.PathToXPlane(htf,closest.origin().x(), 0., 0).get(0);
+                        double X0 = closest.getMaterialTraversedInRL(HelixUtils.Direction(htf, s_closest));
+                        ScatterAngle scatterAngle = new ScatterAngle(s_closest, _scattering.msangle(htf.p(Math.abs(_B)),X0));
+                        scatAngle = scatterAngle.Angle();
+                    }
+                } 
+                else {
+                    throw new UnsupportedOperationException("Should not happen. This problem is only solved with the MaterialSupervisor.");
+                }
+            }
+            
+            
+            // Scattering angle in the curvilinear frame
+            //Note the cosLambda to correct for the projection in the phi direction
+            BasicMatrix scatErr = new BasicMatrix(0,2);
+            scatErr.setElement(0, 0, scatAngle);
+            scatErr.setElement(0, 1, scatAngle / cosLambda);
+            BasicMatrix scatPrec = new BasicMatrix(0,2);
+            scatPrec.setElement(0, 0, 1.0 / (scatErr.e(0, 0) * scatErr.e(0, 0)));
+            scatPrec.setElement(0, 1, 1.0 / (scatErr.e(0, 1) * scatErr.e(0, 1)));
+            
+            // add scatterer if not using the uncorrelated MS covariances for testing
+            if (! useUncorrMS) {
+              point.addScatterer(scat, scatPrec);
+              if (_debug) {
+            	  System.out.printf("%s: scatError to this point \n%s\n",this.getClass().getSimpleName(),scatErr.toString());
+              }
+            }
+			
+            // Add this GBL point to list that will be used in fit
+            listOfPoints.add(point);
+            int iLabel = listOfPoints.size();
+            
+            // Update MS covariance matrix 
+            msCov.setElement(1, 1, msCov.e(1, 1) + scatErr.e(0, 0)*scatErr.e(0, 0));
+            msCov.setElement(2, 2, msCov.e(2, 2) + scatErr.e(0, 1)*scatErr.e(0, 1));
+            
+            
+            
+            /*
+
+            ##### 
+            ## Calculate global derivatives for this point
+            # track direction in tracking/global frame
+            tDirGlobal = np.array( [ [cosPhi * cosLambda, sinPhi * cosLambda, sinLambda] ] )        
+            # Cross-check that the input is consistent
+            if( np.linalg.norm( tDirGlobal - strip.tDir) > 0.00001):
+              print 'ERROR: tDirs are not consistent!'
+              sys.exit(1)
+            # rotate track direction to measurement frame          
+            tDirMeas = np.dot( tDirGlobal, np.array([strip.u, strip.v, strip.w]) )
+            #tDirMeas = utils.rotateGlToMeas(strip,tDirGlobal)
+            normalMeas = np.dot( strip.w , np.array([strip.u, strip.v, strip.w]) ) 
+            #normalMeas = utils.rotateGlToMeas(strip,strip.w) 
+            # non-measured directions 
+            vmeas = 0.
+            wmeas = 0.
+            # calculate and add derivatives to point
+            glDers = utils.globalDers(strip.layer,strip.meas,vmeas,wmeas,tDirMeas,normalMeas)
+            ders = glDers.getDers(track.isTop())
+            labGlobal = ders['labels']
+            addDer = ders['ders']
+            if debug:
+              print 'global derivatives:'
+              print labGlobal
+              print addDer
+            point.addGlobals(labGlobal, addDer)
+            ##### 
+
+             */
+            
+        
+
+            //move on to next point
+            s += step;
+        
+            // save strip and label map
+            //stripLabelMap[strip] = iLabel;
+        
+        
+          
+
+            
+            
+            
+		}
+	
+
+		//create the trajectory
+		_traj = new GblTrajectory(listOfPoints); //,seedLabel, clSeed);
+			  
+		if (! _traj.isValid()) {
+			System.out.printf("%s:  Invalid GblTrajectory -> skip \n",this.getClass().getSimpleName());
+			return -3;
+		}
+		
+		// fit trajectory
+		_traj.fit(m_chi2, m_ndf, m_lost_weight);
+		
+		if( _debug ) {
+			System.out.printf("%s:  Chi2  Fit: %f , %d , %d\n",this.getClass().getSimpleName(), m_chi2, m_ndf,m_lost_weight);
+		}
+		
+		// write to MP binary file
+		if(_mille != null) {
+			_traj.milleOut(_mille);
+		}
+		
+		//stop the clock
+		//clock_t endTime = clock();
+		//double diff = endTime - startTime;
+		//double cps = CLOCKS_PER_SEC;
+		//if( m_debug ) {
+		//	std::cout << "HpsGblFitter: " << " Time elapsed " << diff / cps << " s" << std::endl;
+		//}
+
+		if(_debug) {
+			System.out.printf("%s:  Fit() done successfully.\n",this.getClass().getSimpleName());
+		}
+		
+		return 0;
+	}
+	
+
+	public static class HelicalTrackStripComparer implements Comparator<HelicalTrackStrip> {
+		public int compare(HelicalTrackStrip o1, HelicalTrackStrip o2) {
+			// TODO Change this to path length!?
+			return compare(o1.layer(),o2.layer());
+		}
+	
+		private static int compare(int s1, int s2) {
+			return s1 < s2 ? -1 : s2 > s1 ? 1 : 0;
+		}
+	
+	
+	}
+
+
+}

java/trunk/tracking/src/main/java/org/hps/recon/tracking/gbl
MilleBinary.java added at 391
--- java/trunk/tracking/src/main/java/org/hps/recon/tracking/gbl/MilleBinary.java	                        (rev 0)
+++ java/trunk/tracking/src/main/java/org/hps/recon/tracking/gbl/MilleBinary.java	2014-03-26 23:09:46 UTC (rev 391)
@@ -0,0 +1,5 @@
+package org.hps.recon.tracking.gbl;
+
+public class MilleBinary {
+
+}
SVNspam 0.1