Merge branch 'develop' into releases/Release_2_11_2_Branch
authorJim Procter <j.procter@dundee.ac.uk>
Wed, 16 Feb 2022 12:04:42 +0000 (12:04 +0000)
committerJim Procter <j.procter@dundee.ac.uk>
Wed, 16 Feb 2022 12:04:42 +0000 (12:04 +0000)
20 files changed:
help/help/html/features/pymol.html
help/help/html/releases.html
src/jalview/datamodel/PDBEntry.java
src/jalview/ext/jmol/JmolCommands.java
src/jalview/ext/pymol/PymolCommands.java
src/jalview/ext/rbvi/chimera/ChimeraCommands.java
src/jalview/ext/rbvi/chimera/ChimeraXCommands.java
src/jalview/gui/PymolBindingModel.java
src/jalview/gui/structurechooser/ThreeDBStructureChooserQuerySource.java
src/jalview/structure/StructureCommandsBase.java
src/jalview/structure/StructureCommandsI.java
src/jalview/structures/models/AAStructureBindingModel.java
test/jalview/bin/CommandLineOperations.java
test/jalview/bin/testProps.jvprops
test/jalview/datamodel/PDBEntryTest.java
test/jalview/ext/jmol/JmolCommandsTest.java
test/jalview/ext/pymol/PymolCommandsTest.java
test/jalview/ext/rbvi/chimera/ChimeraCommandsTest.java
test/jalview/ext/rbvi/chimera/ChimeraXCommandsTest.java
test/jalview/structures/models/AAStructureBindingModelTest.java

index 061434f..573310a 100644 (file)
     <strong>The Pymol Viewer</strong>
   </p>
   <p>
