Feature Request: Expose rotation to python

The repr of an xform shows the opengl rotation matrix. I want to get this efficiently in python, but I don't believe it is exposed. Could a getter please be added returning a 4x4 tuple, so a Numeric array can be trivial/efficiently made from it? If there is a current approach please let me know. Thanks, Charlie

Hi Charlie, I second your request for having a Xform.getMatrix() method that provides 3x4 Numeric array or tuple of tuples. I use this a good bit. My solution is to use the Chimera PDBmatrices.matrices module which deals with 3x4 matrices where the first 3 columns are the rotation and the last column is the translation. It's been in Chimera for the last couple years (with ocassional changes). Look at Python code chimera/share/PDBmatrices/matrices.py to see what is there. Example,
xf = chimera.Xform.zRotation(30) from PDBmatrices import matrices m = matrices.xform_matrix(xf) print m ((0.866025, -0.5, 0.0, 0.0), (0.5, 0.866025, 0.0, 0.0), (0.0, 0.0, 1.0, 0.0))
There is a chimera_xform() routine to go from matrix to Xform, and other routines to apply 3x4 matrices to points, or vectors, invert matrices, multiply matrices, .... Tom

Then would this be a practical solution: matrices.xform_matrix(chimera.openModels.list()[0].openState.xform) On 11/28/05, Thomas Goddard <goddard@cgl.ucsf.edu> wrote:
Hi Charlie,
I second your request for having a Xform.getMatrix() method that provides 3x4 Numeric array or tuple of tuples.
I use this a good bit. My solution is to use the Chimera PDBmatrices.matrices module which deals with 3x4 matrices where the first 3 columns are the rotation and the last column is the translation. It's been in Chimera for the last couple years (with ocassional changes).
Look at Python code
chimera/share/PDBmatrices/matrices.py
to see what is there.
Example,
xf = chimera.Xform.zRotation(30) from PDBmatrices import matrices m = matrices.xform_matrix(xf) print m ((0.866025, -0.5, 0.0, 0.0), (0.5, 0.866025, 0.0, 0.0), (0.0, 0.0, 1.0, 0.0))
There is a chimera_xform() routine to go from matrix to Xform, and other routines to apply 3x4 matrices to points, or vectors, invert matrices, multiply matrices, ....
Tom

Hi Charlie, Yeah, you can apply matrices.xform_matrix() to m.openState.xform to get the 3 by 4 matrix. Tom

On Mon, 28 Nov 2005, Charlie Moad wrote:
The repr of an xform shows the opengl rotation matrix. I want to get this efficiently in python, but I don't believe it is exposed. Could a getter please be added returning a 4x4 tuple, so a Numeric array can be trivial/efficiently made from it? If there is a current approach please let me know.
The new and improved method is to use the getCoordFrame method :-) and the coorresponding Xform.coordFrame constructor. I agree that it would be better for Python to have a method that returned a Numeric array. Example: >>> xf = chimera.Xform.zRotation(30) >>> x, y, z, o = xf.getCoordFrame() >>> print "x: %s, y: %s, z: %s, o: %s" % (x, y, z, o) x: 0.866025 0.5 0, y: -0.5 0.866025 0, z: 0 0 1, o: 0 0 0 Using getCoordFrame would simplify PDBmatrices.matrices.xform_matrix to be: rx, ry, rz, t = xform.getCoordFrame() return ((rx[0], ry[0], rz[0], t[0]), (rx[1], ry[1], rz[1], t[1]), (rx[2], ry[2], rz[2], t[2])) You could do something similar to construct a Numeric array. Xforms have improved in the latest release. Now you can easily make copies of matrices using the constructor: xformprime = chimera.Xform(xform) or: import copy xformprime = copy.copy(xform) Type: help(chimera.Xform) to see all of the methods and static methods. Hope this helps, Greg Couch UCSF Computer Graphics Lab gregc@cgl.ucsf.edu

Thanks for all this. It is working great! Now comes the inverse question which should hopefully be easy. How do I apply an xform to a structure to update the viewer? Applying rotations to the model.openState.xform seems to have no effect. I would like to be able to reset to the original view by doing something like, model.openState.xform.multiply(model.openState.xform.inverse()). Thanks, Charlie On 11/28/05, Greg Couch <gregc@cgl.ucsf.edu> wrote:
On Mon, 28 Nov 2005, Charlie Moad wrote:
The repr of an xform shows the opengl rotation matrix. I want to get this efficiently in python, but I don't believe it is exposed. Could a getter please be added returning a 4x4 tuple, so a Numeric array can be trivial/efficiently made from it? If there is a current approach please let me know.
The new and improved method is to use the getCoordFrame method :-) and the coorresponding Xform.coordFrame constructor. I agree that it would be better for Python to have a method that returned a Numeric array.
Example:
>>> xf = chimera.Xform.zRotation(30) >>> x, y, z, o = xf.getCoordFrame() >>> print "x: %s, y: %s, z: %s, o: %s" % (x, y, z, o) x: 0.866025 0.5 0, y: -0.5 0.866025 0, z: 0 0 1, o: 0 0 0
Using getCoordFrame would simplify PDBmatrices.matrices.xform_matrix to be:
rx, ry, rz, t = xform.getCoordFrame() return ((rx[0], ry[0], rz[0], t[0]), (rx[1], ry[1], rz[1], t[1]), (rx[2], ry[2], rz[2], t[2]))
You could do something similar to construct a Numeric array.
Xforms have improved in the latest release. Now you can easily make copies of matrices using the constructor:
xformprime = chimera.Xform(xform)
or:
import copy xformprime = copy.copy(xform)
Type:
help(chimera.Xform)
to see all of the methods and static methods.
Hope this helps,
Greg Couch UCSF Computer Graphics Lab gregc@cgl.ucsf.edu

Hi Charlie, To set a model's transformation to the identity: identity = chimera.Xform() model.openState.xform = identity This may throw the model out of view. To apply a rotation about the z-axis in the model's coordinate system: zrot = chimera.Xform.zRotation(30) # rotation by 30 degrees model.openState.localXform(zrot) To apply a rotation about the screen z-axis: zrot = chimera.Xform.zRotation(30) # rotation by 30 degrees model.openState.globalXform(zrot) The localXform() and globalXform() methods just multiply the current transformation by the given one (on the right or left) and set the model's transformation to the result. The model transformation maps a point in the model coordinate system to the screen coordinate system (x horizontal, y vertical, z out of screen) controlling where the model appears on the screen. When you use localXform(xf) the xf gets applied first, and then the current transformation. When you use globalXform(xf) the current transform is applied first and then xf. Some more examples are given in the Programmer's Guide FAQ: http://www.cgl.ucsf.edu/chimera/docs/ProgrammersGuide/faq.html#q4 Getting the transformation math right can be tricky. Tom

On Nov 29, 2005, at 10:11 AM, Thomas Goddard wrote:
Hi Charlie,
To set a model's transformation to the identity:
identity = chimera.Xform() model.openState.xform = identity
The key thing to realize is that in a statement like: x = model.openState.xform x is now a _copy_ of the transformation matrix -- making changes to this copy doesn't affect the actual transformation matrix. To make the changes take effect you need to: <make changes to x> model.openState.xform = x --Eric Eric Pettersen UCSF Computer Graphics Lab pett@cgl.ucsf.edu http://www.cgl.ucsf.edu
participants (4)
-
Charlie Moad
-
Eric Pettersen
-
Greg Couch
-
Thomas Goddard