def doit(self,mobAtoms):
        """
mobAtoms: AtomSet that is being frozen.
Assuming the AtomSet are from same molecule
        """

        # fixme: need checking for mat (matrix) and mobAtoms
        geomContainer = mobAtoms[0].top.geomContainer
        mGeom = geomContainer.masterGeom
        mat = mGeom.rotation
        mat = Numeric.reshape(mat, (4,4))

        # update coords
        mobAtoms = mobAtoms.findType(Atom)
        coords = mobAtoms.coords
        hCoords = Numeric.concatenate((coords,Numeric.ones((len(coords),1),\
                                                            'd')), 1)
        tCoords = Numeric.dot(hCoords, mat)[:,:3]
        tCoords = tCoords.tolist()
        mobAtoms.updateCoords(tCoords, 0) # overwritten the original coords
        
        # reset the rotation matrix of masterGeom
        identity = Numeric.identity(4,'f').ravel()
        mGeom.SetRotation(Numeric.identity(4,'f').ravel() ) 

        event = EditAtomsEvent('coords', mobAtoms)
        self.vf.dispatchEvent(event)
        
        mGeom.viewer.Redraw()
        
        return
    def getMatrices(self, mol=None, keyword='MTRIX'):
        if mol is None:
            return

        matrices = []
        next = 0

        lines = mol.data[0].parser.allLines
        arr = Numeric.identity(4).astype('f')
    
        for l in lines:
            
            spl = string.split(l)
            if spl[0][:-1] != keyword: continue
            index = int(spl[0][-1:])-1

            arr[index][0] = float(spl[2])
            arr[index][1] = float(spl[3])
            arr[index][2] = float(spl[4])

            if index == 2:
                matrices.append(arr)
                arr = Numeric.identity(4).astype('f')
                
        return matrices
Exemple #3
0
def inverse4X4(matrix):
    """ returns the inverse of the given 4x4 transformation matrix
t_1: the negetive of Translation vector
r_1: the inverse of rotation matrix

inversed transformation is
1) t_1 applied first
2) then r_1 is applied

to validate the result, N.dot(matrix, mat_inverse)==N.identity(4,'f')
"""
    # check the shape
    if matrix.shape != (4, 4) and matrix.shape != (16, ):
        raise ValueError("Argument must Numeric array of shape (4,4) or (16,)")
        return None
    if matrix.shape == (16, ):
        matrix = N.array(matrix, 'f')
        matrix = N.reshape(matrix, (4, 4))  # force the matrix to be (4,4)
    t_1 = N.identity(4, 'f')
    t_1[:2, 3] = -matrix[:2, 3]
    r_1 = N.identity(4, 'f')
    r_1[:3, :3] = N.transpose(matrix[:3, :3])
    mat_inverse = N.dot(r_1, t_1)
    #asert N.dot(matrix, mat_inverse) is N.identity(4,'f')
    return mat_inverse
Exemple #4
0
def inverse4X4(matrix):
    """ returns the inverse of the given 4x4 transformation matrix
t_1: the negetive of Translation vector
r_1: the inverse of rotation matrix

inversed transformation is
1) t_1 applied first
2) then r_1 is applied

to validate the result, N.dot(matrix, mat_inverse)==N.identity(4,'f')
"""
    # check the shape
    if matrix.shape !=(4,4) and matrix.shape !=(16,) :
        raise ValueError("Argument must Numeric array of shape (4,4) or (16,)")
        return None
    if matrix.shape ==(16,):            
        matrix=N.array(matrix,'f')
        matrix=N.reshape(matrix,(4,4))  # force the matrix to be (4,4)
    t_1=N.identity(4,'f')
    t_1[:2,3]= - matrix[:2, 3]
    r_1=N.identity(4,'f')
    r_1[:3,:3] = N.transpose(matrix[:3,:3])
    mat_inverse=N.dot(r_1, t_1)
    #asert N.dot(matrix, mat_inverse) is N.identity(4,'f')
    return mat_inverse
    def doit(self, mobAtoms):
        """
mobAtoms: AtomSet that is being frozen.
Assuming the AtomSet are from same molecule
        """

        # fixme: need checking for mat (matrix) and mobAtoms
        geomContainer = mobAtoms[0].top.geomContainer
        mGeom = geomContainer.masterGeom
        mat = mGeom.rotation
        mat = Numeric.reshape(mat, (4, 4))

        # update coords
        mobAtoms = mobAtoms.findType(Atom)
        coords = mobAtoms.coords
        hCoords = Numeric.concatenate((coords,Numeric.ones((len(coords),1),\
                                                            'd')), 1)
        tCoords = Numeric.dot(hCoords, mat)[:, :3]
        tCoords = tCoords.tolist()
        mobAtoms.updateCoords(tCoords, 0)  # overwritten the original coords

        # reset the rotation matrix of masterGeom
        identity = Numeric.identity(4, 'f').ravel()
        mGeom.SetRotation(Numeric.identity(4, 'f').ravel())

        event = EditAtomsEvent('coords', mobAtoms)
        self.vf.dispatchEvent(event)

        mGeom.viewer.Redraw()

        return
    def getMatrices(self):
        m=[]
        mat=Numeric.identity(4).astype('f')

        if self.length is None or self.length == 0:
            m.append( Numeric.identity(4).astype('f') )
            return m

        if self.identity == 1:
            m.append( Numeric.identity(4).astype('f') )

        mat[:3, 3] = (self.vector*self.length).astype('f')
        m.append(mat)
        return m
Exemple #7
0
    def test_0031(self ):
        # example we test glMultMatrixf
        import Tkinter
        root = Tkinter.Tk()
        vi = OGLTkWidget(root)
        id = Numeric.array([1.,0.,0.,0.,
                            0.,1.,0.,0.,
                            0.,0.,1.,0.,
                            0.,0.,0.,1.], "d")
        from opengltk.extent import _gllib as gllib
        #GL.glMultMatrixf(id)
        try:
            gllib.cvar.checkArgumentsInCWrapper = 0
            GL.glMultMatrixf(id)
            # calling with bad argument
            gllib.cvar.checkArgumentsInCWrapper = 1
            #import numpy.oldnumeric as Numeric
            id = Numeric.identity(4).astype('d')
            try:
                GL.glMultMatrixf(id)
                raise RuntimeError('failed to catch type error in wrapper')
            except TypeError:
                print 'Type Error caught succefully in wrapper'
        except ImportError:
            pass

        root.after(1000, root.quit )
        root.mainloop()
        root.destroy()
Exemple #8
0
    def doit(self, geom, matrix):
        # gets called from NodeRepr()
        blender = []

        # if self.usePROTO is set to 1: don't convert instance matrices
        # geoms into geoms, but use the vrml2 USE
        if self.usePROTOFlag:
            # create all the necessary data to be put in the PROTO which goes
            # in the header of the vrml2 file
            if geom.VRML2CreatedPROTOForThisGeom == 0:
                name = self.getGeomName(geom)
                blender.append("PROTO " + name + " [ ] {\n")
                identityMatrix = Numeric.identity(4).astype('f')
                blender.extend(self.doitReally(geom, identityMatrix))
                blender.append("}\n")

                # now insert this into the header of self.output
                for i in range(len(vrml2)):
                    self.output.insert(i + 1, blender[i])
                geom.VRML2CreatedPROTOForThisGeom = 1  # don't add this geom
                # to the header next time
                # this PROTO flag will be deleted when we leave the recursive

            # and add it as USE to the body
            blender = []  # clear the list because this data has been added
            blender.extend(self.doitUsePROTO(geom, matrix))
            return blender

        else:
            # here we save all the data for all geoms
            return self.doitReally(geom, matrix)
Exemple #9
0
def rotz(angle):
    ret = numerix.identity(4).astype(numerix.Float)
    ret[0, 0] = ret[1, 1] = numerix.cos(angle)
    sn = numerix.sin(angle)
    ret[0, 1] = -sn
    ret[1, 0] = sn
    return ret
Exemple #10
0
 def _checkOrth(self, T, TT, eps=0.0001, output=False):
     """check if the basis is orthogonal on a set of points x: TT == T*transpose(T) == c*Identity
     INPUT:  T: matrix of values of polynomials calculated at common reference points (x)
             TT = T * transpose(T)
             eps: max numeric error
     """
     TTd0 = (-1. * Numeric.identity(Numeric.shape(TT)[0]) +
             1) * TT  # TTd0 = TT with 0s on the main diagonal
     s = Numeric.sum(Numeric.sum(Numeric.absolute(TTd0)))
     minT = MLab.min(MLab.min(T))
     maxT = MLab.max(MLab.max(T))
     minTTd0 = MLab.min(MLab.min(TTd0))
     maxTTd0 = MLab.max(MLab.max(TTd0))
     if not s < eps:
         out = "NOT ORTHOG, min(T), max(T):\t%f\t%f\n" % (minT, maxT)
         out += "  min(TTd0), max(TTd0), sum-abs-el(TTd0):\t%f\t%f\t%f" % (
             minTTd0, maxTTd0, s)
         if output:
             print out
             return False
         else:
             raise out
     elif output:
         out = "ORTHOGONAL, min(T), max(T):\t%f\t%f\n" % (minT, maxT)
         out += "  min(TTd0), max(TTd0), sum-abs-el(TTd0):\t%f\t%f\t%f" % (
             minTTd0, maxTTd0, s)
         print out
     return True
