JAL-4307 View->Ligands submenu, implementation for Jmol and documentation
authorJames Procter <j.procter@dundee.ac.uk>
Thu, 19 Oct 2023 17:27:33 +0000 (18:27 +0100)
committerJames Procter <j.procter@dundee.ac.uk>
Thu, 19 Oct 2023 17:27:33 +0000 (18:27 +0100)
help/help/html/features/jmol.html
help/markdown/releases/release-2_11_3_0.md
resources/lang/Messages.properties
src/jalview/api/structures/JalviewStructureDisplayI.java
src/jalview/ext/jmol/JalviewJmolBinding.java
src/jalview/ext/jmol/JmolCommands.java
src/jalview/gui/StructureViewerBase.java
src/jalview/jbgui/GStructureViewer.java
src/jalview/structure/StructureCommandsI.java
src/jalview/structures/models/AAStructureBindingModel.java

index ac2489b..491a03f 100644 (file)
         <li><strong>Show Chains<br>
         </strong><em>Select which of the PDB file's chains are to be
             displayed.</em></li>
         <li><strong>Show Chains<br>
         </strong><em>Select which of the PDB file's chains are to be
             displayed.</em></li>
-        <li><strong>Colour by ..<br></strong><em>Submenu
+                               <li><strong>Ligands<br>
+                               </strong><em>When available, allows the display of all, none or specific
+                                               ligands (also known as HETATM groups) in the Jmol view, using CPK
+                                               spacefilling.</em></li>
+                               <li><strong>Colour by ..<br></strong><em>Submenu
             allowing specific alignment views to be selected for
             colouring associated chains in the structure display. This
             menu contains all the alignment views associated with the
             allowing specific alignment views to be selected for
             colouring associated chains in the structure display. This
             menu contains all the alignment views associated with the
index 8847eb2..d7bdd25 100644 (file)
@@ -19,6 +19,7 @@ channel: "release"
 - <!-- JAL-4273 --> Visible adjuster marks to grab and adjust annotation panel height and id width
 - <!-- JAL-4260 --> Adjustable ID margin when alignment is wrapped
 - <!-- JAL-4274 --> Command line options and configurable bitmap export preferences for height, width and scale factor
 - <!-- JAL-4273 --> Visible adjuster marks to grab and adjust annotation panel height and id width
 - <!-- JAL-4260 --> Adjustable ID margin when alignment is wrapped
 - <!-- JAL-4274 --> Command line options and configurable bitmap export preferences for height, width and scale factor
+- <!-- JAL-4307 --> Show or hide ligands in a Jmol structure view via View Ligands submenu
 
 ### Improved support for working with computationally determined models
 - <!-- JAL-3895 --> Alphafold red/orange/yellow/green colourscheme for structures
 
 ### Improved support for working with computationally determined models
 - <!-- JAL-3895 --> Alphafold red/orange/yellow/green colourscheme for structures
index 70eeb95..58f9805 100644 (file)
@@ -1468,3 +1468,4 @@ label.command_line_arguments = Command Line Arguments
 warning.using_old_command_line_arguments = It looks like you are using old command line arguments.  These are now deprecated and will be removed in a future release of Jalview.\nFind out about the new command line arguments at\n
 warning.using_mixed_command_line_arguments = Jalview cannot use both old (-arg) and new (--arg) command line arguments.  Please check your command line arguments.\ne.g. {0} and {1}
 warning.the_following_errors = The following errors and warnings occurred whilst processing files:
 warning.using_old_command_line_arguments = It looks like you are using old command line arguments.  These are now deprecated and will be removed in a future release of Jalview.\nFind out about the new command line arguments at\n
 warning.using_mixed_command_line_arguments = Jalview cannot use both old (-arg) and new (--arg) command line arguments.  Please check your command line arguments.\ne.g. {0} and {1}
 warning.the_following_errors = The following errors and warnings occurred whilst processing files:
