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