Exemple #11
0
def rotz(angle):
    ret = numerix.identity(4).astype(numerix.Float)
    ret[0,0] = ret[1,1] = numerix.cos(angle)
    sn = numerix.sin(angle)
    ret[0,1] = -sn
    ret[1,0] = sn
    return ret
Exemple #12
0
    def GetMatrix(self, root=None, instance=None, scale=True, transpose=True):
        if __debug__:
         if hasattr(DejaVu, 'functionName'): DejaVu.functionName()
	"""Returns the matrix by which this object is transformed
scale = False: returns the rotation and translation. no scaling info included
               Used to save the transformed geom --> coords --> new pdb file
instance is a list of integer instance indices for all parents
"""
        if root is None:
            root = self.viewer.rootObject

        if instance is None:
            instance = [0]
            p = self.parent
            while p:
                instance.append(0)
                p = p.parent

        GL.glPushMatrix()
        GL.glLoadIdentity()
        #print 'GetMatrix', instance
        self.BuildMat(self, root, scale, instance)
        #GL.glMultMatrixf(self.instanceMatricesFortran[instanceList[0]]])
        m = Numeric.array(GL.glGetDoublev(GL.GL_MODELVIEW_MATRIX)).astype('f')
        GL.glPopMatrix()
        if Numeric.alltrue(m==Numeric.zeros(16).astype('f')):
            # this happens when Pmv has no GUI
            m = Numeric.identity(4)
        if transpose:
            return Numeric.transpose(Numeric.reshape(m, (4,4)))
        else:
            return Numeric.reshape(m, (4,4))
    def doit(self, geom, matrix):
        # gets called from NodeRepr()
        blender = []
        
        # if self.usePROTO is set to 1: don't convert instance matrices
        # geoms into geoms, but use the vrml2 USE 
        if self.usePROTOFlag:
            # create all the necessary data to be put in the PROTO which goes
            # in the header of the vrml2 file
            if geom.VRML2CreatedPROTOForThisGeom == 0:
                name = self.getGeomName(geom)
                blender.append("PROTO "+name+" [ ] {\n")
                identityMatrix = Numeric.identity(4).astype('f')
                blender.extend( self.doitReally(geom, identityMatrix) )
                blender.append("}\n")

                # now insert this into the header of self.output
                for i in range(len(vrml2)):
                    self.output.insert(i+1,blender[i])
                geom.VRML2CreatedPROTOForThisGeom = 1 # don't add this geom
                                                      # to the header next time
                # this PROTO flag will be deleted when we leave the recursive
                
            # and add it as USE to the body
            blender = [] # clear the list because this data has been added
            blender.extend( self.doitUsePROTO(geom, matrix) )
            return blender

        else:
            # here we save all the data for all geoms
            return self.doitReally(geom, matrix)
Exemple #14
0
 def _checkOrth(self, T, TT, eps=0.0001, output=False):
     """check if the basis is orthogonal on a set of points x: TT == T*transpose(T) == c*Identity
     INPUT:  T: matrix of values of polynomials calculated at common reference points (x)
             TT = T * transpose(T)
             eps: max numeric error
     """
     TTd0 = (-1.*Numeric.identity(Numeric.shape(TT)[0])+1) * TT  # TTd0 = TT with 0s on the main diagonal
     s = Numeric.sum(Numeric.sum(Numeric.absolute(TTd0)))
     minT = MLab.min(MLab.min(T))
     maxT = MLab.max(MLab.max(T))
     minTTd0 = MLab.min(MLab.min(TTd0))
     maxTTd0 = MLab.max(MLab.max(TTd0))
     if not s < eps:
         out = "NOT ORTHOG, min(T), max(T):\t%f\t%f\n" % (minT, maxT)
         out += "  min(TTd0), max(TTd0), sum-abs-el(TTd0):\t%f\t%f\t%f" % (minTTd0, maxTTd0, s)
         if output:
             print out
             return False
         else:
             raise out
     elif output:
         out = "ORTHOGONAL, min(T), max(T):\t%f\t%f\n" % (minT, maxT)
         out += "  min(TTd0), max(TTd0), sum-abs-el(TTd0):\t%f\t%f\t%f" % (minTTd0, maxTTd0, s)
         print out
     return True
    def getMatrices(self):
        angle=360.0/self.symmetry
        m=[]
        t=Numeric.array(self.point)*-1

        if self.identity == 1:
            mat = Numeric.identity(4).astype('f')
            m.append(mat)
               
        T = Transformation(trans=t)
        T1 = T.inverse()
        for i in range(self.symmetry-1):
            newList=[]
            newList.extend(list(self.vector))
            newList.append(angle)

            R = Transformation(quaternion=newList)
            
            mt = T1 * R * T
            #newmat = mt.getMatrix()
            newmat = mt.getDejaVuMatrix()
            m.append(newmat)
            angle=angle+360.0/self.symmetry
            
        return m
Exemple #16
0
def scale(sxyz):
    ret = numerix.identity(4).astype(numerix.Float)
    s = numerix.ones(3, numerix.Float)
    s[0:len(sxyz)] = sxyz
    ret[0, 0] = s[0]
    ret[1, 1] = s[1]
    ret[2, 2] = s[2]
    return ret
 def set(self, coords=None, matrices=None):
     if coords is None: return
     else: self.coords = Numeric.array(coords).astype('f')
     if matrices is None:
         self.matrices = [Numeric.identity(4).astype('f')] 
     else:
         #assert matrices.shape[-2] == 4 and matrices.shape[-1] == 4
         self.matrices = matrices
Exemple #18
0
def scale(sxyz):
    ret = numerix.identity(4).astype(numerix.Float)
    s = numerix.ones(3, numerix.Float)
    s[0:len(sxyz)] = sxyz
    ret[0,0] = s[0]
    ret[1,1] = s[1]
    ret[2,2] = s[2]
    return ret
    def __call__(self, inMatrices, applyIndex=None):
        """outMatrices <- SymMerge(inMatrices, applyIndex=None)
        inMatrices: list of 4x4 matrices
        outMatrices: list of 4x4 matrices
        """

        if not inMatrices: inMatrices = [Numeric.identity(4).astype('f')]
        return inMatrices
    def __init__(self, name='Common2d3dObject', check=1, **kw):
        """Constructor
"""
        #self.newList = GL.glGenLists(1)

        self.name = name
        self.viewer = None
        self.immediateRendering = False
        self.needsRedoDpyListOnResize = False
        self.protected = False      # False == not protected against deletion
        self.replace = True     # this is used to store in a geometry the 
          # desired behavior when adding the geom to the Viewer.
          # in AddObject, if replace is not specified, geom.replace will be
          # used
        self.isExpandedInObjectList = 1 # set to 1 when children of that geom
                                # are visible in ViewerGUI object list
        
        self.parent = None      # parent object
        self.fullName = name    # object's name including parent's name
        self.children = []      # list of children
        self.listed = True         # When true the name of this object appears
                                # in the GUI's object

        self.pickable = True       # when set the object can be picked

        self.pickNum = 0

        self.dpyList = None     # display list for drawing
        self.pickDpyList = None # display list for picking
        
        # FIXME: quick hack. Flag set by SetCurrentXxxx. When set object's
        # transformation and material are saved in log file
        self.hasBeenCurrent = False


        self.depthMask = 1 # 0: zbuffer is readOnly for transparent objects
                           # 1: zbuffer is read write for transparent objects
        self.srcBlendFunc = GL.GL_SRC_ALPHA
        #self.dstBlendFunc = GL.GL_ONE #GL.GL_ONE_MINUS_SRC_COLOR
        # ONE_MINUS_SRC_ALPHA works for colorMapEditor
        self.dstBlendFunc = GL.GL_ONE_MINUS_SRC_ALPHA 

        self.transparent = False #viewerConst.NO
        
        self.visible = True

        m = Numeric.reshape( Numeric.identity(4), (1,16) )
        self.instanceMatricesFortran = m.astype('f')

        self.ownGui = None

        self.animatable = True

        apply( self.Set, (check, 0), kw)

        self._modified = False  # used to decide if we should save state
 def __call__(self, inMatrices, applyIndex=None):
     """outMatrices <- SymSplit(inMatrices, applyIndex=None)
     inMatrices: list of 4x4 matrices
     outMatrices: list of 4x4 matrices
     """
     if not inMatrices:
         outMatrices = [Numeric.identity(4).astype('f')]
     else:
         outMatrices = self.getMatrices()
     return outMatrices