-    In Jalview 2.11.2, support was added for <a href="https://pymol.org/2/">Pymol</a>
-    (https://pymol.org/2/) to be used for viewing
-    structures opened via the <a href="structurechooser.html"><strong>&quot;View
-        Structure Data..&quot;</strong> dialog</a>.
+    In Jalview 2.11.2, support was added for viewing structures opened
+    via the <a href="structurechooser.html"><strong>&quot;View
+        Structure Data..&quot;</strong> dialog</a> with <a
+      href="https://pymol.org/2/">Pymol</a> (https://pymol.org/2/). Like
+    with <a href="chimera.html">Chimera and ChimeraX</a>, Pymol views
+    can be saved and restored from Jalview Project files on any machine
+    with it installed, and structures can be coloured and superimposed
+    according to the alignment.
   </p>
   <p>
-               You can configure Pymol as your preferred structure viewer in
-               <a href="preferences.html#structure"> Preferences</a>. You can also
-               optionally specify the path to the Pymol program here (if it differs
-               from the standard paths searched by Jalview).<br /> <strong>Jalview
-                       requires Pymol's RPC interface, which is not available in older
-                       versions of the Pymol community edition.<br />Please make sure your
-                       version of Pymol is up to date.
-               </strong>
-       </p>
+    <em>Configuring Jalview to use Pymol</em><br /> You can configure
+    Pymol as your preferred structure viewer in <a
+      href="preferences.html#structure"> Preferences</a>. Jalview will
+    look for an existing installation, and will ask you to specify the
+    installation's path if it cannot be found. You can also optionally
+    specify the path to the Pymol program here if you want Jalview to
+    use a specific installation.
+  </p>
+  <p>
+    <strong>Jalview requires Pymol V 2.5.0 (community edition)
+      or later</strong> <br />Jalview requires Pymol's RPC interface, which is
+    not available in older versions of the Pymol community edition.
+  </p>
   <p>
-    If you save your Jalview session as a project file, the state of any
-    open Pymol windows will also be saved, and can be reopened by
-    loading the project file on any machine with Pymol installed.
-    </p>
-       <p>
-               <strong>Known Limitations</strong><br /> Jalview provides an easy way
-               to employ Pymol for linked analysis of sequences and structures in the
-               same way as <a href="chimera.html">Chimera and ChimeraX</a>. There are
-               some limitations, however:
-       </p>
-       <ul>
-               <li>Pymol does not support some forms of legacy structural data
-                       (e.g. the 1A70 C-alpha only PDB file included in the Jalview example
-                       project).</li>
-               <li>Pymol to Jalview communication does not support transfer of
-                       properties or highlighting sequence regions corresponding to
-                       structure selections or mouse-overs in Pymol.</li>
-       </ul>
+    <strong>Known Limitations</strong><br />
+  </p>
+  <ul>
+    <li>Pymol does not support some forms of legacy structural data
+      (e.g. the 1A70 C-alpha only PDB file included in the Jalview
+      example project).</li>
+    <li>Pymol to Jalview communication does not support transfer of
+      properties or highlighting sequence regions corresponding to
+      structure selections or mouse-overs in Pymol.</li>
+    <li>Jalview to Pymol communication currently doesn't highlight
+      the positions on structures corresponging to moused over residues
+      in Jalview.</li>
+  </ul>
   <p>
     Basic screen operations (see <a
-      href="https://pymol.org/dokuwiki/doku.php?id=mouse">Pymol Wiki</a> at
-    https://pymol.org/dokuwiki/doku.php?id=mouse
-    for full details).
+      href="https://pymol.org/dokuwiki/doku.php?id=mouse">Pymol Wiki</a>
+    at https://pymol.org/dokuwiki/doku.php?id=mouse for full details).
   <table border="1">
     <tr>
       <td><strong>Action</strong></td>
             colourschemes.<br>
         </strong><em>The remaining entries apply the colourschemes available
             from the standard and user defined <a
-            href="../colourSchemes/index.html">amino acid
-              colours</a>.
+            href="../colourSchemes/index.html">amino acid colours</a>.
         </em></li>
       </ul></li>
     <li><strong>Pymol<br>
-    </strong><em>This pulldown menu provides access to Pymol's capabilities from Jalview.</em>
+    </strong><em>This pulldown menu provides access to Pymol's capabilities
+        from Jalview.</em>
       <ul>
         <li><strong><a name="sAlign">Align</a> <br> </strong><em>
             When selected, the associated alignment will be used to
             superimpose all the structures in the view onto the first
-            structure in the alignment. The regions used to calculate
+            structure in the alignment via the pair_fit command. The regions used to calculate
             the superposition will be highlighted using the 'Cartoon'
             rendering style, and the remaining data shown as a chain
-            trace.<br />
-          <br />
+            trace. RMSD values are output in the Pymol log.<br /> <br />
         </em></li>
         <li><a name="annotxfer"><strong>Write Jalview
               features</strong></a><br /> <em>Selecting this option will create
             new atom properties for any features currently visible in
-            the associated alignment views. This allows those atoms to 
-            be selected and analysed in Pymol directly.
-        </em><br>
-        <ul><li>Feature transfer in Pymol is experimental.</li><li>To select by a particular feature use the string matching syntax:<br>
-        select foo,p.jv_helix in helix
-        </li>
-        <li>To view transferred properties use Pymol's Properties Inspector</li><li>
-        For more information see <a href="https://pymol.org/dokuwiki/doku.php?id=properties#selection_language">Property based selection in Pymol's Documentation</a>.
-        </li>
-        </ul>
-        </li>
+            the associated alignment views. This allows those atoms to
+            be selected and analysed in Pymol directly. </em><br>
+          <ul>
+            <li>Feature transfer in Pymol is experimental.</li>
+            <li>To select by a particular feature use the string
+              matching syntax:<br> select foo,p.jv_helix in helix
+            </li>
+            <li>To view transferred properties use Pymol's
+              Properties Inspector</li>
+            <li>For more information see <a
+              href="https://pymol.org/dokuwiki/doku.php?id=properties#selection_language">Property
+                based selection in Pymol's Documentation</a>.
+            </li>
+          </ul></li>
       </ul></li>
     <li><strong>Help<br>
     </strong>
       <ul>
         <li><strong>Pymol Help<br>
-        </strong><em>Access the Pymol Help documentation in a new browser window.
-            window.</em></li>
+        </strong><em>Access the Pymol Help documentation in a new browser
+            window. window.</em></li>
       </ul></li>
   </ul>
   <p>
     <strong>Pymol and Windows Firewall</strong>
   </p>
-  Jalview and Pymol communicate using the <a href="https://pymolwiki.org/index.php/RPC">Pymol's XML-RPC over HTTP interface</a>(https://pymolwiki.org/index.php/RPC).
-  
-<br> Technically this requires both Pymol and Jalview to open
+  Jalview and Pymol communicate using the
+  <a href="https://pymolwiki.org/index.php/RPC">Pymol's XML-RPC over
+    HTTP interface</a>(https://pymolwiki.org/index.php/RPC).
+
+  <br> Technically this requires both Pymol and Jalview to open
   ports on the local network, and this may be blocked by Windows
   Firewall with a warning message such as
   <br /> "Windows Firewall has blocked some features of this program"
index 9fe5da5..6c86e2e 100755 (executable)
@@ -59,7 +59,7 @@ li:before {
     <tr>
       <td width="60" align="center" nowrap><strong><a
           id="Jalview.2.11.2">2.11.2</a><a id="Jalview.2.11.2.0">.0</a><br />
-          <em>01/02/2022</em></strong></td>
+          <em>24/02/2022</em></strong></td>
       <td align="left" valign="top">
         <ul>
           <li>
index adcefb3..741ef07 100755 (executable)
@@ -38,7 +38,14 @@ public class PDBEntry
 
   private static final int PDB_ID_LENGTH = 4;
 
+  /**
+   * property set when id is a 'manufactured' identifier from the structure data's filename
+   */
   private static final String FAKED_ID = "faked_pdbid";
+  /**
+   * property set when the id is authoritative, and should be used in preference to any identifiers in the structure data
+   */
+  private static final String AUTHORITATIVE_ID = "authoritative_pdbid";
 
   private String file;
 
@@ -406,7 +413,7 @@ public class PDBEntry
           // this shouldn't happen, but could do if the id from the
           // file is not the same as the id from the authority that provided
           // the file
-          if (!newEntry.fakedPDBId())
+          if (!newEntry.fakedPDBId() && !isAuthoritative())
           {
             return false;
           } // otherwise we can update
@@ -474,7 +481,7 @@ public class PDBEntry
        */
       String key = newProps.nextElement();
       Object value = newEntry.getProperty(key);
-      if (FAKED_ID.equals(key))
+      if (FAKED_ID.equals(key) || AUTHORITATIVE_ID.equals(key))
       {
         // we never update the fake ID property
         continue;
@@ -487,6 +494,25 @@ public class PDBEntry
     return true;
   }
   
+  public void setAuthoritative(boolean isAuthoritative)
+  {
+    setProperty(AUTHORITATIVE_ID, Boolean.valueOf(isAuthoritative));
+  }
+  
+  /**
+   * 
+   * @return true if the identifier should be preferred over any identifiers
+   *         embedded in the structure data
+   */
+  public boolean isAuthoritative()
+  {
+    if (_hasProperty(AUTHORITATIVE_ID))
+    {
+      return ((Boolean)getProperty(AUTHORITATIVE_ID));
+    }
+    return false;
+  }
+
   /**
    * set when Jalview has manufactured the ID using a local filename
    * @return
index 25f6aec..8b67ad9 100644 (file)
@@ -40,6 +40,7 @@ import jalview.structure.StructureCommandI;
 import jalview.structure.StructureCommandsBase;
 import jalview.structure.StructureMapping;
 import jalview.structure.StructureSelectionManager;
+import jalview.structure.StructureCommandsI.AtomSpecType;
 import jalview.util.Comparison;
 import jalview.util.Platform;
 
@@ -178,7 +179,7 @@ public class JmolCommands extends StructureCommandsBase
    */
   @Override
   public List<StructureCommandI> superposeStructures(AtomSpecModel refAtoms,
-          AtomSpecModel atomSpec)
+          AtomSpecModel atomSpec, AtomSpecType backbone)
   {
     StringBuilder sb = new StringBuilder(64);
     String refModel = refAtoms.getModels().iterator().next();
@@ -190,16 +191,16 @@ public class JmolCommands extends StructureCommandsBase
      * command examples don't include modelspec with atoms, getAtomSpec does;
      * it works, so leave it as it is for simplicity
      */
-    sb.append(getAtomSpec(atomSpec, true)).append("}{");
-    sb.append(getAtomSpec(refAtoms, true)).append("}");
+    sb.append(getAtomSpec(atomSpec, backbone)).append("}{");
+    sb.append(getAtomSpec(refAtoms, backbone)).append("}");
     sb.append(" ROTATE TRANSLATE ");
     sb.append(getCommandSeparator());
 
     /*
      * show residues used for superposition as ribbon
      */
-    sb.append("select ").append(getAtomSpec(atomSpec, false)).append("|");
-    sb.append(getAtomSpec(refAtoms, false)).append(getCommandSeparator())
+    sb.append("select ").append(getAtomSpec(atomSpec, AtomSpecType.RESIDUE_ONLY)).append("|");
+    sb.append(getAtomSpec(refAtoms, AtomSpecType.RESIDUE_ONLY)).append(getCommandSeparator())
             .append("cartoons");
 
     return Arrays.asList(new StructureCommand(sb.toString()));
@@ -250,7 +251,7 @@ public class JmolCommands extends StructureCommandsBase
    * a separate clause in the {@code compare} (superposition) command.
    */
   @Override
-  public String getAtomSpec(AtomSpecModel model, boolean alphaOnly)
+  public String getAtomSpec(AtomSpecModel model, AtomSpecType specType)
   {
     StringBuilder sb = new StringBuilder(128);
 
index 36957f5..ed64c00 100644 (file)
@@ -106,20 +106,22 @@ public class PymolCommands extends StructureCommandsBase
 
   @Override
   public List<StructureCommandI> superposeStructures(AtomSpecModel refAtoms,
-          AtomSpecModel atomSpec)
+          AtomSpecModel atomSpec, AtomSpecType specType)
   {
+             
     // https://pymolwiki.org/index.php/Super
     List<StructureCommandI> commands = new ArrayList<>();
-    String refAtomsAlphaOnly = getAtomSpec(refAtoms, true);
-    String atomSpec2AlphaOnly = getAtomSpec(atomSpec, true);
-    commands.add(new StructureCommand("super", refAtomsAlphaOnly,
-            atomSpec2AlphaOnly));
+    String refAtomsAlphaOnly = "("+getAtomSpec(refAtoms, specType)+" and (altloc '' or altloc 'a'))";
+    String atomSpec2AlphaOnly = "("+getAtomSpec(atomSpec, specType)+" and (altloc '' or altloc 'a'))";
+    // pair_fit mobile -> reference
+    commands.add(new StructureCommand("pair_fit", 
+            atomSpec2AlphaOnly, refAtomsAlphaOnly));
 
     /*
      * and show superposed residues as cartoon
      */
-    String refAtomsAll = getAtomSpec(refAtoms, false);
-    String atomSpec2All = getAtomSpec(atomSpec, false);
+    String refAtomsAll = getAtomSpec(refAtoms, AtomSpecType.RESIDUE_ONLY);
+    String atomSpec2All = getAtomSpec(atomSpec, AtomSpecType.RESIDUE_ONLY);
     commands.add(new StructureCommand("show", "cartoon",
             refAtomsAll + " " + atomSpec2All));
 
@@ -153,7 +155,7 @@ public class PymolCommands extends StructureCommandsBase
    * @see https://pymolwiki.org/index.php/Selection_Macros
    */
   @Override
-  public String getAtomSpec(AtomSpecModel model, boolean alphaOnly)
+  public String getAtomSpec(AtomSpecModel model, AtomSpecType specType)
   {
     StringBuilder sb = new StringBuilder(64);
     boolean first = true;
@@ -184,10 +186,14 @@ public class PymolCommands extends StructureCommandsBase
           }
         }
         sb.append("/");
-        if (alphaOnly)
+        if (specType == AtomSpecType.ALPHA)
         {
           sb.append("CA");
         }
+        if (specType == AtomSpecType.PHOSPHATE)
+        {
+          sb.append("P");
+        }
       }
     }
     return sb.toString();
@@ -261,7 +267,7 @@ public class PymolCommands extends StructureCommandsBase
     StringBuilder sb = new StringBuilder(128);
     sb.append("p.").append(attributeName).append("='")
             .append(attributeValue).append("'");
-    String atomSpec = getAtomSpec(atomSpecModel, false);
+    String atomSpec = getAtomSpec(atomSpecModel, AtomSpecType.RESIDUE_ONLY);
     return new StructureCommand("iterate", atomSpec, sb.toString());
   }
 
index 02b7136..6d4caa2 100644 (file)
@@ -32,6 +32,7 @@ import jalview.structure.AtomSpecModel;
 import jalview.structure.StructureCommand;
 import jalview.structure.StructureCommandI;
 import jalview.structure.StructureCommandsBase;
+import jalview.structure.StructureCommandsI.AtomSpecType;
 import jalview.util.ColorUtils;
 
 /**
@@ -161,7 +162,7 @@ public class ChimeraCommands extends StructureCommandsBase
     StringBuilder sb = new StringBuilder(128);
     sb.append("setattr res ").append(attributeName).append(" '")
             .append(attributeValue).append("' ");
-    sb.append(getAtomSpec(atomSpecModel, false));
+    sb.append(getAtomSpec(atomSpecModel, AtomSpecType.RESIDUE_ONLY));
     return new StructureCommand(sb.toString());
   }
 
@@ -259,7 +260,7 @@ public class ChimeraCommands extends StructureCommandsBase
 
   @Override
   public List<StructureCommandI> superposeStructures(AtomSpecModel ref,
-          AtomSpecModel spec)
+          AtomSpecModel spec, AtomSpecType backbone)
   {
     /*
      * Form Chimera match command to match spec to ref
@@ -270,15 +271,15 @@ public class ChimeraCommands extends StructureCommandsBase
      * @see https://www.cgl.ucsf.edu/chimera/docs/UsersGuide/midas/match.html
      */
     StringBuilder cmd = new StringBuilder();
-    String atomSpecAlphaOnly = getAtomSpec(spec, true);
-    String refSpecAlphaOnly = getAtomSpec(ref, true);
+    String atomSpecAlphaOnly = getAtomSpec(spec, backbone);
+    String refSpecAlphaOnly = getAtomSpec(ref, backbone);
     cmd.append("match ").append(atomSpecAlphaOnly).append(" ").append(refSpecAlphaOnly);
 
     /*
      * show superposed residues as ribbon
      */
-    String atomSpec = getAtomSpec(spec, false);
-    String refSpec = getAtomSpec(ref, false);
+    String atomSpec = getAtomSpec(spec, AtomSpecType.RESIDUE_ONLY);
+    String refSpec = getAtomSpec(ref, AtomSpecType.RESIDUE_ONLY);
     cmd.append("; ribbon ");
     cmd.append(atomSpec).append("|").append(refSpec).append("; focus");
 
@@ -319,12 +320,12 @@ public class ChimeraCommands extends StructureCommandsBase
    * <pre>
    * 
    * @param model
-   * @param alphaOnly
+   * @param specType
    * @return
    * @see https://www.cgl.ucsf.edu/chimera/current/docs/UsersGuide/midas/frameatom_spec.html
    */
   @Override
-  public String getAtomSpec(AtomSpecModel atomSpec, boolean alphaOnly)
+  public String getAtomSpec(AtomSpecModel atomSpec, AtomSpecType specType)
   {
     StringBuilder sb = new StringBuilder(128);
     boolean firstModel = true;
@@ -335,7 +336,7 @@ public class ChimeraCommands extends StructureCommandsBase
         sb.append("|");
       }
       firstModel = false;
-      appendModel(sb, model, atomSpec, alphaOnly);
+      appendModel(sb, model, atomSpec, specType);
     }
     return sb.toString();
   }
