/*======================================================================
A GENESIS GUI for network models, with a control panel, a graph with
axis scaling, and a network view to visualize Vm in each cell
======================================================================*/
//=========================================
// Function definitions used by GUI
//=========================================
function overlaytoggle(widget)
str widget
setfield /##[TYPE=xgraph] overlay {getfield {widget} state}
end
function change_stepsize(dialog)
str dialog
dt = {getfield {dialog} value}
setclock 0 {dt}
echo "Changing step size to "{dt}
end
function change_runtime(dialog)
str dialog
tmax = {getfield {dialog} value}
setfield /data/voltage xmax {tmax}
setfield /data/Inh_voltage xmax {tmax}
setfield /MGBv_Vm/voltage xmax {tmax} // from input_graphics.g
setfield /EPSCform/EPSC_sum xmax {tmax} // from ACnet2-3.g
end
function set_drive_weights(dialog)
str dialog
drive_weight = {getfield {dialog} value}
setall_driveweights {drive_weight}
end
/* A subset of the functions defined in genesis/startup/xtools.g
These are used to provide a "scale" button to graphs.
"makegraphscale path_to_graph" creates the button and the popup
menu to change the graph scale.
*/
function setgraphscale(graph)
str graph
str form = graph @ "_scaleform"
str xmin = {getfield {form}/xmin value}
str xmax = {getfield {form}/xmax value}
str ymin = {getfield {form}/ymin value}
str ymax = {getfield {form}/ymax value}
setfield {graph} xmin {xmin} xmax {xmax} ymin {ymin} ymax {ymax}
xhide {form}
end
function showgraphscale(form)
str form
str x, y
// find the parent form
str parent = {el {form}/..}
while (!{isa xform {parent}})
parent = {el {parent}/..}
end
x = {getfield {parent} xgeom}
y = {getfield {parent} ygeom}
setfield {form} xgeom {x} ygeom {y}
xshow {form}
end
function makegraphscale(graph)
if ({argc} < 1)
echo usage: makegraphscale graph
return
end
str graph
str graphName = {getpath {graph} -tail}
float x, y
str form = graph @ "_scaleform"
str parent = {el {graph}/..}
while (!{isa xform {parent}})
parent = {el {parent}/..}
end
x = {getfield {graph} x}
y = {getfield {graph} y}
create xbutton {graph}_scalebutton \
[{getfield {graph} xgeom},{getfield {graph} ygeom},50,25] \
-title scale -script "showgraphscale "{form}
create xform {form} [{x},{y},180,170] -nolabel
disable {form}
pushe {form}
create xbutton DONE [10,5,55,25] -script "setgraphscale "{graph}
create xbutton CANCEL [70,5,55,25] -script "xhide "{form}
create xdialog xmin [10,35,160,25] -value {getfield {graph} xmin}
create xdialog xmax [10,65,160,25] -value {getfield {graph} xmax}
create xdialog ymin [10,95,160,25] -value {getfield {graph} ymin}
create xdialog ymax [10,125,160,25] -value {getfield {graph} ymax}
pope
end
/* Add some interesting colors to any widgets that have been created */
function colorize
setfield /##[ISA=xlabel] fg white bg blue3
setfield /##[ISA=xbutton] offbg rosybrown1 onbg rosybrown1
setfield /##[ISA=xtoggle] onfg red offbg cadetblue1 onbg cadetblue1
setfield /##[ISA=xdialog] bg palegoldenrod
setfield /##[ISA=xgraph] bg ivory
end
// function to return a color name from an index into the colorlist
// Usage example: str color = {colors 3}
function colors(col_num)
int col_num
str colorlist = "black blue cyan green magenta red orange"
str color
// convert col_num to range 1 though 7
col_num = col_num - {trunc {col_num/7.0}}*7 + 1
color = {getarg {arglist {colorlist}} -arg {col_num}}
return {color}
end
/* Functions to drop and add plots of Vm for middle cell of input target row */
function add_Vmplot(row_num)
int row_num, cell_num, dup_num, n, count
str label, msglabel
float offset
float delta_y = 0.02 // vertical displacement of subsequent plots
int first_row = 8 // the first row to be plotted has no vertical offset
cell_num = row_num*Ex_NX + {round {(Ex_NX -1)/2.0}}
// generate PLOTSCALE options {value} *{label} *{color} scale offset
label = "row_" @ {row_num}
offset = (row_num - first_row)*delta_y
count = {getmsg /data/voltage -in -count}
dup_num = -1 // default is that the message doesn't already exist
for (n = 0; n < count; n = n +1)
msglabel = {getmsg /data/voltage -in -slot {n} 1 }
if ({msglabel} == {label})
dup_num = n
echo "Plot " {n} " " {msglabel} " already exists"
end
end
if (dup_num < 0)
if({hflag} && {hsolve_chanmode > 1})
addmsg /Ex_layer/{Ex_cell_name}[{cell_num}]/solver \
/data/voltage PLOTSCALE \
{findsolvefield /Ex_layer/{Ex_cell_name}[{cell_num}]/solver \
soma Vm} *{label} *{colors {row_num}} 1 {offset}
else
addmsg /Ex_layer/{Ex_cell_name}[{cell_num}]/soma /data/voltage \
PLOTSCALE Vm *{label} *{colors {row_num}} 1 {offset}
end
end
// MGBv inputs target y-coord range, not a row, and Inh cells have
// twice the spacing of Ex cell. Thus the row numbers of Inh inputs
// increase at half the rate.
cell_num = {round {row_num*Inh_NX/2.0}} + {round {(Inh_NX -1)/2.0}}
// redo this for /data/Inh_voltage without assuming it has same messages
count = {getmsg /data/Inh_voltage -in -count}
dup_num = -1 // default is that the message doesn't already exist
for (n = 0; n < count; n = n +1)
msglabel = {getmsg /data/Inh_voltage -in -slot {n} 1 }
if ({msglabel} == {label})
dup_num = n
echo "Plot " {n} " " {msglabel} " already exists"
end
end
if (dup_num < 0)
if({hflag} && {hsolve_chanmode > 1})
addmsg /Inh_layer/{Inh_cell_name}[{cell_num}]/solver \
/data/Inh_voltage PLOTSCALE \
{findsolvefield /Inh_layer/{Inh_cell_name}[{cell_num}]/solver \
soma Vm} *{label} *{colors {row_num}} 1 {offset}
else
addmsg /Inh_layer/{Inh_cell_name}[{cell_num}]/soma /data/Inh_voltage \
PLOTSCALE Vm *{label} *{colors {row_num}} 1 {offset}
end
end
end
/* This is a much simplified version of add_Vmplot, to add plots
of synaptic currents. It does no checking for existing plots.
*/
function add_Ikplot(row_num)
int row_num, cell_num, dup_num, n, count
str label, msglabel
float offset
float iscale = 100e-12 // 100 pA
int first_row = 8 // the first row to be plotted has no vertical offset
float delta_y = 2.0*iscale // vertical displacement of subsequent plots
// target is middle cell in row targeted by row_num
cell_num = row_num*Ex_NX + {round {(Ex_NX -1)/2.0}}
// generate PLOTSCALE options {value} *{label} *{color} scale offset
label = "row_" @ {row_num}
offset = (row_num - first_row)*delta_y //
if({hflag} && {hsolve_chanmode > 1})
addmsg /Ex_layer/{Ex_cell_name}[{cell_num}]/solver \
/Isyndata/syncurrent PLOTSCALE \
{findsolvefield /Ex_layer/{Ex_cell_name}[{cell_num}]/solver \
{Ex_ex_synpath} Ik} *{label} *{colors {row_num}} 1 {offset}
addmsg /Ex_layer/{Ex_cell_name}[{cell_num}]/solver \
/Isyndata/syncurrent PLOTSCALE \
{findsolvefield /Ex_layer/{Ex_cell_name}[{cell_num}]/solver \
{Ex_inh_synpath} Ik} *"Inh_"{label} *{colors {row_num}} 1 {offset}
// MGBv inputs target y-coord range, not a row, and Inh cells have
// twice the spacing of Ex cell. Thus the row numbers of Inh inputs
// increase at half the rate.
cell_num = {round {row_num*Inh_NX/2.0}} + {round {(Inh_NX -1)/2.0}}
addmsg /Inh_layer/{Inh_cell_name}[{cell_num}]/solver \
/Isyndata/Inh_syncurrent PLOTSCALE \
{findsolvefield /Inh_layer/{Inh_cell_name}[{cell_num}]/solver \
{Inh_ex_synpath} Ik} *{label} *{colors {row_num}} 1 {offset}
addmsg /Inh_layer/{Inh_cell_name}[{cell_num}]/solver \
/Isyndata/Inh_syncurrent PLOTSCALE \
{findsolvefield /Inh_layer/{Inh_cell_name}[{row_num}]/solver \
{Inh_inh_synpath} Ik} *"Inh_"{label} *{colors {row_num}} 1 {offset}
else
addmsg /Ex_layer/{Ex_cell_name}[{cell_num}]/{Ex_ex_synpath} \
/Isyndata/syncurrent \
PLOTSCALE Ik *{label} *{colors {row_num}} 1 {offset}
addmsg /Ex_layer/{Ex_cell_name}[{cell_num}]/{Ex_inh_synpath} \
/Isyndata/syncurrent \
PLOTSCALE Ik *"Inh_"{label} *{colors {row_num}} 1 {offset}
// MGBv inputs target y-coord range, not a row, and Inh cells have
// twice the spacing of Ex cell. Thus the row numbers of Inh inputs
// increase at half the rate.
cell_num = {round {row_num*Inh_NX/2.0}} + {round {(Inh_NX -1)/2.0}}
addmsg /Inh_layer/{Inh_cell_name}[{cell_num}]/{Inh_ex_synpath} \
/Isyndata/Inh_syncurrent \
PLOTSCALE Ik *{label} *{colors {row_num}} 1 {offset}
addmsg /Inh_layer/{Inh_cell_name}[{cell_num}]/{Inh_inh_synpath} \
/Isyndata/Inh_syncurrent \
PLOTSCALE Ik *"Inh_"{label} *{colors {row_num}} 1 {offset}
end
end // function add_Ikplot
//==================================
// Functions to set up the GUI
//==================================
function make_control
create xform /control [0,0,270,530]
pushe /control
create xlabel label -hgeom 25 -bg cyan -label "CONTROL PANEL"
create xbutton RESET -wgeom 25% -script reset
create xbutton RUN -xgeom 0:RESET -ygeom 0:label -wgeom 25% \
-script step_tmax
create xbutton STOP -xgeom 0:RUN -ygeom 0:label -wgeom 25% \
-script stop
create xbutton QUIT -xgeom 0:STOP -ygeom 0:label -wgeom 25% -script quit
create xdialog RUNID -title "RUNID string:" -value {RUNID} \
-script "change_RUNID <value>"
create xdialog stepsize -title "dt (sec)" -value {dt} \
-script "change_stepsize <widget>"
create xdialog runtime -title "runtime (sec)" -value {tmax} \
-script "change_runtime <widget>"
create xtoggle overlay -script "overlaytoggle <widget>"
setfield overlay offlabel "Overlay OFF" onlabel "Overlay ON" state 0
create xlabel connlabel -label "Connection Parameters"
create xdialog Ex_ex_gmax -label "Ex_cell ex gmax (nS)" \
-value {Ex_ex_gmax*1e9} -script "set_Ex_ex_gmax <v>"
create xdialog Ex_inh_gmax -label "Ex_cell inh gmax (nS)" \
-value {Ex_inh_gmax*1e9} -script "set_Ex_inh_gmax <v>"
create xdialog Inh_ex_gmax -label "Inh_cell ex gmax (nS)" \
-value {Inh_ex_gmax*1e9} -script "set_Inh_ex_gmax <v>"
create xdialog Inh_inh_gmax -label "Inh_cell inh gmax (nS)" \
-value {Inh_inh_gmax*1e9} -script "set_Inh_inh_gmax <v>"
create xdialog weight -label "Weight" \
-value {syn_weight} -script "set_weights <v>"
create xdialog propdelay -label "Prop delay (sec/m)" \
-value {prop_delay} -script "set_delays <v>"
create xlabel randact -label "Random background activation"
create xdialog randfreq -wgeom 50% -label "Freq" -value {frequency} \
-script "set_frequency <v>"
create xdialog Ex_bg_gmax -wgeom 50% -ygeom 0:randact -xgeom 0:randfreq \
-label "gmax (nS)" -value {Ex_bg_gmax*1e9} -script "set_Ex_bg_gmax <v>"
create xlabel drive_input -label "Thalamic Drive Input"
create xdialog Ex_dr_gmax -wgeom 50% -label "Ex gmax (nS)" \
-value {Ex_drive_gmax*1e9} -script "set_Ex_drive_gmax <v>"
create xdialog Inh_dr_gmax -wgeom 50% -xgeom 0:Ex_dr_gmax \
-ygeom 0:drive_input -label "Inh gmax (nS)" \
-value {Inh_drive_gmax*1e9} -script "set_Inh_drive_gmax <v>"
create xdialog drive_weights -label "Default drive weights" \
-value {drive_weight} -script "set_drive_weights <widget>"
create xdialog show_params -label "Show params for input:" \
-value 1 -script "show_params <v>"
pope
xshow /control
end
function make_Vmgraph
str graph_form = "/data"
str graphlabel = "Vm of center input targets"
float vmin = -0.07
float vmax = 0.65
create xform {graph_form} [275,0,400,800]
pushe {graph_form}
create xlabel label -label {graphlabel}
create xgraph voltage -hgeom 60% -title "Ex_cell Membrane Potential" !
setfield ^ XUnits sec YUnits V
setfield ^ xmax {tmax} ymin {vmin} ymax {vmax}
makegraphscale {graph_form}/voltage
useclock voltage 2 // the clock used to write the netview file
create xgraph Inh_voltage -hgeom 30% -ygeom 0:voltage \
-title "Inh_cell Membrane Potential" -bg white
setfield ^ XUnits sec YUnits V
setfield ^ xmax {tmax} ymin {vmin} ymax {vmax}
makegraphscale {graph_form}/Inh_voltage
pope
xshow {graph_form}
end
function make_Ikgraph
str graph_form = "/Isyndata"
str graphlabel = "Syn cuurents of center input targets"
float iscale = 100e-12 // 100 pA
float imin = -5*iscale
float imax = 80*iscale
int xpos = 684; int ypos = 0
create xform {graph_form} [{xpos}, {ypos},400,800]
pushe {graph_form}
create xlabel label -label {graphlabel}
create xgraph syncurrent -hgeom 64% -title "Ex_cell synaptic currents" !
setfield ^ XUnits sec YUnits I
setfield ^ xmax {tmax} ymin {imin} ymax {imax}
makegraphscale {graph_form}/syncurrent
useclock voltage 2 // the clock used to write the netview file
create xgraph Inh_syncurrent -hgeom 30% -ygeom 0:syncurrent \
-title "Inh_cell synaptic currents" -bg white
setfield ^ XUnits sec YUnits I
setfield ^ xmax {tmax} ymin {imin} ymax {imax}
makegraphscale {graph_form}/Inh_syncurrent
create xbutton DISMISS -ygeom 0:Inh_syncurrent -script "xhide "{graph_form}
pope
xshow {graph_form}
end
function make_graph_messages
/* Set up plotting messages, with offsets */
add_Vmplot 8
add_Vmplot 12
add_Vmplot 18
add_Vmplot 24
add_Vmplot 30
add_Vmplot 36
add_Ikplot 18
add_Ikplot 24
add_Ikplot 30
add_Ikplot 36
str MGBv_graph = "/MGBv_Vm/voltage"
if (input_type == "MGBv")
// This needs to be generalized
str src = "soma"
addmsg /MGBv[1]/{src} {MGBv_graph} PLOTSCALE Vm *MGBv1_Vm *black 1 0
elif (input_type == "pulsed_spiketrain" || input_type == "pulsed_randomspike")
str src = "spikepulse/spike"
setfield {MGBv_graph} ymin 0.0 ymax 6.0
// should loop over Ninputs to see which are enabled with spiketoggle
addmsg /MGBv[5]/{src} {MGBv_graph} PLOTSCALE state *MGBv5_Vm *black 1 0
addmsg /MGBv[17]/{src} {MGBv_graph} PLOTSCALE state *MGBv17_Vm *blue 1 2
addmsg /MGBv[29]/{src} {MGBv_graph} PLOTSCALE state *MGBv29_Vm *red 1 4
end
end // function make_graph_messages
function make_netview // sets up xview widget to display Vm of each cell
// Adjust the aspect ratio for rectangular networks of width around 400
// Make view for Ex_cell[]
int npixels = 2*{round {180/Ex_NX}}
int Ex_view_width = npixels*Ex_NX + 20
int Ex_view_height = npixels*Ex_NY + 17
if ({exists /Ex_netview}) // make a new one of the right size
delete /Ex_netview
end
create xform /Ex_netview [680,0,{Ex_view_width}, {Ex_view_height}]
create xdraw /Ex_netview/draw [0%,0%,100%, 100%]
// Make the display region a little larger than the cell array
setfield /Ex_netview/draw xmin {-Ex_SEP_X} xmax {Ex_NX*Ex_SEP_X} \
ymin {-Ex_SEP_Y} ymax {Ex_NY*Ex_SEP_Y}
create xview /Ex_netview/draw/view
setfield /Ex_netview/draw/view value_min -0.08 value_max 0.03 \
viewmode colorview sizescale {Ex_SEP_X}
/* GENESIS doesn't like the wildcard path "{Ex_cell_name}[]/solver"
if({hflag} && {hsolve_chanmode > 1})
setfield /Ex_netview/draw/view path /Ex_layer/{Ex_cell_name}[]/solver \
field {findsolvefield /Ex_layer/{Ex_cell_name}[]/solver soma Vm}
else
setfield /Ex_netview/draw/view path /Ex_layer/{Ex_cell_name}[]/soma \
field Vm
end
*/
setfield /Ex_netview/draw/view path /Ex_layer/{Ex_cell_name}[]/soma \
field Vm
xshow /Ex_netview
int Inh_view_width = npixels*Inh_NX + 20
int Inh_view_height = npixels*Inh_NY + 10
if ({exists /Inh_netview}) // make a new one of the right size
delete /Inh_netview
end
create xform /Inh_netview [680,{20 + Ex_view_height}, \
{Inh_view_width + npixels}, {Inh_view_height}]
create xdraw /Inh_netview/draw [0%,0%,100%, 100%]
// Make the display region a little larger than the cell array
setfield /Inh_netview/draw xmin {-Inh_SEP_X} xmax {Inh_NX*Inh_SEP_X} \
ymin {-Inh_SEP_Y} ymax {Inh_NY*Inh_SEP_Y}
create xview /Inh_netview/draw/view
setfield /Inh_netview/draw/view value_min -0.08 value_max 0.03 \
viewmode colorview sizescale {Inh_SEP_X}
/*
if({hflag} && {hsolve_chanmode > 1})
setfield /Inh_netview/draw/view path /Inh_layer/{Inh_cell_name}[]/solver \
field {findsolvefield /Inh_layer/{Inh_cell_name}[]/solver soma Vm}
else
setfield /Inh_netview/draw/view path /Inh_layer/{Inh_cell_name}[]/soma \
field Vm
end
*/
setfield /Inh_netview/draw/view path /Inh_layer/{Inh_cell_name}[]/soma \
field Vm
xshow /Inh_netview
end