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