[Chimera-users] matrixget/set, keyframes, and interpolation

Thomas Goddard goddard at cgl.ucsf.edu
Fri Jun 16 10:22:54 PDT 2006


Hi Jonathan,

  I just made an animation in Chimera that does more complicated motions
than rock and roll.  It is the myosin thick filament analysis animation on
the Chimera animations page:

	http://www.cgl.ucsf.edu/chimera/animations/animations.html

  I created this with a Python script because it does many transitions
for which there is no Chimera command.  I include my Python script
below (700 lines).  It is messy but maybe you can mine it.  The part
most relevant to your question is the move_model() function:

   move_model(model_name, from_matrix, to_matrix, relative_to, fraction)

It moves a model a certain fraction (0-1) of the way from one position to
another position, with the positions given relative to a second model using
3 by 4 matrices.  It uses positions relative to another model instead of
absolute positions because I was using this to fit a crystal structure into
a density map.  If I later changed my viewpoint in Chimera I wanted it
to still work.  To get these matrices I used the write_relative_transforms()
function called via a keyboard shortcut "wt".  That wrote the matrices to
the Chimera reply log which I then copied into my script.

  I think using the "matrixset <filename>" command for doing a smooth
transition is unwieldy.  Every matrix would have to be in a separate file.
Two alternatives are to use a Python script to produce an animation as I
did, or to add a command to Chimera that does the smooth interpolation --
a Chimera command version of the above move_model() function.  Using Python
requires more expertise.  I think introducing the new Chimera command is
the way to go.  There should also be a command to print the current matrices
like my "wt" shortcut.  These two commands would be more usable versions
of matrixget/matrixset for the purpose of making smooth transitions.
If you would like I can write some Python code for these two commands
that you can drop into your existing Chimera.

	Tom

----
Script that plays through myosin thick filament animation.
This will not run for you since you do not have the data files.



# -----------------------------------------------------------------------------
# Script that runs through animation of myosin thick filament density map.
#

