JAL-1152 prototype of new Annotations menu with sort options
[jalview.git] / test / jalview / analysis / AnnotationSorterTest.java
1 package jalview.analysis;
2
3 import static org.junit.Assert.assertEquals;
4 import static org.junit.Assert.assertTrue;
5 import jalview.datamodel.Alignment;
6 import jalview.datamodel.AlignmentAnnotation;
7 import jalview.datamodel.Sequence;
8 import jalview.datamodel.SequenceI;
9
10 import java.util.ArrayList;
11 import java.util.List;
12 import java.util.Random;
13
14 import org.junit.Before;
15 import org.junit.Test;
16
17 public class AnnotationSorterTest
18 {
19   private static final int NUM_SEQS = 6;
20
21   private static final int NUM_ANNS = 7;
22
23   private static final String SS = "secondary structure";
24
25   AlignmentAnnotation[] anns = new AlignmentAnnotation[0];
26
27   Alignment al = null;
28
29   /*
30    * Set up 6 sequences and 7 annotations.
31    */
32   @Before
33   public void setUp()
34   {
35     al = buildAlignment(NUM_SEQS);
36     anns = buildAnnotations(NUM_ANNS);
37   }
38
39   /**
40    * Construct an array of numAnns annotations
41    * 
42    * @param numAnns
43    * 
44    * @return
45    */
46   protected AlignmentAnnotation[] buildAnnotations(int numAnns)
47   {
48     List<AlignmentAnnotation> annlist = new ArrayList<AlignmentAnnotation>();
49     for (int i = 0; i < numAnns; i++)
50     {
51       AlignmentAnnotation ann = new AlignmentAnnotation(SS + i, "", 0);
52       annlist.add(ann);
53     }
54     return annlist.toArray(anns);
55   }
56
57   /**
58    * Make an alignment with numSeqs sequences in it.
59    * 
60    * @param numSeqs
61    * 
62    * @return
63    */
64   private Alignment buildAlignment(int numSeqs)
65   {
66     SequenceI[] seqs = new Sequence[numSeqs];
67     for (int i = 0; i < numSeqs; i++)
68     {
69       seqs[i] = new Sequence("Sequence" + i, "axrdkfp");
70     }
71     return new Alignment(seqs);
72   }
73
74   /**
75    * Test sorting by annotation type (label) within sequence order, including
76    * <ul>
77    * <li>annotations with no sequence reference - sort to end keeping mutual
78    * ordering</li>
79    * <li>annotations with sequence ref = sort in sequence order</li>
80    * <li>multiple annotations for same sequence ref - sort by label
81    * non-case-specific</li>
82    * <li>annotations with reference to sequence not in alignment - treat like no
83    * sequence ref</li>
84    * </ul>
85    */
86   @Test
87   public void testSortBySequenceAndType()
88   {
89     // @formatter:off
90     anns[0].sequenceRef = al.getSequenceAt(1); anns[0].label = "label0";
91     anns[1].sequenceRef = al.getSequenceAt(3); anns[1].label = "structure";
92     anns[2].sequenceRef = al.getSequenceAt(3); anns[2].label = "iron";
93     anns[3].sequenceRef = null;                anns[3].label = "Quality";
94     anns[4].sequenceRef = null;                anns[4].label = "Consensus";
95     anns[5].sequenceRef = al.getSequenceAt(0); anns[5].label = "label5";
96     anns[6].sequenceRef = al.getSequenceAt(3); anns[6].label = "IRP";
97     // @formatter:on
98
99     AnnotationSorter testee = new AnnotationSorter(al);
100     testee.sortBySequenceAndType(anns);
101     assertEquals("label5", anns[0].label); // for sequence 0
102     assertEquals("label0", anns[1].label); // for sequence 1
103     assertEquals("iron", anns[2].label); // sequence 3 /iron
104     assertEquals("IRP", anns[3].label); // sequence 3/IRP
105     assertEquals("structure", anns[4].label); // sequence 3/structure
106     assertEquals("Quality", anns[5].label); // non-sequence annotations
107     assertEquals("Consensus", anns[6].label); // retain ordering
108   }
109
110   /**
111    * Test sorting by annotation type (label) within sequence order, including
112    * <ul>
113    * <li>annotations with no sequence reference - sort to end keeping mutual
114    * ordering</li>
115    * <li>annotations with sequence ref = sort in sequence order</li>
116    * <li>multiple annotations for same sequence ref - sort by label
117    * non-case-specific</li>
118    * <li>annotations with reference to sequence not in alignment - treat like no
119    * sequence ref</li>
120    * </ul>
121    */
122   @Test
123   public void testSortByTypeAndSequence()
124   {
125     // @formatter:off
126     anns[0].sequenceRef = al.getSequenceAt(1); anns[0].label = "label0";
127     anns[1].sequenceRef = al.getSequenceAt(3); anns[1].label = "structure";
128     anns[2].sequenceRef = al.getSequenceAt(3); anns[2].label = "iron";
129     anns[3].sequenceRef = null;                anns[3].label = "Quality";
130     anns[4].sequenceRef = null;                anns[4].label = "Consensus";
131     anns[5].sequenceRef = al.getSequenceAt(0); anns[5].label = "IRON";
132     anns[6].sequenceRef = al.getSequenceAt(2); anns[6].label = "Structure";
133     // @formatter:on
134
135     AnnotationSorter testee = new AnnotationSorter(al);
136     testee.sortByTypeAndSequence(anns);
137     assertEquals("IRON", anns[0].label); // IRON / sequence 0
138     assertEquals("iron", anns[1].label); // iron / sequence 3
139     assertEquals("label0", anns[2].label); // label0 / sequence 1
140     assertEquals("Structure", anns[3].label); // Structure / sequence 2
141     assertEquals("structure", anns[4].label); // structure / sequence 3
142     assertEquals("Quality", anns[5].label); // non-sequence annotations
143     assertEquals("Consensus", anns[6].label); // retain ordering
144   }
145
146   @Test
147   public void testSortBySequenceAndType_timing()
148   {
149     final long targetTime = 300;        // ms
150     final int numSeqs = 10000;
151     final int numAnns = 20000;
152     al = buildAlignment(numSeqs);
153     anns = buildAnnotations(numAnns);
154
155     /*
156      * Set the annotations in random order with respect to the sequences
157      */
158     Random r = new Random();
159     final SequenceI[] sequences = al.getSequencesArray();
160     for (int i = 0; i < anns.length; i++)
161     {
162       SequenceI randomSequenceRef = sequences[r.nextInt(sequences.length)];
163       anns[i].sequenceRef = randomSequenceRef;
164     }
165     long startTime = System.currentTimeMillis();
166     AnnotationSorter testee = new AnnotationSorter(al);
167     testee.sortByTypeAndSequence(anns);
168     long endTime = System.currentTimeMillis();
169     final long elapsed = endTime - startTime;
170     System.out.println("Timing test for " + numSeqs + " sequences and "
171             + numAnns + " annotations took " + elapsed + "ms");
172     assertTrue("Sort took more than " + targetTime + "ms",
173             elapsed <= targetTime);
174   }
175 }