Mercurial > repos > chemteam > vmd_hbonds
comparison hbonds/hbonds.tcl @ 0:8aa5e465b043 draft default tip
"planemo upload for repository https://github.com/thatchristoph/vmd-cvs-github/tree/master/vmd commit a48d8046b8d9c8093daaa35bfedafa62fc5c5fd9"
author | chemteam |
---|---|
date | Thu, 24 Oct 2019 07:00:24 -0400 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:8aa5e465b043 |
---|---|
1 # hbonds - finds hydrogen bonds in a trajectory | |
2 # | |
3 # Authors: | |
4 # JC Gumbart (gumbart@ks.uiuc.edu) | |
5 # with the detailed hbond calculations contributed by Dong Luo (us917@yahoo.com) | |
6 # also with thanks to Leo Trabuco and Elizabeth Villa whose salt bridge plugin provided the foundation for this one | |
7 # | |
8 # $Id: hbonds.tcl,v 1.9 2013/04/15 15:50:16 johns Exp $ | |
9 # | |
10 | |
11 # | |
12 # TODO: | |
13 # | |
14 # - show hbonds in the gui? | |
15 # | |
16 | |
17 package provide hbonds 1.2 | |
18 | |
19 namespace eval ::hbonds:: { | |
20 namespace export hbonds | |
21 | |
22 variable defaultAng 20 | |
23 variable defaultDist 3.0 | |
24 variable defaultWrite 0 | |
25 variable defaultFrames "all" | |
26 variable defaultOutdir | |
27 variable defaultLogFile "" | |
28 variable defaultUpdateSel 1 | |
29 variable defaultPlot 1 | |
30 variable defaultPolar 0 | |
31 variable debug 0 | |
32 variable currentMol none | |
33 variable atomselectText1 "protein" | |
34 variable atomselectText2 "" | |
35 variable defaultDatFile "hbonds.dat" | |
36 variable statusMsg "" | |
37 | |
38 variable defaultDetailFile "hbonds-details.dat" | |
39 variable defaultDetailType none | |
40 variable defaultDA both | |
41 } | |
42 | |
43 proc ::hbonds::hbonds_gui {} { | |
44 variable defaultDist | |
45 variable defaultAng | |
46 variable defaultWrite | |
47 variable defaultPlot | |
48 variable defaultFrames | |
49 variable defaultLogFile | |
50 variable defaultUpdateSel | |
51 variable defaultDatFile | |
52 variable defaultDetailFile | |
53 variable defaultDetailType | |
54 variable defaultPolar | |
55 variable w | |
56 variable defaultDA | |
57 | |
58 variable nullMolString "none" | |
59 variable currentMol | |
60 variable molMenuButtonText | |
61 | |
62 trace add variable [namespace current]::currentMol write [namespace code { | |
63 variable currentMol | |
64 variable molMenuButtonText | |
65 if { ! [catch { molinfo $currentMol get name } name ] } { | |
66 set molMenuButtonText "$currentMol: $name" | |
67 } else { | |
68 set molMenuButtonText $currentMol | |
69 } | |
70 # } ] | |
71 set currentMol $nullMolString | |
72 variable usableMolLoaded 0 | |
73 | |
74 variable atomselectText1 "protein" | |
75 variable atomselectText2 "" | |
76 | |
77 # Add traces to the checkboxes, so various widgets can be disabled | |
78 # appropriately | |
79 if {[llength [trace info variable [namespace current]::atomselectText2]] == 0} { | |
80 trace add variable [namespace current]::atomselectText2 write ::hbonds::sel2_state | |
81 } | |
82 | |
83 if {[llength [trace info variable [namespace current]::guiWrite]] == 0} { | |
84 trace add variable [namespace current]::guiWrite write ::hbonds::write_state | |
85 } | |
86 | |
87 if {[llength [trace info variable [namespace current]::guiType]] == 0} { | |
88 trace add variable [namespace current]::guiType write ::hbonds::write_state | |
89 } | |
90 | |
91 | |
92 # If already initialized, just turn on | |
93 if { [winfo exists .hbonds] } { | |
94 wm deiconify $w | |
95 return | |
96 } | |
97 set w [toplevel ".hbonds"] | |
98 wm title $w "Hydrogen Bonds" | |
99 wm resizable $w 0 0 | |
100 | |
101 variable statusMsg "Ready." | |
102 variable guiDist $defaultDist | |
103 variable guiAng $defaultAng | |
104 variable guiWrite $defaultWrite | |
105 variable guiPlot $defaultPlot | |
106 variable guiFrames $defaultFrames | |
107 variable guiLogFile $defaultLogFile | |
108 variable guiUpdateSel $defaultUpdateSel | |
109 variable guiDatFile $defaultDatFile | |
110 variable guiPolar $defaultPolar | |
111 variable guiType $defaultDetailType | |
112 variable guiDetailFile $defaultDetailFile | |
113 variable guiOutdir [pwd] | |
114 variable guiDA $defaultDA | |
115 | |
116 # Add a menu bar | |
117 frame $w.menubar -relief raised -bd 2 | |
118 pack $w.menubar -padx 1 -fill x | |
119 | |
120 menubutton $w.menubar.help -text Help -underline 0 -menu $w.menubar.help.menu | |
121 # XXX - set menubutton width to avoid truncation in OS X | |
122 $w.menubar.help config -width 5 | |
123 | |
124 # Help menu | |
125 menu $w.menubar.help.menu -tearoff no | |
126 $w.menubar.help.menu add command -label "About" \ | |
127 -command {tk_messageBox -type ok -title "About Hbonds" \ | |
128 -message "The H Bonds plugin searches for hydrogen bonds (subject to user criteria) within one selection or between two selections and then outputs the number of bonds as a function of time."} | |
129 $w.menubar.help.menu add command -label "Help..." \ | |
130 -command "vmd_open_url [string trimright [vmdinfo www] /]/plugins/hbonds" | |
131 | |
132 pack $w.menubar.help -side right | |
133 | |
134 ############## frame for input options ################# | |
135 labelframe $w.in -bd 2 -relief ridge -text "Input options" -padx 1m -pady 1m | |
136 | |
137 set f [frame $w.in.all] | |
138 set row 0 | |
139 | |
140 grid [label $f.mollable -text "Molecule: "] \ | |
141 -row $row -column 0 -sticky e | |
142 grid [menubutton $f.mol -textvar [namespace current]::molMenuButtonText \ | |
143 -menu $f.mol.menu -relief raised] \ | |
144 -row $row -column 1 -columnspan 3 -sticky ew | |
145 menu $f.mol.menu -tearoff no | |
146 incr row | |
147 | |
148 fill_mol_menu $f.mol.menu | |
149 trace add variable ::vmd_initialize_structure write [namespace code " | |
150 fill_mol_menu $f.mol.menu | |
151 # " ] | |
152 | |
153 grid [label $f.sellabel1 -text "Selection 1 (Required): "] \ | |
154 -row $row -column 0 -sticky e | |
155 grid [entry $f.sel1 -width 50 \ | |
156 -textvariable [namespace current]::atomselectText1] \ | |
157 -row $row -column 1 -columnspan 3 -sticky ew | |
158 incr row | |
159 | |
160 grid [label $f.sellabel2 -text "Selection 2 (Optional): "] \ | |
161 -row $row -column 0 -sticky e | |
162 grid [entry $f.sel2 -width 50 \ | |
163 -textvariable [namespace current]::atomselectText2] \ | |
164 -row $row -column 1 -columnspan 3 -sticky ew | |
165 incr row | |
166 | |
167 grid [label $f.selwarning -text "NOTE: if sel1 and sel2 overlap, hbonds output is unreliable!"] \ | |
168 -row $row -column 1 -columnspan 2 -sticky w | |
169 incr row | |
170 | |
171 grid [label $f.frameslabel -text "Frames: "] \ | |
172 -row $row -column 0 -sticky e | |
173 grid [entry $f.frames -width 10 \ | |
174 -textvariable [namespace current]::guiFrames] \ | |
175 -row $row -column 1 -sticky ew | |
176 grid [label $f.framescomment -text "(now, all, b:e, or b:s:e)"] \ | |
177 -row $row -column 2 -columnspan 2 -sticky w | |
178 incr row | |
179 | |
180 ### -row $row -column 0 -columnspan 4 -sticky w | |
181 | |
182 ## -row $row -column 1 -columnspan 4 -sticky e | |
183 | |
184 grid [checkbutton $f.check -text \ | |
185 "Update selections every frame?" \ | |
186 -variable [namespace current]::guiUpdateSel] \ | |
187 -row $row -column 0 -sticky w | |
188 grid [checkbutton $f.check2 -text \ | |
189 "Only polar atoms (N, O, S, F)?" \ | |
190 -variable [namespace current]::guiPolar] \ | |
191 -row $row -column 1 -sticky e | |
192 incr row | |
193 | |
194 pack $f -side top -padx 0 -pady 0 -expand 1 -fill none | |
195 | |
196 set f [frame $w.in.cutoffs] | |
197 set row 0 | |
198 | |
199 #### donor/acceptor check #### | |
200 grid [label $f.typelabel1 -text "Selection 1 is the: "] \ | |
201 -row $row -column 0 -sticky e | |
202 grid [radiobutton $f.type11 -text "Donor" -state disabled \ | |
203 -variable [namespace current]::guiDA -value "D"] \ | |
204 -row $row -column 1 -sticky w | |
205 grid [radiobutton $f.type12 -text "Acceptor" -state disabled \ | |
206 -variable [namespace current]::guiDA -value "A"] \ | |
207 -row $row -column 2 -sticky w | |
208 grid [radiobutton $f.type13 -text "Both" \ | |
209 -variable [namespace current]::guiDA -value "both"] \ | |
210 -row $row -column 3 -sticky w | |
211 incr row | |
212 | |
213 grid [label $f.ondistlabel -text "Donor-Acceptor distance (A): "] \ | |
214 -row $row -column 0 -sticky e | |
215 grid [entry $f.ondist -width 5 \ | |
216 -textvariable [namespace current]::guiDist] \ | |
217 -row $row -column 1 -columnspan 3 -sticky ew | |
218 incr row | |
219 | |
220 grid [label $f.comdistlabel -text "Angle cutoff (degrees): "] \ | |
221 -row $row -column 0 -sticky e | |
222 grid [entry $f.comdist -width 5 \ | |
223 -textvariable [namespace current]::guiAng] \ | |
224 -row $row -column 1 -columnspan 3 -sticky ew | |
225 incr row | |
226 | |
227 #### hbonds type define #### | |
228 grid [label $f.typelabel -text "Calculate detailed info for: "] \ | |
229 -row $row -column 0 -sticky e | |
230 grid [radiobutton $f.type1 -text "None" \ | |
231 -variable [namespace current]::guiType -value "none"] \ | |
232 -row $row -column 1 -sticky ew | |
233 grid [radiobutton $f.type2 -text "All hbonds" \ | |
234 -variable [namespace current]::guiType -value "all"] \ | |
235 -row $row -column 2 -sticky ew | |
236 grid [radiobutton $f.type3 -text "Residue pairs" \ | |
237 -variable [namespace current]::guiType -value "pair"] \ | |
238 -row $row -column 3 -sticky ew | |
239 grid [radiobutton $f.type4 -text "Unique hbond" \ | |
240 -variable [namespace current]::guiType -value "unique"] \ | |
241 -row $row -column 4 -sticky ew | |
242 incr row | |
243 | |
244 pack $f -side top -padx 0 -pady 5 -expand 1 -fill x | |
245 | |
246 pack $w.in -side top -pady 5 -padx 3 -fill x -anchor w | |
247 | |
248 ############## frame for output options ################# | |
249 labelframe $w.out -bd 2 -relief ridge -text "Output options" -padx 1m -pady 1m | |
250 | |
251 set f [frame $w.out.all] | |
252 set row 0 | |
253 | |
254 grid [checkbutton $f.check1 -text \ | |
255 "Plot the data with MultiPlot?" \ | |
256 -variable [namespace current]::guiPlot] \ | |
257 -row $row -column 0 -columnspan 2 -sticky w | |
258 incr row | |
259 grid [label $f.label -text "Output directory: "] \ | |
260 -row $row -column 0 -columnspan 1 -sticky e | |
261 grid [entry $f.entry -textvariable [namespace current]::guiOutdir \ | |
262 -width 35 -relief sunken -justify left -state readonly] \ | |
263 -row $row -column 1 -columnspan 1 -sticky e | |
264 grid [button $f.button -text "Choose" -command "::hbonds::getoutdir"] \ | |
265 -row $row -column 2 -columnspan 1 -sticky e | |
266 incr row | |
267 grid [label $f.loglabel -text "Log file? "] \ | |
268 -row $row -column 0 -sticky e | |
269 grid [entry $f.logname -width 30 \ | |
270 -textvariable [namespace current]::guiLogFile] \ | |
271 -row $row -column 1 -columnspan 2 -sticky ew | |
272 incr row | |
273 | |
274 grid [checkbutton $f.check2 -text \ | |
275 "Write output to files?" \ | |
276 -variable [namespace current]::guiWrite] \ | |
277 -row $row -column 0 -columnspan 3 -sticky w | |
278 incr row | |
279 grid [label $f.fbdata -text "Frame/bond data? " -state disabled] \ | |
280 -row $row -column 0 -sticky e | |
281 grid [entry $f.datname -width 30 \ | |
282 -textvariable [namespace current]::guiDatFile -state disabled] \ | |
283 -row $row -column 1 -columnspan 2 -sticky ew | |
284 incr row | |
285 grid [label $f.detdata -text "Detailed hbond data? " -state disabled] \ | |
286 -row $row -column 0 -sticky e | |
287 grid [entry $f.detname -width 30 \ | |
288 -textvariable [namespace current]::guiDetailFile -state disabled] \ | |
289 -row $row -column 1 -columnspan 2 -sticky ew | |
290 | |
291 | |
292 pack $f -side left -padx 0 -pady 5 -expand 1 -fill x | |
293 pack $w.out -side top -pady 5 -padx 3 -fill x -anchor w | |
294 | |
295 ############## frame for status ################# | |
296 labelframe $w.status -bd 2 -relief ridge -text "Status" -padx 1m -pady 1m | |
297 | |
298 set f [frame $w.status.all] | |
299 label $f.label -textvariable [namespace current]::statusMsg | |
300 pack $f $f.label | |
301 pack $w.status -side top -pady 5 -padx 3 -fill x -anchor w | |
302 | |
303 set f [frame $w.control] | |
304 button $f.button -text "Find hydrogen bonds!" -width 20 \ | |
305 -command {::hbonds::hbonds -gui 1 -dist $::hbonds::guiDist -ang $::hbonds::guiAng -writefile $::hbonds::guiWrite -outdir $::hbonds::guiOutdir -frames $::hbonds::guiFrames -log $::hbonds::guiLogFile -upsel $::hbonds::guiUpdateSel -plot $::hbonds::guiPlot -outfile $::hbonds::guiDatFile -polar $::hbonds::guiPolar -type $::hbonds::guiType -detailout $::hbonds::guiDetailFile -DA $::hbonds::guiDA } | |
306 | |
307 pack $f $f.button | |
308 | |
309 } | |
310 | |
311 # Adapted from pmepot gui | |
312 proc ::hbonds::fill_mol_menu {name} { | |
313 | |
314 variable usableMolLoaded | |
315 variable currentMol | |
316 variable nullMolString | |
317 $name delete 0 end | |
318 | |
319 set molList "" | |
320 foreach mm [array names ::vmd_initialize_structure] { | |
321 if { $::vmd_initialize_structure($mm) != 0} { | |
322 lappend molList $mm | |
323 $name add radiobutton -variable [namespace current]::currentMol \ | |
324 -value $mm -label "$mm [molinfo $mm get name]" | |
325 } | |
326 } | |
327 | |
328 #set if any non-Graphics molecule is loaded | |
329 if {[lsearch -exact $molList $currentMol] == -1} { | |
330 if {[lsearch -exact $molList [molinfo top]] != -1} { | |
331 set currentMol [molinfo top] | |
332 set usableMolLoaded 1 | |
333 } else { | |
334 set currentMol $nullMolString | |
335 set usableMolLoaded 0 | |
336 } | |
337 } | |
338 | |
339 } | |
340 | |
341 proc ::hbonds::getoutdir {} { | |
342 variable guiOutdir | |
343 | |
344 set newdir [tk_chooseDirectory \ | |
345 -title "Choose output directory" \ | |
346 -initialdir $guiOutdir -mustexist true] | |
347 | |
348 if {[string length $newdir] > 0} { | |
349 set guiOutdir $newdir | |
350 } | |
351 } | |
352 | |
353 proc hbonds { args } { return [eval ::hbonds::hbonds $args] } | |
354 proc hbondsgui { } { return [eval ::hbonds::hbonds_gui] } | |
355 | |
356 proc ::hbonds::hbonds_usage { } { | |
357 | |
358 variable defaultDist | |
359 variable defaultAng | |
360 variable defaultWrite | |
361 variable defaultPlot | |
362 variable defaultFrames | |
363 variable defaultDatFile | |
364 variable defaultDetailType | |
365 variable defaultDA | |
366 | |
367 puts "Usage: hbonds -sel1 <atom selection> <option1> <option2> ..." | |
368 puts "Options:" | |
369 puts " -sel2 <atom selection> (default: none)" | |
370 puts " NOTE: if sel1 and sel2 overlap, hbonds output is unreliable!" | |
371 if $defaultWrite { | |
372 puts " -writefile <yes|no> (default: yes)" | |
373 } else { | |
374 puts " -writefile <yes|no> (default: no)" | |
375 } | |
376 | |
377 puts " -upsel <yes|no> (update atom selections every frame? default: yes)" | |
378 puts " -frames <begin:end> or <begin:step:end> or all or now (default: $defaultFrames)" | |
379 puts " -dist <cutoff distance between donor and acceptor> (default: $defaultDist)" | |
380 puts " -ang <angle cutoff> (default: $defaultAng)" | |
381 puts " -plot <yes|no> (plot with MultiPlot, default: yes)" | |
382 puts " -outdir <output directory> (default: current)" | |
383 puts " -log <log filename> (default: none)" | |
384 puts " -outfile <dat filename> (default: $defaultDatFile)" | |
385 puts " -polar <yes|no> (consider only polar atoms (N, O, S, F)? default: no)" | |
386 puts " -DA <D|A|both> (sel1 is the donor (D), acceptor (A), or donor and acceptor (both)?" | |
387 puts " Only valid when used with two selections, default: $defaultDA)" | |
388 puts " -type: (default: $defaultDetailType)" | |
389 puts " none--no detailed bonding information will be calculated" | |
390 puts " all--hbonds in the same residue pair type are all counted" | |
391 puts " pair--hbonds in the same residue pair type are counted once" | |
392 puts " unique--hbonds are counted according to the donor-acceptor atom pair type" | |
393 puts " -detailout <details output file> (default: stdout)" | |
394 return | |
395 } | |
396 | |
397 proc ::hbonds::hbonds { args } { | |
398 | |
399 global tk_version | |
400 variable hbondcount | |
401 variable hbondallframes | |
402 variable multichain | |
403 variable molid | |
404 variable detailType | |
405 | |
406 variable defaultDist | |
407 variable defaultAng | |
408 variable defaultFrames | |
409 variable defaultWrite | |
410 variable defaultPlot | |
411 variable defaultFrames | |
412 variable defaultUpdateSel | |
413 variable defaultDatFile | |
414 variable defaultPolar | |
415 variable defaultDA | |
416 variable currentMol | |
417 variable atomselectText1 | |
418 variable atomselectText2 | |
419 variable debug | |
420 variable log | |
421 variable statusMsg | |
422 variable plotHbonds | |
423 | |
424 variable defaultOutdir [pwd] | |
425 | |
426 variable defaultDetailFile | |
427 variable defaultDetailType | |
428 | |
429 set nargs [llength $args] | |
430 if { $nargs == 0 || $nargs % 2 } { | |
431 if { $nargs == 0 } { | |
432 hbonds_usage | |
433 error "" | |
434 } | |
435 if { $nargs % 2 } { | |
436 hbonds_usage | |
437 error "error: odd number of arguments $args" | |
438 } | |
439 } | |
440 | |
441 foreach {name val} $args { | |
442 switch -- $name { | |
443 -sel1 { set arg(sel1) $val } | |
444 -sel2 { set arg(sel2) $val } | |
445 -upsel { set arg(upsel) $val } | |
446 -frames { set arg(frames) $val } | |
447 -dist { set arg(dist) $val } | |
448 -ang { set arg(ang) $val } | |
449 -writefile { set arg(writefile) $val } | |
450 -outdir { set arg(outdir) $val } | |
451 -log { set arg(log) $val } | |
452 -gui { set arg(gui) $val } | |
453 -debug { set arg(debug) $val } | |
454 -plot {set arg(plot) $val} | |
455 -outfile {set arg(outfile) $val} | |
456 -type { set arg(type) $val } | |
457 -detailout { set arg(detout) $val } | |
458 -polar {set arg(polar) $val } | |
459 -DA { set arg(DA) $val } | |
460 | |
461 default { error "unknown argument: $name $val" } | |
462 } | |
463 } | |
464 | |
465 # was I called by the gui? | |
466 if [info exists arg(gui)] { | |
467 set gui 1 | |
468 } else { | |
469 set gui 0 | |
470 } | |
471 | |
472 # debug flag | |
473 if [info exists arg(debug)] { | |
474 set debug 1 | |
475 } | |
476 | |
477 # outdir | |
478 if [info exists arg(outdir)] { | |
479 set outdir $arg(outdir) | |
480 } else { | |
481 set outdir $defaultOutdir | |
482 } | |
483 if { ![file isdirectory $outdir] } { | |
484 error "$outdir is not a directory." | |
485 } | |
486 | |
487 # log file | |
488 if { [info exists arg(log)] && $arg(log) != "" } { | |
489 set log [open [file join $outdir $arg(log)] w] | |
490 } else { | |
491 set log "stdout" | |
492 } | |
493 | |
494 # polar atoms only? | |
495 if [info exists arg(polar)] { | |
496 if { $arg(polar) == "no" || $arg(polar) == 0 } { | |
497 set polar 0 | |
498 } elseif { $arg(polar) == "yes" || $arg(polar) == 1 } { | |
499 set polar 1 | |
500 } else { | |
501 error "error: bad argument for option -polar $arg(polar): acceptable arguments are 'yes' or 'no'" | |
502 } | |
503 } else { | |
504 set polar $defaultPolar | |
505 } | |
506 | |
507 # donor/acceptor? | |
508 if [info exists arg(DA)] { | |
509 if { $arg(DA) == "D" || $arg(DA) == "donor" } { | |
510 set DA "D" | |
511 } elseif { $arg(DA) == "A" || $arg(DA) == "acceptor" } { | |
512 set DA "A" | |
513 } elseif { $arg(DA) == "both" } { | |
514 set DA "both" | |
515 } else { | |
516 error "error: bad argument for option -DA $arg(DA): acceptable arguments are 'D', 'A', or 'both'" | |
517 } | |
518 } else { | |
519 set DA $defaultDA | |
520 } | |
521 | |
522 # get selection | |
523 if [info exists arg(sel1)] { | |
524 set molid [$arg(sel1) molid] | |
525 if { $polar } { | |
526 set sel1 [atomselect $molid "([$arg(sel1) text]) and (name \"N.*\" \"O.*\" \"S.*\" FA F1 F2 F3)"] | |
527 } else { | |
528 set sel1 $arg(sel1) | |
529 } | |
530 if [info exists arg(sel2)] { | |
531 if { $polar } { | |
532 set sel2 [atomselect $molid "([$arg(sel2) text]) and (name \"N.*\" \"O.*\" \"S.*\" FA F1 F2 F3)"] | |
533 } else { | |
534 set sel2 $arg(sel2) | |
535 } | |
536 } | |
537 | |
538 } elseif $gui { | |
539 if { $currentMol == "none" } { | |
540 error "No molecules were found." | |
541 } else { | |
542 set molid $currentMol | |
543 if { $polar } { | |
544 set sel1 [atomselect $currentMol "($atomselectText1) and (name \"N.*\" \"O.*\" \"S.*\" FA F1 F2 F3)"] | |
545 } else { | |
546 set sel1 [atomselect $currentMol $atomselectText1] | |
547 } | |
548 if {$atomselectText2 != ""} { | |
549 if { $polar } { | |
550 set sel2 [atomselect $currentMol "($atomselectText2) and (name \"N.*\" \"O.*\" \"S.*\" FA F1 F2 F3)"] | |
551 } else { | |
552 set sel2 [atomselect $currentMol $atomselectText2] | |
553 } | |
554 } | |
555 } | |
556 } else { | |
557 hbonds_usage | |
558 error "No atomselection was given." | |
559 } | |
560 | |
561 # update selections? | |
562 if [info exists arg(upsel)] { | |
563 if { $arg(upsel) == "no" || $arg(upsel) == 0 } { | |
564 set updateSel 0 | |
565 } elseif { $arg(upsel) == "yes" || $arg(upsel) == 1 } { | |
566 set updateSel 1 | |
567 } else { | |
568 error "error: bad argument for option -upsel $arg(upsel): acceptable arguments are 'yes' or 'no'" | |
569 } | |
570 } else { | |
571 set updateSel $defaultUpdateSel | |
572 } | |
573 | |
574 # SETTING FRAMES | |
575 | |
576 set nowframe [molinfo $molid get frame] | |
577 set lastframe [expr [molinfo $molid get numframes] - 1] | |
578 if { ! [info exists arg(frames)] } { set arg(frames) $defaultFrames } | |
579 if [info exists arg(frames)] { | |
580 set fl [split $arg(frames) :] | |
581 switch -- [llength $fl] { | |
582 1 { | |
583 switch -- $fl { | |
584 all { | |
585 set frames_begin 0 | |
586 set frames_end $lastframe | |
587 } | |
588 now { | |
589 set frames_begin $nowframe | |
590 } | |
591 last { | |
592 set frames_begin $lastframe | |
593 } | |
594 default { | |
595 set frames_begin $fl | |
596 } | |
597 } | |
598 } | |
599 2 { | |
600 set frames_begin [lindex $fl 0] | |
601 set frames_end [lindex $fl 1] | |
602 } | |
603 3 { | |
604 set frames_begin [lindex $fl 0] | |
605 set frames_step [lindex $fl 1] | |
606 set frames_end [lindex $fl 2] | |
607 } | |
608 default { error "bad -frames arg: $arg(frames)" } | |
609 } | |
610 } else { | |
611 set frames_begin 0 | |
612 } | |
613 if { ! [info exists frames_step] } { set frames_step 1 } | |
614 if { ! [info exists frames_end] } { set frames_end $lastframe } | |
615 switch -- $frames_end { | |
616 end - last { set frames_end $lastframe } | |
617 } | |
618 if { [ catch { | |
619 if { $frames_begin < 0 } { | |
620 set frames_begin [expr $lastframe + 1 + $frames_begin] | |
621 } | |
622 if { $frames_end < 0 } { | |
623 set frames_end [expr $lastframe + 1 + $frames_end] | |
624 } | |
625 if { ! ( [string is integer $frames_begin] && \ | |
626 ( $frames_begin >= 0 ) && ( $frames_begin <= $lastframe ) && \ | |
627 [string is integer $frames_end] && \ | |
628 ( $frames_end >= 0 ) && ( $frames_end <= $lastframe ) && \ | |
629 ( $frames_begin <= $frames_end ) && \ | |
630 [string is integer $frames_step] && ( $frames_step > 0 ) ) } { | |
631 error | |
632 } | |
633 } ok ] } { error "bad -frames arg: $arg(frames)" } | |
634 if $debug { | |
635 puts $log "frames_begin: $frames_begin" | |
636 puts $log "frames_step: $frames_step" | |
637 puts $log "frames_end: $frames_end" | |
638 flush $log | |
639 } | |
640 | |
641 # DONE SETTING FRAMES | |
642 | |
643 # get Dist | |
644 if [info exists arg(dist)] { | |
645 set dist $arg(dist) | |
646 } else { | |
647 set dist $defaultDist | |
648 } | |
649 | |
650 # get Ang | |
651 if [info exists arg(ang)] { | |
652 set ang $arg(ang) | |
653 } else { | |
654 set ang $defaultAng | |
655 } | |
656 | |
657 # write files? | |
658 if [info exists arg(writefile)] { | |
659 if { $arg(writefile) == "no" || $arg(writefile) == 0 } { | |
660 set writefile 0 | |
661 } elseif { $arg(writefile) == "yes" || $arg(writefile) == 1 } { | |
662 set writefile 1 | |
663 if [info exists arg(outfile)] { | |
664 if {$arg(outfile) != ""} { | |
665 set datfile $arg(outfile) | |
666 } else { | |
667 set datfile $defaultDatFile | |
668 } | |
669 } else { | |
670 set datfile $defaultDatFile | |
671 } | |
672 | |
673 if [info exists arg(detout)] { | |
674 if {$arg(detout) != ""} { | |
675 set detailFile $arg(detout) | |
676 } else { | |
677 set detailFile $defaultDetailFile | |
678 } | |
679 } else { | |
680 set detailFile $defaultDetailFile | |
681 } | |
682 | |
683 } else { | |
684 error "error: bad argument for option -writefile $arg(writefile): acceptable arguments are 'yes' or 'no'" | |
685 } | |
686 | |
687 } else { | |
688 set writefile $defaultWrite | |
689 set datfile $defaultDatFile | |
690 set detailFile $defaultDetailFile | |
691 } | |
692 | |
693 # Plot? | |
694 if [info exists arg(plot)] { | |
695 if { ($arg(plot) == "no" || $arg(plot) == 0) && $writefile } { | |
696 set plotHbonds 0 | |
697 } elseif { ($arg(plot) == "yes" || $arg(plot) == 1) || !$writefile } { | |
698 set plotHbonds 1 | |
699 } else { | |
700 error "error: bad argument for option -plot $arg(plot): acceptable arguments are 'yes' or 'no'" | |
701 } | |
702 } else { | |
703 set plotHbonds $defaultPlot | |
704 } | |
705 | |
706 # Don't call multiplot in text mode | |
707 if {![info exists tk_version]} { | |
708 set plotHbonds 0 | |
709 } | |
710 | |
711 # calculate details? | |
712 if [info exists arg(type)] { | |
713 if { $arg(type) == "none" || $arg(type) == 0 } { | |
714 set detailType "none" | |
715 } elseif { $arg(type) == "unique" || $arg(type) == "all" || $arg(type) == "pair" } { | |
716 set detailType $arg(type) | |
717 } else { | |
718 error "error: bad argument for option -type $arg(type): acceptable arguments are 'none', 'all', 'pair', or 'unique'" | |
719 } | |
720 } else { | |
721 set detailType $defaultDetailType | |
722 } | |
723 | |
724 # print name, version and date of plugin | |
725 puts $log "H-Bonds Plugin, Version 1.1" | |
726 puts $log "[clock format [clock scan now]]\n" | |
727 puts $log "Parameters used in the calculation of hydrogen bonds:" | |
728 puts $log "- Atomselection 1: [$sel1 text]" | |
729 if [info exists sel2] { | |
730 puts $log "- Atomselection 2: [$sel2 text]" | |
731 } | |
732 if $updateSel { | |
733 puts $log "- Update selections every frame: yes" | |
734 } else { | |
735 puts $log "- Update selections every frame: no" | |
736 } | |
737 puts $log "- Initial frame: $frames_begin" | |
738 puts $log "- Frame step: $frames_step" | |
739 puts $log "- Final frame: $frames_end" | |
740 puts $log "- Donor-Acceptor distance: $dist" | |
741 puts $log "- Angle cutoff: $ang" | |
742 puts $log "- Type: $detailType" | |
743 if $writefile { | |
744 puts $log "- Write a file with H bond/frame data: yes" | |
745 puts $log "- Filename: $datfile" | |
746 if {$detailType != "none"} { | |
747 puts $log "- Details output file: $detailFile" | |
748 } | |
749 } else { | |
750 puts $log "- Write a file with H bond/frame data: no" | |
751 } | |
752 puts $log "" | |
753 flush $log | |
754 | |
755 ### CALCULATES HBONDS HERE | |
756 | |
757 # check if multiple chains/molecules exist in the two selections | |
758 set chainlist [$sel1 get chain] | |
759 if { [lsearch -not $chainlist [lindex $chainlist 0]] == -1 } { | |
760 set multichain 0 | |
761 } else { set multichain 1 } | |
762 if {[info exists sel2]} { | |
763 set chainlist [$sel2 get chain] | |
764 } | |
765 if { [lsearch -not $chainlist [lindex $chainlist 0]] == -1 && $multichain == 0} { | |
766 set multichain 0 | |
767 } else { set multichain 1 } | |
768 | |
769 set hbondallframes {} | |
770 set hbondcount {} | |
771 set numberofframes [expr { ($frames_end - $frames_begin) / $frames_step + 1 }] | |
772 | |
773 | |
774 for { set f $frames_begin } { $f <= $frames_end } { incr f $frames_step } { | |
775 | |
776 $sel1 frame $f | |
777 if {[info exists sel2]} { | |
778 $sel2 frame $f | |
779 } | |
780 | |
781 if $updateSel { | |
782 $sel1 update | |
783 if {[info exists sel2]} { | |
784 $sel2 update | |
785 } | |
786 } | |
787 | |
788 ### CHECK DA HERE!!! | |
789 | |
790 if {[info exists sel2]} { | |
791 | |
792 set count1 0 | |
793 set count2 0 | |
794 | |
795 if {$DA == "D" || $DA == "both"} { | |
796 set hbondsingleframe1 [measure hbonds $dist $ang $sel1 $sel2] | |
797 set count1 [llength [lindex $hbondsingleframe1 0]] | |
798 } | |
799 if {$DA == "A" || $DA == "both"} { | |
800 set hbondsingleframe2 [measure hbonds $dist $ang $sel2 $sel1] | |
801 set count2 [llength [lindex $hbondsingleframe2 0]] | |
802 } | |
803 | |
804 lappend framecount $f | |
805 lappend numHbonds [expr $count1 + $count2] | |
806 | |
807 if {$detailType != "none"} { | |
808 if {$DA == "D" || $DA == "both"} { | |
809 hbonds::hbonddetails $hbondsingleframe1 | |
810 } | |
811 if {$DA == "A" || $DA == "both"} { | |
812 hbonds::hbonddetails $hbondsingleframe2 | |
813 } | |
814 } | |
815 } else { | |
816 set hbondsingleframe1 [measure hbonds $dist $ang $sel1] | |
817 set count1 [llength [lindex $hbondsingleframe1 0]] | |
818 | |
819 lappend framecount $f | |
820 lappend numHbonds $count1 | |
821 | |
822 if {$detailType != "none"} { | |
823 hbonds::hbonddetails $hbondsingleframe1 | |
824 } | |
825 | |
826 } | |
827 } | |
828 | |
829 | |
830 # delete the selection if it was created here | |
831 if { ![info exists arg(sel1)] } { | |
832 $sel1 delete | |
833 } | |
834 | |
835 if {[info exists sel2]} { | |
836 if { ![info exists arg(sel2)] } { | |
837 $sel2 delete | |
838 } | |
839 } | |
840 | |
841 if { $writefile } { | |
842 | |
843 set statusMsg "Printing frame/hbond data to file... " | |
844 update | |
845 puts -nonewline $log $statusMsg | |
846 flush $log | |
847 | |
848 set outfile [open [file join $outdir $datfile] w] | |
849 if $debug { | |
850 puts $log "Printing to file $datfile" | |
851 } | |
852 | |
853 foreach fr $framecount hb $numHbonds { | |
854 puts $outfile "$fr $hb" | |
855 } | |
856 unset fr hb | |
857 close $outfile | |
858 | |
859 append statusMsg "Done." | |
860 update | |
861 puts $log "Done." | |
862 flush $log | |
863 } | |
864 | |
865 if {$detailType != "none"} { | |
866 if { $writefile } { | |
867 set outfile [open [file join $outdir $detailFile] w] | |
868 if $debug { | |
869 puts $log "Printing detailed hbond info to file $detailFile" | |
870 } | |
871 } else { set outfile "stdout" } | |
872 set statusMsg "Printing results ... " | |
873 update | |
874 puts $outfile "Found [llength $hbondcount] hbonds." | |
875 if { $multichain } { | |
876 puts -nonewline $outfile "donor \t\t\t " | |
877 } else { puts -nonewline $outfile "donor \t\t " } | |
878 if { $multichain } { | |
879 puts $outfile "acceptor \t\t occupancy" | |
880 } else { puts $outfile "acceptor \t occupancy" } | |
881 foreach { h } $hbondallframes { o } $hbondcount { | |
882 set occupancy [expr { 100*$o/($numberofframes+0.0) } ] | |
883 set i -1 | |
884 if { $multichain } { puts -nonewline $outfile "Seg[lindex $h [incr i]]-" } | |
885 ### if { $multichain } { puts -nonewline $outfile "Chain[lindex $h [incr i]]-" } | |
886 if { $detailType != "unique" } { | |
887 puts -nonewline $outfile [format "%s%s%s \t " \ | |
888 [lindex $h [incr i]] [lindex $h [incr i]] [lindex $h [incr i]]] | |
889 } else { | |
890 puts -nonewline $outfile [format "%s%s%s%s \t " \ | |
891 [lindex $h [incr i]] [lindex $h [incr i]] [lindex $h [incr i]] [lindex $h [incr i]]] | |
892 } | |
893 if { $multichain } { puts -nonewline $outfile "Seg[lindex $h [incr i]]-" } | |
894 ### if { $multichain } { puts -nonewline $outfile "Chain[lindex $h [incr i]]-" } | |
895 if { $detailType != "unique" } { | |
896 puts $outfile [format "%s%s%s \t %.2f%%" \ | |
897 [lindex $h [incr i]] [lindex $h [incr i]] [lindex $h [incr i]] $occupancy] | |
898 } else { | |
899 puts $outfile [format "%s%s%s%s \t %.2f%%" \ | |
900 [lindex $h [incr i]] [lindex $h [incr i]] [lindex $h [incr i]] [lindex $h [incr i]] $occupancy] | |
901 } | |
902 } | |
903 if { $outfile != "stdout" } { | |
904 close $outfile | |
905 } | |
906 | |
907 | |
908 | |
909 } | |
910 | |
911 | |
912 if { $plotHbonds } { | |
913 | |
914 set title [format "%s %s %s: %s" Molecule $molid, [molinfo $molid get name] "H-Bonds vs. Frame"] | |
915 | |
916 # feed everything to the plotter | |
917 set plothandle [multiplot -title $title -xlabel "Frame " -ylabel "No. Bonds"] | |
918 | |
919 $plothandle add $framecount $numHbonds -lines -linewidth 1 -linecolor black -marker none | |
920 $plothandle replot | |
921 } | |
922 | |
923 if { $log != "stdout" } { | |
924 close $log | |
925 } | |
926 | |
927 set statusMsg "Done." | |
928 update | |
929 | |
930 return | |
931 | |
932 } | |
933 | |
934 | |
935 # This gets called by VMD the first time the menu is opened. | |
936 proc hbonds_tk_cb {} { | |
937 hbondsgui ;# start the PDB Tool | |
938 return $::hbonds::w | |
939 } | |
940 | |
941 | |
942 proc ::hbonds::sel2_state {args} { | |
943 variable w | |
944 variable atomselectText2 | |
945 variable guiDA | |
946 variable defaultDA | |
947 | |
948 # Disable the prefix file field | |
949 if {$atomselectText2 == ""} { | |
950 if {[winfo exists $w.in.cutoffs]} { | |
951 $w.in.cutoffs.type11 configure -state disabled | |
952 $w.in.cutoffs.type12 configure -state disabled | |
953 set guiDA $defaultDA | |
954 } | |
955 } else { | |
956 if {[winfo exists $w.in.cutoffs]} { | |
957 $w.in.cutoffs.type11 configure -state normal | |
958 $w.in.cutoffs.type12 configure -state normal | |
959 } | |
960 } | |
961 | |
962 } | |
963 | |
964 proc ::hbonds::write_state {args} { | |
965 variable w | |
966 variable guiWrite | |
967 variable guiType | |
968 | |
969 # Disable the prefix file field | |
970 if {$guiWrite == 0} { | |
971 if {[winfo exists $w.out.all]} { | |
972 $w.out.all.fbdata configure -state disabled | |
973 $w.out.all.datname configure -state disabled | |
974 } | |
975 } else { | |
976 if {[winfo exists $w.out.all]} { | |
977 $w.out.all.fbdata configure -state normal | |
978 $w.out.all.datname configure -state normal | |
979 } | |
980 } | |
981 if {$guiWrite == 0 || $guiType == "none"} { | |
982 if {[winfo exists $w.out.all]} { | |
983 $w.out.all.detdata configure -state disabled | |
984 $w.out.all.detname configure -state disabled | |
985 } | |
986 } else { | |
987 if {[winfo exists $w.out.all]} { | |
988 $w.out.all.detdata configure -state normal | |
989 $w.out.all.detname configure -state normal | |
990 } | |
991 } | |
992 | |
993 } | |
994 | |
995 | |
996 | |
997 | |
998 proc hbonds::hbonddetails {hbondlist} { | |
999 | |
1000 variable molid | |
1001 variable hbondcount | |
1002 variable hbondallframes | |
1003 variable multichain | |
1004 variable detailType | |
1005 | |
1006 set framehbond {} | |
1007 | |
1008 foreach { d } [lindex $hbondlist 0] { a } [lindex $hbondlist 1] { | |
1009 set newhbond_donor {} | |
1010 set donor [atomselect $molid "index $d"] | |
1011 if $multichain { lappend newhbond_donor [$donor get segname] } | |
1012 ### if $multichain { lappend newhbond_donor [$donor get chain] } | |
1013 | |
1014 lappend newhbond_donor [$donor get resname] [$donor get resid] | |
1015 set atomname [$donor get name] | |
1016 if { [ lsearch { "N" "CA" "C" "O" } $atomname ] != -1 } { | |
1017 lappend newhbond_donor "-Main" | |
1018 } else { | |
1019 lappend newhbond_donor "-Side" | |
1020 } | |
1021 if { $detailType == "unique" } { | |
1022 # if { [lsearch { "OD1" "OD2" "OE1" "OE2" "OT1" "OT2" "NH1" "NH2" } $atomname] != -1 } { | |
1023 # lappend newhbond_donor "-[string range $atomname 0 1]" | |
1024 # } else { lappend newhbond_donor "-$atomname" } | |
1025 lappend newhbond_donor "-$atomname" | |
1026 } | |
1027 # add support for water molecule here | |
1028 if { [$donor get chain] == "W" } { | |
1029 set newhbond_donor {} | |
1030 if $multichain { lappend newhbond_donor "W" } | |
1031 lappend newhbond_donor "water" "" "-O " | |
1032 if { $detailType == "unique" } { lappend newhbond_donor " " } | |
1033 } | |
1034 $donor delete | |
1035 | |
1036 set newhbond_acceptor {} | |
1037 set acceptor [atomselect $molid "index $a"] | |
1038 if $multichain { lappend newhbond_acceptor [$acceptor get segname] } | |
1039 ### if $multichain { lappend newhbond_acceptor [$acceptor get chain] } | |
1040 lappend newhbond_acceptor [$acceptor get resname] [$acceptor get resid] | |
1041 set atomname [$acceptor get name] | |
1042 if { [ lsearch { "N" "CA" "C" "O" } $atomname ] != -1 } { | |
1043 lappend newhbond_acceptor "-Main" | |
1044 } else { | |
1045 lappend newhbond_acceptor "-Side" | |
1046 } | |
1047 if { $detailType == "unique" } { | |
1048 # if { [lsearch { "OD1" "OD2" "OE1" "OE2" "OT1" "OT2" "NH1" "NH2" } $atomname] != -1 } { | |
1049 # lappend newhbond_acceptor "-[string range $atomname 0 1]" | |
1050 # } else { lappend newhbond_acceptor "-$atomname" } | |
1051 lappend newhbond_acceptor "-$atomname" | |
1052 } | |
1053 # add support for water molecule here | |
1054 if { [$acceptor get chain] == "W" } { | |
1055 set newhbond_acceptor {} | |
1056 if $multichain { lappend newhbond_acceptor "W" } | |
1057 lappend newhbond_acceptor "water" "" "-O " | |
1058 if { $detailType == "unique" } { lappend newhbond_acceptor " " } | |
1059 } | |
1060 $acceptor delete | |
1061 | |
1062 set newhbond [concat $newhbond_donor $newhbond_acceptor] | |
1063 if { [lsearch $framehbond $newhbond] == -1 } { | |
1064 if { $detailType != "all" } { lappend framehbond $newhbond } | |
1065 set hbondexist [lsearch $hbondallframes $newhbond] | |
1066 if { $hbondexist == -1 } { | |
1067 lappend hbondallframes $newhbond | |
1068 lappend hbondcount 1 | |
1069 } else { | |
1070 lset hbondcount $hbondexist [expr { [lindex $hbondcount $hbondexist] + 1 } ] | |
1071 } | |
1072 } | |
1073 } | |
1074 return | |
1075 | |
1076 } | |
1077 | |
1078 |