Clover icon

Coverage Report

  1. Project Clover database Thu Nov 7 2024 17:01:39 GMT
  2. Package jalview.schemes

File FeatureColourTest.java

 

Code metrics

0
366
13
1
802
500
15
0.04
28.15
13
1.15

Classes

Class Line # Actions
FeatureColourTest 41 366 15
0.00%
 

Contributing tests

No tests hitting this source file were found.

Source view

1    /*
2    * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3    * Copyright (C) $$Year-Rel$$ The Jalview Authors
4    *
5    * This file is part of Jalview.
6    *
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.
11    *
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.
16    *
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.
20    */
21    package jalview.schemes;
22   
23    import static org.testng.AssertJUnit.assertEquals;
24    import static org.testng.AssertJUnit.assertFalse;
25    import static org.testng.AssertJUnit.assertNull;
26    import static org.testng.AssertJUnit.assertTrue;
27    import static org.testng.AssertJUnit.fail;
28    import static org.testng.internal.junit.ArrayAsserts.assertArrayEquals;
29   
30    import jalview.api.FeatureColourI;
31    import jalview.datamodel.SequenceFeature;
32    import jalview.gui.JvOptionPane;
33    import jalview.util.ColorUtils;
34    import jalview.util.Format;
35   
36    import java.awt.Color;
37   
38    import org.testng.annotations.BeforeClass;
39    import org.testng.annotations.Test;
40   
 
