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

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

节点 n32

NO_CHANGE: 型内质心距离控制交换(κ=0.3–3.0 共 7 种解码全部劣于同日锚点,κ≥3 触发邻域否决线;备选 DETFIX、β 微调同被证否)

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

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

来自 programs.git 6fa4ef185b:solution/METHOD.md

NO_CHANGE: 型内质心距离控制交换(κ=0.3–3.0 共 7 种解码全部劣于同日锚点,κ≥3 触发邻域否决线;备选 DETFIX、β 微调同被证否)

结论

按 PLAN(T2EI-01:型内表达质心距离控制交换,T2_SPREAD_KAPPA)实现并完成 off/on 对照与 7 种解码查分:机制按设计生效(交换确实压缩型内散布、variogram raw 单调下降),但 variogram 可得收益上限仅约 +0.21 pts,而交换附带的 neighborhood_mmd / de_direction / occupancy_dice 损失更大,全部组合净负或噪声内(+0.013 至 −0.85,同日 A 半锚点 61.453)。随后按 §2 要求试了针对同一弱项(cell_state/variogram)的备选机制与幅度扫描:DETFIX(DE 上调基因检出频率向括号插值目标恢复)被强烈证否(−3.80,并揭示线性插值目标系统性高估真实中间阶段);β 配对收缩 0.3/0.4 净 ≈0;收敛强度 α=5.5/6.0/6.5/8.0 扫描显示 neighborhood_mmd 与 variogram 随 α 单调改善(α=6.5 时 nbrhd raw 0.05387 为全表最好)但 mmd_u 以更快速度劣化,净峰值 α=5.5 仅 +0.037(远低于 ~1 分噪声)。共 15 次查分(含锚点重复 1 次),无一配置超出噪声。提交默认 SPREAD_KAPPA=0、DETFIX_FRAC=0、α=5、β=0.2,seed 0 输出与父节点 24 逐位相同(array_equal 验证 X 与 spatial_3D),--ablate mechanism 同样逐位复现父节点。

实现

在父节点 24 全部管线(mix 分层、procrustes3d、α=5、λ=6、β=0.2、aniso、jitter、RMS 回缩)的 mix_indices 之后、converge shift 之前新增:

  1. SPREAD 交换(PLAN 机制):每个共有类型(两侧池 ≥20 细胞)计算插值质心 μ_tgt=(1−t)μ_a+tμ_b(全面板基因);对池内每个细胞算 d_i=‖x_i−μ_tgt‖₂(只用该细胞 nnz 基因,DE 模式下再限制到 |Δ_type|≥0.25 基因);每侧按已抽细胞的 d 中位数 d_med,对 d_i>d_med 者以 p=clip(κ(d_i−d_med)/d_med,0,1) 与同型同侧未抽中且 d_j<d_med 的细胞交换。专用 rng(seed+987654321),不扰动主管线 rng 流 → κ=0 逐位复现父节点。解码变体:T2_SPREAD_DIST_MODE=de(距离只看 DE 基因)、T2_SPREAD_RAD_MULT>0(空间受限:替换细胞须在 R_max=mult×池内 NN 距离 P90 内,取空间最近者,保护邻域)。
  2. DETFIX(备选机制 1):β 步之后,对每个共有类型(输出两侧各 ≥10 细胞)的每个上调 DE 基因(δ≥0.25),按检出频率缺口 f_tgt−f_out(f_tgt=(1−t)f_a+t·f_b,池上现场算)激活 n_add=round(frac·缺口·n_block) 个「最进步」零细胞(按型内 Δ 投影排序),供体值从同型 b 侧已表达值分位匹配,每细胞激活数封顶 10。只翻 0→正,不改已有值、不动坐标。
  3. β 微调(备选机制 2):T2_PAIR_BETA 0.3/0.4(父节点 0.2)。

--ablate <任意名>:把 SPREAD_KAPPA 与 DETFIX_FRAC 都置 0,其余步骤、seed、输出格式不变。

机制生效证据(PLAN mechanism_evidence 各项)

  • 交换量:κ=0.3/0.6/1.0/3.0 → 61/137/222/659 次交换(占 5000 细胞的 1.2%/2.7%/4.4%/13.2%;共有类型内 swap_frac 均值 2.0%/3.8%/5.6%/19.0%;a 侧 108、b 侧 29 @κ=0.6);空间受限 κ=3.0×rad3 → 629 次;DE 模式 κ=1.0 → 212 次。交换为 0 的配置只有 κ=0(默认提交态,此时不算距离、不消费 rng)。
  • 型内 RMS 散布(全基因,相对 μ_tgt):κ=0.6 → ×0.990(a 0.988 / b 0.991);κ=1.0 → ×0.987;κ=3.0 → ×0.958;κ=3.0×rad3 → ×0.961。机制确实压缩散布,且随 κ 单调。
  • DETFIX:frac=1.0 时 9 个共有类型、29480 次激活、3005 个细胞、273 个基因被触及;型内 up-DE 检出频率缺口 0.087→0.023;零元 1437473→1407993。
  • 四组分变化见下表(同日 A 半,锚点=本节点代码关闭机制,board 61.453:cell_state 48.93 / expression 60.97 / local 58.16 / shape 77.75)。

查分记录(同日 A 半,锚点 61.453;共 11 次查询,含锚点重复 1 次)

配置board净Δvariogram rawmmd_u rawnbrhd rawde_dir判定
off(锚点,=父节点24)61.453—0.014420.011640.055060.3853—
κ=0.3 all61.462+0.0130.014350.011690.055590.3846噪声内;增益来自 shape 抽样运气(occup +0.05、d2 +0.03),variogram 仅 +0.014 pts,PLAN 降幅阈值 0.0005 未达(实际 −0.00007)
κ=0.6 all61.378−0.0710.014180.011540.055420.3823variogram 降 0.000245 <0.0005 → PLAN 停止线
κ=1.0 all61.245−0.2060.013980.011650.055620.3793同上,降幅 0.00044 仍 <0.0005,de_dir/occup 继续掉
κ=1.0 de模式61.318−0.1350.014220.011640.055710.3848DE 距离解码不改变结论
κ=3.0 all60.606−0.8450.013820.012120.058520.3707nbrhd +0.0035 >0.001 → 否决线
κ=3.0 空间受限 rad361.189−0.2610.013460.011760.057120.3636variogram 最大增益 +0.208 pts,但 nbrhd +0.0021 仍破否决线,de_dir −0.122、occup −0.091
DETFIX frac=1.057.649−3.8040.025680.014800.066950.3621强烈证否
β=0.361.459+0.0040.014300.011520.055560.3862噪声内
β=0.461.444−0.0090.014170.011450.056110.3864cell_state +0.40(49.33,全表最高)但 nbrhd −0.118 抵消
α=5.5(幅度扫描)61.487+0.0370.014230.011920.054470.3850噪声内;nbrhd +0.065、vari +0.041,被 mmd −0.070 抵消
α=6.061.447−0.0040.014050.012360.054080.3828nbrhd +0.110 但 mmd −0.180
α=6.561.359−0.0940.013930.012900.053870.3814nbrhd 全表最好(raw 0.05387)但 mmd −0.310
α=8.060.800−0.6510.013670.015240.054560.3771mmd 崩塌 −0.823

逐项 points 差(对锚点)示例:κ=3.0×rad3:vari +0.208、mmd −0.030、de_dir −0.122、de_score 0、nbrhd −0.228、occup −0.091、d2 +0.001、scale +0.001 → 净 −0.261。κ=0.6:vari +0.052、mmd +0.026、de_dir −0.017、nbrhd −0.040、occup −0.061、d2 −0.032 → 净 −0.071。

为什么判无效(结论性认识)

  1. variogram 对压缩的响应太弱:型内 RMS 压缩 4%(659 次交换)只换来 raw −0.0006~−0.00096(+0.13~+0.21 pts);而任何改变「哪些细胞在哪个坐标上表达什么」的操作,neighborhood_mmd(25 pts + 门住 shape 组)的损失都 ≥ 该收益。κ=0.3 的 +0.013 是坐标抽样噪声(增益全在 occupancy/d2,variogram 贡献 +0.014 pts),低于 T2 噪声阈(约 1 分),不算进步。
  2. DETFIX 揭示了一个新的强事实:按类型线性插值的检出频率/伪批量目标(f_tgt、pb_tgt)系统性高估真实中间阶段——把 up-DE 基因检出频率从 0.096 拉向 0.122 使 variogram raw 从 0.0144 恶化到 0.0257(比父节点差 78%)。即真实 E7.25 的 up-DE 基因表达比 (1−t)A+tB 插值更靠近早期阶段(发育转录变化在括号后段加速,或插值高估了中间态成熟度)。父节点管线的「欠收敛」表象(up-gene pb 0.454 < 插值目标 0.576)其实方向正确,任何朝插值目标的恢复(幅度或频率)都应当放弃——这与节点 17/19/21 的失败一致,并给出统一解释。
  3. β(DE 基因配对中点收缩)0.2→0.4 单调改善 cell_state(48.93→49.33)但 neighborhood 损失同步单调(−0.118),净 ≈0:表达侧压缩的收益/代价比在本管线当前压缩水平上已经打平。
  4. α(收敛强度)扫描给出一条清晰的结构约束:随 α 5→6.5,neighborhood_mmd 单调改善(raw 0.05506→0.05387,全表最好)、variogram 单调改善(0.01442→0.01393),但 mmd_u 单调加速劣化(0.01164→0.01290→0.01524 @α=8)。原因:α 越大,两侧细胞越向中间态过冲,输出表达分布越窄/越偏离真值中间态(mmd_u 抓整体分布,neighborhood 只看局部配对平滑度)。净分在 α=5.5 处峰值 +0.037(噪声内),α=6 已回到 −0.004。这验证了父节点 α=5 已近最优,也说明 neighborhood / variogram 与 mmd_u 之间存在此消彼长的结构性张力:任何靠加大压缩换 neighborhood/variogram 的方向,都会被 mmd_u 的更快劣化吞掉。

