JAL-3070 use ArgumentI in all public constructors, convert to service specific argume...
[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.Jalview2XML;
30 import jalview.gui.JvOptionPane;
31 import jalview.io.AnnotationFile;
32 import jalview.io.DataSourceType;
33 import jalview.io.FileFormat;
34 import jalview.io.FormatAdapter;
35 import jalview.io.StockholmFileTest;
36 import jalview.ws.jws2.JabaParamStore;
37 import jalview.ws.jws2.Jws2Discoverer;
38 import jalview.ws.jws2.RNAalifoldClient;
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   jalview.ws.jws2.RNAalifoldClient 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 RNAalifoldClient(rnaalifoldws, af, null, null);
159
160     af.getViewport().getCalcManager().startWorker(alifoldClient);
161
162     do
163     {
164       try
165       {
166         Thread.sleep(50);
167       } catch (InterruptedException x)
168       {
169       }
170     } while (af.getViewport().getCalcManager().isWorking());
171
172     AlignmentI orig_alig = af.getViewport().getAlignment();
173     for (AlignmentAnnotation aa : orig_alig.getAlignmentAnnotation())
174     {
175       if (alifoldClient.involves(aa))
176       {
177         if (aa.isRNA())
178         {
179           assertTrue(
180                   "Did not create valid structure from RNAALiFold prediction",
181                   aa.isValidStruc());
182         }
183       }
184     }
185   }
186
187   @Test(groups = { "Network" })
188   public void testRNAStructExport()
189   {
190
191     alifoldClient = new RNAalifoldClient(rnaalifoldws, af, null, null);
192
193     af.getViewport().getCalcManager().startWorker(alifoldClient);
194
195     do
196     {
197       try
198       {
199         Thread.sleep(50);
200       } catch (InterruptedException x)
201       {
202       }
203     } while (af.getViewport().getCalcManager().isWorking());
204
205     AlignmentI orig_alig = af.getViewport().getAlignment();
206     // JBPNote: this assert fails (2.10.2) because the 'Reference Positions'
207     // annotation is mistakenly recognised as an RNA annotation row when read in
208     // as an annotation file.
209     verifyAnnotationFileIO("Testing RNAalifold Annotation IO", orig_alig);
210
211   }
212
213   static void verifyAnnotationFileIO(String testname, AlignmentI al)
214   {
215     try
216     {
217       // what format would be appropriate for RNAalifold annotations?
218       String aligfileout = FileFormat.Pfam.getWriter(null).print(
219               al.getSequencesArray(), true);
220
221       String anfileout = new AnnotationFile()
222               .printAnnotationsForAlignment(al);
223       assertNotNull(
224               "Test "
225                       + testname
226                       + "\nAlignment annotation file was not regenerated. Null string",
227               anfileout);
228       assertTrue(
229               "Test "
230                       + testname
231                       + "\nAlignment annotation file was not regenerated. Empty string",
232               anfileout.length() > "JALVIEW_ANNOTATION".length());
233
234       System.out.println("Output annotation file:\n" + anfileout
235               + "\n<<EOF\n");
236
237       // again what format would be appropriate?
238       AlignmentI al_new = new FormatAdapter().readFile(aligfileout,
239               DataSourceType.PASTE, FileFormat.Pfam);
240       assertTrue(
241               "Test "
242                       + testname
243                       + "\nregenerated annotation file did not annotate alignment.",
244               new AnnotationFile().readAnnotationFile(al_new, anfileout,
245                       DataSourceType.PASTE));
246
247       // test for consistency in io
248       StockholmFileTest.testAlignmentEquivalence(al, al_new, false, false,
249               false);
250       return;
251     } catch (Exception e)
252     {
253       e.printStackTrace();
254     }
255     Assert.fail("Test "
256             + testname
257             + "\nCouldn't complete Annotation file roundtrip input/output/input test.");
258   }
259
260   @Test(groups = { "Network" })
261   public void testRnaalifoldSettingsRecovery()
262   {
263     List<Argument> opts = new ArrayList<>();
264     for (Argument rg : (List<Argument>) rnaalifoldws.getRunnerConfig()
265             .getArguments())
266     {
267       if (rg.getDescription().contains("emperature"))
268       {
269         try
270         {
271           rg.setValue("292");
272         } catch (WrongParameterException q)
273         {
274           Assert.fail("Couldn't set the temperature parameter "
275                   + q.getStackTrace());
276         }
277         opts.add(rg);
278       }
279       if (rg.getDescription().contains("max"))
280       {
281         opts.add(rg);
282       }
283     }
284     alifoldClient = new RNAalifoldClient(rnaalifoldws, af, null,
285             JabaParamStore.getJwsArgsfromJaba(opts));
286
287     af.getViewport().getCalcManager().startWorker(alifoldClient);
288
289     do
290     {
291       try
292       {
293         Thread.sleep(50);
294       } catch (InterruptedException x)
295       {
296       }
297       ;
298     } while (af.getViewport().getCalcManager().isWorking());
299     AutoCalcSetting oldacs = af.getViewport().getCalcIdSettingsFor(
300             alifoldClient.getCalcId());
301     String oldsettings = oldacs.getWsParamFile();
302     // write out parameters
303     jalview.gui.AlignFrame nalf = null;
304     assertTrue("Couldn't write out the Jar file",
305             new Jalview2XML(false).saveAlignment(af, JAR_FILE_NAME,
306                     "trial parameter writeout"));
307     assertTrue("Couldn't read back the Jar file", (nalf = new Jalview2XML(
308             false).loadJalviewAlign(JAR_FILE_NAME)) != null);
309     if (nalf != null)
310     {
311       AutoCalcSetting acs = af.getViewport().getCalcIdSettingsFor(
312               alifoldClient.getCalcId());
313       assertTrue("Calc ID settings not recovered from viewport stash",
314               acs.equals(oldacs));
315       assertTrue(
316               "Serialised Calc ID settings not identical to those recovered from viewport stash",
317               acs.getWsParamFile().equals(oldsettings));
318       JMenu nmenu = new JMenu();
319       new SequenceAnnotationWSClient().attachWSMenuEntry(nmenu,
320               rnaalifoldws, af);
321       assertTrue("Couldn't get menu entry for service",
322               nmenu.getItemCount() > 0);
323       for (Component itm : nmenu.getMenuComponents())
324       {
325         if (itm instanceof JMenuItem)
326         {
327           JMenuItem i = (JMenuItem) itm;
328           if (i.getText().equals(
329                   rnaalifoldws.getAlignAnalysisUI().getAAconToggle()))
330           {
331             i.doClick();
332             break;
333           }
334         }
335       }
336       while (af.getViewport().isCalcInProgress())
337       {
338         try
339         {
340           Thread.sleep(200);
341         } catch (Exception x)
342         {
343         }
344         ;
345       }
346       AutoCalcSetting acs2 = af.getViewport().getCalcIdSettingsFor(
347               alifoldClient.getCalcId());
348       assertTrue(
349               "Calc ID settings after recalculation has not been recovered.",
350               acs2.getWsParamFile().equals(oldsettings));
351     }
352   }
353 }