<commit_before>package org.biojava.bio.structure.align.xml;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;

import org.biojava.bio.structure.Atom;
import org.biojava.bio.structure.StructureException;
import org.biojava.bio.structure.align.model.AFPChain;
import org.biojava.bio.structure.jama.Matrix;
import org.biojava.utils.xml.PrettyXMLWriter;


public class AFPChainXMLConverter {


	/** Convert an afpChain to a simple XML representation
	 * 
	 * @param afpChain
	 * @return
	 */
	public static String toXML(AFPChain afpChain, Atom[] ca1, Atom[]ca2) throws IOException{
		StringWriter result = new StringWriter();	
		toXML(afpChain,result,ca1,ca2);
		return result.toString();

	}


	/** Write the XML representation to a StringWriter
	 * 
	 * @param afpChain
	 * @param swriter
	 * @throws IOException
	 */
	public static void toXML(AFPChain afpChain, StringWriter swriter,Atom[] ca1, Atom[]ca2) throws IOException{

		PrintWriter writer = new PrintWriter(swriter);
		PrettyXMLWriter xml = new PrettyXMLWriter(writer);
		
		xml.openTag("AFPChain");
		
		printXMLHeader(xml,afpChain);


		// that is the initial alignment...
		// we don't serialize that at the present.
		//int[] blockResSize = afpChain.getBlockResSize();
		//int[][][] blockResList = afpChain.getBlockResList();


		// get the alignment blocks
		int blockNum = afpChain.getBlockNum();

		for(int bk = 0; bk < blockNum; bk ++) {

			xml.openTag("block");

			printXMLBlockHeader(xml,afpChain, bk);

			if ( ca1 == null || ca2 == null) {
				try {
					printXMLEQRKnownPositions(xml,afpChain,bk);
				} catch (StructureException ex ){
					throw new IOException(ex.getMessage());
				}
			}
			else 
				printXMLEQRInferPositions(xml, afpChain,bk,ca1,ca2);

			printXMLMatrixShift(xml, afpChain, bk);

			xml.closeTag("block");
		}

		xml.closeTag("AFPChain");

		writer.close();


	}



	private static void printXMLEQRKnownPositions(PrettyXMLWriter xml,
			AFPChain afpChain, int blockNr) throws IOException, StructureException{
		int[] optLen       = afpChain.getOptLen();


		String[][][] pdbAln = afpChain.getPdbAln();
		if ( pdbAln == null){
			throw new StructureException("Can't convert to XML without known the PDB coordinates. Please provide Ca atoms and call toXML(afpChain,ca1, ca2)");
		}

		for ( int eqrNr = 0 ; eqrNr < optLen[blockNr] ; eqrNr++ ){
			
			String pdbResnum1 = pdbAln[blockNr][0][eqrNr];
			String pdbResnum2 = pdbAln[blockNr][1][eqrNr];
			
			//System.out.println(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];

			xml.openTag("eqr");
			xml.attribute("eqrNr",eqrNr+"");
			xml.attribute("pdbres1",pdbres1);
			xml.attribute("chain1", chain1);
			xml.attribute("pdbres2",pdbres2);
			xml.attribute("chain2", chain2);
			xml.closeTag("eqr");
		}
	}


	private static void printXMLEQRInferPositions(PrettyXMLWriter xml,			
			AFPChain afpChain, int bk, Atom[] ca1, Atom[] ca2)  throws IOException{
		
		int[] optLen       = afpChain.getOptLen();
		
		if ( optLen == null)
			return;
		
		
		
		int[][][] optAln   = afpChain.getOptAln();
		
		
		for ( int pos=0;pos< optLen[bk];pos++){
			int pos1 = optAln[bk][0][pos];
			int pos2 = optAln[bk][1][pos];
			xml.openTag("eqr");
			xml.attribute("eqrNr",pos+"");
			xml.attribute("pdbres1",ca1[pos1].getParent().getPDBCode());
			xml.attribute("chain1", ca1[pos1].getParent().getParent().getName());
			xml.attribute("pdbres2",ca2[pos2].getParent().getPDBCode());
			xml.attribute("chain2", ca2[pos2].getParent().getParent().getName());
			
			xml.closeTag("eqr");
			/*System.out.println("aligned position: " + pos1  + ":" + pos2 + 
			" pdbresnum " + ca1[pos1].getParent().getPDBCode() + " " +
			ca1[pos1].getParent().getPDBName()+":" + 
			ca2[pos2].getParent().getPDBCode() + " " + ca2[pos2].getParent().getPDBName());
	 */
		}	 

	}


