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