Hi, 

I understood the question a little differently than Andreas, and I have a
different answer to you. 

If what you want to do is to be able to define your own x, y and z axis and
rotate about them, I can help you. I've made a script that will make a
transformation matrix that can be input to transform_selection().  This will
enable you to choose the x, y and z axis yourself, and after you've performed
transform_selection(), you can rotete about your newly defined x, y and z axis
using the rotate command as you would normally do. 

I'm including the script along with an example of a run here, so you can see how
it works. 

Basically, you have to choose three atoms, given with a selection string each,
and these three atoms will form a 2D plane. From the unit vectors the z axis can
also be computed, and thus a transformation matrix can be generated. 

Note that transform_selection() is currently unsupported, so I don't know if
this script will work through newer versions of Pymol. Also, I made this script
purely for myself, so it doesn't contain alot of error checking :) 

Hope this helps! 

Example of usage: 

PyMOL>import coordinateOperations
PyMOL>a =  "r. CLA and i. 612 and n. C1B"
PyMOL>b =  "r. CLA and i. 612 and n. CHA"
PyMOL>c =  "r. CLA and i. 612 and n. C4C"
PyMOL>matrix = coordinateOperations.getTransformationMatrix(a, b, c)
PyMOL>m_list = coordinateOperations.listOfTransformationMatrix(matrix)
PyMOL>cmd.transform_selection("all", m_list)

Cheers, 
Siv

On 2007-06-24 16:07:00, Andreas Henschel wrote:

> you define a rotation axis by the rotation axis x, y or z (first 
> argument in cmd.rotate) and a point in 3d (origin argument in cmd.rotate).
> Instead of rotations around axes that are not parallel to the x, y or z 
> axis you can do composite rotations.
> 
> Btw, for the case of GroEL (PDB 2c7e), the structure is oriented along 
> the Z axis, so you can flap the flexible regions with a single rotation 
> around the axis that goes through the regions center of mass and is 
> parallel to the z-axis.
> See the attached file.
> 
> repeat the last rotate command from the gray window
> cmd.rotate("z", 30, "flexregion", camera=0, origin=rotationCenter)
> 
> Minh Nhat wrote:
> >Hi everyone,
> >Is it possible to make a selection rotate about an arbitrary axis 
> >(which we can actively define ourself (not x,y, z) ?)
> >Thanks,
> >
> >Send instant messages to your online friends 
> >http://uk.messenger.yahoo.com
> >
> >------------------------------------------------------------------------
> >
> >-------------------------------------------------------------------------
> >This SF.net email is sponsored by DB2 Express
> >Download DB2 Express C - the FREE version of DB2 express and take
> >control of your XML. No limits. Just data. Click to get it now.
> >http://sourceforge.net/powerbar/db2/
> >------------------------------------------------------------------------
> >
> >_______________________________________________
> >PyMOL-users mailing list
> >PyMOL-users@lists.sourceforge.net
> >https://lists.sourceforge.net/lists/listinfo/pymol-users
> >  
> 
> -- 
> Andreas Henschel
> Bioinformatics Group
> TU Dresden
> Tatzberg 47-51
> 01307 Dresden, Germany
> 
> Phone: +49 351 463 40063
> EMail: a...@biotec.tu-dresden.de
> 
> 


> -------------------------------------------------------------------------
> This SF.net email is sponsored by DB2 Express
> Download DB2 Express C - the FREE version of DB2 express and take
> control of your XML. No limits. Just data. Click to get it now.
> http://sourceforge.net/powerbar/db2/
> _______________________________________________
> PyMOL-users mailing list
> PyMOL-users@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/pymol-users


-- 
Siv Midtun Hollup 
PhD Student
Dept. of Informatics
University of Bergen, Norway
s...@ii.uib.no (NOTE: new email adress)
- Blessed are the flexible, for they can be tied into knots. -
import Numeric
import LinearAlgebra
import math
from pymol import cmd


#Must have a single atom as input
def findAtomFromSelection(sel):
    model = cmd.get_model(sel)
    a = Numeric.array(model.atom[0].coord)
    return a

def getTransformationMatrix(a_sel, b_sel, c_sel):
    a_orig = findAtomFromSelection(a_sel)
    b_orig = findAtomFromSelection(b_sel)
    c_orig = findAtomFromSelection(c_sel)

    a = Numeric.zeros(3, 'f')
    b = Numeric.zeros(3, 'f')
    c = Numeric.zeros(3, 'f')
    matrix = Numeric.zeros((4, 4), 'f')
    transformToOrigo(a_orig, b_orig, c_orig, a, b, c, matrix)
    matrix_t = LinearAlgebra.inverse(matrix)
    return matrix_t