# -----------------------------------------------------------------------------
#
def play():
   
  from os.path import join, dirname, realpath
  import myosinmovie
  dir = join(dirname(realpath(myosinmovie.__path__[0])), 'data')

  map_name = 'myosin2.mrc'
  map_color = (.7, .7, .7, 1)           # gray
  map_color_t = map_color[:3] + (.7,)   # transparent
  head_color = (1,.7,0,1)               # orange
  subfil_color = (.980, .502, .447, 1)  # salmon
  map2 = map_name + ' <1>'
  pdb1i84 = '1i84-notail.pdb'
  tail = 'tail.cmm'
  tailname = 'myosin tail'
  subfil = map(lambda s: 'subfilament%d.mrc' % s, range(13))
  sfpaths = map(lambda sf: join(dir,sf), subfil)
  sfeven = subfil[::2]
  sfodd = subfil[1::2]
  sfocolor = (.7,.7,.3,1)               # yellow
  sf = 'subfilament9.mrc'
  fc = 'subfilament0.mrc'
  fc_color = (.8,.6,.4,1)
  sfo = filter(lambda s: s != fc, subfil)
  sf11= sfo[sfo.index(sf)+1:] + sfo[:sfo.index(sf)]
  sf11r = list(sf11)
  sf11r.reverse()

  show_caption = '2dlabel change caption text "%s" color black xpos %f ypos .95 visibility show'
  show_caption2 = '2dlabel change caption text "%s" color black xpos %f ypos .97 size %d visibility show'
  caption_fade = '2dlabel change caption visibility hide frames 5'
  caption_fade_delay = 15
  
  # Position of 1i84 close to eye.
  mt1 = ((-0.099649198789025978, 0.74111595074467951, 0.66394064850144952, -1008.6712224936828), (0.5863861489863087, -0.49534104948956315, 0.64092786565072368, -966.59941472485207), (0.80387892213797729, 0.45319354832389019, -0.38521978960054565, -124.9728590025926))

  # Position of 1i84 to right of filament
  mt2 = ((0.073345968301112466, 0.62005697667643067, 0.78112080666748807, -140.8575902922845), (0.55558955434916146, -0.6758394649115651, 0.48431525349317678, -344.80539061238528), (0.82821531984869479, 0.39845998963878676, -0.3940672793127869, -124.7725634028488))

  # Position of 1i84 hand fit
  mt3 = ((-0.011137186324278462, 0.57090152267568484, 0.8209430031904611, -117.86331645089319), (0.64007270897455237, -0.62668401091081916, 0.4444930569702038, -121.04296346830751), (0.76823361701162263, 0.53041361396114306, -0.35843898758075837, -132.97686247292341))

  # Position of 1i84 computationally optimized
  mt4 = ((0.067350631154440885, 0.35912771983826075, 0.93085507643610677, -94.436118828488432), (0.78371645512883981, -0.59642399619826492, 0.1733981969894075, -121.53565912095156), (0.61745640367833565, 0.71784796273491214, -0.32162383610975182, -142.36032454320915))

  # Position of 1i84 backwards fit by hand
  mt5 = ((0.040717288582604753, -0.68893892247763189, -0.72367483271552346, -41.989737858895808), (0.015968304931079015, 0.72463165183091871, -0.68895136432292714, -177.57106879703232), (0.9990430999952451, 0.016496371120766563, 0.040506222876700852, -112.28404385096682))

  # Position of 1i84 backwards fit optimized
  mt6 = ((0.075798794154165489, -0.41125005975496942, -0.90836552728310249, -50.078309013435728), (0.26520245923950292, 0.88648910828917349, -0.37921592331808268, -190.88698833314771), (0.96120871740641978, -0.21215666201229763, 0.17625933264853111, -90.233284436572831))

  # Position of 1i84 forward and right of filament for float in.
  mt7 = ((0.067350631154428922, 0.3591277198382945, 0.93085507643609822, -58.351913517245023), (0.78371645512883925, -0.59642399619825837, 0.17339819698943759, -483.01076846693888), (0.61745640367833865, 0.71784796273490414, -0.3216238361097708, -244.42186962044607))

  # Position of subfilament tilted out.
  sfmt1 = ((0.97415635283527546, -0.025843647164727198, -0.22439141278557448, -103.49134676516807), (-0.025843647164727226, 0.97415635283527724, -0.22439141278557453, -107.25466846571966), (0.22439141278557431, 0.2243914127855747, 0.94831270567054426, -10.644281176985976))

  # Position of subfilament displaced out.
  sfmt2 = ((0.9999957248565281, -4.2751434744161616e-06, -0.0029240811200199287, -214.50933693143944), (-4.275143474582695e-06, 0.9999957248565301, -0.0029240811200196941, -218.27265863199113), (0.0029240811200198034, 0.0029240811200199092, 0.99999144971304987, 11.974816324109245))

  # Positioning of tail forward and right of filament for float in.
  tmt1 = ((1.0000000000000038, 0.0, -1.262386893235071e-32, 36.084205311245618), (0.0, 1.0000000000000038, -1.4293409452891395e-31, -361.47510934598643), (-1.262386893235071e-32, -1.4293409452891395e-31, 1.0, -102.06154507723714))

  from PDBmatrices import identity_matrix
  identity = identity_matrix()

  from chimera.statusline import show_status_line
  from Accelerators.standard_accelerators import sphere_representation
  from Accelerators.standard_accelerators import select_all, clear_selection

  p = Player()
  sequence = [
      (show_status_line, {'show': False}), # Needed to set small window widths.
      (set_window, {'size': (440,800), 'color':(1,1,1)}),
      2,        # Need window size update before setting label background.
      (label_background, {'position': (0,.92), 'size': (1.0,.11),
                          'color': 'white'}),
      '2dlabel create caption text "Myosin thick filament, EM map" color black xpos .1 ypos .95',
      'open %s' % join(dir,map_name),
      'scale 2',
      (set_center_of_rotation, {'center': (0,0,0)}),
      'turn x -90',
      (set_map, {'map_name': map_name,'threshold': 0.2, 'style': 'surface'}),
      'roll y 0.5 90',
      75,
      (duplicate_map, {'map_name': map_name}),
      (set_map, {'map_name': map2, 'threshold': 0.15, 'style': 'surface',
                 'bounds':((0,0,41), (99,99,81),(1,1,1))}),
      (set_map, {'map_name': map2, 'color': (.2,.2,.6,.0)},
        {'color': (.2,.2,.6,.5)}, 30),
      30,
      caption_fade, caption_fade_delay,
      show_caption % ('Symmetry: 90 degree rotation', .1),
      (move_only, {'model_name': map2}),
      'turn y 3 30',
      50,
      caption_fade, caption_fade_delay,
      show_caption % ('Symmetry: 43.5 nm translation', .1),
      'move y 7.5 58',
      80,
      caption_fade, caption_fade_delay,
      show_caption % ('Four strand helix', .3),
      'turn y -1 30',
      'move y -5 29',
      45,
      'turn y -1 30',
      'move y -5 29',
      45,
      'turn y -1 30',
      'move y -5 29',
      60,
      (set_map, {'map_name': map2, 'color': (.2,.2,.6,.5)},
       {'color': (.2,.2,.6,0)}, 20),
      20,
      (unshow_map, {'map_name': map2}),
      (move_only, {'model_name': 'all'}),
      caption_fade, caption_fade_delay,
      show_caption % ("Myosin heads, 'J' shapes on surface", .02),
      (cylinder_color,
       {'model_name': map_name, 'colormap':((120, map_color),(121, map_color))},
       {'colormap':((120, map_color),(121, head_color))}, 30),
      60,
      caption_fade, caption_fade_delay,
      show_caption % ('Myosin tails make filament body', .1),
      (cylinder_color,
       {'model_name': map_name, 'colormap':((120, map_color),(121, head_color))},
       {'colormap':((110, subfil_color),(111, map_color))}, 30),
      60,
      caption_fade, caption_fade_delay,
      show_caption % ('Fit myosin model, hand placement', .05),
      'open %s' % join(dir,pdb1i84),
      'rainbow chain',
      (sphere_representation, {}),
      (place_model, {'model_name': pdb1i84, 'matrix': mt1, 'relative_to':map_name}),
      (set_near_far, {'near': 577.7, 'far':-568.161},
       {'near': 1700, 'far':-1700}, 10),
      30,
      (move_model, {'model_name': pdb1i84, 'relative_to':map_name,
                    'from_matrix': mt1, 'to_matrix': mt2, 'fraction':0},
       {'fraction':1}, 30),
      30,
      (move_model, {'model_name': pdb1i84, 'relative_to':map_name,
                    'from_matrix': mt2, 'to_matrix': mt3, 'fraction':0},
       {'fraction':1}, 30),
      20,
      'scale 1.02 25',
      30,
      caption_fade, caption_fade_delay,
      show_caption % ('Computational fit optimization', .1),
      (select_all, {}),
      (cylinder_color,
       {'model_name': map_name, 'colormap':((110, subfil_color),(111, map_color))},
       {'colormap':((110, subfil_color),(111, map_color_t))}, 30),
      (move_model, {'model_name': pdb1i84, 'relative_to':map_name,
                    'from_matrix': mt3, 'to_matrix': mt4, 'fraction':0},
       {'fraction':1}, 30),
      30,
      (clear_selection, {}),
      30,
      caption_fade, caption_fade_delay,
      show_caption % ('Flip and fit - wrong orientation', .1),
      (move_model, {'model_name': pdb1i84, 'relative_to':map_name,
                    'from_matrix': mt4, 'to_matrix': mt5, 'fraction':0},
       {'fraction':1}, 15),
      15,
      (move_model, {'model_name': pdb1i84, 'relative_to':map_name,
                    'from_matrix': mt5, 'to_matrix': mt6, 'fraction':0},
       {'fraction':1}, 15),
      45,
      caption_fade, caption_fade_delay,
      show_caption % ('Fitting with symmetric copies', .1),
      (symmetric_copies, {'molecule_name': pdb1i84}),
      (move_only, {'model_name': pdb1i84}),     # Needed for sym copies to work
      'rainbow chain',
      15,
      (move_model, {'model_name': pdb1i84, 'relative_to':map_name,
                    'from_matrix': mt6, 'to_matrix': mt4, 'fraction':0},
       {'fraction':1}, 30),
      60,
      (symmetric_copies, {'molecule_name': pdb1i84, 'show': False}),
      (move_only, {'model_name': 'all'}),
      (cylinder_color,
       {'model_name': map_name, 'colormap':((110, subfil_color),(111, map_color_t))},
       {'colormap':((110, map_color_t),(111, map_color_t))}, 30),
      30,
      caption_fade, caption_fade_delay,
      show_caption % ('Myosin tail, hand traced', .2),
      'open %s' % join(dir,tail),
      (show_atom_sequence, {'molecule_name': tailname, 'count': 1},
       {'count': 10}, 60),
      30,
      'scale .975 30',
      60,
      (cylinder_color,
       {'model_name': map_name, 'colormap':((110, map_color_t),(111, map_color_t))},
       {'colormap':((110, map_color),(111, map_color))}, 15),
      15,
      (unshow_model, {'model_name': (pdb1i84, tailname)}),
      caption_fade, caption_fade_delay,
      show_caption % ('Filament has 12 subfilaments', .1),
      (open_models, {'paths': sfpaths}),
      (set_map, {'map_name': subfil, 'threshold': 0.2, 'style': 'surface', 'color': map_color}),
      (set_map, {'map_name': fc, 'color': fc_color}),
      (unshow_map, {'map_name': map_name}),
      (set_map, {'map_name': sfodd, 'color': map_color},
       {'color':sfocolor}, 60),
      60,
      (set_center_of_rotation, {'center': (0, 0, 0)}),
      'roll y 3 15',
      30,
      (move_model, {'model_name': sf, 'relative_to': map_name,
                    'from_matrix': identity, 'to_matrix': sfmt1, 'fraction':0},
       {'fraction':1}, 15),
      15,
      (move_model, {'model_name': sf, 'relative_to': map_name,
                    'from_matrix': sfmt1, 'to_matrix': sfmt2, 'fraction':0},
       {'fraction':1}, 15),
      25,
      (set_center_of_rotation, {'center': (275, 10, 257)}),
      (move_only, {'model_name': sf}),
      'roll y 4 90',
      90,
      (move_only, {'model_name': 'all'}),
      (set_center_of_rotation, {'center': (0, 0, 0)}),
      (explode, {'model_names': sfo, 'factor': 1.03}, {}, 60),
      45,
      (set_map, {'map_name': sfo, 'opacity': 1.0}, {'opacity':0}, 15),
      45,
      caption_fade, caption_fade_delay,
      show_caption % ('Filament core, contents unknown', .05),
      'roll y -0.5 90',
      'scale 1.01 60',
      45,
      (place_model, {'model_name': subfil, 'matrix': identity, 'relative_to':map_name}),
      (set_map, {'map_name': sf11, 'opacity': 1.0}),
      (place_model, {'model_name': sf11, 'matrix': identity, 'relative_to':map_name}),
      (show_model_sequence, {'model_names': sf11r, 'count': 1},
       {'count':11}, 45),
      45,
      caption_fade, caption_fade_delay,
      show_caption2 % ('  Animation created with UCSF Chimera.\\nData from John Woodhead and Roger Craig', .05, 18),
      (set_map, {'map_name': sf, 'style': 'mesh', 'color': sfocolor,
                 'opacity': 0.0, 'square_mesh': True}, {'opacity':0.4}, 30),
      (show_model, {'model_name': (pdb1i84, tailname)}),
      (move_model, {'model_name': pdb1i84, 'relative_to': map_name,
                    'from_matrix': mt7, 'to_matrix': mt4, 'fraction':0},
       {'fraction':1}, 30),
      (move_model, {'model_name': tailname, 'relative_to': map_name,
                    'from_matrix': tmt1, 'to_matrix': identity, 'fraction':0},
       {'fraction':1}, 30),
      ]
  
  p.play_sequence(sequence)
  
