The cairo library is a great tool that allows generation of hi-quality graphics in both bitmap (PNG) and vector (PDF, EPS, SVG) formats. It is multi-platform and has bindings into several scripting languages, including Python. For this reason I use it for export both in OASA and BKChem.
In this post I would like to show one feature of Cairo that recently backfired on me - fallback rendering.
As was reported by several users, the BKChem EPS export via Cairo was not what it was expected to be - it was a bitmap rendering of the drawing embedded into an EPS. I tried to find out what is going on and after much googling I quite unexpectedly found a clue in the source of the EPS file - one magical word "fallback". I googled "fallback" in relation to cairo and found these release notes mentioning that the PostScript export uses fallback rendering in case translucency is used.
This led back to discovery that BKChem cairo export inserts some invisible (completely transparent) rectangles into the drawing (these are used internally in BKChem for text borders) and these are causing the fall back to bitmap rendering (even though they are invisible in the output). By removing these from the export, I was able to make the EPS export work properly. It will be part of the next BKChem release.
As always, I hope that this post would be useful to other people possibly struggling with the same problem.
The lesson is clear - Watch out for invisible rectangles :)
středa 20. května 2009
úterý 17. března 2009
Default values of keyword arguments in Python
Today I stumbled upon a piece of code on the web which showed some addition to the Django framework. The code itself is not important, but it contains one serious and hard to spot (when you are not aware of this problem) flaw.
In Python you can give function argument default values - these arguments are called keyword arguments. It works like this:
If you call the function without arguments, the default value will be used, producing the output:
Otherwise the supplied value of name will be used.
Thus far nothing special and certainly nothing dangerous...
The problem is that the value of the default argument is not created afresh each time the function is executed, but only once when the function object is created (typically when the module is loaded). While this is not problem for numbers, strings and other immutable types, it has unexpected side-effects for mutable types, such as lists or dictionaries. For these types the content of the default objects is preserved between function calls.
The following code shows how this works:
The result is:
Because of this, when the function is called without an explicit value of such keyword argument, it might not get empty dictionary as expected, but a dictionary that was already populated by the previous run of the function or even some other parts of the code if the dictionary was returned as result of the previous function call.
Even though this feature could be exploited consciously to preserve state between function calls, it is most often undesired and unexpected.
There are several ways out of this problem. I prefer to use the following solution:
I believe that this problem is not well understood by many Python developers and belongs to the category of problems that you have to be bitten by to fully appreciate (at least it was my case). If this post could save at least one person from making the above mistake in their code, I would consider it worth the time it took me to write it :)
In Python you can give function argument default values - these arguments are called keyword arguments. It works like this:
def hi(name="there"):
print "Hi %s." % name
If you call the function without arguments, the default value will be used, producing the output:
Hi there.
Otherwise the supplied value of name will be used.
Thus far nothing special and certainly nothing dangerous...
The problem is that the value of the default argument is not created afresh each time the function is executed, but only once when the function object is created (typically when the module is loaded). While this is not problem for numbers, strings and other immutable types, it has unexpected side-effects for mutable types, such as lists or dictionaries. For these types the content of the default objects is preserved between function calls.
The following code shows how this works:
def hi(param={}):
print param
param['test'] = 1
hi()
hi()
The result is:
{}
{'test': 1}
Because of this, when the function is called without an explicit value of such keyword argument, it might not get empty dictionary as expected, but a dictionary that was already populated by the previous run of the function or even some other parts of the code if the dictionary was returned as result of the previous function call.
Even though this feature could be exploited consciously to preserve state between function calls, it is most often undesired and unexpected.
There are several ways out of this problem. I prefer to use the following solution:
def hi(param=None):
if param == None:
param = {}
print param
param['test'] = 1
I believe that this problem is not well understood by many Python developers and belongs to the category of problems that you have to be bitten by to fully appreciate (at least it was my case). If this post could save at least one person from making the above mistake in their code, I would consider it worth the time it took me to write it :)
neděle 15. března 2009
Sending big files using Django
And now for something completely different...
Even though it is recommended not to serve static files using Django and one should run a separate lightweight server (such as lighthttpd) for this task, it is not uncommon that website systems written in Django sometimes need to send big files directly. In my case it was to restrict access to PDF files only to specific IP addresses which are stored in the systems database.
The main reason you should not send static files directly from Django - by reading the content of the file and sending it out - is that the whole file would be read into memory before sending it. For larger files - in my case about one to several megabytes - this is very inefficient and could easily choke the system where 90% of the traffic is generated by those bulky PDFs.
My original idea was to serve this data as other static files and use some form of name mangling in order for the user not to be able to guess the right name. However, such security through obscurity just moves the problem somewhere else - once a user obtains the right URL, he is not restricted in any way to use it.
Because of this, I decided that it would be useful to find a way to more effectively serve static files from Django, even if I should write it myself. Fortunately, I did not have to :)
After quick Google search, I found this ticket on Django website. It is an already approved patch that adds the HttpResponseSendFile function which does exactly what I need - very efficiently sends static files using the underlying systems optimized routines.
The patch attached to this ticked applied without problems to my Django 1.0.2 installation and in fifteen minutes was serving my static files to the world :)
I hope this information might get useful to other Django fans who stumble upon a similar problem.
Even though it is recommended not to serve static files using Django and one should run a separate lightweight server (such as lighthttpd) for this task, it is not uncommon that website systems written in Django sometimes need to send big files directly. In my case it was to restrict access to PDF files only to specific IP addresses which are stored in the systems database.
The main reason you should not send static files directly from Django - by reading the content of the file and sending it out - is that the whole file would be read into memory before sending it. For larger files - in my case about one to several megabytes - this is very inefficient and could easily choke the system where 90% of the traffic is generated by those bulky PDFs.
My original idea was to serve this data as other static files and use some form of name mangling in order for the user not to be able to guess the right name. However, such security through obscurity just moves the problem somewhere else - once a user obtains the right URL, he is not restricted in any way to use it.
Because of this, I decided that it would be useful to find a way to more effectively serve static files from Django, even if I should write it myself. Fortunately, I did not have to :)
After quick Google search, I found this ticket on Django website. It is an already approved patch that adds the HttpResponseSendFile function which does exactly what I need - very efficiently sends static files using the underlying systems optimized routines.
The patch attached to this ticked applied without problems to my Django 1.0.2 installation and in fifteen minutes was serving my static files to the world :)
I hope this information might get useful to other Django fans who stumble upon a similar problem.
čtvrtek 26. února 2009
BKChem enters Trophees du Libre
I am pround to announce that BKChem has entered the competition for important free software awards - Trophees du Libre.
pondělí 23. února 2009
Find 9 differences
Can you find nine differences in the following two pictures?


