Tcl error : wrong # args: should be "set varName ?newValue?"

Merly picture Merly · Dec 4, 2015 · Viewed 11.6k times · Source

I tried to run the following Tcl script and got the error: wrong # args: should be "set varName ?newValue?"

What does this mean?

Note: The script includes terms specific to VMD program, such as mol and resid. Please disregard them.

#count water molecules between chain A and chain C or between #chain B and chain C


set input_file [open ./name_3_pdb_chain_renamed.dat r]

set data [read $input_file]
set data [split $data "\n"]
close $input_file

set chain_list [lindex $data 0]

cd 7_count_water

set outfile [open count_water3.dat w]


set chain_compare ""

set pdblen [llength $chain_list]

for {set i 0} {$i<$pdblen} {incr i} {
    set pid [lindex [lindex $chain_list $i] 0]

    set len [llength [lindex $chain_list $i]]

    mol load pdb ../2_chain_rename/${pid}_chain_revised.pdb


    mol modstyle 0 top NewCartoon



    if {$len==4} {
        set chain_compare [lappend chain_compare $pid]
    }

    set 11 [atomselect top all]

    set mid [$11 molid]

    mol delete $mid
}




set lll [llength $chain_compare]

for {set j 0} {$j< $lll} {incr j} {

    set pid [lindex $chain_compare $j]

    mol load pdb ../2_chain_rename/${pid}_chain_revised.pdb

    set 11 [atomselect top "chain A and name CA"]

    set res_len [llength [$11 get resid]]

    set res_id [$11 get resid]

    #residue length for chain C
    set ag [atomselect top "chain C and name CA"]
    set ag_len [llength [$ag get resid]]
    set ag_id [$ag get resid]


    #loop water between chain A and chain C
    for {set k 0} {$k<$res_len} {incr k} {

        set water_around_a [atomselect top "{resname HOH and {within 5.0 of {chain A and resid [lindex $res_id $k]} and {within 5.0 of chain C}}} "]


        set water_around_a_resid [$water_around_a get resid]
        set water_around_a_resname [$water_around_a get resname]

        #loop antigen residues around water
        for {set g 0} {$g < $ag_len} {incr g} {

          set ag_around_water [atomselect top "{chain C and resid [lindex $ag_id $g] and {within 5.0 of {resname HOH and {within 5.0 of {chain A and resid [lindex $res_id $k]}}}}} "]

            set ag_around_water resid [$ag_around_water get resid]

            set ag_around_water_resname [$ag_around_water get resname]


            puts $outfile "$pid [lindex $res_id $k] [lindex [$11 get resname] $k] $ag_around_water_resname A: $water_around_a_resname"
       }
    }



    set b11 [atomselect top "chain B and name CA"]

    set b_res_len [llength [$b11 get resid]]

    set b_res_id [$b11 get resid]

    #residue length for chain C
    set ag [atomselect top "chain C and name CA"]
    set ag_len [llength [$ag get resid]]
    set ag_id [$ag get resid]

    for {set k 0} {$k<$res_len} {incr k} {


        set water_around_b [atomselect top "{resname HOH and {within 5.0 of {chain B and resid [lindex $b_res_id $k]} and {within 5.0 of chain C}}} "]

        set water_around_b_resid [$water_around_b get resid]
        set water_around_b_resname [$water_around_b get resname]

        #loop antigen residues around water
        for {set g 0} {$g < $ag_len} {incr g} {

             set ag_around_water [atomselect top "{chain C and resid [lindex $ag_id $g] and {within 5.0 of {resname HOH and {within 5.0 of {chain B and resid [lindex $b_res_id $k]}}}}} "]


            set ag_around_water resid [$ag_around_water get resid]

            set ag_around_water_resname [$ag_around_water get resname]

            puts $outfile "$pid [lindex $b_res_id $k] [lindex [$b11 get resname] $k] $ag_around_water_resname A: $water_around_b_resname"


        }

    }

}


close $outfile

cd ..

Thank you

Answer

Donal Fellows picture Donal Fellows · Dec 4, 2015

That message:

wrong # args: should be "set varName ?newValue?"

is a standard error thrown when a built-in command gets the wrong number of arguments to evaluate. In this case, it's coming from the set command, and indicates that you've either said set on its own, or given more than two further arguments to it.

If you examine the stack trace (usually printed with the error message when using standard tclsh, though it's changeable with user code) then you'll get told where the problem happened. However, in this case we can look through and see that this line near the bottom of the script:

            set ag_around_water resid [$ag_around_water get resid]

has what appears to be a space instead of an underscore in the variable name. Now, spaces are legal in variable names, but then the variable name needs to be quoted, and that can get a bit annoying. It's usually best to avoid using them like that. Without quoting, Tcl doesn't know that that's meant to be one word; the generic parsing layer decides there's really four words there (set, ag_around_water, resid and the complex [$ag_around_water get resid]) and tells set to deal with that, which it doesn't like.

Remember, Tcl's generic syntactic parsing happens first, before command arguments are interpreted semantically. Always.