import ipywidgets import numpy as np import pylab as plt from traitlets import link #running current (default) or voltage clamp runMode = 'iclamp' #default input parameters default_capacitance = 1 default_cond_Na = 120 default_cond_K = 36 default_cond_L = 0.3 default_E_Na = 63.54 default_E_K = -74.16 default_E_L = -54.3 default_t0 = 0 default_tn = 50 default_deltat = 0.01 default_ic_amplitude = 2.0 default_ic_duration = 25 default_ic_delay = 5 #voltage clamp default values default_vc_delay = 10 default_vc_duration = 30 default_condVoltage = -65 default_testVoltage = 10 default_returnVoltage = -65 default_tn_vclamp = 50 default_deltat_vclamp = 0.0005 #function to reset input values to default on button click def resetTodefault(_): slider_capacitance.value = default_capacitance slider_cond_Na.value = default_cond_Na slider_cond_K.value = default_cond_K slider_cond_L.value = default_cond_L slider_E_Na.value = default_E_Na slider_E_K.value = default_E_K slider_E_L.value = default_E_L time_end.value = default_tn time_step.value = default_deltat slider_amplitude.value = default_ic_amplitude slider_width.value = default_ic_duration slider_translation.value = default_ic_delay #voltage clamp slider_delay.value = default_vc_delay slider_duration.value = default_vc_duration slider_condVoltage.value = default_condVoltage slider_testVoltage.value = default_testVoltage slider_returnVoltage.value = default_returnVoltage #default runMode runMode_togglebtns.value='Current Clamp' def showDefault(response): if showValue_togglebtn.value: defalultValues.layout.display = '' else: defalultValues.layout.display = 'none' def runModeChange(c): global runMode if runMode_togglebtns.value=='Current Clamp': runMode_iclamp.layout.display = '' runMode_vclamp.layout.display = 'none' runMode = 'iclamp' time_step.value = default_deltat time_end.value = default_tn else: runMode_iclamp.layout.display = 'none' runMode_vclamp.layout.display = '' runMode = 'vclamp' time_end.value = default_tn_vclamp time_step.value = default_deltat_vclamp #function to change slider handle colour when move from default def highlight_slider(): inputList = [slider_capacitance, slider_cond_Na, slider_cond_K, slider_cond_L, slider_E_Na, slider_E_K, slider_E_L, slider_amplitude, slider_width, slider_translation, slider_delay, slider_duration, slider_condVoltage, slider_testVoltage, slider_returnVoltage] inputDefault = [default_capacitance, default_cond_Na, default_cond_K, default_cond_L, default_E_Na, default_E_K, default_E_L, default_ic_amplitude, default_ic_duration, default_ic_delay, default_vc_delay, default_vc_duration, default_condVoltage, default_testVoltage, default_returnVoltage] for l, d in zip(inputList,inputDefault): if l.value == d: l.style.handle_color = 'white' else: l.style.handle_color = 'orange' #defining the widgets #Header or texts as HTMLMath to include symbols header_capacitance = ipywidgets.HTMLMath(value=r" Membrane Capacitance, \(\mu{F}/cm^2\)") header_conductance = ipywidgets.HTMLMath(value=r" Maximum Conductances, \(mS/cm^2\)") header_potential = ipywidgets.HTMLMath(value=r" Reversal Potentials, \(mV\)") header_simTime = ipywidgets.HTMLMath(value=r" Simulation Time, \(ms\)") header_injCurrent = ipywidgets.HTMLMath(value=r" Injection Current, \(\mu{A}/cm^2\) (or \(pA\) if cell has area 100 \(\mu{m}^2\))") header_runMode = ipywidgets.HTML(value=r"Select Run Mode") header_vclamp_time = ipywidgets.HTMLMath(value=r" Time, \(ms\)") header_vclamp_volt = ipywidgets.HTMLMath(value=r" Voltage, \(mV\)") #slider widgets slider_capacitance = ipywidgets.FloatSlider(value=default_capacitance,min=0,max=3,step=0.1,description='Capacitance',readout=False,continuous_update=False) slider_cond_Na = ipywidgets.FloatSlider(value=default_cond_Na,min=0,max=160,step=0.1,description='Sodium',readout=False,continuous_update=False) slider_cond_K = ipywidgets.FloatSlider(value=default_cond_K,min=0,max=80,step=0.1,description='Potassium',readout=False,continuous_update=False) slider_cond_L = ipywidgets.FloatSlider(value=default_cond_L,min=0,max=1,step=0.1,description='Leak',readout=False,continuous_update=False) slider_E_Na = ipywidgets.FloatSlider(value=default_E_Na,min=-100,max=100,step=0.1,description='Sodium',readout=False,continuous_update=False) slider_E_K = ipywidgets.FloatSlider(value=default_E_K,min=-100,max=100,step=0.1,description='Potassium',readout=False,continuous_update=False) slider_E_L = ipywidgets.FloatSlider(value=default_E_L,min=-100,max=100,step=0.1,description='Leak',readout=False,continuous_update=False) slider_amplitude = ipywidgets.FloatSlider(value=default_ic_amplitude,min=-20.0,max=200.0,step=0.1,description='Amplitude',readout=False,continuous_update=False) slider_width = ipywidgets.FloatSlider(value=default_ic_duration,min=0,max=500,step=0.1,description='Duration',readout=False,continuous_update=False) slider_translation = ipywidgets.FloatSlider(value=default_ic_delay,min=0,max=250,step=0.1,description='Time Delay',readout=False,continuous_update=False) #vclamp sliders slider_delay = ipywidgets.FloatSlider(value=default_vc_delay ,min=0,max=250,step=0.1,description='Time Delay',readout=False,continuous_update=False) slider_duration = ipywidgets.FloatSlider(value=default_vc_duration ,min=0,max=500,step=0.1,description='Duration',readout=False,continuous_update=False) slider_condVoltage = ipywidgets.FloatSlider(value=default_condVoltage ,min=-120,max=100,step=1,description='Conditioning',readout=False,continuous_update=False) slider_testVoltage = ipywidgets.FloatSlider(value=default_testVoltage ,min=-120,max=100,step=1,description='Testing',readout=False,continuous_update=False) slider_returnVoltage = ipywidgets.FloatSlider(value=default_returnVoltage ,min=-120,max=100,step=1,description='Returning',readout=False,continuous_update=False) #text box widgets time_end = ipywidgets.FloatText(value=default_tn,description='Total Time',disabled=False) time_step = ipywidgets.FloatText(value=default_deltat,description='Time Step',disabled=False) #text box widgets to link with sliders (included to type in values for slider inputs also) textBox_capacitance = ipywidgets.FloatText(value=default_capacitance,step=0.1,layout=ipywidgets.Layout(width='10%')) textBox_cond_Na = ipywidgets.FloatText(value=default_cond_Na,step=1,layout=ipywidgets.Layout(width='10%')) textBox_cond_K = ipywidgets.FloatText(value=default_cond_K,step=1,layout=ipywidgets.Layout(width='10%')) textBox_cond_L = ipywidgets.FloatText(value=default_cond_L,step=0.1,layout=ipywidgets.Layout(width='10%')) textBox_E_Na = ipywidgets.FloatText(value=default_E_Na,step=1,layout=ipywidgets.Layout(width='10%')) textBox_E_K = ipywidgets.FloatText(value=default_E_K,step=1,layout=ipywidgets.Layout(width='10%')) textBox_E_L = ipywidgets.FloatText(value=default_E_L,step=1,layout=ipywidgets.Layout(width='10%')) textBox_amplitude = ipywidgets.FloatText(value=default_ic_amplitude,step=1,layout=ipywidgets.Layout(width='10%')) textBox_width = ipywidgets.FloatText(value=default_ic_duration,step=1,layout=ipywidgets.Layout(width='10%')) textBox_translation = ipywidgets.FloatText(value=default_ic_delay,step=1,layout=ipywidgets.Layout(width='10%')) #voltage clamp textboxes to link with sliders textBox_delay = ipywidgets.FloatText(value=default_vc_delay,step=1,layout=ipywidgets.Layout(width='10%')) textBox_duration = ipywidgets.FloatText(value=default_vc_duration,step=1,layout=ipywidgets.Layout(width='10%')) textBox_condVoltage = ipywidgets.FloatText(value=default_condVoltage,step=1,layout=ipywidgets.Layout(width='10%')) textBox_testVoltage = ipywidgets.FloatText(value=default_testVoltage,step=1,layout=ipywidgets.Layout(width='10%')) textBox_returnVoltage = ipywidgets.FloatText(value=default_returnVoltage,step=1,layout=ipywidgets.Layout(width='10%')) #linking sliders and textbox for values link_capacitance = link((slider_capacitance, 'value'), (textBox_capacitance, 'value')) link_cond_Na = link((slider_cond_Na, 'value'), (textBox_cond_Na, 'value')) link_cond_K = link((slider_cond_K, 'value'), (textBox_cond_K, 'value')) link_cond_L = link((slider_cond_L, 'value'), (textBox_cond_L, 'value')) link_E_Na = link((slider_E_Na, 'value'), (textBox_E_Na, 'value')) link_E_K = link((slider_E_K, 'value'), (textBox_E_K, 'value')) link_E_L = link((slider_E_L, 'value'), (textBox_E_L, 'value')) link_amplitude = link((slider_amplitude, 'value'), (textBox_amplitude, 'value')) link_width = link((slider_width, 'value'), (textBox_width, 'value')) link_translation = link((slider_translation, 'value'), (textBox_translation, 'value')) #voltage clamp slider and textbox link for values link_delay = link((slider_delay , 'value'), (textBox_delay , 'value')) link_duration = link((slider_duration , 'value'), (textBox_duration , 'value')) link_condVoltage = link((slider_condVoltage , 'value'), (textBox_condVoltage , 'value')) link_testVoltage = link((slider_testVoltage , 'value'), (textBox_testVoltage , 'value')) link_returnVoltage = link((slider_returnVoltage , 'value'), (textBox_returnVoltage , 'value')) #define reset button and connect to fucntion call reset_button = ipywidgets.Button(description="Reset All",button_style='warning',tooltip='Reset to default values for all user inputs') reset_button.on_click(resetTodefault) #define toggle button for default values and connect to fucntion call showValue_togglebtn = ipywidgets.ToggleButton(value=False,description='Default Values',disabled=False,button_style='info',tooltip='Show/Hide default value below') # 'success', 'info', 'warning', 'danger' or '' showValue_togglebtn.observe(showDefault) defalultValues = ipywidgets.HTMLMath(value=r"\(C = %s\)
\(G_{Na} = %s, G_{K} = %s, G_{L} = %s\)
\(E_{Na} = %s, E_{K} = %s, E_{L} = %s\)" % \ (default_capacitance, default_cond_Na, default_cond_K, default_cond_L, default_E_Na, default_E_K, default_E_L)) defalultValues.layout.display = 'none' #define toggle buttons for iclamp/vclamp run mode runMode_togglebtns = ipywidgets.ToggleButtons(options=['Current Clamp', 'Voltage Clamp'],description='',button_style='', tooltips=['Simulate using an injected square current pulse', 'Simulate in voltage clamp mode - inject varying current to force specific voltage profile']) runMode_togglebtns.observe(runModeChange,'value') #layout widgets in column using HBox h1=ipywidgets.HBox([header_capacitance]) h2=ipywidgets.HBox([slider_capacitance, textBox_capacitance]) h3=ipywidgets.HBox([header_conductance]) h4=ipywidgets.HBox([slider_cond_Na,textBox_cond_Na,slider_cond_K,textBox_cond_K,slider_cond_L,textBox_cond_L]) h5=ipywidgets.HBox([header_potential]) h6=ipywidgets.HBox([slider_E_Na,textBox_E_Na,slider_E_K,textBox_E_K,slider_E_L,textBox_E_L]) h7=ipywidgets.HBox([header_simTime]) h8=ipywidgets.HBox([time_end,time_step]) h9=ipywidgets.HBox([header_runMode]) h10=ipywidgets.HBox([runMode_togglebtns]) #widget for current clamp mode (default) iclamp_sliders=ipywidgets.HBox([slider_amplitude,textBox_amplitude,slider_width,textBox_width,slider_translation,textBox_translation]) runMode_iclamp=ipywidgets.VBox([header_injCurrent,iclamp_sliders]) #widget for voltage clamp mode vclamp_sliders_time =ipywidgets.HBox([slider_delay,textBox_delay,slider_duration,textBox_duration]) vclamp_sliders_volt =ipywidgets.HBox([slider_condVoltage,textBox_condVoltage,slider_testVoltage,textBox_testVoltage,slider_returnVoltage,textBox_returnVoltage]) runMode_vclamp =ipywidgets.VBox([header_vclamp_time,vclamp_sliders_time,header_vclamp_volt,vclamp_sliders_volt]) runMode_vclamp.layout.display = 'none' #reset and defalult value buttons in single row button_row=ipywidgets.HBox([reset_button,showValue_togglebtn]) #plot selectors header_plotting = ipywidgets.HTMLMath(value=r" Select plots to show") injected_current_plot_value = ipywidgets.Checkbox(value=True, description="1) Current injection", disabled=False,) gating_plot_value = ipywidgets.Checkbox(value=True, description="2) Gating variables", disabled=False,) cond_scaling_value = ipywidgets.Checkbox(value=False, description="3) Conductance scaling", disabled=False,) cond_dens_plot_value = ipywidgets.Checkbox(value=True, description="4) Conductance densities", disabled=False,) driving_force_value = ipywidgets.Checkbox(value=False, description="5) Driving force", disabled=False,) current_plot_value = ipywidgets.Checkbox(value=True, description="6) Current densities", disabled=False,) memb_pot_plot_value = ipywidgets.Checkbox(value=True, description="7) Membrane potential", disabled=False,) plot_selection_row=ipywidgets.VBox([header_plotting, ipywidgets.HBox([injected_current_plot_value, gating_plot_value, cond_scaling_value, cond_dens_plot_value]), ipywidgets.HBox([driving_force_value, current_plot_value, memb_pot_plot_value])]) #layout vertically all the widgets defined above modelInputs=ipywidgets.VBox([h1,h2,h3,h4,h5,h6,h7,h8,h9,h10,runMode_iclamp,runMode_vclamp,button_row,defalultValues,plot_selection_row]) # Main method to create interactive widget def launch_interactive_widget(): import ipywidgets from importlib.machinery import SourceFileLoader # imports the module from the given path HHmodel = SourceFileLoader("HodgkinHuxley.py","../../Tutorial/Source/HodgkinHuxley.py").load_module() #function to call python script as a module def runHH(C_m, g_Na, g_K, g_L, E_Na, E_K, E_L, t_n, delta_t, I_inj_max, I_inj_width, I_inj_trans, vc_delay, vc_duration, vc_condVoltage, vc_testVoltage, vc_returnVoltage, runMode, injected_current_plot, gating_plot, cond_scaling_plot, cond_dens_plot, driving_force_plot, current_plot, memb_pot_plot): highlight_slider() runner = HHmodel.HodgkinHuxley(C_m, g_Na, g_K, g_L, E_Na, E_K, E_L, t_n, delta_t, I_inj_max, I_inj_width, I_inj_trans, vc_delay, vc_duration, vc_condVoltage, vc_testVoltage, vc_returnVoltage, runMode, injected_current_plot=injected_current_plot, gating_plot=gating_plot, cond_scaling_plot=cond_scaling_plot, cond_dens_plot=cond_dens_plot, driving_force_plot=driving_force_plot, current_plot=current_plot, memb_pot_plot=memb_pot_plot) # init_values are the steady state values for v,m,h,n at zero current injection runner.simulate(init_values=[-63.8, 0.0609, 0.5538, 0.3361]) #create plot area widget and interact with HHmodel wid_plotArea=ipywidgets.interactive_output(runHH,{'C_m':slider_capacitance, 'g_Na':textBox_cond_Na, 'g_K':textBox_cond_K, 'g_L':textBox_cond_L, 'E_Na':textBox_E_Na, 'E_K':textBox_E_K, 'E_L':textBox_E_L, 't_n':time_end, 'delta_t':time_step, 'I_inj_max':textBox_amplitude,'I_inj_width':textBox_width,'I_inj_trans':textBox_translation, 'vc_delay':textBox_delay,'vc_duration':textBox_duration,'vc_condVoltage':textBox_condVoltage, 'vc_testVoltage':textBox_testVoltage,'vc_returnVoltage':textBox_returnVoltage, 'runMode':runMode_togglebtns, 'injected_current_plot': injected_current_plot_value, 'gating_plot':gating_plot_value, 'cond_scaling_plot':cond_scaling_value, 'cond_dens_plot':cond_dens_plot_value, 'driving_force_plot':driving_force_value, 'current_plot':current_plot_value, 'memb_pot_plot':memb_pot_plot_value}) #display the widgets and plot area display(modelInputs,wid_plotArea)