X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fdatamodel%2FAlignmentAnnotation.java;h=7858822483796789e3f310acae6dd5aeee7876f7;hb=b5667f39acdf309cd92881b73edfda591e0acaf4;hp=6c33c1b866861f0c8b4fe82c59e4894e442b8cfc;hpb=62086b8b7a0b9436c445a94bfab5eff253adb6d5;p=jalview.git diff --git a/src/jalview/datamodel/AlignmentAnnotation.java b/src/jalview/datamodel/AlignmentAnnotation.java index 6c33c1b..7858822 100755 --- a/src/jalview/datamodel/AlignmentAnnotation.java +++ b/src/jalview/datamodel/AlignmentAnnotation.java @@ -25,6 +25,7 @@ import jalview.analysis.SecStrConsensus.SimpleBP; import jalview.analysis.WUSSParseException; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; @@ -164,6 +165,64 @@ public class AlignmentAnnotation } /** + * Get the RNA Secondary Structure SequenceFeature Array if present + */ + public SequenceFeature[] getRnaSecondaryStructure() + { + return this._rnasecstr; + } + + /** + * Check the RNA Secondary Structure is equivalent to one in given + * AlignmentAnnotation param + */ + public boolean rnaSecondaryStructureEquivalent(AlignmentAnnotation that) + { + return rnaSecondaryStructureEquivalent(that, true); + } + + public boolean rnaSecondaryStructureEquivalent(AlignmentAnnotation that, boolean compareType) + { + SequenceFeature[] thisSfArray = this.getRnaSecondaryStructure(); + SequenceFeature[] thatSfArray = that.getRnaSecondaryStructure(); + if (thisSfArray == null || thatSfArray == null) + { + return thisSfArray == null && thatSfArray == null; + } + if (thisSfArray.length != thatSfArray.length) + { + return false; + } + Arrays.sort(thisSfArray, new SFSortByEnd()); // probably already sorted + // like this + Arrays.sort(thatSfArray, new SFSortByEnd()); // probably already sorted + // like this + for (int i=0; i < thisSfArray.length; i++) { + SequenceFeature thisSf = thisSfArray[i]; + SequenceFeature thatSf = thatSfArray[i]; + if (compareType) { + if (thisSf.getType() == null || thatSf.getType() == null) { + if (thisSf.getType() == null && thatSf.getType() == null) { + continue; + } else { + return false; + } + } + if (! thisSf.getType().equals(thatSf.getType())) { + return false; + } + } + if (!(thisSf.getBegin() == thatSf.getBegin() + && thisSf.getEnd() == thatSf.getEnd())) + { + return false; + } + } + return true; + + } + + /** * map of positions in the associated annotation */ private Map sequenceMapping; @@ -282,6 +341,245 @@ public class AlignmentAnnotation } /** + * Copy constructor creates a new independent annotation row with the same + * associated sequenceRef + * + * @param annotation + */ + public AlignmentAnnotation(AlignmentAnnotation annotation) + { + setAnnotationId(); + this.label = new String(annotation.label); + if (annotation.description != null) + { + this.description = new String(annotation.description); + } + this.graphMin = annotation.graphMin; + this.graphMax = annotation.graphMax; + this.graph = annotation.graph; + this.graphHeight = annotation.graphHeight; + this.graphGroup = annotation.graphGroup; + this.groupRef = annotation.groupRef; + this.editable = annotation.editable; + this.autoCalculated = annotation.autoCalculated; + this.hasIcons = annotation.hasIcons; + this.hasText = annotation.hasText; + this.height = annotation.height; + this.label = annotation.label; + this.padGaps = annotation.padGaps; + this.visible = annotation.visible; + this.centreColLabels = annotation.centreColLabels; + this.scaleColLabel = annotation.scaleColLabel; + this.showAllColLabels = annotation.showAllColLabels; + this.calcId = annotation.calcId; + if (annotation.properties != null) + { + properties = new HashMap<>(); + for (Map.Entry val : annotation.properties.entrySet()) + { + properties.put(val.getKey(), val.getValue()); + } + } + if (this.hasScore = annotation.hasScore) + { + this.score = annotation.score; + } + if (annotation.threshold != null) + { + threshold = new GraphLine(annotation.threshold); + } + Annotation[] ann = annotation.annotations; + if (annotation.annotations != null) + { + this.annotations = new Annotation[ann.length]; + for (int i = 0; i < ann.length; i++) + { + if (ann[i] != null) + { + annotations[i] = new Annotation(ann[i]); + if (_linecolour != null) + { + _linecolour = annotations[i].colour; + } + } + } + } + if (annotation.sequenceRef != null) + { + this.sequenceRef = annotation.sequenceRef; + if (annotation.sequenceMapping != null) + { + Integer p = null; + sequenceMapping = new HashMap<>(); + Iterator pos = annotation.sequenceMapping.keySet() + .iterator(); + while (pos.hasNext()) + { + // could optimise this! + p = pos.next(); + Annotation a = annotation.sequenceMapping.get(p); + if (a == null) + { + continue; + } + if (ann != null) + { + for (int i = 0; i < ann.length; i++) + { + if (ann[i] == a) + { + sequenceMapping.put(p, annotations[i]); + } + } + } + } + } + else + { + this.sequenceMapping = null; + } + } + // TODO: check if we need to do this: JAL-952 + // if (this.isrna=annotation.isrna) + { + // _rnasecstr=new SequenceFeature[annotation._rnasecstr]; + } + validateRangeAndDisplay(); // construct hashcodes, etc. + } + + /** + * copy constructor with edit based on the hidden columns marked in colSel + * + * @param alignmentAnnotation + * @param colSel + */ + public AlignmentAnnotation(AlignmentAnnotation alignmentAnnotation, + HiddenColumns hidden) + { + this(alignmentAnnotation); + if (annotations == null) + { + return; + } + makeVisibleAnnotation(hidden); + } + + /** + * Creates a new AlignmentAnnotation object. + * + * @param label + * DOCUMENT ME! + * @param description + * DOCUMENT ME! + * @param annotations + * DOCUMENT ME! + * @param min + * DOCUMENT ME! + * @param max + * DOCUMENT ME! + * @param winLength + * DOCUMENT ME! + */ + public AlignmentAnnotation(String label, String description, + Annotation[] annotations, float min, float max, int graphType) + { + setAnnotationId(); + // graphs are not editable + editable = graphType == 0; + + this.label = label; + this.description = description; + this.annotations = annotations; + graph = graphType; + graphMin = min; + graphMax = max; + validateRangeAndDisplay(); + } + + /** + * Score only annotation + * + * @param label + * @param description + * @param score + */ + public AlignmentAnnotation(String label, String description, double score) + { + this(label, description, null); + setScore(score); + } + + /** + * Updates the _rnasecstr field Determines the positions that base pair and + * the positions of helices based on secondary structure from a Stockholm file + * + * @param rnaAnnotation + */ + private void _updateRnaSecStr(CharSequence rnaAnnotation) + { + try + { + _rnasecstr = Rna.getHelixMap(rnaAnnotation); + invalidrnastruc = -1; + } catch (WUSSParseException px) + { + // DEBUG System.out.println(px); + invalidrnastruc = px.getProblemPos(); + } + if (invalidrnastruc > -1) + { + return; + } + + if (_rnasecstr != null && _rnasecstr.length > 0) + { + // show all the RNA secondary structure annotation symbols. + isrna = true; + showAllColLabels = true; + scaleColLabel = true; + _markRnaHelices(); + } + // System.out.println("featuregroup " + _rnasecstr[0].getFeatureGroup()); + + } + + private void _markRnaHelices() + { + int mxval = 0; + // Figure out number of helices + // Length of rnasecstr is the number of pairs of positions that base pair + // with each other in the secondary structure + for (int x = 0; x < _rnasecstr.length; x++) + { + + /* + * System.out.println(this.annotation._rnasecstr[x] + " Begin" + + * this.annotation._rnasecstr[x].getBegin()); + */ + // System.out.println(this.annotation._rnasecstr[x].getFeatureGroup()); + int val = 0; + try + { + val = Integer.valueOf(_rnasecstr[x].getFeatureGroup()); + if (mxval < val) + { + mxval = val; + } + } catch (NumberFormatException q) + { + } + ; + + annotations[_rnasecstr[x].getBegin()].value = val; + annotations[_rnasecstr[x].getEnd()].value = val; + + // annotations[_rnasecstr[x].getBegin()].displayCharacter = "" + val; + // annotations[_rnasecstr[x].getEnd()].displayCharacter = "" + val; + } + setScore(mxval); + } + + /** * Checks if annotation labels represent secondary structures * */ @@ -294,6 +592,7 @@ public class AlignmentAnnotation char firstChar = 0; for (int i = 0; i < annotations.length; i++) { + // DEBUG System.out.println(i + ": " + annotations[i]); if (annotations[i] == null) { continue; @@ -301,12 +600,15 @@ public class AlignmentAnnotation if (annotations[i].secondaryStructure == 'H' || annotations[i].secondaryStructure == 'E') { + // DEBUG System.out.println( "/H|E/ '" + + // annotations[i].secondaryStructure + "'"); hasIcons |= true; } else // Check for RNA secondary structure { - // System.out.println(annotations[i].secondaryStructure); + // DEBUG System.out.println( "/else/ '" + + // annotations[i].secondaryStructure + "'"); // TODO: 2.8.2 should this ss symbol validation check be a function in // RNA/ResidueProperties ? if (annotations[i].secondaryStructure == '(' @@ -317,10 +619,12 @@ public class AlignmentAnnotation || annotations[i].secondaryStructure == 'B' || annotations[i].secondaryStructure == 'C' || annotations[i].secondaryStructure == 'D' - || annotations[i].secondaryStructure == 'E' + // || annotations[i].secondaryStructure == 'E' // ambiguous on + // its own -- already checked above || annotations[i].secondaryStructure == 'F' || annotations[i].secondaryStructure == 'G' - || annotations[i].secondaryStructure == 'H' + // || annotations[i].secondaryStructure == 'H' // ambiguous on + // its own -- already checked above || annotations[i].secondaryStructure == 'I' || annotations[i].secondaryStructure == 'J' || annotations[i].secondaryStructure == 'K' @@ -367,7 +671,7 @@ public class AlignmentAnnotation // && // annotations[i].displayCharacter.charAt(0)==annotations[i].secondaryStructure firstChar != ' ' && firstChar != '$' && firstChar != 0xCE - && firstChar != '(' && firstChar != '[' && firstChar != '>' + && firstChar != '(' && firstChar != '[' && firstChar != '<' && firstChar != '{' && firstChar != 'A' && firstChar != 'B' && firstChar != 'C' && firstChar != 'D' && firstChar != 'E' && firstChar != 'F' && firstChar != 'G' && firstChar != 'H' @@ -521,38 +825,6 @@ public class AlignmentAnnotation } /** - * Creates a new AlignmentAnnotation object. - * - * @param label - * DOCUMENT ME! - * @param description - * DOCUMENT ME! - * @param annotations - * DOCUMENT ME! - * @param min - * DOCUMENT ME! - * @param max - * DOCUMENT ME! - * @param winLength - * DOCUMENT ME! - */ - public AlignmentAnnotation(String label, String description, - Annotation[] annotations, float min, float max, int graphType) - { - setAnnotationId(); - // graphs are not editable - editable = graphType == 0; - - this.label = label; - this.description = description; - this.annotations = annotations; - graph = graphType; - graphMin = min; - graphMax = max; - validateRangeAndDisplay(); - } - - /** * checks graphMin and graphMax, secondary structure symbols, sets graphType * appropriately, sets null labels to the empty string if appropriate. */ @@ -633,113 +905,6 @@ public class AlignmentAnnotation } /** - * Copy constructor creates a new independent annotation row with the same - * associated sequenceRef - * - * @param annotation - */ - public AlignmentAnnotation(AlignmentAnnotation annotation) - { - setAnnotationId(); - this.label = new String(annotation.label); - if (annotation.description != null) - { - this.description = new String(annotation.description); - } - this.graphMin = annotation.graphMin; - this.graphMax = annotation.graphMax; - this.graph = annotation.graph; - this.graphHeight = annotation.graphHeight; - this.graphGroup = annotation.graphGroup; - this.groupRef = annotation.groupRef; - this.editable = annotation.editable; - this.autoCalculated = annotation.autoCalculated; - this.hasIcons = annotation.hasIcons; - this.hasText = annotation.hasText; - this.height = annotation.height; - this.label = annotation.label; - this.padGaps = annotation.padGaps; - this.visible = annotation.visible; - this.centreColLabels = annotation.centreColLabels; - this.scaleColLabel = annotation.scaleColLabel; - this.showAllColLabels = annotation.showAllColLabels; - this.calcId = annotation.calcId; - if (annotation.properties != null) - { - properties = new HashMap<>(); - for (Map.Entry val : annotation.properties.entrySet()) - { - properties.put(val.getKey(), val.getValue()); - } - } - if (this.hasScore = annotation.hasScore) - { - this.score = annotation.score; - } - if (annotation.threshold != null) - { - threshold = new GraphLine(annotation.threshold); - } - Annotation[] ann = annotation.annotations; - if (annotation.annotations != null) - { - this.annotations = new Annotation[ann.length]; - for (int i = 0; i < ann.length; i++) - { - if (ann[i] != null) - { - annotations[i] = new Annotation(ann[i]); - if (_linecolour != null) - { - _linecolour = annotations[i].colour; - } - } - } - } - if (annotation.sequenceRef != null) - { - this.sequenceRef = annotation.sequenceRef; - if (annotation.sequenceMapping != null) - { - Integer p = null; - sequenceMapping = new HashMap<>(); - Iterator pos = annotation.sequenceMapping.keySet() - .iterator(); - while (pos.hasNext()) - { - // could optimise this! - p = pos.next(); - Annotation a = annotation.sequenceMapping.get(p); - if (a == null) - { - continue; - } - if (ann != null) - { - for (int i = 0; i < ann.length; i++) - { - if (ann[i] == a) - { - sequenceMapping.put(p, annotations[i]); - } - } - } - } - } - else - { - this.sequenceMapping = null; - } - } - // TODO: check if we need to do this: JAL-952 - // if (this.isrna=annotation.isrna) - { - // _rnasecstr=new SequenceFeature[annotation._rnasecstr]; - } - validateRangeAndDisplay(); // construct hashcodes, etc. - } - - /** * clip the annotation to the columns given by startRes and endRes (inclusive) * and prune any existing sequenceMapping to just those columns. * @@ -895,6 +1060,7 @@ public class AlignmentAnnotation * @param seqRef * @param startRes * @param alreadyMapped + * - annotation are at aligned columns */ public void createSequenceMapping(SequenceI seqRef, int startRes, boolean alreadyMapped) @@ -926,7 +1092,7 @@ public class AlignmentAnnotation seqPos = i + startRes; } - sequenceMapping.put(new Integer(seqPos), annotations[i]); + sequenceMapping.put(Integer.valueOf(seqPos), annotations[i]); } } @@ -965,7 +1131,7 @@ public class AlignmentAnnotation { for (a = sequenceRef.getStart(); a <= sequenceRef.getEnd(); a++) { - index = new Integer(a); + index = Integer.valueOf(a); Annotation annot = sequenceMapping.get(index); if (annot != null) { @@ -1097,36 +1263,6 @@ public class AlignmentAnnotation return hasScore || !Double.isNaN(score); } - /** - * Score only annotation - * - * @param label - * @param description - * @param score - */ - public AlignmentAnnotation(String label, String description, double score) - { - this(label, description, null); - setScore(score); - } - - /** - * copy constructor with edit based on the hidden columns marked in colSel - * - * @param alignmentAnnotation - * @param colSel - */ - public AlignmentAnnotation(AlignmentAnnotation alignmentAnnotation, - HiddenColumns hidden) - { - this(alignmentAnnotation); - if (annotations == null) - { - return; - } - makeVisibleAnnotation(hidden); - } - public void setPadGaps(boolean padgaps, char gapchar) { this.padGaps = padgaps; @@ -1185,7 +1321,7 @@ public class AlignmentAnnotation /** * machine readable ID string indicating what generated this annotation */ - protected String calcId = ""; + private String calcId = ""; /** * properties associated with the calcId @@ -1582,4 +1718,69 @@ public class AlignmentAnnotation } } + public static Iterable findAnnotations( + Iterable list, SequenceI seq, String calcId, + String label) + { + List aa = new ArrayList<>(); + for (AlignmentAnnotation ann : list) + { + if ((calcId == null || (ann.getCalcId() != null + && ann.getCalcId().equals(calcId))) + && (seq == null || (ann.sequenceRef != null + && ann.sequenceRef == seq)) + && (label == null + || (ann.label != null && ann.label.equals(label)))) + { + aa.add(ann); + } + } + return aa; + } + + /** + * Answer true if any annotation matches the calcId passed in (if not null). + * + * @param list + * annotation to search + * @param calcId + * @return + */ + public static boolean hasAnnotation(List list, + String calcId) + { + + if (calcId != null && !"".equals(calcId)) + { + for (AlignmentAnnotation a : list) + { + if (a.getCalcId() == calcId) + { + return true; + } + } + } + return false; + } + + public static Iterable findAnnotation( + List list, String calcId) + { + List aa = new ArrayList<>(); + if (calcId == null) + { + return aa; + } + for (AlignmentAnnotation a : list) + { + + if (a.getCalcId() == calcId || (a.getCalcId() != null + && calcId != null && a.getCalcId().equals(calcId))) + { + aa.add(a); + } + } + return aa; + } + }