Pages

Saturday, December 29, 2012

CTR #2: Depict a compound as an image

This one was relatively easy, and roughly based on the first CDK-JChemPaint tutorial. Key aspects are the SMILES parsing, 2D coordinate generation with the StructureDiagramGenerator. The solution does not render the structure's title yet. I have do not have a solution for that right now (the CDK may; I am not sure).

import java.util.List;
import java.awt.*;
import java.awt.image.*;
import javax.imageio.*;
import org.openscience.cdk.silent.*;
import org.openscience.cdk.interfaces.*;
import org.openscience.cdk.layout.*;
import org.openscience.cdk.renderer.*;
import org.openscience.cdk.renderer.font.*;
import org.openscience.cdk.renderer.generators.*;
import org.openscience.cdk.renderer.visitor.*;
import org.openscience.cdk.smiles.SmilesParser;
import org.openscience.cdk.templates.*;
import org.openscience.cdk.renderer.generators.BasicSceneGenerator.Margin;
import org.openscience.cdk.renderer.generators.BasicSceneGenerator.ZoomFactor;

smiles = "CN1C=NC2=C1C(=O)N(C(=O)N2C)C"
int WIDTH = 200
int HEIGHT = 250
Rectangle drawArea = new Rectangle(WIDTH, HEIGHT);
Image image = new BufferedImage(
  WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB
);
smilesParser = new SmilesParser(
  SilentChemObjectBuilder.getInstance()
)
molecule = smilesParser.parseSmiles(smiles)
StructureDiagramGenerator sdg =
  new StructureDiagramGenerator();
sdg.setMolecule(molecule);
sdg.generateCoordinates();
molecule = sdg.getMolecule();
List generators =
  new ArrayList();
generators.add(new BasicSceneGenerator());
generators.add(new BasicBondGenerator());
generators.add(new BasicAtomGenerator());
AtomContainerRenderer renderer =
  new AtomContainerRenderer(
    generators, new AWTFontManager()
  );
renderer.setup(molecule, drawArea);
model = renderer.getRenderer2DModel();
model.set(ZoomFactor.class, (double)0.9);
Graphics2D g2 = (Graphics2D)image.getGraphics();
g2.setColor(Color.WHITE);
g2.fillRect(0, 0, WIDTH, HEIGHT);
renderer.paint(molecule, new AWTDrawVisitor(g2));
ImageIO.write(
  (RenderedImage)image, "PNG",
  new File("CTR2.png")
);

3 comments:

  1. Nice series :) I don't think there is a 'TitleGenerator' in the CDK at the moment, but that could be a good idea.

    Centering the text beneath the bounding box of the molecule is easy enough, but I suspect that for really long names it would be necessary to wrap the text somehow.

    ReplyDelete
  2. Good day sir! I have a question. I have a SMILES string "SC(=O)C(C)C(O)C(C)" and the generated image produces the desired molecule except that -O should be -OH in the structure. I tried making the implicit hydrogens to be explicit but it showed all the hydrogens. Is there a way to create my desired output? Thank you and Happy holidays!

    ReplyDelete
  3. Dear John, please have a look at this blog post, which explains how to render the "implicit" hydrogens too:

    http://chem-bla-ics.blogspot.nl/2011/12/cdk-jchempaint-9-implicit-hydrogens-and.html

    A full overview of rendering tutorials I have written can be found here:

    https://github.com/egonw/groovy-jcp

    ReplyDelete