From 6fc326ccd1411174dbf30c2080825274d2ebe975 Mon Sep 17 00:00:00 2001 From: Digital Drosophila Archive Date: Wed, 30 Sep 2026 01:00:16 +0800 Subject: [PATCH] Audit frozen LIF semantics and real recurrent motifs without learning changes --- CURRENT.md | 61 +-- docs/progress/phase4ac-interpretation.md | 71 ++++ docs/progress/phase4ac-lif-semantics.md | 83 ++++ .../lif-semantics-audit-v1/PROTOCOL.md | 61 +++ .../lif-semantics-audit-v1/audit_semantics.py | 256 ++++++++++++ .../brian2-evidence.json | 32 ++ .../lif-semantics-audit-v1/checksums.sha256 | 7 + .../lif-semantics-audit-v1/config.yaml | 33 ++ .../lif-semantics-audit-v1/manifest.json | 40 ++ .../lif-semantics-audit-v1/math_reference.py | 70 ++++ .../lif-semantics-audit-v1/report.py | 49 +++ .../lif-semantics-audit-v1/test_math.py | 59 +++ .../evidence-index.json | 242 ++++++++++++ .../evidence/INTERPRETATION.zh.md | 71 ++++ .../phase4ac-lif-semantics/evidence/REPORT.md | 83 ++++ .../evidence/audit/author-source-clauses.json | 40 ++ .../evidence/audit/final-status.json | 7 + .../audit/local-inhibition-crosswalk.csv | 33 ++ .../evidence/audit/run-complete.json | 8 + .../evidence/audit/selected-real-edges.csv | 14 + .../evidence/audit/semantics-differences.csv | 8 + .../evidence/checksums.sha256 | 57 +++ .../evidence/external-resources/LICENSE | 21 + .../external-resources/environment_full.yml | 109 +++++ .../evidence/external-resources/model.py | 373 ++++++++++++++++++ .../external-resources/provenance.json | 29 ++ .../evidence/gpu-reference/extension.json | 17 + .../evidence/manifest.json | 290 ++++++++++++++ .../evidence/motifs/feedforward-edges.csv | 5 + .../evidence/motifs/five-edges.csv | 14 + .../evidence/motifs/no_input-edges.csv | 14 + .../evidence/motifs/pair-edges.csv | 3 + .../evidence/motifs/summary.csv | 21 + .../evidence/motifs/trio-edges.csv | 7 + .../evidence/performance/summary.json | 6 + .../evidence/protocol/dynamics.json | 12 + .../protocol/frozen-input-hashes.json | 7 + .../protocol/prepared-input-hashes.json | 7 + .../evidence/protocol/preregistered.json | 123 ++++++ .../anatomical-edge-validation.json | 10 + .../evidence/regression/feedforward.json | 13 + .../evidence/regression/final-integrity.json | 48 +++ .../evidence/regression/five.json | 13 + .../evidence/regression/frozen-five.json | 61 +++ .../evidence/regression/motifs.json | 27 ++ .../evidence/regression/no_input.json | 13 + .../evidence/regression/pair.json | 13 + .../evidence/regression/preflight.json | 48 +++ .../evidence/regression/run-start.json | 6 + .../evidence/regression/synthetic.json | 8 + .../evidence/regression/trio.json | 13 + .../evidence/regression/unit-tests.json | 4 + .../evidence/synthetic/results.csv | 69 ++++ .../seal-verification.json | 16 + tools/publish_phase4ac.py | 30 ++ 55 files changed, 2809 insertions(+), 26 deletions(-) create mode 100644 docs/progress/phase4ac-interpretation.md create mode 100644 docs/progress/phase4ac-lif-semantics.md create mode 100644 models/male-cns-lif/lif-semantics-audit-v1/PROTOCOL.md create mode 100644 models/male-cns-lif/lif-semantics-audit-v1/audit_semantics.py create mode 100644 models/male-cns-lif/lif-semantics-audit-v1/brian2-evidence.json create mode 100644 models/male-cns-lif/lif-semantics-audit-v1/checksums.sha256 create mode 100644 models/male-cns-lif/lif-semantics-audit-v1/config.yaml create mode 100644 models/male-cns-lif/lif-semantics-audit-v1/manifest.json create mode 100644 models/male-cns-lif/lif-semantics-audit-v1/math_reference.py create mode 100644 models/male-cns-lif/lif-semantics-audit-v1/report.py create mode 100644 models/male-cns-lif/lif-semantics-audit-v1/test_math.py create mode 100644 registry/phase4ac-lif-semantics/evidence-index.json create mode 100644 registry/phase4ac-lif-semantics/evidence/INTERPRETATION.zh.md create mode 100644 registry/phase4ac-lif-semantics/evidence/REPORT.md create mode 100644 registry/phase4ac-lif-semantics/evidence/audit/author-source-clauses.json create mode 100644 registry/phase4ac-lif-semantics/evidence/audit/final-status.json create mode 100644 registry/phase4ac-lif-semantics/evidence/audit/local-inhibition-crosswalk.csv create mode 100644 registry/phase4ac-lif-semantics/evidence/audit/run-complete.json create mode 100644 registry/phase4ac-lif-semantics/evidence/audit/selected-real-edges.csv create mode 100644 registry/phase4ac-lif-semantics/evidence/audit/semantics-differences.csv create mode 100644 registry/phase4ac-lif-semantics/evidence/checksums.sha256 create mode 100644 registry/phase4ac-lif-semantics/evidence/external-resources/LICENSE create mode 100644 registry/phase4ac-lif-semantics/evidence/external-resources/environment_full.yml create mode 100644 registry/phase4ac-lif-semantics/evidence/external-resources/model.py create mode 100644 registry/phase4ac-lif-semantics/evidence/external-resources/provenance.json create mode 100644 registry/phase4ac-lif-semantics/evidence/gpu-reference/extension.json create mode 100644 registry/phase4ac-lif-semantics/evidence/manifest.json create mode 100644 registry/phase4ac-lif-semantics/evidence/motifs/feedforward-edges.csv create mode 100644 registry/phase4ac-lif-semantics/evidence/motifs/five-edges.csv create mode 100644 registry/phase4ac-lif-semantics/evidence/motifs/no_input-edges.csv create mode 100644 registry/phase4ac-lif-semantics/evidence/motifs/pair-edges.csv create mode 100644 registry/phase4ac-lif-semantics/evidence/motifs/summary.csv create mode 100644 registry/phase4ac-lif-semantics/evidence/motifs/trio-edges.csv create mode 100644 registry/phase4ac-lif-semantics/evidence/performance/summary.json create mode 100644 registry/phase4ac-lif-semantics/evidence/protocol/dynamics.json create mode 100644 registry/phase4ac-lif-semantics/evidence/protocol/frozen-input-hashes.json create mode 100644 registry/phase4ac-lif-semantics/evidence/protocol/prepared-input-hashes.json create mode 100644 registry/phase4ac-lif-semantics/evidence/protocol/preregistered.json create mode 100644 registry/phase4ac-lif-semantics/evidence/regression/anatomical-edge-validation.json create mode 100644 registry/phase4ac-lif-semantics/evidence/regression/feedforward.json create mode 100644 registry/phase4ac-lif-semantics/evidence/regression/final-integrity.json create mode 100644 registry/phase4ac-lif-semantics/evidence/regression/five.json create mode 100644 registry/phase4ac-lif-semantics/evidence/regression/frozen-five.json create mode 100644 registry/phase4ac-lif-semantics/evidence/regression/motifs.json create mode 100644 registry/phase4ac-lif-semantics/evidence/regression/no_input.json create mode 100644 registry/phase4ac-lif-semantics/evidence/regression/pair.json create mode 100644 registry/phase4ac-lif-semantics/evidence/regression/preflight.json create mode 100644 registry/phase4ac-lif-semantics/evidence/regression/run-start.json create mode 100644 registry/phase4ac-lif-semantics/evidence/regression/synthetic.json create mode 100644 registry/phase4ac-lif-semantics/evidence/regression/trio.json create mode 100644 registry/phase4ac-lif-semantics/evidence/regression/unit-tests.json create mode 100644 registry/phase4ac-lif-semantics/evidence/synthetic/results.csv create mode 100644 registry/phase4ac-lif-semantics/seal-verification.json create mode 100644 tools/publish_phase4ac.py diff --git a/CURRENT.md b/CURRENT.md index 2202949..626160e 100644 --- a/CURRENT.md +++ b/CURRENT.md @@ -1,38 +1,47 @@ -# 当前研究状态 — Phase 4AB +# 当前研究状态 — Phase 4AC -最新结果:**COMPLETE-SCOPE-COUNTERFACTUAL / NO-DYNAMICS-CANDIDATE**。 +最新结果:**COMPLETE-SEMANTICS-AUDIT / LEARNING-NOT-ACHIEVED**。 +学习可用的总目标尚未达到,不把审计 PASS 当成学习 PASS。 初始化 README/registry 保留原字节,最新结论从本页进入。 -- [本轮中文机制解读](docs/progress/phase4ab-terminal-scope.md) -- [完整逐气味结果与限制](docs/progress/phase4ab-technical-results.md) -- [预先声明的诊断方案](models/male-cns-lif/terminal-scope-diagnostic-v1/PROTOCOL.md) -- [最终结果及 SHA-256 证据](registry/phase4ab-terminal-scope/evidence/audit/final-summary.json) -- [上一轮官方突触空间定位](docs/progress/phase4aa-apl-pn-scope.md) +- [中文机制结论及限制](docs/progress/phase4ac-interpretation.md) +- [完整小回路/单细胞结果](docs/progress/phase4ac-lif-semantics.md) +- [预先声明的诊断方案](models/male-cns-lif/lif-semantics-audit-v1/PROTOCOL.md) +- [新阶段校验清单](registry/phase4ac-lif-semantics/seal-verification.json) +- [上一轮末梢作用范围诊断](docs/progress/phase4ab-terminal-scope.md) -## 新证据 +## 新增机制证据 -以官方 primary_post ROI 和真实 APL→PN / PN→KC 接触选择 229 个 PN。 -局部诊断范围是 20,263 条边中的 337,099 个 calyx 接触,影响 3,760 个 KC。 -没有把 46,159 个未细分 ROI 的 PN→KC 接触重标为 calyx;没有推测 bouton/receptor。 +只施加一次初始 spike,使用原有冻结动力学: -24 组主对照(6 个旧 calibration 气味、一个旧 seed)显示: +| 真实小回路 | 1 s 内总 spike | 500–1,000 ms spike | +|---|---:|---:| +| 2 个 ALLN | 473 | 238 | +| 3 个 ALLN | 1,064 | 535 | +| 3 ALLN + VA6 PN + KC | 1,483 | 747 | +| 真实前向边对照 | 3 | 0 | +| 无初始刺激 | 0 | 0 | -- 仅阻断上述 calyx 接触,目标 KC82312 晚期 spikes 从 60–61 降到 0。 -- VA6 PN 晚期仍有 212–214 spikes;受观察的 ALLN 仍有 454–456 Hz 活动。 -- 全部活跃 KC 从原来的 139–172 个降到 1–2 个:这不是编码/记忆修复。 -- 更广的 PN 快速输出阻断使回路近乎静默,不能把这种结果认作正确生理模型。 +最小回路:body 11478 → 11620(235 contacts),11620 → 11478(283 contacts),两者为 lLN1_bc / ACh。 +单次输入足以在隔离小回路中产生持续到观察期末的活动;不代表已证明全脑必要性,也不代表真实果蝇该回路必然如此。 -上述只是独立工程极端对照,不是 APL 抑制强度标定;未保存正式新权重。 -Base CSR、raw counts、transmitter signs、LIF/APL calibration、eligibility-v2 和 14,232 plastic mask 不变。 +## 原作者实现与本项目适配差异 -## 验证与状态 +固定作者代码在 spike 后清零 g,对不应期内 g 更新/输入设限,并有不同积分、阈值和刺激时序。 +本项目冻结版本明确保留 g,继续衰减/接收输入。这是建模语义差异,不是本轮发现的 GPU 回归错误。 +单细胞组件测试证明这些选择会改变响应,但真实连接强度的一次输入下,reset-only 并未改变 spike 数。 +因此 **g reset 不得直接称为学习修复**,也不能仅据放电减少自动选择新模型。 -6 组历史 trial 精确重现,4 组诊断重复精确一致,5/5 frozen deterministic-v2 reference 回归精确通过。 -230,239 个原有科学文件及 Phase 4AA 模型/数据 manifests 前后完整性通过。 -6 项单元测试、10,000 个随机算子检查通过;ComfyUI 未停用/卸载,未升级依赖。 +## 验证与下一步 -顶层 gates 仍是 5/10(50%);本轮改进了机制定位和可重复诊断,不代表已获得学习能力。 -下一步优先约束 upstream feedback 与局部 compartment physiology,不能靠增大整体抑制、调学习率/阈值或扩大 mask 达成通过。 -不进入游戏、RL、视觉或 action decoder。 +7 项单元测试、17×4 单细胞 fixture、5 个真实小回路 CPU/GPU 全状态/事件精确对照通过。 +五组 deterministic-v2 全脑冻结参考 trial 精确一致。 +原快照 230,239 项及 Phase 4AA / 4AB 模型与实验前后校验无变化。 +新产物有独立 manifest/SHA-256;未训练、未生成 learned candidate。 +ComfyUI 保持驻留,不停用、不卸载、不升级依赖。 -Git 仅同步代码、小报告和校验清单。大数据/全部 spike 输出保留在服务器,不等于已有完整异机备份。 +后续需要明确授权的独立动力学模型分支:先验证原作者 oracle 和局部机制,再检查输入区别与学习功能。 +仍要求独立 evaluation seeds、A 对 B 的特异性、MBON/downstream readout 和完整 conditioning controls。 +不调整学习率/阈值或扩大 mask,不进入游戏、RL、decoder、视觉;不修改已冻结版本。 + +Git 仅同步代码、小报告、官方小型源代码及校验清单。大数据/完整 spike 输出仍在服务器,不等于完整异机备份。 diff --git a/docs/progress/phase4ac-interpretation.md b/docs/progress/phase4ac-interpretation.md new file mode 100644 index 0000000..352f0e9 --- /dev/null +++ b/docs/progress/phase4ac-interpretation.md @@ -0,0 +1,71 @@ +# Phase 4AC:反馈环路足以持续放电,尚未得到学习修复 + +状态:`COMPLETE-SEMANTICS-AUDIT / LEARNING-NOT-ACHIEVED`。 + +## 这次真正增加的证据 + +从已有异常传播路径选取真实 MaleCNS 神经元和 13 条真实连接。 +只施加一次初始脉冲,随后无外部输入,观察 1 s。所有真实回路测试继续使用冻结动力学。 + +| 小回路 | 总放电数 | 500–1,000 ms 放电数 | +|---|---:|---:| +| 两枚 ALLN 互相连接 | 473 | 238 | +| 三枚 ALLN | 1,064 | 535 | +| 三枚 ALLN + VA6 PN + KC | 1,483 | 747 | +| 只保留四条真实前向连接的对照 | 3 | 0 | +| 五神经元回路,无初始输入 | 0 | 0 | + +最小互相连接的两枚神经元是: + +- neuron_idx 1381 / body_id 11478 → neuron_idx 1511 / body_id 11620:235 contacts。 +- neuron_idx 1511 / body_id 11620 → neuron_idx 1381 / body_id 11478:283 contacts。 +- 两者 metadata 均为 ALLN / lLN1_bc,递质 annotation 和 ground truth 均为 acetylcholine。未改变符号。 + +它们在冻结 LIF 下,从一次输入即可相互维持放电到 1 s 观察期末。 +五神经元回路的 VA6 PN(133666 / 527577)有 297 次放电,KC(82312 / 109321)有 80 次放电。 +这把“持续反馈驱动 KC”缩小到可逐步检查的真实局部回路。 + +**限定结论:**这是隔离回路中的充分性证据,不是全脑必要性证据;外部抑制、分级 APL 及其他回路在这里不参与。 +前向对照移除了反馈连接,只是诊断 harness,不是提交了一个删边新模型。1 s 持续不等于证明无限持续。 + +## 原作者语义差异,不等于已找到修复 + +[Shiu 作者固定版本代码](https://github.com/philshiu/Drosophila_brain_model/blob/91bdd1e7dcf193f3e7ca5a8933497fcef63b7960/model.py) +在 spike 后清零 g,v/g 的不应期更新受限,使用 linear 积分和严格 > 阈值;刺激细胞的 Poisson 输入及不应期也与本项目不同。 +本项目的冻结版本明确记录了保留 g、不应期继续衰减/接收输入、Euler 积分等适配选择。 +因此不能把它说成 CUDA 引入的新错误,也不能把“g 清零”称为严格复现原作者模型。 + +本次单细胞 component tests 有意保留冻结的其他数学语义,仅分别比较 g reset 和 refractory gate。 +真实 13 条连接强度加一个单突触 fixture 下,冻结策略、reset-only、reset+gate 的单次输入 spike 数相同(0 或 1)。 +单独冻结不应期 g、但不清零 g,反而在 283-contact fixture 中产生 2 次 spike,而其他三种策略为 1 次。 +人工持续输入停止后,冻结策略有 4 次尾随 spike,reset-only 有 1 次、reset+gate 有 0 次,gate-only 则有 14 次。 + +这些结果表明组件选择确实会改变响应,但不支持“随便加一个不应期限制就能解决”。 +两个强连接各自仍能从一次输入触发一次响应,所以也不能仅凭单细胞 reset 测试宣称真实反馈环已被消除。 +所有替代组件仅运行于人工单细胞 fixture,没有部署到 MaleCNS 全脑或训练实验。 + +[Brian2 2.5.1 固定实现](https://github.com/brian-team/brian2/blob/577bb35ec677947d6f3d4af367a8a4b3b88815ee/brian2/groups/neurongroup.py) +在默认非 legacy 设置下,不应期是 22 steps;第 23 step 才积分某些新到达输入属于调度顺序,不是不应期延长。 +原作者模型、license、环境文件、固定 commit、SHA-256 与源码位置均已记录;尚未执行独立 Brian2 oracle。 + +## 验证 + +- 7 项单元测试通过;17 组单细胞 fixture × 4 策略均有限且重复一致。 +- 五个真实小回路的全部事件、计数、每步 V/g/ref、最终状态和环形队列 CPU/GPU 精确一致。 +- 五组 deterministic-v2 全脑参考 trial 的事件、计数、最终 V/g 精确一致。 +- 逐条核对真实 edge_id、源 CSR 行、目标和原始 count;准备输入另有 SHA-256。 +- 完整性终检覆盖原快照 230,239 项,以及 Phase 4AA / 4AB 的模型与实验 manifest。 +- GPU 诊断含构建/观察/回归共 95.398 s;本进程 peak allocated VRAM 285,994,496 bytes。不是性能 benchmark,不含 ComfyUI 驻留显存。 +- 保留旧加载器只读 NumPy→Torch 警告;未修改加载器,完整性和回归另行验证。 + +## 学习目标与下一道关口 + +当前没有新的 learned model,没有训练,也没有重新宣称学习 PASS。 +可用学习仍须在独立评价种子上证明 A 相对中性 B 的特异性、MBON/downstream 功能变化及完整对照;权重变化、稀疏化或静默都不能替代。 + +下一步应先在明确授权的新模型分支中验证作者算子与有生理依据的局部反馈机制,并用独立 oracle 区分每一项语义。 +不能将减少放电自动选为正确模型;还必须保留输入区别、可传播性和后续关联记忆能力。 +不改 raw、CSR、原始突触数、已定递质符号、冻结版本、APL calibration、eligibility-v2 或 plastic mask。 +不进入游戏、decoder、RL 或视觉路线。 + +Git 只同步源代码、小报告与校验清单。完整数据仍在服务器,不能声称已完成异机大数据备份。 diff --git a/docs/progress/phase4ac-lif-semantics.md b/docs/progress/phase4ac-lif-semantics.md new file mode 100644 index 0000000..5ceb8f4 --- /dev/null +++ b/docs/progress/phase4ac-lif-semantics.md @@ -0,0 +1,83 @@ +# Phase 4AC — LIF semantics and unchanged-dynamics motif audit + +Status: COMPLETE-SEMANTICS-AUDIT / LEARNING-NOT-ACHIEVED. +No alternative dynamics deployed to MaleCNS; no conditioning, learned candidate or new formal runtime. + +## Author model versus frozen adapted model + +Pinned author model resets g on a spike and declares v/g `(unless refractory)`, uses linear integration, strict > threshold and voltage Poisson input with zero refractory on stimulated cells. +The frozen adapted model retains g, decays/accepts events during refractory, uses explicit Euler and >= threshold, and forced sensory spikes respect refractory. +These are documented model choices, not a newly established GPU regression. g is an additive voltage-valued drive, not a measured conductance. +W_syn=0.275 is transferred from a free parameter calibrated in the original FlyWire feeding model, not a measured universal MaleCNS synaptic efficacy. + +## Synthetic single-cell component tests + +All impulse amplitudes derive from the complete unique contact counts of the predeclared 13 real motif edges plus a one-contact fixture; other boundary/sustained cases are explicitly synthetic unit tests. +These ablations retain frozen Euler arithmetic/scheduling and are NOT complete Brian2 replication. No successful amplitude or policy was selected after seeing results. + +| Single-impulse fixture | Frozen | Reset g only | Refractory gate only | Reset + gate | +|---|---:|---:|---:|---:| +| one_impulse_contacts_1 | 0 | 0 | 0 | 0 | +| one_impulse_contacts_104 | 0 | 0 | 0 | 0 | +| one_impulse_contacts_172 | 1 | 1 | 1 | 1 | +| one_impulse_contacts_210 | 1 | 1 | 1 | 1 | +| one_impulse_contacts_226 | 1 | 1 | 1 | 1 | +| one_impulse_contacts_235 | 1 | 1 | 1 | 1 | +| one_impulse_contacts_259 | 1 | 1 | 1 | 1 | +| one_impulse_contacts_283 | 1 | 1 | 2 | 1 | +| one_impulse_contacts_43 | 0 | 0 | 0 | 0 | +| one_impulse_contacts_57 | 0 | 0 | 0 | 0 | +| one_impulse_contacts_64 | 0 | 0 | 0 | 0 | +| one_impulse_contacts_70 | 0 | 0 | 0 | 0 | +| one_impulse_contacts_76 | 0 | 0 | 0 | 0 | +| one_impulse_contacts_95 | 0 | 0 | 0 | 0 | + +Reset-only and combined policies can produce at most one spike from a single isolated input by construction. This does not establish biological correctness or whole-brain learning improvement. + +## Real anatomical motifs — frozen mathematics ONLY + +One forced seed spike at step 0 except the no-input control; no subsequent input; observed for 1 s. Late window=500–1,000 ms. +The recurrent pair/trio/five are induced subgraphs. The feedforward control selects four existing edges and removes feedback only within this isolated diagnostic harness. +External inhibition, graded APL and other whole-brain inputs are absent. A sustained isolated motif is evidence of sufficiency in this harness, NOT necessity in the complete brain. + +| Motif | neuron_idx | Total spikes | Late spikes | Last ms | +|---|---:|---:|---:|---:| +| pair | 1381 | 237 | 119 | 999.3 | +| pair | 1511 | 236 | 119 | 997.5 | +| trio | 1197 | 355 | 179 | 999.3 | +| trio | 1381 | 355 | 178 | 997.8 | +| trio | 1511 | 354 | 178 | 997.4 | +| five | 1197 | 370 | 185 | 998.8 | +| five | 1381 | 369 | 185 | 997.4 | +| five | 1511 | 367 | 186 | 999.5 | +| five | 82312 | 80 | 41 | 990.3 | +| five | 133666 | 297 | 150 | 999.5 | +| feedforward | 1197 | 1 | 0 | 10.0 | +| feedforward | 1381 | 1 | 0 | 0.0 | +| feedforward | 1511 | 1 | 0 | 4.9 | +| feedforward | 82312 | 0 | 0 | none | +| feedforward | 133666 | 0 | 0 | none | +| no_input | 1197 | 0 | 0 | none | +| no_input | 1381 | 0 | 0 | none | +| no_input | 1511 | 0 | 0 | none | +| no_input | 82312 | 0 | 0 | none | +| no_input | 133666 | 0 | 0 | none | + +## Verification and boundaries + +Seven unit tests; all five real motifs CPU/GPU event, count, final V/g/refractory, queue and timestep history exact; five archived deterministic-v2 full-brain trials exact. +Every selected edge_id, source CSR row, destination and original weight validated; generated prepared inputs hashed. All original snapshot files and Phase 4AA/4AB model/experiment manifests checked before and after. +Diagnostic wall time including compilation and observation: 95.398 s. Peak allocated process VRAM: 285994496 bytes. Not a runtime-speed benchmark. +Original author code was inspected, not executed; no Brian2 oracle run and no new package installation. ComfyUI was not stopped or unloaded. + +## Decision + +The usable-learning gate remains unmet: independent evaluation, A-vs-neutral-B specificity in MBON/downstream, multiple training seeds and conditioning controls still required. +Before any full-network alternative, obtain explicit separate model authorization and distinguish each semantic component; do not claim g reset alone reproduces the author implementation. +No evidence here permits changing eta, thresholds, gain, frozen APL calibration, transmitter signs or the plastic mask. + +## Primary provenance + +[Shiu et al. 2024](https://www.nature.com/articles/s41586-024-07763-9) +[Pinned author implementation](https://github.com/philshiu/Drosophila_brain_model/blob/91bdd1e7dcf193f3e7ca5a8933497fcef63b7960/model.py) +Downloaded source, MIT license, environment specification, exact commit, SHA-256 and source clauses retained under external-resources and audit. diff --git a/models/male-cns-lif/lif-semantics-audit-v1/PROTOCOL.md b/models/male-cns-lif/lif-semantics-audit-v1/PROTOCOL.md new file mode 100644 index 0000000..09e09ec --- /dev/null +++ b/models/male-cns-lif/lif-semantics-audit-v1/PROTOCOL.md @@ -0,0 +1,61 @@ +# Phase 4AC — upstream LIF semantics audit + +Goal context: usable stimulus-specific associative learning remains unachieved. +This stage is a prerequisite diagnosis, never a substitute for that goal. + +All raw, base CSR, old models/experiments and signs remain read-only. No eta, +threshold, gain, mask or APL calibration is changed. No conditioning, games, +decoder, visual stimulation, or new formal runtime is produced. + +## New evidence and hypotheses + +The official Shiu paper links philshiu/Drosophila_brain_model. Commit +91bdd1e7dcf193f3e7ca5a8933497fcef63b7960 (2024-09-14) model.py explicitly resets g +on a spike, declares both v and g `(unless refractory)`, uses linear integration +and strict `v > v_th`, and removes refractory time on Poisson-target neurons. +Current frozen Phase 4B/P instead retains g, decays/accepts arrivals during +refractory, uses explicit Euler, `>=`, and force requests respecting refractory. +The Phase 4B config documents its refractory-g policy, so this is a documented +adaptation difference, NOT evidence that deterministic CUDA regressed its oracle. +Neither implementation is automatically a more accurate MaleCNS physiology model. + +## Scope of work allowed without replacing frozen brain dynamics + +1. Preserve official code/license at a pinned commit, with hashes; do not execute + downloaded code. Extract exact source statements into an evidence table. +2. Synthetic one-cell mathematical fixtures compare the frozen g policy with + reset-only, refractory-only, and combined component ablations. Other arithmetic + stays frozen. These are NOT a Brian2 reproduction (integration and scheduling + also differ), and are not deployed to the MaleCNS brain. +3. Simulate only the UNCHANGED frozen dynamics on actual induced 2/3/5-neuron + circuits selected from the already observed Phase 4Z path. One force request at + t=0, then no input, for 1,000 ms. Include no-input and real-edge feedforward + controls. Missing external network inhibition/feedback is explicitly excluded; + a sustained isolated response is not proof of whole-brain necessity. +4. Validate every frozen CPU small-circuit event/state against the unchanged CUDA + kernel, using exact float32 ordered accumulation and delay=18 steps. +5. Recheck the five archived deterministic reference trials and all old hashes. + +All single-cell amplitudes derive from the complete unique contact-count set in +the selected real subgraph, plus a one-contact unit fixture. Do not choose a +successful amplitude after observing outcomes. Add a refractory-arrival fixture +at t=0/1/2/2.2/2.3 ms and a sustained-input-then-off fixture (100 ms then100 ms). +These describe operator consequences, not measured cell physiology or tuning. + +The full learning gate still requires >=5 training seeds, independent evaluation, +A-vs-neutral-B specificity in MBON/downstream, appropriate controls, acquisition, +reversal, retention and delayed-reward tests. Existing transfer PASS is not that. + +## Next-stage authorization boundary + +Testing alternative semantics or measured local physiology on the full MaleCNS +network would be a NEW model experiment, not an exact runtime optimization. +User confirmation is requested separately. This stage does not silently execute +or promote that experiment, even if synthetic ablations reduce firing. + +## Caveats to record + +W_syn=0.275 is the original paper's free parameter selected on its feeding circuit, +not a universal measured MaleCNS contact efficacy. g reset by itself does not make +the model equivalent to the author's Brian2 implementation. Old reference PASS +means consistency with our old oracle, not matching the original author software. diff --git a/models/male-cns-lif/lif-semantics-audit-v1/audit_semantics.py b/models/male-cns-lif/lif-semantics-audit-v1/audit_semantics.py new file mode 100644 index 0000000..83dd384 --- /dev/null +++ b/models/male-cns-lif/lif-semantics-audit-v1/audit_semantics.py @@ -0,0 +1,256 @@ +"""Evidence-only audit and unchanged-dynamics real motif tests; no learning.""" +import argparse +import ast +from datetime import datetime, timezone +import json +import os +from pathlib import Path +import shutil +import subprocess +import sys +import time +import unittest +import urllib.request +import numpy as np +import pandas as pd +import yaml +from math_reference import params, single, state, cpu_motif + +CFG = yaml.safe_load(Path(__file__).with_name('config.yaml').read_text()) +ROOT = Path(CFG['root']); MODEL = ROOT/CFG['model']; EXP = ROOT/CFG['experiment'] +sys.path.insert(0, str(ROOT/'models/male-cns-lif/apl-pn-scope-audit-v1')) +from audit import save, digest, immutable_check, seal +sys.path.insert(0, str(ROOT/'models/male-cns-lif/terminal-scope-diagnostic-v1')) +from diagnostic import manifest_check, queues + + +def integrity(): + result = {'original': immutable_check(ROOT, ROOT/CFG['old_snapshot'], 4)} + for name in CFG['additional_frozen']: result[name] = manifest_check(ROOT/name, digest) + assert all(x['pass'] for x in result.values()), result + return result + + +def prepare(): + if EXP.exists() and any(EXP.iterdir()): raise RuntimeError('Refusing nonempty output') + EXP.mkdir(exist_ok=True) + for d in ['protocol', 'external-resources', 'audit', 'synthetic', 'motifs', 'regression', 'performance']: + (EXP/d).mkdir() + save(EXP/'protocol/preregistered.json', {'config': CFG, 'before_analysis': True, + 'timestamp_utc': datetime.now(timezone.utc).isoformat(), + 'parent_commit': subprocess.check_output(['git', '-C', str(ROOT), 'rev-parse', 'HEAD'], text=True).strip(), + 'sources': {p.name: digest(p) for p in sorted(MODEL.iterdir()) if p.is_file()}}) + save(EXP/'regression/preflight.json', integrity()) + external = EXP/'external-resources'; commit = CFG['author']['commit']; records = [] + for filename in ['model.py', 'LICENSE', 'environment_full.yml']: + url = f'https://raw.githubusercontent.com/philshiu/Drosophila_brain_model/{commit}/{filename}' + with urllib.request.urlopen(url, timeout=60) as response: data = response.read() + target = external/filename + with target.open('xb') as out: out.write(data) + records.append({'path': filename, 'url': url, 'bytes': len(data), 'sha256': digest(target), 'license': 'MIT'}) + assert digest(external/'model.py') == CFG['author']['model_sha256'] + assert 'MIT License' in (external/'LICENSE').read_text() + text = (external/'model.py').read_text(); ast.parse(text) + clauses = ['dg/dt = -g / tau', '(unless refractory)', 'v = v_rst; w = 0; g = 0 * mV', + "method='linear'", "'v > v_th'", 'neu[i].rfc = 0 * ms'] + assert all(clause in text for clause in clauses) + lines = text.splitlines() + save(EXP/'audit/author-source-clauses.json', [{'clause': clause, 'line_numbers_1based': [i+1 for i, line in enumerate(lines) if clause in line]} for clause in clauses]) + save(external/'provenance.json', {'files': records, 'commit': commit, 'paper': CFG['author']['paper'], + 'downloaded_code_executed': False, 'new_dependencies_installed': False}) + can = ROOT/CFG['canonical']; metadata = pd.read_parquet(can/'neuron-index/unified-metadata.parquet').sort_values('neuron_idx').reset_index(drop=True) + ptr = np.load(can/'gpu/csr-indptr.int64.npy', mmap_mode='r'); dst = np.load(can/'gpu/csr-indices.int32.npy', mmap_mode='r'); raw = np.load(can/'gpu/csr-weights.int64.npy', mmap_mode='r') + assert len(metadata) == 166700 and len(dst) == 25582938 and int(raw.sum()) == 124177617 + nodes = np.array(CFG['selected_nodes'], np.int32) + meta = metadata.iloc[nodes].copy(); assert np.array_equal(meta.neuron_idx, nodes) + assert meta.neurotransmitter.eq('acetylcholine').all(), 'No sign inference or reassignment' + alln = meta[meta.annotation_class.eq('ALLN')]; assert alln.annotation_type.eq('lLN1_bc').all() and alln.nt_ground_truth.eq('acetylcholine').all() + ids = np.concatenate([np.arange(ptr[n], ptr[n+1], dtype=np.int64) for n in nodes]) + src = np.concatenate([np.full(ptr[n+1]-ptr[n], n, np.int32) for n in nodes]) + keep = np.isin(dst[ids], nodes); ids = ids[keep]; src = src[keep] + edges = pd.DataFrame({'edge_id': ids, 'source_neuron_idx': src, 'target_neuron_idx': dst[ids], 'raw_count': raw[ids]}) + edges['source_body_id'] = metadata.body_id.to_numpy()[src]; edges['target_body_id'] = metadata.body_id.to_numpy()[dst[ids]] + assert len(edges) == 13 + meta.to_parquet(EXP/'audit/selected-metadata.parquet', index=False); edges.to_csv(EXP/'audit/selected-real-edges.csv', index=False) + # Explicit metadata mapping only, not physiological parameter assignment. + graded = metadata[metadata.annotation_type.isin(['lLN2P_a', 'lLN2P_b', 'lLN2P_c', 'lLN2F_b'])].copy() + cols = ['neuron_idx','body_id','annotation_type','annotation_hemibrainType','annotation_flywireType','annotation_matchingNotes','neurotransmitter','nt_ground_truth'] + graded[cols].to_csv(EXP/'audit/local-inhibition-crosswalk.csv', index=False) + frozen_yaml = ROOT/CFG['runtime']/'phase4p.yaml'; pc = yaml.safe_load(frozen_yaml.read_text()) + save(EXP/'protocol/frozen-input-hashes.json', {'runtime_config': digest(frozen_yaml), + 'runtime_cpp': digest(ROOT/CFG['runtime']/'phase4p_ext.cpp'), 'runtime_cuda': digest(ROOT/CFG['runtime']/'phase4p_ext.cu'), + 'baseline_phase4b': digest(ROOT/'models/male-cns-lif/phase4b.py'), + 'metadata': digest(can/'neuron-index/unified-metadata.parquet')}) + save(EXP/'protocol/dynamics.json', pc['model']) + evidence = [ + ['spike reset g', 'reset to zero', 'retain g'], + ['g during refractory', 'ODE paused; synaptic writes blocked', 'decay and accept arrivals'], + ['integration', 'linear exact state updater', 'forward Euler with decayed g'], + ['threshold', 'strict >', '>='], + ['within-step arrivals', 'after integration, before reset', 'before integration'], + ['stimulated neurons', 'voltage Poisson input; refractory=0', 'forced spikes subject to 22-step refractory'], + ['W_syn', 'free parameter calibrated on FlyWire feeding response', 'same value transferred to MaleCNS; not independently measured']] + pd.DataFrame(evidence, columns=['item', 'author', 'frozen_adapted']).to_csv(EXP/'audit/semantics-differences.csv', index=False) + prepared = ['protocol/dynamics.json','audit/selected-real-edges.csv','audit/selected-metadata.parquet', + 'protocol/frozen-input-hashes.json','audit/local-inhibition-crosswalk.csv'] + save(EXP/'protocol/prepared-input-hashes.json', {name:digest(EXP/name) for name in prepared}) + print('PREPARED: pinned author source, 13 actual motif edges, frozen integrity PASS', flush=True) + + +def synthetic(): + m = json.loads((EXP/'protocol/dynamics.json').read_text()); p = params(m) + edges = pd.read_csv(EXP/'audit/selected-real-edges.csv'); counts = np.unique(np.r_[1, edges.raw_count.to_numpy(np.int64)]) + results, traces = [], {} + cases = {} + for count in counts: + a = np.zeros(round(100/m['dt_ms']), np.float32); a[0] = np.float32(count)*np.float32(m['w_syn_mv_per_anatomical_synapse']) + cases[f'one_impulse_contacts_{count}'] = a + # The separate refractory boundary fixture is a synthetic unit test, not a biological stimulation. + a = np.zeros(round(20/m['dt_ms']), np.float32) + a[0] = np.float32(2000) # enough for a spike at t=0 in every component policy + a[[1,10,20,22,23]] += np.float32(10) + cases['refractory_boundary'] = a + a = np.zeros(round(200/m['dt_ms']), np.float32); a[:round(100/m['dt_ms'])] = np.float32(10) + cases['sustained_then_off'] = a + cases['zero_input'] = np.zeros(round(100/m['dt_ms']), np.float32) + for name, a in cases.items(): + for policy in CFG['synthetic_policies']: + events, history = single(a, p, policy) + repeat = single(a, p, policy) + assert np.array_equal(events, repeat[0]) and np.array_equal(history, repeat[1]) + if policy in ('reset_g_only', 'reset_and_refractory'): assert np.all(history[events,1] == 0) + if name.startswith('one_impulse') and policy in ('reset_g_only', 'reset_and_refractory'): assert len(events) <= 1 + if name == 'zero_input': assert not len(events) + if name == 'refractory_boundary' and policy == 'reset_and_refractory': + assert np.all(history[:22,1] == 0) and history[22,1] > 0 + results.append({'case': name, 'policy': policy, 'spikes': len(events), + 'spike_times_ms': json.dumps((events.astype(float)*m['dt_ms']).tolist()), + 'post_input_spikes': int((events >= 1000).sum()) if name == 'sustained_then_off' else None, + 'final_g': float(history[-1,1]), 'finite': bool(np.isfinite(history).all()), 'exact_repeat': True, + 'not_full_Brian2_replication': True}) + traces[name+'__'+policy] = history + traces[name+'__input'] = a + pd.DataFrame(results).to_csv(EXP/'synthetic/results.csv', index=False) + np.savez_compressed(EXP/'synthetic/traces.npz', **traces) + save(EXP/'regression/synthetic.json', {'pass': True, 'cases': len(cases), 'policies': 4, + 'proves_only_operator_difference': True, 'brain_model_modified': False, 'Brian2_executed': False}) + + +def gpu_motif(rt, nodes, edges, weights, p, steps, seed): + import torch + n = len(nodes); lookup = {int(node): i for i, node in enumerate(nodes)} + src = np.array([lookup[int(x)] for x in edges.source_neuron_idx], np.int32) + dst = np.array([lookup[int(x)] for x in edges.target_neuron_idx], np.int32) + d = rt.device; qlen = p['delay_steps']+1 + v = torch.full((n,), float(p['rest']), dtype=torch.float32, device=d); g = torch.zeros_like(v) + ref = torch.zeros(n, dtype=torch.int32, device=d); spike = torch.zeros(n, dtype=torch.uint8, device=d); counts = torch.zeros_like(ref) + queue = torch.zeros((qlen,n), dtype=torch.float32, device=d); wg = torch.as_tensor(weights, device=d) + history = np.empty((steps,3,n), np.float32); ts, ns = [], [] + for t in range(steps): + rt.ext.state_step(v,g,ref,queue[t%qlen],spike,counts,float(p['gd']),float(p['alpha']),float(p['rest']),float(p['reset']),float(p['threshold']),p['ref_steps']) + if t == 0 and seed is not None: + targets = torch.tensor([lookup[seed]], dtype=torch.int64, device=d); force = torch.ones(1,dtype=torch.uint8,device=d) + rt.ext.force_step(v,ref,spike,counts,targets,force,float(p['reset']),p['ref_steps']) + active = spike.cpu().numpy().astype(bool) + indices = np.flatnonzero(active); ts.extend([t]*len(indices)); ns.extend(nodes[indices].tolist()) + selected = np.flatnonzero(active[src]); selected = selected[np.argsort(dst[selected],kind='stable')] + if len(selected): + st = dst[selected]; starts = np.flatnonzero(np.r_[True,st[1:] != st[:-1]]) + rt.ext.segmented_sum(torch.as_tensor(selected,dtype=torch.int64,device=d), + torch.as_tensor(starts,dtype=torch.int64,device=d), torch.as_tensor(st[starts],dtype=torch.int32,device=d), + wg,queue[(t+p['delay_steps'])%qlen]) + history[t] = torch.stack([v,g,ref.float()]).cpu().numpy() + return {'step': np.asarray(ts,np.int32),'neuron_idx':np.asarray(ns,np.int32),'counts':counts.cpu().numpy(), + 'v':v.cpu().numpy(),'g':g.cpu().numpy(),'ref':ref.cpu().numpy(),'history':history,'queue':queue.cpu().numpy()} + + +def run(): + pre = json.loads((EXP/'protocol/preregistered.json').read_text()) + assert all(digest(MODEL/name) == h for name,h in pre['sources'].items()) + assert not (EXP/'regression/run-start.json').exists(), 'Refusing overwrite' + prepared = json.loads((EXP/'protocol/prepared-input-hashes.json').read_text()) + assert all(digest(EXP/name) == h for name,h in prepared.items()), 'Prepared-input drift' + runtime = ROOT/CFG['runtime']; pc = yaml.safe_load((runtime/'phase4p.yaml').read_text()) + assert pc['model'] == json.loads((EXP/'protocol/dynamics.json').read_text()) + suite = unittest.defaultTestLoader.discover(str(MODEL), pattern='test_math.py') + test_result = unittest.TextTestRunner(verbosity=2).run(suite) + assert test_result.wasSuccessful() and test_result.testsRun == 7 + save(EXP/'regression/unit-tests.json', {'pass': True, 'tests': test_result.testsRun}) + queues(); os.environ['CUDA_VISIBLE_DEVICES'] = pc['device']['visible_gpu_uuid'] + os.environ['CUDA_HOME'] = '/usr/local/cuda'; os.environ['MAX_JOBS'] = '2'; os.environ['TORCH_CUDA_ARCH_LIST'] = '8.9' + os.environ['PATH'] = str(ROOT/'models/male-cns-lif/.venv/bin')+':/usr/local/cuda/bin:'+os.environ['PATH'] + sys.path.insert(0,str(ROOT/'models/male-cns-lif')); sys.path.insert(0,str(runtime)) + import torch, phase4p + free,total = torch.cuda.mem_get_info(); assert free > 2*1024**3 + save(EXP/'regression/run-start.json', {'free_VRAM': free,'device':torch.cuda.get_device_name(), + 'whole_brain_uses_only_frozen_reference':True,'alternative_policies_only_synthetic_single_cell':True}) + start = time.perf_counter(); torch.cuda.reset_peak_memory_stats() + rt = phase4p.CanonicalRuntime(pc,runtime,EXP); p = params(pc['model']) + synthetic() + edges = pd.read_csv(EXP/'audit/selected-real-edges.csv').sort_values('edge_id') + eid=edges.edge_id.to_numpy(np.int64); src=edges.source_neuron_idx.to_numpy(np.int32) + assert np.all(eid >= rt.indptr_np[src]) and np.all(eid < rt.indptr_np[src+1]) + assert np.array_equal(rt.indices_np[eid],edges.target_neuron_idx) + assert np.array_equal(rt.raw_np[eid],edges.raw_count) + save(EXP/'regression/anatomical-edge-validation.json', {'pass':True,'edges':len(edges), + 'checks':['canonical edge_id in source CSR row','exact target','exact raw int64 count','exact effective float32 weight']}) + effective = rt.weights.cpu().numpy(); rows, regress = [], [] + assert np.array_equal(effective[edges.edge_id], edges.raw_count.to_numpy(np.float32)*np.float32(pc['model']['w_syn_mv_per_anatomical_synapse'])) + for spec in CFG['motifs']: + queues(); nodes = np.sort(np.array(spec['nodes'],np.int32)); subset = edges[edges.source_neuron_idx.isin(nodes)&edges.target_neuron_idx.isin(nodes)].copy() + if 'pairs' in spec: + pairs = {tuple(x) for x in spec['pairs']} + subset = subset[[tuple(x) in pairs for x in subset[['source_neuron_idx','target_neuron_idx']].to_numpy()]] + assert len(subset) == len(pairs) + w = effective[subset.edge_id]; seed = CFG['seed_node'] if spec.get('force',True) else None + steps = round(CFG['duration_ms']/pc['model']['dt_ms']); t0 = time.perf_counter() + cpu = cpu_motif(nodes,subset,w,p,steps,seed); gpu = gpu_motif(rt,nodes,subset,w,p,steps,seed) + eq = {key:bool(np.array_equal(value,gpu[key])) for key,value in cpu.items()} + save(EXP/'regression'/(spec['name']+'.json'), {'exact':eq,'pass':all(eq.values())}); assert all(eq.values()),eq + if seed is None: assert len(cpu['step']) == 0 + subset.to_csv(EXP/'motifs'/(spec['name']+'-edges.csv'),index=False) + pd.DataFrame({'step':cpu['step'],'neuron_idx':cpu['neuron_idx']}).to_parquet(EXP/'motifs'/(spec['name']+'-events.parquet'),index=False) + np.savez_compressed(EXP/'motifs'/(spec['name']+'-state.npz'), nodes=nodes, **{k:v for k,v in cpu.items() if k not in ('step','neuron_idx')}) + late = cpu['step'] >= round(CFG['late_start_ms']/pc['model']['dt_ms']) + for node in nodes: + chosen = cpu['neuron_idx'] == node + rows.append({'motif':spec['name'],'neuron_idx':int(node),'spikes':int(chosen.sum()), + 'late_spikes':int((chosen&late).sum()),'first_ms':float(cpu['step'][chosen][0]*pc['model']['dt_ms']) if chosen.any() else None, + 'last_ms':float(cpu['step'][chosen][-1]*pc['model']['dt_ms']) if chosen.any() else None, + 'external_force_requests':int(seed == node),'frozen_math_unchanged':True,'whole_brain_necessity_proven':False}) + regress.append({'motif':spec['name'],'CPU_GPU_exact':True,'wall_seconds':time.perf_counter()-t0}) + print(json.dumps({'motif':spec['name'],'events':len(cpu['step']),'late_events':int(late.sum()),'exact':True}),flush=True) + pd.DataFrame(rows).to_csv(EXP/'motifs/summary.csv',index=False) + save(EXP/'regression/motifs.json',regress) + refs=[] + for spec in pc['reference_trials']: + queues(); base = ROOT/'experiments/phase4p-deterministic-runtime/phase4c-v2/reference'/spec['name'] + ev=pd.read_parquet(base/'spike-events.parquet') + expected={'step':ev.step.to_numpy(),'neuron_idx':ev.neuron_idx.to_numpy(), + 'counts':np.load(base/'per-neuron-spike-counts.int32.npy'),'v':np.load(base/'final-voltage.float32.npy'),'g':np.load(base/'final-g.float32.npy')} + r=rt.run(np.flatnonzero(rt.pops[spec['population']]),spec['rate_hz'],spec['seed'],spec['duration_ms']) + eq={k:bool(np.array_equal(r[k],v)) for k,v in expected.items()};assert all(eq.values()),eq + refs.append({'trial':spec['name'],'exact':eq,'wall_seconds':r['metrics']['wall_seconds']}) + print(json.dumps({'frozen_trial':spec['name'],'exact':True}),flush=True) + save(EXP/'regression/frozen-five.json',{'pass':True,'trials':refs,'oracle':'frozen deterministic-v2, not Brian2'}) + save(EXP/'performance/summary.json',{'wall_seconds':time.perf_counter()-start,'peak_allocated_VRAM':int(torch.cuda.max_memory_allocated()), + 'not_runtime_benchmark':True,'ComfyUI_unloaded':False}) + save(EXP/'audit/run-complete.json',{'synthetic_policies':4,'real_motifs_frozen_only':5,'all_CPU_GPU_exact':True,'learning_achieved':False, + 'alternative_MaleCNS_dynamics_run':False,'original_author_code_executed':False}) + + +def finalize(): + assert (EXP/'audit/run-complete.json').exists() + post=integrity();assert post==json.loads((EXP/'regression/preflight.json').read_text()) + save(EXP/'regression/final-integrity.json',post) + pre=json.loads((EXP/'protocol/preregistered.json').read_text());assert all(digest(MODEL/n)==h for n,h in pre['sources'].items()) + from report import write_report + write_report(EXP) + save(EXP/'audit/final-status.json',{'status':'COMPLETE-SEMANTICS-AUDIT / LEARNING-NOT-ACHIEVED','frozen_integrity_pass':True, + 'documented_adaptation_not_GPU_regression':True,'new_model_authorization_separate':True,'goal_remains_active':True}) + for folder in (MODEL,EXP): + print('SEALED',folder,seal(folder),flush=True);assert manifest_check(folder,digest)['pass'] + + +if __name__=='__main__': + parser=argparse.ArgumentParser();parser.add_argument('task',choices=['prepare','run','finalize']);a=parser.parse_args();globals()[a.task]() diff --git a/models/male-cns-lif/lif-semantics-audit-v1/brian2-evidence.json b/models/male-cns-lif/lif-semantics-audit-v1/brian2-evidence.json new file mode 100644 index 0000000..91da85b --- /dev/null +++ b/models/male-cns-lif/lif-semantics-audit-v1/brian2-evidence.json @@ -0,0 +1,32 @@ +{ + "version": "Brian2 2.5.1", + "source_commit": "577bb35ec677947d6f3d4af367a8a4b3b88815ee", + "method": "Read official source and tests; no executable oracle run", + "claims": [ + { + "claim": "Every differential variable flagged unless refractory has writes guarded by not_refractory; this includes g. Reset explicitly bypasses the guard.", + "source": "https://github.com/brian-team/brian2/blob/577bb35ec677947d6f3d4af367a8a4b3b88815ee/brian2/groups/neurongroup.py", + "lines_1based": [[794,802],[334,351]] + }, + { + "claim": "Default non-legacy refractory release compares integer elapsed steps >= refractory steps; with 2.2 ms and dt 0.1 ms release is n+22.", + "source": "https://github.com/brian-team/brian2/blob/577bb35ec677947d6f3d4af367a8a4b3b88815ee/brian2/groups/neurongroup.py", + "lines_1based": [[178,198],[215,239]] + }, + { + "claim": "Default schedule places groups before thresholds, then synapses, then resets. Newly accepted g at n+22 is integrated in the next groups slot; this is not a 23-step refractory duration.", + "source": "https://github.com/brian-team/brian2/blob/577bb35ec677947d6f3d4af367a8a4b3b88815ee/brian2/core/network.py", + "lines_1based": [[34,42]] + }, + { + "claim": "Official tests assert ten-dt refractory gives ten-dt spike spacing and reject same-tick writes on spiking refractory targets.", + "source": "https://github.com/brian-team/brian2/blob/577bb35ec677947d6f3d4af367a8a4b3b88815ee/brian2/tests/test_refractory.py", + "lines_1based": [[120,127],[232,248]] + } + ], + "caveats": [ + "Assumes default schedule/clocks and legacy.refractory_timing=False.", + "The version 2.5.1 prose refractory documentation uses an inconsistent <= example; use pinned implementation and tests for the release boundary.", + "Synthetic reset/refractory ablations in this audit retain frozen Euler and arrival timing; they are not a Brian2 reproduction." + ] +} diff --git a/models/male-cns-lif/lif-semantics-audit-v1/checksums.sha256 b/models/male-cns-lif/lif-semantics-audit-v1/checksums.sha256 new file mode 100644 index 0000000..5c3a3cd --- /dev/null +++ b/models/male-cns-lif/lif-semantics-audit-v1/checksums.sha256 @@ -0,0 +1,7 @@ +484296e132a836900efaa336d387b6974aa39c6af2dee211b7ba668cf71be257 PROTOCOL.md +f20724387ca7ed63b9e35fb9ce3d2964da44f85318856b7403b5536a442422b8 audit_semantics.py +bebd4dfa2dda1aca601a52b24e3eabdd887ce261c3548e377198ab154d81f16e brian2-evidence.json +433151183a4755f5fdfec33f6a9404aa5fb186ec45866ebb58be4ba3e4ebb568 config.yaml +5166366251f99359b1301f514f5d9ae5f0f041fd3a3f98902386192117f01aea math_reference.py +76a21eca32ff8caba88ab84616e226e687dd0d2df5da62816c81b5ba08297394 report.py +9ee96ed78bfa692b12f0db6862087a19dc351c4afd9bb94cf02733ec6a002f01 test_math.py diff --git a/models/male-cns-lif/lif-semantics-audit-v1/config.yaml b/models/male-cns-lif/lif-semantics-audit-v1/config.yaml new file mode 100644 index 0000000..aa83467 --- /dev/null +++ b/models/male-cns-lif/lif-semantics-audit-v1/config.yaml @@ -0,0 +1,33 @@ +phase: 4AC +root: /data/digital-drosophila +model: models/male-cns-lif/lif-semantics-audit-v1 +experiment: experiments/phase4ac-lif-semantics +runtime: models/male-cns-lif/deterministic-runtime-v2 +canonical: datasets/male-cns-v1.0/processed/neuron-only +old_snapshot: registry/snapshots/bootstrap-20260929 +additional_frozen: + - models/male-cns-lif/apl-pn-scope-audit-v1 + - experiments/phase4aa-apl-pn-scope + - models/male-cns-lif/terminal-scope-diagnostic-v1 + - experiments/phase4ab-terminal-scope +author: + repository: https://github.com/philshiu/Drosophila_brain_model + commit: 91bdd1e7dcf193f3e7ca5a8933497fcef63b7960 + model_sha256: fc45837d7122c6ce2a7f3f2f23c515992e4b232aadb919efabb72337fac88e4e + paper: https://www.nature.com/articles/s41586-024-07763-9 +selected_nodes: [1197, 1381, 1511, 82312, 133666] +seed_node: 1381 +duration_ms: 1000 +late_start_ms: 500 +motifs: + - {name: pair, nodes: [1381, 1511]} + - {name: trio, nodes: [1197, 1381, 1511]} + - {name: five, nodes: [1197, 1381, 1511, 82312, 133666]} + - {name: feedforward, nodes: [1197, 1381, 1511, 82312, 133666], pairs: [[1381,1511],[1511,1197],[1197,133666],[133666,82312]]} + - {name: no_input, nodes: [1197, 1381, 1511, 82312, 133666], force: false} +synthetic_policies: [frozen, reset_g_only, refractory_gate_only, reset_and_refractory] +scope: + full_brain_alternative_dynamics: false + conditioning: false + learned_candidate: false + requires_separate_authorization_for_new_brain_model: true diff --git a/models/male-cns-lif/lif-semantics-audit-v1/manifest.json b/models/male-cns-lif/lif-semantics-audit-v1/manifest.json new file mode 100644 index 0000000..0acdbe5 --- /dev/null +++ b/models/male-cns-lif/lif-semantics-audit-v1/manifest.json @@ -0,0 +1,40 @@ +{ + "created_utc": "2026-09-29T16:58:20.616795+00:00", + "files": [ + { + "bytes": 3661, + "path": "PROTOCOL.md", + "sha256": "484296e132a836900efaa336d387b6974aa39c6af2dee211b7ba668cf71be257" + }, + { + "bytes": 18769, + "path": "audit_semantics.py", + "sha256": "f20724387ca7ed63b9e35fb9ce3d2964da44f85318856b7403b5536a442422b8" + }, + { + "bytes": 1963, + "path": "brian2-evidence.json", + "sha256": "bebd4dfa2dda1aca601a52b24e3eabdd887ce261c3548e377198ab154d81f16e" + }, + { + "bytes": 1464, + "path": "config.yaml", + "sha256": "433151183a4755f5fdfec33f6a9404aa5fb186ec45866ebb58be4ba3e4ebb568" + }, + { + "bytes": 3768, + "path": "math_reference.py", + "sha256": "5166366251f99359b1301f514f5d9ae5f0f041fd3a3f98902386192117f01aea" + }, + { + "bytes": 5237, + "path": "report.py", + "sha256": "76a21eca32ff8caba88ab84616e226e687dd0d2df5da62816c81b5ba08297394" + }, + { + "bytes": 2902, + "path": "test_math.py", + "sha256": "9ee96ed78bfa692b12f0db6862087a19dc351c4afd9bb94cf02733ec6a002f01" + } + ] +} diff --git a/models/male-cns-lif/lif-semantics-audit-v1/math_reference.py b/models/male-cns-lif/lif-semantics-audit-v1/math_reference.py new file mode 100644 index 0000000..74f9789 --- /dev/null +++ b/models/male-cns-lif/lif-semantics-audit-v1/math_reference.py @@ -0,0 +1,70 @@ +"""Exact float32 frozen state arithmetic plus explicitly labelled synthetic ablations.""" +import numpy as np + + +def params(model): + f = np.float32 + return {'gd': f(1-model['dt_ms']/model['synaptic_tau_ms']), + 'alpha': f(model['dt_ms']/model['membrane_tau_ms']), + 'rest': f(model['resting_potential_mv']), 'reset': f(model['reset_potential_mv']), + 'threshold': f(model['threshold_mv']), + 'ref_steps': round(model['refractory_ms']/model['dt_ms']), + 'delay_steps': round(model['synaptic_delay_ms']/model['dt_ms'])} + + +def state(v, g, ref, arrival, p, policy='frozen'): + if policy not in ('frozen', 'reset_g_only', 'refractory_gate_only', 'reset_and_refractory'): + raise ValueError('Unknown synthetic policy: '+policy) + r = np.maximum(ref-1, 0).astype(np.int32) + available = r == 0 + gi = np.add(np.multiply(g, p['gd'], dtype=np.float32), arrival, dtype=np.float32) + if policy in ('refractory_gate_only', 'reset_and_refractory'): + gi = np.where(available, gi, g).astype(np.float32) + leak = np.subtract(v, p['rest'], dtype=np.float32) + dv = np.multiply(p['alpha'], np.subtract(gi, leak, dtype=np.float32), dtype=np.float32) + vi = np.where(available, np.add(v, dv, dtype=np.float32), p['reset']).astype(np.float32) + fire = available & (vi >= p['threshold']) + vi[fire] = p['reset']; r[fire] = p['ref_steps'] + if policy in ('reset_g_only', 'reset_and_refractory'): gi[fire] = np.float32(0) + return vi, gi, r, fire + + +def single(arrivals, p, policy='frozen'): + v = np.array([p['rest']], np.float32); g = np.zeros(1, np.float32); r = np.zeros(1, np.int32) + history = np.empty((len(arrivals), 3), np.float32); events = [] + for t, a in enumerate(arrivals): + v, g, r, fire = state(v, g, r, np.array([a], np.float32), p, policy) + if fire[0]: events.append(t) + history[t] = v[0], g[0], r[0] + return np.asarray(events, np.int32), history + + +def cpu_motif(nodes, edges, weights, p, steps, seed): + assert np.all(np.diff(nodes) > 0), 'Canonical nodes must be sorted and unique' + assert np.all(np.diff(edges.edge_id.to_numpy()) > 0), 'Canonical edge order required' + n = len(nodes); lookup = {int(node): i for i, node in enumerate(nodes)} + src = np.array([lookup[int(x)] for x in edges.source_neuron_idx], np.int32) + dst = np.array([lookup[int(x)] for x in edges.target_neuron_idx], np.int32) + qlen = p['delay_steps']+1; queue = np.zeros((qlen, n), np.float32) + v = np.full(n, p['rest'], np.float32); g = np.zeros(n, np.float32); ref = np.zeros(n, np.int32) + counts = np.zeros(n, np.int32); history = np.empty((steps, 3, n), np.float32) + ts, ns = [], [] + for t in range(steps): + slot = t % qlen + v, g, ref, fire = state(v, g, ref, queue[slot], p); queue[slot] = 0 + if t == 0 and seed is not None: + i = lookup[seed] + assert not fire[i] and ref[i] == 0 + fire[i] = True; v[i] = p['reset']; ref[i] = p['ref_steps'] + counts += fire + active = np.flatnonzero(fire) + ts.extend([t]*len(active)); ns.extend(nodes[active].tolist()) + selected = np.flatnonzero(fire[src]); selected = selected[np.argsort(dst[selected], kind='stable')] + for target in np.unique(dst[selected]): + ix = selected[dst[selected] == target]; acc = np.float32(0) + for e in ix: acc = np.float32(acc+weights[e]) + outslot = (t+p['delay_steps']) % qlen + queue[outslot, target] = np.float32(queue[outslot, target]+acc) + history[t] = v, g, ref + return {'step': np.asarray(ts, np.int32), 'neuron_idx': np.asarray(ns, np.int32), 'counts': counts, + 'v': v, 'g': g, 'ref': ref, 'history': history, 'queue': queue} diff --git a/models/male-cns-lif/lif-semantics-audit-v1/report.py b/models/male-cns-lif/lif-semantics-audit-v1/report.py new file mode 100644 index 0000000..03e2833 --- /dev/null +++ b/models/male-cns-lif/lif-semantics-audit-v1/report.py @@ -0,0 +1,49 @@ +"""Derive a descriptive report, never pick a model winner from activity reduction.""" +import json +import pandas as pd + + +def write_report(exp): + synthetic = pd.read_csv(exp/'synthetic/results.csv') + motifs = pd.read_csv(exp/'motifs/summary.csv') + one = synthetic[synthetic['case'].str.startswith('one_impulse')] + combined = one.pivot(index='case',columns='policy',values='spikes') + lines = [ + '# Phase 4AC — LIF semantics and unchanged-dynamics motif audit', '', + 'Status: COMPLETE-SEMANTICS-AUDIT / LEARNING-NOT-ACHIEVED.', + 'No alternative dynamics deployed to MaleCNS; no conditioning, learned candidate or new formal runtime.', '', + '## Author model versus frozen adapted model', '', + 'Pinned author model resets g on a spike and declares v/g `(unless refractory)`, uses linear integration, strict > threshold and voltage Poisson input with zero refractory on stimulated cells.', + 'The frozen adapted model retains g, decays/accepts events during refractory, uses explicit Euler and >= threshold, and forced sensory spikes respect refractory.', + 'These are documented model choices, not a newly established GPU regression. g is an additive voltage-valued drive, not a measured conductance.', + 'W_syn=0.275 is transferred from a free parameter calibrated in the original FlyWire feeding model, not a measured universal MaleCNS synaptic efficacy.', '', + '## Synthetic single-cell component tests', '', + 'All impulse amplitudes derive from the complete unique contact counts of the predeclared 13 real motif edges plus a one-contact fixture; other boundary/sustained cases are explicitly synthetic unit tests.', + 'These ablations retain frozen Euler arithmetic/scheduling and are NOT complete Brian2 replication. No successful amplitude or policy was selected after seeing results.', '', + '| Single-impulse fixture | Frozen | Reset g only | Refractory gate only | Reset + gate |', + '|---|---:|---:|---:|---:|'] + for name,row in combined.iterrows(): + lines.append(f"| {name} | {int(row.frozen)} | {int(row.reset_g_only)} | {int(row.refractory_gate_only)} | {int(row.reset_and_refractory)} |") + lines += ['', 'Reset-only and combined policies can produce at most one spike from a single isolated input by construction. This does not establish biological correctness or whole-brain learning improvement.', '', + '## Real anatomical motifs — frozen mathematics ONLY', '', + 'One forced seed spike at step 0 except the no-input control; no subsequent input; observed for 1 s. Late window=500–1,000 ms.', + 'The recurrent pair/trio/five are induced subgraphs. The feedforward control selects four existing edges and removes feedback only within this isolated diagnostic harness.', + 'External inhibition, graded APL and other whole-brain inputs are absent. A sustained isolated motif is evidence of sufficiency in this harness, NOT necessity in the complete brain.', '', + '| Motif | neuron_idx | Total spikes | Late spikes | Last ms |', '|---|---:|---:|---:|---:|'] + for r in motifs.itertuples(): + lines.append(f'| {r.motif} | {r.neuron_idx} | {r.spikes} | {r.late_spikes} | {r.last_ms if pd.notna(r.last_ms) else "none"} |') + perf=json.loads((exp/'performance/summary.json').read_text()) + lines += ['', '## Verification and boundaries', '', + 'Seven unit tests; all five real motifs CPU/GPU event, count, final V/g/refractory, queue and timestep history exact; five archived deterministic-v2 full-brain trials exact.', + 'Every selected edge_id, source CSR row, destination and original weight validated; generated prepared inputs hashed. All original snapshot files and Phase 4AA/4AB model/experiment manifests checked before and after.', + f"Diagnostic wall time including compilation and observation: {perf['wall_seconds']:.3f} s. Peak allocated process VRAM: {perf['peak_allocated_VRAM']} bytes. Not a runtime-speed benchmark.", + 'Original author code was inspected, not executed; no Brian2 oracle run and no new package installation. ComfyUI was not stopped or unloaded.', '', + '## Decision', '', + 'The usable-learning gate remains unmet: independent evaluation, A-vs-neutral-B specificity in MBON/downstream, multiple training seeds and conditioning controls still required.', + 'Before any full-network alternative, obtain explicit separate model authorization and distinguish each semantic component; do not claim g reset alone reproduces the author implementation.', + 'No evidence here permits changing eta, thresholds, gain, frozen APL calibration, transmitter signs or the plastic mask.', '', + '## Primary provenance', '', + '[Shiu et al. 2024](https://www.nature.com/articles/s41586-024-07763-9)', + '[Pinned author implementation](https://github.com/philshiu/Drosophila_brain_model/blob/91bdd1e7dcf193f3e7ca5a8933497fcef63b7960/model.py)', + 'Downloaded source, MIT license, environment specification, exact commit, SHA-256 and source clauses retained under external-resources and audit.', ''] + with (exp/'REPORT.md').open('x',encoding='utf-8') as f: f.write('\n'.join(lines)) diff --git a/models/male-cns-lif/lif-semantics-audit-v1/test_math.py b/models/male-cns-lif/lif-semantics-audit-v1/test_math.py new file mode 100644 index 0000000..e0b5bbd --- /dev/null +++ b/models/male-cns-lif/lif-semantics-audit-v1/test_math.py @@ -0,0 +1,59 @@ +"""Independent fixtures; no access to the MaleCNS raw data or experiment outputs.""" +import unittest +import numpy as np +import pandas as pd +from math_reference import params, state, single, cpu_motif + + +class Operators(unittest.TestCase): + def setUp(self): + self.p = params(dict(dt_ms=.1, synaptic_tau_ms=5., membrane_tau_ms=20., + resting_potential_mv=-52., reset_potential_mv=-52., threshold_mv=-45., + refractory_ms=2.2, synaptic_delay_ms=1.8)) + + def test_zero_input_and_exact_repeat(self): + for policy in ('frozen','reset_g_only','refractory_gate_only','reset_and_refractory'): + a, h = single(np.zeros(1000,np.float32),self.p,policy) + self.assertEqual(len(a),0) + np.testing.assert_array_equal(h[:,0],np.full(1000,-52,np.float32)) + self.assertTrue(np.isfinite(h).all()) + np.testing.assert_array_equal(h,single(np.zeros(1000,np.float32),self.p,policy)[1]) + + def test_single_spike_reset(self): + a = np.zeros(1000,np.float32); a[0] = 2000 + for policy in ('reset_g_only','reset_and_refractory'): + ev, h = single(a,self.p,policy) + np.testing.assert_array_equal(ev,[0]); self.assertEqual(h[0,1],0) + + def test_refractory_release_at_22(self): + a = np.zeros(30,np.float32); a[0] = 2000; a[1:23] = 10 + ev, h = single(a,self.p,'reset_and_refractory') + self.assertEqual(ev[0],0) + np.testing.assert_array_equal(h[:22,1],np.zeros(22)) + self.assertEqual(h[21,2],1); self.assertEqual(h[22,2],0) + self.assertEqual(h[22,1],10) + + def test_inhibitory_arrival_sign_preserved(self): + v,g,r,f = state(np.array([-52],np.float32),np.zeros(1,np.float32), + np.zeros(1,np.int32),np.array([-10],np.float32),self.p) + self.assertLess(v[0],-52); self.assertEqual(g[0],-10); self.assertFalse(f[0]) + + def test_exact_delay_and_no_duplicate_count(self): + edges = pd.DataFrame(dict(edge_id=[17],source_neuron_idx=[100],target_neuron_idx=[200])) + r = cpu_motif(np.array([100,200],np.int32),edges,np.array([1],np.float32),self.p,40,100) + np.testing.assert_array_equal(r['step'],[0]); np.testing.assert_array_equal(r['counts'],[1,0]) + self.assertTrue((r['history'][:18,1,1] == 0).all()) + self.assertEqual(r['history'][18,1,1],1) + np.testing.assert_array_equal(r['queue'],np.zeros((19,2),np.float32)) + + def test_ref_gate_is_not_identical_to_reset(self): + a = np.zeros(60,np.float32); a[0] = 2000 + _, frozen = single(a,self.p,'frozen') + _, gate = single(a,self.p,'refractory_gate_only') + self.assertLess(frozen[1,1],frozen[0,1]); self.assertEqual(gate[1,1],gate[0,1]) + + def test_unknown_policy_rejected(self): + with self.assertRaises(ValueError): single(np.zeros(1,np.float32),self.p,'guess') + + +if __name__ == '__main__': unittest.main(verbosity=2) diff --git a/registry/phase4ac-lif-semantics/evidence-index.json b/registry/phase4ac-lif-semantics/evidence-index.json new file mode 100644 index 0000000..13b39ae --- /dev/null +++ b/registry/phase4ac-lif-semantics/evidence-index.json @@ -0,0 +1,242 @@ +[ + { + "bytes": 5154, + "copy": "evidence/INTERPRETATION.zh.md", + "sha256": "e62102c1084dd513dec04f9fdc41570441b25100d5fdcea9e43427f70870f0d7", + "source": "experiments/phase4ac-lif-semantics/INTERPRETATION.zh.md" + }, + { + "bytes": 5210, + "copy": "evidence/REPORT.md", + "sha256": "a8b24e795ee1fc8b2c212367525ef9508d4edce74876a361a9164ce146158569", + "source": "experiments/phase4ac-lif-semantics/REPORT.md" + }, + { + "bytes": 558, + "copy": "evidence/audit/author-source-clauses.json", + "sha256": "7cce72b98892eac115e500340a8c11f6737c0dd83bfd7c9fbd28b2167bf2f60e", + "source": "experiments/phase4ac-lif-semantics/audit/author-source-clauses.json" + }, + { + "bytes": 227, + "copy": "evidence/audit/final-status.json", + "sha256": "c61d57cfb8808b0af5133e5d061e3ed6c435a6475f7a23b90f16c2de45d999fb", + "source": "experiments/phase4ac-lif-semantics/audit/final-status.json" + }, + { + "bytes": 1552, + "copy": "evidence/audit/local-inhibition-crosswalk.csv", + "sha256": "d2e2c65cffa100598c6f991bcf8df3b094501fbe59d34519839df280a2d8b087", + "source": "experiments/phase4ac-lif-semantics/audit/local-inhibition-crosswalk.csv" + }, + { + "bytes": 208, + "copy": "evidence/audit/run-complete.json", + "sha256": "4480a78f84ecca51e4153fa8cc9650a7f77ca3a91c04cd14cbe653a4f9162e4c", + "source": "experiments/phase4ac-lif-semantics/audit/run-complete.json" + }, + { + "bytes": 547, + "copy": "evidence/audit/selected-real-edges.csv", + "sha256": "9103e9d03fa21058a4f6cd21780c56fed8cdcfca26c34c2a43726e39aed8ec55", + "source": "experiments/phase4ac-lif-semantics/audit/selected-real-edges.csv" + }, + { + "bytes": 531, + "copy": "evidence/audit/semantics-differences.csv", + "sha256": "1ea234a0a1fff64234dbff05e1f25513151295b0cfb0a1fc7bd174d3f5b7e3e6", + "source": "experiments/phase4ac-lif-semantics/audit/semantics-differences.csv" + }, + { + "bytes": 5427, + "copy": "evidence/checksums.sha256", + "sha256": "81bb3a86454147f1562bc3592438b6a6d0091dbe1d2a777e802882ecf1d0db35", + "source": "experiments/phase4ac-lif-semantics/checksums.sha256" + }, + { + "bytes": 1085, + "copy": "evidence/external-resources/LICENSE", + "sha256": "3621f6d6476189190e2960fa43f11b275ba4eca848fdac50a1ba2925de6223e8", + "source": "experiments/phase4ac-lif-semantics/external-resources/LICENSE" + }, + { + "bytes": 3445, + "copy": "evidence/external-resources/environment_full.yml", + "sha256": "402fcef4968c99397b0e908b3323ab9e6ef86af5583e46e6427f96f3d1091adf", + "source": "experiments/phase4ac-lif-semantics/external-resources/environment_full.yml" + }, + { + "bytes": 11900, + "copy": "evidence/external-resources/model.py", + "sha256": "fc45837d7122c6ce2a7f3f2f23c515992e4b232aadb919efabb72337fac88e4e", + "source": "experiments/phase4ac-lif-semantics/external-resources/model.py" + }, + { + "bytes": 1137, + "copy": "evidence/external-resources/provenance.json", + "sha256": "7dc4014bbf9fbe64665a82d4542bba71df7c4497064850d30ef0278f23ba2e49", + "source": "experiments/phase4ac-lif-semantics/external-resources/provenance.json" + }, + { + "bytes": 442, + "copy": "evidence/gpu-reference/extension.json", + "sha256": "9d88976e53ac778d64887e0708aaf06922af3fddb69717b4cda2ea4bb750c2ae", + "source": "experiments/phase4ac-lif-semantics/gpu-reference/extension.json" + }, + { + "bytes": 9363, + "copy": "evidence/manifest.json", + "sha256": "4e7d1606e107fe72f5dad935952705260577edaba6f811d65b4105ce07abd72c", + "source": "experiments/phase4ac-lif-semantics/manifest.json" + }, + { + "bytes": 228, + "copy": "evidence/motifs/feedforward-edges.csv", + "sha256": "add7a3b450e3f3043af602baf8e770e5358c1c024d44bb21a74ef18429c0680e", + "source": "experiments/phase4ac-lif-semantics/motifs/feedforward-edges.csv" + }, + { + "bytes": 547, + "copy": "evidence/motifs/five-edges.csv", + "sha256": "9103e9d03fa21058a4f6cd21780c56fed8cdcfca26c34c2a43726e39aed8ec55", + "source": "experiments/phase4ac-lif-semantics/motifs/five-edges.csv" + }, + { + "bytes": 547, + "copy": "evidence/motifs/no_input-edges.csv", + "sha256": "9103e9d03fa21058a4f6cd21780c56fed8cdcfca26c34c2a43726e39aed8ec55", + "source": "experiments/phase4ac-lif-semantics/motifs/no_input-edges.csv" + }, + { + "bytes": 152, + "copy": "evidence/motifs/pair-edges.csv", + "sha256": "05a7c7a5547aaeea4d1522f9cea75463405f0c3cdfbc4d563f111ad51cb80e00", + "source": "experiments/phase4ac-lif-semantics/motifs/pair-edges.csv" + }, + { + "bytes": 1009, + "copy": "evidence/motifs/summary.csv", + "sha256": "4e762a26ecc7d3c3f862260495b6064a60832431b61dd41b944e8c501617a906", + "source": "experiments/phase4ac-lif-semantics/motifs/summary.csv" + }, + { + "bytes": 288, + "copy": "evidence/motifs/trio-edges.csv", + "sha256": "c842c5bce0b11275c0eba9532955026a4b58931c2346e178bfa8a84227289c71", + "source": "experiments/phase4ac-lif-semantics/motifs/trio-edges.csv" + }, + { + "bytes": 138, + "copy": "evidence/performance/summary.json", + "sha256": "ef768705779fdf1fa5563e00d80b703ee70804742bbf4fa701c4d63532896f80", + "source": "experiments/phase4ac-lif-semantics/performance/summary.json" + }, + { + "bytes": 291, + "copy": "evidence/protocol/dynamics.json", + "sha256": "a5aa62f5588fbf754c6164b69d61a5154d23fc8f749ae4c36aea3f4ad1fa2576", + "source": "experiments/phase4ac-lif-semantics/protocol/dynamics.json" + }, + { + "bytes": 434, + "copy": "evidence/protocol/frozen-input-hashes.json", + "sha256": "6cbe6b4b43f7e3928b247a2188b955be5431224a01f8c0838544a0b9f34fe569", + "source": "experiments/phase4ac-lif-semantics/protocol/frozen-input-hashes.json" + }, + { + "bytes": 524, + "copy": "evidence/protocol/prepared-input-hashes.json", + "sha256": "726e949b87ebd4e15e10ed3a57336f03bc8e4c2e13ebe8b7e8dbb718166b4f6e", + "source": "experiments/phase4ac-lif-semantics/protocol/prepared-input-hashes.json" + }, + { + "bytes": 3227, + "copy": "evidence/protocol/preregistered.json", + "sha256": "00a18f5e7e41892011cc69e25a151e61d1a44352b2152a11f77ef4576dfb83bf", + "source": "experiments/phase4ac-lif-semantics/protocol/preregistered.json" + }, + { + "bytes": 182, + "copy": "evidence/regression/anatomical-edge-validation.json", + "sha256": "96eed02282d703f483873bf56cacc9147ebdfb6c7cd25d159a8161a2d3532ee5", + "source": "experiments/phase4ac-lif-semantics/regression/anatomical-edge-validation.json" + }, + { + "bytes": 185, + "copy": "evidence/regression/feedforward.json", + "sha256": "1125ada92933e1f69c53b1f2085c9678c154854b2ff1bbfcc68ffe851bac118b", + "source": "experiments/phase4ac-lif-semantics/regression/feedforward.json" + }, + { + "bytes": 1664, + "copy": "evidence/regression/final-integrity.json", + "sha256": "f39187d9efcc54ca48beed0b6daf3e18368652e11bef62065bcc988a9fc4fcdc", + "source": "experiments/phase4ac-lif-semantics/regression/final-integrity.json" + }, + { + "bytes": 185, + "copy": "evidence/regression/five.json", + "sha256": "1125ada92933e1f69c53b1f2085c9678c154854b2ff1bbfcc68ffe851bac118b", + "source": "experiments/phase4ac-lif-semantics/regression/five.json" + }, + { + "bytes": 1206, + "copy": "evidence/regression/frozen-five.json", + "sha256": "0aa4d6b309121bf203ea475ea797136f21a46aba8e1dc513c2b522d3b2c97434", + "source": "experiments/phase4ac-lif-semantics/regression/frozen-five.json" + }, + { + "bytes": 494, + "copy": "evidence/regression/motifs.json", + "sha256": "31716107c5c2c6b9d05b81373f0ec7d95be15147e9cb84296fd8ef898e2338af", + "source": "experiments/phase4ac-lif-semantics/regression/motifs.json" + }, + { + "bytes": 185, + "copy": "evidence/regression/no_input.json", + "sha256": "1125ada92933e1f69c53b1f2085c9678c154854b2ff1bbfcc68ffe851bac118b", + "source": "experiments/phase4ac-lif-semantics/regression/no_input.json" + }, + { + "bytes": 185, + "copy": "evidence/regression/pair.json", + "sha256": "1125ada92933e1f69c53b1f2085c9678c154854b2ff1bbfcc68ffe851bac118b", + "source": "experiments/phase4ac-lif-semantics/regression/pair.json" + }, + { + "bytes": 1664, + "copy": "evidence/regression/preflight.json", + "sha256": "f39187d9efcc54ca48beed0b6daf3e18368652e11bef62065bcc988a9fc4fcdc", + "source": "experiments/phase4ac-lif-semantics/regression/preflight.json" + }, + { + "bytes": 179, + "copy": "evidence/regression/run-start.json", + "sha256": "68c3f652297bd8e7f8de7fb286ff45f1d3a59668df8313f17d1b6793ddada6ab", + "source": "experiments/phase4ac-lif-semantics/regression/run-start.json" + }, + { + "bytes": 155, + "copy": "evidence/regression/synthetic.json", + "sha256": "25cf81371c5a05ba841406f2ede9c4ddd4e2dec00230e90c3985879624337336", + "source": "experiments/phase4ac-lif-semantics/regression/synthetic.json" + }, + { + "bytes": 185, + "copy": "evidence/regression/trio.json", + "sha256": "1125ada92933e1f69c53b1f2085c9678c154854b2ff1bbfcc68ffe851bac118b", + "source": "experiments/phase4ac-lif-semantics/regression/trio.json" + }, + { + "bytes": 33, + "copy": "evidence/regression/unit-tests.json", + "sha256": "abe9ac4065f0ddeb5697b971e12aab4f36946eaa819536a06ecc58d0d2f0eb70", + "source": "experiments/phase4ac-lif-semantics/regression/unit-tests.json" + }, + { + "bytes": 7495, + "copy": "evidence/synthetic/results.csv", + "sha256": "3a05e5a7f0d95935c1e14ad4eb733575759f1f170f3c61ee9e94c7d86dd917c4", + "source": "experiments/phase4ac-lif-semantics/synthetic/results.csv" + } +] diff --git a/registry/phase4ac-lif-semantics/evidence/INTERPRETATION.zh.md b/registry/phase4ac-lif-semantics/evidence/INTERPRETATION.zh.md new file mode 100644 index 0000000..352f0e9 --- /dev/null +++ b/registry/phase4ac-lif-semantics/evidence/INTERPRETATION.zh.md @@ -0,0 +1,71 @@ +# Phase 4AC:反馈环路足以持续放电,尚未得到学习修复 + +状态:`COMPLETE-SEMANTICS-AUDIT / LEARNING-NOT-ACHIEVED`。 + +## 这次真正增加的证据 + +从已有异常传播路径选取真实 MaleCNS 神经元和 13 条真实连接。 +只施加一次初始脉冲,随后无外部输入,观察 1 s。所有真实回路测试继续使用冻结动力学。 + +| 小回路 | 总放电数 | 500–1,000 ms 放电数 | +|---|---:|---:| +| 两枚 ALLN 互相连接 | 473 | 238 | +| 三枚 ALLN | 1,064 | 535 | +| 三枚 ALLN + VA6 PN + KC | 1,483 | 747 | +| 只保留四条真实前向连接的对照 | 3 | 0 | +| 五神经元回路,无初始输入 | 0 | 0 | + +最小互相连接的两枚神经元是: + +- neuron_idx 1381 / body_id 11478 → neuron_idx 1511 / body_id 11620:235 contacts。 +- neuron_idx 1511 / body_id 11620 → neuron_idx 1381 / body_id 11478:283 contacts。 +- 两者 metadata 均为 ALLN / lLN1_bc,递质 annotation 和 ground truth 均为 acetylcholine。未改变符号。 + +它们在冻结 LIF 下,从一次输入即可相互维持放电到 1 s 观察期末。 +五神经元回路的 VA6 PN(133666 / 527577)有 297 次放电,KC(82312 / 109321)有 80 次放电。 +这把“持续反馈驱动 KC”缩小到可逐步检查的真实局部回路。 + +**限定结论:**这是隔离回路中的充分性证据,不是全脑必要性证据;外部抑制、分级 APL 及其他回路在这里不参与。 +前向对照移除了反馈连接,只是诊断 harness,不是提交了一个删边新模型。1 s 持续不等于证明无限持续。 + +## 原作者语义差异,不等于已找到修复 + +[Shiu 作者固定版本代码](https://github.com/philshiu/Drosophila_brain_model/blob/91bdd1e7dcf193f3e7ca5a8933497fcef63b7960/model.py) +在 spike 后清零 g,v/g 的不应期更新受限,使用 linear 积分和严格 > 阈值;刺激细胞的 Poisson 输入及不应期也与本项目不同。 +本项目的冻结版本明确记录了保留 g、不应期继续衰减/接收输入、Euler 积分等适配选择。 +因此不能把它说成 CUDA 引入的新错误,也不能把“g 清零”称为严格复现原作者模型。 + +本次单细胞 component tests 有意保留冻结的其他数学语义,仅分别比较 g reset 和 refractory gate。 +真实 13 条连接强度加一个单突触 fixture 下,冻结策略、reset-only、reset+gate 的单次输入 spike 数相同(0 或 1)。 +单独冻结不应期 g、但不清零 g,反而在 283-contact fixture 中产生 2 次 spike,而其他三种策略为 1 次。 +人工持续输入停止后,冻结策略有 4 次尾随 spike,reset-only 有 1 次、reset+gate 有 0 次,gate-only 则有 14 次。 + +这些结果表明组件选择确实会改变响应,但不支持“随便加一个不应期限制就能解决”。 +两个强连接各自仍能从一次输入触发一次响应,所以也不能仅凭单细胞 reset 测试宣称真实反馈环已被消除。 +所有替代组件仅运行于人工单细胞 fixture,没有部署到 MaleCNS 全脑或训练实验。 + +[Brian2 2.5.1 固定实现](https://github.com/brian-team/brian2/blob/577bb35ec677947d6f3d4af367a8a4b3b88815ee/brian2/groups/neurongroup.py) +在默认非 legacy 设置下,不应期是 22 steps;第 23 step 才积分某些新到达输入属于调度顺序,不是不应期延长。 +原作者模型、license、环境文件、固定 commit、SHA-256 与源码位置均已记录;尚未执行独立 Brian2 oracle。 + +## 验证 + +- 7 项单元测试通过;17 组单细胞 fixture × 4 策略均有限且重复一致。 +- 五个真实小回路的全部事件、计数、每步 V/g/ref、最终状态和环形队列 CPU/GPU 精确一致。 +- 五组 deterministic-v2 全脑参考 trial 的事件、计数、最终 V/g 精确一致。 +- 逐条核对真实 edge_id、源 CSR 行、目标和原始 count;准备输入另有 SHA-256。 +- 完整性终检覆盖原快照 230,239 项,以及 Phase 4AA / 4AB 的模型与实验 manifest。 +- GPU 诊断含构建/观察/回归共 95.398 s;本进程 peak allocated VRAM 285,994,496 bytes。不是性能 benchmark,不含 ComfyUI 驻留显存。 +- 保留旧加载器只读 NumPy→Torch 警告;未修改加载器,完整性和回归另行验证。 + +## 学习目标与下一道关口 + +当前没有新的 learned model,没有训练,也没有重新宣称学习 PASS。 +可用学习仍须在独立评价种子上证明 A 相对中性 B 的特异性、MBON/downstream 功能变化及完整对照;权重变化、稀疏化或静默都不能替代。 + +下一步应先在明确授权的新模型分支中验证作者算子与有生理依据的局部反馈机制,并用独立 oracle 区分每一项语义。 +不能将减少放电自动选为正确模型;还必须保留输入区别、可传播性和后续关联记忆能力。 +不改 raw、CSR、原始突触数、已定递质符号、冻结版本、APL calibration、eligibility-v2 或 plastic mask。 +不进入游戏、decoder、RL 或视觉路线。 + +Git 只同步源代码、小报告与校验清单。完整数据仍在服务器,不能声称已完成异机大数据备份。 diff --git a/registry/phase4ac-lif-semantics/evidence/REPORT.md b/registry/phase4ac-lif-semantics/evidence/REPORT.md new file mode 100644 index 0000000..5ceb8f4 --- /dev/null +++ b/registry/phase4ac-lif-semantics/evidence/REPORT.md @@ -0,0 +1,83 @@ +# Phase 4AC — LIF semantics and unchanged-dynamics motif audit + +Status: COMPLETE-SEMANTICS-AUDIT / LEARNING-NOT-ACHIEVED. +No alternative dynamics deployed to MaleCNS; no conditioning, learned candidate or new formal runtime. + +## Author model versus frozen adapted model + +Pinned author model resets g on a spike and declares v/g `(unless refractory)`, uses linear integration, strict > threshold and voltage Poisson input with zero refractory on stimulated cells. +The frozen adapted model retains g, decays/accepts events during refractory, uses explicit Euler and >= threshold, and forced sensory spikes respect refractory. +These are documented model choices, not a newly established GPU regression. g is an additive voltage-valued drive, not a measured conductance. +W_syn=0.275 is transferred from a free parameter calibrated in the original FlyWire feeding model, not a measured universal MaleCNS synaptic efficacy. + +## Synthetic single-cell component tests + +All impulse amplitudes derive from the complete unique contact counts of the predeclared 13 real motif edges plus a one-contact fixture; other boundary/sustained cases are explicitly synthetic unit tests. +These ablations retain frozen Euler arithmetic/scheduling and are NOT complete Brian2 replication. No successful amplitude or policy was selected after seeing results. + +| Single-impulse fixture | Frozen | Reset g only | Refractory gate only | Reset + gate | +|---|---:|---:|---:|---:| +| one_impulse_contacts_1 | 0 | 0 | 0 | 0 | +| one_impulse_contacts_104 | 0 | 0 | 0 | 0 | +| one_impulse_contacts_172 | 1 | 1 | 1 | 1 | +| one_impulse_contacts_210 | 1 | 1 | 1 | 1 | +| one_impulse_contacts_226 | 1 | 1 | 1 | 1 | +| one_impulse_contacts_235 | 1 | 1 | 1 | 1 | +| one_impulse_contacts_259 | 1 | 1 | 1 | 1 | +| one_impulse_contacts_283 | 1 | 1 | 2 | 1 | +| one_impulse_contacts_43 | 0 | 0 | 0 | 0 | +| one_impulse_contacts_57 | 0 | 0 | 0 | 0 | +| one_impulse_contacts_64 | 0 | 0 | 0 | 0 | +| one_impulse_contacts_70 | 0 | 0 | 0 | 0 | +| one_impulse_contacts_76 | 0 | 0 | 0 | 0 | +| one_impulse_contacts_95 | 0 | 0 | 0 | 0 | + +Reset-only and combined policies can produce at most one spike from a single isolated input by construction. This does not establish biological correctness or whole-brain learning improvement. + +## Real anatomical motifs — frozen mathematics ONLY + +One forced seed spike at step 0 except the no-input control; no subsequent input; observed for 1 s. Late window=500–1,000 ms. +The recurrent pair/trio/five are induced subgraphs. The feedforward control selects four existing edges and removes feedback only within this isolated diagnostic harness. +External inhibition, graded APL and other whole-brain inputs are absent. A sustained isolated motif is evidence of sufficiency in this harness, NOT necessity in the complete brain. + +| Motif | neuron_idx | Total spikes | Late spikes | Last ms | +|---|---:|---:|---:|---:| +| pair | 1381 | 237 | 119 | 999.3 | +| pair | 1511 | 236 | 119 | 997.5 | +| trio | 1197 | 355 | 179 | 999.3 | +| trio | 1381 | 355 | 178 | 997.8 | +| trio | 1511 | 354 | 178 | 997.4 | +| five | 1197 | 370 | 185 | 998.8 | +| five | 1381 | 369 | 185 | 997.4 | +| five | 1511 | 367 | 186 | 999.5 | +| five | 82312 | 80 | 41 | 990.3 | +| five | 133666 | 297 | 150 | 999.5 | +| feedforward | 1197 | 1 | 0 | 10.0 | +| feedforward | 1381 | 1 | 0 | 0.0 | +| feedforward | 1511 | 1 | 0 | 4.9 | +| feedforward | 82312 | 0 | 0 | none | +| feedforward | 133666 | 0 | 0 | none | +| no_input | 1197 | 0 | 0 | none | +| no_input | 1381 | 0 | 0 | none | +| no_input | 1511 | 0 | 0 | none | +| no_input | 82312 | 0 | 0 | none | +| no_input | 133666 | 0 | 0 | none | + +## Verification and boundaries + +Seven unit tests; all five real motifs CPU/GPU event, count, final V/g/refractory, queue and timestep history exact; five archived deterministic-v2 full-brain trials exact. +Every selected edge_id, source CSR row, destination and original weight validated; generated prepared inputs hashed. All original snapshot files and Phase 4AA/4AB model/experiment manifests checked before and after. +Diagnostic wall time including compilation and observation: 95.398 s. Peak allocated process VRAM: 285994496 bytes. Not a runtime-speed benchmark. +Original author code was inspected, not executed; no Brian2 oracle run and no new package installation. ComfyUI was not stopped or unloaded. + +## Decision + +The usable-learning gate remains unmet: independent evaluation, A-vs-neutral-B specificity in MBON/downstream, multiple training seeds and conditioning controls still required. +Before any full-network alternative, obtain explicit separate model authorization and distinguish each semantic component; do not claim g reset alone reproduces the author implementation. +No evidence here permits changing eta, thresholds, gain, frozen APL calibration, transmitter signs or the plastic mask. + +## Primary provenance + +[Shiu et al. 2024](https://www.nature.com/articles/s41586-024-07763-9) +[Pinned author implementation](https://github.com/philshiu/Drosophila_brain_model/blob/91bdd1e7dcf193f3e7ca5a8933497fcef63b7960/model.py) +Downloaded source, MIT license, environment specification, exact commit, SHA-256 and source clauses retained under external-resources and audit. diff --git a/registry/phase4ac-lif-semantics/evidence/audit/author-source-clauses.json b/registry/phase4ac-lif-semantics/evidence/audit/author-source-clauses.json new file mode 100644 index 0000000..99340cf --- /dev/null +++ b/registry/phase4ac-lif-semantics/evidence/audit/author-source-clauses.json @@ -0,0 +1,40 @@ +[ + { + "clause": "dg/dt = -g / tau", + "line_numbers_1based": [ + 46 + ] + }, + { + "clause": "(unless refractory)", + "line_numbers_1based": [ + 45, + 46 + ] + }, + { + "clause": "v = v_rst; w = 0; g = 0 * mV", + "line_numbers_1based": [ + 52 + ] + }, + { + "clause": "method='linear'", + "line_numbers_1based": [ + 163 + ] + }, + { + "clause": "'v > v_th'", + "line_numbers_1based": [ + 50 + ] + }, + { + "clause": "neu[i].rfc = 0 * ms", + "line_numbers_1based": [ + 92, + 103 + ] + } +] diff --git a/registry/phase4ac-lif-semantics/evidence/audit/final-status.json b/registry/phase4ac-lif-semantics/evidence/audit/final-status.json new file mode 100644 index 0000000..9fc4ca8 --- /dev/null +++ b/registry/phase4ac-lif-semantics/evidence/audit/final-status.json @@ -0,0 +1,7 @@ +{ + "documented_adaptation_not_GPU_regression": true, + "frozen_integrity_pass": true, + "goal_remains_active": true, + "new_model_authorization_separate": true, + "status": "COMPLETE-SEMANTICS-AUDIT / LEARNING-NOT-ACHIEVED" +} diff --git a/registry/phase4ac-lif-semantics/evidence/audit/local-inhibition-crosswalk.csv b/registry/phase4ac-lif-semantics/evidence/audit/local-inhibition-crosswalk.csv new file mode 100644 index 0000000..729ecd1 --- /dev/null +++ b/registry/phase4ac-lif-semantics/evidence/audit/local-inhibition-crosswalk.csv @@ -0,0 +1,33 @@ +neuron_idx,body_id,annotation_type,annotation_hemibrainType,annotation_flywireType,annotation_matchingNotes,neurotransmitter,nt_ground_truth +119,10133,lLN2F_b,lLN2F_b,lLN2F_b,,gaba, +153,10169,lLN2F_b,lLN2F_b,lLN2F_b,,gaba, +348,10376,lLN2F_b,lLN2F_b,lLN2F_b,,gaba, +478,10515,lLN2F_b,lLN2F_b,lLN2F_b,,gaba, +1495,11603,lLN2P_a,lLN2P_a,lLN2P_a,,gaba, +3104,13315,lLN2P_b,lLN2P_b,lLN2P_b,,gaba,gaba +6699,17325,lLN2P_a,lLN2P_a,lLN2P_a,,gaba, +7323,18016,lLN2P_c,lLN2P_c,lLN2P_c,,gaba, +7454,18165,lLN2P_b,lLN2P_b,lLN2P_b,,gaba,gaba +7955,18726,lLN2P_c,lLN2P_c,lLN2P_c,,gaba, +7959,18730,lLN2P_b,lLN2P_b,lLN2P_b,,gaba,gaba +8889,19767,lLN2P_b,lLN2P_b,lLN2P_b,,gaba,gaba +9025,19921,lLN2P_a,lLN2P_a,lLN2P_a,,gaba, +9447,20402,lLN2P_b,lLN2P_b,lLN2P_b,,gaba,gaba +9607,20581,lLN2P_c,lLN2P_c,lLN2P_c,,gaba, +9643,20620,lLN2P_b,lLN2P_b,lLN2P_b,,gaba,gaba +10488,21567,lLN2P_c,lLN2P_c,lLN2P_c,,gaba, +11035,22166,lLN2P_c,lLN2P_c,lLN2P_c,,gaba, +11106,22243,lLN2P_c,lLN2P_c,lLN2P_c,,gaba, +11136,22276,lLN2P_a,lLN2P_a,lLN2P_a,,gaba, +12550,23854,lLN2P_a,lLN2P_a,lLN2P_a,,gaba, +13411,24828,lLN2P_b,lLN2P_b,lLN2P_b,,gaba,gaba +15720,27416,lLN2P_b,lLN2P_b,lLN2P_b,,gaba,gaba +15896,27614,lLN2P_b,lLN2P_b,lLN2P_b,,gaba,gaba +16611,28406,lLN2P_c,lLN2P_c,lLN2P_c,,gaba, +16714,28525,lLN2P_b,lLN2P_b,lLN2P_b,,gaba,gaba +18392,30421,lLN2P_b,lLN2P_b,lLN2P_b,,gaba,gaba +22591,35196,lLN2P_a,lLN2P_a,lLN2P_a,,gaba, +96266,130279,lLN2P_b,lLN2P_b,lLN2P_b,,gaba,gaba +123710,267437,lLN2P_c,lLN2P_c,lLN2P_c,,gaba, +141783,551294,lLN2P_c,lLN2P_c,lLN2P_c,,gaba, +164024,918582,lLN2P_a,lLN2P_a,lLN2P_a,,gaba, diff --git a/registry/phase4ac-lif-semantics/evidence/audit/run-complete.json b/registry/phase4ac-lif-semantics/evidence/audit/run-complete.json new file mode 100644 index 0000000..f93f228 --- /dev/null +++ b/registry/phase4ac-lif-semantics/evidence/audit/run-complete.json @@ -0,0 +1,8 @@ +{ + "all_CPU_GPU_exact": true, + "alternative_MaleCNS_dynamics_run": false, + "learning_achieved": false, + "original_author_code_executed": false, + "real_motifs_frozen_only": 5, + "synthetic_policies": 4 +} diff --git a/registry/phase4ac-lif-semantics/evidence/audit/selected-real-edges.csv b/registry/phase4ac-lif-semantics/evidence/audit/selected-real-edges.csv new file mode 100644 index 0000000..cbdc51f --- /dev/null +++ b/registry/phase4ac-lif-semantics/evidence/audit/selected-real-edges.csv @@ -0,0 +1,14 @@ +edge_id,source_neuron_idx,target_neuron_idx,raw_count,source_body_id,target_body_id +1336648,1197,1381,210,11289,11478 +1336655,1197,1511,172,11289,11620 +1337065,1197,133666,104,11289,527577 +1467340,1381,1197,259,11478,11289 +1467355,1381,1511,235,11478,11620 +1467852,1381,133666,64,11478,527577 +1559765,1511,1197,226,11620,11289 +1559772,1511,1381,283,11620,11478 +1560267,1511,133666,70,11620,527577 +20992285,133666,1197,95,527577,11289 +20992291,133666,1381,57,527577,11478 +20992294,133666,1511,76,527577,11620 +20992891,133666,82312,43,527577,109321 diff --git a/registry/phase4ac-lif-semantics/evidence/audit/semantics-differences.csv b/registry/phase4ac-lif-semantics/evidence/audit/semantics-differences.csv new file mode 100644 index 0000000..3be4103 --- /dev/null +++ b/registry/phase4ac-lif-semantics/evidence/audit/semantics-differences.csv @@ -0,0 +1,8 @@ +item,author,frozen_adapted +spike reset g,reset to zero,retain g +g during refractory,ODE paused; synaptic writes blocked,decay and accept arrivals +integration,linear exact state updater,forward Euler with decayed g +threshold,strict >,>= +within-step arrivals,"after integration, before reset",before integration +stimulated neurons,voltage Poisson input; refractory=0,forced spikes subject to 22-step refractory +W_syn,free parameter calibrated on FlyWire feeding response,same value transferred to MaleCNS; not independently measured diff --git a/registry/phase4ac-lif-semantics/evidence/checksums.sha256 b/registry/phase4ac-lif-semantics/evidence/checksums.sha256 new file mode 100644 index 0000000..0f179c3 --- /dev/null +++ b/registry/phase4ac-lif-semantics/evidence/checksums.sha256 @@ -0,0 +1,57 @@ +e62102c1084dd513dec04f9fdc41570441b25100d5fdcea9e43427f70870f0d7 INTERPRETATION.zh.md +a8b24e795ee1fc8b2c212367525ef9508d4edce74876a361a9164ce146158569 REPORT.md +7cce72b98892eac115e500340a8c11f6737c0dd83bfd7c9fbd28b2167bf2f60e audit/author-source-clauses.json +c61d57cfb8808b0af5133e5d061e3ed6c435a6475f7a23b90f16c2de45d999fb audit/final-status.json +d2e2c65cffa100598c6f991bcf8df3b094501fbe59d34519839df280a2d8b087 audit/local-inhibition-crosswalk.csv +4480a78f84ecca51e4153fa8cc9650a7f77ca3a91c04cd14cbe653a4f9162e4c audit/run-complete.json +c1dde5df5408aeb878d6c422bc1c86ba44c3c5770f986014e594e356412a013d audit/selected-metadata.parquet +9103e9d03fa21058a4f6cd21780c56fed8cdcfca26c34c2a43726e39aed8ec55 audit/selected-real-edges.csv +1ea234a0a1fff64234dbff05e1f25513151295b0cfb0a1fc7bd174d3f5b7e3e6 audit/semantics-differences.csv +3621f6d6476189190e2960fa43f11b275ba4eca848fdac50a1ba2925de6223e8 external-resources/LICENSE +402fcef4968c99397b0e908b3323ab9e6ef86af5583e46e6427f96f3d1091adf external-resources/environment_full.yml +fc45837d7122c6ce2a7f3f2f23c515992e4b232aadb919efabb72337fac88e4e external-resources/model.py +7dc4014bbf9fbe64665a82d4542bba71df7c4497064850d30ef0278f23ba2e49 external-resources/provenance.json +cb6874d704e9a87f617eef07b92ab961a0440c6667a2f1a501982c9d9dfdee6d gpu-reference/extension-build/.ninja_deps +d7d7f7a1769a481f922466bc05f05c1e8684c46da24d46d0edc0ffe434a5be23 gpu-reference/extension-build/.ninja_log +c570f72b9a2f486e104ed3bf5b1b9f2ccc729ecab02046cd62389d629fb4f48f gpu-reference/extension-build/build.ninja +e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 gpu-reference/extension-build/lock +f65d7c0d58aa7434a74eab446c528146b3fbd7282a1d5c47e3253999ba037721 gpu-reference/extension-build/male_cns_lif_deterministic_v2_ext.so +0635c52d1a7ffe457b52cf01fa71edf99295136abe73f0abd75ac8152e415151 gpu-reference/extension-build/phase4p_ext.cuda.o +27d284f6a369221a931251b5a03ce133cc8231a97942567d4efafbfb45483811 gpu-reference/extension-build/phase4p_ext.o +9d88976e53ac778d64887e0708aaf06922af3fddb69717b4cda2ea4bb750c2ae gpu-reference/extension.json +add7a3b450e3f3043af602baf8e770e5358c1c024d44bb21a74ef18429c0680e motifs/feedforward-edges.csv +f687cf303d9318404c954e2e699d65d7893ad3f33115c0f9c5ea45b9698ff275 motifs/feedforward-events.parquet +6a24c8d2ad476e2250af49172be12de9d43346bc84f043b19d012fa0c53d2fba motifs/feedforward-state.npz +9103e9d03fa21058a4f6cd21780c56fed8cdcfca26c34c2a43726e39aed8ec55 motifs/five-edges.csv +19fef92b32be32ced2ec6b6581c9dac05055e9d550c104dd0d5ec5e33e25e759 motifs/five-events.parquet +15095ada05014741f6b6576c2d12d1a8f1ae482ae6f012d5e2be346c796baf4b motifs/five-state.npz +9103e9d03fa21058a4f6cd21780c56fed8cdcfca26c34c2a43726e39aed8ec55 motifs/no_input-edges.csv +071326bc3033505f431e38d716cb8ec681dc192b8389792059bb8a75027a1f10 motifs/no_input-events.parquet +a74134da72381d0dbff10bb5143691add6081487dede488a939bb0a4dbf5c20e motifs/no_input-state.npz +05a7c7a5547aaeea4d1522f9cea75463405f0c3cdfbc4d563f111ad51cb80e00 motifs/pair-edges.csv +962a440924a9b2a4a3677b8968e63042de0b80ea4e496c213ebcf40d5e530e85 motifs/pair-events.parquet +924774344956dd5a530c3d00c8103fe4d1b584837d5e91f05b60094540a78897 motifs/pair-state.npz +4e762a26ecc7d3c3f862260495b6064a60832431b61dd41b944e8c501617a906 motifs/summary.csv +c842c5bce0b11275c0eba9532955026a4b58931c2346e178bfa8a84227289c71 motifs/trio-edges.csv +a39d58de867f4f1ce1291e0ece25a52b70a3e04024508f77cb4a29eb4e09fa0e motifs/trio-events.parquet +46c8a495ee1358a6173a2eebebe9ce2d6481b27f10e0c56cf9602c7969cd8702 motifs/trio-state.npz +ef768705779fdf1fa5563e00d80b703ee70804742bbf4fa701c4d63532896f80 performance/summary.json +a5aa62f5588fbf754c6164b69d61a5154d23fc8f749ae4c36aea3f4ad1fa2576 protocol/dynamics.json +6cbe6b4b43f7e3928b247a2188b955be5431224a01f8c0838544a0b9f34fe569 protocol/frozen-input-hashes.json +726e949b87ebd4e15e10ed3a57336f03bc8e4c2e13ebe8b7e8dbb718166b4f6e protocol/prepared-input-hashes.json +00a18f5e7e41892011cc69e25a151e61d1a44352b2152a11f77ef4576dfb83bf protocol/preregistered.json +96eed02282d703f483873bf56cacc9147ebdfb6c7cd25d159a8161a2d3532ee5 regression/anatomical-edge-validation.json +1125ada92933e1f69c53b1f2085c9678c154854b2ff1bbfcc68ffe851bac118b regression/feedforward.json +f39187d9efcc54ca48beed0b6daf3e18368652e11bef62065bcc988a9fc4fcdc regression/final-integrity.json +1125ada92933e1f69c53b1f2085c9678c154854b2ff1bbfcc68ffe851bac118b regression/five.json +0aa4d6b309121bf203ea475ea797136f21a46aba8e1dc513c2b522d3b2c97434 regression/frozen-five.json +31716107c5c2c6b9d05b81373f0ec7d95be15147e9cb84296fd8ef898e2338af regression/motifs.json +1125ada92933e1f69c53b1f2085c9678c154854b2ff1bbfcc68ffe851bac118b regression/no_input.json +1125ada92933e1f69c53b1f2085c9678c154854b2ff1bbfcc68ffe851bac118b regression/pair.json +f39187d9efcc54ca48beed0b6daf3e18368652e11bef62065bcc988a9fc4fcdc regression/preflight.json +68c3f652297bd8e7f8de7fb286ff45f1d3a59668df8313f17d1b6793ddada6ab regression/run-start.json +25cf81371c5a05ba841406f2ede9c4ddd4e2dec00230e90c3985879624337336 regression/synthetic.json +1125ada92933e1f69c53b1f2085c9678c154854b2ff1bbfcc68ffe851bac118b regression/trio.json +abe9ac4065f0ddeb5697b971e12aab4f36946eaa819536a06ecc58d0d2f0eb70 regression/unit-tests.json +3a05e5a7f0d95935c1e14ad4eb733575759f1f170f3c61ee9e94c7d86dd917c4 synthetic/results.csv +b5d14e98dda652c18dc626371d85f8239348feb7aedf78e9d2b6f0a14858f986 synthetic/traces.npz diff --git a/registry/phase4ac-lif-semantics/evidence/external-resources/LICENSE b/registry/phase4ac-lif-semantics/evidence/external-resources/LICENSE new file mode 100644 index 0000000..deca2d0 --- /dev/null +++ b/registry/phase4ac-lif-semantics/evidence/external-resources/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 Philip Shiu and Nico Spiller + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/registry/phase4ac-lif-semantics/evidence/external-resources/environment_full.yml b/registry/phase4ac-lif-semantics/evidence/external-resources/environment_full.yml new file mode 100644 index 0000000..1428b31 --- /dev/null +++ b/registry/phase4ac-lif-semantics/evidence/external-resources/environment_full.yml @@ -0,0 +1,109 @@ +name: brian2 +channels: + - defaults + - conda-forge +dependencies: + - abseil-cpp=20211102.0=h0e60522_0 + - arrow-cpp=11.0.0=py310h7cee713_0 + - asttokens=2.2.1=pyhd8ed1ab_0 + - aws-c-common=0.4.57=ha925a31_1 + - aws-c-event-stream=0.1.6=hd77b12b_5 + - aws-checksums=0.1.9=ha925a31_0 + - aws-sdk-cpp=1.8.185=hd77b12b_0 + - backcall=0.2.0=pyh9f0ad1d_0 + - backports=1.0=pyhd8ed1ab_3 + - backports.functools_lru_cache=1.6.4=pyhd8ed1ab_0 + - boost-cpp=1.78.0=h5b4e17d_0 + - brian2=2.5.1=py310hc781a3c_0 + - bzip2=1.0.8=he774522_0 + - c-ares=1.19.0=h2bbff1b_0 + - ca-certificates=2023.5.7=h56e8100_0 + - colorama=0.4.6=pyhd8ed1ab_0 + - cython=0.29.33=py310hd77b12b_0 + - debugpy=1.5.1=py310hd77b12b_0 + - decorator=5.1.1=pyhd8ed1ab_0 + - executing=1.2.0=pyhd8ed1ab_0 + - gflags=2.2.2=ha925a31_1004 + - glog=0.5.0=h4797de2_0 + - gsl=2.7=hdfb1a43_0 + - importlib-metadata=6.6.0=pyha770c72_0 + - importlib_metadata=6.6.0=hd8ed1ab_0 + - intel-openmp=2023.1.0=h57928b3_46319 + - ipykernel=6.15.0=pyh025b116_0 + - ipython=8.14.0=pyh08f2357_0 + - jedi=0.18.2=pyhd8ed1ab_0 + - jinja2=2.11.3=pyhd8ed1ab_2 + - joblib=1.2.0=pyhd8ed1ab_0 + - jupyter_client=8.2.0=pyhd8ed1ab_0 + - jupyter_core=5.3.0=py310h5588dad_0 + - libblas=3.9.0=8_mkl + - libbrotlicommon=1.0.9=h8ffe710_7 + - libbrotlidec=1.0.9=h8ffe710_7 + - libbrotlienc=1.0.9=h8ffe710_7 + - libcblas=3.9.0=8_mkl + - libcurl=7.88.1=h86230a5_0 + - libffi=3.4.4=hd77b12b_0 + - liblapack=3.9.0=8_mkl + - libprotobuf=3.20.3=h23ce68f_0 + - libsodium=1.0.18=h8d14728_1 + - libssh2=1.10.0=hcd4344a_0 + - libthrift=0.15.0=h636ae23_0 + - lz4-c=1.9.4=h2bbff1b_0 + - m2w64-gcc-libgfortran=5.3.0=6 + - m2w64-gcc-libs=5.3.0=7 + - m2w64-gcc-libs-core=5.3.0=7 + - m2w64-gmp=6.1.0=2 + - m2w64-libwinpthread-git=5.0.0.4634.697f757=2 + - markupsafe=1.1.1=py310he2412df_4 + - matplotlib-inline=0.1.6=pyhd8ed1ab_0 + - mkl=2020.4=hb70f87d_311 + - mpmath=1.3.0=pyhd8ed1ab_0 + - msys2-conda-epoch=20160418=1 + - nest-asyncio=1.5.6=pyhd8ed1ab_0 + - numpy=1.22.3=py310hed7ac4c_2 + - openssl=1.1.1t=h2bbff1b_0 + - orc=1.7.4=h623e30f_1 + - packaging=23.1=pyhd8ed1ab_0 + - pandas=1.4.3=py310hf5e1058_0 + - parso=0.8.3=pyhd8ed1ab_0 + - pickleshare=0.7.5=py_1003 + - pip=23.0.1=py310haa95532_0 + - platformdirs=3.5.1=pyhd8ed1ab_0 + - prompt-toolkit=3.0.38=pyha770c72_0 + - prompt_toolkit=3.0.38=hd8ed1ab_0 + - psutil=5.9.0=py310h2bbff1b_0 + - pure_eval=0.2.2=pyhd8ed1ab_0 + - py-cpuinfo=9.0.0=pyhd8ed1ab_0 + - pyarrow=11.0.0=py310h790e06d_0 + - pygments=2.15.1=pyhd8ed1ab_0 + - pyparsing=3.0.9=pyhd8ed1ab_0 + - python=3.10.11=h966fe2a_2 + - python-dateutil=2.8.2=pyhd8ed1ab_0 + - python_abi=3.10=2_cp310 + - pytz=2023.3=pyhd8ed1ab_0 + - pywin32=305=py310h2bbff1b_0 + - pyzmq=25.0.2=py310hd77b12b_0 + - re2=2022.04.01=h0e60522_0 + - scipy=1.8.1=py310h7c00807_2 + - setuptools=67.8.0=py310haa95532_0 + - six=1.16.0=pyh6c4a22f_0 + - snappy=1.1.9=h6c2663c_0 + - sqlite=3.41.2=h2bbff1b_0 + - stack_data=0.6.2=pyhd8ed1ab_0 + - sympy=1.12=pyh04b8f61_3 + - tk=8.6.12=h2bbff1b_0 + - tornado=6.2=py310he2412df_0 + - traitlets=5.9.0=pyhd8ed1ab_0 + - typing-extensions=4.6.3=hd8ed1ab_0 + - typing_extensions=4.6.3=pyha770c72_0 + - tzdata=2023c=h04d1e81_0 + - utf8proc=2.6.1=h2bbff1b_0 + - vc=14.2=h21ff451_1 + - vs2015_runtime=14.27.29016=h5e58377_2 + - wcwidth=0.2.6=pyhd8ed1ab_0 + - wheel=0.38.4=py310haa95532_0 + - xz=5.4.2=h8cc25b3_0 + - zeromq=4.3.4=h0e60522_1 + - zipp=3.15.0=pyhd8ed1ab_0 + - zlib=1.2.13=h8cc25b3_0 + - zstd=1.5.5=hd43e919_0 diff --git a/registry/phase4ac-lif-semantics/evidence/external-resources/model.py b/registry/phase4ac-lif-semantics/evidence/external-resources/model.py new file mode 100644 index 0000000..5ba7083 --- /dev/null +++ b/registry/phase4ac-lif-semantics/evidence/external-resources/model.py @@ -0,0 +1,373 @@ +import pandas as pd +from textwrap import dedent + +# brian 2 +from brian2 import NeuronGroup, Synapses, PoissonInput, SpikeMonitor, Network +from brian2 import mV, ms, Hz + +# file handling +from pathlib import Path + +# parallelization +from joblib import Parallel, delayed, parallel_backend +from time import time + +default_params = { + # trials + 't_run' : 1000 * ms, # duration of trial + 'n_run' : 30, # number of runs + + # network constants + # Kakaria and de Bivort 2017 https://doi.org/10.3389/fnbeh.2017.00008 + 'v_0' : -52 * mV, # resting potential + 'v_rst' : -52 * mV, # reset potential after spike + 'v_th' : -45 * mV, # threshold for spiking + 't_mbr' : 20 * ms, # membrane time scale (capacitance * resistance = .002 * uF * 10. * Mohm) + + # Jürgensen et al https://doi.org/10.1088/2634-4386/ac3ba6 + 'tau' : 5 * ms, # time constant + + # Lazar et al https://doi.org/10.7554/eLife.62362 + 't_rfc' : 2.2 * ms, # refractory period + + # Paul et al 2015 doi: 10.3389/fncel.2015.00029 + 't_dly' : 1.8*ms, # delay for changes in post-synaptic neuron + + # Free parameter + 'w_syn' : .275 * mV, # weight per synapse (note: modulated by exponential decay) + # Default activation rates + 'r_poi' : 150*Hz, # default rate of the Poisson inputs + 'r_poi2' : 0*Hz, # default rate of a 2nd class of Poisson inputs + 'f_poi' : 250, # scaling factor for Poisson synapse; 250 is sufficient to cause spiking + + # equations for neurons # alpha synapse https://doi.org/10.1017/CBO9780511815706; See https://brian2.readthedocs.io/en/stable/user/converting_from_integrated_form.html + 'eqs' : dedent(''' + dv/dt = (v_0 - v + g) / t_mbr : volt (unless refractory) + dg/dt = -g / tau : volt (unless refractory) + rfc : second + '''), + # condition for spike + 'eq_th' : 'v > v_th', + # rules for spike + 'eq_rst' : 'v = v_rst; w = 0; g = 0 * mV', +} + + +####################### +# brian2 model setup +def poi(neu, exc, exc2, params): + '''Create PoissonInput for neurons. + + For each neuron in 'names' a PoissonInput is generated and + the refractory period of that neuron is set to 0 in NeuronGroup. + + Parameters + ---------- + neu : NeuronGroup + Defined brian2.NeuronGroup object + exc : list + Indices of neurons for which to create Poisson input + exc2 : list + Indices of neurons for which to create Poisson input with `r_poi` + params : dict + Constants and equations that are used to construct the brian2 network model + + Returns + ------- + pois : list + PoissonInput objects for each neuron in 'exc' + neu : NeuronGroup + NeuronGroup with adjusted refractory periods + ''' + + pois = [] + for i in exc: + p = PoissonInput( + target=neu[i], + target_var='v', + N=1, + rate=params['r_poi'], + weight=params['w_syn']*params['f_poi'] + ) + neu[i].rfc = 0 * ms # no refractory period for Poisson targets + pois.append(p) + + for i in exc2: + p = PoissonInput( + target=neu[i], + target_var='v', + N=1, + rate=params['r_poi2'], + weight=params['w_syn']*params['f_poi'] + ) + neu[i].rfc = 0 * ms # no refractory period for Poisson targets + pois.append(p) + + return pois, neu + +def silence(slnc, syn): + '''Silence neuron by setting weights of all synapses from it to 0 + + Parameters + ---------- + slnc : list + List of neuron indices to silence + syn : brian2.Synapses + Defined synapses object + + Returns + ------- + syn : brian2.Synapses + Synapses with modified weights + ''' + + for i in slnc: + syn.w[' {} == i'.format(i)] = 0*mV + + return syn + +def create_model(path_comp, path_con, params): + '''Create default network model. + + Convert the "completeness materialization" and "connectivity" dataframes + into a brian2 neural network model. Network constants and equations + are defined at the beginning of this file. + + Parameters + ---------- + path_comp : str + path to "completeness materialization" dataframe + path_con : str + path to "connectivity" dataframe + params : dict + Constants and equations that are used to construct the brian2 network model + + + Returns + ------- + neu : NeuronGroup + brian2.NeuronGroup object with neurons as in 'path_comp' + syn : Synapses + brian2.Synapses object with connections as in 'path_con' + spk_mon : SpikeMonitor + brian2.SpikeMonitor object, which records time of spike events + ''' + + # load neuron connectivity dataframes + df_comp = pd.read_csv(path_comp, index_col=0) + df_con = pd.read_parquet(path_con) + + neu = NeuronGroup( # create neurons + N=len(df_comp), + model=params['eqs'], + method='linear', + threshold=params['eq_th'], + reset=params['eq_rst'], + refractory='rfc', + name='default_neurons', + namespace=params, + ) + neu.v = params['v_0'] # initialize values + neu.g = 0 + neu.rfc = params['t_rfc'] + + # create synapses + syn = Synapses(neu, neu, 'w : volt', on_pre='g += w', delay=params['t_dly'], name='default_synapses') + + # connect synapses + i_pre = df_con.loc[:, 'Presynaptic_Index'].values + i_post = df_con.loc[:, 'Postsynaptic_Index'].values + syn.connect(i=i_pre, j=i_post) + + # define connection weight + syn.w = df_con.loc[:,'Excitatory x Connectivity'].values * params['w_syn'] + + # object to record spikes + spk_mon = SpikeMonitor(neu) + + return neu, syn, spk_mon + +##################### +# running simulations +def get_spk_trn(spk_mon): + '''Extracts spike times from 'spk_mon' + + The spike times recorded in the SpikeMonitor object during + simulation are converted to a list of times for each neurons. + Returns dict with "brian ID": "list of spike times". + + Parameters + ---------- + spk_mon : SpikeMonitor + Contains recorded spike times + + Returns + ------- + spk_trn : dict + Mapping between brian neuron IDs and spike times + ''' + + spk_trn = {k: v for k, v in spk_mon.spike_trains().items() if len(v)} + + return spk_trn + +def construct_dataframe(res, exp_name, i2flyid): + '''Take spike time dict and collects spikes in pandas dataframe + + Parameters + ---------- + res : list + List with spike time dicts for each trial + exp_name : str + Name of the experiment + i2flyid : dict + Mapping between Brian IDs and flywire IDs + + Returns + ------- + df : pandas.DataFrame + Dataframe where each row is one spike + ''' + + ids, ts, nrun = [], [], [] + + for n, i in enumerate(res): + for j, k in i.items(): + ids.extend([j for _ in k]) + nrun.extend([n for _ in k]) + ts.extend([float(l) for l in k]) + + d = { + 't': ts, + 'trial': nrun, + 'flywire_id': [i2flyid[i] for i in ids], + 'exp_name': exp_name + } + df = pd.DataFrame(d) + + return df + +def run_trial(exc, exc2, slnc, path_comp, path_con, params): + '''Run single trial of coactivation/silencng experiment + + During the coactivation experiment, the neurons in 'exc' are + Poisson inputs. The simulation runs for 't_run'. + + + Parameters + ---------- + exc: list + contains indices of neurons for PoissonInput + exc2: list + contains indices of neurons for PoissonInput of different frequency `r_poi2` + slnc: list + contains indices of neurons to silence + path_comp: Path + path to "completeness materialization" dataframe + path_con: Path + path to "connectivity" dataframe + params : dict + Constants and equations that are used to construct the brian2 network model + + Returns + ------- + spk_trn : dict + Mapping between brian neuron IDs and spike times + ''' + + # get default network + neu, syn, spk_mon = create_model(path_comp, path_con, params) + # define Poisson input for excitation + poi_inp, neu = poi(neu, exc, exc2, params) + # silence neurons + syn = silence(slnc, syn) + # collect in Network object + net = Network(neu, syn, spk_mon, *poi_inp) + + # run simulation + net.run(duration=params['t_run']) + + # spike times + spk_trn = get_spk_trn(spk_mon) + + return spk_trn + + +def run_exp(exp_name, neu_exc, path_res, path_comp, path_con, + params=default_params, neu_slnc=[], neu_exc2=[], + n_proc=-1, force_overwrite=False): + ''' + Run default network experiment + Neurons in `neu_exc` are Poisson external inputs + Neurons in `neu_slnc` are silenced + + + Parameters + ---------- + exp_name: str + name of the experiment + neu_exc: list + contains custom names or flywire IDs of neurons to be excited + path_res: str + path to the output folder where spike data is stored + path_comp: str + path to "completeness materialization" dataframe + path_con: str + path to "connectivity" dataframe + params : dict + Constants and equations that are used to construct the brian2 network model + neu_slnc : list (optional) + contains custom names or flywire IDs of neurons to be silenced + neu_exc2 : list (optional) + contains custom names or flywire IDs of neurons to be excited with different frequency + requires `r_poi2` to be defined in `params` + n_proc: int (optional) + number of cores to be used for parallel runs + default: -1 (use all available cores) + n_proc=1 is equivalent serial code + force_overwrite : bool (optional) + If True, overwrite output files, else skip simulation, by default False + ''' + + # convert to Path objects + path_res, path_comp, path_con = [ Path(i) for i in [path_res, path_comp, path_con] ] + + # define output files + path_save = path_res / '{}.parquet'.format(exp_name) + if path_save.is_file() and not force_overwrite: + print('>>> Skipping experiment {} because {} exists and force_overwrite = {}'.format(exp_name, path_save, force_overwrite)) + return + + # load name/id mappings + df_comp = pd.read_csv(path_comp, index_col=0) # load completeness dataframe + flyid2i = {j: i for i, j in enumerate(df_comp.index)} # flywire id: biran ID + i2flyid = {j: i for i, j in flyid2i.items()} # brian ID: flywire ID + + # print info + print('>>> Experiment: {}'.format(exp_name)) + print(' Output file: {}'.format(path_save)) + print(' Excited neurons: {}'.format(len(neu_exc + neu_exc2))) + if neu_slnc: + print(' Silenced neurons: {}'.format(len(neu_slnc))) + + # start parallel calculation + n_run = params['n_run'] + start = time() + with parallel_backend('loky', n_jobs=n_proc): + exc = [ flyid2i[n] for n in neu_exc ] + exc2 = [ flyid2i[n] for n in neu_exc2 ] + slnc = [ flyid2i[n] for n in neu_slnc ] + res = Parallel()( + delayed( + run_trial)(exc, exc2, slnc, path_comp, path_con, params) for _ in range(n_run)) + + + # print simulation time + walltime = time() - start + print(' Elapsed time: {} s'.format(int(walltime))) + + # dataframe with spike times + df = construct_dataframe(res, exp_name, i2flyid) + + # store spike data + df.to_parquet(path_save, compression='brotli') diff --git a/registry/phase4ac-lif-semantics/evidence/external-resources/provenance.json b/registry/phase4ac-lif-semantics/evidence/external-resources/provenance.json new file mode 100644 index 0000000..82a6899 --- /dev/null +++ b/registry/phase4ac-lif-semantics/evidence/external-resources/provenance.json @@ -0,0 +1,29 @@ +{ + "commit": "91bdd1e7dcf193f3e7ca5a8933497fcef63b7960", + "downloaded_code_executed": false, + "files": [ + { + "bytes": 11900, + "license": "MIT", + "path": "model.py", + "sha256": "fc45837d7122c6ce2a7f3f2f23c515992e4b232aadb919efabb72337fac88e4e", + "url": "https://raw.githubusercontent.com/philshiu/Drosophila_brain_model/91bdd1e7dcf193f3e7ca5a8933497fcef63b7960/model.py" + }, + { + "bytes": 1085, + "license": "MIT", + "path": "LICENSE", + "sha256": "3621f6d6476189190e2960fa43f11b275ba4eca848fdac50a1ba2925de6223e8", + "url": "https://raw.githubusercontent.com/philshiu/Drosophila_brain_model/91bdd1e7dcf193f3e7ca5a8933497fcef63b7960/LICENSE" + }, + { + "bytes": 3445, + "license": "MIT", + "path": "environment_full.yml", + "sha256": "402fcef4968c99397b0e908b3323ab9e6ef86af5583e46e6427f96f3d1091adf", + "url": "https://raw.githubusercontent.com/philshiu/Drosophila_brain_model/91bdd1e7dcf193f3e7ca5a8933497fcef63b7960/environment_full.yml" + } + ], + "new_dependencies_installed": false, + "paper": "https://www.nature.com/articles/s41586-024-07763-9" +} diff --git a/registry/phase4ac-lif-semantics/evidence/gpu-reference/extension.json b/registry/phase4ac-lif-semantics/evidence/gpu-reference/extension.json new file mode 100644 index 0000000..7b301a8 --- /dev/null +++ b/registry/phase4ac-lif-semantics/evidence/gpu-reference/extension.json @@ -0,0 +1,17 @@ +{ + "binary": "/data/digital-drosophila/experiments/phase4ac-lif-semantics/gpu-reference/extension-build/male_cns_lif_deterministic_v2_ext.so", + "binary_sha256": "f65d7c0d58aa7434a74eab446c528146b3fbd7282a1d5c47e3253999ba037721", + "build_seconds": 58.064692621002905, + "flags": { + "cuda": [ + "-O3", + "--fmad=false", + "-std=c++20" + ], + "cxx": [ + "-O3", + "-ffp-contract=off" + ] + }, + "status": "PASS" +} diff --git a/registry/phase4ac-lif-semantics/evidence/manifest.json b/registry/phase4ac-lif-semantics/evidence/manifest.json new file mode 100644 index 0000000..50be328 --- /dev/null +++ b/registry/phase4ac-lif-semantics/evidence/manifest.json @@ -0,0 +1,290 @@ +{ + "created_utc": "2026-09-29T16:58:20.625630+00:00", + "files": [ + { + "bytes": 5154, + "path": "INTERPRETATION.zh.md", + "sha256": "e62102c1084dd513dec04f9fdc41570441b25100d5fdcea9e43427f70870f0d7" + }, + { + "bytes": 5210, + "path": "REPORT.md", + "sha256": "a8b24e795ee1fc8b2c212367525ef9508d4edce74876a361a9164ce146158569" + }, + { + "bytes": 558, + "path": "audit/author-source-clauses.json", + "sha256": "7cce72b98892eac115e500340a8c11f6737c0dd83bfd7c9fbd28b2167bf2f60e" + }, + { + "bytes": 227, + "path": "audit/final-status.json", + "sha256": "c61d57cfb8808b0af5133e5d061e3ed6c435a6475f7a23b90f16c2de45d999fb" + }, + { + "bytes": 1552, + "path": "audit/local-inhibition-crosswalk.csv", + "sha256": "d2e2c65cffa100598c6f991bcf8df3b094501fbe59d34519839df280a2d8b087" + }, + { + "bytes": 208, + "path": "audit/run-complete.json", + "sha256": "4480a78f84ecca51e4153fa8cc9650a7f77ca3a91c04cd14cbe653a4f9162e4c" + }, + { + "bytes": 34348, + "path": "audit/selected-metadata.parquet", + "sha256": "c1dde5df5408aeb878d6c422bc1c86ba44c3c5770f986014e594e356412a013d" + }, + { + "bytes": 547, + "path": "audit/selected-real-edges.csv", + "sha256": "9103e9d03fa21058a4f6cd21780c56fed8cdcfca26c34c2a43726e39aed8ec55" + }, + { + "bytes": 531, + "path": "audit/semantics-differences.csv", + "sha256": "1ea234a0a1fff64234dbff05e1f25513151295b0cfb0a1fc7bd174d3f5b7e3e6" + }, + { + "bytes": 1085, + "path": "external-resources/LICENSE", + "sha256": "3621f6d6476189190e2960fa43f11b275ba4eca848fdac50a1ba2925de6223e8" + }, + { + "bytes": 3445, + "path": "external-resources/environment_full.yml", + "sha256": "402fcef4968c99397b0e908b3323ab9e6ef86af5583e46e6427f96f3d1091adf" + }, + { + "bytes": 11900, + "path": "external-resources/model.py", + "sha256": "fc45837d7122c6ce2a7f3f2f23c515992e4b232aadb919efabb72337fac88e4e" + }, + { + "bytes": 1137, + "path": "external-resources/provenance.json", + "sha256": "7dc4014bbf9fbe64665a82d4542bba71df7c4497064850d30ef0278f23ba2e49" + }, + { + "bytes": 723996, + "path": "gpu-reference/extension-build/.ninja_deps", + "sha256": "cb6874d704e9a87f617eef07b92ab961a0440c6667a2f1a501982c9d9dfdee6d" + }, + { + "bytes": 224, + "path": "gpu-reference/extension-build/.ninja_log", + "sha256": "d7d7f7a1769a481f922466bc05f05c1e8684c46da24d46d0edc0ffe434a5be23" + }, + { + "bytes": 2109, + "path": "gpu-reference/extension-build/build.ninja", + "sha256": "c570f72b9a2f486e104ed3bf5b1b9f2ccc729ecab02046cd62389d629fb4f48f" + }, + { + "bytes": 0, + "path": "gpu-reference/extension-build/lock", + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + { + "bytes": 291280, + "path": "gpu-reference/extension-build/male_cns_lif_deterministic_v2_ext.so", + "sha256": "f65d7c0d58aa7434a74eab446c528146b3fbd7282a1d5c47e3253999ba037721" + }, + { + "bytes": 101992, + "path": "gpu-reference/extension-build/phase4p_ext.cuda.o", + "sha256": "0635c52d1a7ffe457b52cf01fa71edf99295136abe73f0abd75ac8152e415151" + }, + { + "bytes": 377136, + "path": "gpu-reference/extension-build/phase4p_ext.o", + "sha256": "27d284f6a369221a931251b5a03ce133cc8231a97942567d4efafbfb45483811" + }, + { + "bytes": 442, + "path": "gpu-reference/extension.json", + "sha256": "9d88976e53ac778d64887e0708aaf06922af3fddb69717b4cda2ea4bb750c2ae" + }, + { + "bytes": 228, + "path": "motifs/feedforward-edges.csv", + "sha256": "add7a3b450e3f3043af602baf8e770e5358c1c024d44bb21a74ef18429c0680e" + }, + { + "bytes": 1716, + "path": "motifs/feedforward-events.parquet", + "sha256": "f687cf303d9318404c954e2e699d65d7893ad3f33115c0f9c5ea45b9698ff275" + }, + { + "bytes": 85957, + "path": "motifs/feedforward-state.npz", + "sha256": "6a24c8d2ad476e2250af49172be12de9d43346bc84f043b19d012fa0c53d2fba" + }, + { + "bytes": 547, + "path": "motifs/five-edges.csv", + "sha256": "9103e9d03fa21058a4f6cd21780c56fed8cdcfca26c34c2a43726e39aed8ec55" + }, + { + "bytes": 9974, + "path": "motifs/five-events.parquet", + "sha256": "19fef92b32be32ced2ec6b6581c9dac05055e9d550c104dd0d5ec5e33e25e759" + }, + { + "bytes": 268297, + "path": "motifs/five-state.npz", + "sha256": "15095ada05014741f6b6576c2d12d1a8f1ae482ae6f012d5e2be346c796baf4b" + }, + { + "bytes": 547, + "path": "motifs/no_input-edges.csv", + "sha256": "9103e9d03fa21058a4f6cd21780c56fed8cdcfca26c34c2a43726e39aed8ec55" + }, + { + "bytes": 1472, + "path": "motifs/no_input-events.parquet", + "sha256": "071326bc3033505f431e38d716cb8ec681dc192b8389792059bb8a75027a1f10" + }, + { + "bytes": 3114, + "path": "motifs/no_input-state.npz", + "sha256": "a74134da72381d0dbff10bb5143691add6081487dede488a939bb0a4dbf5c20e" + }, + { + "bytes": 152, + "path": "motifs/pair-edges.csv", + "sha256": "05a7c7a5547aaeea4d1522f9cea75463405f0c3cdfbc4d563f111ad51cb80e00" + }, + { + "bytes": 4157, + "path": "motifs/pair-events.parquet", + "sha256": "962a440924a9b2a4a3677b8968e63042de0b80ea4e496c213ebcf40d5e530e85" + }, + { + "bytes": 14660, + "path": "motifs/pair-state.npz", + "sha256": "924774344956dd5a530c3d00c8103fe4d1b584837d5e91f05b60094540a78897" + }, + { + "bytes": 1009, + "path": "motifs/summary.csv", + "sha256": "4e762a26ecc7d3c3f862260495b6064a60832431b61dd41b944e8c501617a906" + }, + { + "bytes": 288, + "path": "motifs/trio-edges.csv", + "sha256": "c842c5bce0b11275c0eba9532955026a4b58931c2346e178bfa8a84227289c71" + }, + { + "bytes": 7476, + "path": "motifs/trio-events.parquet", + "sha256": "a39d58de867f4f1ce1291e0ece25a52b70a3e04024508f77cb4a29eb4e09fa0e" + }, + { + "bytes": 18538, + "path": "motifs/trio-state.npz", + "sha256": "46c8a495ee1358a6173a2eebebe9ce2d6481b27f10e0c56cf9602c7969cd8702" + }, + { + "bytes": 138, + "path": "performance/summary.json", + "sha256": "ef768705779fdf1fa5563e00d80b703ee70804742bbf4fa701c4d63532896f80" + }, + { + "bytes": 291, + "path": "protocol/dynamics.json", + "sha256": "a5aa62f5588fbf754c6164b69d61a5154d23fc8f749ae4c36aea3f4ad1fa2576" + }, + { + "bytes": 434, + "path": "protocol/frozen-input-hashes.json", + "sha256": "6cbe6b4b43f7e3928b247a2188b955be5431224a01f8c0838544a0b9f34fe569" + }, + { + "bytes": 524, + "path": "protocol/prepared-input-hashes.json", + "sha256": "726e949b87ebd4e15e10ed3a57336f03bc8e4c2e13ebe8b7e8dbb718166b4f6e" + }, + { + "bytes": 3227, + "path": "protocol/preregistered.json", + "sha256": "00a18f5e7e41892011cc69e25a151e61d1a44352b2152a11f77ef4576dfb83bf" + }, + { + "bytes": 182, + "path": "regression/anatomical-edge-validation.json", + "sha256": "96eed02282d703f483873bf56cacc9147ebdfb6c7cd25d159a8161a2d3532ee5" + }, + { + "bytes": 185, + "path": "regression/feedforward.json", + "sha256": "1125ada92933e1f69c53b1f2085c9678c154854b2ff1bbfcc68ffe851bac118b" + }, + { + "bytes": 1664, + "path": "regression/final-integrity.json", + "sha256": "f39187d9efcc54ca48beed0b6daf3e18368652e11bef62065bcc988a9fc4fcdc" + }, + { + "bytes": 185, + "path": "regression/five.json", + "sha256": "1125ada92933e1f69c53b1f2085c9678c154854b2ff1bbfcc68ffe851bac118b" + }, + { + "bytes": 1206, + "path": "regression/frozen-five.json", + "sha256": "0aa4d6b309121bf203ea475ea797136f21a46aba8e1dc513c2b522d3b2c97434" + }, + { + "bytes": 494, + "path": "regression/motifs.json", + "sha256": "31716107c5c2c6b9d05b81373f0ec7d95be15147e9cb84296fd8ef898e2338af" + }, + { + "bytes": 185, + "path": "regression/no_input.json", + "sha256": "1125ada92933e1f69c53b1f2085c9678c154854b2ff1bbfcc68ffe851bac118b" + }, + { + "bytes": 185, + "path": "regression/pair.json", + "sha256": "1125ada92933e1f69c53b1f2085c9678c154854b2ff1bbfcc68ffe851bac118b" + }, + { + "bytes": 1664, + "path": "regression/preflight.json", + "sha256": "f39187d9efcc54ca48beed0b6daf3e18368652e11bef62065bcc988a9fc4fcdc" + }, + { + "bytes": 179, + "path": "regression/run-start.json", + "sha256": "68c3f652297bd8e7f8de7fb286ff45f1d3a59668df8313f17d1b6793ddada6ab" + }, + { + "bytes": 155, + "path": "regression/synthetic.json", + "sha256": "25cf81371c5a05ba841406f2ede9c4ddd4e2dec00230e90c3985879624337336" + }, + { + "bytes": 185, + "path": "regression/trio.json", + "sha256": "1125ada92933e1f69c53b1f2085c9678c154854b2ff1bbfcc68ffe851bac118b" + }, + { + "bytes": 33, + "path": "regression/unit-tests.json", + "sha256": "abe9ac4065f0ddeb5697b971e12aab4f36946eaa819536a06ecc58d0d2f0eb70" + }, + { + "bytes": 7495, + "path": "synthetic/results.csv", + "sha256": "3a05e5a7f0d95935c1e14ad4eb733575759f1f170f3c61ee9e94c7d86dd917c4" + }, + { + "bytes": 366125, + "path": "synthetic/traces.npz", + "sha256": "b5d14e98dda652c18dc626371d85f8239348feb7aedf78e9d2b6f0a14858f986" + } + ] +} diff --git a/registry/phase4ac-lif-semantics/evidence/motifs/feedforward-edges.csv b/registry/phase4ac-lif-semantics/evidence/motifs/feedforward-edges.csv new file mode 100644 index 0000000..f386691 --- /dev/null +++ b/registry/phase4ac-lif-semantics/evidence/motifs/feedforward-edges.csv @@ -0,0 +1,5 @@ +edge_id,source_neuron_idx,target_neuron_idx,raw_count,source_body_id,target_body_id +1337065,1197,133666,104,11289,527577 +1467355,1381,1511,235,11478,11620 +1559765,1511,1197,226,11620,11289 +20992891,133666,82312,43,527577,109321 diff --git a/registry/phase4ac-lif-semantics/evidence/motifs/five-edges.csv b/registry/phase4ac-lif-semantics/evidence/motifs/five-edges.csv new file mode 100644 index 0000000..cbdc51f --- /dev/null +++ b/registry/phase4ac-lif-semantics/evidence/motifs/five-edges.csv @@ -0,0 +1,14 @@ +edge_id,source_neuron_idx,target_neuron_idx,raw_count,source_body_id,target_body_id +1336648,1197,1381,210,11289,11478 +1336655,1197,1511,172,11289,11620 +1337065,1197,133666,104,11289,527577 +1467340,1381,1197,259,11478,11289 +1467355,1381,1511,235,11478,11620 +1467852,1381,133666,64,11478,527577 +1559765,1511,1197,226,11620,11289 +1559772,1511,1381,283,11620,11478 +1560267,1511,133666,70,11620,527577 +20992285,133666,1197,95,527577,11289 +20992291,133666,1381,57,527577,11478 +20992294,133666,1511,76,527577,11620 +20992891,133666,82312,43,527577,109321 diff --git a/registry/phase4ac-lif-semantics/evidence/motifs/no_input-edges.csv b/registry/phase4ac-lif-semantics/evidence/motifs/no_input-edges.csv new file mode 100644 index 0000000..cbdc51f --- /dev/null +++ b/registry/phase4ac-lif-semantics/evidence/motifs/no_input-edges.csv @@ -0,0 +1,14 @@ +edge_id,source_neuron_idx,target_neuron_idx,raw_count,source_body_id,target_body_id +1336648,1197,1381,210,11289,11478 +1336655,1197,1511,172,11289,11620 +1337065,1197,133666,104,11289,527577 +1467340,1381,1197,259,11478,11289 +1467355,1381,1511,235,11478,11620 +1467852,1381,133666,64,11478,527577 +1559765,1511,1197,226,11620,11289 +1559772,1511,1381,283,11620,11478 +1560267,1511,133666,70,11620,527577 +20992285,133666,1197,95,527577,11289 +20992291,133666,1381,57,527577,11478 +20992294,133666,1511,76,527577,11620 +20992891,133666,82312,43,527577,109321 diff --git a/registry/phase4ac-lif-semantics/evidence/motifs/pair-edges.csv b/registry/phase4ac-lif-semantics/evidence/motifs/pair-edges.csv new file mode 100644 index 0000000..b8873be --- /dev/null +++ b/registry/phase4ac-lif-semantics/evidence/motifs/pair-edges.csv @@ -0,0 +1,3 @@ +edge_id,source_neuron_idx,target_neuron_idx,raw_count,source_body_id,target_body_id +1467355,1381,1511,235,11478,11620 +1559772,1511,1381,283,11620,11478 diff --git a/registry/phase4ac-lif-semantics/evidence/motifs/summary.csv b/registry/phase4ac-lif-semantics/evidence/motifs/summary.csv new file mode 100644 index 0000000..97a1df3 --- /dev/null +++ b/registry/phase4ac-lif-semantics/evidence/motifs/summary.csv @@ -0,0 +1,21 @@ +motif,neuron_idx,spikes,late_spikes,first_ms,last_ms,external_force_requests,frozen_math_unchanged,whole_brain_necessity_proven +pair,1381,237,119,0.0,999.3000000000001,1,True,False +pair,1511,236,119,4.9,997.5,0,True,False +trio,1197,355,179,4.5,999.3000000000001,0,True,False +trio,1381,355,178,0.0,997.8000000000001,1,True,False +trio,1511,354,178,4.9,997.4000000000001,0,True,False +five,1197,370,185,4.5,998.8000000000001,0,True,False +five,1381,369,185,0.0,997.4000000000001,1,True,False +five,1511,367,186,4.9,999.5,0,True,False +five,82312,80,41,26.400000000000002,990.3000000000001,0,True,False +five,133666,297,150,8.8,999.5,0,True,False +feedforward,1197,1,0,10.0,10.0,0,True,False +feedforward,1381,1,0,0.0,0.0,1,True,False +feedforward,1511,1,0,4.9,4.9,0,True,False +feedforward,82312,0,0,,,0,True,False +feedforward,133666,0,0,,,0,True,False +no_input,1197,0,0,,,0,True,False +no_input,1381,0,0,,,0,True,False +no_input,1511,0,0,,,0,True,False +no_input,82312,0,0,,,0,True,False +no_input,133666,0,0,,,0,True,False diff --git a/registry/phase4ac-lif-semantics/evidence/motifs/trio-edges.csv b/registry/phase4ac-lif-semantics/evidence/motifs/trio-edges.csv new file mode 100644 index 0000000..a86e33c --- /dev/null +++ b/registry/phase4ac-lif-semantics/evidence/motifs/trio-edges.csv @@ -0,0 +1,7 @@ +edge_id,source_neuron_idx,target_neuron_idx,raw_count,source_body_id,target_body_id +1336648,1197,1381,210,11289,11478 +1336655,1197,1511,172,11289,11620 +1467340,1381,1197,259,11478,11289 +1467355,1381,1511,235,11478,11620 +1559765,1511,1197,226,11620,11289 +1559772,1511,1381,283,11620,11478 diff --git a/registry/phase4ac-lif-semantics/evidence/performance/summary.json b/registry/phase4ac-lif-semantics/evidence/performance/summary.json new file mode 100644 index 0000000..dc7086a --- /dev/null +++ b/registry/phase4ac-lif-semantics/evidence/performance/summary.json @@ -0,0 +1,6 @@ +{ + "ComfyUI_unloaded": false, + "not_runtime_benchmark": true, + "peak_allocated_VRAM": 285994496, + "wall_seconds": 95.39833069499582 +} diff --git a/registry/phase4ac-lif-semantics/evidence/protocol/dynamics.json b/registry/phase4ac-lif-semantics/evidence/protocol/dynamics.json new file mode 100644 index 0000000..3c38c8b --- /dev/null +++ b/registry/phase4ac-lif-semantics/evidence/protocol/dynamics.json @@ -0,0 +1,12 @@ +{ + "dt_ms": 0.1, + "integration": "forward_euler", + "membrane_tau_ms": 20.0, + "refractory_ms": 2.2, + "reset_potential_mv": -52.0, + "resting_potential_mv": -52.0, + "synaptic_delay_ms": 1.8, + "synaptic_tau_ms": 5.0, + "threshold_mv": -45.0, + "w_syn_mv_per_anatomical_synapse": 0.275 +} diff --git a/registry/phase4ac-lif-semantics/evidence/protocol/frozen-input-hashes.json b/registry/phase4ac-lif-semantics/evidence/protocol/frozen-input-hashes.json new file mode 100644 index 0000000..d7c3d17 --- /dev/null +++ b/registry/phase4ac-lif-semantics/evidence/protocol/frozen-input-hashes.json @@ -0,0 +1,7 @@ +{ + "baseline_phase4b": "693468685a7ff3db1d09a088e0bbdaa78c595d64086b27e9cc18abceb4c7d174", + "metadata": "922af16846a065c3dbfca7c11146b83ca217fcbd7392edc745f444a04eae8c63", + "runtime_config": "6d0189f4ec570cb3352d15ed8d195d1ccb32ee1d29c33dc1e4f00d377b74787e", + "runtime_cpp": "9d204d77d70b3723567671a61ce8e2e6162e261f48825e86fb34565e3faa622d", + "runtime_cuda": "c24985f4e366f90790d25ab5eceb9d6aff0f9064dd61c7413c13d2a2a4fa5fcd" +} diff --git a/registry/phase4ac-lif-semantics/evidence/protocol/prepared-input-hashes.json b/registry/phase4ac-lif-semantics/evidence/protocol/prepared-input-hashes.json new file mode 100644 index 0000000..6d065c4 --- /dev/null +++ b/registry/phase4ac-lif-semantics/evidence/protocol/prepared-input-hashes.json @@ -0,0 +1,7 @@ +{ + "audit/local-inhibition-crosswalk.csv": "d2e2c65cffa100598c6f991bcf8df3b094501fbe59d34519839df280a2d8b087", + "audit/selected-metadata.parquet": "c1dde5df5408aeb878d6c422bc1c86ba44c3c5770f986014e594e356412a013d", + "audit/selected-real-edges.csv": "9103e9d03fa21058a4f6cd21780c56fed8cdcfca26c34c2a43726e39aed8ec55", + "protocol/dynamics.json": "a5aa62f5588fbf754c6164b69d61a5154d23fc8f749ae4c36aea3f4ad1fa2576", + "protocol/frozen-input-hashes.json": "6cbe6b4b43f7e3928b247a2188b955be5431224a01f8c0838544a0b9f34fe569" +} diff --git a/registry/phase4ac-lif-semantics/evidence/protocol/preregistered.json b/registry/phase4ac-lif-semantics/evidence/protocol/preregistered.json new file mode 100644 index 0000000..7b501e8 --- /dev/null +++ b/registry/phase4ac-lif-semantics/evidence/protocol/preregistered.json @@ -0,0 +1,123 @@ +{ + "before_analysis": true, + "config": { + "additional_frozen": [ + "models/male-cns-lif/apl-pn-scope-audit-v1", + "experiments/phase4aa-apl-pn-scope", + "models/male-cns-lif/terminal-scope-diagnostic-v1", + "experiments/phase4ab-terminal-scope" + ], + "author": { + "commit": "91bdd1e7dcf193f3e7ca5a8933497fcef63b7960", + "model_sha256": "fc45837d7122c6ce2a7f3f2f23c515992e4b232aadb919efabb72337fac88e4e", + "paper": "https://www.nature.com/articles/s41586-024-07763-9", + "repository": "https://github.com/philshiu/Drosophila_brain_model" + }, + "canonical": "datasets/male-cns-v1.0/processed/neuron-only", + "duration_ms": 1000, + "experiment": "experiments/phase4ac-lif-semantics", + "late_start_ms": 500, + "model": "models/male-cns-lif/lif-semantics-audit-v1", + "motifs": [ + { + "name": "pair", + "nodes": [ + 1381, + 1511 + ] + }, + { + "name": "trio", + "nodes": [ + 1197, + 1381, + 1511 + ] + }, + { + "name": "five", + "nodes": [ + 1197, + 1381, + 1511, + 82312, + 133666 + ] + }, + { + "name": "feedforward", + "nodes": [ + 1197, + 1381, + 1511, + 82312, + 133666 + ], + "pairs": [ + [ + 1381, + 1511 + ], + [ + 1511, + 1197 + ], + [ + 1197, + 133666 + ], + [ + 133666, + 82312 + ] + ] + }, + { + "force": false, + "name": "no_input", + "nodes": [ + 1197, + 1381, + 1511, + 82312, + 133666 + ] + } + ], + "old_snapshot": "registry/snapshots/bootstrap-20260929", + "phase": "4AC", + "root": "/data/digital-drosophila", + "runtime": "models/male-cns-lif/deterministic-runtime-v2", + "scope": { + "conditioning": false, + "full_brain_alternative_dynamics": false, + "learned_candidate": false, + "requires_separate_authorization_for_new_brain_model": true + }, + "seed_node": 1381, + "selected_nodes": [ + 1197, + 1381, + 1511, + 82312, + 133666 + ], + "synthetic_policies": [ + "frozen", + "reset_g_only", + "refractory_gate_only", + "reset_and_refractory" + ] + }, + "parent_commit": "3213aada793740961885ba525494e95f019be6f8", + "sources": { + "PROTOCOL.md": "484296e132a836900efaa336d387b6974aa39c6af2dee211b7ba668cf71be257", + "audit_semantics.py": "f20724387ca7ed63b9e35fb9ce3d2964da44f85318856b7403b5536a442422b8", + "brian2-evidence.json": "bebd4dfa2dda1aca601a52b24e3eabdd887ce261c3548e377198ab154d81f16e", + "config.yaml": "433151183a4755f5fdfec33f6a9404aa5fb186ec45866ebb58be4ba3e4ebb568", + "math_reference.py": "5166366251f99359b1301f514f5d9ae5f0f041fd3a3f98902386192117f01aea", + "report.py": "76a21eca32ff8caba88ab84616e226e687dd0d2df5da62816c81b5ba08297394", + "test_math.py": "9ee96ed78bfa692b12f0db6862087a19dc351c4afd9bb94cf02733ec6a002f01" + }, + "timestamp_utc": "2026-09-29T16:52:46.554275+00:00" +} diff --git a/registry/phase4ac-lif-semantics/evidence/regression/anatomical-edge-validation.json b/registry/phase4ac-lif-semantics/evidence/regression/anatomical-edge-validation.json new file mode 100644 index 0000000..49a6f2a --- /dev/null +++ b/registry/phase4ac-lif-semantics/evidence/regression/anatomical-edge-validation.json @@ -0,0 +1,10 @@ +{ + "checks": [ + "canonical edge_id in source CSR row", + "exact target", + "exact raw int64 count", + "exact effective float32 weight" + ], + "edges": 13, + "pass": true +} diff --git a/registry/phase4ac-lif-semantics/evidence/regression/feedforward.json b/registry/phase4ac-lif-semantics/evidence/regression/feedforward.json new file mode 100644 index 0000000..c113354 --- /dev/null +++ b/registry/phase4ac-lif-semantics/evidence/regression/feedforward.json @@ -0,0 +1,13 @@ +{ + "exact": { + "counts": true, + "g": true, + "history": true, + "neuron_idx": true, + "queue": true, + "ref": true, + "step": true, + "v": true + }, + "pass": true +} diff --git a/registry/phase4ac-lif-semantics/evidence/regression/final-integrity.json b/registry/phase4ac-lif-semantics/evidence/regression/final-integrity.json new file mode 100644 index 0000000..b747f21 --- /dev/null +++ b/registry/phase4ac-lif-semantics/evidence/regression/final-integrity.json @@ -0,0 +1,48 @@ +{ + "experiments/phase4aa-apl-pn-scope": { + "checked": 68, + "checksums_sha256": "a69b2511689207b0d9ddbe2fabce3be71908f457bb898e3b685a213a796a272a", + "manifest_sha256": "6d75567af2a6c0993d4fc08e272814910c19fa9602811cfacd1ebc4ba76bc737", + "mismatches": [], + "pass": true + }, + "experiments/phase4ab-terminal-scope": { + "checked": 199, + "checksums_sha256": "d83926a3055d9f9ca471ceba328076d7ceba883f267468750914080733e95e31", + "manifest_sha256": "cb3723f9dae29d4889489ae39f40293c927f4f9e532551e2c4d5214bf0a70140", + "mismatches": [], + "pass": true + }, + "models/male-cns-lif/apl-pn-scope-audit-v1": { + "checked": 12, + "checksums_sha256": "55dc418f2d62be04601af33cbd8789578447e6a2289d3a581dc713cbb7466a25", + "manifest_sha256": "9120685eb02dc2bd3b38d42b2ade1f38f6bbc2a1ec269fd4d555cead2d628277", + "mismatches": [], + "pass": true + }, + "models/male-cns-lif/terminal-scope-diagnostic-v1": { + "checked": 11, + "checksums_sha256": "92a03195cb41863027fd0397ad3811248354a5d3f2e91ffa2c297eba62dc2821", + "manifest_sha256": "5cea0035a95345825b73385c6e3056244c2a614d10a6fa6742487a331d8f0f3e", + "mismatches": [], + "pass": true + }, + "original": { + "checked": 230239, + "exclusions": [ + ".cache", + ".git", + ".mypy_cache", + ".pytest_cache", + ".venv", + "__pycache__", + "node_modules", + "venv" + ], + "meaning": "All original listed bytes checked; only newly named stage outputs are additions.", + "mismatches": [], + "new_stage_additions_allowed": true, + "pass": true, + "reference_sha256": "6f186112e6102f2f7969de7442fa7ee4432200a3678586cfc4e10c490b31bca4" + } +} diff --git a/registry/phase4ac-lif-semantics/evidence/regression/five.json b/registry/phase4ac-lif-semantics/evidence/regression/five.json new file mode 100644 index 0000000..c113354 --- /dev/null +++ b/registry/phase4ac-lif-semantics/evidence/regression/five.json @@ -0,0 +1,13 @@ +{ + "exact": { + "counts": true, + "g": true, + "history": true, + "neuron_idx": true, + "queue": true, + "ref": true, + "step": true, + "v": true + }, + "pass": true +} diff --git a/registry/phase4ac-lif-semantics/evidence/regression/frozen-five.json b/registry/phase4ac-lif-semantics/evidence/regression/frozen-five.json new file mode 100644 index 0000000..bb76502 --- /dev/null +++ b/registry/phase4ac-lif-semantics/evidence/regression/frozen-five.json @@ -0,0 +1,61 @@ +{ + "oracle": "frozen deterministic-v2, not Brian2", + "pass": true, + "trials": [ + { + "exact": { + "counts": true, + "g": true, + "neuron_idx": true, + "step": true, + "v": true + }, + "trial": "auditory-10hz", + "wall_seconds": 2.72041380200244 + }, + { + "exact": { + "counts": true, + "g": true, + "neuron_idx": true, + "step": true, + "v": true + }, + "trial": "auditory-100hz", + "wall_seconds": 4.963989064999623 + }, + { + "exact": { + "counts": true, + "g": true, + "neuron_idx": true, + "step": true, + "v": true + }, + "trial": "olfactory-50hz", + "wall_seconds": 4.997483518993249 + }, + { + "exact": { + "counts": true, + "g": true, + "neuron_idx": true, + "step": true, + "v": true + }, + "trial": "mechanosensory-50hz", + "wall_seconds": 5.009357625996927 + }, + { + "exact": { + "counts": true, + "g": true, + "neuron_idx": true, + "step": true, + "v": true + }, + "trial": "gustatory-50hz", + "wall_seconds": 4.982761088991538 + } + ] +} diff --git a/registry/phase4ac-lif-semantics/evidence/regression/motifs.json b/registry/phase4ac-lif-semantics/evidence/regression/motifs.json new file mode 100644 index 0000000..096f7a9 --- /dev/null +++ b/registry/phase4ac-lif-semantics/evidence/regression/motifs.json @@ -0,0 +1,27 @@ +[ + { + "CPU_GPU_exact": true, + "motif": "pair", + "wall_seconds": 1.4125005870009772 + }, + { + "CPU_GPU_exact": true, + "motif": "trio", + "wall_seconds": 1.4483178199880058 + }, + { + "CPU_GPU_exact": true, + "motif": "five", + "wall_seconds": 1.5178599859937094 + }, + { + "CPU_GPU_exact": true, + "motif": "feedforward", + "wall_seconds": 1.3267560910026077 + }, + { + "CPU_GPU_exact": true, + "motif": "no_input", + "wall_seconds": 1.3030154559965013 + } +] diff --git a/registry/phase4ac-lif-semantics/evidence/regression/no_input.json b/registry/phase4ac-lif-semantics/evidence/regression/no_input.json new file mode 100644 index 0000000..c113354 --- /dev/null +++ b/registry/phase4ac-lif-semantics/evidence/regression/no_input.json @@ -0,0 +1,13 @@ +{ + "exact": { + "counts": true, + "g": true, + "history": true, + "neuron_idx": true, + "queue": true, + "ref": true, + "step": true, + "v": true + }, + "pass": true +} diff --git a/registry/phase4ac-lif-semantics/evidence/regression/pair.json b/registry/phase4ac-lif-semantics/evidence/regression/pair.json new file mode 100644 index 0000000..c113354 --- /dev/null +++ b/registry/phase4ac-lif-semantics/evidence/regression/pair.json @@ -0,0 +1,13 @@ +{ + "exact": { + "counts": true, + "g": true, + "history": true, + "neuron_idx": true, + "queue": true, + "ref": true, + "step": true, + "v": true + }, + "pass": true +} diff --git a/registry/phase4ac-lif-semantics/evidence/regression/preflight.json b/registry/phase4ac-lif-semantics/evidence/regression/preflight.json new file mode 100644 index 0000000..b747f21 --- /dev/null +++ b/registry/phase4ac-lif-semantics/evidence/regression/preflight.json @@ -0,0 +1,48 @@ +{ + "experiments/phase4aa-apl-pn-scope": { + "checked": 68, + "checksums_sha256": "a69b2511689207b0d9ddbe2fabce3be71908f457bb898e3b685a213a796a272a", + "manifest_sha256": "6d75567af2a6c0993d4fc08e272814910c19fa9602811cfacd1ebc4ba76bc737", + "mismatches": [], + "pass": true + }, + "experiments/phase4ab-terminal-scope": { + "checked": 199, + "checksums_sha256": "d83926a3055d9f9ca471ceba328076d7ceba883f267468750914080733e95e31", + "manifest_sha256": "cb3723f9dae29d4889489ae39f40293c927f4f9e532551e2c4d5214bf0a70140", + "mismatches": [], + "pass": true + }, + "models/male-cns-lif/apl-pn-scope-audit-v1": { + "checked": 12, + "checksums_sha256": "55dc418f2d62be04601af33cbd8789578447e6a2289d3a581dc713cbb7466a25", + "manifest_sha256": "9120685eb02dc2bd3b38d42b2ade1f38f6bbc2a1ec269fd4d555cead2d628277", + "mismatches": [], + "pass": true + }, + "models/male-cns-lif/terminal-scope-diagnostic-v1": { + "checked": 11, + "checksums_sha256": "92a03195cb41863027fd0397ad3811248354a5d3f2e91ffa2c297eba62dc2821", + "manifest_sha256": "5cea0035a95345825b73385c6e3056244c2a614d10a6fa6742487a331d8f0f3e", + "mismatches": [], + "pass": true + }, + "original": { + "checked": 230239, + "exclusions": [ + ".cache", + ".git", + ".mypy_cache", + ".pytest_cache", + ".venv", + "__pycache__", + "node_modules", + "venv" + ], + "meaning": "All original listed bytes checked; only newly named stage outputs are additions.", + "mismatches": [], + "new_stage_additions_allowed": true, + "pass": true, + "reference_sha256": "6f186112e6102f2f7969de7442fa7ee4432200a3678586cfc4e10c490b31bca4" + } +} diff --git a/registry/phase4ac-lif-semantics/evidence/regression/run-start.json b/registry/phase4ac-lif-semantics/evidence/regression/run-start.json new file mode 100644 index 0000000..24b9813 --- /dev/null +++ b/registry/phase4ac-lif-semantics/evidence/regression/run-start.json @@ -0,0 +1,6 @@ +{ + "alternative_policies_only_synthetic_single_cell": true, + "device": "NVIDIA GeForce RTX 4090", + "free_VRAM": 12494438400, + "whole_brain_uses_only_frozen_reference": true +} diff --git a/registry/phase4ac-lif-semantics/evidence/regression/synthetic.json b/registry/phase4ac-lif-semantics/evidence/regression/synthetic.json new file mode 100644 index 0000000..234d9a2 --- /dev/null +++ b/registry/phase4ac-lif-semantics/evidence/regression/synthetic.json @@ -0,0 +1,8 @@ +{ + "Brian2_executed": false, + "brain_model_modified": false, + "cases": 17, + "pass": true, + "policies": 4, + "proves_only_operator_difference": true +} diff --git a/registry/phase4ac-lif-semantics/evidence/regression/trio.json b/registry/phase4ac-lif-semantics/evidence/regression/trio.json new file mode 100644 index 0000000..c113354 --- /dev/null +++ b/registry/phase4ac-lif-semantics/evidence/regression/trio.json @@ -0,0 +1,13 @@ +{ + "exact": { + "counts": true, + "g": true, + "history": true, + "neuron_idx": true, + "queue": true, + "ref": true, + "step": true, + "v": true + }, + "pass": true +} diff --git a/registry/phase4ac-lif-semantics/evidence/regression/unit-tests.json b/registry/phase4ac-lif-semantics/evidence/regression/unit-tests.json new file mode 100644 index 0000000..c172c9c --- /dev/null +++ b/registry/phase4ac-lif-semantics/evidence/regression/unit-tests.json @@ -0,0 +1,4 @@ +{ + "pass": true, + "tests": 7 +} diff --git a/registry/phase4ac-lif-semantics/evidence/synthetic/results.csv b/registry/phase4ac-lif-semantics/evidence/synthetic/results.csv new file mode 100644 index 0000000..18461bc --- /dev/null +++ b/registry/phase4ac-lif-semantics/evidence/synthetic/results.csv @@ -0,0 +1,69 @@ +case,policy,spikes,spike_times_ms,post_input_spikes,final_g,finite,exact_repeat,not_full_Brian2_replication +one_impulse_contacts_1,frozen,0,[],,4.722705559956353e-10,True,True,True +one_impulse_contacts_1,reset_g_only,0,[],,4.722705559956353e-10,True,True,True +one_impulse_contacts_1,refractory_gate_only,0,[],,4.722705559956353e-10,True,True,True +one_impulse_contacts_1,reset_and_refractory,0,[],,4.722705559956353e-10,True,True,True +one_impulse_contacts_43,frozen,0,[],,2.030761692140004e-08,True,True,True +one_impulse_contacts_43,reset_g_only,0,[],,2.030761692140004e-08,True,True,True +one_impulse_contacts_43,refractory_gate_only,0,[],,2.030761692140004e-08,True,True,True +one_impulse_contacts_43,reset_and_refractory,0,[],,2.030761692140004e-08,True,True,True +one_impulse_contacts_57,frozen,0,[],,2.691940537147275e-08,True,True,True +one_impulse_contacts_57,reset_g_only,0,[],,2.691940537147275e-08,True,True,True +one_impulse_contacts_57,refractory_gate_only,0,[],,2.691940537147275e-08,True,True,True +one_impulse_contacts_57,reset_and_refractory,0,[],,2.691940537147275e-08,True,True,True +one_impulse_contacts_64,frozen,0,[],,3.022531558372066e-08,True,True,True +one_impulse_contacts_64,reset_g_only,0,[],,3.022531558372066e-08,True,True,True +one_impulse_contacts_64,refractory_gate_only,0,[],,3.022531558372066e-08,True,True,True +one_impulse_contacts_64,reset_and_refractory,0,[],,3.022531558372066e-08,True,True,True +one_impulse_contacts_70,frozen,0,[],,3.3058963566645616e-08,True,True,True +one_impulse_contacts_70,reset_g_only,0,[],,3.3058963566645616e-08,True,True,True +one_impulse_contacts_70,refractory_gate_only,0,[],,3.3058963566645616e-08,True,True,True +one_impulse_contacts_70,reset_and_refractory,0,[],,3.3058963566645616e-08,True,True,True +one_impulse_contacts_76,frozen,0,[],,3.589252628444228e-08,True,True,True +one_impulse_contacts_76,reset_g_only,0,[],,3.589252628444228e-08,True,True,True +one_impulse_contacts_76,refractory_gate_only,0,[],,3.589252628444228e-08,True,True,True +one_impulse_contacts_76,reset_and_refractory,0,[],,3.589252628444228e-08,True,True,True +one_impulse_contacts_95,frozen,0,[],,4.486569693540332e-08,True,True,True +one_impulse_contacts_95,reset_g_only,0,[],,4.486569693540332e-08,True,True,True +one_impulse_contacts_95,refractory_gate_only,0,[],,4.486569693540332e-08,True,True,True +one_impulse_contacts_95,reset_and_refractory,0,[],,4.486569693540332e-08,True,True,True +one_impulse_contacts_104,frozen,0,[],,4.911609963187402e-08,True,True,True +one_impulse_contacts_104,reset_g_only,0,[],,4.911609963187402e-08,True,True,True +one_impulse_contacts_104,refractory_gate_only,0,[],,4.911609963187402e-08,True,True,True +one_impulse_contacts_104,reset_and_refractory,0,[],,4.911609963187402e-08,True,True,True +one_impulse_contacts_172,frozen,1,[6.0],,8.123046768560016e-08,True,True,True +one_impulse_contacts_172,reset_g_only,1,[6.0],,0.0,True,True,True +one_impulse_contacts_172,refractory_gate_only,1,[6.0],,1.2415698336099013e-07,True,True,True +one_impulse_contacts_172,reset_and_refractory,1,[6.0],,0.0,True,True,True +one_impulse_contacts_210,frozen,1,[3.8000000000000003],,9.917685872551374e-08,True,True,True +one_impulse_contacts_210,reset_g_only,1,[3.8000000000000003],,0.0,True,True,True +one_impulse_contacts_210,refractory_gate_only,1,[3.8000000000000003],,1.5158722987962392e-07,True,True,True +one_impulse_contacts_210,reset_and_refractory,1,[3.8000000000000003],,0.0,True,True,True +one_impulse_contacts_226,frozen,1,[3.3000000000000003],,1.0673294070784323e-07,True,True,True +one_impulse_contacts_226,reset_g_only,1,[3.3000000000000003],,0.0,True,True,True +one_impulse_contacts_226,refractory_gate_only,1,[3.3000000000000003],,1.6313636308495916e-07,True,True,True +one_impulse_contacts_226,reset_and_refractory,1,[3.3000000000000003],,0.0,True,True,True +one_impulse_contacts_235,frozen,1,[3.1],,1.109835494617073e-07,True,True,True +one_impulse_contacts_235,reset_g_only,1,[3.1],,0.0,True,True,True +one_impulse_contacts_235,refractory_gate_only,1,[3.1],,1.6963321058938163e-07,True,True,True +one_impulse_contacts_235,reset_and_refractory,1,[3.1],,0.0,True,True,True +one_impulse_contacts_259,frozen,1,[2.7],,1.2231805612827884e-07,True,True,True +one_impulse_contacts_259,reset_g_only,1,[2.7],,0.0,True,True,True +one_impulse_contacts_259,refractory_gate_only,1,[2.7],,1.8695746462071838e-07,True,True,True +one_impulse_contacts_259,reset_and_refractory,1,[2.7],,0.0,True,True,True +one_impulse_contacts_283,frozen,1,[2.3000000000000003],,1.3365253437314095e-07,True,True,True +one_impulse_contacts_283,reset_g_only,1,[2.3000000000000003],,0.0,True,True,True +one_impulse_contacts_283,refractory_gate_only,2,"[2.3000000000000003, 10.3]",,3.122351870388229e-07,True,True,True +one_impulse_contacts_283,reset_and_refractory,1,[2.3000000000000003],,0.0,True,True,True +refractory_boundary,frozen,7,"[0.0, 2.3000000000000003, 4.6000000000000005, 7.0, 9.600000000000001, 12.600000000000001, 16.400000000000002]",,37.13106155395508,True,True,True +refractory_boundary,reset_g_only,1,[0.0],,1.2371366024017334,True,True,True +refractory_boundary,refractory_gate_only,10,"[0.0, 2.2, 4.4, 6.6000000000000005, 8.8, 11.0, 13.200000000000001, 15.4, 17.6, 19.8]",,1676.00341796875,True,True,True +refractory_boundary,reset_and_refractory,1,[0.0],,0.5655308961868286,True,True,True +sustained_then_off,frozen,45,"[1.7000000000000002, 4.3, 6.800000000000001, 9.3, 11.8, 14.200000000000001, 16.6, 19.0, 21.400000000000002, 23.8, 26.200000000000003, 28.6, 31.0, 33.4, 35.800000000000004, 38.2, 40.6, 43.0, 45.400000000000006, 47.800000000000004, 50.2, 52.6, 55.0, 57.400000000000006, 59.800000000000004, 62.2, 64.60000000000001, 67.0, 69.4, 71.8, 74.2, 76.60000000000001, 79.0, 81.4, 83.80000000000001, 86.2, 88.60000000000001, 91.0, 93.4, 95.80000000000001, 98.2, 100.7, 103.4, 106.5, 110.80000000000001]",4.0,8.414999115302635e-07,True,True,True +sustained_then_off,reset_g_only,35,"[1.7000000000000002, 4.6000000000000005, 7.5, 10.4, 13.3, 16.2, 19.1, 22.0, 24.900000000000002, 27.8, 30.700000000000003, 33.6, 36.5, 39.400000000000006, 42.300000000000004, 45.2, 48.1, 51.0, 53.900000000000006, 56.800000000000004, 59.7, 62.6, 65.5, 68.4, 71.3, 74.2, 77.10000000000001, 80.0, 82.9, 85.80000000000001, 88.7, 91.60000000000001, 94.5, 97.4, 100.30000000000001]",1.0,0.0,True,True,True +sustained_then_off,refractory_gate_only,54,"[1.7000000000000002, 4.6000000000000005, 7.4, 10.100000000000001, 12.700000000000001, 15.3, 17.900000000000002, 20.5, 23.0, 25.5, 28.0, 30.5, 33.0, 35.5, 38.0, 40.5, 43.0, 45.5, 48.0, 50.5, 53.0, 55.5, 58.0, 60.5, 63.0, 65.5, 68.0, 70.5, 72.9, 75.3, 77.7, 80.10000000000001, 82.5, 84.9, 87.30000000000001, 89.7, 92.10000000000001, 94.5, 96.9, 99.30000000000001, 101.80000000000001, 104.30000000000001, 106.80000000000001, 109.30000000000001, 111.9, 114.5, 117.2, 119.9, 122.7, 125.60000000000001, 128.70000000000002, 132.1, 135.9, 140.70000000000002]",14.0,0.0004200958937872201,True,True,True +sustained_then_off,reset_and_refractory,26,"[1.7000000000000002, 5.6000000000000005, 9.5, 13.4, 17.3, 21.200000000000003, 25.1, 29.0, 32.9, 36.800000000000004, 40.7, 44.6, 48.5, 52.400000000000006, 56.300000000000004, 60.2, 64.10000000000001, 68.0, 71.9, 75.8, 79.7, 83.60000000000001, 87.5, 91.4, 95.30000000000001, 99.2]",0.0,0.0,True,True,True +zero_input,frozen,0,[],,0.0,True,True,True +zero_input,reset_g_only,0,[],,0.0,True,True,True +zero_input,refractory_gate_only,0,[],,0.0,True,True,True +zero_input,reset_and_refractory,0,[],,0.0,True,True,True diff --git a/registry/phase4ac-lif-semantics/seal-verification.json b/registry/phase4ac-lif-semantics/seal-verification.json new file mode 100644 index 0000000..f88b881 --- /dev/null +++ b/registry/phase4ac-lif-semantics/seal-verification.json @@ -0,0 +1,16 @@ +{ + "experiments/phase4ac-lif-semantics": { + "checked": 57, + "checksums_sha256": "81bb3a86454147f1562bc3592438b6a6d0091dbe1d2a777e802882ecf1d0db35", + "manifest_sha256": "4e7d1606e107fe72f5dad935952705260577edaba6f811d65b4105ce07abd72c", + "mismatches": [], + "pass": true + }, + "models/male-cns-lif/lif-semantics-audit-v1": { + "checked": 7, + "checksums_sha256": "15b7b7828492387beed2c885ad9d22af682cff1dc38198c0770ab7175759c69d", + "manifest_sha256": "53e53d51bba86ec11a02e920f2c2653db4c138dd9562e8416dd001780635070c", + "mismatches": [], + "pass": true + } +} diff --git a/tools/publish_phase4ac.py b/tools/publish_phase4ac.py new file mode 100644 index 0000000..fab4c67 --- /dev/null +++ b/tools/publish_phase4ac.py @@ -0,0 +1,30 @@ +"""Publish only new, sealed, small Phase 4AC evidence; no bulk data in Git.""" +import json +from pathlib import Path +import shutil +import sys + +ROOT=Path('/data/digital-drosophila') +MODEL=ROOT/'models/male-cns-lif/lif-semantics-audit-v1' +EXP=ROOT/'experiments/phase4ac-lif-semantics' +sys.path.insert(0,str(MODEL)) +from audit_semantics import digest, save, manifest_check + +for folder in (MODEL,EXP): assert manifest_check(folder,digest)['pass'] +registry=ROOT/'registry/phase4ac-lif-semantics'; registry.mkdir(exist_ok=False) +records=[] +for p in sorted(EXP.rglob('*')): + if not p.is_file() or p.stat().st_size > 4*1024**2: continue + external=p.parent==EXP/'external-resources' + if p.suffix not in ('.json','.csv','.md','.sha256') and not external: continue + dst=registry/'evidence'/p.relative_to(EXP);dst.parent.mkdir(parents=True,exist_ok=True) + with p.open('rb') as src,dst.open('xb') as out: shutil.copyfileobj(src,out) + assert digest(p)==digest(dst) + records.append(dict(source=str(p.relative_to(ROOT)),copy=str(dst.relative_to(registry)), + sha256=digest(p),bytes=p.stat().st_size)) +save(registry/'evidence-index.json',records) +save(registry/'seal-verification.json',{str(p.relative_to(ROOT)):manifest_check(p,digest) for p in (MODEL,EXP)}) +for source,destination in [('REPORT.md','phase4ac-lif-semantics.md'),('INTERPRETATION.zh.md','phase4ac-interpretation.md')]: + target=ROOT/'docs/progress'/destination + with (EXP/source).open('rb') as src,target.open('xb') as out: shutil.copyfileobj(src,out) +print('Published',len(records),'small evidence files; original scientific data read-only')