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

org.biojava.nbio.structure.align.xml.AFPChainXMLParser Maven / Gradle / Ivy

/*
 *                    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.align.xml;


import org.biojava.nbio.structure.*;
import org.biojava.nbio.structure.align.ce.CeCPMain;
import org.biojava.nbio.structure.align.model.AFP;
import org.biojava.nbio.structure.align.model.AFPChain;
import org.biojava.nbio.structure.align.util.AFPAlignmentDisplay;
import org.biojava.nbio.structure.jama.Matrix;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;

//http://www.developerfusion.com/code/2064/a-simple-way-to-read-an-xml-file-in-java/

public class AFPChainXMLParser
{

	private static final Logger logger = LoggerFactory.getLogger(AFPChainXMLParser.class);
	public static final String DEFAULT_ALGORITHM_NAME = "jFatCat_rigid";

	/** new utility method that checks that the order of the pair in the XML alignment is correct and flips the direction if needed
	 *
	 * @param xml
	 * @param name1
	 * @param name1
	 * @param ca1
	 * @param ca2
	 * @return
	 */
	 public static AFPChain fromXML(String xml, String name1, String name2, Atom[] ca1, Atom[] ca2) throws IOException, StructureException{
			AFPChain[] afps = parseMultiXML( xml);
			if ( afps.length > 0 ) {

				AFPChain afpChain = afps[0];

				String n1 = afpChain.getName1();
				String n2 = afpChain.getName2();

				if ( n1 == null )
					n1 = "";
				if ( n2 == null)
					n2 = "";

				//System.out.println("from AFPCHAIN: " + n1 + " " + n2);
				if ( n1.equals(name2) && n2.equals(name1)){
					// flipped order
					//System.out.println("AfpChain in wrong order, flipping...");
					afpChain  = AFPChainFlipper.flipChain(afpChain);
				}
				rebuildAFPChain(afpChain, ca1, ca2);

				return afpChain;
			}
			return null;

	 }

	public static AFPChain fromXML(String xml, Atom[] ca1, Atom[] ca2) throws IOException
	{
		AFPChain[] afps = parseMultiXML( xml);
		if ( afps.length > 0 ) {

			AFPChain afpChain = afps[0];
			rebuildAFPChain(afpChain, ca1, ca2);

			return afpChain;
		}
		return null;
	}

	/** returns true if the alignment XML contains an error message
	 *
	 * @param xml
	 * @return flag if there was an Error while processing the alignment.
	 */
	public static boolean isErrorXML(String xml){

		if ( xml.contains("error=\""))
			return true;

		return false;


	}

	/** Takes an XML representation of the alignment and flips the positions of name1 and name2
	 *
	 * @param xml String representing the alignment
	 * @return XML representation of the flipped alignment
	 */
	public static String flipAlignment(String xml) throws IOException,StructureException{
		AFPChain[] afps = parseMultiXML( xml);
		if ( afps.length < 1 )
			return null;

		if ( afps.length == 1) {
			AFPChain newChain = AFPChainFlipper.flipChain(afps[0]);
			if ( newChain.getAlgorithmName() == null) {
				newChain.setAlgorithmName(DEFAULT_ALGORITHM_NAME);
			}
			return AFPChainXMLConverter.toXML(newChain);
		}
		throw new StructureException("not Implemented yet!");
	}


	/**  replace the PDB res nums with atom positions:
	 *
	 * @param afpChain
	 * @param ca1
	 * @param ca2
	 */
	public static void rebuildAFPChain(AFPChain afpChain, Atom[] ca1, Atom[] ca2){

		if ( afpChain.getAlgorithmName() == null) {
			afpChain.setAlgorithmName(DEFAULT_ALGORITHM_NAME);
		}
		if ( afpChain.getVersion() == null){
			afpChain.setVersion("1.0");
		}

		int blockNum  = afpChain.getBlockNum();
		int ca1Length = afpChain.getCa1Length();
		int ca2Length = afpChain.getCa2Length();

		int minLength = Math.min(ca1Length, ca2Length);
		int[][][] optAln = new int[blockNum][2][minLength];

		int[][][] blockResList = afpChain.getBlockResList();
		if ( blockResList == null){
			blockResList = new int[blockNum][2][minLength];
		}
		int[] optLen = afpChain.getOptLen();

		String[][][] pdbAln = afpChain.getPdbAln();
		int[] verifiedOptLen = null;
		if ( optLen != null)
		  verifiedOptLen = afpChain.getOptLen().clone();
		else {
			logger.warn("did not find optimal alignment, building up empty alignment.");
			optLen = new int[1];
			optLen[0] = 0;
		}
		for (int blockNr = 0 ; blockNr < blockNum ; blockNr++){

			//System.out.println("got block " + blockNr + " size: " + optLen[blockNr]);
			int verifiedEQR = -1;
			for ( int eqrNr = 0 ; eqrNr < optLen[blockNr] ; eqrNr++ ){
				String pdbResnum1 = pdbAln[blockNr][0][eqrNr];
				String pdbResnum2 = pdbAln[blockNr][1][eqrNr];

				//System.out.println(blockNr + " " + eqrNr + " got resnum: " + pdbResnum1 + " " + pdbResnum2);
				String[] spl1 = pdbResnum1.split(":");
				String[] spl2 = pdbResnum2.split(":");

				String chain1 = spl1[0];
				String pdbres1 = spl1[1];

				String chain2 = spl2[0];
				String pdbres2 = spl2[1];

				int pos1 = getPositionForPDBresunm(pdbres1,chain1,ca1);
				int pos2 = getPositionForPDBresunm(pdbres2,chain2,ca2);

				if ( pos1 == -1 || pos2 == -1 ){
					// this can happen when parsing old files that contained Calcium atoms...
					logger.warn("pos1: {} (residue {}), pos2: {} (residue {}), should never be -1. Probably parsing an old file.",
							pos1, pdbResnum1, pos2, pdbResnum2);
					verifiedOptLen[blockNr]-- ;
					continue;
				}

				verifiedEQR++;
				//System.out.println(blockNr + " " + eqrNr + " " + pos1 + " " + pos2);
				optAln[blockNr][0][verifiedEQR] = pos1;
				optAln[blockNr][1][verifiedEQR] = pos2;
				blockResList[blockNr][0][verifiedEQR] = pos1;
				blockResList[blockNr][1][verifiedEQR] = pos2;
			}
		}

		afpChain.setOptLen(verifiedOptLen);
		afpChain.setOptAln(optAln);
		afpChain.setBlockResList(blockResList);
		// build up alignment image:
		AFPAlignmentDisplay.getAlign(afpChain, ca1, ca2);


	}

	public static AFPChain[] parseMultiXML(String xml) throws IOException {
		List afpChains = new ArrayList();

		try
		{
			//Convert string to XML document
			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();


			//Element rootElement = doc.getDocumentElement();

			NodeList listOfAFPChains = doc.getElementsByTagName("AFPChain");
			//int numArrays = listOfArrays.getLength();
			// go over the blocks
			for(int afpPos=0; afpPos afpSet = new ArrayList();
				for (int afp=0;afp" + residueNumber +"<");
			if ( g.getResidueNumber().equals(residueNumber)){
				//System.out.println(g + " == " + residueNumber );
				Chain c = g.getChain();
				if ( blankChain || c.getName().equals(authId)){
					return i;
				}
			}
		}
		return -1;
	}



}





© 2015 - 2025 Weber Informatics LLC | Privacy Policy