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

总览 · ← 返回运行 20261003-004922-search-t2-heart-interp-g24-D

节点 n18

在 mix 上实现 T2HI-05 型内径向尺度插值(型内径向 RMS 按 t 插值,s=(r_t/r_out)^strength 径向缩放坐标);5 档全低于关闭对照,按止损以 strength=0 提交,与父节点逐位相同。

运行?一次完整的自动搜索或 Agent 会话,有自己的锁定配置和证据包。20261003-004922-search-t2-heart-interp-g24-D
父节点n12
子节点—
操作?种子:人写的起点;改进:在父节点上改;草稿:从头写;修复:修父节点的报错。改进
状态已打分
分数搜索目标分 59.50(+0.0) · proxy 59.50(+0.0)
审查未审查
用时?从运行开始到结束(或到现在)的挂钟时间。23 分
程序版本119eb56d2e2ced8c363cfb707de227e6452fa58f (programs.git)

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

来自 programs.git 119eb56d2e:solution/METHOD.md

在 mix 上实现 T2HI-05 型内径向尺度插值(型内径向 RMS 按 t 插值,s=(r_t/r_out)^strength 径向缩放坐标);5 档全低于关闭对照,按止损以 strength=0 提交,与父节点逐位相同。

方法族与机制

  • family_id: T2HI-05(mix 基线 + 型内径向尺度插值修正 shape_scale)。
  • 机制:对每个输出细胞型,在两个括号输入阶段的对齐+目标 RMS 缩放帧(与 mix 内部完全相同的 align_pair + scale_to_rms,procrustes、保 z)里计算该型细胞到型心的径向 RMS r_a、r_b;目标 r_t=(1−t)·r_a+t·r_b(仅一侧有该型时退化为该侧值);在输出云中计算该型到输出型心的径向 RMS r_out,缩放因子 s=(r_t/r_out)^strength,裁剪到 [1−clip, 1+clip];每个细胞 new_pos = c_out + (pos−c_out)·s(纯径向,中心不动、边缘最多)。表达、细胞数、类型组成完全不动。与常数位移的区别:位移=(s−1)×径向向量,逐型独立。
  • 输出细胞来源用 mix_indices 以同一 default_rng(params["seed"]) 重放(沿用节点12 验证过的做法),断言 len(ia)==n_from_a,把型标签落到正确行。
  • 单输入(无括号)退路:与父节点相同,直接分层抽样输出,不做任何校正。
  • 所有时间量都用 manifest 的相对时间(t 来自括号),无绝对时间、无视图相关分支。

关闭对照(mechanism_off_control)

--strength 0 ⇒ s^0=1 ⇒ 所有坐标不动。实测与父节点12 默认输出逐位相同(X 与 spatial_3D 均 np.array_equal,seed 0,proxy 视图)。父的趋势位移机制也保留为 --trend(默认 0,节点12 已证伪)。

机制生效证据(proxy:E8.25+E9.5→E8.75,t=0.4,n=17616)

  • 全部 50 个型被校正,17616 个细胞全部移动;s 均值 0.973–0.993(<1:输出型内云比时间插值目标更弥散,因为 procrustes 只有 5 个共有型,两侧同名型的型心未完全对齐,合并后围绕联合型心的径向 RMS 被抬高),s 的 min/max 大量触及裁剪边界(0.8/1.2 到 0.95/1.05),机制确有空间、并非空转。
  • 全局 out_rms 不变(346.33,径向缩放绕各型心、不改变型心布局)。
  • 坐标最大位移:clip0.05→36、clip0.10→72、clip0.20→125(微米级,真实移动)。

查分结果(vec-score,A 半,共 5 次,余 15)

配置榜分shape_scalelocal_spatialcell_stateexpr_change
父(strength=0)59.5053.3754.0366.7063.90
s=1.0, clip=0.0558.9652.6553.4265.9363.83
s=0.5, clip=0.0558.9952.7253.4965.9363.83
s=1.0, clip=0.1059.0652.9553.5565.9363.83
s=1.5, clip=0.2058.9352.4253.5365.9363.83

四组分开看:目标组 shape_scale 全线下滑(53.37→52.4–53.0,d2_shape 0.041→0.043、occupancy_dice 0.835→0.831、scale_log_ratio 0.467→0.445–0.455——注意 out_rms 逐位不变而 scale_log_ratio 仍变,说明它含抽样/型内成分或评分噪声);local_spatial 也降(54.03→53.4–53.6,径向收缩破坏型内局部结构);cell_state/expression_change 在 X 逐位不变下从 66.70/63.90 变为 65.93/63.83,且 4 个不同坐标的配置给出完全相同的值——这是评分器抽样噪声(约 ±0.8),不是机制效果,但也说明小幅榜分差不能全信。

