Skip to content

Commit

Permalink
Still quite slow but improved API to allow InChI options to be passed…
Browse files Browse the repository at this point in the history
… in. We can't remove the old method that forces slow execution but it has now be deprecated. New tests added to demonstrate correct exectution.
  • Loading branch information
johnmay committed Feb 14, 2017
1 parent b4b0e0a commit 55a80e7
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
import org.openscience.cdk.graph.invariant.InChINumbersTools;
import org.openscience.cdk.inchi.InChIGenerator;
import org.openscience.cdk.inchi.InChIGeneratorFactory;
import org.openscience.cdk.inchi.InChIToStructure;
import org.openscience.cdk.interfaces.IAtom;
import org.openscience.cdk.interfaces.IAtomContainer;
import org.openscience.cdk.interfaces.IAtomType;
Expand All @@ -56,12 +55,43 @@
* @cdk.module tautomer
* @cdk.githash
*/
public class InChITautomerGenerator {
public final class InChITautomerGenerator {

private final static ILoggingTool LOGGER = LoggingToolFactory.createLoggingTool(InChITautomerGenerator.class);

private static final SmilesGenerator CANSMI = new SmilesGenerator(SmiFlavor.Canonical);

/** Generate InChI with -KET (keto-enol tautomers) option. */
public static final int KETO_ENOL = 0x1;

/** Generate InChI with -15T (1,5-shift tautomers) option. */
public static final int ONE_FIVE_SHIFT = 0x2;

private final int flags;

/**
* Create a tautomer generator specifygin whether to enable, keto-enol (-KET) and 1,5-shifts (-15T).
*
* <pre>{@code
* // enabled -KET option
* InChITautomerGenerator tautgen = new InChITautomerGenerator(InChITautomerGenerator.KETO_ENOL);
* // enabled both -KET and -15T
* InChITautomerGenerator tautgen = new InChITautomerGenerator(InChITautomerGenerator.KETO_ENOL | InChITautomerGenerator.ONE_FIVE_SHIFT);
* }</pre>
*
* @param flags the options
*/
public InChITautomerGenerator(int flags) {
this.flags = flags;
}

/**
* Create a tautomer generator, keto-enol (-KET) and 1,5-shifts (-15T) are disabled.
*/
public InChITautomerGenerator() {
this(0);
}

/**
* Public method to get tautomers for an input molecule, based on the InChI which will be calculated by JNI-InChI.
* @param mol molecule for which to generate tautomers
Expand All @@ -71,7 +101,13 @@ public class InChITautomerGenerator {
*/
public List<IAtomContainer> getTautomers(IAtomContainer mol) throws CDKException, CloneNotSupportedException {

InChIGenerator gen = InChIGeneratorFactory.getInstance().getInChIGenerator(mol, "");
String opt = "";
if ((flags & KETO_ENOL) != 0)
opt += " -KET";
if ((flags & ONE_FIVE_SHIFT) != 0)
opt += " -15T";

InChIGenerator gen = InChIGeneratorFactory.getInstance().getInChIGenerator(mol, opt);
String inchi = gen.getInchi();
String aux = gen.getAuxInfo();

Expand All @@ -84,6 +120,18 @@ public List<IAtomContainer> getTautomers(IAtomContainer mol) throws CDKException
return getTautomers(mol, inchi, amap);
}

/**
* This method is slower than recalculating the InChI with {@link #getTautomers(IAtomContainer)} as the mapping
* between the two can be found more efficiently.
*
* @param mol
* @param inchi
* @return
* @throws CDKException
* @throws CloneNotSupportedException
* @deprecated use {@link #getTautomers(IAtomContainer)} directly
*/
@Deprecated
public List<IAtomContainer> getTautomers(IAtomContainer mol, String inchi) throws CDKException, CloneNotSupportedException {
return getTautomers(mol, inchi, null);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,16 @@ private List<IAtomContainer> unitTestWithInchiProvided(String smiles, String inc
return tautomers;
}

private List<IAtomContainer> unitTestWithoutInchiProvided(String smiles, int flags, int tautCountExpected)
throws Exception {
IAtomContainer container = smilesParser.parseSmiles(smiles);
AtomContainerManipulator.percieveAtomTypesAndConfigureAtoms(container);
InChITautomerGenerator tautegen = new InChITautomerGenerator(flags);
List<IAtomContainer> tautomers = tautegen.getTautomers(container);
Assert.assertEquals(tautCountExpected, tautomers.size());
return tautomers;
}

@Test
public void test1() throws Exception {
unitTestWithInchiProvided("NC1=CC(N)=NC(O)=N1", "InChI=1S/C4H6N4O/c5-2-1-3(6)8-4(9)7-2/h1H,(H5,5,6,7,8,9)", 5);
Expand Down Expand Up @@ -108,6 +118,37 @@ public void test6() throws Exception {
+ "h2-10,15H,1H3,(H2,11,20)(H,17,21,22)", 6);
}

@Test
public void test1_fast() throws Exception {
unitTestWithoutInchiProvided("NC1=CC(N)=NC(O)=N1", 0, 5);
}

@Test
public void test2_fast() throws Exception {
unitTestWithoutInchiProvided("CCCN1C2=C(NC=N2)C(=O)NC1=O", 0, 8);
}

@Test
public void test3_fast() throws Exception {
unitTestWithoutInchiProvided("CCNC(=N)NC", 0, 3);
}

@Test
public void test4_fast() throws Exception {
unitTestWithoutInchiProvided("O=C1NC=CC(=O)N1", 0, 6);
}

@Test
public void test5_fast() throws Exception {
unitTestWithoutInchiProvided("CCN1CCOC2=CC(NC3=NCCN3)=CC=C12", 0, 2);
}

@Test
public void test6_fast() throws Exception {
//Warfarin: not you need to create the InChI with option KET to get the ketone/hydroxyl tautomerism
unitTestWithoutInchiProvided("CC(=O)CC(C1=CC=CC=C1)C1=C(O)C2=C(OC1=O)C=CC=C2", InChITautomerGenerator.KETO_ENOL, 6);
}

@Test(expected = CDKException.class)
// bail out on dots in formula
public void testFail1() throws Exception {
Expand Down

0 comments on commit 55a80e7

Please sign in to comment.