2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
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.
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.
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.
21 package jalview.analysis.scoremodels;
23 import static org.testng.Assert.assertEquals;
24 import static org.testng.Assert.assertTrue;
26 import jalview.api.analysis.SimilarityParamsI;
27 import jalview.datamodel.Alignment;
28 import jalview.datamodel.AlignmentI;
29 import jalview.datamodel.AlignmentView;
30 import jalview.datamodel.Sequence;
31 import jalview.datamodel.SequenceFeature;
32 import jalview.datamodel.SequenceI;
33 import jalview.gui.AlignFrame;
34 import jalview.gui.AlignViewport;
35 import jalview.gui.JvOptionPane;
36 import jalview.io.DataSourceType;
37 import jalview.io.FileLoader;
38 import jalview.math.MatrixI;
40 import java.util.Arrays;
42 import org.testng.Assert;
43 import org.testng.annotations.BeforeClass;
44 import org.testng.annotations.Test;
46 public class FeatureDistanceModelTest
49 @BeforeClass(alwaysRun = true)
50 public void setUpJvOptionPane()
52 JvOptionPane.setInteractiveMode(false);
53 JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
56 public static String alntestFile = "FER1_MESCR/72-76 DVYIL\nFER1_SPIOL/71-75 DVYIL\nFER3_RAPSA/21-25 DVYVL\nFER1_MAIZE/73-77 DVYIL\n";
58 int[] sf1 = new int[] { 74, 74, 73, 73, 23, 23, -1, -1 };
60 int[] sf2 = new int[] { -1, -1, 74, 75, -1, -1, 76, 77 };
62 int[] sf3 = new int[] { -1, -1, -1, -1, -1, -1, 76, 77 };
66 * Load test alignment and add features to sequences:
67 * FER1_MESCR FER1_SPIOL FER3_RAPSA FER1_MAIZE
75 public AlignFrame getTestAlignmentFrame()
77 AlignFrame alf = new FileLoader(false).LoadFileWaitTillLoaded(
78 alntestFile, DataSourceType.PASTE);
79 AlignmentI al = alf.getViewport().getAlignment();
80 Assert.assertEquals(al.getHeight(), 4);
81 Assert.assertEquals(al.getWidth(), 5);
82 for (int i = 0; i < 4; i++)
84 SequenceI ds = al.getSequenceAt(i).getDatasetSequence();
87 ds.addSequenceFeature(new SequenceFeature("sf1", "sf1", "sf1",
88 sf1[i * 2], sf1[i * 2 + 1], "sf1"));
92 ds.addSequenceFeature(new SequenceFeature("sf2", "sf2", "sf2",
93 sf2[i * 2], sf2[i * 2 + 1], "sf2"));
97 ds.addSequenceFeature(new SequenceFeature("sf3", "sf3", "sf3",
98 sf3[i * 2], sf3[i * 2 + 1], "sf3"));
101 alf.setShowSeqFeatures(true);
102 alf.getFeatureRenderer().setVisible("sf1");
103 alf.getFeatureRenderer().setVisible("sf2");
104 alf.getFeatureRenderer().setVisible("sf3");
105 alf.getFeatureRenderer().findAllFeatures(true);
106 Assert.assertEquals(alf.getFeatureRenderer().getDisplayedFeatureTypes()
107 .size(), 3, "Number of feature types");
108 assertTrue(alf.getCurrentView().areFeaturesDisplayed());
112 @Test(groups = { "Functional" })
113 public void testFeatureScoreModel() throws Exception
115 AlignFrame alf = getTestAlignmentFrame();
116 FeatureDistanceModel fsm = new FeatureDistanceModel();
117 assertTrue(fsm.configureFromAlignmentView(alf.getCurrentView()
119 alf.selectAllSequenceMenuItem_actionPerformed(null);
121 MatrixI dm = fsm.findDistances(
122 alf.getViewport().getAlignmentView(true),
123 SimilarityParams.Jalview);
124 assertEquals(dm.getValue(0, 2), 0d,
125 "FER1_MESCR (0) should be identical with RAPSA (2)");
126 assertTrue(dm.getValue(0, 1) > dm.getValue(0, 2),
127 "FER1_MESCR (0) should be further from SPIOL (1) than it is from RAPSA (2)");
130 @Test(groups = { "Functional" })
131 public void testFeatureScoreModel_hiddenFirstColumn() throws Exception
133 AlignFrame alf = getTestAlignmentFrame();
134 // hiding first two columns shouldn't affect the tree
135 alf.getViewport().hideColumns(0, 1);
136 FeatureDistanceModel fsm = new FeatureDistanceModel();
137 assertTrue(fsm.configureFromAlignmentView(alf.getCurrentView()
139 alf.selectAllSequenceMenuItem_actionPerformed(null);
140 MatrixI dm = fsm.findDistances(
141 alf.getViewport().getAlignmentView(true),
142 SimilarityParams.Jalview);
143 assertEquals(dm.getValue(0, 2), 0d,
144 "FER1_MESCR (0) should be identical with RAPSA (2)");
145 assertTrue(dm.getValue(0, 1) > dm.getValue(0, 2),
146 "FER1_MESCR (0) should be further from SPIOL (1) than it is from RAPSA (2)");
149 @Test(groups = { "Functional" })
150 public void testFeatureScoreModel_HiddenColumns() throws Exception
152 AlignFrame alf = getTestAlignmentFrame();
153 // hide columns and check tree changes
154 alf.getViewport().hideColumns(3, 4);
155 alf.getViewport().hideColumns(0, 1);
156 FeatureDistanceModel fsm = new FeatureDistanceModel();
157 assertTrue(fsm.configureFromAlignmentView(alf.getCurrentView()
159 alf.selectAllSequenceMenuItem_actionPerformed(null);
160 MatrixI dm = fsm.findDistances(
161 alf.getViewport().getAlignmentView(true),
162 SimilarityParams.Jalview);
166 "After hiding last two columns FER1_MESCR (0) should still be identical with RAPSA (2)");
170 "After hiding last two columns FER1_MESCR (0) should now also be identical with SPIOL (1)");
171 for (int s = 0; s < 3; s++)
173 assertTrue(dm.getValue(s, 3) > 0d, "After hiding last two columns "
174 + alf.getViewport().getAlignment().getSequenceAt(s).getName()
175 + "(" + s + ") should still be distinct from FER1_MAIZE (3)");
180 * Check findFeatureAt doesn't return contact features except at contact
181 * points TODO:move to under the FeatureRendererModel test suite
183 @Test(groups = { "Functional" })
184 public void testFindFeatureAt_PointFeature() throws Exception
186 String alignment = "a CCCCCCGGGGGGCCCCCC\n" + "b CCCCCCGGGGGGCCCCCC\n"
187 + "c CCCCCCGGGGGGCCCCCC\n";
188 AlignFrame af = new jalview.io.FileLoader(false)
189 .LoadFileWaitTillLoaded(alignment, DataSourceType.PASTE);
190 SequenceI aseq = af.getViewport().getAlignment().getSequenceAt(0);
191 SequenceFeature sf = null;
192 sf = new SequenceFeature("disulphide bond", "", 2, 5, Float.NaN, "");
193 aseq.addSequenceFeature(sf);
194 assertTrue(sf.isContactFeature());
195 af.refreshFeatureUI(true);
196 af.getFeatureRenderer().setAllVisible(Arrays.asList("disulphide bond"));
197 Assert.assertEquals(af.getFeatureRenderer().getDisplayedFeatureTypes()
198 .size(), 1, "Should be just one feature type displayed");
199 // step through and check for pointwise feature presence/absence
200 Assert.assertEquals(af.getFeatureRenderer().findFeaturesAtRes(aseq, 1)
202 // step through and check for pointwise feature presence/absence
203 Assert.assertEquals(af.getFeatureRenderer().findFeaturesAtRes(aseq, 2)
205 // step through and check for pointwise feature presence/absence
206 Assert.assertEquals(af.getFeatureRenderer().findFeaturesAtRes(aseq, 3)
208 // step through and check for pointwise feature presence/absence
209 Assert.assertEquals(af.getFeatureRenderer().findFeaturesAtRes(aseq, 4)
211 // step through and check for pointwise feature presence/absence
212 Assert.assertEquals(af.getFeatureRenderer().findFeaturesAtRes(aseq, 5)
214 // step through and check for pointwise feature presence/absence
215 Assert.assertEquals(af.getFeatureRenderer().findFeaturesAtRes(aseq, 6)
219 @Test(groups = { "Functional" })
220 public void testFindDistances() throws Exception
222 String seqs = ">s1\nABCDE\n>seq2\nABCDE\n";
223 AlignFrame alf = new FileLoader().LoadFileWaitTillLoaded(seqs,
224 DataSourceType.PASTE);
225 SequenceI s1 = alf.getViewport().getAlignment().getSequenceAt(0);
226 SequenceI s2 = alf.getViewport().getAlignment().getSequenceAt(1);
229 * set domain and variant features thus:
236 * The number of unshared feature types per column is
237 * 20120 (two features of the same type doesn't affect score)
238 * giving an average (pairwise distance) of 5/5 or 1.0
240 s1.addSequenceFeature(new SequenceFeature("domain", null, 1, 3, 0f,
242 s1.addSequenceFeature(new SequenceFeature("variant", null, 2, 4, 0f,
244 s1.addSequenceFeature(new SequenceFeature("variant", null, 3, 5, 0f,
246 s2.addSequenceFeature(new SequenceFeature("domain", null, 2, 4, 0f,
248 s2.addSequenceFeature(new SequenceFeature("variant", null, 1, 2, 0f,
250 s2.addSequenceFeature(new SequenceFeature("variant", null, 5, 5, 0f,
252 alf.setShowSeqFeatures(true);
253 alf.getFeatureRenderer().findAllFeatures(true);
255 FeatureDistanceModel fsm = new FeatureDistanceModel();
256 assertTrue(fsm.configureFromAlignmentView(alf.getCurrentView()
258 alf.selectAllSequenceMenuItem_actionPerformed(null);
260 MatrixI distances = fsm.findDistances(alf.getViewport()
261 .getAlignmentView(true), SimilarityParams.Jalview);
262 assertEquals(distances.width(), 2);
263 assertEquals(distances.height(), 2);
264 assertEquals(distances.getValue(0, 0), 0d);
265 assertEquals(distances.getValue(1, 1), 0d);
267 assertEquals(distances.getValue(0, 1), 1d,
268 "expected identical pairs. (check normalisation for similarity score)");
269 assertEquals(distances.getValue(1, 0), 1d);
273 * Verify computed distances with varying parameter options
275 @Test(groups = "Functional")
276 public void testFindDistances_withParams()
278 AlignFrame af = setupAlignmentView();
279 AlignViewport viewport = af.getViewport();
280 AlignmentView view = viewport.getAlignmentView(false);
282 FeatureDistanceModel sm = new FeatureDistanceModel();
283 sm.configureFromAlignmentView(af.alignPanel);
286 * feature distance model always normalises by region width
287 * gap-gap is always included (but scores zero)
288 * the only variable parameter is 'includeGaps'
293 * score = 3 + 3 + 0 + 2 + 3 + 2 = 13/6
295 SimilarityParamsI params = new SimilarityParams(true, true, true, true);
296 MatrixI distances = sm.findDistances(view, params);
297 assertEquals(distances.getValue(0, 0), 0d);
298 assertEquals(distances.getValue(1, 1), 0d);
299 assertEquals(distances.getValue(0, 1), 13d / 6); // should be 13d/6
300 assertEquals(distances.getValue(1, 0), 13d / 6);
304 * score = 3 + 3 + 0 + 0 + 0 + 0 = 6/6
306 params = new SimilarityParams(true, true, false, true);
307 distances = sm.findDistances(view, params);
308 assertEquals(distances.getValue(0, 1), 6d / 6);// should be 6d/6
322 * scores: 3 3 0 2 3 2
327 protected AlignFrame setupAlignmentView()
330 * for now, using space for gap to match callers of
331 * AlignmentView.getSequenceStrings()
332 * may change this to '-' (with corresponding change to matrices)
334 SequenceI s1 = new Sequence("s1", "FR K S");
335 SequenceI s2 = new Sequence("s2", "FS L");
337 s1.addSequenceFeature(new SequenceFeature("chain", null, 1, 4, 0f, null));
338 s1.addSequenceFeature(new SequenceFeature("domain", null, 1, 4, 0f,
340 s2.addSequenceFeature(new SequenceFeature("chain", null, 1, 3, 0f, null));
341 s2.addSequenceFeature(new SequenceFeature("metal", null, 1, 3, 0f, null));
342 s2.addSequenceFeature(new SequenceFeature("Pfam", null, 1, 3, 0f, null));
343 AlignmentI al = new Alignment(new SequenceI[] { s1, s2 });
344 AlignFrame af = new AlignFrame(al, 300, 300);
345 af.setShowSeqFeatures(true);
346 af.getFeatureRenderer().findAllFeatures(true);