Clover icon

jalviewX

  1. Project Clover database Wed Oct 31 2018 15:13:58 GMT
  2. Package jalview.renderer.seqfeatures

File FeatureColourFinderTest.java

 

Code metrics

0
210
17
1
557
334
17
0.08
12.35
17
1

Classes

Class Line # Actions
FeatureColourFinderTest 44 210 17 1
0.9955947499.6%
 

Contributing tests

This file is covered by 15 tests. .

Source view

1    package jalview.renderer.seqfeatures;
2   
3    import static org.testng.Assert.assertEquals;
4    import static org.testng.Assert.assertFalse;
5    import static org.testng.Assert.assertNotEquals;
6    import static org.testng.Assert.assertNull;
7    import static org.testng.Assert.assertTrue;
8   
9    import jalview.api.FeatureColourI;
10    import jalview.datamodel.SequenceFeature;
11    import jalview.datamodel.SequenceI;
12    import jalview.gui.AlignFrame;
13    import jalview.gui.AlignViewport;
14    import jalview.gui.FeatureRenderer;
15    import jalview.io.DataSourceType;
16    import jalview.io.FileLoader;
17    import jalview.schemes.FeatureColour;
18    import jalview.viewmodel.seqfeatures.FeatureRendererModel.FeatureSettingsBean;
19   
20    import java.awt.Color;
21    import java.util.List;
22   
23    import org.testng.annotations.BeforeMethod;
24    import org.testng.annotations.BeforeTest;
25    import org.testng.annotations.Test;
26   
27    /**
28    * Unit tests for feature colour determination, including but not limited to
29    * <ul>
30    * <li>gap position</li>
31    * <li>no features present</li>
32    * <li>features present but show features turned off</li>
33    * <li>features displayed but selected feature turned off</li>
34    * <li>features displayed but feature group turned off</li>
35    * <li>feature displayed but none at the specified position</li>
36    * <li>multiple features at position, with no transparency</li>
37    * <li>multiple features at position, with transparency</li>
38    * <li>score graduated feature colour</li>
39    * <li>contact feature start at the selected position</li>
40    * <li>contact feature end at the selected position</li>
41    * <li>contact feature straddling the selected position (not shown)</li>
42    * </ul>
43    */
 
44    public class FeatureColourFinderTest
45    {
46    private AlignViewport av;
47   
48    private SequenceI seq;
49   
50    private FeatureColourFinder finder;
51   
52    private AlignFrame af;
53   
54    private FeatureRenderer fr;
55   
 
56  1 toggle @BeforeTest(alwaysRun = true)
57    public void setUp()
58    {
59    // aligned column 8 is sequence position 6
60  1 String s = ">s1\nABCDE---FGHIJKLMNOPQRSTUVWXYZ\n";
61  1 af = new FileLoader().LoadFileWaitTillLoaded(s,
62    DataSourceType.PASTE);
63  1 av = af.getViewport();
64  1 seq = av.getAlignment().getSequenceAt(0);
65  1 fr = af.getFeatureRenderer();
66  1 finder = new FeatureColourFinder(fr);
67    }
68   
69    /**
70    * Clear down any sequence features before each test (not as easy as it
71    * sounds...)
72    */
 
73  15 toggle @BeforeMethod(alwaysRun = true)
74    public void setUpBeforeTest()
75    {
76  15 List<SequenceFeature> sfs = seq.getSequenceFeatures();
77  15 for (SequenceFeature sf : sfs)
78    {
79  20 seq.deleteFeature(sf);
80    }
81  15 fr.findAllFeatures(true);
82   
83    /*
84    * reset all feature groups to visible
85    */
86  15 for (String group : fr.getGroups(false))
87    {
88  0 fr.setGroupVisibility(group, true);
89    }
90   
91  15 fr.clearRenderOrder();
92  15 av.setShowSequenceFeatures(true);
93    }
94   
 
95  1 toggle @Test(groups = "Functional")
96    public void testFindFeatureColour_noFeatures()
97    {
98  1 av.setShowSequenceFeatures(false);
99  1 Color c = finder.findFeatureColour(Color.blue, seq, 10);
100  1 assertEquals(c, Color.blue);
101   
102  1 av.setShowSequenceFeatures(true);
103  1 c = finder.findFeatureColour(Color.blue, seq, 10);
104  1 assertEquals(c, Color.blue);
105    }
106   
 
107  1 toggle @Test(groups = "Functional")
108    public void testFindFeatureColour_noFeaturesShown()
109    {
110  1 seq.addSequenceFeature(new SequenceFeature("Metal", "Metal", 2, 12,
111    Float.NaN, "MetalGroup"));
112  1 fr.featuresAdded();
113  1 av.setShowSequenceFeatures(false);
114  1 Color c = finder.findFeatureColour(Color.blue, seq, 10);
115  1 assertEquals(c, Color.blue);
116    }
117   
 
118  1 toggle @Test(groups = "Functional")
119    public void testFindFeatureColour_singleFeatureAtPosition()
120    {
121  1 seq.addSequenceFeature(new SequenceFeature("Metal", "Metal", 2, 12,
122    Float.NaN, "MetalGroup"));
123  1 fr.setColour("Metal", new FeatureColour(Color.red));
124  1 fr.featuresAdded();
125  1 av.setShowSequenceFeatures(true);
126  1 Color c = finder.findFeatureColour(Color.blue, seq, 10);
127  1 assertEquals(c, Color.red);
128    }
129   
130    /**
131    * feature colour at a gap is null (not white) - a user defined colour scheme
132    * can then provide a bespoke gap colour if configured to do so
133    */
 
134  1 toggle @Test(groups = "Functional")
135    public void testFindFeatureColour_gapPosition()
136    {
137  1 seq.addSequenceFeature(new SequenceFeature("Metal", "Metal", 2, 12, 0f,
138    null));
139  1 fr.setColour("Metal", new FeatureColour(Color.red));
140  1 fr.featuresAdded();
141  1 av.setShowSequenceFeatures(true);
142  1 Color c = finder.findFeatureColour(null, seq, 6);
143  1 assertNull(c);
144    }
145   
 
146  1 toggle @Test(groups = "Functional")
147    public void testFindFeatureColour_multipleFeaturesAtPositionNoTransparency()
148    {
149    /*
150    * featuresAdded -> FeatureRendererModel.updateRenderOrder which adds any
151    * new features 'on top' (but reverses the order of any added features)
152    */
153  1 seq.addSequenceFeature(new SequenceFeature("Metal", "Metal", 2, 12,
154    Float.NaN, "MetalGroup"));
155  1 FeatureColour red = new FeatureColour(Color.red);
156  1 fr.setColour("Metal", red);
157  1 fr.featuresAdded();
158  1 seq.addSequenceFeature(new SequenceFeature("Domain", "Domain", 4, 15,
159    Float.NaN, "DomainGroup"));
160  1 FeatureColour green = new FeatureColour(Color.green);
161  1 fr.setColour("Domain", green);
162  1 fr.featuresAdded();
163  1 av.setShowSequenceFeatures(true);
164   
165    /*
166    * expect Domain (green) to be rendered above Metal (red)
167    */
168  1 Color c = finder.findFeatureColour(Color.blue, seq, 10);
169  1 assertEquals(c, Color.green);
170   
171    /*
172    * now promote Metal above Domain
173    * - currently no way other than mimicking reordering of
174    * table in Feature Settings
175    */
176  1 FeatureSettingsBean[] data = new FeatureSettingsBean[2];
177  1 data[0] = new FeatureSettingsBean("Metal", red, null, true);
178  1 data[1] = new FeatureSettingsBean("Domain", green, null, true);
179  1 fr.setFeaturePriority(data);
180  1 c = finder.findFeatureColour(Color.blue, seq, 10);
181  1 assertEquals(c, Color.red);
182   
183    /*
184    * ..and turn off display of Metal
185    */
186  1 data[0] = new FeatureSettingsBean("Metal", red, null, false);
187  1 fr.setFeaturePriority(data);
188  1 c = finder.findFeatureColour(Color.blue, seq, 10);
189  1 assertEquals(c, Color.green);
190    }
191   
 
192  1 toggle @Test(groups = "Functional")
193    public void testFindFeatureColour_singleFeatureNotAtPosition()
194    {
195  1 seq.addSequenceFeature(new SequenceFeature("Metal", "Metal", 8, 12,
196    Float.NaN, "MetalGroup"));
197  1 fr.setColour("Metal", new FeatureColour(Color.red));
198  1 fr.featuresAdded();
199  1 av.setShowSequenceFeatures(true);
200    // column 2 = sequence position 3
201  1 Color c = finder.findFeatureColour(Color.blue, seq, 2);
202  1 assertEquals(c, Color.blue);
203    }
204   
 
205  1 toggle @Test(groups = "Functional")
206    public void testFindFeatureColour_featureTypeNotDisplayed()
207    {
208  1 seq.addSequenceFeature(new SequenceFeature("Metal", "Metal", 2, 12,
209    Float.NaN, "MetalGroup"));
210  1 FeatureColour red = new FeatureColour(Color.red);
211  1 fr.setColour("Metal", red);
212  1 fr.featuresAdded();
213  1 av.setShowSequenceFeatures(true);
214  1 Color c = finder.findFeatureColour(Color.blue, seq, 10);
215  1 assertEquals(c, Color.red);
216   
217    /*
218    * turn off display of Metal - is this the easiest way to do it??
219    */
220  1 FeatureSettingsBean[] data = new FeatureSettingsBean[1];
221  1 data[0] = new FeatureSettingsBean("Metal", red, null, false);
222  1 fr.setFeaturePriority(data);
223  1 c = finder.findFeatureColour(Color.blue, seq, 10);
224  1 assertEquals(c, Color.blue);
225   
226    /*
227    * turn display of Metal back on
228    */
229  1 data[0] = new FeatureSettingsBean("Metal", red, null, true);
230  1 fr.setFeaturePriority(data);
231  1 c = finder.findFeatureColour(Color.blue, seq, 10);
232  1 assertEquals(c, Color.red);
233    }
234   
 
235  1 toggle @Test(groups = "Functional")
236    public void testFindFeatureColour_featureGroupNotDisplayed()
237    {
238  1 seq.addSequenceFeature(new SequenceFeature("Metal", "Metal", 2, 12,
239    Float.NaN, "MetalGroup"));
240  1 FeatureColour red = new FeatureColour(Color.red);
241  1 fr.setColour("Metal", red);
242  1 fr.featuresAdded();
243  1 av.setShowSequenceFeatures(true);
244  1 Color c = finder.findFeatureColour(Color.blue, seq, 10);
245  1 assertEquals(c, Color.red);
246   
247    /*
248    * turn off display of MetalGroup
249    */
250  1 fr.setGroupVisibility("MetalGroup", false);
251  1 c = finder.findFeatureColour(Color.blue, seq, 10);
252  1 assertEquals(c, Color.blue);
253   
254    /*
255    * turn display of MetalGroup back on
256    */
257  1 fr.setGroupVisibility("MetalGroup", true);
258  1 c = finder.findFeatureColour(Color.blue, seq, 10);
259  1 assertEquals(c, Color.red);
260    }
261   
 
262  1 toggle @Test(groups = "Functional")
263    public void testFindFeatureColour_contactFeature()
264    {
265    /*
266    * currently contact feature == type "Disulphide Bond" or "Disulfide Bond" !!
267    */
268  1 seq.addSequenceFeature(new SequenceFeature("Disulphide Bond",
269    "Contact", 2, 12, Float.NaN, "Disulphide"));
270  1 fr.setColour("Disulphide Bond", new FeatureColour(Color.red));
271  1 fr.featuresAdded();
272  1 av.setShowSequenceFeatures(true);
273   
274    /*
275    * Contact positions are residues 2 and 12
276    * which are columns 1 and 14
277    * positions in between don't count for a contact feature!
278    */
279  1 Color c = finder.findFeatureColour(Color.blue, seq, 10);
280  1 assertEquals(c, Color.blue);
281  1 c = finder.findFeatureColour(Color.blue, seq, 8);
282  1 assertEquals(c, Color.blue);
283  1 c = finder.findFeatureColour(Color.blue, seq, 1);
284  1 assertEquals(c, Color.red);
285  1 c = finder.findFeatureColour(Color.blue, seq, 14);
286  1 assertEquals(c, Color.red);
287    }
288   
 
289  1 toggle @Test(groups = "Functional")
290    public void testFindFeatureAtEnd()
291    {
292    /*
293    * terminal residue feature
294    */
295  1 seq.addSequenceFeature(new SequenceFeature("PDBRESNUM", "pdb res 1",
296    seq.getEnd(), seq.getEnd(), Float.NaN, "1seq.pdb"));
297  1 fr.setColour("PDBRESNUM", new FeatureColour(Color.red));
298  1 fr.featuresAdded();
299  1 av.setShowSequenceFeatures(true);
300   
301    /*
302    * final column should have PDBRESNUM feature, the others not
303    */
304  1 Color c = finder.findFeatureColour(Color.blue, seq,
305    seq.getLength() - 2);
306  1 assertNotEquals(c, Color.red);
307  1 c = finder.findFeatureColour(Color.blue, seq, seq.getLength() - 1);
308  1 assertEquals(c, Color.red);
309    }
310   
 
311  1 toggle @Test(groups = "Functional")
312    public void testFindFeatureColour_graduatedFeatureColour()
313    {
314  1 seq.addSequenceFeature(new SequenceFeature("kd", "hydrophobicity", 2,
315    2, 0f, "KdGroup"));
316  1 seq.addSequenceFeature(new SequenceFeature("kd", "hydrophobicity", 4,
317    4, 5f, "KdGroup"));
318  1 seq.addSequenceFeature(new SequenceFeature("kd", "hydrophobicity", 7,
319    7, 10f, "KdGroup"));
320   
321    /*
322    * graduated colour from 0 to 10
323    */
324  1 Color min = new Color(100, 50, 150);
325  1 Color max = new Color(200, 0, 100);
326  1 FeatureColourI fc = new FeatureColour(min, max, 0, 10);
327  1 fr.setColour("kd", fc);
328  1 fr.featuresAdded();
329  1 av.setShowSequenceFeatures(true);
330   
331    /*
332    * position 2, column 1, score 0 - minimum colour in range
333    */
334  1 Color c = finder.findFeatureColour(Color.blue, seq, 1);
335  1 assertEquals(c, min);
336   
337    /*
338    * position 7, column 9, score 10 - maximum colour in range
339    */
340  1 c = finder.findFeatureColour(Color.blue, seq, 9);
341  1 assertEquals(c, max);
342   
343    /*
344    * position 4, column 3, score 5 - half way from min to max
345    */
346  1 c = finder.findFeatureColour(Color.blue, seq, 3);
347  1 assertEquals(c, new Color(150, 25, 125));
348    }
349   
 
350  1 toggle @Test(groups = "Functional")
351    public void testFindFeatureColour_transparencySingleFeature()
352    {
353  1 seq.addSequenceFeature(new SequenceFeature("Metal", "Metal", 2, 12,
354    Float.NaN, "MetalGroup"));
355  1 FeatureColour red = new FeatureColour(Color.red);
356  1 fr.setColour("Metal", red);
357  1 fr.featuresAdded();
358  1 av.setShowSequenceFeatures(true);
359   
360    /*
361    * the FeatureSettings transparency slider has range 0-70 which
362    * corresponds to a transparency value of 1 - 0.3
363    * A value of 0.4 gives a combination of
364    * 0.4 * red(255, 0, 0) + 0.6 * cyan(0, 255, 255) = (102, 153, 153)
365    */
366  1 fr.setTransparency(0.4f);
367  1 Color c = finder.findFeatureColour(Color.cyan, seq, 10);
368  1 assertEquals(c, new Color(102, 153, 153));
369    }
370   
 
371  1 toggle @Test(groups = "Functional")
372    public void testFindFeatureColour_transparencyTwoFeatures()
373    {
374  1 seq.addSequenceFeature(new SequenceFeature("Metal", "Metal", 2, 12,
375    Float.NaN, "MetalGroup"));
376  1 FeatureColour red = new FeatureColour(Color.red);
377  1 fr.setColour("Metal", red);
378  1 fr.featuresAdded();
379  1 seq.addSequenceFeature(new SequenceFeature("Domain", "Domain", 4, 15,
380    Float.NaN, "DomainGroup"));
381  1 FeatureColour green = new FeatureColour(Color.green);
382  1 fr.setColour("Domain", green);
383  1 fr.featuresAdded();
384  1 av.setShowSequenceFeatures(true);
385   
386    /*
387    * Domain (green) rendered above Metal (red) above background (cyan)
388    * 1) 0.6 * red(255, 0, 0) + 0.4 * cyan(0, 255, 255) = (153, 102, 102)
389    * 2) 0.6* green(0, 255, 0) + 0.4 * (153, 102, 102) = (61, 194, 41) rounded
390    */
391  1 fr.setTransparency(0.6f);
392  1 Color c = finder.findFeatureColour(Color.cyan, seq, 10);
393  1 assertEquals(c, new Color(61, 194, 41));
394   
395    /*
396    * now promote Metal above Domain
397    * - currently no way other than mimicking reordering of
398    * table in Feature Settings
399    * Metal (red) rendered above Domain (green) above background (cyan)
400    * 1) 0.6 * green(0, 255, 0) + 0.4 * cyan(0, 255, 255) = (0, 255, 102)
401    * 2) 0.6* red(255, 0, 0) + 0.4 * (0, 255, 102) = (153, 102, 41) rounded
402    */
403  1 FeatureSettingsBean[] data = new FeatureSettingsBean[2];
404  1 data[0] = new FeatureSettingsBean("Metal", red, null, true);
405  1 data[1] = new FeatureSettingsBean("Domain", green, null, true);
406  1 fr.setFeaturePriority(data);
407  1 c = finder.findFeatureColour(Color.cyan, seq, 10);
408  1 assertEquals(c, new Color(153, 102, 41));
409   
410    /*
411    * ..and turn off display of Metal
412    * Domain (green) above background (pink)
413    * 0.6 * green(0, 255, 0) + 0.4 * pink(255, 175, 175) = (102, 223, 70)
414    */
415  1 data[0] = new FeatureSettingsBean("Metal", red, null, false);
416  1 fr.setFeaturePriority(data);
417  1 c = finder.findFeatureColour(Color.pink, seq, 10);
418  1 assertEquals(c, new Color(102, 223, 70));
419    }
420   
 
421  1 toggle @Test(groups = "Functional")
422    public void testNoFeaturesDisplayed()
423    {
424    /*
425    * no features on alignment to render
426    */
427  1 assertTrue(finder.noFeaturesDisplayed());
428   
429    /*
430    * add a feature
431    * it will be automatically set visible but we leave
432    * the viewport configured not to show features
433    */
434  1 av.setShowSequenceFeatures(false);
435  1 seq.addSequenceFeature(new SequenceFeature("Metal", "Metal", 2, 12,
436    Float.NaN, "MetalGroup"));
437  1 FeatureColour red = new FeatureColour(Color.red);
438  1 fr.setColour("Metal", red);
439  1 fr.featuresAdded();
440  1 assertTrue(finder.noFeaturesDisplayed());
441   
442    /*
443    * turn on feature display
444    */
445  1 av.setShowSequenceFeatures(true);
446  1 assertFalse(finder.noFeaturesDisplayed());
447   
448    /*
449    * turn off display of Metal
450    */
451  1 FeatureSettingsBean[] data = new FeatureSettingsBean[1];
452  1 data[0] = new FeatureSettingsBean("Metal", red, null, false);
453  1 fr.setFeaturePriority(data);
454  1 assertTrue(finder.noFeaturesDisplayed());
455   
456    /*
457    * turn display of Metal back on
458    */
459  1 fr.setVisible("Metal");
460  1 assertFalse(finder.noFeaturesDisplayed());
461   
462    /*
463    * turn off MetalGroup - has no effect here since the group of a
464    * sequence feature instance is independent of its type
465    */
466  1 fr.setGroupVisibility("MetalGroup", false);
467  1 assertFalse(finder.noFeaturesDisplayed());
468   
469    /*
470    * a finder with no feature renderer
471    */
472  1 FeatureColourFinder finder2 = new FeatureColourFinder(null);
473  1 assertTrue(finder2.noFeaturesDisplayed());
474    }
475   
 
476  1 toggle @Test(groups = "Functional")
477    public void testFindFeatureColour_graduatedWithThreshold()
478    {
479  1 String kdFeature = "kd";
480  1 String metalFeature = "Metal";
481  1 seq.addSequenceFeature(new SequenceFeature(kdFeature, "hydrophobicity", 2,
482    2, 0f, "KdGroup"));
483  1 seq.addSequenceFeature(new SequenceFeature(kdFeature, "hydrophobicity", 4,
484    4, 5f, "KdGroup"));
485  1 seq.addSequenceFeature(new SequenceFeature(metalFeature, "Fe", 4, 4,
486    5f, "MetalGroup"));
487  1 seq.addSequenceFeature(new SequenceFeature(kdFeature, "hydrophobicity", 7,
488    7, 10f, "KdGroup"));
489   
490    /*
491    * kd feature has graduated colour from 0 to 10
492    * above threshold value of 5
493    */
494  1 Color min = new Color(100, 50, 150);
495  1 Color max = new Color(200, 0, 100);
496  1 FeatureColourI fc = new FeatureColour(min, max, 0, 10);
497  1 fc.setAboveThreshold(true);
498  1 fc.setThreshold(5f);
499  1 fr.setColour(kdFeature, fc);
500  1 FeatureColour green = new FeatureColour(Color.green);
501  1 fr.setColour(metalFeature, green);
502  1 fr.featuresAdded();
503   
504    /*
505    * render order is kd above Metal
506    */
507  1 FeatureSettingsBean[] data = new FeatureSettingsBean[2];
508  1 data[0] = new FeatureSettingsBean(kdFeature, fc, null, true);
509  1 data[1] = new FeatureSettingsBean(metalFeature, green, null, true);
510  1 fr.setFeaturePriority(data);
511   
512  1 av.setShowSequenceFeatures(true);
513   
514    /*
515    * position 2, column 1, score 0 - below threshold - default colour
516    */
517  1 Color c = finder.findFeatureColour(Color.blue, seq, 1);
518  1 assertEquals(c, Color.blue);
519   
520    /*
521    * position 4, column 3, score 5 - at threshold
522    * should return Green (colour of Metal feature)
523    */
524  1 c = finder.findFeatureColour(Color.blue, seq, 3);
525  1 assertEquals(c, Color.green);
526   
527    /*
528    * position 7, column 9, score 10 - maximum colour in range
529    */
530  1 c = finder.findFeatureColour(Color.blue, seq, 9);
531  1 assertEquals(c, max);
532   
533    /*
534    * now colour below threshold of 5
535    */
536  1 fc.setBelowThreshold(true);
537   
538    /*
539    * position 2, column 1, score 0 - min colour
540    */
541  1 c = finder.findFeatureColour(Color.blue, seq, 1);
542  1 assertEquals(c, min);
543   
544    /*
545    * position 4, column 3, score 5 - at threshold
546    * should return Green (colour of Metal feature)
547    */
548  1 c = finder.findFeatureColour(Color.blue, seq, 3);
549  1 assertEquals(c, Color.green);
550   
551    /*
552    * position 7, column 9, score 10 - above threshold - default colour
553    */
554  1 c = finder.findFeatureColour(Color.blue, seq, 9);
555  1 assertEquals(c, Color.blue);
556    }
557    }