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

Add/fix checks that inline expressions, parameters and internals cannot be assigned to #953

Merged
merged 17 commits into from
Sep 18, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
44e5ae1
add/fix checks that inline expressions, parameters and internals cann…
Sep 12, 2023
a172ff9
add/fix checks that inline expressions, parameters and internals cann…
Sep 12, 2023
ddad860
add/fix checks that inline expressions, parameters and internals cann…
Sep 12, 2023
2d36470
add/fix checks that inline expressions, parameters and internals cann…
Sep 12, 2023
ab6f934
move model state initialization to Node::init_state_()
Sep 13, 2023
e72b21c
add/fix checks that inline expressions, parameters and internals cann…
Sep 13, 2023
509d511
add/fix checks that inline expressions, parameters and internals cann…
Sep 13, 2023
be71111
Merge remote-tracking branch 'upstream/master' into coco_set_internal
Sep 13, 2023
c6978c4
add/fix checks that inline expressions, parameters and internals cann…
Sep 13, 2023
bb7e518
add/fix checks that inline expressions, parameters and internals cann…
Sep 14, 2023
ba6bedf
improve handling of NEST synaptic delay parameter
Sep 14, 2023
4849881
add/fix checks that inline expressions, parameters and internals cann…
Sep 14, 2023
af78bc8
add/fix checks that inline expressions, parameters and internals cann…
Sep 14, 2023
727784b
Merge remote-tracking branch 'upstream/master' into coco_set_internal
Sep 15, 2023
d042e7d
Update doc/nestml_language/nestml_language_concepts.rst
clinssen Sep 15, 2023
b85a369
add/fix checks that inline expressions, parameters and internals cann…
Sep 15, 2023
1b29681
Merge remote-tracking branch 'upstream/master' into coco_set_internal
Sep 18, 2023
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
Original file line number Diff line number Diff line change
Expand Up @@ -217,8 +217,6 @@ std::vector< std::tuple< int, int > > {{neuronName}}::rport_to_nestml_buffer_idx

