JAL-3390 pull up of getShownResidues() to AAStructureBindingModel
[jalview.git] / src / jalview / ext / rbvi / chimera / JalviewChimeraBinding.java
index 6fa06d2..44bcbe4 100644 (file)
@@ -22,7 +22,6 @@ 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;
@@ -32,13 +31,11 @@ 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;
 import jalview.schemes.ResidueProperties;
 import jalview.structure.AtomSpec;
-import jalview.structure.StructureMapping;
 import jalview.structure.StructureMappingcommandSet;
 import jalview.structure.StructureSelectionManager;
 import jalview.structures.models.AAStructureBindingModel;
@@ -251,43 +248,6 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
   }
 
   /**
-   * 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.
    */
@@ -502,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);
@@ -579,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())
     {
@@ -594,7 +556,8 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
      */
     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;
   }
 
   /**
@@ -704,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);
   }
 
   /**
@@ -938,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);
@@ -951,9 +913,11 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
               ? 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);
@@ -1123,8 +1087,7 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
     }
 
     StructureMappingcommandSet commandSet = ChimeraCommands
-            .getSetAttributeCommandsForFeatures(getSsm(), files,
-                    getSequence(), avp);
+            .getSetAttributeCommandsForFeatures(avp, this);
     String[] commands = commandSet.commands;
     if (commands.length > 10)
     {
@@ -1324,100 +1287,23 @@ 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);
-    }
-    else
+
+    AtomSpecModel model = getShownResidues(av);
+    String atomSpec = ChimeraCommands.getAtomSpec(model, this);
+    
+    cmd.append("ribbon ").append(atomSpec);
+    if (!isShowAlignmentOnly())
     {
       cmd.append("chain @CA|P; ribbon");
     }
-    cmd.append("; focus");
-    sendChimeraCommand(cmd.toString(), false);
-  }
-
-  /**
-   * Builds a Chimera atomSpec of residues mapped from sequences, of the format
-   * (#model:residues.chain)
-   * 
-   * <pre>
-   * #0:2-94.A | #1:1-93.C | #2:1-93.A
-   * </pre>
-   * 
-   * Only residues visible in the alignment are included, that is, hidden columns
-   * and sequences are excluded.
-   * 
-   * @param av
-   * @return
-   */
-  private String getMappedResidues(AlignViewportI av)
-  {
-    AlignmentI alignment = av.getAlignment();
-    final int width = alignment.getWidth();
-  
-    String[] files = getStructureFiles();
-
-    StringBuilder atomSpec = new StringBuilder(256);
-
-    for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++)
+    if (refocus)
     {
-      StructureMapping[] mappings = getSsm().getMapping(files[pdbfnum]);
-
-      /*
-       * Find the first mapped sequence (if any) for this PDB entry which is in
-       * the alignment
-       */
-      final int seqCountForPdbFile = getSequence()[pdbfnum].length;
-      for (int s = 0; s < seqCountForPdbFile; s++)
-      {
-        for (StructureMapping mapping : mappings)
-        {
-          final SequenceI theSequence = getSequence()[pdbfnum][s];
-          if (mapping.getSequence() == theSequence
-                  && alignment.findIndex(theSequence) > -1)
-          {
-            String chainCd = mapping.getChain();
-
-            // TODO only process sequence ranges within visible columns
-            VisibleContigsIterator visible = alignment.getHiddenColumns()
-                    .getVisContigsIterator(0, width, true);
-            while (visible.hasNext())
-            {
-              int[] visibleRegion = visible.next();
-              int seqStartPos = theSequence.findPosition(visibleRegion[0]);
-              int seqEndPos = theSequence.findPosition(visibleRegion[1]);
-              List<int[]> residueRanges = mapping
-                      .getPDBResNumRanges(seqStartPos, seqEndPos);
-              if (!residueRanges.isEmpty())
-              {
-                if (atomSpec.length() > 0)
-                {
-                  atomSpec.append("| ");
-                }
-                atomSpec.append(getModelSpec(pdbfnum)).append(":");
-                boolean first = true;
-                for (int[] range : residueRanges)
-                {
-                  if (!first)
-                  {
-                    atomSpec.append(",");
-                  }
-                  first = false;
-                  atomSpec.append(range[0]).append("-").append(range[1]);
-                  atomSpec.append(".").append(chainCd);
-                }
-              }
-            }
-          }
-        }
-      }
+      cmd.append("; focus");
     }
-
-    return atomSpec.toString();
+    sendChimeraCommand(cmd.toString(), false);
   }
 }