JAL-3746 apply copyright to tests
[jalview.git] / test / jalview / schemes / AnnotationColourGradientTest.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.schemes;
22
23 import static org.testng.Assert.assertEquals;
24
25 import jalview.datamodel.Alignment;
26 import jalview.datamodel.AlignmentAnnotation;
27 import jalview.datamodel.AlignmentI;
28 import jalview.datamodel.Annotation;
29 import jalview.datamodel.GraphLine;
30 import jalview.datamodel.Sequence;
31 import jalview.datamodel.SequenceI;
32
33 import java.awt.Color;
34
35 import org.testng.annotations.BeforeClass;
36 import org.testng.annotations.Test;
37
38 public class AnnotationColourGradientTest
39 {
40   final static int WIDTH = 11;
41
42   final static int THRESHOLD_FIVE = 5;
43
44   private AlignmentAnnotation ann;
45
46   private SequenceI seq;
47
48   private AlignmentI al;
49
50   Color minColour = new Color(50, 200, 150);
51
52   Color maxColour = new Color(150, 100, 250);
53
54   /**
55    * Setup creates an annotation over 11 columns with values 0-10 and threshold
56    * 5
57    */
58   @BeforeClass(alwaysRun = true)
59   public void setUp()
60   {
61     Annotation[] anns = new Annotation[WIDTH];
62     /*
63      * set annotations with values 0-10, graded colours
64      */
65     for (int col = 0; col < WIDTH; col++)
66     {
67       int hue = col * 20;
68       Color colour = new Color(hue, hue, hue);
69       anns[col] = new Annotation("a", "a", 'a', col, colour);
70     }
71
72     seq = new Sequence("Seq", "");
73     al = new Alignment(new SequenceI[] { seq });
74
75     /*
76      * AlignmentAnnotation constructor works out min-max range
77      */
78     ann = new AlignmentAnnotation("", "", anns);
79     ann.setThreshold(new GraphLine(THRESHOLD_FIVE, "", Color.RED));
80     seq.addAlignmentAnnotation(ann);
81   }
82
83   @Test(groups = "Functional")
84   public void testShadeCalculation_noThreshold()
85   {
86     AnnotationColourGradient testee = new AnnotationColourGradient(ann,
87             minColour, maxColour, AnnotationColourGradient.NO_THRESHOLD);
88     for (int col = 0; col < WIDTH; col++)
89     {
90       Color result = testee.shadeCalculation(ann, col);
91       /*
92        * column <n> is n/10 of the way from minCol to maxCol
93        */
94       Color expected = new Color(50 + 10 * col, 200 - 10 * col,
95               150 + 10 * col);
96       assertEquals(result, expected, "for column " + col);
97     }
98   }
99
100   /**
101    * Test the 'colour above threshold' case
102    */
103   @Test(groups = "Functional")
104   public void testShadeCalculation_aboveThreshold()
105   {
106     AnnotationColourGradient testee = new AnnotationColourGradient(ann,
107             minColour, maxColour, AnnotationColourGradient.ABOVE_THRESHOLD);
108     for (int col = 0; col < WIDTH; col++)
109     {
110       Color result = testee.shadeCalculation(ann, col);
111       /*
112        * colour is derived regardless of the threshold value 
113        * (the renderer will suppress colouring if above/below threshold)
114        */
115       Color expected = new Color(50 + 10 * col, 200 - 10 * col,
116               150 + 10 * col);
117       assertEquals(result, expected, "for column " + col);
118     }
119
120     /*
121      * now make 6-10 the span of the colour range
122      * (annotation value == column number in this test)
123      */
124     testee.setThresholdIsMinMax(true);
125     for (int col = 0; col < THRESHOLD_FIVE; col++)
126     {
127       /*
128        * colours below the threshold are computed as before
129        */
130       Color expected = new Color(50 + 10 * col, 200 - 10 * col,
131               150 + 10 * col);
132       Color result = testee.shadeCalculation(ann, col);
133       assertEquals(result, expected, "for column " + col);
134     }
135     for (int col = THRESHOLD_FIVE; col < WIDTH; col++)
136     {
137       /*
138        * colours for values >= threshold are graduated
139        * range is 6-10 so steps of 100/5 = 20
140        */
141       int factor = col - THRESHOLD_FIVE;
142       Color expected = new Color(50 + 20 * factor, 200 - 20 * factor,
143               150 + 20 * factor);
144       Color result = testee.shadeCalculation(ann, col);
145       assertEquals(result, expected, "for column " + col);
146     }
147
148     /*
149      * test for boundary case threshold == graphMax (JAL-3206)
150      */
151     float thresh = ann.threshold.value;
152     ann.threshold.value = ann.graphMax;
153     Color result = testee.shadeCalculation(ann, WIDTH - 1);
154     assertEquals(result, maxColour);
155     testee.setThresholdIsMinMax(false);
156     result = testee.shadeCalculation(ann, WIDTH - 1);
157     assertEquals(result, maxColour);
158     ann.threshold.value = thresh; // reset
159   }
160
161   /**
162    * Test the 'colour below threshold' case
163    */
164   @Test(groups = "Functional")
165   public void testShadeCalculation_belowThreshold()
166   {
167     AnnotationColourGradient testee = new AnnotationColourGradient(ann,
168             minColour, maxColour, AnnotationColourGradient.BELOW_THRESHOLD);
169
170     for (int col = 0; col < WIDTH; col++)
171     {
172       Color result = testee.shadeCalculation(ann, col);
173       /*
174        * colour is derived regardless of the threshold value 
175        * (the renderer will suppress colouring if above/below threshold)
176        */
177       Color expected = new Color(50 + 10 * col, 200 - 10 * col,
178               150 + 10 * col);
179       assertEquals(result, expected, "for column " + col);
180     }
181
182     /*
183      * now make 0-5 the span of the colour range
184      * (annotation value == column number in this test)
185      */
186     testee.setThresholdIsMinMax(true);
187     for (int col = THRESHOLD_FIVE + 1; col < WIDTH; col++)
188     {
189       /*
190        * colours above the threshold are computed as before
191        */
192       Color expected = new Color(50 + 10 * col, 200 - 10 * col,
193               150 + 10 * col);
194       Color result = testee.shadeCalculation(ann, col);
195       assertEquals(result, expected, "for column " + col);
196     }
197
198     for (int col = 0; col <= THRESHOLD_FIVE; col++)
199     {
200       /*
201        * colours for values <= threshold are graduated
202        * range is 0-5 so steps of 100/5 = 20
203        */
204       Color expected = new Color(50 + 20 * col, 200 - 20 * col,
205               150 + 20 * col);
206       Color result = testee.shadeCalculation(ann, col);
207       assertEquals(result, expected, "for column " + col);
208     }
209
210     /*
211      * test for boundary case threshold == graphMin (JAL-3206)
212      */
213     float thresh = ann.threshold.value;
214     ann.threshold.value = ann.graphMin;
215     Color result = testee.shadeCalculation(ann, 0);
216     assertEquals(result, minColour);
217     testee.setThresholdIsMinMax(false);
218     result = testee.shadeCalculation(ann, 0);
219     assertEquals(result, minColour);
220     ann.threshold.value = thresh; // reset
221   }
222
223   /**
224    * Test the 'colour above threshold' case
225    */
226   @Test(groups = "Functional")
227   public void testFindColour_aboveThreshold()
228   {
229     AnnotationColourGradient testee = new AnnotationColourGradient(ann,
230             minColour, maxColour, AnnotationColourGradient.ABOVE_THRESHOLD);
231     testee = (AnnotationColourGradient) testee.getInstance(null, al);
232
233     for (int col = 0; col < WIDTH; col++)
234     {
235       Color result = testee.findColour('a', col, seq);
236       /*
237        * expect white at or below threshold of 5
238        */
239       Color expected = col <= 5 ? Color.white
240               : new Color(50 + 10 * col, 200 - 10 * col, 150 + 10 * col);
241       assertEquals(result, expected, "for column " + col);
242     }
243
244     /*
245      * now make 6-10 the span of the colour range
246      * (annotation value == column number in this test)
247      */
248     testee.setThresholdIsMinMax(true);
249     for (int col = 0; col < WIDTH; col++)
250     {
251       /*
252        * colours for values > threshold are graduated
253        * range is 6-10 so steps of 100/5 = 20
254        */
255       int factor = col - THRESHOLD_FIVE;
256       Color expected = col <= 5 ? Color.white
257               : new Color(50 + 20 * factor, 200 - 20 * factor,
258                       150 + 20 * factor);
259       Color result = testee.findColour('a', col, seq);
260       assertEquals(result, expected, "for column " + col);
261     }
262   }
263
264   /**
265    * Test the 'colour below threshold' case
266    */
267   @Test(groups = "Functional")
268   public void testFindColour_belowThreshold()
269   {
270     AnnotationColourGradient testee = new AnnotationColourGradient(ann,
271             minColour, maxColour, AnnotationColourGradient.BELOW_THRESHOLD);
272     testee = (AnnotationColourGradient) testee.getInstance(null, al);
273
274     for (int col = 0; col < WIDTH; col++)
275     {
276       Color result = testee.findColour('a', col, seq);
277       Color expected = col >= 5 ? Color.white
278               : new Color(50 + 10 * col, 200 - 10 * col, 150 + 10 * col);
279       assertEquals(result, expected, "for column " + col);
280     }
281
282     /*
283      * now make 0-5 the span of the colour range
284      * (annotation value == column number in this test)
285      */
286     testee.setThresholdIsMinMax(true);
287     for (int col = 0; col < WIDTH; col++)
288     {
289       /*
290        * colours for values < threshold are graduated
291        * range is 0-5 so steps of 100/5 = 20
292        */
293       Color expected = col >= 5 ? Color.white
294               : new Color(50 + 20 * col, 200 - 20 * col, 150 + 20 * col);
295       Color result = testee.findColour('a', col, seq);
296       assertEquals(result, expected, "for column " + col);
297     }
298   }
299
300   @Test(groups = "Functional")
301   public void testFindColour_noThreshold()
302   {
303     AnnotationColourGradient testee = new AnnotationColourGradient(ann,
304             minColour, maxColour, AnnotationColourGradient.NO_THRESHOLD);
305     testee = (AnnotationColourGradient) testee.getInstance(null, al);
306
307     for (int col = 0; col < WIDTH; col++)
308     {
309       Color result = testee.findColour('a', col, seq);
310       /*
311        * column <n> is n/10 of the way from minCol to maxCol
312        */
313       Color expected = new Color(50 + 10 * col, 200 - 10 * col,
314               150 + 10 * col);
315       assertEquals(result, expected, "for column " + col);
316     }
317   }
318
319   @Test(groups = "Functional")
320   public void testFindColour_originalColours()
321   {
322     AnnotationColourGradient testee = new AnnotationColourGradient(ann,
323             minColour, maxColour, AnnotationColourGradient.NO_THRESHOLD);
324     testee = (AnnotationColourGradient) testee.getInstance(null, al);
325
326     /*
327      * flag corresponding to 'use original colours' checkbox
328      * - just use the individual annotation colours
329      */
330     testee.setPredefinedColours(true);
331
332     /*
333      * the annotation colour is returned, except for column 0 where it is
334      * black - in this case the colour scheme colour overrides it
335      */
336     for (int col = 0; col < WIDTH; col++)
337     {
338       int hue = col * 20;
339       Color c = col == 0 ? minColour : new Color(hue, hue, hue);
340       assertEquals(testee.findColour('a', col, seq), c,
341               "for column " + col);
342     }
343   }
344 }