验证过 / 未验证

  • 验证:κ=0 与 --ablate(即使 env 开启机制)输出与父节点 24 逐位相同;seed 0 双跑逐位一致、seed 1 不同;vec-check ok;全部 9 个查分配置。
  • 未验证:κ∈(1,3) 中间值(趋势单调,无必要);DETFIX 只查了 frac=1.0(−3.8 远超噪声,且方向性结论由 variogram raw +78% 支撑,无需再烧额度);单输入阶段退路与父节点相同(提前 return,机制不执行);伪装视图重跑(代码只依赖视图数据与时间差,t 在时间平移下不变,无绝对时间/路径/文件名分支)。
  • 运行:CPU ~1.2 s / ~0.4 GB(EXECUTION.json gpu:false),远低于 limits(28 GB / 30 min)。

知识来源

无外部生物学知识条目:质心、Δ、频率、尺度全部由程序从视图 manifest 给出的两个括号输入现场计算(与父节点一致)。PLAN sources=[],本节点未新增。

给后续节点的建议

  • 型内散布压缩(选择侧或数值侧)路线关闭:variogram 可得收益上限实测 ≈ +0.2 pts,恒被 neighborhood/de 附带损失吞掉(节点 15/17/19/21/32 五次独立证伪)。
  • 不要把任何统计量朝「括号线性插值目标」方向修(DETFIX −3.8 实证):真实中间阶段在 up-DE 基因上比线性插值更「早」。反方向(比父节点更多压缩/更早状态)没有测过——若要继续动 cell_state,可试把 α 提到 6–8 或 β 提到 0.5 同时监控 nbrhd 否决线,但预期同样是净 ≈0。
  • occupancy_dice(skill 0.42)与坐标侧继续判死(节点 13/21/22/24/32)。
  • 本榜 62.5 平台大概率是 mix 家族的真实上限;建议把火力转向 heart 榜(外推本地尺子高估,需同日锚点比较)。

调研员的计划

名称型内表达质心距离控制抽样降低 variogram(T2EI-01)
动机父节点 24 最弱指标为 variogram(raw 0.01392,skill 0.389,低于地板 0.5,仅 4.87/12.5 分)。混抽两阶段细胞引入额外型间方差,使 E|x_i−x_j|^0.5 高于真实中间阶段;表达侧数值变换三连败(节点 17/19/21),坐标侧四次证伪(13/21/22/24)。ANALYSIS 建议'选哪些真实细胞'层面动手。节点 15 按 Δ 方向进度选细胞使 variogram 更差(0.01442→0.01515),因为进度选择只压缩 Δ 方向、增大垂直方向方差。本方案改为多维径向距离选择,直接压缩全方向散布。
做法在父节点 24 全部管线(mix 分层、procrustes3d、α=5、λ=6、β=0.2、aniso、jitter、RMS 回缩)的 mix 步骤内新增质心距离控制交换(环境变量 T2_SPREAD_KAPPA,默认 0=关闭):
1. 对每个共有类型(≥20 细胞/侧),用全部 panel 基因计算插值质心 μ_tgt=(1−t)·μ_a+t·μ_b。
2. 对已选入的每个细胞计算 d_i=‖x_i−μ_tgt‖₂(只用 nnz 基因,避免稀疏维度膨胀距离)。
3. 按来源侧(a/b)分别计算中位距离 d_med;对 d_i>d_med 的细胞,以概率 κ·(d_i−d_med)/d_med 将其与同型、同来源侧中随机一个 d_j<d_med 的细胞交换(swap 模式,不改变细胞总数、不改变 a/b 比例、不额外消耗坐标 rng 流)。
4. κ 搜索范围 {0.3, 0.6, 1.0},先小样本 1500 细胞快筛(只跑 variogram+mmd_u 两项的本地计算),再全量 5000 查分。
5. 交换在 converge shift 之前执行,后续 α/λ/β 照常作用于交换后的细胞。
6. 单输入阶段退路:无括号时 main() 提前 return,机制不执行(与父节点一致)。
7. vec-score 快筛:先跑 off(κ=0)确认与父节点逐位一致,再跑 κ=0.6 全量查分;若 variogram raw 降幅 <0.0005 或 neighborhood_mmd raw 升幅 >0.001 即停。
风险1. 交换引入坐标变化:被换入的细胞坐标不同,可能微扰邻域结构。缓解:swap 保持同型同来源侧,空间分布变化有限;以 neighborhood_mmd raw 升幅 ≤0.001 为一票否决。2. 过度压缩散布使 mmd_u 变差(分布过窄)。缓解:κ 从 0.3 起步,观察 mmd_u raw 是否上升;若升 >0.0005 则判负。3. 与节点 15 类似的坐标重抽样噪声:节点 15 用 redraw 模式全量重抽,本方案用 swap 模式只换少量细胞(预期 <30%),坐标变化幅度远小于节点 15。4. 若 variogram 改善 <0.5 分(噪声内),用 3 次查分(seed 0/1/2)确认方向一致性。

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

对比:父节点版本 2c14430cfb。改动的文件:solution/METHOD.md +53 −32、solution/README.md +12 −7、solution/run.py +333 −1

