X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2Fjalview%2Fstructure%2FAtomSpec.java;h=8b8161fe6bd265f2451742557744a11a6223e7a9;hb=34567bb79dfa8f163f44c3f3448083fcd145f308;hp=54c57daeb26ad71e5e6caa62f37a77a31135ac6d;hpb=c19d2a91ca05e052e3408bf5852d88eb5d0608f1;p=jalview.git diff --git a/src/jalview/structure/AtomSpec.java b/src/jalview/structure/AtomSpec.java index 54c57da..8b8161f 100644 --- a/src/jalview/structure/AtomSpec.java +++ b/src/jalview/structure/AtomSpec.java @@ -1,6 +1,6 @@ /* - * Jalview - A Sequence Alignment Editor and Viewer (Version 2.9.0b2) - * Copyright (C) 2015 The Jalview Authors + * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$) + * Copyright (C) $$Year-Rel$$ The Jalview Authors * * This file is part of Jalview. * @@ -29,9 +29,8 @@ package jalview.structure; */ public class AtomSpec { - // TODO clarify do we want pdbFile here, or pdbId? - // compare highlightAtom in 2.8.2 for JalviewJmolBinding and - // javascript.MouseOverStructureListener + int modelNo; + private String pdbFile; private String chain; @@ -41,6 +40,78 @@ public class AtomSpec private int atomIndex; /** + * Parses a Chimera atomspec e.g. #1:12.A to construct an AtomSpec model (with + * null pdb file name) + * + *
+   * Chimera format: 
+   *    #1.2:12-20.A     model 1, submodel 2, chain A, atoms 12-20
+   * ChimeraX format:
+   *    #1.2/A:12-20
+   * 
+ * + * @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, boolean chimeraX) + { + int modelSeparatorPos = spec.indexOf(chimeraX ? "/" : ":"); + if (modelSeparatorPos == -1) + { + throw new IllegalArgumentException(spec); + } + + int hashPos = spec.indexOf("#"); + if (hashPos == -1 && modelSeparatorPos != 0) + { + // # is missing but something precedes : - reject + throw new IllegalArgumentException(spec); + } + + String modelSubmodel = spec.substring(hashPos + 1, modelSeparatorPos); + int modelId = 0; + try + { + int subModelPos = modelSubmodel.indexOf("."); + modelId = Integer.valueOf( + subModelPos > 0 ? modelSubmodel.substring(0, subModelPos) + : modelSubmodel); + } catch (NumberFormatException e) + { + // ignore, default to model 0 + } + + /* + * 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(atoms); + } catch (NumberFormatException e) + { + // could be a range e.g. #1:4-7.B + throw new IllegalArgumentException(spec); + } + + String chainId = tokens.length == 1 ? "" + : (chimeraX ? tokens[0] : tokens[1]); + + return new AtomSpec(modelId, chainId, resNum, 0); + } + + /** * Constructor * * @param pdbFile @@ -56,6 +127,22 @@ public class AtomSpec this.atomIndex = atomNo; } + /** + * Constructor + * + * @param modelId + * @param chainId + * @param resNo + * @param atomNo + */ + public AtomSpec(int modelId, String chainId, int resNo, int atomNo) + { + this.modelNo = modelId; + this.chain = chainId; + this.pdbResNum = resNo; + this.atomIndex = atomNo; + } + public String getPdbFile() { return pdbFile; @@ -76,6 +163,16 @@ public class AtomSpec return atomIndex; } + public int getModelNumber() + { + return modelNo; + } + + public void setPdbFile(String file) + { + pdbFile = file; + } + @Override public String toString() {