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