cc9aba0444651201e63740388e93d03989dc4b7d
[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.datamodel.AlignmentAnnotation;
30 import jalview.datamodel.AlignmentI;
31 import jalview.gui.JvOptionPane;
32 import jalview.io.AnnotationFile;
33 import jalview.io.DataSourceType;
34 import jalview.io.FileFormat;
35 import jalview.io.FormatAdapter;
36 import jalview.io.StockholmFileTest;
37 import jalview.project.Jalview2XML;
38 import jalview.ws.jws2.Jws2Discoverer;
39 import jalview.ws.jws2.RNAalifoldClient;
40 import jalview.ws.jws2.SequenceAnnotationWSClient;
41 import jalview.ws.jws2.jabaws2.Jws2Instance;
42 import jalview.ws.params.AutoCalcSetting;
43
44 import java.awt.Component;
45 import java.io.File;
46 import java.util.ArrayList;
47 import java.util.List;
48
49 import javax.swing.JMenu;
50 import javax.swing.JMenuItem;
51
52 import org.testng.Assert;
53 import org.testng.annotations.AfterClass;
54 import org.testng.annotations.BeforeClass;
55 import org.testng.annotations.Test;
56
57 import compbio.metadata.Argument;
58 import compbio.metadata.WrongParameterException;
59
60 /*
61  * All methods in this class are set to the Network group because setUpBeforeClass will fail
62  * if there is no network.
63  */
64 @Test(singleThreaded = true)
65 public class RNAStructExportImport
66 {
67
68   @BeforeClass(alwaysRun = true)
69   public void setUpJvOptionPane()
70   {
71     JvOptionPane.setInteractiveMode(false);
72     JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
73   }
74
75   private static final String JAR_FILE_NAME = "testRnalifold_param.jar";
76
77   public static String testseqs = "examples/RF00031_folded.stk";
78
79   public static Jws2Discoverer disc;
80
81   public static Jws2Instance rnaalifoldws;
82
83   jalview.ws.jws2.RNAalifoldClient alifoldClient;
84
85   public static jalview.gui.AlignFrame af = null;
86
87   @BeforeClass(alwaysRun = true)
88   public static void setUpBeforeClass() throws Exception
89   {
90     Cache.loadProperties("test/jalview/io/testProps.jvprops");
91     Cache.initLogger();
92     disc = JalviewJabawsTestUtils.getJabawsDiscoverer(false);
93
94     while (disc.isRunning())
95     {
96       // don't get services until discoverer has finished
97       Thread.sleep(100);
98     }
99
100     for (Jws2Instance svc : disc.getServices())
101     {
102
103       if (svc.getServiceTypeURI().toLowerCase(Locale.ROOT).contains("rnaalifoldws"))
104       {
105         rnaalifoldws = svc;
106       }
107     }
108
109     System.out.println("State of rnaalifoldws: " + rnaalifoldws);
110
111     if (rnaalifoldws == null)
112     {
113       Assert.fail("no web service");
114     }
115
116     jalview.io.FileLoader fl = new jalview.io.FileLoader(false);
117
118     af = fl.LoadFileWaitTillLoaded(testseqs, jalview.io.DataSourceType.FILE);
119
120     assertNotNull("Couldn't load test data ('" + testseqs + "')", af);
121
122     // remove any existing annotation
123     List<AlignmentAnnotation> aal = new ArrayList<>();
124     for (AlignmentAnnotation rna : af.getViewport().getAlignment()
125             .getAlignmentAnnotation())
126     {
127       if (rna.isRNA())
128       {
129         aal.add(rna);
130       }
131     }
132     for (AlignmentAnnotation rna : aal)
133     {
134       af.getViewport().getAlignment().deleteAnnotation(rna);
135     }
136     af.getViewport().alignmentChanged(af.alignPanel); // why is af.alignPanel
137                                                       // public?
138   }
139
140   @AfterClass(alwaysRun = true)
141   public static void tearDownAfterClass() throws Exception
142   {
143     if (af != null)
144     {
145       af.setVisible(false);
146       af.dispose();
147       File f = new File(JAR_FILE_NAME);
148       if (f.exists())
149       {
150         f.delete();
151       }
152     }
153   }
154
155   @Test(groups = { "Network" })
156   public void testRNAAliFoldValidStructure()
157   {
158
159     alifoldClient = new RNAalifoldClient(rnaalifoldws, af, null, 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 RNAalifoldClient(rnaalifoldws, af, null, null);
193
194     af.getViewport().getCalcManager().startWorker(alifoldClient);
195
196     do
197     {
198       try
199       {
200         Thread.sleep(50);
201       } catch (InterruptedException x)
202       {
203       }
204     } while (af.getViewport().getCalcManager().isWorking());
205
206     AlignmentI orig_alig = af.getViewport().getAlignment();
207     // JBPNote: this assert fails (2.10.2) because the 'Reference Positions'
208     // annotation is mistakenly recognised as an RNA annotation row when read in
209     // as an annotation file.
210     verifyAnnotationFileIO("Testing RNAalifold Annotation IO", orig_alig);
211
212   }
213
214   static void verifyAnnotationFileIO(String testname, AlignmentI al)
215   {
216     try
217     {
218       // what format would be appropriate for RNAalifold annotations?
219       String aligfileout = FileFormat.Pfam.getWriter(null).print(
220               al.getSequencesArray(), true);
221
222       String anfileout = new AnnotationFile()
223               .printAnnotationsForAlignment(al);
224       assertNotNull(
225               "Test "
226                       + testname
227                       + "\nAlignment annotation file was not regenerated. Null string",
228               anfileout);
229       assertTrue(
230               "Test "
231                       + testname
232                       + "\nAlignment annotation file was not regenerated. Empty string",
233               anfileout.length() > "JALVIEW_ANNOTATION".length());
234
235       System.out.println("Output annotation file:\n" + anfileout
236               + "\n<<EOF\n");
237
238       // again what format would be appropriate?
239       AlignmentI al_new = new FormatAdapter().readFile(aligfileout,
240               DataSourceType.PASTE, FileFormat.Pfam);
241       assertTrue(
242               "Test "
243                       + testname
244                       + "\nregenerated annotation file did not annotate alignment.",
245               new AnnotationFile().readAnnotationFile(al_new, anfileout,
246                       DataSourceType.PASTE));
247
248       // test for consistency in io
249       StockholmFileTest.testAlignmentEquivalence(al, al_new, false, false,
250               false);
251       return;
252     } catch (Exception e)
253     {
254       e.printStackTrace();
255     }
256     Assert.fail("Test "
257             + testname
258             + "\nCouldn't complete Annotation file roundtrip input/output/input test.");
259   }
260
261   @Test(groups = { "Network" })
262   public void testRnaalifoldSettingsRecovery()
263   {
264     List<Argument> opts = new ArrayList<>();
265     for (Argument rg : (List<Argument>) rnaalifoldws.getRunnerConfig()
266             .getArguments())
267     {
268       if (rg.getDescription().contains("emperature"))
269       {
270         try
271         {
272           rg.setValue("292");
273         } catch (WrongParameterException q)
274         {
275           Assert.fail("Couldn't set the temperature parameter "
276                   + q.getStackTrace());
277         }
278         opts.add(rg);
279       }
280       if (rg.getDescription().contains("max"))
281       {
282         opts.add(rg);
283       }
284     }
285     alifoldClient = new RNAalifoldClient(rnaalifoldws, af, null, 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 }