Merge branch 'develop' into feature/JAL-3390hideUnmappedStructure
[jalview.git] / src / jalview / structure / AtomSpec.java
index f20cd31..8b8161f 100644 (file)
@@ -43,52 +43,70 @@ public class AtomSpec
    * Parses a Chimera atomspec e.g. #1:12.A to construct an AtomSpec model (with
    * null pdb file name)
    * 
+   * <pre>
+   * Chimera format: 
+   *    #1.2:12-20.A     model 1, submodel 2, chain A, atoms 12-20
+   * ChimeraX format:
+   *    #1.2/A:12-20
+   * </pre>
+   * 
    * @param spec
+   * @param chimeraX
    * @return
    * @throw IllegalArgumentException if the spec cannot be parsed, or represents
    *        more than one residue
+   * @see https://www.cgl.ucsf.edu/chimera/current/docs/UsersGuide/midas/frameatom_spec.html
+   * @see http://rbvi.ucsf.edu/chimerax/docs/user/commands/atomspec.html
    */
-  public static AtomSpec fromChimeraAtomspec(String spec)
+  public static AtomSpec fromChimeraAtomspec(String spec, boolean chimeraX)
   {
-    int colonPos = spec.indexOf(":");
-    if (colonPos == -1)
+    int modelSeparatorPos = spec.indexOf(chimeraX ? "/" : ":");
+    if (modelSeparatorPos == -1)
     {
       throw new IllegalArgumentException(spec);
     }
 
     int hashPos = spec.indexOf("#");
-    if (hashPos == -1 && colonPos != 0)
+    if (hashPos == -1 && modelSeparatorPos != 0)
     {
       // # is missing but something precedes : - reject
       throw new IllegalArgumentException(spec);
     }
 
-    String modelSubmodel = spec.substring(hashPos + 1, colonPos);
-    int dotPos = modelSubmodel.indexOf(".");
+    String modelSubmodel = spec.substring(hashPos + 1, modelSeparatorPos);
     int modelId = 0;
     try
     {
-      modelId = Integer.valueOf(dotPos == -1 ? modelSubmodel
-              : modelSubmodel.substring(0, dotPos));
+      int subModelPos = modelSubmodel.indexOf(".");
+      modelId = Integer.valueOf(
+              subModelPos > 0 ? modelSubmodel.substring(0, subModelPos)
+                      : modelSubmodel);
     } catch (NumberFormatException e)
     {
       // ignore, default to model 0
     }
 
-    String residueChain = spec.substring(colonPos + 1);
-    dotPos = residueChain.indexOf(".");
+    /*
+     * now process what follows the model, either
+     * Chimera:  atoms.chain
+     * ChimeraX: chain:atoms
+     */
+    String atomsAndChain = spec.substring(modelSeparatorPos + 1);
+    String[] tokens = atomsAndChain.split(chimeraX ? "\\:" : "\\.");
+    String atoms = tokens.length == 1 ? atomsAndChain
+            : (chimeraX ? tokens[1] : tokens[0]);
     int resNum = 0;
     try
     {
-      resNum = Integer.parseInt(dotPos == -1 ? residueChain
-              : residueChain.substring(0, dotPos));
+      resNum = Integer.parseInt(atoms);
     } catch (NumberFormatException e)
     {
       // could be a range e.g. #1:4-7.B
       throw new IllegalArgumentException(spec);
     }
 
-    String chainId = dotPos == -1 ? "" : residueChain.substring(dotPos + 1);
+    String chainId = tokens.length == 1 ? ""
+            : (chimeraX ? tokens[0] : tokens[1]);
 
     return new AtomSpec(modelId, chainId, resNum, 0);
   }