Exemple #22
0
    def __init__(self, name='Common2d3dObject', check=1, **kw):
        """Constructor
"""
        #self.newList = GL.glGenLists(1)

        self.name = name
        self.viewer = None
        self.immediateRendering = False
        self.needsRedoDpyListOnResize = False
        self.protected = False  # False == not protected against deletion
        self.replace = True  # this is used to store in a geometry the
        # desired behavior when adding the geom to the Viewer.
        # in AddObject, if replace is not specified, geom.replace will be
        # used
        self.isExpandedInObjectList = 1  # set to 1 when children of that geom
        # are visible in ViewerGUI object list

        self.parent = None  # parent object
        self.fullName = name  # object's name including parent's name
        self.children = []  # list of children
        self.listed = True  # When true the name of this object appears
        # in the GUI's object

        self.pickable = True  # when set the object can be picked

        self.pickNum = 0

        self.dpyList = None  # display list for drawing
        self.pickDpyList = None  # display list for picking

        # FIXME: quick hack. Flag set by SetCurrentXxxx. When set object's
        # transformation and material are saved in log file
        self.hasBeenCurrent = False

        self.depthMask = 1  # 0: zbuffer is readOnly for transparent objects
        # 1: zbuffer is read write for transparent objects
        self.srcBlendFunc = GL.GL_SRC_ALPHA
        #self.dstBlendFunc = GL.GL_ONE #GL.GL_ONE_MINUS_SRC_COLOR
        # ONE_MINUS_SRC_ALPHA works for colorMapEditor
        self.dstBlendFunc = GL.GL_ONE_MINUS_SRC_ALPHA

        self.transparent = False  #viewerConst.NO

        self.visible = True

        m = Numeric.reshape(Numeric.identity(4), (1, 16))
        self.instanceMatricesFortran = m.astype('f')

        self.ownGui = None

        self.animatable = True

        apply(self.Set, (check, 0), kw)

        self._modified = False  # used to decide if we should save state
Exemple #23
0
def interpolate3DTransform(matrixList, indexList, percent):
    """ This function gets input of two list and a percent value.
Return value is a 4x4 matrix corresponding to percent% of the transformation.

matrixList: a list of 4x4 transformation matrix
indexList : a list of sorted index (positive float number)
percent   : a positive float number.
if only one matrix in the matrix list:
percent =   0.0  means no transformation (identity)
            1.0  means 100% of the transformation (returns mat)
            0.58 means 58% of translation and rotatetion 58% of rotation angle
            along the same rotation axis
percent can go above 1.0

If matrixList has more than one matrix:
matrixList=[M1,  M2,  M3]     #Attention: All M uses the same reference frame
indexList =[0.2, 0.5, 1.0]    #Attention: assume the list sorted ascendingly
p = 0.5 means apply M2
p = 0.8 means apply M3
p = 0.9 means apply M2 first, then apply 50% of M'.  M' is the transformation
                    from M2 to M3.   50% = (0.9-0.8) / (1.0-0.8)
                    M2 x M' = M3
                    -->  M2.inverse x M2 x M'= M2.inverse x M3 
                    -->  M'= M2.inverse x M
"""
    listLen = len(matrixList)
    if listLen != len(indexList):
        raise ValueError("matrix list should have same length of index list")
    if listLen == 0:
        raise ValueError("no matrix found in the matrix list")

    offset = -1
    for i in range(listLen):
        if indexList[i] >= percent:
            offset = i
            break

    prevMat = nextMat = N.identity(4, 'f')
    if offset == -1:
        prevMat = matrixList[-1]
        p = percent / indexList[-1]
        return _interpolateMat(matrixList[-1], p)
    elif offset == 0:
        nextMat = matrixList[0]
        p = percent / indexList[0]
        return _interpolateMat(N.array(matrixList[0]), p)
    else:
        prevMat = matrixList[offset - 1]
        nextMat = matrixList[offset]
        p = (percent - indexList[offset - 1]) / (indexList[offset] -
                                                 indexList[offset - 1])
        from numpy.oldnumeric.linear_algebra import inverse
        M = N.dot(inverse(prevMat), nextMat)
        Mat = _interpolateMat(M, p)
        return N.dot(prevMat, Mat)
Exemple #24
0
def interpolate3DTransform(matrixList, indexList, percent):
    """ This function gets input of two list and a percent value.
Return value is a 4x4 matrix corresponding to percent% of the transformation.

matrixList: a list of 4x4 transformation matrix
indexList : a list of sorted index (positive float number)
percent   : a positive float number.
if only one matrix in the matrix list:
percent =   0.0  means no transformation (identity)
            1.0  means 100% of the transformation (returns mat)
            0.58 means 58% of translation and rotatetion 58% of rotation angle
            along the same rotation axis
percent can go above 1.0

If matrixList has more than one matrix:
matrixList=[M1,  M2,  M3]     #Attention: All M uses the same reference frame
indexList =[0.2, 0.5, 1.0]    #Attention: assume the list sorted ascendingly
p = 0.5 means apply M2
p = 0.8 means apply M3
p = 0.9 means apply M2 first, then apply 50% of M'.  M' is the transformation
                    from M2 to M3.   50% = (0.9-0.8) / (1.0-0.8)
                    M2 x M' = M3
                    -->  M2.inverse x M2 x M'= M2.inverse x M3 
                    -->  M'= M2.inverse x M
"""
    listLen = len(matrixList)
    if listLen != len(indexList):
        raise ValueError("matrix list should have same length of index list")
    if listLen == 0:
        raise ValueError("no matrix found in the matrix list")

    offset = -1
    for i in range(listLen):
        if indexList[i] >= percent:
            offset = i
            break

    prevMat = nextMat = N.identity(4,'f')
    if offset == -1:
        prevMat = matrixList[-1]
        p = percent/indexList[-1]
        return _interpolateMat(matrixList[-1], p)
    elif offset == 0:
        nextMat = matrixList[0]
        p = percent/indexList[0]
        return _interpolateMat(N.array(matrixList[0]), p)
    else:
        prevMat = matrixList[offset-1]
        nextMat = matrixList[offset]
        p = (percent-indexList[offset-1])/(
                                    indexList[offset]-indexList[offset-1])
        from numpy.oldnumeric.linear_algebra import inverse
        M = N.dot(inverse(prevMat), nextMat)
        Mat = _interpolateMat(M, p)
        return N.dot(prevMat, Mat)
Exemple #25
0
 def transformIsIdentity(self):
     if __debug__:
      if hasattr(DejaVu, 'functionName'): DejaVu.functionName()
     """return true if this object has the identity matrix as
     transformation"""
     mat = self.GetMatrix()
     diff = Numeric.sum( (mat-Numeric.identity(4)).ravel() )
     if math.fabs(diff) < 0.00001:
         return True
     else:
         return False
Exemple #26
0
def mat_to_axis_angle(matrix):
    """
    NOTE: This function is added by Yong 2/01/04: given a 4x4 transformation
matrix of hinge motion, now returns the rotation angle and axis (defined by
vector and a point) Please be noticed that if the motion is not hinge, the
function will complain and return none
"""
    if matrix.shape != (16, ) and matrix.shape != (4, 4):
        raise ValueError("matrix should be of shape (4,4) or (16,)")
        return None

    if matrix.shape == (16, ):
        matrix = N.reshape(matrix, (4, 4))

    from math import sin, cos, pi, sqrt, fabs, acos
    degtorad = pi / 180.

    transf = matrix
    from mglutil.math.rotax import mat_to_quat
    rotMat = N.identity(4, 'f')
    rotMat[:3, :3] = transf[:3, :3]
    qB = mat_to_quat(matrix=N.array(rotMat).ravel())
    angle = qB[3]
    sa = sin(angle * degtorad / 2.0)
    if (fabs(angle) < 0.0005):
        sa = 1
    if angle > 180.:
        vector = [-qB[0] / sa, -qB[1] / sa, -qB[2] / sa]
    else:
        vector = [qB[0] / sa, qB[1] / sa, qB[2] / sa]
    tranMat = transf[3, :3]

    # check if the transformation is a hinge motion
    a = vector
    b = tranMat
    c = [a[0] - b[0], a[1] - b[1], a[2] - b[2]]
    a2 = a[0] * a[0] + a[1] * a[1] + a[2] * a[2]
    b2 = b[0] * b[0] + b[1] * b[1] + b[2] * b[2]
    c2 = c[0] * c[0] + c[1] * c[1] + c[2] * c[2]
    theta = acos((c2 - a2 - b2) / (2 * sqrt(a2 * b2))) / pi * 180
    if fabs(theta - 90) > 1e-4:
        raise ValueError("The given transformation is not a hinge motion")
        return None, None, None

    ratio = sqrt(1. / (2. * (1. - cos(degtorad * angle))))
    p = [tranMat[0] * ratio, tranMat[1] * ratio, tranMat[2] * ratio]

    ang = 90. - angle / 2.0
    rot = rotax([0., 0., 0.], vector, ang * degtorad, transpose=1)
    rot = rot[:3, :3]
    point = N.dot(p, rot)

    return vector, point, angle
