Hi Tom, hi Eric,
thanks a lot for answering my previous question so comprehensively! Hope it's OK to bother you again. This is about something completely unrelated.
I would like to apply a transformation (rotation plus translation) to an atomic model. I need to change the coordinates of the model relative to the overall coordinate system. Changing the scene or camera coordinates is not an option, since in the end I want to place multiple copies of my model (in this case a nucleosome) in a specific orientation relative to each other (i.e. within the same coordinate system) to model an array of nucleosomes.
If I remember correctly, back in Chimera this could be achieved with "model.openState.global/localXform(transformation)" where transformation was an chimera.Xform object. But as far as I can see this is not supported in chimeraX.
Here is a reproducible example of the simplest case, in which I define the center and two (roughly) orthogonal axes of my atomic model (i.e. the normal of the DNA superhelix and the dyad axis) and try to map those onto the origin of the coordinate system and two unit vectors.
"""
from chimerax.core.commands import run
import numpy as np
from numpy import cross, dot
np.set_printoptions(suppress = True)
run (session, 'close session')
run (session, 'windowsize 360 360')
target_centre = np.array((0, 0, 0))
target_normal = np.array((0, 1, 0))
target_dyad = np.array((0, 0, 1))
target_3rd_axis = cross(target_normal, target_dyad)
run (session, 'open 3lz0 name 3lz0')
pdb3lz0_DNA_plane = run (session, 'define plane #1/I,J:-56-56')
pdb3lz0_DNA_centre = run (session, 'define centroid #1/I,J:-56-56')
pdb3lz0_dyad_base_pair = run (session, 'define centroid #1/I,J:0')
pdb3lz0_dyad_axis = run (session, 'define axis #1.4 #1.5')
pdb3lz0_centre = session.models[3].xform_center
pdb3lz0_normal = session.models[3].xform_normal
pdb3lz0_dyad = session.models[6].xform_direction
pdb3lz0_3rd_axis = cross(pdb3lz0_normal, pdb3lz0_dyad)
rotation_inverse = np.c_[pdb3lz0_3rd_axis, pdb3lz0_normal, pdb3lz0_dyad]
rotation = np.linalg.inv(rotation_inverse)
translation = -pdb3lz0_centre
transformation = np.c_[rotation, translation]
print(session.models[0].position.matrix)
"""
At this point I have tried to modify the position.matrix with
"session.models[0].position.matrix = transformation"
but this gives me an "AttributeError: property 'matrix' of 'Place' object has no setter".
I'm sure there must be a way to transform an atomic model in this way and would be really grateful for your help.
Thanks a lot in advance,
Maik