def listOfTransformationMatrix(matrix):
    list = []
    list.append(matrix[0,0])
    list.append(matrix[0,1])
    list.append(matrix[0,2])
    list.append(matrix[0,3])
    list.append(matrix[1,0])
    list.append(matrix[1,1])
    list.append(matrix[1,2])
    list.append(matrix[1,3])
    list.append(matrix[2,0])
    list.append(matrix[2,1])
    list.append(matrix[2,2])
    list.append(matrix[2,3])
    list.append(matrix[3,0])
    list.append(matrix[3,1])
    list.append(matrix[3,2])
    list.append(matrix[3,3])
    return list


#Computes euclidian distance between two points in three dimensions
def euclidianDistance(a, b):
    try:
        assert len(a) is 3
        assert len(b) is 3

        return (math.sqrt((a[0]-b[0])**2 + (a[1]-b[1])**2 + (a[2]-b[2])**2))
    except AssertionError:
        print 'euclidianDistance: a or b is not of three dimensions.'
        sys.exit(1)

def cross(v, w):
    try:
        assert len(v) is 3
        assert len(w) is 3
        cross = Numeric.array([0.0, 0.0, 0.0])

        cross[0] = v[1]*w[2] - v[2]*w[1]
        cross[1] = v[2]*w[0] - v[0]*w[2]
        cross[2] = v[0]*w[1] - v[1]*w[0]
        return cross

    except AssertionError:
        print 'cross: input vectors are not of dimension 3'
        sys.exit(1)


#a, b and c-orig are coordinates, a, b and c coordinates, trans_matrix 4*4 
float matrix
#all of them Numeric.array
def transformToOrigo(a_orig, b_orig, c_orig, a, b, c, trans_matrix):

    bx = 0.0
    by = 0.0

    #Vectors
    ab = Numeric.array([(b_orig[0]-a_orig[0]), (b_orig[1]-a_orig[1]), 
(b_orig[2]-a_orig[2])])
    ac = Numeric.array([(c_orig[0]-a_orig[0]), (c_orig[1]-a_orig[1]), 
(c_orig[2]-a_orig[2])])
    bc = Numeric.array([(c_orig[0]-b_orig[0]), (c_orig[1]-b_orig[1]), 
(c_orig[2]-b_orig[2])])

    #Vector lengths
    ab_length = euclidianDistance(a_orig, b_orig)
    ac_length = euclidianDistance(a_orig, c_orig)
    bc_length = euclidianDistance(b_orig, c_orig)

    #Unit vectors
    x_unit = Numeric.zeros(3, 'f')
    y_unit = Numeric.zeros(3, 'f')
    z_unit = Numeric.zeros(3, 'f')

    #Final new coordinate for c
    c[0] = ac_length

    #Unit vector for x plane
    x_unit = ac/ac_length

    alpha = math.degrees(math.acos(Numeric.dot(ab, ac)/(ab_length*ac_length)))
    bx = ab_length*math.cos(math.radians(alpha))
    by = math.sin(math.radians(alpha))*ab_length
    #Final new coordinates for b
    b[0] = bx
    b[1] = by

    #Unit vector for y plane
    y_unit = (ab - (bx*x_unit))/by

    #Unit vector for z plane
    z_unit = cross(x_unit, y_unit)

    trans_matrix[0][0] = x_unit[0]
    trans_matrix[1][0] = x_unit[1]
    trans_matrix[2][0] = x_unit[2]
    trans_matrix[3][0] = 0.0

    trans_matrix[0][1] = y_unit[0]
    trans_matrix[1][1] = y_unit[1]
    trans_matrix[2][1] = y_unit[2]
    trans_matrix[3][1] = 0.0

    trans_matrix[0][2] = z_unit[0]
    trans_matrix[1][2] = z_unit[1]
    trans_matrix[2][2] = z_unit[2]
    trans_matrix[3][2] = 0.0

    trans_matrix[0][3] = a_orig[0]
    trans_matrix[1][3] = a_orig[1]
    trans_matrix[2][3] = a_orig[2]
    trans_matrix[3][3] = 1.0


def transformCoordinate(coord, trans_matrix):
    c = Numeric.array([coord[0], coord[1], coord[2], 1], 'f')
    return Numeric.matrixmultiply(trans_matrix, c)

Reply via email to