1
package org.openscience.cdk.modeling.forcefield;
3
import org.openscience.cdk.interfaces.IAtom;
4
import org.openscience.cdk.interfaces.IAtomContainer;
6
import javax.vecmath.GVector;
7
import javax.vecmath.Point3d;
8
import javax.vecmath.Vector3d;
9
import java.util.Vector;
12
* To work with the coordinates of the molecule, like get the 3d coordinates of
13
* the atoms or calculate the distance between two atoms.
16
* @cdk.created 2005-03-03
18
public abstract class ForceFieldTools {
20
static Vector3d xji = null;
21
static Vector3d xjk = null;
22
static Vector3d xlk = null;
23
static Vector3d v1 = null;
24
static Vector3d v2 = null;
26
static Point3d atomiCoordinates = new Point3d();
27
static Point3d atomjCoordinates = new Point3d();
28
static Point3d atomkCoordinates = new Point3d();
29
static Point3d atomlCoordinates = new Point3d();
30
static Point3d atom1Coordinates = new Point3d();
31
static Point3d atom2Coordinates = new Point3d();
36
* Get the coordinates 3xN vector of a molecule of N atoms from its atom
39
*@param molecule molecule store in an AtomContainer
40
*@return GVector with 3xN coordinates (N: atom numbers)
42
public static GVector getCoordinates3xNVector(IAtomContainer molecule) {
44
//logger.debug("molecule: " + molecule.toString());
45
//logger.debug("Atoms number = " + molecule.getAtomCount());
46
GVector coords3d_0 = new GVector(3 * (molecule.getAtomCount()));
47
//logger.debug("coords3d_0 = " + coords3d_0);
51
for (int i = 0; i < molecule.getAtomCount(); i++) {
52
//logger.debug("thisAtom = " + thisAtom);
53
//logger.debug("thisAtom.getPoint3d() = " + thisAtom.getPoint3d());
56
coords3d_0.setElement(j, molecule.getAtom(i).getPoint3d().x);
57
coords3d_0.setElement(j + 1, molecule.getAtom(i).getPoint3d().y);
58
coords3d_0.setElement(j + 2, molecule.getAtom(i).getPoint3d().z);
61
//logger.debug("Atoms coordinates vector: " + coords3d_0);
68
* Get the set of N coordinates 3d of a molecule of N atoms from its atom
71
*@param molecule molecule store in an AtomContainer
72
*@return Vector with the N coordinates 3d of a molecule of N atoms
74
public static Vector getPoint3dCoordinates(IAtomContainer molecule) {
76
//logger.debug("molecule: " + molecule.toString());
77
//logger.debug("Atoms number = " + molecule.getAtomCount());
78
Vector point3dCoordinates = new Vector();
80
for (int i = 0; i < molecule.getAtomCount(); i++) {
81
//logger.debug("thisAtom = " + thisAtom);
82
//logger.debug("thisAtom.getPoint3d() = " + thisAtom.getPoint3d());
84
point3dCoordinates.add(new Point3d(molecule.getAtom(i).getPoint3d()));
85
//Point3d ia = (Point3d)point3dCoordinates.get(i);
86
//logger.debug(i + "a = " + ia);
89
//logger.debug("Atoms 3d coordinates : " + point3dCoordinates);
91
return point3dCoordinates;
96
* Calculate 3d distance between two atoms coordinates
98
*@param atom1 First atom.
99
*@param atom2 Second atom.
100
*@return Distance between the two atoms.
102
public static double distanceBetweenTwoAtoms(IAtom atom1, IAtom atom2) {
104
atom1Coordinates = atom1.getPoint3d();
105
atom2Coordinates = atom2.getPoint3d();
107
double atomsDistance = atom1Coordinates.distance(atom2Coordinates);
109
System.out.println("distanceBetweenTwoAtoms, atomsDistance = " + atomsDistance);
111
return atomsDistance;
116
* Calculate 3d distance between two atoms in one molecule from its 3xN
119
*@param coords3d Molecule 3xN coordinates.
120
*@param atom1Position Atom position in the molecule (from 0 to N-1) for the first atom.
121
*@param atom2Position Atom position in the molecule (from 0 to N-1) for the second atom.
122
*@return Distance between the two atoms.
124
public static double distanceBetweenTwoAtomsFrom3xNCoordinates(GVector coords3d, int atom1Position, int atom2Position) {
126
atom1Coordinates.x = coords3d.getElement(3 * atom1Position);
127
atom1Coordinates.y = coords3d.getElement(3 * atom1Position + 1);
128
atom1Coordinates.z = coords3d.getElement(3 * atom1Position + 2);
129
atom2Coordinates.x = coords3d.getElement(3 * atom2Position);
130
atom2Coordinates.y = coords3d.getElement(3 * atom2Position + 1);
131
atom2Coordinates.z = coords3d.getElement(3 * atom2Position + 2);
133
double atomsDistance;
134
atomsDistance = atom1Coordinates.distance(atom2Coordinates);
136
return atomsDistance;
141
* Calculate 3d distance between two atoms in one molecule from its N
144
*@param atoms3dCoordinates Vector with the N coordinates 3d
145
*@param atomNum1 Atom position in the 3xN coordinates vector (from
146
* 0 to N-1) for the first atom.
147
*@param atomNum2 Atom position in the 3xN coordinates vector (from
148
* 0 to N-1) for the second atom.
149
*@return Distance between the two atoms in the molecule.
151
public static double distanceBetweenTwoAtomsFromNCoordinates3d(Vector atoms3dCoordinates, int atomNum1, int atomNum2) {
153
Point3d atom13dCoord = (Point3d) atoms3dCoordinates.get(atomNum1);
154
Point3d atom23dCoord = (Point3d) atoms3dCoordinates.get(atomNum2);
156
double atomsDistance;
157
atomsDistance = atom13dCoord.distance(atom23dCoord);
158
//logger.debug("atomsDistance = " + atomsDistance);
160
return atomsDistance;
165
* Assign the 3D coordinates saved in a GVector back to the molecule
167
*@param moleculeCoords GVector with the coordinates
168
*@param molecule AtomContainer
169
*@return the molecule as AtomContainer
171
public static IAtomContainer assignCoordinatesToMolecule(GVector moleculeCoords, IAtomContainer molecule) {
172
for (int i = 0; i < molecule.getAtomCount(); i++) {
173
molecule.getAtom(i).setPoint3d(
175
moleculeCoords.getElement(i * 3),
176
moleculeCoords.getElement(i * 3 + 1),
177
moleculeCoords.getElement(i * 3 + 2)
186
* Calculate 3d distance between two atoms from two different 3xN coordinate
189
*@param atomsCoordinatesVector1 3xN coordinates from the first molecule.
190
*@param atomsCoordinatesVector2 3xN coordinates from the second molecule.
191
*@param atomNumM1 Atom position in the first molecule.
192
*@param atomNumM2 Atom position in the second molecule.
193
*@return Distance between the two atoms.
195
public static double distanceBetweenTwoAtomFromTwo3xNCoordinates(GVector atomsCoordinatesVector1, GVector atomsCoordinatesVector2, int atomNumM1, int atomNumM2) {
197
double atomsDistance = 0;
199
for (int j = 0; j < 3; j++) {
200
difference = atomsCoordinatesVector1.getElement(atomNumM1 * 3 + j) - atomsCoordinatesVector2.getElement(atomNumM2 * 3 + j);
201
difference = Math.pow(difference, 2);
202
atomsDistance = atomsDistance + difference;
204
atomsDistance = Math.sqrt(atomsDistance);
205
//logger.debug("atomsDistance = " + atomsDistance);
206
return atomsDistance;
211
* calculates the angle between two bonds, i-j and j-k, given the atoms i,j and k.
213
*@param atomi Atom i.
214
*@param atomj Atom j.
215
*@param atomk Atom k.
216
*@return Angle value.
218
public static double angleBetweenTwoBonds(IAtom atomi, IAtom atomj, IAtom atomk) {
220
Vector3d bondij = new Vector3d();
221
bondij.sub(atomi.getPoint3d(), atomj.getPoint3d());
223
Vector3d bondjk = new Vector3d();
224
bondjk.sub(atomk.getPoint3d(), atomj.getPoint3d());
226
return Math.toDegrees(bondij.angle(bondjk));
230
* calculates the angle between two bonds, i-j and j-k, given the 3xN atoms coordinates and the atom i,j and k positions.
232
*@param coords3d 3xN atoms coordinates.
233
*@param atomiPosition Atom i position.
234
*@param atomjPosition Atom j position.
235
*@param atomkPosition Atom k position.
236
*@return Angle value.
238
public static double angleBetweenTwoBondsFrom3xNCoordinates(GVector coords3d,int atomiPosition,int atomjPosition,int atomkPosition) {
240
atomiCoordinates.set(coords3d.getElement(3 * atomiPosition), coords3d.getElement(3 * atomiPosition + 1), coords3d.getElement(3 * atomiPosition + 2));
241
atomjCoordinates.set(coords3d.getElement(3 * atomjPosition), coords3d.getElement(3 * atomjPosition + 1), coords3d.getElement(3 * atomjPosition + 2));
242
atomkCoordinates.set(coords3d.getElement(3 * atomkPosition), coords3d.getElement(3 * atomkPosition + 1), coords3d.getElement(3 * atomkPosition + 2));
244
Vector3d bondij = new Vector3d();
245
bondij.sub(atomiCoordinates, atomjCoordinates);
247
Vector3d bondjk = new Vector3d();
248
bondjk.sub(atomkCoordinates, atomjCoordinates);
250
return Math.toDegrees(bondij.angle(bondjk));
256
* Calculate the torsion angle from 4 atoms i,j,k and l, where i-j, j-k, and
257
* k-l are bonded pairs.
259
*@param atomi Atom i.
260
*@param atomj Atom j.
261
*@param atomk Atom k.
262
*@param atoml Atom l.
263
*@return Torsion angle value.
265
public static double torsionAngle(IAtom atomi, IAtom atomj, IAtom atomk, IAtom atoml) {
267
xji = new Vector3d(atomi.getPoint3d());
268
xji.sub(atomj.getPoint3d());
269
xjk = new Vector3d(atomk.getPoint3d());
270
xjk.sub(atomj.getPoint3d());
271
xlk = new Vector3d(atomk.getPoint3d());
272
xlk.sub(atoml.getPoint3d());
275
// v1 = xji x xjk / |xji x xjk|
280
// v2 = xjk x xlk / |xjk x xlk|
284
double torsion = v1.dot(v2);
285
//Math.toDegrees(v1.angle(v2));
286
System.out.println("torsion = " + torsion);
293
* Calculate the torsion angle from 4 atoms i,j,k and l positions, where i-j, j-k, and k-l are bonded pairs.
295
*@param coords3d 3xN atoms coordinates.
296
*@param atomiPosition Atom i position.
297
*@param atomjPosition Atom j position.
298
*@param atomkPosition Atom k position.
299
*@param atomlPosition Atom l position.
300
*@return Torsion angle value.
302
public static double torsionAngleFrom3xNCoordinates(GVector coords3d, int atomiPosition, int atomjPosition, int atomkPosition, int atomlPosition) {
304
atomiCoordinates.set(coords3d.getElement(3 * atomiPosition), coords3d.getElement(3 * atomiPosition + 1), coords3d.getElement(3 * atomiPosition + 2));
305
atomjCoordinates.set(coords3d.getElement(3 * atomjPosition), coords3d.getElement(3 * atomjPosition + 1), coords3d.getElement(3 * atomjPosition + 2));
306
atomkCoordinates.set(coords3d.getElement(3 * atomkPosition), coords3d.getElement(3 * atomkPosition + 1), coords3d.getElement(3 * atomkPosition + 2));
307
atomlCoordinates.set(coords3d.getElement(3 * atomlPosition), coords3d.getElement(3 * atomlPosition + 1), coords3d.getElement(3 * atomlPosition + 2));
309
xji = new Vector3d(atomiCoordinates);
310
xji.sub(atomjCoordinates);
311
xjk = new Vector3d(atomkCoordinates);
312
xjk.sub(atomjCoordinates);
313
xlk = new Vector3d(atomkCoordinates);
314
xlk.sub(atomlCoordinates);
316
v1 = new Vector3d(); // v1 = xji x xjk / |xji x xjk|
320
v2 = new Vector3d(); // v2 = xjk x xlk / |xjk x xlk|
324
double cosang = v1.dot(v2);
333
double torsion = Math.acos(cosang);
334
double dot=xji.dot(v2);
335
double absDot=Math.abs(dot);
336
torsion = (dot/absDot > 0) ? torsion : (2 * Math.PI - torsion);
338
//logger.debug("torsion" + torsion);
343
public static double toDegrees(double angleRad){
344
return angleRad*180/Math.PI;