From b8cd52fe7bed59130e5b080acfd42c3ef2effdbb Mon Sep 17 00:00:00 2001 From: tcofoegbu Date: Mon, 5 Jun 2017 14:48:53 +0100 Subject: [PATCH] JAL-2136 Introduced DynamicData model, modified AnnotionFile to store Phyre meta-data in DynamicData object, modified SequenceAnnotationReport to build Phyre html meta-data from DynamicData list --- src/jalview/datamodel/DynamicData.java | 97 ++++++++++++++++++++ src/jalview/io/AnnotationFile.java | 48 +++++----- src/jalview/io/AnnotationUtil.java | 124 ++++++++++++++++++++++++++ src/jalview/io/SequenceAnnotationReport.java | 65 +++++++++++++- test/jalview/io/AnnotationFileIOTest.java | 45 ++++------ 5 files changed, 320 insertions(+), 59 deletions(-) create mode 100644 src/jalview/datamodel/DynamicData.java create mode 100644 src/jalview/io/AnnotationUtil.java diff --git a/src/jalview/datamodel/DynamicData.java b/src/jalview/datamodel/DynamicData.java new file mode 100644 index 0000000..18d350f --- /dev/null +++ b/src/jalview/datamodel/DynamicData.java @@ -0,0 +1,97 @@ +package jalview.datamodel; + +public class DynamicData +{ + + private String fieldTitle; + + private String fieldValue; + + private DataType dataType; + + private String source; + + private Boolean display; + + public enum DataType + { + N("Number"), S("String"), B("Boolean"); + + private String name; + + DataType(String name) + { + this.setName(name); + } + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } + } + + public DynamicData(String fieldTitle, String fieldValue, + DataType dataType, String source, Boolean display) + { + this.fieldTitle = fieldTitle; + this.fieldValue = fieldValue; + this.dataType = dataType; + this.source = source; + this.display = display; + } + + public String getFieldTitle() + { + return fieldTitle; + } + + public void setFieldTitle(String fieldTitle) + { + this.fieldTitle = fieldTitle; + } + + public String getSource() + { + return source; + } + + public void setSource(String source) + { + this.source = source; + } + + public DataType getDataType() + { + return dataType; + } + + public void setDataType(DataType dataType) + { + this.dataType = dataType; + } + + public String getFieldValue() + { + return fieldValue; + } + + public void setFieldValue(String fieldValue) + { + this.fieldValue = fieldValue; + } + + public Boolean isDisplay() + { + return display; + } + + public void setDisplay(Boolean display) + { + this.display = display; + } +} diff --git a/src/jalview/io/AnnotationFile.java b/src/jalview/io/AnnotationFile.java index 206d971..a22b7a4 100755 --- a/src/jalview/io/AnnotationFile.java +++ b/src/jalview/io/AnnotationFile.java @@ -26,6 +26,8 @@ import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.AlignmentI; import jalview.datamodel.Annotation; import jalview.datamodel.ColumnSelection; +import jalview.datamodel.DynamicData; +import jalview.datamodel.DynamicData.DataType; import jalview.datamodel.GraphLine; import jalview.datamodel.HiddenSequences; import jalview.datamodel.PDBEntry; @@ -1293,9 +1295,9 @@ public class AnnotationFile PDBEntry phyre2PDBEntry = new PDBEntry(modelName, " ", Type.PDB, structureModelFile); - String phyre2ModelDesc = generatePhyre2InfoHTMLTable( + List phyreDD = generatePhyreDynamicDataList( structModelHeader, structModelData); - phyre2PDBEntry.setProperty("PHYRE2_MODEL_INFO", phyre2ModelDesc); + phyre2PDBEntry.setProperty("DYNAMIC_DATA_PHYRE2", phyreDD); templateSeq.getDatasetSequence().addPDBId(phyre2PDBEntry); if (querySequence != null) { @@ -1318,37 +1320,33 @@ public class AnnotationFile return added; } - static String generatePhyre2InfoHTMLTable(String[] structModelHeader, - String[] structModelData) + static List generatePhyreDynamicDataList( + String[] headerArray, + String[] dataArray) { - StringBuilder phyre2InfoBuilder = new StringBuilder(); - if (isGenerateStructInfoHtml(structModelHeader, structModelData)) + + if (headerArray == null || dataArray == null) { - phyre2InfoBuilder.append("") - .append(""); - for (int x = 4; x < structModelData.length; x++) - { - phyre2InfoBuilder.append(""); - } - phyre2InfoBuilder.append("
Phyre2 Template Info
").append(structModelHeader[x]) - .append("").append(structModelData[x]) - .append("
"); + throw new IllegalArgumentException( + "Header or data arrays must not be null"); } - return phyre2InfoBuilder.toString(); - } - static boolean isGenerateStructInfoHtml(String[] header, String[] data) - { - boolean generate = true; - if (header == null || data == null) + if (headerArray.length != dataArray.length) { - return false; + throw new IllegalArgumentException( + "Header and data arrays must be of same lenght"); } - if (header.length < 3 || data.length < 3) + List dynamicDataList = new ArrayList(); + int x = 0; + for (String data : dataArray) { - generate = false; + // first four column should be hidden; + boolean show = (x > 4); + dynamicDataList.add(new DynamicData(headerArray[x], data, DataType.S, + "PHYRE2", show)); + x++; } - return generate; + return dynamicDataList; } static String resolveAbsolutePath(String relURI, String _baseUri) diff --git a/src/jalview/io/AnnotationUtil.java b/src/jalview/io/AnnotationUtil.java new file mode 100644 index 0000000..4973d5e --- /dev/null +++ b/src/jalview/io/AnnotationUtil.java @@ -0,0 +1,124 @@ +package jalview.io; + +import jalview.analysis.AAFrequency; +import jalview.analysis.Conservation; +import jalview.datamodel.AlignmentAnnotation; +import jalview.datamodel.AlignmentI; +import jalview.datamodel.Annotation; +import jalview.datamodel.ProfilesI; +import jalview.datamodel.SequenceI; + +public class AnnotationUtil +{ + + public static AlignmentAnnotation getConsensusAnnotationFromFile( + String file) + { + AlignmentI alignment = readAlignmentFile(file); + // AlignFrame af = new AlignFrame(alignment, 5, 5); + // af.setVisible(false); + // AlignmentAnnotation consensus = af.getViewport() + // .getAlignmentConsensusAnnotation(); + // af.dispose(); + // System.out.println(consensus); + + SequenceI[] alignmentSeqs = alignment.getSequencesArray(); + int width = alignment.getWidth(); + long nseq = alignmentSeqs.length; + boolean ignoreGapsConsensus = true; + boolean showSequenceLogo = false; + + AlignmentAnnotation consensusAnnotation = new AlignmentAnnotation( + "Consensus", + "PID", new Annotation[1], 0f, 100f, + AlignmentAnnotation.BAR_GRAPH); + consensusAnnotation.hasText = true; + consensusAnnotation.autoCalculated = true; + + alignment.addAnnotation(consensusAnnotation); + ProfilesI hconsensus = AAFrequency.calculate(alignmentSeqs, width, 0, + width, + true); + + AAFrequency.completeConsensus(consensusAnnotation, hconsensus, + hconsensus.getStartColumn(), hconsensus.getEndColumn() + 1, + ignoreGapsConsensus, showSequenceLogo, nseq); + + System.out.println(">>>>> Consensus Annotation : " + + consensusAnnotation); + return consensusAnnotation; + } + + public static AlignmentAnnotation getConservationAnnotationFromFile( + String file, SequenceI seqRef) + { + AlignmentAnnotation conservationAnnotation = null; + int foundAnnotCount = seqRef.getAnnotation().length; + if (seqRef != null && foundAnnotCount < 3) + { + AlignmentI alignment = readAlignmentFile("/Users/tcnofoegbu/Desktop/query.jal"); + // AlignmentI alignment = readAlignmentFile(file); + // ColumnSelection cs = new ColumnSelection(); + // SequenceI querySeq = alignment.getSequenceAt(0); + // cs.hideInsertionsFor(querySeq); + // AlignViewport av = new AlignViewport(alignment); + // av.setColumnSelection(cs); + // + // alignment = av.getAlignment(); + int alWidth = alignment.getWidth(); + int ConsPercGaps = 25; + + AlignmentAnnotation quality = new AlignmentAnnotation("Quality", + "Alignment Quality based on Blosum62 scores", + new Annotation[1], 0f, 11f, AlignmentAnnotation.BAR_GRAPH); + quality.hasText = true; + quality.autoCalculated = true; + + conservationAnnotation = new AlignmentAnnotation("Conservation", + "PID", new Annotation[1], 0f, 100f, + AlignmentAnnotation.BAR_GRAPH); + conservationAnnotation.hasText = true; + conservationAnnotation.autoCalculated = true; + alignment.addAnnotation(conservationAnnotation); + Conservation cons = Conservation.calculateConservation("All", + alignment.getSequences(), 0, alWidth - 1, false, + ConsPercGaps, quality != null); + cons.completeAnnotations(conservationAnnotation, quality, 0, alWidth); + System.out.println(">>>"); + + conservationAnnotation.createSequenceMapping(seqRef, 1, true); + seqRef.addAlignmentAnnotation(conservationAnnotation); + + // conservationAnnotation.createSequenceMapping( + // seqRef.getDatasetSequence(), 1, true); + // seqRef.getDatasetSequence().addAlignmentAnnotation( + // conservationAnnotation); + } + + return conservationAnnotation; + } + + private static AlignmentI readAlignmentFile(String f) + { + System.out.println("Reading file: " + f); + try + { + FormatAdapter rf = new FormatAdapter(); + DataSourceType protocol = AppletFormatAdapter.checkProtocol(f); + AlignmentI al = rf.readFile(f, protocol, + new IdentifyFile().identify(f, protocol)); + return al; + } catch (Exception e) + { + e.printStackTrace(); + } + return null; + } + + public static void main(String[] args) + { + // getConservationAnnotationFromFile("http://www.sbg.bio.ic.ac.uk/phyre2/phyre2_output/cd1b897af035cdf5/query.jal"); + getConsensusAnnotationFromFile("http://www.sbg.bio.ic.ac.uk/phyre2/phyre2_output/cd1b897af035cdf5/query.jal"); + } + +} diff --git a/src/jalview/io/SequenceAnnotationReport.java b/src/jalview/io/SequenceAnnotationReport.java index a855aa2..3a7ee65 100644 --- a/src/jalview/io/SequenceAnnotationReport.java +++ b/src/jalview/io/SequenceAnnotationReport.java @@ -22,6 +22,7 @@ package jalview.io; import jalview.datamodel.DBRefEntry; import jalview.datamodel.DBRefSource; +import jalview.datamodel.DynamicData; import jalview.datamodel.PDBEntry; import jalview.datamodel.SequenceFeature; import jalview.datamodel.SequenceI; @@ -450,15 +451,71 @@ public class SequenceAnnotationReport } } sb.append(""); + List pdbEntries = ds.getAllPDBEntries(); + sb.append(getToolTipTextFromPDBEntries(pdbEntries)); + return maxWidth; + } - for (PDBEntry pdb : ds.getAllPDBEntries()) + private String getToolTipTextFromPDBEntries(List pdbEntries) + { + String tooltip = ""; + if (pdbEntries.isEmpty()) { - if (pdb != null && pdb.getProperty("PHYRE2_MODEL_INFO") != null) + return tooltip; + } + if (pdbEntries.size() > 1) + { + int x = 0; + PDBEntry bestRanked = null; + for (PDBEntry pdb : pdbEntries) { - sb.append(pdb.getProperty("PHYRE2_MODEL_INFO")); + if (pdb.getProperty("DYNAMIC_DATA_PHYRE2") != null) + { + x++; + } + // best ranked entry must be from a Phyre + if (x > 0 && bestRanked == null) + { + bestRanked = pdb; + } } + tooltip = (x > 0) ? "" + + "
Contains " + + x + + " Phyre2 model structure(s)
Best ranked Phyre2 model is " + + bestRanked.getId() + "
" + : ""; } - return maxWidth; + else + { + PDBEntry pdb = pdbEntries.iterator().next(); + if (pdb.getProperty("DYNAMIC_DATA_PHYRE2") != null) + { + tooltip = getPhyreToolTipFromDynamicData((List) pdb + .getProperty("DYNAMIC_DATA_PHYRE2")); + } + } + return tooltip; + } + + private String getPhyreToolTipFromDynamicData( + List dynamicDataList) + { + StringBuilder phyre2InfoBuilder = new StringBuilder(); + phyre2InfoBuilder + .append("") + .append(""); + for (DynamicData data : dynamicDataList) + { + if (data.isDisplay()) + { + phyre2InfoBuilder.append(""); + } + } + phyre2InfoBuilder.append("
Phyre2 Template Info
").append(data.getFieldTitle()) + .append("").append(data.getFieldValue()) + .append("
"); + return phyre2InfoBuilder.toString(); } public void createTooltipAnnotationReport(final StringBuilder tip, diff --git a/test/jalview/io/AnnotationFileIOTest.java b/test/jalview/io/AnnotationFileIOTest.java index 4bc8c3b..e016f54 100644 --- a/test/jalview/io/AnnotationFileIOTest.java +++ b/test/jalview/io/AnnotationFileIOTest.java @@ -25,16 +25,17 @@ import static org.testng.AssertJUnit.assertTrue; import jalview.datamodel.AlignmentI; import jalview.datamodel.ColumnSelection; +import jalview.datamodel.DynamicData; import jalview.datamodel.PDBEntry; import jalview.datamodel.PDBEntry.Type; import jalview.datamodel.SequenceI; -import jalview.gui.Desktop; import jalview.gui.JvOptionPane; import jalview.io.AnnotationFile.ViewDef; import jalview.structure.StructureSelectionManager; import java.io.File; import java.util.Hashtable; +import java.util.List; import org.testng.Assert; import org.testng.annotations.BeforeClass; @@ -177,6 +178,14 @@ public class AnnotationFileIOTest @BeforeClass(alwaysRun = true) void testProcessStructModel() { + try + { + + ssm = StructureSelectionManager.getStructureSelectionManager(); + } catch (NullPointerException e) + { + ssm = new StructureSelectionManager(); + } File alignmentFile = new File( "examples/testdata/phyre2results/56da5616b4559c93/allhits.fasta"); String annotationFile = "examples/testdata/phyre2results/56da5616b4559c93/allhits.ann"; @@ -185,8 +194,6 @@ public class AnnotationFileIOTest boolean annotationRead = new AnnotationFile().readAnnotationFile(al, cs, annotationFile, DataSourceType.FILE); Assert.assertTrue(annotationRead); - ssm = StructureSelectionManager - .getStructureSelectionManager(Desktop.instance); System.out.println("bla"); } @@ -208,9 +215,11 @@ public class AnnotationFileIOTest PDBEntry expectedPDBEntry = new PDBEntry(pdbId, " ", Type.PDB, baseDir + pdbId); - String phyre2ModelDesc = AnnotationFile.generatePhyre2InfoHTMLTable(structModelHeader, - structModelData); - expectedPDBEntry.setProperty("PHYRE2_MODEL_INFO", phyre2ModelDesc); + List phyreDD = AnnotationFile + .generatePhyreDynamicDataList(structModelHeader, + structModelData); + expectedPDBEntry.setProperty("DYNAMIC_DATA_PHYRE2", phyreDD); + Assert.assertEquals(actualPDBEntry, expectedPDBEntry); } @@ -228,30 +237,6 @@ public class AnnotationFileIOTest expectedPhyre2FastaMappingFile); } - @Test( - groups = { "Functional" }, - dataProvider = "phyre2InfoHTMLTableDataProvider") - void testGeneratePhyre2InfoHTMLTable(String caseDescription, - String[] header, String[] data, String expectedHtml) - { - System.out.println(">>>> Testing Case - " + caseDescription); - String actualHtmlGenerated = AnnotationFile - .generatePhyre2InfoHTMLTable(header, data); - System.out.println("-----> " + actualHtmlGenerated); - Assert.assertEquals(actualHtmlGenerated, expectedHtml); - } - - @Test( - groups = { "Functional" }, - dataProvider = "StructModelHtmlDataProvider") - void testIsGenerateStructInfoHtml(String caseDescription, - String[] header, String[] data, boolean expectedOutcome) - { - System.out.println(">>>> Testing Case - " + caseDescription); - boolean actual = AnnotationFile.isGenerateStructInfoHtml(header, data); - Assert.assertEquals(actual, expectedOutcome); - } - @Test(groups = { "Functional" }, dataProvider = "FilePathProvider") void testResolveAbsolutePath(String caseDescription, String suppliedPath, String baseURI, String expectedURI) -- 1.7.10.2