Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[Newbie] Howto pass file handle to proc?

1,567 views
Skip to first unread message

Sascha T.

unread,
Mar 2, 2005, 4:09:14 PM3/2/05
to

Hi!

I am rather new to tcl, used to code in C/C++/Fortran/Perl.
Anyway, I've encountered a problem and I hope you can
help me with that:


Suggesting, I have a proc like that:

-----------------------------
proc test { frame } {
set A 4;
puts $frame:$A
}
-----------------------------

and I need to write output to a file, so I'd rather use

puts $filehandle $frame:$A

However, test is called repetively from within a loop,
so I don't want to open/close file in test, but
before/after calling test, somewhat like

-----------------------
[open-file]
[loop-start]
[test]
[loop-end]
[close-file]
----------------------------

But trying to give handle to test ends up with
all sorts of errors.

Any suggestions?

Thank you


Sascha T.

Don Porter

unread,
Mar 2, 2005, 4:13:01 PM3/2/05
to
Sascha T. wrote:
> But trying to give handle to test ends up with
> all sorts of errors.
>
> Any suggestions?

How about you tell us what you are trying and what errors you
get in response?

--
| Don Porter Mathematical and Computational Sciences Division |
| donald...@nist.gov Information Technology Laboratory |
| http://math.nist.gov/~DPorter/ NIST |
|______________________________________________________________________|

Sascha T.

unread,
Mar 2, 2005, 4:28:06 PM3/2/05
to
Am Wed, 02 Mar 2005 21:13:01 +0000 schrieb Don Porter:

> How about you tell us what you are trying and what errors you
> get in response?

Err, o.k., I was afraid this could become too exhausting, but
never mind that, here it is:

I am using a molecular graphics program named VMD
( http://www.ks.uiuc.edu/Research/vmd/ ) that uses tcl-scripting
language for interaction. However, there's a script I need
to make use of. I would like to post it here, but I don't
know if that could violat some copyright, so here's an url
where the script can be viewed:

http://www.ks.uiuc.edu/Research/vmd/script_library/scripts/bigdcd/bigdcd.tcl


Within the comments, you find this:


# Example 1:
# This computes the center of mass for each frame in the DCD file.
#
# proc mycenter { frame } {
# global all
# puts "$frame: [measure center $all weight mass]"
# }
# mol load psf alanin.psf
# set all [atomselect top all]
# $all global
# bigdcd mycenter alanin.dcd
#


See the line where it writes to stdout: puts "$frame: [measure center $all....

I would like to write that output to a file rather than screen. Any
suggestion how I could do that *without* opening/closing file in
mycenter itself?

cheers

Sascha T.

Bryan Oakley

unread,
Mar 2, 2005, 4:42:59 PM3/2/05
to
Sascha T. wrote:
> # Example 1:
> # This computes the center of mass for each frame in the DCD file.
> #
> # proc mycenter { frame } {
> # global all
> # puts "$frame: [measure center $all weight mass]"
> # }
> # mol load psf alanin.psf
> # set all [atomselect top all]
> # $all global
> # bigdcd mycenter alanin.dcd
> #
>
>
> See the line where it writes to stdout: puts "$frame: [measure center $all....
>
> I would like to write that output to a file rather than screen. Any
> suggestion how I could do that *without* opening/closing file in
> mycenter itself?

proc mycenter { f frame } {
global all
puts $f "$frame: [measure center $all weight mass]"
}
...
set f [open "output.txt" w]
mycenter $f $frame

Darren New

unread,
Mar 2, 2005, 5:18:41 PM3/2/05
to

It looks like bigdcd actually invokes mycenter with one argument. Hence,
you'd need to do

proc mycenter { frame } {
global all
global filehandle
puts $filehandle "$frame: ..."
}

set filehandle [open xyz w]
mol load ...


set all [atomselect top all]

$all global
bigdcd mycenter alanin.dcd
close $filehandle

Open it outside, get to it via "global", close it when you're done.

HTH


--
Darren New / San Diego, CA, USA (PST)
He had a name like someone sneezing with
a mouth full of alphabet soup...

Sascha T.

unread,
Mar 3, 2005, 3:57:02 AM3/3/05
to

Hi!

Thanks to all for your suggestions so far, I hope you
will show a little more kind patience with me.

I did both, what was suggested by Darran and
by Bryan. No matter how, I always get this error:


bigdcd aborting at frame 1
can not find channel named "file16"

which obviosly comes from line
--------------------------------
if { [catch {uplevel #0 $bigdcdproc...
--------------------------------

I tested a minimal script:
---------------------------------
#!/usr/bin/tclsh
proc pmain { script args } {
uplevel #0 $script $args
}
proc pcustom { var } {
global all
global handle
puts $handle $var;
}
set handle [open tt.dat w];
set var "Hello";
pmain pcustom $var
close $handle
-----------------------------------------

which actually works! Anyway, this is only part of how that
bigdcd.tcl script works. I guess it must have something to
do with this lines in bigdcd.tcl:
-----------------------------------------
uplevel #0 trace variable vmd_frame w bigdcd_callback
-----------------------------------------

To me, it is not quite clear what happens there. What does
this "uplevel" line do exactly? Actually, I do *have* looked
up, what "uplevel" does, but I did not find and hint on what
"trace variable ...."-syntax does.


Sincerly and, again, thanks your four patience

Sascha T.


Darren New

unread,
Mar 3, 2005, 11:57:31 AM3/3/05
to
Sascha T. wrote:
> uplevel #0 trace variable vmd_frame w bigdcd_callback

"uplevel #0" means basically take the rest of the command and run it at
the top of the callstack. In other words, invoke


"trace variable vmd_frame w bigdcd_callback"

as if you'd typed it at the main prompt, rather than as if you
called it from inside some other procedure. (It's a very Tcl kind of
thing. The only language I know that lets you do that.) Basically, it
gets rid of all the local variables, all the functions you're nested
inside, etc.

"trace variable vmd_frame w bigdcd_callback"

means whenever you write (the "w" there) to the variable vmd_frame, call
the bigdcd_callback procedure. Kind of like insert/update triggers in
SQL, if you know about that, or the "Observer" pattern, sorta.

Of course, since this is being called at uplevel #0, the vmd_frame is a
global variable. I'm not sure how that variable gets set.

Since all this is uplevel #0'ed, I expect that what's happening is the


set handle [open tt.dat w]

is actually happening inside some proceudre, so your "handle" variable
isn't global. Try the same test again with the line
global handle
inserted just before the
set handle [open ...]
line. That way, you're sure that both "handle" variables are the same.

0 new messages