Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Minor quirk of beam internal, a recent update in CDK unsets the bond …
…order when reading non-kekulé SMILES, during the conversion we need to tell the converter this to avoid nulling out single bonds between aromatic atoms.
  • Loading branch information
johnmay committed Sep 6, 2016
1 parent 1906a87 commit 6a9c249
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 9 deletions.
Expand Up @@ -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()];
Expand All @@ -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++) {
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down
Expand Up @@ -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 {
Expand Down
Expand Up @@ -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]));
Expand All @@ -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]));
Expand All @@ -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]));
Expand Down Expand Up @@ -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);
}

}
Expand Up @@ -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;
Expand All @@ -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.
Expand Down Expand Up @@ -2518,6 +2521,15 @@ public void atomBasedDbStereoReversing() throws Exception {
is("F/C=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.
Expand Down

0 comments on commit 6a9c249

Please sign in to comment.