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).LoadFileWaitTillLoaded(
79 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);
107 Assert.assertEquals(alf.getFeatureRenderer().getDisplayedFeatureTypes()
108 .size(), 3, "Number of feature types");
109 assertTrue(alf.getCurrentView().areFeaturesDisplayed());
113 @Test(groups = { "Functional" })
114 public void testFeatureScoreModel() throws Exception
116 AlignFrame alf = getTestAlignmentFrame();
117 ScoreModelI sm = new FeatureDistanceModel();
118 sm = ScoreModels.getInstance().getScoreModel(sm.getName(),
119 alf.getCurrentView().getAlignPanel());
120 alf.selectAllSequenceMenuItem_actionPerformed(null);
122 MatrixI dm = sm.findDistances(
123 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(
142 alf.getViewport().getAlignmentView(true),
143 SimilarityParams.Jalview);
144 assertEquals(dm.getValue(0, 2), 0d,
145 "FER1_MESCR (0) should be identical with RAPSA (2)");
146 assertTrue(dm.getValue(0, 1) > dm.getValue(0, 2),
147 "FER1_MESCR (0) should be further from SPIOL (1) than it is from RAPSA (2)");
150 @Test(groups = { "Functional" })
151 public void testFeatureScoreModel_HiddenColumns() throws Exception
153 AlignFrame alf = getTestAlignmentFrame();
154 // hide columns and check tree changes
155 alf.getViewport().hideColumns(3, 4);
156 alf.getViewport().hideColumns(0, 1);
157 // getName() can become static in Java 8
158 ScoreModelI sm = new FeatureDistanceModel();
159 sm = ScoreModels.getInstance().getScoreModel(sm.getName(),
160 alf.getCurrentView().getAlignPanel());
161 alf.selectAllSequenceMenuItem_actionPerformed(null);
162 MatrixI dm = sm.findDistances(
163 alf.getViewport().getAlignmentView(true),
164 SimilarityParams.Jalview);
168 "After hiding last two columns FER1_MESCR (0) should still be identical with RAPSA (2)");
172 "After hiding last two columns FER1_MESCR (0) should now also be identical with SPIOL (1)");
173 for (int s = 0; s < 3; s++)
175 assertTrue(dm.getValue(s, 3) > 0d, "After hiding last two columns "
176 + alf.getViewport().getAlignment().getSequenceAt(s).getName()
177 + "(" + s + ") should still be distinct from FER1_MAIZE (3)");
182 * Check findFeatureAt doesn't return contact features except at contact
183 * points TODO:move to under the FeatureRendererModel test suite
185 @Test(groups = { "Functional" })
186 public void testFindFeatureAt_PointFeature() throws Exception
188 String alignment = "a CCCCCCGGGGGGCCCCCC\n" + "b CCCCCCGGGGGGCCCCCC\n"
189 + "c CCCCCCGGGGGGCCCCCC\n";
190 AlignFrame af = new jalview.io.FileLoader(false)
191 .LoadFileWaitTillLoaded(alignment, DataSourceType.PASTE);
192 SequenceI aseq = af.getViewport().getAlignment().getSequenceAt(0);
193 SequenceFeature sf = null;
194 sf = new SequenceFeature("disulphide bond", "", 2, 5, Float.NaN, "");
195 aseq.addSequenceFeature(sf);
196 assertTrue(sf.isContactFeature());
197 af.refreshFeatureUI(true);
198 af.getFeatureRenderer().setAllVisible(Arrays.asList("disulphide bond"));
199 Assert.assertEquals(af.getFeatureRenderer().getDisplayedFeatureTypes()
200 .size(), 1, "Should be just one feature type displayed");
201 // step through and check for pointwise feature presence/absence
202 Assert.assertEquals(af.getFeatureRenderer().findFeaturesAtColumn(aseq, 1)
204 // step through and check for pointwise feature presence/absence
205 Assert.assertEquals(af.getFeatureRenderer().findFeaturesAtColumn(aseq, 2)
207 // step through and check for pointwise feature presence/absence
208 Assert.assertEquals(af.getFeatureRenderer().findFeaturesAtColumn(aseq, 3)
210 // step through and check for pointwise feature presence/absence
211 Assert.assertEquals(af.getFeatureRenderer().findFeaturesAtColumn(aseq, 4)
213 // step through and check for pointwise feature presence/absence
214 Assert.assertEquals(af.getFeatureRenderer().findFeaturesAtColumn(aseq, 5)
216 // step through and check for pointwise feature presence/absence
217 Assert.assertEquals(af.getFeatureRenderer().findFeaturesAtColumn(aseq, 6)
221 @Test(groups = { "Functional" })
222 public void testFindDistances() throws Exception
224 String seqs = ">s1\nABCDE\n>seq2\nABCDE\n";
225 AlignFrame alf = new FileLoader().LoadFileWaitTillLoaded(seqs,
226 DataSourceType.PASTE);
227 SequenceI s1 = alf.getViewport().getAlignment().getSequenceAt(0);
228 SequenceI s2 = alf.getViewport().getAlignment().getSequenceAt(1);
231 * set domain and variant features thus:
238 * The number of unshared feature types per column is
239 * 20120 (two features of the same type doesn't affect score)
240 * giving an average (pairwise distance) of 5/5 or 1.0
242 s1.addSequenceFeature(new SequenceFeature("domain", null, 1, 3, 0f,
244 s1.addSequenceFeature(new SequenceFeature("variant", null, 2, 4, 0f,
246 s1.addSequenceFeature(new SequenceFeature("variant", null, 3, 5, 0f,
248 s2.addSequenceFeature(new SequenceFeature("domain", null, 2, 4, 0f,
250 s2.addSequenceFeature(new SequenceFeature("variant", null, 1, 2, 0f,
252 s2.addSequenceFeature(new SequenceFeature("variant", null, 5, 5, 0f,
254 alf.setShowSeqFeatures(true);
255 alf.getFeatureRenderer().findAllFeatures(true);
257 ScoreModelI sm = new FeatureDistanceModel();
258 sm = ScoreModels.getInstance().getScoreModel(sm.getName(),
259 alf.getCurrentView().getAlignPanel());
260 alf.selectAllSequenceMenuItem_actionPerformed(null);
262 AlignmentView alignmentView = alf.getViewport()
263 .getAlignmentView(true);
264 MatrixI distances = sm.findDistances(alignmentView,
265 SimilarityParams.Jalview);
266 assertEquals(distances.width(), 2);
267 assertEquals(distances.height(), 2);
268 assertEquals(distances.getValue(0, 0), 0d);
269 assertEquals(distances.getValue(1, 1), 0d);
271 assertEquals(distances.getValue(0, 1), 1d,
272 "expected identical pairs. (check normalisation for similarity score)");
273 assertEquals(distances.getValue(1, 0), 1d);
277 * Verify computed distances with varying parameter options
279 @Test(groups = "Functional")
280 public void testFindDistances_withParams()
282 AlignFrame af = setupAlignmentView();
283 AlignViewport viewport = af.getViewport();
284 AlignmentView view = viewport.getAlignmentView(false);
286 ScoreModelI sm = new FeatureDistanceModel();
287 sm = ScoreModels.getInstance().getScoreModel(sm.getName(),
291 * feature distance model always normalises by region width
292 * gap-gap is always included (but scores zero)
293 * the only variable parameter is 'includeGaps'
298 * score = 3 + 3 + 0 + 2 + 3 + 2 = 13/6
300 SimilarityParamsI params = new SimilarityParams(true, true, true, true);
301 MatrixI distances = sm.findDistances(view, params);
302 assertEquals(distances.getValue(0, 0), 0d);
303 assertEquals(distances.getValue(1, 1), 0d);
304 assertEquals(distances.getValue(0, 1), 13d / 6); // should be 13d/6
305 assertEquals(distances.getValue(1, 0), 13d / 6);
309 * score = 3 + 3 + 0 + 0 + 0 + 0 = 6/6
311 params = new SimilarityParams(true, true, false, true);
312 distances = sm.findDistances(view, params);
313 assertEquals(distances.getValue(0, 1), 6d / 6);// should be 6d/6
327 * scores: 3 3 0 2 3 2
332 protected AlignFrame setupAlignmentView()
335 * for now, using space for gap to match callers of
336 * AlignmentView.getSequenceStrings()
337 * may change this to '-' (with corresponding change to matrices)
339 SequenceI s1 = new Sequence("s1", "FR K S");
340 SequenceI s2 = new Sequence("s2", "FS L");
342 s1.addSequenceFeature(new SequenceFeature("chain", null, 1, 4, 0f, null));
343 s1.addSequenceFeature(new SequenceFeature("domain", null, 1, 4, 0f,
345 s2.addSequenceFeature(new SequenceFeature("chain", null, 1, 3, 0f, null));
346 s2.addSequenceFeature(new SequenceFeature("metal", null, 1, 3, 0f, null));
347 s2.addSequenceFeature(new SequenceFeature("Pfam", null, 1, 3, 0f, null));
348 AlignmentI al = new Alignment(new SequenceI[] { s1, s2 });
349 AlignFrame af = new AlignFrame(al, 300, 300);
350 af.setShowSeqFeatures(true);
351 af.getFeatureRenderer().findAllFeatures(true);