Validate isolated author LIF semantics without changing frozen models

This commit is contained in:
Digital Drosophila Archive
2026-09-30 07:23:09 +08:00
parent 5008cd85ca
commit 92241aea02
460 changed files with 46900 additions and 47 deletions
@@ -0,0 +1,76 @@
{
"gate": true,
"checks": {
"exact_author_source": true,
"one_poisson_input": true,
"initial_refractory_is_original": true,
"only_excited_target_loses_refractory": true,
"actual_voltage_interface": true,
"actual_N_one": true,
"actual_rate_150_hz": true,
"actual_weight_68_75_mv": true,
"actual_synapses_slot_order_zero": true,
"zero_elapsed_time": true,
"no_recorded_spikes": true,
"compile_preserves_voltage": true,
"compile_preserves_g": true,
"compile_preserves_weights": true,
"compile_preserves_refractory_configuration": true
},
"author_commit": "91bdd1e7dcf193f3e7ca5a8933497fcef63b7960",
"author_sha256": "fc45837d7122c6ce2a7f3f2f23c515992e4b232aadb919efabb72337fac88e4e",
"fixture": "two synthetic nodes, one raw_count=1 connection",
"nodes": [
-2,
-1
],
"exc_local_indices": [
0
],
"exc2_local_indices": [],
"rfc_before_ms": [
2.2,
2.2
],
"rfc_after_ms": [
0.0,
2.2
],
"poisson_inputs": [
{
"name": "poissoninput",
"type": "PoissonInput",
"target_group": "default_neurons_subgroup",
"target_local_start": 0,
"target_local_stop": 1,
"target_global_nodes": [
-2
],
"target_var": "v",
"N": 1,
"rate_hz": 150.0,
"weight_mv": 68.75,
"weight_volt": 0.06875,
"when": "synapses",
"order": 0,
"dt_ms": 0.1,
"abstract_code": "v += poissoninput_binomial()*68.75 * mvolt",
"generated_code": [
"after_run:\n import numpy as _numpy\n from brian2.codegen.runtime.numpy_rt.numpy_rt import LazyArange\n # EMPTY_CODE_BLOCK -- overwrite in child template\nbefore_run:\n import numpy as _numpy\n from brian2.codegen.runtime.numpy_rt.numpy_rt import LazyArange\n # EMPTY_CODE_BLOCK -- overwrite in child template\nrun:\n import numpy as _numpy\n from brian2.codegen.runtime.numpy_rt.numpy_rt import LazyArange\n # scalar code\n _vectorisation_idx = 1\n _lio_1 = 68.75 * mvolt\n # vector code\n _vectorisation_idx = LazyArange(N)\n _sub_idx = _array_default_neurons_subgroup__sub_idx\n v = _array_default_neurons_v[_sub_idx]\n not_refractory = _array_default_neurons_not_refractory[_sub_idx]\n v[not_refractory] += _lio_1 * poissoninput_binomial(_vectorisation_idx[not_refractory])\n _array_default_neurons_v[_sub_idx] = v\n"
]
}
],
"synaptic_weight_mv": [
0.275
],
"input_hashes": {
"completeness.csv": "06e601b217fdbc48eee57eac01cc9a9fa649ec2a1810a2e212efcd3e4b632303",
"connectivity.parquet": "34f12d50889ccf2e637d913a0f3c4104d49032a6a67f9c3fbcd52e68ce95d701"
},
"simulation_duration_ms": 0.0,
"stochastic_time_steps": 0,
"random_realization_tested": false,
"common_seed_experiment": false,
"interpretation": "Original poi adds 68.75 mV to voltage at 150 Hz with N=1 in the synapses slot and sets its target rfc to zero. This interface is not the common initial seed experiment.",
"scope": "Compile-time interface audit only; no stochastic trial, learning, or whole-brain simulation. The optional exc2 helper branch is not exercised."
}
@@ -0,0 +1,3 @@
synthetic_global_neuron_idx,local_index
-2,0
-1,1
1 synthetic_global_neuron_idx local_index
2 -2 0
3 -1 1
@@ -0,0 +1,102 @@
{
"python": "3.10.12",
"author_python": "3.10.11",
"python_patch_matches": false,
"python_executable": "/data/digital-drosophila/experiments/phase4ad-author-semantics/environment/.venv/bin/python",
"platform": "Linux-5.15.0-194-generic-x86_64-with-glibc2.35",
"author_platform": "Windows",
"packages": {
"brian2": {
"expected": "2.5.1",
"actual": "2.5.1",
"matches": true
},
"numpy": {
"expected": "1.22.3",
"actual": "1.22.3",
"matches": true
},
"pandas": {
"expected": "1.4.3",
"actual": "1.4.3",
"matches": true
},
"scipy": {
"expected": "1.8.1",
"actual": "1.8.1",
"matches": true
},
"pyarrow": {
"expected": "11.0.0",
"actual": "11.0.0",
"matches": true
},
"joblib": {
"expected": "1.2.0",
"actual": "1.2.0",
"matches": true
},
"cython": {
"expected": "0.29.33",
"actual": "0.29.33",
"matches": true
},
"jinja2": {
"expected": "2.11.3",
"actual": "2.11.3",
"matches": true
},
"markupsafe": {
"expected": "1.1.1",
"actual": "1.1.1",
"matches": true
},
"sympy": {
"expected": "1.12",
"actual": "1.12",
"matches": true
},
"mpmath": {
"expected": "1.3.0",
"actual": "1.3.0",
"matches": true
},
"pyparsing": {
"expected": "3.0.9",
"actual": "3.0.9",
"matches": true
},
"packaging": {
"expected": "23.1",
"actual": "23.1",
"matches": true
},
"setuptools": {
"expected": "67.8.0",
"actual": "67.8.0",
"matches": true
},
"python-dateutil": {
"expected": "2.8.2",
"actual": "2.8.2",
"matches": true
},
"pytz": {
"expected": "2023.3",
"actual": "2023.3",
"matches": true
},
"six": {
"expected": "1.16.0",
"actual": "1.16.0",
"matches": true
},
"wheel": {
"expected": "0.38.4",
"actual": "0.38.4",
"matches": true
}
},
"all_package_pins_match": true,
"binary_identical_author_environment_claimed": false
}
@@ -0,0 +1,119 @@
[
{
"name": "default_neurons",
"type": "NeuronGroup",
"when": "start",
"order": 0,
"active": true,
"code_objects": []
},
{
"name": "default_synapses",
"type": "Synapses",
"when": "start",
"order": 0,
"active": true,
"code_objects": []
},
{
"name": "default_neurons_stateupdater",
"type": "StateUpdater",
"when": "groups",
"order": 0,
"active": true,
"abstract_code": "not_refractory = timestep(t - lastspike, dt) >= timestep(rfc, dt)\n_g = g*exp(-dt*int(not_refractory)/tau)\n_v = g*tau*(-exp(dt*int(not_refractory)/t_mbr) + exp(dt*int(not_refractory)/tau))*exp(-dt*int(not_refractory)/t_mbr)*exp(-dt*int(not_refractory)/tau)/(t_mbr - tau) + v*exp(-dt*int(not_refractory)/t_mbr) + v_0 - v_0*exp(-dt*int(not_refractory)/t_mbr)\ng = _g\nv = _v",
"user_code": "g = -g*int(not_refractory)/tau\nv = (g - v + v_0)*int(not_refractory)/t_mbr",
"code_objects": [
{
"name": "default_neurons_stateupdater_codeobject_7",
"type": "CallableProxyType",
"generated_code": "after_run:\n import numpy as _numpy\n from brian2.codegen.runtime.numpy_rt.numpy_rt import LazyArange\n # EMPTY_CODE_BLOCK -- overwrite in child template\nbefore_run:\n import numpy as _numpy\n from brian2.codegen.runtime.numpy_rt.numpy_rt import LazyArange\n # EMPTY_CODE_BLOCK -- overwrite in child template\nrun:\n import numpy as _numpy\n from brian2.codegen.runtime.numpy_rt.numpy_rt import LazyArange\n # scalar code\n _vectorisation_idx = 1\n dt = _array_defaultclock_dt[0]\n _lio_1 = (- dt) / tau\n _lio_2 = exp(_lio_1)\n _lio_3 = tau / (t_mbr - tau)\n _lio_4 = dt / t_mbr\n _lio_5 = dt / tau\n _lio_6 = (- dt) / t_mbr\n _lio_7 = v_0 - v_0\n _lio_8 = v_0 - (v_0 * exp(_lio_6))\n _lio_9 = ((_lio_3 * ((- exp(_lio_4)) + exp(_lio_5))) * exp(_lio_6)) * exp(_lio_1)\n _lio_10 = exp(_lio_6)\n # vector code\n _vectorisation_idx = LazyArange(N)\n g = _array_default_neurons_g.copy()\n t = _array_defaultclock_t[0]\n dt = _array_defaultclock_dt[0]\n rfc = _array_default_neurons_rfc\n v = _array_default_neurons_v.copy()\n lastspike = _array_default_neurons_lastspike\n not_refractory = _array_default_neurons_not_refractory.copy()\n not_refractory = timestep(t - lastspike, dt) >= timestep(rfc, dt)\n _g = _numpy.where(not_refractory, _lio_2 * g, g)\n _v = _numpy.where(not_refractory, _lio_8 + ((_lio_9 * g) + (_lio_10 * v)), _lio_7 + v)\n g[not_refractory] = _g[not_refractory]\n v[not_refractory] = _v[not_refractory]\n _array_default_neurons_g[:] = g\n _array_default_neurons_v[:] = v\n _array_default_neurons_not_refractory[:] = not_refractory\n"
}
]
},
{
"name": "default_neurons_spike_thresholder",
"type": "Thresholder",
"when": "thresholds",
"order": 0,
"active": true,
"abstract_code": "_cond = (v > v_th) and not_refractory",
"user_code": "_cond = v > v_th",
"code_objects": [
{
"name": "default_neurons_spike_thresholder_codeobject_7",
"type": "CallableProxyType",
"generated_code": "after_run:\n import numpy as _numpy\n from brian2.codegen.runtime.numpy_rt.numpy_rt import LazyArange\n _array_default_neurons__spikespace[-1] = 0\nbefore_run:\n import numpy as _numpy\n from brian2.codegen.runtime.numpy_rt.numpy_rt import LazyArange\n # EMPTY_CODE_BLOCK -- overwrite in child template\nrun:\n import numpy as _numpy\n from brian2.codegen.runtime.numpy_rt.numpy_rt import LazyArange\n numpy_True = _numpy.bool_(True)\n numpy_False = _numpy.bool_(False)\n # scalar code\n _vectorisation_idx = 1\n # vector code\n _vectorisation_idx = LazyArange(N)\n v = _array_default_neurons_v\n not_refractory = _array_default_neurons_not_refractory\n _cond = (v > v_th) & not_refractory\n if _cond is True or _cond is numpy_True:\n _events = _numpy.arange(N)\n elif _cond is False or _cond is numpy_False:\n _events = _numpy.array([])\n else:\n _events, = _cond.nonzero()\n _array_default_neurons__spikespace[-1] = len(_events)\n _array_default_neurons__spikespace[:len(_events)] = _events\n # Set the neuron to refractory\n _array_default_neurons_not_refractory[_events] = False\n _array_default_neurons_lastspike[_events] = _array_defaultclock_t[0]\n"
}
]
},
{
"name": "spikemonitor",
"type": "SpikeMonitor",
"when": "thresholds",
"order": 1,
"active": true,
"abstract_code": "_to_record_i = _source_i\n_to_record_t = _source_t",
"user_code": "None",
"code_objects": [
{
"name": "spikemonitor_codeobject",
"type": "CallableProxyType",
"generated_code": "after_run:\n import numpy as _numpy\n from brian2.codegen.runtime.numpy_rt.numpy_rt import LazyArange\n # EMPTY_CODE_BLOCK -- overwrite in child template\nbefore_run:\n import numpy as _numpy\n from brian2.codegen.runtime.numpy_rt.numpy_rt import LazyArange\n # EMPTY_CODE_BLOCK -- overwrite in child template\nrun:\n import numpy as _numpy\n from brian2.codegen.runtime.numpy_rt.numpy_rt import LazyArange\n _n_events = _array_default_neurons__spikespace[-1]\n if _n_events > 0:\n _events = _array_default_neurons__spikespace[:_n_events]\n # Take subgroups into account\n if _source_start != 0 or _source_stop != _source_N:\n _events = _events[(_events >= _source_start) & (_events < _source_stop)]\n _n_events = len(_events)\n if _n_events > 0:\n _vectorisation_idx = 1\n _curlen = _array_spikemonitor_N[0]\n _newlen = _curlen + _n_events\n _owner.resize(_newlen)\n _array_spikemonitor_N[0] = _newlen\n _vectorisation_idx = _events\n _idx = _events\n _source_i = _array_default_neurons_i[_idx]\n _source_t = _array_defaultclock_t[0]\n _to_record_i = _source_i\n _to_record_t = _source_t\n _dynamic_array_spikemonitor_t[_curlen:_newlen] = _to_record_t\n _dynamic_array_spikemonitor_i[_curlen:_newlen] = _to_record_i\n _array_spikemonitor_count[_events - _source_start] += 1\n"
}
]
},
{
"name": "default_synapses_pre",
"type": "SynapticPathway",
"when": "synapses",
"order": -1,
"active": true,
"abstract_code": "g += w\n",
"user_code": "None",
"code_objects": [
{
"name": "default_synapses_pre_push_spikes",
"type": "CallableProxyType",
"generated_code": "after_run:\n import numpy as _numpy\n from brian2.codegen.runtime.numpy_rt.numpy_rt import LazyArange\n # EMPTY_CODE_BLOCK -- overwrite in child template\nbefore_run:\n import numpy as _numpy\n from brian2.codegen.runtime.numpy_rt.numpy_rt import LazyArange\n _owner.initialise_queue()\nrun:\n import numpy as _numpy\n from brian2.codegen.runtime.numpy_rt.numpy_rt import LazyArange\n _owner.push_spikes()\n"
},
{
"name": "default_synapses_pre_codeobject_7",
"type": "CallableProxyType",
"generated_code": "after_run:\n import numpy as _numpy\n from brian2.codegen.runtime.numpy_rt.numpy_rt import LazyArange\n # EMPTY_CODE_BLOCK -- overwrite in child template\nbefore_run:\n import numpy as _numpy\n from brian2.codegen.runtime.numpy_rt.numpy_rt import LazyArange\n # EMPTY_CODE_BLOCK -- overwrite in child template\nrun:\n import numpy as _numpy\n from brian2.codegen.runtime.numpy_rt.numpy_rt import LazyArange\n _spiking_synapses = _queue.peek()\n if len(_spiking_synapses):\n # scalar code\n # vector code\n _idx = _spiking_synapses\n _vectorisation_idx = _idx\n # Abstract code: g += w\n _postsynaptic_idx = _array_default_synapses__synaptic_post[_idx]\n w = _array_default_synapses_w[_idx]\n not_refractory = _array_default_neurons_not_refractory[_postsynaptic_idx]\n _numpy.add.at(_array_default_neurons_g, _postsynaptic_idx[not_refractory], w[not_refractory])\n # Advance the spike queue\n _queue.advance()\n"
}
]
},
{
"name": "poissoninput",
"type": "PoissonInput",
"when": "synapses",
"order": 0,
"active": true,
"abstract_code": "v += poissoninput_binomial()*68.75 * mvolt",
"user_code": "",
"code_objects": [
{
"name": "poissoninput_codeobject",
"type": "CallableProxyType",
"generated_code": "after_run:\n import numpy as _numpy\n from brian2.codegen.runtime.numpy_rt.numpy_rt import LazyArange\n # EMPTY_CODE_BLOCK -- overwrite in child template\nbefore_run:\n import numpy as _numpy\n from brian2.codegen.runtime.numpy_rt.numpy_rt import LazyArange\n # EMPTY_CODE_BLOCK -- overwrite in child template\nrun:\n import numpy as _numpy\n from brian2.codegen.runtime.numpy_rt.numpy_rt import LazyArange\n # scalar code\n _vectorisation_idx = 1\n _lio_1 = 68.75 * mvolt\n # vector code\n _vectorisation_idx = LazyArange(N)\n _sub_idx = _array_default_neurons_subgroup__sub_idx\n v = _array_default_neurons_v[_sub_idx]\n not_refractory = _array_default_neurons_not_refractory[_sub_idx]\n v[not_refractory] += _lio_1 * poissoninput_binomial(_vectorisation_idx[not_refractory])\n _array_default_neurons_v[_sub_idx] = v\n"
}
]
},
{
"name": "default_neurons_spike_resetter",
"type": "Resetter",
"when": "resets",
"order": 0,
"active": true,
"abstract_code": "v = v_rst; w = 0; g = 0 * mV",
"user_code": "None",
"code_objects": [
{
"name": "default_neurons_spike_resetter_codeobject_7",
"type": "CallableProxyType",
"generated_code": "after_run:\n import numpy as _numpy\n from brian2.codegen.runtime.numpy_rt.numpy_rt import LazyArange\n # EMPTY_CODE_BLOCK -- overwrite in child template\nbefore_run:\n import numpy as _numpy\n from brian2.codegen.runtime.numpy_rt.numpy_rt import LazyArange\n # EMPTY_CODE_BLOCK -- overwrite in child template\nrun:\n import numpy as _numpy\n from brian2.codegen.runtime.numpy_rt.numpy_rt import LazyArange\n # scalar code\n _vectorisation_idx = 1\n w = 0\n # vector code\n _idx = _array_default_neurons__spikespace[:_array_default_neurons__spikespace[-1]]\n _vectorisation_idx = _idx\n v = v_rst\n g = 0.0\n _array_default_neurons_g[_idx] = g\n _array_default_neurons_v[_idx] = v\n"
}
]
}
]
@@ -0,0 +1,11 @@
{
"schedule": [
"start",
"groups",
"thresholds",
"synapses",
"resets",
"end"
],
"summary": " object | part of | Clock dt | when | order | active\n------------------------------------------------+-------------------------------------+----------------------+------------+-------+-------\ndefault_neurons_stateupdater (StateUpdater) | default_neurons (NeuronGroup) | 100. us (every step) | groups | 0 | yes \ndefault_neurons_spike_thresholder (Thresholder) | default_neurons (NeuronGroup) | 100. us (every step) | thresholds | 0 | yes \nspikemonitor (SpikeMonitor) | spikemonitor (SpikeMonitor) | 100. us (every step) | thresholds | 1 | yes \ndefault_synapses_pre (SynapticPathway) | default_synapses (Synapses) | 100. us (every step) | synapses | -1 | yes \npoissoninput (PoissonInput) | default_neurons_subgroup (Subgroup) | 100. us (every step) | synapses | 0 | yes \ndefault_neurons_spike_resetter (Resetter) | default_neurons (NeuronGroup) | 100. us (every step) | resets | 0 | yes "
}