+action.show_hetatm = Show Ligands (HETATM)
index 532e545..77f2b6d 100644 (file)
@@ -21,6 +21,8 @@
 package jalview.api.structures;
 
 import java.io.File;
 package jalview.api.structures;
 
 import java.io.File;
+import java.util.Collections;
+import java.util.List;
 
 import jalview.api.AlignmentViewPanel;
 import jalview.datamodel.PDBEntry;
 
 import jalview.api.AlignmentViewPanel;
 import jalview.datamodel.PDBEntry;
@@ -192,4 +194,12 @@ public interface JalviewStructureDisplayI
 
   File saveSession();
 
 
   File saveSession();
 
+  /**
+   * 
+   * @return heteroatoms in a form suitable for display and passing to command generator to display hetatms
+   */
+  default List<String> getHetatms() {
+    return Collections.EMPTY_LIST;
+  }
+
 }
 }
index dc18369..c8ce3cd 100644 (file)
@@ -26,6 +26,8 @@ import java.awt.event.ComponentListener;
 import java.io.File;
 import java.net.URL;
 import java.util.ArrayList;
 import java.io.File;
 import java.net.URL;
 import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.StringTokenizer;
 import java.util.List;
 import java.util.Map;
 import java.util.StringTokenizer;
@@ -41,6 +43,8 @@ import org.jmol.api.JmolViewer;
 import org.jmol.c.CBK;
 import org.jmol.viewer.Viewer;
 
 import org.jmol.c.CBK;
 import org.jmol.viewer.Viewer;
 
+import com.google.common.collect.Lists;
+
 import jalview.api.AlignmentViewPanel;
 import jalview.api.FeatureRenderer;
 import jalview.api.FeatureSettingsModelI;
 import jalview.api.AlignmentViewPanel;
 import jalview.api.FeatureRenderer;
 import jalview.api.FeatureSettingsModelI;
@@ -184,7 +188,25 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel
 
   // End StructureListener
   // //////////////////////////
 
   // End StructureListener
   // //////////////////////////
-
+  
+  ////////////////////////////
+  // HETATM get
+  //
+  
+  @Override
+  public List<String> getHetatmNames()
+  {
+    HashMap<String,String> hetlist=new HashMap();
+    for (int mc=0;mc<jmolViewer.ms.mc; mc++)
+    {
+      Map<String,String> hets = jmolViewer.ms.getHeteroList(mc);
+      hetlist.putAll(hets);
+    }
+    return Arrays.asList(hetlist.keySet().toArray(new String[0]));
+  }
+  //
+  ////////////////////////////
+  
   @Override
   public float[][] functionXY(String functionName, int x, int y)
   {
   @Override
   public float[][] functionXY(String functionName, int x, int y)
   {
index f9ba1e4..106d458 100644 (file)
@@ -323,6 +323,31 @@ public class JmolCommands extends StructureCommandsBase
             "restore STATE \"" + Platform.escapeBackslashes(filePath) + "\"");
   }
 
             "restore STATE \"" + Platform.escapeBackslashes(filePath) + "\"");
   }
 
