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,
128 FeatureColour fc = new FeatureColour(Color.GRAY, Color.RED, 0f, 100f);
129 // feature score is 75 which is 3/4 of the way from GRAY to RED
130 SequenceFeature sf = new SequenceFeature("type", "desc", 0, 20, 75f,
132 // the colour gradient is computed in float values from 0-1 (where 1 == 255)
133 float red = 128 / 255f + 3 / 4f * (255 - 128) / 255f;
134 float green = 128 / 255f + 3 / 4f * (0 - 128) / 255f;
135 float blue = 128 / 255f + 3 / 4f * (0 - 128) / 255f;
136 Color expected = new Color(red, green, blue);
137 assertEquals(expected, fc.getColor(sf));
140 @Test(groups = { "Functional" })
141 public void testGetColor_belowThreshold()
143 // gradient from [50, 150] from WHITE(255, 255, 255) to BLACK(0, 0, 0)
144 FeatureColour fc = new FeatureColour(Color.WHITE, Color.BLACK, 50f,
146 SequenceFeature sf = new SequenceFeature("type", "desc", 0, 20, 70f,
148 fc.setThreshold(100f); // ignore for now
149 assertTrue(fc.isColored(sf));
150 assertEquals(new Color(204, 204, 204), fc.getColor(sf));
152 fc.setAboveThreshold(true); // feature lies below threshold
153 assertFalse(fc.isColored(sf));
154 assertEquals(new Color(204, 204, 204), fc.getColor(sf));
158 * Test output of feature colours to Jalview features file format
160 @Test(groups = { "Functional" })
161 public void testToJalviewFormat()
164 * plain colour - to RGB hex code
166 FeatureColour fc = new FeatureColour(Color.RED);
167 String redHex = Format.getHexString(Color.RED);
168 String hexColour = redHex;
169 assertEquals("domain\t" + hexColour, fc.toJalviewFormat("domain"));
172 * colour by label (no threshold)
174 fc = new FeatureColour();
175 fc.setColourByLabel(true);
176 assertEquals("domain\tlabel", fc.toJalviewFormat("domain"));
179 * colour by label (autoscaled) (an odd state you can reach by selecting
180 * 'above threshold', then deselecting 'threshold is min/max' then 'colour
183 fc.setAutoScaled(true);
184 assertEquals("domain\tlabel", fc.toJalviewFormat("domain"));
187 * colour by label (above threshold) (min/max values are output though not
188 * used by this scheme)
190 fc.setAutoScaled(false);
191 fc.setThreshold(12.5f);
192 fc.setAboveThreshold(true);
193 assertEquals("domain\tlabel|||0.0|0.0|above|12.5",
194 fc.toJalviewFormat("domain"));
197 * colour by label (below threshold)
199 fc.setBelowThreshold(true);
200 assertEquals("domain\tlabel|||0.0|0.0|below|12.5",
201 fc.toJalviewFormat("domain"));
204 * graduated colour, no threshold
206 fc = new FeatureColour(Color.GREEN, Color.RED, 12f, 25f);
207 String greenHex = Format.getHexString(Color.GREEN);
208 String expected = String.format("domain\t%s|%s|abso|12.0|25.0|none",
210 assertEquals(expected, fc.toJalviewFormat("domain"));
213 * colour ranges over the actual score ranges (not min/max)
215 fc.setAutoScaled(true);
216 expected = String.format("domain\t%s|%s|12.0|25.0|none", greenHex,
218 assertEquals(expected, fc.toJalviewFormat("domain"));
221 * graduated colour below threshold
223 fc.setThreshold(12.5f);
224 fc.setBelowThreshold(true);
225 expected = String.format("domain\t%s|%s|12.0|25.0|below|12.5",
227 assertEquals(expected, fc.toJalviewFormat("domain"));
230 * graduated colour above threshold
232 fc.setThreshold(12.5f);
233 fc.setAboveThreshold(true);
234 fc.setAutoScaled(false);
235 expected = String.format("domain\t%s|%s|abso|12.0|25.0|above|12.5",
237 assertEquals(expected, fc.toJalviewFormat("domain"));
241 * Test parsing of feature colours from Jalview features file format
243 @Test(groups = { "Functional" })
244 public void testParseJalviewFeatureColour()
247 * simple colour by name
249 FeatureColour fc = FeatureColour.parseJalviewFeatureColour("red");
250 assertTrue(fc.isSimpleColour());
251 assertEquals(Color.RED, fc.getColour());
254 * simple colour by hex code
256 fc = FeatureColour.parseJalviewFeatureColour(Format
257 .getHexString(Color.RED));
258 assertTrue(fc.isSimpleColour());
259 assertEquals(Color.RED, fc.getColour());
262 * simple colour by rgb triplet
264 fc = FeatureColour.parseJalviewFeatureColour("255,0,0");
265 assertTrue(fc.isSimpleColour());
266 assertEquals(Color.RED, fc.getColour());
273 fc = FeatureColour.parseJalviewFeatureColour("oops");
274 fail("expected exception");
275 } catch (IllegalArgumentException e)
277 assertEquals("Invalid colour descriptor: oops", e.getMessage());
281 * colour by label (no threshold)
283 fc = FeatureColour.parseJalviewFeatureColour("label");
284 assertTrue(fc.isColourByLabel());
285 assertFalse(fc.hasThreshold());
288 * colour by label (with threshold)
291 .parseJalviewFeatureColour("label|||0.0|0.0|above|12.0");
292 assertTrue(fc.isColourByLabel());
293 assertTrue(fc.isAboveThreshold());
294 assertEquals(12.0f, fc.getThreshold());
297 * graduated colour (by name) (no threshold)
299 fc = FeatureColour.parseJalviewFeatureColour("red|green|10.0|20.0");
300 assertTrue(fc.isGraduatedColour());
301 assertFalse(fc.hasThreshold());
302 assertEquals(Color.RED, fc.getMinColour());
303 assertEquals(Color.GREEN, fc.getMaxColour());
304 assertEquals(10f, fc.getMin());
305 assertEquals(20f, fc.getMax());
306 assertTrue(fc.isAutoScaled());
309 * graduated colour (by hex code) (above threshold)
311 String descriptor = String.format("%s|%s|10.0|20.0|above|15",
312 Format.getHexString(Color.RED),
313 Format.getHexString(Color.GREEN));
314 fc = FeatureColour.parseJalviewFeatureColour(descriptor);
315 assertTrue(fc.isGraduatedColour());
316 assertTrue(fc.hasThreshold());
317 assertTrue(fc.isAboveThreshold());
318 assertEquals(15f, fc.getThreshold());
319 assertEquals(Color.RED, fc.getMinColour());
320 assertEquals(Color.GREEN, fc.getMaxColour());
321 assertEquals(10f, fc.getMin());
322 assertEquals(20f, fc.getMax());
323 assertTrue(fc.isAutoScaled());
326 * graduated colour (by RGB triplet) (below threshold), absolute scale
328 descriptor = String.format("255,0,0|0,255,0|abso|10.0|20.0|below|15");
329 fc = FeatureColour.parseJalviewFeatureColour(descriptor);
330 assertTrue(fc.isGraduatedColour());
331 assertFalse(fc.isAutoScaled());
332 assertTrue(fc.hasThreshold());
333 assertTrue(fc.isBelowThreshold());
334 assertEquals(15f, fc.getThreshold());
335 assertEquals(Color.RED, fc.getMinColour());
336 assertEquals(Color.GREEN, fc.getMaxColour());
337 assertEquals(10f, fc.getMin());
338 assertEquals(20f, fc.getMax());
341 .format("blue|255,0,255|absolute|20.0|95.0|below|66.0");
342 fc = FeatureColour.parseJalviewFeatureColour(descriptor);
343 assertTrue(fc.isGraduatedColour());