wiki:ChimeraAnimationState

Version 25 (modified by Darren Weber, 15 years ago) ( diff )

--

Animation Resources

State Parameters: Categories

  • Elements
    • 2D Labels
    • Models (Molecules, Atoms)
    • Surfaces
    • Volumes
    • Selections
  • Display State
    • Hidden
    • Active for Motion
  • Spatial
    • Camera
    • Model Geometry (Center of Rotation, Xform, etc.)
    • Clipping Planes
  • Lighting
    • Background
    • Directional Lights
  • Surfacing
    • Textures
    • Materials (Color, Specular reflection, etc.)
    • Transparency
  • Rendering
    • Model and ribbon styles (ball-and-stick, wire, sphere, ribbons)
    • Surfaces: wire, solid, dots
    • Motion Blur

State Parameters: initial work based on savepos and reset

The savepos/reset functionality works with a tuple:

#
# savepos returns a tuple of various parameters (my comments added)
#
return (
    chimera.viewer.scaleFactor, #cam
    chimera.viewer.viewSize, #cam
    cam.center, #cam
    cam.nearFar, #cam
    cam.focal, #cam
    xforms, # spatial/geometry
    clips, # per-model clipping
    chimera.openModels.cofrMethod, # spatial/geometry
    cofr, # spatial/geometry
    chimera.viewer.clipping #cam
)

State Parameters: Saving Immutable State

Options for saving state:

  1. incremental diff for sequential key-frames
  2. saving immutable openModels.list()
    1. If it's possible, options include:
      1. by default, python objects are in RAM, use tuples for immutability
      2. saving to disk (pickle, sqlite, etc.)
      3. optimization issues (threading, using some kind set object)
      4. see http://docs.python.org/library/persistence.html
    2. The c++ implementation of Chimera objects doesn't fully support pickle

Model Types

Model types are Python classes. They all subclass from chimera.Model, but Python does not keep track of what classes subclass from a base class. The best you can do is to get a set of all the currently open model types. Keep in mind that a Chimera extension can introduce additional model types, so the set is always a subset.

modelTypes = [x.__class__ for x in chimera.openModels.list(all=True)]
modelTypes = list(set(modelTypes))
for i, t in enumerate(modelTypes):
    modelTypes[i] = re.findall("_chimera[.](.*)[']", str(t))[0]

Custom Models

The Chimera module called PythonModel is used to define custom model types entirely in Python, drawn using PyOpenGL.

# See this base class (also called PythonModel) that is subclassed to make a custom model.
more ${CHIMERA_SVN}/libs/PythonModel/PythonModel.py

See also the Chimera BILD commands.

'Active' models

#
# Working with a specific active model:
# openState(id: int, subid: int)
modelID = chimera.openModels.listIds()[0]
model_openState = chimera.openModels.openState(*modelID)
if model_openState.active:
    # do something useful with it
    print model_openState.xform
    print model_openState.xform.getRotation()
    print model_openState.xform.getTranslation()
#
# looping over all open-active models
#
if chimera.openModels.hasActiveModels():
    om = chimera.openModels.list(all=True)
    for m in om:
        if m.openState.active:
            # do something useful with it
            print m.openState.xform
#
# Setting 'active' models:
# chimera.openModels.setActive(id: int, active: bool)
#
chimera.openModels.setActive(modelID[0], False)
model_openState.active
# False
chimera.openModels.setActive(modelID[0], True)
model_openState.active
# True

openState attributes

Get the OpenState attributes of a model: chimera.openModels.openState(id: int, subid: int)

From the FAQ, item (10): The openState attribute of a Model controls whether that model is active for motion ('.active'), and contains the model's transformation matrix ('.xform') and center of rotation ('.cofr'). Since some models must move in synchrony (e.g. a molecule and its surface), OpenState instances may be shared among multiple models. If you create a model that needs a shared openState with another model, then when adding your model to the list of open models with chimera.openModels.add(), you should use the 'sameAs' keyword to specify the other model.

openState.xform

