Skip to content

Commit

Permalink
Default behavior is for electrodes to input membrane current instead …
Browse files Browse the repository at this point in the history
…of electrode current
  • Loading branch information
joseph-tharayil committed Apr 10, 2024
1 parent ecf26d0 commit d343786
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 16 deletions.
16 changes: 12 additions & 4 deletions neurodamus/core/stimuli.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,21 @@

class SignalSource:

def __init__(self, base_amp=0.0, *, delay=0, rng=None):
def __init__(self, base_amp=0.0, *, delay=0, rng=None, represents_physical_electrode=False):
"""
Creates a new signal source, which can create composed signals
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
"""
h = Neuron.h
self.stim_vec = h.Vector()
self.time_vec = h.Vector()
self._cur_t = 0
self._base_amp = base_amp
self._rng = rng
self._represents_physical_electrode = represents_physical_electrode
if delay > .0:
self._add_point(base_amp)
self._cur_t = delay
Expand Down Expand Up @@ -379,7 +381,13 @@ 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):
self.clamp = Neuron.h.IClamp(position, sec=cell_section)

# 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"):
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 Down Expand Up @@ -434,8 +442,8 @@ 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
if hasattr(Neuron.h, "conductanceSource"):
# 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"):
self.clamp = Neuron.h.conductanceSource(position, sec=cell_section)
else:
self.clamp = Neuron.h.SEClamp(position, sec=cell_section)
Expand Down
25 changes: 13 additions & 12 deletions neurodamus/stimulus_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@ 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]

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 @@ -123,7 +127,7 @@ 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}
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 @@ -252,7 +256,7 @@ 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}
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 @@ -455,7 +459,7 @@ def __init__(self, target, stim_info: dict, cell_manager):

# generate ramp current source
cs = CurrentSource.ramp(self.amp_start, self.amp_end, self.duration,
delay=self.delay)
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 @@ -581,7 +585,7 @@ def __init__(self, target, stim_info: dict, cell_manager):

# generate noise current source
cs = CurrentSource.noise(self.mean, self.var, self.duration,
dt=self.dt, delay=self.delay, rng=rng)
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 @@ -661,7 +665,7 @@ def __init__(self, target, stim_info: dict, cell_manager):

# generate pulse train current source
cs = CurrentSource.train(self.amp, self.freq, self.width,
self.duration, delay=self.delay)
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 @@ -697,7 +701,7 @@ def __init__(self, target, stim_info: dict, cell_manager):

# generate sinusoidal current source
cs = CurrentSource.sin(self.amp, self.duration, self.freq,
step=self.dt, delay=self.delay)
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 @@ -733,12 +737,9 @@ def __init__(self, target, stim_info: dict, cell_manager):
if not sc.exists():
continue

# If conductanceSource not available, insert standard SEClamp
if hasattr(Nd.h, "conductanceSource"):
seclamp = Nd.h.conductanceSource(tpoint_list.x[sec_id], sec=sc.sec)
else:
# create single electrode voltage clamp at location
seclamp = Nd.h.SEClamp(tpoint_list.x[sec_id], sec=sc.sec)

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

seclamp.rs = self.rs
seclamp.dur1 = self.duration
Expand Down

0 comments on commit d343786

Please sign in to comment.