Clover icon

Coverage Report

  1. Project Clover database Tue Mar 10 2026 14:58:44 GMT
  2. Package jalview.analysis.scoremodels

File FeatureDistanceModelTest.java

 

Code metrics

10
113
9
1
362
240
14
0.12
12.56
9
1.56

Classes

Class Line # Actions
FeatureDistanceModelTest 47 113 14
0.00%
 

Contributing tests

No tests hitting this source file were found.

Source view

1    /*
2    * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3    * Copyright (C) $$Year-Rel$$ The Jalview Authors
4    *
5    * This file is part of Jalview.
6    *
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.
11    *
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.
16    *
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.
20    */
21    package jalview.analysis.scoremodels;
22   
23    import static org.testng.Assert.assertEquals;
24    import static org.testng.Assert.assertTrue;
25   
26    import jalview.api.AlignViewportI;
27    import jalview.api.analysis.ScoreModelI;
28    import jalview.api.analysis.SimilarityParamsI;
29    import jalview.datamodel.Alignment;
30    import jalview.datamodel.AlignmentI;
31    import jalview.datamodel.AlignmentView;
32    import jalview.datamodel.Sequence;
33    import jalview.datamodel.SequenceFeature;
34    import jalview.datamodel.SequenceI;
35    import jalview.gui.AlignFrame;
36    import jalview.gui.JvOptionPane;
37    import jalview.io.DataSourceType;
38    import jalview.io.FileLoader;
39    import jalview.math.MatrixI;
40   
41    import java.util.Arrays;
42   
43    import org.testng.Assert;
44    import org.testng.annotations.BeforeClass;
45    import org.testng.annotations.Test;
46   
 
47    public class FeatureDistanceModelTest
48    {
49   
 
50  0 toggle @BeforeClass(alwaysRun = true)
51    public void setUpJvOptionPane()
52    {
53  0 JvOptionPane.setInteractiveMode(false);
54  0 JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
55    }
56   
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";
58   
59    int[] sf1 = new int[] { 74, 74, 73, 73, 23, 23, -1, -1 };
60   
61    int[] sf2 = new int[] { -1, -1, 74, 75, -1, -1, 76, 77 };
62   
63    int[] sf3 = new int[] { -1, -1, -1, -1, -1, -1, 76, 77 };
64   
65    /**
66    * <pre>
67    * Load test alignment and add features to sequences:
68    * FER1_MESCR FER1_SPIOL FER3_RAPSA FER1_MAIZE
69    * sf1 X X X
70    * sf2 X X
71    * sf3 X
72    * </pre>
73    *
74    * @return
75    */
 
76  0 toggle public AlignFrame getTestAlignmentFrame()
77    {
78  0 AlignFrame alf = new FileLoader(false)
79    .LoadFileWaitTillLoaded(alntestFile, DataSourceType.PASTE);
80  0 AlignmentI al = alf.getViewport().getAlignment();
81  0 Assert.assertEquals(al.getHeight(), 4);
82  0 Assert.assertEquals(al.getWidth(), 5);
83  0 for (int i = 0; i < 4; i++)
84    {
85  0 SequenceI ds = al.getSequenceAt(i).getDatasetSequence();
86  0 if (sf1[i * 2] > 0)
87    {
88  0 ds.addSequenceFeature(new SequenceFeature("sf1", "sf1", sf1[i * 2],
89    sf1[i * 2 + 1], "sf1"));
90    }
91  0 if (sf2[i * 2] > 0)
92    {
93  0 ds.addSequenceFeature(new SequenceFeature("sf2", "sf2", sf2[i * 2],
94    sf2[i * 2 + 1], "sf2"));
95    }
96  0 if (sf3[i * 2] > 0)
97    {
98  0 ds.addSequenceFeature(new SequenceFeature("sf3", "sf3", sf3[i * 2],
99    sf3[i * 2 + 1], "sf3"));
100    }
101    }
102  0 alf.setShowSeqFeatures(true);
103  0 alf.getFeatureRenderer().setVisible("sf1");
104  0 alf.getFeatureRenderer().setVisible("sf2");
105  0 alf.getFeatureRenderer().setVisible("sf3");
106  0 alf.getFeatureRenderer().findAllFeatures(true);
107  0 Assert.assertEquals(
108    alf.getFeatureRenderer().getDisplayedFeatureTypes().size(), 3,
109    "Number of feature types");
110  0 assertTrue(alf.getCurrentView().areFeaturesDisplayed());
111  0 return alf;
112    }
113   
 
114  0 toggle @Test(groups = { "Functional" })
115    public void testFeatureScoreModel() throws Exception
116    {
117  0 AlignFrame alf = getTestAlignmentFrame();
118  0 ScoreModelI sm = new FeatureDistanceModel();
119  0 sm = ScoreModels.getInstance().getScoreModel(sm.getName(),
120    alf.getCurrentView().getAlignPanel());
121  0 alf.selectAllSequenceMenuItem_actionPerformed(null);
122   
123  0 MatrixI dm = sm.findDistances(alf.getViewport().getAlignmentView(true),
124    SimilarityParams.Jalview);
125  0 assertEquals(dm.getValue(0, 2), 0d,
126    "FER1_MESCR (0) should be identical with RAPSA (2)");
127  0 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)");
129    }
130   
 
