2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
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.
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.
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.
21 package jalview.schemes;
23 import static org.testng.Assert.assertEquals;
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;
33 import java.awt.Color;
35 import org.testng.annotations.BeforeClass;
36 import org.testng.annotations.Test;
38 public class AnnotationColourGradientTest
40 final static int WIDTH = 11;
42 final static int THRESHOLD_FIVE = 5;
44 private AlignmentAnnotation ann;
46 private SequenceI seq;
48 private AlignmentI al;
50 Color minColour = new Color(50, 200, 150);
52 Color maxColour = new Color(150, 100, 250);
55 * Setup creates an annotation over 11 columns with values 0-10 and threshold
58 @BeforeClass(alwaysRun = true)
61 Annotation[] anns = new Annotation[WIDTH];
63 * set annotations with values 0-10, graded colours
65 for (int col = 0; col < WIDTH; col++)
68 Color colour = new Color(hue, hue, hue);
69 anns[col] = new Annotation("a", "a", 'a', col, colour);
72 seq = new Sequence("Seq", "");
73 al = new Alignment(new SequenceI[] { seq });
76 * AlignmentAnnotation constructor works out min-max range
78 ann = new AlignmentAnnotation("", "", anns);
79 ann.setThreshold(new GraphLine(THRESHOLD_FIVE, "", Color.RED));
80 seq.addAlignmentAnnotation(ann);
83 @Test(groups = "Functional")
84 public void testShadeCalculation_noThreshold()
86 AnnotationColourGradient testee = new AnnotationColourGradient(ann,
87 minColour, maxColour, AnnotationColourGradient.NO_THRESHOLD);
88 for (int col = 0; col < WIDTH; col++)
90 Color result = testee.shadeCalculation(ann, col);
92 * column <n> is n/10 of the way from minCol to maxCol
94 Color expected = new Color(50 + 10 * col, 200 - 10 * col,
96 assertEquals(result, expected, "for column " + col);
101 * Test the 'colour above threshold' case
103 @Test(groups = "Functional")
104 public void testShadeCalculation_aboveThreshold()
106 AnnotationColourGradient testee = new AnnotationColourGradient(ann,
107 minColour, maxColour, AnnotationColourGradient.ABOVE_THRESHOLD);
108 for (int col = 0; col < WIDTH; col++)
110 Color result = testee.shadeCalculation(ann, col);
112 * colour is derived regardless of the threshold value
113 * (the renderer will suppress colouring if above/below threshold)
115 Color expected = new Color(50 + 10 * col, 200 - 10 * col,
117 assertEquals(result, expected, "for column " + col);
121 * now make 6-10 the span of the colour range
122 * (annotation value == column number in this test)
124 testee.setThresholdIsMinMax(true);
125 for (int col = 0; col < THRESHOLD_FIVE; col++)
128 * colours below the threshold are computed as before
130 Color expected = new Color(50 + 10 * col, 200 - 10 * col,
132 Color result = testee.shadeCalculation(ann, col);
133 assertEquals(result, expected, "for column " + col);
135 for (int col = THRESHOLD_FIVE; col < WIDTH; col++)
138 * colours for values >= threshold are graduated
139 * range is 6-10 so steps of 100/5 = 20
141 int factor = col - THRESHOLD_FIVE;
142 Color expected = new Color(50 + 20 * factor, 200 - 20 * factor,
144 Color result = testee.shadeCalculation(ann, col);
145 assertEquals(result, expected, "for column " + col);
149 * test for boundary case threshold == graphMax (JAL-3206)
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
162 * Test the 'colour below threshold' case
164 @Test(groups = "Functional")
165 public void testShadeCalculation_belowThreshold()
167 AnnotationColourGradient testee = new AnnotationColourGradient(ann,
168 minColour, maxColour, AnnotationColourGradient.BELOW_THRESHOLD);
170 for (int col = 0; col < WIDTH; col++)
172 Color result = testee.shadeCalculation(ann, col);
174 * colour is derived regardless of the threshold value
175 * (the renderer will suppress colouring if above/below threshold)
177 Color expected = new Color(50 + 10 * col, 200 - 10 * col,
179 assertEquals(result, expected, "for column " + col);
183 * now make 0-5 the span of the colour range
184 * (annotation value == column number in this test)
186 testee.setThresholdIsMinMax(true);
187 for (int col = THRESHOLD_FIVE + 1; col < WIDTH; col++)
190 * colours above the threshold are computed as before
192 Color expected = new Color(50 + 10 * col, 200 - 10 * col,
194 Color result = testee.shadeCalculation(ann, col);
195 assertEquals(result, expected, "for column " + col);
198 for (int col = 0; col <= THRESHOLD_FIVE; col++)
201 * colours for values <= threshold are graduated
202 * range is 0-5 so steps of 100/5 = 20
204 Color expected = new Color(50 + 20 * col, 200 - 20 * col,
206 Color result = testee.shadeCalculation(ann, col);
207 assertEquals(result, expected, "for column " + col);
211 * test for boundary case threshold == graphMin (JAL-3206)
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
224 * Test the 'colour above threshold' case
226 @Test(groups = "Functional")
227 public void testFindColour_aboveThreshold()
229 AnnotationColourGradient testee = new AnnotationColourGradient(ann,
230 minColour, maxColour, AnnotationColourGradient.ABOVE_THRESHOLD);
231 testee = (AnnotationColourGradient) testee.getInstance(null, al);
233 for (int col = 0; col < WIDTH; col++)
235 Color result = testee.findColour('a', col, seq);
237 * expect white at or below threshold of 5
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);
245 * now make 6-10 the span of the colour range
246 * (annotation value == column number in this test)
248 testee.setThresholdIsMinMax(true);
249 for (int col = 0; col < WIDTH; col++)
252 * colours for values > threshold are graduated
253 * range is 6-10 so steps of 100/5 = 20
255 int factor = col - THRESHOLD_FIVE;
256 Color expected = col <= 5 ? Color.white
257 : new Color(50 + 20 * factor, 200 - 20 * factor,
259 Color result = testee.findColour('a', col, seq);
260 assertEquals(result, expected, "for column " + col);
265 * Test the 'colour below threshold' case
267 @Test(groups = "Functional")
268 public void testFindColour_belowThreshold()
270 AnnotationColourGradient testee = new AnnotationColourGradient(ann,
271 minColour, maxColour, AnnotationColourGradient.BELOW_THRESHOLD);
272 testee = (AnnotationColourGradient) testee.getInstance(null, al);
274 for (int col = 0; col < WIDTH; col++)
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);
283 * now make 0-5 the span of the colour range
284 * (annotation value == column number in this test)
286 testee.setThresholdIsMinMax(true);
287 for (int col = 0; col < WIDTH; col++)
290 * colours for values < threshold are graduated
291 * range is 0-5 so steps of 100/5 = 20
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);
300 @Test(groups = "Functional")
301 public void testFindColour_noThreshold()
303 AnnotationColourGradient testee = new AnnotationColourGradient(ann,
304 minColour, maxColour, AnnotationColourGradient.NO_THRESHOLD);
305 testee = (AnnotationColourGradient) testee.getInstance(null, al);
307 for (int col = 0; col < WIDTH; col++)
309 Color result = testee.findColour('a', col, seq);
311 * column <n> is n/10 of the way from minCol to maxCol
313 Color expected = new Color(50 + 10 * col, 200 - 10 * col,
315 assertEquals(result, expected, "for column " + col);
319 @Test(groups = "Functional")
320 public void testFindColour_originalColours()
322 AnnotationColourGradient testee = new AnnotationColourGradient(ann,
323 minColour, maxColour, AnnotationColourGradient.NO_THRESHOLD);
324 testee = (AnnotationColourGradient) testee.getInstance(null, al);
327 * flag corresponding to 'use original colours' checkbox
328 * - just use the individual annotation colours
330 testee.setPredefinedColours(true);
333 * the annotation colour is returned, except for column 0 where it is
334 * black - in this case the colour scheme colour overrides it
336 for (int col = 0; col < WIDTH; col++)
339 Color c = col == 0 ? minColour : new Color(hue, hue, hue);
340 assertEquals(testee.findColour('a', col, seq), c,
341 "for column " + col);