Skip to content

Commit 67c27bd

Browse files
Stephan Beiskenegonw
authored andcommitted
Added aromaticity-based perception: N.planar3
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>
1 parent 0a981a4 commit 67c27bd

2 files changed

Lines changed: 73 additions & 4 deletions

File tree

src/main/org/openscience/cdk/atomtype/CDKAtomTypeMatcher.java

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -637,7 +637,10 @@ private boolean atLeastTwoNeighborsAreSp2(IAtom atom, IAtomContainer atomContain
637637
} else if (countAttachedDoubleBonds(atomContainer, nextAtom) > 0) {
638638
// OK, it's SP2
639639
count++;
640-
} // OK, not SP2
640+
} else if (atomContainer.getBond(atom, nextAtom).getFlag(CDKConstants.ISAROMATIC)) {
641+
// two aromatic bonds indicate sp2
642+
count++;
643+
} // OK, not SP2
641644
}
642645
}
643646
return count >= 2;
@@ -845,9 +848,14 @@ private IAtomType perceiveNitrogens(IAtomContainer atomContainer, IAtom atom) th
845848
bonds.get(1).getFlag(CDKConstants.ISAROMATIC)) {
846849
Integer hCount = atom.getImplicitHydrogenCount();
847850
if (hCount == CDKConstants.UNSET || hCount == 0) {
848-
IAtomType type = getAtomType("N.sp2");
849-
if (isAcceptable(atom, atomContainer, type))
850-
return type;
851+
if (atomContainer.getMaximumBondOrder(atom) == CDKConstants.BONDORDER_SINGLE &&
852+
isSingleHeteroAtom(atom, atomContainer)) {
853+
IAtomType type = getAtomType("N.planar3");
854+
if (isAcceptable(atom, atomContainer, type)) return type;
855+
} else {
856+
IAtomType type = getAtomType("N.sp2");
857+
if (isAcceptable(atom, atomContainer, type)) return type;
858+
}
851859
} else if (hCount == 1) {
852860
IAtomType type = getAtomType("N.planar3");
853861
if (isAcceptable(atom, atomContainer, type))
@@ -901,6 +909,25 @@ private IAtomType perceiveNitrogens(IAtomContainer atomContainer, IAtom atom) th
901909
return null;
902910
}
903911

912+
private boolean isSingleHeteroAtom(IAtom atom, IAtomContainer atomContainer) {
913+
914+
for (IAtom atom1 : atomContainer.getConnectedAtomsList(atom)) {
915+
if (atomContainer.getBond(atom, atom1).getFlag(CDKConstants.ISAROMATIC) && !atom1.getSymbol().equals("C")) {
916+
return false;
917+
} else if (atomContainer.getBond(atom, atom1).getFlag(CDKConstants.ISAROMATIC)) {
918+
for (IAtom atom2 : atomContainer.getConnectedAtomsList(atom1)) {
919+
if (atom2 != atom && atomContainer.getBond(atom1, atom2).getFlag(CDKConstants.ISAROMATIC) &&
920+
!atom2.getSymbol().equals("C")) {
921+
return false;
922+
}
923+
}
924+
} else {
925+
continue;
926+
}
927+
}
928+
return true;
929+
}
930+
904931
private boolean isRingAtom(IAtom atom, IAtomContainer atomContainer) {
905932
SpanningTree st = new SpanningTree(atomContainer);
906933
return st.getCyclicFragmentsContainer().contains(atom);

src/test/org/openscience/cdk/atomtype/CDKAtomTypeMatcherTest.java

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
import org.openscience.cdk.nonotify.NNAtomType;
5151
import org.openscience.cdk.nonotify.NoNotificationChemObjectBuilder;
5252
import org.openscience.cdk.templates.MoleculeFactory;
53+
import org.openscience.cdk.tools.manipulator.AtomContainerManipulator;
5354
import org.openscience.cdk.tools.manipulator.AtomTypeManipulator;
5455
import org.openscience.cdk.tools.periodictable.PeriodicTable;
5556

@@ -6374,6 +6375,47 @@ public void test_Ru_6() throws Exception {
63746375
String[] expectedTypes = {"Ru.6", "C.sp3", "C.sp3", "C.sp3", "C.sp3", "C.sp3", "C.sp3"};
63756376
assertAtomTypes(testedAtomTypes, expectedTypes, mol);
63766377
}
6378+
6379+
@Test
6380+
public void test_n_planar3_sp2_aromaticity() throws Exception {
6381+
6382+
IChemObjectBuilder builder = SilentChemObjectBuilder.getInstance();
6383+
6384+
// simulate an IAtomContainer returned from a SDFile with bond order 4 to indicate aromaticity
6385+
IAtomContainer pyrrole = builder.newInstance(IAtomContainer.class);
6386+
6387+
IAtom n1 = builder.newInstance(IAtom.class,"N");
6388+
IAtom c2 = builder.newInstance(IAtom.class,"C");
6389+
IAtom c3 = builder.newInstance(IAtom.class,"C");
6390+
IAtom c4 = builder.newInstance(IAtom.class,"C");
6391+
IAtom c5 = builder.newInstance(IAtom.class,"C");
6392+
6393+
IBond b1 = builder.newInstance(IBond.class,n1, c2, IBond.Order.SINGLE);
6394+
b1.setFlag(CDKConstants.ISAROMATIC, true);
6395+
IBond b2 = builder.newInstance(IBond.class,c2, c3, IBond.Order.SINGLE);
6396+
b2.setFlag(CDKConstants.ISAROMATIC, true);
6397+
IBond b3 = builder.newInstance(IBond.class,c3, c4, IBond.Order.SINGLE);
6398+
b3.setFlag(CDKConstants.ISAROMATIC, true);
6399+
IBond b4 = builder.newInstance(IBond.class,c4, c5, IBond.Order.SINGLE);
6400+
b4.setFlag(CDKConstants.ISAROMATIC, true);
6401+
IBond b5 = builder.newInstance(IBond.class,c5, n1, IBond.Order.SINGLE);
6402+
b5.setFlag(CDKConstants.ISAROMATIC, true);
6403+
6404+
pyrrole.addAtom(n1);
6405+
pyrrole.addAtom(c2);
6406+
pyrrole.addAtom(c3);
6407+
pyrrole.addAtom(c4);
6408+
pyrrole.addAtom(c5);
6409+
pyrrole.addBond(b1);
6410+
pyrrole.addBond(b2);
6411+
pyrrole.addBond(b3);
6412+
pyrrole.addBond(b4);
6413+
pyrrole.addBond(b5);
6414+
6415+
AtomContainerManipulator.percieveAtomTypesAndConfigureAtoms(pyrrole);
6416+
6417+
Assert.assertEquals(pyrrole.getAtom(0).getHybridization().name(), "PLANAR3");
6418+
}
63776419

63786420
/*
63796421
* This method *must* be the last method in the class.

0 commit comments

Comments
 (0)