131  0 toggle @Test(groups = { "Functional" })
132    public void testFeatureScoreModel_hiddenFirstColumn() throws Exception
133    {
134  0 AlignFrame alf = getTestAlignmentFrame();
135    // hiding first two columns shouldn't affect the tree
136  0 alf.getViewport().hideColumns(0, 1);
137  0 ScoreModelI sm = new FeatureDistanceModel();
138  0 sm = ScoreModels.getInstance().getScoreModel(sm.getName(),
139    alf.getCurrentView().getAlignPanel());
140  0 alf.selectAllSequenceMenuItem_actionPerformed(null);
141  0 MatrixI dm = sm.findDistances(alf.getViewport().getAlignmentView(true),
142    SimilarityParams.Jalview);
143  0 assertEquals(dm.getValue(0, 2), 0d,
144    "FER1_MESCR (0) should be identical with RAPSA (2)");
145  0 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)");
147    }
148   
 
149  0 toggle @Test(groups = { "Functional" })
150    public void testFeatureScoreModel_HiddenColumns() throws Exception
151    {
152  0 AlignFrame alf = getTestAlignmentFrame();
153    // hide columns and check tree changes
154  0 alf.getViewport().hideColumns(3, 4);
155  0 alf.getViewport().hideColumns(0, 1);
156    // getName() can become static in Java 8
157  0 ScoreModelI sm = new FeatureDistanceModel();
158  0 sm = ScoreModels.getInstance().getScoreModel(sm.getName(),
159    alf.getCurrentView().getAlignPanel());
160  0 alf.selectAllSequenceMenuItem_actionPerformed(null);
161  0 MatrixI dm = sm.findDistances(alf.getViewport().getAlignmentView(true),
162    SimilarityParams.Jalview);
163  0 assertEquals(dm.getValue(0, 2), 0d,
164    "After hiding last two columns FER1_MESCR (0) should still be identical with RAPSA (2)");
165  0 assertEquals(dm.getValue(0, 1), 0d,
166    "After hiding last two columns FER1_MESCR (0) should now also be identical with SPIOL (1)");
167  0 for (int s = 0; s < 3; s++)
168    {
169  0 assertTrue(dm.getValue(s, 3) > 0d,
170    "After hiding last two columns "
171    + alf.getViewport().getAlignment().getSequenceAt(s)
172    .getName()
173    + "(" + s
174    + ") should still be distinct from FER1_MAIZE (3)");
175    }
176    }
177   
178    /**
179    * Check findFeatureAt doesn't return contact features except at contact
180    * points TODO:move to under the FeatureRendererModel test suite
181    */
 
