Browse files

The rotatable bond count descriptor should not include C-N amides and…

… terminal hydrogen- and hetero-atoms for the extended Lipinki's rule of five implementation (see Veber, D.F. et al., 2002. Journal of medicinal chemistry, 45(12), pp.2615–23). The parameters for the rotatable bond counts descriptor have been modified to that end and an option has been added to exclude simple C-N amides (ignoring tautomeric or charged constitutions).

Signed-off-by: Egon Willighagen <egonw@users.sourceforge.net>
  • Loading branch information...
1 parent 07a41b2 commit e7691f8200fc4a24506e847c9968e9d8d6342575 @SBeisken SBeisken committed with egonw Feb 3, 2014
View
51 ...in/java/org/openscience/cdk/qsar/descriptors/molecular/RotatableBondsCountDescriptor.java
@@ -60,6 +60,11 @@
* <td>false</td>
* <td>True if terminal bonds are included</td>
* </tr>
+ * <tr>
+ * <td>excludeAmides</td>
+ * <td>false</td>
+ * <td>True if amide C-N bonds should be excluded</td>
+ * </tr>
* </table>
*
* Returns a single value named <i>nRotB</i>
@@ -77,6 +82,7 @@
@TestClass("org.openscience.cdk.qsar.descriptors.molecular.RotatableBondsCountDescriptorTest")
public class RotatableBondsCountDescriptor extends AbstractMolecularDescriptor implements IMolecularDescriptor {
private boolean includeTerminals = false;
+ private boolean excludeAmides = false;
/**
@@ -108,14 +114,15 @@ public DescriptorSpecification getSpecification() {
*/
@TestMethod("testSetParameters_arrayObject")
public void setParameters(Object[] params) throws CDKException {
- if (params.length != 1) {
- throw new CDKException("RotatableBondsCount expects one parameter");
+ if (params.length != 2) {
+ throw new CDKException("RotatableBondsCount expects two parameters");
}
- if (!(params[0] instanceof Boolean)) {
- throw new CDKException("The parameter must be of type Boolean");
+ if (!(params[0] instanceof Boolean) || !(params[1] instanceof Boolean)) {
+ throw new CDKException("The parameters must be of type Boolean");
}
// ok, all should be fine
includeTerminals = (Boolean) params[0];
+ excludeAmides = (Boolean) params[1];
}
@@ -127,8 +134,9 @@ public void setParameters(Object[] params) throws CDKException {
@TestMethod("testGetParameters")
public Object[] getParameters() {
// return the parameters as used for the descriptor calculation
- Object[] params = new Object[1];
+ Object[] params = new Object[2];
params[0] = includeTerminals;
+ params[1] = excludeAmides;
return params;
}
@@ -170,6 +178,11 @@ public DescriptorValue calculate(IAtomContainer ac) {
if ((BondManipulator.isLowerOrder(ac.getMaximumBondOrder(atom0), IBond.Order.TRIPLE)) &&
(BondManipulator.isLowerOrder(ac.getMaximumBondOrder(atom1), IBond.Order.TRIPLE))) {
if (!bond.getFlag(CDKConstants.ISINRING)) {
+
+ if (excludeAmides && (isAmide(atom0, atom1, ac) || isAmide(atom1, atom0, ac))) {
+ continue;
+ }
+
// if there are explicit H's we should ignore those bonds
degree0 = ac.getConnectedBondsCount(atom0) - getConnectedHCount(ac, atom0);
degree1 = ac.getConnectedBondsCount(atom1) - getConnectedHCount(ac, atom1);
@@ -189,6 +202,31 @@ public DescriptorValue calculate(IAtomContainer ac) {
}
+ /**
+ * Checks whether both atoms are involved in an amide C-N bond: *N(*)C(*)=O.
+ *
+ * Only the most common constitution is considered. Tautomeric, O\C(*)=N\*,
+ * and charged forms, [O-]\C(*)=N\*, are ignored.
+ *
+ * @param atom0 the first bonding partner
+ * @param atom1 the second bonding partner
+ * @param ac the parent container
+ *
+ * @return if both partners are involved in an amide C-N bond
+ */
+ private boolean isAmide(IAtom atom0, IAtom atom1, IAtomContainer ac) {
+
+ if (atom0.getSymbol().equals("C") && atom1.getSymbol().equals("N")) {
+ for (IAtom neighbor : ac.getConnectedAtomsList(atom0)) {
+ if (neighbor.getSymbol().equals("O") &&
+ ac.getBond(atom0, neighbor).getOrder() == CDKConstants.BONDORDER_DOUBLE) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
private int getConnectedHCount(IAtomContainer atomContainer, IAtom atom) {
List<IAtom> connectedAtoms = atomContainer.getConnectedAtomsList(atom);
int n = 0;
@@ -221,8 +259,9 @@ public IDescriptorResult getDescriptorResultType() {
*/
@TestMethod("testGetParameterNames")
public String[] getParameterNames() {
- String[] params = new String[1];
+ String[] params = new String[2];
params[0] = "includeTerminals";
+ params[1] = "excludeAmides";
return params;
}
View
6 ...ar/src/main/java/org/openscience/cdk/qsar/descriptors/molecular/RuleOfFiveDescriptor.java
@@ -178,8 +178,12 @@ public DescriptorValue calculate(IAtomContainer mol) {
mw.setParameters(mwparams);
double mwvalue = ((DoubleResult) mw.calculate(mol).getValue()).doubleValue();
+ // exclude (heavy atom) terminal bonds
+ // exclude amide C-N bonds because of their high rotational barrier
+ // see Veber, D.F. et al., 2002, 45(12), pp.2615–23.
IMolecularDescriptor rotata = new RotatableBondsCountDescriptor();
- rotata.setParameters(hBondparams);
+ Object[] rotatableBondsParams = { false, true };
+ rotata.setParameters(rotatableBondsParams);
int rotatablebonds = ((IntegerResult) rotata.calculate(mol).getValue()).intValue();
if (xlogPvalue > 5.0) {
View
44 ...ava/org/openscience/cdk/qsar/descriptors/molecular/RotatableBondsCountDescriptorTest.java
@@ -40,6 +40,8 @@
import org.openscience.cdk.tools.CDKHydrogenAdder;
import org.openscience.cdk.tools.manipulator.AtomContainerManipulator;
+import static org.hamcrest.Matchers.is;
+
/**
* TestSuite that runs all QSAR tests.
*
@@ -58,7 +60,7 @@ public void setUp() throws Exception {
@Test
public void testRotatableBondsCount() throws ClassNotFoundException, CDKException, java.lang.Exception {
- Object[] params = {new Boolean(true)};
+ Object[] params = { true, false };
descriptor.setParameters(params);
SmilesParser sp = new SmilesParser(DefaultChemObjectBuilder.getInstance());
IAtomContainer mol = sp.parseSmiles("CC2CCC(C1CCCCC1)CC2"); // molecule with 2 bridged cicloexane and 1 methyl
@@ -85,31 +87,31 @@ private IAtomContainer makeButane() {
@Test public void testEthaneIncludeTerminals() throws Exception {
IAtomContainer container = makeEthane();
IMolecularDescriptor descriptor = new RotatableBondsCountDescriptor();
- descriptor.setParameters(new Object[]{Boolean.TRUE});
+ descriptor.setParameters(new Object[]{ true, false });
DescriptorValue result = descriptor.calculate(container);
Assert.assertEquals(1, ((IntegerResult)result.getValue()).intValue());
}
@Test public void testEthane() throws Exception {
IAtomContainer container = makeEthane();
IMolecularDescriptor descriptor = new RotatableBondsCountDescriptor();
- descriptor.setParameters(new Object[]{Boolean.FALSE});
+ descriptor.setParameters(new Object[]{ false, false });
DescriptorValue result = descriptor.calculate(container);
Assert.assertEquals(0, ((IntegerResult)result.getValue()).intValue());
}
@Test public void testButaneIncludeTerminals() throws Exception {
IAtomContainer container = makeButane();
IMolecularDescriptor descriptor = new RotatableBondsCountDescriptor();
- descriptor.setParameters(new Object[]{Boolean.TRUE});
+ descriptor.setParameters(new Object[]{ true, false });
DescriptorValue result = descriptor.calculate(container);
Assert.assertEquals(3, ((IntegerResult)result.getValue()).intValue());
}
@Test public void testButane() throws Exception {
IAtomContainer container = makeButane();
IMolecularDescriptor descriptor = new RotatableBondsCountDescriptor();
- descriptor.setParameters(new Object[]{Boolean.FALSE});
+ descriptor.setParameters(new Object[]{ false, false });
DescriptorValue result = descriptor.calculate(container);
Assert.assertEquals(1, ((IntegerResult)result.getValue()).intValue());
}
@@ -124,7 +126,7 @@ private IAtomContainer makeButane() {
adder.addImplicitHydrogens(container);
AtomContainerManipulator.convertImplicitToExplicitHydrogens(container);
IMolecularDescriptor descriptor = new RotatableBondsCountDescriptor();
- descriptor.setParameters(new Object[]{Boolean.TRUE});
+ descriptor.setParameters(new Object[]{ true, false });
DescriptorValue result = descriptor.calculate(container);
Assert.assertEquals(1, ((IntegerResult)result.getValue()).intValue());
}
@@ -139,7 +141,7 @@ private IAtomContainer makeButane() {
adder.addImplicitHydrogens(container);
AtomContainerManipulator.convertImplicitToExplicitHydrogens(container);
IMolecularDescriptor descriptor = new RotatableBondsCountDescriptor();
- descriptor.setParameters(new Object[]{Boolean.FALSE});
+ descriptor.setParameters(new Object[]{ false, false });
DescriptorValue result = descriptor.calculate(container);
Assert.assertEquals(0, ((IntegerResult)result.getValue()).intValue());
}
@@ -154,7 +156,7 @@ private IAtomContainer makeButane() {
adder.addImplicitHydrogens(container);
AtomContainerManipulator.convertImplicitToExplicitHydrogens(container);
IMolecularDescriptor descriptor = new RotatableBondsCountDescriptor();
- descriptor.setParameters(new Object[]{Boolean.TRUE});
+ descriptor.setParameters(new Object[]{ true, false });
DescriptorValue result = descriptor.calculate(container);
Assert.assertEquals(3, ((IntegerResult)result.getValue()).intValue());
}
@@ -169,9 +171,33 @@ private IAtomContainer makeButane() {
adder.addImplicitHydrogens(container);
AtomContainerManipulator.convertImplicitToExplicitHydrogens(container);
IMolecularDescriptor descriptor = new RotatableBondsCountDescriptor();
- descriptor.setParameters(new Object[]{Boolean.FALSE});
+ descriptor.setParameters(new Object[]{ false, false });
DescriptorValue result = descriptor.calculate(container);
Assert.assertEquals(1, ((IntegerResult)result.getValue()).intValue());
}
+
+ @Test public void testAmideIncluded() throws Exception {
+ String amide = "CCNC(=O)CC(C)C"; // N-ethyl-3-methylbutanamide
+ SmilesParser sp = new SmilesParser(DefaultChemObjectBuilder.getInstance());
+ IAtomContainer mol = sp.parseSmiles(amide);
+ AtomContainerManipulator.percieveAtomTypesAndConfigureAtoms(mol);
+ addExplicitHydrogens(mol);
+ IMolecularDescriptor descriptor = new RotatableBondsCountDescriptor();
+ descriptor.setParameters(new Object[]{ false, false });
+ DescriptorValue result = descriptor.calculate(mol);
+ Assert.assertThat(((IntegerResult) result.getValue()).intValue(), is(4));
+ }
+
+ @Test public void testAmideExcluded() throws Exception {
+ String amide = "CCNC(=O)CC(C)C"; // N-ethyl-3-methylbutanamide
+ SmilesParser sp = new SmilesParser(DefaultChemObjectBuilder.getInstance());
+ IAtomContainer mol = sp.parseSmiles(amide);
+ AtomContainerManipulator.percieveAtomTypesAndConfigureAtoms(mol);
+ addExplicitHydrogens(mol);
+ IMolecularDescriptor descriptor = new RotatableBondsCountDescriptor();
+ descriptor.setParameters(new Object[]{ false, true });
+ DescriptorValue result = descriptor.calculate(mol);
+ Assert.assertThat(((IntegerResult)result.getValue()).intValue(), is(3));
+ }
}
View
20 ...rc/test/java/org/openscience/cdk/qsar/descriptors/molecular/RuleOfFiveDescriptorTest.java
@@ -32,6 +32,8 @@
import org.openscience.cdk.qsar.result.IntegerResult;
import org.openscience.cdk.smiles.SmilesParser;
+import static org.hamcrest.Matchers.is;
+
/**
* TestSuite that runs all QSAR tests.
*
@@ -57,5 +59,23 @@ public void testRuleOfFiveDescriptor() throws ClassNotFoundException, CDKExcepti
addExplicitHydrogens(mol);
Assert.assertEquals(2, ((IntegerResult) descriptor.calculate(mol).getValue()).intValue());
}
+
+ @Test public void testRuleOfFiveRotatableBonds() throws java.lang.Exception {
+ Object[] params = { true };
+ descriptor.setParameters(params);
+ SmilesParser sp = new SmilesParser(DefaultChemObjectBuilder.getInstance());
+ IAtomContainer mol = sp.parseSmiles("CCCC1=CC(NC(=O)CC)=CC(CCC)=C1"); // nRot = 10 (excl. amide C-N bond)
+ addExplicitHydrogens(mol);
+ Assert.assertThat(((IntegerResult) descriptor.calculate(mol).getValue()).intValue(), is(0));
+ }
+
+ @Test public void testRuleOfFiveRotatableBondsViolated() throws java.lang.Exception {
+ Object[] params = { true };
+ descriptor.setParameters(params);
+ SmilesParser sp = new SmilesParser(DefaultChemObjectBuilder.getInstance());
+ IAtomContainer mol = sp.parseSmiles("CCCCC1=CC(CCC)=CC(NC(=O)CC)=C1"); // nRot = 11 (excl. amide C-N bond)
+ addExplicitHydrogens(mol);
+ Assert.assertThat(((IntegerResult) descriptor.calculate(mol).getValue()).intValue(), is(1));
+ }
}

0 comments on commit e7691f8

Please sign in to comment.