JAL-3390 JAL-3400 revised commands to show structure / hide chains
authorgmungoc <g.m.carstairs@dundee.ac.uk>
Wed, 21 Aug 2019 08:41:58 +0000 (09:41 +0100)
committergmungoc <g.m.carstairs@dundee.ac.uk>
Wed, 21 Aug 2019 08:41:58 +0000 (09:41 +0100)
src/jalview/appletgui/AppletJmol.java
src/jalview/ext/jmol/JalviewJmolBinding.java
src/jalview/ext/rbvi/chimera/JalviewChimeraBinding.java
src/jalview/gui/StructureViewerBase.java
src/jalview/jbgui/GStructureViewer.java
src/jalview/structures/models/AAStructureBindingModel.java

index 1ac3abc..44a73d9 100644 (file)
@@ -400,13 +400,13 @@ public class AppletJmol extends EmbmenuFrame implements
       if (chainMenu.getItem(i) instanceof CheckboxMenuItem)
       {
         CheckboxMenuItem item = (CheckboxMenuItem) chainMenu.getItem(i);
-        if (item.getState())
+        if (!item.getState())
         {
           toshow.addElement(item.getLabel());
         }
       }
     }
-    jmb.setChainsToShow(toshow);
+    jmb.setChainsToHide(toshow);
     jmb.centerViewer();
   }
 
index fe64154..6da0eb5 100644 (file)
@@ -141,7 +141,7 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel
   {
     StringBuilder cmd = new StringBuilder(128);
     int mlength, p;
-    for (String lbl : chainsToShow)
+    for (String lbl : chainsToHide)
     {
       mlength = 0;
       do
@@ -151,13 +151,14 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel
       } while (p < mlength && mlength < (lbl.length() - 2));
       // TODO: lookup each pdb id and recover proper model number for it.
       cmd.append(":" + lbl.substring(mlength + 1) + " /"
-              + (1 + getModelNum(chainFile.get(lbl))) + " or ");
+              + (getModelNum(chainFile.get(lbl))) + " or ");
     }
     if (cmd.length() > 0)
     {
       cmd.setLength(cmd.length() - 4);
     }
-    String command = "select *;restrict " + cmd + ";cartoon;center " + cmd;
+    // todo: revised command is untested - but this method is obsolete anyway
+    String command = "select *;hide " + cmd + ";cartoon;center " + cmd;
     evalStateCommand(command);
   }
 
@@ -564,6 +565,13 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel
    */
   public abstract void refreshPdbEntries();
 
