1

I've been trying to run MMPBSA calculations using CAFE, however, when I use -pb_rad charmm. VMD prints the following error when it begins to run PB calculations: "Unmatched open quote in list "

I suspect that the error originates from the following section of the cafe_mmpsa script:

 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"
}

However I need help identifying the part that needs correction. I am hoping someone can help me or recommend any other PB Radius I could use.

Thank you, Javier

  • Do any of the values you append to `ar_args` have quotes in them? (That whole bit can be rewritten to be better and avoid the eval unless you're using an ancient and long outdated version of tcl) – Shawn Oct 08 '21 at 02:38
  • Yes, they have. Even though they are taken into account in other sections of the script, I am willing to edit those. – Javier Wong Oct 08 '21 at 02:58
  • https://wiki.tcl-lang.org/page/eval and https://wiki.tcl-lang.org/page/Tcl+Quoting have some relevant discussion. – Shawn Oct 08 '21 at 04:38

1 Answers1

1

You're building a string that is a tcl command, and evaluating it. Part of what you're doing is adding quotes around arguments, which handles things like spaces in the arguments, but if they themselves have quotes, you have to take special action to avoid issues.

A demonstration of the sort of thing you're likely running into:

% 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

In modern versions of tcl, the easy way to get around that is to build a list of arguments, not a string, and use {*} 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

Some quick googling suggests that this VMD program is still using tcl 8.4.1, which was released in... 2002. Just a little bit outdated.

Luckily, the Tcler's Wiki page on eval still demonstrates the historical alternative to {*} that builds a list and uses that as the argument to eval, relying on stringification to handle quoting issues:

% 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"}

or, adapting to your code:

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
Shawn
  • 47,241
  • 3
  • 26
  • 60
  • Actually, if you build a proper list (with `list` or `lappend` or …) then `eval` will work just fine on it, and will actually be pretty quick; the Tcl code tracks if lists are made properly, and if so it skips all the parsing in `eval` and goes straight to command dispatch. – Donal Fellows Oct 08 '21 at 07:56
  • @DonalFellows That's what the last version does, yes. – Shawn Oct 08 '21 at 21:48
  • It worked! Thank you very much. I just had to remove the last eval from your answer – Javier Wong Oct 09 '21 at 00:15