[MMTK] Controlling orientation of two molecules

Konrad Hinsen research at khinsen.fastmail.net
Mon Oct 12 10:02:47 UTC 2009

On 12.10.2009, at 10:33, Kamilla Kopec wrote:

> I am trying to build a  universe consisting of  an indole ring and a  
> water molecule.  I have managed to do this by adding indole to the  
> molecule database and using universe.addObject(Molecule(indole)) and  
> universe.addObject(Molecule(water)) to create the required objects.

For 3-4 hours of experience, that's pretty good :-)

> Instead, I would like to control the relative position of the two:  
> placing the water molecule at a specific position relative the N-H  
> group of the indole ring. In the script that I am writing I need to  
> place the water molecule in the same plane as the N-H group as shown  
> below and then move it away from the N-H moeity in 0.1 Ang  
> increments by extending/shorting the H...O distance.

The N-H group is linear, so it doesn't specify a plane. You need one  
more atom of your indole for that. Moreover, the alignment of the two  
planes does not fully specify the relative orientations of the two  
molecules: you can rotate the water molecule in its plane by any angle  
and still maintain the two molecules in the same plane.

One way to align the two planes is:

1) Define the normal vector of the water plane.
2) Define the normal vector of the N-H-xx plane.
3) Define a rotation that aligns the two normal vectors.
4) Apply that rotation to the water molecule.

Assuming you have

	water = Molecule('water')
	indole = Molecule('indole')

you'd get the normal vector of the water plane by

	OH1 = universe.distanceVector(water.O, water.H1)
	OH2 = universe.distanceVector(water.O, water.H2)
	normal_water = OH1.cross(OH2).normal()

A similar procedure will get you normal_indole from the three atoms in  
the indole molecule. The rotation that makes normal_water align with  
normal_indole is then given by

	from Scientific.Geometry.Transformation import Rotation
	axis = normal_water.cross(normal_indole).normal()
	angle = normal_water.angle(normal_indole)
	rotation = Rotation(axis, angle)

and you can apply it to the water molecule using


For the second part of your problem (changing the distance), you could  
use the same approach of constructing a transformation object and  
applying it as often as you need:

	from Scientific.Geometry.Transformation import Translation
	direction = universe.distanceVector(indole.N, indole.H).normal()
	t = Translation(0.1*Units.Ang*direction)

	for i in range(10):

As so often, there are other ways to obtain the same results, so take  
these code lines as suggestions rather than authoritative solutions!

Konrad Hinsen
Centre de Biophysique Moléculaire, CNRS Orléans
Synchrotron Soleil - Division Expériences
Saint Aubin - BP 48
91192 Gif sur Yvette Cedex, France
Tel. +33-1 69 35 97 15
E-Mail: research at khinsen dot fastmail dot net

More information about the mmtk mailing list