结论与止损

假设在 proxy 上证伪:型内径向尺度校正的收缩方向(s<1)把细胞推向型心,d2_shape/occupancy/邻域全变差;强度、裁剪单调地越弱越接近基线,无任何配置 ≥ 基线+1。按 PLAN 止损条款以 strength=0 提交(与父节点12 逐位一致,预期 59.50)。

验证过 / 没验证

  • 验证过:strength=0 逐位对照(X+坐标);5 档配置的 proxy 查分;vec-check 通过;运行时 ~2.2s、内存远低于上限;确定性(所有 rng 以 seed 播种,校正本身无随机)。
  • 没验证:final 视图(354→217 括号,型内尺度差更大,机制方向可能不同,但 proxy 上收缩方向已明确有害,未冒险);proxy2 不适用(本节点板为 T2:heart:val_interp,单视图);strength>2 或负 strength(膨胀方向,与机制假设相反);各向异性/按轴缩放(节点17 已在 proxy 证伪)。

知识来源

未使用任何保留阶段/基因型的测量信息;未使用文献数值。仅用了 mix 管线已有的通用几何操作(型心、RMS、procrustes 对齐),全部从视图数据现场计算。

给后续节点

  • shape_scale 的 scale_log_ratio 短板是全局 out_rms(346 vs 真实 E8.75 的 217)问题,型内径向缩放改不了全局 RMS(绕型心缩放保持型心布局),这条路线在 proxy 上走不通;要动 out_rms 只能改全局 scale_damp/目标 RMS,但方法卡已注明代理两端都大、验证不了。
  • 评分器对 X 逐位相同的预测给出过 66.70 与 65.93 两个 cell_state 值(不同坐标文件),榜分噪声约 ±0.5–0.8,小于 1 分的差异不要当作机制效果。
  • 型内径向收缩与节点15/17 的 kNN 平滑方向相反(一个散开一个致密):17 的致密化 +6.37 local_spatial,本节点的收缩 −0.5,进一步支持"局部致密化有效、去弥散有害"。

调研员的计划

名称mix基线型内径向尺度插值修正shape_scale
动机shape_scale 53.37 是父节点12(=节点2 mix)最弱组,scale_log_ratio 0.467 为主要短板(out_rms=346 偏大)。mix 用全局 log 线性 RMS 缩放两朵云,无法捕捉型特异尺度变化:不同型在两个输入阶段的型内扩展(到型心距离)趋势可能不同,全局缩放后型内尺度系统性偏差。节点15已证明坐标侧操作可在不扰动表达/组成的前提下提升分组(local_spatial +6.37),本方案继续坐标侧但针对尺度而非平滑,与节点15/17方向正交。
做法1) 复制节点12 run.py,保留 --trend 0 逐位对照不变。2) 在 mix 输出后新增型内径向尺度校正:对每个细胞型,在输入阶段 a、b 分别计算该型细胞到型心的 RMS 距离 r_a、r_b;目标 r_t=(1-t)r_a+tr_b;在输出中计算该型到输出型心的 RMS 距离 r_out;缩放因子 s=(r_t/r_out)^strength。3) 对每个该型细胞:new_pos = centroid_out + (pos−centroid_out)*s,坐标其余不动。4) 裁剪:s 限制在 [1−clip, 1+clip]。5) 网格:strength∈{0,0.5,1.0,1.5},clip∈{0.05,0.10,0.20};先跑 strength=0 确认与父逐位一致(np.array_equal),再跑 6-8 个配置,用 vec-score A 半筛选;若最佳配置≤基线+1 分则以 strength=0 提交(止损)。6) 单输入退路:无括号时不做校正,直接沿用父回退。7) proxy2/final:同样用两个输入的型内尺度插值,缺失基因不影响坐标;final 括号尺度差更大(354→217),型内校正空间更大。8) 实现注意:复用节点12已有的 read_stage/type_means 工具函数;型心用稀疏矩阵 mean 即可;需断言每个型至少 2 个细胞否则跳过。
风险proxy 两阶段全局 RMS 仅差 5%(354 vs 335),型内尺度差异可能更小,所有型的 s 都落在 [0.98,1.02] 内则机制无空间——Engineer 前 2 次查分若 |Δ|<1 应止损;径向缩放改变型内细胞间距,可能轻微影响 local_spatial(预期 <1 分),需监控;型心计算依赖标签完整性,需断言标签非空。

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

对比:父节点版本 7c5a1fbaee。改动的文件:solution/METHOD.md +35 −26、solution/run.py +109 −0

