Проблема с записью в файл в TCL-скрипте
Покажи, что за скрипт.
вот эта часть относится к записи в файл. Но он работает без ошибок, пока размер output файла не превышает определенный размер.
set outputfile [open all.dat w]
set i 3
puts -nonewline $outputfile "frame "
while {$i <= $hb+2} {
puts -nonewline $outputfile "$ldonatom($i)*$laccatom($i) "
incr i
}
puts $outputfile " "
set j 0
set num_frames [molinfo top get numframes]
for {set n 0} {$n < $num_frames} {incr n} {
puts -nonewline $outputfile "$n "
hbonds -sel1 [atomselect top "resid $ldon and not water"] -sel2 [atomselect top "resid $lacc and not water"] -writefile yes -upsel no -frames $n:$n -DA D -dist 3.1 -ang 30 -plot no -polar yes -type unique -detailout tmp.dat
set inputfile [open tmp.dat r]
set i 3
while {$i <= $hb+2} {
set count 0
seek $inputfile 0 start
while {[gets $inputfile line] >= 0} {
incr j
if {$j>2} then {
set occup($j) [split $line " "]
if {[lindex $occup($j) 0] eq $ldonatom($i) && [lindex $occup($j) 2] eq $laccatom($i)} then {
incr count
}
}
}
puts -nonewline $outputfile "$count "
incr i
}
close $inputfile
puts $outputfile " "
}
close $outputfile
потому что другой мой скрипт без проблем пишет файлы таких размеров...
я много раз обращаюсь к открытому для записи файлу. это может как-то влиять?
ты главное проверь что ты не открываешь его тыщу раз
if {[lindex $occup($j) 0] eq $ldonatom($i) && [lindex $occup($j) 2] eq $laccatom($i)} then {в Tcl нет команды then, если только синтаксис не был подхачен
incr count
}
надо так
if {condition} {
do something
}
похоже, что глючит программа, внутри которой расположился Tcl
можно попробовать вырезать все обращения к не-Tcl-library командам, таким как atomselect, molinfo, hbonds (заменить их фейками какими-нибудь) и проверить работоспособность
в Tcl нет команды then, если только синтаксис не был подхаченТам есть syntactic sugar у команды if.
А глючит действительно скорее всего внешняя программа или откуда там берутся эти команды.
Там есть syntactic sugar у команды if.точно. никогда не использовал его
но это решило проблему не полностью - теперь вылетает при размере файла 520192 bytes.
Может быть есть какие-то внутренние ограничения на количество элементов в списке или количество переменных, которое может храниться в памяти?.....
Я нашла ошибку в скрипте
теперь вылетает при размере файла 520192 bytes.ты не нашла ошибку
Пользуюсь программой, в которую встроен TCLо какой программе речь? какая версия ?
TK-консоль: tkcon v2.3, Using: Tcl v8.5.6 / Tk v8.5.6
Программа VMD1.8.7 - если это чем-то поможет.
И все таки бывают ли внутренние ограничения на количество переменных? Если бывают, то о числах каких порядков идет речь?
set occup($j) [split $line " "]Массив съедает всю память? Что там в $line вообще?
Величина i и j примерно 200
величина n где-то 3000-5000
и я уже заменила occup($j) на occup - так чтобы не создавать большой массив, а записывать временную информацию все время в одну переменную.
после обнуления j с матрицей occup($j) - скрипт стал дольше работать
после обнуления j и замены матрицы на переменную occup - вообще ничего не изменилось - скрипт вылетает в тот же самый момент.
сейчас скрипт выглядит так:
set outputfile [open $nf-all.dat w]
set i 3
puts -nonewline $outputfile "frame "
while {$i <= $hb+2} {
puts -nonewline $outputfile "$ldonatom($i)*$laccatom($i) "
incr i
}
puts $outputfile " "
set j 0
set num_frames [molinfo top get numframes]
for {set n 0} {$n < $num_frames} {incr n} {
puts -nonewline $outputfile "$n "
hbonds -sel1 [atomselect top "resid $ldon and not water"] -sel2 [atomselect top "resid $lacc and not water"] -writefile yes -upsel no -frames $n:$n -DA D -dist $dist -ang $ang -plot no -polar yes -type unique -detailout tmp.dat
set inputfile [open tmp.dat r]
set i 3
while {$i <= $hb+2} {
set count 0
set j 0
seek $inputfile 0 start
while {[gets $inputfile line] >= 0} {
incr j
if {$j>2} then {
set occup [split $line " "]
if {[lindex $occup 0] eq $ldonatom($i) && [lindex $occup 2] eq $laccatom($i)} then {
incr count
}
}
}
puts -nonewline $outputfile "$count "
incr i
}
close $inputfile
puts $outputfile " "
}
close $outputfile
hbonds -sel1 [atomselect top "resid $ldon and not water"] -sel2 [atomselect top "resid $lacc and not water"] -writefile yes -upsel no -frames $n:$n -DA D -dist $dist -ang $ang -plot no -polar yes -type unique -detailout tmp.dat
скрипт не виснет.
hbonds - это встроенный скрипт...
Если предположить, что после 1000 обращений к нему, скажем кончается память или превышается лимит чего-нибудь, можно как-нибудь все "обнулять" в процессе работы моего скрипта?
Я правильно понимаю, что объём используемой процессом памяти резко растёт, потом возникает runtime error?
Upd. Написанное ниже уже неактуально, ибо вы это сделали.
Попробуйте локализовать проблему: поотключать вывод в файл, выключить часть циклов.
Было бы ещё интересно собрать vmd с debug info, чтобы посмотреть, где падает.
Дайте описание atomselect и hbonds.
а как на счет "обнуления"? такое вообще можно сделать?
а какое именно нужно описание? у этого скрипта открытый код, но для меня он слишком сложный.
Обнуление - можно с помощью interp делать дочерние интерпретаторы, в них исполнять код, потом их удалять. Но это уже извращения пошли.
А hbonds в других скриптах используется? Если да, то там память кончается?
Если запускать последовательно маленькие, то они прекрасно работают, а одна большая не работает (
Конечно, можно написать скрипт так, чтобы первая задача начинала запись в output файл, а остальные продолжали - но это как-то странно.
Здесь документация по всем плагинам и есть ссылка на страничку с HBonds (раздел Analysis но там ничего нет интересного. Вероятно, Plugin Developer Documentation: - это то, что нужно.
VMD plugins
А внизу есть ссылка для скачивания. Но если нужно, могу прислать отдельно код к hbonds.
Вероятно, это и есть способ очищать память - заканчивать работу процедуры и начинать заново.
В любом случае ничего лучше в голову не приходит
Спасибо всем за помощь!
Оставить комментарий
salex50
Пользуюсь программой, в которую встроен TCL (TK-консоль: tkcon v2.3, Using: Tcl v8.5.6 / Tk v8.5.6).Я написала скрипт, который записывает данные в файл. При размере файла 23162 bytes - программа вылетает с ошибкой "Microsoft Visual C++ Runtime library. Runtime error!" . В командной строке появляется строчка "unable to alloc 24 bytes". (ХР)
На другом компьютере скрипт так же вылетает, но уже при размере файла 225073 bytes, и при этом ничего не пишет. (Vista)
Кто-нибудь сталкивался с таким? и как можно с этим бороться?