@@ -349,7 +350,7 @@ public class ChimeraCommands extends StructureCommandsBase
    * @param alphaOnly
    */
   protected void appendModel(StringBuilder sb, String model,
-          AtomSpecModel atomSpec, boolean alphaOnly)
+          AtomSpecModel atomSpec, AtomSpecType specType)
   {
     sb.append("#").append(model).append(":");
 
@@ -367,15 +368,18 @@ public class ChimeraCommands extends StructureCommandsBase
         firstPositionForModel = false;
       }
     }
-    if (alphaOnly)
+    if (specType == AtomSpecType.ALPHA)
     {
       /*
        * restrict to alpha carbon, no alternative locations
        * (needed to ensuring matching atom counts for superposition)
        */
-      // TODO @P instead if RNA - add nucleotide flag to AtomSpecModel?
       sb.append("@CA").append(NO_ALTLOCS);
     }
+    if (specType == AtomSpecType.PHOSPHATE)
+    {
+      sb.append("@P").append(NO_ALTLOCS);
+    }
   }
 
   @Override
index 4e45ac8..780d292 100644 (file)
@@ -28,6 +28,7 @@ import java.util.List;
 import jalview.structure.AtomSpecModel;
 import jalview.structure.StructureCommand;
 import jalview.structure.StructureCommandI;
+import jalview.structure.StructureCommandsI.AtomSpecType;
 
 /**
  * Routines for generating ChimeraX commands for Jalview/ChimeraX binding
@@ -119,7 +120,7 @@ public class ChimeraXCommands extends ChimeraCommands
           String attributeValue, AtomSpecModel atomSpecModel)
   {
     StringBuilder sb = new StringBuilder(128);
-    sb.append("setattr ").append(getAtomSpec(atomSpecModel, false));
+    sb.append("setattr ").append(getAtomSpec(atomSpecModel, AtomSpecType.RESIDUE_ONLY));
     sb.append(" res ").append(attributeName).append(" '")
             .append(attributeValue).append("'");
     sb.append(" create true");
@@ -153,7 +154,7 @@ public class ChimeraXCommands extends ChimeraCommands
    * @return
    */
   @Override
-  public String getAtomSpec(AtomSpecModel atomSpec, boolean alphaOnly)
+  public String getAtomSpec(AtomSpecModel atomSpec, AtomSpecType specType)
   {
     StringBuilder sb = new StringBuilder(128);
     boolean firstModel = true;
@@ -165,11 +166,14 @@ public class ChimeraXCommands extends ChimeraCommands
       }
       firstModel = false;
       appendModel(sb, model, atomSpec);