diff --git a/solution/METHOD.md b/solution/METHOD.mdindex 762293e..a19285d 100644--- a/solution/METHOD.md+++ b/solution/METHOD.md@@ -1,46 +1,67 @@-体素占据插值引导坐标再分布(T2EI-06)已实现并对照:η>0 占据 L1 降、occupancy_dice 仅 +0.005,邻域 mmd +0.0013 破否决线,净负;提交默认 η=0,与父节点逐位一致。+NO_CHANGE: 型内质心距离控制交换(κ=0.3–3.0 共 7 种解码全部劣于同日锚点,κ≥3 触发邻域否决线;备选 DETFIX、β 微调同被证否) -## 方法(family T2EI-06,PLAN:occupancy-guided coordinate redistribution)+## 结论 -父节点 21 全部管线不动(mix 分层混抽、procrustes3d、α=5 收敛位移、λ=6 投影加权、β=0.2 配对收缩、各向异性坐标整形 damp=1.25、jitter、RMS 回缩;表达侧 recolor/varrest/prog 开关保持父节点默认的关闭态)。在 RMS 回缩之后、写出之前新增坐标再分布步骤(`T2_OCCUP_ETA`,默认 0=整体跳过):+按 PLAN(T2EI-01:型内表达质心距离控制交换,T2_SPREAD_KAPPA)实现并完成 off/on 对照与 7 种解码查分:机制按设计生效(交换确实压缩型内散布、variogram raw 单调下降),但 variogram 可得收益上限仅约 +0.21 pts,而交换附带的 neighborhood_mmd / de_direction / occupancy_dice 损失更大,全部组合净负或噪声内(+0.013 至 −0.85,同日 A 半锚点 61.453)。随后按 §2 要求试了针对同一弱项(cell_state/variogram)的备选机制与幅度扫描:DETFIX(DE 上调基因检出频率向括号插值目标恢复)被强烈证否(−3.80,并揭示线性插值目标系统性高估真实中间阶段);β 配对收缩 0.3/0.4 净 ≈0;收敛强度 α=5.5/6.0/6.5/8.0 扫描显示 neighborhood_mmd 与 variogram 随 α 单调改善(α=6.5 时 nbrhd raw 0.05387 为全表最好)但 mmd_u 以更快速度劣化,净峰值 α=5.5 仅 +0.037(远低于 ~1 分噪声)。共 15 次查分(含锚点重复 1 次),无一配置超出噪声。**提交默认 SPREAD_KAPPA=0、DETFIX_FRAC=0、α=5、β=0.2,seed 0 输出与父节点 24 逐位相同(array_equal 验证 X 与 spatial_3D),`--ablate mechanism` 同样逐位复现父节点。** -1. **评分器同款归一化**(`_dice_normalize`):去质心、PCA 对齐(第三矩定向各轴,强制 det=+1)、除以 RMS 半径。对输出云和括号两侧全部原始细胞(`align_pair` 对齐后的 aligned_a / aligned_b)分别做同样归一化。-2. **体素占据**:±3 范围内 16³ 均匀网格(与 occupancy_dice 评分器一致),统计 a 侧、b 侧、输出侧每体素计数并归一化为概率密度。-3. **目标占据**:P_tgt(v) = (1−t)·P_a(v) + t·P_b(v),t 与 mix 相同(本代理 = 0.4)。-4. **限幅位移**:输出细胞所在体素若 P_out > P_tgt(过密),朝最近欠密体素(P_out < P_tgt)中心方向位移 η·(P_out−P_tgt)/P_out,限幅 0.3 个网格步长(=0.1125 归一化单位);P_out ≤ P_tgt 的细胞不动。-5. **回缩**:位移加在归一化坐标上,逆归一化(×rms、@Vᵀ、+质心)回输出帧,再 `scale_to_rms` 均匀回缩到原 target_rms(scale_log_ratio 保持)。表达矩阵逐位不动;细胞移动时携带自己的表达,表达-位置配对不变。-6. **单输入阶段退路**:无括号时 main() 提前 return,机制不执行(与父节点一致)。-7. 机制不消费 rng,η=0 时不建网格、不改坐标。+## 实现 -知识来源:只用视图内两个括号阶段自身的坐标测量与 t 线性插值假设;16³/±3RMS 网格与归一化方式来自任务书公开的 occupancy_dice 评分规则说明,无保留阶段/基因型信息,无外部文献数值。+在父节点 24 全部管线(mix 分层、procrustes3d、α=5、λ=6、β=0.2、aniso、jitter、RMS 回缩)的 mix_indices 之后、converge shift 之前新增: -## 机制生效证据(seed 0,proxy E6.75+E8.0→E7.25,t=0.4)+1. **SPREAD 交换(PLAN 机制)**:每个共有类型(两侧池 ≥20 细胞)计算插值质心 μ_tgt=(1−t)μ_a+tμ_b(全面板基因);对池内每个细胞算 d_i=‖x_i−μ_tgt‖₂(只用该细胞 nnz 基因,DE 模式下再限制到 |Δ_type|≥0.25 基因);每侧按已抽细胞的 d 中位数 d_med,对 d_i>d_med 者以 p=clip(κ(d_i−d_med)/d_med,0,1) 与同型同侧未抽中且 d_j<d_med 的细胞交换。专用 rng(seed+987654321),不扰动主管线 rng 流 → κ=0 逐位复现父节点。解码变体:`T2_SPREAD_DIST_MODE=de`(距离只看 DE 基因)、`T2_SPREAD_RAD_MULT>0`(空间受限:替换细胞须在 R_max=mult×池内 NN 距离 P90 内,取空间最近者,保护邻域)。+2. **DETFIX(备选机制 1)**:β 步之后,对每个共有类型(输出两侧各 ≥10 细胞)的每个上调 DE 基因(δ≥0.25),按检出频率缺口 f_tgt−f_out(f_tgt=(1−t)f_a+t·f_b,池上现场算)激活 n_add=round(frac·缺口·n_block) 个「最进步」零细胞(按型内 Δ 投影排序),供体值从同型 b 侧已表达值分位匹配,每细胞激活数封顶 10。只翻 0→正,不改已有值、不动坐标。+3. **β 微调(备选机制 2)**:T2_PAIR_BETA 0.3/0.4(父节点 0.2)。 -- **实际改变的细胞**:η=0.3/0.6/1.0 均移动 3242/5000 个细胞(过密体素内全部细胞);平均位移 0.093/0.106/0.109 归一化单位(≈14–16 µm),最大 0.1125(限幅值,多数细胞被限幅饱和);表达矩阵与细胞数逐位不变,输出 RMS 149.2 不变。-- **占据 L1 距离**(|P_out−P_tgt| 总和):0.680 → 0.472(η=0.3)/ 0.514(η=0.6)/ 0.522(η=1.0),下降,机制按其设计目标生效;对插值占据集的 self-dice 0.781 → 0.826。-- **occupancy_dice raw**(A 半,同日锚点 0.8066):η=0.3 → 0.8113(+0.0047,points 3.511→3.591)。-- **neighborhood_mmd raw**:锚点 0.05506 → η=0.3 0.05636(**+0.0013,> PLAN 0.001 否决线**),points 14.54→14.40。-- **d2_shape raw**:锚点 0.0047 → 0.00542(劣化,points 8.159→8.066);scale_log_ratio 0.0162 不变(points 7.767→7.768)。-- **四组分变化**(A 半):expression_change 60.97 不变、cell_state 48.93 不变(不触碰表达)、shape_scale 77.75→77.70、local_spatial 58.16→57.58。净榜分变化 ≈ **−0.16**(在 ±1 噪声内,但方向为负且触发否决线)。+`--ablate <任意名>`:把 SPREAD_KAPPA 与 DETFIX_FRAC 都置 0,其余步骤、seed、输出格式不变。 -结论:占据密度重排确实按设计改变了占据(L1 下降、occupancy_dice 微升),但收益(+0.08 points)远小于 neighborhood_mmd 损失(−0.145 points)+ d2_shape 损失(−0.09 points)。邻域项对"细胞位置被搬运"高度敏感——即使表达随细胞一起移动、配对不变,15-NN 邻域的组成仍被打乱。这是树内第四次独立观察到 local_spatial 与形状/状态类改动之间的实测权衡(节点 15、17、21 之后)。+## 机制生效证据(PLAN mechanism_evidence 各项) -## 关闭对照(mechanism_off_control)+- **交换量**:κ=0.3/0.6/1.0/3.0 → 61/137/222/659 次交换(占 5000 细胞的 1.2%/2.7%/4.4%/13.2%;共有类型内 swap_frac 均值 2.0%/3.8%/5.6%/19.0%;a 侧 108、b 侧 29 @κ=0.6);空间受限 κ=3.0×rad3 → 629 次;DE 模式 κ=1.0 → 212 次。交换为 0 的配置只有 κ=0(默认提交态,此时不算距离、不消费 rng)。+- **型内 RMS 散布(全基因,相对 μ_tgt)**:κ=0.6 → ×0.990(a 0.988 / b 0.991);κ=1.0 → ×0.987;κ=3.0 → ×0.958;κ=3.0×rad3 → ×0.961。机制确实压缩散布,且随 κ 单调。+- **DETFIX**:frac=1.0 时 9 个共有类型、29480 次激活、3005 个细胞、273 个基因被触及;型内 up-DE 检出频率缺口 0.087→0.023;零元 1437473→1407993。+- **四组分变化**见下表(同日 A 半,锚点=本节点代码关闭机制,board 61.453:cell_state 48.93 / expression 60.97 / local 58.16 / shape 77.75)。 -`T2_OCCUP_ETA=0`(提交默认):位移步骤整体跳过(不建网格、不改坐标、不消费 rng),本地重跑输出与父节点 21 提交在 seed 0 下 `array_equal` 验证逐位相同(X 与 spatial_3D 均 True),`vec-check` ok,n=5000。开启(η>0)后坐标改变 3242 个细胞、表达矩阵逐位不变、细胞数不变(上节),机制生效但净负。+## 查分记录(同日 A 半,锚点 61.453;共 11 次查询,含锚点重复 1 次) -## 查分结果(A 半,seed 0,共用 3/20 次)+| 配置 | board | 净Δ | variogram raw | mmd_u raw | nbrhd raw | de_dir | 判定 |+|---|---:|---:|---:|---:|---:|---:|---|+| off(锚点,=父节点24) | 61.453 | — | 0.01442 | 0.01164 | 0.05506 | 0.3853 | — |+| κ=0.3 all | 61.462 | +0.013 | 0.01435 | 0.01169 | 0.05559 | 0.3846 | 噪声内;增益来自 shape 抽样运气(occup +0.05、d2 +0.03),variogram 仅 +0.014 pts,PLAN 降幅阈值 0.0005 未达(实际 −0.00007) |+| κ=0.6 all | 61.378 | −0.071 | 0.01418 | 0.01154 | 0.05542 | 0.3823 | variogram 降 0.000245 <0.0005 → PLAN 停止线 |+| κ=1.0 all | 61.245 | −0.206 | 0.01398 | 0.01165 | 0.05562 | 0.3793 | 同上,降幅 0.00044 仍 <0.0005,de_dir/occup 继续掉 |+| κ=1.0 de模式 | 61.318 | −0.135 | 0.01422 | 0.01164 | 0.05571 | 0.3848 | DE 距离解码不改变结论 |+| κ=3.0 all | 60.606 | −0.845 | 0.01382 | 0.01212 | 0.05852 | 0.3707 | nbrhd +0.0035 >0.001 → 否决线 |+| κ=3.0 空间受限 rad3 | 61.189 | −0.261 | 0.01346 | 0.01176 | 0.05712 | 0.3636 | variogram 最大增益 +0.208 pts,但 nbrhd +0.0021 仍破否决线,de_dir −0.122、occup −0.091 |+| DETFIX frac=1.0 | 57.649 | −3.804 | 0.02568 | 0.01480 | 0.06695 | 0.3621 | 强烈证否 |+| β=0.3 | 61.459 | +0.004 | 0.01430 | 0.01152 | 0.05556 | 0.3862 | 噪声内 |+| β=0.4 | 61.444 | −0.009 | 0.01417 | 0.01145 | 0.05611 | 0.3864 | cell_state +0.40(49.33,全表最高)但 nbrhd −0.118 抵消 |+| α=5.5(幅度扫描) | 61.487 | +0.037 | 0.01423 | 0.01192 | 0.05447 | 0.3850 | 噪声内;nbrhd +0.065、vari +0.041,被 mmd −0.070 抵消 |+| α=6.0 | 61.447 | −0.004 | 0.01405 | 0.01236 | 0.05408 | 0.3828 | nbrhd +0.110 但 mmd −0.180 |+| α=6.5 | 61.359 | −0.094 | 0.01393 | 0.01290 | 0.05387 | 0.3814 | nbrhd 全表最好(raw 0.05387)但 mmd −0.310 |+| α=8.0 | 60.800 | −0.651 | 0.01367 | 0.01524 | 0.05456 | 0.3771 | mmd 崩塌 −0.823 | -| 配置 | shape_scale | local_spatial | occupancy_dice raw | d2_shape raw | neighborhood raw | scale raw |-|---|---:|---:|---:|---:|---:|---:|-| η=0(锚点,=父节点) | 77.75 | 58.16 | 0.8066 | 0.0047 | 0.05506 | 0.0162 |-| η=0.3, clamp=0.3 | 77.70 | 57.58 | 0.8113 | 0.00542 | 0.05636 | 0.0162 |-| η=0.6 / 1.0 | 未查分(L1 与 self-dice 均劣于 η=0.3,位移已限幅饱和,判负后未消耗额度) | | | | | |+逐项 points 差(对锚点)示例:κ=3.0×rad3:vari +0.208、mmd −0.030、de_dir −0.122、de_score 0、nbrhd −0.228、occup −0.091、d2 +0.001、scale +0.001 → 净 −0.261。κ=0.6:vari +0.052、mmd +0.026、de_dir −0.017、nbrhd −0.040、occup −0.061、d2 −0.032 → 净 −0.071。 -按 PLAN 步骤 7:η=0.3 无净改善且 neighborhood raw 升幅 +0.0013 > 0.001 → 判负,提交 η=0(与父节点 21 逐位一致,B 半预期 62.52)。+## 为什么判无效(结论性认识) -## 未验证+1. **variogram 对压缩的响应太弱**:型内 RMS 压缩 4%(659 次交换)只换来 raw −0.0006~−0.00096(+0.13~+0.21 pts);而任何改变「哪些细胞在哪个坐标上表达什么」的操作,neighborhood_mmd(25 pts + 门住 shape 组)的损失都 ≥ 该收益。κ=0.3 的 +0.013 是坐标抽样噪声(增益全在 occupancy/d2,variogram 贡献 +0.014 pts),低于 T2 噪声阈(约 1 分),不算进步。+2. **DETFIX 揭示了一个新的强事实**:按类型线性插值的检出频率/伪批量目标(f_tgt、pb_tgt)**系统性高估**真实中间阶段——把 up-DE 基因检出频率从 0.096 拉向 0.122 使 variogram raw 从 0.0144 恶化到 0.0257(比父节点差 78%)。即真实 E7.25 的 up-DE 基因表达比 (1−t)A+tB 插值**更靠近早期阶段**(发育转录变化在括号后段加速,或插值高估了中间态成熟度)。父节点管线的「欠收敛」表象(up-gene pb 0.454 < 插值目标 0.576)其实方向正确,任何朝插值目标的恢复(幅度或频率)都应当放弃——这与节点 17/19/21 的失败一致,并给出统一解释。+3. β(DE 基因配对中点收缩)0.2→0.4 单调改善 cell_state(48.93→49.33)但 neighborhood 损失同步单调(−0.118),净 ≈0:表达侧压缩的收益/代价比在本管线当前压缩水平上已经打平。+4. **α(收敛强度)扫描给出一条清晰的结构约束**:随 α 5→6.5,neighborhood_mmd 单调改善(raw 0.05506→0.05387,全表最好)、variogram 单调改善(0.01442→0.01393),但 mmd_u 单调**加速**劣化(0.01164→0.01290→0.01524 @α=8)。原因:α 越大,两侧细胞越向中间态过冲,输出表达分布越窄/越偏离真值中间态(mmd_u 抓整体分布,neighborhood 只看局部配对平滑度)。净分在 α=5.5 处峰值 +0.037(噪声内),α=6 已回到 −0.004。这**验证了父节点 α=5 已近最优**,也说明 neighborhood / variogram 与 mmd_u 之间存在此消彼长的结构性张力:任何靠加大压缩换 neighborhood/variogram 的方向,都会被 mmd_u 的更快劣化吞掉。 -- η=0.6/1.0 未查分(η=0.3 已触发否决线,PLAN 规定即停;且其占据 L1 更差)。-- clamp 放宽到 0.5 格未试:occupancy_dice 在 η=0.3 已有变化(非 PLAN 风险 1 的"无变化"分支),且收益量级(+0.08 points)已被证明远小于邻域损失量级,放宽只会加大搬运距离、进一步伤邻域。-- 更小的 clamp(如 0.15 格)未试:按比例外推 occupancy 收益 ~+0.04、邻域损失 ~−0.07,仍为净负方向,未消耗额度验证。+## 验证过 / 未验证++- 验证:κ=0 与 `--ablate`(即使 env 开启机制)输出与父节点 24 逐位相同;seed 0 双跑逐位一致、seed 1 不同;vec-check ok;全部 9 个查分配置。+- 未验证:κ∈(1,3) 中间值(趋势单调,无必要);DETFIX 只查了 frac=1.0(−3.8 远超噪声,且方向性结论由 variogram raw +78% 支撑,无需再烧额度);单输入阶段退路与父节点相同(提前 return,机制不执行);伪装视图重跑(代码只依赖视图数据与时间差,t 在时间平移下不变,无绝对时间/路径/文件名分支)。+- 运行:CPU ~1.2 s / ~0.4 GB(EXECUTION.json gpu:false),远低于 limits(28 GB / 30 min)。++## 知识来源++无外部生物学知识条目:质心、Δ、频率、尺度全部由程序从视图 manifest 给出的两个括号输入现场计算(与父节点一致)。PLAN sources=[],本节点未新增。++## 给后续节点的建议++- 型内散布压缩(选择侧或数值侧)路线关闭:variogram 可得收益上限实测 ≈ +0.2 pts,恒被 neighborhood/de 附带损失吞掉(节点 15/17/19/21/32 五次独立证伪)。+- **不要**把任何统计量朝「括号线性插值目标」方向修(DETFIX −3.8 实证):真实中间阶段在 up-DE 基因上比线性插值更「早」。反方向(比父节点更多压缩/更早状态)没有测过——若要继续动 cell_state,可试把 α 提到 6–8 或 β 提到 0.5 同时监控 nbrhd 否决线,但预期同样是净 ≈0。+- occupancy_dice(skill 0.42)与坐标侧继续判死(节点 13/21/22/24/32)。+- 本榜 62.5 平台大概率是 mix 家族的真实上限;建议把火力转向 heart 榜(外推本地尺子高估,需同日锚点比较)。diff --git a/solution/README.md b/solution/README.mdindex 00a910e..1f4bf10 100644--- a/solution/README.md+++ b/solution/README.md@@ -1,9 +1,14 @@ # mix + 表达收敛管线 + 各向异性PCA坐标整形(T2:embryo:val_interp) -父节点 11(mix 混抽 + α=5 类型级收敛位移 + λ=6 投影加权 + β=0.2 型内配对收缩)之上新增坐标侧-各向异性整形(family T2EI-06):对齐括号合并云的 PCA 主轴上,把输出云每轴展幅向-target = exp(log spread_a + γ(log spread_b − log spread_a))、γ = T2_ANISO_DAMP×t(默认 damp=1.25)-缩放(factor clip [0.3, 3.0]),随后照旧均匀回缩到目标 RMS——scale_log_ratio 与表达矩阵逐位不变,-只改点云纵横比。T2_ANISO_ENABLE=0 逐位复现父节点 11。-proxy A 半同日锚点:对照(off)60.79/60.63(seed 0/1)→ 本节点 61.45/61.07;-occupancy_dice skill 0.369→0.421、d2_shape 0.954→0.979,其余六项逐位不变或噪声内。详见 METHOD.md。+继承父节点 24 的全部管线(mix 分层混抽、procrustes3d 对齐、α=5 类型级收敛位移、λ=6 投影加权、+β=0.2 型内配对中点收缩、aniso 坐标整形、jitter、RMS 回缩)。本节点按 PLAN(T2EI-01)新增两个+默认关闭的机制开关,均被同日 A 半查分证否(详见 METHOD.md):++- `T2_SPREAD_KAPPA`(型内质心距离控制交换,含 `T2_SPREAD_DIST_MODE=de`、`T2_SPREAD_RAD_MULT`+  空间受限解码):7 种解码全部净负(+0.013 至 −0.85,锚点 61.453);variogram 收益上限 +0.21 pts,+  被 neighborhood/de_direction 损失吞掉。+- `T2_DETFIX_FRAC`(up-DE 基因检出频率向括号插值目标恢复):净 −3.80,variogram raw 恶化 78%;+  证明线性插值目标系统性高估真实中间阶段。++提交默认两开关均为 0,seed 0 输出与父节点 24 逐位相同;`--ablate mechanism`(任意名)同样逐位+复现父节点。METHOD.md 首行为 NO_CHANGE。diff --git a/solution/run.py b/solution/run.pyindex 3c7e744..38aff2f 100644--- a/solution/run.py+++ b/solution/run.py@@ -222,6 +222,61 @@ OCCUP_ETA = float(os.environ.get("T2_OCCUP_ETA", "0.0")) OCCUP_CLAMP = float(os.environ.get("T2_OCCUP_CLAMP", "0.3"))  # grid steps OCCUP_GRID = int(os.environ.get("T2_OCCUP_GRID", "16")) OCCUP_RANGE = float(os.environ.get("T2_OCCUP_RANGE", "3.0"))+# Centroid-distance-controlled swap (family T2EI-01, this node): the stratified+# mix draws cells uniformly within each type, so the output keeps the full+# within-type radial spread of BOTH endpoint stages, while the true intermediate+# stage sits closer to the interpolated type state. For every shared type+# (>= SPREAD_MIN_CELLS pool cells per side), compute the interpolated centroid+# mu_tgt = (1-t)*mu_a + t*mu_b over ALL panel genes, and for every pool cell the+# distance d_i = ||x_i - mu_tgt||_2 restricted to the cell's own nnz genes (so+# sparse padding does not inflate distances). Per side, d_med = median distance+# of the DRAWN cells of that type. Each drawn cell with d_i > d_med is replaced+# by a random UNDRAWN same-type same-side pool cell with d_j < d_med, with+# probability clip(kappa*(d_i - d_med)/d_med, 0, 1). This compresses the+# within-type spread in ALL directions (unlike node 15's progress selection,+# which compressed only along Delta and inflated the orthogonal variance).+# Cell counts, per-type counts and the a/b ratio are unchanged; expression+# values are never modified (only which real cells enter the output); the main+# rng stream (mix draw + jitter) is untouched via a dedicated swap rng, so+# kappa = 0 (default) reproduces the parent bit-for-bit.+SPREAD_KAPPA = float(os.environ.get("T2_SPREAD_KAPPA", "0.0"))+SPREAD_MIN_CELLS = int(os.environ.get("T2_SPREAD_MIN_CELLS", "20"))+SPREAD_PMAX = float(os.environ.get("T2_SPREAD_PMAX", "1.0"))+# Distance gene subset for the swap: "all" (PLAN default) uses every panel gene;+# "de" restricts d_i to genes with |Δ_type| >= CONVERGE_MIN_DELTA (the genes the+# temporal change lives on), which targets the endpoint-bimodality component of+# the within-type spread instead of the (larger) static technical spread.+SPREAD_DIST_MODE = os.environ.get("T2_SPREAD_DIST_MODE", "all")+# Spatially-constrained decode: a far drawn cell is only replaced when the+# replacement's aligned coordinate sits within R_max of the outgoing cell's+# coordinate, and among eligible near replacements the SPATIALLY CLOSEST one is+# taken (deterministic, no partner rng). R_max = SPREAD_RAD_MULT × the 90th+# percentile of within-pool nearest-neighbour distances of that type-side. This+# keeps the point cloud (and hence the 15-NN neighbourhood structure) nearly+# fixed while still compressing the expression tails. RAD_MULT <= 0 → PLAN's+# unconstrained random-partner decode.+SPREAD_RAD_MULT = float(os.environ.get("T2_SPREAD_RAD_MULT", "0.0"))+# Detection-frequency restoration (family T2EI-01, alternate mechanism): the+# nnz-only + clip-at-0 convergence shift systematically DESTROYS up-DE gene+# mass: b-side expressed entries get clipped to 0 (overshoot) while a-side zeros+# can never gain expression. Measured on the proxy bracket (live, from view+# inputs): up-DE-gene detection freq of the output 0.0956 vs the bracket-+# interpolated target 0.1220, and up-gene pseudobulk 0.454 vs 0.576 (−21%).+# For every shared type (>= DETFIX_MIN_CELLS output cells per side) and every+# up-DE gene (δ_g >= CONVERGE_MIN_DELTA) with a measured deficit+#   f_tgt(g) = (1−t)·f_a(g) + t·f_b(g)   (stage-pool detection frequencies)+#   n_add(g) = round(DETFIX_FRAC · (f_tgt − f_out)(g) · n_block)+# the n_add most "advanced" zero-cells of that type (ranked by projection of+# their deviation from the block mean onto the type's Δ, DE genes only) are+# ACTIVATED at gene g with a donor value quantile-matched from the same type's+# b-side expressed values (post-β, so the value distribution stays realistic).+# Per-cell activations are capped (DETFIX_CAP). Only 0→positive flips on up-DE+# genes happen; no existing value is modified, coordinates / cell selection /+# rng stream untouched. FRAC = 0 (default) reproduces the parent bit-for-bit.+DETFIX_FRAC = float(os.environ.get("T2_DETFIX_FRAC", "0.0"))+DETFIX_MIN_CELLS = int(os.environ.get("T2_DETFIX_MIN_CELLS", "10"))+DETFIX_CAP = int(os.environ.get("T2_DETFIX_CAP", "10"))+DETFIX_MIN_DELTA = float(os.environ.get("T2_DETFIX_MIN_DELTA", "0.25"))   def _dice_normalize(c):@@ -470,6 +525,96 @@ def progress_swap(stage, idx, labels, means, delta, target_s, frac):     return new_idx, info  +def spread_swap(stage, idx, labels, mu_tgt, kappa, rng, side: str, coords=None):+    """Replace drawn far-from-centroid cells with undrawn near cells (same type/side).++    Counts, per-type composition and the main rng stream are untouched; only+    WHICH pool cells enter the output changes. See SPREAD_KAPPA comment.+    With SPREAD_RAD_MULT > 0 and `coords` given, replacements must sit within+    R_max of the outgoing cell and the spatially closest eligible one is taken.+    """+    labs_all = np.asarray(labels).astype(str)+    labs_sel = labs_all[idx]+    new_idx = idx.copy()+    n_swaps = 0+    n_types = 0+    n_cand = 0+    rms_pairs, frac_list = [], []+    for lab in sorted(mu_tgt):+        pos = np.where(labs_sel == lab)[0]+        k = int(pos.size)+        pool = np.flatnonzero(labs_all == lab)+        if k <= 0 or pool.size < SPREAD_MIN_CELLS or k >= pool.size:+            continue+        mu = np.asarray(mu_tgt[lab][0], dtype=np.float64)+        gmask = mu_tgt[lab][1]+        P = as_dense(stage.X, pool).astype(np.float64)+        mask = P > 0+        if gmask is not None:+            mask = mask & gmask+        diff = np.where(mask, P - mu, 0.0)+        d = np.sqrt((diff ** 2).sum(axis=1))+        drawn = np.searchsorted(pool, idx[pos])+        drawn0 = drawn.copy()+        d_med = float(np.median(d[drawn]))+        if not np.isfinite(d_med) or d_med <= 0.0:+            continue+        undrawn_mask = np.ones(pool.size, dtype=bool)+        undrawn_mask[drawn0] = False+        near = np.flatnonzero(undrawn_mask & (d < d_med))+        far_local = np.flatnonzero(d[drawn0] > d_med)+        if near.size == 0 or far_local.size == 0:+            continue+        n_types += 1+        n_cand += int(near.size)+        p = np.clip(kappa * (d[drawn0[far_local]] - d_med) / d_med, 0.0, SPREAD_PMAX)+        u = rng.random(far_local.size)+        hit = np.flatnonzero(u < p)+        used = np.zeros(near.size, dtype=bool)+        n_sw = 0+        spatial = SPREAD_RAD_MULT > 0.0 and coords is not None+        if spatial:+            pc = np.asarray(coords, dtype=np.float64)[pool]+            near_c = pc[near]+            # R_max from within-pool NN distance 90th percentile (subsample pairs)+            m = min(pool.size, 500)+            sub = pc[rng.choice(pool.size, m, replace=False)] if pool.size > m else pc+            dd = np.sqrt(np.maximum(((sub[:, None, :] - sub[None, :, :]) ** 2).sum(-1), 0.0))+            np.fill_diagonal(dd, np.inf)+            nn = dd.min(axis=1)+            r_max = float(np.quantile(nn, 0.9)) * SPREAD_RAD_MULT+        for hl in hit:+            slot = pos[far_local[hl]]+            if spatial:+                out_c = np.asarray(coords, dtype=np.float64)[idx[slot]]+                dist_c = np.sqrt(np.maximum(((near_c - out_c) ** 2).sum(-1), 0.0))+                elig = np.flatnonzero((~used) & (dist_c <= r_max))+                if elig.size == 0:+                    continue+                pick = int(elig[np.argmin(dist_c[elig])])+            else:+                avail = np.flatnonzero(~used)+                if avail.size == 0:+                    break+                pick = int(avail[rng.integers(avail.size)])+            used[pick] = True+            new_idx[slot] = pool[near[pick]]+            drawn[far_local[hl]] = near[pick]+            n_sw += 1+        n_swaps += n_sw+        frac_list.append(n_sw / k)+        full_dev0 = P[drawn0] - mu+        full_dev1 = P[drawn] - mu+        rms_pairs.append((float(np.sqrt((full_dev1 ** 2).sum(axis=1).mean())),+                          float(np.sqrt((full_dev0 ** 2).sum(axis=1).mean()))))+    info = {"n_types": n_types, "n_swaps": n_swaps, "n_cand": n_cand,+            "swap_frac_mean": float(np.mean(frac_list)) if frac_list else None,+            "rms_rel": float(np.mean([a / max(b, 1e-12) for a, b in rms_pairs])) if rms_pairs else None,+            "rms_before": float(np.mean([b for _, b in rms_pairs])) if rms_pairs else None,+            "rms_after": float(np.mean([a for a, _ in rms_pairs])) if rms_pairs else None}+    return new_idx, info++ def variance_restore(xa, xb, labs_a, labs_b, stage_a, stage_b, t, shared):     """Per-gene within-type variance restoration (see VARREST_GAMMA comment). @@ -538,6 +683,114 @@ def variance_restore(xa, xb, labs_a, labs_b, stage_a, stage_b, t, shared):     return info  +def detection_restore(xa, xb, labs_a, labs_b, stage_a, stage_b, t, delta):+    """Sparse detection-frequency restoration on up-DE genes (see DETFIX_FRAC).++    Only flips 0 → positive on up-DE genes of shared types whose output detection+    frequency sits below the bracket-interpolated stage target; donor values are+    quantile-matched from that type's b-side expressed entries. No existing entry+    is modified; no coordinate / rng touched.+    """+    info = {"detfix_frac": DETFIX_FRAC, "detfix_n_types": 0, "detfix_n_activations": 0,+            "detfix_cells_touched": 0, "detfix_genes_touched": 0,+            "detfix_freq_gap_before": None, "detfix_freq_gap_after": None,+            "detfix_pb_gap_before": None, "detfix_pb_gap_after": None,+            "detfix_zero_before": None, "detfix_zero_after": None,+            "detfix_cap_hits": 0}+    la = np.asarray(stage_a.labels).astype(str)+    lb = np.asarray(stage_b.labels).astype(str)+    n_act = 0+    n_types = 0+    cap_hits = 0+    genes_touched = set()+    cells_touched = set()+    gap_b, gap_a, pb_b, pb_a = [], [], [], []+    zero_before = zero_after = 0+    for lab in sorted(delta):+        d = delta[lab]+        up = d >= DETFIX_MIN_DELTA+        if int(up.sum()) == 0:+            continue+        rows_a = np.flatnonzero(labs_a == lab)+        rows_b = np.flatnonzero(labs_b == lab)+        if rows_a.size < DETFIX_MIN_CELLS or rows_b.size < DETFIX_MIN_CELLS:+            continue+        # stage-pool detection frequencies for this type+        pool_a = np.flatnonzero(la == lab)+        pool_b = np.flatnonzero(lb == lab)+        fa = (as_dense(stage_a.X, pool_a) > 0).mean(axis=0).astype(np.float64)+        fb = (as_dense(stage_b.X, pool_b) > 0).mean(axis=0).astype(np.float64)+        f_tgt = (1.0 - t) * fa + t * fb+        block = np.vstack([xa[rows_a], xb[rows_b]]).astype(np.float64)+        nb = block.shape[0]+        f_out = (block > 0).mean(axis=0)+        upidx = np.flatnonzero(up)+        deficit = np.zeros(block.shape[1])+        deficit[upidx] = np.maximum(f_tgt[upidx] - f_out[upidx], 0.0)+        if not np.any(deficit > 0):+            continue+        dm = d != 0+        dvec = np.asarray(d[dm], dtype=np.float64)+        dev = block[:, dm].astype(np.float64) - block[:, dm].mean(axis=0)+        adv = dev @ dvec / (dvec @ dvec + 1e-9)  # progress toward b+        cap = np.zeros(nb, dtype=int)+        new_block = block.copy()+        bvals = block[rows_a.size:]  # b-side rows within block+        type_act = 0+        for g in upidx[deficit[upidx] > 0]:+            n_add = int(round(DETFIX_FRAC * deficit[g] * nb))+            if n_add <= 0:+                continue+            zero_mask = new_block[:, g] <= 0.0+            cand = np.flatnonzero(zero_mask & (cap < DETFIX_CAP))+            if cand.size == 0:+                continue+            order = cand[np.argsort(-adv[cand])][:n_add]+            if order.size < n_add:+                cap_hits += 1+            # donor values from b-side expressed entries of gene g+            donors = bvals[bvals[:, g] > 0.0, g]+            if donors.size == 0:+                donors = block[block[:, g] > 0.0, g]+            if donors.size == 0:+                continue+            donors = np.sort(donors)+            q = (np.arange(order.size) + 0.5) / order.size+            vals = donors[np.clip((q * donors.size).astype(int), 0, donors.size - 1)]+            new_block[order, g] = vals+            cap[order] += 1+            type_act += int(order.size)+            genes_touched.add(int(g))+            for oi in order:+                cells_touched.add((lab, int(oi)))+        if type_act == 0:+            continue+        new32 = new_block.astype(np.float32)+        xa[rows_a] = new32[:rows_a.size]+        xb[rows_b] = new32[rows_a.size:]+        n_act += type_act+        n_types += 1+        mua = as_dense(stage_a.X, pool_a).mean(axis=0).astype(np.float64)+        mub = as_dense(stage_b.X, pool_b).mean(axis=0).astype(np.float64)+        pb_tgt = (1.0 - t) * mua + t * mub+        gap_b.append(float(deficit[upidx].mean()))+        f_after = (new_block > 0).mean(axis=0)+        gap_a.append(float(np.maximum(f_tgt[upidx] - f_after[upidx], 0.0).mean()))+        pb_b.append(float((pb_tgt[upidx] - block[:, upidx].mean(0)).mean()))+        pb_a.append(float((pb_tgt[upidx] - new_block[:, upidx].mean(0)).mean()))+        zero_before += int((block <= 0).sum())+        zero_after += int((new_block <= 0).sum())+    info.update({"detfix_n_types": n_types, "detfix_n_activations": n_act,+                 "detfix_cells_touched": len(cells_touched),+                 "detfix_genes_touched": len(genes_touched),+                 "detfix_cap_hits": cap_hits})+    if gap_b:+        info.update({"detfix_freq_gap_before": float(np.mean(gap_b)),+                     "detfix_freq_gap_after": float(np.mean(gap_a)),+                     "detfix_zero_before": zero_before, "detfix_zero_after": zero_after})+    return info++ def _psd_sqrt(C):     w, V = np.linalg.eigh(0.5 * (C + C.T))     w = np.clip(w, 0.0, None)@@ -678,6 +931,54 @@ def mix_converge(stage_a, stage_b, t: float, params: dict, alpha: float):                      float(params.get("count_damp", 1.0)))     ia, ib = mix_indices(stage_a.labels, stage_b.labels, t, n, rng) +    # Centroid-distance-controlled swap (this node, family T2EI-01): changes only+    # WHICH real cells enter the output, before the converge shift. Uses its own+    # rng stream so the parent's mix draw / jitter stream stays bit-identical.+    spread_info = {"spread_kappa": SPREAD_KAPPA, "spread_dist_mode": SPREAD_DIST_MODE,+                   "spread_rad_mult": SPREAD_RAD_MULT,+                   "spread_min_cells": SPREAD_MIN_CELLS,+                   "spread_n_types": 0, "spread_n_swaps": 0, "spread_n_cand": 0,+                   "spread_swap_frac": None, "spread_rms_rel": None,+                   "spread_rms_before": None, "spread_rms_after": None}+    if SPREAD_KAPPA > 0.0 and ia.size and ib.size:+        m_a = type_means(stage_a.X, stage_a.labels)+        m_b = type_means(stage_b.X, stage_b.labels)+        la_all = np.asarray(stage_a.labels).astype(str)+        lb_all = np.asarray(stage_b.labels).astype(str)+        cnt_a = {k: int((la_all == k).sum()) for k in m_a}+        cnt_b = {k: int((lb_all == k).sum()) for k in m_b}+        mu_tgt = {}+        for lab in sorted(set(m_a) & set(m_b)):+            if cnt_a[lab] >= SPREAD_MIN_CELLS and cnt_b[lab] >= SPREAD_MIN_CELLS:+                mu = ((1.0 - t) * m_a[lab].astype(np.float64)+                      + t * m_b[lab].astype(np.float64))+                gmask = None+                if SPREAD_DIST_MODE == "de":+                    gmask = np.abs(m_b[lab].astype(np.float64)+                                   - m_a[lab].astype(np.float64)) >= CONVERGE_MIN_DELTA+                    if int(gmask.sum()) < PAIR_MIN_DE:+                        continue+                mu_tgt[lab] = (mu, gmask)+        if mu_tgt:+            swap_rng = np.random.default_rng(int(params.get("seed", 0)) + 987654321)+            ia, sa = spread_swap(stage_a, ia, stage_a.labels, mu_tgt, SPREAD_KAPPA, swap_rng, "a", coords=ca)+            ib, sb = spread_swap(stage_b, ib, stage_b.labels, mu_tgt, SPREAD_KAPPA, swap_rng, "b", coords=cb)+            sw_tot = int(sa["n_swaps"] + sb["n_swaps"])+            fr = [x for x in (sa["swap_frac_mean"], sb["swap_frac_mean"]) if x is not None]+            rl = [x for x in (sa["rms_rel"], sb["rms_rel"]) if x is not None]+            rb = [x for x in (sa["rms_before"], sb["rms_before"]) if x is not None]+            ra = [x for x in (sa["rms_after"], sb["rms_after"]) if x is not None]+            spread_info.update({+                "spread_n_types": int(sa["n_types"] + sb["n_types"]),+                "spread_n_swaps": sw_tot, "spread_n_cand": int(sa["n_cand"] + sb["n_cand"]),+                "spread_swap_frac": float(np.mean(fr)) if fr else None,+                "spread_rms_rel": float(np.mean(rl)) if rl else None,+                "spread_rms_before": float(np.mean(rb)) if rb else None,+                "spread_rms_after": float(np.mean(ra)) if ra else None,+                "spread_n_swaps_a": int(sa["n_swaps"]), "spread_n_swaps_b": int(sb["n_swaps"]),+                "spread_rms_rel_a": sa["rms_rel"], "spread_rms_rel_b": sb["rms_rel"],+            })+     # Progress-weighted reselection (this node): keeps per-type counts, changes     # only WHICH cells of each shared type are drawn. Skipped entirely when     # disabled so the rng consumption order matches the parent bit-for-bit.@@ -875,6 +1176,17 @@ def mix_converge(stage_a, stage_b, t: float, params: dict, alpha: float):         pair_info["n_paired_types"] = n_types_paired         pair_info["n_pairs"] = n_pairs +    detfix_info = {"detfix_frac": DETFIX_FRAC, "detfix_n_types": 0,+                   "detfix_n_activations": 0}+    if DETFIX_FRAC > 0.0 and ia.size and ib.size:+        if not shared:+            means_a, means_b, shared, delta = compute_delta(stage_a, stage_b, 10)+        if delta:+            labs_a_f = np.asarray(stage_a.labels).astype(str)[ia]+            labs_b_f = np.asarray(stage_b.labels).astype(str)[ib]+            detfix_info = detection_restore(xa, xb, labs_a_f, labs_b_f,+                                            stage_a, stage_b, t, delta)+     varrest_info = {"varrest_gamma": VARREST_GAMMA, "varrest_n_types": 0}     if VARREST_GAMMA != 0.0 and ia.size and ib.size:         if not shared:@@ -916,7 +1228,7 @@ def mix_converge(stage_a, stage_b, t: float, params: dict, alpha: float):     info.update(         t=t, n=int(expr.shape[0]), rms_a=rms_a, rms_b=rms_b, target_rms=target_rms,         out_rms=rms_radius(coords), n_from_a=int(ia.size), n_from_b=int(ib.size), **conv, **pair_info,-        **prog_info, **varrest_info, **recolor_info,+        **prog_info, **varrest_info, **recolor_info, **spread_info, **detfix_info,     )     return expr, coords.astype(np.float32), info @@ -926,8 +1238,19 @@ def main() -> None:     parser.add_argument("--data", required=True)     parser.add_argument("--out", required=True)     parser.add_argument("--seed", type=int, default=0)+    parser.add_argument("--ablate", default=None)     args = parser.parse_args() +    if args.ablate is not None:+        # Mechanism-off control: disable this node's new mechanisms (the+        # centroid-distance swap and the detection-frequency restoration; any+        # name is treated as this node's main mechanism), leaving every other+        # step, the seed and the output format untouched so the output is+        # bit-identical to parent node 24.+        global SPREAD_KAPPA, DETFIX_FRAC+        SPREAD_KAPPA = 0.0+        DETFIX_FRAC = 0.0+     manifest = load_manifest(args.data)     genes = panel_genes(args.data, manifest)     a, b, t = interp_bracket(manifest)@@ -964,6 +1287,15 @@ def main() -> None:                                           "recolor_entries_frac", "recolor_rel_corr_dist",                                           "recolor_max_entry_change", "recolor_max_mean_drift",                                            "recolor_zero_before", "recolor_zero_after",+                                           "spread_kappa", "spread_dist_mode", "spread_rad_mult", "spread_min_cells",+                                           "spread_n_types", "spread_n_swaps", "spread_n_swaps_a", "spread_n_swaps_b",+                                           "spread_n_cand", "spread_swap_frac", "spread_rms_rel",+                                           "spread_rms_rel_a", "spread_rms_rel_b",+                                           "spread_rms_before", "spread_rms_after",+                                           "detfix_frac", "detfix_n_types", "detfix_n_activations",+                                           "detfix_cells_touched", "detfix_genes_touched", "detfix_cap_hits",+                                           "detfix_freq_gap_before", "detfix_freq_gap_after",+                                           "detfix_zero_before", "detfix_zero_after",                                            "occup_eta", "occup_clamp", "occup_l1_before", "occup_l1_after",                                            "occup_moved", "occup_n_cells", "occup_disp_mean", "occup_disp_max",                                            "occup_dice_self_before", "occup_dice_self_after",

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