diff --git a/solution/METHOD.md b/solution/METHOD.mdindex d91e800..1bef6d2 100644--- a/solution/METHOD.md+++ b/solution/METHOD.md@@ -1,41 +1,50 @@-在 mix(节点2)上实现型×基因时间趋势位移(同名/伪批量相关配对+全局回退,±0.5SD 裁剪);6 档强度全部低于关闭对照,按 PLAN 止损条款以 trend=0(与父节点逐位一致)提交。+在 mix 上实现 T2HI-05 型内径向尺度插值(型内径向 RMS 按 t 插值,s=(r_t/r_out)^strength 径向缩放坐标);5 档全低于关闭对照,按止损以 strength=0 提交,与父节点逐位相同。 -## 方法+## 方法族与机制 -基线 = 父节点2 的 `mix`(align=procrustes, scale_damp=1):取目标前后最近两个输入括号,两朵云对齐并缩放到 log 线性 RMS,按 (1−t, t) 分层抽真实细胞,表达坐标一起走。+- family_id: T2HI-05(mix 基线 + 型内径向尺度插值修正 shape_scale)。+- 机制:对每个输出细胞型,在两个括号输入阶段的对齐+目标 RMS 缩放帧(与 mix 内部完全相同的 `align_pair` + `scale_to_rms`,procrustes、保 z)里计算该型细胞到型心的径向 RMS r_a、r_b;目标 r_t=(1−t)·r_a+t·r_b(仅一侧有该型时退化为该侧值);在输出云中计算该型到输出型心的径向 RMS r_out,缩放因子 s=(r_t/r_out)^strength,裁剪到 [1−clip, 1+clip];每个细胞 new_pos = c_out + (pos−c_out)·s(纯径向,中心不动、边缘最多)。表达、细胞数、类型组成完全不动。与常数位移的区别:位移=(s−1)×径向向量,逐型独立。+- 输出细胞来源用 `mix_indices` 以同一 `default_rng(params["seed"])` 重放(沿用节点12 验证过的做法),断言 `len(ia)==n_from_a`,把型标签落到正确行。+- 单输入(无括号)退路:与父节点相同,直接分层抽样输出,不做任何校正。+- 所有时间量都用 manifest 的相对时间(t 来自括号),无绝对时间、无视图相关分支。 -在此之上实现了 PLAN 指定的家族机制 T2HI-01(`--trend` / `--clip` / `--pair-r` 开关):+## 关闭对照(mechanism_off_control) -1. 细胞型跨阶段配对:同名型直接配;非共有型用两阶段伪批量均值(500 基因)的 Pearson 相关取最优,阈值 r≥0.6;配不上的型回退到全局伪批量均值差。-2. 每(型,基因)斜率 m = mean_paired − mean_own;对每个抽中细胞按来源阶段取带符号几何时间分数:早阶段 α=t(前推)、晚阶段 α=t−1(回拉),delta = α·trend·m。-3. 裁剪:|delta| ≤ clip × 该型该基因在来源阶段的细胞级 SD(默认 clip=0.5)。-4. 坐标、细胞数、分层抽样完全不动;单输入(无括号)沿用父回退且不做位移。-5. 来源阶段复原:用同一 `default_rng(seed)` 重放 `mix_indices`(它是 interpolate 里第一个 rng 消费者),并断言 `len(ia)==info["n_from_a"]`,不一致即报错,保证位移落在正确的行上。+`--strength 0` ⇒ s^0=1 ⇒ 所有坐标不动。实测与父节点12 默认输出**逐位相同**(X 与 spatial_3D 均 `np.array_equal`,seed 0,proxy 视图)。父的趋势位移机制也保留为 `--trend`(默认 0,节点12 已证伪)。 -## 对照与证据(proxy, seed 0)+## 机制生效证据(proxy:E8.25+E9.5→E8.75,t=0.4,n=17616) -- 关闭对照(`--trend 0`)与父节点2 输出**逐位相同**(X 与 spatial_3D 均 `np.array_equal` True),位移逻辑不泄漏到抽样/坐标;预期分 59.50。-- 机制生效证据(trend=1, clip=0.5):89.1% 细胞拿到型特异斜率(其余走全局回退);54.2% 的表达值被改变,mean|delta|=0.115;早/晚来源阶段 α 符号相反(+t vs t−1);坐标逐位不变。+- 全部 50 个型被校正,17616 个细胞全部移动;s 均值 0.973–0.993(<1:输出型内云比时间插值目标更弥散,因为 procrustes 只有 5 个共有型,两侧同名型的型心未完全对齐,合并后围绕联合型心的径向 RMS 被抬高),s 的 min/max 大量触及裁剪边界(0.8/1.2 到 0.95/1.05),机制确有空间、并非空转。+- 全局 out_rms 不变(346.33,径向缩放绕各型心、不改变型心布局)。+- 坐标最大位移:clip0.05→36、clip0.10→72、clip0.20→125(微米级,真实移动)。 -## vec-score 网格(A 半;父=59.50:cell_state 66.70 / expr_change 63.90 / local 54.03 / shape 53.37)+## 查分结果(vec-score,A 半,共 5 次,余 15) -| 配置 | 榜分 | expr_change | cell_state | local | shape |+| 配置 | 榜分 | shape_scale | local_spatial | cell_state | expr_change | |---|---:|---:|---:|---:|---:|-| trend1 clip0.5 | 55.49 | 66.84 | 53.50 | 49.30 | 52.33 |-| trend0.5 clip0.3 | 56.88 | 65.51 | 57.79 | 51.14 | 53.07 |-| trend0.3 clip0.5 | 57.54 | 65.72 | 59.58 | 51.81 | 53.07 |-| 仅早侧位移 trend1 | 56.78 | 64.33 | 61.86 | 48.96 | 51.97 |-| 仅晚侧位移 trend1 | 57.54 | 67.37 | 57.38 | 52.35 | 53.07 |-| trend0.2 clip0.2 | 57.88 | 64.66 | 61.35 | 52.42 | 53.07 |+| 父(strength=0) | 59.50 | 53.37 | 54.03 | 66.70 | 63.90 |+| s=1.0, clip=0.05 | 58.96 | 52.65 | 53.42 | 65.93 | 63.83 |+| s=0.5, clip=0.05 | 58.99 | 52.72 | 53.49 | 65.93 | 63.83 |+| s=1.0, clip=0.10 | 59.06 | 52.95 | 53.55 | 65.93 | 63.83 |+| s=1.5, clip=0.20 | 58.93 | 52.42 | 53.53 | 65.93 | 63.83 | -结论:expression_change 随强度单调上升(至 +3.5),但 cell_state(mmd_u)与 local_spatial(neighborhood_mmd)下降更快,榜分随 trend→0 单调回到 59.5。PLAN 风险①兑现——mix 基线的 expr_change 已 63.9(节点7 基线仅 44.3),真实中间态细胞本身已编码目标时间的表达,逐型常数位移把细胞推离真实流形,得不偿失。按 PLAN 的止损条款,提交版本默认 `TREND=0`(行为=父节点),机制代码保留、开关可用。+四组分开看:目标组 shape_scale 全线下滑(53.37→52.4–53.0,d2_shape 0.041→0.043、occupancy_dice 0.835→0.831、scale_log_ratio 0.467→0.445–0.455——注意 out_rms 逐位不变而 scale_log_ratio 仍变,说明它含抽样/型内成分或评分噪声);local_spatial 也降(54.03→53.4–53.6,径向收缩破坏型内局部结构);cell_state/expression_change 在 X 逐位不变下从 66.70/63.90 变为 65.93/63.83,且 4 个不同坐标的配置给出完全相同的值——这是评分器抽样噪声(约 ±0.8),不是机制效果,但也说明小幅榜分差不能全信。 -## 未验证 / 风险+## 结论与止损 -- 位移在 final 括号(31 个共有型、t=0.5)上未验证;proxy 结论(基线 expr_change 已高)在 final 上大概率同样成立,但型特异覆盖会更高,若未来节点想重试,建议 trend≤0.3 且先查一次分。-- shape_scale 在表达被改动的配置下也小幅波动(51.97–53.07 vs 53.37),尽管 d2_shape/occupancy/scale_log_ratio 三项指标逐位不变,说明该组还依赖表达;未深究。-- proxy 上 out_rms=346 vs 参考 RMS 更小(scale_log_ratio 0.467)是 shape_scale 的主要短板,但两端 RMS 都大(354/335),任何尺度阻尼都需外推 damp≫1,在 final(354→217 括号)上方向不可验证,未尝试(PLAN 明确本轮不修 shape)。+假设在 proxy 上证伪:型内径向尺度校正的收缩方向(s<1)把细胞推向型心,d2_shape/occupancy/邻域全变差;强度、裁剪单调地越弱越接近基线,无任何配置 ≥ 基线+1。按 PLAN 止损条款以 strength=0 提交(与父节点12 逐位一致,预期 59.50)。++## 验证过 / 没验证++- 验证过:strength=0 逐位对照(X+坐标);5 档配置的 proxy 查分;vec-check 通过;运行时 ~2.2s、内存远低于上限;确定性(所有 rng 以 seed 播种,校正本身无随机)。+- 没验证:final 视图(354→217 括号,型内尺度差更大,机制方向可能不同,但 proxy 上收缩方向已明确有害,未冒险);proxy2 不适用(本节点板为 T2:heart:val_interp,单视图);strength>2 或负 strength(膨胀方向,与机制假设相反);各向异性/按轴缩放(节点17 已在 proxy 证伪)。  ## 知识来源 -仅通用机制知识:伪批量均值差近似细胞型的时间趋势、Pearson 相关做型配对、log1p 表达上加性位移后截断到 ≥0。未使用任何保留阶段/基因型的测量信息;程序只读 manifest 的相对时间,对时间平移不变(t、α 均为差值之比)。+未使用任何保留阶段/基因型的测量信息;未使用文献数值。仅用了 mix 管线已有的通用几何操作(型心、RMS、procrustes 对齐),全部从视图数据现场计算。++## 给后续节点++- shape_scale 的 scale_log_ratio 短板是全局 out_rms(346 vs 真实 E8.75 的 217)问题,型内径向缩放改不了全局 RMS(绕型心缩放保持型心布局),这条路线在 proxy 上走不通;要动 out_rms 只能改全局 scale_damp/目标 RMS,但方法卡已注明代理两端都大、验证不了。+- 评分器对 X 逐位相同的预测给出过 66.70 与 65.93 两个 cell_state 值(不同坐标文件),榜分噪声约 ±0.5–0.8,小于 1 分的差异不要当作机制效果。+- 型内径向收缩与节点15/17 的 kNN 平滑方向相反(一个散开一个致密):17 的致密化 +6.37 local_spatial,本节点的收缩 −0.5,进一步支持"局部致密化有效、去弥散有害"。diff --git a/solution/run.py b/solution/run.pyindex 89837f2..e42820a 100644--- a/solution/run.py+++ b/solution/run.py@@ -25,6 +25,18 @@ stage. Coordinates, cell counts and composition are untouched. output bit-for-bit. Single input (no bracket): parent fallback, no displacement (alpha undefined). All times used are relative (from the manifest); behaviour is invariant to a uniform time shift of the view.++On top of that (T2HI-05, off by default): ``--strength > 0`` applies a+per-type radial scale correction to the mixed coordinates. For each cell type,+the within-type radial RMS (distance to the type centroid) is interpolated in+time from the two bracketing stages (r_t = (1-t) r_a + t r_b, measured in the+aligned, target-RMS-rescaled frames the mix itself uses), and every output+cell of that type is moved radially around the output type centroid by+s = (r_t / r_out) ** strength, clipped to [1 - scale_clip, 1 + scale_clip].+Expression, cell counts and composition are untouched. ``--strength 0``+leaves s == 1 and reproduces the parent output bit-for-bit; all proxy+configurations tried scored below the strength=0 baseline (see METHOD.md), so+the shipped default keeps the correction off. """  from __future__ import annotations@@ -35,6 +47,7 @@ import sys  import numpy as np +from src.task2_spatial.frame import align_pair, log_interp, rms_radius, scale_to_rms from src.task2_spatial.methods import interpolate from src.task2_spatial.sample import mix_indices, take from src.task2_spatial.shift import type_means@@ -47,6 +60,79 @@ CLIP = 0.5 # below the no-displacement baseline on every configuration tried, so the # shipped default keeps it off (--trend > 0 re-enables the family mechanism). TREND = 0.0+# Per-type radial scale correction (T2HI-05): strength 0 reproduces the parent+# output bit-for-bit (s**0 == 1 leaves every coordinate untouched).+STRENGTH = 0.0+SCALE_CLIP = 0.10+++def _radial_rms(points: np.ndarray) -> float:+    """RMS distance of points to their own centroid."""+    if len(points) == 0:+        return float("nan")+    x = points - points.mean(axis=0)+    return float(np.sqrt((x * x).sum(axis=1).mean()))+++def _radial_scale_correct(coords, out_labels, ca, cb, labels_a, labels_b,+                          t, strength, clip, min_cells=2):+    """Per-type radial scale interpolation (T2HI-05).++    For every cell type present in the output: r_a = within-type radial RMS at+    stage a (in the aligned, target-RMS-rescaled frame ca), r_b likewise at+    stage b, target r_t = (1 - t) r_a + t r_b. The output cloud's within-type+    radial RMS r_out (around the output type centroid) is corrected to r_t via+    s = (r_t / r_out) ** strength clipped to [1 - clip, 1 + clip]; each cell+    moves along the radial direction only: p -> c_out + (p - c_out) * s.+    Coordinates are modified in place; returns evidence dict.+    """+    out_labels = np.asarray(out_labels).astype(str)+    la = np.asarray(labels_a).astype(str)+    lb = np.asarray(labels_b).astype(str)+    s_stats = {}+    n_corrected = 0+    for lab in np.unique(out_labels):+        m = out_labels == lab+        pts = coords[m]+        if int(m.sum()) < min_cells:+            continue+        c_out = pts.mean(axis=0)+        r_out = _radial_rms(pts)+        if not np.isfinite(r_out) or r_out < 1e-8:+            continue+        r_side = []+        w_side = []+        ma = la == lab+        if ma.any():+            r_side.append(_radial_rms(ca[ma]))+            w_side.append(1.0 - t)+        mb = lb == lab+        if mb.any():+            r_side.append(_radial_rms(cb[mb]))+            w_side.append(t)+        if not r_side or not np.isfinite(r_side).all():+            continue+        w = np.asarray(w_side, dtype=np.float64)+        if w.sum() <= 0:+            continue+        r_t = float((np.asarray(r_side) * w).sum() / w.sum())+        s = (r_t / r_out) ** float(strength)+        s = float(np.clip(s, 1.0 - clip, 1.0 + clip))+        s_stats[lab] = {"r_a": r_side[0] if ma.any() else None,+                        "r_b": r_side[-1] if mb.any() else None,+                        "r_t": r_t, "r_out": r_out, "s": s, "n": int(m.sum())}+        if abs(s - 1.0) > 1e-12:+            coords[m] = c_out + (pts - c_out) * s+            n_corrected += int(m.sum())+    ss = np.array([v["s"] for v in s_stats.values()]) if s_stats else np.array([1.0])+    ev = {+        "n_types_corrected": int(len(s_stats)),+        "cells_moved": n_corrected,+        "s_mean": float(ss.mean()),+        "s_min": float(ss.min()),+        "s_max": float(ss.max()),+    }+    return ev   def _pair_map(own: dict, other: dict, thresh: float) -> dict:@@ -106,6 +192,8 @@ def main() -> None:     parser.add_argument("--trend", type=float, default=TREND)     parser.add_argument("--clip", type=float, default=CLIP)     parser.add_argument("--pair-r", type=float, default=PAIR_R)+    parser.add_argument("--strength", type=float, default=STRENGTH)+    parser.add_argument("--scale-clip", type=float, default=SCALE_CLIP)     args = parser.parse_args()      manifest = load_manifest(args.data)@@ -123,6 +211,27 @@ def main() -> None:     expr, coords, info = interpolate(stage_a, stage_b, t, params)      ev = {}+    if args.strength != 0.0:+        n = int(info["n"])+        n_from_a = int(info["n_from_a"])+        rng = np.random.default_rng(int(params["seed"]))+        ia, ib = mix_indices(stage_a.labels, stage_b.labels, t, n, rng)+        if len(ia) != n_from_a or len(ia) + len(ib) != n:+            raise RuntimeError("source reproduction mismatch")+        # Frame-consistent per-type spreads: same alignment + global rescale mix used.+        aligned_a, aligned_b, _ = align_pair(+            stage_a.coords, stage_b.coords, stage_a.labels, stage_b.labels, str(params.get("align", "procrustes")))+        rms_a = rms_radius(stage_a.coords)+        rms_b = rms_radius(stage_b.coords)+        target_rms = log_interp(rms_a, rms_b, t, float(params.get("scale_damp", 1.0)))+        ca = scale_to_rms(aligned_a, target_rms)+        cb = scale_to_rms(aligned_b, target_rms)+        la = np.asarray(stage_a.labels).astype(str)+        lb = np.asarray(stage_b.labels).astype(str)+        lab_out = np.concatenate([la[ia], lb[ib]]) if n_from_a else lb[ib]+        coords = np.asarray(coords, dtype=np.float64).copy()+        ev.update(_radial_scale_correct(coords, lab_out, ca, cb, la, lb,+                                        t, args.strength, args.scale_clip))     if args.trend != 0.0:         n = int(info["n"])         n_from_a = int(info["n_from_a"])

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

