X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fws%2Fphyre2%2FPhyre2Client.java;fp=src%2Fjalview%2Fws%2Fphyre2%2FPhyre2Client.java;h=0a2941281a4abd6c9ff4352326fe32c3fc839c3b;hb=42ca4613b0a07bab7c27a61b11acafdc9a3c27d1;hp=0000000000000000000000000000000000000000;hpb=f1ad88cc8d9b26244086e5c24b73fb80b0ff0a38;p=jalview.git diff --git a/src/jalview/ws/phyre2/Phyre2Client.java b/src/jalview/ws/phyre2/Phyre2Client.java new file mode 100644 index 0000000..0a29412 --- /dev/null +++ b/src/jalview/ws/phyre2/Phyre2Client.java @@ -0,0 +1,466 @@ +package jalview.ws.phyre2; + +import jalview.datamodel.AlignmentI; +import jalview.datamodel.SequenceI; +import jalview.fts.core.DecimalFormatTableCellRenderer; +import jalview.io.DataSourceType; +import jalview.io.FileFormat; +import jalview.io.FormatAdapter; +import jalview.io.StructureFile; +import jalview.schemes.ResidueProperties; +import jalview.structure.StructureMapping; +import jalview.structure.StructureMappingClient; +import jalview.structures.models.MappingOutputModel; +import jalview.util.Comparison; +import jalview.util.Format; + +import java.io.File; +import java.io.IOException; +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import javax.swing.JTable; +import javax.swing.table.DefaultTableModel; + +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.nodes.Element; +import org.jsoup.select.Elements; + +public class Phyre2Client extends StructureMappingClient +{ + private final static String NEWLINE = System.lineSeparator(); + + public static final int UNASSIGNED = -1; + + private final static String PATH_SEPARATOR = File.separator; + + public Phyre2Client(StructureFile structureFile) + { + this.structureFile = structureFile; + } + + @Override + public StructureMapping getStructureMapping(SequenceI seq, + String pdbFile, String chain) + { + final StringBuilder mappingDetails = new StringBuilder(128); + PrintStream ps = new PrintStream(System.out) + { + @Override + public void print(String x) + { + mappingDetails.append(x); + } + + @Override + public void println() + { + mappingDetails.append(NEWLINE); + } + }; + HashMap mapping = getPhyre2FastaMapping(seq, ps); + + String mappingOutput = mappingDetails.toString(); + StructureMapping phyre2ModelMapping = new StructureMapping(seq, + pdbFile, structureFile.getId(), chain, mapping, mappingOutput); + return phyre2ModelMapping; + } + + public HashMap getPhyre2FastaMapping(SequenceI inputSeq, + java.io.PrintStream os) + { + HashMap mapping = new HashMap(); + AlignmentI seq2Phyre2ModelFastaMapping = null; + try + { + seq2Phyre2ModelFastaMapping = new FormatAdapter().readFile( + getFastaMappingFile(), DataSourceType.FILE, FileFormat.Fasta); + } catch (IOException e1) + { + e1.printStackTrace(); + } + SequenceI[] seqs = seq2Phyre2ModelFastaMapping.getSequencesArray(); + SequenceI tSequenceRes = seqs[0]; + SequenceI tStructureRes = seqs[1]; + + // Essential to resolve fastaAlignment to input sequence and model sequence + // coordinates + tSequenceRes.setStart(inputSeq.getStart()); + tSequenceRes.setEnd(inputSeq.getEnd()); + + tStructureRes.setStart(structureFile.getSeqsAsArray()[0].getStart()); + tStructureRes.setEnd(structureFile.getSeqsAsArray()[0].getEnd()); + try + { + int sequenceResLenght = tSequenceRes.getLength(); + int structureResLenght = tStructureRes.getLength(); + if (sequenceResLenght == structureResLenght) + { + int prevStructResNum = -1; + int alignmentLenght = sequenceResLenght + tSequenceRes.getStart(); + for (int x = 0; x < alignmentLenght; x++) + { + int alignSeqResidueIndex = tSequenceRes.findIndex(x); + int structResNum = tStructureRes + .findPosition(alignSeqResidueIndex); + int sequenceResNum = tSequenceRes + .findPosition(alignSeqResidueIndex - 1); + boolean sameResNum = (structResNum == prevStructResNum); + // System.out.println(sequenceResNum + " : " + // + (sameResNum ? -1 : prevStructResNum)); + mapping.put(sequenceResNum, new int[] { + sameResNum ? -1 : prevStructResNum, -1 }); + prevStructResNum = structResNum; + } + } + } catch (Exception e) + { + e.printStackTrace(); + } + + try + { + populateAtomPositions(" ", mapping); + } catch (IllegalArgumentException e) + { + e.printStackTrace(); + } catch (StructureMappingException e) + { + e.printStackTrace(); + } + + if (os != null) + { + MappingOutputModel mop = new MappingOutputModel(); + mop.setSeqStart(tSequenceRes.getStart()); + mop.setSeqEnd(tSequenceRes.getEnd()); + mop.setSeqName(tSequenceRes.getName()); + mop.setSeqResidue(tSequenceRes.getSequenceAsString()); + + mop.setStrStart(tStructureRes.getStart()); + mop.setStrEnd(tStructureRes.getEnd()); + mop.setStrName(tStructureRes.getName()); + mop.setStrResidue(tStructureRes.getSequenceAsString()); + + mop.setType("pep"); + try + { + os.print(getMappingOutput(mop).toString()); + } catch (Exception e) + { + e.printStackTrace(); + } + os.println(); + } + return mapping; + } + + private String getFastaMappingFile() + { + File phyre2ModelFile = new File(structureFile.getDataName()); + String phyre2ModelResultDir = phyre2ModelFile.getParent(); + String modelId = structureFile.getId().substring(0, + structureFile.getId().lastIndexOf(".pdb")); + return phyre2ModelResultDir + PATH_SEPARATOR + modelId + ".fasta"; + } + + @Override + public StringBuffer getMappingOutput(MappingOutputModel mp) + throws StructureMappingException + { + String seqRes = mp.getSeqResidue(); + String seqName = mp.getSeqName(); + int sStart = mp.getSeqStart(); + int sEnd = mp.getSeqEnd(); + + String strRes = mp.getStrResidue(); + String strName = mp.getStrName(); + int pdbStart = mp.getStrStart(); + int pdbEnd = mp.getStrEnd(); + + String type = mp.getType(); + + int maxid = (seqName.length() >= strName.length()) ? seqName.length() + : strName.length(); + int len = 72 - maxid - 1; + + int nochunks = ((seqRes.length()) / len) + + ((seqRes.length()) % len > 0 ? 1 : 0); + // output mappings + StringBuffer output = new StringBuffer(); + output.append(NEWLINE); + output.append("Sequence \u27f7 Structure mapping details").append( + NEWLINE); + output.append("Method: Phyre2 Alignment"); + output.append(NEWLINE).append(NEWLINE); + + output.append(new Format("%" + maxid + "s").form(seqName)); + output.append(" : "); + output.append(String.valueOf(sStart)); + output.append(" - "); + output.append(String.valueOf(sEnd)); + output.append(" Maps to "); + output.append(NEWLINE); + output.append(new Format("%" + maxid + "s").form(strName)); + output.append(" : "); + output.append(String.valueOf(pdbStart)); + output.append(" - "); + output.append(String.valueOf(pdbEnd)); + output.append(NEWLINE).append(NEWLINE); + + int matchedSeqCount = 0; + for (int j = 0; j < nochunks; j++) + { + // Print the first aligned sequence + output.append(new Format("%" + (maxid) + "s").form(seqName)).append( + " "); + + for (int i = 0; i < len; i++) + { + if ((i + (j * len)) < seqRes.length()) + { + output.append(seqRes.charAt(i + (j * len))); + } + } + + output.append(NEWLINE); + output.append(new Format("%" + (maxid) + "s").form(" ")).append(" "); + + // Print out the matching chars + for (int i = 0; i < len; i++) + { + try + { + if ((i + (j * len)) < seqRes.length()) + { + boolean sameChar = Comparison.isSameResidue( + seqRes.charAt(i + (j * len)), + strRes.charAt(i + (j * len)), false); + if (sameChar + && !jalview.util.Comparison.isGap(seqRes.charAt(i + + (j * len)))) + { + matchedSeqCount++; + output.append("|"); + } + else if (type.equals("pep")) + { + if (ResidueProperties.getPAM250(seqRes.charAt(i + (j * len)), + strRes.charAt(i + (j * len))) > 0) + { + output.append("."); + } + else + { + output.append(" "); + } + } + else + { + output.append(" "); + } + } + } catch (IndexOutOfBoundsException e) + { + continue; + } + } + // Now print the second aligned sequence + output = output.append(NEWLINE); + output = output.append(new Format("%" + (maxid) + "s").form(strName)) + .append(" "); + for (int i = 0; i < len; i++) + { + if ((i + (j * len)) < strRes.length()) + { + output.append(strRes.charAt(i + (j * len))); + } + } + output.append(NEWLINE).append(NEWLINE); + } + float pid = (float) matchedSeqCount / seqRes.length() * 100; + // if (pid < SiftsSettings.getFailSafePIDThreshold()) + // { + // throw new Exception(">>> Low PID detected for Phyre2 mapping..."); + // } + output.append("Length of alignment = " + seqRes.length()).append( + NEWLINE); + output.append(new Format("Percentage ID = %2.2f").form(pid)); + return output; + } + + + + public static List parsePhyre2ResultSummaryTable( + String html) + { + List phyre2Results = new ArrayList(); + try + { + File in = new File(html); + Document doc = Jsoup.parse(in, null); + // Document doc = Jsoup.connect(html).get(); + Elements tableElements = doc.select("table.midshade"); + for (Element table : tableElements) + { + System.out.println(); + Elements tableRowElements = table.select(":not(thead) tr"); + for (int i = 0; i < tableRowElements.size(); i++) + { + Element row = tableRowElements.get(i); + Elements rowItems = row.select("td"); + if (rowItems.size() > 11) + { + // for (int j = 0; j < rowItems.size(); j++) + // { + // System.out.println(">>> r:" + j + " = " + // + rowItems.get(j).text()); + // } + + String c = rowItems.get(6).select("input").attr("onmouseover"); + String alignedRange = c.substring(c.indexOf("Residues ") + 9, + c.indexOf(" of your sequence aligned ")); + String coverage = c.substring(c.lastIndexOf(" (") + 2, + c.lastIndexOf(" coverage). Click to view detailed")); + // System.out.println("coverage" + coverage); + try + { + Phyre2SummaryPojo psp = new Phyre2SummaryPojo(); + String sn = rowItems.get(0).text(); + psp.setSerialNo(Integer.valueOf(sn)); + psp.setTemplateId(rowItems.get(1).text()); + psp.setCoverage(coverage); + psp.setAlignedRange(alignedRange); + psp.setConfidence(Double.valueOf(rowItems.get(8).text())); + psp.setPid(Integer.valueOf(rowItems.get(9).text())); + psp.setTemplateSummary(rowItems.get(10).text()); + // System.out.println("row >>>> " + psp.toString()); + // System.out.println(); + phyre2Results.add(psp); + } catch (NumberFormatException e) + { + e.printStackTrace(); + } catch (IndexOutOfBoundsException e) + { + e.printStackTrace(); + } catch (Exception e) + { + e.printStackTrace(); + } + } + } + } + return phyre2Results; + + } catch (Exception e) + { + e.printStackTrace(); + return null; + } + } + + public static DefaultTableModel getTableModel( + List phyreResults) + { + if (phyreResults == null) + { + return null; + } + DefaultTableModel tableModel = new DefaultTableModel() + { + @Override + public boolean isCellEditable(int row, int column) + { + return false; + } + + @Override + public Class getColumnClass(int columnIndex) + { + switch (columnIndex) + { + case 0: + return Integer.class; + case 1: + return String.class; + case 2: + return String.class; + case 3: + return String.class; + case 4: + return Double.class; + case 5: + return Integer.class; + case 6: + return String.class; + default: + return String.class; + } + } + + }; + + tableModel.addColumn("#"); + tableModel.addColumn("Template"); + tableModel.addColumn("Aligned Range"); + tableModel.addColumn("Coverage"); + tableModel.addColumn("Confidence"); + tableModel.addColumn("%.i.d"); + tableModel.addColumn("Template Information"); + + for (Phyre2SummaryPojo res : phyreResults) + { + tableModel.addRow(new Object[] { res.getSerialNo(), + res.getTemplateId(), res.getAlignedRange(), res.getCoverage(), + res.getConfidence(), res.getPid(), res.getTemplateSummary() }); + } + return tableModel; + } + + public static void configurePhyreResultTable(JTable phyreResultTable) + { + + DecimalFormatTableCellRenderer idCellRender = new DecimalFormatTableCellRenderer( + true, 0); + DecimalFormatTableCellRenderer pidCellRender = new DecimalFormatTableCellRenderer( + true, 1); + DecimalFormatTableCellRenderer confidenceCellRender = new DecimalFormatTableCellRenderer( + true, 1); + + phyreResultTable.getColumn("#").setMinWidth(20); + phyreResultTable.getColumn("#").setPreferredWidth(30); + phyreResultTable.getColumn("#").setMaxWidth(40); + phyreResultTable.getColumn("#").setCellRenderer(idCellRender); + + phyreResultTable.getColumn("Template").setMinWidth(60); + phyreResultTable.getColumn("Template").setPreferredWidth(60); + phyreResultTable.getColumn("Template").setMaxWidth(90); + + phyreResultTable.getColumn("Aligned Range").setMinWidth(80); + phyreResultTable.getColumn("Aligned Range").setPreferredWidth(80); + phyreResultTable.getColumn("Aligned Range").setMaxWidth(120); + + phyreResultTable.getColumn("Coverage").setMinWidth(60); + phyreResultTable.getColumn("Coverage").setPreferredWidth(60); + phyreResultTable.getColumn("Coverage").setMaxWidth(90); + + phyreResultTable.getColumn("Confidence").setMinWidth(60); + phyreResultTable.getColumn("Confidence").setPreferredWidth(60); + phyreResultTable.getColumn("Confidence").setMaxWidth(90); + phyreResultTable.getColumn("Confidence").setCellRenderer( + confidenceCellRender); + + phyreResultTable.getColumn("%.i.d").setMinWidth(45); + phyreResultTable.getColumn("%.i.d").setPreferredWidth(450); + phyreResultTable.getColumn("%.i.d").setMaxWidth(65); + phyreResultTable.getColumn("%.i.d").setCellRenderer(pidCellRender); + + phyreResultTable.getColumn("Template Information").setMinWidth(400); + phyreResultTable.getColumn("Template Information").setPreferredWidth( + 600); + phyreResultTable.getColumn("Template Information").setMaxWidth(1500); + } +}