Exemple #27
0
def mat_to_axis_angle( matrix ):
    """
    NOTE: This function is added by Yong 2/01/04: given a 4x4 transformation
matrix of hinge motion, now returns the rotation angle and axis (defined by
vector and a point) Please be noticed that if the motion is not hinge, the
function will complain and return none
"""
    if matrix.shape != (16,) and matrix.shape != (4,4):
        raise ValueError("matrix should be of shape (4,4) or (16,)")
        return None

    if matrix.shape == (16,):
        matrix = N.reshape(matrix, (4,4))

    from math import sin, cos, pi, sqrt, fabs, acos
    degtorad = pi/180.

    transf = matrix
    from mglutil.math.rotax import mat_to_quat
    rotMat =  N.identity(4, 'f')
    rotMat[:3,:3] = transf[:3,:3]
    qB = mat_to_quat(matrix=N.array(rotMat).ravel())
    angle = qB[3]
    sa=sin(angle*degtorad/2.0)
    if(fabs(angle) < 0.0005):
        sa = 1
    if angle > 180.:
        vector=[-qB[0]/sa, -qB[1]/sa, -qB[2]/sa]
    else:
        vector=[qB[0]/sa, qB[1]/sa, qB[2]/sa]
    tranMat = transf[3,:3]

    # check if the transformation is a hinge motion
    a=vector
    b=tranMat
    c =[a[0]-b[0], a[1]-b[1], a[2]-b[2]]
    a2= a[0]*a[0] + a[1]*a[1] + a[2]*a[2]
    b2= b[0]*b[0] + b[1]*b[1] + b[2]*b[2]
    c2= c[0]*c[0] + c[1]*c[1] + c[2]*c[2]
    theta = acos((c2-a2-b2)/(2* sqrt(a2*b2))) / pi * 180
    if fabs(theta -90) > 1e-4:
        raise ValueError("The given transformation is not a hinge motion")
        return None, None, None
    
    ratio = sqrt( 1. / (2. * (1.- cos(degtorad * angle ))))
    p = [tranMat[0]*ratio, tranMat[1]*ratio, tranMat[2]*ratio]

    ang = 90. - angle/2.0
    rot = rotax([0.,0.,0.], vector, ang*degtorad, transpose=1)
    rot = rot[:3,:3]
    point = N.dot(p, rot)
    
    return vector, point, angle
    def set(self, inA=None, inB=None):
        
        if inA is None and inB is not None:
            matInA = matInB = inB
        elif inA is not None and inB is None:
            matInA = matInB = inA
        elif inA is not None and inB is not None:
            matInA = inA
            matInB = inB
        elif inA is None and inB is None:
            matInA = matInB = Numeric.identity(4).astype('f') 

        return matInA, matInB
Exemple #29
0
    def ResetTransformation(self, redo=1):
        if __debug__:
         if hasattr(DejaVu, 'functionName'): DejaVu.functionName()
        """Reset the tranformations (Rotation, translation, pivot, scale)"""
	self.rotation = Numeric.identity(4).astype('f')
	self.rotation.shape = (16, )
	self.translation = Numeric.zeros( (3,), 'f')
	self.pivot = Numeric.zeros( (3,), 'f')
	self.scale = Numeric.ones( (3,), 'f')
        if self.viewer:
            if self.viewer.currentObject != self.viewer.rootObject \
               and redo:
                self.viewer.deleteOpenglList()
Exemple #30
0
    def __init__(self, viewer=None):
        if __debug__:
         if hasattr(DejaVu, 'functionName'): DejaVu.functionName()
	"""Constructor"""

        self.inheritXform = 1                    # set to 0 not to inherit
	self.redirectXform = None                # object to which transf.
	                                         # should be redirected
	self.propagateRedirection = 1

	self.copyXform = []                      # list of objects to be
                                                 # transf. along with me

                                                 # Object's original transf.
                                                 # in OpenGL form (shape (16,))
        self.Matrix = Numeric.identity(4).astype('f')
        self.Matrix.shape = (16, )
        self.MatrixRot = self.Matrix
        self.MatrixRotInv = self.Matrix
        self.MatrixScale = Numeric.ones((3,), 'f')
        self.MatrixTransl = Numeric.zeros( (3,), 'f')
        self.viewer = viewer
        
	self.ResetTransformation(redo=0)               # init object's transf.

	self.R = Numeric.identity(4).astype('f') # Object's frame rotation
	self.R.shape = (16, )

	self.Ri = Numeric.identity(4) .astype('f') # Inverse of R
	self.Ri.shape = (16, )

	self.Si = Numeric.ones( (3, ) ).astype('f') # Inverse of frame's scale
	self.isScalable = 1

        self.immediateRendering = False
        #self.hasChildWithImmediateRendering = False # set to True if a child is not using dpyList
        self.needsRedoDpyListOnResize = False
Exemple #31
0
    def _uinv(self, mat):
        """Inverts a transformation matrix used to go from cartesian to cell
        coordinates"""

        dmat = Numeric.identity(3).astype('d')
        imat = Numeric.identity(3).astype('d')

        dmat[0][0]=mat[1][1]*mat[2][2]-mat[2][1]*mat[1][2]
        dmat[1][0]=mat[1][2]*mat[2][0]-mat[1][0]*mat[2][2]
        dmat[2][0]=mat[1][0]*mat[2][1]-mat[1][1]*mat[2][0]
        dmat[0][1]=mat[0][2]*mat[2][1]-mat[0][1]*mat[2][2]
        dmat[1][1]=mat[0][0]*mat[2][2]-mat[0][2]*mat[2][0]
        dmat[2][1]=mat[0][1]*mat[2][0]-mat[0][0]*mat[2][1]
        dmat[0][2]=mat[0][1]*mat[1][2]-mat[0][2]*mat[1][1]
        dmat[1][2]=mat[0][2]*mat[1][0]-mat[0][0]*mat[1][2]
        dmat[2][2]=mat[0][0]*mat[1][1]-mat[0][1]*mat[1][0]
        det = mat[0][0]*mat[1][1]*mat[2][2]+mat[1][0]*mat[2][1]*mat[0][2]+ \
              mat[2][0]*mat[0][1]*mat[1][2]-mat[2][2]*mat[0][1]*mat[1][0]- \
              mat[0][0]*mat[2][1]*mat[1][2]-mat[2][0]*mat[1][1]*mat[0][2]
        for i in (0,1,2):
            for j in (0,1,2):
                imat[j][i]=dmat[j][i]/det

        return Numeric.transpose(imat)
Exemple #32
0
def _interpolateMat(mat, percent):
    """ called only by interpolate3DTransform()
    """
    if mat.shape != (16, ) and mat.shape != (4, 4):
        raise ValueError("matrix should be of shape (4,4) or (16,)")
        return None

    if mat.shape == (16, ):
        mat = N.reshape(mat, (4, 4))

#  if percent <0.0:
#      raise ValueError('The parameter percent should be a positive float"')
#      return

    p = percent
    transf = mat[:, :]
    rotMat = N.identity(4, 'f')
    rotMat[:3, :3] = transf.astype(N.Float32)[:3, :3]

    from mglutil.math.rotax import mat_to_quat
    quat = mat_to_quat(matrix=N.array(rotMat).ravel())
    angle = quat[3] * p

    newRotMat = rotax([0., 0., 0.], quat[:3], angle * degtorad, transpose=1)
    newTranMat = N.identity(4, 'f')
    newTranMat[3][0] = transf[3][0] * p
    newTranMat[3][1] = transf[3][1] * p
    newTranMat[3][2] = transf[3][2] * p

    transform = newRotMat
    transform[3][0] = newTranMat[3][0]
    transform[3][1] = newTranMat[3][1]
    transform[3][2] = newTranMat[3][2]
    # That's it.. the self.transform is now updated.

    return transform
