From: Ben Soares Date: Sat, 22 Apr 2023 00:26:15 +0000 (+0100) Subject: JAL-629 Test and fix --annotation --ssannotation args. Added a viewerType arg/subval... X-Git-Tag: Release_2_11_3_0~14^2~111 X-Git-Url: http://source.jalview.org/gitweb/?p=jalview.git;a=commitdiff_plain;h=0788111a588187a04dd0d254d70b055274cf2c9d JAL-629 Test and fix --annotation --ssannotation args. Added a viewerType arg/subval. Fixed multi value getClosest...(). Added a jalview.bin.Launcher eclipse script. Lots of tests for opening structures from CLI. --- diff --git a/src/jalview/bin/Commands.java b/src/jalview/bin/Commands.java index 6d514b0..fc2ee1a 100644 --- a/src/jalview/bin/Commands.java +++ b/src/jalview/bin/Commands.java @@ -5,7 +5,7 @@ import java.io.IOException; import java.util.AbstractMap; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; +import java.util.EnumSet; import java.util.HashMap; import java.util.Iterator; import java.util.List; @@ -16,11 +16,11 @@ import java.util.Map.Entry; import jalview.analysis.AlignmentUtils; import jalview.bin.argparser.Arg; import jalview.bin.argparser.ArgParser; +import jalview.bin.argparser.ArgParser.Position; import jalview.bin.argparser.ArgValue; import jalview.bin.argparser.ArgValues; import jalview.bin.argparser.ArgValuesMap; import jalview.bin.argparser.SubVals; -import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.AlignmentI; import jalview.datamodel.SequenceI; import jalview.datamodel.annotations.AlphaFoldAnnotationRowBuilder; @@ -30,6 +30,7 @@ import jalview.gui.Desktop; import jalview.gui.Preferences; import jalview.gui.StructureChooser; import jalview.gui.StructureViewer; +import jalview.gui.StructureViewer.ViewerType; import jalview.io.AppletFormatAdapter; import jalview.io.DataSourceType; import jalview.io.FileFormat; @@ -38,13 +39,11 @@ import jalview.io.FileFormatI; import jalview.io.FileLoader; import jalview.io.HtmlSvgOutput; import jalview.io.IdentifyFile; -import jalview.schemes.AnnotationColourGradient; import jalview.structure.StructureImportSettings.TFType; import jalview.structure.StructureSelectionManager; import jalview.util.HttpUtils; import jalview.util.MessageManager; import jalview.util.Platform; -import mc_view.PDBChain; public class Commands { @@ -226,11 +225,11 @@ public class Commands { /* * this approach isn't working yet // get default annotations before opening - * AlignFrame if (m.get(Arg.SSANNOTATION) != null) { - * Console.debug("##### SSANNOTATION=" + m.get(Arg.SSANNOTATION).getBoolean()); + * AlignFrame if (m.get(Arg.SSANNOTATIONS) != null) { + * Console.debug("##### SSANNOTATIONS=" + m.get(Arg.SSANNOTATIONS).getBoolean()); * } if (m.get(Arg.NOTEMPFAC) != null) { Console.debug( "##### NOTEMPFAC=" + * m.get(Arg.NOTEMPFAC).getBoolean()); } boolean showSecondaryStructure = - * (m.get(Arg.SSANNOTATION) != null) ? m.get(Arg.SSANNOTATION).getBoolean() : + * (m.get(Arg.SSANNOTATIONS) != null) ? m.get(Arg.SSANNOTATIONS).getBoolean() : * false; boolean showTemperatureFactor = (m.get(Arg.NOTEMPFAC) != null) ? * !m.get(Arg.NOTEMPFAC).getBoolean() : false; Console.debug("##### tempfac=" + * showTemperatureFactor + ", showSS=" + showSecondaryStructure); @@ -246,6 +245,10 @@ public class Commands af = fileLoader.LoadFileWaitTillLoaded(openFile, protocol, format); + boolean showAnnotations = ArgParser.getFromSubValArgOrPref(avm, + Arg.ANNOTATIONS, av.getSubVals(), null, + "SHOW_ANNOTATIONS", true); + af.setAnnotationsVisibility(showAnnotations, false, true); // wrap alignment? if (avm.getBoolean(Arg.WRAP)) @@ -263,15 +266,19 @@ public class Commands if (avm.containsArg(Arg.TITLE)) af.setTitle(avm.getValue(Arg.TITLE)); - /* hacky approach to hiding the annotations */ // show secondary structure annotations? - if (avm.getBoolean(Arg.SSANNOTATION)) + boolean showSSAnnotations = ArgParser.getFromSubValArgOrPref(avm, + Arg.SSANNOTATIONS, av.getSubVals(), null, + "STRUCT_FROM_PDB", true); + if (avm.getBoolean(Arg.SSANNOTATIONS)) { - // do this better (annotation types?) + af.setAnnotationsVisibility(showSSAnnotations, true, false); + /* AlignmentUtils.showOrHideSequenceAnnotations( af.getCurrentView().getAlignment(), Collections.singleton("Secondary Structure"), null, false, false); + */ } // show temperature factor annotations? @@ -291,6 +298,7 @@ public class Commands * (showTemperatureFactor) */ { + /* if (avm.containsArg(Arg.TEMPFAC_LABEL)) { AlignmentAnnotation aa = AlignmentUtils @@ -309,6 +317,7 @@ public class Commands + label); } } + */ } // store the AlignFrame for this id @@ -463,7 +472,13 @@ public class Commands } } - // get TEMPFAC type from subvals or Arg.TEMPFAC + // showing annotations from structure file or not + boolean ssFromStructure = ArgParser.getFromSubValArgOrPref(avm, + Arg.SSANNOTATIONS, subVals, null, "STRUCT_FROM_PDB", + true); + + // get TEMPFAC type from subvals or Arg.TEMPFAC in case user Adds + // reference annotations String tftString = subVals.get("tempfac"); TFType tft = avm.getBoolean(Arg.NOTEMPFAC) ? null : TFType.DEFAULT; @@ -500,13 +515,36 @@ public class Commands } } - // TODO pass PAE label + String sViewer = ArgParser.getFromSubValArgOrPref(avm, + Arg.STRUCTUREVIEWER, Position.AFTER, av, subVals, + "viewer", null, "jmol"); + ViewerType viewerType = null; + if (!"none".equals(sViewer)) + { + for (ViewerType v : EnumSet.allOf(ViewerType.class)) + { + String name = v.name().toLowerCase(Locale.ROOT) + .replaceAll(" ", ""); + if (sViewer.equals(name)) + { + viewerType = v; + break; + } + } + } + + boolean addTempFac = tft != null + || Cache.getDefault("ADD_TEMPFACT_ANN", false); + + // TODO use ssFromStructure StructureChooser.openStructureFileForSequence(null, null, ap, seq, - false, structureFilepath, tft, paeFilepath, false); + false, structureFilepath, tft, paeFilepath, false, + ssFromStructure, false, viewerType); } } } + /* boolean doShading = avm.getBoolean(Arg.TEMPFAC_SHADING); if (doShading) { @@ -521,6 +559,7 @@ public class Commands Console.info("Changed colour " + acg.toString()); } } + */ return theseArgsWereParsed; } diff --git a/src/jalview/bin/Jalview.java b/src/jalview/bin/Jalview.java index 5d14f98..d70326e 100755 --- a/src/jalview/bin/Jalview.java +++ b/src/jalview/bin/Jalview.java @@ -283,12 +283,14 @@ public class Jalview */ void doMain(String[] args) { - if (!Platform.isJS()) { System.setSecurityManager(null); } + if (args == null) + args = new String[] {}; + // Move any new getdown-launcher-new.jar into place over old // getdown-launcher.jar String appdirString = System.getProperty("getdownappdir"); diff --git a/src/jalview/bin/Launcher.java b/src/jalview/bin/Launcher.java index cab2c00..dc42f8c 100644 --- a/src/jalview/bin/Launcher.java +++ b/src/jalview/bin/Launcher.java @@ -181,6 +181,12 @@ public class Launcher // Leaving it in in case it gets fixed command.add( "-Xdock:name=" + ChannelProperties.getProperty("app_name")); + // this launches WITHOUT an icon in the macOS dock. Could be useful for + // getdown? + // command.add("-Dapple.awt.UIElement=false"); + // This also does not work for the dock + command.add("-Dcom.apple.mrj.application.apple.menu.about.name=" + + ChannelProperties.getProperty("app_name")); } } diff --git a/src/jalview/bin/argparser/Arg.java b/src/jalview/bin/argparser/Arg.java index e22cfc6..f712010 100644 --- a/src/jalview/bin/argparser/Arg.java +++ b/src/jalview/bin/argparser/Arg.java @@ -10,11 +10,10 @@ import java.util.stream.Collectors; public enum Arg { HELP("h"), CALCULATION, MENUBAR, STATUS, SHOWOVERVIEW, ANNOTATIONS, - COLOUR, FEATURES, GROOVY, GROUPS, HEADLESS, JABAWS, ANNOTATION, - ANNOTATION2, DISPLAY, GUI, NEWS, SORTBYTREE, USAGESTATS, OPEN, OPENNEW, - PROPS, QUESTIONNAIRE, SETPROP, TREE, VDOC, VSESS, OUTPUT, OUTPUTTYPE, - SSANNOTATION, NOTEMPFAC, TEMPFAC, TEMPFAC_LABEL, TEMPFAC_DESC, - TEMPFAC_SHADING, TITLE, PAEMATRIX, WRAP, NOSTRUCTURE, STRUCTURE, IMAGE, + COLOUR, FEATURES, GROOVY, GROUPS, HEADLESS, JABAWS, DISPLAY, GUI, NEWS, + SORTBYTREE, USAGESTATS, OPEN, OPENNEW, PROPS, QUESTIONNAIRE, SETPROP, + TREE, VDOC, VSESS, OUTPUT, OUTPUTTYPE, SSANNOTATIONS, NOTEMPFAC, TEMPFAC, + TITLE, PAEMATRIX, WRAP, NOSTRUCTURE, STRUCTURE, STRUCTUREVIEWER, IMAGE, QUIT, CLOSE, DEBUG("d"), QUIET("q"), ARGFILE, INCREMENT, NPP("n++"), SUBSTITUTIONS, INITSUBSTITUTIONS, NIL, SPLASH, SETARGFILE, UNSETARGFILE; @@ -32,7 +31,7 @@ public enum Arg MENUBAR.setOptions(true, Opt.BOOLEAN); STATUS.setOptions(true, Opt.BOOLEAN); SHOWOVERVIEW.setOptions(Opt.UNARY, Opt.LINKED); - ANNOTATIONS.setOptions(Opt.STRING, Opt.LINKED); + ANNOTATIONS.setOptions(Opt.BOOLEAN, Opt.LINKED); COLOUR.setOptions(Opt.STRING, Opt.LINKED); FEATURES.setOptions(Opt.STRING, Opt.LINKED, Opt.MULTI, Opt.ALLOWSUBSTITUTIONS); @@ -41,8 +40,6 @@ public enum Arg GROUPS.setOptions(Opt.STRING, Opt.LINKED); HEADLESS.setOptions(Opt.UNARY, Opt.BOOTSTRAP); JABAWS.setOptions(Opt.STRING); - ANNOTATION.setOptions(true, Opt.BOOLEAN, Opt.LINKED); - ANNOTATION2.setOptions(true, Opt.BOOLEAN, Opt.LINKED); DISPLAY.setOptions(true, Opt.BOOLEAN); GUI.setOptions(true, Opt.BOOLEAN); NEWS.setOptions(true, Opt.BOOLEAN, Opt.BOOTSTRAP); @@ -65,18 +62,16 @@ public enum Arg OUTPUT.setOptions(Opt.STRING, Opt.LINKED, Opt.ALLOWSUBSTITUTIONS); OUTPUTTYPE.setOptions(Opt.STRING, Opt.LINKED, Opt.MULTI); - SSANNOTATION.setOptions(Opt.BOOLEAN, Opt.LINKED); + SSANNOTATIONS.setOptions(Opt.BOOLEAN, Opt.LINKED); NOTEMPFAC.setOptions(Opt.UNARY, Opt.LINKED); TEMPFAC.setOptions(Opt.STRING, Opt.LINKED); - TEMPFAC_LABEL.setOptions(Opt.STRING, Opt.LINKED); - TEMPFAC_DESC.setOptions(Opt.STRING, Opt.LINKED); - TEMPFAC_SHADING.setOptions(Opt.BOOLEAN, Opt.LINKED); TITLE.setOptions(Opt.STRING, Opt.LINKED); PAEMATRIX.setOptions(Opt.STRING, Opt.LINKED, Opt.MULTI, Opt.ALLOWSUBSTITUTIONS); NOSTRUCTURE.setOptions(Opt.UNARY, Opt.LINKED); STRUCTURE.setOptions(Opt.STRING, Opt.LINKED, Opt.MULTI, Opt.ALLOWSUBSTITUTIONS); + STRUCTUREVIEWER.setOptions(Opt.STRING, Opt.LINKED, Opt.MULTI); WRAP.setOptions(Opt.BOOLEAN, Opt.LINKED); IMAGE.setOptions(Opt.STRING, Opt.LINKED, Opt.ALLOWSUBSTITUTIONS); QUIT.setOptions(Opt.UNARY); diff --git a/src/jalview/bin/argparser/ArgParser.java b/src/jalview/bin/argparser/ArgParser.java index 0ff1845..70ed5d1 100644 --- a/src/jalview/bin/argparser/ArgParser.java +++ b/src/jalview/bin/argparser/ArgParser.java @@ -29,8 +29,10 @@ import java.util.Arrays; import java.util.EnumSet; import java.util.HashMap; import java.util.List; +import java.util.Locale; import java.util.Map; +import jalview.bin.Cache; import jalview.bin.Console; import jalview.bin.Jalview; import jalview.bin.argparser.Arg.Opt; @@ -707,4 +709,63 @@ public class ArgParser return args; } + public static enum Position + { + FIRST, BEFORE, AFTER + } + + public static String getValueFromSubValOrArg(ArgValuesMap avm, Arg a, + SubVals sv) + { + return getFromSubValArgOrPref(avm, a, sv, null, null, null); + } + + public static String getFromSubValArgOrPref(ArgValuesMap avm, Arg a, + SubVals sv, String key, String pref, String def) + { + return getFromSubValArgOrPref(avm, a, Position.FIRST, null, sv, key, + pref, def); + } + + public static String getFromSubValArgOrPref(ArgValuesMap avm, Arg a, + Position pos, ArgValue av, SubVals sv, String key, String pref, + String def) + { + if (key == null) + key = a.getName(); + if (sv != null && sv.has(key) && sv.get(key) != null) + return sv.get(key); + if (avm != null && avm.containsArg(a)) + { + String val = null; + if (pos == Position.FIRST && avm.getValue(a) != null) + return avm.getValue(a); + else if (pos == Position.BEFORE + && avm.getClosestPreviousArgValueOfArg(av, a) != null) + return avm.getClosestPreviousArgValueOfArg(av, a).getValue(); + else if (pos == Position.AFTER + && avm.getClosestNextArgValueOfArg(av, a) != null) + return avm.getClosestNextArgValueOfArg(av, a).getValue(); + } + return pref != null ? Cache.getDefault(pref, def) : def; + } + + public static boolean getBoolFromSubValOrArg(ArgValuesMap avm, Arg a, + SubVals sv) + { + return getFromSubValArgOrPref(avm, a, sv, null, null, false); + } + + public static boolean getFromSubValArgOrPref(ArgValuesMap avm, Arg a, + SubVals sv, String key, String pref, boolean def) + { + if (key == null) + key = a.getName(); + if (sv != null && sv.has(key) && sv.get(key) != null) + return sv.get(key).toLowerCase(Locale.ROOT).equals("true"); + if (avm != null && avm.containsArg(a)) + return avm.getBoolean(a); + return pref != null ? Cache.getDefault(pref, def) : def; + } + } \ No newline at end of file diff --git a/src/jalview/bin/argparser/ArgValuesMap.java b/src/jalview/bin/argparser/ArgValuesMap.java index 2117ee9..176dc7c 100644 --- a/src/jalview/bin/argparser/ArgValuesMap.java +++ b/src/jalview/bin/argparser/ArgValuesMap.java @@ -92,8 +92,7 @@ public class ArgValuesMap { if (m == null || !m.containsKey(a)) return false; - return a.hasOption(Opt.STRING) ? getArgValue(a) != null - : this.getBoolean(a); + return a.hasOption(Opt.STRING) ? getArgValue(a) != null : true; } public boolean hasValue(Arg a, String val) diff --git a/src/jalview/gui/AlignFrame.java b/src/jalview/gui/AlignFrame.java index 2d02e79..5fdaabb 100644 --- a/src/jalview/gui/AlignFrame.java +++ b/src/jalview/gui/AlignFrame.java @@ -3440,8 +3440,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, @Override public void overviewMenuItem_actionPerformed(ActionEvent e) { - boolean showHiddenRegions = Cache.getDefault(Preferences.SHOW_OV_HIDDEN_AT_START, - false); + boolean showHiddenRegions = Cache + .getDefault(Preferences.SHOW_OV_HIDDEN_AT_START, false); openOverviewPanel(showHiddenRegions); } @@ -3452,14 +3452,15 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, return alignPanel.overviewPanel; } JInternalFrame frame = new JInternalFrame(); - final OverviewPanel overview = new OverviewPanel(alignPanel, frame, showHidden); + final OverviewPanel overview = new OverviewPanel(alignPanel, frame, + showHidden); frame.setContentPane(overview); - Desktop.addInternalFrame(frame, "", true, frame.getWidth(), frame.getHeight(), - true, true); + Desktop.addInternalFrame(frame, "", true, frame.getWidth(), + frame.getHeight(), true, true); frame.setFrameIcon(null); frame.pack(); frame.setLayer(JLayeredPane.PALETTE_LAYER); - final AlignmentPanel thePanel = this.alignPanel; + final AlignmentPanel thePanel = this.alignPanel; frame.addInternalFrameListener( new javax.swing.event.InternalFrameAdapter() { @@ -3478,7 +3479,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, alignPanel.setOverviewPanel(overview); alignPanel.setOverviewTitle(this); - + return overview; } @@ -4133,7 +4134,6 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, return showNewickTree(nf, treeTitle, null, w, h, x, y); } - /** * Add a treeviewer for the tree extracted from a Newick file object to the * current alignment view @@ -4184,13 +4184,12 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, return tp; } - public void showContactMapTree(AlignmentAnnotation aa, PAEContactMatrix cm) { int x = 4, y = 5; int w = 400, h = 500; - + try { NewickFile fin = new NewickFile( @@ -4198,42 +4197,43 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, String title = "PAE Matrix Tree for " + cm.getReferenceSeq().getDisplayId(false); - showColumnWiseTree(fin, aa, title, w,h, x,y); + showColumnWiseTree(fin, aa, title, w, h, x, y); } catch (Throwable xx) { Console.error("Unexpected exception showing tree for contact matrix", xx); } } - public TreePanel showColumnWiseTree(NewickFile nf, AlignmentAnnotation aa, String treeTitle, - int w, int h, int x, int y) + + public TreePanel showColumnWiseTree(NewickFile nf, AlignmentAnnotation aa, + String treeTitle, int w, int h, int x, int y) { - try + try + { + nf.parse(); + if (nf.getTree() == null) { - nf.parse(); - if (nf.getTree() == null) - { - return null; - } - TreePanel tp = new TreePanel(alignPanel, nf, aa, title); - - tp.setSize(w, h); + return null; + } + TreePanel tp = new TreePanel(alignPanel, nf, aa, title); - if (x > 0 && y > 0) - { - tp.setLocation(x, y); - } + tp.setSize(w, h); - Desktop.addInternalFrame(tp, title, w, h); - return tp; - } catch (Throwable xx) + if (x > 0 && y > 0) { - Console.error("Unexpected exception showing tree for contact matrix", - xx); + tp.setLocation(x, y); } - return null; + + Desktop.addInternalFrame(tp, title, w, h); + return tp; + } catch (Throwable xx) + { + Console.error("Unexpected exception showing tree for contact matrix", + xx); + } + return null; } - + private boolean buildingMenu = false; /** @@ -5027,7 +5027,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, * to add view name "Original" if necessary */ alignPanel.setOverviewTitle(this); - + /* * switch panels and set Overview title (if there is one * because it was opened automatically) @@ -5698,7 +5698,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, * update non-sequence-related annotations */ @Override - protected void setAnnotationsVisibility(boolean visible, + public void setAnnotationsVisibility(boolean visible, boolean forSequences, boolean forAlignment) { AlignmentAnnotation[] anns = alignPanel.getAlignment() diff --git a/src/jalview/gui/StructureChooser.java b/src/jalview/gui/StructureChooser.java index 7d2d907..35972b0 100644 --- a/src/jalview/gui/StructureChooser.java +++ b/src/jalview/gui/StructureChooser.java @@ -67,6 +67,7 @@ import jalview.fts.core.FTSRestRequest; import jalview.fts.core.FTSRestResponse; import jalview.fts.service.pdb.PDBFTSRestClient; import jalview.fts.service.threedbeacons.TDB_FTSData; +import jalview.gui.StructureViewer.ViewerType; import jalview.gui.structurechooser.PDBStructureChooserQuerySource; import jalview.gui.structurechooser.StructureChooserQuerySource; import jalview.gui.structurechooser.ThreeDBStructureChooserQuerySource; @@ -1344,6 +1345,15 @@ public class StructureChooser extends GStructureChooser StructureSelectionManager ssm, final PDBEntry[] pdbEntriesToView, final AlignmentPanel alignPanel, SequenceI[] sequences) { + return launchStructureViewer(ssm, pdbEntriesToView, alignPanel, + sequences, null); + } + + private StructureViewer launchStructureViewer( + StructureSelectionManager ssm, final PDBEntry[] pdbEntriesToView, + final AlignmentPanel alignPanel, SequenceI[] sequences, + ViewerType viewerType) + { long progressId = sequences.hashCode(); setProgressBar(MessageManager .getString("status.launching_3d_structure_viewer"), progressId); @@ -1408,7 +1418,8 @@ public class StructureChooser extends GStructureChooser MessageManager.getString( "status.fetching_3d_structures_for_selected_entries"), progressId); - theViewer.viewStructures(pdbEntriesToView, sequences, alignPanel); + theViewer.viewStructures(pdbEntriesToView, sequences, alignPanel, + viewerType); } else { @@ -1416,7 +1427,8 @@ public class StructureChooser extends GStructureChooser "status.fetching_3d_structures_for", pdbEntriesToView[0].getId()), progressId); // Can we pass a pre-computeMappinged pdbFile? - theViewer.viewStructures(pdbEntriesToView[0], sequences, alignPanel); + theViewer.viewStructures(pdbEntriesToView[0], sequences, alignPanel, + viewerType); } setProgressBar(null, progressId); // remember the last viewer we used... @@ -1721,20 +1733,20 @@ public class StructureChooser extends GStructureChooser boolean doXferSettings) { openStructureFileForSequence(ssm, sc, ap, seq, prompt, sFilename, tft, - paeFilename, false, true, doXferSettings); + paeFilename, false, true, doXferSettings, null); } public static void openStructureFileForSequence( StructureSelectionManager ssm, StructureChooser sc, AlignmentPanel ap, SequenceI seq, boolean prompt, String sFilename, TFType tft, String paeFilename, - boolean forceHeadless, boolean showAnnotations, - boolean doXferSettings) + boolean forceHeadless, boolean showRefAnnotations, + boolean doXferSettings, ViewerType viewerType) { boolean headless = forceHeadless; if (sc == null) { - headless = true; + // headless = true; prompt = false; sc = new StructureChooser(new SequenceI[] { seq }, seq, ap, false); } @@ -1747,14 +1759,15 @@ public class StructureChooser extends GStructureChooser // if headless, "false" in the sc constructor above will avoid GUI behaviour // in sc.launchStructureViewer() - sc.launchStructureViewer(ssm, new PDBEntry[] { fileEntry }, ap, - new SequenceI[] - { seq }); + if (!headless && !(viewerType == null)) + sc.launchStructureViewer(ssm, new PDBEntry[] { fileEntry }, ap, + new SequenceI[] + { seq }, viewerType); if (headless) sc.mainFrame.dispose(); - if (showAnnotations) + if (showRefAnnotations) showReferenceAnnotationsForSequence(ap.alignFrame, seq); } diff --git a/src/jalview/gui/StructureViewer.java b/src/jalview/gui/StructureViewer.java index 5effa1a..0c12eb2 100644 --- a/src/jalview/gui/StructureViewer.java +++ b/src/jalview/gui/StructureViewer.java @@ -119,6 +119,12 @@ public class StructureViewer public JalviewStructureDisplayI viewStructures(PDBEntry[] pdbs, SequenceI[] seqs, AlignmentPanel ap) { + return viewStructures(pdbs, seqs, ap, null); + } + + public JalviewStructureDisplayI viewStructures(PDBEntry[] pdbs, + SequenceI[] seqs, AlignmentPanel ap, ViewerType viewerType) + { JalviewStructureDisplayI viewer = onlyOnePdb(pdbs, seqs, ap); if (viewer != null) { @@ -128,7 +134,8 @@ public class StructureViewer return viewer; } - ViewerType viewerType = getViewerType(); + if (viewerType == null) + viewerType = getViewerType(); Map seqsForPdbs = getSequencesForPdbs(pdbs, seqs); @@ -299,6 +306,12 @@ public class StructureViewer public JalviewStructureDisplayI viewStructures(PDBEntry pdb, SequenceI[] seqsForPdb, AlignmentPanel ap) { + return viewStructures(pdb, seqsForPdb, ap, null); + } + + public JalviewStructureDisplayI viewStructures(PDBEntry pdb, + SequenceI[] seqsForPdb, AlignmentPanel ap, ViewerType viewerType) + { if (sview != null) { sview.setAlignAddedStructures(superposeAdded); @@ -311,7 +324,8 @@ public class StructureViewer sview.raiseViewer(); return sview; } - ViewerType viewerType = getViewerType(); + if (viewerType == null) + viewerType = getViewerType(); if (viewerType.equals(ViewerType.JMOL)) { sview = new AppJmol(pdb, seqsForPdb, null, ap); diff --git a/src/jalview/jbgui/GAlignFrame.java b/src/jalview/jbgui/GAlignFrame.java index 8ae97b0..5b886b6 100755 --- a/src/jalview/jbgui/GAlignFrame.java +++ b/src/jalview/jbgui/GAlignFrame.java @@ -2157,7 +2157,7 @@ public class GAlignFrame extends JInternalFrame * @param forAlignment * update non-sequence-related annotations */ - protected void setAnnotationsVisibility(boolean visible, + public void setAnnotationsVisibility(boolean visible, boolean forSequences, boolean forAlignment) { diff --git a/src/jalview/jbgui/GPreferences.java b/src/jalview/jbgui/GPreferences.java index 69c0f4d..03538ef 100755 --- a/src/jalview/jbgui/GPreferences.java +++ b/src/jalview/jbgui/GPreferences.java @@ -39,6 +39,7 @@ import java.awt.event.KeyListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.Arrays; +import java.util.EnumSet; import java.util.List; import javax.swing.AbstractCellEditor; @@ -1679,10 +1680,16 @@ public class GPreferences extends JPanel */ structViewer.setFont(LABEL_FONT); structViewer.setBounds(new Rectangle(190, ypos, 120, height)); + for (ViewerType v : EnumSet.allOf(ViewerType.class)) + { + structViewer.addItem(v.name()); + } + /* structViewer.addItem(ViewerType.JMOL.name()); structViewer.addItem(ViewerType.CHIMERA.name()); structViewer.addItem(ViewerType.CHIMERAX.name()); structViewer.addItem(ViewerType.PYMOL.name()); + */ structViewer.addActionListener(new ActionListener() { @Override diff --git a/test/jalview/bin/CommandsTest2.java b/test/jalview/bin/CommandsTest2.java new file mode 100644 index 0000000..71452e2 --- /dev/null +++ b/test/jalview/bin/CommandsTest2.java @@ -0,0 +1,173 @@ +package jalview.bin; + +import java.util.Date; +import java.util.List; + +import org.testng.Assert; +import org.testng.annotations.AfterClass; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import jalview.api.AlignViewportI; +import jalview.datamodel.AlignmentAnnotation; +import jalview.datamodel.AlignmentI; +import jalview.datamodel.SequenceI; +import jalview.gui.AlignFrame; +import jalview.gui.AlignmentPanel; +import jalview.gui.Desktop; +import jalview.gui.JvOptionPane; +import jalview.gui.StructureViewerBase; + +@Test +public class CommandsTest2 +{ + @BeforeClass(alwaysRun = true) + public static void setUpBeforeClass() throws Exception + { + Cache.loadProperties("test/jalview/testProps.jvprops"); + Date oneHourFromNow = new Date( + System.currentTimeMillis() + 3600 * 1000); + Cache.setDateProperty("JALVIEW_NEWS_RSS_LASTMODIFIED", oneHourFromNow); + if (Desktop.instance != null) + Desktop.instance.closeAll_actionPerformed(null); + + } + + @AfterClass(alwaysRun = true) + public static void resetProps() + { + Cache.loadProperties("test/jalview/testProps.jvprops"); + } + + @BeforeClass(alwaysRun = true) + public void setUpJvOptionPane() + { + JvOptionPane.setInteractiveMode(false); + JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION); + } + + @AfterMethod(alwaysRun = true) + public void tearDown() + { + if (Desktop.instance != null) + Desktop.instance.closeAll_actionPerformed(null); + } + + @Test( + groups = + { "Functional" }, + dataProvider = "structureOpeningArgsParams") + public void structureOpeningArgsTest(String cmdLine, int seqNum, + int annNum, int viewerNum) + { + String[] args = cmdLine.split("\\s+"); + + Jalview.main(args); + AlignFrame[] afs = Desktop.getAlignFrames(); + Assert.assertNotNull(afs); + Assert.assertTrue(afs.length > 0); + + AlignFrame af = afs[0]; + Assert.assertNotNull(af); + + AlignmentPanel ap = af.alignPanel; + Assert.assertNotNull(ap); + + AlignmentI al = ap.getAlignment(); + Assert.assertNotNull(al); + + List seqs = al.getSequences(); + Assert.assertNotNull(seqs); + + Assert.assertEquals(seqs.size(), seqNum, "Wrong number of sequences"); + + AlignViewportI av = ap.getAlignViewport(); + Assert.assertNotNull(av); + + AlignmentAnnotation[] aas = al.getAlignmentAnnotation(); + int visibleAnn = 0; + for (AlignmentAnnotation aa : aas) + { + if (aa.visible) + visibleAnn++; + } + + Assert.assertEquals(visibleAnn, annNum, + "Wrong number of visible annotations"); + + if (viewerNum > -1) + { + try + { + Thread.sleep(100); + } catch (InterruptedException e) + { + // TODO Auto-generated catch block + e.printStackTrace(); + } + List openViewers = Desktop.instance + .getStructureViewers(ap, null); + Assert.assertNotNull(openViewers); + Assert.assertEquals(openViewers.size(), viewerNum, + "Wrong number of structure viewers opened"); + } + } + + @DataProvider(name = "structureOpeningArgsParams") + public Object[][] structureOpeningArgsParams() + { + /* + String cmdLine, + int seqNum, + int annNum, + int viewerNum, + String propsFile + */ + return new Object[][] { { "--nonews --nosplash --debug " + + "--open=examples/uniref50.fa " + "--colour=gecos:flower " + + "--structure=[seqid=FER1_SPIOL]examples/AlphaFold/AF-P00221-F1-model_v4.cif " + + "--paematrix=examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json " + + "--props=test/jalview/bin/commandsTest2.jvprops1 ", + 15, 7, 1 }, + { "--nonews --nosplash --debug " + "--open=examples/uniref50.fa " + + "--colour=gecos:flower " + + "--structure=[seqid=FER1_SPIOL]examples/AlphaFold/AF-P00221-F1-model_v4.cif " + + "--paematrix=examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json " + + "--props=test/jalview/bin/commandsTest2.jvprops2 ", + 15, 4, 1 }, + { "--nonews --nosplash --debug " + "--open=examples/uniref50.fa " + + "--colour=gecos:flower " + + "--structure=[seqid=FER1_SPIOL]examples/AlphaFold/AF-P00221-F1-model_v4.cif " + + "--paematrix=examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json " + + "--nossannotations " + + "--props=test/jalview/bin/commandsTest2.jvprops1 ", + 15, 4, 1 }, + { "--nonews --nosplash --debug " + "--open=examples/uniref50.fa " + + "--colour=gecos:flower " + + "--structure=[seqid=FER1_SPIOL]examples/AlphaFold/AF-P00221-F1-model_v4.cif " + + "--paematrix=examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json " + + "--noannotations " + + "--props=test/jalview/bin/commandsTest2.jvprops1 ", + 15, 3, 1 }, + { "--nonews --nosplash --debug " + "--open=examples/uniref50.fa " + + "--colour=gecos:flower " + + "--structure=[seqid=FER1_SPIOL]examples/AlphaFold/AF-P00221-F1-model_v4.cif " + + "--paematrix=examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json " + + "--noannotations " + "--nossannotations " + + "--props=test/jalview/bin/commandsTest2.jvprops1 ", + 15, 0, 1 }, + { "--nonews --nosplash --debug " + "--open=examples/uniref50.fa " + + "--colour=gecos:flower " + + "--structure=[seqid=FER1_SPIOL]examples/AlphaFold/AF-P00221-F1-model_v4.cif " + + "--paematrix=examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json " + + "--noannotations " + "--nossannotations " + + "--props=test/jalview/bin/commandsTest2.jvprops1 ", + 15, 0, 1 }, + { "--argfile=test/jalview/bin/commandsTest2.argfile1 ", 16, 19, 3 }, + { "--argfile=test/jalview/bin/commandsTest2.argfile2 ", 16, 0, 2 }, + // + }; + } +} diff --git a/test/jalview/bin/commandsTest2.argfile1 b/test/jalview/bin/commandsTest2.argfile1 new file mode 100644 index 0000000..a9c602d --- /dev/null +++ b/test/jalview/bin/commandsTest2.argfile1 @@ -0,0 +1,25 @@ +--debug +--nonews +--nosplash +--substitutions +--open=examples/test_fab41.result/sample.a2m +--annotations +--ssannotations +--colour=gecos:flower +--structure=[viewer=jmol;tempfac=plddt;paematrix={dirname}/test_fab41_unrelaxed_rank_1_model_3_scores.json]{dirname}/test_fab41_unrelaxed_rank_1_model_3.pdb +--structure={dirname}/test_fab41_unrelaxed_rank_2_model_4.pdb +--structureviewer=jmol +--paematrix={dirname}/test_fab41_unrelaxed_rank_2_model_4_scores.json +--tempfac=plddt +--structure={dirname}/test_fab41_unrelaxed_rank_3_model_2.pdb +--structureviewer=jmol +--paematrix={dirname}/test_fab41_unrelaxed_rank_3_model_2_scores.json +--tempfac=plddt +--structure=[viewer=none]{dirname}/test_fab41_unrelaxed_rank_4_model_5.pdb +--paematrix={dirname}/test_fab41_unrelaxed_rank_4_model_5_scores.json +--tempfac=plddt +--structure={dirname}/test_fab41_unrelaxed_rank_5_model_1.pdb +--structureviewer=none +--tempfac=plddt +--paematrix={dirname}/test_fab41_unrelaxed_rank_5_model_1_scores.json +#--headless diff --git a/test/jalview/bin/commandsTest2.argfile2 b/test/jalview/bin/commandsTest2.argfile2 new file mode 100644 index 0000000..d057858 --- /dev/null +++ b/test/jalview/bin/commandsTest2.argfile2 @@ -0,0 +1,26 @@ +--debug +--nonews +--nosplash +--substitutions +--open=examples/test_fab41.result/sample.a2m +--noannotations +--nossannotations +--colour=gecos:flower +--structure=[tempfac=plddt;paematrix={dirname}/test_fab41_unrelaxed_rank_1_model_3_scores.json]{dirname}/test_fab41_unrelaxed_rank_1_model_3.pdb +--structureviewer=none +--structure={dirname}/test_fab41_unrelaxed_rank_2_model_4.pdb +--structureviewer=jmol +--paematrix={dirname}/test_fab41_unrelaxed_rank_2_model_4_scores.json +--tempfac=plddt +--structure={dirname}/test_fab41_unrelaxed_rank_3_model_2.pdb +--structureviewer=jmol +--paematrix={dirname}/test_fab41_unrelaxed_rank_3_model_2_scores.json +--tempfac=plddt +--structure=[viewer=none]{dirname}/test_fab41_unrelaxed_rank_4_model_5.pdb +--paematrix={dirname}/test_fab41_unrelaxed_rank_4_model_5_scores.json +--tempfac=plddt +--structure={dirname}/test_fab41_unrelaxed_rank_5_model_1.pdb +--structureviewer=none +--tempfac=plddt +--paematrix={dirname}/test_fab41_unrelaxed_rank_5_model_1_scores.json +#--headless diff --git a/test/jalview/bin/commandsTest2.jvprops1 b/test/jalview/bin/commandsTest2.jvprops1 new file mode 100644 index 0000000..bd510e7 --- /dev/null +++ b/test/jalview/bin/commandsTest2.jvprops1 @@ -0,0 +1,4 @@ +SHOW_STARTUP_FILE=false +SPLASH=false +STRUCT_FROM_PDB=true +ADD_TEMPFACT_ANN=true diff --git a/test/jalview/bin/commandsTest2.jvprops2 b/test/jalview/bin/commandsTest2.jvprops2 new file mode 100644 index 0000000..576269a --- /dev/null +++ b/test/jalview/bin/commandsTest2.jvprops2 @@ -0,0 +1,4 @@ +SHOW_STARTUP_FILE=false +SPLASH=false +STRUCT_FROM_PDB=false +ADD_TEMPFACT_ANN=true diff --git a/test/jalview/gui/StructureChooserTest.java b/test/jalview/gui/StructureChooserTest.java index b74baf1..b4eaf68 100644 --- a/test/jalview/gui/StructureChooserTest.java +++ b/test/jalview/gui/StructureChooserTest.java @@ -24,15 +24,23 @@ import static org.testng.Assert.assertEquals; import static org.testng.AssertJUnit.assertNotNull; import static org.testng.AssertJUnit.assertTrue; +import java.io.File; import java.util.Collection; +import java.util.List; import java.util.Vector; import org.junit.Assert; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeMethod; +import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import jalview.api.AlignViewportI; +import jalview.bin.Cache; +import jalview.bin.Jalview; +import jalview.datamodel.AlignmentAnnotation; +import jalview.datamodel.AlignmentI; import jalview.datamodel.DBRefEntry; import jalview.datamodel.PDBEntry; import jalview.datamodel.Sequence; @@ -43,8 +51,15 @@ import jalview.fts.service.pdb.PDBFTSRestClient; import jalview.fts.service.pdb.PDBFTSRestClientTest; import jalview.fts.service.threedbeacons.TDBeaconsFTSRestClient; import jalview.fts.threedbeacons.TDBeaconsFTSRestClientTest; +import jalview.gui.StructureViewer.ViewerType; import jalview.gui.structurechooser.PDBStructureChooserQuerySource; +import jalview.io.DataSourceType; +import jalview.io.FileFormatException; +import jalview.io.FileFormatI; +import jalview.io.FileLoader; +import jalview.io.IdentifyFile; import jalview.jbgui.FilterOption; +import jalview.structure.StructureImportSettings.TFType; import junit.extensions.PA; @Test(singleThreaded = true) @@ -259,4 +274,140 @@ public class StructureChooserTest assertEquals("abcde12345afg", PDBStructureChooserQuerySource.sanitizeSeqName(name)); } + + @Test(groups = { "Functional" }, dataProvider = "openStructureFileParams") + public void openStructureFileForSequenceTest(String alfile, String seqid, + String sFilename, TFType tft, String paeFilename, + boolean showRefAnnotations, boolean doXferSettings, + ViewerType viewerType, int seqNum, int annNum, int viewerNum, + String propsFile) + { + Cache.loadProperties( + propsFile == null ? "test/jalview/io/testProps.jvprops" + : propsFile); + + Jalview.main( + propsFile == null ? null : new String[] + { "--props", propsFile }); + if (Desktop.instance != null) + Desktop.instance.closeAll_actionPerformed(null); + JvOptionPane.setInteractiveMode(false); + JvOptionPane.setMockResponse(JvOptionPane.OK_OPTION); + + FileLoader fileLoader = new FileLoader(true); + FileFormatI format = null; + File alFile = new File(alfile); + try + { + format = new IdentifyFile().identify(alFile, DataSourceType.FILE); + } catch (FileFormatException e1) + { + Assert.fail( + "Unknown file format for '" + alFile.getAbsolutePath() + "'"); + } + + AlignFrame af = fileLoader.LoadFileWaitTillLoaded(alFile, + DataSourceType.FILE, format); + AlignmentPanel ap = af.alignPanel; + Assert.assertNotNull("No alignPanel", ap); + + AlignmentI al = ap.getAlignment(); + Assert.assertNotNull(al); + + SequenceI seq = al.findName(seqid); + Assert.assertNotNull("Sequence '" + seqid + "' not found in alignment", + seq); + + StructureChooser.openStructureFileForSequence(null, null, ap, seq, + false, sFilename, tft, paeFilename, false, showRefAnnotations, + doXferSettings, viewerType); + + List seqs = al.getSequences(); + Assert.assertNotNull(seqs); + + Assert.assertEquals("Wrong number of sequences", seqNum, seqs.size()); + + AlignViewportI av = ap.getAlignViewport(); + Assert.assertNotNull(av); + + AlignmentAnnotation[] aas = al.getAlignmentAnnotation(); + int visibleAnn = 0; + for (AlignmentAnnotation aa : aas) + { + if (aa.visible) + visibleAnn++; + } + Assert.assertEquals("Wrong number of viewed annotations", annNum, + visibleAnn); + + if (viewerNum > -1) + { + try + { + Thread.sleep(100); + } catch (InterruptedException e) + { + // TODO Auto-generated catch block + e.printStackTrace(); + } + List openViewers = Desktop.instance + .getStructureViewers(ap, null); + Assert.assertNotNull(openViewers); + Assert.assertEquals("Wrong number of structure viewers opened", + viewerNum, openViewers.size()); + } + + if (af != null) + { + af.setVisible(false); + af.dispose(); + } + } + + @DataProvider(name = "openStructureFileParams") + public Object[][] openStructureFileParams() + { + /* + String alFile, + String seqid, + String structureFilename, + TFType tft, + String paeFilename, + boolean showRefAnnotations, + boolean doXferSettings, // false for Commands + ViewerType viewerType, + int seqNum, + int annNum, + int viewerNum, + String propsFile + */ + return new Object[][] { + /* + */ + { "examples/uniref50.fa", "FER1_SPIOL", + "examples/AlphaFold/AF-P00221-F1-model_v4.cif", TFType.DEFAULT, + "examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json", + true, false, null, 15, 7, 0, null }, + { "examples/uniref50.fa", "FER1_SPIOL", + "examples/AlphaFold/AF-P00221-F1-model_v4.cif", TFType.PLDDT, + "examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json", + true, false, null, 15, 7, 0, null }, + { "examples/uniref50.fa", "FER1_SPIOL", + "examples/AlphaFold/AF-P00221-F1-model_v4.cif", TFType.PLDDT, + "examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json", + false, false, null, 15, 4, 0, null }, + { "examples/uniref50.fa", "FER1_SPIOL", + "examples/AlphaFold/AF-P00221-F1-model_v4.cif", TFType.DEFAULT, + "examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json", + true, false, ViewerType.JMOL, 15, 7, 1, null }, + { "examples/uniref50.fa", "FER1_SPIOL", + "examples/AlphaFold/AF-P00221-F1-model_v4.cif", TFType.PLDDT, + "examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json", + true, false, ViewerType.JMOL, 15, 7, 1, null }, + { "examples/uniref50.fa", "FER1_SPIOL", + "examples/AlphaFold/AF-P00221-F1-model_v4.cif", TFType.PLDDT, + "examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json", + false, false, ViewerType.JMOL, 15, 4, 1, null }, }; + } + } diff --git a/test/jalview/testProps.jvprops b/test/jalview/testProps.jvprops index 95da22e..fc58822 100644 --- a/test/jalview/testProps.jvprops +++ b/test/jalview/testProps.jvprops @@ -83,3 +83,4 @@ USE_PROXY=false WRAP_ALIGNMENT=false #DAS_REGISTRY_URL=http\://www.dasregistry.org/das/ # retired 01/05/2015 DAS_REGISTRY_URL=http\://www.ebi.ac.uk/das-srv/registry/das/ +SPLASH=false diff --git a/test/jalview/ws/dbsources/EBIAlphaFoldTest.java b/test/jalview/ws/dbsources/EBIAlphaFoldTest.java index e619b8e..076ee7e 100644 --- a/test/jalview/ws/dbsources/EBIAlphaFoldTest.java +++ b/test/jalview/ws/dbsources/EBIAlphaFoldTest.java @@ -1,14 +1,22 @@ package jalview.ws.dbsources; +import java.io.File; import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import org.json.simple.parser.ParseException; import org.junit.Assert; +import org.testng.FileAssert; import org.testng.annotations.BeforeClass; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import jalview.datamodel.Sequence; +import jalview.gui.Desktop; import jalview.gui.JvOptionPane; +import jalview.structure.StructureMapping; +import jalview.structure.StructureSelectionManager; import jalview.ws.datamodel.alphafold.PAEContactMatrix; public class EBIAlphaFoldTest @@ -40,4 +48,36 @@ public class EBIAlphaFoldTest new FileInputStream(paeFile))); Assert.assertNotEquals("No data from " + paeFile, cm.getMax(), 0); } + + @Test(groups = { "Functional" }, dataProvider = "getPDBandPAEfiles") + public void checkImportPAEToStructure(String pdbFile, String paeFile) + { + FileInputStream paeInput = null; + try + { + paeInput = new FileInputStream(paeFile); + } catch (FileNotFoundException e) + { + e.printStackTrace(); + FileAssert.assertFile(new File(paeFile), + "Test file '" + paeFile + "' doesn't seem to exist"); + } + StructureSelectionManager ssm = StructureSelectionManager + .getStructureSelectionManager(Desktop.instance); + + StructureMapping[] smArray = ssm.getMapping(pdbFile); + + try + { + boolean done = EBIAlfaFold.importPaeJSONAsContactMatrixToStructure( + smArray, paeInput, "label"); + Assert.assertTrue( + "Import of '" + paeFile + "' didn't complete successfully", + done); + } catch (IOException | ParseException e) + { + e.printStackTrace(); + } + + } } diff --git a/utils/eclipse/launcher b/utils/eclipse/launcher new file mode 100755 index 0000000..ccb1d75 --- /dev/null +++ b/utils/eclipse/launcher @@ -0,0 +1,3 @@ +#!/usr/bin/env sh + +java -cp "./bin/main:./j11lib/*:./resources:./help" jalview.bin.Launcher "${@}"