X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fanalysis%2FAnnotationSorter.java;h=81398ebcd8683cdf5bbc54c5d3ae28ecef58a438;hb=c4609f79463d463d471b207a092f4d5af807391d;hp=fa9c1a83f82ca41bfeda16ca30d5de61f758f3c3;hpb=eaf9092bfa74b5162589c8775f68a19dd79dbb1d;p=jalview.git diff --git a/src/jalview/analysis/AnnotationSorter.java b/src/jalview/analysis/AnnotationSorter.java index fa9c1a8..81398eb 100644 --- a/src/jalview/analysis/AnnotationSorter.java +++ b/src/jalview/analysis/AnnotationSorter.java @@ -6,6 +6,8 @@ import jalview.datamodel.SequenceI; import java.util.Arrays; import java.util.Comparator; +import java.util.HashMap; +import java.util.Map; /** * A helper class to sort all annotations associated with an alignment in @@ -17,15 +19,54 @@ import java.util.Comparator; public class AnnotationSorter { + /** + * enum for annotation sort options. The text description is used in the + * Preferences drop-down options. The enum name is saved in the preferences + * file. + * + * @author gmcarstairs + * + */ public enum SequenceAnnotationOrder { - SEQUENCE_AND_LABEL, LABEL_AND_SEQUENCE, NONE + // Text descriptions surface in the Preferences Sort by... options + SEQUENCE_AND_LABEL("Sequence"), LABEL_AND_SEQUENCE("Label"), NONE( + "No sort"); + + private String description; + + private SequenceAnnotationOrder(String s) + { + description = s; + } + + @Override + public String toString() + { + return description; + } + + public static SequenceAnnotationOrder forDescription(String d) { + for (SequenceAnnotationOrder order : values()) + { + if (order.toString().equals(d)) + { + return order; + } + } + return null; + } } - + + // the alignment with respect to which annotations are sorted private final AlignmentI alignment; + // user preference for placement of non-sequence annotations private boolean showAutocalcAbove; + // working map of sequence index in alignment + private final Map sequenceIndices = new HashMap(); + /** * Constructor given an alignment and the location (top or bottom) of * Consensus and similar. @@ -158,7 +199,7 @@ public class AnnotationSorter return 0; } }; - + /** * Sort by the specified ordering of sequence-specific annotations. * @@ -168,16 +209,40 @@ public class AnnotationSorter public void sort(AlignmentAnnotation[] alignmentAnnotations, SequenceAnnotationOrder order) { - if (order != SequenceAnnotationOrder.NONE) + if (alignmentAnnotations == null) { - Comparator comparator = getComparator(order); + return; + } + // cache 'alignment sequence position' for the annotations + saveSequenceIndices(alignmentAnnotations); + + Comparator comparator = getComparator(order); - if (alignmentAnnotations != null) + if (alignmentAnnotations != null) + { + synchronized (alignmentAnnotations) { - synchronized (alignmentAnnotations) - { - Arrays.sort(alignmentAnnotations, comparator); - } + Arrays.sort(alignmentAnnotations, comparator); + } + } + } + + /** + * Calculate and save in a temporary map the position of each annotation's + * sequence (if it has one) in the alignment. Faster to do this once than for + * every annotation comparison. + * + * @param alignmentAnnotations + */ + private void saveSequenceIndices( + AlignmentAnnotation[] alignmentAnnotations) + { + sequenceIndices.clear(); + for (AlignmentAnnotation ann : alignmentAnnotations) { + SequenceI seq = ann.sequenceRef; + if (seq != null) { + int index = AlignmentUtils.getSequenceIndex(alignment, seq); + sequenceIndices.put(seq, index); } } } @@ -268,8 +333,8 @@ public class AnnotationSorter return showAutocalcAbove ? 1 : -1; } // get sequence index - but note -1 means 'at end' so needs special handling - int index1 = AlignmentUtils.getSequenceIndex(alignment, seq1); - int index2 = AlignmentUtils.getSequenceIndex(alignment, seq2); + int index1 = sequenceIndices.get(seq1); + int index2 = sequenceIndices.get(seq2); if (index1 == index2) { return 0;