Exemple #33
0
def _interpolateMat(mat, percent):
    """ called only by interpolate3DTransform()
    """
    if mat.shape != (16,) and mat.shape != (4,4):
        raise ValueError("matrix should be of shape (4,4) or (16,)")
        return None

    if mat.shape == (16,):
        mat = N.reshape(mat, (4,4))

  #  if percent <0.0:
  #      raise ValueError('The parameter percent should be a positive float"')
  #      return

    p = percent
    transf = mat[:,:]
    rotMat =  N.identity(4, 'f')
    rotMat[:3,:3]=transf.astype(N.Float32)[:3,:3]

    from mglutil.math.rotax import mat_to_quat
    quat = mat_to_quat(matrix=N.array(rotMat).ravel())
    angle = quat[3] * p

    newRotMat = rotax([0.,0.,0.], quat[:3], angle*degtorad, transpose = 1)
    newTranMat =  N.identity(4, 'f')
    newTranMat[3][0] = transf[3][0]*p
    newTranMat[3][1] = transf[3][1]*p
    newTranMat[3][2] = transf[3][2]*p

    transform = newRotMat
    transform[3][0] = newTranMat[3][0]
    transform[3][1] = newTranMat[3][1]
    transform[3][2] = newTranMat[3][2]
    # That's it.. the self.transform is now updated.    
    
    return transform
    def doit(self, refAtoms, mobAtoms, updateGeom=True, showRMSD=True):
        """
        The SuperImposeAtomsCommand takes two set of Atoms of the same length
        compute the rotation and translation matrices to superimpose the
        mobAtoms onto the refAtoms using rigidFit module and then transform the
        corresponding geometry.

        updateGeom = True : transform the masterGeom of mobAtoms.
        showRMSD   = True : print and return RMSD 
        """

        if refAtoms is None or mobAtoms is None: return
        assert isinstance(refAtoms, TreeNodeSet)
        assert isinstance(mobAtoms, TreeNodeSet)

        refAtoms = refAtoms.findType(Atom)
        mobAtoms = mobAtoms.findType(Atom)
        # validate the inputs
        if len(refAtoms) != len(mobAtoms):
            print "The two atomSet are not of equal length"
            return
        if len(refAtoms) < 3:
            print "At least three atoms are needed for superimposition"
            return

        refCoords = refAtoms.coords
        mobCoords = mobAtoms.coords

        rigidfitAligner = RigidfitBodyAligner()
        rigidfitAligner.setRefCoords(refCoords)
        rigidfitAligner.rigidFit(mobCoords)

        if updateGeom:
            rotMat = Numeric.identity(4).astype('d')
            rotMat[:3, :3] = rigidfitAligner.rotationMatrix
            transMat = Numeric.array(rigidfitAligner.translationMatrix)
            rotMat[3, :3] = transMat
            #print rotMat  # the matrix
            mGeom = mobAtoms[0].top.geomContainer.masterGeom
            mGeom.SetRotation(Numeric.reshape(rotMat, (16, )).astype('f'))
            mGeom.viewer.Redraw()

        if showRMSD:
            rmsd = rigidfitAligner.rmsdAfterSuperimposition(mobCoords)
            print "RMSD = ", rmsd
            return rmsd
        else:
            return
    def doit(self, refAtoms, mobAtoms, updateGeom=True, showRMSD=True):
        """
        The SuperImposeAtomsCommand takes two set of Atoms of the same length
        compute the rotation and translation matrices to superimpose the
        mobAtoms onto the refAtoms using rigidFit module and then transform the
        corresponding geometry.

        updateGeom = True : transform the masterGeom of mobAtoms.
        showRMSD   = True : print and return RMSD 
        """

        if refAtoms is None or mobAtoms is None: return
        assert isinstance(refAtoms, TreeNodeSet)
        assert isinstance(mobAtoms, TreeNodeSet)

        refAtoms = refAtoms.findType(Atom)
        mobAtoms = mobAtoms.findType(Atom)
        # validate the inputs
        if len(refAtoms) !=len(mobAtoms):
            print "The two atomSet are not of equal length"
            return
        if len(refAtoms) < 3 :
            print "At least three atoms are needed for superimposition"
            return
        
        refCoords = refAtoms.coords
        mobCoords = mobAtoms.coords
        
        rigidfitAligner = RigidfitBodyAligner()
        rigidfitAligner.setRefCoords(refCoords)                
        rigidfitAligner.rigidFit(mobCoords)

        if updateGeom:
            rotMat =  Numeric.identity(4).astype('d')
            rotMat[:3,:3] = rigidfitAligner.rotationMatrix               
            transMat = Numeric.array(rigidfitAligner.translationMatrix)
            rotMat[3,:3] = transMat
            #print rotMat  # the matrix
            mGeom = mobAtoms[0].top.geomContainer.masterGeom        
            mGeom.SetRotation(Numeric.reshape(rotMat, (16,)).astype('f'))
            mGeom.viewer.Redraw()

        if showRMSD:
            rmsd=rigidfitAligner.rmsdAfterSuperimposition(mobCoords)
            print "RMSD = ", rmsd
            return rmsd
        else:
            return
    def __call__(self, inMatrices, applyIndex=None):
        """outMatrices <- SymOrient(inMatrices, applyIndex=None)
        inMatrices: list of 4x4 matrices
        outMatrices: list of 4x4 matrices
        """

        if not inMatrices: inMatrices = [Numeric.identity(4).astype('f')]
        matrices = Numeric.array(inMatrices)
        assert len(matrices.shape)==3
        assert matrices.shape[-2] == 4 and matrices.shape[-1] == 4
        ownmat = self.getMatrices()
        out = []
        for m in ownmat: # loop over this node's own transformation matrices
            for im in matrices: #loop over node's incoming matrices
                out.append( Numeric.dot(m, im) )
        return out
    def __call__(self, inMatrices=None, applyIndex=None):
        """outMatrices <- SymTranspose(inMatrices, applyIndex=None)
        inMatrices: list of 4x4 matrices
        outMatrices: list of 4x4 matrices
        """

        if not inMatrices:
            inMatrices = [Numeric.identity(4).astype('f')]

        matrices = Numeric.array(inMatrices)
        assert matrices.shape[-2] == 4 and matrices.shape[-1] == 4

        out = []
        for im in matrices: #loop over node's incoming matrices
            out.append( Numeric.transpose(im) )
        return out
    def __call__(self, inMatrices=None, applyIndex=None):
        """outMatrices <- SymInverse(inMatrices, applyIndex=None)
        inMatrices: list of 4x4 matrices
        outMatrices: list of 4x4 matrices
        """

        import numpy.oldnumeric.linear_algebra as LinearAlgebra 

        if not inMatrices:
            inMatrices = [Numeric.identity(4).astype('f')]

        matrices = Numeric.array(inMatrices)
        assert matrices.shape[-2] == 4 and matrices.shape[-1] == 4

        out = []
        for im in matrices: #loop over node's incoming matrices
            out.append( LinearAlgebra.inverse(im) )
        return out
    def __call__(self, inMatrices, scaleFactor, applyIndex=None, selection=[True,True,True]):
        """outMatrices <- SymScale(inMatrices, applyIndex=None, selection=[1,1,1])
        inMatrices: list of 4x4 matrices
        outMatrices: list of 4x4 matrices
        (selection: scale x,y, and/or z) can be 1,True or 0,False)
        """
        
        if not inMatrices:
            inMatrices = [Numeric.identity(4).astype('f')]

        matrices = Numeric.array(inMatrices)
        assert len(matrices.shape)==3
        assert matrices.shape[-2] == 4 and matrices.shape[-1] == 4
        ownmat = self.getMatrices(scaleFactor, selection)
        out = []
        for im in matrices: #loop over node's incoming matrices
                out.append( Numeric.dot(im, ownmat) )
        return out
    def __call__(self, inMatrices, applyIndex=None):
        """outMatrices <- SymNFold(inMatrices, applyIndex=None)
        inMatrices: list of 4x4 matrices
        outMatrices: list of 4x4 matrices
        if applyIndex is given it should be a list of 0-based indices of
        matrices to which this operator's transformation will be applied.
        """

        if not inMatrices: inMatrices = [Numeric.identity(4).astype('f')]
        matrices = Numeric.array(inMatrices)
        assert len(matrices.shape)==3
        assert matrices.shape[-2] == 4 and matrices.shape[-1] == 4
        ownmat = self.getMatrices()
        out = []
        for m in ownmat: # loop over this node's own transformation matrices
            for im in matrices: #loop over node's incoming matrices
                out.append( Numeric.dot(m, im) )
        return out
    def getMatrices(self):
        m=[]
        newList=[]
        mat = Numeric.identity(4).astype('f')
        if self.identity == 1:
            m.append(mat)

        newList.extend(list(self.vector))
        newList.append(self.angle)
        t=Numeric.array(self.center)*-1
        
        T = Transformation(trans=t)
        R = Transformation(quaternion=newList)

        mt = T.inverse() * R * T
        newmat = mt.getMatrix()

        m.append(newmat)
        return m
Exemple #42
0
def EulerAnglesToMat( angles ):
    """Builds a rotation matrix from Euler angles given in degrees"""

    from math import pi, cos, sin
    
    t1 = angles[0]* (pi/180.0)
    t2 = angles[1]* (pi/180.0)
    t3 = angles[2]* (pi/180.0)
    # from Lattman, Meth. Enzymology V. 115 p. 63
    rot = Numeric.identity(3).astype('d')
    rot[0][0]= -sin(t1)*cos(t2)*sin(t3) + cos(t1)*cos(t3)
    rot[0][1]= cos(t1)*cos(t2)*sin(t3) + sin(t1)*cos(t3)
    rot[0][2]= sin(t2)*sin(t3)
    rot[1][0]= -sin(t1)*cos(t2)*cos(t3) - cos(t1)*sin(t3)
    rot[1][1]= cos(t1)*cos(t2)*cos(t3) - sin(t1)*sin(t3)
    rot[1][2]= sin(t2)*cos(t3)
    rot[2][0]= sin(t1)*sin(t2)
    rot[2][1]= -cos(t1)*sin(t2)
    rot[2][2]= cos(t2)
    return rot