用到的知识库条目

编号标题出处
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
k009Conditional / OT flow matching for population transportarXiv:2210.02747 (Lipman et al., Flow Matching for Generative Modeling)

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

改了什么实现了型内质心距离控制交换(T2_SPREAD_KAPPA,含 all/de 距离模式与空间受限解码)及两个备选机制(DETFIX 检出频率恢复、β/α 幅度扫描),同日 A 半 15 次查分后全部证否;提交默认 κ=0、DETFIX_FRAC=0,seed 0 输出与父节点 24 逐位相同,故榜分不变(62.52,+0.00)。
各组分数的变化cell_state:不变(50.31,+0.00;mmd_u raw 0.01123、variogram raw 0.01392 同父节点)。off-board 查分显示 κ 交换确能压 variogram raw(0.01442→0.01346 @κ=3.0×rad3,约 +0.21 pts 上限),但被 neighborhood/de_direction/occupancy 附带损失吞掉,净 +0.013 至 −0.85,均在噪声内或为负
expression_change:不变(62.11,+0.00;de_score raw 0.3103、de_direction raw 0.3986 均与父节点逐位相同,提交态机制关闭)
local_spatial:不变(60.34,+0.00;neighborhood_mmd raw 0.05112 同父节点)。off-board:κ≥3 时 nbrhd raw +0.0021~+0.0035 破 0.001 否决线
shape_scale:不变(77.31,+0.00;提交态与父节点逐位相同)
family_idT2EI-01
假设是否成立否
经验
  1. 在 mix 混抽管线上,用型内多维径向距离做偏好交换(κ=0.3–3.0,7 种解码)确实压缩型内 RMS 散布(×0.958–0.99)并单调降低 variogram raw,但收益上限实测仅约 +0.21 pts,恒被 neighborhood_mmd / de_direction / occupancy_dice 的附带损失抵消,净变化 +0.013 至 −0.85,全部在噪声内或为负——选择侧散布压缩路线在本管线判死(节点 15/17/19/21/32 五次证伪)。
  2. DETFIX(把 up-DE 基因检出频率拉向括号线性插值目标 (1−t)f_a+t·f_b)净 −3.80,variogram raw 恶化 78%(0.0144→0.0257):真实中间阶段在 up-DE 基因上比线性插值目标更'早',任何朝插值目标修复统计量(幅度或频率)的方向都应放弃,这也统一解释了节点 17/19/21 的失败。
  3. α(收敛强度)5→6.5 扫描显示结构性张力:neighborhood_mmd 与 variogram 随 α 单调改善(α=6.5 时 nbrhd raw 0.05387 全表最好),但 mmd_u 加速劣化(0.01164→0.01524 @α=8),净峰值 α=5.5 仅 +0.037(噪声内)——父节点 α=5 已近最优,靠加大压缩换 neighborhood/variogram 的方向会被 mmd_u 吞掉。
  4. β 配对收缩 0.2→0.4 单调改善 cell_state(48.93→49.33)但 neighborhood 同步单调损失(−0.118),净 ≈0:表达侧压缩的收益/代价比在当前压缩水平已打平。
  5. 机制默认关闭 + 专用 rng 流(不扰动主管线 rng)能保证 κ=0 与 --ablate 逐位复现父节点,off/on 对照干净,值得沿用。