# -----------------------------------------------------------------------------
#
class Player:

  def __init__(self):

    self.sequence = []
    self.delay = 0
    self.transitions = []
    self.new_frame_handler = None

  # ---------------------------------------------------------------------------
  #
  def play_sequence(self, sequence):

    self.sequence = sequence
    self.delay = 0

    from chimera import triggers
    h = triggers.addHandler('new frame', self.new_frame, None)
    self.new_frame_handler = h

  # ---------------------------------------------------------------------------
  #
  def new_frame(self, trigger_name, call_data, trigger_data):

    t = 0
    while t < len(self.transitions):
      command, kw_begin, kw_end, frames, cur = self.transitions[t]
      cur += 1
      if cur > frames:
        del self.transitions[t]
        continue
      self.transitions[t] = (command, kw_begin, kw_end, frames, cur)
      kw = self.interpolate_parameters(kw_begin, kw_end, frames, cur)
      command(**kw)
      t += 1
      
    while self.sequence:
      if self.delay > 0:
        self.delay -= 1
        break
      s = self.sequence[0]
      del self.sequence[0]
      if type(s) is int:
        self.frame_delay(s)
      elif type(s) is type(''):
        run_command(s)
      elif len(s) == 2:
        command, kw = s 
        command(**kw)
      elif len(s) == 4:
        command, kw_begin, kw_end, frames = s
        command(**kw_begin)
        if frames > 1:
          self.transitions.append((command, kw_begin, kw_end, frames, 1))
          
    if (len(self.sequence) == 0 and
        len(self.transitions) == 0 and
        self.new_frame_handler):
      from chimera import triggers
      triggers.deleteHandler('new frame', self.new_frame_handler)
      self.new_frame_handler = None
  
  # ---------------------------------------------------------------------------
  #
  def frame_delay(self, frames):

    self.delay = frames
  
  # ---------------------------------------------------------------------------
  #
  def interpolate_parameters(self, kw_begin, kw_end, frames, cur):

    kw = {}
    kw.update(kw_begin)
    f = float(cur) / frames
    for key, value in kw_end.items():
      kw[key] = self.interpolate_parameter(kw[key], value, f)
    return kw
  
  # ---------------------------------------------------------------------------
  #
  def interpolate_parameter(self, v0, v1, f):

    if type(v0) in (int, float):
      v = (1-f) * v0 + f * v1
      return v
    elif type(v0) in (tuple, list):
      v = map(lambda e0, e1: self.interpolate_parameter(e0, e1, f), v0, v1)
      return v
    raise TypeError, 'Bad transition parameter of type ' + str(type(v0))
  
