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

Fixed bug where treeChange update to ERev always uses T=37 #7

Open
wants to merge 6 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
10 changes: 6 additions & 4 deletions neurodemo/channelparam.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ def __init__(self, ion: IonClass):
dict(name='[C]out', type='float', value=ion.Cout, suffix='mM', siPrefix=True, step=1),
dict(name='[C]in', type='float', value=ion.Cin, suffix='mM', siPrefix=True, step=1),
]
self.temperatureC = 37.
self.ion.Erev = self.Nernst(ion)
self.ion_params.append(dict(name="Erev", type='float', value=self.ion.Erev, suffix='V', siPrefix=True, readonly=True))
pt.parameterTypes.GroupParameter.__init__(self, name=name, type='group',
Expand All @@ -72,12 +73,13 @@ def treeChange(self, root, changes: list[tuple[pt.Parameter, str, typing.Any]]):
self.ion.Cin = val
self['Erev'] = self.Nernst(self.ion)

def updateErev(self, temp:float=37.):
self['Erev']=self.Nernst(self.ion, temp=temp)
def updateTemperature(self, temp:float=37.):
self.temperatureC = temp
self['Erev']=self.Nernst(self.ion)

def Nernst(self, ion, temp:float=37.):
def Nernst(self, ion):
R = 8.135 # J/K/M
F = 96840 # C/M
RTF = R*(273.16+temp)/F
RTF = R*(273.16+self.temperatureC)/F
Er = (2.303*RTF/ion.valence)*np.log10(ion.Cout/ion.Cin)
return Er
10 changes: 10 additions & 0 deletions neurodemo/clampparam.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,13 @@ def __init__(self, clamp: neurodemo.neuronsim.PatchClamp, sim: neurodemo.main_wi
dict(name="Plot Current", type="bool", value=False),
dict(name="Plot Voltage", type="bool", value=False),
dict(name="Plot Command", type="bool", value=False),
dict(name="Cursor values",
type="group",
children=[
dict(name="Relative time", type="float", value=0.0, suffix="s", siPrefix=True, step=0.0001),
dict(name="Memb voltage", type="float", value=0.0, suffix="V", siPrefix=True),
dict(name="Command", type="float", value=0.0, suffix="A", siPrefix=True),
]),
dict(
name="Pulse",
type="group",
Expand Down Expand Up @@ -243,6 +250,9 @@ def set_mode(self, mode):
self.child("Holding").setOpts(
suffix=suff, value=self.clamp.holding[mode], step=step
)

self.child("Cursor values", "Command").setOpts(suffix=suff)

self.child("Pulse", "Pre-amplitude").setOpts(suffix=suff, value=pre_amp, step=step)
self.child("Pulse", "Post-amplitude").setOpts(suffix=suff, value=post_amp, step=step)
self.child("Pulse", "Amplitude").setOpts(suffix=suff, value=amp, step=step)
Expand Down
64 changes: 31 additions & 33 deletions neurodemo/main_window.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,12 +127,15 @@ def __init__(self, multiprocessing=False):
]

for ch in self.channel_params:
# These will use default Erev values defined in neuronsim.py, Section(SimObject) class, which
# are INDEPENDENT of values defined in self.use_default_erev(). Consider replacing both with
# calculated Erev.
ch.plots_changed.connect(self.plots_changed)

self.ion_concentrations = [IonConcentrations(ion) for ion in ions.all_ions]
for ion in self.ion_concentrations:
ion.updateErev(self.sim.temp) # match temperature with an update
ion.updateTemperature(self.sim.temp) # match temperature with an update

self.params = pt.Parameter.create(name='Parameters', type='group', children=[
dict(name='Preset', type='list', value='HH AP', limits=['Passive', 'HH AP', 'LG AP']),
dict(name='Run/Stop', type='action', value=False),
Expand All @@ -145,14 +148,16 @@ def __init__(self, multiprocessing=False):
dict(name='Capacitance', type='float', value=self.neuron.cap, limits=[0.1e-12, 1000.e-12], suffix='F', siPrefix=True, dec=True, children=[
dict(name='Plot Current', type='bool', value=False),
]),
dict(name='Ions', type='bool', children=self.ion_concentrations),
dict(name='Ions', type='group', children=self.ion_concentrations),
dict(name='Cell Schematic', type='bool', value=True, children=[
dict(name='Show Circuit', type='bool', value=False),
]),
# self.clamp_param, # now in the adjacent window
dict(name='Ion Channels', type='group', children=self.channel_params),
])

self.use_calculated_erev()

# Now that add_plot() sets x-axis limits, it must be called AFTER defining self.params,
# rather than before, since it uses "Plot Duration" field in self.params.
self.vm_plot = self.add_plot('soma.V', 'Membrane Potential', 'V')
Expand Down Expand Up @@ -217,7 +222,7 @@ def params_changed(self, root, changes):
self.sim.temp = val
# also update the ion channel values = specifically Erev
for ion in self.ion_concentrations:
ion.updateErev(self.sim.temp)
ion.updateTemperature(self.sim.temp)
elif param is self.params.child('Capacitance'):
self.neuron.cap = val
elif param is self.params.child('Capacitance', 'Plot Current'):
Expand All @@ -231,20 +236,22 @@ def params_changed(self, root, changes):
self.neuronview.setVisible(val)
elif param is self.params.child('Cell Schematic', 'Show Circuit'):
self.neuronview.show_circuit(val)
elif param is self.params.child('Ions'):
if val: # checkbox checked
self.use_calculated_erev()
else: # not checked
self.use_default_erev()
elif param in [ # change in ion concentrations and erev...
elif param in [ # change in ion concentrations and erev...
self.params.child('Ions', "Na", "[C]in"),
self.params.child('Ions', "Na", "[C]out"),
self.params.child('Ions', "K", "[C]in"),
self.params.child('Ions', "K", "[C]out"),
self.params.child('Ions', "Cl", "[C]in"),
self.params.child('Ions', "Cl", "[C]out"),
] and self.params.child('Ions').value():
]:
self.use_calculated_erev() # force update of erevs
elif param in self.params.child('Ion Channels'):
if not param.value():
# When turning ion off, also remove any plots associated with this ion
for p in param.children():
if p.name().startswith('Plot') and p.value():
# Turn off any plots that are currently ON
p.setValue(False)

def plots_changed(self, param, channel, name, plot):
key = channel.name + '.' + name
Expand Down Expand Up @@ -353,7 +360,19 @@ def set_hover_time(self, t):
plt.hover_line.setPos(t)
state = self.result_buffer.get_state_at_time(t)
if state is not None:
self.neuronview.update_state(state)
self.clamp_param['Cursor values', 'Relative time'] = t
if 'soma.V' in self.clamp_param.plot_keys:
self.clamp_param['Cursor values', 'Memb voltage'] = state['soma.V']
if 'soma.PatchClamp.cmd' in self.channel_plots.keys():
# Command values are not in the state variable, so we grab them out of the actual plot object
plt: ScrollingPlot = self.channel_plots['soma.PatchClamp.cmd']
dc: pg.PlotDataItem = plt.data_curve
[x, y] = [dc.xData, dc.yData]
dx = x[1] - x[0]
idx = int(t / dx) # Note that t will be negative, since it represents time before present. This will make idx negative, so index will count from end
if idx >= -len(y):
self.clamp_param['Cursor values', 'Command'] = y[idx]
self.neuronview.update_state(state)

def running(self):
return self.runner.running()
Expand Down Expand Up @@ -492,20 +511,6 @@ def use_calculated_erev(self):
self.set_hh_erev(ENa_erev, EK_erev, Eleak_erev, Eh_erev)
self.set_lg_erev(ENa_erev, EK_erev, EK_erev, -55*NU.mV)

def use_default_erev(self):
chans: pt.Parameter = self.params.child('Ion Channels')
ENa_revs = {"INa": 50*NU.mV, "INa1": 74*NU.mV}
for ch in ["INa", "INa1"]:
chans[f"soma.{ch:s}", 'Erev'] = ENa_revs[ch]
EK_revs = {"IK": -74*NU.mV, "IKf": -90*NU.mV, "IKs": -90*NU.mV}
for ch in ["IK", "IKf", "IKs"]:
chans[f"soma.{ch:s}", 'Erev'] = EK_revs[ch]
Eh_revs = {"IH": -43*NU.mV,}
for ch in ["IH"]:
chans[f"soma.{ch:s}", 'Erev'] = Eh_revs[ch]
self.set_hh_erev(ENa_revs["INa"], EK_revs["IK"], -55*NU.mV, Eh_revs["IH"])
self.set_lg_erev(ENa_revs["INa1"], EK_revs["IKf"], EK_revs["IKs"], -55*NU.mV, )

def set_hh_erev(self, ENa_erev=50*NU.mV, EK_erev=-74*NU.mV,
Eleak_erev=-55*NU.mV, Eh_erev=-43*NU.mV):
"""Set new reversal potentials for the HH currents
Expand Down Expand Up @@ -536,13 +541,6 @@ def set_lg_erev(self, ENa_erev=74*NU.mV, EKf_erev=-90*NU.mV,
self.lgks.set_erev(EKs_erev)
self.leak.set_erev(Eleak_erev)

def set_ions_off(self):
"""Turn off use of ion concentrations, and reset
all of the checkboxes associated with those.
"""
self.params.child('Ions', 'Na').setValue(False)
self.params.child('Ions', 'K').setValue(False)
self.params.child('Ions', 'Cl').setValue(False)

def load_preset(self, preset):
"""Load preset configurations for the simulations.
Expand Down
95 changes: 0 additions & 95 deletions pgtest.py

This file was deleted.

60 changes: 0 additions & 60 deletions setup_win.spec

This file was deleted.

Loading