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