# -----------------------------------------------------------------------------
#
def set_window(size = None, color = None):

  if size != None:
    set_window_size(*size)

  if color != None:
    from Accelerators.standard_accelerators import set_background
    set_background(color)
  
# -----------------------------------------------------------------------------
#
def set_window_size(width, height):

  from chimera import viewer
  viewer.windowSize = (width, height)

# -----------------------------------------------------------------------------
#
def run_command(command):

  from chimera import runCommand
  runCommand(command)

# -----------------------------------------------------------------------------
#
def move_only(model_name):

  from chimera import openModels
  mlist = openModels.list()
  if model_name == 'all':
    for m in mlist:
      m.openState.active = True
  else:
    for m in mlist:
      m.openState.active = False
    for m in filter(lambda m: m.name == model_name, mlist):
      m.openState.active = True
  
# -----------------------------------------------------------------------------
#
def set_map(map_name, style = None, threshold = None, color = None,
            opacity = None, square_mesh = None, bounds = None):

  if type(map_name) in (list, tuple):
    for mname in map_name:
      set_map(mname, style, threshold, color, opacity, square_mesh, bounds)
    return
  
  dr = find_map(map_name)
  if style != None:
    set_map_style(map_name, style)
  if threshold != None:
    set_map_threshold(map_name, threshold)
  if color != None:
    set_map_color(map_name, color)
  if opacity != None:
    set_map_opacity(map_name, opacity)
  if square_mesh != None:
    set_map_rendering_option(map_name, 'square_mesh', square_mesh)
  if bounds != None:
    set_map_bounds(map_name, bounds)
  show_map(map_name)
    