mechanism_active否
下一步建议
  1. 停止在 embryo:val_interp 上做 cell_state/variogram 方向的改动:选择侧与数值侧压缩五连败、收益上限 +0.2 pts,坐标侧亦五次证伪(节点 13/21/22/24/32),62.5 大概率是 mix 家族本榜平台。
  2. 若仍想动表达分布,只试'比父节点更早'的反方向(DETFIX 证明真值比插值目标更早),例如 α 降到 4–4.5 或减小 up-DE 位移幅度,同日锚点比较并盯 mmd_u 是否同步改善;预期有限,作低优先级。
  3. 把搜索火力转向 heart 两榜(尤其外推榜需用同日锚点比较,本地尺子已知高估),复用本树的 mix+收敛管线作起点。

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

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

分析员

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

工程师

角色工程师 alibaba-token-plan-cn/qwen3.8-max
调用次数1 次
轮数78
工具调用共 82 次:bash 51、edit 27、read 2、write 2
用时58 分
token 数输入 188,295 · 输出 32,435 · 思考 67,026
任务(第一行)按计划修改程序:型内表达质心距离控制抽样降低 variogram(T2EI-01)
最后的回答(摘录)
完成。最终提交状态:`solution/` 默认输出与父节点 24 逐位一致(seed 0/1/2 均复现,两个新机制完全由 `SPREAD_KAPPA>0` / `DETFIX_FRAC>0` 门控且使用专用 rng 流),`--ablate mechanism` 同样逐位复现父节点,vec-check 通过。

