2D Molecule Diagrams in Clojure

April 21, 2009

I’ve been at Hinxton Hall yesterday and today, for the CDK workshop 2009. I was very impressed: a very engaged and engaging bunch of attendees, and the facilities and setting were absolutely top notch. They even booked perfect April weather where the spring morning mist dissolves to bathe the idyllic cobble-and-thatch villages in clean, mellow sunlight. All very poetic and inspiring. Reminded me why I like living round here.

I digress.

The workshop ended with an unconference element, in which my proposed theme of chatting about clojure proved popular enough to run. I gave an unstructured and as-it-occured-to-me introduction to various aspects of clojure, then pointed folks at the install docs and answered questions as I could. My personal agenda was to work out how to use CDK to read in CML molecules, generate 2D co-ordinates and then render them to a PNG file. It proved to be … involved… and I wouldn’t have prevailed without the assistance of Gilleain Torrance (so thank-you again Gilleain!). It’s a little rough on the clojure side, and understandably heavy on Java interop features. As far I understand it, it will only work on the “jchempaint-primary” branch in CDK; let’s hope that gets merged with trunk in time for the 1.2.2 release. Here’s the code: –

;; render2png

(import '(org.openscience.cdk ChemFile Molecule)
'(org.openscience.cdk.layout StructureDiagramGenerator)
'(org.openscience.cdk.io CMLReader)
'(org.openscience.cdk.renderer Renderer)
'(org.openscience.cdk.renderer.font AWTFontManager)
'(org.openscience.cdk.renderer.generators BasicBondGenerator BasicAtomGenerator)
'(org.openscience.cdk.renderer.visitor AWTDrawVisitor)
'(org.openscience.cdk.tools.manipulator ChemFileManipulator)
'(javax.imageio ImageIO)
'(java.awt.image BufferedImage)
'(java.awt Color Rectangle)
'(java.io File FileInputStream)
'(java.util ArrayList))

(defn layout [mol]
(def sdg (StructureDiagramGenerator. mol))
(.generateCoordinates sdg)
(.getMolecule sdg))

(defn render [mol file]
"Renders a PNG of a mol"
(def laid-out (layout mol))
(def bimage (BufferedImage. 300, 300, (BufferedImage/TYPE_BYTE_INDEXED)))
(def g (.createGraphics bimage))
(doto g
(.setBackground (Color/WHITE))
(.setColor (Color/WHITE))
(.fillRect 0, 0, 300, 300))
(def generators (ArrayList.))
(doto generators
(.add (BasicBondGenerator.))
(.add (BasicAtomGenerator.)))
(def r (Renderer. generators (AWTFontManager.)))
(.setScale r laid-out)
(. r paintMolecule laid-out (AWTDrawVisitor. g) (Rectangle. 300 300) true)
(. ImageIO write bimage, "png", file))

(defn readmol
"Reads a CML file and returns a molecule"
(def reader (CMLReader. (FileInputStream. filename)))
(def cf (.read reader (ChemFile.)))
(Molecule. (first (. ChemFileManipulator getAllAtomContainers cf))))

;invoke using e.g.
(render (readmol "my.cml") (File. "my.png"))

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: