*/
package jalview.analysis;
+import jalview.api.AlignViewportI;
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.SequenceI;
}
}
- // the alignment with respect to which annotations are sorted
+ /*
+ * the alignment with respect to which annotations are sorted
+ */
private final AlignmentI alignment;
- // user preference for placement of non-sequence annotations
+ /*
+ * if true, autocalculated are sorted first, if false, last
+ */
private boolean showAutocalcAbove;
- // working map of sequence index in alignment
+ /*
+ * working map of sequence index in alignment
+ */
private final Map<SequenceI, Integer> sequenceIndices = new HashMap<>();
- // if true, sort only repositions auto-calculated annotation (to top or
- // bottom)
- private final boolean autocalcOnly;
+ /*
+ * if true, sort only repositions auto-calculated annotation (to top or bottom)
+ */
+ private boolean autocalcOnly;
/**
- * Constructor given an alignment and the location (top or bottom) of
- * Consensus and similar.
+ * Constructor
*
- * @param alignmentI
- * @param showAutocalculatedAbove
- * @param autoCalcOnly
+ * @param av
*/
- public AnnotationSorter(AlignmentI alignmentI,
- boolean showAutocalculatedAbove, boolean autoCalcOnly)
+ public AnnotationSorter(AlignViewportI av)
{
- this.alignment = alignmentI;
- this.showAutocalcAbove = showAutocalculatedAbove;
- this.autocalcOnly = autoCalcOnly;
+ this.alignment = av.getAlignment();
+ this.showAutocalcAbove = av.isShowAutocalculatedAbove();
}
/**
};
/**
- * Sort by the specified ordering of sequence-specific annotations.
+ * Sorts by the specified ordering. If order is {@code CUSTOM}, meaning
+ * annotations have been manually ordered by the user, no sort is performed.
*
- * @param alignmentAnnotations
- * @param order
+ * @param sortBy
+ * the sort order to apply
+ * @param autoCalcOnly
+ * if true, only autocalculated annotations are repositioned (to top
+ * or bottom), others are left in their current order
*/
- public void sort(AlignmentAnnotation[] alignmentAnnotations,
- SequenceAnnotationOrder order)
+ public void sort(SequenceAnnotationOrder sortBy, boolean autoCalcOnly)
{
- if (alignmentAnnotations == null
- || order == SequenceAnnotationOrder.CUSTOM)
+ if (sortBy == null || sortBy == SequenceAnnotationOrder.CUSTOM)
{
return;
}
+ this.autocalcOnly = autoCalcOnly;
+
/*
* cache 'alignment sequence positions' if required for sorting
*/
- if (order == SequenceAnnotationOrder.SEQUENCE_AND_LABEL
- || order == SequenceAnnotationOrder.LABEL_AND_SEQUENCE)
+ if (sortBy == SequenceAnnotationOrder.SEQUENCE_AND_LABEL
+ || sortBy == SequenceAnnotationOrder.LABEL_AND_SEQUENCE)
{
- saveSequenceIndices(alignmentAnnotations);
+ saveSequenceIndices();
}
Comparator<? super AlignmentAnnotation> comparator = getComparator(
- order);
+ sortBy);
- if (alignmentAnnotations != null)
+ AlignmentAnnotation[] annotations = alignment.getAlignmentAnnotation();
+ synchronized (annotations)
{
- synchronized (alignmentAnnotations)
- {
- Arrays.sort(alignmentAnnotations, comparator);
- }
+ Arrays.sort(annotations, 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
+ * Calculates and saves in a temporary map the position of each annotation's
+ * associated sequence (if it has one) in the alignment. Faster to do this
+ * once than for every annotation comparison.
*/
- private void saveSequenceIndices(
- AlignmentAnnotation[] alignmentAnnotations)
+ private void saveSequenceIndices()
{
sequenceIndices.clear();
Map<SequenceI, Integer> seqPositions = alignment.getSequencePositions();
+ AlignmentAnnotation[] alignmentAnnotations = alignment
+ .getAlignmentAnnotation();
for (AlignmentAnnotation ann : alignmentAnnotations)
{
SequenceI seq = ann.sequenceRef;
import static org.testng.AssertJUnit.assertEquals;
import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder;
+import jalview.api.AlignViewportI;
+import jalview.bin.Cache;
import jalview.datamodel.Alignment;
import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.AlignmentI;
import jalview.datamodel.Sequence;
import jalview.datamodel.SequenceI;
+import jalview.gui.AlignViewport;
import jalview.gui.JvOptionPane;
-import java.util.ArrayList;
-import java.util.List;
import java.util.Random;
import org.testng.annotations.BeforeClass;
private static final String SS = "secondary structure";
- AlignmentAnnotation[] anns = new AlignmentAnnotation[0];
+ AlignViewportI av = null;
- Alignment al = null;
+ /**
+ * Configure so that the viewport does not create autocalculated annotation -
+ * test methods flag selected annotation as autocalculated instead
+ */
+ @BeforeClass(alwaysRun = true)
+ public void setUpBeforeClass()
+ {
+ Cache.loadProperties("test/jalview/io/testProps.jvprops");
+ Cache.setProperty("SHOW_QUALITY", "false");
+ Cache.setProperty("SHOW_CONSERVATION", "false");
+ Cache.setProperty("SHOW_IDENTITY", "false");
+ Cache.setProperty("SHOW_OCCUPANCY", "false");
+ }
/*
* Set up 6 sequences and 7 annotations.
@BeforeMethod(alwaysRun = true)
public void setUp()
{
- al = buildAlignment(NUM_SEQS);
- anns = buildAnnotations(NUM_ANNS);
- }
-
- /**
- * Construct an array of numAnns annotations
- *
- * @param numAnns
- *
- * @return
- */
- protected AlignmentAnnotation[] buildAnnotations(int numAnns)
- {
- List<AlignmentAnnotation> annlist = new ArrayList<>();
- for (int i = 0; i < numAnns; i++)
- {
- AlignmentAnnotation ann = new AlignmentAnnotation(SS + i, "", 0);
- annlist.add(ann);
- }
- return annlist.toArray(anns);
+ av = buildAlignment(NUM_SEQS, NUM_ANNS);
}
/**
- * Make an alignment with numSeqs sequences in it.
+ * Make an alignment viewport with numSeqs sequences and numAnns annotations
+ * in it
*
* @param numSeqs
+ * @param numAnns
*
* @return
*/
- private Alignment buildAlignment(int numSeqs)
+ private AlignViewportI buildAlignment(int numSeqs, int numAnns)
{
SequenceI[] seqs = new Sequence[numSeqs];
for (int i = 0; i < numSeqs; i++)
{
seqs[i] = new Sequence("Sequence" + i, "axrdkfp");
}
- return new Alignment(seqs);
+ Alignment al = new Alignment(seqs);
+
+ for (int i = 0; i < numAnns; i++)
+ {
+ AlignmentAnnotation ann = new AlignmentAnnotation(SS + i, "", 0);
+ al.addAnnotation(ann);
+ }
+
+ return new AlignViewport(al);
}
/**
@Test(groups = { "Functional" })
public void testSortBySequenceAndLabel_autocalcLast()
{
+ AlignmentI al = av.getAlignment();
+ AlignmentAnnotation[] anns = al.getAlignmentAnnotation();
+
// @formatter:off
anns[0].sequenceRef = al.getSequenceAt(1); anns[0].label = "label0";
anns[1].sequenceRef = al.getSequenceAt(3); anns[1].label = "structure";
anns[6].sequenceRef = al.getSequenceAt(3); anns[6].label = "IRP";
// @formatter:on
- AnnotationSorter testee = new AnnotationSorter(al, false, false);
- testee.sort(anns, SequenceAnnotationOrder.SEQUENCE_AND_LABEL);
+ av.setShowAutocalculatedAbove(false);
+ AnnotationSorter testee = new AnnotationSorter(av);
+ testee.sort(SequenceAnnotationOrder.SEQUENCE_AND_LABEL, false);
assertEquals("label5", anns[0].label); // for sequence 0
assertEquals("label0", anns[1].label); // for sequence 1
assertEquals("iron", anns[2].label); // sequence 3 /iron
@Test(groups = { "Functional" })
public void testSortBySequenceAndLabel_autocalcFirst()
{
+ AlignmentI al = av.getAlignment();
+ AlignmentAnnotation[] anns = al.getAlignmentAnnotation();
+
// @formatter:off
anns[0].sequenceRef = al.getSequenceAt(1); anns[0].label = "label0";
anns[1].sequenceRef = al.getSequenceAt(3); anns[1].label = "structure";
anns[6].sequenceRef = al.getSequenceAt(3); anns[6].label = "IRP";
// @formatter:on
- AnnotationSorter testee = new AnnotationSorter(al, true, false);
- testee.sort(anns, SequenceAnnotationOrder.SEQUENCE_AND_LABEL);
+ av.setShowAutocalculatedAbove(true);
+ AnnotationSorter testee = new AnnotationSorter(av);
+ testee.sort(SequenceAnnotationOrder.SEQUENCE_AND_LABEL, false);
assertEquals("Quality", anns[0].label); // autocalc annotations
assertEquals("Consensus", anns[1].label); // retain ordering
assertEquals("label5", anns[2].label); // for sequence 0
@Test(groups = { "Functional" })
public void testSortByLabelAndSequence_autocalcLast()
{
+ AlignmentI al = av.getAlignment();
+ AlignmentAnnotation[] anns = al.getAlignmentAnnotation();
+
// @formatter:off
anns[0].sequenceRef = al.getSequenceAt(1); anns[0].label = "label0";
anns[1].sequenceRef = al.getSequenceAt(3); anns[1].label = "structure";
anns[6].sequenceRef = al.getSequenceAt(2); anns[6].label = "Structure";
// @formatter:on
- AnnotationSorter testee = new AnnotationSorter(al, false, false);
- testee.sort(anns, SequenceAnnotationOrder.LABEL_AND_SEQUENCE);
+ av.setShowAutocalculatedAbove(false);
+ AnnotationSorter testee = new AnnotationSorter(av);
+ testee.sort(SequenceAnnotationOrder.LABEL_AND_SEQUENCE, false);
assertEquals("IRON", anns[0].label); // IRON / sequence 0
assertEquals("iron", anns[1].label); // iron / sequence 3
assertEquals("label0", anns[2].label); // label0 / sequence 1
@Test(groups = { "Functional" })
public void testSortByLabelAndSequence_autocalcFirst()
{
+ AlignmentI al = av.getAlignment();
+ AlignmentAnnotation[] anns = al.getAlignmentAnnotation();
+
// @formatter:off
anns[0].sequenceRef = al.getSequenceAt(1); anns[0].label = "label0";
anns[1].sequenceRef = al.getSequenceAt(3); anns[1].label = "structure";
anns[6].sequenceRef = al.getSequenceAt(2); anns[6].label = "Structure";
// @formatter:on
- AnnotationSorter testee = new AnnotationSorter(al, true, false);
- testee.sort(anns, SequenceAnnotationOrder.LABEL_AND_SEQUENCE);
+ av.setShowAutocalculatedAbove(true);
+ AnnotationSorter testee = new AnnotationSorter(av);
+ testee.sort(SequenceAnnotationOrder.LABEL_AND_SEQUENCE, false);
assertEquals("Quality", anns[0].label); // autocalc annotations
assertEquals("Consensus", anns[1].label); // retain ordering
assertEquals("IRON", anns[2].label); // IRON / sequence 0
@Test(groups = { "Functional" })
public void testNoSort_autocalcFirst()
{
+ AlignmentI al = av.getAlignment();
+ AlignmentAnnotation[] anns = al.getAlignmentAnnotation();
+
// @formatter:off
anns[0].sequenceRef = al.getSequenceAt(1); anns[0].label = "label0";
anns[1].sequenceRef = al.getSequenceAt(3); anns[1].label = "structure";
anns[6].sequenceRef = al.getSequenceAt(2); anns[6].label = "Structure";
// @formatter:on
- AnnotationSorter testee = new AnnotationSorter(al, true, false);
- testee.sort(anns, SequenceAnnotationOrder.NONE);
+ av.setShowAutocalculatedAbove(true);
+ AnnotationSorter testee = new AnnotationSorter(av);
+ testee.sort(SequenceAnnotationOrder.NONE, false);
assertEquals("Quality", anns[0].label); // autocalc annotations
assertEquals("Consensus", anns[1].label); // retain ordering
assertEquals("label0", anns[2].label);
*/
private void testTiming_presorted(final int numSeqs, final int numAnns)
{
- Alignment alignment = buildAlignment(numSeqs);
- AlignmentAnnotation[] annotations = buildAnnotations(numAnns);
+ AlignViewportI viewport = buildAlignment(numSeqs, numAnns);
+ AlignmentI alignment = viewport.getAlignment();
+ AlignmentAnnotation[] annotations = alignment.getAlignmentAnnotation();
/*
* Set the annotations presorted by label
annotations[i].label = "label" + i;
}
long startTime = System.currentTimeMillis();
- AnnotationSorter testee = new AnnotationSorter(alignment, false, false);
- testee.sort(annotations, SequenceAnnotationOrder.LABEL_AND_SEQUENCE);
+ viewport.setShowAutocalculatedAbove(false);
+ AnnotationSorter testee = new AnnotationSorter(viewport);
+ testee.sort(SequenceAnnotationOrder.LABEL_AND_SEQUENCE, false);
long endTime = System.currentTimeMillis();
final long elapsed = endTime - startTime;
System.out.println("Timing test for presorted " + numSeqs
*/
private void testTiming_unsorted(final int numSeqs, final int numAnns)
{
- Alignment alignment = buildAlignment(numSeqs);
- AlignmentAnnotation[] annotations = buildAnnotations(numAnns);
+ AlignViewportI viewport = buildAlignment(numSeqs, numAnns);
+ AlignmentI alignment = viewport.getAlignment();
+ AlignmentAnnotation[] annotations = alignment.getAlignmentAnnotation();
/*
* Set the annotations in random order with respect to the sequences
annotations[i].label = "label" + i;
}
long startTime = System.currentTimeMillis();
- AnnotationSorter testee = new AnnotationSorter(alignment, false, false);
- testee.sort(annotations, SequenceAnnotationOrder.SEQUENCE_AND_LABEL);
+ av.setShowAutocalculatedAbove(false);
+ AnnotationSorter testee = new AnnotationSorter(av);
+ testee.sort(SequenceAnnotationOrder.SEQUENCE_AND_LABEL, false);
long endTime = System.currentTimeMillis();
final long elapsed = endTime - startTime;
System.out.println("Timing test for unsorted " + numSeqs
*/
private void testTiming_semiSorted(final int numSeqs, final int numAnns)
{
- Alignment alignment = buildAlignment(numSeqs);
- AlignmentAnnotation[] annotations = buildAnnotations(numAnns);
+ AlignViewportI viewport = buildAlignment(numSeqs, numAnns);
+ AlignmentI alignment = viewport.getAlignment();
+ AlignmentAnnotation[] annotations = alignment.getAlignmentAnnotation();
String[] labels = new String[] { "label1", "label2", "label3",
"label4", "label5", "label6" };
annotations[i].label = labels[r.nextInt(labels.length)];
}
long startTime = System.currentTimeMillis();
- AnnotationSorter testee = new AnnotationSorter(alignment, false, false);
- testee.sort(annotations, SequenceAnnotationOrder.LABEL_AND_SEQUENCE);
+ av.setShowAutocalculatedAbove(false);
+ AnnotationSorter testee = new AnnotationSorter(av);
+ testee.sort(SequenceAnnotationOrder.LABEL_AND_SEQUENCE, false);
long endTime = System.currentTimeMillis();
long elapsed = endTime - startTime;
System.out.println("Sort by label for semisorted " + numSeqs
// now resort by sequence
startTime = System.currentTimeMillis();
- testee.sort(annotations, SequenceAnnotationOrder.SEQUENCE_AND_LABEL);
+ testee.sort(SequenceAnnotationOrder.SEQUENCE_AND_LABEL, false);
endTime = System.currentTimeMillis();
elapsed = endTime - startTime;
System.out.println("Resort by sequence for semisorted " + numSeqs
// now resort by label
startTime = System.currentTimeMillis();
- testee.sort(annotations, SequenceAnnotationOrder.LABEL_AND_SEQUENCE);
+ testee.sort(SequenceAnnotationOrder.LABEL_AND_SEQUENCE, false);
endTime = System.currentTimeMillis();
elapsed = endTime - startTime;
System.out.println("Resort by label for semisorted " + numSeqs
@Test(groups = { "Functional" })
public void testSort_custom()
{
+ AlignmentI al = av.getAlignment();
+ AlignmentAnnotation[] anns = al.getAlignmentAnnotation();
+
// @formatter:off
anns[0].sequenceRef = al.getSequenceAt(1); anns[0].label = "label0";
anns[1].sequenceRef = al.getSequenceAt(3); anns[1].label = "structure";
/*
* showAutocalcAbove=true ignored if CUSTOM ordering
*/
- AnnotationSorter testee = new AnnotationSorter(al, true, false);
- testee.sort(anns, SequenceAnnotationOrder.CUSTOM);
+ av.setShowAutocalculatedAbove(true);
+ AnnotationSorter testee = new AnnotationSorter(av);
+ testee.sort(SequenceAnnotationOrder.CUSTOM, false);
assertEquals("label0", anns[0].label); // all unchanged
assertEquals("structure", anns[1].label);
assertEquals("iron", anns[2].label);
@Test(groups = { "Functional" })
public void testSort_autocalcOnly()
{
+ AlignmentI al = av.getAlignment();
+ AlignmentAnnotation[] anns = al.getAlignmentAnnotation();
+
// @formatter:off
anns[0].sequenceRef = al.getSequenceAt(1); anns[0].label = "label0";
anns[1].sequenceRef = al.getSequenceAt(3); anns[1].label = "structure";
/*
* showAutocalcAbove=true, autocalcOnly=true
*/
- AnnotationSorter testee = new AnnotationSorter(al, true, true);
- testee.sort(anns, SequenceAnnotationOrder.LABEL_AND_SEQUENCE);
+ av.setShowAutocalculatedAbove(true);
+ AnnotationSorter testee = new AnnotationSorter(av);
+ testee.sort(SequenceAnnotationOrder.LABEL_AND_SEQUENCE, true);
assertEquals("Quality", anns[0].label); // moved to top
assertEquals("Consensus", anns[1].label); // moved to top
assertEquals("label0", anns[2].label); // the rest unchanged
/*
* showAutocalcAbove=false, autocalcOnly=true
*/
- testee = new AnnotationSorter(al, false, true);
- testee.sort(anns, SequenceAnnotationOrder.LABEL_AND_SEQUENCE);
+ av.setShowAutocalculatedAbove(false);
+ testee = new AnnotationSorter(av);
+ testee.sort(SequenceAnnotationOrder.LABEL_AND_SEQUENCE, true);
assertEquals("label0", anns[0].label); // unchanged
assertEquals("structure", anns[1].label);
assertEquals("iron", anns[2].label);