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
> >[email protected]
> >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: [email protected]
>
>
> -------------------------------------------------------------------------
> 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
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/pymol-users
--
Siv Midtun Hollup
PhD Student
Dept. of Informatics
University of Bergen, Norway
[email protected] (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)