JAL-2094 new classes ColorI, Colour added
[jalview.git] / test / jalview / schemes / FeatureColourTest.java
1 package jalview.schemes;
2
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;
7
8 import jalview.api.ColorI;
9 import jalview.datamodel.SequenceFeature;
10 import jalview.util.Format;
11
12 import java.awt.Color;
13
14 import org.testng.annotations.Test;
15
16 public class FeatureColourTest
17 {
18   @Test(groups = { "Functional" })
19   public void testIsColored_simpleColour()
20   {
21     FeatureColour fc = new FeatureColour(Color.RED);
22     assertTrue(fc.isColored(new SequenceFeature()));
23   }
24
25   @Test(groups = { "Functional" })
26   public void testIsColored_colourByLabel()
27   {
28     FeatureColour fc = new FeatureColour();
29     fc.setColourByLabel(true);
30     assertTrue(fc.isColored(new SequenceFeature()));
31   }
32
33   @Test(groups = { "Functional" })
34   public void testIsColored_aboveThreshold()
35   {
36     // graduated colour range from score 20 to 100
37     FeatureColour fc = new FeatureColour(new Colour(Color.WHITE),
38             new Colour(Color.BLACK), 20f, 100f);
39
40     // score 0 is adjusted to bottom of range
41     SequenceFeature sf = new SequenceFeature("type", "desc", 0, 20, 0f,
42             null);
43     assertTrue(fc.isColored(sf));
44     assertEquals(fc.getColor(sf), Colour.white);
45
46     // score 120 is adjusted to top of range
47     sf.setScore(120f);
48     assertEquals(fc.getColor(sf), Colour.black);
49
50     // value below threshold is still rendered
51     // setting threshold has no effect yet...
52     fc.setThreshold(60f);
53     sf.setScore(36f);
54     assertTrue(fc.isColored(sf));
55     assertEquals(fc.getColor(sf), new Colour(204, 204, 204));
56
57     // now apply threshold:
58     fc.setAboveThreshold(true);
59     assertFalse(fc.isColored(sf));
60     // colour is still returned though ?!?
61     assertEquals(fc.getColor(sf), new Colour(204, 204, 204));
62
63     sf.setScore(84); // above threshold now
64     assertTrue(fc.isColored(sf));
65     assertEquals(fc.getColor(sf), new Colour(51, 51, 51));
66   }
67
68   @Test(groups = { "Functional" })
69   public void testGetColor_simpleColour()
70   {
71     FeatureColour fc = new FeatureColour(Colour.red);
72     assertEquals(fc.getColor(new SequenceFeature()), Colour.red);
73   }
74
75   @Test(groups = { "Functional" })
76   public void testGetColor_colourByLabel()
77   {
78     FeatureColour fc = new FeatureColour();
79     fc.setColourByLabel(true);
80     SequenceFeature sf = new SequenceFeature("type", "desc", 0, 20, 1f,
81             null);
82     ColorI expected = new Colour(
83             UserColourScheme.createColourFromName("desc"));
84     assertEquals(fc.getColor(sf), expected);
85     // assertEquals(expected, fc.getColor(sf));
86   }
87
88   @Test(groups = { "Functional" })
89   public void testGetColor_Graduated()
90   {
91     // graduated colour from score 0 to 100, gray(128, 128, 128) to red(255, 0, 0)
92     FeatureColour fc = new FeatureColour(Color.GRAY, Color.RED, 0f, 100f);
93     // feature score is 75 which is 3/4 of the way from GRAY to RED
94     SequenceFeature sf = new SequenceFeature("type", "desc", 0, 20, 75f,
95             null);
96     // the colour gradient is computed in float values from 0-1 (where 1 == 255)
97     float red = 128 / 255f + 3 / 4f * (255 - 128) / 255f;
98     float green = 128 / 255f + 3 / 4f * (0 - 128) / 255f;
99     float blue = 128 / 255f + 3 / 4f * (0 - 128) / 255f;
100     Colour expected = new Colour(red, green, blue);
101     assertEquals(fc.getColor(sf), expected);
102     // assertEquals(expected, fc.getColor(sf));
103   }
104
105   @Test(groups = { "Functional" })
106   public void testGetColor_belowThreshold()
107   {
108     // gradient from [50, 150] from WHITE(255, 255, 255) to BLACK(0, 0, 0)
109     FeatureColour fc = new FeatureColour(Color.WHITE, Color.BLACK, 50f,
110             150f);
111     SequenceFeature sf = new SequenceFeature("type", "desc", 0, 20, 70f,
112             null);
113     fc.setThreshold(100f); // ignore for now
114     assertTrue(fc.isColored(sf));
115     assertEquals(fc.getColor(sf), new Colour(204, 204, 204));
116     // assertEquals(new Color(204, 204, 204), fc.getColor(sf));
117
118     fc.setAboveThreshold(true); // feature lies below threshold
119     assertFalse(fc.isColored(sf));
120     assertEquals(fc.getColor(sf), new Colour(204, 204, 204));
121     // assertEquals(new Color(204, 204, 204), fc.getColor(sf));
122   }
123
124   /**
125    * Test output of feature colours to Jalview features file format
126    */
127   @Test(groups = { "Functional" })
128   public void testToJalviewFormat()
129   {
130     /*
131      * plain colour - to RGB hex code
132      */
133     FeatureColour fc = new FeatureColour(Color.RED);
134     String redHex = Format.getHexString(Color.RED);
135     String hexColour = redHex;
136     assertEquals("domain\t" + hexColour, fc.toJalviewFormat("domain"));
137     
138     /*
139      * colour by label (no threshold)
140      */
141     fc = new FeatureColour();
142     fc.setColourByLabel(true);
143     assertEquals("domain\tlabel", fc.toJalviewFormat("domain"));
144
145     /*
146      * colour by label (autoscaled) (an odd state you can reach by selecting
147      * 'above threshold', then deselecting 'threshold is min/max' then 'colour
148      * by label')
149      */
150     fc.setAutoScaled(true);
151     assertEquals("domain\tlabel", fc.toJalviewFormat("domain"));
152
153     /*
154      * colour by label (above threshold) (min/max values are output though not
155      * used by this scheme)
156      */
157     fc.setAutoScaled(false);
158     fc.setThreshold(12.5f);
159     fc.setAboveThreshold(true);
160     assertEquals("domain\tlabel|||0.0|0.0|above|12.5",
161             fc.toJalviewFormat("domain"));
162
163     /*
164      * colour by label (below threshold)
165      */
166     fc.setBelowThreshold(true);
167     assertEquals("domain\tlabel|||0.0|0.0|below|12.5",
168             fc.toJalviewFormat("domain"));
169
170     /*
171      * graduated colour, no threshold
172      */
173     fc = new FeatureColour(Color.GREEN, Color.RED, 12f, 25f);
174     String greenHex = Format.getHexString(Color.GREEN);
175     String expected = String.format("domain\t%s|%s|12.0|25.0|none",
176             greenHex, redHex);
177     assertEquals(expected, fc.toJalviewFormat("domain"));
178
179     /*
180      * colour ranges over the actual score ranges (not min/max)
181      */
182     fc.setAutoScaled(true);
183     expected = String.format("domain\t%s|%s|abso|12.0|25.0|none", greenHex,
184             redHex);
185     assertEquals(expected, fc.toJalviewFormat("domain"));
186
187     /*
188      * graduated colour below threshold
189      */
190     fc.setThreshold(12.5f);
191     fc.setBelowThreshold(true);
192     expected = String.format("domain\t%s|%s|abso|12.0|25.0|below|12.5",
193             greenHex, redHex);
194     assertEquals(expected, fc.toJalviewFormat("domain"));
195
196     /*
197      * graduated colour above threshold
198      */
199     fc.setThreshold(12.5f);
200     fc.setAboveThreshold(true);
201     expected = String.format("domain\t%s|%s|abso|12.0|25.0|above|12.5",
202             greenHex, redHex);
203     assertEquals(expected, fc.toJalviewFormat("domain"));
204   }
205
206   /**
207    * Test parsing of feature colours from Jalview features file format
208    */
209   @Test(groups = { "Functional" })
210   public void testParseJalviewFeatureColour()
211   {
212     /*
213      * simple colour by name
214      */
215     FeatureColour fc = FeatureColour.parseJalviewFeatureColour("red");
216     assertTrue(fc.isSimpleColour());
217     assertEquals(fc.getColour(), Colour.red);
218
219     /*
220      * simple colour by hex code
221      */
222     fc = FeatureColour.parseJalviewFeatureColour(Format
223             .getHexString(Color.RED));
224     assertTrue(fc.isSimpleColour());
225     assertEquals(fc.getColour(), Colour.red);
226     // assertEquals(Color.RED, fc.getColour());
227
228     /*
229      * simple colour by rgb triplet
230      */
231     fc = FeatureColour.parseJalviewFeatureColour("255,0,0");
232     assertTrue(fc.isSimpleColour());
233     assertEquals(fc.getColour(), Colour.red);
234     // assertEquals(Color.RED, fc.getColour());
235
236     /*
237      * malformed colour
238      */
239     try
240     {
241       fc = FeatureColour.parseJalviewFeatureColour("oops");
242       fail("expected exception");
243     } catch (IllegalArgumentException e)
244     {
245       assertEquals("Invalid colour descriptor: oops", e.getMessage());
246     }
247
248     /*
249      * colour by label (no threshold)
250      */
251     fc = FeatureColour.parseJalviewFeatureColour("label");
252     assertTrue(fc.isColourByLabel());
253     assertFalse(fc.hasThreshold());
254
255     /*
256      * colour by label (with threshold)
257      */
258     fc = FeatureColour
259             .parseJalviewFeatureColour("label|||0.0|0.0|above|12.0");
260     assertTrue(fc.isColourByLabel());
261     assertTrue(fc.isAboveThreshold());
262     assertEquals(12.0f, fc.getThreshold());
263
264     /*
265      * graduated colour (by name) (no threshold)
266      */
267     fc = FeatureColour.parseJalviewFeatureColour("red|green|10.0|20.0");
268     assertTrue(fc.isGraduatedColour());
269     assertFalse(fc.hasThreshold());
270     assertEquals(fc.getMinColour(), Colour.red);
271     // assertEquals(Color.RED, fc.getMinColour());
272     assertEquals(fc.getMaxColour(), Colour.green);
273     // assertEquals(Color.GREEN, fc.getMaxColour());
274     assertEquals(10f, fc.getMin());
275     assertEquals(20f, fc.getMax());
276     assertTrue(fc.isAutoScaled());
277
278     /*
279      * graduated colour (by hex code) (above threshold)
280      */
281     String descriptor = String.format("%s|%s|10.0|20.0|above|15",
282             Format.getHexString(Color.RED),
283             Format.getHexString(Color.GREEN));
284     fc = FeatureColour.parseJalviewFeatureColour(descriptor);
285     assertTrue(fc.isGraduatedColour());
286     assertTrue(fc.hasThreshold());
287     assertTrue(fc.isAboveThreshold());
288     assertEquals(15f, fc.getThreshold());
289     assertEquals(fc.getMinColour(), Colour.red);
290     // assertEquals(Color.RED, fc.getMinColour());
291     assertEquals(fc.getMaxColour(), Colour.green);
292     // assertEquals(Color.GREEN, fc.getMaxColour());
293     assertEquals(10f, fc.getMin());
294     assertEquals(20f, fc.getMax());
295     assertTrue(fc.isAutoScaled());
296
297     /*
298      * graduated colour (by RGB triplet) (below threshold), absolute scale
299      */
300     descriptor = String.format("255,0,0|0,255,0|abso|10.0|20.0|below|15");
301     fc = FeatureColour.parseJalviewFeatureColour(descriptor);
302     assertTrue(fc.isGraduatedColour());
303     assertFalse(fc.isAutoScaled());
304     assertTrue(fc.hasThreshold());
305     assertTrue(fc.isBelowThreshold());
306     assertEquals(15f, fc.getThreshold());
307     assertEquals(fc.getMinColour(), Colour.red);
308     // assertEquals(Color.RED, fc.getMinColour());
309     assertEquals(fc.getMaxColour(), Colour.green);
310     // assertEquals(Color.GREEN, fc.getMaxColour());
311     assertEquals(10f, fc.getMin());
312     assertEquals(20f, fc.getMax());
313   }
314 }