Virtual Embryo Challenge更新于 10-03 21:49(北京时间) / 每 5 分钟更新

总览 · ← 返回运行 20261003-171955-search-t2-embryo-interp-chain-12h

节点 n40

DETR+DETRX:按共有类型把检出率向几何插值 p_a^(1−t)·p_b^t 做 OFF-only 置零(s=2.0),单侧独有类型用共有类型的逐基因检出漂移作代理置零(s=0.7),叠加在父幅度收缩之上;PLAN 的 SPATGATE 空间门控经 7 配置证否。

运行?一次完整的自动搜索或 Agent 会话,有自己的锁定配置和证据包。20261003-171955-search-t2-embryo-interp-chain-12h
父节点n38
子节点n42
操作?种子:人写的起点;改进:在父节点上改;草稿:从头写;修复:修父节点的报错。改进
状态已打分
分数搜索目标分 64.69(+1.1) · proxy 64.69(+1.1) · 3 次复测均分 64.16
审查通过 1 越界读取:未发现问题。所有文件访问均相对 --data 视图(run.py:807 tf_regulons、run.py:919 prior/*.gmt 均在 view_manifest.json 的 prior 清单内;阶段数据经 view_io.read_stage 读 manifest['inputs']),无绝对路径、'..'、/mnt、打分器路径,无联网代码(无 http/urllib/socket)。; 2 硬编码目标统计量:未发现问题。检出率 p_a/p_b、漂移 d_g、DE 支持集(|δ|≥0.25 且 |dp|≥0.3)、细胞数 n、t 均在运行时从括号输入现场计算(…
用时?从运行开始到结束(或到现在)的挂钟时间。45 分
程序版本1073fb42d0745b90f581a1c1fab4c1a65f69b83e (programs.git)

方法说明?节点程序自带的 METHOD.md:这个程序做了什么、为什么。

来自 programs.git 1073fb42d0:solution/METHOD.md

DETR+DETRX:按共有类型把检出率向几何插值 p_a^(1−t)·p_b^t 做 OFF-only 置零(s=2.0),单侧独有类型用共有类型的逐基因检出漂移作代理置零(s=0.7),叠加在父幅度收缩之上;PLAN 的 SPATGATE 空间门控经 7 配置证否。

节点

  • family_id: T2EI-01;op: improve;parent: node 38(A 半 3 种子 62.74/62.35/62.84,均值 62.64;官方分 63.60)。
  • 靶弱项(来自父 ANALYSIS):cell_state 最弱(variogram skill 0.433 在地板下),且父的均匀幅度收缩以 local_spatial −0.51(nbhd)为代价。

PLAN 机制 SPATGATE —— 已实现、已证否

按 PLAN 逐字实现:在输出坐标上建 15-NN(scipy cKDTree,与 neighborhood_mmd 同 k),对 DE 支持集(|δ|≥0.25 且 |dp|≥0.3,本视图 51 基因)每基因算空间结构比 s_g = var(NN均值_g)/var(x_g),γ_g = γ_max·clip(1 − s_g/s_ref, 0, 1),再做与父相同的逐列乘性精确缩放 k_g = 1 − γ_g·dp_g/pb_out_g。二值门控(PLAN 步骤6)也实现(s_g > median → γ=0,否则 γ_max)。

s_g 分布(51 基因):min 0.107 / p25 0.170 / p50 0.220 / p75 0.290 / p90 0.320 / max 0.431 —— 压缩在 [0.11, 0.43],即便最"空间均匀"的基因 NN 均值方差也不为 0(有限采样),连续门控因此把 γ 整体压到均值 0.03–0.08(远低于均匀 0.25)。

A 半 seed 0 网格(parent = 62.74):

配置boardcell_statelocal_spatialexprnbhd rawvariogrammmd_ude_score
parent 均匀 γ=.2562.7451.7359.8361.66.05143.01210.01102.2857
cont .25 p7562.5350.2560.3861.72.05029.01321.01139.2857
cont .35 p9062.4050.5260.3361.01.05040.01303.01129.2500
cont .35 p7562.3950.4160.3961.02.05026.01312.01132.2500
cont .25 p9062.3650.3360.3461.02.05038.01315.01137.2500
cont .25 p5062.2950.0160.3761.03.05031.01333.01151.2500
binary .2562.2050.4960.2460.34.05059.01305.01131.2143
binary .3562.1950.6160.0760.33.05093.01291.01131.2143

结论:门控确实如假设回收了 nbhd(所有配置 nbhd raw .05143→.0503–.0509,local_spatial +0.4…+0.6),但 cell_state 损失更大(−1.2…−1.7):variogram/mmd_u 的收益与总收缩质量成正比,门控削弱它就丢收益;部分收缩还重排 dp 使 de_score .2857→.2143–.25。越接近均匀收缩分越高(cont p75 保留 de_score,是门控里最好的 62.53),极限即父节点。7 配置 8 次查分全部低于父,SPATGATE 在 A 半证否。

提交的备选机制 DETR + DETRX(同靶弱项 cell_state + local_spatial)

DETR 走的是与"连续幅度"正交的二值检出模式通道:中间时刻一个基因在谱系内的检出率(阳性细胞比例)应按括号两端检出率的几何插值 p_tgt = p_a^(1−t)·p_b^t 取值(基因随时间关闭时阳性比例按一级衰减乘性经过中间频率;概率的几何平均即对数可加插值,是分数阳性细胞的标准对数线性模型)。mix 的算术混池给出 ≥ 几何目标的检出率,故 DETR 移除多余检出。

  • DETR(共有类型):对两侧都 ≥10 细胞的共有类型,逐基因若输出检出计数 k > p_tgt·n,则把超出的 floor(strength·excess) 个最弱 ON 条目(值最小、确定性 stable argsort)置零。OFF-only(从不新增检出),坐标不动,其他基因零模式不动,pb 只减去被移除的弱值。强度扫描(A 半 seed 0,父 62.74):s=1.0→63.16、1.5→63.35、2.0→63.45、2.5→63.47(nbhd 开始劣化)、3.0→63.45(nbhd 已劣于父);提交 s=2.0(local_spatial/expr 门裕度最健康)。
  • DETRX(单侧独有类型,~36% 输出细胞):单侧类型缺另一侧检出率、无法构造几何目标,用 DETR 自己在共有类型上量到的逐基因乘性漂移 d_g = (Σ_c p_tgt(g,c)·n_c + m·d̄)/(Σ_c k_g,c + m)(伪计数 m=10 向全局漂移平滑;d̄ 为全局漂移)作缺失侧代理,移除 floor(s_ext·k·max(1−d_g,0)) 个最弱 ON。生物学读法:短区间内基因 ON→OFF 衰减是基因调控关闭的谱系内禀属性(一级衰减),共有谱系的典型乘性检出漂移可迁移到未知谱系细胞(GRN 关闭动力学,Davidson & Erwin 2006, doi:10.1126/science.1121590)。d_g 实测 mean 0.946、范围 [0.33, 1.73](d_g≥1 的基因 shrink=0,不动)。强度扫描 seed 0:s_ext=0.35→63.51、0.7→63.94、1.0→63.98(但 nbhd 回落、local_spatial 降);提交 s_ext=0.7(nbhd/local_spatial 更安全)。
机制生效证据
  • 实际改变的细胞/条目(seed 0):DETR 命中 10 个共有类型、~1775 个 (类型,基因)、置零 13690 个条目,nnz .0571→.0516;DETRX 命中 22 个单侧类型、1815 个细胞、置零 ~3420 个条目,nnz→.0502。
  • 四组分(A 半 seed 0,vs 父 62.74):cell_state 51.73→55.09(variogram .0121→.00954、mmd_u .01102→.01071);expression_change 61.66→62.99(de_score .2857→.3571,de_dir .3851→.378 微降);local_spatial 59.83→59.99(nbhd raw .05143→.05126,不劣反微升,正是 SPATGATE 想要而没净赚到的);shape_scale 77.75 不变(坐标逐位未动,符合设计)。
  • 关闭对照:--ablate mechanism 同时关 DETR 与 DETRX(保留父的均匀幅度收缩),输出与父节点 38 seed 0 逐位一致(sha256 前缀 8db00160… 相同,已验证)。
验证过什么
  • A 半多种子:DETR-only s2.0 三种子 63.45/63.07/63.32(vs 父 62.74/62.35/62.84,+0.71/+0.72/+0.48,方向一致);DETRX s0.7 两种子 63.94/63.11(vs 父 +1.19/+0.76)。cell_state 收益(variogram/mmd_u)跨种子稳定;de_score 的 .3571 跳升只在 seed 0 出现、seed 1 回 .2857,是 top-N 集合的抽样噪声,不作为收益依据。
  • 视图无关:把 view 换成随机路径、打乱 manifest 键序、所有阶段时间统一 +1 天后重跑 seed 0,输出与真实视图逐位一致(sha256 相同,已验证)。程序只读 manifest 数据、只用时间差 t 与类型标签,不读绝对时间/路径/board 字段。
  • 确定性:给定 seed 输出确定(DETR/DETRX 用 stable argsort 选最弱 ON,无全局随机;rng 仅用于 random select 模式,默认 lowest 不用)。
  • 格式:vec-check 通过;23 s / 0.6 GB,远在 limits(30 min / 28 GB)内。
  • 单输入退路:无括号(b is None)时在 DETR 之前就 return,不触及本机制。
没验证 / 风险
  • B 半与真实 final 视图未验证(查分额度已用尽,只有 A 半)。DETR/DETRX 由类型与几何插值驱动、与括号宽度和 t 无关,应可迁移;同族的节点 37(DETR)/39(DETR_EXT)已在本谱系证明该通道有效(节点 39 是表内最高分 65.08)。final 视图两端相邻、共有类型更多、单侧类型更少,DETRX 贡献会变小但 OFF-only + 向全局漂移平滑应保证不伤。
  • DETRX 的漂移代理假设"基因关闭速率谱系内禀",对谱系特异的快速关闭基因可能低估/高估;伪计数平滑与 OFF-only(只在 d_g<1 时移除)限制了下行风险。
  • de_dir 随 DETRX 微降(.385→.378):置零弱检出轻微改变全基因秩;被 de_score 的净升覆盖,但 B 半若 de_score 跳升不重现,expr 组可能持平或微动。
  • 幅度收缩(node 38)与 DETR 叠加:两者都降信号,可能部分冗余(表内 node 39 在无幅度收缩的 base 上把 cell_state 推到 59.35,我在含幅度收缩的 base 上到 55)。但 A 半逐种子证据显示 DETR 叠加在本父上净正,故提交。

下一步最值得试

  1. 在本 DETR+DETRX 之上关掉/减弱幅度收缩(recal γ),检验 cell_state 是否像 node 39 那样进一步上探(幅度收缩与 DETR 可能冗余)——这等于把 node 38 base 换回 node 36/37 base,可能超过本节点。
  2. DETRX 漂移代理换成逐类型(而非全基因池)的 d_g,或按 a-only / b-only 分别定向(a-only 衰退型 vs b-only 新生型的检出漂移方向可能不同)。
  3. 在 B 半 / final 宽括号上验证 DETR s 与 DETRX s_ext 的可迁移性(本节点只有 A 半证据)。

知识来源

  • 检出率几何插值 p_tgt = p_a^(1−t)·p_b^t:概率的对数可加(几何)插值,分数阳性细胞沿时间的标准乘性模型(一级衰减动力学);用于 variogram/细胞状态分布校准,不涉及任何保留阶段的测量值。
  • 基因调控关闭的谱系内禀性(DETRX 漂移迁移的依据):GRN 层级与调控动力学,Davidson & Erwin 2006, doi:10.1126/science.1121590。
  • 所有检出率、漂移、类型清单、t、细胞数均从 manifest 指定的括号输入现场计算;无保留阶段/保留基因型的任何测量值写入程序。

调研员的计划

名称空间结构门控DE幅度收缩(SPATGATE):保cell_state收益、消nbhd代价
动机父节点38的均匀γ=0.25幅度收缩使cell_state +2.03(variogram raw 0.01296→0.0117,mmd_u 0.01097→0.0103),但local_spatial −0.51(nbhd raw 0.04774→0.04877,得分−0.13)。ANALYSIS明确指出'幅度收缩破坏了部分表达-位置配对'并建议'差异化γ:对nbhd不敏感的基因子集加大收缩、对nbhd敏感基因保持/降低γ'。当前cell_state 53.49仍是最弱组(variogram skill 0.433在地板下),而local_spatial 61.48有0.51可回收损失。节点37的DETR已证明variogram可在不伤nbhd的情况下大幅改善(nbhd raw 0.04779→0.04775),说明存在不破坏配对的cell_state改善路径。
做法在父节点38的RECAL步骤中,把均匀γ=0.25改为逐基因空间门控γ_g:
1. 在输出坐标上建15-NN(与neighborhood_mmd指标同k=15),scipy cKDTree,5000细胞<1 s。
2. 对DE支持集(|δ|≥0.25且|dp|≥0.3,本视图51基因)中每个基因g,计算空间结构比 s_g = var(NN均值_g) / var(x_g)。s_g高→表达有空间模式,收缩会扭曲邻域表达环境;s_g低→空间均匀,收缩不影响邻域结构。
3. γ_g = γ_max · clip(1 − s_g / s_ref, 0, 1),s_ref取支持集内s_g的指定分位数。空间结构强的基因γ_g→0(不缩),空间均匀的基因γ_g→γ_max(全缩)。
4. 逐列乘性缩放 k_g = 1 − γ_g·dp_g/pb_out_g(与父节点相同的精确pb缩放),零模式、基因内排序、坐标不动。
5. 网格:γ_max ∈ {0.25, 0.35},s_ref ∈ {p50, p75, p90}(支持集内s_g分位数),共6配置 + 父节点均匀γ=0.25对照。用vec-score A半seed 0快筛,选前2配置跑seed 1/2确认。
6. 若连续门控全网格无改善,尝试二值门控:s_g > median的基因γ=0、其余γ=0.25,作为最简对照。
7. 单输入阶段退路:与父节点相同,无括号时不经过本步。
8. 预期提升幅度<1分噪声,需3种子方向一致确认。
风险1. s_g可能不是nbhd敏感性的正确代理——若nbhd损伤来自PCA投影权重变化而非空间模式,门控无效。Engineer应在首配置后检查:被排除基因(γ_g≈0)是否确实是高空间自相关基因,且排除后nbhd raw是否回落。2. 若支持集51基因中s_g分布过于集中(全部高或全部低),门控退化为恒等或均匀收缩,无区分度——此时应检查s_g分布并考虑换用Moran's I或邻域方差绝对值。3. 收益在1分噪声内,需3种子确认。4. 15-NN增加~1 s运行时间,不影响时限。

代码改动?这个节点的程序和父节点程序的逐行差别:绿色是新增,红色是删除。

对比:父节点版本 9b9efbb332。改动的文件:solution/METHOD.md +47 −46、solution/run.py +337 −15

diff --git a/solution/METHOD.md b/solution/METHOD.mdindex 0ca21b2..7e01ab7 100644--- a/solution/METHOD.md+++ b/solution/METHOD.md@@ -1,66 +1,67 @@-对输出中 |δ|≥0.25 且 |dp|≥0.3 的 51 个 DE 基因,把伪批量变化 dp 线性收缩 25%(逐列精确缩放),校准细胞状态分布幅度;PLAN 的向 δ 对齐重标定经 add/mul 两种解码证否。+DETR+DETRX:按共有类型把检出率向几何插值 p_a^(1−t)·p_b^t 做 OFF-only 置零(s=2.0),单侧独有类型用共有类型的逐基因检出漂移作代理置零(s=0.7),叠加在父幅度收缩之上;PLAN 的 SPATGATE 空间门控经 7 配置证否。 -## 方法+## 节点 -父节点 36 管线全部原样保留(mix 混抽 + procrustes3d + 阻尼 log-RMS + α=5 逐类型收敛位移 + λ=6 投影加权 + 软阈值 + β=0.2 配对收缩 + CORRPROJ 不对称相关扩散 η_a=1.5/η_b=0.15 + 各向异性坐标整形)。本节点在其后、写出前新增一步 **RECAL(DE 幅度校准)**:+- family_id: T2EI-01;op: improve;parent: node 38(A 半 3 种子 62.74/62.35/62.84,均值 62.64;官方分 63.60)。+- 靶弱项(来自父 ANALYSIS):cell_state 最弱(variogram skill 0.433 在地板下),且父的均匀幅度收缩以 local_spatial −0.51(nbhd)为代价。 -- 计算括号伪批量 pb_a、pb_b(全细胞逐基因均值)、δ = t·(pb_b − pb_a)、当前输出变化 dp = pb_out − pb_a(全部运行时从视图输入算出,无硬编码常数)。-- 支持集:DE 基因 |δ_g| ≥ 0.25 **且** |dp_g| ≥ 0.3(本视图 498 基因中 51 个)。-- 修正:dp_g ← (1−γ)·dp_g,γ = 0.25。实现为逐列乘性缩放 k_g = 1 − γ·dp_g/pb_out_g(在 pb 上精确;零/非零模式、基因内细胞排序与相对分布、逐基因 pb 记账都保持;坐标完全不动 → 形状组按构造逐位不变)。-- 单输入阶段退路(无括号)在更早的分支返回,不经过本步;γ=0 时本步为恒等变换。-- `--ablate mechanism` → γ=0(其余父节点默认全部保留):输出与父节点 36 seed 0 **逐位一致**(sha256 c3aa2ed5…,本地已验证)。+## PLAN 机制 SPATGATE —— 已实现、已证否 -## 机制生效的证据+按 PLAN 逐字实现:在输出坐标上建 15-NN(scipy cKDTree,与 neighborhood_mmd 同 k),对 DE 支持集(|δ|≥0.25 且 |dp|≥0.3,本视图 51 基因)每基因算空间结构比 s_g = var(NN均值_g)/var(x_g),γ_g = γ_max·clip(1 − s_g/s_ref, 0, 1),再做与父相同的逐列乘性精确缩放 k_g = 1 − γ_g·dp_g/pb_out_g。二值门控(PLAN 步骤6)也实现(s_g > median → γ=0,否则 γ_max)。 -- 改变的细胞/基因:全部 5000 个输出细胞的 51 个 DE 基因列被乘性缩放(k_g ≈ 0.93–0.98,随 dp_g/pb_out_g 变化);零值模式逐位不变(nzfrac 前后相同),坐标逐位不变。-- proxy A 半三种子(同流程父节点对照):+s_g 分布(51 基因):min 0.107 / p25 0.170 / p50 0.220 / p75 0.290 / p90 0.320 / max 0.431 —— 压缩在 [0.11, 0.43],即便最"空间均匀"的基因 NN 均值方差也不为 0(有限采样),连续门控因此把 γ 整体压到均值 0.03–0.08(远低于均匀 0.25)。 -| seed | 父 36 | 本节点 | Δ | variogram raw | mmd_u raw | nbhd raw | de_score raw | de_dir raw |+A 半 seed 0 网格(parent = 62.74):++| 配置 | board | cell_state | local_spatial | expr | nbhd raw | variogram | mmd_u | de_score | |---|---|---|---|---|---|---|---|---|-| 0 | 62.38 | 62.74 | +0.36 | 0.01342→0.01210 | 0.01165→0.01102 | 0.05053→0.05143 | 0.2857→0.2857 | 0.3872→0.3851 |-| 1 | 61.91 | 62.35 | +0.44 | 0.01382→0.01243 | 0.01114→0.01045 | 0.05060→0.05123 | 0.2500→0.2500 | 0.3880→0.3882 |-| 2 | 62.47 | 62.84 | +0.37 | (同结构) | (同结构) | (同结构) | 不变 | ≈不变 |+| parent 均匀 γ=.25 | 62.74 | 51.73 | 59.83 | 61.66 | .05143 | .01210 | .01102 | .2857 |+| cont .25 p75 | 62.53 | 50.25 | 60.38 | 61.72 | .05029 | .01321 | .01139 | .2857 |+| cont .35 p90 | 62.40 | 50.52 | 60.33 | 61.01 | .05040 | .01303 | .01129 | .2500 |+| cont .35 p75 | 62.39 | 50.41 | 60.39 | 61.02 | .05026 | .01312 | .01132 | .2500 |+| cont .25 p90 | 62.36 | 50.33 | 60.34 | 61.02 | .05038 | .01315 | .01137 | .2500 |+| cont .25 p50 | 62.29 | 50.01 | 60.37 | 61.03 | .05031 | .01333 | .01151 | .2500 |+| binary .25 | 62.20 | 50.49 | 60.24 | 60.34 | .05059 | .01305 | .01131 | .2143 |+| binary .35 | 62.19 | 50.61 | 60.07 | 60.33 | .05093 | .01291 | .01131 | .2143 |++结论:门控确实如假设回收了 nbhd(**所有**配置 nbhd raw .05143→.0503–.0509,local_spatial +0.4…+0.6),但 cell_state 损失更大(−1.2…−1.7):variogram/mmd_u 的收益与**总收缩质量**成正比,门控削弱它就丢收益;部分收缩还重排 dp 使 de_score .2857→.2143–.25。越接近均匀收缩分越高(cont p75 保留 de_score,是门控里最好的 62.53),极限即父节点。**7 配置 8 次查分全部低于父**,SPATGATE 在 A 半证否。++## 提交的备选机制 DETR + DETRX(同靶弱项 cell_state + local_spatial) -- 四组分变化(seed 0):cell_state +1.95(variogram +0.32、mmd_u +0.17),local_spatial −0.43(nbhd −0.10),expression_change −0.05(噪声内),shape_scale +0.00(坐标未动,三项 raw 逐位相同)。三种子结构一致。-- 幅度提升低于 T2 约 1 分的板分噪声,但逐项方向在 3 个种子上完全一致(variogram/mmd_u 升、nbhd 微降、de 不动),是系统性小收益而非单次波动。+DETR 走的是与"连续幅度"正交的**二值检出模式**通道:中间时刻一个基因在谱系内的检出率(阳性细胞比例)应按括号两端检出率的几何插值 p_tgt = p_a^(1−t)·p_b^t 取值(基因随时间关闭时阳性比例按一级衰减乘性经过中间频率;概率的几何平均即对数可加插值,是分数阳性细胞的标准对数线性模型)。mix 的算术混池给出 ≥ 几何目标的检出率,故 DETR 移除多余检出。 -## 证伪记录(本节点共查分 18 次,A 半 seed 0,父基线 62.38)+- **DETR(共有类型)**:对两侧都 ≥10 细胞的共有类型,逐基因若输出检出计数 k > p_tgt·n,则把超出的 floor(strength·excess) 个**最弱 ON 条目**(值最小、确定性 stable argsort)置零。OFF-only(从不新增检出),坐标不动,其他基因零模式不动,pb 只减去被移除的弱值。强度扫描(A 半 seed 0,父 62.74):s=1.0→63.16、1.5→63.35、2.0→63.45、2.5→63.47(nbhd 开始劣化)、3.0→63.45(nbhd 已劣于父);提交 **s=2.0**(local_spatial/expr 门裕度最健康)。+- **DETRX(单侧独有类型,~36% 输出细胞)**:单侧类型缺另一侧检出率、无法构造几何目标,用 DETR 自己在共有类型上量到的逐基因乘性漂移 d_g = (Σ_c p_tgt(g,c)·n_c + m·d̄)/(Σ_c k_g,c + m)(伪计数 m=10 向全局漂移平滑;d̄ 为全局漂移)作缺失侧代理,移除 floor(s_ext·k·max(1−d_g,0)) 个最弱 ON。生物学读法:短区间内基因 ON→OFF 衰减是基因调控关闭的谱系内禀属性(一级衰减),共有谱系的典型乘性检出漂移可迁移到未知谱系细胞(GRN 关闭动力学,Davidson & Erwin 2006, doi:10.1126/science.1121590)。d_g 实测 mean 0.946、范围 [0.33, 1.73](d_g≥1 的基因 shrink=0,不动)。强度扫描 seed 0:s_ext=0.35→63.51、0.7→63.94、1.0→63.98(但 nbhd 回落、local_spatial 降);提交 **s_ext=0.7**(nbhd/local_spatial 更安全)。 -PLAN 字面机制(向 δ 对齐,r_g = 1+γ·clip(δ/dp−1,±cap),|δ|≥0.25、|dp|≥0.05):+### 机制生效证据 -| 配置 | 板分 | de_score raw | de_dir raw | mmd_u raw | vario raw | nbhd raw |-|---|---|---|---|---|---|---|-| mul γ0.5 cap0.3(PLAN 主配置) | 61.68 | **0.2500**(−0.036) | 0.3865 | 0.01249 | 0.01463 | 0.05095 |-| add γ0.5 cap0.3(nnz 平移解码) | (榜分头部被截断未留存) | 未留存 | 未留存 | 未留存 | 未留存 | 0.05111(劣化) |+- 实际改变的细胞/条目(seed 0):DETR 命中 10 个共有类型、~1775 个 (类型,基因)、置零 13690 个条目,nnz .0571→.0516;DETRX 命中 22 个单侧类型、1815 个细胞、置零 ~3420 个条目,nnz→.0502。+- 四组分(A 半 seed 0,vs 父 62.74):cell_state 51.73→**55.09**(variogram .0121→.00954、mmd_u .01102→.01071);expression_change 61.66→**62.99**(de_score .2857→.3571,de_dir .3851→.378 微降);local_spatial 59.83→**59.99**(nbhd raw .05143→.05126,不劣反微升,正是 SPATGATE 想要而没净赚到的);shape_scale 77.75 不变(坐标逐位未动,符合设计)。+- 关闭对照:`--ablate mechanism` 同时关 DETR 与 DETRX(保留父的均匀幅度收缩),输出与父节点 38 seed 0 **逐位一致**(sha256 前缀 8db00160… 相同,已验证)。 -→ 把 dp 推向 δ 使 de_score 显著变差、全组劣化,PLAN 的"δ 是 dt 的一阶近似"前提在本括号上不成立(机制证否)。+### 验证过什么 -方向探针与备选网格(全部同一父管线之上):+- A 半多种子:DETR-only s2.0 三种子 63.45/63.07/63.32(vs 父 62.74/62.35/62.84,+0.71/+0.72/+0.48,方向一致);DETRX s0.7 两种子 63.94/63.11(vs 父 +1.19/+0.76)。cell_state 收益(variogram/mmd_u)跨种子稳定;de_score 的 .3571 跳升只在 seed 0 出现、seed 1 回 .2857,是 top-N 集合的抽样噪声,不作为收益依据。+- 视图无关:把 view 换成随机路径、打乱 manifest 键序、所有阶段时间统一 +1 天后重跑 seed 0,输出与真实视图**逐位一致**(sha256 相同,已验证)。程序只读 manifest 数据、只用时间差 t 与类型标签,不读绝对时间/路径/board 字段。+- 确定性:给定 seed 输出确定(DETR/DETRX 用 stable argsort 选最弱 ON,无全局随机;rng 仅用于 random select 模式,默认 lowest 不用)。+- 格式:vec-check 通过;23 s / 0.6 GB,远在 limits(30 min / 28 GB)内。+- 单输入退路:无括号(b is None)时在 DETR 之前就 return,不触及本机制。 -| 配置 | 板分 | 关键分项 |-|---|---|---|-| shrink γ0.25(全 116 DE) | 62.73 | vario +0.44 / nbhd −0.20;seed1 62.28(+0.37) |-| shrink γ0.35(全 DE) | 62.64 | vario +0.62 / nbhd −0.40 |-| shrink γ0.5(全 DE) | 62.23 | vario 0.01012 / nbhd 0.05778(过度) |-| **shrink γ0.25, \|dp\|≥0.3(提交)** | **62.74** | 三种子 +0.36/+0.44/+0.37 |-| shrink γ0.35, \|dp\|≥0.3 | 62.54 | 峰值在 γ≈0.25 |-| shrink γ0.5, \|dp\|≥0.3 | 61.98 | 过度 |-| shrink γ0.25, sup 0.15(182 基因) | 62.67 | 无增益 |-| dev f0.7(均值保持、只缩型内展布) | 62.08 | vario 反而 0.01372、nbhd 0.05340 → 增益来自幅度而非展布 |-| SIDECLUSTER(PC1 侧别坐标重配对,只动 nbhd 的干净探针) | 61.05 | nbhd 0.05999(−1.05)→ 真实表达-位置配对必须保留,坐标重配对方向关闭 |-| BRACKET_CLIP=1.0 + 提交机制 | 61.53 | de_score 0.2500、nbhd 0.05823 → 值域钳制破坏 dp 排序 |-| 单侧 clamp-to-δ(只缩过冲基因) | 未查分 | 本地分析:仅 4/116 基因过冲,≈恒等,放弃 |+### 没验证 / 风险 -结论:de_score raw 在 shrink 全网格上逐位不动(0.2857),boost 单向劣化 → expression_change 对逐基因 pb 缩放已饱和;真实收益在 cell_state(A 半最弱组,49.78)的幅度校准上。+- **B 半与真实 final 视图未验证**(查分额度已用尽,只有 A 半)。DETR/DETRX 由类型与几何插值驱动、与括号宽度和 t 无关,应可迁移;同族的节点 37(DETR)/39(DETR_EXT)已在本谱系证明该通道有效(节点 39 是表内最高分 65.08)。final 视图两端相邻、共有类型更多、单侧类型更少,DETRX 贡献会变小但 OFF-only + 向全局漂移平滑应保证不伤。+- DETRX 的漂移代理假设"基因关闭速率谱系内禀",对谱系特异的快速关闭基因可能低估/高估;伪计数平滑与 OFF-only(只在 d_g<1 时移除)限制了下行风险。+- de_dir 随 DETRX 微降(.385→.378):置零弱检出轻微改变全基因秩;被 de_score 的净升覆盖,但 B 半若 de_score 跳升不重现,expr 组可能持平或微动。+- 幅度收缩(node 38)与 DETR 叠加:两者都降信号,可能部分冗余(表内 node 39 在无幅度收缩的 base 上把 cell_state 推到 59.35,我在含幅度收缩的 base 上到 55)。但 A 半逐种子证据显示 DETR 叠加在本父上净正,故提交。 -## 已验证 / 未验证+## 下一步最值得试 -- 已验证:默认输出 = 查分过的提交配置(sha256 逐位一致);`--ablate mechanism` 与父节点 36 输出逐位一致;同 seed 重复运行逐位确定;两个输出均过 vec-check;纯 CPU ~10 s、峰值内存 <1 GB。-- 未验证:B 半与真实 final 视图上的收益幅度(A 半 +0.39 均值小于 1 分噪声,B 半可能兑现也可能不兑现;机制方向在 3 个种子上一致,按系统性小收益提交);真实括号两端相邻、共有类型多,DE 支持集与 k_g 分布会不同,但机制全部由输入现场计算,无阶段特化分支。-- 视图无关:γ、支持阈值是固定超参;δ、dp、k_g 全部由视图数据运行时计算;只用相对时间 t,不用绝对阶段时间。+1. 在本 DETR+DETRX 之上**关掉/减弱幅度收缩**(recal γ),检验 cell_state 是否像 node 39 那样进一步上探(幅度收缩与 DETR 可能冗余)——这等于把 node 38 base 换回 node 36/37 base,可能超过本节点。+2. DETRX 漂移代理换成**逐类型**(而非全基因池)的 d_g,或按 a-only / b-only 分别定向(a-only 衰退型 vs b-only 新生型的检出漂移方向可能不同)。+3. 在 B 半 / final 宽括号上验证 DETR s 与 DETRX s_ext 的可迁移性(本节点只有 A 半证据)。  ## 知识来源 -- 提交机制不依赖任何外部生物学知识(纯数据驱动的幅度校准,全部统计量运行时从 manifest 指定的输入计算)。-- 已证否并关闭的 SIDECLUSTER 探针的设计动机引用教科书发育事件程序:胚体区域存在发育成熟度梯度(如体节发生波沿头尾轴推进),Gilbert, *Developmental Biology*, 10th ed., Sinauer, ch. 12–13(ISBN 978-0-87893-978-7)。该探针被 A 半证否(nbhd −1.05),默认关闭,不影响输出。-- 未使用任何保留阶段/保留基因型数据或由其导出的测量值;δ、dp 只来自视图内已发布输入阶段。+- 检出率几何插值 p_tgt = p_a^(1−t)·p_b^t:概率的对数可加(几何)插值,分数阳性细胞沿时间的标准乘性模型(一级衰减动力学);用于 variogram/细胞状态分布校准,不涉及任何保留阶段的测量值。+- 基因调控关闭的谱系内禀性(DETRX 漂移迁移的依据):GRN 层级与调控动力学,Davidson & Erwin 2006, doi:10.1126/science.1121590。+- 所有检出率、漂移、类型清单、t、细胞数均从 manifest 指定的括号输入现场计算;无保留阶段/保留基因型的任何测量值写入程序。diff --git a/solution/run.py b/solution/run.pyindex b43f475..567645c 100644--- a/solution/run.py+++ b/solution/run.py@@ -8,7 +8,35 @@ exp(log r_a + SCALE_DAMP·t·Δlog r), and draws cells stratified by type: round(t·n) from the later stage, the rest from the earlier one. Coordinates travel with the cells. n is log-linear in t, clipped to the board range. -This node (38, family T2EI-01): PLAN mechanism RECAL — per-gene pseudobulk+This node (40, family T2EI-01): PLAN mechanism SPATGATE — per-gene spatial+gating of node 38's uniform DE-amplitude shrink (γ_g = γ_max·clip(1 −+s_g/s_ref, 0, 1), s_g = var(15-NN mean)/var(x) on the output coordinates) —+was implemented in 7 configurations (continuous s_ref ∈ {p50, p75, p90} ×+γ_max ∈ {0.25, 0.35} + binary median gate × γ_max ∈ {0.25, 0.35}) and+FALSIFIED on the proxy A half (parent 62.74 at seed 0; every config+62.19–62.53). The gate does recover neighborhood_mmd as hypothesized (nbhd+raw .05143 → .0503–.0509, local_spatial +0.4..+0.6 in ALL configs) but the+cell_state gain of the shrink is proportional to the TOTAL shrink mass+(variogram/mmd_u degrade monotonically as gating weakens it) and partial+shrink also re-ranks dp (de_score .2857 → .2143–.25), so every gate lands+below the uniform parent; the closer to uniform, the higher (sg_p75, which+keeps de_score, is the best gate at 62.53). SUBMITTED BACKUP MECHANISM (same+weakness, cell_state + local_spatial): DETR + DETRX — detection-rate+geometric interpolation (see the DETR_* / DETRX_* config docs below for the+full mechanism, evidence and grids). Per shared cell type, genes whose output+detection count exceeds p_tgt·n with p_tgt = p_a^(1−t)·p_b^t lose the excess+weakest ON entries (OFF-only, floor(s·excess), s = 2.0); one-sided output+types (~36% of cells) get the same removal at s_ext = 0.7 with the per-gene+multiplicative drift d_g of the shared types as the missing-side proxy.+A half seed 0/1: 63.94/63.11 vs parent 62.74/62.35 (+1.19/+0.76;+cell_state +3.4/+3.0 via variogram .0121→.0095/.0100, nbhd raw+.05143→.05126/.05150 flat-to-better, de_score .2857→.3571 at seed 0 and+back at seed 1 — the top-N gain is draw-dependent, the variogram/mmd_u gain+is consistent). Coordinates untouched → shape group bit-for-bit unchanged.+--ablate mechanism disables DETR+DETRX (uniform shrink stays) and reproduces+parent node 38 bit-for-bit.++Parent (node 38, family T2EI-01): PLAN mechanism RECAL — per-gene pseudobulk magnitude recalibration toward the bracket-linear target change δ = t·(pb_b − pb_a) — was implemented in two exact realizations (additive nnz-shift and multiplicative column rescale, γ ∈ {0.5}, cap ∈ {0.3}) and@@ -342,6 +370,78 @@ RECAL_SUPPORT = float(os.environ.get("T2_RECAL_SUPPORT", "0.25")) RECAL_MIN_DP = float(os.environ.get("T2_RECAL_MIN_DP", "0.3")) RECAL_MODE = os.environ.get("T2_RECAL_MODE", "shrink")  # add | mul | shrink | dev RECAL_SMAX = float(os.environ.get("T2_RECAL_SMAX", "2.0"))+# SPATGATE (node 40, family T2EI-01, PLAN mechanism): the node-38 uniform+# shrink (γ = 0.25 on every DE-support gene) bought cell_state (+2.03 board+# groups: variogram/mmd_u improve — the A-half truth prefers smaller DE+# amplitudes) but cost local_spatial (−0.51: neighborhood_mmd raw degrades,+# the column rescale distorts the expression–position pairing that the+# 15-NN neighborhood means see). SPATGATE replaces the uniform γ with a+# per-gene spatial gate: build the 15-NN graph on the OUTPUT coordinates+# (same k as the neighborhood_mmd metric), compute for each DE-support gene+# the spatial-structure ratio s_g = var(NN-mean_g) / var(x_g) (s_g → 1/k for+# spatially uniform expression, → 1 for strong spatial pattern), and set+#   γ_g = γ_max · clip(1 − s_g / s_ref, 0, 1),  s_ref = quantile(s_g | support)+# so spatially structured genes (whose neighborhood means carry real tissue+# pattern) are NOT shrunk and spatially uniform genes (shrink cannot break+# any pairing) get the full γ_max. Decode unchanged: exact per-column+# multiplicative rescale k_g = 1 − γ_g·dp_g/pb_out_g (zero pattern, within-+# gene ranking, coordinates untouched). SPATGATE_MODE "binary": γ_g = 0 for+# s_g > median(support), else γ_max (PLAN step-6 fallback).+# --ablate mechanism disables the gate (all γ_g = RECAL_GAMMA uniform) and+# reproduces node 38 bit-for-bit. Single-input fallback never reaches this.+SPATGATE_ENABLE = os.environ.get("T2_SPATGATE_ENABLE", "0") == "1"+SPATGATE_GMAX = float(os.environ.get("T2_SPATGATE_GMAX", "0.25"))+SPATGATE_SREF = os.environ.get("T2_SPATGATE_SREF", "p75")  # p50 | p75 | p90 | <float quantile>+SPATGATE_K = int(os.environ.get("T2_SPATGATE_K", "15"))+SPATGATE_MODE = os.environ.get("T2_SPATGATE_MODE", "cont")  # cont | binary+# DETR (node 40 SUBMITTED BACKUP mechanism, cell_state/variogram): the SPATGATE+# grid falsified "shrink less on structured genes" (7 configs, all below parent+# 62.74 A-half seed 0: cont p50/p75/p90 × γ_max .25/.35 → 62.29–62.53, binary+# .25/.35 → 62.20/62.19; the variogram/mmd_u gain is proportional to the TOTAL+# shrink mass and partial shrink re-ranks dp, dropping de_score .2857→.21–.25).+# The remaining nbhd-neutral cell_state channel is the BINARY detection pattern+# instead of the continuous amplitude: at an intermediate time the detection+# rate of a gene within a lineage follows the geometric interpolation of the+# bracket rates (a gene turning OFF over time passes intermediate frequencies+# multiplicatively, like a first-order decay; standard log-additive model for+# fraction of positive cells, cf. geometric mean of probabilities), p_tgt =+# p_a^(1−t)·p_b^t, which is ≤ the arithmetic pooling the mix produces. DETR+# therefore removes excess detections: per shared cell type (present with+# ≥ DETR_MIN_CELLS cells on both bracket sides), for genes whose output+# detection count exceeds p_tgt·n, zero the weakest ON entries (lowest values,+# deterministic) — count = floor(strength·excess). OFF-only (never creates+# detections), other genes' zero patterns untouched, coordinates untouched,+# pseudobulk moves only by the removed weak values. Same lever as sibling-+# lineage node 37 (DETR, +0.8 board over its parent, variogram repaired, nbhd+# raw flat), here on top of node 38's amplitude shrink with its own strength+# scan. A-half seed 0/1/2: 63.45/63.07/63.32 vs parent 62.74/62.35/62.84+# (+0.71/+0.72/+0.48; cell_state +2.7/+2.6/+3.3 via variogram .0121→.0100 and+# mmd_u, local_spatial +0.2/+0.1/+0.6 with nbhd raw IMPROVED .05143→.05100,+# de_score frozen at .2857). Strength scan (seed 0): 1.0→63.16, 1.5→63.35,+# 2.0→63.45, 2.5→63.47 (nbhd starts degrading, local_spatial −0.12 vs 2.0),+# 3.0→63.45 (nbhd worse than parent) — submitted s = 2.0 (safer gate margin).+# DETR_ENABLE=0 or --ablate mechanism disables → node 38 bit-for-bit.+DETR_ENABLE = os.environ.get("T2_DETR_ENABLE", "1") == "1"+DETR_STRENGTH = float(os.environ.get("T2_DETR_STRENGTH", "2.0"))+DETR_MIN_CELLS = int(os.environ.get("T2_DETR_MIN_CELLS", "10"))+DETR_SELECT = os.environ.get("T2_DETR_SELECT", "lowest")  # lowest | random+# DETRX (node 40, extension of DETR to one-sided types): ~36% of the drawn+# output cells belong to types present on only ONE bracket side (a-only+# lineages regressing / b-only lineages emerging), where the missing side's+# detection rate is unknown so the geometric target cannot be formed. Proxy:+# the per-gene detection drift d_g = (Σ_c p_tgt(g,c)·n_c + m·d̄) / (Σ_c k_g,c + m)+# measured by DETR itself on the SHARED-type output cells (aggregate target+# count over aggregate observed count, pseudocount m smoothing toward the+# global drift d̄) — the textbook reading is that gene-level ON→OFF decay over+# a short interval is a lineage-intrinsic property of the gene's regulatory+# shutdown (first-order decay), so the typical multiplicative detection drift+# of shared lineages transfers to cells of unknown lineage. One-sided types+# then get p_tgt' = p_out·d_g and OFF-only removal at a weaker strength+# floor(s_ext·max(k − p_tgt'·n, 0)) (node 39 on the sibling lineage used+# s_ext = 0.35 with the same idea). Disabled by --ablate together with DETR.+DETRX_ENABLE = os.environ.get("T2_DETRX_ENABLE", "1") == "1"+DETRX_STRENGTH = float(os.environ.get("T2_DETRX_STRENGTH", "0.7"))+DETRX_SMOOTH = float(os.environ.get("T2_DETRX_SMOOTH", "10")) # SIDECLUSTER (node 38 probe, local_spatial): neighborhood_mmd is the only # ranked metric that sees the expression↔coordinate PAIRING (all others see # either the expression multiset or the coordinate point set). The stratified@@ -391,15 +491,74 @@ def _spearman(x: np.ndarray, y: np.ndarray) -> float:     return float((rx * ry).sum() / den) if den > 0 else 0.0  -def recalibrate(expr, pb_a, pb_b, t, gamma, cap, support, min_dp, mode, smax):+def spatial_gate_gammas(expr, coords, de, gmax, sref, k, mode):+    """Per-gene spatial-gate γ_g for the DE-support genes (bool mask `de`).++    s_g = var(15-NN mean of x_g) / var(x_g) on the OUTPUT coordinates;+    γ_g = gmax·clip(1 − s_g/s_ref, 0, 1) with s_ref = quantile(s_g | de)+    (mode "cont"), or γ_g = 0 where s_g > median(s_g | de) else gmax+    (mode "binary"). Genes outside the support get γ_g = 0. Returns+    (gamma_vec, info)."""+    G = expr.shape[1]+    gam = np.zeros(G, dtype=np.float64)+    info = {"spatgate_enable": True, "spatgate_gmax": gmax, "spatgate_sref": sref,+            "spatgate_k": k, "spatgate_mode": mode, "spatgate_n_support": int(de.sum()),+            "spatgate_s_min": None, "spatgate_s_p25": None, "spatgate_s_p50": None,+            "spatgate_s_p75": None, "spatgate_s_p90": None, "spatgate_s_max": None,+            "spatgate_sref_val": None, "spatgate_gamma_mean": None,+            "spatgate_gamma_min": None, "spatgate_gamma_max": None,+            "spatgate_n_zero_gamma": None, "spatgate_applied": False}+    n = expr.shape[0]+    if not de.any() or n < max(k + 1, 3) or gmax == 0.0:+        return gam, info+    from scipy.spatial import cKDTree+    C = np.asarray(coords, dtype=np.float64)+    kk = int(min(k, n - 1))+    tree = cKDTree(C)+    _, idx = tree.query(C, k=kk + 1)  # includes self+    Xd = np.asarray(expr, dtype=np.float64)+    nn = Xd[idx].mean(axis=1)  # (n, G) neighborhood means+    var_x = Xd.var(axis=0)+    var_nn = nn.var(axis=0)+    s = np.where(var_x > 1e-12, var_nn / np.maximum(var_x, 1e-12), 0.0)+    ss = s[de]+    info.update(spatgate_s_min=float(ss.min()), spatgate_s_p25=float(np.quantile(ss, 0.25)),+                spatgate_s_p50=float(np.quantile(ss, 0.50)),+                spatgate_s_p75=float(np.quantile(ss, 0.75)),+                spatgate_s_p90=float(np.quantile(ss, 0.90)),+                spatgate_s_max=float(ss.max()), spatgate_applied=True)+    if mode == "binary":+        thr = float(np.median(ss))+        info["spatgate_sref_val"] = thr+        gam[de] = np.where(s[de] > thr, 0.0, gmax)+    else:+        qmap = {"p50": 0.50, "p75": 0.75, "p90": 0.90}+        q = qmap.get(str(sref), None)+        qv = q if q is not None else float(sref)+        sref_val = float(np.quantile(ss, qv))+        info["spatgate_sref_val"] = sref_val+        if sref_val > 1e-12:+            gam[de] = gmax * np.clip(1.0 - s[de] / sref_val, 0.0, 1.0)+        else:+            gam[de] = np.where(s[de] <= 1e-12, gmax, 0.0)+    g = gam[de]+    info.update(spatgate_gamma_mean=float(g.mean()), spatgate_gamma_min=float(g.min()),+                spatgate_gamma_max=float(g.max()),+                spatgate_n_zero_gamma=int((g <= 1e-9).sum()))+    return gam, info+++def recalibrate(expr, pb_a, pb_b, t, gamma, cap, support, min_dp, mode, smax,+                coords=None, gate=None):     info = {"recal_gamma": gamma, "recal_cap": cap, "recal_mode": mode,             "recal_support": support, "recal_min_dp": min_dp, "recal_smax": smax,+            "spatgate_enable": False,             "recal_n_genes": 0, "recal_clip_rate": None,             "recal_spear_before": None, "recal_spear_after": None,             "recal_dp_gap_before": None, "recal_dp_gap_after": None,             "recal_nzfrac_before": None, "recal_nzfrac_after": None,             "recal_realized_frac": None}-    if gamma == 0.0 or expr.shape[0] == 0:+    if (gamma == 0.0 and gate is None) or expr.shape[0] == 0:         return expr, info     delta = t * (pb_b - pb_a)     dp = expr.mean(axis=0).astype(np.float64) - pb_a@@ -409,7 +568,14 @@ def recalibrate(expr, pb_a, pb_b, t, gamma, cap, support, min_dp, mode, smax):         de = np.abs(delta) >= support         if min_dp > 0:             de = de & (np.abs(dp) >= min_dp)-        corr = np.where(de, -gamma * dp, 0.0)+        # SPATGATE (node 40): replace the uniform γ with a per-gene spatial gate.+        gam_vec = np.full(dp.shape, float(gamma), dtype=np.float64)+        if gate is not None and coords is not None:+            gg, ginfo = spatial_gate_gammas(+                expr, coords, de, gate["gmax"], gate["sref"], gate["k"], gate["mode"])+            gam_vec = gg  # zero outside the support by construction+            info.update(ginfo)+        corr = np.where(de, -gam_vec * dp, 0.0)         act = de & (np.abs(corr) > 1e-12)         info["recal_n_genes"] = int(act.sum())         k = np.ones_like(dp)@@ -480,6 +646,121 @@ def recalibrate(expr, pb_a, pb_b, t, gamma, cap, support, min_dp, mode, smax):     return expr, info  +def detection_recalibrate(expr, out_labels, stage_a, stage_b, t, strength,+                          min_cells, select, rng,+                          detr_x=False, x_strength=0.35, x_smooth=10.0):+    """DETR: per shared cell type, remove excess gene detections toward the+    geometric interpolation p_tgt = p_a^(1−t)·p_b^t of the bracket detection+    rates. OFF-only: zero the weakest (lowest-value) ON entries, deterministic;+    coordinates, other genes' zero patterns and cell order untouched.++    DETRX (detr_x=True): after the shared pass, per-gene multiplicative drift+    d_g = (Σ_c p_tgt(g,c)·n_c + m·d̄)/(Σ_c k_g,c + m) accumulated over the+    shared types is applied as the missing-side proxy to ONE-SIDED output+    types (present on a single bracket side): removal count+    floor(x_strength·k_g·max(1−d_g, 0)), same weakest-ON selection."""+    G = expr.shape[1]+    info = {"detr_enable": True, "detr_strength": strength, "detr_min_cells": min_cells,+            "detr_select": select, "detr_n_types": 0, "detr_n_genes_touched": 0,+            "detr_n_entries_zeroed": 0, "detr_nnz_before": float((expr != 0).mean()),+            "detr_nnz_after": None, "detr_pb_shift_max": None,+            "detrx_enable": bool(detr_x), "detrx_strength": x_strength,+            "detrx_n_types": 0, "detrx_n_cells": 0, "detrx_n_zeroed": 0,+            "detrx_d_mean": None, "detrx_d_min": None, "detrx_d_max": None}+    if expr.shape[0] == 0 or strength <= 0.0:+        info["detr_enable"] = False+        return expr, info+    la = np.asarray(stage_a.labels).astype(str)+    lb = np.asarray(stage_b.labels).astype(str)+    Xa_sp = stage_a.X+    Xb_sp = stage_b.X+    pb_before = expr.mean(axis=0).astype(np.float64)+    n_touched = 0+    n_zeroed = 0+    n_types = 0+    G = expr.shape[1]+    tgt_sum = np.zeros(G, dtype=np.float64)   # Σ p_tgt(g,c)·n_c over shared types+    obs_sum = np.zeros(G, dtype=np.float64)   # Σ k_g,c (pre-DETR) over shared types+    for c in sorted(set(la.tolist()) & set(lb.tolist())):+        ma = la == c+        mb = lb == c+        cnt_a = int(ma.sum())+        cnt_b = int(mb.sum())+        if cnt_a < min_cells or cnt_b < min_cells:+            continue+        mo = out_labels == c+        n_c = int(mo.sum())+        if n_c < 5:+            continue+        n_types += 1+        pa = np.asarray((Xa_sp[ma] != 0).sum(axis=0)).ravel().astype(np.float64) / cnt_a+        pb = np.asarray((Xb_sp[mb] != 0).sum(axis=0)).ravel().astype(np.float64) / cnt_b+        eps = 0.5 / max(min(cnt_a, cnt_b), 1)+        pt = np.power(np.maximum(pa, eps), 1.0 - t) * np.power(np.maximum(pb, eps), t)+        Xc = expr[mo]+        nz = Xc > 0+        k = nz.sum(axis=0).astype(np.float64)+        if detr_x:+            tgt_sum += pt * n_c+            obs_sum += k+        rem = np.floor(strength * np.maximum(k - pt * n_c, 0.0)).astype(np.int64)+        rem = np.minimum(rem, k.astype(np.int64))+        rows_c = np.where(mo)[0]+        for g in np.where(rem > 0)[0]:+            r = int(rem[g])+            on_local = np.where(nz[:, g])[0]+            if select == "random":+                pick = rng.choice(on_local, size=r, replace=False)+            else:+                vals = Xc[on_local, g]+                pick = on_local[np.argsort(vals, kind="stable")[:r]]+            expr[rows_c[pick], g] = 0.0+            n_touched += 1+            n_zeroed += r+    x_types = 0+    x_cells = 0+    x_zeroed = 0+    if detr_x and obs_sum.sum() > 0:+        # Per-gene multiplicative detection drift from shared lineages, smoothed+        # toward the global drift with pseudocount x_smooth.+        d_glob = tgt_sum.sum() / max(obs_sum.sum(), 1e-9)+        d_g = (tgt_sum + x_smooth * d_glob) / (obs_sum + x_smooth)+        info.update(detrx_d_mean=float(d_g.mean()), detrx_d_min=float(d_g.min()),+                    detrx_d_max=float(d_g.max()))+        shrink_g = np.clip(1.0 - d_g, 0.0, None)  # genes whose detection falls+        shared_set = set(la.tolist()) & set(lb.tolist())+        for c in sorted(set(out_labels.tolist()) - shared_set):+            mo = out_labels == c+            n_c = int(mo.sum())+            if n_c < 5:+                continue+            x_types += 1+            x_cells += n_c+            Xc = expr[mo]+            nz = Xc > 0+            k = nz.sum(axis=0).astype(np.float64)+            rem = np.floor(x_strength * k * shrink_g).astype(np.int64)+            rem = np.minimum(rem, k.astype(np.int64))+            rows_c = np.where(mo)[0]+            for g in np.where(rem > 0)[0]:+                r = int(rem[g])+                on_local = np.where(nz[:, g])[0]+                if select == "random":+                    pick = rng.choice(on_local, size=r, replace=False)+                else:+                    vals = Xc[on_local, g]+                    pick = on_local[np.argsort(vals, kind="stable")[:r]]+                expr[rows_c[pick], g] = 0.0+                x_zeroed += r+    info.update(detrx_n_types=x_types, detrx_n_cells=x_cells, detrx_n_zeroed=x_zeroed)+    info.update(detr_n_types=n_types, detr_n_genes_touched=n_touched,+                detr_n_entries_zeroed=n_zeroed,+                detr_nnz_after=float((expr != 0).mean()),+                detr_pb_shift_max=float(np.abs(expr.mean(axis=0).astype(np.float64)+                                               - pb_before).max()) if expr.shape[0] else None)+    return expr, info++ def timing_fraction(stage_a, stage_b, shared_labels, kappa: float):     """Per-gene f_g in [FLO·t, min(FHI·t, 0.9)] from within-stage slope asymmetry."""     genes_n = len(stage_a.genes)@@ -1440,6 +1721,14 @@ def mix_converge(stage_a, stage_b, t: float, params: dict, alpha: float, view: s     if ib.size:         coord_parts.append(np.asarray(cb[ib], dtype=np.float64))     coords = np.vstack(coord_parts)+    # Output cell type labels (a-drawn rows first, then b-drawn rows) so that+    # downstream per-type steps (DETR) can group the drawn cells without+    # re-deriving the mix. Not JSON-serialised (excluded from the keep filter).+    _la = np.asarray(stage_a.labels).astype(str)+    _lb = np.asarray(stage_b.labels).astype(str)+    out_labels = np.concatenate([_la[ia] if ia.size else _la[:0],+                                 _lb[ib] if ib.size else _lb[:0]])+    info["out_labels"] = out_labels     aniso_info = {"aniso_enable": bool(ANISO_ENABLE), "aniso_damp": ANISO_DAMP}     if ANISO_ENABLE and coords.shape[0] >= 10:         coords, ai = aniso_reshape(coords, aligned_a, aligned_b, t, ANISO_DAMP)@@ -1474,14 +1763,17 @@ def main() -> None:     parser.add_argument("--out", required=True)     parser.add_argument("--seed", type=int, default=0)     parser.add_argument("--ablate", default=None,-                        help="mechanism-off control: 'mechanism' (or any name) disables this "-                             "node's per-gene pseudobulk recalibration step (T2_RECAL_GAMMA -> 0), "-                             "reproducing the parent node 36 output bit-for-bit")+                        help="mechanism-off control (node 40): 'mechanism' (or any name) disables "+                             "the SPATGATE per-gene spatial gate and falls back to node 38's uniform "+                             "DE-amplitude shrink (γ = T2_RECAL_GAMMA = 0.25 on every support gene), "+                             "reproducing parent node 38 output bit-for-bit")     args = parser.parse_args()-    # Mechanism-off control (node 38): RECAL only. Every knob of parent node 36-    # (asymmetric corr diffusion eta_a=1.5/eta_b=0.15 and all earlier steps)-    # keeps its submitted default, so the ablated output is bit-for-bit node 36.-    recal_gamma = 0.0 if args.ablate else RECAL_GAMMA+    # Mechanism-off control (node 40): SPATGATE only. The uniform shrink of+    # parent node 38 (RECAL_MODE=shrink, γ=0.25) and every earlier knob of node+    # 36 keep their submitted defaults, so the ablated output is bit-for-bit+    # node 38 (γ_g = 0.25 for all support genes; no spatial gating).+    recal_gamma = RECAL_GAMMA+    spatgate_on = SPATGATE_ENABLE and not args.ablate     sidecluster = 0 if args.ablate else SIDECLUSTER     proj_eta = None     proj_eta2 = None@@ -1506,8 +1798,24 @@ def main() -> None:     pb_b_r = np.asarray(stage_b.X.mean(axis=0)).ravel().astype(np.float64)     expr, recal_info = recalibrate(expr, pb_a_r, pb_b_r, float(t), recal_gamma,                                    RECAL_CAP, RECAL_SUPPORT, RECAL_MIN_DP,-                                   RECAL_MODE, RECAL_SMAX)+                                   RECAL_MODE, RECAL_SMAX,+                                   coords=coords if spatgate_on else None,+                                   gate=({"gmax": SPATGATE_GMAX, "sref": SPATGATE_SREF,+                                          "k": SPATGATE_K, "mode": SPATGATE_MODE}+                                         if spatgate_on else None))     info.update(recal_info)+    # DETR (node 40 backup mechanism): detection-rate geometric interpolation,+    # applied AFTER the amplitude shrink (ablate disables DETR only, so the+    # control run is node 38 bit-for-bit).+    detr_on = (DETR_ENABLE or DETRX_ENABLE) and not args.ablate+    if detr_on:+        out_labels = info.get("out_labels")+        if out_labels is not None and out_labels.shape[0] == expr.shape[0]:+            expr, detr_info = detection_recalibrate(+                expr, out_labels, stage_a, stage_b, float(t), DETR_STRENGTH,+                DETR_MIN_CELLS, DETR_SELECT, np.random.default_rng(args.seed),+                detr_x=DETRX_ENABLE, x_strength=DETRX_STRENGTH, x_smooth=DETRX_SMOOTH)+            info.update(detr_info)     sc_info = {"sidecluster": sidecluster}     if sidecluster and expr.shape[0]:         coords, sci = side_cluster_repair(coords, int(info.get("n_from_a", 0)))@@ -1553,9 +1861,23 @@ def main() -> None:                                        "recal_min_dp", "recal_smax", "recal_n_genes", "recal_clip_rate",                                        "recal_spear_before", "recal_spear_after",                                        "recal_dp_gap_before", "recal_dp_gap_after",-                                       "recal_nzfrac_before", "recal_nzfrac_after",-                                       "recal_realized_frac",-                                       "sidecluster", "sidecluster_n_a", "sidecluster_applied")}+                                        "recal_nzfrac_before", "recal_nzfrac_after",+                                        "recal_realized_frac",+                                        "spatgate_enable", "spatgate_gmax", "spatgate_sref",+                                        "spatgate_k", "spatgate_mode", "spatgate_n_support",+                                        "spatgate_s_min", "spatgate_s_p25", "spatgate_s_p50",+                                        "spatgate_s_p75", "spatgate_s_p90", "spatgate_s_max",+                                        "spatgate_sref_val", "spatgate_gamma_mean",+                                        "spatgate_gamma_min", "spatgate_gamma_max",+                                        "spatgate_n_zero_gamma", "spatgate_applied",+                                        "detr_enable", "detr_strength", "detr_min_cells",+                                        "detr_select", "detr_n_types", "detr_n_genes_touched",+                                        "detr_n_entries_zeroed", "detr_nnz_before",+                                         "detr_nnz_after", "detr_pb_shift_max",+                                         "detrx_enable", "detrx_strength", "detrx_n_types",+                                         "detrx_n_cells", "detrx_n_zeroed", "detrx_d_mean",+                                         "detrx_d_min", "detrx_d_max",+                                         "sidecluster", "sidecluster_n_a", "sidecluster_applied")}     print(json.dumps({"bracket": [a["stage"], b["stage"]], **keep}, default=float), file=sys.stderr)     write_t2(args.out, expr, coords, genes, seed=args.seed) 

调研来源?调研员查到并用到的知识条目和文献检索结果(只列标题和编号)。

用到的知识库条目

编号标题出处
k007Interval staging and held-out-window filtering of external datanotes/official/来件/virtualembryo.ai/rules.md
k024World-model evaluation dimensions for state-transition predictorsnotes/competition/07_biomedical_world_models.md
k026Canonicalise predicted 3D coordinates before submissionnotes/pitfalls/04_scorer_invariance.md

分析结果?分析员写的 ANALYSIS.json:改了什么、各组分数怎么变、假设是否成立、经验和下一步建议。

改了什么PLAN 的 SPATGATE(15-NN 空间门控逐基因 γ_g 收缩)被完整实现并在 A 半 7 配置全网格证否(62.19–62.53 全低于父 62.74)后,实际提交的是备选机制 DETR+DETRX:共有类型检出率向几何插值目标 p_a^(1−t)·p_b^t 做 OFF-only 最弱置零(s=2.0),单侧独有类型用共有类型逐基因检出漂移 d_g 作代理(s_ext=0.7);父节点 38 的均匀幅度收缩 γ=0.25 保留,坐标不动。
各组分数的变化cell_state:变好 +3.25(56.74 vs 53.49):variogram raw 0.0117→0.009266,skill 0.433→0.493,得分 +0.75(从地板下回到接近地板);mmd_u raw 0.0103→0.01009,得分 +0.06(噪声内)
expression_change:变好 +1.34(63.44 vs 62.10):de_score raw 0.3103→0.3793,得分 +0.35;de_direction raw 0.3983→0.3958,得分 −0.01(噪声内)
local_spatial:噪声内 −0.23(61.25 vs 61.48):nbhd raw 0.04877→0.04923,得分 −0.06
shape_scale:不变 +0.00(77.31,坐标逐位未动,三项 raw 逐位相同)
family_idT2EI-01
假设是否成立否
经验
  1. 在 node 38 均匀 γ=0.25 收缩之上做空间门控差异化 γ(s_g = var(15-NN均值)/var(x)):门控确实如假设回收 nbhd(7 配置全部 local_spatial +0.4…+0.6,nbhd raw .05143→.0503–.0509),但 variogram/mmd_u 收益与总收缩质量成正比、部分收缩还重排 dp 掉 de_score(.2857→.2143–.25),净亏 0.2–0.6 分——收缩类收益不能靠'少缩一部分基因'来保 nbhd。
  2. s_g 分布压缩在 [0.11, 0.43](有限采样下 NN 均值方差不会趋 0),连续门控 clip(1−s_g/s_ref) 把 γ 整体压到均值 0.03–0.08,远低于名义 γ_max=0.25——设计比例型门控前先查代理统计量的实际分布范围,否则会退化成'几乎不缩'。
  3. DETR(检出率向几何插值 p_a^(1−t)·p_b^t 的 OFF-only 弱值置零)走的是与连续幅度正交的二值检出通道:在本父(已含幅度收缩)上仍拿到 cell_state +3.25、variogram raw .0117→.0093,且 nbhd 不劣化,A 半两种子方向一致(+1.19/+0.76),官方兑现 +1.09——检出模式校准与幅度校准可叠加。
  4. de_score 的 raw 跳升(.2857→.3571)只在 A 半 seed 0 出现、seed 1 回落,是 top-N 命中集合的抽样噪声;跨种子稳定的才是 variogram/mmd_u 收益,选配置时以后者为准。
  5. DETRX 用共有类型量到的逐基因检出漂移 d_g(伪计数 m=10 向全局平滑、只在 d_g<1 时移除)作单侧类型的缺失侧代理,在 ~36% 单侧细胞上叠加 s_ext=0.7 净正(seed 0 +1.19 vs DETR-only +0.71);s_ext=1.0 分更高但 nbhd 回落,0.7 是更安全的门裕度。
mechanism_active是
下一步建议
  1. 针对 cell_state:在本 DETR+DETRX 之上关掉或减弱父的均匀幅度收缩(γ 从 0.25 扫到 0/0.1,T2_RECAL_GAMMA),检验两者是否冗余——node 39 在无收缩 base 上 cell_state 到 59.35,本节点含收缩只到 56.74。
  2. 针对 cell_state/local_spatial:DETRX 的漂移代理 d_g 改成逐类型(而非全基因池化)计算,或按 a-only(衰退型)/b-only(新生型)分别定向漂移,单侧细胞占 ~36%,是当前最大的未精修面。
  3. 针对 local_spatial:variogram skill 已到 0.493(近地板)、nbhd raw .0492 略高于父,可在 DETR 强度上做细扫(s ∈ {1.75, 2.0, 2.25})配合 s_ext,找 nbhd 不劣化的更强检出校准点;B 半/final 视图上 s、s_ext 的可迁移性未验证,final 共有类型更多、DETRX 贡献会变小。

对话摘要?每个角色和大模型对话的统计:轮数、工具调用、用时、token 数和最后的回答摘录;原始记录只给路径。

只给统计和最后回答的摘录;完整对话请到原始记录位置里列出的文件看。

分析员

角色?调研员写计划、工程师改代码、分析员解读分数、审查员检查作弊。分析员 alibaba-token-plan-cn/qwen3.8-max
调用次数1 次
轮数?大模型一共回复了几轮(每轮可以调用多个工具)。3
工具调用?大模型调用读文件、执行命令等工具的次数,按工具名统计。共 2 次:bash 1、write 1
用时1 分
token 数?输入 / 输出(含思考)的 token 数,来自接口返回的用量。输入 21,642 · 输出 1,496 · 思考 1,380
任务(第一行)分析节点 n40 的打分结果,写 ANALYSIS.json
最后的回答(摘录)
ANALYSIS.json written
原始记录位置?完整对话记录在 Spark 上的文件路径;看板不复制原始内容。/home/spark-longxinyang/vec/runs/formal/20261003-171955-search-t2-embryo-interp-chain-12h/nodes/40/analyst.jsonl 7 KB
/home/spark-longxinyang/vec/runs/formal/20261003-171955-search-t2-embryo-interp-chain-12h/nodes/40/analyst.stderr

工程师

角色工程师 alibaba-token-plan-cn/qwen3.8-max
调用次数1 次
轮数69
工具调用共 71 次:bash 34、edit 25、read 11、write 1
用时40 分
token 数输入 158,206 · 输出 28,548 · 思考 43,614
任务(第一行)按计划修改程序:空间结构门控DE幅度收缩(SPATGATE):保cell_state收益、消nbhd代价
最后的回答(摘录)
Done. Final state verified.

**做了什么**:按 PLAN 实现 SPATGATE(15-NN 空间门控逐基因收缩 γ_g),7 配置全网格在 A 半 seed 0 全部低于父节点(62.19–62.53 vs 62.74)——门控确实回收了 nbhd(所有配置 local_spatial +0.4…+0.6),但 variogram/mmd_u 收益与总收缩质量成正比、部分收缩还重排 dp 掉 de_score,净亏,证否。改交备选机制 **DETR+DETRX**:共有类型检出率向几何插值目标 p_a^(1−t)·p_b^t 做 OFF-only 最弱置零(s=2.0,强度扫 1.0–3.0 五档),单侧独有类型(36% 细胞)用共有类型逐基因检出漂移作缺失侧代理(s_ext=0.7,扫 0.35/0.7/1.0)。

**查分结果**(A 半,20 次额度用尽):提交配置 seed 0 = **63.94**(+1.19 vs 父 62.74),seed 1 = **63.11**(+0.76);cell_state +3.4/+3.0(variogram .0121→.0095),nbhd 不劣反微升,de_score seed 0 跳 .2857→.3571(seed 1 回落,抽样噪声)。`--ablate` 与节点 38 逐位一致;伪装视图(+1 天平移、乱序 manifest、换路径)输出逐位相同;vec-check 通过;23 s / 0.6 GB。

**下一步最值得试**:在本管线上关掉/减弱幅度收缩(DETR 与 γ=0.25 收缩可能冗余——node 39 在无收缩 base 上 cell_state 到 59.35,本节点只到 55);DETRX 漂移代理改逐类型或按 a-only/b-only 定向;B 半验证 s、s_ext 可迁移性。
原始记录位置/home/spark-longxinyang/vec/runs/formal/20261003-171955-search-t2-embryo-interp-chain-12h/nodes/40/engineer.jsonl 462 KB
/home/spark-longxinyang/vec/runs/formal/20261003-171955-search-t2-embryo-interp-chain-12h/nodes/40/engineer.stderr

调研员

角色调研员 alibaba-token-plan-cn/qwen3.8-max
调用次数1 次
轮数1
工具调用共 0 次:—
用时3 分
token 数输入 20,507 · 输出 1,391 · 思考 6,629
任务(第一行)为节点 n40(改进,父节点 n38)写改进计划 PLAN.json
最后的回答(摘录)
 53.49仍是最弱组(variogram skill 0.433在地板下),而local_spatial 61.48有0.51可回收损失。节点37的DETR已证明variogram可在不伤nbhd的情况下大幅改善(nbhd raw 0.04779→0.04775),说明存在不破坏配对的cell_state改善路径。",
  "approach": "在父节点38的RECAL步骤中,把均匀γ=0.25改为逐基因空间门控γ_g:\n1. 在输出坐标上建15-NN(与neighborhood_mmd指标同k=15),scipy cKDTree,5000细胞<1 s。\n2. 对DE支持集(|δ|≥0.25且|dp|≥0.3,本视图51基因)中每个基因g,计算空间结构比 s_g = var(NN均值_g) / var(x_g)。s_g高→表达有空间模式,收缩会扭曲邻域表达环境;s_g低→空间均匀,收缩不影响邻域结构。\n3. γ_g = γ_max · clip(1 − s_g / s_ref, 0, 1),s_ref取支持集内s_g的指定分位数。空间结构强的基因γ_g→0(不缩),空间均匀的基因γ_g→γ_max(全缩)。\n4. 逐列乘性缩放 k_g = 1 − γ_g·dp_g/pb_out_g(与父节点相同的精确pb缩放),零模式、基因内排序、坐标不动。\n5. 网格:γ_max ∈ {0.25, 0.35},s_ref ∈ {p50, p75, p90}(支持集内s_g分位数),共6配置 + 父节点均匀γ=0.25对照。用vec-score A半seed 0快筛,选前2配置跑seed 1/2确认。\n6. 若连续门控全网格无改善,尝试二值门控:s_g > median的基因γ=0、其余γ=0.25,作为最简对照。\n7. 单输入阶段退路:与父节点相同,无括号时不经过本步。\n8. 预期提升幅度<1分噪声,需3种子方向一致确认。",
  "expected_groups": ["local_spatial", "cell_state"],
  "risks": "1. s_g可能不是nbhd敏感性的正确代理——若nbhd损伤来自PCA投影权重变化而非空间模式,门控无效。Engineer应在首配置后检查:被排除基因(γ_g≈0)是否确实是高空间自相关基因,且排除后nbhd raw是否回落。2. 若支持集51基因中s_g分布过于集中(全部高或全部低),门控退化为恒等或均匀收缩,无区分度——此时应检查s_g分布并考虑换用Moran's I或邻域方差绝对值。3. 收益在1分噪声内,需3种子确认。4. 15-NN增加~1 s运行时间,不影响时限。",
  "family_id": "T2EI-01",
  "mechanism": "把父节点的均匀DE幅度收缩改为逐基因空间门控:每个基因按其输出表达的空间自相关程度(15-NN均值方差/全局方差)连续调节收缩强度γ_g∈[0, γ_max],空间结构强的基因不缩、空间均匀的基因全缩,保住幅度校准收益同时避免破坏表达-位置配对。",
  "vs_constant_shift": "常数位移对所有细胞所有基因加同一偏移;本机制是逐基因乘性缩放,且缩放系数由每个基因的空间结构连续决定(γ从0到γ_max),空间模式强的基因完全不被修改。不改变细胞比例(非组成重加权),不改变坐标,不改变零模式;不同基因得到不同强度的校准。",
  "mechanism_evidence": "1. γ_g分布应呈宽分布或双峰(空间均匀基因γ≈0.25,空间结构基因γ≈0),而非父节点的单值0.25;若全部γ_g相同则门控未生效。2. nbhd raw应从0.04877回到≤0.0478(父36水平),同时variogram raw保持≤0.0120。3. 四组分:local_spatial应回到≥62(消掉−0.51),cell_state保持≥52.5(可能略低于53.49因部分基因不缩)。4. 被门控排除的基因列表应与输出中15-NN均值方差最高的基因一致(可打印前10个验证)。",
  "mechanism_off_control": "--ablate mechanism 设所有γ_g = γ_max = 0.25(退回父节点38的均匀收缩,忽略空间门控),输出应与父节点38 seed 0逐位一致(可验证sha256)。预期差别:ablate后nbhd raw回到0.04877(父38水平)、local_spatial 61.48;默认配置应展示nbhd改善(raw下降)+ cell_state基本保持。若ablate与默认输出逐位相同,说明所有基因的s_g都在阈值同侧,门控未实际运行。"
}
```
原始记录位置/home/spark-longxinyang/vec/runs/formal/20261003-171955-search-t2-embryo-interp-chain-12h/nodes/40/researcher.jsonl 5 KB
/home/spark-longxinyang/vec/runs/formal/20261003-171955-search-t2-embryo-interp-chain-12h/nodes/40/researcher.stderr

审查员

角色审查员 alibaba-token-plan-cn/qwen3.8-max
调用次数1 次
轮数11
工具调用共 17 次:read 9、bash 5、grep 2、write 1
用时3 分
token 数输入 63,747 · 输出 2,375 · 思考 2,584
任务(第一行)审查节点 n40 的程序是否越界读取、写死目标、钻评分器漏洞
最后的回答(摘录)
REVIEW.json written
原始记录位置/home/spark-longxinyang/vec/runs/formal/20261003-171955-search-t2-embryo-interp-chain-12h/nodes/40/reviewer.jsonl 317 KB
/home/spark-longxinyang/vec/runs/formal/20261003-171955-search-t2-embryo-interp-chain-12h/nodes/40/reviewer.stderr