-      if (alphaOnly)
+      if (specType == AtomSpecType.ALPHA)
       {
-        // TODO @P if RNA - add nucleotide flag to AtomSpecModel?
         sb.append("@CA");
       }
+      if (specType == AtomSpecType.PHOSPHATE)
+      {
+        sb.append("@P");
+      }
     }
     return sb.toString();
   }
@@ -213,7 +217,7 @@ public class ChimeraXCommands extends ChimeraCommands
 
   @Override
   public List<StructureCommandI> superposeStructures(AtomSpecModel ref,
-          AtomSpecModel spec)
+          AtomSpecModel spec, AtomSpecType backbone)
   {
     /*
      * Form ChimeraX match command to match spec to ref
@@ -223,8 +227,8 @@ public class ChimeraXCommands extends ChimeraCommands
      * @see https://www.cgl.ucsf.edu/chimerax/docs/user/commands/align.html
      */
     StringBuilder cmd = new StringBuilder();
-    String atomSpec = getAtomSpec(spec, true);
-    String refSpec = getAtomSpec(ref, true);
+    String atomSpec = getAtomSpec(spec, backbone);
+    String refSpec = getAtomSpec(ref, backbone);
     cmd.append("align ").append(atomSpec).append(" toAtoms ")
             .append(refSpec);
 
@@ -232,8 +236,8 @@ public class ChimeraXCommands extends ChimeraCommands
      * show superposed residues as ribbon, others as chain
      */
     cmd.append("; ribbon ");
-    cmd.append(getAtomSpec(spec, false)).append("|");
-    cmd.append(getAtomSpec(ref, false)).append("; view");
+    cmd.append(getAtomSpec(spec, AtomSpecType.RESIDUE_ONLY)).append("|");
+    cmd.append(getAtomSpec(ref, AtomSpecType.RESIDUE_ONLY)).append("; view");
 
     return Arrays.asList(new StructureCommand(cmd.toString()));
   }
index 9ef45fb..6aba7b6 100644 (file)
@@ -70,15 +70,14 @@ public class PymolBindingModel extends AAStructureBindingModel
   public void highlightAtoms(List<AtomSpec> atoms)
   {
     /*
-     * https://pymolwiki.org/index.php/Label#examples
+     * https://pymolwiki.org/index.php/indicate#examples
      */
     StringBuilder sb = new StringBuilder();
     for (AtomSpec atom : atoms)
     {
       // todo promote to StructureCommandsI.showLabel()
-      // todo handle CA|P correctly
       String modelId = getModelIdForFile(atom.getPdbFile());
-      sb.append(String.format(" %s//%s/%d/CA", modelId,
+      sb.append(String.format(" %s//%s/%d/*", modelId,
               atom.getChain(),
               atom.getPdbResNum()));
     }
@@ -87,18 +86,9 @@ public class PymolBindingModel extends AAStructureBindingModel
     {
       return;
     }
-    StructureCommandI command = new StructureCommand("label", labelSpec, LABEL_FORMAT);
+    StructureCommandI command = new StructureCommand("indicate", labelSpec);
     executeCommand(command, false);
 
-    /*
-     * and remove the label(s) previously shown
-     */
-    if (lastLabelSpec != null)
-    {
-      command = new StructureCommand("label", lastLabelSpec, "");
-      executeCommand(command, false);
-    }
-
     lastLabelSpec = labelSpec;
   }
 
index 23b96c9..669e58a 100644 (file)
@@ -415,6 +415,7 @@ public class ThreeDBStructureChooserQuerySource
       {
         pdbEntry = new PDBEntry();
         pdbEntry.setId(pdbIdStr);
+        pdbEntry.setAuthoritative(true);
         try
         {
           pdbEntry.setType(PDBEntry.Type.valueOf(strucFormat));
index 8716691..fdc8d16 100644 (file)
@@ -141,7 +141,7 @@ public abstract class StructureCommandsBase implements StructureCommandsI
   protected StructureCommandI getColourCommand(AtomSpecModel atomSpecModel,
           Color colour)
   {
-    String atomSpec = getAtomSpec(atomSpecModel, false);
+    String atomSpec = getAtomSpec(atomSpecModel, AtomSpecType.RESIDUE_ONLY);
     return colourResidues(atomSpec, colour);
   }
 
index 91e0494..0489bda 100644 (file)
@@ -86,10 +86,11 @@ public interface StructureCommandsI
    * 
    * @param refAtoms
    * @param atomSpec
+   * @param backbone - superpose based on which kind of atomType
    * @return
    */
   List<StructureCommandI> superposeStructures(AtomSpecModel refAtoms,
-          AtomSpecModel atomSpec);
+          AtomSpecModel atomSpec, AtomSpecType backbone);
 
   /**
    * Returns a command to open a file of commands at the given path
@@ -108,16 +109,17 @@ public interface StructureCommandsI
    */
   StructureCommandI saveSession(String filepath);
 
+  enum AtomSpecType { RESIDUE_ONLY, ALPHA, PHOSPHATE }; 
   /**
    * Returns a representation of the atom set represented by the model, in
    * viewer syntax format. If {@code alphaOnly} is true, this is restricted to
    * Alpha Carbon (peptide) or Phosphorous (rna) only
    * 
    * @param model
-   * @param alphaOnly
+   * @param specType
    * @return
    */
-  String getAtomSpec(AtomSpecModel model, boolean alphaOnly);
+  String getAtomSpec(AtomSpecModel model, AtomSpecType specType);
 
   /**
    * Returns the lowest model number used by the structure viewer (likely 0 or
index 3414e95..9ecf630 100644 (file)
@@ -61,6 +61,7 @@ import jalview.structure.AtomSpec;
 import jalview.structure.AtomSpecModel;
 import jalview.structure.StructureCommandI;
 import jalview.structure.StructureCommandsI;
+import jalview.structure.StructureCommandsI.AtomSpecType;
 import jalview.structure.StructureListener;
 import jalview.structure.StructureMapping;
 import jalview.structure.StructureSelectionManager;
@@ -91,6 +92,9 @@ public abstract class AAStructureBindingModel
 
     public String chain = "";
 
+    /**
+     * is the mapped sequence not protein ?
+     */
     public boolean isRna;
 
     /*
@@ -167,6 +171,9 @@ public abstract class AAStructureBindingModel
 
   protected boolean colourBySequence = true;
 
+  /**
+   * true if all sequences appear to be nucleotide
+   */
   private boolean nucleotide;
 
   private boolean finishedInit = false;
@@ -716,7 +723,7 @@ public abstract class AAStructureBindingModel
               structures[pdbfnum].chain = chain;
             }
             structures[pdbfnum].pdbId = mapping.getPdbId();
-            structures[pdbfnum].isRna = theSequence.getRNA() != null;
+            structures[pdbfnum].isRna = !theSequence.isProtein();
 
             /*
              * move on to next pdb file (ignore sequences for other chains
@@ -918,7 +925,8 @@ public abstract class AAStructureBindingModel
        */
       // todo better way to ensure synchronous than setting getReply true!!
       executeCommands(commandGenerator.showBackbone(), true, null);
-
+      
+      AtomSpecType backbone = structures[refStructure].isRna ? AtomSpecType.PHOSPHATE : AtomSpecType.ALPHA;
       /*
        * superpose each (other) structure to the reference in turn
        */
@@ -928,7 +936,7 @@ public abstract class AAStructureBindingModel
         {
           AtomSpecModel atomSpec = getAtomSpec(structures[i], matched);
           List<StructureCommandI> commands = commandGenerator
-                  .superposeStructures(refAtoms, atomSpec);
+                  .superposeStructures(refAtoms, atomSpec, backbone);
           List<String> replies = executeCommands(commands, true, null);
           for (String reply : replies)
           {
index d829aae..ee03e77 100644 (file)
@@ -226,7 +226,7 @@ public class CommandLineOperations
   public void setUpForHeadlessCommandLineInputOperations()
           throws IOException
   {
-    String cmds = "nodisplay -open examples/uniref50.fa -sortbytree -props test/jalview/io/testProps.jvprops -colour zappo "
+    String cmds = "nodisplay -open examples/uniref50.fa -sortbytree -props test/jalview/bin/testProps.jvprops -colour zappo "
             + "-jabaws http://www.compbio.dundee.ac.uk/jabaws -nosortbytree "
             + "-features examples/testdata/plantfdx.features -annotations examples/testdata/plantfdx.annotations -tree examples/testdata/uniref50_test_tree";
     Worker worker = getJalviewDesktopRunner(true, cmds, SETUP_TIMEOUT);
@@ -252,7 +252,7 @@ public class CommandLineOperations
     
     // number of lines expected on STDERR when Jalview starts up normally
     // may need to adjust this if Jalview is excessively noisy ?
-    final int STDERR_SETUPLINES=50;
+    final int STDERR_SETUPLINES=30;
     
     // thread monitors stderr - bails after SETUP_TIMEOUT or when
     // STDERR_SETUPLINES have been read
@@ -345,7 +345,7 @@ public class CommandLineOperations
         // headless mode input operations
         { "CMD [-color zappo] executed successfully!",
             "Failed command : -color zappo" },
-        { "CMD [-props test/jalview/io/testProps.jvprops] executed successfully!",
+        { "CMD [-props test/jalview/bin/testProps.jvprops] executed successfully!",
             "Failed command : -props File" },
         { "CMD [-sortbytree] executed successfully!",
             "Failed command : -sortbytree" },
index a1ab82a..7018dc4 100644 (file)
@@ -1,2 +1,3 @@
 VERSION_CHECK=true
 LATEST_VERSION=test
+logs.Jalview.level=INFO
index 198cde3..80b7376 100644 (file)
@@ -90,7 +90,7 @@ public class PDBEntryTest
     PDBEntry case9 = new PDBEntry("1xyz", "A", null, "x/y/z/File");
     // different file only
     PDBEntry case10 = new PDBEntry("1xyz", "A", null, "a/b/c/File");
-
+    
     /*
      * assertEquals will invoke PDBEntry.equals()
      */
@@ -269,6 +269,21 @@ public class PDBEntryTest
     pdb2.setProperty("hello", "moon");
     assertTrue(pdb1.updateFrom(pdb2));
     assertEquals(pdb1.getProperty("hello"), "moon");
+    
+    /*
+    * different id but authoritative
+    */
+    pdb1 = new PDBEntry("af:1xyz", "A", null, "a/b/c/File");
+    pdb2 = new PDBEntry("af-1xyz", "A", null, "a/b/c/File");
+    pdb1.setAuthoritative(true);
+
+    assertTrue(pdb1.isAuthoritative());
+    assertFalse(pdb2.isAuthoritative());
+    // can update pdb1 (authoritative) from pdb2 (non-authoritative)
+    assertTrue(pdb1.updateFrom(pdb2));
+    // but the ID must remain the same
+    assertEquals(pdb1.getId(),"af:1xyz");
+    
   }
 
   @Test(groups = { "Functional" })
index 21f7e19..6265c05 100644 (file)
@@ -42,6 +42,7 @@ import jalview.gui.SequenceRenderer;
 import jalview.schemes.JalviewColourScheme;
 import jalview.structure.AtomSpecModel;
 import jalview.structure.StructureCommandI;
+import jalview.structure.StructureCommandsI.AtomSpecType;
 import jalview.structure.StructureMapping;
 import jalview.structure.StructureSelectionManager;
 
@@ -130,34 +131,34 @@ public class JmolCommandsTest
   public void testGetAtomSpec()
   {
     AtomSpecModel model = new AtomSpecModel();
-    assertEquals(testee.getAtomSpec(model, false), "");
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.RESIDUE_ONLY), "");
     model.addRange("1", 2, 4, "A");
-    assertEquals(testee.getAtomSpec(model, false), "2-4:A/1.1");
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.RESIDUE_ONLY), "2-4:A/1.1");
     model.addRange("1", 8, 8, "A");
-    assertEquals(testee.getAtomSpec(model, false), "2-4:A/1.1|8:A/1.1");
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.RESIDUE_ONLY), "2-4:A/1.1|8:A/1.1");
     model.addRange("1", 5, 7, "B");