用到的知识库条目

编号标题出处
k007Interval staging and held-out-window filtering of external datanotes/official/来件/virtualembryo.ai/rules.md
k026Canonicalise predicted 3D coordinates before submissionnotes/pitfalls/04_scorer_invariance.md
k027Joint expression-geometry generation with relative geometrynotes/competition/03_solution_landscape.md

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

改了什么在节点12(mix)代码上实现了 T2HI-05 型内径向尺度插值(--strength/--scale-clip 开关,逐型 r_t=(1−t)r_a+t·r_b,s=(r_t/r_out)^strength 绕输出型心径向缩放),但 proxy 上 4 档配置全部低于基线,按 PLAN 止损条款以 strength=0 提交,输出与父节点逐位相同。
各组分数的变化cell_state:噪声内 +0.00(66.70→66.70,提交输出与父逐位一致)
expression_change:噪声内 +0.00(63.90→63.90,提交输出与父逐位一致)
local_spatial:噪声内 +0.00(54.03→54.03;机制开启时实测降至 53.4–53.6)
shape_scale:噪声内 +0.00(53.37→53.37,目标组未改善;机制开启时实测反降至 52.4–53.0)
family_idT2HI-05
假设是否成立否
经验
  1. 在 T2:heart proxy(E8.25+E9.5→E8.75)上,mix 输出的型内径向 RMS 系统性大于时间插值目标(s≈0.97–0.99),逐型径向收缩(s<1)使 shape_scale 从 53.37 降到 52.4–53.0、local_spatial 降约 0.5,且强度/裁剪越弱越接近基线——去弥散方向明确有害,与节点15/17 的'局部致密化 +6.37 local_spatial'结论相反,二者合起来支持'致密化有效、径向收缩有害'。
  2. shape_scale 的短板 scale_log_ratio(0.467)由全局 out_rms=346 vs 真实 217 决定;绕型心的径向缩放保持型心布局、不改全局 RMS(实测 out_rms 逐位不变),因此型内尺度操作原理上修不了这个指标,后续不要再走型内径向缩放路线修 shape_scale。
  3. 评分器对 X 逐位相同的预测给出过 cell_state 66.70 与 65.93 两个值,且 4 个不同坐标配置给出完全相同的 cell_state/expression_change——榜分噪声约 ±0.5–0.8,小于 1 分的差异不能当作机制效果;查分时先看指标明细是否逐位变化再下结论。
  4. 止损机制有效:本节点 5 次查分即证伪假设,以 strength=0 提交保住了 59.50 基线,未浪费预算;'关闭对照逐位一致(np.array_equal)+ 网格低于基线即回退'的模式可复用。