>>> dir(model_openState.xform)
['__class__', '__copy__', '__delattr__', '__dict__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'apply', 'coordFrame', 'getCoordFrame', 'getOpenGLMatrix', 'getRotation', 'getTranslation', 'identity', 'inverse', 'invert', 'isIdentity', 'lookAt', 'makeOrthogonal', 'multiply', 'premultiply', 'rotate', 'rotation', 'translate', 'translation', 'xRotate', 'xRotation', 'xform', 'yRotate', 'yRotation', 'zAlign', 'zRotate', 'zRotation']

>>> help(model_openState.xform)
Help on Xform object:

...

>>> models = chimera.openModels.list(all=True)
>>> for m in models:
        chimera.openModels.openState(m.id, m.subid).xform

Molecules

# Locating the Molecule object depends a bit on what your script does.
# If your script opened the PDB file itself with:

chimera.openModels.open("/home/eortega/data.pdb")

# The return value of that is a list of Molecule objects (it's a list
# because some kinds of files cause multiple Molecules to be 
# created [e.g. NMR ensembles]).

# Similarly to get a list of all currently open Molecule objects:
chimera.openModels.list(modelTypes=[chimera.Molecule])

# Lastly, if the structure is selected, get a list of selected Molecules:
chimera.selection.currentMolecules()
# To get all selected atoms use: 
chimera.selection.currentAtoms()
a = chimera.openModels.list(modelTypes=[chimera.Molecule])[0].atoms[0]

Molecule models have some global attributes, like display and color, that can alter their appearance. Note that color properties will propagate into all elements of a molecule model (residues, atoms, bonds) that do not have any specific 'component' settings. Whenever a component (residue, atom, bond) has it's own color properties, they override the global molecule color properties.

>>> m.display
True
>>> m
<_chimera.Molecule object at 0x4f464b8>
>>> m.color.ambientDiffuse
(1.0, 1.0, 1.0)
>>> m.color.isTranslucent
<built-in method isTranslucent of _chimera.MaterialColor object at 0x4f5a3a0>
>>> m.color.opacity
1.0
>>> m.color.isTranslucent()
False
>>> m.color.opacity = 0.0
>>> m.color.isTranslucent()
True
>>> m.color.opacity = 0.0  # no display
>>> m.color.opacity = 0.5  # half display
>>> m.color.opacity = 1.0  # full display

Atoms

atomSelections = chimera.selection.currentAtoms()
anAtom = chimera.openModels.list(modelTypes=[chimera.Molecule])[0].atoms[0]

for atom in model.atoms:
    if atom.color is not None:
        atom.color.rgba()
    atom.display
    atom.drawMode
    if atom.label is not None:
        atom.label
    atom.surfaceDisplay
    atom.surfaceColor
    atom.surfaceOpacity

Representations

Each atom in a molecule has a drawMode attribute, with possible values: 0 = 'dot', 1 = 'sphere', 2 = 'endcap', 3 = 'ball'. These values can be compared with the equivalent 'enum' values in chimera.Atom, i.e.:

>>> chimera.Atom.Dot
0
>>> chimera.Atom.Sphere
1
>>> chimera.Atom.EndCap
2
>>> chimera.Atom.Ball
3
molecules = chimera.openModels.list(modelTypes=[chimera.Molecule])
for m in molecules:
    for a in m.atoms:
        print a.drawMode == chimera.Atom.Sphere

Color and Material Attributes

See Main_ColorWellUI example.

molecules = chimera.openModels.list(modelTypes=[chimera.Molecule])
for m in molecules:
    for a in m.atoms:
        print a.color

# example session:
>>> import chimera
>>> mc1 = chimera.MaterialColor
>>> mc1 = chimera.MaterialColor( 1.0, 1.0, 0.0, 0.0)
>>> mc2 = chimera.MaterialColor( 1.0, 1.0, 0.0, 0.0)
>>> mc1 == mc2
True
>>> mc2 = chimera.MaterialColor( 1.0, 0.0, 0.0, 0.0)
>>> mc1 == mc2
False
>>> 
>>> a = chimera.openModels.list(modelTypes=[chimera.Molecule])[0].atoms[0]
>>> a.color
<_chimera.MaterialColor object at 0x3f36490>
>>> a.color.rgba()
(0.18823529411764706, 0.3137254901960784, 0.9725490196078431, 1.0)
>>> R,G,B,A = a.color.rgba()
>>> mc = chimera.MaterialColor( R,G,B,A )
>>> mc == a.color
True
>>> mc != a.color
False
>>> mc < a.color
False
>>> mc <= a.color
True
>>> mc > a.color
False
>>> mc >= a.color
True

Interpolating color:

>>> red = chimera.MaterialColor( 1.0, 0.0, 0.0, 0.0)
>>> green = chimera.MaterialColor( 0.0, 1.0, 0.0, 0.0)
>>> for w in [i/10.0 for i in range(11)]:
        mc = chimera.MaterialColor(red, green, w)
        print mc.rgba()

(1.0, 0.0, 0.0, 0.0)
(1.0, 0.2, 0.0, 0.0)
(1.0, 0.4, 0.0, 0.0)
(1.0, 0.6, 0.0, 0.0)
(1.0, 0.8, 0.0, 0.0)
(1.0, 1.0, 0.0, 0.0)
(0.8, 1.0, 0.0, 0.0)
(0.6, 1.0, 0.0, 0.0)
(0.4, 1.0, 0.0, 0.0)
(0.2, 1.0, 0.0, 0.0)
(0.0, 1.0, 0.0, 0.0)
>>> 

An example IDLE session. Start with a PDB molecule to play with:

chimera.runCommand('open 2por')
om = chimera.openModels.list(all=True)
por2 = om[1]

Exploring color properties:

>>> por2.color
<_chimera.MaterialColor object at 0x3d50dc8>
>>> por2.color.name()
u'_openColor00'
>>> por2.color.rgba()
(1.0, 1.0, 1.0, 1.0)
>>> por2.color.ambientDiffuse
(1.0, 1.0, 1.0)
>>> por2.color.isTranslucent()
False
>>> por2.color.opacity
1.0

Chimera material attributes are collected with color attributes.

# chimera.Material object
>>> por2.color.material
<_chimera.Material object at 0x2fd7c60>
>>> por2.color.material.name()  # material name (unicode str)
u'default'
>>> por2.color.material.shininess
30.0
>>> por2.color.material.specular
(0.85, 0.85, 0.85)
>>> por2.color.material.opacity
1.0
>>> por2.color.material.ambientDiffuse
(1.0, 1.0, 1.0)
>>> por2.color.material.isTexture()
False
>>> por2.color.material.isTranslucent()
False

Bonds

for bond in model.bonds:
    bond.display
    if bond.color is not None:
        bond.color.rgba()

Residues

General Spatial Properties

>>> cofr = chimera.openModels.cofr
>>> cofr
chimera.Point(0.00000000000000000, 0.00000000000000000, 0.00000000000000000)
>>> cofr.toVector()
chimera.Vector(0.00000000000000000, 0.00000000000000000, 0.00000000000000000)
>>> chimera.openModels.cofrMethod
4
>>> # cofrMethods
>>> chimera.openModels.Fixed
0
>>> chimera.openModels.CenterOfModels
1
>>> chimera.openModels.Independent
2
>>> chimera.openModels.CenterOfView
3
>>> chimera.openModels.FrontCenter
4

Parameter Access Methods

Something like this gains access to a lot of view parameters:

for n in dir(chimera.viewer):
    print n, eval('type(chimera.viewer.%s)' % n)

Some tips in the programming FAQ are useful (esp, items 4, 5, 7-10).

Attributes: To Copy or Not to Copy, that is the question!

From the FAQ, item (7): Some attributes return a copy of an object.

>>> xf = model.openState.xform  # xf is a copy of the model's Xform matrix.
>>> xf.zRotate(45)              # This will not rotate the model.

>>> c = model.atoms[0].color    # c is the MaterialColor object for the atom
>>> c.ambientDiffuse = (1,0,0)  # The Atom color changes immediately to red.

Some Chimera objects returned as attributes are always copies, some are always references to the uncopied object. Objects that are always copied include Xform, Vector, Point, Sphere, Element, MolResId, Coord, .... Objects that are never copied include Atom, Bond, PseudoBond, CoordSet, Molecule, Residue, RibbonStyle, .... Object that can be copied have a __copy__ method. In order to know if an object type is passed by value is to look at the Chimera C++ header files. Classes without a WrapPy base class are always copied. This base class is part of the C++ to Python interface generation.

Note: See TracWiki for help on using the wiki.