-    assertEquals(testee.getAtomSpec(model, false),
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.RESIDUE_ONLY),
             "2-4:A/1.1|8:A/1.1|5-7:B/1.1");
     model.addRange("1", 3, 5, "A");
-    assertEquals(testee.getAtomSpec(model, false),
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.RESIDUE_ONLY),
             "2-5:A/1.1|8:A/1.1|5-7:B/1.1");
     model.addRange("2", 1, 4, "B");
-    assertEquals(testee.getAtomSpec(model, false),
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.RESIDUE_ONLY),
             "2-5:A/1.1|8:A/1.1|5-7:B/1.1|1-4:B/2.1");
     model.addRange("2", 5, 9, "C");
-    assertEquals(testee.getAtomSpec(model, false),
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.RESIDUE_ONLY),
             "2-5:A/1.1|8:A/1.1|5-7:B/1.1|1-4:B/2.1|5-9:C/2.1");
     model.addRange("1", 8, 10, "B");
-    assertEquals(testee.getAtomSpec(model, false),
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.RESIDUE_ONLY),
             "2-5:A/1.1|8:A/1.1|5-10:B/1.1|1-4:B/2.1|5-9:C/2.1");
     model.addRange("1", 8, 9, "B");
-    assertEquals(testee.getAtomSpec(model, false),
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.RESIDUE_ONLY),
             "2-5:A/1.1|8:A/1.1|5-10:B/1.1|1-4:B/2.1|5-9:C/2.1");
     model.addRange("2", 3, 10, "C"); // subsumes 5-9
-    assertEquals(testee.getAtomSpec(model, false),
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.RESIDUE_ONLY),
             "2-5:A/1.1|8:A/1.1|5-10:B/1.1|1-4:B/2.1|3-10:C/2.1");
     model.addRange("5", 25, 35, " ");
-    assertEquals(testee.getAtomSpec(model, false),
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.RESIDUE_ONLY),
             "2-5:A/1.1|8:A/1.1|5-10:B/1.1|1-4:B/2.1|3-10:C/2.1|25-35:/5.1");
 
   }
@@ -199,7 +200,7 @@ public class JmolCommandsTest
     toAlign.addRange("2", 20, 21, "B");
     toAlign.addRange("2", 22, 22, "C");
     List<StructureCommandI> command = testee.superposeStructures(ref,
-            toAlign);
+            toAlign, AtomSpecType.ALPHA); // doesn't matter for Jmol whether nuc or protein
     assertEquals(command.size(), 1);
     String refSpec = "12-14:A/1.1|18:B/1.1|22-23:B/1.1";
     String toAlignSpec = "15-17:B/2.1|20-21:B/2.1|22:C/2.1";
index f6bad92..7759724 100644 (file)
@@ -36,6 +36,7 @@ import jalview.ext.rbvi.chimera.ChimeraCommands;
 import jalview.structure.AtomSpecModel;
 import jalview.structure.StructureCommand;
 import jalview.structure.StructureCommandI;
