Check out the new USENIX Web site. next up previous
Next: Challenges associated with Chimera Up: Chimera: Affordable Desktop Molecular Previous: User Interface

Extension Mechanism

Molecular modeling has a long tradition of ``rapid idea development''. Often, a scientist will come up with a new idea, and wants to implement the idea quickly in a scripting language such as Perl or Python to determine whether it is feasible and useful. If the idea is feasible, the implementation is typically recoded in C, FORTRAN, or C++, for performance reasons. We have built a sophisticated extension mechanism which provides support for users to add new features to Chimera without needing to recompile the entire application. The extension mechanism is convenient and can be used to rapidly develop new functionality as needed. Extensions can be written in Python or C++, can access all the molecular data structures provided by Chimera, and use Tkinter to present a GUI for the extension to users. Examples of extensions which have already been contributed to Chimera include the ``VolumeViewer'' extension [10] for viewing molecular volume data, and the ``Collaboratory'' [11] which provides synchronized modeling between geographically distant scientists. Although most extensions are written in Python for rapid application development, convenience, and easy cross-platform usage, performance-critical components can be rewritten in C++ and compiled to native object code. An extension which requires C++ is the implementation of the ``marching cubes algorithm'' [12] which converts molecular volume data into isosurfaces.

Extensions are loaded at runtime using the standard Python mechanism for loading modules: the ``import'' statement. The Python import statement locates the code which provides the named functionality, either in the form of a Python file or a shared object, and loads it. In the case of a shared object, Python loads the module using the dynamic linker.

Supporting interaction between C++ and Python requires extensive ``wrapping'' of code. Chimera internally stores all primary molecular data structures as C++ objects, with ``shadow'' Python objects that have the same attributes and methods as the C++ objects. There are a number of applications which can wrap C functions and C++ objects for use in scripting languages, but our requirement of sophisticated C++ support eliminated all the various wrapping applications available at the time (since that time, better C++ wrappers have become available, and we intend to determine whether they satisfy our requirements). Our wrapping application ``wrappy'' is part of the freely available OTF (``Object Technology Framework'') [17].

An example extension, which hides some of the atoms in a protein molecule based on their name, follows. It is clear from the code that Python deserves its description of ``executable pseudocode''; a programmer who does not know Python or anything about molecules could quickly pick up the gist of the algorithm.

# Import system modules used
# in this example.
import re

# Import Chimera modules used
# in this example.
import chimera

# Define a regular expression
# for matching the names of
# protein backbone atoms (we
# do not include the carbonyl
# oxygens because they tend to
# clutter up the graphics
# display without adding much
# information).


MAINCHAIN = re.compile(\
	'^(N|CA|C)\$', re.I)

# Do the actual work of
# setting the display status
# of atoms and bonds.  The
# following 'for' statement
# iterates over molecules.
# The function call
# 'chimera.openModels.list(\
#	modelTypes=[chimera.Molecule])'
# returns a list of all open
# molecules; non-molecular
# models such as surfaces and
# graphics objects will not
# appear in the list.  The
# loop variable 'm' refers to
# each model successively.

for m in chimera.openModels.list(\
	modelTypes=[chimera.Molecule]):

# The following 'for'
# statement iterates over
# atoms. The attribute
# reference 'm.atoms' returns
# a list of all atoms in model
# 'm', in no particular order.
# The loop variable 'a' refers
# to each atom successively.

    for a in m.atoms:

# Set the display status of
# atom 'a'.  First, we match
# the atom name, 'a.name',
# against the backbone atom
# name regular expression,
# 'MAINCHAIN'. The function
# call
# 'MAINCHAIN.match(a.name)'
# returns an 're.Match' object
# if the atom name matches the
# regular expression or 'None'
# otherwise.  The display
# status of the atom is set to
# true if there is a match
# (return value is not 'None')
# and false otherwise.

        a.display = \
		MAINCHAIN.match(\
		a.name) != None

# By default, bonds are
# displayed if and only if
# both endpoint atoms are
# displayed, so therefore we
# don't have to explicitly set
# bond display modes; they
# will automatically "work
# right".


next up previous
Next: Challenges associated with Chimera Up: Chimera: Affordable Desktop Molecular Previous: User Interface
2001-09-14