cb308744c3dbbfb3d4c20a7048608a0b282dbb03
[jalview.git] / test / jalview / io / ScoreMatrixFileTest.java
1 package jalview.io;
2
3 import static org.testng.Assert.assertEquals;
4 import static org.testng.Assert.assertFalse;
5 import static org.testng.Assert.assertNotNull;
6 import static org.testng.Assert.assertNull;
7 import static org.testng.Assert.assertTrue;
8 import static org.testng.Assert.fail;
9
10 import jalview.analysis.scoremodels.ScoreMatrix;
11
12 import java.io.IOException;
13 import java.net.MalformedURLException;
14
15 import org.testng.annotations.Test;
16
17 public class ScoreMatrixFileTest
18 {
19
20   /**
21    * Test a successful parse of a (small) score matrix file
22    * 
23    * @throws IOException
24    * @throws MalformedURLException
25    */
26   @Test(groups = "Functional")
27   public void testParse() throws MalformedURLException, IOException
28   {
29     /*
30      * some messy but valid input data, with comma, space
31      * or tab (or combinations) as score value delimiters
32      * this example includes 'guide' symbols on score rows
33      */
34     String data = "ScoreMatrix MyTest (example)\n" + "A\tT\tU\tt\tx\t-\n"
35             + "A,1.1,1.2,1.3,1.4, 1.5, 1.6\n"
36             + "T,2.1 2.2 2.3 2.4 2.5 2.6\n"
37             + "U\t3.1\t3.2\t3.3\t3.4\t3.5\t3.6\t\n"
38             + "t, 5.1,5.3,5.3,5.4,5.5, 5.6\n"
39             + "x\t6.1, 6.2 6.3 6.4 6.5 6.6\n"
40             + "-, \t7.1\t7.2 7.3, 7.4, 7.5\t,7.6\n";
41     FileParse fp = new FileParse(data, DataSourceType.PASTE);
42     ScoreMatrixFile parser = new ScoreMatrixFile(fp);
43     ScoreMatrix sm = parser.parseMatrix();
44
45     assertNotNull(sm);
46     assertEquals(sm.getName(), "MyTest (example)");
47     assertEquals(sm.getSize(), 6);
48     assertNull(sm.getDescription());
49     assertTrue(sm.isDNA());
50     assertFalse(sm.isProtein());
51     assertEquals(sm.getPairwiseScore('A', 'A'), 1.1f);
52     assertEquals(sm.getPairwiseScore('A', 'T'), 1.2f);
53     assertEquals(sm.getPairwiseScore('a', 'T'), 1.2f); // A/a equivalent
54     assertEquals(sm.getPairwiseScore('A', 't'), 1.4f); // T/t not equivalent
55     assertEquals(sm.getPairwiseScore('a', 't'), 1.4f);
56     assertEquals(sm.getPairwiseScore('U', 'x'), 3.5f);
57     assertEquals(sm.getPairwiseScore('u', 'x'), 3.5f);
58     assertEquals(sm.getPairwiseScore('U', 'X'), 0f); // X (upper) unmapped
59     assertEquals(sm.getPairwiseScore('A', '.'), 0f); // . unmapped
60     assertEquals(sm.getPairwiseScore('-', '-'), 7.6f);
61     assertEquals(sm.getPairwiseScore('A', (char) 128), 0f); // out of range
62   }
63
64   @Test(groups = "Functional")
65   public void testParse_headerMissing()
66   {
67     String data;
68
69     data = "X Y\n1 2\n3 4\n";
70     try
71     {
72       new ScoreMatrixFile(new FileParse(data, DataSourceType.PASTE))
73               .parseMatrix();
74       fail("expected exception");
75     } catch (IOException e)
76     {
77       assertEquals(e.getMessage(),
78               "Format error: 'ScoreMatrix <name>' should be the first non-comment line");
79     }
80   }
81
82   @Test(groups = "Functional")
83   public void testParse_notEnoughRows()
84   {
85     String data = "ScoreMatrix MyTest\nX Y\n1 2\n";
86     try
87     {
88       new ScoreMatrixFile(new FileParse(data, DataSourceType.PASTE))
89               .parseMatrix();
90       fail("expected exception");
91     } catch (IOException e)
92     {
93       assertEquals(e.getMessage(),
94               "Expected 2 rows of score data in score matrix but only found 1");
95     }
96   }
97
98   @Test(groups = "Functional")
99   public void testParse_notEnoughColumns()
100   {
101     String data = "ScoreMatrix MyTest\nX Y\n1 2\n3\n";
102     try
103     {
104       new ScoreMatrixFile(new FileParse(data, DataSourceType.PASTE))
105               .parseMatrix();
106       fail("expected exception");
107     } catch (IOException e)
108     {
109       assertEquals(e.getMessage(),
110               "Expected 2 scores at line 4 but found 1");
111     }
112   }
113
114   @Test(groups = "Functional")
115   public void testParse_tooManyColumns()
116   {
117     /*
118      * with two too many columns:
119      */
120     String data = "ScoreMatrix MyTest\nX\tY\n1 2\n3 4 5 6\n";
121     try
122     {
123       new ScoreMatrixFile(new FileParse(data, DataSourceType.PASTE))
124               .parseMatrix();
125       fail("expected exception");
126     } catch (IOException e)
127     {
128       assertEquals(e.getMessage(),
129               "Expected 2 scores at line 4 but found 4");
130     }
131
132     /*
133      * with guide character and one too many columns:
134      */
135     data = "ScoreMatrix MyTest\nX Y\nX 1 2\nY 3 4 5\n";
136     try
137     {
138       new ScoreMatrixFile(new FileParse(data, DataSourceType.PASTE))
139               .parseMatrix();
140       fail("expected exception");
141     } catch (IOException e)
142     {
143       assertEquals(e.getMessage(),
144               "Expected 2 scores at line 4 but found 4");
145     }
146
147     /*
148      * with no guide character and one too many columns:
149      * parser guesses the first column is the guide character
150      */
151     data = "ScoreMatrix MyTest\nX Y\n1 2\n3 4 5\n";
152     try
153     {
154       new ScoreMatrixFile(new FileParse(data, DataSourceType.PASTE))
155               .parseMatrix();
156       fail("expected exception");
157     } catch (IOException e)
158     {
159       assertEquals(e.getMessage(),
160               "Error parsing score matrix at line 4, expected 'Y' but found '3'");
161     }
162   }
163
164   @Test(groups = "Functional")
165   public void testParse_tooManyRows()
166   {
167     String data = "ScoreMatrix MyTest\n\tX\tY\n1 2\n3 4\n6 7";
168     try
169     {
170       new ScoreMatrixFile(new FileParse(data, DataSourceType.PASTE))
171               .parseMatrix();
172       fail("expected exception");
173     } catch (IOException e)
174     {
175       assertEquals(e.getMessage(),
176               "Unexpected extra input line in score model file: '6 7'");
177     }
178   }
179
180   @Test(groups = "Functional")
181   public void testParse_badDelimiter()
182   {
183     String data = "ScoreMatrix MyTest\n X Y Z\n1|2|3\n4|5|6\n";
184     try
185     {
186       new ScoreMatrixFile(new FileParse(data, DataSourceType.PASTE))
187               .parseMatrix();
188       fail("expected exception");
189     } catch (IOException e)
190     {
191       assertEquals(e.getMessage(),
192               "Invalid score value '1|2|3' at line 3 column 0");
193     }
194   }
195
196   @Test(groups = "Functional")
197   public void testParse_badFloat()
198   {
199     String data = "ScoreMatrix MyTest\n\tX\tY\n1 2\n3 four\n";
200     try
201     {
202       new ScoreMatrixFile(new FileParse(data, DataSourceType.PASTE))
203               .parseMatrix();
204       fail("expected exception");
205     } catch (IOException e)
206     {
207       assertEquals(e.getMessage(),
208               "Invalid score value 'four' at line 4 column 1");
209     }
210   }
211
212   @Test(groups = "Functional")
213   public void testParse_badGuideCharacter()
214   {
215     String data = "ScoreMatrix MyTest\n\tX Y\nX 1 2\ny 3 4\n";
216     try
217     {
218       new ScoreMatrixFile(new FileParse(data, DataSourceType.PASTE))
219               .parseMatrix();
220       fail("expected exception");
221     } catch (IOException e)
222     {
223       assertEquals(e.getMessage(),
224               "Error parsing score matrix at line 4, expected 'Y' but found 'y'");
225     }
226   }
227
228   @Test(groups = "Functional")
229   public void testParse_nameMissing()
230   {
231     /*
232      * Name missing
233      */
234     String data = "ScoreMatrix\nX Y\n1 2\n3 4\n";
235     try
236     {
237       new ScoreMatrixFile(new FileParse(data, DataSourceType.PASTE))
238               .parseMatrix();
239       fail("expected exception");
240     } catch (IOException e)
241     {
242       assertEquals(
243               e.getMessage(),
244               "Format error: expected 'ScoreMatrix <name>', found 'ScoreMatrix' at line 1");
245     }
246   }
247
248   /**
249    * Test a successful parse of a (small) score matrix file
250    * 
251    * @throws IOException
252    * @throws MalformedURLException
253    */
254   @Test(groups = "Functional")
255   public void testParse_ncbiFormat() throws MalformedURLException,
256           IOException
257   {
258     String data = "ScoreMatrix MyTest\n" + "\tA\tB\tC\n"
259             + "A\t1.0\t2.0\t3.0\n" + "B\t4.0\t5.0\t6.0\n"
260             + "C\t7.0\t8.0\t9.0\n";
261     FileParse fp = new FileParse(data, DataSourceType.PASTE);
262     ScoreMatrixFile parser = new ScoreMatrixFile(fp);
263     ScoreMatrix sm = parser.parseMatrix();
264   
265     assertNotNull(sm);
266     assertEquals(sm.getName(), "MyTest");
267     assertEquals(sm.getPairwiseScore('A', 'A'), 1.0f);
268     assertEquals(sm.getPairwiseScore('B', 'c'), 6.0f);
269     assertEquals(sm.getSize(), 3);
270   }
271
272   /**
273    * Test a successful parse of a (small) score matrix file
274    * 
275    * @throws IOException
276    * @throws MalformedURLException
277    */
278   @Test(groups = "Functional")
279   public void testParse_aaIndexBlosum80() throws MalformedURLException,
280           IOException
281   {
282     FileParse fp = new FileParse("resources/scoreModel/blosum80.scm",
283             DataSourceType.FILE);
284     ScoreMatrixFile parser = new ScoreMatrixFile(fp);
285     ScoreMatrix sm = parser.parseMatrix();
286   
287     assertNotNull(sm);
288     assertEquals(sm.getName(), "HENS920103");
289     assertEquals(sm.getDescription(),
290             "BLOSUM80 substitution matrix (Henikoff-Henikoff, 1992)");
291     assertFalse(sm.isDNA());
292     assertTrue(sm.isProtein());
293     assertEquals(20, sm.getSize());
294     assertEquals(sm.getGapIndex(), -1);
295
296     assertEquals(sm.getPairwiseScore('A', 'A'), 7f);
297     assertEquals(sm.getPairwiseScore('A', 'R'), -3f);
298     assertEquals(sm.getPairwiseScore('r', 'a'), -3f); // A/a equivalent
299   }
300 }