From 13953b6236c6b5de369e3598358d833e07328508 Mon Sep 17 00:00:00 2001 From: Charles Ofoegbu Date: Wed, 12 Nov 2014 09:30:02 +0000 Subject: [PATCH] Modified biojs exporter/importer to preserve SequenceFeatures during a write/read operation --- examples/example_biojs.html | 199 +++++++------------- resources/templates/BioJSTemplate.txt | 150 +++------------ src/jalview/io/BioJsHTMLOutput.java | 67 +++++-- src/jalview/io/FileLoader.java | 7 + src/jalview/io/HtmlFile.java | 185 +++++++++++++----- .../json/binding/v1/BioJsAlignmentPojo.java | 105 +++++++++++ src/jalview/json/binding/v1/BioJsFeaturePojo.java | 60 ++++++ src/jalview/json/binding/v1/BioJsSeqPojo.java | 40 +++- 8 files changed, 494 insertions(+), 319 deletions(-) create mode 100644 src/jalview/json/binding/v1/BioJsFeaturePojo.java diff --git a/examples/example_biojs.html b/examples/example_biojs.html index 1d602d6..5b0d71e 100644 --- a/examples/example_biojs.html +++ b/examples/example_biojs.html @@ -1,117 +1,4 @@ - - -
BioJS viewer
@@ -119,20 +6,22 @@ - - - -
press "Run with JS"
- -
-
-
This html page was generated from Jalview, to import the data back to Jalview, please drag the generated html file and drop it unto the Jalview workbench.
-
-
Alternatively, you could copy the url from the address bar and use Jalview's url importer (main menu-> File-> Input Alignment-> from URL) to import back the alignment jalview. + + Jalview Logo +

+ + +
+
+ +
press "Run with JS"
+ @@ -140,6 +29,52 @@ diff --git a/resources/templates/BioJSTemplate.txt b/resources/templates/BioJSTemplate.txt index 88ade1a..d86fa65 100644 --- a/resources/templates/BioJSTemplate.txt +++ b/resources/templates/BioJSTemplate.txt @@ -1,117 +1,4 @@ - - -
BioJS viewer
@@ -119,20 +6,22 @@ - - -
press "Run with JS"
- -
-
-
This html page was generated from Jalview, to import the data back to Jalview, please drag the generated html file and drop it unto the Jalview workbench.
-
-
Alternatively, you could copy the url from the address bar and use Jalview's url importer (main menu-> File-> Input Alignment-> from URL) to import back the alignment jalview. + + Jalview Logo +