+  @Override
+  public List<StructureCommandI> showHetatms(List<String> toShow)
+  {
+    // always clear the current hetero cpk display
+    
+    StringBuilder sb = new StringBuilder();
+    sb.append("select hetero; cpk off;");
+    
+    if (toShow != null && !toShow.isEmpty())
+    {
+      // select what was requested
+      sb.append("select ");
+      boolean or = false;
+      for (String k : toShow)
+      {
+        sb.append(or ? " or " : " ");
+        sb.append(k);
+        or = true;
+      }
+      // and show as
+      sb.append("; cpk;");
+    }
+    
+    return Arrays.asList(new StructureCommand(sb.toString()));
+  }
   /**
    * Obsolete method, only referenced from
    * jalview.javascript.MouseOverStructureListener
   /**
    * Obsolete method, only referenced from
    * jalview.javascript.MouseOverStructureListener
index ed42ffa..09d2dcb 100644 (file)
@@ -141,6 +141,8 @@ public abstract class StructureViewerBase extends GStructureViewer
 
   protected boolean allChainsSelected = false;
 
 
   protected boolean allChainsSelected = false;
 
+  protected boolean allHetatmBeingSelected = false;
+
   protected JMenu viewSelectionMenu;
 
   /**
   protected JMenu viewSelectionMenu;
 
   /**
@@ -604,6 +606,80 @@ public abstract class StructureViewerBase extends GStructureViewer
       chainMenu.add(menuItem);
     }
   }
       chainMenu.add(menuItem);
     }
   }
+  void setHetatmMenuItems(List<String> hetatmNames)
+  {
+    hetatmMenu.removeAll();
+    if (hetatmNames == null || hetatmNames.isEmpty())
+    {
+      hetatmMenu.setVisible(false);
+      return;
+    }
+    hetatmMenu.setVisible(true);
+    allHetatmBeingSelected=false;
+    JMenuItem allMenuItem = new JMenuItem(
+            MessageManager.getString("label.all"));
+    JMenuItem noneMenuItem = new JMenuItem(
+            MessageManager.getString("label.none"));
+    allMenuItem.addActionListener(new ActionListener()
+    {
+      @Override
+      public void actionPerformed(ActionEvent e) {
+      {
+        allHetatmBeingSelected=true;
+        // Toggle state of everything - on
+        for (int i = 0; i < hetatmMenu.getItemCount(); i++)
+        {
+          if (hetatmMenu.getItem(i) instanceof JCheckBoxMenuItem)
+          {
+            ((JCheckBoxMenuItem) hetatmMenu.getItem(i)).setSelected(true);
+          }
+        }
+        allHetatmBeingSelected=false;
+        showSelectedHetatms();
+      }
+      }});
+
+    noneMenuItem.addActionListener(new ActionListener()
+    {
+      @Override
+      public void actionPerformed(ActionEvent e) {
+      {
+        allHetatmBeingSelected=true;
+        // Toggle state of everything off
+        for (int i = 0; i < hetatmMenu.getItemCount(); i++)
+        {
+          if (hetatmMenu.getItem(i) instanceof JCheckBoxMenuItem)
+          {
+            ((JCheckBoxMenuItem) hetatmMenu.getItem(i)).setSelected(false);
+          }
+        }
+        allHetatmBeingSelected=false;
+        showSelectedHetatms();
+      }
+      }});
+    hetatmMenu.add(noneMenuItem);
+    hetatmMenu.add(allMenuItem);
+
+    for (String chain : hetatmNames)
+    {
+      JCheckBoxMenuItem menuItem = new JCheckBoxMenuItem(chain, false);
+      menuItem.addItemListener(new ItemListener()
+      {
+        @Override
+        public void itemStateChanged(ItemEvent evt)
+        {
+          if (!allHetatmBeingSelected)
+          { 
+            // update viewer only when we were clicked, not programmatically
+            // checked/unchecked
+            showSelectedHetatms();
+          }
+        }
+      });
+
+      hetatmMenu.add(menuItem);
+    }
+  }
 
   /**
    * Action on selecting one of Jalview's registered colour schemes
 
   /**
    * Action on selecting one of Jalview's registered colour schemes
@@ -1009,6 +1085,7 @@ public abstract class StructureViewerBase extends GStructureViewer
       return;
     }
     setChainMenuItems(binding.getChainNames());
       return;
     }
     setChainMenuItems(binding.getChainNames());
+    setHetatmMenuItems(binding.getHetatmNames());
 
     this.setTitle(binding.getViewerTitle(getViewerName(), true));
 
 
     this.setTitle(binding.getViewerTitle(getViewerName(), true));
 
@@ -1158,7 +1235,25 @@ public abstract class StructureViewerBase extends GStructureViewer
     }
     getBinding().showChains(toshow);
   }
     }
     getBinding().showChains(toshow);
   }
-
+  /**
+   * Display selected hetatms in viewer
+   */
+  protected void showSelectedHetatms()
+  {
+    List<String> toshow = new ArrayList<>();
+    for (int i = 0; i < hetatmMenu.getItemCount(); i++)
+    {
+      if (hetatmMenu.getItem(i) instanceof JCheckBoxMenuItem)
+      {
+        JCheckBoxMenuItem item = (JCheckBoxMenuItem) hetatmMenu.getItem(i);
+        if (item.isSelected())
+        {
+          toshow.add(item.getText());
+        }
+      }
+    }
+    getBinding().showHetatms(toshow);
+  }
   /**
    * Tries to fetch a PDB file and save to a temporary local file. Returns the
    * saved file path if successful, or null if not.
   /**
    * Tries to fetch a PDB file and save to a temporary local file. Returns the
    * saved file path if successful, or null if not.
index 18e4c9f..fceb50c 100644 (file)
@@ -52,6 +52,8 @@ public abstract class GStructureViewer extends JInternalFrame
 
   protected JMenu chainMenu;
 
 
   protected JMenu chainMenu;
 
+  protected JMenu hetatmMenu;
+
   protected JMenu viewerActionMenu;
 
   protected JMenuItem alignStructs;
   protected JMenu viewerActionMenu;
 
   protected JMenuItem alignStructs;
@@ -152,6 +154,9 @@ public abstract class GStructureViewer extends JInternalFrame
     chainMenu = new JMenu();
     chainMenu.setText(MessageManager.getString("action.show_chain"));
 
     chainMenu = new JMenu();
     chainMenu.setText(MessageManager.getString("action.show_chain"));
 
+    hetatmMenu = new JMenu();
+    hetatmMenu.setText(MessageManager.getString("action.show_hetatm"));
+
     fitToWindow = new JMenuItem();
     fitToWindow.setText(MessageManager.getString("label.fit_to_window"));
     fitToWindow.addActionListener(new ActionListener()
     fitToWindow = new JMenuItem();
     fitToWindow.setText(MessageManager.getString("label.fit_to_window"));
     fitToWindow.addActionListener(new ActionListener()
@@ -197,6 +202,7 @@ public abstract class GStructureViewer extends JInternalFrame
     savemenu.add(png);
     savemenu.add(eps);
     viewMenu.add(chainMenu);
     savemenu.add(png);
     savemenu.add(eps);
     viewMenu.add(chainMenu);
+    viewMenu.add(hetatmMenu);
     helpMenu.add(helpItem);
 
     menuBar.add(fileMenu);
     helpMenu.add(helpItem);
 
     menuBar.add(fileMenu);
index b1e1486..8ba94b0 100644 (file)
@@ -21,6 +21,7 @@
 package jalview.structure;
 
 import java.awt.Color;
 package jalview.structure;
 
 import java.awt.Color;
+import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 
 import java.util.List;
 import java.util.Map;
 
@@ -254,4 +255,8 @@ public interface StructureCommandsI
   StructureCommandI getResidueAttributes(String attName);
 
   List<StructureCommandI> centerViewOn(List<AtomSpecModel> residues);
   StructureCommandI getResidueAttributes(String attName);
 
   List<StructureCommandI> centerViewOn(List<AtomSpecModel> residues);
+
+  default List<StructureCommandI> showHetatms(List<String> toShow) {
+    return Collections.EMPTY_LIST;
+  }
 }
 }
index dcedafa..55955a8 100644 (file)
@@ -26,6 +26,7 @@ import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.BitSet;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.BitSet;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.List;
@@ -2006,4 +2007,18 @@ public abstract class AAStructureBindingModel
   {
     return 0;
   }
   {
     return 0;
   }
+
+  public List<String> getHetatmNames() {
+    return Collections.EMPTY_LIST;
+  }
+  /**
+   * Generates and executes a command to show the given hetatm types as CPK
+   * 
+   * @param toShow - one or more of strings from getHetatmNames
+   */
+  public void showHetatms(List<String> toShow)
+  {
+    executeCommands(commandGenerator.showHetatms(toShow), false, "Adjusting hetatm visibility");
+  }
+
 }
 }