X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fio%2FAnnotationFile.java;h=f0f1ca3dfb07cc17c106d784b425818e93cbe16a;hb=17e4ea278bc9a5fb280db1252ce78b7a295215f5;hp=b3a22df894f169bc408c3bef653c8eb86d691723;hpb=59c3078b53669a38f4e1c1158675691fe60349b3;p=jalview.git diff --git a/src/jalview/io/AnnotationFile.java b/src/jalview/io/AnnotationFile.java index b3a22df..f0f1ca3 100755 --- a/src/jalview/io/AnnotationFile.java +++ b/src/jalview/io/AnnotationFile.java @@ -1,29 +1,54 @@ /* - * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8) - * Copyright (C) 2012 J Procter, AM Waterhouse, LM Lui, J Engelhardt, G Barton, M Clamp, S Searle + * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$) + * Copyright (C) $$Year-Rel$$ The Jalview Authors * * This file is part of Jalview. * * Jalview is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + * as published by the Free Software Foundation, either version 3 + * of the License, or (at your option) any later version. * * Jalview is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along with Jalview. If not, see . + * You should have received a copy of the GNU General Public License + * along with Jalview. If not, see . + * The Jalview Authors are detailed in the 'AUTHORS' file. */ package jalview.io; -import java.io.*; -import java.net.*; -import java.util.*; - -import jalview.analysis.*; -import jalview.datamodel.*; -import jalview.schemes.*; +import jalview.analysis.Conservation; +import jalview.api.AlignViewportI; +import jalview.datamodel.AlignmentAnnotation; +import jalview.datamodel.AlignmentI; +import jalview.datamodel.Annotation; +import jalview.datamodel.ColumnSelection; +import jalview.datamodel.GraphLine; +import jalview.datamodel.HiddenColumns; +import jalview.datamodel.HiddenSequences; +import jalview.datamodel.SequenceGroup; +import jalview.datamodel.SequenceI; +import jalview.schemes.ColourSchemeI; +import jalview.schemes.ColourSchemeProperty; +import jalview.util.ColorUtils; + +import java.awt.Color; +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.InputStreamReader; +import java.io.StringReader; +import java.net.URL; +import java.util.ArrayList; +import java.util.BitSet; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.List; +import java.util.Map; +import java.util.StringTokenizer; +import java.util.Vector; public class AnnotationFile { @@ -64,18 +89,19 @@ public class AnnotationFile } /** - * convenience method for pre-2.4 feature files which have no view, hidden + * convenience method for pre-2.9 annotation files which have no view, hidden * columns or hidden row keywords. * * @param annotations * @param list * @param properties - * @return feature file as a string. + * @return annotation file as a string. */ public String printAnnotations(AlignmentAnnotation[] annotations, List list, Hashtable properties) { - return printAnnotations(annotations, list, properties, null); + return printAnnotations(annotations, list, properties, null, null, + null); } @@ -85,23 +111,22 @@ public class AnnotationFile */ public class ViewDef { - public String viewname; - - public HiddenSequences hidseqs; + // TODO this class is not used - remove? + public final String viewname; - public ColumnSelection hiddencols; + public final HiddenSequences hidseqs; - public Vector visibleGroups; + public final HiddenColumns hiddencols; - public Hashtable hiddenRepSeqs; + public final Hashtable hiddenRepSeqs; - public ViewDef(String viewname, HiddenSequences hidseqs, - ColumnSelection hiddencols, Hashtable hiddenRepSeqs) + public ViewDef(String vname, HiddenSequences hseqs, HiddenColumns hcols, + Hashtable hRepSeqs) { - this.viewname = viewname; - this.hidseqs = hidseqs; - this.hiddencols = hiddencols; - this.hiddenRepSeqs = hiddenRepSeqs; + this.viewname = vname; + this.hidseqs = hseqs; + this.hiddencols = hcols; + this.hiddenRepSeqs = hRepSeqs; } } @@ -116,10 +141,43 @@ public class AnnotationFile * @return annotation file */ public String printAnnotations(AlignmentAnnotation[] annotations, - List list, Hashtable properties, ViewDef[] views) + List list, Hashtable properties, HiddenColumns cs, + AlignmentI al, ViewDef view) { - // TODO: resolve views issue : annotationFile could contain visible region, - // or full data + hidden region specifications for a view. + if (view != null) + { + if (view.viewname != null) + { + text.append("VIEW_DEF\t" + view.viewname + "\n"); + } + if (list == null) + { + // list = view.visibleGroups; + } + if (cs == null) + { + cs = view.hiddencols; + } + if (al == null) + { + // add hidden rep sequences. + } + } + // first target - store and restore all settings for a view. + if (al != null && al.hasSeqrep()) + { + text.append("VIEW_SETREF\t" + al.getSeqrep().getName() + "\n"); + } + if (cs != null && cs.hasHiddenColumns()) + { + text.append("VIEW_HIDECOLS\t"); + + String regions = cs.regionsToString(",", "-"); + text.append(regions); + text.append("\n"); + } + // TODO: allow efficient recovery of annotation data shown in several + // different views if (annotations != null) { boolean oneColour = true; @@ -131,8 +189,8 @@ public class AnnotationFile StringBuffer colours = new StringBuffer(); StringBuffer graphLine = new StringBuffer(); StringBuffer rowprops = new StringBuffer(); - Hashtable graphGroup = new Hashtable(); - Hashtable graphGroup_refs = new Hashtable(); + Hashtable graphGroup = new Hashtable<>(); + Hashtable graphGroup_refs = new Hashtable<>(); BitSet graphGroupSeen = new BitSet(); java.awt.Color color; @@ -141,22 +199,24 @@ public class AnnotationFile { row = annotations[i]; - if (!row.visible && !row.hasScore() && !(row.graphGroup>-1 && graphGroupSeen.get(row.graphGroup))) + if (!row.visible && !row.hasScore() && !(row.graphGroup > -1 + && graphGroupSeen.get(row.graphGroup))) { continue; } color = null; oneColour = true; - + // mark any sequence references for the row - writeSequence_Ref(refSeq ,row.sequenceRef); + writeSequence_Ref(refSeq, row.sequenceRef); refSeq = row.sequenceRef; // mark any group references for the row writeGroup_Ref(refGroup, row.groupRef); refGroup = row.groupRef; - boolean hasGlyphs = row.hasIcons, hasLabels = row.hasText, hasValues = row.hasScore, hasText = false; + boolean hasGlyphs = row.hasIcons, hasLabels = row.hasText, + hasValues = row.hasScore, hasText = false; // lookahead to check what the annotation row object actually contains. for (int j = 0; row.annotations != null && j < row.annotations.length @@ -165,14 +225,15 @@ public class AnnotationFile if (row.annotations[j] != null) { hasLabels |= (row.annotations[j].displayCharacter != null - && row.annotations[j].displayCharacter.length() > 0 && !row.annotations[j].displayCharacter - .equals(" ")); - hasGlyphs |= (row.annotations[j].secondaryStructure != 0 && row.annotations[j].secondaryStructure != ' '); - hasValues |= (row.annotations[j].value != Float.NaN); // NaNs can't + && row.annotations[j].displayCharacter.length() > 0 + && !row.annotations[j].displayCharacter.equals(" ")); + hasGlyphs |= (row.annotations[j].secondaryStructure != 0 + && row.annotations[j].secondaryStructure != ' '); + hasValues |= (!Float.isNaN(row.annotations[j].value)); // NaNs can't // be // rendered.. - hasText |= (row.annotations[j].description != null && row.annotations[j].description - .length() > 0); + hasText |= (row.annotations[j].description != null + && row.annotations[j].description.length() > 0); } } @@ -205,23 +266,23 @@ public class AnnotationFile graphLine.append("\t"); graphLine.append(row.getThreshold().label); graphLine.append("\t"); - graphLine.append(jalview.util.Format.getHexString(row - .getThreshold().colour)); + graphLine.append(jalview.util.Format + .getHexString(row.getThreshold().colour)); graphLine.append(newline); } if (row.graphGroup > -1) { graphGroupSeen.set(row.graphGroup); - Integer key = new Integer(row.graphGroup); + Integer key = Integer.valueOf(row.graphGroup); if (graphGroup.containsKey(key)) { graphGroup.put(key, graphGroup.get(key) + "\t" + row.label); - + } else { - graphGroup_refs.put(key, new Object[] { refSeq, refGroup}); + graphGroup_refs.put(key, new Object[] { refSeq, refGroup }); graphGroup.put(key, row.label); } } @@ -257,13 +318,13 @@ public class AnnotationFile } if (hasValues) { - if (row.annotations[j].value != Float.NaN) + if (!Float.isNaN(row.annotations[j].value)) { text.append(comma + row.annotations[j].value); } else { - System.err.println("Skipping NaN - not valid value."); + // System.err.println("Skipping NaN - not valid value."); text.append(comma + 0f);// row.annotations[j].value); } comma = ","; @@ -301,11 +362,8 @@ public class AnnotationFile if (row.annotations[j].colour != null && row.annotations[j].colour != java.awt.Color.black) { - text.append(comma - + "[" - + jalview.util.Format - .getHexString(row.annotations[j].colour) - + "]"); + text.append(comma + "[" + jalview.util.Format + .getHexString(row.annotations[j].colour) + "]"); comma = ","; } } @@ -313,7 +371,9 @@ public class AnnotationFile } if (row.hasScore()) + { text.append("\t" + row.score); + } text.append(newline); @@ -338,32 +398,38 @@ public class AnnotationFile rowprops.append(row.centreColLabels); rowprops.append(newline); } + if (graphLine.length() > 0) + { + text.append(graphLine.toString()); + graphLine.setLength(0); + } } text.append(newline); text.append(colours.toString()); - text.append(graphLine.toString()); if (graphGroup.size() > 0) { SequenceI oldRefSeq = refSeq; SequenceGroup oldRefGroup = refGroup; - for (Map.Entry combine_statement:graphGroup.entrySet()) - { - Object[] seqRefAndGroup=graphGroup_refs.get(combine_statement.getKey()); - - writeSequence_Ref(refSeq, (SequenceI)seqRefAndGroup[0]); - refSeq = (SequenceI)seqRefAndGroup[0]; - - writeGroup_Ref(refGroup, (SequenceGroup)seqRefAndGroup[1]); - refGroup = (SequenceGroup)seqRefAndGroup[1]; + for (Map.Entry combine_statement : graphGroup + .entrySet()) + { + Object[] seqRefAndGroup = graphGroup_refs + .get(combine_statement.getKey()); + + writeSequence_Ref(refSeq, (SequenceI) seqRefAndGroup[0]); + refSeq = (SequenceI) seqRefAndGroup[0]; + + writeGroup_Ref(refGroup, (SequenceGroup) seqRefAndGroup[1]); + refGroup = (SequenceGroup) seqRefAndGroup[1]; text.append("COMBINE\t"); text.append(combine_statement.getValue()); text.append(newline); } writeSequence_Ref(refSeq, oldRefSeq); refSeq = oldRefSeq; - + writeGroup_Ref(refGroup, oldRefGroup); refGroup = oldRefGroup; } @@ -390,13 +456,16 @@ public class AnnotationFile text.append(properties.get(key)); } // TODO: output alignment visualization settings here if required - + // iterate through one or more views, defining, marking columns and rows + // as visible/hidden, and emmitting view properties. + // View specific annotation is } return text.toString(); } - private Object writeGroup_Ref(SequenceGroup refGroup, SequenceGroup next_refGroup) + private Object writeGroup_Ref(SequenceGroup refGroup, + SequenceGroup next_refGroup) { if (next_refGroup == null) { @@ -421,13 +490,13 @@ public class AnnotationFile return true; } } - return false; + return false; } - + private boolean writeSequence_Ref(SequenceI refSeq, SequenceI next_refSeq) { - if (next_refSeq==null) + if (next_refSeq == null) { if (refSeq != null) { @@ -452,7 +521,7 @@ public class AnnotationFile return false; } - public void printGroups(List list) + protected void printGroups(List list) { SequenceI seqrep = null; for (SequenceGroup sg : list) @@ -498,7 +567,8 @@ public class AnnotationFile if (sg.cs != null) { text.append("colour="); - text.append(ColourSchemeProperty.getColourName(sg.cs)); + text.append(ColourSchemeProperty + .getColourName(sg.cs.getColourScheme())); text.append("\t"); if (sg.cs.getThreshold() != 0) { @@ -576,26 +646,56 @@ public class AnnotationFile String refSeqId = null; + public boolean annotateAlignmentView(AlignViewportI viewport, Object file, + DataSourceType protocol) + { + ColumnSelection colSel = viewport.getColumnSelection(); + HiddenColumns hidden = viewport.getAlignment().getHiddenColumns(); + if (colSel == null) + { + colSel = new ColumnSelection(); + } + if (hidden == null) + { + hidden = new HiddenColumns(); + } + boolean rslt = readAnnotationFile(viewport.getAlignment(), hidden, file, + protocol); + if (rslt && (colSel.hasSelectedColumns() || hidden.hasHiddenColumns())) + { + viewport.setColumnSelection(colSel); + viewport.getAlignment().setHiddenColumns(hidden); + } + + return rslt; + } + public boolean readAnnotationFile(AlignmentI al, String file, - String protocol) + DataSourceType sourceType) + { + return readAnnotationFile(al, null, file, sourceType); + } + + public boolean readAnnotationFile(AlignmentI al, HiddenColumns hidden, + Object file, DataSourceType sourceType) { BufferedReader in = null; try { - if (protocol.equals(AppletFormatAdapter.FILE)) + if (sourceType == DataSourceType.FILE) { - in = new BufferedReader(new FileReader(file)); + in = FileLoader.getBufferedReader(file); } - else if (protocol.equals(AppletFormatAdapter.URL)) + else if (sourceType == DataSourceType.URL) { - URL url = new URL(file); + URL url = new URL(file.toString()); in = new BufferedReader(new InputStreamReader(url.openStream())); } - else if (protocol.equals(AppletFormatAdapter.PASTE)) + else if (sourceType == DataSourceType.PASTE) { - in = new BufferedReader(new StringReader(file)); + in = new BufferedReader(new StringReader(file.toString())); } - else if (protocol.equals(AppletFormatAdapter.CLASSLOADER)) + else if (sourceType == DataSourceType.CLASSLOADER) { java.io.InputStream is = getClass().getResourceAsStream("/" + file); if (is != null) @@ -605,27 +705,35 @@ public class AnnotationFile } if (in != null) { - return parseAnnotationFrom(al, in); + return parseAnnotationFrom(al, hidden, in); } } catch (Exception ex) { ex.printStackTrace(); System.out.println("Problem reading annotation file: " + ex); - if (nlinesread>0) { - System.out.println("Last read line "+nlinesread+": '"+lastread+"' (first 80 chars) ..."); + if (nlinesread > 0) + { + System.out.println("Last read line " + nlinesread + ": '" + lastread + + "' (first 80 chars) ..."); } return false; } return false; } - long nlinesread=0; - String lastread=""; - public boolean parseAnnotationFrom(AlignmentI al, BufferedReader in) - throws Exception + + long nlinesread = 0; + + String lastread = ""; + + private static String GRAPHLINE = "GRAPHLINE", COMBINE = "COMBINE"; + + public boolean parseAnnotationFrom(AlignmentI al, HiddenColumns hidden, + BufferedReader in) throws Exception { nlinesread = 0; - ArrayList combineAnnotation_calls = new ArrayList(); + ArrayList combineAnnotation_calls = new ArrayList<>(); + ArrayList deferredAnnotation_calls = new ArrayList<>(); boolean modified = false; String groupRef = null; Hashtable groupRefRows = new Hashtable(); @@ -654,7 +762,7 @@ public class AnnotationFile autoAnnotsKey(aa[aai], aa[aai].sequenceRef, (aa[aai].groupRef == null ? null : aa[aai].groupRef.getName())), - new Integer(1)); + Integer.valueOf(1)); } } } @@ -670,7 +778,8 @@ public class AnnotationFile boolean jvAnnotationFile = false; while ((line = in.readLine()) != null) { - nlinesread++;lastread = new String(line); + nlinesread++; + lastread = new String(line); if (line.indexOf("#") == 0) { continue; @@ -691,7 +800,8 @@ public class AnnotationFile while ((line = in.readLine()) != null) { - nlinesread++;lastread = new String(line); + nlinesread++; + lastread = new String(line); if (line.indexOf("#") == 0 || line.indexOf("JALVIEW_ANNOTATION") > -1 || line.length() == 0) @@ -709,10 +819,12 @@ public class AnnotationFile continue; } - else if (token.equalsIgnoreCase("COMBINE")) + else if (token.equalsIgnoreCase(COMBINE)) { // keep a record of current state and resolve groupRef at end - combineAnnotation_calls.add(new Object[] { st, refSeq, groupRef}); + combineAnnotation_calls + .add(new Object[] + { st, refSeq, groupRef }); modified = true; continue; } @@ -722,9 +834,12 @@ public class AnnotationFile modified = true; continue; } - else if (token.equalsIgnoreCase("GRAPHLINE")) + else if (token.equalsIgnoreCase(GRAPHLINE)) { - addLine(al, st); + // resolve at end + deferredAnnotation_calls + .add(new Object[] + { GRAPHLINE, st, refSeq, groupRef }); modified = true; continue; } @@ -744,8 +859,8 @@ public class AnnotationFile if (refSeqIndex < 1) { refSeqIndex = 1; - System.out - .println("WARNING: SEQUENCE_REF index must be > 0 in AnnotationFile"); + System.out.println( + "WARNING: SEQUENCE_REF index must be > 0 in AnnotationFile"); } } catch (Exception ex) { @@ -784,6 +899,7 @@ public class AnnotationFile else if (token.equalsIgnoreCase("SEQUENCE_GROUP")) { addGroup(al, st); + modified = true; continue; } @@ -806,6 +922,58 @@ public class AnnotationFile modified = true; continue; } + // else if (token.equalsIgnoreCase("VIEW_DEF")) + // { + // addOrSetView(al,st); + // modified = true; + // continue; + // } + else if (token.equalsIgnoreCase("VIEW_SETREF")) + { + if (refSeq != null) + { + al.setSeqrep(refSeq); + } + modified = true; + continue; + } + else if (token.equalsIgnoreCase("VIEW_HIDECOLS")) + { + if (st.hasMoreTokens()) + { + if (hidden == null) + { + hidden = new HiddenColumns(); + } + parseHideCols(hidden, st.nextToken()); + } + modified = true; + continue; + } + else if (token.equalsIgnoreCase("HIDE_INSERTIONS")) + { + SequenceI sr = refSeq == null ? al.getSeqrep() : refSeq; + if (sr == null) + { + sr = al.getSequenceAt(0); + } + if (sr != null) + { + if (hidden == null) + { + System.err.println( + "Cannot process HIDE_INSERTIONS without an alignment view: Ignoring line: " + + line); + } + else + { + // consider deferring this till after the file has been parsed ? + hidden.hideList(sr.getInsertions()); + } + } + modified = true; + continue; + } // Parse out the annotation row graphStyle = AlignmentAnnotation.getGraphValueFromString(token); @@ -824,7 +992,9 @@ public class AnnotationFile { description = line; if (st.hasMoreTokens()) + { line = st.nextToken(); + } } if (st.hasMoreTokens()) @@ -875,9 +1045,8 @@ public class AnnotationFile (index == 0) ? null : annotations, 0, 0, graphStyle); annotation.score = score; - if (!overrideAutoAnnot - && autoAnnots.containsKey(autoAnnotsKey(annotation, refSeq, - groupRef))) + if (!overrideAutoAnnot && autoAnnots + .containsKey(autoAnnotsKey(annotation, refSeq, groupRef))) { // skip - we've already got an automatic annotation of this type. continue; @@ -895,14 +1064,14 @@ public class AnnotationFile // TODO: verify that undo/redo with 1:many sequence associated // annotations can be undone correctly AlignmentAnnotation ann = new AlignmentAnnotation(annotation); - annotation - .createSequenceMapping(referedSeq, refSeqIndex, false); + annotation.createSequenceMapping(referedSeq, refSeqIndex, + false); annotation.adjustForAlignment(); referedSeq.addAlignmentAnnotation(annotation); al.addAnnotation(annotation); al.setAnnotationIndex(annotation, - al.getAlignmentAnnotation().length - - existingAnnotations - 1); + al.getAlignmentAnnotation().length - existingAnnotations + - 1); if (groupRef != null) { ((Vector) groupRefRows.get(groupRef)).addElement(annotation); @@ -910,8 +1079,8 @@ public class AnnotationFile // and recover our virgin copy to use again if necessary. annotation = ann; - } while (refSeqId != null - && (referedSeq = al.findName(referedSeq, refSeqId, true)) != null); + } while (refSeqId != null && (referedSeq = al.findName(referedSeq, + refSeqId, true)) != null); } else { @@ -928,7 +1097,7 @@ public class AnnotationFile modified = true; } // Resolve the groupRefs - Hashtable groupRefLookup=new Hashtable(); + Hashtable groupRefLookup = new Hashtable<>(); Enumeration en = groupRefRows.keys(); while (en.hasMoreElements()) @@ -944,19 +1113,20 @@ public class AnnotationFile { // TODO: specify and implement duplication of alignment annotation // for multiple group references. - System.err - .println("Ignoring 1:many group reference mappings for group name '" + System.err.println( + "Ignoring 1:many group reference mappings for group name '" + groupRef + "'"); } else { matched = true; Vector rowset = (Vector) groupRefRows.get(groupRef); - groupRefLookup.put(groupRef, theGroup); + groupRefLookup.put(groupRef, theGroup); if (rowset != null && rowset.size() > 0) { AlignmentAnnotation alan = null; - for (int elm = 0, elmSize = rowset.size(); elm < elmSize; elm++) + for (int elm = 0, elmSize = rowset + .size(); elm < elmSize; elm++) { alan = (AlignmentAnnotation) rowset.elementAt(elm); alan.groupRef = theGroup; @@ -967,24 +1137,78 @@ public class AnnotationFile } ((Vector) groupRefRows.get(groupRef)).removeAllElements(); } + // process any deferred attribute settings for each context + for (Object[] _deferred_args : deferredAnnotation_calls) + { + if (_deferred_args[0] == GRAPHLINE) + { + addLine(al, (StringTokenizer) _deferred_args[1], // st + (SequenceI) _deferred_args[2], // refSeq + (_deferred_args[3] == null) ? null + : groupRefLookup.get(_deferred_args[3]) // the + // reference + // group, or + // null + ); + } + } + // finally, combine all the annotation rows within each context. /** - * number of combine statements in this annotation file. Used to create new groups for combined annotation graphs without disturbing existing ones + * number of combine statements in this annotation file. Used to create + * new groups for combined annotation graphs without disturbing existing + * ones */ int combinecount = 0; - for (Object[] _combine_args:combineAnnotation_calls) { - combineAnnotations(al, - ++combinecount, + for (Object[] _combine_args : combineAnnotation_calls) + { + combineAnnotations(al, ++combinecount, (StringTokenizer) _combine_args[0], // st (SequenceI) _combine_args[1], // refSeq - (_combine_args[2]==null) ? null : groupRefLookup.get((String)_combine_args[2]) // the reference group, or null - ); + (_combine_args[2] == null) ? null + : groupRefLookup.get(_combine_args[2]) // the reference + // group, + // or null + ); } - } return modified; } + private void parseHideCols(HiddenColumns hidden, String nextToken) + { + StringTokenizer inval = new StringTokenizer(nextToken, ","); + while (inval.hasMoreTokens()) + { + String range = inval.nextToken().trim(); + int from, to = range.indexOf("-"); + if (to == -1) + { + from = to = Integer.parseInt(range); + if (from >= 0) + { + hidden.hideColumns(from, to); + } + } + else + { + from = Integer.parseInt(range.substring(0, to)); + if (to < range.length() - 1) + { + to = Integer.parseInt(range.substring(to + 1)); + } + else + { + to = from; + } + if (from > 0 && to >= from) + { + hidden.hideColumns(from, to); + } + } + } + } + private Object autoAnnotsKey(AlignmentAnnotation annotation, SequenceI refSeq, String groupRef) { @@ -995,29 +1219,20 @@ public class AnnotationFile Annotation parseAnnotation(String string, int graphStyle) { - boolean hasSymbols = (graphStyle == AlignmentAnnotation.NO_GRAPH); // don't - // do the - // glyph - // test - // if we - // don't - // want - // secondary - // structure + // don't do the glyph test if we don't want secondary structure + boolean hasSymbols = (graphStyle == AlignmentAnnotation.NO_GRAPH); String desc = null, displayChar = null; char ss = ' '; // secondaryStructure float value = 0; boolean parsedValue = false, dcset = false; // find colour here - java.awt.Color colour = null; + Color colour = null; int i = string.indexOf("["); int j = string.indexOf("]"); if (i > -1 && j > -1) { - UserColourScheme ucs = new UserColourScheme(); - - colour = ucs.getColourFromString(string.substring(i + 1, j)); + colour = ColorUtils.parseColourString(string.substring(i + 1, j)); if (i > 0 && string.charAt(i - 1) == ',') { // clip the preceding comma as well @@ -1056,7 +1271,7 @@ public class AnnotationFile { displayChar = token; // foo - value = new Float(token).floatValue(); + value = Float.valueOf(token).floatValue(); parsedValue = true; continue; } catch (NumberFormatException ex) @@ -1070,9 +1285,9 @@ public class AnnotationFile displayChar = token; } } - if (hasSymbols - && (token.equals("H") || token.equals("E") - || token.equals("S") || token.equals(" "))) + if (hasSymbols && (token.length() == 1 + && "()<>[]{}AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz" + .contains(token))) { // Either this character represents a helix or sheet // or an integer which can be displayed @@ -1119,7 +1334,7 @@ public class AnnotationFile void colourAnnotations(AlignmentI al, String label, String colour) { - UserColourScheme ucs = new UserColourScheme(colour); + Color awtColour = ColorUtils.parseColourString(colour); Annotation[] annotations; for (int i = 0; i < al.getAlignmentAnnotation().length; i++) { @@ -1130,38 +1345,42 @@ public class AnnotationFile { if (annotations[j] != null) { - annotations[j].colour = ucs.findColour('A'); + annotations[j].colour = awtColour; } } } } } - void combineAnnotations(AlignmentI al, int combineCount, StringTokenizer st, SequenceI seqRef, SequenceGroup groupRef) + void combineAnnotations(AlignmentI al, int combineCount, + StringTokenizer st, SequenceI seqRef, SequenceGroup groupRef) { String group = st.nextToken(); // First make sure we are not overwriting the graphIndex - int graphGroup=0; + int graphGroup = 0; if (al.getAlignmentAnnotation() != null) { for (int i = 0; i < al.getAlignmentAnnotation().length; i++) { AlignmentAnnotation aa = al.getAlignmentAnnotation()[i]; - - if (aa.graphGroup>graphGroup) + + if (aa.graphGroup > graphGroup) { // try to number graphGroups in order of occurence. - graphGroup=aa.graphGroup+1; + graphGroup = aa.graphGroup + 1; } - if (aa.sequenceRef==seqRef && aa.groupRef==groupRef && aa.label.equalsIgnoreCase(group)) + if (aa.sequenceRef == seqRef && aa.groupRef == groupRef + && aa.label.equalsIgnoreCase(group)) { - if (aa.graphGroup>-1) + if (aa.graphGroup > -1) { graphGroup = aa.graphGroup; - } else { + } + else + { if (graphGroup <= combineCount) { - graphGroup=combineCount+1; + graphGroup = combineCount + 1; } aa.graphGroup = graphGroup; } @@ -1176,7 +1395,8 @@ public class AnnotationFile for (int i = 0; i < al.getAlignmentAnnotation().length; i++) { AlignmentAnnotation aa = al.getAlignmentAnnotation()[i]; - if (aa.sequenceRef==seqRef && aa.groupRef==groupRef && aa.label.equalsIgnoreCase(group)) + if (aa.sequenceRef == seqRef && aa.groupRef == groupRef + && aa.label.equalsIgnoreCase(group)) { aa.graphGroup = graphGroup; break; @@ -1186,41 +1406,44 @@ public class AnnotationFile } else { - System.err - .println("Couldn't combine annotations. None are added to alignment yet!"); + System.err.println( + "Couldn't combine annotations. None are added to alignment yet!"); } } - void addLine(AlignmentI al, StringTokenizer st) + void addLine(AlignmentI al, StringTokenizer st, SequenceI seqRef, + SequenceGroup groupRef) { String group = st.nextToken(); - AlignmentAnnotation annotation = null, alannot[] = al - .getAlignmentAnnotation(); + AlignmentAnnotation[] alannot = al.getAlignmentAnnotation(); + String nextToken = st.nextToken(); + float value = 0f; + try + { + value = Float.valueOf(nextToken); + } catch (NumberFormatException e) + { + System.err.println("line " + nlinesread + ": Threshold '" + nextToken + + "' invalid, setting to zero"); + } + String label = st.hasMoreTokens() ? st.nextToken() : null; + Color colour = null; + if (st.hasMoreTokens()) + { + colour = ColorUtils.parseColourString(st.nextToken()); + } if (alannot != null) { for (int i = 0; i < alannot.length; i++) { - if (alannot[i].label.equalsIgnoreCase(group)) + if (alannot[i].label.equalsIgnoreCase(group) + && (seqRef == null || alannot[i].sequenceRef == seqRef) + && (groupRef == null || alannot[i].groupRef == groupRef)) { - annotation = alannot[i]; - break; + alannot[i].setThreshold(new GraphLine(value, label, colour)); } } } - if (annotation == null) - { - return; - } - float value = new Float(st.nextToken()).floatValue(); - String label = st.hasMoreTokens() ? st.nextToken() : null; - java.awt.Color colour = null; - if (st.hasMoreTokens()) - { - UserColourScheme ucs = new UserColourScheme(st.nextToken()); - colour = ucs.findColour('A'); - } - - annotation.setThreshold(new GraphLine(value, label, colour)); } void addGroup(AlignmentI al, StringTokenizer st) @@ -1250,8 +1473,8 @@ public class AnnotationFile } } catch (Exception e) { - System.err - .println("Couldn't parse Group Start or End Field as '*' or a valid column or sequence index: '" + System.err.println( + "Couldn't parse Group Start or End Field as '*' or a valid column or sequence index: '" + rng + "' - assuming alignment width for group."); // assume group is full width sg.setStartRes(0); @@ -1297,7 +1520,8 @@ public class AnnotationFile } else { - sg.addSequence(al.getSequenceAt(Integer.parseInt(tmp) - 1), false); + sg.addSequence(al.getSequenceAt(Integer.parseInt(tmp) - 1), + false); } } } @@ -1380,8 +1604,7 @@ public class AnnotationFile if (sg != null) { String keyValue, key, value; - ColourSchemeI def = sg.cs; - sg.cs = null; + ColourSchemeI def = sg.getColourScheme(); while (st.hasMoreTokens()) { keyValue = st.nextToken(); @@ -1394,7 +1617,10 @@ public class AnnotationFile } else if (key.equalsIgnoreCase("colour")) { - sg.cs = ColourSchemeProperty.getColour(al, value); + // TODO need to notify colourscheme of view reference once it is + // available + sg.cs.setColourScheme( + ColourSchemeProperty.getColourScheme(null, al, value)); } else if (key.equalsIgnoreCase("pidThreshold")) { @@ -1404,8 +1630,7 @@ public class AnnotationFile else if (key.equalsIgnoreCase("consThreshold")) { sg.cs.setConservationInc(Integer.parseInt(value)); - Conservation c = new Conservation("Group", - ResidueProperties.propHash, 3, sg.getSequences(null), + Conservation c = new Conservation("Group", sg.getSequences(null), sg.getStartRes(), sg.getEndRes() + 1); c.calculate(); @@ -1416,7 +1641,7 @@ public class AnnotationFile } else if (key.equalsIgnoreCase("outlineColour")) { - sg.setOutlineColour(new UserColourScheme(value).findColour('A')); + sg.setOutlineColour(ColorUtils.parseColourString(value)); } else if (key.equalsIgnoreCase("displayBoxes")) { @@ -1436,11 +1661,11 @@ public class AnnotationFile } else if (key.equalsIgnoreCase("textCol1")) { - sg.textColour = new UserColourScheme(value).findColour('A'); + sg.textColour = ColorUtils.parseColourString(value); } else if (key.equalsIgnoreCase("textCol2")) { - sg.textColour2 = new UserColourScheme(value).findColour('A'); + sg.textColour2 = ColorUtils.parseColourString(value); } else if (key.equalsIgnoreCase("textColThreshold")) { @@ -1448,9 +1673,8 @@ public class AnnotationFile } else if (key.equalsIgnoreCase("idColour")) { - // consider warning if colour doesn't resolve to a real colour - sg.setIdColour((def = new UserColourScheme(value)) - .findColour('A')); + Color idColour = ColorUtils.parseColourString(value); + sg.setIdColour(idColour == null ? Color.black : idColour); } else if (key.equalsIgnoreCase("hide")) { @@ -1464,9 +1688,9 @@ public class AnnotationFile } sg.recalcConservation(); } - if (sg.cs == null) + if (sg.getColourScheme() == null) { - sg.cs = def; + sg.setColourScheme(def); } } } @@ -1477,8 +1701,8 @@ public class AnnotationFile AlignmentAnnotation aa, ala[] = al.getAlignmentAnnotation(); if (ala == null) { - System.err - .print("Warning - no annotation to set below for sequence associated annotation:"); + System.err.print( + "Warning - no annotation to set below for sequence associated annotation:"); } while (st.hasMoreTokens()) { @@ -1526,6 +1750,10 @@ public class AnnotationFile */ public String printCSVAnnotations(AlignmentAnnotation[] annotations) { + if (annotations == null) + { + return ""; + } StringBuffer sp = new StringBuffer(); for (int i = 0; i < annotations.length; i++) { @@ -1550,4 +1778,22 @@ public class AnnotationFile } return sp.toString(); } + + public String printAnnotationsForView(AlignViewportI viewport) + { + return printAnnotations( + viewport.isShowAnnotation() + ? viewport.getAlignment().getAlignmentAnnotation() + : null, + viewport.getAlignment().getGroups(), + viewport.getAlignment().getProperties(), + viewport.getAlignment().getHiddenColumns(), + viewport.getAlignment(), null); + } + + public String printAnnotationsForAlignment(AlignmentI al) + { + return printAnnotations(al.getAlignmentAnnotation(), al.getGroups(), + al.getProperties(), null, al, null); + } }