Exemple #43
0
    def __init__(self, name='Set Instances', **kw):
        kw['name'] = name

        apply(NetworkNode.__init__, (self, ), kw)

        self.inputPortsDescr.append(datatype='Molecule', name='molecule')
        self.inputPortsDescr.append(datatype='instancemat(0)',
                                    name='matrices',
                                    required=False,
                                    defaultValue=[Numeric.identity(4, 'f')])

        code = """def doit(self, molecule, matrices):
    if molecule:
        assert hasattr(molecule, 'geomContainer')   

        geom = molecule.geomContainer.geoms['master']
        geom.Set(instanceMatrices=matrices)
        
        geom.viewer.Redraw()\n"""

        self.setFunction(code)
Exemple #44
0
def rotxyz(angles):
    ret = numerix.identity(4).astype(numerix.Float)

    ret[1, 1] = ret[2, 2] = numerix.cos(angles[0])
    sn = numerix.sin(angles[0])
    ret[1, 2] = -sn
    ret[2, 1] = sn

    cs = numerix.cos(angles[1])
    ret[0, 0] = cs
    ret[2, 2] += cs
    sn = numerix.sin(angles[1])
    ret[0, 2] = sn
    ret[2, 0] = -sn

    cs = numerix.cos(angles[2])
    ret[0, 0] += cs
    ret[1, 1] += cs
    sn = numerix.sin(angles[2])
    ret[0, 1] = -sn
    ret[1, 0] = sn
    return ret
Exemple #45
0
    def transformCoords(self, setCoords):
        """ The transformCoords method applies the transformation matrices
        computed by rigidFit method to the given list of coordinates.
        """
        # This can only be done if the transformation matrices have been computed
        # by the rigidFit method.
        if not self.superimposed: return

        # 1- apply the rotation and the translation matrix to the given set of coords.
        transfoMatrix = Numeric.identity(4, 'd')
        transfoMatrix[:3, :3] = self.rotationMatrix
        transfoMatrix[3][0] = self.translationMatrix[0]
        transfoMatrix[3][1] = self.translationMatrix[1]
        transfoMatrix[3][2] = self.translationMatrix[2]

        # 2- now apply the transformation to the list of given coordinates list:
        # make homogeneous coords
        homoCoords = Numeric.concatenate(
            (setCoords, Numeric.ones((len(setCoords), 1), 'd')), 1)
        # 3- apply the transformation matrix to the homogeneous coords.
        transformedCoords = Numeric.dot(homoCoords, transfoMatrix)

        return transformedCoords
Exemple #46
0
 def Decompose4x4(self, matrix, cleanup=True):
     if __debug__:
      if hasattr(DejaVu, 'functionName'): DejaVu.functionName()
     """ takes a matrix in shape (16,) in OpenGL form (sequential values go
     down columns) and decomposes it into its rotation (shape (16,)),
     translation (shape (3,)), and scale (shape (3,)) """
     m = matrix
     transl = Numeric.array((m[12], m[13], m[14]), 'f')
     scale0 = Numeric.sqrt(m[0]*m[0]+m[4]*m[4]+m[8]*m[8])
     scale1 = Numeric.sqrt(m[1]*m[1]+m[5]*m[5]+m[9]*m[9])
     scale2 = Numeric.sqrt(m[2]*m[2]+m[6]*m[6]+m[10]*m[10])
     scale = Numeric.array((scale0,scale1,scale2)).astype('f')
     mat = Numeric.reshape(m, (4,4))
     rot = Numeric.identity(4).astype('f')
     rot[:3,:3] = mat[:3,:3].astype('f')
     rot[:,0] = (rot[:,0]/scale0).astype('f')
     rot[:,1] = (rot[:,1]/scale1).astype('f')
     rot[:,2] = (rot[:,2]/scale2).astype('f')
     if cleanup:
         rot = glCleanRotMat(rot.ravel())
     rot.shape = (16,)
     #rot1 = rot.astype('f')
     return rot, transl, scale
Exemple #47
0
    def doit(self, refAtoms, mobAtoms):
        """
        The SuperImposeAtomsCommand takes two set of Atoms of the same length
        compute the rotation and translation matrices to superimpose the
        mobAtoms onto the refAtoms using rigidFit module and then transform the
        corresponding geometry.
        """
        refCoords = refAtoms.coords
        mobCoords = mobAtoms.coords
        
        self.rigidfitAligner.setRefCoords(refCoords)

        # Nothing can be done if the two sets of coords are not of the same
        # size
        if not len(refCoords) == len(mobCoords):
            print " ERROR: Cannot perform the superimposition because the 2 \
            mv.lsets of Atoms are not of the same length"
            return

        # Get the rotation and the translation ysing mglutil.math.rigidFit
        self.rigidfitAligner.rigidFit(mobCoords)
        #rotation, translation= rigidFit.rigid_fit( refCoords, inCoords)
        rotMat =  Numeric.identity(4).astype('f')
        rotMat[:3,:3] = self.rigidfitAligner.rotationMatrix
        rotMat = Numeric.reshape(rotMat, (16,))
        transMat = Numeric.array(self.rigidfitAligner.translationMatrix)
        
        # transform the geometry representing the atoms only if a gui has been
        # created:
        #if not self.vf.hasGui:
        #    return

        # Transform the mob geometry
        mobMol = mobAtoms.top.uniq()[0]
        mob = mobMol.geomContainer.masterGeom
        self.vf.transformObject('rotation', mob.fullName, matrix=tuple(rotMat))
        self.vf.transformObject('translation', mob.fullName, matrix=tuple(transMat))
Exemple #48
0
 def sartran(self, rho, x, force=0, precis=DELTA):
     n = len(x)
     listflag = 0
     if type(x) == list:
         x = Numeric.array(x, Numeric.Float)
         listflag = 1
     sarx = Numeric.zeros(n, Numeric.Float)
     if n > WT_SMALL or force:
         sarx = x
         wx = self.splag(x) * rho
         sarx += wx
         while max(wx) > precis:
             wx = self.splag(wx) * rho
             sarx += wx
     else:  # small weights full matrix inverse
         w = self.wt2mat()
         w *= -rho
         w += Numeric.identity(n)
         wx = LinearAlgebra.inverse(w)
         sarx = Numeric.matrixmultiply(wx, x)
     if listflag:
         return sarx.tolist()
     else:
         return sarx
Exemple #49
0
def translate(txyz):
    ret = numerix.identity(4).astype(numerix.Float)
    ret[0:len(txyz), 3] = txyz
    return ret
