Merge branch 'apifix/JAL-1926_JAL-2106' into develop
[jalview.git] / test / jalview / io / AnnotatedPDBFileInputTest.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 jalview.io;
22
23 import static org.testng.AssertJUnit.assertEquals;
24 import static org.testng.AssertJUnit.assertNotNull;
25 import static org.testng.AssertJUnit.assertTrue;
26
27 import jalview.bin.Cache;
28 import jalview.datamodel.AlignmentAnnotation;
29 import jalview.datamodel.AlignmentI;
30 import jalview.datamodel.PDBEntry;
31 import jalview.datamodel.SequenceFeature;
32 import jalview.datamodel.SequenceI;
33 import jalview.gui.AlignFrame;
34 import jalview.structure.StructureImportSettings;
35 import jalview.structure.StructureImportSettings.StructureParser;
36
37 import java.io.File;
38
39 import org.testng.annotations.AfterClass;
40 import org.testng.annotations.BeforeClass;
41 import org.testng.annotations.BeforeMethod;
42 import org.testng.annotations.Test;
43
44 public class AnnotatedPDBFileInputTest
45 {
46
47   AlignmentI al;
48
49   String pdbId;
50
51   /**
52    * Ensure 'process secondary structure from PDB and add annotations' are set
53    * in preferences, and load PDB example file 1gaq
54    * 
55    * @throws Exception
56    */
57   @BeforeMethod(alwaysRun = true)
58   public void setup() throws Exception
59   {
60     Cache.applicationProperties.setProperty("STRUCT_FROM_PDB",
61             Boolean.TRUE.toString());
62     Cache.applicationProperties.setProperty("ADD_SS_ANN",
63             Boolean.TRUE.toString());
64     FileLoader loader = new FileLoader(false);
65     AlignFrame af = loader.LoadFileWaitTillLoaded("examples/1gaq.txt",
66             FormatAdapter.FILE);
67     al = af.getViewport().getAlignment();
68     pdbId = al.getSequenceAt(0).getDatasetSequence().getAllPDBEntries()
69             .get(0).getId();
70     StructureImportSettings.setDefaultStructureFileFormat("PDB");
71     StructureImportSettings
72             .setDefaultPDBFileParser(StructureParser.JALVIEW_PARSER);
73   }
74
75   @Test(groups = { "Functional" })
76   public void checkNoDuplicates()
77   {
78     // not strictly a requirement, but strange things may happen if multiple
79     // instances of the same annotation are placed in the alignment annotation
80     // vector
81     assertNotNull(al.getAlignmentAnnotation());
82     // verify that all sequence annotation is doubly referenced
83     AlignmentAnnotation[] avec = al.getAlignmentAnnotation();
84     for (int p = 0; p < avec.length; p++)
85     {
86       for (int q = p + 1; q < avec.length; q++)
87       {
88         assertTrue("Found a duplicate annotation row "
89                 + avec[p].label, avec[p] != avec[q]);
90       }
91     }
92   }
93
94   @Test(groups = { "Functional" })
95   public void checkPDBannotationSource()
96   {
97
98     for (SequenceI asq : al.getSequences())
99     {
100       for (AlignmentAnnotation aa : asq.getAnnotation())
101       {
102
103         System.out.println("CalcId: " + aa.getCalcId());
104         assertTrue(MCview.PDBfile.isCalcIdForFile(aa, pdbId));
105       }
106     }
107   }
108
109   /**
110    * Check sequence features have been added
111    */
112   @Test(groups = { "Functional" })
113   public void checkPDBSequenceFeatures()
114   {
115     /*
116      * 1GAQ/A
117      */
118     SequenceFeature[] sf = al.getSequenceAt(0).getSequenceFeatures();
119     assertEquals(296, sf.length);
120     assertEquals("RESNUM", sf[0].getType());
121     assertEquals("GLU:  19  1gaqA", sf[0].getDescription());
122     assertEquals("RESNUM", sf[295].getType());
123     assertEquals("TYR: 314  1gaqA", sf[295].getDescription());
124
125     /*
126      * 1GAQ/B
127      */
128     sf = al.getSequenceAt(1).getSequenceFeatures();
129     assertEquals(98, sf.length);
130     assertEquals("RESNUM", sf[0].getType());
131     assertEquals("ALA:   1  1gaqB", sf[0].getDescription());
132     assertEquals("RESNUM", sf[97].getType());
133     assertEquals("ALA:  98  1gaqB", sf[97].getDescription());
134
135     /*
136      * 1GAQ/C
137      */
138     sf = al.getSequenceAt(2).getSequenceFeatures();
139     assertEquals(296, sf.length);
140     assertEquals("RESNUM", sf[0].getType());
141     assertEquals("GLU:  19  1gaqC", sf[0].getDescription());
142     assertEquals("RESNUM", sf[295].getType());
143     assertEquals("TYR: 314  1gaqC", sf[295].getDescription());
144   }
145
146   @Test(groups = { "Functional" })
147   public void checkAnnotationWiring()
148   {
149     assertTrue(al.getAlignmentAnnotation() != null);
150     // verify that all sequence annotation is doubly referenced
151     for (AlignmentAnnotation aa : al.getAlignmentAnnotation())
152     {
153       if (aa.sequenceRef != null)
154       {
155         assertTrue(al.getSequences().contains(aa.sequenceRef));
156         assertNotNull(aa.sequenceRef.getAnnotation());
157         boolean found = false;
158         for (AlignmentAnnotation sqan : aa.sequenceRef.getAnnotation())
159         {
160           if (sqan == aa)
161           {
162             found = true;
163             break;
164           }
165         }
166         assertTrue(
167                 "Couldn't find sequence associated annotation "
168                         + aa.label
169                         + " on the sequence it is associated with.\nSequence associated editing will fail.",
170                 found);
171       }
172     }
173   }
174
175   /**
176    * @throws java.lang.Exception
177    */
178   @BeforeClass(alwaysRun = true)
179   public static void setUpBeforeClass() throws Exception
180   {
181     jalview.bin.Jalview.main(new String[] { "-props",
182         "test/jalview/io/testProps.jvprops" });
183   }
184
185   /**
186    * @throws java.lang.Exception
187    */
188   @AfterClass(alwaysRun = true)
189   public static void tearDownAfterClass() throws Exception
190   {
191     jalview.gui.Desktop.instance.closeAll_actionPerformed(null);
192
193   }
194
195   @Test(groups = { "Functional" })
196   public void testJalviewProjectRelocationAnnotation() throws Exception
197   {
198
199     String inFile = "examples/1gaq.txt";
200     String tfile = File.createTempFile("JalviewTest", ".jvp")
201             .getAbsolutePath();
202     AlignFrame af = new jalview.io.FileLoader().LoadFileWaitTillLoaded(
203             inFile, FormatAdapter.FILE);
204     assertTrue("Didn't read input file " + inFile, af != null);
205     assertTrue("Failed to store as a project.",
206             af.saveAlignment(tfile, "Jalview"));
207     af.closeMenuItem_actionPerformed(true);
208     af = null;
209     af = new jalview.io.FileLoader().LoadFileWaitTillLoaded(tfile,
210             FormatAdapter.FILE);
211     assertTrue("Failed to import new project", af != null);
212     for (SequenceI asq : af.getViewport().getAlignment().getSequences())
213     {
214       SequenceI sq = asq;
215       while (sq.getDatasetSequence() != null)
216       {
217         sq = sq.getDatasetSequence();
218       }
219       assertNotNull(sq.getAllPDBEntries());
220       assertEquals("Expected only one PDB ID",
221               sq.getAllPDBEntries().size(), 1);
222       for (PDBEntry pdbentry : sq.getAllPDBEntries())
223       {
224         System.err.println("PDB Entry " + pdbentry.getId() + " "
225                 + pdbentry.getFile());
226         boolean exists = false, found = false;
227         for (AlignmentAnnotation ana : sq.getAnnotation())
228         {
229           System.err.println("CalcId " + ana.getCalcId());
230           if (ana.getCalcId() != null
231                   && MCview.PDBfile.isCalcIdHandled(ana.getCalcId()))
232           {
233             exists = true;
234             if (MCview.PDBfile.isCalcIdForFile(ana, pdbentry.getId()))
235             {
236               found = true;
237             }
238           }
239         }
240         if (exists)
241         {
242           assertTrue("Couldn't find any annotation for " + pdbentry.getId()
243                   + " (file handle " + pdbentry.getFile() + ")", found);
244         }
245       }
246     }
247   }
248 }