# -----------------------------------------------------------------------------
#
def set_map_threshold(map_name, threshold):

  dr = find_map(map_name)
  dr.components[0].surface_levels = [threshold]
  show_map(map_name)
    
# -----------------------------------------------------------------------------
#
def set_map_bounds(map_name, bounds):

  dr = find_map(map_name)
  dr.new_region(bounds)
  show_map(map_name)

# -----------------------------------------------------------------------------
#
def set_map_style(map_name, style):

  dr = find_map(map_name)
  dr.representation = style
  show_map(map_name)
  
# -----------------------------------------------------------------------------
#
def set_map_color(map_name, rgba):

  dr = find_map(map_name)
  for c in dr.components:
    c.surface_colors = [rgba] * len(c.surface_colors)
  show_map(map_name)
  
# -----------------------------------------------------------------------------
#
def set_map_opacity(map_name, opacity):

  dr = find_map(map_name)
  for c in dr.components:
    c.surface_colors = map(lambda rgba: tuple(rgba[:3]) + (opacity,),
                           c.surface_colors)
  show_map(map_name)
  
# -----------------------------------------------------------------------------
#
def set_map_rendering_option(map_name, option_name, value):

  dr = find_map(map_name)
  setattr(dr.rendering_options, option_name, value)
  show_map(map_name)