This is the difference between double bonds for which the second line is drawn using only 2D coordinates of the end atoms and for which the complete 3D geometry is used.
Because chemical drawings, unlike real molecules, are often flat, there was never much need for me to implement the better drawing method, especially when there are always many more important things to do. However this omission cropped up again when I rotated benzene in 3D during testing of new BKChem code that allows 3D rotation of molecular fragment around a particular bond. Because I had this feature on my to-do list for a long time anyway, I finally decided to dust off my basic knowledge of analytic geometry and implement this feature.
You can see the result on the pictures above.
Note: the pictures were created using OASA 0.12.7 and 0.13.0 respectively and a similar code is used in BKChem 0.13.0.


This is the difference between double bonds for which the second line is drawn using only 2D coordinates of the end atoms and for which the complete 3D geometry is used.
Because chemical drawings, unlike real molecules, are often flat, there was never much need for me to implement the better drawing method, especially when there are always many more important things to do. However this omission cropped up again when I rotated benzene in 3D during testing of new BKChem code that allows 3D rotation of molecular fragment around a particular bond. Because I had this feature on my to-do list for a long time anyway, I finally decided to dust off my basic knowledge of analytic geometry and implement this feature.
You can see the result on the pictures above.
Note: the pictures were created using OASA 0.12.7 and 0.13.0 respectively and a similar code is used in BKChem 0.13.0.
pondělí 16. února 2009
How to embed PDF in LaTeX documents
In the previous entry to this blog, I have shown that OASA can create pictures of molecules in PDF. However a picture of a molecule as a separate PDF file is not very useful.
Today, I will show a snippet of LaTeX code that can be used to embed the exported PDF file inside a PDF document produced by
The whole LaTeX source looks like this:
The most important commands are the following two -
After running
Today, I will show a snippet of LaTeX code that can be used to embed the exported PDF file inside a PDF document produced by
pdflatex. (Please note that this post is not intended to be an in-depth tutorial, its main purpose it to inform that the possibility to use PDFs this way even exists.)The whole LaTeX source looks like this:
\documentclass[a4paper,12pt]{article}
\usepackage{graphics}
\usepackage[left=1.5cm,right=2cm,top=2cm]{geometry}
\begin{document}
\begin{center}
\begin{large}Exam - \bf{1A}\end{large}
\end{center}
Write down SMILES for the following molecule:
\includegraphics{test}
Name the following molecule:
\includegraphics{test2}
\end{document}
The most important commands are the following two -
\usepackage{graphics} and \includegraphics{test} (please note that the name of the file to embed is used without the extension .pdf).After running
pdflatex on this code you will get a PDF file with the two images embedded inside (provided the two images exist in the same directory). The result looks like this, you can download the source files of this example here.
pondělí 9. února 2009
PDF and SVG support added to OASA
In the newest versions of OASA, I have added the possibility to create images not only in PNG, but also in SVG and PDF.
This functionality comes for free as a courtesy of the Cairo library and gives the user the possibility to create output much more suitable for printing.
Here is a small example code showing how to create a PDF export:
The output looks like this (of course, this is rendered to PNG, the PDF can be found here):
For SVG, just replace "pdf" with "svg" in the example above.
The cairo_out.mol_to_cairo function has many keyword arguments that allows for changing of almost every aspect of the output. For example, the following adds hydrogen symbols to hetero-atoms and changes the line width for bonds.
The output now looks like this (again in PNG, the SVG can be found here):

One big advantage of the SVG generated by Cairo is that all text is converted to curves. This means that the output will look the same on every machine, regardless of installed fonts.
This functionality comes for free as a courtesy of the Cairo library and gives the user the possibility to create output much more suitable for printing.
Here is a small example code showing how to create a PDF export:
from oasa import smiles, cairo_out
mol = smiles.text_to_mol( "Oc1ccc(N)cc1Cl")
mol.normalize_bond_length( 30)
mol.remove_unimportant_hydrogens()
cairo_out.mol_to_cairo( mol, "example.pdf", format="pdf")
The output looks like this (of course, this is rendered to PNG, the PDF can be found here):
(Because SMILES was used as input, OASA generates the 2D structure for you.)
For SVG, just replace "pdf" with "svg" in the example above.
The cairo_out.mol_to_cairo function has many keyword arguments that allows for changing of almost every aspect of the output. For example, the following adds hydrogen symbols to hetero-atoms and changes the line width for bonds.
cairo_out.mol_to_cairo( mol, "example.svg", format="svg",
show_hydrogens_on_hetero=True,
line_width=2)
The output now looks like this (again in PNG, the SVG can be found here):

One big advantage of the SVG generated by Cairo is that all text is converted to curves. This means that the output will look the same on every machine, regardless of installed fonts.
Přihlásit se k odběru:
Příspěvky (Atom)
