fa8af3d341a71a81f47ab66fcf27a50a0a485447
[jalview.git] / test / jalview / analysis / AnnotationSorterTest.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3  * Copyright (C) $$Year-Rel$$ The Jalview Authors
4  * 
5  * This file is part of Jalview.
6  * 
7  * Jalview is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License 
9  * as published by the Free Software Foundation, either version 3
10  * of the License, or (at your option) any later version.
11  *  
12  * Jalview is distributed in the hope that it will be useful, but 
13  * WITHOUT ANY WARRANTY; without even the implied warranty 
14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
15  * PURPOSE.  See the GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
19  * The Jalview Authors are detailed in the 'AUTHORS' file.
20  */
21 package jalview.analysis;
22
23 import static org.testng.AssertJUnit.assertEquals;
24
25 import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder;
26 import jalview.api.AlignViewportI;
27 import jalview.bin.Cache;
28 import jalview.datamodel.Alignment;
29 import jalview.datamodel.AlignmentAnnotation;
30 import jalview.datamodel.AlignmentI;
31 import jalview.datamodel.Sequence;
32 import jalview.datamodel.SequenceI;
33 import jalview.gui.AlignViewport;
34 import jalview.gui.JvOptionPane;
35
36 import java.util.Arrays;
37 import java.util.List;
38 import java.util.Random;
39
40 import org.testng.annotations.BeforeClass;
41 import org.testng.annotations.BeforeMethod;
42 import org.testng.annotations.Test;
43
44 public class AnnotationSorterTest
45 {
46
47   @BeforeClass(alwaysRun = true)
48   public void setUpJvOptionPane()
49   {
50     JvOptionPane.setInteractiveMode(false);
51     JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
52   }
53
54   private static final int NUM_SEQS = 6;
55
56   private static final int NUM_ANNS = 7;
57
58   private static final String SS = "secondary structure";
59
60   AlignViewportI av = null;
61
62   /**
63    * Configure so that the viewport does not create autocalculated annotation -
64    * test methods flag selected annotation as autocalculated instead
65    */
66   @BeforeClass(alwaysRun = true)
67   public void setUpBeforeClass()
68   {
69     Cache.loadProperties("test/jalview/io/testProps.jvprops");
70     Cache.setProperty("SHOW_QUALITY", "false");
71     Cache.setProperty("SHOW_CONSERVATION", "false");
72     Cache.setProperty("SHOW_IDENTITY", "false");
73     Cache.setProperty("SHOW_OCCUPANCY", "false");
74   }
75
76   /*
77    * Set up 6 sequences and 7 annotations.
78    */
79   @BeforeMethod(alwaysRun = true)
80   public void setUp()
81   {
82     av = buildAlignment(NUM_SEQS, NUM_ANNS);
83   }
84
85   /**
86    * Make an alignment viewport with numSeqs sequences and numAnns annotations
87    * in it
88    * 
89    * @param numSeqs
90    * @param numAnns
91    * 
92    * @return
93    */
94   private AlignViewportI buildAlignment(int numSeqs, int numAnns)
95   {
96     SequenceI[] seqs = new Sequence[numSeqs];
97     for (int i = 0; i < numSeqs; i++)
98     {
99       seqs[i] = new Sequence("Sequence" + i, "axrdkfp");
100     }
101     Alignment al = new Alignment(seqs);
102
103     for (int i = 0; i < numAnns; i++)
104     {
105       AlignmentAnnotation ann = new AlignmentAnnotation(SS + i, "", 0);
106       al.addAnnotation(ann);
107     }
108
109     return new AlignViewport(al);
110   }
111
112   /**
113    * Test sorting by annotation type (label) within sequence order, including
114    * <ul>
115    * <li>annotations with no sequence reference - sort to end keeping mutual
116    * ordering</li>
117    * <li>annotations with sequence ref = sort in sequence order</li>
118    * <li>multiple annotations for same sequence ref - sort by label
119    * non-case-specific</li>
120    * <li>annotations with reference to sequence not in alignment - treat like no
121    * sequence ref</li>
122    * </ul>
123    */
124   @Test(groups = { "Functional" })
125   public void testSortBySequenceAndLabel_autocalcLast()
126   {
127     AlignmentI al = av.getAlignment();
128     AlignmentAnnotation[] anns = al.getAlignmentAnnotation();
129
130     // @formatter:off
131     anns[0].sequenceRef = al.getSequenceAt(1); anns[0].label = "label0";
132     anns[1].sequenceRef = al.getSequenceAt(3); anns[1].label = "structure";
133     anns[2].sequenceRef = al.getSequenceAt(3); anns[2].label = "iron";
134     anns[3].autoCalculated = true;             anns[3].label = "Quality";
135     anns[4].autoCalculated = true;             anns[4].label = "Consensus";
136     anns[5].sequenceRef = al.getSequenceAt(0); anns[5].label = "label5";
137     anns[6].sequenceRef = al.getSequenceAt(3); anns[6].label = "IRP";
138     // @formatter:on
139
140     av.setShowAutocalculatedAbove(false);
141     AnnotationSorter testee = new AnnotationSorter(av);
142     testee.sort(SequenceAnnotationOrder.SEQUENCE_AND_LABEL, false);
143     anns = al.getAlignmentAnnotation();
144     assertEquals("label5", anns[0].label); // for sequence 0
145     assertEquals("label0", anns[1].label); // for sequence 1
146     assertEquals("iron", anns[2].label); // sequence 3 /iron
147     assertEquals("IRP", anns[3].label); // sequence 3/IRP
148     assertEquals("structure", anns[4].label); // sequence 3/structure
149     assertEquals("Quality", anns[5].label); // autocalc annotations
150     assertEquals("Consensus", anns[6].label); // retain ordering
151   }
152
153   /**
154    * Variant with autocalculated annotations sorting to front
155    */
156   @Test(groups = { "Functional" })
157   public void testSortBySequenceAndLabel_autocalcFirst()
158   {
159     AlignmentI al = av.getAlignment();
160     AlignmentAnnotation[] anns = al.getAlignmentAnnotation();
161
162     // @formatter:off
163     anns[0].sequenceRef = al.getSequenceAt(1); anns[0].label = "label0";
164     anns[1].sequenceRef = al.getSequenceAt(3); anns[1].label = "structure";
165     anns[2].sequenceRef = al.getSequenceAt(3); anns[2].label = "iron";
166     anns[3].autoCalculated = true;             anns[3].label = "Quality";
167     anns[4].autoCalculated = true;             anns[4].label = "Consensus";
168     anns[5].sequenceRef = al.getSequenceAt(0); anns[5].label = "label5";
169     anns[6].sequenceRef = al.getSequenceAt(3); anns[6].label = "IRP";
170     // @formatter:on
171
172     av.setShowAutocalculatedAbove(true);
173     AnnotationSorter testee = new AnnotationSorter(av);
174     testee.sort(SequenceAnnotationOrder.SEQUENCE_AND_LABEL, false);
175     anns = al.getAlignmentAnnotation();
176     assertEquals("Quality", anns[0].label); // autocalc annotations
177     assertEquals("Consensus", anns[1].label); // retain ordering
178     assertEquals("label5", anns[2].label); // for sequence 0
179     assertEquals("label0", anns[3].label); // for sequence 1
180     assertEquals("iron", anns[4].label); // sequence 3 /iron
181     assertEquals("IRP", anns[5].label); // sequence 3/IRP
182     assertEquals("structure", anns[6].label); // sequence 3/structure
183   }
184
185   /**
186    * Test sorting by annotation type (label) within sequence order, including
187    * <ul>
188    * <li>annotations with no sequence reference - sort to end keeping mutual
189    * ordering</li>
190    * <li>annotations with sequence ref = sort in sequence order</li>
191    * <li>multiple annotations for same sequence ref - sort by label
192    * non-case-specific</li>
193    * <li>annotations with reference to sequence not in alignment - treat like no
194    * sequence ref</li>
195    * </ul>
196    */
197   @Test(groups = { "Functional" })
198   public void testSortByLabelAndSequence_autocalcLast()
199   {
200     AlignmentI al = av.getAlignment();
201     AlignmentAnnotation[] anns = al.getAlignmentAnnotation();
202
203     // @formatter:off
204     anns[0].sequenceRef = al.getSequenceAt(1); anns[0].label = "label0";
205     anns[1].sequenceRef = al.getSequenceAt(3); anns[1].label = "structure";
206     anns[2].sequenceRef = al.getSequenceAt(3); anns[2].label = "iron";
207     anns[3].autoCalculated = true;             anns[3].label = "Quality";
208     anns[4].autoCalculated = true;             anns[4].label = "Consensus";
209     anns[5].sequenceRef = al.getSequenceAt(0); anns[5].label = "IRON";
210     anns[6].sequenceRef = al.getSequenceAt(2); anns[6].label = "Structure";
211     // @formatter:on
212
213     av.setShowAutocalculatedAbove(false);
214     AnnotationSorter testee = new AnnotationSorter(av);
215     testee.sort(SequenceAnnotationOrder.LABEL_AND_SEQUENCE, false);
216     anns = al.getAlignmentAnnotation();
217     assertEquals("IRON", anns[0].label); // IRON / sequence 0
218     assertEquals("iron", anns[1].label); // iron / sequence 3
219     assertEquals("label0", anns[2].label); // label0 / sequence 1
220     assertEquals("Structure", anns[3].label); // Structure / sequence 2
221     assertEquals("structure", anns[4].label); // structure / sequence 3
222     assertEquals("Quality", anns[5].label); // autocalc annotations
223     assertEquals("Consensus", anns[6].label); // retain ordering
224   }
225
226   /**
227    * Variant of test with autocalculated annotations sorted to front
228    */
229   @Test(groups = { "Functional" })
230   public void testSortByLabelAndSequence_autocalcFirst()
231   {
232     AlignmentI al = av.getAlignment();
233     AlignmentAnnotation[] anns = al.getAlignmentAnnotation();
234
235     // @formatter:off
236     anns[0].sequenceRef = al.getSequenceAt(1); anns[0].label = "label0";
237     anns[1].sequenceRef = al.getSequenceAt(3); anns[1].label = "structure";
238     anns[2].sequenceRef = al.getSequenceAt(3); anns[2].label = "iron";
239     anns[3].autoCalculated = true;             anns[3].label = "Quality";
240     anns[4].autoCalculated = true;             anns[4].label = "Consensus";
241     anns[5].sequenceRef = al.getSequenceAt(0); anns[5].label = "IRON";
242     anns[6].sequenceRef = al.getSequenceAt(2); anns[6].label = "Structure";
243     // @formatter:on
244
245     av.setShowAutocalculatedAbove(true);
246     AnnotationSorter testee = new AnnotationSorter(av);
247     testee.sort(SequenceAnnotationOrder.LABEL_AND_SEQUENCE, false);
248     anns = al.getAlignmentAnnotation();
249     assertEquals("Quality", anns[0].label); // autocalc annotations
250     assertEquals("Consensus", anns[1].label); // retain ordering
251     assertEquals("IRON", anns[2].label); // IRON / sequence 0
252     assertEquals("iron", anns[3].label); // iron / sequence 3
253     assertEquals("label0", anns[4].label); // label0 / sequence 1
254     assertEquals("Structure", anns[5].label); // Structure / sequence 2
255     assertEquals("structure", anns[6].label); // structure / sequence 3
256   }
257
258   /**
259    * Variant of test with autocalculated annotations sorted to front but
260    * otherwise no change.
261    */
262   @Test(groups = { "Functional" })
263   public void testNoSort_autocalcFirst()
264   {
265     AlignmentI al = av.getAlignment();
266     AlignmentAnnotation[] anns = al.getAlignmentAnnotation();
267
268     // @formatter:off
269     anns[0].sequenceRef = al.getSequenceAt(1); anns[0].label = "label0";
270     anns[1].sequenceRef = al.getSequenceAt(3); anns[1].label = "structure";
271     anns[2].sequenceRef = al.getSequenceAt(3); anns[2].label = "iron";
272     anns[3].autoCalculated = true;             anns[3].label = "Quality";
273     anns[4].autoCalculated = true;             anns[4].label = "Consensus";
274     anns[5].sequenceRef = al.getSequenceAt(0); anns[5].label = "IRON";
275     anns[6].sequenceRef = al.getSequenceAt(2); anns[6].label = "Structure";
276     // @formatter:on
277
278     av.setShowAutocalculatedAbove(true);
279     AnnotationSorter testee = new AnnotationSorter(av);
280     testee.sort(SequenceAnnotationOrder.NONE, false);
281     anns = al.getAlignmentAnnotation();
282     assertEquals("Quality", anns[0].label); // autocalc annotations
283     assertEquals("Consensus", anns[1].label); // retain ordering
284     assertEquals("label0", anns[2].label);
285     assertEquals("structure", anns[3].label);
286     assertEquals("iron", anns[4].label);
287     assertEquals("IRON", anns[5].label);
288     assertEquals("Structure", anns[6].label);
289   }
290
291   @Test(groups = { "Functional" })
292   public void testSort_timingPresorted()
293   {
294     testTiming_presorted(50, 100);
295     testTiming_presorted(500, 1000);
296     testTiming_presorted(5000, 10000);
297   }
298
299   /**
300    * Test timing to sort annotations already in the sort order.
301    * 
302    * @param numSeqs
303    * @param numAnns
304    */
305   private void testTiming_presorted(final int numSeqs, final int numAnns)
306   {
307     AlignViewportI viewport = buildAlignment(numSeqs, numAnns);
308     AlignmentI alignment = viewport.getAlignment();
309     AlignmentAnnotation[] annotations = alignment.getAlignmentAnnotation();
310
311     /*
312      * Set the annotations presorted by label
313      */
314     Random r = new Random();
315     final SequenceI[] sequences = alignment.getSequencesArray();
316     for (int i = 0; i < annotations.length; i++)
317     {
318       SequenceI randomSequenceRef = sequences[r.nextInt(sequences.length)];
319       annotations[i].sequenceRef = randomSequenceRef;
320       annotations[i].label = "label" + i;
321     }
322     long startTime = System.currentTimeMillis();
323     viewport.setShowAutocalculatedAbove(false);
324     AnnotationSorter testee = new AnnotationSorter(viewport);
325     testee.sort(SequenceAnnotationOrder.LABEL_AND_SEQUENCE, false);
326     long endTime = System.currentTimeMillis();
327     final long elapsed = endTime - startTime;
328     System.out.println("Timing test for presorted " + numSeqs
329             + " sequences and " + numAnns + " annotations took " + elapsed
330             + "ms");
331   }
332
333   /**
334    * Timing tests for sorting randomly sorted annotations for various sizes.
335    */
336   @Test(groups = { "Functional" })
337   public void testSort_timingUnsorted()
338   {
339     testTiming_unsorted(50, 100);
340     testTiming_unsorted(500, 1000);
341     testTiming_unsorted(5000, 10000);
342   }
343
344   /**
345    * Generate annotations randomly sorted with respect to sequences, and time
346    * sorting.
347    * 
348    * @param numSeqs
349    * @param numAnns
350    */
351   private void testTiming_unsorted(final int numSeqs, final int numAnns)
352   {
353     AlignViewportI viewport = buildAlignment(numSeqs, numAnns);
354     AlignmentI alignment = viewport.getAlignment();
355     AlignmentAnnotation[] annotations = alignment.getAlignmentAnnotation();
356
357     /*
358      * Set the annotations in random order with respect to the sequences
359      */
360     Random r = new Random();
361     final SequenceI[] sequences = alignment.getSequencesArray();
362     for (int i = 0; i < annotations.length; i++)
363     {
364       SequenceI randomSequenceRef = sequences[r.nextInt(sequences.length)];
365       annotations[i].sequenceRef = randomSequenceRef;
366       annotations[i].label = "label" + i;
367     }
368     long startTime = System.currentTimeMillis();
369     av.setShowAutocalculatedAbove(false);
370     AnnotationSorter testee = new AnnotationSorter(av);
371     testee.sort(SequenceAnnotationOrder.SEQUENCE_AND_LABEL, false);
372     long endTime = System.currentTimeMillis();
373     final long elapsed = endTime - startTime;
374     System.out.println("Timing test for unsorted " + numSeqs
375             + " sequences and " + numAnns + " annotations took " + elapsed
376             + "ms");
377   }
378
379   /**
380    * Timing test for sorting annotations with a limited range of types (labels).
381    */
382   @Test(groups = { "Functional" })
383   public void testSort_timingSemisorted()
384   {
385     testTiming_semiSorted(50, 100);
386     testTiming_semiSorted(500, 1000);
387     testTiming_semiSorted(5000, 10000);
388   }
389
390   /**
391    * Mimic 'semi-sorted' annotations:
392    * <ul>
393    * <li>set up in sequence order, with randomly assigned labels from a limited
394    * range</li>
395    * <li>sort by label and sequence order, report timing</li>
396    * <li>resort by sequence and label, report timing</li>
397    * <li>resort by label and sequence, report timing</li>
398    * </ul>
399    * 
400    * @param numSeqs
401    * @param numAnns
402    */
403   private void testTiming_semiSorted(final int numSeqs, final int numAnns)
404   {
405     AlignViewportI viewport = buildAlignment(numSeqs, numAnns);
406     AlignmentI alignment = viewport.getAlignment();
407     AlignmentAnnotation[] annotations = alignment.getAlignmentAnnotation();
408
409     String[] labels = new String[] { "label1", "label2", "label3",
410         "label4", "label5", "label6" };
411
412     /*
413      * Set the annotations in sequence order with randomly assigned labels.
414      */
415     Random r = new Random();
416     final SequenceI[] sequences = alignment.getSequencesArray();
417     for (int i = 0; i < annotations.length; i++)
418     {
419       SequenceI sequenceRef = sequences[i % sequences.length];
420       annotations[i].sequenceRef = sequenceRef;
421       annotations[i].label = labels[r.nextInt(labels.length)];
422     }
423     long startTime = System.currentTimeMillis();
424     av.setShowAutocalculatedAbove(false);
425     AnnotationSorter testee = new AnnotationSorter(av);
426     testee.sort(SequenceAnnotationOrder.LABEL_AND_SEQUENCE, false);
427     long endTime = System.currentTimeMillis();
428     long elapsed = endTime - startTime;
429     System.out.println("Sort by label for semisorted " + numSeqs
430             + " sequences and " + numAnns + " annotations took " + elapsed
431             + "ms");
432
433     // now resort by sequence
434     startTime = System.currentTimeMillis();
435     testee.sort(SequenceAnnotationOrder.SEQUENCE_AND_LABEL, false);
436     endTime = System.currentTimeMillis();
437     elapsed = endTime - startTime;
438     System.out.println("Resort by sequence for semisorted " + numSeqs
439             + " sequences and " + numAnns + " annotations took " + elapsed
440             + "ms");
441
442     // now resort by label
443     startTime = System.currentTimeMillis();
444     testee.sort(SequenceAnnotationOrder.LABEL_AND_SEQUENCE, false);
445     endTime = System.currentTimeMillis();
446     elapsed = endTime - startTime;
447     System.out.println("Resort by label for semisorted " + numSeqs
448             + " sequences and " + numAnns + " annotations took " + elapsed
449             + "ms");
450   }
451
452   /**
453    * Test that sort does nothing if sort order is CUSTOM (manually ordered
454    * annotations)
455    */
456   @Test(groups = { "Functional" })
457   public void testSort_custom()
458   {
459     AlignmentI al = av.getAlignment();
460     AlignmentAnnotation[] anns = al.getAlignmentAnnotation();
461
462     // @formatter:off
463     anns[0].sequenceRef = al.getSequenceAt(1); anns[0].label = "label0";
464     anns[1].sequenceRef = al.getSequenceAt(3); anns[1].label = "structure";
465     anns[2].sequenceRef = al.getSequenceAt(3); anns[2].label = "iron";
466     anns[3].autoCalculated = true;             anns[3].label = "Quality";
467     anns[4].autoCalculated = true;             anns[4].label = "Consensus";
468     anns[5].sequenceRef = al.getSequenceAt(0); anns[5].label = "label5";
469     anns[6].sequenceRef = al.getSequenceAt(3); anns[6].label = "IRP";
470     // @formatter:on
471
472     /*
473      * showAutocalcAbove=true ignored if CUSTOM ordering
474      */
475     av.setShowAutocalculatedAbove(true);
476     AnnotationSorter testee = new AnnotationSorter(av);
477     testee.sort(SequenceAnnotationOrder.CUSTOM, false);
478     anns = al.getAlignmentAnnotation();
479     assertEquals("label0", anns[0].label); // all unchanged
480     assertEquals("structure", anns[1].label);
481     assertEquals("iron", anns[2].label);
482     assertEquals("Quality", anns[3].label);
483     assertEquals("Consensus", anns[4].label);
484     assertEquals("label5", anns[5].label);
485     assertEquals("IRP", anns[6].label);
486   }
487
488   /**
489    * Test of sorting only autocalculated annotations
490    */
491   @Test(groups = { "Functional" })
492   public void testSort_autocalcOnly()
493   {
494     AlignmentI al = av.getAlignment();
495     AlignmentAnnotation[] anns = al.getAlignmentAnnotation();
496
497     // @formatter:off
498     anns[0].sequenceRef = al.getSequenceAt(1); anns[0].label = "label0";
499     anns[1].sequenceRef = al.getSequenceAt(3); anns[1].label = "structure";
500     anns[2].sequenceRef = al.getSequenceAt(3); anns[2].label = "iron";
501     anns[3].autoCalculated = true;             anns[3].label = "Quality";
502     anns[4].autoCalculated = true;             anns[4].label = "Consensus";
503     anns[5].sequenceRef = al.getSequenceAt(0); anns[5].label = "label5";
504     anns[6].sequenceRef = al.getSequenceAt(3); anns[6].label = "IRP";
505     // @formatter:on
506
507     /*
508      * showAutocalcAbove=true, autocalcOnly=true
509      */
510     av.setShowAutocalculatedAbove(true);
511     AnnotationSorter testee = new AnnotationSorter(av);
512     testee.sort(SequenceAnnotationOrder.LABEL_AND_SEQUENCE, true);
513     anns = al.getAlignmentAnnotation();
514     assertEquals("Quality", anns[0].label); // moved to top
515     assertEquals("Consensus", anns[1].label); // moved to top
516     assertEquals("label0", anns[2].label); // the rest unchanged
517     assertEquals("structure", anns[3].label);
518     assertEquals("iron", anns[4].label);
519     assertEquals("label5", anns[5].label);
520     assertEquals("IRP", anns[6].label);
521
522     /*
523      * showAutocalcAbove=false, autocalcOnly=true
524      */
525     av.setShowAutocalculatedAbove(false);
526     testee = new AnnotationSorter(av);
527     testee.sort(SequenceAnnotationOrder.LABEL_AND_SEQUENCE, true);
528     assertEquals("label0", anns[0].label); // unchanged
529     assertEquals("structure", anns[1].label);
530     assertEquals("iron", anns[2].label);
531     assertEquals("label5", anns[3].label);
532     assertEquals("IRP", anns[4].label);
533     assertEquals("Quality", anns[5].label); // moved to bottom
534     assertEquals("Consensus", anns[6].label); // moved to bottom
535   }
536
537   /**
538    * Test sorting by annotation order
539    */
540   @Test(groups = { "Functional" })
541   public void testSortByAnnotation()
542   {
543     AlignmentI al = av.getAlignment();
544     AlignmentAnnotation[] anns = al.getAlignmentAnnotation();
545   
546     // @formatter:off
547     anns[0].sequenceRef = al.getSequenceAt(1); anns[0].label = "label0";
548     anns[1].sequenceRef = al.getSequenceAt(3); anns[1].label = "structure";
549     anns[2].sequenceRef = al.getSequenceAt(3); anns[2].label = "iron";
550     anns[3].autoCalculated = true;             anns[3].label = "Quality";
551     anns[4].autoCalculated = true;             anns[4].label = "Consensus";
552     anns[5].sequenceRef = al.getSequenceAt(0); anns[5].label = "label5";
553     anns[6].sequenceRef = al.getSequenceAt(3); anns[6].label = "IRP";
554     // @formatter:on
555   
556     av.setShowAutocalculatedAbove(false);
557     AnnotationSorter testee = new AnnotationSorter(av);
558     List<AlignmentAnnotation> reorder = Arrays.asList(anns[2], anns[6],
559             anns[3], anns[0], anns[5], anns[1], anns[4]);
560     testee.sort(reorder);
561
562     /*
563      * should now be ordered as specified by the list
564      */
565     anns = al.getAlignmentAnnotation();
566     assertEquals("iron", anns[0].label);
567     assertEquals("IRP", anns[1].label);
568     assertEquals("Quality", anns[2].label);
569     assertEquals("label0", anns[3].label);
570     assertEquals("label5", anns[4].label);
571     assertEquals("structure", anns[5].label);
572     assertEquals("Consensus", anns[6].label);
573   }
574 }