Exemple #50
0
    def AddGrid3D(self, grid):
        assert isinstance(grid, Grid3DUC)

        if not self.volrenInitialized:
            if not self.viewer:  # we need an OpenGL context before
                print "self.viewer: ", self.viewer
                return  # we can initialize the renderer
            self.InitVolumeRenderer()
            for c in self.viewer.cameras:
                c.addButtonDownCB(self.coarseRendering)
                c.addButtonUpCB(self.fineRendering)

        orig = grid.origin[:]
        step = grid.stepSize

        nx, ny, nz = grid.data.shape
        gridSize = [nx * step[0], ny * step[1], nz * step[2]]
        gridSize2 = [gridSize[0] * 0.5, gridSize[1] * 0.5, gridSize[2] * 0.5]
        maxgrid = [
            orig[0] + gridSize[0], orig[1] + gridSize[1], orig[2] + gridSize[2]
        ]
        transl = [
            orig[0] + gridSize2[0], orig[1] + gridSize2[1],
            orig[2] + gridSize2[2]
        ]

        # save scale and tranlation into Matrix which is not affected
        # by reset
        if grid.crystal:
            # compute cartesian voxel sizes
            x, y, z = grid.getStepSizeReal()

            #build crystal object for length with padding
            from mglutil.math.crystal import Crystal
            if hasattr(grid, 'dataDims'):
                # compute ratios of padding along the 3 dimensions
                dx = grid.dimensions[0] - grid.dataDims[0] - 1
                dy = grid.dimensions[1] - grid.dataDims[1] - 1
                dz = grid.dimensions[2] - grid.dataDims[2] - 1
                ry = float(dx) / dy
                rz = float(dx) / dz
            else:
                ry = rz = 1.0

            dims = (grid.dimensions[0] - 1, (grid.dimensions[1] - 1) * ry,
                    (grid.dimensions[2] - 1) * rz)
            cryst = Crystal((dims[0] * x, dims[1] * y, dims[2] * z),
                            grid.crystal.angles)

            matrix = Numeric.identity(4, 'f')
            matrix[:3, :3] = cryst.ftoc.astype('f')
            matrix.shape = (16, )

            # cleanup=False because rotation can contain shear which should
            # be kept
            self.MatrixRot, MatrixTransl, self.MatrixScale = self.Decompose4x4(
                matrix, cleanup=False)

            # set utvolgeom's Matrix components
            self.MatrixScale = (self.MatrixScale[0], self.MatrixScale[1] / ry,
                                self.MatrixScale[2] / rz)

            origin = grid.crystal.toCartesian(grid.origin)
            self.MatrixTransl = (origin[0] + MatrixTransl[0] +
                                 dims[0] * 0.5 * x, origin[1] +
                                 MatrixTransl[1] + dims[1] * 0.5 * y / ry,
                                 origin[2] + MatrixTransl[2] +
                                 dims[2] * 0.5 * z / rz)
            #o = grid.origin
            #t1 = cryst.toFractional(MatrixTransl)
            #t2 = (0.5, 0.5, 0.5)
            #trans = ( o[0]+t1[0]+t2[0], o[1]+t1[1]+t2[1],o[2]+t1[2]+t2[2])
            #self.MatrixTransl = cryst.toCartesian(trans)
            #print o
            #print t1
            #print t2
            #print trans
            #print self.MatrixTransl

            #self.MatrixTransl = (0.,0.,0.)
            #self.MatrixScale = (1.,1.,1.)

            RotInv = Numeric.transpose(Numeric.reshape(self.MatrixRot, (4, 4)))
            self.MatrixRotInv = Numeric.reshape(RotInv, (16, ))
            #
            self.MatrixRot = self.MatrixRot.astype('f')
            self.MatrixRotInv = self.MatrixRot.astype('f')

        else:
            self.setMatrixComponents(trans=transl)
            self.setMatrixComponents(scale=gridSize, trans=transl)

        if self.firstLoaded:
            if self.viewer:
                rootObject = self.viewer.rootObject
                self.minBB = [-0.5, -0.5, -0.5]
                self.maxBB = [0.5, 0.5, 0.5]
                #print "all objects:", self.viewer.rootObject.AllObjects()
                self.viewer.NormalizeCurrentObject()
                self.firstLoaded = 0

# scale and translate volume
##self.SetScale( gridSize)
##trans = Numeric.array( gridSize2, 'f')
##self.SetTranslation( trans )

#mat = self.GetMatrix(self)
#self.SetMatrix(mat)
#self.ResetTransformation()

        arr = Numeric.ascontiguousarray(Numeric.transpose(grid.data),
                                        grid.data.dtype.char)
        upload = self.volume.uploadColorMappedData
        status = upload(arr.ravel(), nx, ny, nz)
        if status != 1:
            raise RuntimeError(
                "uploadColorMappedData() in AddVolume failed. Status %d" %
                status)

        self.dataArr = Numeric.reshape(arr, (nz, ny, nx))
        self.volumeSize = (nx, ny, nz)
        if self.byte_map == None:
            self.grayRamp()

# update cropping box
        self.crop.updateData()
        self.cropBox.setVolSize((nx, ny, nz))
        self.cropBox.xmin = 0
        self.cropBox.xmax = nx
        self.cropBox.ymin = 0
        self.cropBox.ymax = ny
        self.cropBox.zmin = 0
        self.cropBox.zmax = nz
        self.cropBox.update()
        for c in self.onaddVolume_list:
            c.OnAddVolumeToViewer()
    def doit(self, refAtoms, mobAtoms):
        """
        The SuperImposeAtomsCommand takes two set of Atoms of the same length
        compute the rotation and translation matrices to superimpose the
        mobAtoms onto the refAtoms using rigidFit module and then transform the
        corresponding geometry.
        """

        refCoords = refAtoms.coords
        mobCoords = mobAtoms.coords

        self.rigidfitAligner.setRefCoords(refCoords)

        # Nothing can be done if the two sets of coords are not of the same
        # size
        if not len(refCoords) == len(mobCoords):
            print " ERROR: Cannot perform the superimposition because the 2 \
            mv.lsets of Atoms are not of the same length"

            return

        # Get the rotation and the translation ysing mglutil.math.rigidFit
        self.rigidfitAligner.rigidFit(mobCoords)
        #rotation, translation= rigidFit.rigid_fit( refCoords, inCoords)
        rotMat = Numeric.identity(4).astype('d')
        rotMat[:3, :3] = self.rigidfitAligner.rotationMatrix

        transMat = Numeric.array(self.rigidfitAligner.translationMatrix)

        # transform the geometry representing the atoms only if a gui has been
        # created:
        #if not self.vf.hasGui:
        #    return

        # build the geometry name:
        mobMol = mobAtoms.top.uniq()[0]
        mob = mobMol.geomContainer.masterGeom
        #gName = 'root|'+ mobMol[0].name
        if not self.vf.hasGui:
            vi = self.vf.GUI.VIEWER
            oldCurrent = vi.currentObject
            vi.SetCurrentObject(mob)

            # transform only the given geometry.
            if vi.redirectTransformToRoot == 1:
                old = vi.redirectTransformToRoot
                vi.TransformRootOnly(0)
            else:
                old = 0

        # apply the rotation to the masterGeom of the inMol
        mob.SetRotation(Numeric.reshape(rotMat, (16, )))
        # apply the translation to the masterGeom of the inMol
        mob.SetTranslation(transMat)

        ##         refMol = refAtoms.top.uniq()[0]
        ##         refmg = refMol.geomContainer.masterGeom

        ##         refmg = refAtoms.top.uniq()[0].geomContainer.masterGeom
        ##         mat = refmg.GetMatrix(refmg)
        ##         tmat = Numeric.transpose(mat)

        ##         rot, trans, scale = refmg.Decompose4x4(Numeric.reshape(tmat, (16,)))
        ##         rot_1 = refmg.rotation
        ##         trans_1 = refmg.translation
        ##         print 'rot',rot
        ##         print 'trans',trans
        ##         print 'rot_1',rot_1
        ##         print 'trans_1',trans_1

        ##         mobPivot = list(mob.pivot)
        ##         mobPivot.append(1.)
        ##         transfo = Numeric.identity(4).astype('d')
        ##         transfo[:3,:3] = rotMat[:3,:3]
        ##         transfo[3, :3] = transMat
        ##         hc = Numeric.array(mobPivot)
        ##         tPivot = Numeric.dot(hc, transfo)
        ##         print tPivot[:3]
        ##         mob.SetPivot(tPivot[:3])

        #self.vf.centerOnNodes(refMol)
        #mob.ConcatRotationRelative(Numeric.reshape(rot, (16,)))
        #mob.ConcatTranslation(trans_1)

        if not self.vf.hasGui:
            if old == 1:
                vi.TransformRootOnly(1)
            vi.SetCurrentObject(oldCurrent)
Exemple #52
0
    def Set(self, **kw):
        """Set various clipping plane parameters"""

        self.hasBeenCurrent = True  # remember the light has been changed

        tagModified = True
        val = getkw(kw, 'tagModified')
        if val is not None:
            tagModified = val
        assert tagModified in [True, False]
        self._modified = tagModified

        val = getkw(kw, 'enabled')
        if not val is None:
            if val is True:
                self._Enable(1)
            elif val is False:
                self._Disable()
            else:
                raise AttributeError('enable can only be True or False')
            self.enabled = val

        val = getkw(kw, 'name')
        if not val is None: self.name = val

        val = getkw(kw, 'visible')
        if not val is None:
            if val in [False, True]:
                self.visible = val
            else:
                raise AttributeError('visible can only be 0 or 1')

        val = getkw(kw, 'color')
        if not val is None:
            col = OneColor(val)
            if col:
                self.color = col

        val = getkw(kw, 'lineWidth')
        if not val is None:
            try:
                int(val)
            except:
                raise ValueError('lineWidth must be a positive int')
            if val >= 1:
                self.lineWidth = int(val)
            else:
                raise ValueError('lineWidth must be a positive int')

#	val = getkw(kw, 'antialiased')
#	if not val is None:
#	    if val in (True, False) :
#		self.antialiased = val
#	    else: raise ValueError ('antialiased can only be YES or NO')

        val = getkw(kw, 'rotation')
        if not val is None:
            self.rotation = Numeric.identity(4, 'f').ravel()
            mat = Numeric.reshape(Numeric.array(val), (16, )).astype('f')
            self.ConcatRotation(mat)

        val = getkw(kw, 'translation')
        if not val is None:
            self.translation = Numeric.zeros((3, ), 'f')
            mat = Numeric.reshape(Numeric.array(val), (3, )).astype('f')
            self.ConcatTranslation(mat)

        val = getkw(kw, 'scale')
        if not val is None:
            self.SetScale(val)

        val = getkw(kw, 'pivot')
        if not val is None:
            self.SetPivot(val)

        if len(kw):
            print 'WARNING1: Keyword(s) %s not used' % kw.keys()

        if self.object.viewer:
            self.object.viewer.objectsNeedingRedo[self.object] = None
            self.object.viewer.Redraw()
