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