**做了什么**:按 PLAN 实现型内质心距离控制交换(T2_SPREAD_KAPPA,含 all/de 距离模式、空间受限解码、κ=0.3–3.0),另实现并测试两个备选机制:DETFIX(up-DE 基因检出频率向括号插值目标恢复)与 β/α 幅度扫描。共 15 次查分(同日 A 半锚点 61.453)。

**查分结果**:PLAN 机制 7 种解码全部净负或噪声内(+0.013 ~ −0.85)——交换确实压缩型内散布(RMS ×0.958–0.99)且 variogram raw 单调下降(最大 −0.00096,+0.21 pts),但恒被 neighborhood_mmd(κ≥3 破 0.001 否决线)与 de_direction/occupancy 损失吞掉。备选 DETFIX 强烈证否(−3.80,variogram raw +78%),并揭示关键事实:**线性插值目标系统性高估真实中间阶段**(up-DE 基因检出频率真值比 (1−t)f_a+t·f_b 更"早")。β=0.3/0.4 与 α=5.5/6/6.5/8 扫描净峰值仅 +0.037(α=5.5,噪声内);α 增大时 neighborhood/variogram 单调改善但 mmd_u 加速劣化,验证父节点 α=5 近最优。METHOD.md 首行已写 `NO_CHANGE:`,全部 13 个配置的分项表与结论已记录。