+import jalview.structure.StructureCommandsI.AtomSpecType;
 
 public class PymolCommandsTest
 {
@@ -80,32 +81,32 @@ public class PymolCommandsTest
   public void testGetAtomSpec()
   {
     AtomSpecModel model = new AtomSpecModel();
-    assertEquals(testee.getAtomSpec(model, false), "");
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.RESIDUE_ONLY), "");
     model.addRange("1", 2, 4, "A");
-    assertEquals(testee.getAtomSpec(model, false), "1//A/2-4/");
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.RESIDUE_ONLY), "1//A/2-4/");
     model.addRange("1", 8, 8, "A");
-    assertEquals(testee.getAtomSpec(model, false), "1//A/2-4+8/");
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.RESIDUE_ONLY), "1//A/2-4+8/");
     model.addRange("1", 5, 7, "B");
-    assertEquals(testee.getAtomSpec(model, false), "1//A/2-4+8/ 1//B/5-7/");
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.RESIDUE_ONLY), "1//A/2-4+8/ 1//B/5-7/");
     model.addRange("1", 3, 5, "A");
-    assertEquals(testee.getAtomSpec(model, false), "1//A/2-5+8/ 1//B/5-7/");
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.RESIDUE_ONLY), "1//A/2-5+8/ 1//B/5-7/");
     model.addRange("0", 1, 4, "B");
-    assertEquals(testee.getAtomSpec(model, false),
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.RESIDUE_ONLY),
             "0//B/1-4/ 1//A/2-5+8/ 1//B/5-7/");
     model.addRange("0", 5, 9, "C");
-    assertEquals(testee.getAtomSpec(model, false),
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.RESIDUE_ONLY),
             "0//B/1-4/ 0//C/5-9/ 1//A/2-5+8/ 1//B/5-7/");
     model.addRange("1", 8, 10, "B");
-    assertEquals(testee.getAtomSpec(model, false),
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.RESIDUE_ONLY),
             "0//B/1-4/ 0//C/5-9/ 1//A/2-5+8/ 1//B/5-10/");
     model.addRange("1", 8, 9, "B");
-    assertEquals(testee.getAtomSpec(model, false),
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.RESIDUE_ONLY),
             "0//B/1-4/ 0//C/5-9/ 1//A/2-5+8/ 1//B/5-10/");
     model.addRange("0", 3, 10, "C"); // subsumes 5-9
-    assertEquals(testee.getAtomSpec(model, false),
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.RESIDUE_ONLY),
             "0//B/1-4/ 0//C/3-10/ 1//A/2-5+8/ 1//B/5-10/");
     model.addRange("5", 25, 35, " ");
-    assertEquals(testee.getAtomSpec(model, false),
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.RESIDUE_ONLY),
             "0//B/1-4/ 0//C/3-10/ 1//A/2-5+8/ 1//B/5-10/ 5///25-35/");
 
   }
@@ -122,16 +123,16 @@ public class PymolCommandsTest
     toAlign.addRange("2", 20, 21, "B");
     toAlign.addRange("2", 22, 22, "C");
     List<StructureCommandI> commands = testee.superposeStructures(ref,
-            toAlign);
+            toAlign, AtomSpecType.ALPHA);
     assertEquals(commands.size(), 2);
-    String refSpecCA = "1//A/12-14/CA 1//B/18+22-23/CA";
-    String toAlignSpecCA = "2//B/15-17+20-21/CA 2//C/22/CA";
+    String refSpecCA = "(1//A/12-14/CA 1//B/18+22-23/CA";
+    String toAlignSpecCA = "(2//B/15-17+20-21/CA 2//C/22/CA";
     String refSpec = "1//A/12-14/ 1//B/18+22-23/";
     String toAlignSpec = "2//B/15-17+20-21/ 2//C/22/";
-
+    String altLoc =  " and (altloc '' or altloc 'a'))";
     // super command: separate arguments for regions to align
     assertEquals(commands.get(0),
-            new StructureCommand("super", refSpecCA, toAlignSpecCA));
+            new StructureCommand("pair_fit", toAlignSpecCA+altLoc, refSpecCA+altLoc));
     // show aligned regions: one argument for combined atom specs
     assertEquals(commands.get(1), new StructureCommand("show", "cartoon",
             refSpec + " " + toAlignSpec));
@@ -141,34 +142,34 @@ public class PymolCommandsTest
   public void testGetAtomSpec_alphaOnly()
   {
     AtomSpecModel model = new AtomSpecModel();
-    assertEquals(testee.getAtomSpec(model, true), "");
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.ALPHA), "");
     model.addRange("1", 2, 4, "A");
-    assertEquals(testee.getAtomSpec(model, true), "1//A/2-4/CA");
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.ALPHA), "1//A/2-4/CA");
     model.addRange("1", 8, 8, "A");
-    assertEquals(testee.getAtomSpec(model, true), "1//A/2-4+8/CA");
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.ALPHA), "1//A/2-4+8/CA");
     model.addRange("1", 5, 7, "B");
-    assertEquals(testee.getAtomSpec(model, true),
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.ALPHA),
             "1//A/2-4+8/CA 1//B/5-7/CA");
     model.addRange("1", 3, 5, "A");
-    assertEquals(testee.getAtomSpec(model, true),
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.ALPHA),
             "1//A/2-5+8/CA 1//B/5-7/CA");
     model.addRange("0", 1, 4, "B");
-    assertEquals(testee.getAtomSpec(model, true),
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.ALPHA),
             "0//B/1-4/CA 1//A/2-5+8/CA 1//B/5-7/CA");
     model.addRange("0", 5, 9, "C");
-    assertEquals(testee.getAtomSpec(model, true),
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.ALPHA),
             "0//B/1-4/CA 0//C/5-9/CA 1//A/2-5+8/CA 1//B/5-7/CA");
     model.addRange("1", 8, 10, "B");
-    assertEquals(testee.getAtomSpec(model, true),
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.ALPHA),
             "0//B/1-4/CA 0//C/5-9/CA 1//A/2-5+8/CA 1//B/5-10/CA");
     model.addRange("1", 8, 9, "B");
-    assertEquals(testee.getAtomSpec(model, true),
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.ALPHA),
             "0//B/1-4/CA 0//C/5-9/CA 1//A/2-5+8/CA 1//B/5-10/CA");
     model.addRange("0", 3, 10, "C"); // subsumes 5-9
-    assertEquals(testee.getAtomSpec(model, true),
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.ALPHA),
             "0//B/1-4/CA 0//C/3-10/CA 1//A/2-5+8/CA 1//B/5-10/CA");
     model.addRange("5", 25, 35, " ");
-    assertEquals(testee.getAtomSpec(model, true),
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.ALPHA),
             "0//B/1-4/CA 0//C/3-10/CA 1//A/2-5+8/CA 1//B/5-10/CA 5///25-35/CA");
   }
 
index 6880985..23e42ca 100644 (file)
@@ -35,6 +35,7 @@ import org.testng.annotations.Test;
 import jalview.structure.AtomSpecModel;
 import jalview.structure.StructureCommand;
 import jalview.structure.StructureCommandI;
+import jalview.structure.StructureCommandsI.AtomSpecType;
 
 public class ChimeraCommandsTest
 {
@@ -161,32 +162,32 @@ public class ChimeraCommandsTest
   public void testGetAtomSpec()
   {
     AtomSpecModel model = new AtomSpecModel();
-    assertEquals(testee.getAtomSpec(model, false), "");
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.RESIDUE_ONLY), "");
     model.addRange("1", 2, 4, "A");
