1 package jalview.schemes;
3 import static org.testng.AssertJUnit.assertEquals;
4 import static org.testng.AssertJUnit.assertFalse;
5 import static org.testng.AssertJUnit.assertTrue;
6 import static org.testng.AssertJUnit.fail;
8 import jalview.datamodel.SequenceFeature;
9 import jalview.util.Format;
11 import java.awt.Color;
13 import org.testng.annotations.Test;
15 public class FeatureColourTest
17 @Test(groups = { "Functional" })
18 public void testCopyConstructor()
23 FeatureColour fc = new FeatureColour(Color.RED);
24 FeatureColour fc1 = new FeatureColour(fc);
25 assertTrue(fc1.getColour().equals(Color.RED));
26 assertFalse(fc1.isGraduatedColour());
27 assertFalse(fc1.isColourByLabel());
32 fc = new FeatureColour(Color.gray, Color.black, 10f, 20f);
33 fc.setAboveThreshold(true);
35 fc1 = new FeatureColour(fc);
36 assertTrue(fc1.isGraduatedColour());
37 assertFalse(fc1.isColourByLabel());
38 assertTrue(fc1.isAboveThreshold());
39 assertEquals(12f, fc1.getThreshold());
40 assertEquals(Color.gray, fc1.getMinColour());
41 assertEquals(Color.black, fc1.getMaxColour());
42 assertEquals(10f, fc1.getMin());
43 assertEquals(20f, fc1.getMax());
48 fc = new FeatureColour();
49 fc.setColourByLabel(true);
50 fc1 = new FeatureColour(fc);
51 assertTrue(fc1.isColourByLabel());
52 assertFalse(fc1.isGraduatedColour());
55 @Test(groups = { "Functional" })
56 public void testIsColored_simpleColour()
58 FeatureColour fc = new FeatureColour(Color.RED);
59 assertTrue(fc.isColored(new SequenceFeature()));
62 @Test(groups = { "Functional" })
63 public void testIsColored_colourByLabel()
65 FeatureColour fc = new FeatureColour();
66 fc.setColourByLabel(true);
67 assertTrue(fc.isColored(new SequenceFeature()));
70 @Test(groups = { "Functional" })
71 public void testIsColored_aboveThreshold()
73 // graduated colour range from score 20 to 100
74 FeatureColour fc = new FeatureColour(Color.WHITE, Color.BLACK, 20f,
77 // score 0 is adjusted to bottom of range
78 SequenceFeature sf = new SequenceFeature("type", "desc", 0, 20, 0f,
80 assertTrue(fc.isColored(sf));
81 assertEquals(Color.WHITE, fc.getColor(sf));
83 // score 120 is adjusted to top of range
85 assertEquals(Color.BLACK, fc.getColor(sf));
87 // value below threshold is still rendered
88 // setting threshold has no effect yet...
91 assertTrue(fc.isColored(sf));
92 assertEquals(new Color(204, 204, 204), fc.getColor(sf));
94 // now apply threshold:
95 fc.setAboveThreshold(true);
96 assertFalse(fc.isColored(sf));
97 // colour is still returned though ?!?
98 assertEquals(new Color(204, 204, 204), fc.getColor(sf));
100 sf.setScore(84); // above threshold now
101 assertTrue(fc.isColored(sf));
102 assertEquals(new Color(51, 51, 51), fc.getColor(sf));
105 @Test(groups = { "Functional" })
106 public void testGetColor_simpleColour()
108 FeatureColour fc = new FeatureColour(Color.RED);
109 assertEquals(Color.RED, fc.getColor(new SequenceFeature()));
112 @Test(groups = { "Functional" })
113 public void testGetColor_colourByLabel()
115 FeatureColour fc = new FeatureColour();
116 fc.setColourByLabel(true);
117 SequenceFeature sf = new SequenceFeature("type", "desc", 0, 20, 1f,
119 Color expected = UserColourScheme.createColourFromName("desc");
120 assertEquals(expected, fc.getColor(sf));
123 @Test(groups = { "Functional" })
124 public void testGetColor_Graduated()
126 // graduated colour from score 0 to 100, gray(128, 128, 128) to red(255, 0, 0)
127 FeatureColour fc = new FeatureColour(Color.GRAY, Color.RED, 0f, 100f);
128 // feature score is 75 which is 3/4 of the way from GRAY to RED
129 SequenceFeature sf = new SequenceFeature("type", "desc", 0, 20, 75f,
131 // the colour gradient is computed in float values from 0-1 (where 1 == 255)
132 float red = 128 / 255f + 3 / 4f * (255 - 128) / 255f;
133 float green = 128 / 255f + 3 / 4f * (0 - 128) / 255f;
134 float blue = 128 / 255f + 3 / 4f * (0 - 128) / 255f;
135 Color expected = new Color(red, green, blue);
136 assertEquals(expected, fc.getColor(sf));
139 @Test(groups = { "Functional" })
140 public void testGetColor_belowThreshold()
142 // gradient from [50, 150] from WHITE(255, 255, 255) to BLACK(0, 0, 0)
143 FeatureColour fc = new FeatureColour(Color.WHITE, Color.BLACK, 50f,
145 SequenceFeature sf = new SequenceFeature("type", "desc", 0, 20, 70f,
147 fc.setThreshold(100f); // ignore for now
148 assertTrue(fc.isColored(sf));
149 assertEquals(new Color(204, 204, 204), fc.getColor(sf));
151 fc.setAboveThreshold(true); // feature lies below threshold
152 assertFalse(fc.isColored(sf));
153 assertEquals(new Color(204, 204, 204), fc.getColor(sf));
157 * Test output of feature colours to Jalview features file format
159 @Test(groups = { "Functional" })
160 public void testToJalviewFormat()
163 * plain colour - to RGB hex code
165 FeatureColour fc = new FeatureColour(Color.RED);
166 String redHex = Format.getHexString(Color.RED);
167 String hexColour = redHex;
168 assertEquals("domain\t" + hexColour, fc.toJalviewFormat("domain"));
171 * colour by label (no threshold)
173 fc = new FeatureColour();
174 fc.setColourByLabel(true);
175 assertEquals("domain\tlabel", fc.toJalviewFormat("domain"));
178 * colour by label (autoscaled) (an odd state you can reach by selecting
179 * 'above threshold', then deselecting 'threshold is min/max' then 'colour
182 fc.setAutoScaled(true);
183 assertEquals("domain\tlabel", fc.toJalviewFormat("domain"));
186 * colour by label (above threshold) (min/max values are output though not
187 * used by this scheme)
189 fc.setAutoScaled(false);
190 fc.setThreshold(12.5f);
191 fc.setAboveThreshold(true);
192 assertEquals("domain\tlabel|||0.0|0.0|above|12.5",
193 fc.toJalviewFormat("domain"));
196 * colour by label (below threshold)
198 fc.setBelowThreshold(true);
199 assertEquals("domain\tlabel|||0.0|0.0|below|12.5",
200 fc.toJalviewFormat("domain"));
203 * graduated colour, no threshold
205 fc = new FeatureColour(Color.GREEN, Color.RED, 12f, 25f);
206 String greenHex = Format.getHexString(Color.GREEN);
207 String expected = String.format("domain\t%s|%s|abso|12.0|25.0|none",
209 assertEquals(expected, fc.toJalviewFormat("domain"));
212 * colour ranges over the actual score ranges (not min/max)
214 fc.setAutoScaled(true);
215 expected = String.format("domain\t%s|%s|12.0|25.0|none", greenHex,
217 assertEquals(expected, fc.toJalviewFormat("domain"));
220 * graduated colour below threshold
222 fc.setThreshold(12.5f);
223 fc.setBelowThreshold(true);
224 expected = String.format("domain\t%s|%s|12.0|25.0|below|12.5",
226 assertEquals(expected, fc.toJalviewFormat("domain"));
229 * graduated colour above threshold
231 fc.setThreshold(12.5f);
232 fc.setAboveThreshold(true);
233 fc.setAutoScaled(false);
234 expected = String.format("domain\t%s|%s|abso|12.0|25.0|above|12.5",
236 assertEquals(expected, fc.toJalviewFormat("domain"));
240 * Test parsing of feature colours from Jalview features file format
242 @Test(groups = { "Functional" })
243 public void testParseJalviewFeatureColour()
246 * simple colour by name
248 FeatureColour fc = FeatureColour.parseJalviewFeatureColour("red");
249 assertTrue(fc.isSimpleColour());
250 assertEquals(Color.RED, fc.getColour());
253 * simple colour by hex code
255 fc = FeatureColour.parseJalviewFeatureColour(Format
256 .getHexString(Color.RED));
257 assertTrue(fc.isSimpleColour());
258 assertEquals(Color.RED, fc.getColour());
261 * simple colour by rgb triplet
263 fc = FeatureColour.parseJalviewFeatureColour("255,0,0");
264 assertTrue(fc.isSimpleColour());
265 assertEquals(Color.RED, fc.getColour());
272 fc = FeatureColour.parseJalviewFeatureColour("oops");
273 fail("expected exception");
274 } catch (IllegalArgumentException e)
276 assertEquals("Invalid colour descriptor: oops", e.getMessage());
280 * colour by label (no threshold)
282 fc = FeatureColour.parseJalviewFeatureColour("label");
283 assertTrue(fc.isColourByLabel());
284 assertFalse(fc.hasThreshold());
287 * colour by label (with threshold)
290 .parseJalviewFeatureColour("label|||0.0|0.0|above|12.0");
291 assertTrue(fc.isColourByLabel());
292 assertTrue(fc.isAboveThreshold());
293 assertEquals(12.0f, fc.getThreshold());
296 * graduated colour (by name) (no threshold)
298 fc = FeatureColour.parseJalviewFeatureColour("red|green|10.0|20.0");
299 assertTrue(fc.isGraduatedColour());
300 assertFalse(fc.hasThreshold());
301 assertEquals(Color.RED, fc.getMinColour());
302 assertEquals(Color.GREEN, fc.getMaxColour());
303 assertEquals(10f, fc.getMin());
304 assertEquals(20f, fc.getMax());
305 assertTrue(fc.isAutoScaled());
308 * graduated colour (by hex code) (above threshold)
310 String descriptor = String.format("%s|%s|10.0|20.0|above|15",
311 Format.getHexString(Color.RED),
312 Format.getHexString(Color.GREEN));
313 fc = FeatureColour.parseJalviewFeatureColour(descriptor);
314 assertTrue(fc.isGraduatedColour());
315 assertTrue(fc.hasThreshold());
316 assertTrue(fc.isAboveThreshold());
317 assertEquals(15f, fc.getThreshold());
318 assertEquals(Color.RED, fc.getMinColour());
319 assertEquals(Color.GREEN, fc.getMaxColour());
320 assertEquals(10f, fc.getMin());
321 assertEquals(20f, fc.getMax());
322 assertTrue(fc.isAutoScaled());
325 * graduated colour (by RGB triplet) (below threshold), absolute scale
327 descriptor = String.format("255,0,0|0,255,0|abso|10.0|20.0|below|15");
328 fc = FeatureColour.parseJalviewFeatureColour(descriptor);
329 assertTrue(fc.isGraduatedColour());
330 assertFalse(fc.isAutoScaled());
331 assertTrue(fc.hasThreshold());
332 assertTrue(fc.isBelowThreshold());
333 assertEquals(15f, fc.getThreshold());
334 assertEquals(Color.RED, fc.getMinColour());
335 assertEquals(Color.GREEN, fc.getMaxColour());
336 assertEquals(10f, fc.getMin());
337 assertEquals(20f, fc.getMax());
340 .format("blue|255,0,255|absolute|20.0|95.0|below|66.0");
341 fc = FeatureColour.parseJalviewFeatureColour(descriptor);
342 assertTrue(fc.isGraduatedColour());