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