# -----------------------------------------------------------------------------
#
def find_map(map_name):

  dr = volume_dialog().find_data_by_name(map_name)
  return dr

# -----------------------------------------------------------------------------
#
def show_map(map_name):

  dr = find_map(map_name)
  volume_dialog().show_data_regions([dr])

# -----------------------------------------------------------------------------
#
def unshow_map(map_name):

  dr = find_map(map_name)
  dr.unshow()

# -----------------------------------------------------------------------------
#
def volume_dialog():

  import VolumeViewer
  d = VolumeViewer.volume_dialog()
  return d

# -----------------------------------------------------------------------------
#
def set_center_of_rotation(center):

  from chimera import openModels, Point
  if center == None:
    openModels.cofrMethod = openModels.CenterOfModels
  else:
    openModels.cofr = Point(*center)
    openModels.cofrMethod = openModels.Fixed

# -----------------------------------------------------------------------------
#
def duplicate_map(map_name):

  dr = find_map(map_name)
  d = volume_dialog()
  dr2 = d.duplicate_region(dr)
  d.show_data_regions([dr2])

# -----------------------------------------------------------------------------
#
def cylinder_color(model_name, colormap):

  model = find_model_by_name(model_name)

  from SurfaceColor import Color_Map, Cylinder_Color, color_surface
  values = map(lambda vc: vc[0], colormap)
  colors = map(lambda vc: vc[1], colormap)
  color_source = Cylinder_Color()
  
  color_source.colormap = Color_Map(values, colors)

  color_surface(model, color_source, caps_only = False, auto_update = False)

# -----------------------------------------------------------------------------
#
def find_model_by_name(model_name):

  from chimera import openModels
  m = filter(lambda m: m.name == model_name, openModels.list())[0]
  return m

# -----------------------------------------------------------------------------
#
def show_model(model_name, show = True):

  if type(model_name) in (tuple, list):
    for mname in model_name:
      show_model(mname, show)
    return

  model = find_model_by_name(model_name)
  model.display = show

# -----------------------------------------------------------------------------
#
def unshow_model(model_name):

  show_model(model_name, show = False)

# -----------------------------------------------------------------------------
#
def place_model(model_name, matrix, relative_to):

  if type(model_name) in (tuple, list):
    for mname in model_name:
      place_model(mname, matrix, relative_to)
    return
  
  model = find_model_by_name(model_name)
  rmodel = find_model_by_name(relative_to)
  from PDBmatrices import chimera_xform
  xf = chimera_xform(matrix)
  rxf = rmodel.openState.xform
  xf.premultiply(rxf)
  model.openState.xform = xf