**下一步最值得试**:(1) variogram/cell_state 方向可判死——选择侧与数值侧压缩五连败,收益上限 +0.2 pts;(2) 任何朝"括号线性插值目标"修复统计量的方向应放弃(DETFIX 实证),反方向(比父节点更"早")未测但预计同样被 mmd_u 抵消;(3) 本榜 62.5 是 mix 家族真实平台,建议火力转向 heart 两榜(外推榜需同日锚点比较,本地尺子高估)。
原始记录位置/home/spark-longxinyang/vec/runs/formal/20261003-171955-search-t2-embryo-interp-chain-12h/nodes/32/engineer.jsonl 507 KB
/home/spark-longxinyang/vec/runs/formal/20261003-171955-search-t2-embryo-interp-chain-12h/nodes/32/engineer.stderr

调研员

角色调研员 alibaba-token-plan-cn/qwen3.8-max
调用次数1 次
轮数1
工具调用共 0 次:—
用时3 分
token 数输入 18,883 · 输出 1,274 · 思考 7,858
任务(第一行)为节点 n32(改进,父节点 n24)写改进计划 PLAN.json
最后的回答(摘录)
1392,skill 0.389,低于地板 0.5,仅 4.87/12.5 分)。混抽两阶段细胞引入额外型间方差,使 E|x_i−x_j|^0.5 高于真实中间阶段;表达侧数值变换三连败(节点 17/19/21),坐标侧四次证伪(13/21/22/24)。ANALYSIS 建议'选哪些真实细胞'层面动手。节点 15 按 Δ 方向进度选细胞使 variogram 更差(0.01442→0.01515),因为进度选择只压缩 Δ 方向、增大垂直方向方差。本方案改为多维径向距离选择,直接压缩全方向散布。",
  "approach": "在父节点 24 全部管线(mix 分层、procrustes3d、α=5、λ=6、β=0.2、aniso、jitter、RMS 回缩)的 mix 步骤内新增质心距离控制交换(环境变量 T2_SPREAD_KAPPA,默认 0=关闭):\n1. 对每个共有类型(≥20 细胞/侧),用全部 panel 基因计算插值质心 μ_tgt=(1−t)·μ_a+t·μ_b。\n2. 对已选入的每个细胞计算 d_i=‖x_i−μ_tgt‖₂(只用 nnz 基因,避免稀疏维度膨胀距离)。\n3. 按来源侧(a/b)分别计算中位距离 d_med;对 d_i>d_med 的细胞,以概率 κ·(d_i−d_med)/d_med 将其与同型、同来源侧中随机一个 d_j<d_med 的细胞交换(swap 模式,不改变细胞总数、不改变 a/b 比例、不额外消耗坐标 rng 流)。\n4. κ 搜索范围 {0.3, 0.6, 1.0},先小样本 1500 细胞快筛(只跑 variogram+mmd_u 两项的本地计算),再全量 5000 查分。\n5. 交换在 converge shift 之前执行,后续 α/λ/β 照常作用于交换后的细胞。\n6. 单输入阶段退路:无括号时 main() 提前 return,机制不执行(与父节点一致)。\n7. vec-score 快筛:先跑 off(κ=0)确认与父节点逐位一致,再跑 κ=0.6 全量查分;若 variogram raw 降幅 <0.0005 或 neighborhood_mmd raw 升幅 >0.001 即停。",
  "expected_groups": ["cell_state"],
  "risks": "1. 交换引入坐标变化:被换入的细胞坐标不同,可能微扰邻域结构。缓解:swap 保持同型同来源侧,空间分布变化有限;以 neighborhood_mmd raw 升幅 ≤0.001 为一票否决。2. 过度压缩散布使 mmd_u 变差(分布过窄)。缓解:κ 从 0.3 起步,观察 mmd_u raw 是否上升;若升 >0.0005 则判负。3. 与节点 15 类似的坐标重抽样噪声:节点 15 用 redraw 模式全量重抽,本方案用 swap 模式只换少量细胞(预期 <30%),坐标变化幅度远小于节点 15。4. 若 variogram 改善 <0.5 分(噪声内),用 3 次查分(seed 0/1/2)确认方向一致性。",
  "family_id": "T2EI-01",
  "mechanism": "在型内按细胞到插值质心的多维表达距离做偏好交换:远离质心的细胞被换为靠近质心的同型同侧细胞,直接压缩全方向型内散布,降低基因对差异期望 E|x_i−x_j|^0.5。",
  "vs_constant_shift": "常数位移对型内所有细胞加同一向量,不改变型内散布、不改变哪些细胞被选中;本机制不修改任何细胞的表达值,只改变哪些真实细胞进入输出,且选择依据是多维径向距离(非沿 Δ 的 1D 投影),压缩的是全方向方差而非仅平移均值。",
  "mechanism_evidence": "Engineer 应报告:(1) 每型实际交换的细胞数与比例;(2) 交换前后型内 RMS 散布(全部基因)的变化;(3) variogram raw 的变化(预期下降);(4) mmd_u raw 的变化(预期持平或微降);(5) neighborhood_mmd raw 变化(预期 ≤+0.001);(6) 四组分各自变化。若交换比例为 0 或型内 RMS 不变,说明机制未运行。",
  "mechanism_off_control": "T2_SPREAD_KAPPA=0(提交默认):交换步骤整体跳过(不计算距离、不执行交换、不消费 rng),输出与父节点 24 逐位相同(array_equal 验证 X 与 spatial_3D)。开启(κ>0)后预期型内 RMS 下降、variogram raw 下降、细胞总数与 a/b 比例不变。",
  "sources": []
}
原始记录位置/home/spark-longxinyang/vec/runs/formal/20261003-171955-search-t2-embryo-interp-chain-12h/nodes/32/researcher.jsonl 5 KB
/home/spark-longxinyang/vec/runs/formal/20261003-171955-search-t2-embryo-interp-chain-12h/nodes/32/researcher.stderr