1 package jalview.ws.phyre2;
3 import jalview.datamodel.AlignmentI;
4 import jalview.datamodel.SequenceI;
5 import jalview.fts.core.DecimalFormatTableCellRenderer;
6 import jalview.io.DataSourceType;
7 import jalview.io.FileFormat;
8 import jalview.io.FormatAdapter;
9 import jalview.io.StructureFile;
10 import jalview.schemes.ResidueProperties;
11 import jalview.structure.StructureMapping;
12 import jalview.structure.StructureMappingClient;
13 import jalview.structures.models.MappingOutputModel;
14 import jalview.util.Comparison;
15 import jalview.util.Format;
18 import java.io.IOException;
19 import java.io.PrintStream;
20 import java.util.ArrayList;
21 import java.util.HashMap;
22 import java.util.List;
24 import javax.swing.JTable;
25 import javax.swing.table.DefaultTableModel;
27 import org.jsoup.Jsoup;
28 import org.jsoup.nodes.Document;
29 import org.jsoup.nodes.Element;
30 import org.jsoup.select.Elements;
32 public class Phyre2Client extends StructureMappingClient
34 private final static String NEWLINE = System.lineSeparator();
36 public static final int UNASSIGNED = -1;
38 private final static String PATH_SEPARATOR = File.separator;
40 public Phyre2Client(StructureFile structureFile)
42 this.structureFile = structureFile;
46 public StructureMapping getStructureMapping(SequenceI seq,
47 String pdbFile, String chain)
49 final StringBuilder mappingDetails = new StringBuilder(128);
50 PrintStream ps = new PrintStream(System.out)
53 public void print(String x)
55 mappingDetails.append(x);
61 mappingDetails.append(NEWLINE);
64 HashMap<Integer, int[]> mapping = getPhyre2FastaMapping(seq, ps);
66 String mappingOutput = mappingDetails.toString();
67 StructureMapping phyre2ModelMapping = new StructureMapping(seq,
68 pdbFile, structureFile.getId(), chain, mapping, mappingOutput);
69 return phyre2ModelMapping;
72 public HashMap<Integer, int[]> getPhyre2FastaMapping(SequenceI inputSeq,
73 java.io.PrintStream os)
75 HashMap<Integer, int[]> mapping = new HashMap<Integer, int[]>();
76 AlignmentI seq2Phyre2ModelFastaMapping = null;
79 seq2Phyre2ModelFastaMapping = new FormatAdapter().readFile(
80 getFastaMappingFile(), DataSourceType.FILE, FileFormat.Fasta);
81 } catch (IOException e1)
85 SequenceI[] seqs = seq2Phyre2ModelFastaMapping.getSequencesArray();
86 SequenceI tSequenceRes = seqs[0];
87 SequenceI tStructureRes = seqs[1];
89 // Essential to resolve fastaAlignment to input sequence and model sequence
91 tSequenceRes.setStart(inputSeq.getStart());
92 tSequenceRes.setEnd(inputSeq.getEnd());
94 tStructureRes.setStart(structureFile.getSeqsAsArray()[0].getStart());
95 tStructureRes.setEnd(structureFile.getSeqsAsArray()[0].getEnd());
98 int sequenceResLenght = tSequenceRes.getLength();
99 int structureResLenght = tStructureRes.getLength();
100 if (sequenceResLenght == structureResLenght)
102 int prevStructResNum = -1;
103 int alignmentLenght = sequenceResLenght + tSequenceRes.getStart();
104 for (int x = 0; x < alignmentLenght; x++)
106 int alignSeqResidueIndex = tSequenceRes.findIndex(x);
107 int structResNum = tStructureRes
108 .findPosition(alignSeqResidueIndex);
109 int sequenceResNum = tSequenceRes
110 .findPosition(alignSeqResidueIndex - 1);
111 boolean sameResNum = (structResNum == prevStructResNum);
112 // System.out.println(sequenceResNum + " : "
113 // + (sameResNum ? -1 : prevStructResNum));
114 mapping.put(sequenceResNum, new int[] {
115 sameResNum ? -1 : prevStructResNum, -1 });
116 prevStructResNum = structResNum;
119 } catch (Exception e)
126 populateAtomPositions(" ", mapping);
127 } catch (IllegalArgumentException e)
130 } catch (StructureMappingException e)
137 MappingOutputModel mop = new MappingOutputModel();
138 mop.setSeqStart(tSequenceRes.getStart());
139 mop.setSeqEnd(tSequenceRes.getEnd());
140 mop.setSeqName(tSequenceRes.getName());
141 mop.setSeqResidue(tSequenceRes.getSequenceAsString());
143 mop.setStrStart(tStructureRes.getStart());
144 mop.setStrEnd(tStructureRes.getEnd());
145 mop.setStrName(tStructureRes.getName());
146 mop.setStrResidue(tStructureRes.getSequenceAsString());
151 os.print(getMappingOutput(mop).toString());
152 } catch (Exception e)
161 private String getFastaMappingFile()
163 File phyre2ModelFile = new File(structureFile.getDataName());
164 String phyre2ModelResultDir = phyre2ModelFile.getParent();
165 String modelId = structureFile.getId().substring(0,
166 structureFile.getId().lastIndexOf(".pdb"));
167 return phyre2ModelResultDir + PATH_SEPARATOR + modelId + ".fasta";
171 public StringBuffer getMappingOutput(MappingOutputModel mp)
172 throws StructureMappingException
174 String seqRes = mp.getSeqResidue();
175 String seqName = mp.getSeqName();
176 int sStart = mp.getSeqStart();
177 int sEnd = mp.getSeqEnd();
179 String strRes = mp.getStrResidue();
180 String strName = mp.getStrName();
181 int pdbStart = mp.getStrStart();
182 int pdbEnd = mp.getStrEnd();
184 String type = mp.getType();
186 int maxid = (seqName.length() >= strName.length()) ? seqName.length()
188 int len = 72 - maxid - 1;
190 int nochunks = ((seqRes.length()) / len)
191 + ((seqRes.length()) % len > 0 ? 1 : 0);
193 StringBuffer output = new StringBuffer();
194 output.append(NEWLINE);
195 output.append("Sequence \u27f7 Structure mapping details").append(
197 output.append("Method: Phyre2 Alignment");
198 output.append(NEWLINE).append(NEWLINE);
200 output.append(new Format("%" + maxid + "s").form(seqName));
201 output.append(" : ");
202 output.append(String.valueOf(sStart));
203 output.append(" - ");
204 output.append(String.valueOf(sEnd));
205 output.append(" Maps to ");
206 output.append(NEWLINE);
207 output.append(new Format("%" + maxid + "s").form(strName));
208 output.append(" : ");
209 output.append(String.valueOf(pdbStart));
210 output.append(" - ");
211 output.append(String.valueOf(pdbEnd));
212 output.append(NEWLINE).append(NEWLINE);
214 int matchedSeqCount = 0;
215 for (int j = 0; j < nochunks; j++)
217 // Print the first aligned sequence
218 output.append(new Format("%" + (maxid) + "s").form(seqName)).append(
221 for (int i = 0; i < len; i++)
223 if ((i + (j * len)) < seqRes.length())
225 output.append(seqRes.charAt(i + (j * len)));
229 output.append(NEWLINE);
230 output.append(new Format("%" + (maxid) + "s").form(" ")).append(" ");
232 // Print out the matching chars
233 for (int i = 0; i < len; i++)
237 if ((i + (j * len)) < seqRes.length())
239 boolean sameChar = Comparison.isSameResidue(
240 seqRes.charAt(i + (j * len)),
241 strRes.charAt(i + (j * len)), false);
243 && !jalview.util.Comparison.isGap(seqRes.charAt(i
249 else if (type.equals("pep"))
251 if (ResidueProperties.getPAM250(seqRes.charAt(i + (j * len)),
252 strRes.charAt(i + (j * len))) > 0)
266 } catch (IndexOutOfBoundsException e)
271 // Now print the second aligned sequence
272 output = output.append(NEWLINE);
273 output = output.append(new Format("%" + (maxid) + "s").form(strName))
275 for (int i = 0; i < len; i++)
277 if ((i + (j * len)) < strRes.length())
279 output.append(strRes.charAt(i + (j * len)));
282 output.append(NEWLINE).append(NEWLINE);
284 float pid = (float) matchedSeqCount / seqRes.length() * 100;
285 // if (pid < SiftsSettings.getFailSafePIDThreshold())
287 // throw new Exception(">>> Low PID detected for Phyre2 mapping...");
289 output.append("Length of alignment = " + seqRes.length()).append(
291 output.append(new Format("Percentage ID = %2.2f").form(pid));
297 public static List<Phyre2SummaryPojo> parsePhyre2ResultSummaryTable(
300 List<Phyre2SummaryPojo> phyre2Results = new ArrayList<Phyre2SummaryPojo>();
303 File in = new File(html);
304 Document doc = Jsoup.parse(in, null);
305 // Document doc = Jsoup.connect(html).get();
306 Elements tableElements = doc.select("table.midshade");
307 for (Element table : tableElements)
309 System.out.println();
310 Elements tableRowElements = table.select(":not(thead) tr");
311 for (int i = 0; i < tableRowElements.size(); i++)
313 Element row = tableRowElements.get(i);
314 Elements rowItems = row.select("td");
315 if (rowItems.size() > 11)
317 // for (int j = 0; j < rowItems.size(); j++)
319 // System.out.println(">>> r:" + j + " = "
320 // + rowItems.get(j).text());
323 String c = rowItems.get(6).select("input").attr("onmouseover");
324 String alignedRange = c.substring(c.indexOf("Residues ") + 9,
325 c.indexOf(" of your sequence aligned "));
326 String coverage = c.substring(c.lastIndexOf(" (") + 2,
327 c.lastIndexOf(" coverage). Click to view detailed"));
328 // System.out.println("coverage" + coverage);
331 Phyre2SummaryPojo psp = new Phyre2SummaryPojo();
332 String sn = rowItems.get(0).text();
333 psp.setSerialNo(Integer.valueOf(sn));
334 psp.setTemplateId(rowItems.get(1).text());
335 psp.setCoverage(coverage);
336 psp.setAlignedRange(alignedRange);
337 psp.setConfidence(Double.valueOf(rowItems.get(8).text()));
338 psp.setPid(Integer.valueOf(rowItems.get(9).text()));
339 psp.setTemplateSummary(rowItems.get(10).text());
340 // System.out.println("row >>>> " + psp.toString());
341 // System.out.println();
342 phyre2Results.add(psp);
343 } catch (NumberFormatException e)
346 } catch (IndexOutOfBoundsException e)
349 } catch (Exception e)
356 return phyre2Results;
358 } catch (Exception e)
365 public static DefaultTableModel getTableModel(
366 List<Phyre2SummaryPojo> phyreResults)
368 if (phyreResults == null)
372 DefaultTableModel tableModel = new DefaultTableModel()
375 public boolean isCellEditable(int row, int column)
381 public Class<?> getColumnClass(int columnIndex)
386 return Integer.class;
396 return Integer.class;
406 tableModel.addColumn("#");
407 tableModel.addColumn("Template");
408 tableModel.addColumn("Aligned Range");
409 tableModel.addColumn("Coverage");
410 tableModel.addColumn("Confidence");
411 tableModel.addColumn("%.i.d");
412 tableModel.addColumn("Template Information");
414 for (Phyre2SummaryPojo res : phyreResults)
416 tableModel.addRow(new Object[] { res.getSerialNo(),
417 res.getTemplateId(), res.getAlignedRange(), res.getCoverage(),
418 res.getConfidence(), res.getPid(), res.getTemplateSummary() });
423 public static void configurePhyreResultTable(JTable phyreResultTable)
426 DecimalFormatTableCellRenderer idCellRender = new DecimalFormatTableCellRenderer(
428 DecimalFormatTableCellRenderer pidCellRender = new DecimalFormatTableCellRenderer(
430 DecimalFormatTableCellRenderer confidenceCellRender = new DecimalFormatTableCellRenderer(
433 phyreResultTable.getColumn("#").setMinWidth(20);
434 phyreResultTable.getColumn("#").setPreferredWidth(30);
435 phyreResultTable.getColumn("#").setMaxWidth(40);
436 phyreResultTable.getColumn("#").setCellRenderer(idCellRender);
438 phyreResultTable.getColumn("Template").setMinWidth(60);
439 phyreResultTable.getColumn("Template").setPreferredWidth(60);
440 phyreResultTable.getColumn("Template").setMaxWidth(90);
442 phyreResultTable.getColumn("Aligned Range").setMinWidth(80);
443 phyreResultTable.getColumn("Aligned Range").setPreferredWidth(80);
444 phyreResultTable.getColumn("Aligned Range").setMaxWidth(120);
446 phyreResultTable.getColumn("Coverage").setMinWidth(60);
447 phyreResultTable.getColumn("Coverage").setPreferredWidth(60);
448 phyreResultTable.getColumn("Coverage").setMaxWidth(90);
450 phyreResultTable.getColumn("Confidence").setMinWidth(60);
451 phyreResultTable.getColumn("Confidence").setPreferredWidth(60);
452 phyreResultTable.getColumn("Confidence").setMaxWidth(90);
453 phyreResultTable.getColumn("Confidence").setCellRenderer(
454 confidenceCellRender);
456 phyreResultTable.getColumn("%.i.d").setMinWidth(45);
457 phyreResultTable.getColumn("%.i.d").setPreferredWidth(450);
458 phyreResultTable.getColumn("%.i.d").setMaxWidth(65);
459 phyreResultTable.getColumn("%.i.d").setCellRenderer(pidCellRender);
461 phyreResultTable.getColumn("Template Information").setMinWidth(400);
462 phyreResultTable.getColumn("Template Information").setPreferredWidth(
464 phyreResultTable.getColumn("Template Information").setMaxWidth(1500);