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.AlignViewportI;
8 import jalview.api.FeatureColourI;
9 import jalview.datamodel.SequenceFeature;
10 import jalview.datamodel.SequenceI;
11 import jalview.gui.AlignFrame;
12 import jalview.io.DataSourceType;
13 import jalview.io.FileLoader;
14 import jalview.schemes.FeatureColour;
16 import java.awt.Color;
17 import java.util.Arrays;
18 import java.util.List;
21 import org.testng.annotations.Test;
23 public class FeatureRendererTest
26 @Test(groups = "Functional")
27 public void testFindAllFeatures()
29 String seqData = ">s1\nabcdef\n>s2\nabcdef\n>s3\nabcdef\n>s4\nabcdef\n";
30 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(seqData,
31 DataSourceType.PASTE);
32 AlignViewportI av = af.getViewport();
33 FeatureRenderer fr = new FeatureRenderer(av);
38 fr.findAllFeatures(true);
39 assertTrue(fr.getRenderOrder().isEmpty());
40 assertTrue(fr.getFeatureGroups().isEmpty());
42 List<SequenceI> seqs = av.getAlignment().getSequences();
44 // add a non-positional feature - should be ignored by FeatureRenderer
45 SequenceFeature sf1 = new SequenceFeature("Type", "Desc", 0, 0, 1f,
47 seqs.get(0).addSequenceFeature(sf1);
48 fr.findAllFeatures(true);
49 // ? bug - types and groups added for non-positional features
50 List<String> types = fr.getRenderOrder();
51 List<String> groups = fr.getFeatureGroups();
52 assertEquals(types.size(), 0);
53 assertFalse(types.contains("Type"));
54 assertEquals(groups.size(), 0);
55 assertFalse(groups.contains("Group"));
57 // add some positional features
58 seqs.get(1).addSequenceFeature(
59 new SequenceFeature("Pfam", "Desc", 5, 9, 1f, "PfamGroup"));
60 seqs.get(2).addSequenceFeature(
61 new SequenceFeature("Pfam", "Desc", 14, 22, 2f, "RfamGroup"));
62 // bug in findAllFeatures - group not checked for a known feature type
63 seqs.get(2).addSequenceFeature(
64 new SequenceFeature("Rfam", "Desc", 5, 9, Float.NaN,
66 // existing feature type with null group
67 seqs.get(3).addSequenceFeature(
68 new SequenceFeature("Rfam", "Desc", 5, 9, Float.NaN, null));
69 // new feature type with null group
70 seqs.get(3).addSequenceFeature(
71 new SequenceFeature("Scop", "Desc", 5, 9, Float.NaN, null));
72 // null value for type produces NullPointerException
73 fr.findAllFeatures(true);
74 types = fr.getRenderOrder();
75 groups = fr.getFeatureGroups();
76 assertEquals(types.size(), 3);
77 assertFalse(types.contains("Type"));
78 assertTrue(types.contains("Pfam"));
79 assertTrue(types.contains("Rfam"));
80 assertTrue(types.contains("Scop"));
81 assertEquals(groups.size(), 2);
82 assertFalse(groups.contains("Group"));
83 assertTrue(groups.contains("PfamGroup"));
84 assertTrue(groups.contains("RfamGroup"));
85 assertFalse(groups.contains(null)); // null group is ignored
88 * check min-max values
90 Map<String, float[][]> minMax = fr.getMinMax();
91 assertEquals(minMax.size(), 1); // non-positional and NaN not stored
92 assertEquals(minMax.get("Pfam")[0][0], 1f); // positional min
93 assertEquals(minMax.get("Pfam")[0][1], 2f); // positional max
95 // increase max for Pfam, add scores for Rfam
96 seqs.get(0).addSequenceFeature(
97 new SequenceFeature("Pfam", "Desc", 14, 22, 8f, "RfamGroup"));
98 seqs.get(1).addSequenceFeature(
99 new SequenceFeature("Rfam", "Desc", 5, 9, 6f, "RfamGroup"));
100 fr.findAllFeatures(true);
101 // note minMax is not a defensive copy, shouldn't expose this
102 assertEquals(minMax.size(), 2);
103 assertEquals(minMax.get("Pfam")[0][0], 1f);
104 assertEquals(minMax.get("Pfam")[0][1], 8f);
105 assertEquals(minMax.get("Rfam")[0][0], 6f);
106 assertEquals(minMax.get("Rfam")[0][1], 6f);
109 * check render order (last is on top)
111 List<String> renderOrder = fr.getRenderOrder();
112 assertEquals(renderOrder, Arrays.asList("Scop", "Rfam", "Pfam"));
115 * change render order (todo: an easier way)
116 * nb here last comes first in the data array
118 Object[][] data = new Object[3][];
119 FeatureColourI colour = new FeatureColour(Color.RED);
120 data[0] = new Object[] { "Rfam", colour, true };
121 data[1] = new Object[] { "Pfam", colour, false };
122 data[2] = new Object[] { "Scop", colour, false };
123 fr.setFeaturePriority(data);
124 assertEquals(fr.getRenderOrder(), Arrays.asList("Scop", "Pfam", "Rfam"));
125 assertEquals(fr.getDisplayedFeatureTypes(), Arrays.asList("Rfam"));
128 * add a new feature type: should go on top of render order as visible,
129 * other feature ordering and visibility should be unchanged
131 seqs.get(2).addSequenceFeature(
132 new SequenceFeature("Metal", "Desc", 14, 22, 8f, "MetalGroup"));
133 fr.findAllFeatures(true);
134 assertEquals(fr.getRenderOrder(),
135 Arrays.asList("Scop", "Pfam", "Rfam", "Metal"));
136 assertEquals(fr.getDisplayedFeatureTypes(),
137 Arrays.asList("Rfam", "Metal"));
140 @Test(groups = "Functional")
141 public void testFindFeaturesAtRes()
143 String seqData = ">s1\nabcdefghijklmnopqrstuvwxyz\n";
144 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(seqData,
145 DataSourceType.PASTE);
146 AlignViewportI av = af.getViewport();
147 FeatureRenderer fr = new FeatureRenderer(av);
148 SequenceI seq = av.getAlignment().getSequenceAt(0);
153 List<SequenceFeature> features = fr.findFeaturesAtRes(seq, 3);
154 assertTrue(features.isEmpty());
159 SequenceFeature sf1 = new SequenceFeature("Type1", "Desc", 0, 0, 1f,
160 "Group"); // non-positional
161 seq.addSequenceFeature(sf1);
162 SequenceFeature sf2 = new SequenceFeature("Type2", "Desc", 5, 15, 1f,
164 seq.addSequenceFeature(sf2);
165 SequenceFeature sf3 = new SequenceFeature("Type3", "Desc", 5, 15, 1f,
167 seq.addSequenceFeature(sf3);
168 SequenceFeature sf4 = new SequenceFeature("Type3", "Desc", 5, 15, 1f,
169 null); // null group is always treated as visible
170 seq.addSequenceFeature(sf4);
173 * add contact features
175 SequenceFeature sf5 = new SequenceFeature("Disulphide Bond", "Desc", 4,
177 seq.addSequenceFeature(sf5);
178 SequenceFeature sf6 = new SequenceFeature("Disulphide Bond", "Desc", 4,
180 seq.addSequenceFeature(sf6);
181 SequenceFeature sf7 = new SequenceFeature("Disulphide Bond", "Desc", 4,
183 seq.addSequenceFeature(sf7);
186 * let feature renderer discover features (and make visible)
188 fr.findAllFeatures(true);
189 features = fr.findFeaturesAtRes(seq, 12); // all positional
190 assertEquals(features.size(), 6);
191 assertTrue(features.contains(sf2));
192 assertTrue(features.contains(sf3));
193 assertTrue(features.contains(sf4));
194 assertTrue(features.contains(sf5));
195 assertTrue(features.contains(sf6));
196 assertTrue(features.contains(sf7));
199 * at a non-contact position
201 features = fr.findFeaturesAtRes(seq, 11);
202 assertEquals(features.size(), 3);
203 assertTrue(features.contains(sf2));
204 assertTrue(features.contains(sf3));
205 assertTrue(features.contains(sf4));
208 * make "Type2" not displayed
210 Object[][] data = new Object[4][];
211 FeatureColourI colour = new FeatureColour(Color.RED);
212 data[0] = new Object[] { "Type1", colour, true };
213 data[1] = new Object[] { "Type2", colour, false };
214 data[2] = new Object[] { "Type3", colour, true };
215 data[3] = new Object[] { "Disulphide Bond", colour, true };
216 fr.setFeaturePriority(data);
217 features = fr.findFeaturesAtRes(seq, 12);
218 assertEquals(features.size(), 5); // no sf2
219 assertTrue(features.contains(sf3));
220 assertTrue(features.contains(sf4));
221 assertTrue(features.contains(sf5));
222 assertTrue(features.contains(sf6));
223 assertTrue(features.contains(sf7));
226 * make "Group2" not displayed
228 fr.setGroupVisibility("Group2", false);
229 features = fr.findFeaturesAtRes(seq, 12);
230 assertEquals(features.size(), 3); // no sf2, sf3, sf6
231 assertTrue(features.contains(sf4));
232 assertTrue(features.contains(sf5));
233 assertTrue(features.contains(sf7));