-    assertEquals(testee.getAtomSpec(model, false), "#1:2-4.A");
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.RESIDUE_ONLY), "#1:2-4.A");
     model.addRange("1", 8, 8, "A");
-    assertEquals(testee.getAtomSpec(model, false), "#1:2-4.A,8.A");
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.RESIDUE_ONLY), "#1:2-4.A,8.A");
     model.addRange("1", 5, 7, "B");
-    assertEquals(testee.getAtomSpec(model, false), "#1:2-4.A,8.A,5-7.B");
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.RESIDUE_ONLY), "#1:2-4.A,8.A,5-7.B");
     model.addRange("1", 3, 5, "A");
-    assertEquals(testee.getAtomSpec(model, false), "#1:2-5.A,8.A,5-7.B");
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.RESIDUE_ONLY), "#1:2-5.A,8.A,5-7.B");
     model.addRange("0", 1, 4, "B");
-    assertEquals(testee.getAtomSpec(model, false),
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.RESIDUE_ONLY),
             "#0:1-4.B|#1:2-5.A,8.A,5-7.B");
     model.addRange("0", 5, 9, "C");
-    assertEquals(testee.getAtomSpec(model, false),
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.RESIDUE_ONLY),
             "#0:1-4.B,5-9.C|#1:2-5.A,8.A,5-7.B");
     model.addRange("1", 8, 10, "B");
-    assertEquals(testee.getAtomSpec(model, false),
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.RESIDUE_ONLY),
             "#0:1-4.B,5-9.C|#1:2-5.A,8.A,5-10.B");
     model.addRange("1", 8, 9, "B");
-    assertEquals(testee.getAtomSpec(model, false),
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.RESIDUE_ONLY),
             "#0:1-4.B,5-9.C|#1:2-5.A,8.A,5-10.B");
     model.addRange("0", 3, 10, "C"); // subsumes 5-9
-    assertEquals(testee.getAtomSpec(model, false),
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.RESIDUE_ONLY),
             "#0:1-4.B,3-10.C|#1:2-5.A,8.A,5-10.B");
     model.addRange("5", 25, 35, " ");
-    assertEquals(testee.getAtomSpec(model, false),
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.RESIDUE_ONLY),
             "#0:1-4.B,3-10.C|#1:2-5.A,8.A,5-10.B|#5:25-35.");
 
   }
@@ -203,7 +204,7 @@ public class ChimeraCommandsTest
     toAlign.addRange("2", 20, 21, "B");
     toAlign.addRange("2", 22, 22, "C");
     List<StructureCommandI> command = testee.superposeStructures(ref,
-            toAlign);
+            toAlign, AtomSpecType.ALPHA);
     // qualifier to restrict match to CA and no altlocs
     String carbonAlphas = "@CA&~@.B-Z&~@.2-9";
     String refSpec = "#1:12-14.A,18.B,22-23.B";
@@ -218,36 +219,36 @@ public class ChimeraCommandsTest
   public void testGetAtomSpec_alphaOnly()
   {
     AtomSpecModel model = new AtomSpecModel();
-    assertEquals(testee.getAtomSpec(model, true), "");
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.ALPHA), "");
     model.addRange("1", 2, 4, "A");
-    assertEquals(testee.getAtomSpec(model, true),
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.ALPHA),
             "#1:2-4.A@CA&~@.B-Z&~@.2-9");
     model.addRange("1", 8, 8, "A");
-    assertEquals(testee.getAtomSpec(model, true),
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.ALPHA),
             "#1:2-4.A,8.A@CA&~@.B-Z&~@.2-9");
     model.addRange("1", 5, 7, "B");
-    assertEquals(testee.getAtomSpec(model, true),
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.ALPHA),
             "#1:2-4.A,8.A,5-7.B@CA&~@.B-Z&~@.2-9");
     model.addRange("1", 3, 5, "A");
-    assertEquals(testee.getAtomSpec(model, true),
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.ALPHA),
             "#1:2-5.A,8.A,5-7.B@CA&~@.B-Z&~@.2-9");
     model.addRange("0", 1, 4, "B");
-    assertEquals(testee.getAtomSpec(model, true),
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.ALPHA),
             "#0:1-4.B@CA&~@.B-Z&~@.2-9|#1:2-5.A,8.A,5-7.B@CA&~@.B-Z&~@.2-9");
     model.addRange("0", 5, 9, "C");
-    assertEquals(testee.getAtomSpec(model, true),
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.ALPHA),
             "#0:1-4.B,5-9.C@CA&~@.B-Z&~@.2-9|#1:2-5.A,8.A,5-7.B@CA&~@.B-Z&~@.2-9");
     model.addRange("1", 8, 10, "B");
-    assertEquals(testee.getAtomSpec(model, true),
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.ALPHA),
             "#0:1-4.B,5-9.C@CA&~@.B-Z&~@.2-9|#1:2-5.A,8.A,5-10.B@CA&~@.B-Z&~@.2-9");
     model.addRange("1", 8, 9, "B");
-    assertEquals(testee.getAtomSpec(model, true),
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.ALPHA),
             "#0:1-4.B,5-9.C@CA&~@.B-Z&~@.2-9|#1:2-5.A,8.A,5-10.B@CA&~@.B-Z&~@.2-9");
     model.addRange("0", 3, 10, "C"); // subsumes 5-9
-    assertEquals(testee.getAtomSpec(model, true),
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.ALPHA),
             "#0:1-4.B,3-10.C@CA&~@.B-Z&~@.2-9|#1:2-5.A,8.A,5-10.B@CA&~@.B-Z&~@.2-9");
     model.addRange("5", 25, 35, " "); // empty chain code
-    assertEquals(testee.getAtomSpec(model, true),
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.ALPHA),
             "#0:1-4.B,3-10.C@CA&~@.B-Z&~@.2-9|#1:2-5.A,8.A,5-10.B@CA&~@.B-Z&~@.2-9|#5:25-35.@CA&~@.B-Z&~@.2-9");
 
   }
index 439401a..143a5d8 100644 (file)
@@ -35,6 +35,7 @@ import org.testng.annotations.Test;
 import jalview.structure.AtomSpecModel;
 import jalview.structure.StructureCommand;
 import jalview.structure.StructureCommandI;
+import jalview.structure.StructureCommandsI.AtomSpecType;
 
 public class ChimeraXCommandsTest
 {
@@ -187,7 +188,7 @@ public class ChimeraXCommandsTest
     toAlign.addRange("2", 20, 21, "B");
     toAlign.addRange("2", 22, 22, "C");
     List<StructureCommandI> command = testee.superposeStructures(ref,
-            toAlign);
+            toAlign,AtomSpecType.ALPHA);
     assertEquals(command.size(), 1);
     String cmd = command.get(0).getCommand();
     String refSpec = "#1/A:12-14/B:18,22-23";
@@ -207,32 +208,33 @@ public class ChimeraXCommandsTest
   public void testGetAtomSpec()
   {
     AtomSpecModel model = new AtomSpecModel();
-    assertEquals(testee.getAtomSpec(model, false), "");
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.RESIDUE_ONLY
+            ), "");
     model.addRange("1", 2, 4, "A");
-    assertEquals(testee.getAtomSpec(model, false), "#1/A:2-4");
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.RESIDUE_ONLY), "#1/A:2-4");
     model.addRange("1", 8, 8, "A");
-    assertEquals(testee.getAtomSpec(model, false), "#1/A:2-4,8");
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.RESIDUE_ONLY), "#1/A:2-4,8");
     model.addRange("1", 5, 7, "B");