{{neuronName}}::{{neuronName}}():{{neuron_parent_class}}(), P_(), S_(), B_(*this)
{
const double __resolution = nest::Time::get_resolution().get_ms(); // do not remove, this is necessary for the resolution() function

init_state_internal_();

{%- if has_state_vectors %}
Expand Down Expand Up @@ -337,6 +335,8 @@ void {{neuronName}}::init_state_internal_()
std::cout << "{{neuronName}}::init_state_internal_()" << std::endl;
#endif

const double __resolution = nest::Time::get_resolution().get_ms(); // do not remove, this is necessary for the resolution() function

{%- if uses_numeric_solver %}
{%- if numeric_solver == "rk45" %}

Expand Down
173 changes: 46 additions & 127 deletions tests/nest_tests/third_factor_stdp_synapse_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,11 @@
except Exception:
TEST_PLOTS = False

sim_mdl = True
sim_ref = False


class NestThirdFactorSTDPSynapseTest(unittest.TestCase):

neuron_model_name = "iaf_psc_exp_dend__with_third_factor_stdp"
ref_neuron_model_name = "iaf_psc_exp_nestml_non_jit"

synapse_model_name = "third_factor_stdp__with_iaf_psc_exp_dend"
ref_synapse_model_name = "third_factor_stdp_synapse"

post_trace_var = "I_dend"

Expand Down Expand Up @@ -87,9 +81,7 @@ def test_nest_stdp_synapse(self):
pre_spike_times = np.sort(np.unique(1 + np.round(500 * np.sort(np.abs(np.random.randn(500)))))) # [ms]

self.run_synapse_test(neuron_model_name=self.neuron_model_name,
ref_neuron_model_name=self.ref_neuron_model_name,
synapse_model_name=self.synapse_model_name,
ref_synapse_model_name=self.ref_synapse_model_name,
resolution=.5, # [ms]
delay=1.5, # [ms]
pre_spike_times=pre_spike_times,
Expand All @@ -98,9 +90,7 @@ def test_nest_stdp_synapse(self):
fname_snip=fname_snip)

def run_synapse_test(self, neuron_model_name,
ref_neuron_model_name,
synapse_model_name,
ref_synapse_model_name,
resolution=1., # [ms]
delay=1., # [ms]
sim_time=None, # if None, computed from pre and post spike times
Expand Down Expand Up @@ -132,12 +122,8 @@ def run_synapse_test(self, neuron_model_name,
nest.SetKernelStatus({"resolution": resolution})

wr = nest.Create("weight_recorder")
wr_ref = nest.Create("weight_recorder")
nest.CopyModel(synapse_model_name, "stdp_nestml_rec",
{"weight_recorder": wr[0], "w": 1., "d": 1., "receptor_type": 0, "lambda": .001})
if sim_ref:
nest.CopyModel(ref_synapse_model_name, "stdp_ref_rec",
{"weight_recorder": wr_ref[0], "weight": 1., "delay": 1., "receptor_type": 0, "lambda": .001})

# create spike_generators with these times
pre_sg = nest.Create("spike_generator",
Expand All @@ -147,66 +133,33 @@ def run_synapse_test(self, neuron_model_name,
"allow_offgrid_times": True})

# create parrot neurons and connect spike_generators
if sim_mdl:
pre_neuron = nest.Create("parrot_neuron")
post_neuron = nest.Create(neuron_model_name)

if sim_ref:
pre_neuron_ref = nest.Create("parrot_neuron")
post_neuron_ref = nest.Create(ref_neuron_model_name)

if sim_mdl:
if nest_version.startswith("v2"):
spikedet_pre = nest.Create("spike_detector")
spikedet_post = nest.Create("spike_detector")
else:
spikedet_pre = nest.Create("spike_recorder")
spikedet_post = nest.Create("spike_recorder")
mm = nest.Create("multimeter", params={"record_from": ["V_m", self.post_trace_var]})
if sim_ref:
if nest_version.startswith("v2"):
spikedet_pre_ref = nest.Create("spike_detector")
spikedet_post_ref = nest.Create("spike_detector")
else:
spikedet_pre_ref = nest.Create("spike_recorder")
spikedet_post_ref = nest.Create("spike_recorder")
mm_ref = nest.Create("multimeter", params={"record_from": ["V_m"]})

if sim_mdl:
nest.Connect(pre_sg, pre_neuron, "one_to_one", syn_spec={"delay": 1.})
nest.Connect(post_sg, post_neuron, "one_to_one", syn_spec={"delay": 1., "weight": 9999.})
if nest_version.startswith("v2"):
nest.Connect(pre_neuron, post_neuron, "all_to_all", syn_spec={"model": "stdp_nestml_rec"})
else:
nest.Connect(pre_neuron, post_neuron, "all_to_all", syn_spec={"synapse_model": "stdp_nestml_rec"})
nest.Connect(mm, post_neuron)
nest.Connect(pre_neuron, spikedet_pre)
nest.Connect(post_neuron, spikedet_post)
if sim_ref:
nest.Connect(pre_sg, pre_neuron_ref, "one_to_one", syn_spec={"delay": 1.})
nest.Connect(post_sg, post_neuron_ref, "one_to_one", syn_spec={"delay": 1., "weight": 9999.})
if nest_version.startswith("v2"):
nest.Connect(pre_neuron_ref, post_neuron_ref, "all_to_all",
syn_spec={"model": ref_synapse_model_name})
else:
nest.Connect(pre_neuron_ref, post_neuron_ref, "all_to_all",
syn_spec={"synapse_model": ref_synapse_model_name})
nest.Connect(mm_ref, post_neuron_ref)
nest.Connect(pre_neuron_ref, spikedet_pre_ref)
nest.Connect(post_neuron_ref, spikedet_post_ref)
pre_neuron = nest.Create("parrot_neuron")
post_neuron = nest.Create(neuron_model_name)

if nest_version.startswith("v2"):
spikedet_pre = nest.Create("spike_detector")
spikedet_post = nest.Create("spike_detector")
else:
spikedet_pre = nest.Create("spike_recorder")
spikedet_post = nest.Create("spike_recorder")
mm = nest.Create("multimeter", params={"record_from": ["V_m", self.post_trace_var]})

nest.Connect(pre_sg, pre_neuron, "one_to_one", syn_spec={"delay": 1.})
nest.Connect(post_sg, post_neuron, "one_to_one", syn_spec={"delay": 1., "weight": 9999.})
if nest_version.startswith("v2"):
nest.Connect(pre_neuron, post_neuron, "all_to_all", syn_spec={"model": "stdp_nestml_rec"})
else:
nest.Connect(pre_neuron, post_neuron, "all_to_all", syn_spec={"synapse_model": "stdp_nestml_rec"})
nest.Connect(mm, post_neuron)
nest.Connect(pre_neuron, spikedet_pre)
nest.Connect(post_neuron, spikedet_post)

# get STDP synapse and weight before protocol
if sim_mdl:
syn = nest.GetConnections(source=pre_neuron, synapse_model="stdp_nestml_rec")
if sim_ref:
syn_ref = nest.GetConnections(source=pre_neuron_ref, synapse_model=ref_synapse_model_name)
syn = nest.GetConnections(source=pre_neuron, synapse_model="stdp_nestml_rec")

t = 0.
t_hist = []
if sim_mdl:
w_hist = []
if sim_ref:
w_hist_ref = []
w_hist = []
state = 0
while t <= sim_time:
if t > sim_time / 6. and state == 0:
Expand All @@ -219,10 +172,7 @@ def run_synapse_test(self, neuron_model_name,
nest.Simulate(resolution)
t += resolution
t_hist.append(t)
if sim_ref:
w_hist_ref.append(nest.GetStatus(syn_ref)[0]["weight"])
if sim_mdl:
w_hist.append(nest.GetStatus(syn)[0]["w"])
w_hist.append(nest.GetStatus(syn)[0]["w"])

third_factor_trace = nest.GetStatus(mm, "events")[0][self.post_trace_var]
timevec = nest.GetStatus(mm, "events")[0]["times"]
Expand All @@ -231,15 +181,9 @@ def run_synapse_test(self, neuron_model_name,
fig, ax = plt.subplots(nrows=2)
ax1, ax2 = ax

if sim_mdl:
V_m = nest.GetStatus(mm, "events")[0]["V_m"]
ax2.plot(timevec, third_factor_trace, label="I_dend_post")
ax1.plot(timevec, V_m, alpha=.7, linestyle=":")
if sim_ref:
pre_ref_spike_times_ = nest.GetStatus(spikedet_pre_ref, "events")[0]["times"]
timevec_ = nest.GetStatus(mm_ref, "events")[0]["times"]
V_m_ = nest.GetStatus(mm_ref, "events")[0]["V_m"]
ax1.plot(timevec_, V_m_, label="nest ref", alpha=.7)
V_m = nest.GetStatus(mm, "events")[0]["V_m"]
ax2.plot(timevec, third_factor_trace, label="I_dend_post")
ax1.plot(timevec, V_m, alpha=.7, linestyle=":")
ax1.set_ylabel("V_m")

for _ax in ax:
Expand All @@ -254,47 +198,24 @@ def run_synapse_test(self, neuron_model_name,
fig, ax = plt.subplots(nrows=5)
ax1, ax2, ax3, ax4, ax5 = ax

if sim_mdl:
pre_spike_times_ = nest.GetStatus(spikedet_pre, "events")[0]["times"]
print("Actual pre spike times: " + str(pre_spike_times_))
if sim_ref:
pre_ref_spike_times_ = nest.GetStatus(spikedet_pre_ref, "events")[0]["times"]
print("Actual pre ref spike times: " + str(pre_ref_spike_times_))

if sim_mdl:
n_spikes = len(pre_spike_times_)
for i in range(n_spikes):
ax1.plot(2 * [pre_spike_times_[i] + delay], [0, 1], linewidth=2, color="blue", alpha=.4)

if sim_mdl:
post_spike_times_ = nest.GetStatus(spikedet_post, "events")[0]["times"]
print("Actual post spike times: " + str(post_spike_times_))
if sim_ref:
post_ref_spike_times_ = nest.GetStatus(spikedet_post_ref, "events")[0]["times"]
print("Actual post ref spike times: " + str(post_ref_spike_times_))

if sim_ref:
n_spikes = len(pre_ref_spike_times_)
for i in range(n_spikes):
ax1.plot(2 * [pre_ref_spike_times_[i] + delay], [0, 1], linewidth=2, color="cyan", alpha=.4)
pre_spike_times_ = nest.GetStatus(spikedet_pre, "events")[0]["times"]
print("Actual pre spike times: " + str(pre_spike_times_))

n_spikes = len(pre_spike_times_)
for i in range(n_spikes):
ax1.plot(2 * [pre_spike_times_[i] + delay], [0, 1], linewidth=2, color="blue", alpha=.4)

post_spike_times_ = nest.GetStatus(spikedet_post, "events")[0]["times"]
print("Actual post spike times: " + str(post_spike_times_))
ax1.set_ylabel("Pre spikes")

if sim_mdl:
n_spikes = len(post_spike_times_)
for i in range(n_spikes):
if i == 0:
_lbl = "nestml"
else:
_lbl = None
ax[-4].plot(2 * [post_spike_times_[i]], [0, 1], linewidth=2, color="black", alpha=.4, label=_lbl)
if sim_ref:
n_spikes = len(post_ref_spike_times_)
for i in range(n_spikes):
if i == 0:
_lbl = "nest ref"
else:
_lbl = None
ax[-4].plot(2 * [post_ref_spike_times_[i]], [0, 1], linewidth=2, color="red", alpha=.4, label=_lbl)
n_spikes = len(post_spike_times_)
for i in range(n_spikes):
if i == 0:
_lbl = "nestml"
else:
_lbl = None
ax[-4].plot(2 * [post_spike_times_[i]], [0, 1], linewidth=2, color="black", alpha=.4, label=_lbl)
ax[-4].set_ylabel("Post spikes")

ax[-3].plot(timevec, third_factor_trace)
Expand All @@ -304,25 +225,23 @@ def run_synapse_test(self, neuron_model_name,
ax[-2].set_ylabel(u"Δw")

ax[-1].plot(t_hist, w_hist, marker="o")
if sim_ref:
ax[-1].plot(t_hist, w_hist_ref, linestyle="--", marker="x", label="ref")
ax[-1].set_ylabel("w")

ax[-1].set_xlabel("Time [ms]")
for _ax in ax:
if not _ax == ax[-1]:
_ax.set_xticklabels([])
_ax.grid(which="major", axis="both")
_ax.xaxis.set_major_locator(matplotlib.ticker.FixedLocator(np.arange(0, np.ceil(sim_time))))
_ax.set_xlim(0., sim_time)

fig.savefig("/tmp/stdp_third_factor_synapse_test" + fname_snip + ".png", dpi=300)

# verify
MAX_ABS_ERROR = 1E-6
idx = np.where(np.abs(third_factor_trace) < 1E-3)[0] # find where third_factor_place is (almost) zero
idx = np.where(np.abs(third_factor_trace) < 1E-3)[0] # find where third_factor_trace is (almost) zero
times_dw_should_be_zero = timevec[idx]
for time_dw_should_be_zero in times_dw_should_be_zero:
for time_dw_should_be_zero in times_dw_should_be_zero[:-1]:
_idx = np.argmin((time_dw_should_be_zero - np.array(t_hist))**2)
assert np.abs(np.diff(w_hist)[_idx]) < MAX_ABS_ERROR
assert np.abs(np.diff(w_hist)[_idx + 1]) < MAX_ABS_ERROR
clinssen marked this conversation as resolved.
Show resolved Hide resolved

assert np.any(np.abs(np.array(w_hist) - 1) > MAX_ABS_ERROR), "No change in the weight!"
Loading