Skip to content

Commit

Permalink
Added aromaticity-based perception: N.planar3
Browse files Browse the repository at this point in the history
Added perception of PLANAR3 hyrbidization for aromatic nitrogens that are not in kekule representation (i.e. atomaticity has been read). This patch adds a unit test on pyrrole that demonstrates the functionality is working.

Signed-off-by: John May <john.wilkinsonmay@gmail.com>
  • Loading branch information
Stephan Beisken authored and egonw committed Oct 27, 2012
1 parent 0a981a4 commit 67c27bd
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 4 deletions.
35 changes: 31 additions & 4 deletions src/main/org/openscience/cdk/atomtype/CDKAtomTypeMatcher.java
Original file line number Diff line number Diff line change
Expand Up @@ -637,7 +637,10 @@ private boolean atLeastTwoNeighborsAreSp2(IAtom atom, IAtomContainer atomContain
} else if (countAttachedDoubleBonds(atomContainer, nextAtom) > 0) {
// OK, it's SP2
count++;
} // OK, not SP2
} else if (atomContainer.getBond(atom, nextAtom).getFlag(CDKConstants.ISAROMATIC)) {
// two aromatic bonds indicate sp2
count++;
} // OK, not SP2
}
}
return count >= 2;
Expand Down Expand Up @@ -845,9 +848,14 @@ private IAtomType perceiveNitrogens(IAtomContainer atomContainer, IAtom atom) th
bonds.get(1).getFlag(CDKConstants.ISAROMATIC)) {
Integer hCount = atom.getImplicitHydrogenCount();
if (hCount == CDKConstants.UNSET || hCount == 0) {
IAtomType type = getAtomType("N.sp2");
if (isAcceptable(atom, atomContainer, type))
return type;
if (atomContainer.getMaximumBondOrder(atom) == CDKConstants.BONDORDER_SINGLE &&
isSingleHeteroAtom(atom, atomContainer)) {
IAtomType type = getAtomType("N.planar3");
if (isAcceptable(atom, atomContainer, type)) return type;
} else {
IAtomType type = getAtomType("N.sp2");
if (isAcceptable(atom, atomContainer, type)) return type;
}
} else if (hCount == 1) {
IAtomType type = getAtomType("N.planar3");
if (isAcceptable(atom, atomContainer, type))
Expand Down Expand Up @@ -901,6 +909,25 @@ private IAtomType perceiveNitrogens(IAtomContainer atomContainer, IAtom atom) th
return null;
}

private boolean isSingleHeteroAtom(IAtom atom, IAtomContainer atomContainer) {

for (IAtom atom1 : atomContainer.getConnectedAtomsList(atom)) {
if (atomContainer.getBond(atom, atom1).getFlag(CDKConstants.ISAROMATIC) && !atom1.getSymbol().equals("C")) {
return false;
} else if (atomContainer.getBond(atom, atom1).getFlag(CDKConstants.ISAROMATIC)) {
for (IAtom atom2 : atomContainer.getConnectedAtomsList(atom1)) {
if (atom2 != atom && atomContainer.getBond(atom1, atom2).getFlag(CDKConstants.ISAROMATIC) &&
!atom2.getSymbol().equals("C")) {
return false;
}
}
} else {
continue;
}
}
return true;
}

private boolean isRingAtom(IAtom atom, IAtomContainer atomContainer) {
SpanningTree st = new SpanningTree(atomContainer);
return st.getCyclicFragmentsContainer().contains(atom);
Expand Down
42 changes: 42 additions & 0 deletions src/test/org/openscience/cdk/atomtype/CDKAtomTypeMatcherTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
import org.openscience.cdk.nonotify.NNAtomType;
import org.openscience.cdk.nonotify.NoNotificationChemObjectBuilder;
import org.openscience.cdk.templates.MoleculeFactory;
import org.openscience.cdk.tools.manipulator.AtomContainerManipulator;
import org.openscience.cdk.tools.manipulator.AtomTypeManipulator;
import org.openscience.cdk.tools.periodictable.PeriodicTable;

Expand Down Expand Up @@ -6374,6 +6375,47 @@ public void test_Ru_6() throws Exception {
String[] expectedTypes = {"Ru.6", "C.sp3", "C.sp3", "C.sp3", "C.sp3", "C.sp3", "C.sp3"};
assertAtomTypes(testedAtomTypes, expectedTypes, mol);
}

@Test
public void test_n_planar3_sp2_aromaticity() throws Exception {

IChemObjectBuilder builder = SilentChemObjectBuilder.getInstance();

// simulate an IAtomContainer returned from a SDFile with bond order 4 to indicate aromaticity
IAtomContainer pyrrole = builder.newInstance(IAtomContainer.class);

IAtom n1 = builder.newInstance(IAtom.class,"N");
IAtom c2 = builder.newInstance(IAtom.class,"C");
IAtom c3 = builder.newInstance(IAtom.class,"C");
IAtom c4 = builder.newInstance(IAtom.class,"C");
IAtom c5 = builder.newInstance(IAtom.class,"C");

IBond b1 = builder.newInstance(IBond.class,n1, c2, IBond.Order.SINGLE);
b1.setFlag(CDKConstants.ISAROMATIC, true);
IBond b2 = builder.newInstance(IBond.class,c2, c3, IBond.Order.SINGLE);
b2.setFlag(CDKConstants.ISAROMATIC, true);
IBond b3 = builder.newInstance(IBond.class,c3, c4, IBond.Order.SINGLE);
b3.setFlag(CDKConstants.ISAROMATIC, true);
IBond b4 = builder.newInstance(IBond.class,c4, c5, IBond.Order.SINGLE);
b4.setFlag(CDKConstants.ISAROMATIC, true);
IBond b5 = builder.newInstance(IBond.class,c5, n1, IBond.Order.SINGLE);
b5.setFlag(CDKConstants.ISAROMATIC, true);

pyrrole.addAtom(n1);
pyrrole.addAtom(c2);
pyrrole.addAtom(c3);
pyrrole.addAtom(c4);
pyrrole.addAtom(c5);
pyrrole.addBond(b1);
pyrrole.addBond(b2);
pyrrole.addBond(b3);
pyrrole.addBond(b4);
pyrrole.addBond(b5);

AtomContainerManipulator.percieveAtomTypesAndConfigureAtoms(pyrrole);

Assert.assertEquals(pyrrole.getAtom(0).getHybridization().name(), "PLANAR3");
}

/*
* This method *must* be the last method in the class.
Expand Down

0 comments on commit 67c27bd

Please sign in to comment.