82f5c83453be2978dea2580217dd0405f8f69d94
[jalview.git] / test / MCview / PDBfileTest.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 MCview;
22
23 import static org.testng.AssertJUnit.assertEquals;
24 import static org.testng.AssertJUnit.assertFalse;
25 import static org.testng.AssertJUnit.assertNull;
26 import static org.testng.AssertJUnit.assertSame;
27 import static org.testng.AssertJUnit.assertTrue;
28
29 import jalview.datamodel.Alignment;
30 import jalview.datamodel.AlignmentAnnotation;
31 import jalview.datamodel.AlignmentI;
32 import jalview.datamodel.PDBEntry;
33 import jalview.datamodel.Sequence;
34 import jalview.datamodel.SequenceI;
35 import jalview.io.AppletFormatAdapter;
36
37 import java.io.IOException;
38 import java.util.List;
39
40 import org.testng.annotations.Test;
41
42 public class PDBfileTest
43 {
44   @Test(groups = { "Functional" })
45   public void testIsRna()
46   {
47     SequenceI seq = new Sequence("Seq1", "CGAU");
48     assertTrue(PDBfile.isRNA(seq));
49
50     seq.setSequence("CGAu");
51     assertFalse(PDBfile.isRNA(seq));
52
53     seq.setSequence("CGAT");
54     assertFalse(PDBfile.isRNA(seq));
55
56     seq.setSequence("GRSWYFLAVM");
57     assertFalse(PDBfile.isRNA(seq));
58   }
59
60   /**
61    * Test the 'high level' outputs of parsing. More detailed tests in
62    * PDBChainTest.
63    * 
64    * @throws IOException
65    */
66   @Test(groups = { "Functional" })
67   public void testParse() throws IOException
68   {
69     /*
70      * Constructor with file path performs parse()
71      */
72     PDBfile pf = new PDBfile(false, false, false, "examples/3W5V.pdb",
73             AppletFormatAdapter.FILE);
74
75     assertEquals("3W5V", pf.id);
76     // verify no alignment annotations created
77     assertNull(getAlignmentAnnotations(pf));
78
79     assertEquals(4, pf.chains.size());
80     assertEquals("A", pf.chains.get(0).id);
81     assertEquals("B", pf.chains.get(1).id);
82     assertEquals("C", pf.chains.get(2).id);
83     assertEquals("D", pf.chains.get(3).id);
84
85     PDBChain chainA = pf.chains.get(0);
86     assertEquals(0, chainA.seqstart); // not set
87     assertEquals(0, chainA.seqend); // not set
88     assertEquals(18, chainA.sequence.getStart());
89     assertEquals(314, chainA.sequence.getEnd());
90     assertTrue(chainA.sequence.getSequenceAsString().startsWith("KCSKKQEE"));
91     assertTrue(chainA.sequence.getSequenceAsString().endsWith("WNVEVY"));
92     assertEquals("3W5V|A", chainA.sequence.getName());
93     assertNull(chainA.sequence.getAnnotation());
94     assertEquals(1, chainA.sequence.getAllPDBEntries().size());
95     PDBEntry pdb = chainA.sequence.getAllPDBEntries().get(0);
96     assertEquals("A", pdb.getChainCode());
97     assertEquals("PDB", pdb.getType());
98     assertEquals("3W5V", pdb.getId());
99
100     PDBChain chainB = pf.chains.get(1);
101     assertEquals(1, chainB.sequence.getStart());
102     assertEquals(96, chainB.sequence.getEnd());
103     assertTrue(chainB.sequence.getSequenceAsString().startsWith("ATYNVK"));
104     assertTrue(chainB.sequence.getSequenceAsString().endsWith("KEEELT"));
105     assertEquals("3W5V|B", chainB.sequence.getName());
106
107     PDBChain chainC = pf.chains.get(2);
108     assertEquals(18, chainC.sequence.getStart());
109     assertEquals(314, chainC.sequence.getEnd());
110     assertTrue(chainC.sequence.getSequenceAsString().startsWith("KCSKKQEE"));
111     assertTrue(chainC.sequence.getSequenceAsString().endsWith("WNVEVY"));
112     assertEquals("3W5V|C", chainC.sequence.getName());
113
114     PDBChain chainD = pf.chains.get(3);
115     assertEquals(1, chainD.sequence.getStart());
116     assertEquals(96, chainD.sequence.getEnd());
117     assertTrue(chainD.sequence.getSequenceAsString().startsWith("ATYNVK"));
118     assertTrue(chainD.sequence.getSequenceAsString().endsWith("KEEELT"));
119     assertEquals("3W5V|D", chainD.sequence.getName());
120
121     /*
122      * verify PDB-related data in parsed sequences
123      */
124     List<SequenceI> seqs = pf.getSeqs();
125     assertEquals(4, seqs.size());
126     assertEquals("3W5V|A", seqs.get(0).getName());
127     assertEquals("3W5V|B", seqs.get(1).getName());
128     assertEquals("3W5V|C", seqs.get(2).getName());
129     assertEquals("3W5V|D", seqs.get(3).getName());
130     assertEquals(1, seqs.get(0).getAllPDBEntries().size());
131     PDBEntry pdbe = seqs.get(0).getAllPDBEntries().get(0);
132     assertEquals("A", pdbe.getChainCode());
133     assertEquals("3W5V", pdbe.getId());
134     assertEquals(PDBEntry.Type.PDB.toString(), pdbe.getType());
135   }
136
137   /**
138    * Test parsing, with annotations added to the alignment but no secondary
139    * structure prediction
140    * 
141    * @throws IOException
142    */
143   @Test(groups = { "Functional" })
144   public void testParse_withAnnotations_noSS() throws IOException
145   {
146     PDBfile pf = new PDBfile(true, false, false, "examples/3W5V.pdb",
147             AppletFormatAdapter.FILE);
148
149     AlignmentAnnotation[] anns = getAlignmentAnnotations(pf);
150     assertEquals(4, anns.length);
151
152     /*
153      * Inspect temp factor annotation for chain A
154      */
155     AlignmentAnnotation chainAnnotation = anns[0];
156     assertEquals("Temperature Factor", chainAnnotation.label);
157     // PDBChain constructor changes PDB id to lower case (why?)
158     assertEquals("Temperature Factor for 3w5vA",
159             chainAnnotation.description);
160     assertSame(pf.getSeqs().get(0), chainAnnotation.sequenceRef);
161     assertEquals(AlignmentAnnotation.LINE_GRAPH, chainAnnotation.graph);
162     assertEquals(0f, chainAnnotation.graphMin, 0.001f);
163     assertEquals(40f, chainAnnotation.graphMax, 0.001f);
164     assertEquals(297, chainAnnotation.annotations.length);
165     assertEquals(40f, chainAnnotation.annotations[0].value, 0.001f);
166
167     /*
168      * Chain B temp factor
169      */
170     chainAnnotation = anns[1];
171     assertEquals("Temperature Factor for 3w5vB",
172             chainAnnotation.description);
173     assertSame(pf.getSeqs().get(1), chainAnnotation.sequenceRef);
174     assertEquals(96, chainAnnotation.annotations.length);
175
176     /*
177      * Chain C temp factor
178      */
179     chainAnnotation = anns[2];
180     assertEquals("Temperature Factor for 3w5vC",
181             chainAnnotation.description);
182     assertSame(pf.getSeqs().get(2), chainAnnotation.sequenceRef);
183     assertEquals(297, chainAnnotation.annotations.length);
184
185     /*
186      * Chain D temp factor
187      */
188     chainAnnotation = anns[3];
189     assertEquals("Temperature Factor for 3w5vD",
190             chainAnnotation.description);
191     assertSame(pf.getSeqs().get(3), chainAnnotation.sequenceRef);
192     assertEquals(96, chainAnnotation.annotations.length);
193   }
194
195   /**
196    * Test parsing including secondary structure annotation using JMol; this test
197    * for the case where flag to add annotations to alignment is set false
198    * 
199    * @throws IOException
200    */
201   @Test(groups = { "Functional" })
202   public void testParse_withJmol_noAnnotations() throws IOException
203   {
204     PDBfile pf = new PDBfile(false, true, false, "examples/3W5V.pdb",
205             AppletFormatAdapter.FILE);
206
207     /*
208      * alignment annotations _are_ created anyway (in
209      * AlignSeq.replaceMatchingSeqsWith())
210      */
211     final AlignmentAnnotation[] anns = getAlignmentAnnotations(pf);
212     assertEquals(4, anns.length);
213
214     /*
215      * no sequence annotations created - tempFactor annotation is not added
216      * unless the flag to 'addAlignmentAnnotations' is set true
217      */
218     for (PDBChain c : pf.chains)
219     {
220       assertNull(c.sequence.getAnnotation());
221     }
222   }
223
224   /**
225    * Test parsing including secondary structure prediction and annotation using
226    * JMol
227    * 
228    * @throws IOException
229    */
230   @Test(groups = { "Functional" })
231   public void testParse_withJmolAddAlignmentAnnotations()
232           throws IOException
233   {
234     PDBfile pf = new PDBfile(true, true, false, "examples/3W5V.pdb",
235             AppletFormatAdapter.FILE);
236
237     /*
238      * Alignment annotations for TempFactor, SecStruct, per sequence (chain)
239      */
240     AlignmentAnnotation[] anns = getAlignmentAnnotations(pf);
241     assertEquals(8, anns.length);
242
243     /*
244      * other tests have detailed assertions for Temp Factor annotations
245      */
246     assertEquals("Temperature Factor for 3w5vA", anns[1].description);
247     assertEquals("Temperature Factor for 3w5vB", anns[3].description);
248     assertEquals("Temperature Factor for 3w5vC", anns[5].description);
249     assertEquals("Temperature Factor for 3w5vD", anns[7].description);
250
251     /*
252      * PDBFileWithJmol (unlike PDBChain!) leaves PDB id upper case
253      */
254     assertEquals("Secondary Structure for 3W5VA", anns[0].description);
255     assertEquals("Secondary Structure for 3W5VB", anns[2].description);
256     assertEquals("Secondary Structure for 3W5VC", anns[4].description);
257     assertEquals("Secondary Structure for 3W5VD", anns[6].description);
258
259     /*
260      * Verify SS annotations are linked to respective sequences (chains)
261      */
262     assertSame(pf.getSeqs().get(0), anns[0].sequenceRef);
263     assertSame(pf.getSeqs().get(1), anns[2].sequenceRef);
264     assertSame(pf.getSeqs().get(2), anns[4].sequenceRef);
265     assertSame(pf.getSeqs().get(3), anns[6].sequenceRef);
266
267     /*
268      * Verify a sample of SS predictions
269      */
270     for (int i = 0; i < 20; i++)
271     {
272       assertNull(anns[0].annotations[i]);
273       assertEquals("E", anns[0].annotations[20].displayCharacter);
274       assertEquals('E', anns[0].annotations[20].secondaryStructure);
275       assertEquals("E", anns[2].annotations[18].displayCharacter);
276       assertEquals("H", anns[2].annotations[23].displayCharacter);
277     }
278   }
279
280   /**
281    * Placeholder for a test of parsing RNA structure with secondary structure
282    * prediction using the Annotate3D service
283    * 
284    * @throws IOException
285    */
286
287   @Test(groups = { "Functional" }, enabled = false)
288   public void testParse_withAnnotate3D() throws IOException
289   {
290     // TODO requires a mock for Annotate3D processing
291     // and/or run as an integration test
292     PDBfile pf = new PDBfile(true, true, true, "examples/2GIS.pdb",
293             AppletFormatAdapter.FILE);
294   }
295
296   /**
297    * Helper method to extract parsed annotations from the PDBfile
298    * 
299    * @param pf
300    * @return
301    */
302   private AlignmentAnnotation[] getAlignmentAnnotations(PDBfile pf)
303   {
304     AlignmentI al = new Alignment(pf.getSeqsAsArray());
305     pf.addAnnotations(al);
306     return al.getAlignmentAnnotation();
307   }
308 }