mechanism_active否
下一步建议
  1. 针对 local_spatial/shape_scale:沿节点17 的 kNN 致密化方向继续(当前最佳 61.41),本节点结果进一步支持致密化,可试更强的邻域收缩权重或叠加到 mix 基线。
  2. 针对 shape_scale:全局 out_rms 过大是唯一可动杠杆,但 proxy 两端 RMS 都大(354/335)无法验证外推 damp>1 的方向;若某节点能在 final 视图(354→217 括号)上安全试跑,再考虑全局 scale_damp 外推,proxy 上不要试。
  3. 不要重试 T2HI-05 型内径向缩放(含膨胀方向 strength<0 或各向异性按轴缩放——节点17 已在 proxy 证伪),除非有新证据表明输出型内尺度偏小而非偏大。

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

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

分析员

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

工程师

角色工程师 alibaba-token-plan-cn/qwen3.8-max
调用次数1 次
轮数26
工具调用共 29 次:bash 17、edit 7、read 4、write 1
用时15 分
token 数输入 64,069 · 输出 9,785 · 思考 10,051
任务(第一行)按计划修改程序:mix基线型内径向尺度插值修正shape_scale
最后的回答(摘录)
完成。总结:

**做了什么**:在节点12(mix)上按 PLAN 实现 T2HI-05 型内径向尺度插值:逐型在对齐+目标RMS帧里算 r_a/r_b,r_t=(1−t)r_a+t·r_b,s=(r_t/r_out)^strength 裁剪后绕输出型心径向缩放坐标,表达/组成不动;保留 `--strength 0` 逐位关闭对照(实测 X 与 spatial_3D 均与父 `np.array_equal`)。

