The Chimera graphics window displays models according to their graphical attribute values (e.g., visibility, color and representation). Lenses are regions of the graphics window that display the models in a different manner by overriding graphical attributes selectively. Lenses may be used to display additional information (e.g., display protein side chains when the main display only shows the backbone), or they may remove information (e.g., remove molecular surface to reveal atoms and bonds).
Lenses are arranged in a tree. At the root of the tree is the Chimera graphics window, which is also known as the "background lens" and, of course, spans the entire window. A child lens (call it C1) of the background lens can cover any rectangular region within the window. A child lens of C1 (call it C2) can only cover a rectangular region within C1. Chimera uses its Lens Inspector to manage the tree of lenses. A selected lens within the Lens Inspector may be moved, resized or inspected. Inspection of a lens simply displays the graphical user interface associated with the lens; thus, lenses may provide some control over their behavior to the user, e.g., the choice of what values to assign to overridden attributes.
A lens must obey a certain protocol to work with the Lens Inspector. This protocol
has been encapsulated in the methods of a Chimera class, chimera.lenses.BaseLens
,
and new lenses should be written as derived classes from this base class. At
least three methods should be overridden in a new lens class: __init__
,
showInspector
and hideInspector
. __init__
is the constructor for the class and is called when a new lens is created. showInspector
and hideInspector
are called by the Lens Inspector when the lens
graphical user interface is displayed or hidden. A number of other methods may
be overridden, but these three are the minimum necessary to implement a fully
functional lens. In addition to deriving from chimera.lenses.BaseLens
,
the class must also register itself with the chimera.LensInspector
module so that it appears as one of the available classes when the user is adding
a lens.
The example below shows how to implement a lens that changes the color of the protein backbone atoms. The lens keeps track of the list of all backbone atoms by monitoring the opening and closing of models. Its user interface consists of a single color well, whose callback function sets the override color for the backbone atoms.
Import the standard Python modules used by this example.
Import the Chimera modules used by this example. The
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).
Define the
Define the constructor for
Invoke the base class constructor, specifying that
Initialize instance variables that will refer to the
inspector frame and the color well option; the variables
are initialized to
Declare the instance variable that will keep track of
all backbone atoms in the Chimera session.
Register trigger handlers for opening and closing of models;
these handlers update the list of backbone atoms.
Invoke
Define the "destructor" for
Define
Check whether the user interface has already been created.
If not, create the frame in which all other user
interface element will appear; having a single frame
containing all elements makes it easier to display or
hide the entire user interface.
Create an user interface element,
Once the inspector user interface exists, add it into the
master widget supplied by the Lens Inspector for display.
Define
Simply hide the inspector frame (created by
Define
Check whether any of the models are molecules; if so,
call
Define
Start with an empty list of atoms.
Iterate over all models, adding backbone atoms in molecules
to atom list.
Save the list as an instance variable.
Invoke
Define
Make sure that no action is taken when the color
option (user interface) does not exist.
Fetch the current color displayed in the color option.
Iterate over the list of backbone atoms and update the
atom color within the lens. Unlike molecular editing,
where one directly sets the atom attribute, the graphical
attributes of an atom inside a lens is stored in the
lens instance.
Fetch the graphical attributes dictionary,
Either define the color in the dictionary if the
current color is not
Finally, call
Register the Note that a lens does not modify the graphical attribute values of objects;
instead, for each object, the lens maintains a dictionary of the attributes
to override and the overriding values. The keys of the dictionary are strings
containing the names of attributes.
Unlike molecular editing, modifying the lens attribute dictionaries does not
automatically update the Chimera graphics window. An explicit call to The lens object may be created from a lens class that is not registered with
The example code must be saved in a disk file named Select
import Tkinter
import re
tkoptions
module defines some user interface elements; for this example,
the ColorOption
class provides a simple interface to a labeled
color well. The lenses
module contains the required lens base
class, BaseLens
. The LensInspector
module contains the lens
class registration function, registerAddFunc
.
import chimera.tkoptions
import chimera.lenses
import chimera.LensInspector
MAINCHAIN = re.compile("^(N|CA|C)$", re.I)
BackboneColorLens
class whose instances will manage
lens areas in the graphics window. The derivation of
BackboneColorLens
from base class chimera.lenses.BaseLens
is mandatory.
class BackboneColorLens(chimera.lenses.BaseLens):
BackboneColorLens
instances.
Declare that the constructor should be called with the
instance itself and the parent lens in which the new lens
will reside.
def __init__(self, parent):
BackboneColorLens
are opaque lenses, i.e., the
content of the lens will <em>replace</em> the
background lens image; the alternative to
chimera.Lens.Opaque
is chimera.Lens.Overlay
,
which indicates that the content of the lens is drawn
on top of the background lens image. The parent
argument is for maintaining the lens hierarchy
information needed by the Lens Inspector.
chimera.lenses.BaseLens.__init__(self, chimera.Lens.Opaque, parent=parent)
None
to indicate that the user
interface has not been created yet.
self.inspector = None
self.option = None
self._atoms = []
self._addHandlerId = chimera.openModels.addAddHandler(
self._checkModels, None)
self._removeHandlerId = chimera.openModels.addRemoveHandler(
self._checkModels, None)
self._update
to immediately update the backbone
atom list for the currently open models.
self._update()
BackboneColorLens
instances.
We extend the chimera.lenses.BaseLens destroy
method to
unregister our triggers and remove references to the handlers.
We don't use the __del__
method since that only gets called
when there are no more references to the instance. Since the
trigger handlers have embedded references to the instance,
__del__
will never get called until those handlers are
deregistered.
def destroy(self):
chimera.lenses.BaseLens.destroy(self)
chimera.openModels.deleteAddHandler(self._addHandlerId)
chimera.openModels.deleteRemoveHandler(self._removeHandlerId)
self._addHandlerId = None
self._removeHandlerId = None
showInspector
, which is called by the Lens Inspector
when the user inspects the lens. The instance method is invoked
with a an argument, master
, which is the Tk widget in which
the user interface should appear.
def showInspector(self, master):
if self.inspector is None:
self.inspector = Tkinter.Frame(master)
ColorOption
,
defined by Chimera. A ColorOption
is simply a color
well with a text label on its left. The constructor
to a ColorOption
instance takes five arguments:
the frame in which it appears, the row in the frame
that the option occupies, the text for the label,
the default color to display, and the function to call
when the user changes the color in the well.
The constructor also accepts an optional keyword
argument (balloon=
) to specify a balloon-help message.
self.option = chimera.tkoptions.ColorOption(
self.inspector, # parent frame
0, # row number
'Backbone Color', # label
None, # default value
self._setColor, # callback
balloon='Protein backbone color')
self.inspector.pack(expand=1, fill=Tkinter.BOTH)
hideInspector
, which is called by the Lens Inspector
when ther user stops inspecting the lens.
def hideInspector(self):
showInspector
)
by removing it from its master widget.
self.inspector.forget()
_checkModels
, which is the trigger handler registered
by the constructor and is invoked whenever models are opened
or closed. Trigger handlers are called with the trigger name,
an argument supplied at registration time, and the list of
objects that caused the handler invocation. For _checkModels
,
the list consists of models that were opened or closed.
def _checkModels(self, trigger, arg, models):
_update
to recompute the backbone atom list.
for m in models:
if isinstance(m, chimera.Molecule):
self._update()
return
_update
, which extracts the list of backbone atoms
in the currently open models. _update
is called by the
constructor when the lens is first created, and by the
trigger handler when models are opened or closed.
def _update(self):
atoms = []
for m in chimera.openModels.list(modelTypes=[chimera.Molecule]):
for a in m.atoms:
if MAINCHAIN.match(a.name):
atoms.append(a)
self._atoms = atoms
_setColor
to update the lens information using
the new list of atoms.
self._setColor(self.option)
_setColor
, which contains the heart of lens
functionality. _setColor is registered as the callback
function for ColorOption
, which means it will receive
the option as its argument. _setColor is also called by
_update
when the list of backbone atoms is changed;
however, the inspector user interface may not exist when
the _update
is called and _setColor will then receive
an option of None
.
def _setColor(self, option):
if not self.option:
return
color = option.get()
for a in self._atoms:
ga
, for atom a
.
ga = self.gfxAttr(a)
None
, or delete the color
value from the dictionary. The dictionary key that
is used for a graphics attribute is the string
containing the name of the attribute; in this case,
the key is color
.
if color is None:
try:
del ga['color']
except KeyError:
pass
else:
ga['color'] = color
invalidateCache
to force Chimera to
recompute the lens graphical display.
self.invalidateCache()
BackboneColorLens
class with the
chimera.LensInspector
module for inclusion in the list
of available lens classes when the user is adding a lens.
chimera.LensInspector.registerAddFunc('Backbone Color', BackboneColorLens)
Code Notes
invalidateCache
is required to force the update.
chimera.LensInspector
. The lens will still be managed by the Chimera
Lens Inspector. The registration only makes it possible for the user to create
a lens from the class using the standard Lens Inspector interface.
Running the Example
BackboneColorLens.py
(note that the .py extension is required) and Chimera may be invoked
with the file name on the command line, e.g.,
chimera BackboneColorLens.py
Lens Inspector...
from the Tools
menu to bring
up the lens inspector. Select the background lens, either by clicking the window
on the left side or the word background
on the right side of the
inspector. Click the Add...
button to bring up a panel of available
lens types. Select the Backbone Color
type and click Add
.
A new lens should appear and be selected in the lens inspector. Select the Inspector
tab in the lens inspector to bring up the backbone color lens inspector. Open
a protein model and its backbone color within the lens should match that of
the color well in the lens inspector.