+  /**
+   * Answers the Jmol model number (1, 2, ...) for the given file name, or -1 if
+   * not found
+   * 
+   * @param modelFileName
+   * @return
+   */
   private int getModelNum(String modelFileName)
   {
     String[] mfn = getStructureFiles();
@@ -575,7 +583,7 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel
     {
       if (mfn[i].equalsIgnoreCase(modelFileName))
       {
-        return i;
+        return i + 1;
       }
     }
     return -1;
@@ -1120,8 +1128,8 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel
           // add an entry for every chain in the model
           for (int i = 0; i < pdb.getChains().size(); i++)
           {
-            String chid = new String(
-                    pdb.getId() + ":" + pdb.getChains().elementAt(i).id);
+            String chid = pdb.getId() + ":"
+                    + pdb.getChains().elementAt(i).id;
             chainFile.put(chid, fileName);
             chainNames.add(chid);
           }
@@ -1407,8 +1415,30 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel
   @Override
   public void showStructures(AlignViewportI av, boolean refocus)
   {
+    String cmd = buildShowStructuresCommand(av, refocus);
+    evalStateCommand(cmd);
+  }
+
+  /**
+   * Builds a command to show parts of the structure, depending on whether
+   * <ul>
+   * <li>all structures or regions mapped to alignment only are shown</li>
+   * <li>all chains or only selected chains are shown</li>
+   * </ul>
+   * 
+   * @param av
+   * @param refocus
+   * @return
+   */
+  protected String buildShowStructuresCommand(AlignViewportI av,
+          boolean refocus)
+  {
     StringBuilder cmd = new StringBuilder(128);
-    if (isShowAlignmentOnly())
+    if (!isShowAlignmentOnly())
+    {
+      cmd.append("display *");
+    }
+    else
     {
       AtomSpecModel model = getShownResidues(av);
       String atomSpec = JmolCommands.getAtomSpec(model);
@@ -1416,16 +1446,39 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel
       cmd.append("hide *;display ").append(atomSpec)
               .append("; select displayed");
     }
-    else
+
+    /*
+     * hide any chains not selected to be shown
+     */
+    if (!chainsToHide.isEmpty())
     {
-      cmd.append(";display *");
+      cmd.append("; hide add ");
+      boolean firstHide = true;
+      for (String pdbChain : chainsToHide)
+      {
+        String[] toks = pdbChain.split(":");
+        String chainId = toks[1];
+        int modelNo = getModelNum(chainFile.get(pdbChain));
+        if (modelNo == -1)
+        {
+          continue;
+        }
+        if (!firstHide)
+        {
+          cmd.append(",");
+        }
+        firstHide = false;
+        cmd.append(":").append(chainId).append("/")
+                .append(String.valueOf(modelNo)).append(".1");
+      }
     }
+
     cmd.append("; cartoon only");
     if (refocus)
     {
       cmd.append("; zoom 0");
     }
-    evalStateCommand(cmd.toString());
+    return cmd.toString();
   }
 
   /**
index 3498f23..fdd07f6 100644 (file)
@@ -77,6 +77,9 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
 
   private static final String ALPHACARBON = "CA";
 
+  /*
+   * lookup map of {pdbId:chain, filePath}
+   */
   private Hashtable<String, String> chainFile = new Hashtable<>();
 
   /*
@@ -1266,22 +1269,59 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
   @Override
   public void showStructures(AlignViewportI av, boolean refocus)
   {
+    String string = buildShowStructuresCommand(av, refocus);
+    sendChimeraCommand(string, false);
+  }
+
+  /**
+   * Builds a command to show parts of the structure, depending on whether
+   * <ul>
+   * <li>all structures or regions mapped to alignment only are shown</li>
+   * <li>all chains or only selected chains are shown</li>
+   * </ul>
+   * 
+   * @param av
+   * @param refocus
+   * @return
+   */
+  protected String buildShowStructuresCommand(AlignViewportI av,
+          boolean refocus)
+  {
     StringBuilder cmd = new StringBuilder(128);
-    cmd.append("~display; ~ribbon;");
+    cmd.append("~display");
 
-    AtomSpecModel model = getShownResidues(av);
-    String atomSpec = ChimeraCommands.getAtomSpec(model, this);
-    
-    cmd.append("ribbon ").append(atomSpec);
-    if (!isShowAlignmentOnly())
+    if (isShowAlignmentOnly())
     {
-      cmd.append("; chain @CA|P");
+      AtomSpecModel model = getShownResidues(av);
+      String atomSpec = ChimeraCommands.getAtomSpec(model, this);
+      if (!atomSpec.isEmpty())
+      {
+        cmd.append("; ~ribbon; ribbon ").append(atomSpec);
+      }
+    }
+    else
+    {
+      cmd.append("; ribbon");
+    }
+
+    /*
+     * hide any chains selected not to be shown
+     */
+    for (String pdbChain : chainsToHide)
+    {
+      String chainId = pdbChain.split(":")[1];
+      int modelNo = getModelNoForChain(pdbChain);
+      if (modelNo != -1)
+      {
+        cmd.append("; ~ribbon #").append(String.valueOf(modelNo))
+                .append(":.").append(chainId);
+      }
     }
     if (refocus)
     {
       cmd.append("; focus");
     }
-    sendChimeraCommand(cmd.toString(), false);
+    return cmd.toString();
   }
 
   @Override
index b327176..cdfa225 100644 (file)
@@ -76,6 +76,8 @@ import javax.swing.event.MenuListener;
 public abstract class StructureViewerBase extends GStructureViewer
         implements Runnable, ViewSetProvider
 {
+  private static final String UNMAPPED = "(unmapped)";
+
   /*
    * names for colour options (additional to Jalview colour schemes)
    */
@@ -545,13 +547,12 @@ public abstract class StructureViewerBase extends GStructureViewer
      * add a menu item for each structure and chain
      */
     Collections.sort(chainNames);
-    String lastSeqName = "";
     for (String chain : chainNames)
     {
       String seqName = getSequenceNameForChain(chain);
       if (seqName == null)
       {
-        continue;
+        seqName = UNMAPPED;
       }
       int nameLength = seqName.length();
       if (nameLength > 16)
@@ -559,12 +560,7 @@ public abstract class StructureViewerBase extends GStructureViewer
         seqName = seqName.substring(0, 8) + "..."
                 + seqName.substring(nameLength - 8, nameLength);
       }
-      String text = chain;
-      if (!lastSeqName.equals(seqName))
-      {
-        text = text + " " + seqName;
-      }
-      lastSeqName = seqName;
+      String text = chain + " " + seqName;
       menuItem = new JCheckBoxMenuItem(text, true);
       menuItem.addItemListener(new ItemListener()
       {
@@ -1122,7 +1118,7 @@ public abstract class StructureViewerBase extends GStructureViewer
    */
   protected void showSelectedChains()
   {
-    setSelectedChains();
+    setChainsToHide();
   
     /*
      * refresh display without resizing - easier to see what changed
index 7fc56d2..11cbfd7 100644 (file)
@@ -272,11 +272,11 @@ 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
+   * Saves the unselected entries in the 'View Chain' menu into a list. Entries
+   * are formatted as "pdbid:chainid". Unselected chains should be hidden in the
    * structure display.
    */
-  protected void setSelectedChains()
+  protected void setChainsToHide()
   {
     List<String> chains = new ArrayList<>();
     for (int i = 0; i < chainMenu.getItemCount(); i++)
@@ -285,12 +285,12 @@ public abstract class GStructureViewer extends JInternalFrame
       if (menuItem instanceof JCheckBoxMenuItem)
       {
         JCheckBoxMenuItem item = (JCheckBoxMenuItem) menuItem;
-        if (item.isSelected())
+        if (!item.isSelected())
         {
           chains.add(item.getText().split(" ")[0]);
         }
       }
     }
-    getBinding().setChainsToShow(chains);
+    getBinding().setChainsToHide(chains);
   }
 }
index 861daa6..be4333e 100644 (file)
@@ -100,11 +100,10 @@ public abstract class AAStructureBindingModel
   private boolean showAlignmentOnly;
 
   /*
-   * a list of chains "pdbid:chainid" to show in the viewer;
-   * empty means show all
+   * a list of chains "pdbid:chainid" to hide in the viewer
    */
   // TODO make private once deprecated JalviewJmolBinding.centerViewer removed
-  protected List<String> chainsToShow;
+  protected List<String> chainsToHide;
 
   private boolean hideHiddenRegions;
 
@@ -150,7 +149,7 @@ public abstract class AAStructureBindingModel
   {
     this.ssm = ssm;
     this.sequence = seqs;
-    chainsToShow = new ArrayList<>();
+    chainsToHide = new ArrayList<>();
   }
 
   /**
@@ -170,7 +169,7 @@ public abstract class AAStructureBindingModel
     this.nucleotide = Comparison.isNucleotide(sequenceIs);
     this.pdbEntry = pdbentry;
     this.protocol = protocol;
-    chainsToShow = new ArrayList<>();
+    chainsToHide = new ArrayList<>();
 
     resolveChains();
   }
@@ -925,14 +924,13 @@ public abstract class AAStructureBindingModel
   }
 
   /**
-   * Sets the list of chains to display (as "pdbid:chain"), where an empty list
-   * means show all
+   * Sets the list of chains to hide (as "pdbid:chain")
    * 
    * @param chains
    */
-  public void setChainsToShow(List<String> chains)
+  public void setChainsToHide(List<String> chains)
   {
-    chainsToShow = chains;
+    chainsToHide = chains;
   }
 
   /**
@@ -945,11 +943,11 @@ public abstract class AAStructureBindingModel
    */
   protected boolean isShowChain(String pdbId, String chainId)
   {
-    if (chainsToShow.isEmpty())
+    if (chainsToHide.isEmpty())
     {
       return true;
     }
-    return chainsToShow.contains(pdbId + ":" + chainId);
+    return !chainsToHide.contains(pdbId + ":" + chainId);
   }
 
   @Override