**查分结果**(5/20 次):机制确有空间(50 型全动、s 触裁剪边界、坐标最大位移 36–125),但 4 档配置(strength 0.5–1.5 × clip 0.05–0.20)榜分 58.93–59.06,全低于基线 59.50;目标组 shape_scale 反降(53.37→52.4–53.0),local_spatial 也降。径向收缩把细胞推向型心,与节点15/17 证明有效的局部致密化方向相反。按 PLAN 止损以 strength=0 提交(与父逐位一致,预期 59.50),`vec-check` 通过,seed 1 确定性验证通过。

**下一步最值得试**:(1) shape_scale 的短板是全局 out_rms(346 vs 真实 217),型内缩放改不了它——只能想办法约束全局尺度,但 proxy 括号验证不了方向;(2) 沿节点17 的 kNN 致密化继续(当前最佳 61.41),本节点结果进一步支持"致密化有效、去弥散有害";(3) 注意评分噪声:X 逐位相同时 cell_state 出现 66.70/65.93 两个值,<1 分差异不可信。
原始记录位置/home/spark-longxinyang/vec/runs/formal/20261003-004922-search-t2-heart-interp-g24-D/nodes/18/engineer.jsonl 188 KB
/home/spark-longxinyang/vec/runs/formal/20261003-004922-search-t2-heart-interp-g24-D/nodes/18/engineer.stderr

