Commit 8418fb31 authored by Claus Kleinwort's avatar Claus Kleinwort
Browse files

python: access to residuals of measurements/scatterers added

git-svn-id: http://svnsrv.desy.de/public/GeneralBrokenLines/trunk@116 281f6f2b-e318-4fd1-8bce-1a4ba7aab212
parent 8c4683a0
......@@ -423,6 +423,13 @@ class GblData(object):
Chi2 = (self.__value - self.__prediction) ** 2 * self.__precision * self.__downWeight
return Chi2
## Get data for residual (and errors).
#
# @return data components; list
#
def getResidual(self):
return self.__value - self.__prediction, 1.0 / self.__precision, self.__downWeight, self.__parameters, self.__derivatives
## Get data components (for copying to MP binaty record)
#
# @return data components; list
......@@ -458,6 +465,8 @@ class GblData(object):
print " measurement at label ", self.__label, ": ", self.__value, self.__precision
print " param ", self.__parameters
print " deriv ", self.__derivatives
print " global labels ", self.__globalLabels
print " global deriv ", self.__globalDerivatives
#------------------------------------------------------------------------------
......@@ -474,6 +483,11 @@ class GblData(object):
# to the local track parameters (in the local system) and the
# corresponding covariance matrix at any of those points.
# Non-diagonal covariance matrices will be diagonalized internally.
# Outliers can be down-weighted by use of M-estimators.
#
# A position measurement is in a plane defined by two directions.
# Along one direction the measurement precision may be zero,
# defining a 1D measurement in the other direction.
#
# The broken lines trajectory is defined by (2D) offsets at the
# first and last point and all points with a scatterer. The
......@@ -494,10 +508,10 @@ class GblData(object):
#
# \section seq_sec Calling sequence:
# -# Create trajectory:\n
# <tt>traj = GblTrajectory()</tt>
# <tt>traj = \ref gblfit.GblTrajectory "GblTrajectory()" </tt>
# -# For all points on initial trajectory
# - Create point (supply jacobian from previous point):\n
# <tt>point = GblPoint(jacobian)</tt>
# <tt>point = \ref gblfit.GblPoint "GblPoint(jacobian)"</tt>
# - Optionally add measurement to point:\n
# <tt>point.addMeasurement(..)</tt>
# - Optionally additional local or global parameters for measurement:\n
......@@ -514,6 +528,10 @@ class GblData(object):
# -# For any point on inital trajectory
# - Get corrections and covariance matrix for track parameters:\n
# <tt>[..] = traj.getResults(label) </tt>
# - Optionally get resdiduals with errors for measurements:\n
# <tt>[..] = traj.getMeasResults(label) </tt>
# - Optionally get resdiduals with errors for scatterers:\n
# <tt>[..] = traj.getScatResults(label) </tt>
# -# Optionally write trajectory to MP binary file:\n
# <tt>traj.milleOut(..)</tt>
#
......@@ -559,6 +577,10 @@ class GblTrajectory(object):
self.__data = []
## external seed (for local, fit parameters); matrix(float)
self.__externalSeed = None
## mapping points to data blocks from measurements; list(int)
self.__measDataIndex = []
## mapping points to data blocks from scatterers; list(int)
self.__scatDataIndex = []
## Add point to trajectory. Points have to be ordered in arc length.
#
......@@ -601,6 +623,10 @@ class GblTrajectory(object):
for d in self.__data:
d.printData()
## Get data of trajectory.
def getData(self):
return self.__data
## Write (data blocks of) trajectory to MP (binary) file (as *float* or *double* values).
#
# @param aFile MP file
......@@ -809,8 +835,26 @@ class GblTrajectory(object):
return anIndex, aJacobian
## Get residual and errors from data block.
#
# @param aData data block
# @return residual, error of measurement and residual and down-weighting factor; list
#
def __getResAndErr(self, aData):
aResidual, aMeasVar, aDownWeight, indLocal, derLocal = self.__data[aData].getResidual()
aVec = np.array(derLocal) # compressed vector
aMat = self.__matrix.getBlockMatrix(indLocal) # compressed matrix
aFitVar = np.dot(aVec, np.dot(aMat, aVec.T)) # variance from track fit
aMeasError = math.sqrt(aMeasVar) # error of measurement
aResError = math.sqrt(aMeasVar - aFitVar) if aFitVar < aMeasVar else 0. # error of residual
return aResidual, aMeasError, aResError, aDownWeight
## Get results (corrections, covarinace matrix) at point in forward or backward direction.
#
# The point is identified by its label (1..number(points)), the sign distinguised the
# backward (facing previous point) and forward 'side' (facing next point).
# For scatterers the track direction may change inbetween.
#
# @param aLabel signed label of point (<0 backward, >0 forward); int
# @return correction vector, covarinace matrix for track parameters; list
#
......@@ -825,6 +869,55 @@ class GblTrajectory(object):
locCov = np.dot(aJacobian, np.dot(aMat, aJacobian.T))
return locPar, locCov
## Get residuals at point from measurement.
#
# Get (diagonalized) residual, error of measurement and residual and down-weighting factor for measurement at point
#
# @param aLabel label of point; int
# @return vectors with residuals, errors of maeansurements and residuals, down-weighting factors; list
#
def getMeasResults(self, aLabel):
firstData = self.__measDataIndex[aLabel - 1] # first data block with measurement
numData = self.__measDataIndex[aLabel] - firstData # number of data blocks
if numData <= 0:
return 0, None, None, None, None
#
aResiduals = np.empty(numData)
aMeasErr = np.empty(numData)
aResErr = np.empty(numData)
aDownWeight = np.empty(numData)
for i in range(numData):
aResiduals[i], aMeasErr[i], aResErr[i], aDownWeight[i] = self.__getResAndErr(firstData + i)
return numData, aResiduals, aMeasErr, aResErr, aDownWeight
## Get residuals at point from scatterer.
#
# Get (diagonalized) residual, error of measurement and residual and down-weighting factor for scatterering kinks at point
#
# @param aLabel label of point; int
# @return vectors with residuals, errors of maeansurements and residuals, down-weighting factors; list
#
def getScatResults(self, aLabel):
firstData = self.__scatDataIndex[aLabel - 1] # first data block with measurement
numData = self.__scatDataIndex[aLabel] - firstData # number of data blocks
if numData <= 0:
return 0, None, None, None, None
#
aResiduals = np.empty(numData)
aMeasErr = np.empty(numData)
aResErr = np.empty(numData)
aDownWeight = np.empty(numData)
for i in range(numData):
aResiduals[i], aMeasErr[i], aResErr[i], aDownWeight[i] = self.__getResAndErr(firstData + i)
return numData, aResiduals, aMeasErr, aResErr, aDownWeight
## Get residuals from data of trajectory.
#
# @param iData index of data block; int
#
def getResidual(self, iData):
return self.__getResAndErr(iData)
## Perform fit of trajectory.
#
# @param optionList M-estimators to be used (one iteration per character); string
......@@ -880,6 +973,7 @@ class GblTrajectory(object):
def prepare():
aDim = self.__dimensions
# measurements
self.__measDataIndex.append(len(self.__data)) # offset
for aPoint in self.__points:
if (aPoint.hasMeasurement()):
nLabel = aPoint.getLabel()
......@@ -897,8 +991,11 @@ class GblTrajectory(object):
aData.addDerivatives(i, labDer, matPDer, localDer, \
globalLab, globalDer)
self.__data.append(aData)
self.__measDataIndex.append(len(self.__data))
# aPoint.setDataMeas(i, len(self.__data))
# pseudo measurements from kinks
self.__scatDataIndex.append(len(self.__data)) # offset
self.__scatDataIndex.append(len(self.__data)) # first point
for aPoint in self.__points[1:-1]:
if (aPoint.hasScatterer()):
nLabel = aPoint.getLabel()
......@@ -910,7 +1007,9 @@ class GblTrajectory(object):
aData = GblData(nLabel, aMeas[i], aPrec[i])
aData.addDerivatives(i, labDer, matTDer)
self.__data.append(aData)
self.__scatDataIndex.append(len(self.__data))
# aPoint.setDataScat(i, len(self.__data))
self.__scatDataIndex.append(len(self.__data)) # last point
# external seed
if (self.__externalPoint != 0):
externalIndex, aJacobian = self.__getJacobian(self.__externalPoint)
......@@ -924,6 +1023,7 @@ class GblTrajectory(object):
aData = GblData(self.__externalPoint, 0., eigenVal[i])
aData.addExtDerivatives(externalIndex, externalDerivatives)
self.__data.append(aData)
self.__measDataIndex.append(len(self.__data))
## Build linear equation system from data.
def buildLinearEquationSystem():
......
......@@ -122,6 +122,7 @@ class BorderedBandMatrix(object):
#
def getBlockMatrix(self, aIndex):
nBorder = self.__numBorder
nBand = self.__numBand
nSize = len(aIndex)
aMatrix = np.empty((nSize, nSize))
for i in range(nSize):
......@@ -135,8 +136,11 @@ class BorderedBandMatrix(object):
elif (iMin < nBorder):
aMatrix[i, j] = self.__mixed[iMin, iMax - nBorder]
else:
nBand = iIndex - jIndex
aMatrix[i, j] = self.__band[nBand, jIndex - nBorder]
iBand = iMax - iMin
if iBand <= nBand:
aMatrix[i, j] = self.__band[iBand, iMin - nBorder]
else:
aMatrix[i, j] = 0.
aMatrix[j, i] = aMatrix[i, j]
return aMatrix
......
......@@ -200,6 +200,14 @@ def example1():
print " Point> ", i
print " locPar ", locPar
#print " locCov ", locCov
# check residuals
for i in range(traj.getNumPoints()):
numData, aResiduals, aMeasErr, aResErr, aDownWeight = traj.getMeasResults(i + 1)
for j in range(numData):
print " measRes " , i, j, aResiduals[j], aMeasErr[j], aResErr[j], aDownWeight[j]
numData, aResiduals, aMeasErr, aResErr, aDownWeight = traj.getScatResults(i + 1)
for j in range(numData):
print " scatRes " , i, j, aResiduals[j], aMeasErr[j], aResErr[j], aDownWeight[j]
#
end = time.clock()
print " Time [s] ", end - start
......@@ -275,7 +283,7 @@ class gblMeasSystem(object):
## products (T,U,V) * (I,J,K)
self.__prod = np.dot(curviDir, measDir.T)
## Transformation from measurement to local system
## Transformation from local to measurement system
#
# @return None (systems are identical)
#
......@@ -331,7 +339,7 @@ class gblCurviSystem(object):
## projection curvilinear to measurement system: ((U,V)*(J,K))^-1
self.__c2m = np.linalg.inv(np.dot(curviDir[1:3, 1:3], measDir[1:3, 1:3].T))
## Transformation from measurement to local system
## Transformation from local to measurement system
#
# @return Transformation for offsets; 2*2 matrix
#
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment