1 package jalview.renderer.seqfeatures;
3 import static org.testng.Assert.assertEquals;
4 import static org.testng.Assert.assertFalse;
5 import static org.testng.Assert.assertTrue;
7 import jalview.api.FeatureColourI;
8 import jalview.datamodel.SequenceFeature;
9 import jalview.datamodel.SequenceI;
10 import jalview.gui.AlignFrame;
11 import jalview.gui.AlignViewport;
12 import jalview.gui.FeatureRenderer;
13 import jalview.io.DataSourceType;
14 import jalview.io.FileLoader;
15 import jalview.schemes.FeatureColour;
17 import java.awt.Color;
19 import org.testng.annotations.BeforeClass;
20 import org.testng.annotations.BeforeMethod;
21 import org.testng.annotations.Test;
24 * Unit tests for feature colour determination, including but not limited to
26 * <li>gap position</li>
27 * <li>no features present</li>
28 * <li>features present but show features turned off</li>
29 * <li>features displayed but selected feature turned off</li>
30 * <li>features displayed but feature group turned off</li>
31 * <li>feature displayed but none at the specified position</li>
32 * <li>multiple features at position, with no transparency</li>
33 * <li>multiple features at position, with transparency</li>
34 * <li>score graduated feature colour</li>
35 * <li>contact feature start at the selected position</li>
36 * <li>contact feature end at the selected position</li>
37 * <li>contact feature straddling the selected position (not shown)</li>
40 public class FeatureColourFinderTest
42 private AlignViewport av;
44 private SequenceI seq;
46 private FeatureColourFinder finder;
48 private AlignFrame af;
50 private FeatureRenderer fr;
52 @BeforeClass(alwaysRun = true)
55 // aligned column 8 is sequence position 6
56 String s = ">s1\nABCDE---FGHIJKLMNOPQRSTUVWXYZ\n";
57 af = new FileLoader().LoadFileWaitTillLoaded(s,
58 DataSourceType.PASTE);
59 av = af.getViewport();
60 seq = av.getAlignment().getSequenceAt(0);
61 fr = af.getFeatureRenderer();
62 finder = new FeatureColourFinder(fr);
66 * Clear down any sequence features before each test
68 @BeforeMethod(alwaysRun = true)
69 public void setUpBeforeTest()
71 SequenceFeature[] sfs = seq.getSequenceFeatures();
74 for (SequenceFeature sf : sfs)
76 seq.deleteFeature(sf);
79 fr.findAllFeatures(true);
82 * reset all feature groups to visible
84 for (String group : fr.getGroups(false))
86 fr.setGroupVisibility(group, true);
90 @Test(groups = "Functional")
91 public void testFindFeatureColour_noFeatures()
93 av.setShowSequenceFeatures(false);
94 Color c = finder.findFeatureColour(Color.blue, seq, 10);
95 assertEquals(c, Color.blue);
97 av.setShowSequenceFeatures(true);
98 c = finder.findFeatureColour(Color.blue, seq, 10);
99 assertEquals(c, Color.blue);
102 @Test(groups = "Functional")
103 public void testFindFeatureColour_noFeaturesShown()
105 seq.addSequenceFeature(new SequenceFeature("Metal", "Metal", 2, 12,
106 Float.NaN, "MetalGroup"));
108 av.setShowSequenceFeatures(false);
109 Color c = finder.findFeatureColour(Color.blue, seq, 10);
110 assertEquals(c, Color.blue);
113 @Test(groups = "Functional")
114 public void testFindFeatureColour_singleFeatureAtPosition()
116 seq.addSequenceFeature(new SequenceFeature("Metal", "Metal", 2, 12,
117 Float.NaN, "MetalGroup"));
118 fr.setColour("Metal", new FeatureColour(Color.red));
120 av.setShowSequenceFeatures(true);
121 Color c = finder.findFeatureColour(Color.blue, seq, 10);
122 assertEquals(c, Color.red);
125 @Test(groups = "Functional")
126 public void testFindFeatureColour_gapPosition()
128 seq.addSequenceFeature(new SequenceFeature("Metal", "Metal", 2, 12, 0f,
130 fr.setColour("Metal", new FeatureColour(Color.red));
132 av.setShowSequenceFeatures(true);
133 Color c = finder.findFeatureColour(null, seq, 6);
134 assertEquals(c, Color.white);
137 @Test(groups = "Functional")
138 public void testFindFeatureColour_multipleFeaturesAtPositionNoTransparency()
141 * featuresAdded -> FeatureRendererModel.updateRenderOrder which adds any
142 * new features 'on top' (but reverses the order of any added features)
144 seq.addSequenceFeature(new SequenceFeature("Metal", "Metal", 2, 12,
145 Float.NaN, "MetalGroup"));
146 FeatureColour red = new FeatureColour(Color.red);
147 fr.setColour("Metal", red);
149 seq.addSequenceFeature(new SequenceFeature("Domain", "Domain", 4, 15,
150 Float.NaN, "DomainGroup"));
151 FeatureColour green = new FeatureColour(Color.green);
152 fr.setColour("Domain", green);
154 av.setShowSequenceFeatures(true);
157 * expect Domain (green) to be rendered above Metal (red)
159 Color c = finder.findFeatureColour(Color.blue, seq, 10);
160 assertEquals(c, Color.green);
163 * now promote Metal above Domain
164 * - currently no way other than mimicking reordering of
165 * table in Feature Settings
167 Object[][] data = new Object[2][];
168 data[0] = new Object[] { "Metal", red, true };
169 data[1] = new Object[] { "Domain", green, true };
170 fr.setFeaturePriority(data);
171 c = finder.findFeatureColour(Color.blue, seq, 10);
172 assertEquals(c, Color.red);
175 * ..and turn off display of Metal
178 fr.setFeaturePriority(data);
179 c = finder.findFeatureColour(Color.blue, seq, 10);
180 assertEquals(c, Color.green);
183 @Test(groups = "Functional")
184 public void testFindFeatureColour_singleFeatureNotAtPosition()
186 seq.addSequenceFeature(new SequenceFeature("Metal", "Metal", 8, 12,
187 Float.NaN, "MetalGroup"));
188 fr.setColour("Metal", new FeatureColour(Color.red));
190 av.setShowSequenceFeatures(true);
191 // column 2 = sequence position 3
192 Color c = finder.findFeatureColour(Color.blue, seq, 2);
193 assertEquals(c, Color.blue);
196 @Test(groups = "Functional")
197 public void testFindFeatureColour_featureTypeNotDisplayed()
199 seq.addSequenceFeature(new SequenceFeature("Metal", "Metal", 2, 12,
200 Float.NaN, "MetalGroup"));
201 FeatureColour red = new FeatureColour(Color.red);
202 fr.setColour("Metal", red);
204 av.setShowSequenceFeatures(true);
205 Color c = finder.findFeatureColour(Color.blue, seq, 10);
206 assertEquals(c, Color.red);
209 * turn off display of Metal - is this the easiest way to do it??
211 Object[][] data = new Object[1][];
212 data[0] = new Object[] { "Metal", red, false };
213 fr.setFeaturePriority(data);
214 c = finder.findFeatureColour(Color.blue, seq, 10);
215 assertEquals(c, Color.blue);
218 * turn display of Metal back on
220 data[0] = new Object[] { "Metal", red, true };
221 fr.setFeaturePriority(data);
222 c = finder.findFeatureColour(Color.blue, seq, 10);
223 assertEquals(c, Color.red);
226 @Test(groups = "Functional")
227 public void testFindFeatureColour_featureGroupNotDisplayed()
229 seq.addSequenceFeature(new SequenceFeature("Metal", "Metal", 2, 12,
230 Float.NaN, "MetalGroup"));
231 FeatureColour red = new FeatureColour(Color.red);
232 fr.setColour("Metal", red);
234 av.setShowSequenceFeatures(true);
235 Color c = finder.findFeatureColour(Color.blue, seq, 10);
236 assertEquals(c, Color.red);
239 * turn off display of MetalGroup
241 fr.setGroupVisibility("MetalGroup", false);
242 c = finder.findFeatureColour(Color.blue, seq, 10);
243 assertEquals(c, Color.blue);
246 * turn display of MetalGroup back on
248 fr.setGroupVisibility("MetalGroup", true);
249 c = finder.findFeatureColour(Color.blue, seq, 10);
250 assertEquals(c, Color.red);
253 @Test(groups = "Functional")
254 public void testFindFeatureColour_contactFeature()
257 * currently contact feature == type "Disulphide Bond" or "Disulfide Bond" !!
259 seq.addSequenceFeature(new SequenceFeature("Disulphide Bond",
260 "Contact", 2, 12, Float.NaN, "Disulphide"));
261 fr.setColour("Disulphide Bond", new FeatureColour(Color.red));
263 av.setShowSequenceFeatures(true);
266 * Contact positions are residues 2 and 12
267 * which are columns 1 and 14
268 * positions in between don't count for a contact feature!
270 Color c = finder.findFeatureColour(Color.blue, seq, 10);
271 assertEquals(c, Color.blue);
272 c = finder.findFeatureColour(Color.blue, seq, 8);
273 assertEquals(c, Color.blue);
274 c = finder.findFeatureColour(Color.blue, seq, 1);
275 assertEquals(c, Color.red);
276 c = finder.findFeatureColour(Color.blue, seq, 14);
277 assertEquals(c, Color.red);
280 @Test(groups = "Functional")
281 public void testFindFeatureColour_graduatedFeatureColour()
283 seq.addSequenceFeature(new SequenceFeature("kd", "hydrophobicity", 2,
285 seq.addSequenceFeature(new SequenceFeature("kd", "hydrophobicity", 4,
287 seq.addSequenceFeature(new SequenceFeature("kd", "hydrophobicity", 7,
291 * graduated colour from 0 to 10
293 Color min = new Color(100, 50, 150);
294 Color max = new Color(200, 0, 100);
295 FeatureColourI fc = new FeatureColour(min, max, 0, 10);
296 fr.setColour("kd", fc);
298 av.setShowSequenceFeatures(true);
301 * position 2, column 1, score 0 - minimum colour in range
303 Color c = finder.findFeatureColour(Color.blue, seq, 1);
304 assertEquals(c, min);
307 * position 7, column 9, score 10 - maximum colour in range
309 c = finder.findFeatureColour(Color.blue, seq, 9);
310 assertEquals(c, max);
313 * position 4, column 3, score 5 - half way from min to max
315 c = finder.findFeatureColour(Color.blue, seq, 3);
316 assertEquals(c, new Color(150, 25, 125));
319 @Test(groups = "Functional")
320 public void testFindFeatureColour_transparencySingleFeature()
322 seq.addSequenceFeature(new SequenceFeature("Metal", "Metal", 2, 12,
323 Float.NaN, "MetalGroup"));
324 FeatureColour red = new FeatureColour(Color.red);
325 fr.setColour("Metal", red);
327 av.setShowSequenceFeatures(true);
330 * the FeatureSettings transparency slider has range 0-70 which
331 * corresponds to a transparency value of 1 - 0.3
332 * A value of 0.4 gives a combination of
333 * 0.4 * red(255, 0, 0) + 0.6 * cyan(0, 255, 255) = (102, 153, 153)
335 fr.setTransparency(0.4f);
336 Color c = finder.findFeatureColour(Color.cyan, seq, 10);
337 assertEquals(c, new Color(102, 153, 153));
340 @Test(groups = "Functional")
341 public void testFindFeatureColour_transparencyTwoFeatures()
343 seq.addSequenceFeature(new SequenceFeature("Metal", "Metal", 2, 12,
344 Float.NaN, "MetalGroup"));
345 FeatureColour red = new FeatureColour(Color.red);
346 fr.setColour("Metal", red);
348 seq.addSequenceFeature(new SequenceFeature("Domain", "Domain", 4, 15,
349 Float.NaN, "DomainGroup"));
350 FeatureColour green = new FeatureColour(Color.green);
351 fr.setColour("Domain", green);
353 av.setShowSequenceFeatures(true);
356 * Domain (green) rendered above Metal (red) above background (cyan)
357 * 1) 0.6 * red(255, 0, 0) + 0.4 * cyan(0, 255, 255) = (153, 102, 102)
358 * 2) 0.6* green(0, 255, 0) + 0.4 * (153, 102, 102) = (61, 194, 41) rounded
360 fr.setTransparency(0.6f);
361 Color c = finder.findFeatureColour(Color.cyan, seq, 10);
362 assertEquals(c, new Color(61, 194, 41));
365 * now promote Metal above Domain
366 * - currently no way other than mimicking reordering of
367 * table in Feature Settings
368 * Metal (red) rendered above Domain (green) above background (cyan)
369 * 1) 0.6 * green(0, 255, 0) + 0.4 * cyan(0, 255, 255) = (0, 255, 102)
370 * 2) 0.6* red(255, 0, 0) + 0.4 * (0, 255, 102) = (153, 102, 41) rounded
372 Object[][] data = new Object[2][];
373 data[0] = new Object[] { "Metal", red, true };
374 data[1] = new Object[] { "Domain", green, true };
375 fr.setFeaturePriority(data);
376 c = finder.findFeatureColour(Color.cyan, seq, 10);
377 assertEquals(c, new Color(153, 102, 41));
380 * ..and turn off display of Metal
381 * Domain (green) above background (pink)
382 * 0.6 * green(0, 255, 0) + 0.4 * pink(255, 175, 175) = (102, 223, 70)
385 fr.setFeaturePriority(data);
386 c = finder.findFeatureColour(Color.pink, seq, 10);
387 assertEquals(c, new Color(102, 223, 70));
390 @Test(groups = "Functional")
391 public void testNoFeaturesDisplayed()
394 * no features on alignment to render
396 assertTrue(finder.noFeaturesDisplayed());
400 * it will be automatically set visible but the viewport
401 * is still configured not to show features
403 seq.addSequenceFeature(new SequenceFeature("Metal", "Metal", 2, 12,
404 Float.NaN, "MetalGroup"));
405 FeatureColour red = new FeatureColour(Color.red);
406 fr.setColour("Metal", red);
408 assertTrue(finder.noFeaturesDisplayed());
411 * turn on feature display
413 av.setShowSequenceFeatures(true);
414 assertFalse(finder.noFeaturesDisplayed());
417 * turn off display of Metal
419 Object[][] data = new Object[1][];
420 data[0] = new Object[] { "Metal", red, false };
421 fr.setFeaturePriority(data);
422 assertTrue(finder.noFeaturesDisplayed());
425 * turn display of Metal back on
427 fr.setVisible("Metal");
428 assertFalse(finder.noFeaturesDisplayed());
431 * turn off MetalGroup - has no effect here since the group of a
432 * sequence feature instance is independent of its type
434 fr.setGroupVisibility("MetalGroup", false);
435 assertFalse(finder.noFeaturesDisplayed());