next up previous contents index
Next: Simulation frames Up: Trajectory frames Previous: Animating the secondary structure

Viewing selections which change during an animation

     

One of the researchers here needed a way to see which waters bridged between a protein and a nucleic acid during a trajectory. The specific waters change during the simulation, so the static method used in the graphics form doesn't work. Instead, the vmd_frame variable and a caching method similar to the sscache of the previous section was used for the following solution:

The cache data is stored in the array bridging_waters. Unlike sscache, this array is indexed only by the frame number; you'll have to modify it to analyze multiple changing selections.

When the frame number changes, the cache is checked and, if no data exists, the selection is rebuilt. Since the selection is created in a procedure, it must be given by the global command to make it exist outside that procedure's context.

The global Tcl variable bridging is set to the selection for this frame.

The first text selection in the graphics form is set to @bridging. This is one of the special extensions to the selection language which enable the selections to reference a Tcl variable. Note also that the display updates are temporarily turned off. This is used to keep the display from being drawn an additional time by the call to mol modselect. This is done every time the frame changes since that's the only way to tell VMD the graphics have changed; forcing it to recalculate that representation's display.

# start the trace
proc start_bridging {{molid top}} {
 global vmd_frame bridging_molecule
 if {![string compare $molid top]} {
    set molid [molinfo top]
  }
  trace variable vmd_frame($molid) w calc_bridging
  set bridging_molecule $molid
}

# stop the trace
proc stop_bridging {} {
  global bridging_molecule vmd_frame
  trace vdelete vmd_frame($bridging_molecule) w calc_bridging
}

# do the actual calculation
proc calc_bridging {args} {
  global bridging_waters bridging_molecule bridging
  # get the current frame number
  set frame [molinfo $bridging_molecule get frame]

  # has the selection already been made?
  if {! [info exists bridging_waters($frame)]} {
    puts "Calculating frame $frame for $bridging_molecule"
    set bridging_waters($frame) [atomselect $bridging_molecule 
       {(water within 4 of segname DNA) and (water within 4 of segname PRO1)} 
       frame $frame]
  }
  # set things up for the graphics form to use the precomputed selection
  set bridging $bridging_waters($frame)
  # do this since otherwise the selection is deleted when the proc ends
  $bridging global
  # update the 0th element of the graphics molecule
  # Note: if the display wasn't turned off, there would be an extra
  # update of the animation ... very bad
  display update off
  mol modselect 0 $bridging_molecule {@bridging}
  display update on
}

Since the selections are available in the global scope, you can analyze the results at any time. This simple function prints how many atoms are in each selection of the cache.

proc num_bridging {} {
  global bridging_waters
  set nums [lsort -integer [array names bridging_waters]]
  foreach num $nums {
    set num_atoms [$bridging_waters($num) num]
    puts "Frame $num has $num_atoms atoms"
  }
}

It would be nice to change the text selection used, support multiple selections, have the ``@'' variables in more complicated expressions in the graphics selections, and be able to use this script for multiple molecules. These are left to the student as an exercise :).


next up previous contents index
Next: Simulation frames Up: Trajectory frames Previous: Animating the secondary structure

Justin Gullingsrud
Tue Apr 6 09:22:39 CDT 1999