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