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.AssertJUnit.assertEquals;
24 import static org.testng.AssertJUnit.assertFalse;
25 import static org.testng.AssertJUnit.assertTrue;
26 import static org.testng.AssertJUnit.fail;
28 import jalview.datamodel.SequenceFeature;
29 import jalview.gui.JvOptionPane;
30 import jalview.util.ColorUtils;
31 import jalview.util.Format;
33 import java.awt.Color;
35 import org.testng.annotations.BeforeClass;
36 import org.testng.annotations.Test;
38 public class FeatureColourTest
41 @BeforeClass(alwaysRun = true)
42 public void setUpJvOptionPane()
44 JvOptionPane.setInteractiveMode(false);
45 JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
48 @Test(groups = { "Functional" })
49 public void testCopyConstructor()
54 FeatureColour fc = new FeatureColour(Color.RED);
55 FeatureColour fc1 = new FeatureColour(fc);
56 assertTrue(fc1.getColour().equals(Color.RED));
57 assertFalse(fc1.isGraduatedColour());
58 assertFalse(fc1.isColourByLabel());
63 fc = new FeatureColour(Color.gray, Color.black, 10f, 20f);
64 fc.setAboveThreshold(true);
66 fc1 = new FeatureColour(fc);
67 assertTrue(fc1.isGraduatedColour());
68 assertFalse(fc1.isColourByLabel());
69 assertTrue(fc1.isAboveThreshold());
70 assertEquals(12f, fc1.getThreshold());
71 assertEquals(Color.gray, fc1.getMinColour());
72 assertEquals(Color.black, fc1.getMaxColour());
73 assertEquals(10f, fc1.getMin());
74 assertEquals(20f, fc1.getMax());
79 fc = new FeatureColour();
80 fc.setColourByLabel(true);
81 fc1 = new FeatureColour(fc);
82 assertTrue(fc1.isColourByLabel());
83 assertFalse(fc1.isGraduatedColour());
86 @Test(groups = { "Functional" })
87 public void testIsColored_simpleColour()
89 FeatureColour fc = new FeatureColour(Color.RED);
90 assertTrue(fc.isColored(new SequenceFeature()));
93 @Test(groups = { "Functional" })
94 public void testIsColored_colourByLabel()
96 FeatureColour fc = new FeatureColour();
97 fc.setColourByLabel(true);
98 assertTrue(fc.isColored(new SequenceFeature()));
101 @Test(groups = { "Functional" })
102 public void testIsColored_aboveThreshold()
104 // graduated colour range from score 20 to 100
105 FeatureColour fc = new FeatureColour(Color.WHITE, Color.BLACK, 20f,
108 // score 0 is adjusted to bottom of range
109 SequenceFeature sf = new SequenceFeature("type", "desc", 0, 20, 0f,
111 assertTrue(fc.isColored(sf));
112 assertEquals(Color.WHITE, fc.getColor(sf));
114 // score 120 is adjusted to top of range
116 assertEquals(Color.BLACK, fc.getColor(sf));
118 // value below threshold is still rendered
119 // setting threshold has no effect yet...
120 fc.setThreshold(60f);
122 assertTrue(fc.isColored(sf));
123 assertEquals(new Color(204, 204, 204), fc.getColor(sf));
125 // now apply threshold:
126 fc.setAboveThreshold(true);
127 assertFalse(fc.isColored(sf));
128 // colour is still returned though ?!?
129 assertEquals(new Color(204, 204, 204), fc.getColor(sf));
131 sf.setScore(84); // above threshold now
132 assertTrue(fc.isColored(sf));
133 assertEquals(new Color(51, 51, 51), fc.getColor(sf));
136 @Test(groups = { "Functional" })
137 public void testGetColor_simpleColour()
139 FeatureColour fc = new FeatureColour(Color.RED);
140 assertEquals(Color.RED, fc.getColor(new SequenceFeature()));
143 @Test(groups = { "Functional" })
144 public void testGetColor_colourByLabel()
146 FeatureColour fc = new FeatureColour();
147 fc.setColourByLabel(true);
148 SequenceFeature sf = new SequenceFeature("type", "desc", 0, 20, 1f,
150 Color expected = ColorUtils.createColourFromName("desc");
151 assertEquals(expected, fc.getColor(sf));
154 @Test(groups = { "Functional" })
155 public void testGetColor_Graduated()
157 // graduated colour from score 0 to 100, gray(128, 128, 128) to red(255, 0,
159 FeatureColour fc = new FeatureColour(Color.GRAY, Color.RED, 0f, 100f);
160 // feature score is 75 which is 3/4 of the way from GRAY to RED
161 SequenceFeature sf = new SequenceFeature("type", "desc", 0, 20, 75f,
163 // the colour gradient is computed in float values from 0-1 (where 1 == 255)
164 float red = 128 / 255f + 3 / 4f * (255 - 128) / 255f;
165 float green = 128 / 255f + 3 / 4f * (0 - 128) / 255f;
166 float blue = 128 / 255f + 3 / 4f * (0 - 128) / 255f;
167 Color expected = new Color(red, green, blue);
168 assertEquals(expected, fc.getColor(sf));
171 @Test(groups = { "Functional" })
172 public void testGetColor_belowThreshold()
174 // gradient from [50, 150] from WHITE(255, 255, 255) to BLACK(0, 0, 0)
175 FeatureColour fc = new FeatureColour(Color.WHITE, Color.BLACK, 50f,
177 SequenceFeature sf = new SequenceFeature("type", "desc", 0, 20, 70f,
179 fc.setThreshold(100f); // ignore for now
180 assertTrue(fc.isColored(sf));
181 assertEquals(new Color(204, 204, 204), fc.getColor(sf));
183 fc.setAboveThreshold(true); // feature lies below threshold
184 assertFalse(fc.isColored(sf));
185 assertEquals(new Color(204, 204, 204), fc.getColor(sf));
189 * Test output of feature colours to Jalview features file format
191 @Test(groups = { "Functional" })
192 public void testToJalviewFormat()
195 * plain colour - to RGB hex code
197 FeatureColour fc = new FeatureColour(Color.RED);
198 String redHex = Format.getHexString(Color.RED);
199 String hexColour = redHex;
200 assertEquals("domain\t" + hexColour, fc.toJalviewFormat("domain"));
203 * colour by label (no threshold)
205 fc = new FeatureColour();
206 fc.setColourByLabel(true);
207 assertEquals("domain\tlabel", fc.toJalviewFormat("domain"));
210 * colour by label (autoscaled) (an odd state you can reach by selecting
211 * 'above threshold', then deselecting 'threshold is min/max' then 'colour
214 fc.setAutoScaled(true);
215 assertEquals("domain\tlabel", fc.toJalviewFormat("domain"));
218 * colour by label (above threshold) (min/max values are output though not
219 * used by this scheme)
221 fc.setAutoScaled(false);
222 fc.setThreshold(12.5f);
223 fc.setAboveThreshold(true);
224 assertEquals("domain\tlabel|||0.0|0.0|above|12.5",
225 fc.toJalviewFormat("domain"));
228 * colour by label (below threshold)
230 fc.setBelowThreshold(true);
231 assertEquals("domain\tlabel|||0.0|0.0|below|12.5",
232 fc.toJalviewFormat("domain"));
235 * graduated colour, no threshold
237 fc = new FeatureColour(Color.GREEN, Color.RED, 12f, 25f);
238 String greenHex = Format.getHexString(Color.GREEN);
239 String expected = String.format("domain\t%s|%s|abso|12.0|25.0|none",
241 assertEquals(expected, fc.toJalviewFormat("domain"));
244 * colour ranges over the actual score ranges (not min/max)
246 fc.setAutoScaled(true);
247 expected = String.format("domain\t%s|%s|12.0|25.0|none", greenHex,
249 assertEquals(expected, fc.toJalviewFormat("domain"));
252 * graduated colour below threshold
254 fc.setThreshold(12.5f);
255 fc.setBelowThreshold(true);
256 expected = String.format("domain\t%s|%s|12.0|25.0|below|12.5",
258 assertEquals(expected, fc.toJalviewFormat("domain"));
261 * graduated colour above threshold
263 fc.setThreshold(12.5f);
264 fc.setAboveThreshold(true);
265 fc.setAutoScaled(false);
266 expected = String.format("domain\t%s|%s|abso|12.0|25.0|above|12.5",
268 assertEquals(expected, fc.toJalviewFormat("domain"));
272 * Test parsing of feature colours from Jalview features file format
274 @Test(groups = { "Functional" })
275 public void testParseJalviewFeatureColour()
278 * simple colour by name
280 FeatureColour fc = FeatureColour.parseJalviewFeatureColour("red");
281 assertTrue(fc.isSimpleColour());
282 assertEquals(Color.RED, fc.getColour());
285 * simple colour by hex code
287 fc = FeatureColour.parseJalviewFeatureColour(Format
288 .getHexString(Color.RED));
289 assertTrue(fc.isSimpleColour());
290 assertEquals(Color.RED, fc.getColour());
293 * simple colour by rgb triplet
295 fc = FeatureColour.parseJalviewFeatureColour("255,0,0");
296 assertTrue(fc.isSimpleColour());
297 assertEquals(Color.RED, fc.getColour());
304 fc = FeatureColour.parseJalviewFeatureColour("oops");
305 fail("expected exception");
306 } catch (IllegalArgumentException e)
308 assertEquals("Invalid colour descriptor: oops", e.getMessage());
312 * colour by label (no threshold)
314 fc = FeatureColour.parseJalviewFeatureColour("label");
315 assertTrue(fc.isColourByLabel());
316 assertFalse(fc.hasThreshold());
319 * colour by label (with threshold)
322 .parseJalviewFeatureColour("label|||0.0|0.0|above|12.0");
323 assertTrue(fc.isColourByLabel());
324 assertTrue(fc.isAboveThreshold());
325 assertEquals(12.0f, fc.getThreshold());
328 * graduated colour (by name) (no threshold)
330 fc = FeatureColour.parseJalviewFeatureColour("red|green|10.0|20.0");
331 assertTrue(fc.isGraduatedColour());
332 assertFalse(fc.hasThreshold());
333 assertEquals(Color.RED, fc.getMinColour());
334 assertEquals(Color.GREEN, fc.getMaxColour());
335 assertEquals(10f, fc.getMin());
336 assertEquals(20f, fc.getMax());
337 assertTrue(fc.isAutoScaled());
340 * graduated colour (by hex code) (above threshold)
342 String descriptor = String.format("%s|%s|10.0|20.0|above|15",
343 Format.getHexString(Color.RED),
344 Format.getHexString(Color.GREEN));
345 fc = FeatureColour.parseJalviewFeatureColour(descriptor);
346 assertTrue(fc.isGraduatedColour());
347 assertTrue(fc.hasThreshold());
348 assertTrue(fc.isAboveThreshold());
349 assertEquals(15f, fc.getThreshold());
350 assertEquals(Color.RED, fc.getMinColour());
351 assertEquals(Color.GREEN, fc.getMaxColour());
352 assertEquals(10f, fc.getMin());
353 assertEquals(20f, fc.getMax());
354 assertTrue(fc.isAutoScaled());
357 * graduated colour (by RGB triplet) (below threshold), absolute scale
359 descriptor = String.format("255,0,0|0,255,0|abso|10.0|20.0|below|15");
360 fc = FeatureColour.parseJalviewFeatureColour(descriptor);
361 assertTrue(fc.isGraduatedColour());
362 assertFalse(fc.isAutoScaled());
363 assertTrue(fc.hasThreshold());
364 assertTrue(fc.isBelowThreshold());
365 assertEquals(15f, fc.getThreshold());
366 assertEquals(Color.RED, fc.getMinColour());
367 assertEquals(Color.GREEN, fc.getMaxColour());
368 assertEquals(10f, fc.getMin());
369 assertEquals(20f, fc.getMax());
372 .format("blue|255,0,255|absolute|20.0|95.0|below|66.0");
373 fc = FeatureColour.parseJalviewFeatureColour(descriptor);
374 assertTrue(fc.isGraduatedColour());