Tuesday 17 April 2012

Painting molecules your way - Introducing the paint format

If the range of depiction output formats (PNG, SVG and ASCII currently) provided by Open Babel is not enough for you, you can easily draw molecules yourself using the information provided by the new paint utility format.

The paint format simply describes lists of the actions required to generate a depiction of the molecule. For example, I used this information to prototype the ASCII output format in Python. Here it is in action:
>obabel -:c1ccccc1C(=O)Cl -opaint

NewCanvas 218.6 200.0
SetPenColor 0.0 0.0 0.0 1.0 (rgba)
SetPenColor 0.0 0.0 0.0 1.0 (rgba)
SetPenColor 0.0 0.0 0.0 1.0 (rgba)
SetPenColor 0.0 0.0 0.0 1.0 (rgba)
SetPenColor 0.0 0.0 0.0 1.0 (rgba)
SetPenColor 0.0 0.0 0.0 1.0 (rgba)
SetPenColor 0.0 0.0 0.0 1.0 (rgba)
DrawLine 109.3 100.0 to 143.9 120.0
SetPenColor 0.0 0.0 0.0 1.0 (rgba)
DrawLine 146.9 120.0 to 146.9 147.0
DrawLine 140.9 120.0 to 140.9 147.0
SetPenColor 0.0 0.0 0.0 1.0 (rgba)
DrawLine 143.9 120.0 to 167.3 106.5
SetPenColor 0.0 0.0 0.0 1.0 (rgba)
DrawLine 74.6 120.0 to 40.0 100.0
DrawLine 73.0 110.8 to 48.8 96.8
SetPenColor 0.0 0.0 0.0 1.0 (rgba)
DrawLine 40.0 100.0 to 40.0 60.0
SetPenColor 0.0 0.0 0.0 1.0 (rgba)
DrawLine 40.0 60.0 to 74.6 40.0
DrawLine 48.8 63.2 to 73.0 49.2
SetPenColor 0.0 0.0 0.0 1.0 (rgba)
DrawLine 74.6 40.0 to 109.3 60.0
SetPenColor 0.0 0.0 0.0 1.0 (rgba)
DrawLine 109.3 60.0 to 109.3 100.0
DrawLine 102.1 66.0 to 102.1 94.0
SetPenColor 0.0 0.0 0.0 1.0 (rgba)
DrawLine 109.3 100.0 to 74.6 120.0
SetPenColor 0.4 0.4 0.4 1.0 (rgba)
SetPenColor 0.4 0.4 0.4 1.0 (rgba)
SetPenColor 0.4 0.4 0.4 1.0 (rgba)
SetPenColor 0.4 0.4 0.4 1.0 (rgba)
SetPenColor 0.4 0.4 0.4 1.0 (rgba)
SetPenColor 0.4 0.4 0.4 1.0 (rgba)
SetPenColor 0.4 0.4 0.4 1.0 (rgba)
SetPenColor 1.0 0.1 0.1 1.0 (rgba)
SetFontSize 16
SetFontSize 16
SetFontSize 16
DrawText 143.9 160.0 "O"
SetPenColor 0.1 0.9 0.1 1.0 (rgba)
SetFontSize 16
SetFontSize 16
SetFontSize 16
SetFontSize 16
DrawText 178.6 100.0 "Cl"
To create an example depiction I naturally turned to bananas. Why bananas? Well, they're yellow, sweet if properly ripe, and of course are full of potassium. Using the information above and the magic of SVG, we can generate the following image (click to access zoomable SVG):

Other fruit are available, and if you would like me to put together a similar image for you, contact me and maybe we can work something out.

As an exercise for the reader, it would be cool to see the same thing done in 3D using say Blender or Povray.

Notes:
The banana SVG image is from OpenClipArt. It was modified, then I ran the Python script below, and finally trivially modified the output to give the final SVG. Here's that Python script:

Tuesday 10 April 2012

Depict a chemical structure...without graphics Part III

