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; andthe
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.