182  0 toggle @Test(groups = { "Functional" })
183    public void testFindFeatureAt_PointFeature() throws Exception
184    {
185  0 String alignment = "a CCCCCCGGGGGGCCCCCC\n" + "b CCCCCCGGGGGGCCCCCC\n"
186    + "c CCCCCCGGGGGGCCCCCC\n";
187  0 AlignFrame af = new jalview.io.FileLoader(false)
188    .LoadFileWaitTillLoaded(alignment, DataSourceType.PASTE);
189  0 SequenceI aseq = af.getViewport().getAlignment().getSequenceAt(0);
190  0 SequenceFeature sf = null;
191  0 sf = new SequenceFeature("disulphide bond", "", 2, 5, Float.NaN, "");
192  0 aseq.addSequenceFeature(sf);
193  0 assertTrue(sf.isContactFeature());
194  0 af.refreshFeatureUI(true);
195  0 af.getFeatureRenderer().setAllVisible(Arrays.asList("disulphide bond"));
196  0 Assert.assertEquals(
197    af.getFeatureRenderer().getDisplayedFeatureTypes().size(), 1,
198    "Should be just one feature type displayed");
199    // step through and check for pointwise feature presence/absence
200  0 Assert.assertEquals(
201    af.getFeatureRenderer().findFeaturesAtColumn(aseq, 1).size(),
202    0);
203    // step through and check for pointwise feature presence/absence
204  0 Assert.assertEquals(
205    af.getFeatureRenderer().findFeaturesAtColumn(aseq, 2).size(),
206    1);
207    // step through and check for pointwise feature presence/absence
208  0 Assert.assertEquals(
209    af.getFeatureRenderer().findFeaturesAtColumn(aseq, 3).size(),
210    0);
211    // step through and check for pointwise feature presence/absence
212  0 Assert.assertEquals(
213    af.getFeatureRenderer().findFeaturesAtColumn(aseq, 4).size(),
214    0);
215    // step through and check for pointwise feature presence/absence
216  0 Assert.assertEquals(
217    af.getFeatureRenderer().findFeaturesAtColumn(aseq, 5).size(),
218    1);
219    // step through and check for pointwise feature presence/absence
220  0 Assert.assertEquals(
221    af.getFeatureRenderer().findFeaturesAtColumn(aseq, 6).size(),
222    0);
223    }
224   
 
225  0 toggle @Test(groups = { "Functional" })
226    public void testFindDistances() throws Exception
227    {
228  0 String seqs = ">s1\nABCDE\n>seq2\nABCDE\n";
229  0 AlignFrame alf = new FileLoader().LoadFileWaitTillLoaded(seqs,
230    DataSourceType.PASTE);
231  0 SequenceI s1 = alf.getViewport().getAlignment().getSequenceAt(0);
232  0 SequenceI s2 = alf.getViewport().getAlignment().getSequenceAt(1);
233   
234    /*
235    * set domain and variant features thus:
236    * ----5
237    * s1 ddd..
238    * s1 .vvv.
239    * s1 ..vvv
240    * s2 .ddd.
241    * s2 vv..v
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
245    */
246  0 s1.addSequenceFeature(
247    new SequenceFeature("domain", null, 1, 3, 0f, null));
248  0 s1.addSequenceFeature(
249    new SequenceFeature("variant", null, 2, 4, 0f, null));
250  0 s1.addSequenceFeature(
251    new SequenceFeature("variant", null, 3, 5, 0f, null));
252  0 s2.addSequenceFeature(
253    new SequenceFeature("domain", null, 2, 4, 0f, null));
254  0 s2.addSequenceFeature(
255    new SequenceFeature("variant", null, 1, 2, 0f, null));
256  0 s2.addSequenceFeature(
257    new SequenceFeature("variant", null, 5, 5, 0f, null));
258  0 alf.setShowSeqFeatures(true);
259  0 alf.getFeatureRenderer().findAllFeatures(true);
260   
261  0 ScoreModelI sm = new FeatureDistanceModel();
262  0 sm = ScoreModels.getInstance().getScoreModel(sm.getName(),
263    alf.getCurrentView().getAlignPanel());
264  0 alf.selectAllSequenceMenuItem_actionPerformed(null);
265   
266  0 AlignmentView alignmentView = alf.getViewport().getAlignmentView(true);
267  0 MatrixI distances = sm.findDistances(alignmentView,
268    SimilarityParams.Jalview);
269  0 assertEquals(distances.width(), 2);
270  0 assertEquals(distances.height(), 2);
271  0 assertEquals(distances.getValue(0, 0), 0d);
272  0 assertEquals(distances.getValue(1, 1), 0d);
273   
274  0 assertEquals(distances.getValue(0, 1), 1d,
275    "expected identical pairs. (check normalisation for similarity score)");
276  0 assertEquals(distances.getValue(1, 0), 1d);
277    }
278   
279    /**
280    * Verify computed distances with varying parameter options
281    */
 
