From: Amit Gupta (amit__at_outlook.in)
Date: Tue Dec 20 2016 - 09:54:03 CST

Thank you everyone for help. Given below is the script for future reference. It took that long because in enable trace function i was not declaring global vmd_trace. Also I would like to point out that Axel's PDF on vmd scripting along with lots of other material with full on scripts and data is still available here if anyone wnats to practice : http://www.jncasr.ac.in/ccms/sbs2007/lecturenotes/

here is the completed script (it is a simple script for CTAB molecule with "type 6" N atom, it plots a vector from the aliphatic chain C to average point of 3 C in head group):

draw delete all
draw color yellow
proc vmd_draw_arrow {mol start end} {
    # an arrow is made of a cylinder and a cone
    set middle [vecadd $start [vecscale 0.75 [vecsub $end $start]]]
    graphics $mol cylinder $start $middle radius 0.1
    graphics $mol cone $middle $end radius 0.3
}

set n [molinfo top get numframes]
set sel [atomselect top {all}]
set n_list [atomselect top "type 6"]
set all_n_atoms [$n_list get index]
$n_list delete

proc frame_arrow_draw {name element op} {
    draw delete all
    draw color yellow
    global all_n_atoms
    set current_frame_no [molinfo top get frame]
    foreach n_atom $all_n_atoms {
        #get index of atoms from whihc vectors are to be drawn
        set current_c_atom_index [expr $n_atom - 1]
        set current_c_atom_index1 [expr $n_atom + 1]
        set current_c_atom_index2 [expr $n_atom + 2]
        set current_c_atom_index3 [expr $n_atom + 3]

        set start_temp [atomselect top "index $current_c_atom_index" frame $current_frame_no ]
        set start [lindex [$start_temp get {x y z}] 0]
        set c1_temp [atomselect top "index $current_c_atom_index1" frame $current_frame_no ]
        set c1 [lindex [$c1_temp get {x y z}] 0]
        set c2_temp [atomselect top "index $current_c_atom_index2" frame $current_frame_no ]
        set c2 [lindex [$c2_temp get {x y z}] 0]
        set c3_temp [atomselect top "index $current_c_atom_index3" frame $current_frame_no ]
        set c3 [lindex [$c3_temp get {x y z}] 0]

        #avergae opsition of c1 c2 and c3
        set temp [vecadd $c1 $c2 $c3]
        set end [list [expr [lindex $temp 0]/3] [expr [lindex $temp 1]/3] [expr [lindex $temp 2]/3]]

        draw arrow $start $end
        #free memory, else it crashes
        $start_temp delete
        $c1_temp delete
        $c2_temp delete
        $c3_temp delete
    }
}

proc start_arrow {} {
    global vmd_frame
    trace variable vmd_frame([molinfo top]) w frame_arrow_draw
}
start_arrow

Thank you again :)
________________________________________
From: Ajasja Ljubeti <ajasja.ljubetic_at_gmail.com>
Sent: Tuesday, December 20, 2016 8:20:20 PM
To: Amit Gupta
Cc: Ashar Malik; vmd-l_at_ks.uiuc.edu
Subject: Re: Fw: vmd-l: Draw arrows in trajectory file

Hi

Below is a skeleton script to get you started.
drawcallback is called every time the frame of the molecule changes.

proc enabletrace {} {
  global vmd_frame;
  trace variable vmd_frame([molinfo top]) w drawcallback
}

proc disabletrace {} {
  global vmd_frame;
  trace vdelete vmd_frame([molinfo top]) w drawcallback
}

proc drawcallback { name element op } {
  global vmd_frame;

  set i $vmd_frame([molinfo top])

  draw delete all
  # puts "callback!"
  #### Insert your arrow drawing code (for one frame) here
}

#load the molecule than call

enabletrace {}

On 20 December 2016 at 14:25, Amit Gupta <amit__at_outlook.in<mailto:amit__at_outlook.in>> wrote:

Hi, Thank you for time and patience. No it did not work. I gave draw delete all and it deleted all arrows except from the last frame.

"all this in a loop and deleting in the same iteration - it might get drawn and deleted too fast " - yes that is what is happening. I want each frame to retain arrows drawn by itself only. basically arrows should move when molecules move. Is it possible? I know conceptually similar things have been done with text like here: http://www.ks.uiuc.edu/Research/vmd/mailing_list/vmd-l/20596.html

but i do not fully understand it.

I also tried 'display update on' as one of the example does it on vmd and it says on website "update: Force a display update. Used if the display update is off or to force a redraw."

but of no help.

at present my script looks like this:

draw delete all
draw color yellow
proc vmd_draw_arrow {mol start end} {
    # an arrow is made of a cylinder and a cone
    set middle [vecadd $start [vecscale 0.75 [vecsub $end $start]]]
    graphics $mol cylinder $start $middle radius 0.1
    graphics $mol cone $middle $end radius 0.3
}

set n [molinfo top get numframes]
set sel [atomselect top {all}]
set n_list [atomselect top "type 6"]
set all_n_atoms [$n_list get index]
$n_list delete
for {set i 0} {$i < $n} {incr i} {
    #display update on
    #draw delete all
    #draw color yellow
    #$sel frame $i
    foreach n_atom $all_n_atoms {
        #get index of atoms from whihc vectors are to be drawn
        set current_c_atom_index [expr $n_atom - 1]
        set current_c_atom_index1 [expr $n_atom + 1]
        set current_c_atom_index2 [expr $n_atom + 2]
        set current_c_atom_index3 [expr $n_atom + 3]

       #get coords of all atoms
        set start_temp [atomselect top "index $current_c_atom_index" frame $i]
        set start [lindex [$start_temp get {x y z}] 0]

        set c1_temp [atomselect top "index $current_c_atom_index1" frame $i]
        set c1 [lindex [$c1_temp get {x y z}] 0]

        set c2_temp [atomselect top "index $current_c_atom_index2" frame $i]
        set c2 [lindex [$c2_temp get {x y z}] 0]

        set c3_temp [atomselect top "index $current_c_atom_index3" frame $i]
        set c3 [lindex [$c3_temp get {x y z}] 0]

        #avergae opsition of c1 c2 and c3
        set temp [vecadd $c1 $c2 $c3]
        set end [list [expr [lindex $temp 0]/3] [expr [lindex $temp 1]/3] [expr [lindex $temp 2]/3]]

        draw arrow $start $end

        #free memory, else it crashes
        $start_temp delete
        $c1_temp delete
        $c2_temp delete
        $c3_temp delete
    }
}

________________________________
From: Ashar Malik <asharjm_at_gmail.com<mailto:asharjm_at_gmail.com>>
Sent: Tuesday, December 20, 2016 6:11 PM

To: Amit Gupta
Cc: vmd-l_at_ks.uiuc.edu<mailto:vmd-l_at_ks.uiuc.edu>
Subject: Re: Fw: vmd-l: Draw arrows in trajectory file

since you are drawing a new thing every frame and don't need to see the previous thing in the current selection - you should use

draw delete all

I think this should delete everything drawn and redraw at the new positions you pass it - which I am guessing is coming from the loop.
(If you are drawing all this in a loop and deleting in the same iteration - it might get drawn and deleted too fast -- ??? Not sure if that is what you want ?? )
Hope this helps. Otherwise write back.

On Wed, Dec 21, 2016 at 1:28 AM, Amit Gupta <amit__at_outlook.in<mailto:amit__at_outlook.in>> wrote:

Hi,

Yes I realized it and added it later on. Now I can see all the arrows, but together! I mean they are not changing with frame, rather all arrows from all frames are visible all the time