# -----------------------------------------------------------------------------
#
def move_model(model_name, from_matrix, to_matrix, relative_to, fraction):

  model = find_model_by_name(model_name)
  rmodel = find_model_by_name(relative_to)
  from PDBmatrices import chimera_xform
  fxf = chimera_xform(from_matrix)
  txf = chimera_xform(to_matrix)
  rxf = rmodel.openState.xform
  fxf.premultiply(rxf)
  txf.premultiply(rxf)

  # Find model center
  have_box, bbox = model.bbox()
  c = bbox.center()
  cf = fxf.apply(c)
  ct = txf.apply(c)

  # Determine fractional translation
  from chimera import Xform, Vector, Point
  td = Xform.translation((ct-cf)*fraction)

  # Determine fractional rotation
  r = fxf.inverse()
  r.premultiply(txf)
  axis, angle = r.getRotation()
  rd = Xform.rotation(axis, fraction*angle)

  cv = Xform.translation(cf - Point())
  cvi = Xform.translation(Point() - cf)

  xf = Xform()
  xf.multiply(fxf)              # Apply start transform
  xf.premultiply(cvi)           # Shift to put model center at origin
  xf.premultiply(rd)            # Apply fractional rotation
  xf.premultiply(cv)            # Shift center back to from position
  xf.premultiply(td)            # Apply fractional translation
  model.openState.xform = xf
  
# -----------------------------------------------------------------------------
#
def set_near_far(near, far):

  from chimera import viewer
  c = viewer.camera
  c.nearFar = (near, far)
  
# -----------------------------------------------------------------------------
#
def symmetric_copies(molecule_name, show = True):

  m = find_model_by_name(molecule_name)
  if show:
    run_command('sym #%d' % m.id)
  else:
    run_command('~sym #%d' % m.id)
  
# -----------------------------------------------------------------------------
#
def show_atom_sequence(molecule_name, count):

  m = find_model_by_name(molecule_name)
  count = int(count)
  alist = m.atoms
  for a in alist[:count]:
    a.display = True
  for a in alist[count:]:
    a.display = False
    
# -----------------------------------------------------------------------------
#
def show_model_sequence(model_names, count):

  mlist = map(find_model_by_name, model_names)
  count = int(count)
  for m in mlist[:count]:
    m.display = True
  for m in mlist[count:]:
    m.display = False

# -----------------------------------------------------------------------------
#
def open_models(paths):

  for path in paths:
    run_command('open %s' % path)
  
# -----------------------------------------------------------------------------
#
def explode(model_names, factor):

  mlist = map(find_model_by_name, model_names)
  centers = map(lambda m: m.openState.xform.apply(m.bbox()[1].center()), mlist)
  n = len(model_names)
  from chimera import Point, Xform
  c = Point(centers, [1.0/n]*n)

  for k in range(len(mlist)):
    delta = (centers[k] - c) * (factor - 1.0)
    xf = Xform.translation(delta)
    mlist[k].openState.globalXform(xf)
  
# -----------------------------------------------------------------------------
# Make a solid background for drawing labels.
# This hack uses several labels containing strings of ells.
#
def label_background(position, size, color):

  import chimera
  v = chimera.viewer
  wsize = v.windowSize

  fsize = int(size[1] * wsize[1])    # pixels
  lcount = int(5 * float(wsize[0]) / fsize)
  ells = 'l' * lcount
  xstep = (.07 * fsize) / wsize[0]
  for k in range(4):
    run_command('2dlabel create bg%d text "%s" color %s xpos %f ypos %f size %d'
                % (k, ells, color, position[0] + k*xstep, position[1], fsize))

# -----------------------------------------------------------------------------
#
def write_relative_transforms():

  from chimera import openModels
  mlist  = openModels.list()
  m0 = mlist[0]
  print 'Matrices relative to', m0.name
  xf_ref = m0.openState.xform
  xf_ref_inv = xf_ref.inverse()
  for m in mlist[1:]:
    xf = m.openState.xform
    xf.premultiply(xf_ref_inv)
    from PDBmatrices import xform_matrix, is_identity_matrix
    mt = xform_matrix(xf)
    if not is_identity_matrix(mt):
      print m.name, repr(mt)

# -----------------------------------------------------------------------------
#
from Accelerators import add_accelerator
add_accelerator('pm', 'Play myosin thick filament movie', play)
add_accelerator('wt', 'Write relative transformation matrices',
		 write_relative_transforms)



More information about the Chimera-users mailing list