From: Ben Soares Date: Tue, 19 Dec 2023 17:52:45 +0000 (+0000) Subject: Merge branch 'bug/JAL-4353_cannot_output_multiple_different_structure_images_for_one_... X-Git-Tag: Release_2_11_3_3~7^2~2^2~4 X-Git-Url: http://source.jalview.org/gitweb/?a=commitdiff_plain;h=ef0960a1dbe3e3b5050d75cd43279ae9a9f7b922;hp=6caf8e67439a4ea034d8f3575d3f6167c86784d0;p=jalview.git Merge branch 'bug/JAL-4353_cannot_output_multiple_different_structure_images_for_one_alignment' into bug/JAL-4290_headless_alignment_export_with_structure_annotations_doesnt_include_secondary_structure_and_temperature_factor --- diff --git a/src/jalview/bin/Commands.java b/src/jalview/bin/Commands.java index e01d40a..a72da0d 100644 --- a/src/jalview/bin/Commands.java +++ b/src/jalview/bin/Commands.java @@ -179,8 +179,7 @@ public class Commands if (argParser.getBoolean(Arg.QUIT)) { - Jalview.getInstance().exit( - "Exiting due to " + Arg.QUIT.argString() + " argument.", + Jalview.exit("Exiting due to " + Arg.QUIT.argString() + " argument.", ExitCode.OK); return true; } @@ -210,8 +209,13 @@ public class Commands Boolean isError = Boolean.valueOf(false); - // set wrap scope here so it can be applied after structures are opened + // set wrap, showSSAnnotations, showAnnotations and hideTFrows scope here so + // it can be applied after structures are opened boolean wrap = false; + boolean showSSAnnotations = false; + boolean showAnnotations = false; + boolean hideTFrows = false; + AlignFrame af = null; if (avm.containsArg(Arg.APPEND) || avm.containsArg(Arg.OPEN)) { @@ -220,7 +224,6 @@ public class Commands boolean first = true; boolean progressBarSet = false; - AlignFrame af; // Combine the APPEND and OPEN files into one list, along with whether it // was APPEND or OPEN List openAvList = new ArrayList<>(); @@ -392,53 +395,17 @@ public class Commands } // Show secondary structure annotations? - boolean showSSAnnotations = avm.getFromSubValArgOrPref( + showSSAnnotations = avm.getFromSubValArgOrPref( Arg.SHOWSSANNOTATIONS, av.getSubVals(), null, "STRUCT_FROM_PDB", true); - // Show sequence annotations? - boolean showAnnotations = avm.getFromSubValArgOrPref( - Arg.SHOWANNOTATIONS, av.getSubVals(), null, - "SHOW_ANNOTATIONS", true); - - boolean hideTFrows = (avm.getBoolean(Arg.NOTEMPFAC)); - final AlignFrame _af = af; - // many of jalview's format/layout methods are only thread safe on the - // swingworker thread. - // all these methods should be on the alignViewController so it can - // coordinate such details - try - { - SwingUtilities.invokeAndWait(new Runnable() - { + showAnnotations = avm.getFromSubValArgOrPref(Arg.SHOWANNOTATIONS, + av.getSubVals(), null, "SHOW_ANNOTATIONS", true); + // hide the Temperature Factor row? + hideTFrows = (avm.getBoolean(Arg.NOTEMPFAC)); - @Override - public void run() - { - _af.setAnnotationsVisibility(showSSAnnotations, true, - false); - - _af.setAnnotationsVisibility(showAnnotations, false, true); - - // show temperature factor annotations? - if (hideTFrows) - { - // do this better (annotation types?) - List hideThese = new ArrayList<>(); - hideThese.add("Temperature Factor"); - hideThese.add(AlphaFoldAnnotationRowBuilder.LABEL); - AlignmentUtils.showOrHideSequenceAnnotations( - _af.getCurrentView().getAlignment(), hideThese, - null, false, false); - } - } - }); - } catch (Exception x) - { - Console.warn( - "Unexpected exception adjusting annotation row visibility.", - x); - } + // showSSAnnotations, showAnnotations, hideTFrows used after opening + // structure // wrap alignment? do this last for formatting reasons wrap = avm.getFromSubValArgOrPref(Arg.WRAP, sv, null, @@ -496,8 +463,10 @@ public class Commands // open the structure (from same PDB file or given PDBfile) if (!avm.getBoolean(Arg.NOSTRUCTURE)) { - - AlignFrame af = afMap.get(id); + if (af == null) + { + af = afMap.get(id); + } if (avm.containsArg(Arg.STRUCTURE)) { commandArgsProvided = true; @@ -867,10 +836,47 @@ public class Commands } } - if (wrap) + if (af == null) { + af = afMap.get(id); + } + // many of jalview's format/layout methods are only thread safe on the + // swingworker thread. + // all these methods should be on the alignViewController so it can + // coordinate such details + if (headless) + { + showOrHideAnnotations(af, showSSAnnotations, showAnnotations, + hideTFrows); + } + else + { + try + { + AlignFrame _af = af; + final boolean _showSSAnnotations = showSSAnnotations; + final boolean _showAnnotations = showAnnotations; + final boolean _hideTFrows = hideTFrows; + SwingUtilities.invokeAndWait(() -> { + showOrHideAnnotations(_af, _showSSAnnotations, _showAnnotations, + _hideTFrows); + } - AlignFrame af = afMap.get(id); + ); + } catch (Exception x) + { + Console.warn( + "Unexpected exception adjusting annotation row visibility.", + x); + } + } + + if (wrap) + { + if (af == null) + { + af = afMap.get(id); + } if (af != null) { af.setWrapFormat(wrap, true); @@ -897,6 +903,26 @@ public class Commands return theseArgsWereParsed && !isError; } + private static void showOrHideAnnotations(AlignFrame af, + boolean showSSAnnotations, boolean showAnnotations, + boolean hideTFrows) + { + af.setAnnotationsVisibility(showSSAnnotations, true, false); + af.setAnnotationsVisibility(showAnnotations, false, true); + + // show temperature factor annotations? + if (hideTFrows) + { + // do this better (annotation types?) + List hideThese = new ArrayList<>(); + hideThese.add("Temperature Factor"); + hideThese.add(AlphaFoldAnnotationRowBuilder.LABEL); + AlignmentUtils.showOrHideSequenceAnnotations( + af.getCurrentView().getAlignment(), hideThese, null, false, + false); + } + } + protected void processGroovyScript(String id) { ArgValuesMap avm = argParser.getLinkedArgs(id); diff --git a/src/jalview/bin/argparser/ArgValuesMap.java b/src/jalview/bin/argparser/ArgValuesMap.java index 219983f..7385db0 100644 --- a/src/jalview/bin/argparser/ArgValuesMap.java +++ b/src/jalview/bin/argparser/ArgValuesMap.java @@ -653,6 +653,24 @@ public class ArgValuesMap return pref != null ? (invertPref ? !prefVal : prefVal) : def; } + @Override + public String toString() + { + StringBuilder sb = new StringBuilder(); + for (Arg a : this.getArgKeys()) + { + sb.append(a.argString()); + sb.append(":\n"); + for (ArgValue av : this.getArgValueList(a)) + { + sb.append(" "); + sb.append(av.getValue()); + sb.append("\n"); + } + } + return sb.toString(); + } + public class ArgInfo implements Comparable { private Arg arg; diff --git a/src/jalview/gui/AlignmentPanel.java b/src/jalview/gui/AlignmentPanel.java index 8e7c745..358560b 100644 --- a/src/jalview/gui/AlignmentPanel.java +++ b/src/jalview/gui/AlignmentPanel.java @@ -1379,7 +1379,7 @@ public class AlignmentPanel extends GAlignmentPanel implements // need to obtain default alignment width and then add in any // additional allowance for id margin // this duplicates the calculation in getWrappedHeight but adjusts for - // offscreen idWith + // offscreen idWidth width = alignFrame.getWidth() - vscroll.getPreferredSize().width - alignFrame.getInsets().left - alignFrame.getInsets().right - getVisibleIdWidth() + getVisibleIdWidth(false); diff --git a/src/jalview/gui/AnnotationLabels.java b/src/jalview/gui/AnnotationLabels.java index 94f8790..70fef2a 100755 --- a/src/jalview/gui/AnnotationLabels.java +++ b/src/jalview/gui/AnnotationLabels.java @@ -1206,8 +1206,8 @@ public class AnnotationLabels extends JPanel if (ap != null) { iwa = ap.idwidthAdjuster; - if ((Cache.getDefault(ADJUST_ANNOTATION_LABELS_WIDTH_PREF, true) - || Jalview.isHeadlessMode())) + if (Cache.getDefault(ADJUST_ANNOTATION_LABELS_WIDTH_PREF, true) + || Jalview.isHeadlessMode()) { Graphics2D g2d = (Graphics2D) g; Graphics dummy = g2d.create(); diff --git a/src/jalview/gui/Desktop.java b/src/jalview/gui/Desktop.java index 35c7818..bbd4dae 100644 --- a/src/jalview/gui/Desktop.java +++ b/src/jalview/gui/Desktop.java @@ -680,22 +680,7 @@ public class Desktop extends jalview.jbgui.GDesktop // configure services StructureSelectionManager ssm = StructureSelectionManager .getStructureSelectionManager(this); - if (Cache.getDefault(Preferences.ADD_SS_ANN, true)) - { - ssm.setAddTempFacAnnot( - Cache.getDefault(Preferences.ADD_TEMPFACT_ANN, true)); - ssm.setProcessSecondaryStructure( - Cache.getDefault(Preferences.STRUCT_FROM_PDB, true)); - // JAL-3915 - RNAView is no longer an option so this has no effect - ssm.setSecStructServices( - Cache.getDefault(Preferences.USE_RNAVIEW, false)); - } - else - { - ssm.setAddTempFacAnnot(false); - ssm.setProcessSecondaryStructure(false); - ssm.setSecStructServices(false); - } + StructureSelectionManager.doConfigureStructurePrefs(ssm); } public void checkForNews() diff --git a/src/jalview/gui/StructureChooser.java b/src/jalview/gui/StructureChooser.java index 666ff74..6132908 100644 --- a/src/jalview/gui/StructureChooser.java +++ b/src/jalview/gui/StructureChooser.java @@ -1826,6 +1826,7 @@ public class StructureChooser extends GStructureChooser if (ssm == null) { ssm = ap.getStructureSelectionManager(); + StructureSelectionManager.doConfigureStructurePrefs(ssm); } PDBEntry fileEntry = new AssociatePdbFileWithSeq().associatePdbWithSeq( diff --git a/src/jalview/structure/StructureSelectionManager.java b/src/jalview/structure/StructureSelectionManager.java index ec3e0a0..9a9e2a2 100644 --- a/src/jalview/structure/StructureSelectionManager.java +++ b/src/jalview/structure/StructureSelectionManager.java @@ -34,6 +34,7 @@ import java.util.Vector; import jalview.analysis.AlignSeq; import jalview.api.StructureSelectionManagerProvider; +import jalview.bin.Cache; import jalview.bin.Console; import jalview.commands.CommandI; import jalview.commands.EditCommand; @@ -50,6 +51,7 @@ import jalview.datamodel.SearchResultsI; import jalview.datamodel.SequenceI; import jalview.ext.jmol.JmolParser; import jalview.gui.IProgressIndicator; +import jalview.gui.Preferences; import jalview.io.AppletFormatAdapter; import jalview.io.DataSourceType; import jalview.io.StructureFile; @@ -1665,4 +1667,34 @@ public class StructureSelectionManager return pdbIdFileName; } + public static void doConfigureStructurePrefs( + StructureSelectionManager ssm) + { + doConfigureStructurePrefs(ssm, + Cache.getDefault(Preferences.ADD_SS_ANN, true), + Cache.getDefault(Preferences.ADD_TEMPFACT_ANN, true), + Cache.getDefault(Preferences.STRUCT_FROM_PDB, true), + Cache.getDefault(Preferences.USE_RNAVIEW, false)); + } + + public static void doConfigureStructurePrefs( + StructureSelectionManager ssm, boolean add_ss_ann, + boolean add_tempfact_ann, boolean struct_from_pdb, + boolean use_rnaview) + { + if (add_ss_ann) + { + ssm.setAddTempFacAnnot(add_tempfact_ann); + ssm.setProcessSecondaryStructure(struct_from_pdb); + // JAL-3915 - RNAView is no longer an option so this has no effect + ssm.setSecStructServices(use_rnaview); + } + else + { + ssm.setAddTempFacAnnot(false); + ssm.setProcessSecondaryStructure(false); + ssm.setSecStructServices(false); + } + } + } diff --git a/test/jalview/bin/CommandLineOperations.java b/test/jalview/bin/CommandLineOperations.java index 77cbd92..3855dc7 100644 --- a/test/jalview/bin/CommandLineOperations.java +++ b/test/jalview/bin/CommandLineOperations.java @@ -71,7 +71,7 @@ public class CommandLineOperations * @author jimp * */ - private static class Worker extends Thread + public static class Worker extends Thread { private final Process process; @@ -156,7 +156,7 @@ public class CommandLineOperations return classpath; } - private Worker getJalviewDesktopRunner(boolean withAwt, String cmd, + public static Worker getJalviewDesktopRunner(boolean withAwt, String cmd, int timeout) { // Note: JAL-3065 - don't include quotes for lib/* because the arguments are @@ -183,7 +183,7 @@ public class CommandLineOperations new InputStreamReader(ls2_proc.getInputStream())); BufferedReader errorReader = new BufferedReader( new InputStreamReader(ls2_proc.getErrorStream())); - worker = new Worker(ls2_proc); + worker = new CommandLineOperations.Worker(ls2_proc); worker.start(); try { diff --git a/test/jalview/bin/CommandsTest.java b/test/jalview/bin/CommandsTest.java index 7b42737..80354f9 100644 --- a/test/jalview/bin/CommandsTest.java +++ b/test/jalview/bin/CommandsTest.java @@ -20,14 +20,15 @@ */ package jalview.bin; +import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; -import java.lang.reflect.InvocationTargetException; import java.nio.file.Files; import java.util.Date; import java.util.HashSet; import java.util.Set; +import javax.imageio.ImageIO; import javax.swing.SwingUtilities; import org.testng.Assert; @@ -93,7 +94,12 @@ public class CommandsTest public static void callJalviewMain(String[] args) { - if (Jalview.getInstance() != null) + callJalviewMain(args, false); + } + + public static void callJalviewMain(String[] args, boolean newJalview) + { + if (Jalview.getInstance() != null && !newJalview) { Jalview.getInstance().doMain(args); } @@ -116,7 +122,11 @@ public class CommandsTest } */ - @Test(groups = { "Functional", "testTask3" }, dataProvider = "cmdLines", singleThreaded = true) + @Test( + groups = + { "Functional", "testTask3" }, + dataProvider = "cmdLines", + singleThreaded = true) public void commandsOpenTest(String cmdLine, boolean cmdArgs, int numFrames, String[] sequences) @@ -169,40 +179,64 @@ public class CommandsTest @Test( groups = { "Functional", "testTask3" }, - dataProvider = "structureImageOutputFiles", singleThreaded = true) + dataProvider = "structureImageOutputFiles", + singleThreaded = true) public void structureImageOutputTest(String cmdLine, String[] filenames) throws IOException { cleanupFiles(filenames); - String[] args = (cmdLine + " --gui").split("\\s+"); + String[] args = (cmdLine + "").split("\\s+"); try { callJalviewMain(args); Commands cmds = Jalview.getInstance().getCommands(); Assert.assertNotNull(cmds); - File lastFile = null; - for (String filename : filenames) + verifyIncreasingSize(cmdLine, filenames); + } catch (Exception x) + { + Assert.fail("Unexpected exception during structureImageOutputTest", + x); + } finally + { + // cleanupFiles(filenames); + tearDown(); + } + } + + /** + * given two command lines, compare the output files produced - they should + * exist and be equal in size + */ + @Test( + groups = + { "Functional", "testTask3" }, + dataProvider = "compareHeadlessAndGUIOps", + singleThreaded = true) + public void headlessOrGuiImageOutputTest(String[] cmdLines, + String[] filenames) throws IOException + { + cleanupFiles(filenames); + try + { + for (String cmdLine : cmdLines) { - File file = new File(filename); - Assert.assertTrue(file.exists(), "File '" + filename - + "' was not created by '" + cmdLine + "'"); - Assert.assertTrue(file.isFile(), "File '" + filename - + "' is not a file from '" + cmdLine + "'"); - Assert.assertTrue(Files.size(file.toPath()) > 0, "File '" + filename - + "' has no content from '" + cmdLine + "'"); - // make sure the successive output files get bigger! - if (lastFile != null) + CommandLineOperations.Worker runner = CommandLineOperations + .getJalviewDesktopRunner(false, cmdLine, 1000); + long timeOut = 10000; + while (runner.isAlive() && timeOut > 0) { - waitForLastWrite(file,25); - - if (Files.size(file.toPath()) > Files - .size(lastFile.toPath())) - Assert.assertTrue(Files.size(file.toPath()) > Files - .size(lastFile.toPath())); + Thread.sleep(25); + timeOut -= 25; } - // remember it for next file - lastFile = file; } + /* + * larger margin between IDs and alignment/annotations when in --gui mode + * + verifyOrderedFileSet(cmdLines[0] + " vs " + cmdLines[1], filenames, false); + */ + + verifySimilarEnoughImages(cmdLines[0] + " vs " + cmdLines[1], + filenames, 0.6f, 0f); } catch (Exception x) { Assert.fail("Unexpected exception during structureImageOutputTest", @@ -214,21 +248,161 @@ public class CommandsTest } } + @DataProvider(name = "compareHeadlessAndGUIOps") + public Object[][] compareHeadlessAndGUIOps() + { + return new Object[][] { + new Object[] + { new String[] { "--open examples/uniref50.fa " + + "--structure [seqid=FER1_SPIOL,tempfac=plddt,showssannotations,structureviewer=jmol]" + + "examples/AlphaFold/AF-P00221-F1-model_v4.pdb " + + "--paematrix examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json --image=" + + testfiles + "/" + + "test-al-pae-ss-gui.png --overwrite --gui --quit", + "--open examples/uniref50.fa " + + "--structure [seqid=FER1_SPIOL,tempfac=plddt,showssannotations,structureviewer=jmol]" + + "examples/AlphaFold/AF-P00221-F1-model_v4.pdb " + + "--paematrix examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json --image=" + + testfiles + "/" + + "test-al-pae-ss-nogui.png --overwrite --nogui" }, + new String[] + { testfiles + "/test-al-pae-ss-gui.png", + testfiles + "/test-al-pae-ss-nogui.png", } } }; + } + + private static void verifyIncreasingSize(String cmdLine, + String[] filenames) throws Exception + { + verifyOrderedFileSet(cmdLine, filenames, true); + } + + private static void verifyOrderedFileSet(String cmdLine, + String[] filenames, boolean increasingSize) throws Exception + { + File lastFile = null; + for (String filename : filenames) + { + File file = new File(filename); + Assert.assertTrue(file.exists(), "File '" + filename + + "' was not created by '" + cmdLine + "'"); + Assert.assertTrue(file.isFile(), "File '" + filename + + "' is not a file from '" + cmdLine + "'"); + Assert.assertTrue(Files.size(file.toPath()) > 0, "File '" + filename + + "' has no content from '" + cmdLine + "'"); + // make sure the successive output files get bigger! + if (lastFile != null) + { + waitForLastWrite(file, 25); + + if (increasingSize) + { + Assert.assertTrue( + Files.size(file.toPath()) > Files.size(lastFile.toPath()), + "Expected " + file.toPath() + " to be larger than " + + lastFile.toPath()); + } + else + { + Assert.assertEquals(Files.size(file.toPath()), + Files.size(lastFile.toPath()), + "New file " + file.toPath() + + " (actual size) not same as last file's size " + + lastFile.toString()); + } + } + // remember it for next file + lastFile = file; + } + + } + + private static void verifySimilarEnoughImages(String cmdLine, + String[] filenames, float w_tolerance_pc, float h_tolerance_pc) + throws Exception + { + int min_w = -1; + int max_w = -1; + int min_h = -1; + int max_h = -1; + for (String filename : filenames) + { + File file = new File(filename); + Assert.assertTrue(file.exists(), "File '" + filename + + "' was not created by '" + cmdLine + "'"); + Assert.assertTrue(file.isFile(), "File '" + filename + + "' is not a file from '" + cmdLine + "'"); + Assert.assertTrue(Files.size(file.toPath()) > 0, "File '" + filename + + "' has no content from '" + cmdLine + "'"); + + BufferedImage img = ImageIO.read(file); + if (img.getWidth() < min_w || min_w == -1) + { + min_w = img.getWidth(); + } + if (img.getWidth() > max_w || max_w == -1) + { + max_w = img.getWidth(); + } + if (img.getHeight() < min_h || min_h == -1) + { + min_h = img.getHeight(); + } + if (img.getHeight() > max_h || max_h == -1) + { + max_h = img.getHeight(); + } + } + Assert.assertTrue(min_w > 0, + "Minimum width is not positive (" + min_w + ")"); + Assert.assertTrue(max_w > 0, + "Maximum width is not positive (" + max_w + ")"); + Assert.assertTrue(min_h > 0, + "Minimum height is not positive (" + min_h + ")"); + Assert.assertTrue(max_h > 0, + "Maximum height is not positive (" + max_h + ")"); + // tolerance + Assert.assertTrue(100 * (max_w - min_w) / min_w < w_tolerance_pc, + "Width variation (" + (max_w - min_w) + + " not within tolerance of minimum width (" + min_w + + ")"); + if (max_w != min_w) + { + System.out.println("Widths within tolerance (" + w_tolerance_pc + + "%), min_w=" + min_w + " < max_w=" + max_w); + } + Assert.assertTrue(100 * (max_h - min_h) / min_h < w_tolerance_pc, + "Height variation (" + (max_h - min_h) + + " not within tolerance of minimum height (" + min_h + + ")"); + if (max_h != min_h) + { + System.out.println("Heights within tolerance (" + h_tolerance_pc + + "%), min_h=" + min_h + " < max_h=" + max_h); + } + } + private static long waitForLastWrite(File file, int i) throws IOException { - long lastSize,stableSize =Files.size(file.toPath()); + long lastSize, stableSize = Files.size(file.toPath()); // wait around until we are sure the file has been completely written. - do { + do + { lastSize = stableSize; - try { + try + { Thread.sleep(i); - } catch (Exception x) {} - stableSize=Files.size(file.toPath()); - } while (stableSize!=lastSize); + } catch (Exception x) + { + } + stableSize = Files.size(file.toPath()); + } while (stableSize != lastSize); return stableSize; } - @Test(groups = "Functional", dataProvider = "argfileOutputFiles", singleThreaded = true) + @Test( + groups = "Functional", + dataProvider = "argfileOutputFiles", + singleThreaded = true) public void argFilesGlobAndSubstitutionsTest(String cmdLine, String[] filenames) throws IOException @@ -251,10 +425,13 @@ public class CommandsTest Assert.assertTrue(Files.size(file.toPath()) > 0, "File '" + filename + "' has no content from '" + cmdLine + "'"); // make sure the successive output files get bigger! - if (lastFile != null) { + if (lastFile != null) + { Assert.assertTrue(Files.size(file.toPath()) > Files .size(lastFile.toPath())); - System.out.println("this file: "+file+" +"+Files.size(file.toPath()) + " greater than " +Files.size(lastFile.toPath())); + System.out.println("this file: " + file + " +" + + Files.size(file.toPath()) + " greater than " + + Files.size(lastFile.toPath())); } // remember it for next file lastFile = file; @@ -276,6 +453,7 @@ public class CommandsTest { return new Object[][] { // + /* { "--gui --nonews --nosplash --open=./examples/test_fab41.result/sample.a2m " + "--structure=./examples/test_fab41.result/test_fab41_unrelaxed_rank_1_model_3.pdb " + "--structureimage=" + testfiles + "/structureimage1.png " @@ -306,20 +484,26 @@ public class CommandsTest { testfiles + "/structureimage1.png", testfiles + "/structureimage2.png", testfiles + "/structureimage3.png" } }, - { "--gui --nonews --nosplash --open examples/1gaq.txt --append ./examples/3W5V.pdb "+"--structure examples/1gaq.txt --seqid \"1GAQ|A\" "+"--structureimage "+testfiles+"/1gaq.png --structure examples/3W5V.pdb "+"--seqid \"3W5V|A\" --structureimage "+testfiles+"/3w5v.png --overwrite", - - new String[] { - testfiles+"/1gaq.png",testfiles+"/3w5v.png" - } - }, - { "--headless --noquit --open ./examples/1gaq.txt --append ./examples/3W5V.pdb "+"--structure examples/1gaq.txt --seqid \"1GAQ|A\" "+"--structureimage "+testfiles+"/1gaq.png --structure examples/3W5V.pdb "+"--seqid \"3W5V|A\" --structureimage "+testfiles+"/3w5v.png --overwrite", - - new String[] { - testfiles+"/1gaq.png",testfiles+"/3w5v.png" - } - } + */ + { "--gui --nonews --nosplash --open examples/1gaq.txt --append ./examples/3W5V.pdb " + + "--structure examples/1gaq.txt --seqid \"1GAQ|A\" " + + "--structureimage " + testfiles + + "/1gaq.png --structure examples/3W5V.pdb " + + "--seqid \"3W5V|A\" --structureimage " + testfiles + + "/3w5v.png --overwrite", + new String[] + { testfiles + "/1gaq.png", testfiles + "/3w5v.png" } }, /* + { "--headless --noquit --open ./examples/1gaq.txt --append ./examples/3W5V.pdb " + + "--structure examples/1gaq.txt --seqid \"1GAQ|A\" " + + "--structureimage " + testfiles + + "/1gaq.png --structure examples/3W5V.pdb " + + "--seqid \"3W5V|A\" --structureimage " + testfiles + + "/3w5v.png --overwrite", + + new String[] + { testfiles + "/1gaq.png", testfiles + "/3w5v.png" } } */ // }; @@ -674,4 +858,105 @@ public class CommandsTest }; } + @Test( + groups = + { "Functional", "testTask3" }, + dataProvider = "structureImageAnnotationsOutputFiles", + singleThreaded = true) + public void structureImageAnnotationsOutputTest(String cmdLine, + String filename, int height) throws IOException + { + cleanupFiles(new String[] { filename }); + String[] args = (cmdLine).split("\\s+"); + callJalviewMain(args, true); // Create new instance of Jalview each time for + // linkedIds + BufferedImage img = ImageIO.read(new File(filename)); + Assert.assertEquals(height, img.getHeight(), "Output image '" + filename + + "' is not in the expected height range, possibly because of the wrong number of annotations"); + + cleanupFiles(new String[] { filename }); + tearDown(); + } + + @DataProvider(name = "structureImageAnnotationsOutputFiles") + public Object[][] structureImageAnnotationsOutputFiles() + { + String filename = "test/jalview/bin/argparser/testfiles/test_annotations.png"; + return new Object[][] { + // MUST use --noquit with --headless to avoid a System.exit() + { "--noquit --headless --nonews --nosplash --open=./examples/uniref50.fa " + + "--structure=examples/AlphaFold/AF-P00221-F1-model_v4.pdb " + + "--seqid=FER1_SPIOL --structureviewer=jmol " + + "--paematrix examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json " + + "--image=" + filename + " " + "--tempfac=plddt " + + "--overwrite " // + + "--noshowssannotations " + "--noshowannotations", // + filename, // + 252 }, // + { "--noquit --headless --nonews --nosplash --open=./examples/uniref50.fa " + + "--structure=examples/AlphaFold/AF-P00221-F1-model_v4.pdb " + + "--seqid=FER1_SPIOL --structureviewer=jmol " + + "--paematrix examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json " + + "--image=" + filename + " " + "--tempfac=plddt " + + "--overwrite " // + + "--showssannotations " + "--noshowannotations", // + filename, // + 368 }, // + { "--noquit --headless --nonews --nosplash --open=./examples/uniref50.fa " + + "--structure=examples/AlphaFold/AF-P00221-F1-model_v4.pdb " + + "--seqid=FER1_SPIOL --structureviewer=jmol " + + "--paematrix examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json " + + "--image=" + filename + " " + "--tempfac=plddt " + + "--overwrite " // + + "--noshowssannotations " + "--showannotations", // + filename, // + 524 }, // + { "--noquit --headless --nonews --nosplash --open=./examples/uniref50.fa " + + "--structure=examples/AlphaFold/AF-P00221-F1-model_v4.pdb " + + "--seqid=FER1_SPIOL --structureviewer=jmol " + + "--paematrix examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json " + + "--image=" + filename + " " + "--tempfac=plddt " + + "--overwrite " // + + "--showssannotations " + "--showannotations", // + filename, // + 660 }, // + { "--gui --nonews --nosplash --open=./examples/uniref50.fa " + + "--structure=examples/AlphaFold/AF-P00221-F1-model_v4.pdb " + + "--seqid=FER1_SPIOL --structureviewer=jmol " + + "--paematrix examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json " + + "--image=" + filename + " " + "--tempfac=plddt " + + "--overwrite " // + + "--noshowssannotations " + "--noshowannotations", // + filename, // + 252 }, // + { "--gui --nonews --nosplash --open=./examples/uniref50.fa " + + "--structure=examples/AlphaFold/AF-P00221-F1-model_v4.pdb " + + "--seqid=FER1_SPIOL --structureviewer=jmol " + + "--paematrix examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json " + + "--image=" + filename + " " + "--tempfac=plddt " + + "--overwrite " // + + "--showssannotations " + "--noshowannotations", // + filename, // + 368 }, // + { "--gui --nonews --nosplash --open=./examples/uniref50.fa " + + "--structure=examples/AlphaFold/AF-P00221-F1-model_v4.pdb " + + "--seqid=FER1_SPIOL --structureviewer=jmol " + + "--paematrix examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json " + + "--image=" + filename + " " + "--tempfac=plddt " + + "--overwrite " // + + "--noshowssannotations " + "--showannotations", // + filename, // + 524 }, // + { "--gui --nonews --nosplash --open=./examples/uniref50.fa " + + "--structure=examples/AlphaFold/AF-P00221-F1-model_v4.pdb " + + "--seqid=FER1_SPIOL --structureviewer=jmol " + + "--paematrix examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json " + + "--image=" + filename + " " + "--tempfac=plddt " + + "--overwrite " // + + "--showssannotations " + "--showannotations", // + filename, // + 660 }, // + }; + } + }