001/* 002 * BioJava development code 003 * 004 * This code may be freely distributed and modified under the 005 * terms of the GNU Lesser General Public Licence. This should 006 * be distributed with the code. If you do not have a copy, 007 * see: 008 * 009 * http://www.gnu.org/copyleft/lesser.html 010 * 011 * Copyright for this code is held jointly by the individual 012 * authors. These should be listed in @author doc comments. 013 * 014 * For more information on the BioJava project and its aims, 015 * or to join the biojava-l mailing list, visit the home page 016 * at: 017 * 018 * http://www.biojava.org/ 019 * 020 */ 021package org.biojava.nbio.structure.align.xml; 022 023import org.biojava.nbio.structure.Atom; 024import org.biojava.nbio.structure.StructureException; 025import org.biojava.nbio.structure.align.model.AFPChain; 026import org.biojava.nbio.structure.align.util.AlignmentTools; 027import org.biojava.nbio.structure.jama.Matrix; 028import org.biojava.nbio.core.util.PrettyXMLWriter; 029 030import java.io.IOException; 031import java.io.PrintWriter; 032import java.io.StringWriter; 033 034 035 036public class AFPChainXMLConverter { 037 038 039 /** Convert an afpChain to a simple XML representation 040 * 041 * @param afpChain 042 * @return XML representation of the AFPCHain 043 */ 044 public synchronized static String toXML(AFPChain afpChain, Atom[] ca1, Atom[]ca2) throws IOException{ 045 StringWriter result = new StringWriter(); 046 toXML(afpChain,result,ca1,ca2); 047 return result.toString(); 048 } 049 050 /** Write the XML representation to a StringWriter 051 * 052 * @param afpChain 053 * @param swriter 054 * @throws IOException 055 */ 056 public synchronized static void toXML(AFPChain afpChain, StringWriter swriter,Atom[] ca1, Atom[]ca2) throws IOException{ 057 058 PrintWriter writer = new PrintWriter(swriter); 059 PrettyXMLWriter xml = new PrettyXMLWriter(writer); 060 061 xml.openTag("AFPChain"); 062 063 printXMLHeader(xml,afpChain); 064 065 066 // that is the initial alignment... 067 // we don't serialize that at the present. 068 //int[] blockResSize = afpChain.getBlockResSize(); 069 //int[][][] blockResList = afpChain.getBlockResList(); 070 071 072 // get the alignment blocks 073 int blockNum = afpChain.getBlockNum(); 074 //int[] optLen = afpChain.getOptLen(); 075 //int[] blockSize = afpChain.getBlockSize(); 076 for(int bk = 0; bk < blockNum; bk ++) { 077 078 xml.openTag("block"); 079 080 printXMLBlockHeader(xml,afpChain, bk); 081 082 if ( ca1 == null || ca2 == null) { 083 try { 084 printXMLEQRKnownPositions(xml,afpChain,bk); 085 } catch (StructureException ex ){ 086 throw new IOException(ex.getMessage()); 087 } 088 } 089 else 090 printXMLEQRInferPositions(xml, afpChain,bk,ca1,ca2); 091 092 printXMLMatrixShift(xml, afpChain, bk); 093 094 xml.closeTag("block"); 095 } 096 097 xml.closeTag("AFPChain"); 098 099 writer.close(); 100 101 102 } 103 104 105 106 private static void printXMLEQRKnownPositions(PrettyXMLWriter xml, 107 AFPChain afpChain, int blockNr) throws IOException, StructureException{ 108 int[] optLen = afpChain.getOptLen(); 109 110 111 String[][][] pdbAln = afpChain.getPdbAln(); 112 if ( pdbAln == null){ 113 throw new StructureException("Can't convert to XML without known the PDB coordinates. Please provide Ca atoms and call toXML(afpChain,ca1, ca2)"); 114 } 115 116 for ( int eqrNr = 0 ; eqrNr < optLen[blockNr] ; eqrNr++ ){ 117 118 String pdbResnum1 = pdbAln[blockNr][0][eqrNr]; 119 String pdbResnum2 = pdbAln[blockNr][1][eqrNr]; 120 121 //System.out.println(eqrNr + " got resnum: " + pdbResnum1 + " " + pdbResnum2); 122 123 String[] spl1 = pdbResnum1.split(":"); 124 String[] spl2 = pdbResnum2.split(":"); 125 126 String chain1 = spl1[0]; 127 String pdbres1 = spl1[1]; 128 129 String chain2 = spl2[0]; 130 String pdbres2 = spl2[1]; 131 132 xml.openTag("eqr"); 133 xml.attribute("eqrNr", String.valueOf(eqrNr)); 134 xml.attribute("pdbres1",pdbres1); 135 xml.attribute("chain1", chain1); 136 xml.attribute("pdbres2",pdbres2); 137 xml.attribute("chain2", chain2); 138 xml.closeTag("eqr"); 139 } 140 } 141 142 143 public static void printXMLEQRInferPositions(PrettyXMLWriter xml, 144 AFPChain afpChain, int bk, Atom[] ca1, Atom[] ca2) throws IOException{ 145 146 int[] optLen = afpChain.getOptLen(); 147 148 if ( optLen == null) 149 return; 150 151 int[][][] optAln = afpChain.getOptAln(); 152 153 154 for ( int pos=0;pos< optLen[bk];pos++){ 155 int pos1 = optAln[bk][0][pos]; 156 int pos2 = optAln[bk][1][pos]; 157 xml.openTag("eqr"); 158 xml.attribute("eqrNr", String.valueOf(pos)); 159 xml.attribute("pdbres1",ca1[pos1].getGroup().getResidueNumber().toString()); 160 xml.attribute("chain1", ca1[pos1].getGroup().getChain().getName()); 161 xml.attribute("pdbres2",ca2[pos2].getGroup().getResidueNumber().toString()); 162 xml.attribute("chain2", ca2[pos2].getGroup().getChain().getName()); 163 164 xml.closeTag("eqr"); 165 //System.out.println("aligned position: " + pos1 + ":" + pos2 + 166 //" pdbresnum " + ca1[pos1].getGroup().getResidueNumber().toString() + " " + 167 //ca1[pos1].getParent().getPDBName()+":" + 168 //ca2[pos2].getGroup().getResidueNumber().toString() + " " + ca2[pos2].getParent().getPDBName()); 169 170 } 171 172 } 173 174 175 private static void printXMLBlockHeader(PrettyXMLWriter xml, 176 AFPChain afpChain,int blockNr) throws IOException{ 177 178 int bk = blockNr; 179 int[] blockSize = afpChain.getBlockSize(); 180 //if ( blockSize[bk] == 0) { 181 // return; 182 //} 183 int[] blockGap = afpChain.getBlockGap(); 184 185 double[]blockScore = afpChain.getBlockScore(); 186 double[] blockRmsd = afpChain.getBlockRmsd(); 187 188 xml.attribute("blockNr", String.valueOf(bk)); 189 xml.attribute("blockSize", String.valueOf(blockSize[bk])); 190 xml.attribute("blockScore", String.format("%5.2f",blockScore[bk]).trim()); 191 xml.attribute("blockRmsd", String.format("%5.2f",blockRmsd[bk]).trim()); 192 xml.attribute("blockGap", String.valueOf(blockGap[bk])); 193 194 } 195 196 197 private static void printXMLMatrixShift(PrettyXMLWriter xml, 198 AFPChain afpChain, int blockNr) throws IOException { 199 200 Matrix[] ms = afpChain.getBlockRotationMatrix(); 201 if ( ms == null || ms.length == 0) 202 return; 203 204 Matrix matrix = ms[blockNr]; 205 if ( matrix == null) 206 return; 207 xml.openTag("matrix"); 208 209 210 for (int x=0;x<3;x++){ 211 for (int y=0;y<3;y++){ 212 String key = "mat"+(x+1)+(y+1); 213 xml.attribute(key,String.format("%.6f",matrix.get(x,y))); 214 } 215 } 216 xml.closeTag("matrix"); 217 218 Atom[] shifts = afpChain.getBlockShiftVector(); 219 Atom shift = shifts[blockNr]; 220 xml.openTag("shift"); 221 xml.attribute("x", String.format("%.3f",shift.getX())); 222 xml.attribute("y", String.format("%.3f",shift.getY())); 223 xml.attribute("z", String.format("%.3f",shift.getZ())); 224 xml.closeTag("shift"); 225 226 } 227 228 229 public static String toXML(AFPChain afpChain) throws IOException{ 230 231 return toXML(afpChain, null, null); 232 } 233 234 235 public static void printXMLHeader(PrettyXMLWriter xml, AFPChain afpChain) throws IOException{ 236 xml.attribute("name1", afpChain.getName1()); 237 xml.attribute("name2", afpChain.getName2()); 238 xml.attribute("method", afpChain.getAlgorithmName()); 239 xml.attribute("version" , afpChain.getVersion()); 240 xml.attribute("alnLength", afpChain.getAlnLength() + ""); 241 xml.attribute("blockNum", afpChain.getBlockNum() + ""); 242 xml.attribute("gapLen", afpChain.getGapLen() + ""); 243 xml.attribute("optLength", afpChain.getOptLength() + ""); 244 xml.attribute("totalLenIni", afpChain.getTotalLenIni() + ""); 245 246 xml.attribute("alignScore", String.format("%5.2f", afpChain.getAlignScore() ).trim()); 247 xml.attribute("chainRmsd", String.format("%5.2f", afpChain.getChainRmsd() ).trim()); 248 xml.attribute("identity",String.format("%5.4f", afpChain.getIdentity() ).trim()); 249 xml.attribute("normAlignScore", String.format("%5.2f",afpChain.getNormAlignScore()).trim()); 250 xml.attribute("probability", String.format("%.2e", afpChain.getProbability() ).trim()); 251 xml.attribute("similarity", String.format("%5.4f", afpChain.getSimilarity() ).trim()); 252 253 xml.attribute("similarity1", afpChain.getCoverage1() + ""); 254 xml.attribute("similarity2", afpChain.getCoverage2() + ""); 255 xml.attribute("totalRmsdIni", String.format("%5.2f",afpChain.getTotalRmsdIni() ).trim()); 256 xml.attribute("totalRmsdOpt", String.format("%5.2f",afpChain.getTotalRmsdOpt() ).trim()); 257 xml.attribute("ca1Length", afpChain.getCa1Length()+""); 258 xml.attribute("ca2Length", afpChain.getCa2Length()+""); 259 xml.attribute("afpNum",afpChain.getAfpSet().size()+""); 260 xml.attribute("alignScoreUpdate",String.format("%5.2f",afpChain.getAlignScoreUpdate()).trim()); 261 xml.attribute("time", String.format("%d",afpChain.getCalculationTime())); 262 if ( afpChain.getTMScore() != -1){ 263 xml.attribute("tmScore", String.format("%.2f",afpChain.getTMScore())); 264 } 265 266 // test if alignment is CP: 267 if ( ! AlignmentTools.isSequentialAlignment(afpChain,false)) { 268 xml.attribute("cp","true"); 269 } 270 } 271}