Exemple #53
0
    def _orthog(self, length, angles):
        """
           let u be a 3x3 transformation matrix which relates a new cell
           with orthogonal axes of unit dimensions to the original unit
           cell (crystal system).  
            Aug 5, 1991 changed to XPLOR convention was:
            ut[0][0]=as;
            ut[0][1]=0.;
            ut[0][2]=0.;
            ut[1][0]=bs*cosgas;
            ut[1][1]=1./b;
            ut[1][2]= -(1./tan(al))/b;
            ut[2][0]=cs*cosbes;
            ut[2][1]=0.;
            ut[2][2]=1./(c*sin(al));

            June 1, 1996:  Corrected LFT
            The correct orthogonalization matrix for the default
            PDB convention (Cartesion x along A, y in A-B plane,
            and z along c*) is

            1/a   -cos(ga)/(a sin(ga))   as cosbes
             0          1/(b sin(ga))    bs cosals
             0               0              cs

            and the deorthogonalization matrix is

            a   b cos(ga)   c cos(be)
            0   b sin(ga)   -c sin(be) cosals
            0       0         1/cs

            usage:
            xf = x * ut[0][0] + y * ut[0][1] + z * ut[0][2]
            yf = x * ut[1][0] + y * ut[1][1] + z * ut[1][2]
            zf = x * ut[2][0] + y * ut[2][1] + z * ut[2][2]
            """

        from math import pi, cos, sin, sqrt
        degtor=pi/180.
        al=angles[0]*degtor
        be=angles[1]*degtor
        ga=angles[2]*degtor
        vol= length[0]* length[1]* length[2] *sqrt(1.-cos(al)*cos(al)-cos(be)*cos(be)
                          -cos(ga)*cos(ga)+2.*(cos(al)*cos(be)*cos(ga)))
        lAs=(length[1]* length[2]*sin(al))/vol
        bs=(length[0]* length[2]*sin(be))/vol
        cs=(length[0]* length[1]*sin(ga))/vol
        cosals=(cos(be)*cos(ga)-cos(al))/(sin(be)*sin(ga))
        cosbes=(cos(ga)*cos(al)-cos(be))/(sin(ga)*sin(al))
        cosgas=(cos(al)*cos(be)-cos(ga))/(sin(al)*sin(be))

        ut = Numeric.identity(3).astype('f')
        # sabgs1 = sqrt(1.0-cos(al)*cos(al))
        ut[0][0]=1./length[0]
        ut[0][1]= -(cos(ga))/(sin(ga)*length[0])
        # ut[0][2]= -(cos(ga)*sin(be)*cosals + cos(be)*sin(ga))/ */
        #	(sin(be)*sabgs1*sin(ga)*a) */
        ut[0][2]= lAs * cosbes
        ut[1][0]=0.0
        ut[1][1]=1./(sin(ga)*length[1])
        # ut[1][2]=cosals/(sabgs1*sin(ga)*b)
        ut[1][2]= bs * cosals
        ut[2][0]=0.0
        ut[2][1]=0.0
        # ut[2][2]=1.0/(sin(be)*sabgs1*c)
        ut[2][2]= cs
        return Numeric.transpose(ut)
Exemple #54
0
    def rigidFit(self, mobileCoords):
        """
        the rigidFit method computes the necessary
        transformation matrices to superimpose the list of mobileCoords
        onto the list of referenceCoords, and stores the resulting matrices

        (rot, trans) <- rigidFit(mobileCoords)
        Rigid body fit. Finds transformation (rot,trans) such that
        r.m.s dist(x,rot*y+trans) --> min !
        mobileCoords: cartesian coordinates of mobile structure (3,n) (input)
        rot   : rotation matrix (3,3) (output)
        trans : translation vector (3) (output)
        status: 0 if OK, 1 if singular problem (n<3 ...)

        Method: W.Kabsch, Acta Cryst. (1976). A32,922-923
        W.Kabsch, Acta Cryst. (1978). A34,827-828
        """
        if self.refCoords is None:
            raise RuntimeError(" no reference coordinates specified")

        refCoords = self.refCoords
        if len(refCoords) != len(mobileCoords):
            raise RuntimeError("input vector length mismatch")

        refCoords = Numeric.array(refCoords)
        mobileCoords = Numeric.array(mobileCoords)

        #
        # 1. Compute centroids:
        refCentroid = Numeric.sum(refCoords) / len(refCoords)
        mobileCentroid = Numeric.sum(mobileCoords) / len(mobileCoords)

        #
        # 2. Wolfgang Kabsch's method for rotation matrix rot:
        rot = Numeric.identity(3).astype('f')
        # LOOK how to modify that code.
        for i in xrange(3):
            for j in xrange(3):
                rot[j][i] = Numeric.sum(
                    (refCoords[:, i] - refCentroid[i]) *
                    (mobileCoords[:, j] - mobileCentroid[j]))

        rotTransposed = Numeric.transpose(rot)
        e = Numeric.dot(rot, rotTransposed)

        evals, evecs = LinearAlgebra.eigenvectors(e)

        ev = Numeric.identity(3).astype('d')
        # set ev[0] to be the evec or the largest eigenvalue
        # and ev[1] to be the evec or the second largest eigenvalue
        eigenValues = list(evals)
        discard = eigenValues.index(min(eigenValues))
        i = j = 0
        while i < 3:
            if i == discard:
                i = i + 1
                continue
            ev[j] = evecs[i]
            j = j + 1
            i = i + 1
        evecs = ev

        evecs[2][0] = evecs[0][1] * evecs[1][2] - evecs[0][2] * evecs[1][1]
        evecs[2][1] = evecs[0][2] * evecs[1][0] - evecs[0][0] * evecs[1][2]
        evecs[2][2] = evecs[0][0] * evecs[1][1] - evecs[0][1] * evecs[1][0]

        b = Numeric.dot(evecs, rot)

        norm = math.sqrt(b[0][0] * b[0][0] + b[0][1] * b[0][1] +
                         b[0][2] * b[0][2])
        if math.fabs(norm) < 1.0e-20: return -1, -1
        b[0] = b[0] / norm

        norm = math.sqrt(b[1][0] * b[1][0] + b[1][1] * b[1][1] +
                         b[1][2] * b[1][2])
        if math.fabs(norm) < 1.0e-20: return -1, -1
        b[1] = b[1] / norm

        # vvmult(b[0],b[1],b[2])
        b[2][0] = b[0][1] * b[1][2] - b[0][2] * b[1][1]
        b[2][1] = b[0][2] * b[1][0] - b[0][0] * b[1][2]
        b[2][2] = b[0][0] * b[1][1] - b[0][1] * b[1][0]
        # mtrans3(e)
        e = evecs
        tempo = e[0][1]
        e[0][1] = e[1][0]
        e[1][0] = tempo
        tempo = e[0][2]
        e[0][2] = e[2][0]
        e[2][0] = tempo
        tempo = e[1][2]
        e[1][2] = e[2][1]
        e[2][1] = tempo
        # mmmult3(b,e,rot)
        rot[0][0] = b[0][0] * e[0][0] + b[1][0] * e[0][1] + b[2][0] * e[0][2]
        rot[0][1] = b[0][1] * e[0][0] + b[1][1] * e[0][1] + b[2][1] * e[0][2]
        rot[0][2] = b[0][2] * e[0][0] + b[1][2] * e[0][1] + b[2][2] * e[0][2]

        rot[1][0] = b[0][0] * e[1][0] + b[1][0] * e[1][1] + b[2][0] * e[1][2]
        rot[1][1] = b[0][1] * e[1][0] + b[1][1] * e[1][1] + b[2][1] * e[1][2]
        rot[1][2] = b[0][2] * e[1][0] + b[1][2] * e[1][1] + b[2][2] * e[1][2]

        rot[2][0] = b[0][0] * e[2][0] + b[1][0] * e[2][1] + b[2][0] * e[2][2]
        rot[2][1] = b[0][1] * e[2][0] + b[1][1] * e[2][1] + b[2][1] * e[2][2]
        rot[2][2] = b[0][2] * e[2][0] + b[1][2] * e[2][1] + b[2][2] * e[2][2]

        #
        # Compute translation vector trans:
        # mvmult3(rot,cy,cy);
        trans3 = [0, 0, 0]
        for i in range(3):
            trans3[i] = mobileCentroid[0]*rot[0][i] + mobileCentroid[1]*rot[1][i] + \
                        mobileCentroid[2]*rot[2][i]

        #bcopy(t3,cy,sizeof(t3));
        #vvdiff(cx,cy,trans);
        trans = (refCentroid[0] - trans3[0], refCentroid[1] - trans3[1],
                 refCentroid[2] - trans3[2])
        #
        #   That's it...

        self.rotationMatrix = rot
        self.translationMatrix = trans
        self.superimposed = 1