41    public class FeatureColourTest
42    {
43   
 
44  0 toggle @BeforeClass(alwaysRun = true)
45    public void setUpJvOptionPane()
46    {
47  0 JvOptionPane.setInteractiveMode(false);
48  0 JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
49    }
50   
 
51  0 toggle @Test(groups = { "Functional" })
52    public void testConstructors()
53    {
54  0 FeatureColourI fc = new FeatureColour();
55  0 assertNull(fc.getColour());
56  0 assertTrue(fc.isSimpleColour());
57  0 assertFalse(fc.isColourByLabel());
58  0 assertFalse(fc.isGraduatedColour());
59  0 assertFalse(fc.isColourByAttribute());
60  0 assertEquals(Color.white, fc.getMinColour());
61  0 assertEquals(Color.black, fc.getMaxColour());
62   
63  0 fc = new FeatureColour(Color.RED);
64  0 assertEquals(Color.red, fc.getColour());
65  0 assertTrue(fc.isSimpleColour());
66  0 assertFalse(fc.isColourByLabel());
67  0 assertFalse(fc.isGraduatedColour());
68  0 assertFalse(fc.isColourByAttribute());
69  0 assertEquals(ColorUtils.bleachColour(Color.RED, 0.9f),
70    fc.getMinColour());
71  0 assertEquals(Color.RED, fc.getMaxColour());
72   
73    }
74   
 
75  0 toggle @Test(groups = { "Functional" })
76    public void testCopyConstructor()
77    {
78    /*
79    * plain colour
80    */
81  0 FeatureColour fc = new FeatureColour(Color.RED);
82  0 FeatureColour fc1 = new FeatureColour(fc);
83  0 assertTrue(fc1.getColour().equals(Color.RED));
84  0 assertFalse(fc1.isGraduatedColour());
85  0 assertFalse(fc1.isColourByLabel());
86  0 assertFalse(fc1.isColourByAttribute());
87  0 assertNull(fc1.getAttributeName());
88   
89    /*
90    * min-max colour
91    */
92  0 fc = new FeatureColour(null, Color.gray, Color.black, Color.gray, 10f,
93    20f);
94  0 fc.setAboveThreshold(true);
95  0 fc.setThreshold(12f);
96  0 fc1 = new FeatureColour(fc);
97  0 assertTrue(fc1.isGraduatedColour());
98  0 assertFalse(fc1.isColourByLabel());
99  0 assertTrue(fc1.isAboveThreshold());
100  0 assertFalse(fc1.isColourByAttribute());
101  0 assertNull(fc1.getAttributeName());
102  0 assertEquals(12f, fc1.getThreshold());
103  0 assertEquals(Color.gray, fc1.getMinColour());
104  0 assertEquals(Color.black, fc1.getMaxColour());
105  0 assertEquals(Color.gray, fc1.getNoColour());
106  0 assertEquals(10f, fc1.getMin());
107  0 assertEquals(20f, fc1.getMax());
108   
109    /*
110    * min-max-noValue colour
111    */
112  0 fc = new FeatureColour(Color.red, Color.gray, Color.black, Color.green,
113    10f, 20f);
114  0 fc.setAboveThreshold(true);
115  0 fc.setThreshold(12f);
116  0 fc1 = new FeatureColour(fc);
117  0 assertTrue(fc1.isGraduatedColour());
118  0 assertFalse(fc1.isColourByLabel());
119  0 assertFalse(fc1.isSimpleColour());
120  0 assertFalse(fc1.isColourByAttribute());
121  0 assertNull(fc1.getAttributeName());
122  0 assertTrue(fc1.isAboveThreshold());
123  0 assertEquals(12f, fc1.getThreshold());
124  0 assertEquals(Color.gray, fc1.getMinColour());
125  0 assertEquals(Color.black, fc1.getMaxColour());
126  0 assertEquals(Color.green, fc1.getNoColour());
127  0 assertEquals(Color.red, fc1.getColour());
128  0 assertEquals(10f, fc1.getMin());
129  0 assertEquals(20f, fc1.getMax());
130   
131    /*
132    * colour by label
133    */
134  0 fc = new FeatureColour();
135  0 fc.setColourByLabel(true);
136  0 fc1 = new FeatureColour(fc);
137  0 assertTrue(fc1.isColourByLabel());
138  0 assertFalse(fc1.isGraduatedColour());
139  0 assertFalse(fc1.isColourByAttribute());
140  0 assertNull(fc1.getAttributeName());
141   
142    /*
143    * colour by attribute (label)
144    */
145  0 fc = new FeatureColour();
146  0 fc.setColourByLabel(true);
147  0 fc.setAttributeName("AF");
148  0 fc1 = new FeatureColour(fc);
149  0 assertTrue(fc1.isColourByLabel());
150  0 assertFalse(fc1.isGraduatedColour());
151  0 assertTrue(fc1.isColourByAttribute());
152  0 assertArrayEquals(new String[] { "AF" }, fc1.getAttributeName());
153   
154    /*
155    * colour by attribute (value)
156    */
157  0 fc = new FeatureColour(Color.yellow, Color.gray, Color.black,
158    Color.green, 10f, 20f);
159  0 fc.setAboveThreshold(true);
160  0 fc.setThreshold(12f);
161  0 fc.setAttributeName("AF");
162  0 fc1 = new FeatureColour(fc);
163  0 assertTrue(fc1.isGraduatedColour());
164  0 assertFalse(fc1.isColourByLabel());
165  0 assertTrue(fc1.isColourByAttribute());
166  0 assertFalse(fc1.isSimpleColour());
167  0 assertArrayEquals(new String[] { "AF" }, fc1.getAttributeName());
168  0 assertTrue(fc1.isAboveThreshold());
169  0 assertEquals(12f, fc1.getThreshold());
170  0 assertEquals(Color.gray, fc1.getMinColour());
171  0 assertEquals(Color.black, fc1.getMaxColour());
172  0 assertEquals(Color.green, fc1.getNoColour());
173  0 assertEquals(Color.yellow, fc1.getColour());
174  0 assertEquals(10f, fc1.getMin());
175  0 assertEquals(20f, fc1.getMax());
176   
177    /*
178    * modify original attribute label and check that copy doesn't change
179    */
180  0 fc.setAttributeName("MAF", "AF");
181  0 assertArrayEquals(new String[] { "AF" }, fc1.getAttributeName());
182   
183    }
184   
 
185  0 toggle @Test(groups = { "Functional" })
186    public void testGetColor_simpleColour()
187    {
188  0 FeatureColour fc = new FeatureColour(Color.RED);
189  0 assertEquals(Color.RED,
190    fc.getColor(new SequenceFeature("Cath", "", 1, 2, 0f, null)));
191    }
192   
 
193  0 toggle @Test(groups = { "Functional" })
194    public void testGetColor_colourByLabel()
195    {
196  0 FeatureColour fc = new FeatureColour();
197  0 fc.setColourByLabel(true);
198  0 SequenceFeature sf = new SequenceFeature("type", "desc", 0, 20, 1f,
199    null);
200  0 Color expected = ColorUtils.createColourFromName("desc");
201  0 assertEquals(expected, fc.getColor(sf));
202    }
203   
 
204  0 toggle @Test(groups = { "Functional" })
205    public void testGetColor_Graduated()
206    {
207    /*
208    * graduated colour from
209    * score 0 to 100
210    * gray(128, 128, 128) to red(255, 0, 0)
211    */
212  0 FeatureColour fc = new FeatureColour(null, Color.GRAY, Color.RED, null,
213    0f, 100f);
214    // feature score is 75 which is 3/4 of the way from GRAY to RED
215  0 SequenceFeature sf = new SequenceFeature("type", "desc", 0, 20, 75f,
216    null);
217    // the colour gradient is computed in float values from 0-1 (where 1 == 255)
218  0 float red = 128 / 255f + 3 / 4f * (255 - 128) / 255f;
219  0 float green = 128 / 255f + 3 / 4f * (0 - 128) / 255f;
220  0 float blue = 128 / 255f + 3 / 4f * (0 - 128) / 255f;
221  0 Color expected = new Color(red, green, blue);
222  0 assertEquals(expected, fc.getColor(sf));
223    }
224   
 
225  0 toggle @Test(groups = { "Functional" })
226    public void testGetColor_aboveBelowThreshold()
227    {
228    // gradient from [50, 150] from WHITE(255, 255, 255) to BLACK(0, 0, 0)
229  0 FeatureColour fc = new FeatureColour(null, Color.WHITE, Color.BLACK,
230    Color.white, 50f, 150f);
231  0 SequenceFeature sf = new SequenceFeature("type", "desc", 0, 20, 70f,
232    null);
233   
234    /*
235    * feature with score of Float.NaN is always assigned minimum colour
236    */
237  0 SequenceFeature sf2 = new SequenceFeature("type", "desc", 0, 20,
238    Float.NaN, null);
239   
240  0 fc.setThreshold(100f); // ignore for now
241  0 assertEquals(new Color(204, 204, 204), fc.getColor(sf));
242  0 assertEquals(Color.white, fc.getColor(sf2));
243   
244  0 fc.setAboveThreshold(true); // feature lies below threshold
245  0 assertNull(fc.getColor(sf));
246  0 assertEquals(Color.white, fc.getColor(sf2));
247   
248  0 fc.setBelowThreshold(true);
249  0 fc.setThreshold(70f);
250  0 assertNull(fc.getColor(sf)); // feature score == threshold - hidden
251  0 assertEquals(Color.white, fc.getColor(sf2));
252  0 fc.setThreshold(69f);
253  0 assertNull(fc.getColor(sf)); // feature score > threshold - hidden
254  0 assertEquals(Color.white, fc.getColor(sf2));
255    }
256   
257    /**
258    * Test output of feature colours to Jalview features file format
259    */
 
260  0 toggle @Test(groups = { "Functional" })
261    public void testToJalviewFormat()
262    {
263    /*
264    * plain colour - to RGB hex code
265    */
266  0 FeatureColour fc = new FeatureColour(Color.RED);
267  0 String redHex = Format.getHexString(Color.RED);
268  0 String hexColour = redHex;
269  0 assertEquals("domain\t" + hexColour, fc.toJalviewFormat("domain"));
270   
271    /*
272    * colour by label (no threshold)
273    */
274  0 fc = new FeatureColour();
275  0 fc.setColourByLabel(true);
276  0 assertEquals("domain\tlabel", fc.toJalviewFormat("domain"));
277   
278    /*
279    * colour by attribute text (no threshold)
280    */
281  0 fc = new FeatureColour();
282  0 fc.setColourByLabel(true);
283  0 fc.setAttributeName("CLIN_SIG");
284  0 assertEquals("domain\tattribute|CLIN_SIG",
285    fc.toJalviewFormat("domain"));
286   
287    /*
288    * colour by label (autoscaled) (an odd state you can reach by selecting
289    * 'above threshold', then deselecting 'threshold is min/max' then 'colour
290    * by label')
291    */
292  0 fc.setAttributeName((String[]) null);
293  0 fc.setAutoScaled(true);
294  0 assertEquals("domain\tlabel", fc.toJalviewFormat("domain"));
295   
296    /*
297    * colour by label (above threshold)
298    */
299  0 fc.setAutoScaled(false);
300  0 fc.setThreshold(12.5f);
301  0 fc.setAboveThreshold(true);
302    // min/max values are output though not used by this scheme
303  0 assertEquals("domain\tlabel|||0.0|0.0|above|12.5",
304    fc.toJalviewFormat("domain"));
305   
306    /*
307    * colour by label (below threshold)
308    */
309  0 fc.setBelowThreshold(true);
310  0 assertEquals("domain\tlabel|||0.0|0.0|below|12.5",
311    fc.toJalviewFormat("domain"));
312   
313    /*
314    * colour by attributes text (below threshold)
315    */
316  0 fc.setBelowThreshold(true);
317  0 fc.setAttributeName("CSQ", "Consequence");
318  0 assertEquals("domain\tattribute|CSQ:Consequence|||0.0|0.0|below|12.5",
319    fc.toJalviewFormat("domain"));
320   
321    /*
322    * graduated colour by score, no threshold
323    * - default constructor sets noValueColor = minColor
324    */
325  0 fc = new FeatureColour(null, Color.GREEN, Color.RED, Color.GREEN, 12f,
326    25f);
327  0 String greenHex = Format.getHexString(Color.GREEN);
328  0 String expected = String.format(
329    "domain\tscore|%s|%s|noValueMin|abso|12.0|25.0|none", greenHex,
330    redHex);
331  0 assertEquals(expected, fc.toJalviewFormat("domain"));
332   
333    /*
334    * graduated colour by score, no threshold, no value gets min colour
335    */
336  0 fc = new FeatureColour(Color.RED, Color.GREEN, Color.RED, Color.GREEN,
337    12f, 25f);
338  0 expected = String.format(
339    "domain\tscore|%s|%s|noValueMin|abso|12.0|25.0|none", greenHex,
340    redHex);
341  0 assertEquals(expected, fc.toJalviewFormat("domain"));
342   
343    /*
344    * graduated colour by score, no threshold, no value gets max colour
345    */
346  0 fc = new FeatureColour(Color.RED, Color.GREEN, Color.RED, Color.RED,
347    12f, 25f);
348  0 expected = String.format(
349    "domain\tscore|%s|%s|noValueMax|abso|12.0|25.0|none", greenHex,
350    redHex);
351  0 assertEquals(expected, fc.toJalviewFormat("domain"));
352   
353    /*
354    * colour ranges over the actual score ranges (not min/max)
355    */
356  0 fc.setAutoScaled(true);
357  0 expected = String.format(
358    "domain\tscore|%s|%s|noValueMax|12.0|25.0|none", greenHex,
359    redHex);
360  0 assertEquals(expected, fc.toJalviewFormat("domain"));
361   
362    /*
363    * graduated colour by score, below threshold
364    */
365  0 fc.setThreshold(12.5f);
366  0 fc.setBelowThreshold(true);
367  0 expected = String.format(
368    "domain\tscore|%s|%s|noValueMax|12.0|25.0|below|12.5", greenHex,
369    redHex);
370  0 assertEquals(expected, fc.toJalviewFormat("domain"));
371   
372    /*
373    * graduated colour by score, above threshold
374    */
375  0 fc.setThreshold(12.5f);
376  0 fc.setAboveThreshold(true);
377  0 fc.setAutoScaled(false);
378  0 expected = String.format(
379    "domain\tscore|%s|%s|noValueMax|abso|12.0|25.0|above|12.5",
380    greenHex, redHex);
381  0 assertEquals(expected, fc.toJalviewFormat("domain"));
382   
383    /*
384    * graduated colour by attribute, above threshold
385    */
386  0 fc.setAttributeName("CSQ", "AF");
387  0 fc.setAboveThreshold(true);
388  0 fc.setAutoScaled(false);
389  0 expected = String.format(
390    "domain\tattribute|CSQ:AF|%s|%s|noValueMax|abso|12.0|25.0|above|12.5",
391    greenHex, redHex);
392  0 assertEquals(expected, fc.toJalviewFormat("domain"));
393    }
394   
395    /**
396    * Test parsing of feature colours from Jalview features file format
397    */
 
398  0 toggle @Test(groups = { "Functional" })
399    public void testParseJalviewFeatureColour()
400    {
401    /*
402    * simple colour by name
403    */
404  0 FeatureColourI fc = FeatureColour.parseJalviewFeatureColour("red");
405  0 assertTrue(fc.isSimpleColour());
406  0 assertEquals(Color.RED, fc.getColour());
407   
408    /*
409    * simple colour by hex code
410    */
411  0 fc = FeatureColour
412    .parseJalviewFeatureColour(Format.getHexString(Color.RED));
413  0 assertTrue(fc.isSimpleColour());
414  0 assertEquals(Color.RED, fc.getColour());
415   
416    /*
417    * simple colour by rgb triplet
418    */
419  0 fc = FeatureColour.parseJalviewFeatureColour("255,0,0");
420  0 assertTrue(fc.isSimpleColour());
421  0 assertEquals(Color.RED, fc.getColour());
422   
423    /*
424    * malformed colour
425    */
426  0 try
427    {
428  0 fc = FeatureColour.parseJalviewFeatureColour("oops");
429  0 fail("expected exception");
430    } catch (IllegalArgumentException e)
431    {
432  0 assertEquals("Invalid colour descriptor: oops", e.getMessage());
433    }
434   
435    /*
436    * colour by label (no threshold)
437    */
438  0 fc = FeatureColour.parseJalviewFeatureColour("label");
439  0 assertTrue(fc.isColourByLabel());
440  0 assertFalse(fc.hasThreshold());
441   
442    /*
443    * colour by label (with threshold)
444    */
445  0 fc = FeatureColour
446    .parseJalviewFeatureColour("label|||0.0|0.0|above|12.0");
447  0 assertTrue(fc.isColourByLabel());
448  0 assertTrue(fc.isAboveThreshold());
449  0 assertEquals(12.0f, fc.getThreshold());
450   
451    /*
452    * colour by attribute text (no threshold)
453    */
454  0 fc = FeatureColour.parseJalviewFeatureColour("attribute|CLIN_SIG");
455  0 assertTrue(fc.isColourByAttribute());
456  0 assertTrue(fc.isColourByLabel());
457  0 assertFalse(fc.hasThreshold());
458  0 assertArrayEquals(new String[] { "CLIN_SIG" }, fc.getAttributeName());
459   
460    /*
461    * colour by attributes text (with score threshold)
462    */
463  0 fc = FeatureColour.parseJalviewFeatureColour(
464    "attribute|CSQ:Consequence|||0.0|0.0|above|12.0");
465  0 assertTrue(fc.isColourByLabel());
466  0 assertTrue(fc.isColourByAttribute());
467  0 assertArrayEquals(new String[] { "CSQ", "Consequence" },
468    fc.getAttributeName());
469  0 assertTrue(fc.isAboveThreshold());
470  0 assertEquals(12.0f, fc.getThreshold());
471   
472    /*
473    * graduated colour by score (with colour names) (no threshold)
474    */
475  0 fc = FeatureColour.parseJalviewFeatureColour("red|green|10.0|20.0");
476  0 assertTrue(fc.isGraduatedColour());
477  0 assertFalse(fc.hasThreshold());
478  0 assertEquals(Color.RED, fc.getMinColour());
479  0 assertEquals(Color.GREEN, fc.getMaxColour());
480  0 assertEquals(Color.RED, fc.getNoColour());
481  0 assertEquals(10f, fc.getMin());
482  0 assertEquals(20f, fc.getMax());
483  0 assertTrue(fc.isAutoScaled());
484   
485    /*
486    * the same, with 'no value colour' specified as max
487    */
488  0 fc = FeatureColour
489    .parseJalviewFeatureColour("red|green|novaluemax|10.0|20.0");
490  0 assertEquals(Color.RED, fc.getMinColour());
491  0 assertEquals(Color.GREEN, fc.getMaxColour());
492  0 assertEquals(Color.GREEN, fc.getNoColour());
493  0 assertEquals(10f, fc.getMin());
494  0 assertEquals(20f, fc.getMax());
495   
496    /*
497    * the same, with 'no value colour' specified as min
498    */
499  0 fc = FeatureColour
500    .parseJalviewFeatureColour("red|green|novalueMin|10.0|20.0");
501  0 assertEquals(Color.RED, fc.getMinColour());
502  0 assertEquals(Color.GREEN, fc.getMaxColour());
503  0 assertEquals(Color.RED, fc.getNoColour());
504  0 assertEquals(10f, fc.getMin());
505  0 assertEquals(20f, fc.getMax());
506   
507    /*
508    * the same, with 'no value colour' specified as none
509    */
510  0 fc = FeatureColour
511    .parseJalviewFeatureColour("red|green|novaluenone|10.0|20.0");
512  0 assertEquals(Color.RED, fc.getMinColour());
513  0 assertEquals(Color.GREEN, fc.getMaxColour());
514  0 assertNull(fc.getNoColour());
515  0 assertEquals(10f, fc.getMin());
516  0 assertEquals(20f, fc.getMax());
517   
518    /*
519    * the same, with invalid 'no value colour'
520    */
521  0 try
522    {
523  0 fc = FeatureColour
524    .parseJalviewFeatureColour("red|green|blue|10.0|20.0");
525  0 fail("expected exception");
526    } catch (IllegalArgumentException e)
527    {
528  0 assertEquals(
529    "Couldn't parse the minimum value for graduated colour ('blue')",
530    e.getMessage());
531    }
532   
533    /*
534    * graduated colour (explicitly by 'score') (no threshold)
535    */
536  0 fc = FeatureColour
537    .parseJalviewFeatureColour("Score|red|green|10.0|20.0");
538  0 assertTrue(fc.isGraduatedColour());
539  0 assertFalse(fc.hasThreshold());
540  0 assertEquals(Color.RED, fc.getMinColour());
541  0 assertEquals(Color.GREEN, fc.getMaxColour());
542  0 assertEquals(10f, fc.getMin());
543  0 assertEquals(20f, fc.getMax());
544  0 assertTrue(fc.isAutoScaled());
545   
546    /*
547    * graduated colour by attribute (no threshold)
548    */
549  0 fc = FeatureColour
550    .parseJalviewFeatureColour("attribute|AF|red|green|10.0|20.0");
551  0 assertTrue(fc.isGraduatedColour());
552  0 assertTrue(fc.isColourByAttribute());
553  0 assertArrayEquals(new String[] { "AF" }, fc.getAttributeName());
554  0 assertFalse(fc.hasThreshold());
555  0 assertEquals(Color.RED, fc.getMinColour());
556  0 assertEquals(Color.GREEN, fc.getMaxColour());
557  0 assertEquals(10f, fc.getMin());
558  0 assertEquals(20f, fc.getMax());
559  0 assertTrue(fc.isAutoScaled());
560   
561    /*
562    * graduated colour by score (colours by hex code) (above threshold)
563    */
564  0 String descriptor = String.format("%s|%s|10.0|20.0|above|15",
565    Format.getHexString(Color.RED),
566    Format.getHexString(Color.GREEN));
567  0 fc = FeatureColour.parseJalviewFeatureColour(descriptor);
568  0 assertTrue(fc.isGraduatedColour());
569  0 assertTrue(fc.hasThreshold());
570  0 assertTrue(fc.isAboveThreshold());
571  0 assertEquals(15f, fc.getThreshold());
572  0 assertEquals(Color.RED, fc.getMinColour());
573  0 assertEquals(Color.GREEN, fc.getMaxColour());
574  0 assertEquals(10f, fc.getMin());
575  0 assertEquals(20f, fc.getMax());
576  0 assertTrue(fc.isAutoScaled());
577   
578    /*
579    * graduated colour by attributes (below threshold)
580    */
581  0 fc = FeatureColour.parseJalviewFeatureColour(
582    "attribute|CSQ:AF|red|green|10.0|20.0|below|13");
583  0 assertTrue(fc.isGraduatedColour());
584  0 assertTrue(fc.isColourByAttribute());
585  0 assertArrayEquals(new String[] { "CSQ", "AF" }, fc.getAttributeName());
586  0 assertTrue(fc.hasThreshold());
587  0 assertTrue(fc.isBelowThreshold());
588  0 assertEquals(13f, fc.getThreshold());
589  0 assertEquals(Color.RED, fc.getMinColour());
590  0 assertEquals(Color.GREEN, fc.getMaxColour());
591  0 assertEquals(10f, fc.getMin());
592  0 assertEquals(20f, fc.getMax());
593  0 assertTrue(fc.isAutoScaled());
594   
595    /*
596    * graduated colour (by RGB triplet) (below threshold), absolute scale
597    */
598  0 descriptor = "255,0,0|0,255,0|abso|10.0|20.0|below|15";
599  0 fc = FeatureColour.parseJalviewFeatureColour(descriptor);
600  0 assertTrue(fc.isGraduatedColour());
601  0 assertFalse(fc.isAutoScaled());
602  0 assertTrue(fc.hasThreshold());
603  0 assertTrue(fc.isBelowThreshold());
604  0 assertEquals(15f, fc.getThreshold());
605  0 assertEquals(Color.RED, fc.getMinColour());
606  0 assertEquals(Color.GREEN, fc.getMaxColour());
607  0 assertEquals(10f, fc.getMin());
608  0 assertEquals(20f, fc.getMax());
609   
610  0 descriptor = "blue|255,0,255|absolute|20.0|95.0|below|66.0";
611  0 fc = FeatureColour.parseJalviewFeatureColour(descriptor);
612  0 assertTrue(fc.isGraduatedColour());
613    }
614   
 
615  0 toggle @Test(groups = { "Functional" })
616    public void testGetColor_colourByAttributeText()
617    {
618  0 FeatureColour fc = new FeatureColour();
619  0 fc.setColourByLabel(true);
620  0 fc.setAttributeName("consequence");
621  0 SequenceFeature sf = new SequenceFeature("type", "desc", 0, 20, 1f,
622    null);
623   
624    /*
625    * if feature has no such attribute, use 'no value' colour
626    */
627  0 assertEquals(FeatureColour.DEFAULT_NO_COLOUR, fc.getColor(sf));
628   
629    /*
630    * if feature has attribute, generate colour from value
631    */
632  0 sf.setValue("consequence", "benign");
633  0 Color expected = ColorUtils.createColourFromName("benign");
634  0 assertEquals(expected, fc.getColor(sf));
635    }
636   
 
637  0 toggle @Test(groups = { "Functional" })
638    public void testGetColor_GraduatedByAttributeValue()
639    {
640    /*
641    * graduated colour based on attribute value for AF
642    * given a min-max range of 0-100
643    */
644  0 FeatureColour fc = new FeatureColour(Color.white,
645    new Color(50, 100, 150), new Color(150, 200, 250), Color.yellow,
646    0f, 100f);
647  0 String attName = "AF";
648  0 fc.setAttributeName(attName);
649   
650    /*
651    * first case: feature lacks the attribute - use 'no value' colour
652    */
653  0 SequenceFeature sf = new SequenceFeature("type", "desc", 0, 20, 75f,
654    null);
655  0 assertEquals(Color.yellow, fc.getColor(sf));
656   
657    /*
658    * second case: attribute present but not numeric - treat as if absent
659    */
660  0 sf.setValue(attName, "twelve");
661  0 assertEquals(Color.yellow, fc.getColor(sf));
662   
663    /*
664    * third case: valid attribute value
665    */
666  0 sf.setValue(attName, "20.0");
667  0 Color expected = new Color(70, 120, 170);
668  0 assertEquals(expected, fc.getColor(sf));
669    }
670   
 
671  0 toggle @Test(groups = { "Functional" })
672    public void testIsOutwithThreshold()
673    {
674  0 FeatureColourI fc = new FeatureColour(Color.red);
675  0 SequenceFeature sf = new SequenceFeature("METAL", "desc", 10, 12, 1.2f,
676    "grp");
677  0 assertFalse(fc.isOutwithThreshold(null));
678  0 assertFalse(fc.isOutwithThreshold(sf));
679   
680  0 fc = new FeatureColour(null, Color.white, Color.black, Color.green, 0f,
681    10f);
682  0 assertFalse(fc.isOutwithThreshold(sf)); // no threshold
683   
684  0 fc.setAboveThreshold(true);
685  0 fc.setThreshold(1f);
686  0 assertFalse(fc.isOutwithThreshold(sf)); // feature score 1.2 is above 1
687   
688  0 fc.setThreshold(2f);
689  0 assertTrue(fc.isOutwithThreshold(sf)); // feature score 1.2 is not above 2
690   
691  0 fc.setBelowThreshold(true);
692  0 assertFalse(fc.isOutwithThreshold(sf)); // feature score 1.2 is below 2
693   
694  0 fc.setThreshold(1f);
695  0 assertTrue(fc.isOutwithThreshold(sf)); // feature score 1.2 is not below 1
696   
697    /*
698    * with attribute value threshold
699    */
700  0 fc.setAttributeName("AC");
701  0 assertFalse(fc.isOutwithThreshold(sf)); // missing attribute AC is ignored
702   
703  0 sf.setValue("AC", "-1");
704  0 assertFalse(fc.isOutwithThreshold(sf)); // value -1 is below 1
705   
706  0 sf.setValue("AC", "1");
707  0 assertTrue(fc.isOutwithThreshold(sf)); // value 1 is not below 1
708   
709  0 sf.setValue("AC", "junk");
710  0 assertFalse(fc.isOutwithThreshold(sf)); // bad value is ignored
711    }
712   
713    /**
714    * Test description of feature colour suitable for a tooltip
715    */
 
716  0 toggle @Test(groups = { "Functional" })
717    public void testGetDescription()
718    {
719    /*
720    * plain colour
721    */
722  0 FeatureColour fc = new FeatureColour(Color.RED);
723  0 assertEquals(
724    String.format("r=%d,g=%d,b=%d", Color.RED.getRed(),
725    Color.red.getGreen(), Color.red.getBlue()),
726    fc.getDescription());
727   
728    /*
729    * colour by label (no threshold)
730    */
731  0 fc = new FeatureColour();
732  0 fc.setColourByLabel(true);
733  0 assertEquals("By Label", fc.getDescription());
734   
735    /*
736    * colour by attribute text (no threshold)
737    */
738  0 fc = new FeatureColour();
739  0 fc.setColourByLabel(true);
740  0 fc.setAttributeName("CLIN_SIG");
741  0 assertEquals("By CLIN_SIG", fc.getDescription());
742   
743    /*
744    * colour by label (above score threshold)
745    */
746  0 fc = new FeatureColour();
747  0 fc.setColourByLabel(true);
748  0 fc.setAutoScaled(false);
749  0 fc.setThreshold(12.5f);
750  0 fc.setAboveThreshold(true);
751  0 assertEquals("By Label (Score > 12.5)", fc.getDescription());
752   
753    /*
754    * colour by label (below score threshold)
755    */
756  0 fc.setBelowThreshold(true);
757  0 assertEquals("By Label (Score < 12.5)", fc.getDescription());
758   
759    /*
760    * colour by attributes text (below score threshold)
761    */
762  0 fc.setBelowThreshold(true);
763  0 fc.setAttributeName("CSQ", "Consequence");
764  0 assertEquals("By CSQ:Consequence (Score < 12.5)", fc.getDescription());
765   
766    /*
767    * graduated colour by score, no threshold
768    */
769  0 fc = new FeatureColour(null, Color.GREEN, Color.RED, null, 12f, 25f);
770  0 assertEquals("By Score", fc.getDescription());
771   
772    /*
773    * graduated colour by score, below threshold
774    */
775  0 fc.setThreshold(12.5f);
776  0 fc.setBelowThreshold(true);
777  0 assertEquals("By Score (< 12.5)", fc.getDescription());
778   
779    /*
780    * graduated colour by score, above threshold
781    */
782  0 fc.setThreshold(12.5f);
783  0 fc.setAboveThreshold(true);
784  0 fc.setAutoScaled(false);
785  0 assertEquals("By Score (> 12.5)", fc.getDescription());
786   
787    /*
788    * graduated colour by attribute, no threshold
789    */
790  0 fc.setAttributeName("CSQ", "AF");
791  0 fc.setAboveThreshold(false);
792  0 fc.setAutoScaled(false);
793  0 assertEquals("By CSQ:AF", fc.getDescription());
794   
795    /*
796    * graduated colour by attribute, above threshold
797    */
798  0 fc.setAboveThreshold(true);
799  0 fc.setAutoScaled(false);
800  0 assertEquals("By CSQ:AF (> 12.5)", fc.getDescription());
801    }
802    }