From: jprocter Sequence Features File The Sequence features file (which used to be known as the
-"Groups file" prior to version 2.08) is a simple way of
-getting your own sequence annotations into Jalview. It was introduced to
-allow sequence features to be rendered in the Jalview applet, and so is
-intentionally lightweight and minimal because the applet is often used
-in situations where data file size must be kept to a minimum, and no XML
-parser is available. Features files are imported into Jalview in the following ways: Sequence Features File
+
+The Sequence features file (which used to be known as the
+"Groups file" prior to version 2.08) is a simple way of getting
+your own sequence annotations into Jalview. It was introduced to
+allow sequence features to be rendered in the Jalview applet, and
+so is intentionally lightweight and minimal because the applet is
+often used in situations where data file size must be kept to a
+minimum, and no XML parser is available. Features files are imported into Jalview in the following
+ways:
+
+
-
+
- -features <Features filename>
+ -features <Features filename>
+
+
Sequence Features File Format
-A features file is a simple ASCII text file, where each line +
+A features file is a simple ASCII text file, where each line contains tab separated text fields. No comments are allowed.
-The first set of lines contain type definitions:
-Feature label Feature Colour
A feature
-type has a text label, and a colour specification. This can be either:
+
+The first set of lines contain type definitions: + +
+Feature label Feature Colour + ++ +A feature type has a text label, and a colour specification. This +can be either: + +
+[label|]<mincolor>|<maxcolor>|[absolute|]<minvalue>|<maxvalue>[|<thresholdtype>|[<threshold value>]] ++ +The fields are as follows: +
-<mincolor>|<maxcolor>|[absolute|]<minvalue>|<maxvalue>[|<thresholdtype>|[<threshold value>]] -The fields are as follows -
The remaining lines in the file are the sequence annotation -definitions, where the now defined features are attached to regions on -particular sequences, optionally with some descriptive text (displayed -in a tooltip when the mouse is near the feature on that sequence). There -are two alternate ways of referring to a sequence, either by its text -ID, or its index in an associated alignment. +definitions, where the now defined features are attached to regions +on particular sequences. Each feature can optionally include some descriptive text +which is displayed in a tooltip when the mouse is near the feature on that +sequence (and can also be used to generate a colour the feature).
+ +If your sequence annotation is already available in GFF Format (see http://www.sanger.ac.uk/resources/software/gff/spec.html), +then you can leave it as is, after first adding a line containing +only 'GFF' after any Jalview feature colour definitions (this mixed format capability was added in Jalview 2.6). Alternately, you can use Jalview's own sequence feature +annotation format, which additionally allows HTML and URLs to be +directly attached to each piece of annotation.
+ +Jalview's sequence feature annotation format
++Each feature is specified as a tab-separated series of columns as defined below:
-description sequenceId sequenceIndex start end featureType score (optional)-Normally, sequence features are associated with sequences rather than -alignments, and the sequenceIndex field is given as "-1". In -order to specify a sequence by its index in a particular alignment, the -sequenceId should be given as "ID_NOT_SPECIFIED", otherwise -the sequenceId field will be used in preference to the sequenceIndex +description sequenceId sequenceIndex start end featureType score (optional) + + +This format allows two alternate ways of referring to a sequence, either by +its text ID, or its index in an associated alignment. Normally, sequence features are associated with sequences rather +than alignments, and the sequenceIndex field is given as "-1". In +order to specify a sequence by its index in a particular alignment, +the sequenceId should be given as "ID_NOT_SPECIFIED", otherwise the +sequenceId field will be used in preference to the sequenceIndex field. + +
The description may contain simple HTML document body tags if
-enclosed by "<html></html>" and these will be
-rendered as formatted tooltips in the Jalview Application (the Jalview
-applet is not capable of rendering HTML tooltips, so all formatting tags
-will be removed).
-Attaching Links to Sequence Features
-Any anchor tags in an html formatted description line will be translated
-into URL links. A link symbol will be displayed adjacent to any feature
-which includes links, and these are made available from the links submenu of the
-popup menu which is obtained by right-clicking when a link symbol is
-displayed in the tooltip.
+enclosed by "<html></html>" and these will be rendered
+as formatted tooltips in the Jalview Application (the Jalview
+applet is not capable of rendering HTML tooltips, so all formatting
+tags will be removed).
+Attaching Links to Sequence Features
+Any anchor tags in an html formatted description line will be
+translated into URL links. A link symbol will be displayed adjacent
+to any feature which includes links, and these are made available
+from the links
+submenu of the popup menu which is obtained by right-clicking
+when a link symbol is displayed in the tooltip.
Non-positional features
-Specify the start and end for a feature to be 0
-in order to attach it to the whole sequence. Non-positional features are
-shown in a tooltip when the mouse hovers over the sequence ID panel, and
-any embedded links can be accessed from the popup menu.
-Scores
-Scores can be associated with sequence features, and used to sort sequences or shade the alignment (this was added in jalview 2.5). The score field is optional, and malformed scores will be ignored.
-
Feature annotations can be collected into named groups by
-prefixing definitions with lines of the form:startgroup groupname
..
-and subsequently post-fixing the group with:endgroup groupname
Feature
-grouping was introduced in version 2.08, and used to control whether a
-set of features are either hidden or shown together in the sequence Feature settings dialog box.
+startgroup groupname ++ +.. and subsequently post-fixing the group with: + +
+endgroup groupname ++ +Feature grouping was introduced in version 2.08, and used to +control whether a set of features are either hidden or shown +together in the sequence Feature +settings dialog box. + +
A complete example is shown below :
domain red @@ -135,8 +208,9 @@ startgroup secondarystucture PDB secondary structure annotation FER1_SPIOL -1 52 59 strand PDB secondary structure annotation FER1_SPIOL -1 74 80 helix endgroup secondarystructure +GFF +FER_CAPAA GffGroup domain 3 93 . .- - + diff --git a/src/jalview/io/FeaturesFile.java b/src/jalview/io/FeaturesFile.java index 8f5e4bd..ccf7b30 100755 --- a/src/jalview/io/FeaturesFile.java +++ b/src/jalview/io/FeaturesFile.java @@ -104,9 +104,10 @@ public class FeaturesFile extends AlignFile SequenceFeature sf; String featureGroup = null, groupLink = null; Hashtable typeLink = new Hashtable(); - + /** + * when true, assume GFF style features rather than Jalview style. + */ boolean GFFFile = true; - while ((line = nextLine()) != null) { if (line.startsWith("#")) @@ -115,6 +116,15 @@ public class FeaturesFile extends AlignFile } st = new StringTokenizer(line, "\t"); + if (st.countTokens() == 1) + { + if (line.trim().equalsIgnoreCase("GFF")) + { + // Start parsing file as if it might be GFF again. + GFFFile = true; + continue; + } + } if (st.countTokens() > 1 && st.countTokens() < 4) { GFFFile = false; @@ -140,58 +150,109 @@ public class FeaturesFile extends AlignFile { Object colour = null; String colscheme = st.nextToken(); - if (colscheme.indexOf("|") > -1) + if (colscheme.indexOf("|") > -1 + || colscheme.trim().equalsIgnoreCase("label")) { // Parse '|' separated graduated colourscheme fields: - // mincolour|maxcolour|[absolute|]minvalue|maxvalue|thresholdtype|thresholdvalue - // first four are required. - // first two are hexadecimal or word equivalent colours. - // second two are values parsed as floats. + // [label|][mincolour|maxcolour|[absolute|]minvalue|maxvalue|thresholdtype|thresholdvalue] + // can either provide 'label' only, first is optional, next two + // colors are required (but may be + // left blank), next is optional, nxt two min/max are required. + // first is either 'label' + // first/second and third are both hexadecimal or word equivalent + // colour. + // next two are values parsed as floats. // fifth is either 'above','below', or 'none'. // sixth is a float value and only required when fifth is either // 'above' or 'below'. - StringTokenizer gcol = new StringTokenizer(colscheme, "|"); - String mincol = gcol.nextToken(), maxcol = gcol.nextToken(); - String abso = gcol.nextToken(), minval, maxval; - if (abso.toLowerCase().indexOf("abso") != 0) - { - minval = abso; - abso = null; - } - else - { - minval = gcol.nextToken(); - } - maxval = gcol.nextToken(); + StringTokenizer gcol = new StringTokenizer(colscheme, "|", true); // set defaults int threshtype = AnnotationColourGradient.NO_THRESHOLD; float min = Float.MIN_VALUE, max = Float.MAX_VALUE, threshval = Float.NaN; - try - { - if (minval.length() > 0) - { - min = new Float(minval).floatValue(); - } - } catch (Exception e) + boolean labelCol = false; + // Parse spec line + String mincol = gcol.nextToken(); + if (mincol=="|") { System.err - .println("Couldn't parse the minimum value for graduated colour for type (" - + colscheme - + ") - did you misspell 'auto' for the optional automatic colour switch ?"); - e.printStackTrace(); + .println("Expected either 'label' or a colour specification in the line: "+line ); + continue; } - try + String maxcol = null; + if (mincol.toLowerCase().indexOf("label") == 0) + { + labelCol = true; + mincol = (gcol.hasMoreTokens() ? gcol.nextToken() : null); // skip '|' + mincol = (gcol.hasMoreTokens() ? gcol.nextToken() : null); + } + String abso = null, minval, maxval; + if (mincol != null) { - if (maxval.length() > 0) + // at least four more tokens + if (mincol.equals("|")) { - max = new Float(maxval).floatValue(); + mincol=""; + } else { + gcol.nextToken(); // skip next '|' } - } catch (Exception e) + // continue parsing rest of line + maxcol = gcol.nextToken(); + if (maxcol.equals("|")) + { + maxcol=""; + } else { + gcol.nextToken(); // skip next '|' + } + abso = gcol.nextToken(); + gcol.nextToken(); // skip next '|' + if (abso.toLowerCase().indexOf("abso") != 0) + { + minval = abso; + abso = null; + } + else + { + minval = gcol.nextToken(); + gcol.nextToken(); // skip next '|' + } + maxval = gcol.nextToken(); + if (gcol.hasMoreTokens()) { + gcol.nextToken(); // skip next '|' + } + try + { + if (minval.length() > 0) + { + min = new Float(minval).floatValue(); + } + } catch (Exception e) + { + System.err + .println("Couldn't parse the minimum value for graduated colour for type (" + + colscheme + + ") - did you misspell 'auto' for the optional automatic colour switch ?"); + e.printStackTrace(); + } + try + { + if (maxval.length() > 0) + { + max = new Float(maxval).floatValue(); + } + } catch (Exception e) + { + System.err + .println("Couldn't parse the maximum value for graduated colour for type (" + + colscheme + ")"); + e.printStackTrace(); + } + } + else { - System.err - .println("Couldn't parse the maximum value for graduated colour for type (" - + colscheme + ")"); - e.printStackTrace(); + // add in some dummy min/max colours for the label-only + // colourscheme. + mincol = "FFFFFF"; + maxcol = "000000"; } try { @@ -209,6 +270,8 @@ public class FeaturesFile extends AlignFile if (colour != null) { ((jalview.schemes.GraduatedColor) colour) + .setColourByLabel(labelCol); + ((jalview.schemes.GraduatedColor) colour) .setAutoScaled(abso == null); // add in any additional parameters String ttype = null, tval = null; @@ -240,9 +303,10 @@ public class FeaturesFile extends AlignFile } if (((GraduatedColor) colour).getThreshType() != AnnotationColourGradient.NO_THRESHOLD) { - tval = gcol.nextToken(); try { + gcol.nextToken(); + tval = gcol.nextToken(); ((jalview.schemes.GraduatedColor) colour) .setThresh(new Float(tval).floatValue()); } catch (Exception e) @@ -260,7 +324,7 @@ public class FeaturesFile extends AlignFile .println("Ignoring additional tokens in parameters in graduated colour specification\n"); while (gcol.hasMoreTokens()) { - System.err.println("|" + gcol); + System.err.println("|" + gcol.nextToken()); } System.err.println("\n"); } @@ -616,8 +680,8 @@ public class FeaturesFile extends AlignFile if (visible.get(type) instanceof GraduatedColor) { GraduatedColor gc = (GraduatedColor) visible.get(type); - // TODO: NOW: colour by label, autoscale flags. - color = Format.getHexString(gc.getMinColor()) + "|" + color = (gc.isColourByLabel() ? "label|" : "") + + Format.getHexString(gc.getMinColor()) + "|" + Format.getHexString(gc.getMaxColor()) + (gc.isAutoScale() ? "|" : "|abso|") + gc.getMin() + "|" + gc.getMax() + "|"; @@ -754,9 +818,7 @@ public class FeaturesFile extends AlignFile if (next[j].description.indexOf(href) == -1) { - out - .append("" + label - + ""); + out.append("" + label + ""); } }