From: Stephanie Teich-McGoldrick (stephanietm_at_gmail.com)
Date: Mon Sep 30 2013 - 22:08:53 CDT

Hi Axel,

Thanks for the explanation and code example. This seems to have solved my
problem!

Cheers,
Stephanie

On Sat, Sep 28, 2013 at 3:27 AM, Axel Kohlmeyer <akohlmey_at_gmail.com> wrote:

> hi stephanie,
>
> please see my comments below
>
> On Sat, Sep 28, 2013 at 2:42 AM, Stephanie Teich-McGoldrick
> <stephanietm_at_gmail.com> wrote:
> > Hello all,
> >
> > I am trying to write a user defined script to make a movie with vmd
> 1.9.1 on
> > a Mac. However, my commands do not seem to be executing in sequence, and
> > some seem to be skipped entirely. I am using a 'mywait' script John
> posted
> > to the mailing list, as the 'wait' command does not appear to work for
> me.
>
> "wait" is a shell builtin. the equivalent to sleep in Tcl is the
> "after" command. unlike sleep it takes milliseconds as an argument and
> also includes additional features.
>
> > These are my actions:
> >
> > proc xrotate {} {
> > rotate x by 90 20
> > }
> > proc yrotate {} {
> > rotate y by 180 20
> > }
> > proc mywait { waittime } {
> > set starttime [clock seconds]
> > while {[expr [clock seconds] - $starttime < $waittime]} {
> > }
> > }
> >
> > When I run anyone of these commands individually they work. However, if I
> > execute the following:
> >
> > proc MakeMovie { } {
> > xrotate
> > mywait 10
> > yrotate
> > puts "I am done with MakeMovie"
> > }
> >
> > the program waits, then writes "I am done with MakeMovie", then rotates
> > around the y-axis. The rotation about the x-axis never happens. I have
> tried
>
> it does happen, you just don't notice.
>
> > various combinations, but I can't get the program to execute in order.
> Any
> > suggestions of things I might be overlooking?
>
> this is a bit tricky to explain, since this relates to some internals
> of how GUI programs work. i am trying to simplify it, so it may not be
> 100% technically correct, but it should be sufficiently close, so that
> you can see where the issue lies and how to deal with it.
>
> in a nutshell, applications are initialized and then enter what is
> called an "event loop" from which they never return. the event loop
> does "multiplexing" by processing a queue of pending events, i.e. it
> tries to act as if it can do many things at the same time, but it
> actually just monitors the queue of events and then jumps to a
> subroutine designated to react to that event. if this subroutine does
> not do much or just does a bit of work and then stops and creates a
> new event designated to continue the work where it stopped, you don't
> notice that there is actually just a single thread working.
> executing a Tcl script is such an event. thus everything else in VMD
> is suspended until it completes. because of that, the GUI does not
> respond, if you do complex long running script computations or VMD
> commands like measure.
>
> now the rotate command is a very old one and uses the event queue in a
> way, that you would not do nowadays exactly because of the behavior
> you are observing. it creates multiple events and adds them to the
> queue. if you type the rotate command at the commend prompt, this
> works fine, because you drop back into the event loop after the first
> event is executed and then process the rest. however, inside a Tcl
> script, this does not happen. so all rotate events are queued up and
> then executed as one big swoop after your script ends. not exactly
> what you intend to do, right?
>
> this has been recognized, and to alleviate the issue, there is the
> "display update" command. this allows you to deliberately suspend and
> enable the event queue processing (e.g. if you want to do a lot of
> incremental changes, but only want to see the final result) and it
> also allows you to process the event queue with "display update". at
> this point, the issue of how the smooth rotate is implemented rears
> its ugly head, since running the even queue once, is not enough. so
> you have to emulate this behavior.
> what you end up with is something that could look like this:
>
>
> # smooth rotation with display updates for scripts
> # dir: rotation direction {x, y, or z}
> # val: total rotation in degrees
> # inc: rotation increments in degrees
> # del: delay between increment updates in milliseconds
> proc srotate {{dir x} {val 0} {inc 1} {del 0}} {
> set n [expr {int(abs($val) / $inc)}]
> for {set i 0} {$i < $n} {incr i} {
> rotate $dir by $inc
> display update
> after $del
> }
> rotate $dir by [expr {$val - $n*$inc}]
> display update
> after $del
> }
>
> proc MakeMovie { } {
> srotate x 90 20 100
> puts "wait"
> after 10000
> srotate y 180 20 100
> puts "done"
> }
>
> please give it a try and let us know, if that solves your problem.
>
> ciao,
> axel.
>
> > Cheers,
> > Stephanie
>
>
>
> --
> Dr. Axel Kohlmeyer akohlmey_at_gmail.com http://goo.gl/1wk0
> International Centre for Theoretical Physics, Trieste. Italy.
>