# Movers for unspecified DoF

3 posts / 0 new
Movers for unspecified DoF
#1

Hello everyone,

I'm fairly new to PyRosetta, but I ran into a strange issue with a custom mover. For a molecule with a non-cannonical backbone, I built a mover which moves specific torsions via the pose.atom_tree().set_torsion_angle() method by picking torsion angles at random and adding a random angle to them (With the hopes of recreating the Small and Shear movers for custom torsion angles). I have succesfully built the mover, however when I apply it to a pose and update the pose in PyMOL, there is no change in the pose's coordinates. Additionally, PyRosetta does not output any errors when I apply my mover. I can also check the torsion I just changed with pose.atom_tree().torsion_angle() and it registers as being changed, but there is no change to the actual coordinates of the pose.

Here's a snippet of my mover:

at = pose.atom_tree()
dihe_start = np.random.randint(0, len(self.atoms)-3)
old = at.torsion_angle(self.atoms[dihe_start], self.atoms[dihe_start+1], self.atoms[dihe_start+2], self.atoms[dihe_start+3])
new = old + d_angle
at.set_torsion_angle(self.atoms[dihe_start], self.atoms[dihe_start+1], self.atoms[dihe_start+2], self.atoms[dihe_start+3], new)



Is there a better way to make a mover for a unspecified torsion angles?  And does anyone have clues as to why I the pose structure isn't being updated?

Thanks a bunch!

Lenny

Category:
Post Situation:
Wed, 2019-04-17 17:30
tfobe

This is one of the big limitations of the PyRosetta interface.

There are certain objects in Rosetta which are read-only. Unfortunately, due to how PyRosetta gets wrapped, that read-only annotation gets dropped, and you can write to things you aren't supposed to. (Which leads to downstream issues.)

Pose.atom_tree() is one of these cases. The object returned from this function is a read only object, and any attempt to modify it may lead to unspecified behavior.

The way to set a torsion on a Pose is the Pose.set_torsion() function. Unfortunately, this has a slightly different interface than the AtomTree.set_torsion_angle() function.  But, the TorsionID should be somewhat straightforward to create (e.g. TorsionID( seqpos, core.id.BB, bb_torsion_no )).

The other thing to keep in mind is that for efficiency Rosetta caches torsion & coordinate updates. If you modify torsions, you might not see the coordinate update in the PyMolMover until you access a function on the Pose which needs updated coordinates (Pose.residue(seqpos) is the typical one for this.)

Thu, 2019-05-09 14:50
rmoretti

Thanks for the response!

I was able to get my backbone moving. The reason I went the atom_tree() route was that I wanted to define specific atoms to move. I tried going the TorsionID() route but wasn't sure how the bb_torsion_no would be defined for my custom backbone (documentation is specific to Phi Psi and Omega angles). Currently, I'm using the Pose().conformation() object to do my specific moves.

For now, my working implementation follows something like this:

1. Define a list of lists of atoms representing each dihedral. [[Atom1, Atom2, Atom3, Atom4], [Atom2, Atom3, Atom4, Atom5]]

2. Initialize those dihedral angles using Pose().conformation().set_torsion(atomID, atomID, atomID, atomID, current_angle)

3. Pick one dihedral at random and perturb it using Pose().conformation().set_torsion()

It's good to know the atom_tree() object is supposed to be read-only. I ran into some strange behavior with it interacting with the ScoreFxn object, probably because it shouldn't have been written to in the first place!

Mon, 2019-05-20 16:05
tfobe