Skip to content

Commit

Permalink
fixup! Default behavior is for electrodes to input membrane current i…
Browse files Browse the repository at this point in the history
…nstead of electrode current
  • Loading branch information
jorblancoa committed Apr 10, 2024
1 parent d343786 commit 7d2d937
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 26 deletions.
28 changes: 17 additions & 11 deletions neurodamus/core/stimuli.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ def __init__(self, base_amp=0.0, *, delay=0, rng=None, represents_physical_elect
Args:
base_amp: The base (resting) amplitude of the signal (Default: 0)
rng: The Random Number Generator. Used in the Noise functions
represents_physical_electrode: Whether the source represents a phsyical electrode or missing synaptic input
represents_physical_electrode: Whether the source represents a phsyical
electrode or missing synaptic input
"""
h = Neuron.h
self.stim_vec = h.Vector()
Expand Down Expand Up @@ -381,13 +382,14 @@ class _Clamp:
def __init__(self, cell_section, position=0.5, clamp_container=None,
stim_vec_mode=True, time_vec=None, stim_vec=None,
**clamp_params):

# Checks if new MembraneCurrentSource mechanism is available and if source does not represent physical electrode
if self._represents_physical_electrode == False and hasattr(Neuron.h, "MembraneCurrentSource"):
represents_physical_electrode = clamp_params.get('represents_physical_electrode', False)
# Checks if new MembraneCurrentSource mechanism is available and if source does not
# represent physical electrode, otherwise fall back to IClamp.
if not represents_physical_electrode and hasattr(Neuron.h, "MembraneCurrentSource"):
self.clamp = Neuron.h.MembraneCurrentSource(position, sec=cell_section)
else:
self.clamp = Neuron.h.IClamp(position, sec=cell_section)

if stim_vec_mode:
assert time_vec is not None and stim_vec is not None
self.clamp.dur = time_vec[-1]
Expand All @@ -405,8 +407,9 @@ def detach(self):
del self.clamp # Force del on the clamp (there might be references to self)

def attach_to(self, section, position=0.5):
return CurrentSource._Clamp(section, position, self._clamps, True,
self.time_vec, self.stim_vec)
return CurrentSource._Clamp(
section, position, self._clamps, True, self.time_vec, self.stim_vec,
represents_physical_electrode=self._represents_physical_electrode)

# Constant has a special attach_to and doesnt share any composing method
class Constant:
Expand Down Expand Up @@ -442,8 +445,10 @@ class _DynamicClamp:
def __init__(self, cell_section, position=0.5, clamp_container=None,
stim_vec_mode=True, time_vec=None, stim_vec=None,
reversal=0.0, **clamp_params):
# Checks if new conductanceSource mechanism is available and if source does not represent physical electrode
if self._represents_physical_electrode == False and hasattr(Neuron.h, "conductanceSource"):
represents_physical_electrode = clamp_params.get('represents_physical_electrode', False)
# Checks if new conductanceSource mechanism is available and if source does not
# represent physical electrode, otherwise fall back to SEClamp.
if not represents_physical_electrode and hasattr(Neuron.h, "conductanceSource"):
self.clamp = Neuron.h.conductanceSource(position, sec=cell_section)
else:
self.clamp = Neuron.h.SEClamp(position, sec=cell_section)
Expand Down Expand Up @@ -473,8 +478,9 @@ def detach(self):
del self.clamp # Force del on the clamp (there might be references to self)

def attach_to(self, section, position=0.5):
return ConductanceSource._DynamicClamp(section, position, self._clamps, True,
self.time_vec, self.stim_vec, self._reversal)
return ConductanceSource._DynamicClamp(
section, position, self._clamps, True, self.time_vec, self.stim_vec,
self._reversal, represents_physical_electrode=self._represents_physical_electrode)


# EStim class is a derivative of TStim for stimuli with an extracelular electrode. The main
Expand Down
42 changes: 27 additions & 15 deletions neurodamus/stimulus_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,8 @@ class BaseStim:
def __init__(self, _target, stim_info: dict, _cell_manager):
self.duration = float(stim_info["Duration"]) # duration [ms]
self.delay = float(stim_info["Delay"]) # start time [ms]
self.represents_physical_electrode = stim_info.get('represents_physical_electrode', False)

if 'self.represents_physical_electrode' in stim_info.keys():
self.represents_physical_electrode = stim_info['represents_physical_electrode']
else:
self.represents_physical_electrode = False

@StimulusManager.register_type
class OrnsteinUhlenbeck(BaseStim):
Expand Down Expand Up @@ -127,7 +124,10 @@ def __init__(self, target, stim_info: dict, cell_manager):

rng = random.Random123(seed1, seed2, seed3(gid)) # setup RNG
ou_args = (self.tau, self.sigma, self.mean, self.duration)
ou_kwargs = {'dt': self.dt, 'delay': self.delay, 'rng': rng, 'represents_physical_electrode':self.represents_physical_electrode}
ou_kwargs = {
'dt': self.dt, 'delay': self.delay, 'rng': rng,
'represents_physical_electrode': self.represents_physical_electrode
}
# inject Ornstein-Uhlenbeck signal
if stim_info["Mode"] == "Conductance":
cs = ConductanceSource.ornstein_uhlenbeck(*ou_args, **ou_kwargs,
Expand Down Expand Up @@ -256,7 +256,10 @@ def __init__(self, target, stim_info: dict, cell_manager):
rng = random.Random123(seed1, seed2, seed3(gid)) # setup RNG
shotnoise_args = (self.tau_D, self.tau_R, self.rate,
self.amp_mean, self.amp_var, self.duration)
shotnoise_kwargs = {'dt': self.dt, 'delay': self.delay, 'rng': rng, 'represents_physical_electrode':self.represents_physical_electrode}
shotnoise_kwargs = {
'dt': self.dt, 'delay': self.delay, 'rng': rng,
'represents_physical_electrode': self.represents_physical_electrode
}
# generate shot noise current source
if stim_info["Mode"] == "Conductance":
cs = ConductanceSource.shot_noise(*shotnoise_args, **shotnoise_kwargs,
Expand Down Expand Up @@ -458,8 +461,11 @@ def __init__(self, target, stim_info: dict, cell_manager):
continue

# generate ramp current source
cs = CurrentSource.ramp(self.amp_start, self.amp_end, self.duration,
delay=self.delay, represents_physical_electrode=self.represents_physical_electrode)
cs = CurrentSource.ramp(
self.amp_start, self.amp_end, self.duration,
delay=self.delay,
represents_physical_electrode=self.represents_physical_electrode
)
# attach current source to section
cs.attach_to(sc.sec, tpoint_list.x[sec_id])
self.stimList.append(cs) # save CurrentSource
Expand Down Expand Up @@ -584,8 +590,10 @@ def __init__(self, target, stim_info: dict, cell_manager):
continue

# generate noise current source
cs = CurrentSource.noise(self.mean, self.var, self.duration,
dt=self.dt, delay=self.delay, rng=rng, represents_physical_electrode=self.represents_physical_electrode)
cs = CurrentSource.noise(
self.mean, self.var, self.duration, dt=self.dt, delay=self.delay, rng=rng,
represents_physical_electrode=self.represents_physical_electrode
)
# attach current source to section
cs.attach_to(sc.sec, tpoint_list.x[sec_id])
self.stimList.append(cs) # save CurrentSource
Expand Down Expand Up @@ -664,8 +672,11 @@ def __init__(self, target, stim_info: dict, cell_manager):
continue

# generate pulse train current source
cs = CurrentSource.train(self.amp, self.freq, self.width,
self.duration, delay=self.delay,represents_physical_electrode=self.represents_physical_electrode)
cs = CurrentSource.train(
self.amp, self.freq, self.width, self.duration,
delay=self.delay,
represents_physical_electrode=self.represents_physical_electrode
)
# attach current source to section
cs.attach_to(sc.sec, tpoint_list.x[sec_id])
self.stimList.append(cs) # save CurrentSource
Expand Down Expand Up @@ -700,8 +711,10 @@ def __init__(self, target, stim_info: dict, cell_manager):
continue

# generate sinusoidal current source
cs = CurrentSource.sin(self.amp, self.duration, self.freq,
step=self.dt, delay=self.delay,represents_physical_electrode=self.represents_physical_electrode)
cs = CurrentSource.sin(
self.amp, self.duration, self.freq, step=self.dt, delay=self.delay,
represents_physical_electrode=self.represents_physical_electrode
)
# attach current source to section
cs.attach_to(sc.sec, tpoint_list.x[sec_id])
self.stimList.append(cs) # save CurrentSource
Expand Down Expand Up @@ -737,7 +750,6 @@ def __init__(self, target, stim_info: dict, cell_manager):
if not sc.exists():
continue


# create single electrode voltage clamp at location
seclamp = Nd.h.SEClamp(tpoint_list.x[sec_id], sec=sc.sec)

Expand Down

0 comments on commit 7d2d937

Please sign in to comment.