MODELLER programming interface (API)

On most platforms, the core of the MODELLER program is actually a dynamic library ('.so', '.dylib' or '.dll' file). The MODELLER program itself is just a thin 'wrapper' which uses both this library and the Python library to run scripts.

You can use the MODELLER library in your own programs. To do this, you must use the API functions defined in the MODELLER header files, a collection of '.h' files which usually can be found in the $MODINSTALL10v5/src/include directory, when compiling your program, and then link against the MODELLER library. It is most straightforward to do this in C (which we will use here as an example) although any language which can interface with C libraries can be used. See the comments in the main header file 'modeller.h' for simple usage instructions.

The Python interface is also built from these header files, using the SWIG package. All of the files used to build this interface can be found in the $MODINSTALL10v5/src/swig directory. You can use these to build an interface for a different version of Python; see the 'README' file in this directory for instructions.

If you installed the MODELLER RPM package, you can run pkg-config --cflags modeller to get the necessary C compiler flags for you to be able to include the MODELLER header(s). Similarly, the --libs option outputs the linker flags needed to link with the MODELLER library. (If you did not install the RPM, you can get the same information by running mod10.5 --cflags.)

In many cases, it is more convenient to implement extensions to MODELLER in C. These can work together with the main MODELLER code and any Python scripts, and can be much faster than implementing the code in Python. See 'cuser_feat.py', 'cuser_form.py' and 'cuser_term.py' in the examples/c-extensions/ directory for examples.

Example: examples/commands/c-example.c

#include <glib.h>
#include <stdio.h>
#include <stdlib.h>

#include <modeller.h>

/* Example of using Modeller from a C program. This simply reads in a PDB
 * file, prints out some data from that file, and then writes out a new
 * file in MMCIF format.
 *
 * To compile, use (where XXX is your Modeller version):
 * gcc -Wall -o c-example c-example.c `modXXX --cflags --libs` \
 *     `pkg-config --cflags --libs glib-2.0`
 * (If you use a compiler other than gcc, or a non-Unix system, you may need
 * to run 'modXXX --cflags --libs' manually and construct suitable compiler
 * options by hand.)
 *
 * To run, you must ensure that the Modeller dynamic libraries are in your
 * search path. This can be done on most systems by adding the directory
 * reported by 'modXXX --libs' to the LD_LIBRARY_PATH environment variable.
 * (On Mac, set DYLD_LIBRARY_PATH instead. On Windows, PATH. On AIX, LIBPATH.)
 *
 * You must also ensure that Modeller knows where it was installed,
 * and what the license key is. You can either do this by setting the
 * MODINSTALLXXX and KEY_MODELLERXXX environment variables accordingly, or
 * by calling the mod_install_dir_set() and mod_license_key_set() functions
 * before you call mod_start(). For example, if Modeller is installed in
 * /lib/modeller on a 32-bit Linux system, the following would work from the
 * command line (all on one line), where KEY is your license key:
 *     KEY_MODELLERXXX=KEY MODINSTALLXXX=/lib/modeller/
 *     LD_LIBRARY_PATH=/lib/modeller/lib/i386-intel8 ./c-example
 */


/* Exit, reporting the Modeller error, iff one occurred. */
void handle_error(int ierr)
{
  if (ierr != 0) {
    GError *err = mod_error_get();
    fprintf(stderr, "Modeller error: %s\n", err->message);
    g_error_free(err);
    exit(1);
  }
}

int main(void)
{
  struct mod_libraries *libs;
  struct mod_model *mdl;
  struct mod_io_data *io;
  struct mod_file *fh;
  int ierr, *sel1, nsel1;

  /* Uncomment these lines to hard code install location and license key,
     rather than setting MODINSTALLXXX and KEY_MODELLERXXX environment
     variables (see above) */
  /* mod_install_dir_set("/lib/modeller"); */
  /* mod_license_key_set("KEY"); */

  mod_start(&ierr);
  handle_error(ierr);
  mod_header_write();

  mod_log_set(2, 1);
  libs = mod_libraries_new(NULL);
  fh = mod_file_open("${LIB}/restyp.lib", "r");
  if (fh) {
    mod_libraries_read_libs(libs, fh, &ierr);
    mod_file_close(fh, &ierr);
  } else {
    ierr = 1;
  }
  handle_error(ierr);
  mod_libraries_rand_seed_set(libs, -8123);

  mdl = mod_model_new(NULL);
  io = mod_io_data_new();
  fh = mod_file_open("../atom_files/2nbt.pdb", "r");
  if (fh) {
    mod_model_read(mdl, io, libs, fh, "PDB", "FIRST:@LAST:  ", 7, &ierr);
    mod_file_close(fh, &ierr);
  } else {
    ierr = 1;
  }
  handle_error(ierr);
  printf("Model of %s solved at resolution %f, rfactor %f\n", mdl->seq.name,
         mdl->seq.resol, mdl->seq.rfactr);
  fh = mod_file_open("new.cif", "w");
  if (fh) {
    mod_selection_all(mdl, &sel1, &nsel1);
    mod_model_write(mdl, libs, sel1, nsel1, fh, "MMCIF", 0, 1, "", &ierr);
    g_free(sel1);
    mod_file_close(fh, &ierr);
  } else {
    ierr = 1;
  }
  handle_error(ierr);
  mod_libraries_free(libs);
  mod_model_free(mdl);
  mod_io_data_free(io);

  mod_end();
  return 0;
}