________________________________
From: Ashar Malik <asharjm_at_gmail.com<mailto:asharjm_at_gmail.com>>
Sent: Tuesday, December 20, 2016 5:49:33 PM
To: Amit Gupta
Cc: vmd-l_at_ks.uiuc.edu<mailto:vmd-l_at_ks.uiuc.edu>
Subject: Re: Fw: vmd-l: Draw arrows in trajectory file

Hi,

I think this maybe because you are not updating your selections properly. to see the arrow move - I guess your selections for arrows need to be updated on a frame by frame basis.
Try either "$sel update" after "$sel frame $i"

or drop the use of $sel update and use make selections like ...

set end [lindex [[atomselect top "index $n_atom" frame $i] get {x y z}] 0]

notice "frame $i" in the command you used. This will force a selection in the frame controlled by the loop.
I think this should fix it. Otherwise - write back.

Best,
/A

On Tue, Dec 20, 2016 at 10:45 PM, Amit Gupta <amit__at_outlook.in<mailto:amit__at_outlook.in>> wrote:

Sorry I sent the message below to the person who replied rather than to mailing list:

Thank you for the reply. I modified the script as written at the bottom of mail and it worked fine (did not crash). However now i notice that arrows are drawn only once, in the first frame. After which I do not see any movement in the arrows. Is there any way to draw arrows per frame?

Modified lines that worked:

set end_temp [atomselect top "index $n_atom"]
set end [lindex [ $end_temp get {x y z}] 0]

set start_temp [atomselect top "index $current_c_atom_index"]
set start [lindex [$start_temp get {x y z}] 0]

$end_temp delete
$start_temp delete

From: Norman Geist <norman.geist_at_uni-greifswald.de<mailto:norman.geist_at_uni-greifswald.de>>
Sent: Tuesday, December 20, 2016 2:07:25 PM
To: 'Amit Gupta'
Subject: AW: vmd-l: Draw arrows in trajectory file

You produced a common memory leak with many atomselects which you never clear.
After you no more need an atomselect object, you should call delete on it to free memory.

Eg.:

set a [atomselect top all]
set list [$a get index]
$a delete; #<-------

So whats happening is that vmd gets killed for eating up all the memory.

Best of luck

Norman Geist

Von: owner-vmd-l_at_ks.uiuc.edu<mailto:owner-vmd-l_at_ks.uiuc.edu> [mailto:owner-vmd-l_at_ks.uiuc.edu<mailto:owner-vmd-l_at_ks.uiuc.edu>] Im Auftrag von Amit Gupta
Gesendet: Dienstag, 20. Dezember 2016 07:31
An: vmd-l_at_ks.uiuc.edu<mailto:vmd-l_at_ks.uiuc.edu>
Betreff: vmd-l: Draw arrows in trajectory file

I want to draw come arrows in a lammps trajectory file, indicating movement of certain vectors.
I have written script below, it works fine for single frame, but for more than one frame, VMD crashes without any message (even in console). Can anyone suggest a reason?

draw color yellow

##-----------Draw arrow subroutine from VMD website----------

proc vmd_draw_arrow {mol start end} {

    # an arrow is made of a cylinder and a cone

    set middle [vecadd $start [vecscale 0.75 [vecsub $end $start]]]

    graphics $mol cylinder $start $middle radius 0.1

    graphics $mol cone $middle $end radius 0.3

}

##--------------------------------------------------------------------------------

set n [molinfo top get numframes]

set sel [atomselect top "all"]

set n_list [atomselect top "type 6"] #get indexes of all nitrogens in molecules

set all_n_atoms [$n_list get index]

for {set i 0} {$i < $n} {incr i} {

     $sel frame $i

    foreach n_atom $all_n_atoms {

        set current_c_atom_index [expr $n_atom - 1] # get index of C attached to N

        set end [lindex [[atomselect top "index $n_atom"] get {x y z}] 0]

        set start [lindex [[atomselect top "index $current_c_atom_index"] get {x y z}] 0]

        draw arrow $start $end

    }

}

Sorry if certain logic seems slightly convoluted, still getting used to TCL!

--
Best,
/A
--
Best,
/A