Tcl 列表中不匹配的开引号。 VMD MMPBSA 错误

Tcl Unmatched open quote in list. VMD MMPBSA error

我一直在尝试使用 CAFE 运行 MMPBSA 计算,然而,当我使用 -pb_rad charmm 时。 VMD 在开始 运行 PB 计算时打印以下错误: “列表中不匹配的开引号”

我怀疑错误源自 cafe_mmpsa 脚本的以下部分:

 if { $pb } {
    show -info "Calculating the PB term"
    set start [clock seconds]

    # assign radii
    set ar_args "$currmol $pb_rad"
    if { $pb_rad eq "charmm" } {
        foreach p $parfile { append ar_args " \"$p\"" }
    } elseif { $pb_rad eq "parm7" } {
        append ar_args " \"$topfile\""
    }
    eval assign_radii $ar_args

    set com_pb_list [calc_pb $currmol com $comsel]

    if { $recsel ne "" } {
        set rec_pb_list [calc_pb $currmol rec $recsel]
    }

    if { $ligsel ne "" } {
        set lig_pb_list [calc_pb $currmol lig $ligsel]
    }

    foreach { d h m s } [timer $start] { break }
    show -info "It took $d days $h hrs $m min $s sec"
}

但是我需要帮助来确定需要更正的部分。我希望有人可以帮助我或推荐我可以使用的任何其他 PB Radius。

谢谢哈维尔

您正在构建一个作为 tcl 命令的字符串,并对其进行评估。您正在做的部分工作是在参数周围添加引号,它处理参数中的空格之类的事情,但如果它们本身有引号,您必须采取特殊措施来避免出现问题。

演示您可能 运行 喜欢的东西:

% set demo "list "
list
% append demo "\"foo bar\""
list "foo bar"
% set x "another \"string\""
another "string"
% append demo " \"$x\""
list "foo bar" "another "string""
% eval $demo
extra characters after close-quote

tcl 的现代版本中,解决这个问题的简单方法是构建一个 参数列表 ,而不是字符串,然后使用 {*} to expand it:

set ar_args [list $currmol $pb_rad]
if { $pb_rad eq "charmm" } {
    lappend ar_args {*}$parfile
} elseif { $pb_rad eq "parm7" } {
    lappend ar_args $topfile
}
assign_radii {*}$ar_args

一些快速谷歌搜索表明这个 VMD program is still using tcl 8.4.1,发布于... 2002 年。只是有点过时了。

幸运的是,Tcler's Wiki page on eval 仍然展示了 {*} 的历史替代方案,它构建一个列表并将其用作 eval 的参数,依靠字符串化来处理引用问题:

% set demo [list list]
list
% lappend demo "\"foo bar\""
list {"foo bar"}
% lappend demo $x
list {"foo bar"} {another "string"}
% eval $demo
{"foo bar"} {another "string"}

或者,适应您的代码:

set ar_args [list assign_radii $currmol $pb_rad]
if { $pb_rad eq "charmm" } {
    # foreach p $parfile { lappend ar_args $p }
    eval [linsert $parfile 0 lappend ar_args] ;# Avoid a loop
} elseif { $pb_rad eq "parm7" } {
    lappend ar_args $topfile
}
eval $ar_args