G'day, I'm migrating some CDK code from 1.0.1 to 1.2.1 - the code performs two main functions:
1. 2D structure diagram generation 2. structure diagram rendering I thought I'd ask the list the current best-practice for these tasks (in separate posts). So, starting with structure diagram generation the before (CDK 1.0.1) and after (CDK 1.2.1) code are given below. Typically, the layoutMolecule() method is called. This in turn calls the makeHydrogensImplicit(), [CDK]HueckelAromaticityDetector.detectAromaticity(ac) and finally layout2D(), which does the actual structure diagram generation. The CDK 1.2.1 version often produces the following CDKException: IAtom is not typed! C at org.openscience.cdk.tools.CDKHydrogenAdder.addImplicitHydrogens(CDKHydrogenAdder.java:125) at org.openscience.cdk.tools.CDKHydrogenAdder.addImplicitHydrogens(CDKHydrogenAdder.java:110) at com.syngenta.aidi.datavis.chem.StructureUtils.makeHydrogensImplicit(StructureUtils.java:114) at com.syngenta.aidi.datavis.chem.StructureUtils.layoutMolecule(StructureUtils.java:134) at com.syngenta.aidi.datavis.chem.SDFDataVisModelLoader.load(SDFDataVisModelLoader.java:127) at com.syngenta.aidi.datavis.app.SammonMapVisApplet.loadDataModel(SammonMapVisApplet.java:221) at com.syngenta.aidi.datavis.app.SolsticeVisApplet$1.run(SolsticeVisApplet.java:111) So, I currently comment out the call to makeHydrogensImplicit(). Comments? Thanks, Chris. ***** Before (CDK 1.0.1): ***** public class StructureUtils { ///////// // FIELDS ///////// private static final StructureDiagramGenerator sdg = new StructureDiagramGenerator(); private static HydrogenAdder adder; /////////////// // CONSTRUCTORS /////////////// // Static utility class - can't construct. private StructureUtils() { // do nothing. } ////////// // METHODS ////////// /** * Lays out a 2D structure diagram. * * @param ac the molecule to layout. * @return A new molecule laid out in 2D. If the molecule already has 2D * coordinates then it is returned unchanged. If layout fails then null is * returned. */ public static IAtomContainer layout2D(final IAtomContainer ac) { // Generate 2D coordinates? if (GeometryTools.has2DCoordinates(ac)) { return ac; } else { // Generate 2D structure diagram (for each connected component). final IAtomContainer ac2d = new AtomContainer(); final IMoleculeSet som = ConnectivityChecker.partitionIntoMolecules(ac); for (int n = 0; n < som.getMoleculeCount(); n++) { synchronized (sdg) { IMolecule mol = som.getMolecule(n); sdg.setMolecule(mol, true); try { // Generate 2D coords for this molecule. sdg.generateCoordinates(); mol = sdg.getMolecule(); } catch (final Exception e) { // Use projection. Projector.project2D(mol); } ac2d.add(mol); // add 2D molecule. } } return GeometryTools.has2DCoordinates(ac2d) ? ac2d : null; } } /** * Implicitly represent the hydrogens in a structure. * * @param mol The structure to convert. * @return The molecule(s) with implicit hydrogens. */ public static IAtomContainer makeHydrogensImplicit(final IAtomContainer mol) { // Explicit -> Implicit H: addExH then removeH is better than // removeH then addImpH. final IMolecule m2 = DefaultChemObjectBuilder.getInstance().newMolecule(mol); try { lazyHAdder().addHydrogensToSatisfyValency(m2); } catch (final Throwable e) { // failed. } // Explicit -> Implicit H. return new MFAnalyser(m2).removeHydrogensPreserveMultiplyBonded(); } /** * Layout molecule structure diagram. * * @param mol the molecule to layout. * @return Laid out molecule. */ public static IAtomContainer layoutMolecule(final IAtomContainer mol) { // Layout structure. final IAtomContainer ac = makeHydrogensImplicit(mol); // Aromaticity. try { HueckelAromaticityDetector.detectAromaticity(ac); } catch (final CDKException e) { // failed. } ac.setProperties(mol.getProperties()); return layout2D(ac); } // Lazy creation of a Hydrogen adder. private static synchronized HydrogenAdder lazyHAdder() { if (adder == null) { adder = new HydrogenAdder(new ValencyHybridChecker()); } return adder; } } ***** After (CDK 1.2.1): ***** public class StructureUtils { ///////// // FIELDS ///////// private static final StructureDiagramGenerator sdg = new StructureDiagramGenerator(); /////////////// // CONSTRUCTORS /////////////// // Static utility class - can't construct. private StructureUtils() { // do nothing. } ////////// // METHODS ////////// /** * Lays out a 2D structure diagram. * * @param ac the molecule to layout. * @return A new molecule laid out in 2D. If the molecule already has 2D * coordinates then it is returned unchanged. If layout fails then null is * returned. */ public static IAtomContainer layout2D(final IAtomContainer ac) { // Generate 2D coordinates? if (GeometryTools.has2DCoordinates(ac)) { return ac; // already has 2D coordinates. } else { // Generate 2D structure diagram (for each connected component). final IAtomContainer ac2d = new AtomContainer(); final IMoleculeSet som = ConnectivityChecker.partitionIntoMolecules(ac); for (int n = 0; n < som.getMoleculeCount(); n++) { synchronized (sdg) { IMolecule mol = som.getMolecule(n); sdg.setMolecule(mol, true); try { // Generate 2D coords for this molecule. sdg.generateCoordinates(); mol = sdg.getMolecule(); } catch (final Exception e) { // Use projection instead. Projector.project2D(mol); } ac2d.add(mol); // add 2D molecule. } } return GeometryTools.has2DCoordinates(ac2d) ? ac2d : null; } } /** * Implicitly represent the hydrogens in a structure. * * @param mol The structure to convert. * @return The molecule(s) with implicit hydrogens. */ public static IAtomContainer makeHydrogensImplicit(final IAtomContainer mol) { // Explicit -> Implicit H: addExH then removeH is better than // removeH then addImpH. final IMolecule m2 = DefaultChemObjectBuilder.getInstance().newMolecule(mol); try { CDKHydrogenAdder.getInstance(m2.getBuilder()).addImplicitHydrogens(m2); } catch (final Throwable e) { // failed. } // Explicit -> Implicit H. return AtomContainerManipulator.removeHydrogensPreserveMultiplyBonded(m2); } /** * Layout molecule structure diagram. * * @param mol the molecule to layout. * @return Laid out molecule. */ public static IAtomContainer layoutMolecule(final IAtomContainer mol) { // Layout structure. final IAtomContainer ac = makeHydrogensImplicit(mol); // Aromaticity. try { CDKHueckelAromaticityDetector.detectAromaticity(ac); } catch (final CDKException e) { // failed. } ac.setProperties(mol.getProperties()); return layout2D(ac); } } ------------------------------------------------------------------------------ Register Now & Save for Velocity, the Web Performance & Operations Conference from O'Reilly Media. Velocity features a full day of expert-led, hands-on workshops and two days of sessions from industry leaders in dedicated Performance & Operations tracks. Use code vel09scf and Save an extra 15% before 5/3. http://p.sf.net/sfu/velocityconf _______________________________________________ Cdk-user mailing list Cdk-user@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/cdk-user