All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.biojava.nbio.structure.quaternary.BiologicalAssemblyTransformation Maven / Gradle / Ivy

There is a newer version: 7.2.2
Show newest version
/*
 *                    BioJava development code
 *
 * This code may be freely distributed and modified under the
 * terms of the GNU Lesser General Public Licence.  This should
 * be distributed with the code.  If you do not have a copy,
 * see:
 *
 *      http://www.gnu.org/copyleft/lesser.html
 *
 * Copyright for this code is held jointly by the individual
 * authors.  These should be listed in @author doc comments.
 *
 * For more information on the BioJava project and its aims,
 * or to join the biojava-l mailing list, visit the home page
 * at:
 *
 *      http://www.biojava.org/
 *
 */
package org.biojava.nbio.structure.quaternary;

import org.biojava.nbio.structure.xtal.CrystalCell;
import org.biojava.nbio.structure.xtal.CrystalTransform;
import org.biojava.nbio.core.util.PrettyXMLWriter;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import javax.vecmath.Matrix4d;
import javax.vecmath.Point3d;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.*;
import java.util.ArrayList;
import java.util.List;

/**
 * The transformation needed for generation of biological assemblies
 * from the contents of a PDB/mmCIF file. It contains both the actual
 * transformation (rotation+translation) and the chain identifier to
 * which it should be applied.
 *
 * @author Peter Rose
 * @author Andreas Prlic
 * @author rickb
 * @author duarte_j
 * @see CrystalTransform
 */
public class BiologicalAssemblyTransformation implements Cloneable, Serializable {

	private static final long serialVersionUID = -6388503076022480391L;

	private String id;
	private String chainId;
	private Matrix4d transformation;

	/**
	 * Default Constructor
	 */
	public BiologicalAssemblyTransformation() {
		// we initialize to identity so that setting rotation and translation work properly
		transformation = new Matrix4d(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1);
	}

	/**
	 * Copy Constructor
	 *
	 * @param src
	 */
	public BiologicalAssemblyTransformation(final BiologicalAssemblyTransformation src)
	{
		this.transformation = new Matrix4d(src.transformation);
		this.id = src.getId();
		this.chainId =  src.getChainId();
	}


	/**
	 * Sets the identifier for this biological assembly transformation. This is usually
	 * the model number used in the biological assembly files.
	 * @param id
	 */
	public void setId(String id) {
		this.id = id;
	}

	/**
	 * Returns the identifier for this biological assembly transformation.
	 * @return biological assembly transformation identifier
	 */
	public String getId() {
		return id;
	}

	/**
	 * Sets the chain identified this transformation should be applied to.
	 * @param chainId
	 */
	public void setChainId(String chainId) {
		this.chainId = chainId;
	}

	/**
	 * Returns the chain identifier this transformation should be applied to.
	 * @return chain identifier
	 */
	public String getChainId() {
		return this.chainId;
	}

	/**
	 * Sets the transformation using a 4x4 transformation matrix
	 * @param transformation
	 */
	public void setTransformationMatrix(Matrix4d transformation) {
		this.transformation = transformation;
	}

	/**
	 * Return the transformation (both rotational and translational component) as a 4x4 transformation matrix.
	 * The transformation is in orthonormal (cartesian coordinates). If required to be converted to
	 * crystal coordinates then use {@link CrystalCell#transfToCrystal(Matrix4d)}
	 * Note that this is a reference to the variable, thus it remains linked to this object's transformation field.
	 * The user must deep copy it if need changing it.
	 * @return 4x4 transformation matrix
	 */
	public Matrix4d getTransformationMatrix() {
		return transformation;
	}

	public void setRotationMatrix(double[][] m) {
		for (int i=0;i<3;i++) {
			for (int j=0;j<3;j++) {
				this.transformation.setElement(i, j, m[i][j]);
			}
		}
	}

	public void setTranslation(double[] t) {
		for (int i=0;i<3;i++) {
			this.transformation.setElement(i, 3, t[i]);
		}
	}

	/**
	 * Applies the transformation to given point.
	 */
	public void transformPoint(final double[] point) {
		Point3d p = new Point3d(point[0],point[1],point[2]);
		transformation.transform(p);
		point[0] = p.x;
		point[1] = p.y;
		point[2] = p.z;
	}

	/**
	 * Returns the combination (product) of two biological assembly transformations.
	 * @param matrix1
	 * @param matrix2
	 * @return combined transformation
	 */
	public static BiologicalAssemblyTransformation combine(BiologicalAssemblyTransformation matrix1, BiologicalAssemblyTransformation matrix2) {
		Matrix4d transformation = new Matrix4d(matrix1.transformation);
		transformation.mul(matrix2.transformation);
		BiologicalAssemblyTransformation combined = new BiologicalAssemblyTransformation();
		combined.setTransformationMatrix(transformation);
		return combined;
	}

	public String toXML() throws IOException{

		StringWriter sw = new StringWriter();
		PrintWriter writer = new PrintWriter(sw);

		PrettyXMLWriter xml = new PrettyXMLWriter(new PrintWriter(writer));

		toXML(xml);

		xml.close();
		writer.close();
		sw.close();
		return sw.toString();
	}

	public void toXML(PrettyXMLWriter xml) throws IOException{
		xml.openTag("transformation");
		xml.attribute("index",id);

		xml.openTag("matrix");

			for ( int i = 0 ; i<3 ; i++){
				for ( int j = 0 ; j<3 ;j++){
				xml.attribute("m" +  (i+1) + (j+1), String.format("%.8f",transformation.getElement(i,j)));
			}
		}
		xml.closeTag("matrix");

		xml.openTag("shift");
		for ( int i = 0 ; i<3 ; i++) {
			xml.attribute("v"+(i+1),String.format("%.8f", transformation.getElement(i,3)));
		}
		xml.closeTag("shift");

		xml.closeTag("transformation");

	}

	public static BiologicalAssemblyTransformation fromXML(String xml)
			throws SAXException,
			IOException,
			ParserConfigurationException{


		List transformations = fromMultiXML(xml);

		if ( transformations.size() > 0)
			return transformations.get(0);

		else
			return null;
	}

	public static List fromMultiXML(String xml) throws ParserConfigurationException, SAXException, IOException{


		List transformations = new ArrayList();

		// read the XML of a string and returns a ModelTransformationmatrix
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		DocumentBuilder db = factory.newDocumentBuilder();

		InputSource inStream = new InputSource();
		inStream.setCharacterStream(new StringReader(xml));
		Document doc = db.parse(inStream);

		// normalize text representation
		doc.getDocumentElement().normalize();;

		NodeList listOfTransforms = doc.getElementsByTagName("transformation");

		for(int pos=0; pos




© 2015 - 2025 Weber Informatics LLC | Privacy Policy