Following on from earlier posts (here and here), I got to thinking again about molecular depiction using text. The solution I arrived at in Part II had a couple of drawbacks:
  1. It relied on an external library, aalib
  2. aalib doesn't seem to be available on Windows (at least not in a way I can use with MSVC)
  3. aalib is really aimed at bitmap depiction as ASCII, and I'm interested in vectors (lines)
So obviously there was nothing for it but to write some code myself for depicting lines as ASCII, which is essentially what I've done with ASCIIPainter, now part of Open Babel. You could use this to draw an arbitary image, but let's check out how it works for molecules:
It didn't work quite so well for text pasted directly into this blog as the aspect ratio was quite high (i.e. low resolution in the y direction), but once I hit upon adding style="line-height:100%" to the pre tag it was much improved:
obabel -:c1cc(C(=O)Cl)ccc1 -oascii -xw60 -xa1.6

              O



             | |
             | |
             | |
             | |
             | |
             |_|                         __
            _/  \__                   __/  \__
          _/       \__             __/        \_
        _/            \_         _/     __      \__
     __/                \__   __/    __/           \__
Cl                         \_/    __/                 \__
                            |   _/                      |
                            |                           |
                            |                        |  |
                            |                        |  |
                            |                        |  |
                            |                        |  |
                            |                        |  |
                            |                        |  |
                            |                        |  |
                            |   __                      |
                            |_    \__                   _
                              \__    \__             __/
                                 \__    \_         _/
                                    \_          __/
                                      \__    __/
                                         \__/
I've added an output option to help tune the aspect ratio (-xs). Also, multimolecule output is supported, and a fun pastime is to watch ASCII depictions of large libraries fly by at the command line.

Wednesday 4 April 2012

Getting your double bonds in a twist - How to depict unspecified stereo

I've just been adding depiction support for double bonds with unspecified stereo, and thinking about how this should be done: a squiggly bond for a substituent on the double bond, or make the double bond itself twisted? Actually, I didn't have to think too much as Rich and others (also mcule) have already worked through these same issues. In short, the IUPAC recommendation (from 2006) is best avoided, and a twisted bond should be used instead.

So, here's the result after implementing the twisted bond:
obabel -:"Cl/C=C/Br" -:"Cl/C=C\Br" -:"ClC=CBr"
       -O tmp.svg -xr 1


...and with an asymmetric double bond for extra pizazz:
obabel -:"Cl/C=C/Br" -:"Cl/C=C\Br" -:"ClC=CBr"
       -O tmp.svg -xr 1 -xs


Credits: Twisted double bond by me. Everything else of depiction by Chris Morley and Tim Vandermeersch. Structure layout by Sergei Trepalin.

Monday 2 April 2012

Cheer up your LaTeX with SMILES support II

In Part I, I showed how to embed PNGs, automatically generated from SMILES by obabel, into LaTeX documents. An alternative approach is to use the SVG output from obabel.

In a comment to my earlier post, Billy suggests running the SVG through Inkscape or rsvg-convert:
You can also embed the material as a vector graphic, of course. Inkscape doesn't seem to support pipes, and rsvg-convert gives ugly output, but I'm sure there's other options.
\immediate\write18{obabel -:'#1' -osvg -p | rsvg-convert -f pdf -o smilesimg\arabic{smilescounter}.pdf}
\immediate\write18{obabel -:'#1' -O smilesimg\arabic{smilescounter}.svg -p ; inkscape -f smilesimg\arabic{smilescounter}.svg -A smilesimg\arabic{smilescounter}.pdf}
Also, if you don't want to call these applications when the graphic files aren't out of date, then use the code snippet found at the top of the 3rd page from this article.
I found a third approach on the interwebs soon after writing the initial post. It's by Jakob Lykke Andersen who converts the SVG to PDF with ImageMagick's convert. If you download the file graphviz.tex from his website, you can just include it and use it as in the following example:
The resulting PDF looks better than the original (though it could be because I didn't handle the PNGs properly in the first PDF). A nice little touch in Jakob's version is that an error box appears in the PDF if there is a problem generating the image.

Exercise for the reader:
A bit more polish is needed before these methods can be used wholesale by others. If you know a bit about LaTeX, have a go at an obabel package for CTAN.