Audit APL PN scope and localize official synaptic contacts without changing frozen dynamics

This commit is contained in:
Digital Drosophila Archive
2026-09-29 23:58:05 +08:00
parent 3981628ff8
commit d6843e675d
62 changed files with 3974 additions and 0 deletions
@@ -0,0 +1,18 @@
# 授权追加:官方突触位置审计
用户已明确授权下载约 6.78 GB 的官方 syn-partners v1.0 作为新增参考数据。
本追加取代原 CPU 静态审计中“本轮不下载 bulk”的范围限制;不改变原审计结果、原 raw 或任何模型参数。
原静态审计的 unknown 描述“追加数据前”的证据状态,最终结果另存而不覆盖。
在查看位置结果前定义:
1. 以官方 generation 和 MD5 校验下载,另生成本地 SHA-256;不下载 syn-points 全表或 EM。
2. 检查实际 schema 后按原字段读取,不猜列名。坐标为 MaleCNS 8 nm voxel;距离乘 0.008 转 µm。
3. 提取全部 APL 入/出突触对、APL 所连 PN→KC 对、七个既定观察 PN↔ALLN 对。
4. 每个 canonical body pair 的实际突触对行数必须与 base CSR 原 synapse count 一致;有重复配对或 count 差异即停止机制解释。
5. 依据真实 primary_post 字符串报告 ROI,不由神经元名称猜 compartment。
6. 对 APL→PN postsynaptic point 与同一 PN 的 PN→KC presynaptic points 计算最近欧氏距离分布。距离只是空间邻近,不等于同 bouton、受体作用或功能因果。
7. 分别报告 APL→PN、PN→KC、PN↔ALLN 的 ROI,判断 point-neuron 全局电流会不会混淆不同解剖区域。
8. 无受体、时间常数、末梢释放系数的部分继续 unknown;不据此增删边、补抑制、改变阈值或训练。
4090 仅追加五组已有 frozen-v2 reference regression。原五组输入、参数、初态和数值语义不变;所有新输出留在本阶段目录。
@@ -0,0 +1,37 @@
# Phase 4AA — APL→PN scope audit(预先声明)
接续封存 Phase 4Z,仅做 CPU 解剖/实现范围审计。不重新运行旧科学阶段,不使用 GPU,不影响 ComfyUI。
不训练、不改参数/符号、不增加边、不调整 APL calibration、eligibility-v2 或 14,232 plastic mask。
## 选择与检验
- 直接从实际 annotation_type == APL、annotation_class == ALPN / Kenyon_Cell 识别;空 class 不靠名称猜测。
- 审计所有 APL 入/出边,不只选择七个观察 PN。七个 PN 来自封存 Phase 4Z 的全部真实目标 KC 入源。
- 从 CSR 独立抽取,再流式过滤原始 Feather,逐 body pair / 原始 count 严格核对。
- 区分 frozen fast-current out-mask、KC-only graded output、KC/PN-only graded input;输入被 graded 计算忽略不等于原图边被删除。
- 核对 PN↔APL 双向边、PN→KC 与 PN→ALLN 出边;这只证明解剖路径,不宣称空间/生理因果。
- 检查真实 schema 是否含接触位置、ROI、靶位点受体;SWC centerline 不等同 synaptic partner 坐标。
- 保存 Phase 4Z 所用运行时代码相关段落与 SHA-256,核实覆盖数量完全一致。
## 未知与停止条件
缺失的接触 ROI、末梢位置、受体和作用系数均记 unknown。
有配对边和论文支持不等于这只 MaleCNS 中某条连接已经定位到 calyx bouton。
不得据本审计自动恢复 APL→PN whole-cell negative current 或扩大 graded target matrix。
官方 syn-partners/syn-points 只获取 HEAD 元数据;不自动下载数 GB 数据,不请求 EM。
若继续定位需 neuPrint 授权或新的官方附加数据,输出具体需求,不猜测补齐。
## 通过的含义
audit PASS = 原始边核对通过、覆盖重建与 Phase 4Z 相符、旧文件哈希不变、未知被保留。
不等于 learning PASS,不产生新的正式模型候选。全项目顶层 gate 保持 5/10。
复现用新的 experiment_root;禁止覆盖任何已经封存的输出目录。
## 证据
- 官方 MaleCNS 下载定义:https://male-cns.janelia.org/download/
- APL 局部化:https://doi.org/10.7554/eLife.56954
- PN bouton/KC dendrite 研究:https://doi.org/10.7554/eLife.74172
- Google Research 项目说明:https://www.research.google/blog/a-connectomics-milestone-mapping-the-complete-male-fruit-fly-brain/
Google/Janelia 的解剖数据与论文用于约束来源和机制;不能替代受体/电导测量或学习任务验证。
@@ -0,0 +1,111 @@
# Phase 4AA — APL→PN 作用范围与官方突触定位审计
正式结论:**PASS-APL-PN-ANATOMICAL-LOCALIZATION / NO-DYNAMICS-CANDIDATE**。
本轮从 Phase 4Z 接续,先完成只读 CPU 范围审计;随后用户明确授权下载官方 syn-partners 并继续定位,也确认 ComfyUI 空闲以便运行 frozen regression。
原始静态审计 `audit/results.json` 中的空间 unknown/blocked 是追加数据前的状态,保留不覆盖;最终状态以 `audit/final-summary.json` 和本报告为准。
本轮无训练、无参数修改、无新的正式动力学候选。顶层验收仍为 5/10(50%),不是生物学复现比例。
## 核心新证据
以实际 annotation 与原始 CSR 识别 2 个 APL、4,064 个 KC、686 个 ALPN,不通过 neurotransmitter 推断 DAN 身份。
所有 166,700 个 neurons、25,582,938 edges、124,177,617 anatomical contacts 不变。
| 已有 APL 实现范围 | 边数 | 原始 contacts |
|---|---:|---:|
| APL 全部出边 | 5,845 | 209,912 |
| KC-only graded output 覆盖 | 4,633 | 196,200 |
| 非 KC 出边,没有 graded 替代 | 1,212 | 13,712 |
| 上述缺口中的 APL→PN | 268 | 4,600 |
| APL 全部入边 | 6,185 | 234,025 |
| 不被 KC/PN-only graded state 使用的入边 | 1,202 | 18,257 |
268 条 APL→PN 边涉及 259 个 PN;247 对同时存在 PN→APL 反向连接。
“graded state 未使用”不等于原图入边被删除:普通 LIF APL 仍有这些入边,但其快速出边被既有 overlay 置零。基于 KC/PN 计算的独立 graded state 没有使用其余来源。
这属于既有模型作用范围,不能把每个未覆盖来源都自动补入;需要额外生理依据。
## 官方附加数据与精确核对
用户授权下载的 `syn-partners-male-cns-v1.0-minconf-0.5.feather`:
- 6,777,179,098 bytes;官方 generation `1780494942562468`。
- 官方 MD5:`58efcf712f8c4d4de5f2ad51e97def76`,验证通过。
- SHA-256:`959d8ef4173b35382a3e6acfaf5167c795b6d10b877572d146af04e1b487bc07`。
- 流式读取全部 311,833,243 条配对记录;实际字段和 dtype 已保存。
- 来源:[MaleCNS 官方下载页](https://male-cns.janelia.org/download/),许可证 CC BY 4.0。新增文件保存在本阶段 external-resources,不写 raw,不下载 EM。
| 提取范围 | 配对记录总数 | canonical 配对记录 | canonical neuron pairs |
|---|---:|---:|---:|
| APL 所有入/出接触 | 500,348 | 443,915 | 12,027 |
| APL 所连 PN→KC | 385,229 | 385,229 | 21,978 |
| 七个重点 PN→ALLN | 22,599 | 22,599 | 823 |
| ALLN→七个重点 PN | 19,024 | 19,024 | 886 |
每组同时检查重复配对、完整 pair 集合及逐边 count:均与原始 CSR 完全一致。不存在只比较出现过的边而漏掉整条缺失边的情况。
APL 配对中的非 canonical 部分保留来源记录,不加入 neuron-only graph。
## 真实 ROI 定位
4,600 个 APL→PN 接触都取得真实 pre/post 坐标:
- `CA(L)` 2,063;`CA(R)` 1,757;合计 3,820(83.04%)。
- `CentralBrain-unspecified` 731(15.89%):坐标已知,但官方 ROI 未细分,绝不按邻近位置重标为 calyx。
- 其余实际标注合计 49,分布于 LH、PED、SCL、SLP、a'L;不丢弃非 calyx 结果。
CA 对应 calyx,官方作者 [Cell Type Explorer](https://reiserlab.github.io/celltype-explorer-drosophila-male-cns/types/KCg-d_R.html) 提供标签释义。
七个重点 PN:
| neuron_idx / body_id | type | APL→PN contacts | CA(R) | ROI 未细分 |
|---|---|---:|---:|---:|
| 30 / 10039 | VL2a_adPN | 50 | 47 | 3 |
| 179 / 10198 | VA7l_adPN | 7 | 7 | 0 |
| 484 / 10522 | VL2p_adPN | 50 | 49 | 1 |
| 1644 / 11761 | VP1d+VP4_l2PN1 | 78 | 70 | 8 |
| 6065 / 16610 | VA7m_lPN | 14 | 13 | 1 |
| 6842 / 17484 | DC2_adPN | 13 | 13 | 0 |
| 133666 / 527577 | VA6_adPN | 35 | 29 | 6 |
合计 228/247(92.31%)在 CA(R),19 个未细分。
对同一 PN,APL postsynaptic sites 到最近 PN→KC presynaptic site 的距离,中位数范围为 0.545–0.861 µm;坐标按官方 8 nm voxel 转换。
距离不是同 bouton 的证明,更不是受体或功能因果证明。保留全部分布和远距离样本,不设“最佳阈值”筛掉例外。
259 个 APL 靶 PN 中,15 个在本 canonical 图中没有 PN→KC 出边,不能一概当作同一功能入口。
七个 PN→ALLN 的 22,599 个接触全部位于 AL(L/R);ALLN→七个 PN 的 19,024 个接触中,19,021 位于 AL(L/R),另有 1 个 LAL(R)、2 个未细分。
同一 PN 的 calyx 相关接触与触角叶局部回路接触必须区分,不能用单一 whole-neuron 抑制项自动代表两种位置。
## 如何解释,不做什么
已有原始研究支持 APL 的局部抑制与 PN bouton/KC dendrite 相互作用,但不提供当前 MaleCNS 每条边的受体或强度。
见 [Prisco et al., eLife](https://doi.org/10.7554/eLife.74172)、[Amin et al., eLife](https://doi.org/10.7554/eLife.56954)。
本轮数据加强了“空间作用范围缺失”这一机制假设,**没有证明补上它就能修复 KC 持续放电或刺激特异性记忆**。
仍未知:具体 bouton 身份、GABA 受体、末梢释放变化、时间常数、量化作用系数及 whole-brain 干预效果。
下一步应先设计独立的 compartment/terminal-specific input hypothesis 和预声明对照,不直接改变 frozen baseline;对未知系数不能用“学习效果更好”反向调参。
优先处理 upstream encoding / 作用范围,而不是继续改 dopamine eta、扩大 plastic mask 或调 KC/MBON 阈值。
## 回归、完整性与资源
独立新目录重跑 deterministic-v2 的五组冻结试次(各一次):
| trial | biological time | wall time | 事件 / counts / V / g |
|---|---:|---:|---|
| auditory 10 Hz | 1 s | 2.690 s | 全部精确一致 |
| auditory 100 Hz | 1 s | 4.915 s | 全部精确一致 |
| olfactory 50 Hz | 1 s | 4.961 s | 全部精确一致 |
| mechanosensory 50 Hz | 1 s | 4.982 s | 全部精确一致 |
| gustatory 50 Hz | 1 s | 4.977 s | 全部精确一致 |
均无 NaN/Inf,V/g 最大误差 0;4090 本进程 peak allocated VRAM 为 285,994,496 bytes(约 272.75 MiB),不包括 ComfyUI 已驻留显存。
本轮不声称重做了 Phase 4P 的 20 次重复实验;旧 v1/v2 reference 均没有覆盖。
GPU 编译加回归约 85.55 s;CPU 结构审计含两次旧文件哈希扫描约 86.92 s;下载加校验约 375.66 s;空间提取/分析约 37.98 s。
230,239 个旧科学文件的 SHA-256 复核通过。初始 Git payload 的 681 项校验也通过;新阶段另做 manifest。
未停止或卸载 ComfyUI,未更新任何环境包。
## 异常与处理记录
1. 初次建立实验目录遇到写权限限制,在新实验目录单独配置 owner;没有递归修改旧目录。
2. GPU 首次启动 PATH 未包含原 venv 的 Ninja,未开始模拟;失败目录保留。仅补启动 PATH 后,在另一个新目录完成 5/5 回归。
3. 下载首次校验选项分隔符错误,下载未开始;修正为 aria2 要求的语法后完成官方校验,没有坏文件被当作通过。
4. 旧 NumPy→Torch 只读数组警告保留,未修改冻结加载器;文件哈希与数值回归通过。
本轮到此结束,不生成 learning candidate,不进入游戏、RL、视觉或动作 decoder。
@@ -0,0 +1,245 @@
"""CPU-only, read-only APL/PN implementation scope audit. No scientific modules imported."""
import argparse
import ast
import concurrent.futures as cf
from datetime import datetime, timezone
import gzip
import hashlib
import json
from pathlib import Path
import resource
import time
import urllib.request
import numpy as np
import pandas as pd
import pyarrow as pa
import pyarrow.compute as pc
import yaml
def digest(path):
h=hashlib.sha256()
with path.open('rb') as f:
for b in iter(lambda:f.read(8<<20),b''):h.update(b)
return h.hexdigest()
def save(path,value):
path.parent.mkdir(parents=True,exist_ok=True)
with path.open('x',encoding='utf-8') as f:
json.dump(value,f,ensure_ascii=False,indent=2,sort_keys=True,allow_nan=False)
f.write('\n')
def immutable_check(root,snapshot,workers):
summary=json.loads((snapshot/'summary.json').read_text())
assert digest(snapshot/'files.jsonl.gz')==summary['files_jsonl_gz_sha256']
with gzip.open(snapshot/'files.jsonl.gz','rt') as f:rows=[json.loads(x) for x in f]
def check(r):
p=root/r['path']
if r['kind']=='symlink':
ok=p.is_symlink() and str(p.readlink())==r['target']
else:
ok=p.is_file() and p.stat().st_size==r['bytes'] and digest(p)==r['sha256']
return None if ok else r['path']
with cf.ThreadPoolExecutor(max_workers=workers) as pool:bad=[x for x in pool.map(check,rows) if x]
return {'pass':not bad,'checked':len(rows),'mismatches':bad,'reference_sha256':summary['files_jsonl_gz_sha256'],
'exclusions':summary['excluded_directory_names'],'new_stage_additions_allowed':True,
'meaning':'All original listed bytes checked; only newly named stage outputs are additions.'}
def population(meta):
out=meta.annotation_class.fillna('UNKNOWN_CLASS').astype(str).to_numpy(object)
for typ in ('APL','DPM'):out[meta.annotation_type.eq(typ).to_numpy()]=typ
return out
def edge_frame(ids,sources,targets,weights,meta,pops):
src=sources[ids];dst=targets[ids]
f=pd.DataFrame({'edge_id':ids,'source_neuron_idx':src,'target_neuron_idx':dst,'raw_synapse_count':weights[ids]})
for pref,arr in [('source',src),('target',dst)]:
f[pref+'_population']=pops[arr]
for col in ('body_id','annotation_class','annotation_type','annotation_instance','annotation_somaSide','neurotransmitter','nt_ground_truth','annotation_receptorType'):
f[pref+'_'+col]=meta[col].to_numpy()[arr]
return f
def raw_incident(path,bodyids):
tables=[]
with pa.memory_map(str(path),'r') as f:
reader=pa.ipc.open_file(f)
assert reader.schema.names==['body_pre','body_post','weight'],str(reader.schema)
ids=pa.array(bodyids.astype(np.int64))
for i in range(reader.num_record_batches):
batch=reader.get_batch(i)
keep=pc.or_(pc.is_in(batch.column(0),value_set=ids),pc.is_in(batch.column(1),value_set=ids))
selected=batch.filter(keep)
if len(selected):tables.append(pa.Table.from_batches([selected]))
return pa.concat_tables(tables).to_pandas()
def official_head(timeout):
base='https://storage.googleapis.com/flyem-male-cns/v1.0/connectome-data/flat-connectome/'
out=[]
for name in ('syn-partners-male-cns-v1.0-minconf-0.5.feather','syn-points-male-cns-v1.0-minconf-0.5.feather'):
row={'url':base+name,'retrieved_utc':datetime.now(timezone.utc).isoformat(),'method':'HEAD','body_downloaded':False}
try:
with urllib.request.urlopen(urllib.request.Request(base+name,method='HEAD'),timeout=timeout) as r:
row.update(status=r.status,content_length=int(r.headers['Content-Length']),etag=r.headers.get('ETag'),
generation=r.headers.get('x-goog-generation'),upstream_hash_header=r.headers.get('x-goog-hash'),
last_modified=r.headers.get('Last-Modified'),accept_ranges=r.headers.get('Accept-Ranges'))
except Exception as e:row.update(status='UNAVAILABLE',error=type(e).__name__+': '+str(e))
out.append(row)
return out
def seal(root):
paths=sorted(p for p in root.rglob('*') if p.is_file() and p.name not in ('manifest.json','checksums.sha256'))
rows=[{'path':p.relative_to(root).as_posix(),'bytes':p.stat().st_size,'sha256':digest(p)} for p in paths]
save(root/'manifest.json',{'files':rows,'created_utc':datetime.now(timezone.utc).isoformat()})
with (root/'checksums.sha256').open('x') as f:
for r in rows:f.write(r['sha256']+' '+r['path']+'\n')
return len(rows)
def run(cfg):
pa.set_cpu_count(4);pa.set_io_thread_count(4)
start=time.perf_counter();root=Path(cfg['root']);exp=Path(cfg['experiment_root']);model=Path(cfg['model_root'])
assert exp.is_relative_to(root/'experiments') and model.is_relative_to(root/'models/male-cns-lif')
if exp.exists() and any(exp.iterdir()):raise RuntimeError('Refusing nonempty experiment directory')
exp.mkdir(parents=True,exist_ok=True)
for d in ('protocol','audit','connectivity','metadata','spatial','external-resources','regression','performance'):(exp/d).mkdir()
save(exp/'protocol/preregistered.json',{'config':cfg,'source_hashes':{p.name:digest(p) for p in model.iterdir() if p.is_file()},
'created_utc':datetime.now(timezone.utc).isoformat(),'before_analysis':True})
pre=immutable_check(root,root/cfg['snapshot'],cfg['scope']['snapshot_workers']);save(exp/'regression/preflight.json',pre)
assert pre['pass'],'original bytes differ'
canonical=root/cfg['canonical'];prior=root/cfg['prior'];expect=cfg['expected']
meta=pd.read_parquet(canonical/'neuron-index/unified-metadata.parquet').sort_values('neuron_idx').reset_index(drop=True)
ptr=np.load(canonical/'gpu/csr-indptr.int64.npy',mmap_mode='r');dst=np.load(canonical/'gpu/csr-indices.int32.npy',mmap_mode='r');w=np.load(canonical/'gpu/csr-weights.int64.npy',mmap_mode='r')
assert len(meta)==expect['neurons'] and np.array_equal(meta.neuron_idx,np.arange(len(meta)))
assert str(meta.neuron_idx.dtype)=='int32' and str(meta.body_id.dtype)=='uint64' and meta.body_id.is_unique
assert len(ptr)==len(meta)+1 and ptr[0]==0 and ptr[-1]==len(w)==len(dst)==expect['edges']
assert ptr.dtype==np.int64 and dst.dtype==np.int32 and w.dtype==np.int64
assert int(w.sum())==expect['synapse_count_sum'] and np.all(np.diff(ptr)>=0) and w.min()>0
src=np.repeat(np.arange(len(meta),dtype=np.int32),np.diff(ptr));pops=population(meta)
apl=np.flatnonzero(meta.annotation_type.eq('APL'));kc=np.flatnonzero(meta.annotation_class.eq('Kenyon_Cell'));pn=np.flatnonzero(meta.annotation_class.eq('ALPN'))
assert len(apl)==expect['APL'] and len(kc)==expect['KC']
oi=np.flatnonzero(np.isin(src,apl));ii=np.flatnonzero(np.isin(dst,apl))
outgoing=edge_frame(oi,src,dst,w,meta,pops);incoming=edge_frame(ii,src,dst,w,meta,pops)
outgoing['fast_current_masked']=True;outgoing['graded_output_covered']=np.isin(dst[oi],kc)
incoming['graded_input_used']=np.isin(src[ii],np.r_[kc,pn])
# This describes the graded-state input only. Fast synapses into APL remain in CSR/runtime.
watched=json.loads((prior/'protocol/watched.json').read_text())['all_incoming_ALPNs']
focus=outgoing[outgoing.target_neuron_idx.isin(watched)].copy()
old=pd.read_parquet(prior/'audit/APL-target-coverage.parquet')
fields=['edge_id','source_neuron_idx','target_neuron_idx','raw_synapse_count']
assert np.array_equal(outgoing[fields].sort_values('edge_id').to_numpy(np.int64),old[fields].sort_values('edge_id').to_numpy(np.int64))
nonkc=outgoing[~outgoing.graded_output_covered]
assert (len(outgoing),int(outgoing.raw_synapse_count.sum()),len(nonkc),int(nonkc.raw_synapse_count.sum()),len(focus),int(focus.raw_synapse_count.sum()))==(expect['APL_outgoing_edges'],expect['APL_outgoing_contacts'],expect['non_KC_edges'],expect['non_KC_contacts'],expect['watched_PN_edges'],expect['watched_PN_contacts'])
print('CSR and Phase4Z coverage exact',flush=True)
raw_path=root/'datasets/male-cns-v1.0/raw/connectivity/connectome-weights-male-cns-v1.0-minconf-0.5.feather'
raw=raw_incident(raw_path,meta.iloc[apl].body_id.to_numpy())
valid=raw.body_pre.isin(meta.body_id)&raw.body_post.isin(meta.body_id)
actual=raw.loc[valid].sort_values(['body_pre','body_post']).reset_index(drop=True)
assert not actual.duplicated(['body_pre','body_post']).any()
incident=pd.concat([outgoing,incoming]).drop_duplicates('edge_id')
expected=incident[['source_body_id','target_body_id','raw_synapse_count']].rename(columns={'source_body_id':'body_pre','target_body_id':'body_post','raw_synapse_count':'weight'}).sort_values(['body_pre','body_post']).reset_index(drop=True)
assert np.array_equal(actual.to_numpy(np.int64),expected.to_numpy(np.int64))
raw.to_parquet(exp/'connectivity/raw-APL-incident-including-noncanonical.parquet',index=False)
print('Raw Feather APL incident edges exact',len(actual),flush=True)
outgoing.to_parquet(exp/'connectivity/APL-outgoing.parquet',index=False);incoming.to_parquet(exp/'connectivity/APL-incoming.parquet',index=False)
for label,frame,col in [('output',outgoing,'target_population'),('input',incoming,'source_population')]:
grouped=frame.groupby(col,dropna=False).agg(edges=('edge_id','size'),contacts=('raw_synapse_count','sum')).reset_index()
grouped.to_parquet(exp/'connectivity'/f'APL-{label}-population-summary.parquet',index=False)
grouped.to_csv(exp/'connectivity'/f'APL-{label}-population-summary.csv',index=False)
ignored=incoming[~incoming.graded_input_used]
ignored.to_parquet(exp/'connectivity/graded-input-not-used.parquet',index=False)
pairs=incoming[['source_neuron_idx','target_neuron_idx','raw_synapse_count','edge_id']].rename(columns={'source_neuron_idx':'target_neuron_idx','target_neuron_idx':'source_neuron_idx','raw_synapse_count':'reverse_contacts','edge_id':'reverse_edge_id'})
pn_out=outgoing[outgoing.target_neuron_idx.isin(pn)].merge(pairs,on=['source_neuron_idx','target_neuron_idx'],how='left',validate='one_to_one')
pn_out['has_PN_to_APL']=pn_out.reverse_edge_id.notna()
pn_out['watched_in_Phase4Z']=pn_out.target_neuron_idx.isin(watched)
pn_out.to_parquet(exp/'connectivity/APL-PN-reciprocity.parquet',index=False)
pn_out.to_csv(exp/'connectivity/APL-PN-reciprocity.csv',index=False)
downstream=[]
for node in pn_out.target_neuron_idx.unique():
ids=np.arange(ptr[node],ptr[node+1]);cl=pops[dst[ids]]
for pop in ('Kenyon_Cell','ALLN','APL'):
selected=ids[cl==pop]
downstream.append({'PN_neuron_idx':int(node),'PN_body_id':int(meta.iloc[node].body_id),'PN_type':meta.iloc[node].annotation_type,
'target_population':pop,'edges':len(selected),'contacts':int(w[selected].sum())})
pd.DataFrame(downstream).to_parquet(exp/'connectivity/APL-target-PN-downstream.parquet',index=False)
focus=pn_out[pn_out.watched_in_Phase4Z].copy()
focus[['source_neuron_idx','source_body_id','source_annotation_instance','target_neuron_idx','target_body_id','target_annotation_type','raw_synapse_count','reverse_contacts','reverse_edge_id']].to_csv(exp/'connectivity/watched-PN-reciprocity.csv',index=False)
# Reconstruct the exact frozen matrices on CPU; do not simulate or apply any weights.
inp=np.zeros((len(apl),len(meta)),np.float32);output=np.zeros((len(apl),len(kc)),np.float32)
kmap={int(n):i for i,n in enumerate(kc)};amap={int(n):i for i,n in enumerate(apl)}
for r in incoming[incoming.graded_input_used].itertuples():inp[amap[r.target_neuron_idx],r.source_neuron_idx]+=r.raw_synapse_count
for r in outgoing[outgoing.graded_output_covered].itertuples():output[amap[r.source_neuron_idx],kmap[r.target_neuron_idx]]+=r.raw_synapse_count
input_scale=float(inp[inp>0].sum()/np.count_nonzero(np.any(inp>0,axis=0)));output_scale=float(output[output>0].mean())
coverage={'input_scale':input_scale,'output_scale':output_scale,'input_matrix_shape':list(inp.shape),'output_matrix_shape':list(output.shape),
'KC_targets_with_graded_input':int(np.count_nonzero(np.any(output>0,axis=0))),
'normalized_input_matrix_sha256':hashlib.sha256((inp/input_scale).tobytes()).hexdigest(),
'normalized_output_matrix_sha256':hashlib.sha256((output/output_scale).tobytes()).hexdigest()}
save(exp/'audit/frozen-matrix-reconstruction.json',coverage)
frozen=json.loads((prior/'audit/APL-target-coverage.json').read_text());source=Path(frozen['source'])
assert digest(source)==frozen['source_sha256']
body=source.read_text();tree=ast.parse(body)
cls=next(n for n in tree.body if isinstance(n,ast.ClassDef) and n.name=='DeterministicAPLSim')
with (exp/'audit/frozen-APL-class-source.txt').open('x') as f:f.write(ast.get_source_segment(body,cls)+'\n')
save(exp/'audit/frozen-implementation-provenance.json',{'path':str(source),'sha256':digest(source),'same_as_Phase4Z':True,'models_imported':False})
ids=np.unique(np.r_[apl,pn_out.target_neuron_idx]);meta.iloc[ids].to_parquet(exp/'metadata/APL-and-target-PNs.parquet',index=False)
spatial=pn_out[['edge_id','source_neuron_idx','source_body_id','target_neuron_idx','target_body_id','target_annotation_type','raw_synapse_count']].copy()
for col in ('synapse_location','synapse_ROI','PN_subcellular_target','postsynaptic_GABA_receptor','effective_inhibition_coefficient'):spatial[col]='unknown'
spatial['reason']='Local body-pair counts and SWC centerlines do not contain synapse partner locations or target receptor measurements'
spatial.to_parquet(exp/'spatial/APL-PN-unknowns.parquet',index=False)
swc=[]
for node in np.r_[apl,watched]:
p=Path(meta.iloc[node].swc_path)
a=np.loadtxt(p,comments='#',ndmin=2)
assert a.shape[1]==7 and np.all(np.isfinite(a))
swc.append({'neuron_idx':int(node),'body_id':int(meta.iloc[node].body_id),'path':str(p),'sha256':digest(p),
'nodes':len(a),'columns':int(a.shape[1]),'synaptic_partner_identity_in_standard_SWC':False,
'coordinates_used_to_infer_synapse_locations':False})
save(exp/'spatial/watched-SWC-audit.json',swc)
schemas=[]
for p in sorted((root/'datasets/male-cns-v1.0/raw').glob('*/*.feather')):
with pa.memory_map(str(p),'r') as f:sc=pa.ipc.open_file(f).schema
schemas.append({'path':str(p),'sha256':digest(p),'fields':[{'name':x.name,'dtype':str(x.type)} for x in sc]})
save(exp/'spatial/local-schemas.json',schemas)
save(exp/'external-resources/official-data-access.json',official_head(cfg['scope']['official_network_timeout_s']))
evidence={
'official_definition':{'url':'https://male-cns.janelia.org/download/','dataset':'male-cns:v1.0','license':'CC-BY-4.0',
'license_url':'https://creativecommons.org/licenses/by/4.0/','observation':'Official page specifies paired synapse coordinates/primary_post in syn-partners; local flat weights contain none.',
'required_subset':'All outgoing APL partner records; exact body IDs from metadata; minimum confidence 0.5; include pre/post x/y/z, body IDs and primary_post.',
'no_EM_needed':True,'coordinate_units':'synapse coordinates and original SWC in 8nm voxels; precomputed skeletons have different units'},
'primary_physiology':[
{'doi':'10.7554/eLife.74172','url':'https://elifesciences.org/articles/74172','claim':'Local APL inhibition at PN boutons and KC dendritic claws was studied; no edge-specific MaleCNS coefficient follows.'},
{'doi':'10.7554/eLife.56954','url':'https://pmc.ncbi.nlm.nih.gov/articles/PMC7541083/','claim':'APL activity/inhibition can be spatially localized; global point-neuron inhibition is a modeling assumption.'}],
'google_research':{'url':'https://www.research.google/blog/a-connectomics-milestone-mapping-the-complete-male-fruit-fly-brain/',
'role':'Primary project provenance, not evidence of associative-learning performance'},
'access_choices':['Authorized neuPrint male-cns:v1.0 targeted query, requiring user-configured API token',
'Explicitly approved official syn-partners bulk download into a NEW external-reference directory'],
'not_attempted':['bulk synapse download','EM download','credential discovery','unauthenticated query bypass','new dynamics','GPU regression']}
save(exp/'external-resources/evidence-and-limitations.json',evidence)
results={'phase':'4AA','status':'PASS-STATIC-SCOPE-AUDIT / BLOCKED-SPATIAL-PHYSIOLOGY','candidate':False,
'neurons':len(meta),'graph_edges':len(w),'synapse_count_sum':int(w.sum()),'APL_neurons':len(apl),'KC_neurons':len(kc),'ALPN_neurons':len(pn),
'APL_outgoing_edges':len(outgoing),'APL_outgoing_contacts':int(outgoing.raw_synapse_count.sum()),
'non_KC_uncovered_edges':len(nonkc),'non_KC_uncovered_contacts':int(nonkc.raw_synapse_count.sum()),'non_KC_uncovered_targets':int(nonkc.target_neuron_idx.nunique()),
'APL_to_PN_edges':len(pn_out),'APL_to_PN_contacts':int(pn_out.raw_synapse_count.sum()),'APL_target_PNs':int(pn_out.target_neuron_idx.nunique()),
'APL_PN_pairs_with_reverse_edge':int(pn_out.has_PN_to_APL.sum()),'watched_PN_contacts':int(focus.raw_synapse_count.sum()),
'APL_incoming_edges':len(incoming),'APL_incoming_contacts':int(incoming.raw_synapse_count.sum()),
'incoming_edges_not_used_by_graded_state':len(ignored),'incoming_contacts_not_used_by_graded_state':int(ignored.raw_synapse_count.sum()),
'raw_APL_incident_canonical_edges_checked':len(actual),'raw_APL_incident_noncanonical_rows':int((~valid).sum()),
'raw_to_CSR_exact':True,'Phase4Z_static_coverage_exact':True,'APL_PN_pairs_with_confirmed_local_synapse_ROI':0,
'APL_PN_pairs_with_confirmed_subcellular_target':0,'whole_cell_inhibition_repair_authorized_by_evidence':False,
'new_simulation':False,'new_scientific_regression_run':False,'old_reference_files_rehashed':True,
'weights_changed':False,'gpu_used':False,'ComfyUI_models_unloaded':False,'top_level_gates_passed':5,'top_level_gates_total':10}
post=immutable_check(root,root/cfg['snapshot'],cfg['scope']['snapshot_workers']);save(exp/'regression/postflight.json',post);assert post['pass']
results['frozen_integrity_pass']=post['pass'];save(exp/'audit/results.json',results)
save(exp/'performance/resources.json',{'wall_seconds':time.perf_counter()-start,'max_RSS_KiB':resource.getrusage(resource.RUSAGE_SELF).ru_maxrss,'gpu_used':False,'includes_two_full_integrity_scans':True})
print(json.dumps(results,indent=2),flush=True)
if __name__=='__main__':
ap=argparse.ArgumentParser();ap.add_argument('--config',type=Path,required=True);args=ap.parse_args()
run(yaml.safe_load(args.config.read_text()))
@@ -0,0 +1,31 @@
phase: 4AA
name: APL-PN-SCOPE-AUDIT
root: /data/digital-drosophila
model_root: /data/digital-drosophila/models/male-cns-lif/apl-pn-scope-audit-v1
experiment_root: /data/digital-drosophila/experiments/phase4aa-apl-pn-scope
canonical: datasets/male-cns-v1.0/processed/neuron-only
prior: experiments/phase4z-pn-feedback-audit
snapshot: registry/snapshots/bootstrap-20260929
expected:
neurons: 166700
edges: 25582938
synapse_count_sum: 124177617
APL: 2
KC: 4064
APL_outgoing_edges: 5845
APL_outgoing_contacts: 209912
non_KC_edges: 1212
non_KC_contacts: 13712
watched_PN_edges: 7
watched_PN_contacts: 247
scope:
cpu_only: true
new_simulation: false
conditioning: false
parameter_changes: false
sign_changes: false
learned_candidate: false
bulk_data_download: false
new_spatial_positions_inferred_from_skeletons: false
snapshot_workers: 4
official_network_timeout_s: 30
@@ -0,0 +1,12 @@
b87a601d869f0a4cf7f88ccb2b7f5592b22da25d11d3e5bfb1be4bba05c079c0 LOCALIZATION-PROTOCOL.md
e88f765be0fd91178eed1d862b1de8d8b307ba5ec3cc0ae0d0d93202f264acce PROTOCOL.md
fa0bfd5a163a436e061c94e37cf6fe84ca75fdfa94d6f20ce85eda5058ca9ce7 REPORT.md
4ef071ba88f4e1cd78f068be58414dd7f4099dfac69c68266c4f46e175eab9fb audit.py
e0171bbd7dc7e693268eac00152e560e841f885c7d524c74d51fda7f7fbadbbf audit.yaml
23db504ac8f31c62a434b24506cbe8456e2993e923bae4c89040cc6a1d8d06f7 fetch_syn_partners.py
ae203b77c011d01ab8fb1cc76fcf4b0223a71e309d6995445fc7f33ce22a2f06 finalize.py
aca6c69399538a41bc9148f2c837f0546e8a39d6b2b833585b9c55e53fa8414b localize.py
554e9378e068fb13abb4f08dbf9ea710228fa535da2442edb913261fa22fcb20 regression.py
238506a18fb81d544480c815d2517589e5b9d8c1932e86a5fe163a1b2955f712 regression_retry.py
cb67bab972195090d5c4188169982abdc960479b8031477f1f39ac445814e88f test_audit.py
732dcfe1a9c807356f7664393f6678743c61e3fe38a915ca0ce3f00ee7b17d9a validate_localization.py
@@ -0,0 +1,49 @@
"""User-authorized official additional reference download. Never writes raw."""
import base64
import hashlib
import json
from pathlib import Path
import subprocess
import time
import urllib.parse
import urllib.request
from audit import save
ROOT=Path('/data/digital-drosophila')
OUT=ROOT/'experiments/phase4aa-apl-pn-scope/external-resources/synaptic-partners'
NAME='syn-partners-male-cns-v1.0-minconf-0.5.feather'
OBJECT='v1.0/connectome-data/flat-connectome/'+NAME
META='https://storage.googleapis.com/storage/v1/b/flyem-male-cns/o/'+urllib.parse.quote(OBJECT,safe='')
def main():
OUT.mkdir(parents=True,exist_ok=True)
with urllib.request.urlopen(META,timeout=30) as r:meta=json.load(r)
assert meta['name']==OBJECT and int(meta['size'])==6777179098
assert meta['generation']=='1780494942562468','Stop on an unexpected upstream revision'
md5=base64.b64decode(meta['md5Hash']).hex()
if (OUT/'upstream-object.json').exists():
prior=json.loads((OUT/'upstream-object.json').read_text())
assert all(prior[k]==meta[k] for k in ('name','generation','size','md5Hash'))
else:save(OUT/'upstream-object.json',meta)
url='https://storage.googleapis.com/flyem-male-cns/'+OBJECT+'?generation='+meta['generation']
if not (OUT/'authorization-and-source.json').exists():
save(OUT/'authorization-and-source.json',{'user_authorized_additional_download':True,'new_reference_only':True,
'source_page':'https://male-cns.janelia.org/download/','url':url,'metadata_url':META,
'dataset':'male-cns:v1.0','license':'CC-BY-4.0','EM_downloaded':False,
'raw_modified':False,'retrieved_utc':time.strftime('%Y-%m-%dT%H:%M:%SZ',time.gmtime())})
cmd=['aria2c','--continue=true','--max-connection-per-server=8','--split=8','--min-split-size=16M',
'--max-tries=8','--retry-wait=5','--connect-timeout=30','--timeout=60','--auto-file-renaming=false',
'--allow-overwrite=false','--check-integrity=true','--file-allocation=none','--summary-interval=20',
'--enable-color=false','--console-log-level=warn','--checksum=md5='+md5,'--dir='+str(OUT),'--out='+NAME,url]
begin=time.perf_counter();subprocess.run(cmd,check=True)
file=OUT/NAME;hs=hashlib.sha256();hm=hashlib.md5()
with file.open('rb') as f:
for b in iter(lambda:f.read(8<<20),b''):hs.update(b);hm.update(b)
result={'bytes':file.stat().st_size,'sha256':hs.hexdigest(),'md5':hm.hexdigest(),'official_md5':md5,
'generation':meta['generation'],'download_and_verification_seconds':time.perf_counter()-begin,
'pass':file.stat().st_size==int(meta['size']) and hm.hexdigest()==md5,'path':str(file)}
assert result['pass'],'Official MD5/size mismatch; retain file and stop'
if not (OUT/'download-verification.json').exists():save(OUT/'download-verification.json',result)
print(json.dumps(result),flush=True)
if __name__=='__main__':main()
@@ -0,0 +1,51 @@
"""Seal only this newly created audit and copy small evidence into Git registry."""
import json
from pathlib import Path
import shutil
import time
from audit import save,digest,seal,immutable_check
ROOT=Path('/data/digital-drosophila');MODEL=ROOT/'models/male-cns-lif/apl-pn-scope-audit-v1';EXP=ROOT/'experiments/phase4aa-apl-pn-scope'
def main():
assert not (EXP/'manifest.json').exists() and not (MODEL/'manifest.json').exists(),'Already sealed'
static=json.loads((EXP/'audit/results.json').read_text())
local=json.loads((EXP/'localization/summary.json').read_text())
pairs=json.loads((EXP/'localization/complete-pair-set-validation.json').read_text())
gpu=json.loads((EXP/'retry-with-correct-PATH/gpu-frozen-regression/summary.json').read_text())
external=json.loads((EXP/'external-resources/synaptic-partners/download-verification.json').read_text())
assert static['frozen_integrity_pass'] and local['pass'] and pairs['pass'] and gpu['pass'] and external['pass']
post=immutable_check(ROOT,ROOT/'registry/snapshots/bootstrap-20260929',4)
save(EXP/'regression/final-old-files-integrity.json',post);assert post['pass']
result={'phase':'4AA','status':'PASS-APL-PN-ANATOMICAL-LOCALIZATION / NO-DYNAMICS-CANDIDATE',
'candidate':False,'previous_static_spatial_block_resolved_by_user_authorized_reference_data':True,
'old_static_audit_retained_without_overwrite':True,'canonical_neurons':166700,'canonical_edges':25582938,
'APL_PN_edges':268,'APL_target_PNs':259,'APL_PN_contacts':4600,'calyx_contacts':3820,
'calyx_fraction':3820/4600,'ROI_unspecified_contacts':731,'other_ROI_contacts':49,
'watched_PN_contacts':247,'watched_calyx_contacts':228,'watched_unspecified_contacts':19,
'complete_pair_checks':pairs,'frozen_trials_pass':gpu['pass'],'frozen_trials_count':len(gpu['trials']),
'old_scientific_files_verified':post['checked'],'old_file_integrity_pass':post['pass'],
'external_MD5_pass':external['pass'],'external_SHA256':external['sha256'],
'brain_dynamics_changed':False,'training':False,'receptor_or_terminal_gain_calibrated':False,
'bouton_identity_confirmed':False,'ComfyUI_stopped_or_unloaded':False,'top_level_gate_fraction':'5/10',
'failures_preserved':['initial experiment-directory permission before any output','first GPU build lookup of Ninja failed before simulation','first aria2 checksum argument invalid before download'],
'finalized_utc':time.strftime('%Y-%m-%dT%H:%M:%SZ',time.gmtime())}
save(EXP/'audit/final-summary.json',result)
with (MODEL/'REPORT.md').open('rb') as src,(EXP/'REPORT.md').open('xb') as dst:shutil.copyfileobj(src,dst)
model_count=seal(MODEL);experiment_count=seal(EXP)
verified=[]
for base in (MODEL,EXP):
manifest=json.loads((base/'manifest.json').read_text());bad=[r['path'] for r in manifest['files'] if digest(base/r['path'])!=r['sha256']]
assert not bad;verified.append({'path':str(base),'files':len(manifest['files']),'pass':not bad})
registry=ROOT/'registry/phase4aa-apl-pn-scope';registry.mkdir(exist_ok=False)
records=[]
for p in sorted(EXP.rglob('*')):
if not p.is_file() or p.suffix not in ('.json','.csv','.md','.sha256') or p.stat().st_size>2*1024**2: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)
records.append({'original_path':str(p.relative_to(ROOT)),'copy_path':str(dst.relative_to(registry)),'sha256':digest(p),'bytes':p.stat().st_size})
save(registry/'evidence-index.json',records);save(registry/'seal-verification.json',verified)
doc=ROOT/'docs/progress/phase4aa-apl-pn-scope.md';doc.parent.mkdir(parents=True,exist_ok=True)
with (MODEL/'REPORT.md').open('rb') as src,doc.open('xb') as dst:shutil.copyfileobj(src,dst)
print(json.dumps({'result':result['status'],'model_files':model_count,'experiment_files':experiment_count,'evidence_copies':len(records),'all_seals_pass':True}),flush=True)
if __name__=='__main__':main()
@@ -0,0 +1,112 @@
"""Official paired-synapse localization; numerical counts must reconcile to CSR."""
from pathlib import Path
import hashlib
import json
import time
import numpy as np
import pandas as pd
import pyarrow as pa
import pyarrow.compute as pc
from scipy.spatial import cKDTree
from audit import save,digest
ROOT=Path('/data/digital-drosophila');EXP=ROOT/'experiments/phase4aa-apl-pn-scope'
def main():
pa.set_cpu_count(4);pa.set_io_thread_count(4);start=time.perf_counter()
out=EXP/'localization';out.mkdir(exist_ok=False)
official=EXP/'external-resources/synaptic-partners'
verified=json.loads((official/'download-verification.json').read_text());assert verified['pass']
path=Path(verified['path']);assert path.stat().st_size==verified['bytes']
source_hash=digest(path);assert source_hash==verified['sha256']
save(out/'protocol.json',{'source_sha256':source_hash,'source_generation':verified['generation'],
'source_script_sha256':digest(Path(__file__)),'protocol_sha256':digest(Path(__file__).with_name('LOCALIZATION-PROTOCOL.md')),
'coordinate_unit_nm':8,'distance_to_microns_multiplier':0.008,
'nearest_neighbor_is_not_bouton_or_functional_identity':True,'before_analysis':True})
canonical=ROOT/'datasets/male-cns-v1.0/processed/neuron-only'
m=pd.read_parquet(canonical/'neuron-index/unified-metadata.parquet').sort_values('neuron_idx').reset_index(drop=True)
ptr=np.load(canonical/'gpu/csr-indptr.int64.npy',mmap_mode='r');dst=np.load(canonical/'gpu/csr-indices.int32.npy',mmap_mode='r');w=np.load(canonical/'gpu/csr-weights.int64.npy',mmap_mode='r')
body=m.body_id.to_numpy();apl=body[m.annotation_type.eq('APL')];kc=body[m.annotation_class.eq('Kenyon_Cell')];alln=body[m.annotation_class.eq('ALLN')]
pnpairs=pd.read_parquet(EXP/'connectivity/APL-PN-reciprocity.parquet');pn=pnpairs.target_body_id.unique()
watchidx=json.loads((ROOT/'experiments/phase4z-pn-feedback-audit/protocol/watched.json').read_text())['all_incoming_ALPNs']
watch=body[watchidx]
groups={k:[] for k in ('APL-incident','APL-target-PN-to-KC','watched-PN-to-ALLN','ALLN-to-watched-PN')}
sets={name:pa.array(arr.astype(np.int64)) for name,arr in [('APL',apl),('KC',kc),('ALLN',alln),('PN',pn),('watched',watch)]}
total=0
with pa.memory_map(str(path),'r') as f:
reader=pa.ipc.open_file(f);names=reader.schema.names
required=['x_pre','y_pre','z_pre','body_pre','conf_pre','x_post','y_post','z_post','body_post','conf_post','primary_post']
save(out/'actual-schema.json',{'fields':[{'name':x.name,'dtype':str(x.type)} for x in reader.schema],'record_batches':reader.num_record_batches})
assert set(required).issubset(names),names
for i in range(reader.num_record_batches):
batch=reader.get_batch(i);total+=len(batch)
pre=batch.column(names.index('body_pre'));post=batch.column(names.index('body_post'))
masks={
'APL-incident':pc.or_(pc.is_in(pre,value_set=sets['APL']),pc.is_in(post,value_set=sets['APL'])),
'APL-target-PN-to-KC':pc.and_(pc.is_in(pre,value_set=sets['PN']),pc.is_in(post,value_set=sets['KC'])),
'watched-PN-to-ALLN':pc.and_(pc.is_in(pre,value_set=sets['watched']),pc.is_in(post,value_set=sets['ALLN'])),
'ALLN-to-watched-PN':pc.and_(pc.is_in(pre,value_set=sets['ALLN']),pc.is_in(post,value_set=sets['watched']))}
for name,mask in masks.items():
sub=batch.filter(mask)
if len(sub):groups[name].append(pa.Table.from_batches([sub]))
if (i+1)%500==0:print('streamed_batches',i+1,'rows',total,flush=True)
lookup=pd.Series(m.neuron_idx.to_numpy(),index=body)
dfs={};checks=[]
keys=['body_pre','x_pre','y_pre','z_pre','body_post','x_post','y_post','z_post']
for name,tables in groups.items():
a=pa.concat_tables(tables).to_pandas();assert not a.duplicated(keys).any(),name+' duplicate partner row'
a['source_neuron_idx']=a.body_pre.map(lookup);a['target_neuron_idx']=a.body_post.map(lookup)
canonical_rows=a.source_neuron_idx.notna()&a.target_neuron_idx.notna()
pairs=a.loc[canonical_rows].groupby(['source_neuron_idx','target_neuron_idx']).size()
problems=[]
for (s,t),count in pairs.items():
s,t=int(s),int(t);eid=np.arange(ptr[s],ptr[s+1]);found=eid[dst[eid]==t]
if len(found)!=1 or int(w[found[0]])!=count:problems.append({'source':s,'target':t,'actual_partner_count':int(count),'CSR_weight':int(w[found[0]]) if len(found)==1 else None})
result={'group':name,'rows':len(a),'canonical_rows':int(canonical_rows.sum()),'canonical_pairs':len(pairs),'duplicate_partner_rows':0,'mismatches':problems,'pass':not problems}
checks.append(result);save(out/(name+'-count-check.json'),result);assert result['pass'],name+' count mismatch'
a.to_parquet(out/(name+'.parquet'),index=False);dfs[name]=a
print(json.dumps(result),flush=True)
a=dfs['APL-incident'];forward=a[a.body_pre.isin(apl)&a.body_post.isin(pn)].copy();reverse=a[a.body_pre.isin(pn)&a.body_post.isin(apl)].copy()
assert len(forward)==int(pnpairs.raw_synapse_count.sum())==4600
frames={'APL-to-PN':forward,'PN-to-APL':reverse,'PN-to-KC':dfs['APL-target-PN-to-KC'],
'watched-PN-to-ALLN':dfs['watched-PN-to-ALLN'],'ALLN-to-watched-PN':dfs['ALLN-to-watched-PN']}
roi_rows=[];pair_rows=[]
for name,frame in frames.items():
for roi,g in frame.groupby('primary_post',dropna=False,observed=True):
roi_rows.append({'group':name,'primary_post':str(roi),'contacts':len(g),'fraction':len(g)/len(frame),'source_bodies':g.body_pre.nunique(),'target_bodies':g.body_post.nunique()})
for (pre,post,roi),g in frame.groupby(['body_pre','body_post','primary_post'],dropna=False,observed=True):
pair_rows.append({'group':name,'body_pre':int(pre),'body_post':int(post),'primary_post':str(roi),'contacts':len(g)})
rois=pd.DataFrame(roi_rows);rois.to_csv(out/'population-ROI-summary.csv',index=False);rois.to_parquet(out/'population-ROI-summary.parquet',index=False)
pd.DataFrame(pair_rows).to_parquet(out/'pair-ROI-counts.parquet',index=False)
# Neuropil annotation is a location label, not evidence for receptor or inhibitory coefficient.
distances=[];pnkc=dfs['APL-target-PN-to-KC']
for b,g in forward.groupby('body_post'):
q=pnkc[pnkc.body_pre==b]
if len(q):
sites=q[['x_pre','y_pre','z_pre']].drop_duplicates().to_numpy(np.float64)
query=g[['x_post','y_post','z_post']].to_numpy(np.float64)
dist=cKDTree(sites).query(query,workers=1)[0]*0.008
distances.append({'PN_body_id':int(b),'PN_neuron_idx':int(lookup.loc[b]),'APL_postsynaptic_contacts':len(g),'PN_to_KC_unique_presynaptic_sites':len(sites),
'nearest_distance_microns_min':float(dist.min()),'nearest_distance_microns_median':float(np.median(dist)),
'nearest_distance_microns_p95':float(np.quantile(dist,.95)),'nearest_distance_microns_max':float(dist.max()),
'bouton_identity_confirmed':False,'watched':int(lookup.loc[b]) in watchidx})
else:distances.append({'PN_body_id':int(b),'PN_neuron_idx':int(lookup.loc[b]),'APL_postsynaptic_contacts':len(g),'PN_to_KC_unique_presynaptic_sites':0,
'bouton_identity_confirmed':False,'watched':int(lookup.loc[b]) in watchidx})
pd.DataFrame(distances).to_csv(out/'spatial-neighborhoods.csv',index=False)
watched_rows=[]
for node in watchidx:
b=body[node];row={'neuron_idx':node,'body_id':int(b),'type':str(m.iloc[node].annotation_type)}
for name,frame in frames.items():
sub=frame[frame.body_post==b] if name in ('APL-to-PN','ALLN-to-watched-PN') else frame[frame.body_pre==b]
row[name]={str(k):int(v) for k,v in sub.groupby('primary_post',observed=True).size().items()}
watched_rows.append(row)
save(out/'watched-PN-ROI.json',watched_rows)
summary={'pass':all(x['pass'] for x in checks),'source_sha256':source_hash,'full_source_rows_streamed':total,
'groups':checks,'APL_to_PN_contacts_localized':len(forward),'APL_to_PN_pairs_localized':len(pnpairs),
'APL_target_PNs_localized':int(forward.body_post.nunique()),'ROI_counts':rois.to_dict('records'),
'spatial_location_from_official_partners':True,'bouton_identity_confirmed':False,'target_receptor_confirmed':False,
'terminal_inhibition_coefficient_known':False,'new_dynamics':False,'whole_brain_functional_intervention_run':False,
'wall_seconds':time.perf_counter()-start}
save(out/'summary.json',summary);print(json.dumps(summary),flush=True)
if __name__=='__main__':main()
@@ -0,0 +1,65 @@
{
"created_utc": "2026-09-29T15:56:36.952596+00:00",
"files": [
{
"bytes": 1607,
"path": "LOCALIZATION-PROTOCOL.md",
"sha256": "b87a601d869f0a4cf7f88ccb2b7f5592b22da25d11d3e5bfb1be4bba05c079c0"
},
{
"bytes": 2468,
"path": "PROTOCOL.md",
"sha256": "e88f765be0fd91178eed1d862b1de8d8b307ba5ec3cc0ae0d0d93202f264acce"
},
{
"bytes": 7290,
"path": "REPORT.md",
"sha256": "fa0bfd5a163a436e061c94e37cf6fe84ca75fdfa94d6f20ce85eda5058ca9ce7"
},
{
"bytes": 18939,
"path": "audit.py",
"sha256": "4ef071ba88f4e1cd78f068be58414dd7f4099dfac69c68266c4f46e175eab9fb"
},
{
"bytes": 906,
"path": "audit.yaml",
"sha256": "e0171bbd7dc7e693268eac00152e560e841f885c7d524c74d51fda7f7fbadbbf"
},
{
"bytes": 2939,
"path": "fetch_syn_partners.py",
"sha256": "23db504ac8f31c62a434b24506cbe8456e2993e923bae4c89040cc6a1d8d06f7"
},
{
"bytes": 4144,
"path": "finalize.py",
"sha256": "ae203b77c011d01ab8fb1cc76fcf4b0223a71e309d6995445fc7f33ce22a2f06"
},
{
"bytes": 8867,
"path": "localize.py",
"sha256": "aca6c69399538a41bc9148f2c837f0546e8a39d6b2b833585b9c55e53fa8414b"
},
{
"bytes": 4455,
"path": "regression.py",
"sha256": "554e9378e068fb13abb4f08dbf9ea710228fa535da2442edb913261fa22fcb20"
},
{
"bytes": 394,
"path": "regression_retry.py",
"sha256": "238506a18fb81d544480c815d2517589e5b9d8c1932e86a5fe163a1b2955f712"
},
{
"bytes": 1520,
"path": "test_audit.py",
"sha256": "cb67bab972195090d5c4188169982abdc960479b8031477f1f39ac445814e88f"
},
{
"bytes": 2229,
"path": "validate_localization.py",
"sha256": "732dcfe1a9c807356f7664393f6678743c61e3fe38a915ca0ce3f00ee7b17d9a"
}
]
}
@@ -0,0 +1,72 @@
"""Supplement: existing five frozen trials on 4090, new output paths only."""
import json
import os
from pathlib import Path
import sys
import time
import urllib.request
import numpy as np
import pandas as pd
import yaml
ROOT=Path('/data/digital-drosophila')
MODEL=ROOT/'models/male-cns-lif/apl-pn-scope-audit-v1'
EXP=ROOT/'experiments/phase4aa-apl-pn-scope'
sys.path.insert(0,str(MODEL))
from audit import save,digest,immutable_check
def queues():
result=[]
for port in (8188,8189,8190):
with urllib.request.urlopen(f'http://192.168.10.51:{port}/queue',timeout=5) as r:q=json.load(r)
result.append({'port':port,'running':len(q.get('queue_running',[])),'pending':len(q.get('queue_pending',[]))})
return result
def main():
out=EXP/'gpu-frozen-regression';out.mkdir(exist_ok=False)
q=queues();assert all(x['running']==0 and x['pending']==0 for x in q),'ComfyUI busy; defer'
runtime=ROOT/'models/male-cns-lif/deterministic-runtime-v2'
cfg=yaml.safe_load((runtime/'phase4p.yaml').read_text())
os.environ['CUDA_VISIBLE_DEVICES']=cfg['device']['visible_gpu_uuid']
os.environ['TORCH_CUDA_ARCH_LIST']='8.9'
os.environ['CUDA_HOME']='/usr/local/cuda'
os.environ['MAX_JOBS']='2'
os.environ['PYTHONDONTWRITEBYTECODE']='1'
sys.path.insert(0,str(ROOT/'models/male-cns-lif'))
sys.path.insert(0,str(runtime))
import torch
import phase4p
free,total=torch.cuda.mem_get_info();assert free>2*1024**3,'Insufficient free VRAM; no service eviction'
save(out/'protocol-addendum.json',{'scope':'Five frozen reference v2 trials only; supplement to CPU structural audit',
'reason':'User confirmed ComfyUI is not in use; baseline behavior check before any future mechanism intervention',
'new_mechanism_or_training':False,'ComfyUI_queues':q,'available_vram_bytes':free,
'reference':'experiments/phase4p-deterministic-runtime/phase4c-v2/reference',
'historical_files_overwritten':False,'source_sha256':digest(Path(__file__)),
'runtime_sha256':digest(runtime/'phase4p.py'),'config_sha256':digest(runtime/'phase4p.yaml')})
torch.cuda.reset_peak_memory_stats();start=time.perf_counter();rt=phase4p.CanonicalRuntime(cfg,runtime,out)
rows=[]
for spec in cfg['reference_trials']:
q=queues();assert all(x['running']==0 and x['pending']==0 for x in q),'ComfyUI work arrived; stop between trials'
ref=ROOT/'experiments/phase4p-deterministic-runtime/phase4c-v2/reference'/spec['name']
events=pd.read_parquet(ref/'spike-events.parquet')
expected={'step':events.step.to_numpy(),'neuron_idx':events.neuron_idx.to_numpy(),
'counts':np.load(ref/'per-neuron-spike-counts.int32.npy'),'v':np.load(ref/'final-voltage.float32.npy'),'g':np.load(ref/'final-g.float32.npy')}
result=rt.run(np.flatnonzero(rt.pops[spec['population']]),spec['rate_hz'],spec['seed'],spec['duration_ms'])
exact={k:bool(np.array_equal(result[k],v)) for k,v in expected.items()}
finite=bool(np.isfinite(result['v']).all() and np.isfinite(result['g']).all())
row={'trial':spec['name'],'exact':exact,'finite':finite,'pass':all(exact.values()) and finite,
'wall_seconds':result['metrics']['wall_seconds'],'events':len(result['step']),
'events_sha256':phase4p.sha_bytes(result['step'],result['neuron_idx']),
'max_abs_V_error':float(np.max(np.abs(result['v'].astype(float)-expected['v']))),
'max_abs_g_error':float(np.max(np.abs(result['g'].astype(float)-expected['g'])))}
save(out/(spec['name']+'.json'),row);rows.append(row);print(json.dumps(row),flush=True)
assert row['pass'],'Frozen regression diverged'
save(out/'summary.json',{'pass':all(r['pass'] for r in rows),'trials':rows,'total_wall_seconds_including_build':time.perf_counter()-start,
'peak_allocated_VRAM_bytes':int(torch.cuda.max_memory_allocated()),'device':torch.cuda.get_device_name(),
'ComfyUI_models_unloaded':False,'new_dynamics':False,'original_reference_v1_not_overwritten':True,
'oracle':'deterministic v2 / original v1 preserved; not claiming v1 atomic runtime is deterministic'})
# No old scientific artifact may change even after imports/build/run.
post=immutable_check(ROOT,ROOT/'registry/snapshots/bootstrap-20260929',4)
save(out/'post-regression-integrity.json',post);assert post['pass']
if __name__=='__main__':main()
@@ -0,0 +1,10 @@
"""Retry regression with the existing venv/toolkit executables on PATH; no install."""
from pathlib import Path
import os
import regression
root=Path('/data/digital-drosophila')
os.environ['PATH']=str(root/'models/male-cns-lif/.venv/bin')+':/usr/local/cuda/bin:'+os.environ['PATH']
regression.EXP=regression.EXP/'retry-with-correct-PATH'
regression.EXP.mkdir(exist_ok=False)
regression.main()
@@ -0,0 +1,29 @@
import tempfile
from pathlib import Path
import unittest
import numpy as np
import pandas as pd
import pyarrow as pa
import pyarrow.feather as feather
from audit import raw_incident,population,save
class AuditTests(unittest.TestCase):
def test_raw_incident_union_keeps_self_loop_once(self):
with tempfile.TemporaryDirectory(prefix='apl-scope-test-') as d:
p=Path(d)/'raw.feather'
frame=pd.DataFrame({'body_pre':[10,10,20,40],'body_post':[10,30,10,50],'weight':[1,2,3,4]},dtype=np.int64)
feather.write_feather(pa.Table.from_pandas(frame,preserve_index=False),p,chunksize=2)
result=raw_incident(p,np.array([10],np.uint64))
self.assertTrue(np.array_equal(result.to_numpy(),frame.iloc[:3].to_numpy()))
with self.assertRaises(AssertionError):
feather.write_feather(pa.table({'body_pre':[10],'wrong':[30],'weight':[1]}),p)
raw_incident(p,np.array([10],np.uint64))
def test_population_does_not_equate_dopamine_to_DAN(self):
m=pd.DataFrame({'annotation_class':[None,None,'ALPN','DAN'], 'annotation_type':['APL','DPM','VA6_adPN','PAM01']})
self.assertEqual(list(population(m)),['APL','DPM','ALPN','DAN'])
def test_exclusive_output(self):
with tempfile.TemporaryDirectory(prefix='apl-scope-test-') as d:
p=Path(d)/'x.json';save(p,{'original':True})
with self.assertRaises(FileExistsError):save(p,{'original':False})
if __name__=='__main__':unittest.main()
@@ -0,0 +1,34 @@
"""Independent complete-pair-set and weight check (including entirely missing pairs)."""
from pathlib import Path
import json
import numpy as np
import pandas as pd
from audit import save
ROOT=Path('/data/digital-drosophila');EXP=ROOT/'experiments/phase4aa-apl-pn-scope'
c=ROOT/'datasets/male-cns-v1.0/processed/neuron-only'
m=pd.read_parquet(c/'neuron-index/unified-metadata.parquet').sort_values('neuron_idx').reset_index(drop=True)
ptr=np.load(c/'gpu/csr-indptr.int64.npy',mmap_mode='r');dst=np.load(c/'gpu/csr-indices.int32.npy',mmap_mode='r');w=np.load(c/'gpu/csr-weights.int64.npy',mmap_mode='r')
src=np.repeat(np.arange(len(m),dtype=np.int32),np.diff(ptr))
apl=np.flatnonzero(m.annotation_type.eq('APL'));kc=np.flatnonzero(m.annotation_class.eq('Kenyon_Cell'));alln=np.flatnonzero(m.annotation_class.eq('ALLN'))
pn=pd.read_parquet(EXP/'connectivity/APL-PN-reciprocity.parquet').target_neuron_idx.unique()
watch=json.loads((ROOT/'experiments/phase4z-pn-feedback-audit/protocol/watched.json').read_text())['all_incoming_ALPNs']
selectors={
'APL-incident':np.isin(src,apl)|np.isin(dst,apl),
'APL-target-PN-to-KC':np.isin(src,pn)&np.isin(dst,kc),
'watched-PN-to-ALLN':np.isin(src,watch)&np.isin(dst,alln),
'ALLN-to-watched-PN':np.isin(src,alln)&np.isin(dst,watch)}
results=[]
for name,mask in selectors.items():
frame=pd.read_parquet(EXP/'localization'/(name+'.parquet'))
frame=frame[frame.source_neuron_idx.notna()&frame.target_neuron_idx.notna()]
counts=frame.groupby(['source_neuron_idx','target_neuron_idx']).size().reset_index(name='weight')
actual=counts.to_numpy(np.int64)
ids=np.flatnonzero(mask)
expected=np.column_stack((src[ids],dst[ids],w[ids])).astype(np.int64)
actual=actual[np.lexsort((actual[:,1],actual[:,0]))];expected=expected[np.lexsort((expected[:,1],expected[:,0]))]
passed=np.array_equal(actual,expected)
results.append({'group':name,'expected_CSR_pairs':len(expected),'observed_pairs':len(actual),'complete_pair_set_and_weight_exact':passed})
assert passed,name
save(EXP/'localization/complete-pair-set-validation.json',{'pass':all(r['complete_pair_set_and_weight_exact'] for r in results),'groups':results})
print(json.dumps(results,indent=2))