JAL-3390 pull up of getShownResidues() to AAStructureBindingModel
[jalview.git] / src / jalview / ext / rbvi / chimera / JalviewChimeraBinding.java
index ffce90c..44bcbe4 100644 (file)
  */
 package jalview.ext.rbvi.chimera;
 
+import jalview.api.AlignViewportI;
 import jalview.api.AlignmentViewPanel;
-import jalview.api.SequenceRenderer;
 import jalview.api.structures.JalviewStructureDisplayI;
 import jalview.bin.Cache;
 import jalview.datamodel.AlignmentI;
-import jalview.datamodel.ColumnSelection;
+import jalview.datamodel.HiddenColumns;
 import jalview.datamodel.PDBEntry;
 import jalview.datamodel.SearchResultMatchI;
 import jalview.datamodel.SearchResultsI;
@@ -76,10 +76,10 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
 
   private static final String ALPHACARBON = "CA";
 
-  private List<String> chainNames = new ArrayList<String>();
+  private List<String> chainNames = new ArrayList<>();
+
+  private Hashtable<String, String> chainFile = new Hashtable<>();
 
-  private Hashtable<String, String> chainFile = new Hashtable<String, String>();
-  
   /*
    * Object through which we talk to Chimera
    */
@@ -106,7 +106,7 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
   /*
    * Map of ChimeraModel objects keyed by PDB full local file name
    */
-  private Map<String, List<ChimeraModel>> chimeraMaps = new LinkedHashMap<String, List<ChimeraModel>>();
+  private Map<String, List<ChimeraModel>> chimeraMaps = new LinkedHashMap<>();
 
   String lastHighlightCommand;
 
