Skip to content

Commit

Permalink
Do not leave hydrogen counts unset - also load isotope information.
Browse files Browse the repository at this point in the history
Signed-off-by: Egon Willighagen <egonw@users.sourceforge.net>
  • Loading branch information
johnmay authored and egonw committed Dec 10, 2013
1 parent bf9b180 commit 5ad5e0e
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 14 deletions.
44 changes: 30 additions & 14 deletions src/main/org/openscience/cdk/inchi/InChIToStructure.java
Expand Up @@ -20,6 +20,7 @@
*/
package org.openscience.cdk.inchi;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
Expand All @@ -40,6 +41,7 @@
import org.openscience.cdk.CDKConstants;
import org.openscience.cdk.annotations.TestClass;
import org.openscience.cdk.annotations.TestMethod;
import org.openscience.cdk.config.Isotopes;
import org.openscience.cdk.exception.CDKException;
import org.openscience.cdk.interfaces.IAtom;
import org.openscience.cdk.interfaces.IAtomContainer;
Expand Down Expand Up @@ -92,6 +94,9 @@ public class InChIToStructure {

protected IAtomContainer molecule;

// magic number - indicates isotope mass is relative
private static final int ISOTOPIC_SHIFT_FLAG = 10000;

/**
* Constructor. Generates CDK AtomContainer from InChI.
* @param inchi
Expand Down Expand Up @@ -163,23 +168,34 @@ protected void generateAtomContainerFromInchi(IChemObjectBuilder builder) throws
inchiCdkAtomMap.put(iAt, cAt);

cAt.setID("a" + i);
cAt.setSymbol(iAt.getElementType());
cAt.setSymbol(iAt.getElementType());
cAt.setAtomicNumber(PeriodicTable.getAtomicNumber(cAt.getSymbol()));

// Ignore coordinates - all zero

int charge = iAt.getCharge();
if (charge != 0) {
cAt.setFormalCharge(charge);
}
// Ignore coordinates - all zero - unless aux info was given... but
// the CDK doesn't have an API to provide that

// InChI does not have unset properties so we set charge,
// hydrogen count (implicit) and isotopic mass
cAt.setFormalCharge(iAt.getCharge());
cAt.setImplicitHydrogenCount(iAt.getImplicitH());

// hydrogenCount contains number of implict hydrogens, not
// total number
// Ref: Posting to cdk-devel list by Egon Willighagen 2005-09-17
int numH = iAt.getImplicitH();
if (numH != 0) {
cAt.setImplicitHydrogenCount(numH);
}
int isotopicMass = iAt.getIsotopicMass();

if (isotopicMass != 0) {
if (ISOTOPIC_SHIFT_FLAG == (isotopicMass & ISOTOPIC_SHIFT_FLAG)) {
try {
int massNumber = Isotopes.getInstance()
.getMajorIsotope(cAt.getAtomicNumber())
.getMassNumber();
cAt.setMassNumber(massNumber + (isotopicMass - ISOTOPIC_SHIFT_FLAG));
} catch (IOException e) {
throw new CDKException("Could not load Isotopes data", e);
}
}
else {
cAt.setMassNumber(isotopicMass);
}
}

molecule.addAtom(cAt);
}
Expand Down
26 changes: 26 additions & 0 deletions src/test/org/openscience/cdk/inchi/InChIToStructureTest.java
Expand Up @@ -31,6 +31,9 @@
import org.openscience.cdk.silent.AtomContainer;
import org.openscience.cdk.silent.SilentChemObjectBuilder;

import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.junit.Assert.assertNotNull;

/**
Expand Down Expand Up @@ -158,5 +161,28 @@ public void testGetAtomContainer_IChemObjectBuilder() throws CDKException {
// OK, this is not typical use, but maybe the above generate method should be private
Assert.assertTrue(container instanceof AtomContainer);
}

@Test public void atomicOxygen() throws CDKException {
InChIToStructure parser = new InChIToStructure(
"InChI=1S/O", DefaultChemObjectBuilder.getInstance()
);
parser.generateAtomContainerFromInchi(SilentChemObjectBuilder.getInstance());
IAtomContainer container = parser.getAtomContainer();
Assert.assertThat(container, is(instanceOf(AtomContainer.class)));
Assert.assertThat(container.getAtom(0).getImplicitHydrogenCount(), is(notNullValue()));
Assert.assertThat(container.getAtom(0).getImplicitHydrogenCount(), is(0));
}

@Test public void heavyOxygenWater() throws CDKException {
InChIToStructure parser = new InChIToStructure(
"InChI=1S/H2O/h1H2/i1+2", DefaultChemObjectBuilder.getInstance()
);
parser.generateAtomContainerFromInchi(SilentChemObjectBuilder.getInstance());
IAtomContainer container = parser.getAtomContainer();
Assert.assertThat(container, is(instanceOf(AtomContainer.class)));
Assert.assertThat(container.getAtom(0).getImplicitHydrogenCount(), is(notNullValue()));
Assert.assertThat(container.getAtom(0).getImplicitHydrogenCount(), is(2));
Assert.assertThat(container.getAtom(0).getMassNumber(), is(18));
}

}

0 comments on commit 5ad5e0e

Please sign in to comment.