	private static void printXMLBlockHeader(PrettyXMLWriter xml,
			AFPChain afpChain,int blockNr) throws IOException{

		int bk = blockNr;
		int[] blockGap     = afpChain.getBlockGap();
		int[] blockSize    = afpChain.getBlockSize();
		double[]blockScore = afpChain.getBlockScore();
		double[] blockRmsd = afpChain.getBlockRmsd();

		xml.attribute("blockNr",bk+"");
		xml.attribute("blockSize", blockSize[bk]+"");
		xml.attribute("blockScore", String.format("%5.2f",blockScore[bk]).trim());
		xml.attribute("blockRmsd", String.format("%5.2f",blockRmsd[bk]).trim());
		xml.attribute("blockGap", blockGap[bk]+"");

	}


	private static void printXMLMatrixShift(PrettyXMLWriter xml,
			AFPChain afpChain, int blockNr)  throws IOException {
		xml.openTag("matrix");
		Matrix[] ms     = afpChain.getBlockRotationMatrix();
		
		if ( ms == null || ms.length == 0)
			return;
		
		Matrix matrix = ms[blockNr];
		for (int x=0;x<3;x++){
			for (int y=0;y<3;y++){
				String key = "<KEY>
				xml.attribute(key,matrix.get(x,y)+"");
			}
		}
		xml.closeTag("matrix");

		Atom[]   shifts = afpChain.getBlockShiftVector();
		Atom shift = shifts[blockNr];
		xml.openTag("shift");
		xml.attribute("x",shift.getX()+"");
		xml.attribute("y",shift.getY()+"");
		xml.attribute("z",shift.getZ()+"");
		xml.closeTag("shift");

	}


