JAL-2403 JAL-1483 changes to ScoreModelI hierarchy and signatures to
[jalview.git] / test / jalview / analysis / scoremodels / FeatureDistanceModelTest.java
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.datamodel.AlignmentI;
27 import jalview.datamodel.SequenceFeature;
28 import jalview.datamodel.SequenceI;
29 import jalview.gui.AlignFrame;
30 import jalview.gui.JvOptionPane;
31 import jalview.io.DataSourceType;
32 import jalview.io.FileLoader;
33 import jalview.math.MatrixI;
34
35 import java.util.Arrays;
36
37 import org.testng.Assert;
38 import org.testng.annotations.BeforeClass;
39 import org.testng.annotations.Test;
40
41 public class FeatureDistanceModelTest
42 {
43
44   @BeforeClass(alwaysRun = true)
45   public void setUpJvOptionPane()
46   {
47     JvOptionPane.setInteractiveMode(false);
48     JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
49   }
50
51   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";
52
53   int[] sf1 = new int[] { 74, 74, 73, 73, 23, 23, -1, -1 };
54
55   int[] sf2 = new int[] { -1, -1, 74, 75, -1, -1, 76, 77 };
56
57   int[] sf3 = new int[] { -1, -1, -1, -1, -1, -1, 76, 77 };
58
59   /**
60    * <pre>
61    * Load test alignment and add features to sequences: 
62    *      FER1_MESCR FER1_SPIOL FER3_RAPSA FER1_MAIZE 
63    *  sf1     X          X          X  
64    *  sf2                X                     X 
65    *  sf3                                      X
66    * </pre>
67    * 
68    * @return
69    */
70   public AlignFrame getTestAlignmentFrame()
71   {
72     AlignFrame alf = new FileLoader(false).LoadFileWaitTillLoaded(
73             alntestFile, DataSourceType.PASTE);
74     AlignmentI al = alf.getViewport().getAlignment();
75     Assert.assertEquals(al.getHeight(), 4);
76     Assert.assertEquals(al.getWidth(), 5);
77     for (int i = 0; i < 4; i++)
78     {
79       SequenceI ds = al.getSequenceAt(i).getDatasetSequence();
80       if (sf1[i * 2] > 0)
81       {
82         ds.addSequenceFeature(new SequenceFeature("sf1", "sf1", "sf1",
83                 sf1[i * 2], sf1[i * 2 + 1], "sf1"));
84       }
85       if (sf2[i * 2] > 0)
86       {
87         ds.addSequenceFeature(new SequenceFeature("sf2", "sf2", "sf2",
88                 sf2[i * 2], sf2[i * 2 + 1], "sf2"));
89       }
90       if (sf3[i * 2] > 0)
91       {
92         ds.addSequenceFeature(new SequenceFeature("sf3", "sf3", "sf3",
93                 sf3[i * 2], sf3[i * 2 + 1], "sf3"));
94       }
95     }
96     alf.setShowSeqFeatures(true);
97     alf.getFeatureRenderer().setVisible("sf1");
98     alf.getFeatureRenderer().setVisible("sf2");
99     alf.getFeatureRenderer().setVisible("sf3");
100     alf.getFeatureRenderer().findAllFeatures(true);
101     Assert.assertEquals(alf.getFeatureRenderer().getDisplayedFeatureTypes()
102             .size(), 3, "Number of feature types");
103     assertTrue(alf.getCurrentView().areFeaturesDisplayed());
104     return alf;
105   }
106
107   @Test(groups = { "Functional" })
108   public void testFeatureScoreModel() throws Exception
109   {
110     AlignFrame alf = getTestAlignmentFrame();
111     FeatureDistanceModel fsm = new FeatureDistanceModel();
112     assertTrue(fsm.configureFromAlignmentView(alf.getCurrentView()
113             .getAlignPanel()));
114     alf.selectAllSequenceMenuItem_actionPerformed(null);
115
116     MatrixI dm = fsm
117             .findDistances(alf.getViewport().getAlignmentView(
118             true));
119     assertEquals(dm.getValue(0, 2), 0d,
120             "FER1_MESCR (0) should be identical with RAPSA (2)");
121     assertTrue(dm.getValue(0, 1) > dm.getValue(0, 2),
122             "FER1_MESCR (0) should be further from SPIOL (1) than it is from RAPSA (2)");
123   }
124
125   @Test(groups = { "Functional" })
126   public void testFeatureScoreModel_hiddenFirstColumn() throws Exception
127   {
128     AlignFrame alf = getTestAlignmentFrame();
129     // hiding first two columns shouldn't affect the tree
130     alf.getViewport().hideColumns(0, 1);
131     FeatureDistanceModel fsm = new FeatureDistanceModel();
132     assertTrue(fsm.configureFromAlignmentView(alf.getCurrentView()
133             .getAlignPanel()));
134     alf.selectAllSequenceMenuItem_actionPerformed(null);
135     MatrixI dm = fsm
136             .findDistances(alf.getViewport().getAlignmentView(
137             true));
138     assertEquals(dm.getValue(0, 2), 0d,
139             "FER1_MESCR (0) should be identical with RAPSA (2)");
140     assertTrue(dm.getValue(0, 1) > dm.getValue(0, 2),
141             "FER1_MESCR (0) should be further from SPIOL (1) than it is from RAPSA (2)");
142   }
143
144   @Test(groups = { "Functional" })
145   public void testFeatureScoreModel_HiddenColumns() throws Exception
146   {
147     AlignFrame alf = getTestAlignmentFrame();
148     // hide columns and check tree changes
149     alf.getViewport().hideColumns(3, 4);
150     alf.getViewport().hideColumns(0, 1);
151     FeatureDistanceModel fsm = new FeatureDistanceModel();
152     assertTrue(fsm.configureFromAlignmentView(alf.getCurrentView()
153             .getAlignPanel()));
154     alf.selectAllSequenceMenuItem_actionPerformed(null);
155     MatrixI dm = fsm
156             .findDistances(alf.getViewport().getAlignmentView(
157             true));
158     assertEquals(
159             dm.getValue(0, 2),
160             0d,
161             "After hiding last two columns FER1_MESCR (0) should still be identical with RAPSA (2)");
162     assertEquals(
163             dm.getValue(0, 1),
164             0d,
165             "After hiding last two columns FER1_MESCR (0) should now also be identical with SPIOL (1)");
166     for (int s = 0; s < 3; s++)
167     {
168       assertTrue(dm.getValue(s, 3) > 0d, "After hiding last two columns "
169               + alf.getViewport().getAlignment().getSequenceAt(s).getName()
170               + "(" + s + ") should still be distinct from FER1_MAIZE (3)");
171     }
172   }
173
174   /**
175    * Check findFeatureAt doesn't return contact features except at contact
176    * points TODO:move to under the FeatureRendererModel test suite
177    */
178   @Test(groups = { "Functional" })
179   public void testFindFeatureAt_PointFeature() throws Exception
180   {
181     String alignment = "a CCCCCCGGGGGGCCCCCC\n" + "b CCCCCCGGGGGGCCCCCC\n"
182             + "c CCCCCCGGGGGGCCCCCC\n";
183     AlignFrame af = new jalview.io.FileLoader(false)
184             .LoadFileWaitTillLoaded(alignment, DataSourceType.PASTE);
185     SequenceI aseq = af.getViewport().getAlignment().getSequenceAt(0);
186     SequenceFeature sf = null;
187     sf = new SequenceFeature("disulphide bond", "", 2, 5, Float.NaN, "");
188     aseq.addSequenceFeature(sf);
189     assertTrue(sf.isContactFeature());
190     af.refreshFeatureUI(true);
191     af.getFeatureRenderer().setAllVisible(Arrays.asList("disulphide bond"));
192     Assert.assertEquals(af.getFeatureRenderer().getDisplayedFeatureTypes()
193             .size(), 1, "Should be just one feature type displayed");
194     // step through and check for pointwise feature presence/absence
195     Assert.assertEquals(af.getFeatureRenderer().findFeaturesAtRes(aseq, 1)
196             .size(), 0);
197     // step through and check for pointwise feature presence/absence
198     Assert.assertEquals(af.getFeatureRenderer().findFeaturesAtRes(aseq, 2)
199             .size(), 1);
200     // step through and check for pointwise feature presence/absence
201     Assert.assertEquals(af.getFeatureRenderer().findFeaturesAtRes(aseq, 3)
202             .size(), 0);
203     // step through and check for pointwise feature presence/absence
204     Assert.assertEquals(af.getFeatureRenderer().findFeaturesAtRes(aseq, 4)
205             .size(), 0);
206     // step through and check for pointwise feature presence/absence
207     Assert.assertEquals(af.getFeatureRenderer().findFeaturesAtRes(aseq, 5)
208             .size(), 1);
209     // step through and check for pointwise feature presence/absence
210     Assert.assertEquals(af.getFeatureRenderer().findFeaturesAtRes(aseq, 6)
211             .size(), 0);
212   }
213
214   @Test(groups = { "Functional" })
215   public void testFindDistances() throws Exception
216   {
217     String seqs = ">s1\nABCDE\n>seq2\nABCDE\n";
218     AlignFrame alf = new FileLoader().LoadFileWaitTillLoaded(seqs,
219             DataSourceType.PASTE);
220     SequenceI s1 = alf.getViewport().getAlignment().getSequenceAt(0);
221     SequenceI s2 = alf.getViewport().getAlignment().getSequenceAt(1);
222
223     /*
224      * set domain and variant features thus:
225      *     ----5
226      *  s1 ddd..
227      *  s1 .vvv.
228      *  s1 ..vvv    
229      *  s2 .ddd. 
230      *  s2 vv..v
231      *  The number of unshared feature types per column is
232      *     20120 (two features of the same type doesn't affect score)
233      *  giving an average (pairwise distance) of 5/5 or 1.0 
234      */
235     s1.addSequenceFeature(new SequenceFeature("domain", null, 1, 3, 0f,
236             null));
237     s1.addSequenceFeature(new SequenceFeature("variant", null, 2, 4, 0f,
238             null));
239     s1.addSequenceFeature(new SequenceFeature("variant", null, 3, 5, 0f,
240             null));
241     s2.addSequenceFeature(new SequenceFeature("domain", null, 2, 4, 0f,
242             null));
243     s2.addSequenceFeature(new SequenceFeature("variant", null, 1, 2, 0f,
244             null));
245     s2.addSequenceFeature(new SequenceFeature("variant", null, 5, 5, 0f,
246             null));
247     alf.setShowSeqFeatures(true);
248     alf.getFeatureRenderer().findAllFeatures(true);
249
250     FeatureDistanceModel fsm = new FeatureDistanceModel();
251     assertTrue(fsm.configureFromAlignmentView(alf.getCurrentView()
252             .getAlignPanel()));
253     alf.selectAllSequenceMenuItem_actionPerformed(null);
254
255     MatrixI distances = fsm.findDistances(alf.getViewport()
256             .getAlignmentView(true));
257     assertEquals(distances.width(), 2);
258     assertEquals(distances.height(), 2);
259     assertEquals(distances.getValue(0, 0), 0d);
260     assertEquals(distances.getValue(1, 1), 0d);
261     // these left to fail pending resolution of
262     // JAL-2424 (dividing score by 6, not 5)
263     assertEquals(distances.getValue(0, 1), 1f);
264     assertEquals(distances.getValue(1, 0), 1f);
265   }
266
267 }