From 0d2d59f0e052bee613f654c97e4b53e5135634a9 Mon Sep 17 00:00:00 2001 From: John May Date: Tue, 6 Sep 2016 14:08:49 +0100 Subject: [PATCH] =?UTF-8?q?Minor=20quirk=20of=20beam=20internal,=20a=20rec?= =?UTF-8?q?ent=20update=20in=20CDK=20unsets=20the=20bond=20order=20when=20?= =?UTF-8?q?reading=20non-kekul=C3=A9=20SMILES,=20during=20the=20conversion?= =?UTF-8?q?=20we=20need=20to=20tell=20the=20converter=20this=20to=20avoid?= =?UTF-8?q?=20nulling=20out=20single=20bonds=20between=20aromatic=20atoms.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/org/openscience/cdk/smiles/BeamToCDK.java | 9 +++++---- .../org/openscience/cdk/smiles/SmilesParser.java | 3 ++- .../org/openscience/cdk/smiles/BeamToCDKTest.java | 8 ++++---- .../org/openscience/cdk/smiles/SmilesParserTest.java | 12 ++++++++++++ 4 files changed, 23 insertions(+), 9 deletions(-) diff --git a/storage/smiles/src/main/java/org/openscience/cdk/smiles/BeamToCDK.java b/storage/smiles/src/main/java/org/openscience/cdk/smiles/BeamToCDK.java index ca82ea33fef..e200fe73436 100644 --- a/storage/smiles/src/main/java/org/openscience/cdk/smiles/BeamToCDK.java +++ b/storage/smiles/src/main/java/org/openscience/cdk/smiles/BeamToCDK.java @@ -108,13 +108,14 @@ final class BeamToCDK { * Convert a Beam ChemicalGraph to a CDK IAtomContainer. * * @param g Beam graph instance + * @param kekule the input has been kekulzied * @return the CDK {@link IAtomContainer} for the input * @throws IllegalArgumentException the Beam graph was not 'expanded' - and * contained organic subset atoms. If this * happens use the Beam Functions.expand() * to */ - IAtomContainer toAtomContainer(Graph g) { + IAtomContainer toAtomContainer(Graph g, boolean kekule) { IAtomContainer ac = emptyContainer(); IAtom[] atoms = new IAtom[g.order()]; @@ -125,7 +126,7 @@ IAtomContainer toAtomContainer(Graph g) { for (int i = 0; i < g.order(); i++) atoms[i] = toCDKAtom(g.atom(i), g.implHCount(i)); for (Edge e : g.edges()) - bonds[j++] = toCDKBond(e, atoms); + bonds[j++] = toCDKBond(e, atoms, kekule); // atom-centric stereo-specification (only tetrahedral ATM) for (int u = 0; u < g.order(); u++) { @@ -422,7 +423,7 @@ IAtom newCDKAtom(Atom atom) { * @param atoms the already converted atoms * @return new bond instance */ - IBond toCDKBond(Edge edge, IAtom[] atoms) { + IBond toCDKBond(Edge edge, IAtom[] atoms, boolean kekule) { int u = edge.either(); int v = edge.other(u); @@ -439,7 +440,7 @@ IBond toCDKBond(Edge edge, IAtom[] atoms) { atoms[v].setIsAromatic(true); break; case IMPLICIT: - if (atoms[u].isAromatic() && atoms[v].isAromatic()) { + if (!kekule && atoms[u].isAromatic() && atoms[v].isAromatic()) { bond.setIsAromatic(true); bond.setOrder(IBond.Order.UNSET); atoms[u].setIsAromatic(true); diff --git a/storage/smiles/src/main/java/org/openscience/cdk/smiles/SmilesParser.java b/storage/smiles/src/main/java/org/openscience/cdk/smiles/SmilesParser.java index ea7e8d14729..d826fb615fb 100644 --- a/storage/smiles/src/main/java/org/openscience/cdk/smiles/SmilesParser.java +++ b/storage/smiles/src/main/java/org/openscience/cdk/smiles/SmilesParser.java @@ -244,7 +244,8 @@ private IAtomContainer parseSmiles(String smiles, boolean isRxnPart) throws Inva // convert the Beam object model to the CDK - note exception thrown // if a kekule structure could not be assigned. - IAtomContainer mol = beamToCDK.toAtomContainer(kekulise ? g.kekule() : g); + IAtomContainer mol = beamToCDK.toAtomContainer(kekulise ? g.kekule() : g, + kekulise); if (!isRxnPart) { try { diff --git a/storage/smiles/src/test/java/org/openscience/cdk/smiles/BeamToCDKTest.java b/storage/smiles/src/test/java/org/openscience/cdk/smiles/BeamToCDKTest.java index 9771b237700..6f5fd7a3c1b 100644 --- a/storage/smiles/src/test/java/org/openscience/cdk/smiles/BeamToCDKTest.java +++ b/storage/smiles/src/test/java/org/openscience/cdk/smiles/BeamToCDKTest.java @@ -156,7 +156,7 @@ public void aromatic() { public void singleBondEdge() { IAtom[] atoms = new IAtom[]{mock(IAtom.class), mock(IAtom.class), mock(IAtom.class), mock(IAtom.class), mock(IAtom.class), mock(IAtom.class)}; - IBond b = g2c.toCDKBond(Bond.SINGLE.edge(0, 5), atoms); + IBond b = g2c.toCDKBond(Bond.SINGLE.edge(0, 5), atoms, true); assertThat(b.getOrder(), is(IBond.Order.SINGLE)); assertFalse(b.getFlag(CDKConstants.ISAROMATIC)); assertThat(b.getAtom(0), is(atoms[0])); @@ -167,7 +167,7 @@ public void singleBondEdge() { public void aromaticBondEdge() { IAtom[] atoms = new IAtom[]{mock(IAtom.class), mock(IAtom.class), mock(IAtom.class), mock(IAtom.class), mock(IAtom.class), mock(IAtom.class)}; - IBond b = g2c.toCDKBond(Bond.AROMATIC.edge(0, 5), atoms); + IBond b = g2c.toCDKBond(Bond.AROMATIC.edge(0, 5), atoms, true); assertThat(b.getOrder(), is(IBond.Order.SINGLE)); assertTrue(b.getFlag(CDKConstants.ISAROMATIC)); assertThat(b.getAtom(0), is(atoms[0])); @@ -178,7 +178,7 @@ public void aromaticBondEdge() { public void doubleBondEdge() { IAtom[] atoms = new IAtom[]{mock(IAtom.class), mock(IAtom.class), mock(IAtom.class), mock(IAtom.class), mock(IAtom.class), mock(IAtom.class)}; - IBond b = g2c.toCDKBond(Bond.DOUBLE.edge(0, 5), atoms); + IBond b = g2c.toCDKBond(Bond.DOUBLE.edge(0, 5), atoms, true); assertThat(b.getOrder(), is(IBond.Order.DOUBLE)); assertFalse(b.getFlag(CDKConstants.ISAROMATIC)); assertThat(b.getAtom(0), is(atoms[0])); @@ -548,7 +548,7 @@ public void extendedTetrahedral_cw() throws Exception { IAtomContainer convert(String smi) throws IOException { BeamToCDK g2c = new BeamToCDK(SilentChemObjectBuilder.getInstance()); Graph g = Graph.fromSmiles(smi); - return g2c.toAtomContainer(g); + return g2c.toAtomContainer(g, false); } } diff --git a/storage/smiles/src/test/java/org/openscience/cdk/smiles/SmilesParserTest.java b/storage/smiles/src/test/java/org/openscience/cdk/smiles/SmilesParserTest.java index b2269b51cec..4b0d524ccf6 100644 --- a/storage/smiles/src/test/java/org/openscience/cdk/smiles/SmilesParserTest.java +++ b/storage/smiles/src/test/java/org/openscience/cdk/smiles/SmilesParserTest.java @@ -36,10 +36,12 @@ import org.openscience.cdk.CDKTestCase; import org.openscience.cdk.DefaultChemObjectBuilder; import org.openscience.cdk.aromaticity.Aromaticity; +import org.openscience.cdk.aromaticity.ElectronDonation; import org.openscience.cdk.atomtype.CDKAtomTypeMatcher; import org.openscience.cdk.exception.CDKException; import org.openscience.cdk.exception.InvalidSmilesException; import org.openscience.cdk.graph.ConnectivityChecker; +import org.openscience.cdk.graph.Cycles; import org.openscience.cdk.interfaces.IAtom; import org.openscience.cdk.interfaces.IAtomContainer; import org.openscience.cdk.interfaces.IAtomContainerSet; @@ -63,6 +65,7 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; /** * Please see the test.gui package for visual feedback on tests. @@ -2518,6 +2521,15 @@ public void atomBasedDbStereoReversing() throws Exception { is("C(\\F)=C\\F")); } + @Test + public void azuleneHasAllBondOrdersSet() throws Exception { + IAtomContainer mol = load("c1ccc-2cccccc12"); + for (IBond bond : mol.bonds()) { + if (bond.getOrder() == null || bond.getOrder() == IBond.Order.UNSET) + fail("Unset bond order"); + } + } + /** * Counts aromatic atoms in a molecule. * @param mol molecule for which to count aromatic atoms.