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