I’ll be going to the weekly Cambridge Clojure Meetup next Tuesday, 10th November, 2009.

The time place is the usual, 8pm at the Kingston Arms.

Update: I’ve set up an upcoming entry for next week’s meeting.

The Cambridge (UK) Clojure Meetups have become an informal but regular occurence, weekly on Tuesday evenings at 8pm in the Kingston Arms. I’ll be there next Tuesday.

There’s also a camclj google group set up for discussion.

I was scheduled to talk about Maven, but popular demand led me to knock together a very quick intro to Clojure.

My clojure presentation was partly the usual soapbox about why functional languages are necessary to allow most programmers to cope with multicore machines, but mostly a quick look at some very simple code.

For the record (and since I wrote ’em, so I might as well publish ’em, here are the slides for the presentation I didn’t give, and the movie of the jetty plugin in action.

A few folks I’ve been in touch with are keen to meet up, talk about Clojure, FP, Lisp etc and maybe share code and ideas. The format will be chatting-in-a-pub but if it catches on we could do more structured things in the future. All welcome!

Time: Tuesday 1st September, 2009. 8pm
Location: The Kingston Arms. Has food, wifi and usually excellent and varied ale. 10 min walk from the train station.

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"))