/* $Revision$ $Author$ $Date$ * * Copyright (C) 2005-2007 Violeta Labarta <vlabarta@users.sf.net> * * Contact: cdk-devel@lists.sourceforge.net * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2.1 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ package org.openscience.cdk.modeling.forcefield; import org.openscience.cdk.interfaces.IAtom; import org.openscience.cdk.interfaces.IAtomContainer; import javax.vecmath.GVector; import javax.vecmath.Point3d; import javax.vecmath.Vector3d; import java.util.Vector; /** * To work with the coordinates of the molecule, like get the 3d coordinates of * the atoms or calculate the distance between two atoms. * * @author vlabarta * @cdk.githash * @cdk.created 2005-03-03 */ public abstract class ForceFieldTools { static Vector3d xji = null; static Vector3d xjk = null; static Vector3d xlk = null; static Vector3d v1 = null; static Vector3d v2 = null; static Point3d atomiCoordinates = new Point3d(); static Point3d atomjCoordinates = new Point3d(); static Point3d atomkCoordinates = new Point3d(); static Point3d atomlCoordinates = new Point3d(); static Point3d atom1Coordinates = new Point3d(); static Point3d atom2Coordinates = new Point3d(); /** * Get the coordinates 3xN vector of a molecule of N atoms from its atom * container * *@param molecule molecule store in an AtomContainer *@return GVector with 3xN coordinates (N: atom numbers) */ public static GVector getCoordinates3xNVector(IAtomContainer molecule) { //logger.debug("molecule: " + molecule.toString()); //logger.debug("Atoms number = " + molecule.getAtomCount()); GVector coords3d_0 = new GVector(3 * (molecule.getAtomCount())); //logger.debug("coords3d_0 = " + coords3d_0); int j; for (int i = 0; i < molecule.getAtomCount(); i++) { //logger.debug("thisAtom = " + thisAtom); //logger.debug("thisAtom.getPoint3d() = " + thisAtom.getPoint3d()); j = 3 * i; coords3d_0.setElement(j, molecule.getAtom(i).getPoint3d().x); coords3d_0.setElement(j + 1, molecule.getAtom(i).getPoint3d().y); coords3d_0.setElement(j + 2, molecule.getAtom(i).getPoint3d().z); } //logger.debug("Atoms coordinates vector: " + coords3d_0); return coords3d_0; } /** * Get the set of N coordinates 3d of a molecule of N atoms from its atom * container * *@param molecule molecule store in an AtomContainer *@return Vector with the N coordinates 3d of a molecule of N atoms */ public static Vector getPoint3dCoordinates(IAtomContainer molecule) { //logger.debug("molecule: " + molecule.toString()); //logger.debug("Atoms number = " + molecule.getAtomCount()); Vector point3dCoordinates = new Vector(); for (int i = 0; i < molecule.getAtomCount(); i++) { //logger.debug("thisAtom = " + thisAtom); //logger.debug("thisAtom.getPoint3d() = " + thisAtom.getPoint3d()); point3dCoordinates.add(new Point3d(molecule.getAtom(i).getPoint3d())); //Point3d ia = (Point3d)point3dCoordinates.get(i); //logger.debug(i + "a = " + ia); } //logger.debug("Atoms 3d coordinates : " + point3dCoordinates); return point3dCoordinates; } /** * Calculate 3d distance between two atoms coordinates * *@param atom1 First atom. *@param atom2 Second atom. *@return Distance between the two atoms. */ public static double distanceBetweenTwoAtoms(IAtom atom1, IAtom atom2) { atom1Coordinates = atom1.getPoint3d(); atom2Coordinates = atom2.getPoint3d(); double atomsDistance = atom1Coordinates.distance(atom2Coordinates); System.out.println("distanceBetweenTwoAtoms, atomsDistance = " + atomsDistance); return atomsDistance; } /** * Calculate 3d distance between two atoms in one molecule from its 3xN * coordinate vector. * *@param coords3d Molecule 3xN coordinates. *@param atom1Position Atom position in the molecule (from 0 to N-1) for the first atom. *@param atom2Position Atom position in the molecule (from 0 to N-1) for the second atom. *@return Distance between the two atoms. */ public static double distanceBetweenTwoAtomsFrom3xNCoordinates(GVector coords3d, int atom1Position, int atom2Position) { atom1Coordinates.x = coords3d.getElement(3 * atom1Position); atom1Coordinates.y = coords3d.getElement(3 * atom1Position + 1); atom1Coordinates.z = coords3d.getElement(3 * atom1Position + 2); atom2Coordinates.x = coords3d.getElement(3 * atom2Position); atom2Coordinates.y = coords3d.getElement(3 * atom2Position + 1); atom2Coordinates.z = coords3d.getElement(3 * atom2Position + 2); double atomsDistance; atomsDistance = atom1Coordinates.distance(atom2Coordinates); return atomsDistance; } /** * Calculate 3d distance between two atoms in one molecule from its N * coordinates 3d * *@param atoms3dCoordinates Vector with the N coordinates 3d *@param atomNum1 Atom position in the 3xN coordinates vector (from * 0 to N-1) for the first atom. *@param atomNum2 Atom position in the 3xN coordinates vector (from * 0 to N-1) for the second atom. *@return Distance between the two atoms in the molecule. */ public static double distanceBetweenTwoAtomsFromNCoordinates3d(Vector atoms3dCoordinates, int atomNum1, int atomNum2) { Point3d atom13dCoord = (Point3d) atoms3dCoordinates.get(atomNum1); Point3d atom23dCoord = (Point3d) atoms3dCoordinates.get(atomNum2); double atomsDistance; atomsDistance = atom13dCoord.distance(atom23dCoord); //logger.debug("atomsDistance = " + atomsDistance); return atomsDistance; } /** * Assign the 3D coordinates saved in a GVector back to the molecule * *@param moleculeCoords GVector with the coordinates *@param molecule AtomContainer *@return the molecule as AtomContainer */ public static IAtomContainer assignCoordinatesToMolecule(GVector moleculeCoords, IAtomContainer molecule) { for (int i = 0; i < molecule.getAtomCount(); i++) { molecule.getAtom(i).setPoint3d( new Point3d( moleculeCoords.getElement(i * 3), moleculeCoords.getElement(i * 3 + 1), moleculeCoords.getElement(i * 3 + 2) ) ); } return molecule; } /** * Calculate 3d distance between two atoms from two different 3xN coordinate * vectors. * *@param atomsCoordinatesVector1 3xN coordinates from the first molecule. *@param atomsCoordinatesVector2 3xN coordinates from the second molecule. *@param atomNumM1 Atom position in the first molecule. *@param atomNumM2 Atom position in the second molecule. *@return Distance between the two atoms. */ public static double distanceBetweenTwoAtomFromTwo3xNCoordinates(GVector atomsCoordinatesVector1, GVector atomsCoordinatesVector2, int atomNumM1, int atomNumM2) { double atomsDistance = 0; double difference; for (int j = 0; j < 3; j++) { difference = atomsCoordinatesVector1.getElement(atomNumM1 * 3 + j) - atomsCoordinatesVector2.getElement(atomNumM2 * 3 + j); difference = Math.pow(difference, 2); atomsDistance = atomsDistance + difference; } atomsDistance = Math.sqrt(atomsDistance); //logger.debug("atomsDistance = " + atomsDistance); return atomsDistance; } /** * calculates the angle between two bonds, i-j and j-k, given the atoms i,j and k. * *@param atomi Atom i. *@param atomj Atom j. *@param atomk Atom k. *@return Angle value. */ public static double angleBetweenTwoBonds(IAtom atomi, IAtom atomj, IAtom atomk) { Vector3d bondij = new Vector3d(); bondij.sub(atomi.getPoint3d(), atomj.getPoint3d()); Vector3d bondjk = new Vector3d(); bondjk.sub(atomk.getPoint3d(), atomj.getPoint3d()); return Math.toDegrees(bondij.angle(bondjk)); } /** * calculates the angle between two bonds, i-j and j-k, given the 3xN atoms coordinates and the atom i,j and k positions. * *@param coords3d 3xN atoms coordinates. *@param atomiPosition Atom i position. *@param atomjPosition Atom j position. *@param atomkPosition Atom k position. *@return Angle value. */ public static double angleBetweenTwoBondsFrom3xNCoordinates(GVector coords3d,int atomiPosition,int atomjPosition,int atomkPosition) { atomiCoordinates.set(coords3d.getElement(3 * atomiPosition), coords3d.getElement(3 * atomiPosition + 1), coords3d.getElement(3 * atomiPosition + 2)); atomjCoordinates.set(coords3d.getElement(3 * atomjPosition), coords3d.getElement(3 * atomjPosition + 1), coords3d.getElement(3 * atomjPosition + 2)); atomkCoordinates.set(coords3d.getElement(3 * atomkPosition), coords3d.getElement(3 * atomkPosition + 1), coords3d.getElement(3 * atomkPosition + 2)); Vector3d bondij = new Vector3d(); bondij.sub(atomiCoordinates, atomjCoordinates); Vector3d bondjk = new Vector3d(); bondjk.sub(atomkCoordinates, atomjCoordinates); return Math.toDegrees(bondij.angle(bondjk)); } /** * Calculate the torsion angle from 4 atoms i,j,k and l, where i-j, j-k, and * k-l are bonded pairs. * *@param atomi Atom i. *@param atomj Atom j. *@param atomk Atom k. *@param atoml Atom l. *@return Torsion angle value. */ public static double torsionAngle(IAtom atomi, IAtom atomj, IAtom atomk, IAtom atoml) { xji = new Vector3d(atomi.getPoint3d()); xji.sub(atomj.getPoint3d()); xjk = new Vector3d(atomk.getPoint3d()); xjk.sub(atomj.getPoint3d()); xlk = new Vector3d(atomk.getPoint3d()); xlk.sub(atoml.getPoint3d()); v1 = new Vector3d(); // v1 = xji x xjk / |xji x xjk| v1.cross(xji, xjk); v1.normalize(); v2 = new Vector3d(); // v2 = xjk x xlk / |xjk x xlk| v2.cross(xjk, xlk); v2.normalize(); double torsion = v1.dot(v2); //Math.toDegrees(v1.angle(v2)); System.out.println("torsion = " + torsion); return torsion; } /** * Calculate the torsion angle from 4 atoms i,j,k and l positions, where i-j, j-k, and k-l are bonded pairs. * *@param coords3d 3xN atoms coordinates. *@param atomiPosition Atom i position. *@param atomjPosition Atom j position. *@param atomkPosition Atom k position. *@param atomlPosition Atom l position. *@return Torsion angle value. */ public static double torsionAngleFrom3xNCoordinates(GVector coords3d, int atomiPosition, int atomjPosition, int atomkPosition, int atomlPosition) { atomiCoordinates.set(coords3d.getElement(3 * atomiPosition), coords3d.getElement(3 * atomiPosition + 1), coords3d.getElement(3 * atomiPosition + 2)); atomjCoordinates.set(coords3d.getElement(3 * atomjPosition), coords3d.getElement(3 * atomjPosition + 1), coords3d.getElement(3 * atomjPosition + 2)); atomkCoordinates.set(coords3d.getElement(3 * atomkPosition), coords3d.getElement(3 * atomkPosition + 1), coords3d.getElement(3 * atomkPosition + 2)); atomlCoordinates.set(coords3d.getElement(3 * atomlPosition), coords3d.getElement(3 * atomlPosition + 1), coords3d.getElement(3 * atomlPosition + 2)); xji = new Vector3d(atomiCoordinates); xji.sub(atomjCoordinates); xjk = new Vector3d(atomkCoordinates); xjk.sub(atomjCoordinates); xlk = new Vector3d(atomkCoordinates); xlk.sub(atomlCoordinates); v1 = new Vector3d(); // v1 = xji x xjk / |xji x xjk| v1.cross(xji, xjk); v1.normalize(); v2 = new Vector3d(); // v2 = xjk x xlk / |xjk x xlk| v2.cross(xjk, xlk); v2.normalize(); double cosang = v1.dot(v2); if (cosang >1){ cosang = 1; } if (cosang < -1){ cosang=-1; } double torsion = Math.acos(cosang); double dot=xji.dot(v2); double absDot=Math.abs(dot); torsion = (dot/absDot > 0) ? torsion : (2 * Math.PI - torsion); //logger.debug("torsion" + torsion); return torsion; } public static double toDegrees(double angleRad){ return angleRad*180/Math.PI; } }