1 package jalview.analysis;
3 import static org.junit.Assert.assertEquals;
4 import static org.junit.Assert.assertTrue;
5 import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder;
6 import jalview.datamodel.Alignment;
7 import jalview.datamodel.AlignmentAnnotation;
8 import jalview.datamodel.Sequence;
9 import jalview.datamodel.SequenceI;
11 import java.util.ArrayList;
12 import java.util.List;
13 import java.util.Random;
15 import org.junit.Before;
16 import org.junit.Test;
18 public class AnnotationSorterTest
20 private static final int NUM_SEQS = 6;
22 private static final int NUM_ANNS = 7;
24 private static final String SS = "secondary structure";
26 AlignmentAnnotation[] anns = new AlignmentAnnotation[0];
31 * Set up 6 sequences and 7 annotations.
36 al = buildAlignment(NUM_SEQS);
37 anns = buildAnnotations(NUM_ANNS);
41 * Construct an array of numAnns annotations
47 protected AlignmentAnnotation[] buildAnnotations(int numAnns)
49 List<AlignmentAnnotation> annlist = new ArrayList<AlignmentAnnotation>();
50 for (int i = 0; i < numAnns; i++)
52 AlignmentAnnotation ann = new AlignmentAnnotation(SS + i, "", 0);
55 return annlist.toArray(anns);
59 * Make an alignment with numSeqs sequences in it.
65 private Alignment buildAlignment(int numSeqs)
67 SequenceI[] seqs = new Sequence[numSeqs];
68 for (int i = 0; i < numSeqs; i++)
70 seqs[i] = new Sequence("Sequence" + i, "axrdkfp");
72 return new Alignment(seqs);
76 * Test sorting by annotation type (label) within sequence order, including
78 * <li>annotations with no sequence reference - sort to end keeping mutual
80 * <li>annotations with sequence ref = sort in sequence order</li>
81 * <li>multiple annotations for same sequence ref - sort by label
82 * non-case-specific</li>
83 * <li>annotations with reference to sequence not in alignment - treat like no
88 public void testSortBySequenceAndType()
91 anns[0].sequenceRef = al.getSequenceAt(1); anns[0].label = "label0";
92 anns[1].sequenceRef = al.getSequenceAt(3); anns[1].label = "structure";
93 anns[2].sequenceRef = al.getSequenceAt(3); anns[2].label = "iron";
94 anns[3].sequenceRef = null; anns[3].label = "Quality";
95 anns[4].sequenceRef = null; anns[4].label = "Consensus";
96 anns[5].sequenceRef = al.getSequenceAt(0); anns[5].label = "label5";
97 anns[6].sequenceRef = al.getSequenceAt(3); anns[6].label = "IRP";
100 AnnotationSorter testee = new AnnotationSorter(al, false);
101 testee.sort(anns, SequenceAnnotationOrder.SEQUENCE_AND_LABEL);
102 assertEquals("label5", anns[0].label); // for sequence 0
103 assertEquals("label0", anns[1].label); // for sequence 1
104 assertEquals("iron", anns[2].label); // sequence 3 /iron
105 assertEquals("IRP", anns[3].label); // sequence 3/IRP
106 assertEquals("structure", anns[4].label); // sequence 3/structure
107 assertEquals("Quality", anns[5].label); // non-sequence annotations
108 assertEquals("Consensus", anns[6].label); // retain ordering
112 * Test sorting by annotation type (label) within sequence order, including
114 * <li>annotations with no sequence reference - sort to end keeping mutual
116 * <li>annotations with sequence ref = sort in sequence order</li>
117 * <li>multiple annotations for same sequence ref - sort by label
118 * non-case-specific</li>
119 * <li>annotations with reference to sequence not in alignment - treat like no
124 public void testSortByTypeAndSequence()
127 anns[0].sequenceRef = al.getSequenceAt(1); anns[0].label = "label0";
128 anns[1].sequenceRef = al.getSequenceAt(3); anns[1].label = "structure";
129 anns[2].sequenceRef = al.getSequenceAt(3); anns[2].label = "iron";
130 anns[3].sequenceRef = null; anns[3].label = "Quality";
131 anns[4].sequenceRef = null; anns[4].label = "Consensus";
132 anns[5].sequenceRef = al.getSequenceAt(0); anns[5].label = "IRON";
133 anns[6].sequenceRef = al.getSequenceAt(2); anns[6].label = "Structure";
136 AnnotationSorter testee = new AnnotationSorter(al, false);
137 testee.sort(anns, SequenceAnnotationOrder.LABEL_AND_SEQUENCE);
138 assertEquals("IRON", anns[0].label); // IRON / sequence 0
139 assertEquals("iron", anns[1].label); // iron / sequence 3
140 assertEquals("label0", anns[2].label); // label0 / sequence 1
141 assertEquals("Structure", anns[3].label); // Structure / sequence 2
142 assertEquals("structure", anns[4].label); // structure / sequence 3
143 assertEquals("Quality", anns[5].label); // non-sequence annotations
144 assertEquals("Consensus", anns[6].label); // retain ordering
148 public void testSort_timingPresorted()
150 final long targetTime = 100; // ms
151 final int numSeqs = 10000;
152 final int numAnns = 20000;
153 al = buildAlignment(numSeqs);
154 anns = buildAnnotations(numAnns);
157 * Set the annotations presorted by label
159 Random r = new Random();
160 final SequenceI[] sequences = al.getSequencesArray();
161 for (int i = 0; i < anns.length; i++)
163 SequenceI randomSequenceRef = sequences[r.nextInt(sequences.length)];
164 anns[i].sequenceRef = randomSequenceRef;
165 anns[i].label = "label" + i;
167 long startTime = System.currentTimeMillis();
168 AnnotationSorter testee = new AnnotationSorter(al, false);
169 testee.sort(anns, SequenceAnnotationOrder.LABEL_AND_SEQUENCE);
170 long endTime = System.currentTimeMillis();
171 final long elapsed = endTime - startTime;
172 System.out.println("Timing test for presorted " + numSeqs
174 + numAnns + " annotations took " + elapsed + "ms");
175 assertTrue("Sort took more than " + targetTime + "ms",
176 elapsed <= targetTime);
180 * Timing test for sorting randomly sorted annotations
183 public void testSort_timingUnsorted()
185 final int numSeqs = 2000;
186 final int numAnns = 4000;
187 al = buildAlignment(numSeqs);
188 anns = buildAnnotations(numAnns);
191 * Set the annotations in random order with respect to the sequences
193 Random r = new Random();
194 final SequenceI[] sequences = al.getSequencesArray();
195 for (int i = 0; i < anns.length; i++)
197 SequenceI randomSequenceRef = sequences[r.nextInt(sequences.length)];
198 anns[i].sequenceRef = randomSequenceRef;
199 anns[i].label = "label" + i;
201 long startTime = System.currentTimeMillis();
202 AnnotationSorter testee = new AnnotationSorter(al, false);
203 testee.sort(anns, SequenceAnnotationOrder.SEQUENCE_AND_LABEL);
204 long endTime = System.currentTimeMillis();
205 final long elapsed = endTime - startTime;
206 System.out.println("Timing test for unsorted " + numSeqs
208 + numAnns + " annotations took " + elapsed + "ms");
212 * Timing test for sorting annotations with a limited range of types (labels).
215 public void testSort_timingSemisorted()
217 final int numSeqs = 2000;
218 final int numAnns = 4000;
219 al = buildAlignment(numSeqs);
220 anns = buildAnnotations(numAnns);
222 String[] labels = new String[]
223 { "label1", "label2", "label3", "label4", "label5", "label6" };
226 * Set the annotations in sequence order with randomly assigned labels.
228 Random r = new Random();
229 final SequenceI[] sequences = al.getSequencesArray();
230 for (int i = 0; i < anns.length; i++)
232 SequenceI sequenceRef = sequences[i % sequences.length];
233 anns[i].sequenceRef = sequenceRef;
234 anns[i].label = labels[r.nextInt(labels.length)];
236 long startTime = System.currentTimeMillis();
237 AnnotationSorter testee = new AnnotationSorter(al, false);
238 testee.sort(anns, SequenceAnnotationOrder.LABEL_AND_SEQUENCE);
239 long endTime = System.currentTimeMillis();
240 long elapsed = endTime - startTime;
241 System.out.println("Sort by type for semisorted " + numSeqs
243 + numAnns + " annotations took " + elapsed + "ms");
245 // now resort by sequence
246 startTime = System.currentTimeMillis();
247 testee.sort(anns, SequenceAnnotationOrder.SEQUENCE_AND_LABEL);
248 endTime = System.currentTimeMillis();
249 elapsed = endTime - startTime;
250 System.out.println("Resort by sequence for semisorted " + numSeqs
251 + " sequences and " + numAnns + " annotations took " + elapsed
254 // now resort by type
255 startTime = System.currentTimeMillis();
256 testee.sort(anns, SequenceAnnotationOrder.LABEL_AND_SEQUENCE);
257 endTime = System.currentTimeMillis();
258 elapsed = endTime - startTime;
259 System.out.println("Resort by type for semisorted " + numSeqs
260 + " sequences and " + numAnns + " annotations took " + elapsed