org.xmlcml.cml.tools.TorsionTool Maven / Gradle / Ivy
/**
* Copyright 2011 Peter Murray-Rust et. al.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.xmlcml.cml.tools;
import java.util.List;
import java.util.logging.Logger;
import org.xmlcml.cml.base.AbstractTool;
import org.xmlcml.cml.base.CMLElement.CoordinateType;
import org.xmlcml.cml.element.CMLAtom;
import org.xmlcml.cml.element.CMLAtomSet;
import org.xmlcml.cml.element.CMLMolecule;
import org.xmlcml.cml.element.CMLTorsion;
import org.xmlcml.cml.element.CMLTransform3;
import org.xmlcml.euclid.Angle;
import org.xmlcml.euclid.Point3;
import org.xmlcml.euclid.Transform3;
import org.xmlcml.euclid.Vector3;
/**
* tool for managing torsion
*
* @author pmr
*
*/
public class TorsionTool extends AbstractTool {
final static Logger logger = Logger.getLogger(TorsionTool.class.getName());
CMLTorsion torsion = null;
/** constructor.
* requires molecule to contain and optionally
* @param molecule
* @throws RuntimeException must contain a crystal
*/
public TorsionTool(CMLTorsion torsion) throws RuntimeException {
init();
this.torsion = torsion;
}
void init() {
}
/**
* get angle.
*
* @return the angle or null
*/
public CMLTorsion getTorsion() {
return this.torsion;
}
/** gets TorsionTool associated with torsion.
* if null creates one and sets it in torsion
* @param torsion
* @return tool
*/
public static TorsionTool getOrCreateTool(CMLTorsion torsion) {
TorsionTool torsionTool = null;
if (torsion != null) {
torsionTool = (TorsionTool) torsion.getTool();
if (torsionTool == null) {
torsionTool = new TorsionTool(torsion);
torsion.setTool(torsionTool);
}
}
return torsionTool;
}
/** adjusts coordinates in atomSet to torsion angle.
*
* @param molecule
*/
public void adjustCoordinates(CMLMolecule molecule) {
String[] atomRefs4 = torsion.getAtomRefs4();
CMLAtomSet fixedAtomSet = new CMLAtomSet(molecule, atomRefs4);
CMLAtom atom0 = fixedAtomSet.getAtom(1);
CMLAtom atom1 = fixedAtomSet.getAtom(2);
MoleculeTool moleculeTool = MoleculeTool.getOrCreateTool(molecule);
CMLAtomSet moveableSet = moleculeTool.getDownstreamAtoms(atom1, atom0);
adjustCoordinates(fixedAtomSet, moveableSet);
}
/** applies transformation to reset torsion angle.
*
* @param amount
* @param atomSet to define torsion (could be the molecule)
* @param moveableSet set of atoms which can be moved
* (normally those downstream of the rotatable bond)
* coordinates of these atoms will be altered
*/
void adjustCoordinates(CMLAtomSet atomSet, CMLAtomSet moveableSet) {
if (torsion.getValue().trim().length() != 0) {
Double d = torsion.getXMLContent();
if (!Double.isNaN(d)) {
Angle angle = new Angle(d, Angle.Units.DEGREES);
// make sure there are exactly 4 atoms in order
CMLAtomSet atom4Set = atomSet.getAtomSetById(torsion.getAtomRefs4());
CMLTransform3 transform = this.getTransformationToNewTorsion(
angle, atom4Set);
AtomSetTool.getOrCreateTool(moveableSet).transformCartesians(transform);
}
}
}
/** applies transformation to reset torsion angle.
*
* @param angle
* @param atomSet to define torsion (could be the molecule)
* @param moveableSet set of atoms which can be moved
* (normally those downstream of the rotatable bond)
* coordinates of these atoms will be altered
*/
public void adjustCoordinates(Angle angle, CMLAtomSet atomSet, CMLAtomSet moveableSet) {
// make sure there are exactly 4 atoms in order
CMLAtomSet atom4Set = atomSet.getAtomSetById(torsion.getAtomRefs4());
CMLTransform3 transform = this.getTransformationToNewTorsion(
angle, atom4Set);
AtomSetTool.getOrCreateTool(moveableSet).transformCartesians(transform);
}
/** calculates transformation to reset torsion angle.
* T1 = translateion of atom2 to origin
* R = rotation
* T1' = -T1
*
* T = T1' * R * T1
* @param angle
* @param atomSet of 4 atoms
* @return the transform (or null if problems)
*/
public CMLTransform3 getTransformationToNewTorsion(Angle angle, CMLMolecule molecule) {
CMLAtomSet atom4Set = new CMLAtomSet(molecule, torsion.getAtomRefs4());
return this.getTransformationToNewTorsion(angle, atom4Set);
}
/** calculates transformation to reset torsion angle.
* T1 = translateion of atom2 to origin
* R = rotation
* T1' = -T1
*
* T = T1' * R * T1
* @param angle
* @param atomSet of 4 atoms
* @return the transform (or null if problems)
*/
public CMLTransform3 getTransformationToNewTorsion(Angle angle, CMLAtomSet atom4Set) {
if (atom4Set == null || atom4Set.size() != 4) {
throw new RuntimeException("must have 4 atoms in set");
}
Transform3 transform = null;
double tor0 = torsion.getCalculatedTorsion(atom4Set.getAtoms());
List atoms = torsion.getAtoms(atom4Set);
CMLAtom atom1 = atoms.get(1);
CMLAtom atom2 = atoms.get(2);
Point3 point2 = atom2.getPoint3(CoordinateType.CARTESIAN);
double delta = tor0 - angle.getDegrees();
// translate moveable atoms to origin
Vector3 v2 = new Point3(0.0, 0.0, 0.0).subtract(point2);
Transform3 t1 = new Transform3(v2);
Transform3 t1prime = new Transform3(v2.negative());
Vector3 v = atom2.getVector3(atom1);
Transform3 r = new Transform3(v, new Angle(delta, Angle.Units.DEGREES));
transform = r.concatenate(t1);
// translate back
transform = t1prime.concatenate(transform);
return new CMLTransform3(transform);
}
};
© 2015 - 2025 Weber Informatics LLC | Privacy Policy