From 59c3078b53669a38f4e1c1158675691fe60349b3 Mon Sep 17 00:00:00 2001 From: Jim Procter Date: Thu, 23 May 2013 15:48:31 +0100 Subject: [PATCH] patch for JAL-1300 fixes JAL-1294: read and write COMBINE statements that use SEQUENCE_REF and GROUP_REF scope to conserve annotation rows with seqeunce and group references --- src/jalview/io/AnnotationFile.java | 179 +++++++++++++++++++++++------------- 1 file changed, 113 insertions(+), 66 deletions(-) diff --git a/src/jalview/io/AnnotationFile.java b/src/jalview/io/AnnotationFile.java index 3d42475..b3a22df 100755 --- a/src/jalview/io/AnnotationFile.java +++ b/src/jalview/io/AnnotationFile.java @@ -131,7 +131,8 @@ public class AnnotationFile StringBuffer colours = new StringBuffer(); StringBuffer graphLine = new StringBuffer(); StringBuffer rowprops = new StringBuffer(); - Hashtable graphGroup = new Hashtable(); + Hashtable graphGroup = new Hashtable(); + Hashtable graphGroup_refs = new Hashtable(); BitSet graphGroupSeen = new BitSet(); java.awt.Color color; @@ -147,54 +148,13 @@ public class AnnotationFile color = null; oneColour = true; - - if (row.sequenceRef == null) - { - if (refSeq != null) - { - text.append(newline); - text.append("SEQUENCE_REF\tALIGNMENT"); - text.append(newline); - } - - refSeq = null; - } - - else - { - if (refSeq == null || refSeq != row.sequenceRef) - { - refSeq = row.sequenceRef; - text.append(newline); - text.append("SEQUENCE_REF\t"); - text.append(refSeq.getName()); - text.append(newline); - } - } + + // mark any sequence references for the row + writeSequence_Ref(refSeq ,row.sequenceRef); + refSeq = row.sequenceRef; // mark any group references for the row - if (row.groupRef == null) - { - - if (refGroup != null) - { - text.append(newline); - text.append("GROUP_REF\tALIGNMENT"); - text.append(newline); - } - - refGroup = null; - } - else - { - if (refGroup == null || refGroup != row.groupRef) - { - refGroup = row.groupRef; - text.append(newline); - text.append("GROUP_REF\t"); - text.append(refGroup.getName()); - text.append(newline); - } - } + writeGroup_Ref(refGroup, row.groupRef); + refGroup = row.groupRef; boolean hasGlyphs = row.hasIcons, hasLabels = row.hasText, hasValues = row.hasScore, hasText = false; // lookahead to check what the annotation row object actually contains. @@ -253,13 +213,15 @@ public class AnnotationFile if (row.graphGroup > -1) { graphGroupSeen.set(row.graphGroup); - String key = String.valueOf(row.graphGroup); + Integer key = new Integer(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.put(key, row.label); } } @@ -384,13 +346,26 @@ public class AnnotationFile text.append(graphLine.toString()); if (graphGroup.size() > 0) { - Enumeration en = graphGroup.elements(); - while (en.hasMoreElements()) - { + 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]; text.append("COMBINE\t"); - text.append(en.nextElement()); + text.append(combine_statement.getValue()); text.append(newline); } + writeSequence_Ref(refSeq, oldRefSeq); + refSeq = oldRefSeq; + + writeGroup_Ref(refGroup, oldRefGroup); + refGroup = oldRefGroup; } text.append(rowprops.toString()); } @@ -421,6 +396,62 @@ public class AnnotationFile return text.toString(); } + private Object writeGroup_Ref(SequenceGroup refGroup, SequenceGroup next_refGroup) + { + if (next_refGroup == null) + { + + if (refGroup != null) + { + text.append(newline); + text.append("GROUP_REF\t"); + text.append("ALIGNMENT"); + text.append(newline); + } + return true; + } + else + { + if (refGroup == null || refGroup != next_refGroup) + { + text.append(newline); + text.append("GROUP_REF\t"); + text.append(next_refGroup.getName()); + text.append(newline); + return true; + } + } + return false; + } + + private boolean writeSequence_Ref(SequenceI refSeq, SequenceI next_refSeq) + { + + if (next_refSeq==null) + { + if (refSeq != null) + { + text.append(newline); + text.append("SEQUENCE_REF\t"); + text.append("ALIGNMENT"); + text.append(newline); + return true; + } + } + else + { + if (refSeq == null || refSeq != next_refSeq) + { + text.append(newline); + text.append("SEQUENCE_REF\t"); + text.append(next_refSeq.getName()); + text.append(newline); + return true; + } + } + return false; + } + public void printGroups(List list) { SequenceI seqrep = null; @@ -594,10 +625,7 @@ public class AnnotationFile throws Exception { nlinesread = 0; - /** - * number of combine statements in this annotation file. Used to create new groups for combined annotation graphs without disturbing existing ones - */ - int combinecount = 0; + ArrayList combineAnnotation_calls = new ArrayList(); boolean modified = false; String groupRef = null; Hashtable groupRefRows = new Hashtable(); @@ -683,7 +711,8 @@ public class AnnotationFile else if (token.equalsIgnoreCase("COMBINE")) { - combineAnnotations(al, combinecount++, st); + // keep a record of current state and resolve groupRef at end + combineAnnotation_calls.add(new Object[] { st, refSeq, groupRef}); modified = true; continue; } @@ -898,7 +927,8 @@ public class AnnotationFile // and set modification flag modified = true; } - // Finally, resolve the groupRefs + // Resolve the groupRefs + Hashtable groupRefLookup=new Hashtable(); Enumeration en = groupRefRows.keys(); while (en.hasMoreElements()) @@ -922,6 +952,7 @@ public class AnnotationFile { matched = true; Vector rowset = (Vector) groupRefRows.get(groupRef); + groupRefLookup.put(groupRef, theGroup); if (rowset != null && rowset.size() > 0) { AlignmentAnnotation alan = null; @@ -936,6 +967,20 @@ public class AnnotationFile } ((Vector) groupRefRows.get(groupRef)).removeAllElements(); } + // 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 + */ + int combinecount = 0; + 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 + ); + } + } return modified; } @@ -1092,7 +1137,7 @@ public class AnnotationFile } } - void combineAnnotations(AlignmentI al, int combineCount, StringTokenizer st) + 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 @@ -1102,20 +1147,21 @@ public class AnnotationFile for (int i = 0; i < al.getAlignmentAnnotation().length; i++) { AlignmentAnnotation aa = al.getAlignmentAnnotation()[i]; + if (aa.graphGroup>graphGroup) { // try to number graphGroups in order of occurence. - graphGroup=aa.graphGroup; + graphGroup=aa.graphGroup+1; } - if (aa.label.equalsIgnoreCase(group)) + if (aa.sequenceRef==seqRef && aa.groupRef==groupRef && aa.label.equalsIgnoreCase(group)) { if (aa.graphGroup>-1) { graphGroup = aa.graphGroup; } else { - if (graphGroup >= combineCount) + if (graphGroup <= combineCount) { - graphGroup++; + graphGroup=combineCount+1; } aa.graphGroup = graphGroup; } @@ -1129,9 +1175,10 @@ public class AnnotationFile group = st.nextToken(); for (int i = 0; i < al.getAlignmentAnnotation().length; i++) { - if (al.getAlignmentAnnotation()[i].label.equalsIgnoreCase(group)) + AlignmentAnnotation aa = al.getAlignmentAnnotation()[i]; + if (aa.sequenceRef==seqRef && aa.groupRef==groupRef && aa.label.equalsIgnoreCase(group)) { - al.getAlignmentAnnotation()[i].graphGroup = graphGroup; + aa.graphGroup = graphGroup; break; } } -- 1.7.10.2