From 41fa09b7271c0ce6134307c2c6cc2536ee44f365 Mon Sep 17 00:00:00 2001 From: gmungoc Date: Mon, 14 Nov 2016 12:29:24 +0000 Subject: [PATCH] JAL-2296 parse Chimera atomspec to AtomSpec --- src/jalview/structure/AtomSpec.java | 82 ++++++++++++++++++++++++++++++ test/jalview/structure/AtomSpecTest.java | 74 +++++++++++++++++++++++++++ 2 files changed, 156 insertions(+) create mode 100644 test/jalview/structure/AtomSpecTest.java diff --git a/src/jalview/structure/AtomSpec.java b/src/jalview/structure/AtomSpec.java index 271bf1d..f20cd31 100644 --- a/src/jalview/structure/AtomSpec.java +++ b/src/jalview/structure/AtomSpec.java @@ -29,6 +29,8 @@ package jalview.structure; */ public class AtomSpec { + int modelNo; + private String pdbFile; private String chain; @@ -38,6 +40,60 @@ 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) + * + * @param spec + * @return + * @throw IllegalArgumentException if the spec cannot be parsed, or represents + * more than one residue + */ + public static AtomSpec fromChimeraAtomspec(String spec) + { + int colonPos = spec.indexOf(":"); + if (colonPos == -1) + { + throw new IllegalArgumentException(spec); + } + + int hashPos = spec.indexOf("#"); + if (hashPos == -1 && colonPos != 0) + { + // # is missing but something precedes : - reject + throw new IllegalArgumentException(spec); + } + + String modelSubmodel = spec.substring(hashPos + 1, colonPos); + int dotPos = modelSubmodel.indexOf("."); + int modelId = 0; + try + { + modelId = Integer.valueOf(dotPos == -1 ? modelSubmodel + : modelSubmodel.substring(0, dotPos)); + } catch (NumberFormatException e) + { + // ignore, default to model 0 + } + + String residueChain = spec.substring(colonPos + 1); + dotPos = residueChain.indexOf("."); + int resNum = 0; + try + { + resNum = Integer.parseInt(dotPos == -1 ? residueChain + : residueChain.substring(0, dotPos)); + } 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); + + return new AtomSpec(modelId, chainId, resNum, 0); + } + + /** * Constructor * * @param pdbFile @@ -53,6 +109,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; @@ -73,6 +145,16 @@ public class AtomSpec return atomIndex; } + public int getModelNumber() + { + return modelNo; + } + + public void setPdbFile(String file) + { + pdbFile = file; + } + @Override public String toString() { diff --git a/test/jalview/structure/AtomSpecTest.java b/test/jalview/structure/AtomSpecTest.java new file mode 100644 index 0000000..ea53131 --- /dev/null +++ b/test/jalview/structure/AtomSpecTest.java @@ -0,0 +1,74 @@ +package jalview.structure; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNull; +import static org.testng.Assert.fail; + +import org.testng.annotations.Test; + +public class AtomSpecTest +{ + @Test + public void testFromChimeraAtomSpec() + { + AtomSpec as = AtomSpec.fromChimeraAtomspec("#1:12.B"); + assertEquals(as.getModelNumber(), 1); + assertEquals(as.getPdbResNum(), 12); + assertEquals(as.getChain(), "B"); + assertNull(as.getPdbFile()); + + // no model - default to zero + as = AtomSpec.fromChimeraAtomspec(":13.C"); + assertEquals(as.getModelNumber(), 0); + assertEquals(as.getPdbResNum(), 13); + assertEquals(as.getChain(), "C"); + assertNull(as.getPdbFile()); + + // model.submodel + as = AtomSpec.fromChimeraAtomspec("#3.2:15"); + assertEquals(as.getModelNumber(), 3); + assertEquals(as.getPdbResNum(), 15); + assertEquals(as.getChain(), ""); + assertNull(as.getPdbFile()); + + String spec = "3:12.B"; + try + { + as = AtomSpec.fromChimeraAtomspec(spec); + fail("Expected exception for " + spec); + } catch (IllegalArgumentException e) + { + // ok + } + + spec = "#3:12-14.B"; + try + { + as = AtomSpec.fromChimeraAtomspec(spec); + fail("Expected exception for " + spec); + } catch (IllegalArgumentException e) + { + // ok + } + + spec = ""; + try + { + as = AtomSpec.fromChimeraAtomspec(spec); + fail("Expected exception for " + spec); + } catch (IllegalArgumentException e) + { + // ok + } + + spec = null; + try + { + as = AtomSpec.fromChimeraAtomspec(spec); + fail("Expected exception for " + spec); + } catch (NullPointerException e) + { + // ok + } + } +} -- 1.7.10.2