matrixget/set, keyframes, and interpolation

Does anyone have experience making movies in Chimera used more advanced motions, besides the standard roll, rock, etc? My general idea is to use matrixget to output a series of matrices, interpolate them in my standard Python environment (which is related to the question from Vol 38, Issue 10), and create as output a Chimera script composed of hundreds of 'matrixset' matrices. The Python Computer Graphics Kit (http://cgkit.sourceforge.net) will give me the functions for quaternions, as would ScientificPython or pythonOpenGL, but a quick review of their documentation suggests that in any package it will be necessary to interpolate the rotation separately from the translation: obviously it would be more convenient if there is a package that can transparently interpolate the matrices as provided by Chimera. Has anyone gone through this issue before, hopefully with some tips for me? Thanks, Jonathan

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)

I previously replied just to Jonathan, but it was suggested other chimera-users might find the information useful: There are some undocumented extra features of the "reset" command in recent versions of Chimera (2006) that may have the desired effect. The standard behavior is that you can save the positions of models and give each set of positions a name (with the "savepos" command) and later return to any saved position with "reset." The undocumented (newer and less well-tested) behavior is that you can use "reset" to gradually interpolate from one saved position to another over a specified number of frames. The usage is: reset position-name [#-frames [interp-method]] where the only interp-method currently available is "linear" This newer usage of the reset command may be changed, improved, and further developed in future versions of Chimera. Elaine "savepos" man page: http://www.cgl.ucsf.edu/chimera/docs/UsersGuide/midas/savepos.html On Jun 15, 2006, at 7:55 PM, Jonathan Hilmer wrote:
Does anyone have experience making movies in Chimera used more advanced motions, besides the standard roll, rock, etc?
My general idea is to use matrixget to output a series of matrices, interpolate them in my standard Python environment (which is related to the question from Vol 38, Issue 10), and create as output a Chimera script composed of hundreds of 'matrixset' matrices.
The Python Computer Graphics Kit (http://cgkit.sourceforge.net) will give me the functions for quaternions, as would ScientificPython or pythonOpenGL, but a quick review of their documentation suggests that in any package it will be necessary to interpolate the rotation separately from the translation: obviously it would be more convenient if there is a package that can transparently interpolate the matrices as provided by Chimera.
Has anyone gone through this issue before, hopefully with some tips for me?
Thanks, Jonathan _______________________________________________ Chimera-users mailing list Chimera-users@cgl.ucsf.edu http://www.cgl.ucsf.edu/mailman/listinfo/chimera-users
----- Elaine C. Meng, Ph.D. meng@cgl.ucsf.edu UCSF Computer Graphics Lab and Babbitt Lab Department of Pharmaceutical Chemistry University of California, San Francisco http://www.cgl.ucsf.edu/home/meng/index.html

Just a little addendum: savepos positions are remembered in sessions, so you can develop your animation over several days if needed. --Eric On Jun 16, 2006, at 10:40 AM, Elaine Meng wrote:
I previously replied just to Jonathan, but it was suggested other chimera-users might find the information useful:
There are some undocumented extra features of the "reset" command in recent versions of Chimera (2006) that may have the desired effect.
The standard behavior is that you can save the positions of models and give each set of positions a name (with the "savepos" command) and later return to any saved position with "reset."
The undocumented (newer and less well-tested) behavior is that you can use "reset" to gradually interpolate from one saved position to another over a specified number of frames. The usage is:
reset position-name [#-frames [interp-method]]
where the only interp-method currently available is "linear" This newer usage of the reset command may be changed, improved, and further developed in future versions of Chimera. Elaine
"savepos" man page: http://www.cgl.ucsf.edu/chimera/docs/UsersGuide/midas/savepos.html
On Jun 15, 2006, at 7:55 PM, Jonathan Hilmer wrote:
Does anyone have experience making movies in Chimera used more advanced motions, besides the standard roll, rock, etc?
My general idea is to use matrixget to output a series of matrices, interpolate them in my standard Python environment (which is related to the question from Vol 38, Issue 10), and create as output a Chimera script composed of hundreds of 'matrixset' matrices.
The Python Computer Graphics Kit (http://cgkit.sourceforge.net) will give me the functions for quaternions, as would ScientificPython or pythonOpenGL, but a quick review of their documentation suggests that in any package it will be necessary to interpolate the rotation separately from the translation: obviously it would be more convenient if there is a package that can transparently interpolate the matrices as provided by Chimera.
Has anyone gone through this issue before, hopefully with some tips for me?
Thanks, Jonathan _______________________________________________ Chimera-users mailing list Chimera-users@cgl.ucsf.edu http://www.cgl.ucsf.edu/mailman/listinfo/chimera-users
----- Elaine C. Meng, Ph.D. meng@cgl.ucsf.edu UCSF Computer Graphics Lab and Babbitt Lab Department of Pharmaceutical Chemistry University of California, San Francisco http://www.cgl.ucsf.edu/home/meng/index.html
_______________________________________________ Chimera-users mailing list Chimera-users@cgl.ucsf.edu http://www.cgl.ucsf.edu/mailman/listinfo/chimera-users
participants (4)
-
Elaine Meng
-
Eric Pettersen
-
Jonathan Hilmer
-
Thomas Goddard