Wednesday, 11 February 2015

cheminformatics.js: Open Babel

Following on from the preamble, let's convert Open Babel into JavaScript and then use it to depict SMILES in the browser.

And here's the result.

The following gives an overview of how I did this...

Prerequisites

I did all of this on Linux, in a Xubuntu 14.04 VM running on Windows. To begin with, I'll assume you've installed Emscripten master (and all of its associated dependencies) as well as something like CMake 3.1.2. Note that you need a recent version of CMake; for example the one provided with Ubuntu 14.04 (2.8.x) won't handle the toolchain file correctly.

Compile Open Babel with Emscripten

Check out the latest code from github. For the record, I used revision 75414ad.

We need to compile Open Babel with the plugins included statically. Also, since we only need 4 plugins (ASCII, Smiles, SVG, 2D coordinate generation), we don't want to build and include the other 100 or so. To achieve this aim, some delicate customisation of the build files with a machete is required: apply the sharp edge of said instrument to include/openbabel/plugin.h, src/plugin.cpp, src/formats/formats.cmake and src/CMakeLists.txt (*).

Building now would cause some complaints about asciipainter.cpp, so change the #include for openbabel/obutil.h to <math.h> (note to self: push this upstream).;

Create a build directory 'embuild', and from it run cmake as follows:

~/Tools/cmake-3.1.2/bin/cmake -DCMAKE_TOOLCHAIN_FILE=/home/noel/Tools/emscripten/cmake/Modules/Platform/Emscripten.cmake .. -DBUILD_SHARED=OFF -DENABLE_TESTS=OFF 
make -j2
This builds everything, right down to an obabel.js, which you can test as follows with node.js:
nodejs obabel.js -:c1ccccc1 -oascii

Add Open Babel to a webpage

We're going to create a convenience function for use from the webpage, SmilesToSVG. The appropriate code is in webdepict.cpp. To simplify building, add webdepict alongside babel and obabel in tools/CMakeLists.txt so that it is built as part of the Open Babel build.

Running 'make webdepict/fast' will generate webdepict.js, but we want to create a HTML page instead and tweak some of the settings. I've found that the easiest way to do this is to find the command that CMake is using and then edit it. We can find this with "touch webdepict.cpp && VERBOSE=1 make webdepict/fast". I edited this to give the following
$EMSCRIPTEN/em++   -static  -O3  @CMakeFiles/webdepict.dir/objects1.rsp  -o webdepict.html @CMakeFiles/webdepict.dir/linklibs.rsp -s EXPORTED_FUNCTIONS="['_SmilesToSVG']" --closure 1

This generates webdepict.html which you can open in a webbrowser. I modified the result to add some JavaScript that uses the SmilesToSVG function, et voila.

* A tar.gz file, containing the files I refer to, can be found here.

10 comments:

Dave said...

That's just craziness... how's performance?

Geoff said...

I think you should put this up on GitHub and then add to JSdelivr.com or a similar JavaScript CDN. This way, people can use OB without needing to host on their server.

Noel O'Boyle said...

@Dave: I haven't measured performance, but according to the emscripten folk, it should be between 2x and 10x slower than native code, which is good enough for most purposes.

@Geoff: Whoa, let's not get carried away :-) I haven't exposed the OB API, except for a single function, SmilesToSVG, so I don't think this particular javascript is of general use. Exposing the API is alledgedly possible (embind) though.

Dave said...

What I'd really like is to use openbabel's format readers (all of them) in 3Dmol.js.

Since you apparently get to decide which functions to expose, does enscripten do dead code elimination on everything that isn't needed for that function? That might make for a relatively compact general-purpose molecular file reader.

Noel O'Boyle said...

@Dave: That's exactly right about the dead code elimination. I'm not sure that what you suggest is going to be too compact though if you include formats with additional dependencies (e.g. InChI, CML, etc.).

OB has a JSON output format, so you might find it useful to write a convenience function FormatToJSON that takes a format identifier (e.g. "pdb"), the molecular file format text itself, and then returns it as JSON.

Geoff said...

Well, I was referring to the SMILES -> SVG feature. Daylight depict doesn't exist, and this is better since it has live updating.

(For example, hosting this service at openbabel.org/depict...)

The interesting question for me is whether it's possible to have multiple JS files, e.g., one for InChI (shudder), one for CML, etc. You wouldn't expose the full API, but you could have load-on-demand JS files for various file conversion features.

Very interesting possibilities. :-)

Noel O'Boyle said...

Ah right. I'll look into it a bit more. I started on integrating the smiley validation too, but I didn't finish.

guillaume godin said...

Dear Noel,

I try to compile our modified sources on a mac yosemite with cmake 3.3.2 using your command line but it failed any suggestion to solve this problem?


CMake Error at CMakeLists.txt:226 (export):
export FILE option given filename "" which does not have an extension of
".cmake".



CMake Error at CMakeLists.txt:228 (install):
install TARGETS given no ARCHIVE DESTINATION for static library target
"openbabel".


.....

-- Configuring incomplete, errors occurred!

Noel O'Boyle said...

Sorry - I can't help beyond suggesting you try using the version of CMake that I specified above.

Jonas Boström said...

Hey Noel! Thanks for the post. We’re playing around with OpenBabel (c#) on a web-page, but the dll’s are causing problems (I might have mentioned that before ; ). Anyways, we can solve that with php or js. So is there perhaps an openbabel.js package that we simply can be put in a folder on the web-server and call it from the website?