282  0 toggle @Test(groups = "Functional")
283    public void testFindDistances_withParams()
284    {
285  0 AlignFrame af = setupAlignmentView();
286  0 AlignViewportI viewport = af.getViewport();
287  0 AlignmentView view = viewport.getAlignmentView(false);
288   
289  0 ScoreModelI sm = new FeatureDistanceModel();
290  0 sm = ScoreModels.getInstance().getScoreModel(sm.getName(),
291    af.alignPanel);
292   
293    /*
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'
297    */
298   
299    /*
300    * include gaps
301    * score = 3 + 3 + 0 + 2 + 3 + 2 = 13/6
302    */
303  0 SimilarityParamsI params = new SimilarityParams(true, true, true, true);
304  0 MatrixI distances = sm.findDistances(view, params);
305  0 assertEquals(distances.getValue(0, 0), 0d);
306  0 assertEquals(distances.getValue(1, 1), 0d);
307  0 assertEquals(distances.getValue(0, 1), 13d / 6); // should be 13d/6
308  0 assertEquals(distances.getValue(1, 0), 13d / 6);
309   
310    /*
311    * exclude gaps
312    * score = 3 + 3 + 0 + 0 + 0 + 0 = 6/6
313    */
314  0 params = new SimilarityParams(true, true, false, true);
315  0 distances = sm.findDistances(view, params);
316  0 assertEquals(distances.getValue(0, 1), 6d / 6);// should be 6d/6
317    }
318   
319    /**
320    * <pre>
321    * Set up
322    * column 1 2 3 4 5 6
323    * seq s1 F R - K - S
324    * seq s2 F S - - L
325    * s1 chain c c c c
326    * s1 domain d d d d
327    * s2 chain c c c
328    * s2 metal m m m
329    * s2 Pfam P P P
330    * scores: 3 3 0 2 3 2
331    * </pre>
332    *
333    * @return
334    */
 
335  0 toggle protected AlignFrame setupAlignmentView()
336    {
337    /*
338    * for now, using space for gap to match callers of
339    * AlignmentView.getSequenceStrings()
340    * may change this to '-' (with corresponding change to matrices)
341    */
342  0 SequenceI s1 = new Sequence("s1", "FR K S");
343  0 SequenceI s2 = new Sequence("s2", "FS L");
344   
345  0 s1.addSequenceFeature(
346    new SequenceFeature("chain", null, 1, 4, 0f, null));
347  0 s1.addSequenceFeature(
348    new SequenceFeature("domain", null, 1, 4, 0f, null));
349  0 s2.addSequenceFeature(
350    new SequenceFeature("chain", null, 1, 3, 0f, null));
351  0 s2.addSequenceFeature(
352    new SequenceFeature("metal", null, 1, 3, 0f, null));
353  0 s2.addSequenceFeature(
354    new SequenceFeature("Pfam", null, 1, 3, 0f, null));
355  0 AlignmentI al = new Alignment(new SequenceI[] { s1, s2 });
356  0 AlignFrame af = new AlignFrame(al, 300, 300);
357  0 af.setShowSeqFeatures(true);
358  0 af.getFeatureRenderer().findAllFeatures(true);
359  0 return af;
360    }
361   
362    }