JAL-4386 - Implementation of substitution matrix and test cases.
[jalview.git] / test / jalview / analysis / scoremodels / SecondaryStructureDistanceModelTest.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.api.analysis.ScoreModelI;
27 import jalview.api.analysis.SimilarityParamsI;
28 import jalview.datamodel.Alignment;
29 import jalview.datamodel.AlignmentAnnotation;
30 import jalview.datamodel.AlignmentI;
31 import jalview.datamodel.AlignmentView;
32 import jalview.datamodel.Annotation;
33 import jalview.datamodel.Sequence;
34 import jalview.datamodel.SequenceFeature;
35 import jalview.datamodel.SequenceI;
36 import jalview.gui.AlignFrame;
37 import jalview.gui.AlignViewport;
38 import jalview.gui.JvOptionPane;
39 import jalview.io.DataSourceType;
40 import jalview.io.FileLoader;
41 import jalview.math.MatrixI;
42
43 import org.testng.Assert;
44 import org.testng.annotations.BeforeClass;
45 import org.testng.annotations.DataProvider;
46 import org.testng.annotations.Test;
47
48 // This class tests methods in Class SecondaryStructureDistanceModel 
49 public class SecondaryStructureDistanceModelTest
50 {
51   
52   /**
53    * Verify computed distances of sequences with gap
54    */
55   @Test(groups = "Functional")
56   public void testFindDistances_withGap()
57   {
58     AlignFrame af = setupAlignmentViewWithGap();
59     AlignViewport viewport = af.getViewport();
60     AlignmentView view = viewport.getAlignmentView(false);
61
62     ScoreModelI sm = new SecondaryStructureDistanceModel();
63     sm = ScoreModels.getInstance().getScoreModel(sm.getName(),
64             af.alignPanel);
65     
66     /*
67      * feature distance model always normalises by region width
68      * gap-gap is always included (but scores zero)
69      * the only variable parameter is 'includeGaps'
70      */
71
72     /*
73      * include gaps
74      * score = 0 + 0 + 1 + 0 = 1/4
75      */
76     SimilarityParamsI params = new SimilarityParams(false, true, true, true);
77     params.setSecondaryStructureSource("3D Structures");
78     MatrixI distances = sm.findDistances(view, params);
79     assertEquals(distances.getValue(0, 0), 0d);
80     assertEquals(distances.getValue(1, 1), 0d);
81     assertEquals(distances.getValue(0, 1), 1d/4); 
82     assertEquals(distances.getValue(1, 0), 1d/4);
83     
84     /*
85      * exclude gaps
86      * score = 0 + 0 + 0 + 0 = 0/4
87      */
88     
89     SimilarityParamsI params2 = new SimilarityParams(false, true, false, true);
90     MatrixI distances2 = sm.findDistances(view, params2);
91     assertEquals(distances2.getValue(0, 1), 0d); 
92     assertEquals(distances2.getValue(1, 0), 0d);
93   }
94   
95   
96   /**
97    * Verify computed distances of sequences with gap
98    */
99   @Test(groups = "Functional")
100   public void testFindDistances_withSSUndefinedInEitherOneSeq()
101   {
102     AlignFrame af = setupAlignmentViewWithoutSS("either");
103     AlignViewport viewport = af.getViewport();
104     AlignmentView view = viewport.getAlignmentView(false);
105
106     ScoreModelI sm = new SecondaryStructureDistanceModel();
107     sm = ScoreModels.getInstance().getScoreModel(sm.getName(),
108             af.alignPanel);
109     
110     /*
111      * feature distance model always normalises by region width
112      * gap-gap is always included (but scores zero)
113      * the only variable parameter is 'includeGaps'
114      */
115
116     /*
117      * include gaps
118      * score = 0 + 0 + 2 + 2 = 2/4
119      */
120     SimilarityParamsI params = new SimilarityParams(false, true, true, true);
121     params.setSecondaryStructureSource("3D Structures");
122     MatrixI distances = sm.findDistances(view, params);
123     assertEquals(distances.getValue(0, 0), 0d);
124     assertEquals(distances.getValue(1, 1), 0d);
125     assertEquals(distances.getValue(0, 1), 2d); 
126     assertEquals(distances.getValue(1, 0), 2d);
127     
128     /*
129      * exclude gaps
130      * score = 0 + 0 + 2 + 2 = 2/4
131      */
132     
133     SimilarityParamsI params2 = new SimilarityParams(false, true, false, true);
134     params2.setSecondaryStructureSource("3D Structures");
135     MatrixI distances2 = sm.findDistances(view, params2);
136     assertEquals(distances2.getValue(0, 1), 2d); 
137     assertEquals(distances2.getValue(1, 0), 2d);
138   }
139
140   
141   /**
142    * Verify computed distances of sequences with gap
143    */
144   @Test(groups = "Functional")
145   public void testFindDistances_withSSUndefinedInBothSeqs()
146   {
147     AlignFrame af = setupAlignmentViewWithoutSS("both");
148     AlignViewport viewport = af.getViewport();
149     AlignmentView view = viewport.getAlignmentView(false);
150
151     ScoreModelI sm = new SecondaryStructureDistanceModel();
152     sm = ScoreModels.getInstance().getScoreModel(sm.getName(),
153             af.alignPanel);
154     
155     /*
156      * feature distance model always normalises by region width
157      * gap-gap is always included (but scores zero)
158      * the only variable parameter is 'includeGaps'
159      */
160
161     /*
162      * include gaps
163      * score = 0 + 0 + 2 + 2 = 2/4
164      */
165     SimilarityParamsI params = new SimilarityParams(false, true, true, true);
166     params.setSecondaryStructureSource("3D Structures");
167     MatrixI distances = sm.findDistances(view, params);
168     assertEquals(distances.getValue(0, 0), 0d);
169     assertEquals(distances.getValue(1, 1), 0d);
170     assertEquals(distances.getValue(0, 1), 0d); 
171     assertEquals(distances.getValue(1, 0), 0d);
172     
173     /*
174      * exclude gaps
175      * score = 0 + 0 + 2 + 2 = 2/4
176      */
177     
178     SimilarityParamsI params2 = new SimilarityParams(false, true, false, true);
179     params2.setSecondaryStructureSource("3D Structures");
180     MatrixI distances2 = sm.findDistances(view, params2);
181     assertEquals(distances2.getValue(0, 1), 0d); 
182     assertEquals(distances2.getValue(1, 0), 0d);
183   }
184
185
186   
187   /**
188    * <pre>
189    * Set up
190    *   column      1 2 3 4 
191    *        seq s1 F R K S
192    *        
193    *        seq s2 F S J L
194    * </pre>
195    * 
196    * @return
197    */
198   protected AlignFrame setupAlignmentView(String similar)
199   {
200     /*
201      * sequences without gaps
202      */
203     SequenceI s1 = new Sequence("s1", "FRKS");
204     SequenceI s2 = new Sequence("s2", "FSJL");
205
206     s1.addSequenceFeature(
207             new SequenceFeature("chain", null, 1, 4, 0f, null));
208     s1.addSequenceFeature(
209             new SequenceFeature("domain", null, 1, 4, 0f, null));
210     s2.addSequenceFeature(
211             new SequenceFeature("chain", null, 1, 4, 0f, null));
212     s2.addSequenceFeature(
213             new SequenceFeature("metal", null, 1, 4, 0f, null));
214     s2.addSequenceFeature(
215             new SequenceFeature("Pfam", null, 1, 4, 0f, null));
216     
217     
218     /*
219      * Set up secondary structure annotations
220      */
221     Annotation ssE = new Annotation("","",'E',0);
222     Annotation ssH = new Annotation("","",'H',0);
223     Annotation ssC = new Annotation(".","",' ',0);
224     
225     Annotation[] anns1;
226     Annotation[] anns2;
227     
228     /* All secondary structure annotations are similar for each column
229      * Set up
230     *   column      1 2 3 4 
231     *        seq s1 F R K S
232     *            ss E H S E
233     *        
234     *        seq s2 F S J L
235     *            ss E H S E
236     */
237     if(similar == "All Similar") {
238     
239         anns1 = new Annotation[] { ssE, ssH, ssC, ssE};
240         anns2 = new Annotation[] { ssE, ssH, ssC, ssE};
241     
242     }
243     
244     /* All secondary structure annotations are dissimilar for each column
245      * Set up
246      *   column      1 2 3 4 
247      *        seq s1 F R K S
248      *            ss E E C E
249      *        
250      *        seq s2 F S J L
251      *            ss H E E C
252      */
253     else if(similar == "Not Similar") {
254         
255         anns1 = new Annotation[] { ssE, ssE, ssC, ssE};
256         anns2 = new Annotation[] { ssH, ssH, ssE, ssC};
257     
258     }
259     
260     /* All secondary structure annotations are dissimilar for each column
261      * Set up
262      *   column      1 2 3 4 
263      *        seq s1 F R K S
264      *            ss E E C E
265      *        
266      *        seq s2 F S J L
267      *            ss H E E C
268      */
269     else if(similar == "With Coil") {
270         
271       anns1 = new Annotation[] { ssE, ssE, null, ssE};
272       anns2 = new Annotation[] { ssH, ssH, ssE, null};
273     
274     }
275     
276     /*  Set up
277      *   column      1 2 3 4 
278      *        seq s1 F R K S
279      *            ss H E C E
280      *        
281      *        seq s2 F S J L
282      *            ss H E E C
283      */
284     else {
285         
286         anns1 = new Annotation[] { ssH, ssE, ssC, ssE};
287         anns2 = new Annotation[] { ssH, ssE, ssE, ssC};
288     }
289     
290     
291     AlignmentAnnotation ann1 = new AlignmentAnnotation("Secondary Structure",
292             "Secondary Structure", anns1);
293     AlignmentAnnotation ann2 = new AlignmentAnnotation("Secondary Structure",
294             "Secondary Structure", anns2);
295     
296     s1.addAlignmentAnnotation(ann1);
297     s2.addAlignmentAnnotation(ann2);    
298     
299     AlignmentI al = new Alignment(new SequenceI[] { s1, s2 });
300     AlignFrame af = new AlignFrame(al, 300, 300);
301     af.setShowSeqFeatures(true);
302     af.getFeatureRenderer().findAllFeatures(true);
303     return af;
304   }
305   
306
307   /**
308    * <pre>
309    * Set up
310    *   column      1 2 3 4 
311    *        seq s1 F R   S
312    *              SS H E   C
313    *        
314    *        seq s2 F S J L
315    *              ss H E E C
316    * </pre>
317    * 
318    * @return
319    */
320   protected AlignFrame setupAlignmentViewWithGap()
321   {
322     
323     SequenceI s1 = new Sequence("s1", "FR S");
324     SequenceI s2 = new Sequence("s2", "FSJL");
325
326     s1.addSequenceFeature(
327             new SequenceFeature("chain", null, 1, 3, 0f, null));
328     s1.addSequenceFeature(
329             new SequenceFeature("domain", null, 1, 3, 0f, null));
330     s2.addSequenceFeature(
331             new SequenceFeature("chain", null, 1, 4, 0f, null));
332     s2.addSequenceFeature(
333             new SequenceFeature("metal", null, 1, 4, 0f, null));
334     s2.addSequenceFeature(
335             new SequenceFeature("Pfam", null, 1, 4, 0f, null));
336     
337     
338     Annotation ssE = new Annotation("","",'E',0);
339     Annotation ssH = new Annotation("","",'H',0);
340     Annotation ssC = new Annotation(".","",' ',0);
341     
342     Annotation[] anns1;
343     Annotation[] anns2;
344         
345     anns1 = new Annotation[] { ssH, ssE, ssC};
346     anns2 = new Annotation[] { ssH, ssE, ssE, ssC};    
347     
348     AlignmentAnnotation ann1 = new AlignmentAnnotation("Secondary Structure",
349             "Secondary Structure", anns1);
350     AlignmentAnnotation ann2 = new AlignmentAnnotation("Secondary Structure",
351             "Secondary Structure", anns2);
352     
353     s1.addAlignmentAnnotation(ann1);
354     s2.addAlignmentAnnotation(ann2);    
355         
356     AlignmentI al = new Alignment(new SequenceI[] { s1, s2 });
357     AlignFrame af = new AlignFrame(al, 300, 300);
358     af.setShowSeqFeatures(true);
359     af.getFeatureRenderer().findAllFeatures(true);
360     
361     return af;
362   }
363   
364   protected AlignFrame setupAlignmentViewWithoutSS(String type) {
365     
366     SequenceI s1 = new Sequence("s1", "FR S");
367     SequenceI s2 = new Sequence("s2", "FSJL");
368     
369     s1.addSequenceFeature(
370             new SequenceFeature("chain", null, 1, 3, 0f, null));
371     s1.addSequenceFeature(
372             new SequenceFeature("domain", null, 1, 3, 0f, null));
373     s2.addSequenceFeature(
374             new SequenceFeature("chain", null, 1, 4, 0f, null));
375     s2.addSequenceFeature(
376             new SequenceFeature("metal", null, 1, 4, 0f, null));
377     s2.addSequenceFeature(
378             new SequenceFeature("Pfam", null, 1, 4, 0f, null));
379     
380     if(!type.equals("both")) {    
381       Annotation ssE = new Annotation("","",'E',0);
382       Annotation ssH = new Annotation("","",'H',0);
383       Annotation ssC = new Annotation(".","",' ',0);
384       
385       Annotation[] anns1;
386         
387       anns1 = new Annotation[] { ssH, ssE, ssC};
388           
389       AlignmentAnnotation ann1 = new AlignmentAnnotation("Secondary Structure",
390               "Secondary Structure", anns1);    
391   
392       s1.addAlignmentAnnotation(ann1);    
393     }
394     
395     AlignmentI al = new Alignment(new SequenceI[] { s1, s2 });
396     AlignFrame af = new AlignFrame(al, 300, 300);
397     af.setShowSeqFeatures(true);
398     af.getFeatureRenderer().findAllFeatures(true);
399     return af;
400   }
401   
402   
403   @DataProvider(name = "testData")
404   public Object[][] testData() {
405       return new Object[][] {
406               {"All Similar", 0d, 0d, 0d, 0d / 4},
407               {"Partially Similar", 0d, 0d, 1d, 1d},
408               {"Not Similar", 0d, 0d, 2d, 2d},
409               {"With Coil", 0d, 0d, 2d, 2d},
410       };
411   }
412
413   @Test(dataProvider = "testData")
414   public void testFindDistances(String scenario, double expectedValue00, double expectedValue11,
415                                  double expectedValue01, double expectedValue10) {
416       AlignFrame af = setupAlignmentView(scenario);
417       AlignViewport viewport = af.getViewport();
418       AlignmentView view = viewport.getAlignmentView(false);
419
420       ScoreModelI sm = new SecondaryStructureDistanceModel();
421       sm = ScoreModels.getInstance().getScoreModel(sm.getName(),
422               af.alignPanel);
423
424       SimilarityParamsI params = new SimilarityParams(false, true, true, true);
425       params.setSecondaryStructureSource("3D Structures");
426       MatrixI distances = sm.findDistances(view, params);
427
428       assertEquals(distances.getValue(0, 0), expectedValue00);
429       assertEquals(distances.getValue(1, 1), expectedValue11);
430       assertEquals(distances.getValue(0, 1), expectedValue01);
431       assertEquals(distances.getValue(1, 0), expectedValue10);
432   }
433
434   
435 }