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.
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 |
|______________________________________________________________________|
> 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.
proc mycenter { f frame } {
global all
puts $f "$frame: [measure center $all weight mass]"
}
...
set f [open "output.txt" w]
mycenter $f $frame
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...
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.
"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.