调研员

角色调研员 alibaba-token-plan-cn/qwen3.8-max
调用次数1 次
轮数1
工具调用共 0 次:—
用时7 分
token 数输入 11,830 · 输出 11,817 · 思考 8,192
任务(第一行)为节点 n18(改进,父节点 n12)写改进计划 PLAN.json
最后的回答(摘录)
7已经在做了。

我不组合,只做径向尺度校正。如果成功,未来节点可以组合。

最终方案确定。写JSON。

让我再检查一下合规性:
- 数据只用视图里的:是的,只用输入阶段的坐标和标签
- 不硬编码保留阶段的统计量:是的,尺度是从输入阶段动态计算的
- 不针对打分器漏洞优化:是的,径向尺度校正是合理的几何操作
- 对时间平移不变:是的,用的是相对时间t
- 对视图伪装不变:是的,不依赖具体路径或阶段名

好的,一切合规。

现在让我写最终的、完整的方案。
</think>

{
  "name": "mix基线型内径向尺度插值修正shape_scale",
  "motivation": "shape_scale 53.37 是父节点12(=节点2 mix)最弱组,scale_log_ratio 0.467 为主要短板(out_rms=346 偏大)。mix 用全局 log 线性 RMS 缩放两朵云,无法捕捉型特异尺度变化:不同型在两个输入阶段的型内扩展(到型心距离)趋势可能不同,全局缩放后型内尺度系统性偏差。节点15已证明坐标侧操作可在不扰动表达/组成的前提下提升分组(local_spatial +6.37),本方案继续坐标侧但针对尺度而非平滑,与节点15/17方向正交。",
  "approach": "1) 复制节点12 run.py,保留 --trend 0 逐位对照不变。2) 在 mix 输出后新增型内径向尺度校正:对每个细胞型,在输入阶段 a、b 分别计算该型细胞到型心的 RMS 距离 r_a、r_b;目标 r_t=(1-t)*r_a+t*r_b;在输出中计算该型到输出型心的 RMS 距离 r_out;缩放因子 s=(r_t/r_out)^strength。3) 对每个该型细胞:new_pos = centroid_out + (pos−centroid_out)*s,坐标其余不动。4) 裁剪:s 限制在 [1−clip, 1+clip]。5) 网格:strength∈{0,0.5,1.0,1.5},clip∈{0.05,0.10,0.20};先跑 strength=0 确认与父逐位一致(np.array_equal),再跑 6-8 个配置,用 vec-score A 半筛选;若最佳配置≤基线+1 分则以 strength=0 提交(止损)。6) 单输入退路:无括号时不做校正,直接沿用父回退。7) proxy2/final:同样用两个输入的型内尺度插值,缺失基因不影响坐标;final 括号尺度差更大(354→217),型内校正空间更大。8) 实现注意:复用节点12已有的 read_stage/type_means 工具函数;型心用稀疏矩阵 mean 即可;需断言每个型至少 2 个细胞否则跳过。",
  "expected_groups": ["shape_scale"],
  "risks": "proxy 两阶段全局 RMS 仅差 5%(354 vs 335),型内尺度差异可能更小,所有型的 s 都落在 [0.98,1.02] 内则机制无空间——Engineer 前 2 次查分若 |Δ|<1 应止损;径向缩放改变型内细胞间距,可能轻微影响 local_spatial(预期 <1 分),需监控;型心计算依赖标签完整性,需断言标签非空。",
  "family_id": "T2HI-05",
  "mechanism": "对每个细胞型,用两个输入阶段的型内径向尺度(到型心 RMS 距离)按时间线性插值出目标尺度,将 mix 输出中该型细胞的径向距离校正到插值目标,方向不变、仅缩放幅度。",
  "vs_constant_shift": "常数位移给所有细胞加同一向量(平移),本方案以型心为中心做径向缩放:位移=(s−1)×(pos−centroid),方向沿径向、大小正比于到型心距离——中心细胞不动、边缘细胞移动最多,且每个型的缩放因子独立计算,不是全局统一值。",
  "mechanism_evidence": "Engineer 应记录:(1) 每型缩放因子 s 的均值与范围(若全部在 [0.98,1.02] 说明无空间);(2) 校正前后型内 RMS 距离变化百分比;(3) 四组分各自变化,尤其 shape_scale 内 scale_log_ratio;(4) local_spatial 是否被扰动(预期 <1 分)。",
  "mechanism_off_control": "--strength 0 使 s^0=1,所有坐标不变,输出应与父节点逐位相同(np.array_equal 检查 X 和 spatial_3D)。若 strength=0 输出与父不同,说明实现有泄漏,必须修复后再继续网格。"
}
原始记录位置/home/spark-longxinyang/vec/runs/formal/20261003-004922-search-t2-heart-interp-g24-D/nodes/18/researcher.jsonl 45 KB
/home/spark-longxinyang/vec/runs/formal/20261003-004922-search-t2-heart-interp-g24-D/nodes/18/researcher.stderr