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.ScoreModelI;
27 import jalview.api.analysis.SimilarityParamsI;
28 import jalview.datamodel.Alignment;
29 import jalview.datamodel.AlignmentI;
30 import jalview.datamodel.AlignmentView;
31 import jalview.datamodel.Sequence;
32 import jalview.datamodel.SequenceFeature;
33 import jalview.datamodel.SequenceI;
34 import jalview.gui.AlignFrame;
35 import jalview.gui.AlignViewport;
36 import jalview.gui.JvOptionPane;
37 import jalview.io.DataSourceType;
38 import jalview.io.FileLoader;
39 import jalview.math.MatrixI;
41 import java.util.Arrays;
43 import org.testng.Assert;
44 import org.testng.annotations.BeforeClass;
45 import org.testng.annotations.Test;
47 public class FeatureDistanceModelTest
50 @BeforeClass(alwaysRun = true)
51 public void setUpJvOptionPane()
53 JvOptionPane.setInteractiveMode(false);
54 JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
57 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";
59 int[] sf1 = new int[] { 74, 74, 73, 73, 23, 23, -1, -1 };
61 int[] sf2 = new int[] { -1, -1, 74, 75, -1, -1, 76, 77 };
63 int[] sf3 = new int[] { -1, -1, -1, -1, -1, -1, 76, 77 };
67 * Load test alignment and add features to sequences:
68 * FER1_MESCR FER1_SPIOL FER3_RAPSA FER1_MAIZE
76 public AlignFrame getTestAlignmentFrame()
78 AlignFrame alf = new FileLoader(false)
79 .LoadFileWaitTillLoaded(alntestFile, DataSourceType.PASTE);
80 AlignmentI al = alf.getViewport().getAlignment();
81 Assert.assertEquals(al.getHeight(), 4);
82 Assert.assertEquals(al.getWidth(), 5);
83 for (int i = 0; i < 4; i++)
85 SequenceI ds = al.getSequenceAt(i).getDatasetSequence();
88 ds.addSequenceFeature(new SequenceFeature("sf1", "sf1", sf1[i * 2],
89 sf1[i * 2 + 1], "sf1"));
93 ds.addSequenceFeature(new SequenceFeature("sf2", "sf2", sf2[i * 2],
94 sf2[i * 2 + 1], "sf2"));
98 ds.addSequenceFeature(new SequenceFeature("sf3", "sf3", sf3[i * 2],
99 sf3[i * 2 + 1], "sf3"));
102 alf.setShowSeqFeatures(true);
103 alf.getFeatureRenderer().setVisible("sf1");
104 alf.getFeatureRenderer().setVisible("sf2");
105 alf.getFeatureRenderer().setVisible("sf3");
106 alf.getFeatureRenderer().findAllFeatures(true);
108 alf.getFeatureRenderer().getDisplayedFeatureTypes().size(), 3,
109 "Number of feature types");
110 assertTrue(alf.getCurrentView().areFeaturesDisplayed());
114 @Test(groups = { "Functional" })
115 public void testFeatureScoreModel() throws Exception
117 AlignFrame alf = getTestAlignmentFrame();
118 ScoreModelI sm = new FeatureDistanceModel();
119 sm = ScoreModels.getInstance().getScoreModel(sm.getName(),
120 alf.getCurrentView().getAlignPanel());
121 alf.selectAllSequenceMenuItem_actionPerformed(null);
123 MatrixI dm = sm.findDistances(alf.getViewport().getAlignmentView(true),
124 SimilarityParams.Jalview);
125 assertEquals(dm.getValue(0, 2), 0d,
126 "FER1_MESCR (0) should be identical with RAPSA (2)");
127 assertTrue(dm.getValue(0, 1) > dm.getValue(0, 2),
128 "FER1_MESCR (0) should be further from SPIOL (1) than it is from RAPSA (2)");
131 @Test(groups = { "Functional" })
132 public void testFeatureScoreModel_hiddenFirstColumn() throws Exception
134 AlignFrame alf = getTestAlignmentFrame();
135 // hiding first two columns shouldn't affect the tree
136 alf.getViewport().hideColumns(0, 1);
137 ScoreModelI sm = new FeatureDistanceModel();
138 sm = ScoreModels.getInstance().getScoreModel(sm.getName(),
139 alf.getCurrentView().getAlignPanel());
140 alf.selectAllSequenceMenuItem_actionPerformed(null);
141 MatrixI dm = sm.findDistances(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 // getName() can become static in Java 8
157 ScoreModelI sm = new FeatureDistanceModel();
158 sm = ScoreModels.getInstance().getScoreModel(sm.getName(),
159 alf.getCurrentView().getAlignPanel());
160 alf.selectAllSequenceMenuItem_actionPerformed(null);
161 MatrixI dm = sm.findDistances(alf.getViewport().getAlignmentView(true),
162 SimilarityParams.Jalview);
163 assertEquals(dm.getValue(0, 2), 0d,
164 "After hiding last two columns FER1_MESCR (0) should still be identical with RAPSA (2)");
165 assertEquals(dm.getValue(0, 1), 0d,
166 "After hiding last two columns FER1_MESCR (0) should now also be identical with SPIOL (1)");
167 for (int s = 0; s < 3; s++)
169 assertTrue(dm.getValue(s, 3) > 0d,
170 "After hiding last two columns "
171 + alf.getViewport().getAlignment().getSequenceAt(s)
174 + ") should still be distinct from FER1_MAIZE (3)");
179 * Check findFeatureAt doesn't return contact features except at contact
180 * points TODO:move to under the FeatureRendererModel test suite
182 @Test(groups = { "Functional" })
183 public void testFindFeatureAt_PointFeature() throws Exception
185 String alignment = "a CCCCCCGGGGGGCCCCCC\n" + "b CCCCCCGGGGGGCCCCCC\n"
186 + "c CCCCCCGGGGGGCCCCCC\n";
187 AlignFrame af = new jalview.io.FileLoader(false)
188 .LoadFileWaitTillLoaded(alignment, DataSourceType.PASTE);
189 SequenceI aseq = af.getViewport().getAlignment().getSequenceAt(0);
190 SequenceFeature sf = null;
191 sf = new SequenceFeature("disulphide bond", "", 2, 5, Float.NaN, "");
192 aseq.addSequenceFeature(sf);
193 assertTrue(sf.isContactFeature());
194 af.refreshFeatureUI(true);
195 af.getFeatureRenderer().setAllVisible(Arrays.asList("disulphide bond"));
197 af.getFeatureRenderer().getDisplayedFeatureTypes().size(), 1,
198 "Should be just one feature type displayed");
199 // step through and check for pointwise feature presence/absence
201 af.getFeatureRenderer().findFeaturesAtColumn(aseq, 1).size(),
203 // step through and check for pointwise feature presence/absence
205 af.getFeatureRenderer().findFeaturesAtColumn(aseq, 2).size(),
207 // step through and check for pointwise feature presence/absence
209 af.getFeatureRenderer().findFeaturesAtColumn(aseq, 3).size(),
211 // step through and check for pointwise feature presence/absence
213 af.getFeatureRenderer().findFeaturesAtColumn(aseq, 4).size(),
215 // step through and check for pointwise feature presence/absence
217 af.getFeatureRenderer().findFeaturesAtColumn(aseq, 5).size(),
219 // step through and check for pointwise feature presence/absence
221 af.getFeatureRenderer().findFeaturesAtColumn(aseq, 6).size(),
225 @Test(groups = { "Functional" })
226 public void testFindDistances() throws Exception
228 String seqs = ">s1\nABCDE\n>seq2\nABCDE\n";
229 AlignFrame alf = new FileLoader().LoadFileWaitTillLoaded(seqs,
230 DataSourceType.PASTE);
231 SequenceI s1 = alf.getViewport().getAlignment().getSequenceAt(0);
232 SequenceI s2 = alf.getViewport().getAlignment().getSequenceAt(1);
235 * set domain and variant features thus:
242 * The number of unshared feature types per column is
243 * 20120 (two features of the same type doesn't affect score)
244 * giving an average (pairwise distance) of 5/5 or 1.0
246 s1.addSequenceFeature(
247 new SequenceFeature("domain", null, 1, 3, 0f, null));
248 s1.addSequenceFeature(
249 new SequenceFeature("variant", null, 2, 4, 0f, null));
250 s1.addSequenceFeature(
251 new SequenceFeature("variant", null, 3, 5, 0f, null));
252 s2.addSequenceFeature(
253 new SequenceFeature("domain", null, 2, 4, 0f, null));
254 s2.addSequenceFeature(
255 new SequenceFeature("variant", null, 1, 2, 0f, null));
256 s2.addSequenceFeature(
257 new SequenceFeature("variant", null, 5, 5, 0f, null));
258 alf.setShowSeqFeatures(true);
259 alf.getFeatureRenderer().findAllFeatures(true);
261 ScoreModelI sm = new FeatureDistanceModel();
262 sm = ScoreModels.getInstance().getScoreModel(sm.getName(),
263 alf.getCurrentView().getAlignPanel());
264 alf.selectAllSequenceMenuItem_actionPerformed(null);
266 AlignmentView alignmentView = alf.getViewport().getAlignmentView(true);
267 MatrixI distances = sm.findDistances(alignmentView,
268 SimilarityParams.Jalview);
269 assertEquals(distances.width(), 2);
270 assertEquals(distances.height(), 2);
271 assertEquals(distances.getValue(0, 0), 0d);
272 assertEquals(distances.getValue(1, 1), 0d);
274 assertEquals(distances.getValue(0, 1), 1d,
275 "expected identical pairs. (check normalisation for similarity score)");
276 assertEquals(distances.getValue(1, 0), 1d);
280 * Verify computed distances with varying parameter options
282 @Test(groups = "Functional")
283 public void testFindDistances_withParams()
285 AlignFrame af = setupAlignmentView();
286 AlignViewport viewport = af.getViewport();
287 AlignmentView view = viewport.getAlignmentView(false);
289 ScoreModelI sm = new FeatureDistanceModel();
290 sm = ScoreModels.getInstance().getScoreModel(sm.getName(),
294 * feature distance model always normalises by region width
295 * gap-gap is always included (but scores zero)
296 * the only variable parameter is 'includeGaps'
301 * score = 3 + 3 + 0 + 2 + 3 + 2 = 13/6
303 SimilarityParamsI params = new SimilarityParams(true, true, true, true);
304 MatrixI distances = sm.findDistances(view, params);
305 assertEquals(distances.getValue(0, 0), 0d);
306 assertEquals(distances.getValue(1, 1), 0d);
307 assertEquals(distances.getValue(0, 1), 13d / 6); // should be 13d/6
308 assertEquals(distances.getValue(1, 0), 13d / 6);
312 * score = 3 + 3 + 0 + 0 + 0 + 0 = 6/6
314 params = new SimilarityParams(true, true, false, true);
315 distances = sm.findDistances(view, params);
316 assertEquals(distances.getValue(0, 1), 6d / 6);// should be 6d/6
330 * scores: 3 3 0 2 3 2
335 protected AlignFrame setupAlignmentView()
338 * for now, using space for gap to match callers of
339 * AlignmentView.getSequenceStrings()
340 * may change this to '-' (with corresponding change to matrices)
342 SequenceI s1 = new Sequence("s1", "FR K S");
343 SequenceI s2 = new Sequence("s2", "FS L");
345 s1.addSequenceFeature(
346 new SequenceFeature("chain", null, 1, 4, 0f, null));
347 s1.addSequenceFeature(
348 new SequenceFeature("domain", null, 1, 4, 0f, null));
349 s2.addSequenceFeature(
350 new SequenceFeature("chain", null, 1, 3, 0f, null));
351 s2.addSequenceFeature(
352 new SequenceFeature("metal", null, 1, 3, 0f, null));
353 s2.addSequenceFeature(
354 new SequenceFeature("Pfam", null, 1, 3, 0f, null));
355 AlignmentI al = new Alignment(new SequenceI[] { s1, s2 });
356 AlignFrame af = new AlignFrame(al, 300, 300);
357 af.setShowSeqFeatures(true);
358 af.getFeatureRenderer().findAllFeatures(true);