ChimeraX Developer Tutorial

UCSF ChimeraX is designed to be extensible, much like Cytoscape and Mozilla Firefox. In ChimeraX, the units of extension are called bundles, which may be installed at run-time to add commands, graphical interfaces (tools), chemical subgroup selectors, presets, support for fetching from network databases, and reading and writing data files in new formats.

Most bundles can be built using ChimeraX itself. Once built, a bundle is stored as a single file and may be exchanged among developers and users, or made available to the ChimeraX community via the ChimeraX Toolshed, a web-based bundle repository based on the Cytoscape App Store.

Prerequisites

Other than developing graphical interfaces, writing ChimeraX bundles only requires a working knowledge of Python and XML. Graphical interfaces may be written using web development techniques, i.e., using HTML and Javascript. If more graphical capabilities are needed, developers can use PyQt. The standard ChimeraX distribution has all the tools needed to build bundles that only use these languages and toolkits.

For greater performance, it is possible to include C and C++ extensions because ChimeraX is based on CPython. However, developers are responsible for supplying a compatible compilation environment, e.g., installing Visual Studio 2019 on Microsoft Windows.

Pro Tip

One the handiest things to know is that if you want your code to do something that a command already does, instead of figuring out the equivalent Python call you can just run the command. For instance, the code to run the command color red is:

from chimerax.core.commands import run
run(session, "color red")

The run() call will return the result of the command, e.g. a list of opened models for the open command (in most cases a list of one) or a distance value for the distance command. If the “command” is actually a semi-colon-separated list of commands, the the returned value will be a list of the individual return values.

If all you need to do is run a fixed set of commands over a set of data files, you should be aware that the forEachFile option to the open command does exactly that.

What is a ChimeraX Bundle?

ChimeraX is implemented in Python 3, with chunks of C++ thrown in for performance. A bundle is simply a Python package that conform to ChimeraX coding and data conventions. To shorten start-up time, ChimeraX does not import each bundle on initialization. Instead, when a bundle is installed, ChimeraX reads the bundle (package) data to incorporate the new functionality into the application user interface (e.g., registering commands and adding menu items). When the new functionality is used, ChimeraX then imports the bundle and invokes the corresponding code to handle the requests.

The source code for a bundle typically consists of Python modules, but may also include C++ for performance reasons. Additional files, such as license text, icons, images, etc., may also be included. The source code must be turned into a bundle before it is ready for installation into ChimeraX. The Source Code Organization section goes into detail on the recommended file structure for ChimeraX bundle source code.

ChimeraX expects bundles to be in Python wheel format. Python has standard methods for building wheels from source code. However, it typically requires writing a setup.py file that lists the source files, data files and metadata that should be included in the package. To simplify building bundles, ChimeraX provides the devel command that reads an XML file containing the bundle information, generates the corresponding setup.py file, and runs the script to build and/or install the bundle. While the XML file contains the same information as a setup.py file, it is simpler to use because it does not contain extraneous Python code and data that is required (for setup.py to run successfully) yet is identical across all bundles.

Once a bundle is built, it can be added to ChimeraX. Normally, wheels are installed using the pip module in a Python-based application. However, because some post-processing must be done after a wheel is installed (i.e., read package data and integrate functionality into user interface), ChimeraX provides the toolshed install command for use in place of pip. (If a bundle must be installed using pip, one should run the toolshed reload command to properly integrate the bundle into ChimeraX.)

Source Code Organization

The ChimeraX devel command expects bundle source code to be arranged in a folder (a.k.a., directory) in a specific manner: there must be a bundle_info.xml file and a src subfolder.

Bundle Information

The bundle_info.xml file contains information read by the devel command. It describes both what functionality is provided in the bundle, and what source code files need to be included to build the bundle.

The format of bundle_info.xml is, as its name suggests, eXtensible Markup Language (XML). Bundle information is grouped into nested tags, which can have zero or more attributes as well as associated text.

The document tag (the one containing all other tags) is BundleInformation whose attributes include the bundle name, version, and Python package name. (Other attributes are also supported but are not required.) Classifier tags provide information about supported functionality. All Python source files in the src sub-folder are automatically included, but additional files, e.g., icons and data files, must be explicitly listed (e.g., in DataFiles tags) for inclusion in the bundle.