@@ -133,7 +133,7 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
     String file = pe.getFile();
     try
     {
-      List<ChimeraModel> modelsToMap = new ArrayList<ChimeraModel>();
+      List<ChimeraModel> modelsToMap = new ArrayList<>();
       List<ChimeraModel> oldList = viewer.getModelList();
       boolean alreadyOpen = false;
 
@@ -192,7 +192,8 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
    * @param protocol
    */
   public JalviewChimeraBinding(StructureSelectionManager ssm,
-          PDBEntry[] pdbentry, SequenceI[][] sequenceIs, DataSourceType protocol)
+          PDBEntry[] pdbentry, SequenceI[][] sequenceIs,
+          DataSourceType protocol)
   {
     super(ssm, pdbentry, sequenceIs, protocol);
     viewer = new ChimeraManager(new StructureManager(true));
@@ -241,55 +242,18 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
       viewer.startListening(chimeraListener.getUri());
     } catch (BindException e)
     {
-      System.err.println("Failed to start Chimera listener: "
-              + e.getMessage());
+      System.err.println(
+              "Failed to start Chimera listener: " + e.getMessage());
     }
   }
 
   /**
-   * Tells Chimera to display only the specified chains
-   * 
-   * @param toshow
-   */
-  public void showChains(List<String> 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.
    */
   public void closeViewer(boolean closeChimera)
   {
-    getSsm().removeStructureViewerListener(this, this.getPdbFile());
+    getSsm().removeStructureViewerListener(this, this.getStructureFiles());
     if (closeChimera)
     {
       viewer.exitChimera();
@@ -337,10 +301,10 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
    */
   @Override
   public String superposeStructures(AlignmentI[] _alignment,
-          int[] _refStructure, ColumnSelection[] _hiddenCols)
+          int[] _refStructure, HiddenColumns[] _hiddenCols)
   {
     StringBuilder allComs = new StringBuilder(128);
-    String[] files = getPdbFile();
+    String[] files = getStructureFiles();
 
     if (!waitForFileLoad(files))
     {
@@ -353,7 +317,7 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
     {
       int refStructure = _refStructure[a];
       AlignmentI alignment = _alignment[a];
-      ColumnSelection hiddenCols = _hiddenCols[a];
+      HiddenColumns hiddenCols = _hiddenCols[a];
 
       if (refStructure >= files.length)
       {
@@ -498,7 +462,8 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
          * @see
          * https://www.cgl.ucsf.edu/chimera/docs/UsersGuide/midas/match.html
          */
-        command.append("match ").append(getModelSpec(pdbfnum)).append(":");
+        command.append("match ").append(getModelSpec(pdbfnum))
+                .append(":");
         command.append(selcom[pdbfnum]);
         command.append("@").append(
                 structures[pdbfnum].isRna ? PHOSPHORUS : ALPHACARBON);
@@ -515,11 +480,11 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
         if (debug)
         {
           System.out.println("Select regions:\n" + selectioncom.toString());
-          System.out.println("Superimpose command(s):\n"
-                  + command.toString());
+          System.out.println(
+                  "Superimpose command(s):\n" + command.toString());
         }
-        allComs.append("~display all; chain @CA|P; ribbon ")
-                .append(selectioncom.toString())
+        allComs/*.append("~display all; chain @CA|P; ribbon ")
+                .append(selectioncom.toString())*/
                 .append(";" + command.toString());
       }
     }
@@ -536,13 +501,24 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
       {
         System.out.println("Select regions:\n" + selectioncom.toString());
       }
-      allComs.append("; ~display all; chain @CA|P; ribbon ")
-              .append(selectioncom.toString()).append("; focus");
+      allComs.append("; ~display "); // all");
+      if (!isShowAlignmentOnly())
+      {
+        allComs.append("; ribbon; chain @CA|P");
+      }
+      else
+      {
+        allComs.append("; ~ribbon");
+      }
+      allComs.append("; ribbon ").append(selectioncom.toString())
+              .append("; focus");
       List<String> chimeraReplies = sendChimeraCommand(allComs.toString(),
               true);
       for (String reply : chimeraReplies)
       {
-        if (reply.toLowerCase().contains("unequal numbers of atoms"))
+        String lowerCase = reply.toLowerCase();
+        if (lowerCase.contains("unequal numbers of atoms")
+                || lowerCase.contains("at least"))
         {
           error = reply;
         }
@@ -564,7 +540,8 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
    * @param pdbfnum
    * @return
    */
-  protected String getModelSpec(int pdbfnum)
+  @Override
+  public String getModelSpec(int pdbfnum)
   {
     if (pdbfnum < 0 || pdbfnum >= getPdbCount())
     {
@@ -577,9 +554,10 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
      * to the Chimera command 'list models type molecule', see
      * ChimeraManager.getModelList().
      */
-    List<ChimeraModel> maps = chimeraMaps.get(getPdbFile()[pdbfnum]);
+    List<ChimeraModel> maps = chimeraMaps.get(getStructureFiles()[pdbfnum]);
     boolean hasSubModels = maps != null && maps.size() > 1;
-    return "#" + String.valueOf(pdbfnum) + (hasSubModels ? ".1" : "");
+    String spec = "#" + String.valueOf(pdbfnum);
+    return hasSubModels ? spec + ".1" : spec;
   }
 
   /**
@@ -596,8 +574,8 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
       return true;
     }
 
-    boolean launched = viewer.launchChimera(StructureManager
-            .getChimeraPaths());
+    boolean launched = viewer
+            .launchChimera(StructureManager.getChimeraPaths());
     if (launched)
     {
       startChimeraProcessMonitor();
@@ -689,16 +667,15 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
 
   /**
    * @param files
-   * @param sr
    * @param viewPanel
    * @return
    */
   @Override
   protected StructureMappingcommandSet[] getColourBySequenceCommands(
-          String[] files, SequenceRenderer sr, AlignmentViewPanel viewPanel)
+          String[] files, AlignmentViewPanel viewPanel)
   {
-    return ChimeraCommands.getColourBySequenceCommand(getSsm(), files,
-            getSequence(), sr, viewPanel);
+    return ChimeraCommands.getColourBySequenceCommand(files, viewPanel,
+            this);
   }
 
   /**
@@ -741,19 +718,18 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
    */
   private int _modelFileNameMap[];
 
-
   // ////////////////////////////////
   // /StructureListener
   @Override
-  public synchronized String[] getPdbFile()
+  public synchronized String[] getStructureFiles()
   {
     if (viewer == null)
     {
       return new String[0];
     }
 
-    return chimeraMaps.keySet().toArray(
-            modelFileNames = new String[chimeraMaps.size()]);
+    return chimeraMaps.keySet()
+            .toArray(modelFileNames = new String[chimeraMaps.size()]);
   }
 
   /**
@@ -837,7 +813,8 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
      * Parse model number, residue and chain for each selected position,
      * formatted as #0:123.A or #1.2:87.B (#model.submodel:residue.chain)
      */
-    List<AtomSpec> atomSpecs = convertStructureResiduesToAlignment(selection);
+    List<AtomSpec> atomSpecs = convertStructureResiduesToAlignment(
+            selection);
 
     /*
      * Broadcast the selection (which may be empty, if the user just cleared all
@@ -856,7 +833,7 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
   protected List<AtomSpec> convertStructureResiduesToAlignment(
           List<String> structureSelection)
   {
-    List<AtomSpec> atomSpecs = new ArrayList<AtomSpec>();
+    List<AtomSpec> atomSpecs = new ArrayList<>();
     for (String atomSpec : structureSelection)
     {
       try
@@ -923,7 +900,7 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
       return;
     }
 
-    // Chimera expects RBG values in the range 0-1
+    // Chimera expects RGB values in the range 0-1
     final double normalise = 255D;
     viewerCommandHistory(false);
     StringBuilder command = new StringBuilder(128);
@@ -932,12 +909,15 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
             false);
     for (String resName : residueSet)
     {
-      char res = resName.length() == 3 ? ResidueProperties
-              .getSingleCharacterCode(resName) : resName.charAt(0);
+      char res = resName.length() == 3
+              ? ResidueProperties.getSingleCharacterCode(resName)
+              : resName.charAt(0);
       Color col = cs.findColour(res, 0, null, null, 0f);
-      command.append("color " + col.getRed() / normalise + ","
-              + col.getGreen() / normalise + "," + col.getBlue()
-              / normalise + " ::" + resName + ";");
+      command.append("color ")
+              .append(String.valueOf(col.getRed() / normalise)).append(",")
+              .append(String.valueOf(col.getGreen() / normalise))
+              .append(",").append(String.valueOf(col.getBlue() / normalise))
+              .append(" ::").append(resName).append(";");
     }
 
     sendAsynchronousCommand(command.toString(), COLOURING_CHIMERA);
@@ -983,7 +963,7 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
   /**
    * Send the Chimera 'background solid <color>" command.
    * 
-   * @see https 
+   * @see https
    *      ://www.cgl.ucsf.edu/chimera/current/docs/UsersGuide/midas/background
    *      .html
    * @param col
@@ -994,8 +974,8 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
     viewerCommandHistory(false);
     double normalise = 255D;
     final String command = "background solid " + col.getRed() / normalise
-            + "," + col.getGreen() / normalise + "," + col.getBlue()
-            / normalise + ";";
+            + "," + col.getGreen() / normalise + ","
+            + col.getBlue() / normalise + ";";
     viewer.sendChimeraCommand(command, false);
     viewerCommandHistory(true);
   }
@@ -1100,15 +1080,14 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
     // TODO refactor as required to pull up to an interface
     AlignmentI alignment = avp.getAlignment();
 
-    String[] files = getPdbFile();
+    String[] files = getStructureFiles();
     if (files == null)
     {
       return 0;
     }
 
     StructureMappingcommandSet commandSet = ChimeraCommands
-            .getSetAttributeCommandsForFeatures(getSsm(), files,
-                    getSequence(), avp);
+            .getSetAttributeCommandsForFeatures(avp, this);
     String[] commands = commandSet.commands;
     if (commands.length > 10)
     {
@@ -1148,9 +1127,8 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
       sendAsynchronousCommand("open cmd:" + path, null);
     } catch (IOException e)
     {
-      System.err
-              .println("Sending commands to Chimera via file failed with "
-                      + e.getMessage());
+      System.err.println("Sending commands to Chimera via file failed with "
+              + e.getMessage());
     }
   }
 
@@ -1288,7 +1266,6 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
     return CHIMERA_FEATURE_GROUP;
   }
 
-
   public Hashtable<String, String> getChainFile()
   {
     return chainFile;
@@ -1308,4 +1285,25 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
     }
     return -1;
   }
+
+  @Override
+  public void showStructures(AlignViewportI av, boolean refocus)
+  {
+    StringBuilder cmd = new StringBuilder(128);
+    cmd.append("~display; ~ribbon;");
+
+    AtomSpecModel model = getShownResidues(av);
+    String atomSpec = ChimeraCommands.getAtomSpec(model, this);
+    
+    cmd.append("ribbon ").append(atomSpec);
+    if (!isShowAlignmentOnly())
+    {
+      cmd.append("chain @CA|P; ribbon");
+    }
+    if (refocus)
+    {
+      cmd.append("; focus");
+    }
+    sendChimeraCommand(cmd.toString(), false);
+  }
 }