JAL-3404 explicit getModelForPdbFile lookup
[jalview.git] / src / jalview / ext / jmol / JmolCommands.java
index 7a52ba9..a900701 100644 (file)
@@ -27,32 +27,41 @@ import jalview.api.SequenceRenderer;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.HiddenColumns;
 import jalview.datamodel.SequenceI;
+import jalview.ext.rbvi.chimera.AtomSpecModel;
 import jalview.renderer.seqfeatures.FeatureColourFinder;
 import jalview.structure.StructureMapping;
 import jalview.structure.StructureMappingcommandSet;
 import jalview.structure.StructureSelectionManager;
+import jalview.util.StructureCommands;
 
 import java.awt.Color;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 
 /**
- * Routines for generating Jmol commands for Jalview/Jmol binding another
- * cruisecontrol test.
+ * Routines for generating Jmol commands for Jalview/Jmol binding
  * 
  * @author JimP
  * 
  */
-public class JmolCommands
+public class JmolCommands extends StructureCommands
 {
+  private static final String COMMA = ",";
 
   /**
-   * Jmol utility which constructs the commands to colour chains by the given
-   * alignment
-   * 
-   * @returns Object[] { Object[] { <model being coloured>,
+   * Get commands to colour structure by sequence
    * 
+   * @param ssm
+   * @param files
+   * @param sequence
+   * @param sr
+   * @param viewPanel
+   * @return
+   * @deprecated only called by applet code
+   * @see #getColourBySequenceCommand(Map)
    */
+  @Deprecated
   public static StructureMappingcommandSet[] getColourBySequenceCommand(
           StructureSelectionManager ssm, String[] files,
           SequenceI[][] sequence, SequenceRenderer sr,
@@ -63,14 +72,14 @@ public class JmolCommands
     AlignViewportI viewport = viewPanel.getAlignViewport();
     HiddenColumns cs = viewport.getAlignment().getHiddenColumns();
     AlignmentI al = viewport.getAlignment();
-    List<StructureMappingcommandSet> cset = new ArrayList<StructureMappingcommandSet>();
+    List<StructureMappingcommandSet> cset = new ArrayList<>();
 
     for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++)
     {
       StructureMapping[] mapping = ssm.getMapping(files[pdbfnum]);
       StringBuffer command = new StringBuffer();
       StructureMappingcommandSet smc;
-      ArrayList<String> str = new ArrayList<String>();
+      ArrayList<String> str = new ArrayList<>();
 
       if (mapping == null || mapping.length < 1)
       {
@@ -128,7 +137,7 @@ public class JmolCommands
               String newSelcom = (mapping[m].getChain() != " "
                       ? ":" + mapping[m].getChain()
                       : "") + "/" + (pdbfnum + 1) + ".1" + ";color["
-                      + col.getRed() + "," + col.getGreen() + ","
+                      + col.getRed() + COMMA + col.getGreen() + COMMA
                       + col.getBlue() + "]";
               if (command.length() > newSelcom.length() && command
                       .substring(command.length() - newSelcom.length())
@@ -141,7 +150,7 @@ public class JmolCommands
               // - execute command and flush
 
               if (command.length() > 0
-                      && command.charAt(command.length() - 1) == ';')
+                      && command.charAt(command.length() - 1) != ';')
               {
                 command.append(";");
               }
@@ -207,4 +216,79 @@ public class JmolCommands
     return sb;
   }
 
+  /**
+   * Answers a Jmol 'color' command to colour residues as described by the given
+   * map of {@code <Color, AtomSpecModel>}
+   * 
+   * @param map
+   * @return
+   */
+  public static String[] getColourBySequenceCommand(
+          Map<Object, AtomSpecModel> map)
+  {
+    String[] cmds = new String[map.keySet().size()];
+
+    int i = 0;
+    for (Object o : map.keySet())
+    {
+      StringBuilder cmd = new StringBuilder(128);
+      Color c = (Color) o;
+      String atomSpec = getAtomSpec(map.get(o));
+      cmd.append("color (").append(atomSpec).append(") [")
+              .append(c.getRed()).append(COMMA).append(c.getGreen())
+              .append(COMMA).append(c.getBlue()).append("];");
+      cmds[i] = cmd.toString();
+      i++;
+    }
+
+    return cmds;
+  }
+
+  /**
+   * Builds a Jmol syntax selection expression from the given model, for example
+   * 
+   * <pre>
+   * (61-64,70)&:A/1.1,(12-25,41-44)&:B/1.1,12:A/2.1
+   * for model 1, chain A, residues 61-64 and 70, chain B residues 12-25 and 41-44, model 2 chain A residue 12
+   * </pre>
+   * 
+   * Note the brackets to group multiple residue ranges for the same chain
+   * (without bracketing, ranges would apply to all chains)
+   * 
+   * @param atomSpecModel
+   * @return
+   */
+  public static String getAtomSpec(AtomSpecModel atomSpecModel)
+  {
+    StringBuilder sb = new StringBuilder(64);
+    for (int model : atomSpecModel.getModels())
+    {
+      for (String chain : atomSpecModel.getChains(model))
+      {
+        if (sb.length() > 0)
+        {
+          sb.append(COMMA);
+        }
+        boolean firstRange = true;
+
+        List<int[]> rangeList = atomSpecModel.getRanges(model, chain);
+
+        if (rangeList.size() > 1)
+        {
+          sb.append("(");
+        }
+        appendResidueRange(sb, rangeList, null, firstRange);
+        if (rangeList.size() > 1)
+        {
+          sb.append(")&");
+        }
+        sb.append(":").append(chain.trim()).append("/")
+                .append(String.valueOf(model + 1))
+                .append(".1");
+      }
+    }
+
+    return sb.toString();
+  }
+
 }