Examples of bundle_info.xml files are provided in tutorials for building example bundles (see Writing Bundles in a Few Easy Steps). The complete set of supported tags are described in Bundle Information XML Tags.

Python Package

The src folder is organized as a Python package, and implements the bundle functionality. The __init__.py file is required. All other files, source code or data, are optional.

ChimeraX assumes that the Python package contains an object named bundle_api that is an instance of a subclass of chimerax.core.toolshed.BundleAPI, which defines the attributes and methods required by ChimeraX. For example,

  • the api_version attribute controls the calling conventions for defined methods;

  • the register_command method is called to register bundle commands; and

  • the start_tool method is called to start a graphical interface tool.

A bundle does not need to provide all bundle API methods, as the implementation from inherited methods “do the right thing”.

The bundle_api object, typically defined in __init__.py, is the only interface that ChimeraX uses to invoke bundle functionality. The bundle can, of course, invoke ChimeraX functionality through the published APIs for Python Modules.

Because ChimeraX is implemented (mostly) in Python, all code is available for inspection and introspection, so developers can essentially use all defined attributes and methods. However, using only the published APIs has one great advantage. Published ChimeraX APIs conform to semantic versioning rules, i.e., within the same major version of ChimeraX, the APIs from newer minor versions will always be compatible with older minor versions. That means bundles written for one version of ChimeraX will always work with new (minor) versions as well. (Semantic versioning only applies for pure Python ChimeraX bundles. Bundles containing code that compile against ChimeraX C++ APIs are only guaranteed to work with the exact version used in development.)

Writing Bundles in a Few Easy Steps

The easiest way to start developing ChimeraX bundles is to follow these tutorials for building example bundles:

Each tutorial builds on the previous but may also be used as reference for adding a specific type of functionality to ChimeraX.

Building and Testing Bundles

To build a bundle, start ChimeraX and execute the command:

devel build PATH_TO_SOURCE_CODE_FOLDER

Python source code and other resource files are copied into a build sub-folder below the source code folder. C/C++ source files, if any, are compiled and also copied into the build folder. The files in build are then assembled into a Python wheel in the dist sub-folder. The file with the .whl extension in the dist folder is the ChimeraX bundle.

To test the bundle, execute the ChimeraX command:

devel install PATH_TO_SOURCE_CODE_FOLDER

This will build the bundle, if necessary, and install the bundle in ChimeraX. Bundle functionality should be available immediately.

To remove temporary files created while building the bundle, execute the ChimeraX command:

devel clean PATH_TO_SOURCE_CODE_FOLDER

Some files, such as the bundle itself, may still remain and need to be removed manually.

Building bundles as part of a batch process is straightforward, as these ChimeraX commands may be invoked directly by using commands such as:

ChimeraX --nogui --exit --cmd 'devel install PATH_TO_SOURCE_CODE_FOLDER exit true'

This example executes the devel install command without displaying a graphics window (--nogui) and exits immediately after installation (exit true). The initial --exit flag guarantees that ChimeraX will exit even if installation fails for some reason.

Distributing Bundles

With ChimeraX bundles being packaged as standard Python wheel-format files, they can be distributed as plain files and installed using the ChimeraX toolshed install command. Thus, electronic mail, web sites and file sharing services can all be used to distribute ChimeraX bundles.

Private distributions are most useful during bundle development, when circulation may be limited to testers. When bundles are ready for public release, they can be published on the ChimeraX Toolshed, which is designed to help developers by eliminating the need for custom distribution channels, and to aid users by providing a central repository where bundles with a variety of different functionality may be found.

Customizable information for each bundle on the toolshed includes its description, screen captures, authors, citation instructions and license terms. Automatically maintained information includes release history and download statistics.

To submit a bundle for publication on the toolshed, you must first sign in. Currently, only Google sign in is supported. Once signed in, use the Submit a Bundle link at the top of the page to initiate submission, and follow the instructions. The first time a bundle is submitted to the toolshed, it is held for inspection by the ChimeraX team, which may contact the authors for more information. Once approved, all subsequent submissions of new versions of the bundle are posted immediately on the site.