Author: [log in to unmask]
Date: Thu Feb 5 19:17:21 2015
New Revision: 2058
Log:
First version of GBL fits with global derivatives on all size trivial degrees of freedom. Still work in progress, needs to cleanup and fix of a sign-problem and test binary result.
Modified:
java/trunk/tracking/src/main/java/org/hps/recon/tracking/gbl/HpsGblRefitter.java
Modified: java/trunk/tracking/src/main/java/org/hps/recon/tracking/gbl/HpsGblRefitter.java
=============================================================================
--- java/trunk/tracking/src/main/java/org/hps/recon/tracking/gbl/HpsGblRefitter.java (original)
+++ java/trunk/tracking/src/main/java/org/hps/recon/tracking/gbl/HpsGblRefitter.java Thu Feb 5 19:17:21 2015
@@ -5,6 +5,7 @@
import static java.lang.Math.sqrt;
import hep.physics.vec.BasicHep3Vector;
import hep.physics.vec.Hep3Vector;
+import hep.physics.vec.VecOp;
import java.util.ArrayList;
import java.util.HashMap;
@@ -20,6 +21,7 @@
import org.lcsim.event.LCRelation;
import org.lcsim.event.Track;
import org.lcsim.geometry.Detector;
+import org.lcsim.geometry.compact.converter.MilleParameter;
import org.lcsim.util.Driver;
import org.lcsim.util.log.LogUtil;
@@ -29,6 +31,7 @@
* be present in the event.
*
* @author Norman A Graf
+ * @author Per Hansson Adrian <[log in to unmask]>
*
* @version $Id$
*/
@@ -214,14 +217,21 @@
if (_debug) {
System.out.println("HpsGblFitter: " + "Path length step " + step + " from " + s + " to " + strip.getPath3D());
}
+
+ // get measurement frame unit vectors
+ Hep3Vector u = strip.getU();
+ Hep3Vector v = strip.getV();
+ Hep3Vector w = strip.getW();
+
+
// Measurement direction (perpendicular and parallel to strip direction)
Matrix mDir = new Matrix(2, 3);
- mDir.set(0, 0, strip.getUx());
- mDir.set(0, 1, strip.getUy());
- mDir.set(0, 2, strip.getUz());
- mDir.set(1, 0, strip.getVx());
- mDir.set(1, 1, strip.getVy());
- mDir.set(1, 2, strip.getVz());
+ mDir.set(0, 0, u.x());
+ mDir.set(0, 1, u.y());
+ mDir.set(0, 2, u.z());
+ mDir.set(1, 0, v.x());
+ mDir.set(1, 1, v.y());
+ mDir.set(1, 2, v.z());
if (_debug) {
System.out.println("HpsGblFitter: " + "mDir");
mDir.print(4, 6);
@@ -359,37 +369,85 @@
msCov.set(1, 1, msCov.get(1, 1) + scatErr.get(0) * scatErr.get(0));
msCov.set(2, 2, msCov.get(2, 2) + scatErr.get(1) * scatErr.get(1));
+
+
+ //// Calculate global derivatives for this point
+
+ // track direction in tracking/global frame
+ Hep3Vector tDirGlobal = new BasicHep3Vector(cosPhi * cosLambda, sinPhi * cosLambda, sinLambda);
+
+ // Cross-check that the input is consistent
+ if( VecOp.sub(tDirGlobal, strip.getTrackDirection()).magnitude() > 0.00001) {
+ throw new RuntimeException("track directions are inconsistent: " + tDirGlobal.toString() + " and " + strip.getTrackDirection().toString());
+ }
+ // rotate track direction to measurement frame
+ Hep3Vector tDirMeas = new BasicHep3Vector(VecOp.dot(tDirGlobal, u), VecOp.dot(tDirGlobal, v), VecOp.dot(tDirGlobal, w));
+ // TODO this is a trivial one. Fix it.
+ Hep3Vector normalMeas = new BasicHep3Vector(VecOp.dot(w, u), VecOp.dot(w, v), VecOp.dot(w, w));
+
+ // vector coplanar with measurement plane from origin to prediction
+ Hep3Vector tPosMeas = strip.getTrackPos();
+
+ // measurements: non-measured directions
+ double vmeas = 0.;
+ double wmeas = 0.;
+
+ // calculate and add derivatives to point
+ GlobalDers glDers = new GlobalDers(strip.getId(), meas.get(0), vmeas, wmeas, tDirMeas, tPosMeas, normalMeas);
+
+ //TODO find a more robust way to get half.
+ boolean isTop = Math.sin(strip.getTrackLambda()) > 0 ? true : false;
+
+ // Get the list of millepede parameters
+ List<MilleParameter> milleParameters = glDers.getDers(isTop);
+
+ // need to make vector and matrices for interface
+ List<Integer> labGlobal = new ArrayList<Integer>();
+ Matrix addDer = new Matrix(1, milleParameters.size());
+ for(int i=0; i < milleParameters.size(); ++i) {
+ labGlobal.add(milleParameters.get(i).getId());
+ addDer.set(0, i, milleParameters.get(i).getValue());
+ }
+ point.addGlobals(labGlobal, addDer);
+
+ for(int i=0; i < milleParameters.size(); ++i) {
+ logger.info(labGlobal.get(i) + "\t" + addDer.get(0, i));
+ }
+
+
+
/*
-
- #####
- ## 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)
- #####
-
- */
+ #####
+ ## 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)
+ #####
+
+ */
+
+
logger.info("uRes " + strip.getId() + " uRes " + uRes + " pred (" + strip.getTrackPos().x() + "," + strip.getTrackPos().y() + "," + strip.getTrackPos().z() + ") s(3D) " + strip.getPath3D());
//go to next point
@@ -471,54 +529,253 @@
return jac;
}
- public static class FittedGblTrajectory {
- public static enum GBLPARIDX {
- QOVERP(0),XTPRIME(1),YTPRIME(2),XT(3),YT(4);
- private int _value;
- private GBLPARIDX(int value) {
- _value = value;
- }
- public int getValue() {
- return _value;
- }
- };
- private GblTrajectory _traj;
- private double _chi2;
- private double _lost;
- private int _ndf;
- private Track _seed = null;
- private GBLTrackData _t = null;
- public FittedGblTrajectory(GblTrajectory traj, double chi2, int ndf, double lost) {
- _traj = traj;
- _chi2 = chi2;
- _ndf = ndf;
- _lost = lost;
- }
- public void set_track_data(GBLTrackData t) {
- _t = t;
- }
- public GBLTrackData get_track_data() {
- return _t;
- }
- public void set_seed(Track seed) {
- _seed = seed;
- }
- public Track get_seed() {
- return _seed;
- }
- public GblTrajectory get_traj() {
- return _traj;
- }
- public double get_chi2() {
- return _chi2;
- }
- public double get_lost() {
- return _lost;
- }
- public int get_ndf() {
- return _ndf;
- }
-
- }
-
+
+ private static class GlobalDers {
+ private int _layer;
+ private double _umeas; // measurement direction
+ private double _vmeas; // unmeasured direction
+ private double _wmeas; // normal to plane
+ private Hep3Vector _t; // track direction
+ private Hep3Vector _p; // track prediction
+ private Hep3Vector _n; // normal to plane
+ private Matrix _dm_dg; //Global derivaties of the local measurements
+ private Matrix _dr_dm; //Derivatives of residuals w.r.t. measurement
+ private Matrix _dr_dg; //Derivatives of residuals w.r.t. global parameters
+
+ public GlobalDers(int layer,double umeas, double vmeas, double wmeas, Hep3Vector tDir, Hep3Vector tPred, Hep3Vector normal) {
+ _layer = layer;
+ _umeas = umeas;
+ _vmeas = vmeas;
+ _wmeas = wmeas;
+ _t = tDir;
+ _p = tPred;
+ _n = normal;
+ // Derivatives of residuals w.r.t. perturbed measurement
+ _dr_dm = getResDers();
+ // Derivatives of perturbed measurement w.r.t. global parameters
+ _dm_dg = getMeasDers();
+ // Calculate, by chain rule, derivatives of residuals w.r.t. global parameters
+ _dr_dg = _dr_dm.times(_dm_dg);
+ //print 'dm_dg'
+ //print dm_dg
+ //print 'dr_dm'
+ //print dr_dm
+ //print 'dr_dg'
+ //print self.dr_dg
+ }
+
+
+ /**
+ * Derivative of mt, the perturbed measured coordinate vector m w.r.t. to global parameters: u,v,w,alpha,beta,gamma
+ */
+ private Matrix getMeasDers() {
+
+ //Derivative of the local measurement for a translation in u
+ double dmu_du = 1.;
+ double dmv_du = 0.;
+ double dmw_du = 0.;
+ // Derivative of the local measurement for a translation in v
+ double dmu_dv = 0.;
+ double dmv_dv = 1.;
+ double dmw_dv = 0.;
+ // Derivative of the local measurement for a translation in w
+ double dmu_dw = 0.;
+ double dmv_dw = 0.;
+ double dmw_dw = 1.;
+ // Derivative of the local measurement for a rotation around u-axis (alpha)
+ double dmu_dalpha = 0.;
+ double dmv_dalpha = _p.z(); // self.wmeas
+ double dmw_dalpha = -1.0 * _p.y(); // -1.0 * self.vmeas
+ // Derivative of the local measurement for a rotation around v-axis (beta)
+ double dmu_dbeta = -1.0 * _p.z(); //-1.0 * self.wmeas
+ double dmv_dbeta = 0.;
+ double dmw_dbeta = _p.x(); //self.umeas
+ // Derivative of the local measurement for a rotation around w-axis (gamma)
+ double dmu_dgamma = _p.y(); // self.vmeas
+ double dmv_dgamma = -1.0 * _p.x(); // -1.0 * self.umeas
+ double dmw_dgamma = 0.;
+ // put into matrix
+ Matrix dm_dg = new Matrix(3, 6);
+ dm_dg.set(0, 0, dmu_du);
+ dm_dg.set(0, 1, dmu_dv);
+ dm_dg.set(0, 2, dmu_dw);
+ dm_dg.set(0, 3, dmu_dalpha);
+ dm_dg.set(0, 4, dmu_dbeta);
+ dm_dg.set(0, 5, dmu_dgamma);
+ dm_dg.set(1, 0, dmv_du);
+ dm_dg.set(1, 1, dmv_dv);
+ dm_dg.set(1, 2, dmv_dw);
+ dm_dg.set(1, 3, dmv_dalpha);
+ dm_dg.set(1, 4, dmv_dbeta);
+ dm_dg.set(1, 5, dmv_dgamma);
+ dm_dg.set(2, 0, dmw_du);
+ dm_dg.set(2, 1, dmw_dv);
+ dm_dg.set(2, 2, dmw_dw);
+ dm_dg.set(2, 3, dmw_dalpha);
+ dm_dg.set(2, 4, dmw_dbeta);
+ dm_dg.set(2, 5, dmw_dgamma);
+ //dmdg = np.array([[dmu_du, dmu_dv, dmu_dw, dmu_dalpha, dmu_dbeta, dmu_dgamma],[dmv_du, dmv_dv, dmv_dw, dmv_dalpha, dmv_dbeta, dmv_dgamma],[dmw_du, dmw_dv, dmw_dw, dmw_dalpha, dmw_dbeta, dmw_dgamma]])
+ return dm_dg;
+ }
+
+ /**
+ * Derivatives of the local perturbed residual w.r.t. the measurements m (u,v,w)'
+ */
+ private Matrix getResDers() {
+ double tdotn = VecOp.dot(_t, _n);
+ Matrix dr_dm = Matrix.identity(3,3);
+ //print 't ', self.t, ' n ', self.n, ' dot(t,n) ', tdotn
+ double delta, val;
+ for(int i=0; i<3; ++i) {
+ for(int j=0; j<3; ++j) {
+ delta = i==j ? 1. : 0.;
+ val = delta - _t.v()[i] * _n.v()[j]/tdotn;
+ dr_dm.set(i, j, val);
+ }
+ }
+ return dr_dm;
+ }
+
+
+ /**
+ * Turn derivative matrix into @Milleparameter
+ * @param isTop - top or bottom track
+ * @return list of @Milleparameters
+ */
+ private List<MilleParameter> getDers(boolean isTop) {
+ int transRot;
+ int direction;
+ int label;
+ double value;
+ List<MilleParameter> milleParameters = new ArrayList<MilleParameter>();
+ int topBot = isTop == true ? 1 : 2;
+ for(int ip=1; ip<7; ++ip) {
+ if(ip > 3) {
+ transRot = 2;
+ direction = ((ip-1) % 3) + 1;
+ } else {
+ transRot = 1;
+ direction = ip;
+ }
+ label = topBot * MilleParameter.half_offset + transRot * MilleParameter.type_offset + direction * MilleParameter.dimension_offset + _layer;
+ value = _dr_dg.get(0, ip-1);
+ MilleParameter milleParameter = new MilleParameter(label, value, 0.0);
+ milleParameters.add(milleParameter);
+ }
+ return milleParameters;
+ }
+
+
+ /*
+
+ class globalDers:
+ def __init__(self,layer,umeas,vmeas,wmeas, tDir, tPred, normal):
+ self.layer = layer # measurement direction
+ self.umeas = umeas # measurement direction
+ self.vmeas = vmeas # unmeasured direction
+ self.wmeas = wmeas # normal to plane
+ self.t = tDir # track direction
+ self.p = tPred # track prediction
+ self.n = normal # normal to plane
+ # Global derivaties of the local measurements
+ self.dm_dg = self.getMeasDers()
+ # Derivatives of residuals w.r.t. measurement
+ self.dr_dm = self.getResDers()
+ # Derivatives of residuals w.r.t. global parameters
+ self.dr_dg = np.dot(self.dr_dm, self.dm_dg)
+ #print 'dm_dg'
+ #print dm_dg
+ #print 'dr_dm'
+ #print dr_dm
+ #print 'dr_dg'
+ #print self.dr_dg
+
+ def dump(self):
+ print 'globalDers:'
+ print 'layer ', self.layer
+ print 'umeas ', self.umeas, ' vmeas ', self.vmeas, ' wmeas ', self.wmeas
+ print 't ', self.t, ' p ', self.p, ' n ', self.n
+ print 'dm_dg\n',self.dm_dg, '\ndr_dm\n',self.dr_dm,'\ndr_dg\n',self.dr_dg
+
+ def getDers(self,isTop):
+ half_offset = 10000
+ translation_offset = 1000
+ direction_offset = 100
+ topBot = 1
+ transRot = 1
+ direction = 1
+ if not isTop:
+ topBot = 2
+ res = {}
+ labels = []
+ ders = []
+ for ip, name in global_params.iteritems():
+ if ip > 3:
+ transRot = 2
+ direction = ((ip-1) % 3) + 1
+ else:
+ direction = ip
+ label = (int)(topBot * half_offset + transRot * translation_offset + direction * direction_offset + self.layer)
+ labels.append(label)
+ ders.append(self.dr_dg[0,ip-1])
+
+ return {'labels':np.array([labels]) , 'ders':np.array([ders])}
+
+
+
+
+ def getResDers(self):
+ # Derivatives of the local perturbed residual w.r.t. the measurements m (u,v,w)'
+ tdotn = np.dot(self.t.T,self.n)
+ drdg = np.eye(3)
+ #print 't ', self.t, ' n ', self.n, ' dot(t,n) ', tdotn
+ for i in range(3):
+ for j in range(3):
+ delta = 0.
+ if i==j:
+ delta = 1.
+ drdg[i][j] = delta - self.t[i]*self.n[j]/tdotn[0]
+ return drdg
+
+
+
+
+ def getMeasDers(self):
+ # Derivative of mt, the perturbed measured coordinate vector m
+ # w.r.t. to global parameters: u,v,w,alpha,beta,gamma
+
+ # Derivative of the local measurement for a translation in u
+ dmu_du = 1.
+ dmv_du = 0.
+ dmw_du = 0.
+ # Derivative of the local measurement for a translation in v
+ dmu_dv = 0.
+ dmv_dv = 1.
+ dmw_dv = 0.
+ # Derivative of the local measurement for a translation in w
+ dmu_dw = 0.
+ dmv_dw = 0.
+ dmw_dw = 1.
+ # Derivative of the local measurement for a rotation around u-axis (alpha)
+ dmu_dalpha = 0.
+ dmv_dalpha = self.p[2] # self.wmeas
+ dmw_dalpha = -1.0 * self.p[1] # -1.0 * self.vmeas
+ # Derivative of the local measurement for a rotation around v-axis (beta)
+ dmu_dbeta = -1.0 * self.p[2] #-1.0 * self.wmeas
+ dmv_dbeta = 0.
+ dmw_dbeta = self.p[0] #self.umeas
+ # Derivative of the local measurement for a rotation around w-axis (gamma)
+ dmu_dgamma = self.p[1] # self.vmeas
+ dmv_dgamma = -1.0 * self.p[0] # -1.0 * self.umeas
+ dmw_dgamma = 0.
+ # put into matrix
+ dmdg = np.array([[dmu_du, dmu_dv, dmu_dw, dmu_dalpha, dmu_dbeta, dmu_dgamma],[dmv_du, dmv_dv, dmv_dw, dmv_dalpha, dmv_dbeta, dmv_dgamma],[dmw_du, dmw_dv, dmw_dw, dmw_dalpha, dmw_dbeta, dmw_dgamma]])
+ #print dmw_dbeta
+ #dmdg = np.array([[dmu_du, dmu_dv],[dmu_dw, dmu_dalpha], [dmw_dbeta, dmw_dgamma]])
+ return dmdg
+ */
+ }
}
+
+
+
|