Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dashboard improvements #751

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion vmd/cv_dashboard/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2024-02-17
2024-12-12
30 changes: 25 additions & 5 deletions vmd/cv_dashboard/cv_dashboard.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,17 @@
# Usage (after installing):
# package require cv_dashboard
# cv_dashboard
# or select the Extensions/Analysis menu item

# Design principles:
# - take advantage of colvars/VMD binding for maximum user interaction
# - hide the colvars config text from user, instead expose colvar, names and values
# - do not try to parse the colvars config (let the Colvars Module do it)
# to avoid coming up with an incompatible parser

# This plugin only acts on the "top" molecule
# which is most consistent for trajectory animation (determined by the frame number of mol)
# Source file layout:
# - this file contains utility functions and data structure, without GUI
# - other files contain GUI elements

# TODO Multiplot:
# - properly calculate position of cursor in plot when not all the plot is visible (resized window)
Expand Down Expand Up @@ -130,8 +132,8 @@ Please upgrade to VMD 1.9.4 alpha or later."
if { [vecdist $abc {1 1 1}] < 1e-10 } {
set answer [tk_messageBox -icon warning -type okcancel -title "Warning: unlikely periodic box lengths"\
-message "The periodic box lengths are (1, 1, 1), which can be the output of a\
non-periodic simulation in NAMD. Overwrite with (0, 0, 0) to make Colvars detect as non-periodic?
The command line is:
non-periodic simulation in NAMD. Overwrite with (0, 0, 0) to signal a non-periodic system?
This will run the following commands:
package require pbctools
pbc set {0 0 0} -all -molid $::cv_dashboard::mol"]
if { $answer == "ok" } {
Expand Down Expand Up @@ -954,7 +956,8 @@ Read the standard output (terminal) for details."
}


# Create a scripted colvar that returns values from a precomputed trajectory
# Create a scripted colvar that returns values from a precomputed trajectory
# (internal utility function for load_cv_traj, hence not in the main namespace)

proc create_traj_colvar { molid cv } {

Expand Down Expand Up @@ -1010,3 +1013,20 @@ proc create_traj_colvar { molid cv } {
"
cv config $configString
}

# Save trajectory of currently defined colvars to a file in the colvars.traj format

proc ::cv_dashboard::save_traj_file { fileName } {

puts "Writing colvars trajectory to file $fileName"
set o [open $fileName w]
puts -nonewline $o [cv printframelabels]

set nf [molinfo top get numframes]
for {set f 0} {$f< $nf} {incr f} {
cv frame $f
cv update
puts -nonewline $o [cv printframe]
}
close $o
}
19 changes: 16 additions & 3 deletions vmd/cv_dashboard/cv_dashboard_main.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ proc ::cv_dashboard::createWindow {} {
-row $gridrow -column 0 -pady 2 -padx 2 -sticky nsew
grid [ttk::button $w.save -text "Save" -command ::cv_dashboard::save -padding "2 0 2 0"] \
-row $gridrow -column 1 -pady 2 -padx 2 -sticky nsew
grid [ttk::button $w.reset -text "Reset" -command ::cv_dashboard::reset -padding "2 0 2 0"] \
grid [ttk::button $w.reset -text "Reset" -command ::cv_dashboard::reset -padding "2 0 2 0"] \
-row $gridrow -column 2 -pady 2 -padx 2 -sticky nsew

# Table of colvars
Expand Down Expand Up @@ -100,7 +100,10 @@ proc ::cv_dashboard::createWindow {} {
grid [ttk::button $main.del -text "Delete" -command ::cv_dashboard::del_cv -padding "2 0 2 0"] \
-row $gridrow -column 2 -pady 2 -padx 2 -sticky nsew
incr gridrow
grid [ttk::button $main.refresh -text "Refresh list \[F5\]" -command ::cv_dashboard::refresh_table -padding "2 0 2 0"] -row $gridrow -column 0 -columnspan 3 -pady 2 -padx 2 -sticky nsew
grid [ttk::button $main.refresh -text "Refresh list \[F5\]" -command ::cv_dashboard::refresh_table -padding "2 0 2 0"] \
-row $gridrow -column 0 -columnspan 2 -pady 2 -padx 2 -sticky nsew
grid [ttk::button $main.save_traj -text "Save traj file" -command ::cv_dashboard::save_traj_dialog -padding "2 0 2 0"] \
-row $gridrow -column 2 -pady 2 -padx 2 -sticky nsew

# Plots
incr gridrow
Expand Down Expand Up @@ -516,7 +519,7 @@ https://colvars.github.io
In [vmdinfo versionmsg]
Running Tcl/Tk [info patchlevel]
Jérôme Hénin (jerome.henin@ibpc.fr), Giacomo Fiorin (giacomo.fiorin@nih.gov) and the Colvars developers.
Jérôme Hénin (jerome.henin@cnrs.fr), Giacomo Fiorin (giacomo.fiorin@nih.gov) and the Colvars developers.
#Please cite the following references for features currently in use:
Expand Down Expand Up @@ -1488,3 +1491,13 @@ proc ::cv_dashboard::createRotationMenu { row } {

grid remove $menu.show_rotation $menu.hide_rotation
}

# Open file dialog to choose file name, then save colvars trajectory

proc ::cv_dashboard::save_traj_dialog {} {
set file [tk_getSaveFile -title "Colvars trajectory file to be written" \
-filetypes {{"Colvars traj" .colvars.traj} {"All files" *}}]
if {[llength $file] > 0 } {
::cv_dashboard::save_traj_file $file
}
}
113 changes: 77 additions & 36 deletions vmd/cv_dashboard/cv_dashboard_plots.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,20 @@ proc ::cv_dashboard::plot { { type timeline } } {
set plothandle [multiplot -title {Colvars trajectory [click on markers, keyb arrows (+ Shift/Ctrl) to navigate]} \
-xlabel $xname -ylabel $yname -nostats -marker circle -fill white -radius 4 -callback ::cv_dashboard::marker_clicked]
$plothandle add $y($xname) $y($yname)

# Add custom Colvars menu item to Multiplot window
set plot_ns [$plothandle namespace]
set menubar "[set ${plot_ns}::w].menubar"
menubutton $menubar.colvars -text "Colvars" -underline 0 -menu $menubar.colvars.menu
menu $menubar.colvars.menu -tearoff 0
$menubar.colvars.menu add command -label "Swap axes" -command ::cv_dashboard::pairwise_swap_axes
$menubar.colvars.menu add command -label "Turn lines off" -command "::cv_dashboard::display_lines false"
$menubar.colvars.menu add command -label "Turn lines on" -command "::cv_dashboard::display_lines true"
# Add item to existing menu bar
set col [lindex [grid size $menubar] 0]
grid $menubar.colvars -row 0 -column $col -sticky nsw
grid columnconfigure $menubar $col -weight 2

} elseif { $type == "histogram"} {
set xname [lindex $name_list 0]
# Save list of values for navigating
Expand Down Expand Up @@ -112,7 +126,6 @@ proc ::cv_dashboard::plot { { type timeline } } {
-xlabel $xname -ylabel "N" -nostats -xmin $xmin -xmax $xmax \
-ymin 0.0 -x $centers -y $frequencies -nolines -plot]

set ns [namespace qualifiers $plothandle]
# force bars to start at zero
set ymin 0.0

Expand Down Expand Up @@ -251,13 +264,13 @@ proc ::cv_dashboard::plot_bias_energy { } {
# Callback for click inside plot window, at coords x y
proc ::cv_dashboard::plot_clicked { x y } {

set ns [$::cv_dashboard::plothandle namespace]
set xplotmin [set ${ns}::xplotmin]
set xplotmax [set ${ns}::xplotmax]
set yplotmin [set ${ns}::yplotmin]
set yplotmax [set ${ns}::yplotmax]
set scalex [set ${ns}::scalex]
set xmin [set ${ns}::xmin]
set plot_ns [$::cv_dashboard::plothandle namespace]
set xplotmin [set ${plot_ns}::xplotmin]
set xplotmax [set ${plot_ns}::xplotmax]
set yplotmin [set ${plot_ns}::yplotmin]
set yplotmax [set ${plot_ns}::yplotmax]
set scalex [set ${plot_ns}::scalex]
set xmin [set ${plot_ns}::xmin]

# note: ymax < ymin because of pixel coordinate convention
if { [expr {($x < $xplotmin) || ($x > $xplotmax) || ($y > $yplotmin) || ($y < $yplotmax)}] } {
Expand Down Expand Up @@ -330,9 +343,9 @@ proc ::cv_dashboard::chg_frame { shift { order "traj" } } {
proc ::cv_dashboard::zoom { factor } {
variable ::cv_dashboard::plothandle

set ns [namespace qualifiers $plothandle]
set xmin [set ${ns}::xmin]
set xmax [set ${ns}::xmax]
set plot_ns [$plothandle namespace]
set xmin [set ${plot_ns}::xmin]
set xmax [set ${plot_ns}::xmax]

set f $::cv_dashboard::current_frame
# rescale current half-width
Expand All @@ -357,9 +370,9 @@ proc ::cv_dashboard::zoom { factor } {
proc ::cv_dashboard::fit_vertically {} {
variable ::cv_dashboard::plothandle

set ns [namespace qualifiers $plothandle]
set xmin [set ${ns}::xmin]
set xmax [set ${ns}::xmax]
set plot_ns [$plothandle namespace]
set xmin [set ${plot_ns}::xmin]
set xmax [set ${plot_ns}::xmax]
set ydata [$plothandle ydata]
set ymin [lindex [lindex $ydata 0] $xmin]
set ymax $ymin
Expand Down Expand Up @@ -399,11 +412,11 @@ proc ::cv_dashboard::display_marker { f } {
# we tinker a little with Multiplot's internals to get access to its Tk canvas
# necessary because Multiplot does not expose an interface to draw & delete
# objects without redrawing the whole plot - which takes too long for this
set ns [namespace qualifiers $plothandle]
set plot_ns [$plothandle namespace]
if { $::cv_dashboard::plottype == "timeline" } {

set xmin [set ${ns}::xmin]
set xmax [set ${ns}::xmax]
set xmin [set ${plot_ns}::xmin]
set xmax [set ${plot_ns}::xmax]
# Move plot boundaries if necessary
if { $f < $xmin } {
set xmax [expr { $xmax + $f - $xmin }]
Expand All @@ -416,49 +429,49 @@ proc ::cv_dashboard::display_marker { f } {
$plothandle configure -xmin $xmin -xmax $xmax -plot
}

set y1 [set ${ns}::yplotmin]
set y2 [set ${ns}::yplotmax]
set xplotmin [set ${ns}::xplotmin]
set scalex [set ${ns}::scalex]
set y1 [set ${plot_ns}::yplotmin]
set y2 [set ${plot_ns}::yplotmax]
set xplotmin [set ${plot_ns}::xplotmin]
set scalex [set ${plot_ns}::scalex]
set x [expr $xplotmin+($scalex*($f-$xmin))]

set canv "[set ${ns}::w].f.cf"
set canv "[set ${plot_ns}::w].f.cf"
$canv delete frame_marker
$canv create line $x $y1 $x $y2 -fill $timeline_color -tags frame_marker
} elseif { $::cv_dashboard::plottype == "2cv" } {
set x [lindex [ lindex [$plothandle xdata] 0] $f]
set y [lindex [ lindex [$plothandle ydata] 0] $f]

set xmin [set ${ns}::xmin]
set ymin [set ${ns}::ymin]
set xmin [set ${plot_ns}::xmin]
set ymin [set ${plot_ns}::ymin]

set radius 5
set xplotmin [set ${ns}::xplotmin]
set scalex [set ${ns}::scalex]
set xplotmin [set ${plot_ns}::xplotmin]
set scalex [set ${plot_ns}::scalex]
set x1 [expr {$xplotmin+$scalex*($x-$xmin) - $radius}]
set x2 [expr {$xplotmin+$scalex*($x-$xmin) + $radius}]

set yplotmin [set ${ns}::yplotmin]
set scaley [set ${ns}::scaley]
set yplotmin [set ${plot_ns}::yplotmin]
set scaley [set ${plot_ns}::scaley]
set y1 [expr {$yplotmin+$scaley*($y-$ymin) - $radius}]
set y2 [expr {$yplotmin+$scaley*($y-$ymin) + $radius}]

set canv "[set ${ns}::w].f.cf"
set canv "[set ${plot_ns}::w].f.cf"
$canv delete frame_marker
$canv create oval $x1 $y1 $x2 $y2 -outline white -fill $2cv_color -tags frame_marker
} elseif { $::cv_dashboard::plottype == "histogram" } {
set xmin [set ${ns}::xmin]
set xmax [set ${ns}::xmax]
set xmin [set ${plot_ns}::xmin]
set xmax [set ${plot_ns}::xmax]

set y1 [set ${ns}::yplotmin]
set y2 [set ${ns}::yplotmax]
set y1 [set ${plot_ns}::yplotmin]
set y2 [set ${plot_ns}::yplotmax]
set v [lindex $cv_dashboard::histogram_time_series $f]

set xplotmin [set ${ns}::xplotmin]
set scalex [set ${ns}::scalex]
set xplotmin [set ${plot_ns}::xplotmin]
set scalex [set ${plot_ns}::scalex]
set x [expr $xplotmin+($scalex*($v-$xmin))]

set canv "[set ${ns}::w].f.cf"
set canv "[set ${plot_ns}::w].f.cf"
$canv delete frame_marker
$canv create line $x $y1 $x $y2 -fill $histogram_color -tags frame_marker
}
Expand Down Expand Up @@ -519,3 +532,31 @@ proc ::cv_dashboard::simplify x {
set x [expr round($x / $factor) * $factor]
return $x
}


proc ::cv_dashboard::pairwise_swap_axes {} {

variable ::cv_dashboard::plothandle
set plot_ns [$plothandle namespace]

set x [$plothandle xdata]
set y [$plothandle ydata]
set xlabel [set ${plot_ns}::xlabeltext]
set ylabel [set ${plot_ns}::ylabeltext]

$plothandle clear
$plothandle add $y $x -xlabel $ylabel -ylabel $xlabel -plot
}


proc ::cv_dashboard::display_lines { yesno } {

variable ::cv_dashboard::plothandle
if $yesno {
set param "-lines"
} else {
set param "-nolines"
}

$plothandle configure $param -plot
}
19 changes: 10 additions & 9 deletions vmd/cv_dashboard/templates/bias.colvars
Original file line number Diff line number Diff line change
Expand Up @@ -101,18 +101,19 @@ harmonicWalls {
outputEnergy yes
outputAccumulatedWork yes
}
#_harmonic walls with changing force constant
#_harmonic wall with changing force constant: RFEP
# (Restraint Free Energy Perturbation)
harmonicWalls {
colvars <names>
colvars <names>

lowerWalls 0.1
upperWalls 0.2
forceConstant 10.0
upperWalls 10.0
forceConstant 200.0

targetForceconstant 0.0001
targetNumSteps 10
outputEnergy yes
outputAccumulatedWork yes
decoupling yes
lambdaExponent 4 # Nonlinear scaling of the force constant
targetNumSteps 10000
targetNumStages 40
outputEnergy yes
}
#_histogram
histogram {
Expand Down
5 changes: 5 additions & 0 deletions vmd/scripts/calc_cv_mass.tcl
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
# Compute the reduced mass of a collective variable
# and write its trajectory to a file

# M = (\nabla xi m^-1 \nabla_xi)^-1
# where m is the diagonal matrix of Cartesian coordinate (ie atom) masses

proc cv_mass_traj { cv filename } {

Expand Down
Loading