- + + +
+
+ +
press "Run with JS"
+ @@ -148,10 +37,10 @@ function toggleMenuVisibility(){ var divToggleButton = document.getElementById("divToggleButton"); if(menu[0].style.display == 'block'){ menu[0].style.display = 'none'; - divToggleButton.value="Show BioJs Menu"; + divToggleButton.value="Show Menu"; }else{ menu[0].style.display = 'block'; - divToggleButton.value="Hide BioJs Menu"; + divToggleButton.value="Hide Menu"; } } function openJalviewUsingCurrentUrl2(){ @@ -9133,7 +9022,8 @@ var opts = {}; // set your custom properties // @see: https://github.com/greenify/biojs-vis-msa/tree/master/src/g -opts.seqs = JSON.parse(document.getElementById("seqData").value); +var jalviewData = JSON.parse(document.getElementById("seqData").value); +opts.seqs = jalviewData['seqs']; opts.el = document.getElementById("yourDiv"); opts.vis = {conserv: false, overviewbox: false, labelId: false}; @@ -9144,7 +9034,13 @@ opts.zoomer = {alignmentHeight: 225, labelWidth: 130,labelFontsize: "13px",label // init msa var m = new msa.msa(opts); -m.g.colorscheme.set("scheme", "#scheme#"); +m.g.colorscheme.set("scheme", jalviewData['globalColorScheme']); + +var x = 0; +jalviewData.seqs.forEach( function (seq) +{ +m.seqs.at(x++).set("features", new msa.model.featurecol(seq.features)); +}); // the menu is independent to the MSA container var menuOpts = {}; diff --git a/src/jalview/io/BioJsHTMLOutput.java b/src/jalview/io/BioJsHTMLOutput.java index d4c9ba0..068b4b2 100644 --- a/src/jalview/io/BioJsHTMLOutput.java +++ b/src/jalview/io/BioJsHTMLOutput.java @@ -1,13 +1,16 @@ package jalview.io; import jalview.datamodel.AlignmentI; +import jalview.datamodel.SequenceFeature; import jalview.datamodel.SequenceI; import jalview.gui.AlignViewport; import jalview.gui.AlignmentPanel; import jalview.gui.FeatureRenderer; import jalview.gui.SequenceRenderer; import jalview.json.binding.v1.BioJsAlignmentPojo; +import jalview.json.binding.v1.BioJsFeaturePojo; import jalview.json.binding.v1.BioJsSeqPojo; +import jalview.schemes.ColourSchemeProperty; import jalview.util.MessageManager; import java.io.BufferedReader; @@ -15,6 +18,7 @@ import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.URL; +import java.util.ArrayList; import com.json.JSONException; @@ -30,6 +34,7 @@ public class BioJsHTMLOutput this.av = ap.av; this.fr = new FeatureRenderer(ap); fr.transferSettings(fr1); + exportAsBioJsHtml(); } @@ -79,35 +84,75 @@ public class BioJsHTMLOutput throws IOException, JSONException { BioJsAlignmentPojo bjsAlignment = new BioJsAlignmentPojo(); + bjsAlignment.setGlobalColorScheme(ColourSchemeProperty.getColourName(av + .getGlobalColourScheme())); + + // av.setGlobalColourScheme(cs); int count = 0; for (SequenceI seq : alignment.getSequences()) { StringBuilder name = new StringBuilder(); name.append(seq.getName()).append("/").append(seq.getStart()) .append("-").append(seq.getEnd()); - bjsAlignment.getSeqs().add( - new BioJsSeqPojo(String.valueOf(++count), name.toString(), - seq.getSequenceAsString())); + // BioJsSeqPojo seqPojo = new BioJsSeqPojo(seq.getStart(), seq.getEnd(), + // String.valueOf(++count), + // name.toString(), seq.getSequenceAsString()); + // + BioJsSeqPojo seqPojo = new BioJsSeqPojo(); + seqPojo.setId(String.valueOf(++count)); + seqPojo.setEnd(seq.getEnd()); + seqPojo.setStart(seq.getStart()); + seqPojo.setName(name.toString()); + seqPojo.setSeq(seq.getSequenceAsString()); + + SequenceFeature[] seqFeatures = seq.getDatasetSequence() + .getSequenceFeatures(); + if (seqFeatures != null) + { + + ArrayList bjsSeqFeatures = new ArrayList(); + for (SequenceFeature sf : seqFeatures) + { + + String featureColour = jalview.util.Format.getHexString(fr + .getColour(sf)); + BioJsFeaturePojo bjsFeature = new BioJsFeaturePojo(); + bjsFeature.setFillColor(featureColour); + bjsFeature.setXstart(sf.getBegin()); + bjsFeature.setXend(sf.getEnd()); + bjsFeature.setText(sf.getType()); + + bjsSeqFeatures.add(bjsFeature); + + } + + seqPojo.setFeatures(bjsSeqFeatures); + } + bjsAlignment.getSeqs().add(seqPojo); } - String seqs = new com.json.JSONObject(bjsAlignment).getString("seqs"); + String jalviewData = new com.json.JSONObject(bjsAlignment).toString() + .replaceAll("xstart", "xStart").replaceAll("xend", "xEnd"); // String bioJSTemplate = new String( // java.nio.file.Files.readAllBytes(java.nio.file.Paths // .get("resources/templates/BioJSTemplate.txt"))); - String bioJSTemplate = getBioJsTemplateAsString(alignment); - - return bioJSTemplate.replaceAll("#sequenceData#", seqs).replaceAll( - "#scheme#", "zappo"); + String bioJSTemplate = getBioJsTemplateAsString(this); + + return bioJSTemplate.replaceAll("#sequenceData#", jalviewData) + .replaceAll( + "#jalview_logo#", + alignment.getClass() + .getResource("/images/Jalview_Logo.png") + .toString()); } - - public static String getBioJsTemplateAsString(AlignmentI bio) + public static String getBioJsTemplateAsString(Object currentObj) throws IOException { InputStreamReader isReader = null; BufferedReader buffReader = null; StringBuilder sb = new StringBuilder(); - URL url = bio.getClass().getResource( + URL url = currentObj.getClass().getResource( "/templates/BioJSTemplate.txt"); if (url != null) { diff --git a/src/jalview/io/FileLoader.java b/src/jalview/io/FileLoader.java index 82b94c3..29f5632 100755 --- a/src/jalview/io/FileLoader.java +++ b/src/jalview/io/FileLoader.java @@ -152,6 +152,7 @@ public class FileLoader implements Runnable public AlignFrame LoadFileWaitTillLoaded(FileParse source, String format) { this.source = source; + file = source.getInFile(); protocol = source.type; this.format = format; @@ -352,6 +353,12 @@ public class FileLoader implements Runnable { alignFrame.setFileName(file, format); } + if (source instanceof HtmlFile) + { + ((HtmlFile) source).LoadAlignmentFeatures(alignFrame +); + + } if (raiseGUI) { // add the window to the GUI diff --git a/src/jalview/io/HtmlFile.java b/src/jalview/io/HtmlFile.java index bc5c219..a188290 100644 --- a/src/jalview/io/HtmlFile.java +++ b/src/jalview/io/HtmlFile.java @@ -1,6 +1,10 @@ package jalview.io; import jalview.datamodel.Sequence; +import jalview.datamodel.SequenceFeature; +import jalview.gui.AlignFrame; +import jalview.json.binding.v1.BioJsAlignmentPojo.JalviewBioJsColorSchemeMapper; +import jalview.schemes.ColourSchemeI; import java.io.IOException; import java.util.Iterator; @@ -12,57 +16,134 @@ import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; -public class HtmlFile extends AlignFile { - public static final String FILE_EXT = "html"; - - public static final String FILE_DESC = "HTML"; - - public HtmlFile() { - super(); - } - - public HtmlFile(FileParse source) throws IOException { - super(source); - } - - public HtmlFile(String inFile, String type) throws IOException { - super(inFile, type); - } - - @SuppressWarnings("unchecked") - @Override - public void parse() throws IOException { - try { - StringBuilder htmlData = new StringBuilder(); - String currentLine; - while ((currentLine = nextLine()) != null) { - htmlData.append(currentLine); - } - - Document doc = Jsoup.parse(htmlData.toString()); - Element content = doc.getElementById("seqData"); - - String alignmentJsonString = "{\"seqs\":" + content.val() + "}"; - JSONParser jsonParser = new JSONParser(); - JSONObject alignmentJsonObj = (JSONObject) jsonParser.parse(alignmentJsonString); - JSONArray seqJsonArray = (JSONArray) alignmentJsonObj.get("seqs"); - - for (Iterator sequenceIter = seqJsonArray.iterator(); sequenceIter.hasNext();) { - JSONObject sequence = sequenceIter.next(); - System.out.println(sequence.get("id").toString() + " " + sequence.get("name")); - String sequcenceString = sequence.get("seq").toString(); - Sequence seq = new Sequence(sequence.get("name").toString(), sequcenceString, 0, sequcenceString.length()); - seqs.add(seq); - - } - } catch (Exception e) { - e.printStackTrace(); - } - } - - @Override - public String print() { - throw new UnsupportedOperationException("Print method of HtmlFile not yet supported!"); - } +public class HtmlFile extends AlignFile +{ + public static final String FILE_EXT = "html"; + + public static final String FILE_DESC = "HTML"; + + private ColourSchemeI cs; + + public HtmlFile() + { + super(); + } + + public HtmlFile(FileParse source) throws IOException + { + super(source); + } + + public HtmlFile(String inFile, String type) throws IOException + { + super(inFile, type); + } + + @SuppressWarnings("unchecked") + @Override + public void parse() throws IOException + { + try + { + StringBuilder htmlData = new StringBuilder(); + String currentLine; + while ((currentLine = nextLine()) != null) + { + htmlData.append(currentLine); + } + + Document doc = Jsoup.parse(htmlData.toString()); + Element content = doc.getElementById("seqData"); + + String alignmentJsonString = content.val(); + JSONParser jsonParser = new JSONParser(); + JSONObject alignmentJsonObj = (JSONObject) jsonParser + .parse(alignmentJsonString); + JSONArray seqJsonArray = (JSONArray) alignmentJsonObj.get("seqs"); + String bioJsColourScheme = (String) alignmentJsonObj + .get("globalColorScheme"); + cs = getJalviewColorScheme(bioJsColourScheme); + + for (Iterator sequenceIter = seqJsonArray.iterator(); sequenceIter + .hasNext();) + { + JSONObject sequence = sequenceIter.next(); + String sequcenceString = sequence.get("seq").toString(); + Sequence seq = new Sequence(sequence.get("name").toString(), + sequcenceString, 0, sequcenceString.length()); + + JSONArray jsonSeqArray = (JSONArray) sequence.get("features"); + SequenceFeature[] retrievedSeqFeatures = getJalviewSequenceFeatures(jsonSeqArray); + if (retrievedSeqFeatures != null) + { + seq.setSequenceFeatures(retrievedSeqFeatures); + } + seqs.add(seq); + + } + } catch (Exception e) + { + e.printStackTrace(); + } + } + + public SequenceFeature[] getJalviewSequenceFeatures( + JSONArray jsonSeqFeatures) + { + SequenceFeature[] seqFeatures = null; + int count = 0; + if (jsonSeqFeatures != null) + { + seqFeatures = new SequenceFeature[jsonSeqFeatures.size()]; + for (Iterator seqFeatureItr = jsonSeqFeatures.iterator(); seqFeatureItr + .hasNext();) + { + + SequenceFeature sequenceFeature = new SequenceFeature(); + JSONObject jsonFeature = seqFeatureItr.next(); + Long begin = (Long) jsonFeature.get("xStart"); + Long end = (Long) jsonFeature.get("xEnd"); + String type = (String) jsonFeature.get("text"); + + String color = (String) jsonFeature.get("fillColor"); + + sequenceFeature.setBegin(begin.intValue()); + sequenceFeature.setEnd(end.intValue()); + sequenceFeature.setType(type); + seqFeatures[count++] = sequenceFeature; + } + } + return seqFeatures; + } + + public void LoadAlignmentFeatures(AlignFrame af) + { + + af.setShowSeqFeatures(true); + af.changeColour(cs); + af.setMenusForViewport(); + } + + private ColourSchemeI getJalviewColorScheme(String bioJsColourSchemeName) + { + ColourSchemeI jalviewColor = null; + for (JalviewBioJsColorSchemeMapper cs : JalviewBioJsColorSchemeMapper + .values()) + { + if (cs.getBioJsName().equals(bioJsColourSchemeName)) + { + jalviewColor = cs.getJvColourScheme(); + break; + } + } + return jalviewColor; + } + + @Override + public String print() + { + throw new UnsupportedOperationException( + "Print method of HtmlFile not yet supported!"); + } } diff --git a/src/jalview/json/binding/v1/BioJsAlignmentPojo.java b/src/jalview/json/binding/v1/BioJsAlignmentPojo.java index 893e16b..7c2fe10 100644 --- a/src/jalview/json/binding/v1/BioJsAlignmentPojo.java +++ b/src/jalview/json/binding/v1/BioJsAlignmentPojo.java @@ -1,9 +1,24 @@ package jalview.json.binding.v1; +import jalview.schemes.Blosum62ColourScheme; +import jalview.schemes.BuriedColourScheme; +import jalview.schemes.ColourSchemeI; +import jalview.schemes.HelixColourScheme; +import jalview.schemes.HydrophobicColourScheme; +import jalview.schemes.NucleotideColourScheme; +import jalview.schemes.PIDColourScheme; +import jalview.schemes.PurinePyrimidineColourScheme; +import jalview.schemes.RNAInteractionColourScheme; +import jalview.schemes.StrandColourScheme; +import jalview.schemes.TaylorColourScheme; +import jalview.schemes.TurnColourScheme; +import jalview.schemes.ZappoColourScheme; + import java.util.ArrayList; public class BioJsAlignmentPojo { + private String globalColorScheme = "none"; private ArrayList seqs = new ArrayList(); public BioJsAlignmentPojo() @@ -19,4 +34,94 @@ public class BioJsAlignmentPojo { this.seqs = seqs; } + public String getGlobalColorScheme() + { + return globalColorScheme; + } + public void setGlobalColorScheme(String globalColorScheme) + { + for (JalviewBioJsColorSchemeMapper cs : JalviewBioJsColorSchemeMapper + .values()) + { + if (cs.getJalviewName().equals(globalColorScheme)) + { + this.globalColorScheme = cs.getBioJsName(); + break; + } + } + + // JALVIEW colors not in biojs + // Blosum62 + // T-Coffee Scores (almost same with Blosom62 + // RNA Interaction type - no color applied + // RNA Helices - missing + + // BIOJS Colour not in jalview + // schemes.push name: "Lesk", id: "lesk" + // schemes.push name: "Cinema", id: "cinema" + // schemes.push name: "MAE", id: "mae" + // schemes.push name: "Clustal2", id: "clustal2" + + } + + + public enum JalviewBioJsColorSchemeMapper + { + USER_DEFINED("User Defined", "user defined", null), NONE("None", "foo", + null), CLUSTAL("Clustal", "clustal", null), ZAPPO("Zappo", + "zappo", new ZappoColourScheme()), TAYLOR( + "Taylor", "taylor", new TaylorColourScheme()), NUCLEOTIDE( + "Nucleotide", "nucleotide", new NucleotideColourScheme()), PURINE_PYRIMIDINE( + "Purine/Pyrimidine", "purine", + new PurinePyrimidineColourScheme()), HELIX_PROPENCITY( + "Helix Propensity", "helix", new HelixColourScheme()), TURN_PROPENSITY( + "Turn Propensity", "turn", new TurnColourScheme()), STRAND_PROPENSITY( + "Strand Propensity", "strand", new StrandColourScheme()), BURIED_INDEX( + "Buried Index", "buried", new BuriedColourScheme()), HYDROPHOBIC( + "Hydrophobic", "hydro", new HydrophobicColourScheme()), + + // The color types below are not yet supported by BioJs MSA viewer + T_COFFE_SCORES("T-Coffee Scores", "T-Coffee Scores", + null), RNA_INT_TYPE( + "RNA Interaction type", "RNA Interaction type", + new RNAInteractionColourScheme()), BLOSUM62("Blosum62", + "Blosum62", new Blosum62ColourScheme()), RNA_HELICES( + "RNA Helices", "RNA Helices", null), PERCENTAGE_IDENTITY( + "% Identity", "pid", + new PIDColourScheme()); + + private String jalviewName; + private String bioJsName; + + private ColourSchemeI jvColourScheme; + + private JalviewBioJsColorSchemeMapper(String jalviewName, + String bioJsName, ColourSchemeI jvColourScheme) + { + this.jalviewName = jalviewName; + this.bioJsName = bioJsName; + this.setJvColourScheme(jvColourScheme); + } + + public String getJalviewName() + { + return jalviewName; + } + + public String getBioJsName() + { + return bioJsName; + } + + public ColourSchemeI getJvColourScheme() + { + return jvColourScheme; + } + + public void setJvColourScheme(ColourSchemeI jvColourScheme) + { + this.jvColourScheme = jvColourScheme; + } + + } } diff --git a/src/jalview/json/binding/v1/BioJsFeaturePojo.java b/src/jalview/json/binding/v1/BioJsFeaturePojo.java new file mode 100644 index 0000000..3c2fdda --- /dev/null +++ b/src/jalview/json/binding/v1/BioJsFeaturePojo.java @@ -0,0 +1,60 @@ +package jalview.json.binding.v1; + +public class BioJsFeaturePojo +{ + + private int xstart; + + private int xend; + + private String text; + + private String fillColor; + + public BioJsFeaturePojo() + { + } + + + public String getText() + { + return text; + } + + public void setText(String text) + { + this.text = text; + } + + public String getFillColor() + { + return "#" + fillColor; + } + + public void setFillColor(String fillColor) + { + this.fillColor = fillColor; + } + + public int getXstart() + { + return xstart; + } + + public void setXstart(int xstart) + { + this.xstart = xstart; + } + + public int getXend() + { + return xend; + } + + public void setXend(int xend) + { + this.xend = xend; + } + + +} diff --git a/src/jalview/json/binding/v1/BioJsSeqPojo.java b/src/jalview/json/binding/v1/BioJsSeqPojo.java index 6a6c7fe..bac8601 100644 --- a/src/jalview/json/binding/v1/BioJsSeqPojo.java +++ b/src/jalview/json/binding/v1/BioJsSeqPojo.java @@ -1,5 +1,7 @@ package jalview.json.binding.v1; +import java.util.ArrayList; + public class BioJsSeqPojo { @@ -9,11 +11,17 @@ public class BioJsSeqPojo private String id; + private int start; + + private int end; + + private ArrayList features = new ArrayList(); + public BioJsSeqPojo() { } - public BioJsSeqPojo(String id, String name, String seq) + public BioJsSeqPojo(int start, int end, String id, String name, String seq) { this.id = id; this.name = name; @@ -49,4 +57,34 @@ public class BioJsSeqPojo { this.id = id; } + + public int getStart() + { + return start; + } + + public void setStart(int start) + { + this.start = start; + } + + public int getEnd() + { + return end; + } + + public void setEnd(int end) + { + this.end = end; + } + + public ArrayList getFeatures() + { + return features; + } + + public void setFeatures(ArrayList features) + { + this.features = features; + } } -- 1.7.10.2