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