From e1a435a213f105bac3ea0258c6fe26f11df2a392 Mon Sep 17 00:00:00 2001 From: gmungoc Date: Mon, 5 Aug 2019 13:00:32 +0100 Subject: [PATCH] JAL-3390 Chimera showStructures() respects visible/chain selections --- src/jalview/appletgui/AppletJmol.java | 3 +- src/jalview/ext/jmol/JalviewJmolBinding.java | 13 ++-- .../ext/rbvi/chimera/JalviewChimeraBinding.java | 70 ++++++-------------- src/jalview/gui/AlignFrame.java | 2 +- src/jalview/gui/AppJmol.java | 17 +---- src/jalview/gui/ChimeraViewFrame.java | 20 ++---- src/jalview/gui/StructureViewerBase.java | 3 +- src/jalview/jbgui/GStructureViewer.java | 25 +++++++ .../structures/models/AAStructureBindingModel.java | 42 +++++++++++- 9 files changed, 107 insertions(+), 88 deletions(-) diff --git a/src/jalview/appletgui/AppletJmol.java b/src/jalview/appletgui/AppletJmol.java index 3d1442d..f5ab595 100644 --- a/src/jalview/appletgui/AppletJmol.java +++ b/src/jalview/appletgui/AppletJmol.java @@ -406,7 +406,8 @@ public class AppletJmol extends EmbmenuFrame implements } } } - jmb.centerViewer(toshow); + jmb.setChainsToShow(toshow); + jmb.centerViewer(); } void closeViewer() diff --git a/src/jalview/ext/jmol/JalviewJmolBinding.java b/src/jalview/ext/jmol/JalviewJmolBinding.java index 762b08e..e5a1733 100644 --- a/src/jalview/ext/jmol/JalviewJmolBinding.java +++ b/src/jalview/ext/jmol/JalviewJmolBinding.java @@ -135,15 +135,12 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel /** * prepare the view for a given set of models/chains. chainList contains * strings of the form 'pdbfilename:Chaincode' - * - * @param chainList - * list of chains to make visible */ - public void centerViewer(Vector chainList) + public void centerViewer() { StringBuilder cmd = new StringBuilder(128); int mlength, p; - for (String lbl : chainList) + for (String lbl : chainsToShow) { mlength = 0; do @@ -159,7 +156,8 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel { cmd.setLength(cmd.length() - 4); } - evalStateCommand("select *;restrict " + cmd + ";cartoon;center " + cmd); + String command = "select *;restrict " + cmd + ";cartoon;center " + cmd; + evalStateCommand(command); } public void closeViewer() @@ -1419,8 +1417,9 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel } @Override - public void showStructures(AlignViewportI av) + public void showStructures(AlignViewportI av, boolean refocus) { // TODO show Jmol structure optionally restricted to visible alignment + // and/or selected chains } } diff --git a/src/jalview/ext/rbvi/chimera/JalviewChimeraBinding.java b/src/jalview/ext/rbvi/chimera/JalviewChimeraBinding.java index 6fa06d2..1731a05 100644 --- a/src/jalview/ext/rbvi/chimera/JalviewChimeraBinding.java +++ b/src/jalview/ext/rbvi/chimera/JalviewChimeraBinding.java @@ -32,7 +32,6 @@ import jalview.datamodel.SearchResultMatchI; import jalview.datamodel.SearchResultsI; import jalview.datamodel.SequenceFeature; import jalview.datamodel.SequenceI; -import jalview.datamodel.VisibleContigsIterator; import jalview.httpserver.AbstractRequestHandler; import jalview.io.DataSourceType; import jalview.schemes.ColourSchemeI; @@ -54,6 +53,7 @@ import java.util.ArrayList; import java.util.BitSet; import java.util.Collections; import java.util.Hashtable; +import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -251,43 +251,6 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel } /** - * Tells Chimera to display only the specified chains - * - * @param toshow - */ - public void showChains(List toshow) - { - /* - * Construct a chimera command like - * - * ~display #*;~ribbon #*;ribbon :.A,:.B - */ - StringBuilder cmd = new StringBuilder(64); - boolean first = true; - for (String chain : toshow) - { - int modelNumber = getModelNoForChain(chain); - String showChainCmd = modelNumber == -1 ? "" - : modelNumber + ":." + chain.split(":")[1]; - if (!first) - { - cmd.append(","); - } - cmd.append(showChainCmd); - first = false; - } - - /* - * could append ";focus" to this command to resize the display to fill the - * window, but it looks more helpful not to (easier to relate chains to the - * whole) - */ - final String command = "~display #*; ~ribbon #*; ribbon :" - + cmd.toString(); - sendChimeraCommand(command, false); - } - - /** * Close down the Jalview viewer and listener, and (optionally) the associated * Chimera window. */ @@ -1324,20 +1287,20 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel } @Override - public void showStructures(AlignViewportI av) + public void showStructures(AlignViewportI av, boolean refocus) { StringBuilder cmd = new StringBuilder(128); cmd.append("~display; ~ribbon;"); - if (isShowAlignmentOnly()) + String atomSpec = getMappedResidues(av); + cmd.append("ribbon ").append(atomSpec); + if (!isShowAlignmentOnly()) { - String atomSpec = getMappedResidues(av); - cmd.append("ribbon ").append(atomSpec); + cmd.append("chain @CA|P; ribbon"); } - else + if (refocus) { - cmd.append("chain @CA|P; ribbon"); + cmd.append("; focus"); } - cmd.append("; focus"); sendChimeraCommand(cmd.toString(), false); } @@ -1382,10 +1345,21 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel && alignment.findIndex(theSequence) > -1) { String chainCd = mapping.getChain(); - - // TODO only process sequence ranges within visible columns - VisibleContigsIterator visible = alignment.getHiddenColumns() + if (!isShowChain(mapping.getPdbId(), chainCd)) + { + continue; + } + Iterator visible; + if (isShowAlignmentOnly()) + { + visible = alignment.getHiddenColumns() .getVisContigsIterator(0, width, true); + } + else + { + visible = Collections.singletonList(new int[] { 0, width }) + .iterator(); + } while (visible.hasNext()) { int[] visibleRegion = visible.next(); diff --git a/src/jalview/gui/AlignFrame.java b/src/jalview/gui/AlignFrame.java index c847260..bdf4711 100644 --- a/src/jalview/gui/AlignFrame.java +++ b/src/jalview/gui/AlignFrame.java @@ -459,9 +459,9 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, af.setMenusForViewport(); } + avp.setSelected(true); AlignmentPanel ap = (AlignmentPanel) avp; ap.updateLayout(); - ap.setSelected(true); ap.alignFrame.setMenusForViewport(); } } diff --git a/src/jalview/gui/AppJmol.java b/src/jalview/gui/AppJmol.java index b28b81c..9179be6 100644 --- a/src/jalview/gui/AppJmol.java +++ b/src/jalview/gui/AppJmol.java @@ -42,9 +42,7 @@ import java.awt.event.ActionEvent; import java.io.File; import java.util.ArrayList; import java.util.List; -import java.util.Vector; -import javax.swing.JCheckBoxMenuItem; import javax.swing.JPanel; import javax.swing.JSplitPane; import javax.swing.SwingUtilities; @@ -263,19 +261,8 @@ public class AppJmol extends StructureViewerBase @Override void showSelectedChains() { - Vector toshow = new Vector<>(); - for (int i = 0; i < chainMenu.getItemCount(); i++) - { - if (chainMenu.getItem(i) instanceof JCheckBoxMenuItem) - { - JCheckBoxMenuItem item = (JCheckBoxMenuItem) chainMenu.getItem(i); - if (item.isSelected()) - { - toshow.addElement(item.getText()); - } - } - } - jmb.centerViewer(toshow); + setSelectedChains(); + jmb.centerViewer(); } @Override diff --git a/src/jalview/gui/ChimeraViewFrame.java b/src/jalview/gui/ChimeraViewFrame.java index fd84b37..1a5ed5e 100644 --- a/src/jalview/gui/ChimeraViewFrame.java +++ b/src/jalview/gui/ChimeraViewFrame.java @@ -50,7 +50,6 @@ import java.util.Collections; import java.util.List; import java.util.Random; -import javax.swing.JCheckBoxMenuItem; import javax.swing.JInternalFrame; import javax.swing.JMenu; import javax.swing.JMenuItem; @@ -363,19 +362,12 @@ public class ChimeraViewFrame extends StructureViewerBase @Override void showSelectedChains() { - List toshow = new ArrayList<>(); - for (int i = 0; i < chainMenu.getItemCount(); i++) - { - if (chainMenu.getItem(i) instanceof JCheckBoxMenuItem) - { - JCheckBoxMenuItem item = (JCheckBoxMenuItem) chainMenu.getItem(i); - if (item.isSelected()) - { - toshow.add(item.getText()); - } - } - } - jmb.showChains(toshow); + setSelectedChains(); + + /* + * refresh display without resizing - easier to see what changed + */ + jmb.showStructures(getAlignmentPanel().getAlignViewport(), false); } /** diff --git a/src/jalview/gui/StructureViewerBase.java b/src/jalview/gui/StructureViewerBase.java index 47bc823..cc431ac 100644 --- a/src/jalview/gui/StructureViewerBase.java +++ b/src/jalview/gui/StructureViewerBase.java @@ -718,7 +718,8 @@ public abstract class StructureViewerBase extends GStructureViewer public void actionPerformed(ActionEvent e) { getBinding().setShowAlignmentOnly(showAlignmentOnly.isSelected()); - getBinding().showStructures(getAlignmentPanel().getAlignViewport()); + getBinding().showStructures(getAlignmentPanel().getAlignViewport(), + true); } }); viewMenu.add(showAlignmentOnly); diff --git a/src/jalview/jbgui/GStructureViewer.java b/src/jalview/jbgui/GStructureViewer.java index 2094201..418e413 100644 --- a/src/jalview/jbgui/GStructureViewer.java +++ b/src/jalview/jbgui/GStructureViewer.java @@ -28,6 +28,8 @@ import java.awt.BorderLayout; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.util.ArrayList; +import java.util.List; import javax.swing.JCheckBoxMenuItem; import javax.swing.JInternalFrame; @@ -270,4 +272,27 @@ public abstract class GStructureViewer extends JInternalFrame { } + + /** + * Saves the selected entries in the 'View Chain' menu into a list. Entries are + * formatted as "pdbid:chainid". Only the selected chains should be drawn in the + * structure display. + */ + protected void setSelectedChains() + { + List chains = new ArrayList<>(); + for (int i = 0; i < chainMenu.getItemCount(); i++) + { + JMenuItem menuItem = chainMenu.getItem(i); + if (menuItem instanceof JCheckBoxMenuItem) + { + JCheckBoxMenuItem item = (JCheckBoxMenuItem) menuItem; + if (item.isSelected()) + { + chains.add(item.getText()); + } + } + } + getBinding().setChainsToShow(chains); + } } diff --git a/src/jalview/structures/models/AAStructureBindingModel.java b/src/jalview/structures/models/AAStructureBindingModel.java index 6159757..1fc59ed 100644 --- a/src/jalview/structures/models/AAStructureBindingModel.java +++ b/src/jalview/structures/models/AAStructureBindingModel.java @@ -97,6 +97,13 @@ public abstract class AAStructureBindingModel private boolean showAlignmentOnly; + /* + * a list of chains "pdbid:chainid" to show in the viewer; + * empty means show all + */ + // TODO make private once showStructures() deals with this + protected List chainsToShow; + /** * Data bean class to simplify parameterisation in superposeStructures */ @@ -137,6 +144,7 @@ public abstract class AAStructureBindingModel { this.ssm = ssm; this.sequence = seqs; + chainsToShow = new ArrayList<>(); } /** @@ -156,6 +164,8 @@ public abstract class AAStructureBindingModel this.nucleotide = Comparison.isNucleotide(sequenceIs); this.pdbEntry = pdbentry; this.protocol = protocol; + chainsToShow = new ArrayList<>(); + resolveChains(); } @@ -862,8 +872,10 @@ public abstract class AAStructureBindingModel * mapped to visible regions of the alignment. * * @param alignViewportI + * @param refocus + * if true, refit the display to the viewer */ - public void showStructures(AlignViewportI alignViewportI) + public void showStructures(AlignViewportI alignViewportI, boolean refocus) { // override with implementation } @@ -882,4 +894,32 @@ public abstract class AAStructureBindingModel colourBySequence(ap); } } + + /** + * Sets the list of chains to display (as "pdbid:chain"), where an empty list + * means show all + * + * @param chains + */ + public void setChainsToShow(List chains) + { + chainsToShow = chains; + } + + /** + * Answers true if the specified structure and chain are selected to be shown in + * the viewer, else false + * + * @param pdbId + * @param chainId + * @return + */ + protected boolean isShowChain(String pdbId, String chainId) + { + if (chainsToShow.isEmpty()) + { + return true; + } + return chainsToShow.contains(pdbId + ":" + chainId); + } } -- 1.7.10.2