	public static String toXML(AFPChain afpChain) throws IOException{

		return toXML(afpChain, null, null);<commit_msg>fixing a problem if alignment is too short to be calculated<commit_after>package org.biojava.bio.structure.align.xml;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;

import org.biojava.bio.structure.Atom;
import org.biojava.bio.structure.StructureException;
import org.biojava.bio.structure.align.model.AFPChain;
import org.biojava.bio.structure.jama.Matrix;
import org.biojava.utils.xml.PrettyXMLWriter;


public class AFPChainXMLConverter {


	/** Convert an afpChain to a simple XML representation
	 * 
	 * @param afpChain
	 * @return
	 */
	public static String toXML(AFPChain afpChain, Atom[] ca1, Atom[]ca2) throws IOException{
		StringWriter result = new StringWriter();	
		toXML(afpChain,result,ca1,ca2);
		return result.toString();

	}


	/** Write the XML representation to a StringWriter
	 * 
	 * @param afpChain
	 * @param swriter
	 * @throws IOException
	 */
	public static void toXML(AFPChain afpChain, StringWriter swriter,Atom[] ca1, Atom[]ca2) throws IOException{

		PrintWriter writer = new PrintWriter(swriter);
		PrettyXMLWriter xml = new PrettyXMLWriter(writer);
		
		xml.openTag("AFPChain");
		
		printXMLHeader(xml,afpChain);


		// that is the initial alignment...
		// we don't serialize that at the present.
		//int[] blockResSize = afpChain.getBlockResSize();
		//int[][][] blockResList = afpChain.getBlockResList();


		// get the alignment blocks
		int blockNum = afpChain.getBlockNum();

		for(int bk = 0; bk < blockNum; bk ++) {

			xml.openTag("block");

			printXMLBlockHeader(xml,afpChain, bk);

			if ( ca1 == null || ca2 == null) {
				try {
					printXMLEQRKnownPositions(xml,afpChain,bk);
				} catch (StructureException ex ){
					throw new IOException(ex.getMessage());
				}
			}
			else 
				printXMLEQRInferPositions(xml, afpChain,bk,ca1,ca2);

			printXMLMatrixShift(xml, afpChain, bk);

			xml.closeTag("block");
		}

		xml.closeTag("AFPChain");

		writer.close();


	}



	private static void printXMLEQRKnownPositions(PrettyXMLWriter xml,
			AFPChain afpChain, int blockNr) throws IOException, StructureException{
		int[] optLen       = afpChain.getOptLen();


		String[][][] pdbAln = afpChain.getPdbAln();
		if ( pdbAln == null){
			throw new StructureException("Can't convert to XML without known the PDB coordinates. Please provide Ca atoms and call toXML(afpChain,ca1, ca2)");
		}

		for ( int eqrNr = 0 ; eqrNr < optLen[blockNr] ; eqrNr++ ){
			
			String pdbResnum1 = pdbAln[blockNr][0][eqrNr];
			String pdbResnum2 = pdbAln[blockNr][1][eqrNr];
			
			//System.out.println(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];

			xml.openTag("eqr");
			xml.attribute("eqrNr",eqrNr+"");
			xml.attribute("pdbres1",pdbres1);
			xml.attribute("chain1", chain1);
			xml.attribute("pdbres2",pdbres2);
			xml.attribute("chain2", chain2);
			xml.closeTag("eqr");
		}
	}


	private static void printXMLEQRInferPositions(PrettyXMLWriter xml,			
			AFPChain afpChain, int bk, Atom[] ca1, Atom[] ca2)  throws IOException{
		
		int[] optLen       = afpChain.getOptLen();
		
		if ( optLen == null)
			return;
		
		
		
		int[][][] optAln   = afpChain.getOptAln();
		
		
		for ( int pos=0;pos< optLen[bk];pos++){
			int pos1 = optAln[bk][0][pos];
			int pos2 = optAln[bk][1][pos];
			xml.openTag("eqr");
			xml.attribute("eqrNr",pos+"");
			xml.attribute("pdbres1",ca1[pos1].getParent().getPDBCode());
			xml.attribute("chain1", ca1[pos1].getParent().getParent().getName());
			xml.attribute("pdbres2",ca2[pos2].getParent().getPDBCode());
			xml.attribute("chain2", ca2[pos2].getParent().getParent().getName());
			
			xml.closeTag("eqr");
			/*System.out.println("aligned position: " + pos1  + ":" + pos2 + 
			" pdbresnum " + ca1[pos1].getParent().getPDBCode() + " " +
			ca1[pos1].getParent().getPDBName()+":" + 
			ca2[pos2].getParent().getPDBCode() + " " + ca2[pos2].getParent().getPDBName());
	 */
		}	 

	}


	private static void printXMLBlockHeader(PrettyXMLWriter xml,
			AFPChain afpChain,int blockNr) throws IOException{

		int bk = blockNr;
		int[] blockGap     = afpChain.getBlockGap();
		int[] blockSize    = afpChain.getBlockSize();
		double[]blockScore = afpChain.getBlockScore();
		double[] blockRmsd = afpChain.getBlockRmsd();

		xml.attribute("blockNr",bk+"");
		xml.attribute("blockSize", blockSize[bk]+"");
		xml.attribute("blockScore", String.format("%5.2f",blockScore[bk]).trim());
		xml.attribute("blockRmsd", String.format("%5.2f",blockRmsd[bk]).trim());
		xml.attribute("blockGap", blockGap[bk]+"");

	}


	private static void printXMLMatrixShift(PrettyXMLWriter xml,
			AFPChain afpChain, int blockNr)  throws IOException {
	   
	   Matrix[] ms     = afpChain.getBlockRotationMatrix();
	   if ( ms == null || ms.length == 0)
          return;
	   
	   xml.openTag("matrix");
		
		Matrix matrix = ms[blockNr];
		for (int x=0;x<3;x++){
			for (int y=0;y<3;y++){
				String key = "<KEY>
				xml.attribute(key,matrix.get(x,y)+"");
			}
		}
		xml.closeTag("matrix");

		Atom[]   shifts = afpChain.getBlockShiftVector();
		Atom shift = shifts[blockNr];
		xml.openTag("shift");
		xml.attribute("x",shift.getX()+"");
		xml.attribute("y",shift.getY()+"");
		xml.attribute("z",shift.getZ()+"");
		xml.closeTag("shift");

	}


	public static String toXML(AFPChain afpChain) throws IOException{

		return toXML(afpChain, null, null);
{'fraction_non_alphanumeric': 0.16018181818181818, 'fraction_numerical': 0.014909090909090908, 'mean_word_length': 4.0812933025404154, 'pattern_counts': {'":': 8, '<': 15, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 86}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7253908', 'n_tokens_mistral': 4489, 'n_tokens_neox': 3887, 'n_words': 743}