From: Axel Kohlmeyer (akohlmey_at_gmail.com)
Date: Sat Dec 05 2020 - 17:08:10 CST

this is due to a rather peculiar way how the atomselect command works in
VMD.

on the technically side, when you call the atomselect command, it will
create a new function (aka proc) called atomselect# with the # being a
continually increasing number so that each function name is unique.
because the number is unique and depends on how many times the atomselect
command has been called before, you put the atomselect command in square
brackets and assign the result (i.e. the name of the new proc) to the a
variable.

now procedures are global in Tcl, but the VMD implementation uses a trick
(too complicated to explain here) that they become local and thus are
automatically deleted when you leave that scope. thus when you define an
atom selection in a subroutine, you cannot call it outside that scope.

there is help, however, you can call the created function with the "global"
subcommand to change the scope. so your script should be the following:

proc create {} {
    global all
    set all [atomselect top all]
    $all global
}
proc test {} {
    global all
    $all num
}
proc clean {} {
    global all
    catch {$all delete} res
}

please note, that you should delete all atom selections to avoid memory
leaks, and you have to protect the deleting for "globalized" atomselections
with a "catch" to avoid an error message because of an unavoidable side
effect of the trick that makes atomselect functions local in scope.

axel.

On Sat, Dec 5, 2020 at 4:47 PM Arthur Pereira da Fonseca <
arthurpfonseca3k_at_hotmail.com> wrote:

>
>
> Hello, I’m still learning some tcl and I'm trying to write a script in it
> to execute some analysis on VMD. First I'm creating an atom selection
> inside a procedure, then I'm trying to use it on another procedure.
>
> When I create the atom selection outside a *proc* I can use it inside one
> just passing it as *global*. But now that I'm creating it inside one,
> when I try to use it it's just a string with the procedure name.
> Resuming,
>
> This works:
>
> set all [atomselect top all]
>
>
>
> proc test {} {
>
> global all
>
> $all num
>
> }
>
>
>
> test # Outuputs 7111
>
>
>
>
>
> But this don't:
>
> proc create {} {
>
> global all
>
> set all [atomselect top all]
>
> }
>
>
>
> proc test {} {
>
> global all
>
> $all num
>
> }
>
>
>
> test # Outputs -> invalid command name "atomselect1"
>
>
>

-- 
Dr. Axel Kohlmeyer  akohlmey_at_gmail.com  http://goo.gl/1wk0
College of Science & Technology, Temple University, Philadelphia PA, USA
International Centre for Theoretical Physics, Trieste. Italy.