-    assertEquals(testee.getAtomSpec(model, false), "#1/A:2-4,8/B:5-7");
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.RESIDUE_ONLY), "#1/A:2-4,8/B:5-7");
     model.addRange("1", 3, 5, "A");
-    assertEquals(testee.getAtomSpec(model, false), "#1/A:2-5,8/B:5-7");
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.RESIDUE_ONLY), "#1/A:2-5,8/B:5-7");
     model.addRange("0", 1, 4, "B");
-    assertEquals(testee.getAtomSpec(model, false),
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.RESIDUE_ONLY),
             "#0/B:1-4|#1/A:2-5,8/B:5-7");
     model.addRange("0", 5, 9, "C");
-    assertEquals(testee.getAtomSpec(model, false),
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.RESIDUE_ONLY),
             "#0/B:1-4/C:5-9|#1/A:2-5,8/B:5-7");
     model.addRange("1", 8, 10, "B");
-    assertEquals(testee.getAtomSpec(model, false),
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.RESIDUE_ONLY),
             "#0/B:1-4/C:5-9|#1/A:2-5,8/B:5-10");
     model.addRange("1", 8, 9, "B");
-    assertEquals(testee.getAtomSpec(model, false),
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.RESIDUE_ONLY),
             "#0/B:1-4/C:5-9|#1/A:2-5,8/B:5-10");
     model.addRange("0", 3, 10, "C"); // subsumes 5-9
-    assertEquals(testee.getAtomSpec(model, false),
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.RESIDUE_ONLY),
             "#0/B:1-4/C:3-10|#1/A:2-5,8/B:5-10");
     model.addRange("5", 25, 35, " ");
-    assertEquals(testee.getAtomSpec(model, false),
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.RESIDUE_ONLY),
             "#0/B:1-4/C:3-10|#1/A:2-5,8/B:5-10|#5/:25-35");
   }
 
@@ -240,32 +242,32 @@ public class ChimeraXCommandsTest
   public void testGetAtomSpec_alphaOnly()
   {
     AtomSpecModel model = new AtomSpecModel();
-    assertEquals(testee.getAtomSpec(model, true), "");
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.ALPHA), "");
     model.addRange("1", 2, 4, "A");
-    assertEquals(testee.getAtomSpec(model, true), "#1/A:2-4@CA");
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.ALPHA), "#1/A:2-4@CA");
     model.addRange("1", 8, 8, "A");
-    assertEquals(testee.getAtomSpec(model, true), "#1/A:2-4,8@CA");
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.ALPHA), "#1/A:2-4,8@CA");
     model.addRange("1", 5, 7, "B");
-    assertEquals(testee.getAtomSpec(model, true), "#1/A:2-4,8/B:5-7@CA");
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.ALPHA), "#1/A:2-4,8/B:5-7@CA");
     model.addRange("1", 3, 5, "A");
-    assertEquals(testee.getAtomSpec(model, true), "#1/A:2-5,8/B:5-7@CA");
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.ALPHA), "#1/A:2-5,8/B:5-7@CA");
     model.addRange("0", 1, 4, "B");
-    assertEquals(testee.getAtomSpec(model, true),
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.ALPHA),
             "#0/B:1-4@CA|#1/A:2-5,8/B:5-7@CA");
     model.addRange("0", 5, 9, "C");
-    assertEquals(testee.getAtomSpec(model, true),
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.ALPHA),
             "#0/B:1-4/C:5-9@CA|#1/A:2-5,8/B:5-7@CA");
     model.addRange("1", 8, 10, "B");
-    assertEquals(testee.getAtomSpec(model, true),
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.ALPHA),
             "#0/B:1-4/C:5-9@CA|#1/A:2-5,8/B:5-10@CA");
     model.addRange("1", 8, 9, "B");
-    assertEquals(testee.getAtomSpec(model, true),
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.ALPHA),
             "#0/B:1-4/C:5-9@CA|#1/A:2-5,8/B:5-10@CA");
     model.addRange("0", 3, 10, "C"); // subsumes 5-9
-    assertEquals(testee.getAtomSpec(model, true),
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.ALPHA),
             "#0/B:1-4/C:3-10@CA|#1/A:2-5,8/B:5-10@CA");
     model.addRange("5", 25, 35, " "); // empty chain code
-    assertEquals(testee.getAtomSpec(model, true),
+    assertEquals(testee.getAtomSpec(model, AtomSpecType.ALPHA),
             "#0/B:1-4/C:3-10@CA|#1/A:2-5,8/B:5-10@CA|#5/:25-35@CA");
   }
 
index c1ad03a..5187167 100644 (file)
@@ -57,6 +57,7 @@ import jalview.schemes.JalviewColourScheme;
 import jalview.structure.AtomSpec;
 import jalview.structure.AtomSpecModel;
 import jalview.structure.StructureCommandI;
+import jalview.structure.StructureCommandsI.AtomSpecType;
 import jalview.structure.StructureMapping;
 import jalview.structure.StructureSelectionManager;
 import junit.extensions.PA;
@@ -470,7 +471,7 @@ public class AAStructureBindingModelTest
     Color mColor = new Color(0x82827d);
     AtomSpecModel atomSpec = colours.get(mColor);
     assertNotNull(atomSpec);
-    assertEquals(helper.getAtomSpec(atomSpec, false), "#0:21.A|#1:21.B");
+    assertEquals(helper.getAtomSpec(atomSpec, AtomSpecType.RESIDUE_ONLY), "#0:21.A|#1:21.B");
 
     /*
      * H colour is #60609f, seq1.2 mapped to structure 0 residue 22
@@ -478,7 +479,7 @@ public class AAStructureBindingModelTest
     Color hColor = new Color(0x60609f);
     atomSpec = colours.get(hColor);
     assertNotNull(atomSpec);
-    assertEquals(helper.getAtomSpec(atomSpec, false), "#0:22.A");
+    assertEquals(helper.getAtomSpec(atomSpec, AtomSpecType.RESIDUE_ONLY), "#0:22.A");
 
     /*
      * V colour is #ffff00, seq2.2 mapped to structure 1 residue 22
@@ -486,7 +487,7 @@ public class AAStructureBindingModelTest
     Color vColor = new Color(0xffff00);
     atomSpec = colours.get(vColor);
     assertNotNull(atomSpec);
-    assertEquals(helper.getAtomSpec(atomSpec, false), "#1:22.B");
+    assertEquals(helper.getAtomSpec(atomSpec, AtomSpecType.RESIDUE_ONLY), "#1:22.B");
 
     /*
      * hidden columns are Gray (128, 128, 128)
@@ -495,7 +496,7 @@ public class AAStructureBindingModelTest
     Color gray = new Color(128, 128, 128);
     atomSpec = colours.get(gray);
     assertNotNull(atomSpec);
-    assertEquals(helper.getAtomSpec(atomSpec, false), "#0:23-25.A|#1:23-25.B");
+    assertEquals(helper.getAtomSpec(atomSpec, AtomSpecType.RESIDUE_ONLY), "#0:23-25.A|#1:23-25.B");
 
     /*
      * S and G are both coloured #4949b6, structure residues 26-30
@@ -503,7 +504,7 @@ public class AAStructureBindingModelTest
     Color sgColour = new Color(0x4949b6);
     atomSpec = colours.get(sgColour);
     assertNotNull(atomSpec);
-    assertEquals(helper.getAtomSpec(atomSpec, false),
+    assertEquals(helper.getAtomSpec(atomSpec, AtomSpecType.RESIDUE_ONLY),
             "#0:26-30.A|#1:26-30.B");
   }
 }
\ No newline at end of file