1 package jalview.renderer.seqfeatures;
3 import static org.testng.Assert.assertEquals;
5 import jalview.api.FeatureColourI;
6 import jalview.datamodel.SequenceFeature;
7 import jalview.datamodel.SequenceI;
8 import jalview.gui.AlignFrame;
9 import jalview.gui.AlignViewport;
10 import jalview.gui.FeatureRenderer;
11 import jalview.io.DataSourceType;
12 import jalview.io.FileLoader;
13 import jalview.schemes.FeatureColour;
15 import java.awt.Color;
17 import org.testng.annotations.BeforeClass;
18 import org.testng.annotations.BeforeMethod;
19 import org.testng.annotations.Test;
22 * Unit tests for feature colour determination, including but not limited to
24 * <li>gap position</li>
25 * <li>no features present</li>
26 * <li>features present but show features turned off</li>
27 * <li>features displayed but selected feature turned off</li>
28 * <li>features displayed but feature group turned off</li>
29 * <li>feature displayed but none at the specified position</li>
30 * <li>multiple features at position, with no transparency</li>
31 * <li>multiple features at position, with transparency</li>
32 * <li>score graduated feature colour</li>
33 * <li>contact feature start at the selected position</li>
34 * <li>contact feature end at the selected position</li>
35 * <li>contact feature straddling the selected position (not shown)</li>
38 public class FeatureColourFinderTest
40 private AlignViewport av;
42 private SequenceI seq;
44 private FeatureColourFinder finder;
46 private AlignFrame af;
48 private FeatureRenderer fr;
50 @BeforeClass(alwaysRun = true)
53 // aligned column 8 is sequence position 6
54 String s = ">s1\nABCDE---FGHIJKLMNOPQRSTUVWXYZ\n";
55 af = new FileLoader().LoadFileWaitTillLoaded(s,
56 DataSourceType.PASTE);
57 av = af.getViewport();
58 seq = av.getAlignment().getSequenceAt(0);
59 fr = af.getFeatureRenderer();
60 finder = new FeatureColourFinder(fr);
64 * Clear down any sequence features before each test
66 @BeforeMethod(alwaysRun = true)
67 public void setUpBeforeTest()
69 SequenceFeature[] sfs = seq.getSequenceFeatures();
72 for (SequenceFeature sf : sfs)
74 seq.deleteFeature(sf);
77 fr.findAllFeatures(true);
80 * reset all feature groups to visible
82 for (String group : fr.getGroups(false))
84 fr.setGroupVisibility(group, true);
88 @Test(groups = "Functional")
89 public void testFindFeatureColour_noFeatures()
91 av.setShowSequenceFeatures(false);
92 Color c = finder.findFeatureColour(Color.blue, seq, 10);
93 assertEquals(c, Color.blue);
95 av.setShowSequenceFeatures(true);
96 c = finder.findFeatureColour(Color.blue, seq, 10);
97 assertEquals(c, Color.blue);
100 @Test(groups = "Functional")
101 public void testFindFeatureColour_noFeaturesShown()
103 seq.addSequenceFeature(new SequenceFeature("Metal", "Metal", 2, 12,
104 Float.NaN, "MetalGroup"));
106 av.setShowSequenceFeatures(false);
107 Color c = finder.findFeatureColour(Color.blue, seq, 10);
108 assertEquals(c, Color.blue);
111 @Test(groups = "Functional")
112 public void testFindFeatureColour_singleFeatureAtPosition()
114 seq.addSequenceFeature(new SequenceFeature("Metal", "Metal", 2, 12,
115 Float.NaN, "MetalGroup"));
116 fr.setColour("Metal", new FeatureColour(Color.red));
118 av.setShowSequenceFeatures(true);
119 Color c = finder.findFeatureColour(Color.blue, seq, 10);
120 assertEquals(c, Color.red);
123 @Test(groups = "Functional")
124 public void testFindFeatureColour_gapPosition()
126 seq.addSequenceFeature(new SequenceFeature("Metal", "Metal", 2, 12, 0f,
128 fr.setColour("Metal", new FeatureColour(Color.red));
130 av.setShowSequenceFeatures(true);
131 Color c = finder.findFeatureColour(null, seq, 6);
132 assertEquals(c, Color.white);
135 @Test(groups = "Functional")
136 public void testFindFeatureColour_multipleFeaturesAtPositionNoTransparency()
139 * featuresAdded -> FeatureRendererModel.updateRenderOrder which adds any
140 * new features 'on top' (but reverses the order of any added features)
142 seq.addSequenceFeature(new SequenceFeature("Metal", "Metal", 2, 12,
143 Float.NaN, "MetalGroup"));
144 FeatureColour red = new FeatureColour(Color.red);
145 fr.setColour("Metal", red);
147 seq.addSequenceFeature(new SequenceFeature("Domain", "Domain", 4, 15,
148 Float.NaN, "DomainGroup"));
149 FeatureColour green = new FeatureColour(Color.green);
150 fr.setColour("Domain", green);
152 av.setShowSequenceFeatures(true);
155 * expect Domain (green) to be rendered above Metal (red)
157 Color c = finder.findFeatureColour(Color.blue, seq, 10);
158 assertEquals(c, Color.green);
161 * now promote Metal above Domain
162 * - currently no way other than mimicking reordering of
163 * table in Feature Settings
165 Object[][] data = new Object[2][];
166 data[0] = new Object[] { "Metal", red, true };
167 data[1] = new Object[] { "Domain", green, true };
168 fr.setFeaturePriority(data);
169 c = finder.findFeatureColour(Color.blue, seq, 10);
170 assertEquals(c, Color.red);
173 * ..and turn off display of Metal
176 fr.setFeaturePriority(data);
177 c = finder.findFeatureColour(Color.blue, seq, 10);
178 assertEquals(c, Color.green);
181 @Test(groups = "Functional")
182 public void testFindFeatureColour_singleFeatureNotAtPosition()
184 seq.addSequenceFeature(new SequenceFeature("Metal", "Metal", 8, 12,
185 Float.NaN, "MetalGroup"));
186 fr.setColour("Metal", new FeatureColour(Color.red));
188 av.setShowSequenceFeatures(true);
189 // column 2 = sequence position 3
190 Color c = finder.findFeatureColour(Color.blue, seq, 2);
191 assertEquals(c, Color.blue);
194 @Test(groups = "Functional")
195 public void testFindFeatureColour_featureTypeNotDisplayed()
197 seq.addSequenceFeature(new SequenceFeature("Metal", "Metal", 2, 12,
198 Float.NaN, "MetalGroup"));
199 FeatureColour red = new FeatureColour(Color.red);
200 fr.setColour("Metal", red);
202 av.setShowSequenceFeatures(true);
203 Color c = finder.findFeatureColour(Color.blue, seq, 10);
204 assertEquals(c, Color.red);
207 * turn off display of Metal - is this the easiest way to do it??
209 Object[][] data = new Object[1][];
210 data[0] = new Object[] { "Metal", red, false };
211 fr.setFeaturePriority(data);
212 c = finder.findFeatureColour(Color.blue, seq, 10);
213 assertEquals(c, Color.blue);
216 * turn display of Metal back on
218 data[0] = new Object[] { "Metal", red, true };
219 fr.setFeaturePriority(data);
220 c = finder.findFeatureColour(Color.blue, seq, 10);
221 assertEquals(c, Color.red);
224 @Test(groups = "Functional")
225 public void testFindFeatureColour_featureGroupNotDisplayed()
227 seq.addSequenceFeature(new SequenceFeature("Metal", "Metal", 2, 12,
228 Float.NaN, "MetalGroup"));
229 FeatureColour red = new FeatureColour(Color.red);
230 fr.setColour("Metal", red);
232 av.setShowSequenceFeatures(true);
233 Color c = finder.findFeatureColour(Color.blue, seq, 10);
234 assertEquals(c, Color.red);
237 * turn off display of MetalGroup
239 fr.setGroupVisibility("MetalGroup", false);
240 c = finder.findFeatureColour(Color.blue, seq, 10);
241 assertEquals(c, Color.blue);
244 * turn display of MetalGroup back on
246 fr.setGroupVisibility("MetalGroup", true);
247 c = finder.findFeatureColour(Color.blue, seq, 10);
248 assertEquals(c, Color.red);
251 @Test(groups = "Functional")
252 public void testFindFeatureColour_contactFeature()
255 * currently contact feature == type "Disulphide Bond" or "Disulfide Bond" !!
257 seq.addSequenceFeature(new SequenceFeature("Disulphide Bond",
258 "Contact", 2, 12, Float.NaN, "Disulphide"));
259 fr.setColour("Disulphide Bond", new FeatureColour(Color.red));
261 av.setShowSequenceFeatures(true);
264 * Contact positions are residues 2 and 12
265 * which are columns 1 and 14
266 * positions in between don't count for a contact feature!
268 Color c = finder.findFeatureColour(Color.blue, seq, 10);
269 assertEquals(c, Color.blue);
270 c = finder.findFeatureColour(Color.blue, seq, 8);
271 assertEquals(c, Color.blue);
272 c = finder.findFeatureColour(Color.blue, seq, 1);
273 assertEquals(c, Color.red);
274 c = finder.findFeatureColour(Color.blue, seq, 14);
275 assertEquals(c, Color.red);
278 @Test(groups = "Functional")
279 public void testFindFeatureColour_graduatedFeatureColour()
281 seq.addSequenceFeature(new SequenceFeature("kd", "hydrophobicity", 2,
283 seq.addSequenceFeature(new SequenceFeature("kd", "hydrophobicity", 4,
285 seq.addSequenceFeature(new SequenceFeature("kd", "hydrophobicity", 7,
289 * graduated colour from 0 to 10
291 Color min = new Color(100, 50, 150);
292 Color max = new Color(200, 0, 100);
293 FeatureColourI fc = new FeatureColour(min, max, 0, 10);
294 fr.setColour("kd", fc);
296 av.setShowSequenceFeatures(true);
299 * position 2, column 1, score 0 - minimum colour in range
301 Color c = finder.findFeatureColour(Color.blue, seq, 1);
302 assertEquals(c, min);
305 * position 7, column 9, score 10 - maximum colour in range
307 c = finder.findFeatureColour(Color.blue, seq, 9);
308 assertEquals(c, max);
311 * position 4, column 3, score 5 - half way from min to max
313 c = finder.findFeatureColour(Color.blue, seq, 3);
314 assertEquals(c, new Color(150, 25, 125));
317 @Test(groups = "Functional")
318 public void testFindFeatureColour_transparencySingleFeature()
320 seq.addSequenceFeature(new SequenceFeature("Metal", "Metal", 2, 12,
321 Float.NaN, "MetalGroup"));
322 FeatureColour red = new FeatureColour(Color.red);
323 fr.setColour("Metal", red);
325 av.setShowSequenceFeatures(true);
328 * the FeatureSettings transparency slider has range 0-70 which
329 * corresponds to a transparency value of 1 - 0.3
330 * A value of 0.4 gives a combination of
331 * 0.4 * red(255, 0, 0) + 0.6 * cyan(0, 255, 255) = (102, 153, 153)
333 fr.setTransparency(0.4f);
334 Color c = finder.findFeatureColour(Color.cyan, seq, 10);
335 assertEquals(c, new Color(102, 153, 153));
338 @Test(groups = "Functional")
339 public void testFindFeatureColour_transparencyTwoFeatures()
341 seq.addSequenceFeature(new SequenceFeature("Metal", "Metal", 2, 12,
342 Float.NaN, "MetalGroup"));
343 FeatureColour red = new FeatureColour(Color.red);
344 fr.setColour("Metal", red);
346 seq.addSequenceFeature(new SequenceFeature("Domain", "Domain", 4, 15,
347 Float.NaN, "DomainGroup"));
348 FeatureColour green = new FeatureColour(Color.green);
349 fr.setColour("Domain", green);
351 av.setShowSequenceFeatures(true);
354 * Domain (green) rendered above Metal (red) above background (cyan)
355 * 1) 0.6 * red(255, 0, 0) + 0.4 * cyan(0, 255, 255) = (153, 102, 102)
356 * 2) 0.6* green(0, 255, 0) + 0.4 * (153, 102, 102) = (61, 194, 41) rounded
358 fr.setTransparency(0.6f);
359 Color c = finder.findFeatureColour(Color.cyan, seq, 10);
360 assertEquals(c, new Color(61, 194, 41));
363 * now promote Metal above Domain
364 * - currently no way other than mimicking reordering of
365 * table in Feature Settings
366 * Metal (red) rendered above Domain (green) above background (cyan)
367 * 1) 0.6 * green(0, 255, 0) + 0.4 * cyan(0, 255, 255) = (0, 255, 102)
368 * 2) 0.6* red(255, 0, 0) + 0.4 * (0, 255, 102) = (153, 102, 41) rounded
370 Object[][] data = new Object[2][];
371 data[0] = new Object[] { "Metal", red, true };
372 data[1] = new Object[] { "Domain", green, true };
373 fr.setFeaturePriority(data);
374 c = finder.findFeatureColour(Color.cyan, seq, 10);
375 assertEquals(c, new Color(153, 102, 41));
378 * ..and turn off display of Metal
379 * Domain (green) above background (pink)
380 * 0.6 * green(0, 255, 0) + 0.4 * pink(255, 175, 175) = (102, 223, 70)
383 fr.setFeaturePriority(data);
384 c = finder.findFeatureColour(Color.pink, seq, 10);
385 assertEquals(c, new Color(102, 223, 70));