hallo

Compiling VMD as a Python Module

| Comments

Visual Molecular Dynamics (VMD) has a very powerful built-in language for manipulating molecular structures in a variety of file formats with a powerful atom selection.

It can actually be built as a shared library that can be loaded into Python and used in your code, for all sorts of analysis scripts. However compiling it as such can be a bit tricky. This blog post will help you out.

If you are looking to compile regular VMD or want a better overview of the whole process, please reference this earlier post.

Getting the source

Go to the VMD Website and download the source code. You will need to make a free account. Extract the source in a directory of your choosing. I would recommend not putting it in /tmp because you might want it later if you are developing plugins.

I will refer to the director you put the code in as $vmd_src

Compiling

0. A note on Python interpreters

For some reason the resulting shared library knows which version of Python it was compiled against, and will refuse to be loaded from anything else. For example, I compiled against miniconda’s installed Numpy. If I tried to load the resulting library with the python in /usr/bin, it would raise an exception. I don’t know why this happens and I am working on a fix, but for now just try to keep a consistent Python interpreter.

1. Setting the compilation option flags

I set the following compile options:

  • LINUXAMD64 - for a Linux x86_64 build
  • PTHREADS - for parallelization
  • NETCDF - support for binary format trajectories
  • COLVARS - collective variables module for NAMD/LAMMPS support
  • TCL - support for plugins in TCL
  • PYTHON - the whole reason we are compiling from source, enable python support
  • NUMPY - also numpy support
  • SHARED - build as a shared library, not a standalone executable
  • NOSILENT - print the entire make command during compilation

So the entire contents of my $vmd_src/configure.options file is:

LINUXAMD64 PTHREADS COLVARS NETCDF TCL PYTHON NUMPY SHARED NOSILENT

2. Specifying Environment Variables

Some plugins will only be compiled if certain environment variables are set, even if the compiler arguments they reference are redundant.

It is simplest to set all the environment variables in a single script, which is sourced before running the configure script or compiling plugins. Edit the following script as appropriate for your system and the plugins you wish to compile:

WARNING: The options for dmsplugin and hoomdplugin are currently commented out because you will get linker errors. I have submitted a bug fix to the VMD team fixing this. If you need these plugins, please refer to my patch for necessary changes to the Makefiles.

$vmd_src/vmd_env_variables.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#!/bin/bash

# Define directories and names of final binaries
export VMDINSTALLNAME="vmd-1.9.2-shared"
export VMDDIR="/opt/$VMDINSTALLNAME"
export VMDINSTALLBINDIR="$VMDDIR"
export VMDINSTALLLIBRARYDIR="$VMDDIR"
export PLUGINDIR="$VMDDIR/plugins"

# For reading and writing NetCDF format files
export NETCDFLIB="-L/usr/lib64"
export NETCDFINC="-L/usr/include"
export NETCDFLDFLAGS="-lnetcdf"

# For vtfplugin, webpdbplugin
export TCLLIB="-L/usr/lib64"
export TCLINC="-I/usr/include"
export TCLLDFLAGS="-ltcl"

# For dmsplugin (.dms files)
#export SQLITEINC="-I/usr/include"
#export SQLITELIB="-L/usr/lib64"
#export SQLITELDFLAGS="-lsqlite3"

# For hoomd plugin
#export EXPATLIB="-L/usr/lib64"
#export EXPATINC="-I/usr/linclude"
#export EXPATLDFLAGS="-lexpat"

# For python support
export PYTHON_INCLUDE_DIR="/usr/include/python2.7"
export PYTHON_LIBRARY_DIR="/usr/lib64/python2.7"
export NUMPY_INCLUDE_DIR="/usr/lib64/python2.7/site-packages/numpy/core/include"
export NUMPY_LIBRARY_DIR="/usr/lib64/python2.7/site-packages/numpy/core/lib"

# For tcl support, yes, in addition to above variables
export TCL_INCLUDE_DIR="/usr/include"
export TCL_LIBRARY_DIR="/usr/lib64"

Then, source it:

  source $vmd_src/vmd_env_variables.sh

You will need to change the linker command in the configure script to link the appropriate version of Python, in my case 2.7.

$vmd_src/vmd/configure
1
2
3
4
diff -r1.1311 configure
1243c1243
- $python_libs =     "-lpython2.5 -lpthread";
+ $python_libs =     "-lpython2.7 -lpthread";

3. Compile plugins

Make the directory the plugins will go in. Then, compile for the correct architecture, and put the plugins in the right place.

mkdir -p $PLUGINDIR
cd $vmd_src/plugins
gmake LINUXAMD64
gmake distrib

Hopefully, your plugins now appear in $PLUGINDIR.

4. Apply patch

If you continued to compilation, you would get a vmd.so that causes a segfault in libtcl8.5.so when imported in python. There are some pointer shenanigans in initializing the TCL interpreter (which is a core part of the VMD module) that result in an unallocated value being passed to the TCL library.

I have reported this bug to the VMD developers, but in the meantime please apply the following patch to $vmd_src/vmd/py_vmd.C.

$vmd_src/vmd/py_vmd.C
1
2
3
95c95
-  char *argv[1];
+  char **argv = (char**)malloc(sizeof(char*));

5. Compile VMD

Now that the plugins are compiled and in the right place, create a symlink to them from the vmd source directory. Then, we can run the configure script from the VMD source directory, and compile.

ln -s $PLUGINDIR $vmd_src/plugins
$vmd_src/vmd/configure
cd $vmd_src/vmd/src
make veryclean
make vmd.so
make install

Usually the last message is “No resource compiler required on this platform”, which is not an error message. If you’re not sure if make ran successfully (it can be difficult with all that output), try echo $? right after the command finishes. If 0, it was successful. Otherwise, there was an error.

6. Test installation

In theory you should now have a working VMD installation with Python support enabled. You can test this as follows:

PYTHONPATH=$VMDDIR python -c "import vmd, molecule, atomsel"

You should see several info lines, but hopefully no errors. If there are errors, please check that you applied all the patches, and post your issue in the comments.

7. Use installation

Make sure that $VMDDIR is in your $PYTHONPATH when trying to run programs that use this module. I prepended it in my ~/.bashrc.

You can write a lot of useful programs that deal with molecules of all formats in Python now, using the VMD module as a backend. There is (somewhat outdated) documentation here, but the most comprehensive reference is running help() within the python interpreter.

Comments