4af80863f79a71116354a39cc2573dcad6e591a7
[jalview.git] / test / jalview / ws / jabaws / RNAStructExportImport.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.ws.jabaws;
22
23 import static org.testng.AssertJUnit.assertNotNull;
24 import static org.testng.AssertJUnit.assertTrue;
25
26 import jalview.bin.Cache;
27 import jalview.datamodel.AlignmentAnnotation;
28 import jalview.datamodel.AlignmentI;
29 import jalview.gui.JvOptionPane;
30 import jalview.io.AnnotationFile;
31 import jalview.io.DataSourceType;
32 import jalview.io.FileFormat;
33 import jalview.io.FormatAdapter;
34 import jalview.io.StockholmFileTest;
35 import jalview.project.Jalview2XML;
36 import jalview.ws.jws2.AbstractJabaCalcWorker;
37 import jalview.ws.jws2.JabaParamStore;
38 import jalview.ws.jws2.Jws2Discoverer;
39 import jalview.ws.jws2.SequenceAnnotationWSClient;
40 import jalview.ws.jws2.jabaws2.Jws2Instance;
41 import jalview.ws.params.AutoCalcSetting;
42
43 import java.awt.Component;
44 import java.io.File;
45 import java.util.ArrayList;
46 import java.util.List;
47
48 import javax.swing.JMenu;
49 import javax.swing.JMenuItem;
50
51 import org.testng.Assert;
52 import org.testng.annotations.AfterClass;
53 import org.testng.annotations.BeforeClass;
54 import org.testng.annotations.Test;
55
56 import compbio.metadata.Argument;
57 import compbio.metadata.WrongParameterException;
58
59 /*
60  * All methods in this class are set to the Network group because setUpBeforeClass will fail
61  * if there is no network.
62  */
63 @Test(singleThreaded = true)
64 public class RNAStructExportImport
65 {
66
67   @BeforeClass(alwaysRun = true)
68   public void setUpJvOptionPane()
69   {
70     JvOptionPane.setInteractiveMode(false);
71     JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
72   }
73
74   private static final String JAR_FILE_NAME = "testRnalifold_param.jar";
75
76   public static String testseqs = "examples/RF00031_folded.stk";
77
78   public static Jws2Discoverer disc;
79
80   public static Jws2Instance rnaalifoldws;
81
82   AbstractJabaCalcWorker alifoldClient;
83
84   public static jalview.gui.AlignFrame af = null;
85
86   @BeforeClass(alwaysRun = true)
87   public static void setUpBeforeClass() throws Exception
88   {
89     Cache.loadProperties("test/jalview/io/testProps.jvprops");
90     Cache.initLogger();
91     disc = JalviewJabawsTestUtils.getJabawsDiscoverer(false);
92
93     while (disc.isRunning())
94     {
95       // don't get services until discoverer has finished
96       Thread.sleep(100);
97     }
98
99     for (Jws2Instance svc : disc.getServices())
100     {
101
102       if (svc.getNameURI().toLowerCase().contains("rnaalifoldws"))
103       {
104         rnaalifoldws = svc;
105       }
106     }
107
108     System.out.println("State of rnaalifoldws: " + rnaalifoldws);
109
110     if (rnaalifoldws == null)
111     {
112       Assert.fail("no web service");
113     }
114
115     jalview.io.FileLoader fl = new jalview.io.FileLoader(false);
116
117     af = fl.LoadFileWaitTillLoaded(testseqs, jalview.io.DataSourceType.FILE);
118
119     assertNotNull("Couldn't load test data ('" + testseqs + "')", af);
120
121     // remove any existing annotation
122     List<AlignmentAnnotation> aal = new ArrayList<>();
123     for (AlignmentAnnotation rna : af.getViewport().getAlignment()
124             .getAlignmentAnnotation())
125     {
126       if (rna.isRNA())
127       {
128         aal.add(rna);
129       }
130     }
131     for (AlignmentAnnotation rna : aal)
132     {
133       af.getViewport().getAlignment().deleteAnnotation(rna);
134     }
135     af.getViewport().alignmentChanged(af.alignPanel); // why is af.alignPanel
136                                                       // public?
137   }
138
139   @AfterClass(alwaysRun = true)
140   public static void tearDownAfterClass() throws Exception
141   {
142     if (af != null)
143     {
144       af.setVisible(false);
145       af.dispose();
146       File f = new File(JAR_FILE_NAME);
147       if (f.exists())
148       {
149         f.delete();
150       }
151     }
152   }
153
154   @Test(groups = { "Network" })
155   public void testRNAAliFoldValidStructure()
156   {
157
158     alifoldClient = new AbstractJabaCalcWorker(rnaalifoldws, af, null,
159             null);
160
161     af.getViewport().getCalcManager().startWorker(alifoldClient);
162
163     do
164     {
165       try
166       {
167         Thread.sleep(50);
168       } catch (InterruptedException x)
169       {
170       }
171     } while (af.getViewport().getCalcManager().isWorking());
172
173     AlignmentI orig_alig = af.getViewport().getAlignment();
174     for (AlignmentAnnotation aa : orig_alig.getAlignmentAnnotation())
175     {
176       if (alifoldClient.involves(aa))
177       {
178         if (aa.isRNA())
179         {
180           assertTrue(
181                   "Did not create valid structure from RNAALiFold prediction",
182                   aa.isValidStruc());
183         }
184       }
185     }
186   }
187
188   @Test(groups = { "Network" })
189   public void testRNAStructExport()
190   {
191
192     alifoldClient = new AbstractJabaCalcWorker(rnaalifoldws, af, null,
193             null);
194
195     af.getViewport().getCalcManager().startWorker(alifoldClient);
196
197     do
198     {
199       try
200       {
201         Thread.sleep(50);
202       } catch (InterruptedException x)
203       {
204       }
205     } while (af.getViewport().getCalcManager().isWorking());
206
207     AlignmentI orig_alig = af.getViewport().getAlignment();
208     // JBPNote: this assert fails (2.10.2) because the 'Reference Positions'
209     // annotation is mistakenly recognised as an RNA annotation row when read in
210     // as an annotation file. bug is JAL-3122
211     verifyAnnotationFileIO("Testing RNAalifold Annotation IO", orig_alig);
212
213   }
214
215   static void verifyAnnotationFileIO(String testname, AlignmentI al)
216   {
217     try
218     {
219       // what format would be appropriate for RNAalifold annotations?
220       String aligfileout = FileFormat.Pfam.getWriter(null).print(
221               al.getSequencesArray(), true);
222
223       String anfileout = new AnnotationFile()
224               .printAnnotationsForAlignment(al);
225       assertNotNull(
226               "Test "
227                       + testname
228                       + "\nAlignment annotation file was not regenerated. Null string",
229               anfileout);
230       assertTrue(
231               "Test "
232                       + testname
233                       + "\nAlignment annotation file was not regenerated. Empty string",
234               anfileout.length() > "JALVIEW_ANNOTATION".length());
235
236       System.out.println("Output annotation file:\n" + anfileout
237               + "\n<<EOF\n");
238
239       // again what format would be appropriate?
240       AlignmentI al_new = new FormatAdapter().readFile(aligfileout,
241               DataSourceType.PASTE, FileFormat.Pfam);
242       assertTrue(
243               "Test "
244                       + testname
245                       + "\nregenerated annotation file did not annotate alignment.",
246               new AnnotationFile().readAnnotationFile(al_new, anfileout,
247                       DataSourceType.PASTE));
248
249       // test for consistency in io
250       StockholmFileTest.testAlignmentEquivalence(al, al_new, false, false,
251               false);
252       return;
253     } catch (Exception e)
254     {
255       e.printStackTrace();
256     }
257     Assert.fail("Test "
258             + testname
259             + "\nCouldn't complete Annotation file roundtrip input/output/input test.");
260   }
261
262   @Test(groups = { "Network" })
263   public void testRnaalifoldSettingsRecovery()
264   {
265     List<Argument> opts = new ArrayList<>();
266     for (Argument rg : (List<Argument>) rnaalifoldws.getRunnerConfig()
267             .getArguments())
268     {
269       if (rg.getDescription().contains("emperature"))
270       {
271         try
272         {
273           rg.setValue("292");
274         } catch (WrongParameterException q)
275         {
276           Assert.fail("Couldn't set the temperature parameter "
277                   + q.getStackTrace());
278         }
279         opts.add(rg);
280       }
281       if (rg.getDescription().contains("max"))
282       {
283         opts.add(rg);
284       }
285     }
286     alifoldClient = new AbstractJabaCalcWorker(rnaalifoldws, af, null,
287             JabaParamStore.getJwsArgsfromJaba(opts));
288
289     af.getViewport().getCalcManager().startWorker(alifoldClient);
290
291     do
292     {
293       try
294       {
295         Thread.sleep(50);
296       } catch (InterruptedException x)
297       {
298       }
299       ;
300     } while (af.getViewport().getCalcManager().isWorking());
301     AutoCalcSetting oldacs = af.getViewport().getCalcIdSettingsFor(
302             alifoldClient.getCalcId());
303     String oldsettings = oldacs.getWsParamFile();
304     // write out parameters
305     jalview.gui.AlignFrame nalf = null;
306     assertTrue("Couldn't write out the Jar file",
307             new Jalview2XML(false).saveAlignment(af, JAR_FILE_NAME,
308                     "trial parameter writeout"));
309     assertTrue("Couldn't read back the Jar file", (nalf = new Jalview2XML(
310             false).loadJalviewAlign(JAR_FILE_NAME)) != null);
311     if (nalf != null)
312     {
313       AutoCalcSetting acs = af.getViewport().getCalcIdSettingsFor(
314               alifoldClient.getCalcId());
315       assertTrue("Calc ID settings not recovered from viewport stash",
316               acs.equals(oldacs));
317       assertTrue(
318               "Serialised Calc ID settings not identical to those recovered from viewport stash",
319               acs.getWsParamFile().equals(oldsettings));
320       JMenu nmenu = new JMenu();
321       new SequenceAnnotationWSClient().attachWSMenuEntry(nmenu,
322               rnaalifoldws, af);
323       assertTrue("Couldn't get menu entry for service",
324               nmenu.getItemCount() > 0);
325       for (Component itm : nmenu.getMenuComponents())
326       {
327         if (itm instanceof JMenuItem)
328         {
329           JMenuItem i = (JMenuItem) itm;
330           if (i.getText().equals(
331                   rnaalifoldws.getAlignAnalysisUI().getAAconToggle()))
332           {
333             i.doClick();
334             break;
335           }
336         }
337       }
338       while (af.getViewport().isCalcInProgress())
339       {
340         try
341         {
342           Thread.sleep(200);
343         } catch (Exception x)
344         {
345         }
346         ;
347       }
348       AutoCalcSetting acs2 = af.getViewport().getCalcIdSettingsFor(
349               alifoldClient.getCalcId());
350       assertTrue(
351               "Calc ID settings after recalculation has not been recovered.",
352               acs2.getWsParamFile().equals(oldsettings));
353     }
354   }
355 }