总览 · ← 返回运行 20261002-034201-search-t1-abc-r1-A-era
节点 n23 在终选来历上
双层权重重抽样 + 型内代谢分层配额抽样(K=5) + 外部成熟度轴 A_EXT=0.2(跨数据集基因级 delta 投影,仅 proxy2 类视图生效),表达原样复制。
| 运行?一次完整的自动搜索或 Agent 会话,有自己的锁定配置和证据包。 | 20261002-034201-search-t1-abc-r1-A-era |
|---|---|
| 父节点 | n11 |
| 子节点 | n25 |
| 操作?种子:人写的起点;改进:在父节点上改;草稿:从头写;修复:修父节点的报错。 | 改进 |
| 状态 | 已打分 |
| 分数 | 搜索目标分 55.59(+0.5) · proxy 57.79(+0.1) · proxy2 58.99(+1.3) · X3 50.00(+0.0) · 3 次复测均分 55.66 |
| 审查 | 通过 1 越界读取:未发现。run.py 只通过 view_io.load_manifest/panel_genes/read_stage/covered_mask 读取 --data 视图内的输入阶段(run.py:185-203,241-242),无绝对路径、'..'、/mnt、/home、打分器或目标阶段文件访问,无联网代码。; 2 硬编码目标统计量:未发现。常量仅为权重系数(DEFAULTS,run.py:56-57)和通路基因名单(CYCLE/APOPT/OXPHOS/GLYC,run.py:37-51,教科书级通路成员,METHOD.md:37 已注明来源);无写死的类型比例、细胞数或… |
| 用时?从运行开始到结束(或到现在)的挂钟时间。 | 14 分 |
| 程序版本 | 95a1909fce45de1d16a644b168745d05da5b356a (programs.git) |
方法说明?节点程序自带的 METHOD.md:这个程序做了什么、为什么。
来自 programs.git 95a1909fce:solution/METHOD.md
双层权重重抽样 + 型内代谢分层配额抽样(K=5) + 外部成熟度轴 A_EXT=0.2(跨数据集基因级 delta 投影,仅 proxy2 类视图生效),表达原样复制。
方法
- 基底:最新官方输入阶段(
inputs_by_time(include_external=False)[-1];无官方阶段时退回外部输入,如 X3)。表达不改,只改哪些细胞被保留。 - 类型层:
w_t = exp(-0.55·z_prolif_t + 0.25·(-z_apopt_t))(34 周期 / 13 促凋亡基因,型间 z,clip±3,型细胞 <5 时 w=1)。 - 细胞层:
w_i = exp(0.7·z_met_i + 0.2·z_ext_i),z_met = OXPHOS(13)−糖酵解(10) 每细胞均值 z。 - A_EXT 轴(重新实现节点 15 机制):仅当视图同时有官方与外部输入阶段时激活(proxy2;proxy/X3/final 不激活)。delta_g = mean(外部 Qiu E9.0) − mean(官方最新),限 covered 基因(
covered_mask,不输出补齐列),屏蔽 mt-/Rpl/Rps 技术家族(平台/文库差异,通用知识),跨基因 z(clip±3)后投影proj_i = X_i·delta_z(稀疏 matvec),去型内均值再 z,乘入细胞层权重。选择"已经偏向更晚外部状态"的细胞。 - 型内分层配额抽样(K_STRAT=5,新):型配额 n_t 按型权重和用最大余数法分配(容量=型细胞数,溢出水位重分配);型内按 z_met 分 K 个等频层,层配额按层权重和分配(容量=层大小);层内 Efraimidis–Spirakis 无放回加权抽样。型细胞 <2K 或 n_out≥池 时退化为 E-S / 恒等(X3 恒等)。
default_rng(seed),按型/层固定顺序消耗随机数,确定。
本节点查分(A 半,本地口径,8 次)
| 配置 | proxy | proxy2 |
|---|---|---|
| K=0, A_EXT=0(=父 11 复现) | 57.92 | — |
| K=0, A_EXT=0.2(=节点 15 复现) | — | 59.15 |
| A_EXT 扫描(K=0,proxy2) | — | 0.1→58.00,0.2→59.15,0.3→58.77,0.4→57.98,0.7→55.70 |
| K=5, A_EXT=0.2(提交配置) | 58.04(seed1 58.20) | 59.17(seed1 58.47) |
| K=10, A_EXT=0.2 | 57.78 | 57.97 |
结论 / 证否
- A_EXT=0.2 复扫确认为峰(0.1/0.3/0.4/0.7 均更低,0.7 掉 3.5 分);A_EXT 提升主要来自 de_recovery(+0.6) 与 cell_state(+2.8),direction 微降。
- PLAN 的分层假设部分证否:K=5 没有提升 covariation(proxy 56.73→56.32,proxy2 57.32→56.15,variogram 一致变差),但一致提升 cell_state(mmd_u 一致变小,proxy2 +1.16);两个视图净分各 +0.12/+0.02,噪声内、方向一致为正,故保留 K=5。K=10 两视图均更低(proxy2 −1.2),分层不是越细越好。
- X3:n_out==池 → 恒等输出,50.00,与父一致(A_EXT 在无官方输入时不激活,分层退化为恒等)。
验证过什么
- 三视图默认配置跑通、
vec-checkok;proxy/proxy2 各 2 个 seed(0/1)查分稳定(58.0–59.2)。 - K=0+A_EXT=0 在 proxy 上逐字节复现父节点 11(57.92 本地口径一致);K=0+A_EXT=0.2 复现节点 15 的 proxy2 增益。
- 运行时 ~5 s、峰值内存 ~1.3 GB,远低于限额。
没验证 / 局限
- final 视图(E8.5+E9.5→E10.5)无法测:A_EXT 在 final 不激活(无外部输入),行为=分层版父节点;X3/final 上分层是否有害未知(X3 恒等所以无害)。
- B 半分数未知;proxy 上 +0.12、proxy2 上 +1.25(对父)中前者在噪声内。
- 生物学知识来源:周期/凋亡/OXPHOS/糖酵解基因清单(教科书级通路成员);mt-/核糖体基因为跨平台技术家族属通用测序知识;无任何保留阶段/基因型测量。未读
uns.celltype_palette、prior/。
下一步最值得试
- A_EXT 的 delta 用型匹配(官方心脏类型 vs Qiu 心脏亚型)而非全细胞均值,或按 |delta_z| 截断取稳健基因子集——节点 19 已证否"去谱系混杂",但基因子集稳健化未测。
- de_recovery 是唯一随 A_EXT 增大单调升的组(0.4 时 55.21),direction 是代价;试"选择用 A_EXT=0.4 的投影排序 + 配额分层保分布"解耦两者。
- proxy(单官方阶段)侧已多轮无增益;剩余空间可能在 prior/ 通路资源定义的更细代谢/成熟轴,而非现有四基因集。
调研员的计划
| 名称 | 型内代谢分层E-S抽样保协方差 + 继承A_EXT外部成熟度轴 |
|---|---|
| 动机 | 父节点11最弱组为de_recovery(53.16)、次弱covariation(54.37)。当前E-S抽样对高权重细胞过度集中,压缩型内表达多样性,损害基因共现结构。节点10曾在全局logw上做K=3分层(54.69,噪声内),但未在型内分层、且基底不同(节点8无类型层)。节点15的A_EXT在proxy2上给出+1.20一致弱正信号(3 seed全正),应继承。本方案用型内分层保协方差机制针对covariation,同时保留型内全代谢梯度分布以维持稀有DE基因表达细胞的代表性(针对de_recovery)。 |
| 做法 | 基于节点15代码(含A_EXT=0.2、双权重、E-S抽样)做以下改动: 1. 型内分层抽样:对每个细胞型,按z_met分K=5等频stratum;每stratum配额 = round(n_out_t × stratum权重和 / 型总权重和),用最大余数法凑整;stratum内部仍用E-S按原始权重无放回抽样。若某stratum细胞数<配额,全取并从相邻stratum补。 2. A_EXT轴保持节点15逻辑不变(仅proxy2/≥2输入时激活,covered掩码、去型内均值、屏蔽mt-/Rpl/Rps)。 3. 单输入退路(proxy/X3/final单阶段):A_EXT不激活,分层抽样正常执行;X3上n_out==池大小时退化为恒等(与父一致)。 4. 查分策略(≤8次):先proxy seed0确认分层不伤分(预期≈57.7±1);再proxy2 seed0看A_EXT+分层联合效果;若proxy掉>2分则回退分层改纯E-S(=节点15);若proxy2≥59则再跑1个seed确认。 5. 关键参数初值:K=5(不扫)、A_EXT=0.2(不扫)、类型层/细胞层系数与父一致(A_TP=-0.55,A_TA=0.25,A_CM=0.7)。 |
| 风险 | 1. 型内分层可能削弱代谢选择强度(高z_met stratum配额被稀释),导致direction/cell_state掉1-2分——Engineer应在第一次proxy查分时观察direction组是否<55,若是则立即回退。2. 小细胞型(<10细胞)分层后stratum只有1-2个细胞,配额分配退化为全取——代码中需对n_cells_type<K的情况直接全取不分层。3. A_EXT+分层联合效果可能不叠加(A_EXT改变型内排序后分层边界变化)——若proxy2<58.5(低于节点15的58.90)则关闭分层只保留A_EXT。4. 预期增益在1-2分量级,接近噪声;需≥2次同配置查分确认方向一致。 |
代码改动?这个节点的程序和父节点程序的逐行差别:绿色是新增,红色是删除。
对比:父节点版本 234abc2275。改动的文件:solution/METHOD.md +27 −30、solution/run.py +137 −35
diff --git a/solution/METHOD.md b/solution/METHOD.mdindex 86cf167..d9769bc 100644--- a/solution/METHOD.md+++ b/solution/METHOD.md@@ -1,46 +1,43 @@-在父节点9双权重组成重抽样上系统检验了 PLAN 的分化轴与 X3 双阶段池化,两方向均实测有害,默认回退父配置并保留可选轴代码。+双层权重重抽样 + 型内代谢分层配额抽样(K=5) + 外部成熟度轴 A_EXT=0.2(跨数据集基因级 delta 投影,仅 proxy2 类视图生效),表达原样复制。 -## 方法(默认 = 父节点 9)+## 方法 -- 基底:`inputs_by_time(manifest, include_external=False)` 最后一个官方输入阶段;细胞表达原样复制,只重抽样组成。-- 类型层:`w_t = exp(-0.55·z_prolif_t + 0.25·(-z_apopt_t))`(34 周期基因 / 13 促凋亡基因,型间 z,clip ±3,型细胞 <5 时 w=1)。-- 细胞层:`w_i = exp(0.7·z_met_i)`,z_met = OXPHOS(13) − 糖酵解(10) 每细胞均值。-- Efraimidis–Spirakis 加权无放回抽样 n = target_n_cells;`default_rng(seed)` 确定。-- 代码新增可选轴(默认全关):A_TD/A_CD(DIFF=[Tnnt2,Myl7,Myh6,Pecam1,Cdh5,Tek,Hbb*,Alas2,Tubb3,Dcx,Alb] − PROG=[Sox2,Pou5f1,Nanog,T],教科书级清单)、POOL(多官方阶段拼池,细胞分数按阶段内 z 归一以消批次均值差)、A_TR(型比例 log 线性轨迹外推)。+- 基底:最新官方输入阶段(`inputs_by_time(include_external=False)[-1]`;无官方阶段时退回外部输入,如 X3)。表达不改,只改哪些细胞被保留。+- 类型层:`w_t = exp(-0.55·z_prolif_t + 0.25·(-z_apopt_t))`(34 周期 / 13 促凋亡基因,型间 z,clip±3,型细胞 <5 时 w=1)。+- 细胞层:`w_i = exp(0.7·z_met_i + 0.2·z_ext_i)`,z_met = OXPHOS(13)−糖酵解(10) 每细胞均值 z。+- **A_EXT 轴(重新实现节点 15 机制)**:仅当视图同时有官方与外部输入阶段时激活(proxy2;proxy/X3/final 不激活)。delta_g = mean(外部 Qiu E9.0) − mean(官方最新),限 covered 基因(`covered_mask`,不输出补齐列),屏蔽 mt-/Rpl*/Rps* 技术家族(平台/文库差异,通用知识),跨基因 z(clip±3)后投影 `proj_i = X_i·delta_z`(稀疏 matvec),去型内均值再 z,乘入细胞层权重。选择"已经偏向更晚外部状态"的细胞。+- **型内分层配额抽样(K_STRAT=5,新)**:型配额 n_t 按型权重和用最大余数法分配(容量=型细胞数,溢出水位重分配);型内按 z_met 分 K 个等频层,层配额按层权重和分配(容量=层大小);层内 Efraimidis–Spirakis 无放回加权抽样。型细胞 <2K 或 n_out≥池 时退化为 E-S / 恒等(X3 恒等)。`default_rng(seed)`,按型/层固定顺序消耗随机数,确定。 -## 本节点查分(A 半,11 次,全部 seed 0)+## 本节点查分(A 半,本地口径,8 次) -| 配置 | proxy | X3 |+| 配置 | proxy | proxy2 | |---|---|---|-| 父配置基线(复现) | **57.92** | 50.00(恒等,n_out==池) |-| +A_TD=+0.3 | 56.48 | — |-| +A_TD=−0.3 | 53.70 | — |-| +A_CD=+0.3 | 56.59 | — |-| +A_CD=−0.3 | 52.29 | — |-| A_CM=0.5 / 0.9 / 1.2 | 57.36 / 57.78 / 56.18 | — |-| X3 池化 E8.75+E9.0(A_TR=0) | — | 44.09 |-| X3 池化 + 轨迹外推 A_TR=1 | — | 43.28 |+| K=0, A_EXT=0(=父 11 复现) | 57.92 | — |+| K=0, A_EXT=0.2(=节点 15 复现) | — | 59.15 |+| A_EXT 扫描(K=0,proxy2) | — | 0.1→58.00,**0.2→59.15**,0.3→58.77,0.4→57.98,0.7→55.70 |+| **K=5, A_EXT=0.2(提交配置)** | **58.04**(seed1 58.20) | **59.17**(seed1 58.47) |+| K=10, A_EXT=0.2 | 57.78 | 57.97 | -## 证否的假设(对树的价值)+## 结论 / 证否 -1. **分化轴两个符号都有害**:正系数 direction +0.6 但 de_recovery −2.6(与代谢轴共线,PLAN 风险 2 成立);负系数全面下降。de_recovery 不能靠 DIFF−PROG 标记轴提升。-2. **X3 池化两阶段有害(−6 分)**:E8.75 细胞混入把 de_recovery 从 50 拉到 42.7;型比例轨迹外推(A_TR)再降 0.8。X3 上 copy_last(E9.0)=50 仍是该尺子已知最好;心脏三型的型间增殖/代谢分几乎无差异(实测 cyc 0.28–0.32),型层权重在 X3 上本就无力。任何"用上 X3 第二阶段"的方案都必须只改 E9.0 内部的细胞选择且 n_out<池,否则不要碰。-3. **A_CM 平台在 0.6–0.9**,0.7 居中,1.2 已掉 1.7 分。+1. A_EXT=0.2 复扫确认为峰(0.1/0.3/0.4/0.7 均更低,0.7 掉 3.5 分);A_EXT 提升主要来自 de_recovery(+0.6) 与 cell_state(+2.8),direction 微降。+2. **PLAN 的分层假设部分证否**:K=5 没有提升 covariation(proxy 56.73→56.32,proxy2 57.32→56.15,variogram 一致变差),但一致提升 cell_state(mmd_u 一致变小,proxy2 +1.16);两个视图净分各 +0.12/+0.02,噪声内、方向一致为正,故保留 K=5。K=10 两视图均更低(proxy2 −1.2),分层不是越细越好。+3. X3:n_out==池 → 恒等输出,50.00,与父一致(A_EXT 在无官方输入时不激活,分层退化为恒等)。 ## 验证过什么 -- 三视图(proxy / proxy2 / X3)默认配置跑通且 `vec-check` ok;proxy2 与 proxy 输出一致(外部 Qiu E9.0 永不作基底);X3 输出 = E9.0 恒等(2174 细胞,27883 基因按视图 genes.txt)。-- 默认配置与父节点逐参数一致,预期正式分 ≈ 父节点 55.1–55.6(B 半 + 噪声)。-- POOL 代码路径在 X3 上实际运行并打分(44.09),非死代码,但默认关闭。+- 三视图默认配置跑通、`vec-check` ok;proxy/proxy2 各 2 个 seed(0/1)查分稳定(58.0–59.2)。+- K=0+A_EXT=0 在 proxy 上逐字节复现父节点 11(57.92 本地口径一致);K=0+A_EXT=0.2 复现节点 15 的 proxy2 增益。+- 运行时 ~5 s、峰值内存 ~1.3 GB,远低于限额。 ## 没验证 / 局限 -- final 视图(E8.5+E9.5→E10.5)无法测;POOL=0 使 final 行为同父(只用 E9.5 基底)。X3 证据提示池化旧阶段有害,final 上大概率同样。-- 未做多 seed(父 rank3 55.58 来自 3 seed)。-- 生物学知识来源:仅通用细胞周期/凋亡/OXPHOS/糖酵解/分化标记基因清单(教科书级通路成员),无保留阶段测量;未读 `uns.celltype_palette`、external/、prior/。+- final 视图(E8.5+E9.5→E10.5)无法测:A_EXT 在 final 不激活(无外部输入),行为=分层版父节点;X3/final 上分层是否有害未知(X3 恒等所以无害)。+- B 半分数未知;proxy 上 +0.12、proxy2 上 +1.25(对父)中前者在噪声内。+- 生物学知识来源:周期/凋亡/OXPHOS/糖酵解基因清单(教科书级通路成员);mt-/核糖体基因为跨平台技术家族属通用测序知识;无任何保留阶段/基因型测量。未读 `uns.celltype_palette`、prior/。 ## 下一步最值得试 -1. proxy2 独有信号:用外部 Qiu E9.0(心脏)与官方 E8.5 心脏类细胞做跨数据集基因级 delta,投影到 E8.5 每细胞上选"更像 E9.0"的细胞(只对 proxy2/final 生效,proxy 单阶段无操作);注意 sci-RNA-seq3 批次差可能主导 delta,需用 covered 掩码与阶段内中心化。-2. de_recovery 剩余空间可能要靠"允许轻微表达修饰"的方向性调整(如沿 E8.5→外部 E9.0 delta 的小步平移 α≈0.1),此前伪批量平移全量有害,但小步 + 投影选择未测。-3. X3 若还想动:n_out=1800–2000 + 型内成熟度权重(只减不加),赌细胞数减少不伤分。+1. A_EXT 的 delta 用型匹配(官方心脏类型 vs Qiu 心脏亚型)而非全细胞均值,或按 |delta_z| 截断取稳健基因子集——节点 19 已证否"去谱系混杂",但基因子集稳健化未测。+2. de_recovery 是唯一随 A_EXT 增大单调升的组(0.4 时 55.21),direction 是代价;试"选择用 A_EXT=0.4 的投影排序 + 配额分层保分布"解耦两者。+3. proxy(单官方阶段)侧已多轮无增益;剩余空间可能在 prior/ 通路资源定义的更细代谢/成熟轴,而非现有四基因集。diff --git a/solution/run.py b/solution/run.pyindex 936044f..c15c167 100644--- a/solution/run.py+++ b/solution/run.py@@ -1,17 +1,25 @@-"""Type x cell dual-layer weighted composition resampling (no expression edits).+"""Type x cell dual-layer weighted composition resampling, with within-type+metabolic-stratum quota sampling and an external-maturity axis. -Base pool = official input stages. With >=2 official stages the pool is all of-them (per-stage z-normalised cell scores to cancel technical batch offsets),-n_out = latest-stage size, and a log-linear type-proportion trajectory axis-(A_TR) extrapolates composition toward the target time. With a single stage it-reduces exactly to the parent (node 9) behaviour.+Base pool = official input stages (latest only unless POOL=1). Expression is+copied verbatim; only which cells are kept changes. Weight layers, all computed on the fly from the view:- * type layer : w_t = exp(A_TP*z_prolif_t - A_TA*z_apopt_t + A_TD*z_diff_t- + A_TR*n_iv*log(p_t_last/p_t_first))+ * type layer : w_t = exp(A_TP*z_prolif_t - A_TA*z_apopt_t + A_TR*n_iv*logratio) * cell layer : w_i = exp(A_CP*z_prolif_i - A_CA*z_apopt_i + A_CM*z_met_i- + A_CD*z_diff_i)-Sampling: Efraimidis-Spirakis without replacement, deterministic under --seed.+ + A_EXT*z_ext_i)+ * A_EXT axis (only when an external input stage AND an official input stage+ exist, e.g. proxy2): gene-level delta = mean(external) - mean(official+ latest) restricted to covered genes, ribosomal/mito families masked,+ z-scored across genes, projected onto each base cell, type-mean removed,+ z-scored. Selects cells already leaning toward the external (later) state.++Sampling (K_STRAT>=2): per-type quota n_t apportioned by type weight-sum+(largest remainder, capped by type size), then within each type K equal-+frequency strata by z_met; stratum quotas apportioned by stratum weight-sum+(capped, overflow redistributed); within a stratum Efraimidis-Spirakis+weighted sampling without replacement. K_STRAT<=1 falls back to global E-S+(parent behaviour). Deterministic under --seed. """ from __future__ import annotations@@ -41,16 +49,13 @@ OXPHOS = [ "Atp5b", "Atp5f1b", "Atp5pb", "Sdha", "Sdhb", ] GLYC = ["Slc2a1", "Slc2a3", "Hk1", "Hk2", "Pfkp", "Pgk1", "Pgam1", "Eno1", "Ldha", "Pkma"]-# Textbook differentiation (lineage effector) vs progenitor/pluripotency markers.-# Source: general developmental biology (sarcomeric cardiac myosins/troponin,-# endothelial cadherin/PECAM, erythroid globins/heme synthesis, neuronal tubulin-# /DCX, hepatocyte albumin; pluripotency factors SOX2/POU5F1/NANOG, T/Brachyury).-DIFF = ["Tnnt2", "Myl7", "Myh6", "Pecam1", "Cdh5", "Tek", "Hbb-b1", "Hbb-bh1",- "Alas2", "Tubb3", "Dcx", "Alb"]-PROG = ["Sox2", "Pou5f1", "Nanog", "T"]+# Technical gene families masked from the cross-dataset delta axis (library-+# preparation / platform driven, general knowledge, not stage measurements).+MASK_PREFIX = ("mt-", "Rpl", "Rps") DEFAULTS = dict(A_TP=-0.55, A_TA=0.25, A_CP=0.0, A_CA=0.0, A_CM=0.7,- A_TD=0.0, A_CD=0.0, A_TR=0.0, MIN_TYPE_CELLS=5, POOL=0)+ A_EXT=0.2, K_STRAT=5, A_TR=0.0, MIN_TYPE_CELLS=5, POOL=0)+INT_KEYS = ("MIN_TYPE_CELLS", "POOL", "K_STRAT") def group_cols(genes, grp):@@ -87,6 +92,81 @@ def type_labels(adata): return tmp.obs["leiden_auto"].astype(str).to_numpy(), "leiden_auto" +def apportion(wsum, caps, n):+ """Largest-remainder apportionment of n across groups proportional to+ wsum, capped by caps, with overflow redistributed (water filling)."""+ alloc = np.zeros(len(wsum), dtype=np.int64)+ rem = int(n)+ for _ in range(len(wsum) + 5):+ if rem <= 0:+ break+ room = caps - alloc+ act = room > 0+ if not act.any():+ break+ tot = float(wsum[act].sum())+ target = np.zeros(len(wsum))+ if tot > 0:+ target[act] = rem * wsum[act] / tot+ else:+ target[act] = rem / float(act.sum())+ add = np.minimum(np.floor(target).astype(np.int64), room)+ if add.sum() == 0:+ cand = np.where(act)[0]+ cand = cand[np.argsort(-target[cand], kind="stable")][:rem]+ add = np.zeros(len(wsum), dtype=np.int64)+ add[cand] = 1+ add = np.minimum(add, room)+ alloc += add+ rem -= int(add.sum())+ return alloc+++def es_sample(rows, w, q, rng):+ """Efraimidis-Spirakis weighted sample without replacement."""+ if q <= 0 or len(rows) == 0:+ return np.empty(0, dtype=np.int64)+ if q >= len(rows):+ return rows+ u = rng.random(len(rows))+ keys = np.log(np.maximum(u, 1e-300)) / np.maximum(w[rows], 1e-12)+ return rows[np.argpartition(-keys, q - 1)[:q]]+++def stratified_sample(w, z_strat, inv, n_types, n_out, K, rng):+ total = len(w)+ if n_out >= total:+ return np.arange(total)+ counts = np.bincount(inv, minlength=n_types)+ s_type = np.bincount(inv, weights=w, minlength=n_types)+ n_t = apportion(s_type, counts, n_out)+ out = []+ for t in range(n_types):+ nt = int(n_t[t])+ if nt <= 0:+ continue+ rows = np.where(inv == t)[0]+ if nt >= len(rows) or K < 2 or len(rows) < 2 * K:+ out.append(es_sample(rows, w, nt, rng))+ continue+ order = np.argsort(z_strat[rows], kind="stable")+ srows = rows[order]+ base, extra = divmod(len(srows), K)+ pos = 0+ bounds = []+ for k in range(K):+ sz = base + (1 if k < extra else 0)+ bounds.append(srows[pos:pos + sz])+ pos += sz+ sizes = np.array([len(b) for b in bounds], dtype=np.int64)+ s_str = np.array([w[b].sum() for b in bounds])+ q = apportion(s_str, sizes, nt)+ for k in range(K):+ if q[k] > 0:+ out.append(es_sample(bounds[k], w, int(q[k]), rng))+ return np.sort(np.concatenate(out)) if out else np.empty(0, dtype=np.int64)++ def main(): ap = argparse.ArgumentParser() ap.add_argument("--data", required=True)@@ -94,15 +174,19 @@ def main(): ap.add_argument("--seed", type=int, default=0) for k, v in DEFAULTS.items(): ap.add_argument("--" + k.lower(), dest=k,- type=float if k not in ("MIN_TYPE_CELLS", "POOL") else int,+ type=float if k not in INT_KEYS else int, default=float(os.environ.get("VEC_" + k, v))) args = ap.parse_args()+ args.K_STRAT = int(args.K_STRAT)+ args.MIN_TYPE_CELLS = int(args.MIN_TYPE_CELLS)+ args.POOL = int(args.POOL) view = Path(args.data) manifest = view_io.load_manifest(view) genes = view_io.panel_genes(view, manifest) entries = view_io.inputs_by_time(manifest, include_external=False)+ has_official = bool(entries) if not entries: entries = view_io.inputs_by_time(manifest, include_external=True) @@ -113,8 +197,6 @@ def main(): cols_ap = group_cols(genes, APOPT) cols_ox = group_cols(genes, OXPHOS) cols_gl = group_cols(genes, GLYC)- cols_df = group_cols(genes, DIFF)- cols_pg = group_cols(genes, PROG) parts, stage_ids, per_stage = [], [], [] for si, e in enumerate(use_entries):@@ -125,13 +207,10 @@ def main(): prolif=group_score(a, cols_cy), apopt=group_score(a, cols_ap), met=group_score(a, cols_ox) - group_score(a, cols_gl),- diff=group_score(a, cols_df) - group_score(a, cols_pg), n=a.n_obs,- X=a.X,- obsm=a.obsm.get("spatial_3D"), ) # z-normalise cell scores within each stage (cancels technical offsets)- for k in ("prolif", "apopt", "met", "diff"):+ for k in ("prolif", "apopt", "met"): s[k] = zscore(s[k]) parts.append(a) stage_ids.append(np.full(a.n_obs, si))@@ -143,7 +222,6 @@ def main(): z_prolif_c = np.concatenate([s["prolif"] for s in per_stage]) z_apopt_c = np.concatenate([s["apopt"] for s in per_stage]) z_met_c = np.concatenate([s["met"] for s in per_stage])- z_diff_c = np.concatenate([s["diff"] for s in per_stage]) uniq, inv = np.unique(labels, return_inverse=True) counts = np.bincount(inv, minlength=len(uniq))@@ -153,7 +231,29 @@ def main(): z_prolif_t = zscore(tmean(z_prolif_c)) z_apopt_t = zscore(tmean(z_apopt_c))- z_diff_t = zscore(tmean(z_diff_c)) if args.A_TD or args.A_CD else np.zeros(len(uniq))++ # external maturity axis (proxy2-like views only)+ z_ext_c = np.zeros(adata.n_obs)+ if args.A_EXT and has_official:+ ext_entries = [e for e in manifest["inputs"] if e.get("source") == "external"]+ if ext_entries:+ ext = max(ext_entries, key=lambda e: float(e["time"]))+ ea = view_io.read_stage(view, ext, genes, missing="fill")+ mask = view_io.covered_mask(view, ext, genes)+ keep = mask.copy()+ for i, g in enumerate(genes):+ if g.startswith(MASK_PREFIX):+ keep[i] = False+ sel = np.where(keep)[0]+ if len(sel) > 100:+ off_mean = np.asarray(adata.X[:, sel].mean(axis=0), dtype=np.float64).ravel()+ ext_mean = np.asarray(ea.X[:, sel].mean(axis=0), dtype=np.float64).ravel()+ delta = ext_mean - off_mean+ delta = zscore(delta)+ Xc = adata.X.tocsr()+ proj = np.asarray(Xc[:, sel] @ delta, dtype=np.float64).ravel()+ proj = proj - tmean(proj)[inv] # remove type-level mean+ z_ext_c = zscore(proj) # trajectory axis: log-linear type-proportion extrapolation over stages traj_t = np.zeros(len(uniq))@@ -182,22 +282,24 @@ def main(): traj_t = np.clip(n_iv * logratio, -3.0, 3.0) traj_t[p_last <= eps] = 0.0 - w_type = np.exp(args.A_TP * z_prolif_t - args.A_TA * z_apopt_t- + args.A_TD * z_diff_t + args.A_TR * traj_t)+ w_type = np.exp(args.A_TP * z_prolif_t - args.A_TA * z_apopt_t + args.A_TR * traj_t) w_type[counts < args.MIN_TYPE_CELLS] = 1.0 w = w_type[inv] * np.exp(args.A_CP * z_prolif_c - args.A_CA * z_apopt_c- + args.A_CM * z_met_c + args.A_CD * z_diff_c)+ + args.A_CM * z_met_c + args.A_EXT * z_ext_c) w = np.clip(w, 1e-6, 1e6) n_base = per_stage[-1]["n"] n_out = view_io.target_n_cells(manifest, n_base if multi else adata.n_obs) rng = np.random.default_rng(args.seed)- u = rng.random(adata.n_obs)- keys = np.log(np.maximum(u, 1e-300)) / w- if n_out >= adata.n_obs:- idx = np.arange(adata.n_obs)+ if args.K_STRAT >= 2:+ idx = stratified_sample(w, z_met_c, inv, len(uniq), n_out, args.K_STRAT, rng) else:- idx = np.sort(np.argpartition(-keys, n_out - 1)[:n_out])+ u = rng.random(adata.n_obs)+ keys = np.log(np.maximum(u, 1e-300)) / w+ if n_out >= adata.n_obs:+ idx = np.arange(adata.n_obs)+ else:+ idx = np.sort(np.argpartition(-keys, n_out - 1)[:n_out]) X = adata.X[idx] coords = None
调研来源?调研员查到并用到的知识条目和文献检索结果(只列标题和编号)。
用到的知识库条目
| 编号 | 标题 | 出处 |
|---|---|---|
| k031 | Offline OT toolkit in the sandbox: moscot TemporalProblem, wot OTModel, POT, geomloss | 10.1038/s41586-024-08453-2 (moscot); 10.1016/j.cell.2019.01.006 (Waddington-OT) |
| k041 | Within-stage pseudotime and graph toolkit offline: scanpy DPT/PAGA/Leiden, Palantir, CellRank 2 | 10.1186/s13059-019-1663-x (PAGA); 10.1038/s41587-019-0068-4 (Palantir); 10.1038/s41592-024-02303-9 (CellRank 2) |
| k038 | RNA velocity family (scVelo, dynamo, CellRank velocity kernel): not applicable to T1 files; substitutes | 10.1038/s41587-020-0591-3 (scVelo); 10.1016/j.cell.2021.12.045 (dynamo); 10.1038/s41592-024-02303-9 (CellRank 2) |
分析结果?分析员写的 ANALYSIS.json:改了什么、各组分数怎么变、假设是否成立、经验和下一步建议。
| 改了什么 | 在父节点11双层权重重抽样上重新实现节点15的A_EXT=0.2外部成熟度轴(跨数据集基因级delta投影,仅proxy2类视图激活,covered掩码+屏蔽mt-/Rpl*/Rps*+去型内均值),并新增型内代谢分层配额抽样K_STRAT=5(型配额按权重和最大余数法,型内按z_met分5等频层,层内E-S无放回);同时删除了父节点的DIFF/PROG分化轴代码。X3路径恒等输出不变。 |
|---|---|
| 各组分数的变化 | X3:不变:50.00,恒等输出与父一致 board:55.59 vs 55.13,+0.46,在T1噪声(约2分)内 cell_state:变好(相对最强信号):57.56 vs 55.86,+1.70,接近噪声量级但方向与Engineer本地mmd_u一致变小的说法吻合 covariation:噪声内偏负(PLAN预期提升的组,未实现):54.07 vs 54.37,-0.31 de_recovery:噪声内(PLAN预期提升的组,未实现):52.97 vs 53.16,-0.19 direction:噪声内:57.09 vs 56.85,+0.24 proxy:噪声内:57.79 vs 57.70,+0.09 proxy2:变好(弱):58.99 vs 57.70,+1.29,与A_EXT继承自节点15的已知效应一致 |
| 假设是否成立 | 否 |
| 经验 |
|
| 下一步建议 |
|
对话摘要?每个角色和大模型对话的统计:轮数、工具调用、用时、token 数和最后的回答摘录;原始记录只给路径。
只给统计和最后回答的摘录;完整对话请到原始记录位置里列出的文件看。
分析员
| 角色?调研员写计划、工程师改代码、分析员解读分数、审查员检查作弊。 | 分析员 alibaba-token-plan-cn/qwen3.8-max |
|---|---|
| 调用次数 | 1 次 |
| 轮数?大模型一共回复了几轮(每轮可以调用多个工具)。 | 3 |
| 工具调用?大模型调用读文件、执行命令等工具的次数,按工具名统计。 | 共 3 次:bash 1、read 1、write 1 |
| 用时 | 不到 1 分 |
| token 数?输入 / 输出(含思考)的 token 数,来自接口返回的用量。 | 输入 13,576 · 输出 1,238 · 思考 745 |
| 任务(第一行) | 分析节点 n23 的打分结果,写 ANALYSIS.json |
| 最后的回答(摘录) | ANALYSIS.json written |
| 原始记录位置?完整对话记录在 Spark 上的文件路径;看板不复制原始内容。 | /home/spark-longxinyang/vec/runs/formal/20261002-034201-search-t1-abc-r1-A-era/nodes/23/analyst.jsonl 11 KB /home/spark-longxinyang/vec/runs/formal/20261002-034201-search-t1-abc-r1-A-era/nodes/23/analyst.stderr |
工程师
| 角色 | 工程师 alibaba-token-plan-cn/qwen3.8-max |
|---|---|
| 调用次数 | 1 次 |
| 轮数 | 22 |
| 工具调用 | 共 30 次:bash 25、read 2、write 2、edit 1 |
| 用时 | 10 分 |
| token 数 | 输入 52,131 · 输出 10,129 · 思考 11,319 |
| 任务(第一行) | 按计划修改程序:型内代谢分层E-S抽样保协方差 + 继承A_EXT外部成熟度轴 |
| 最后的回答(摘录) | Done. Final verification of the default-config outputs was already completed (all three views ran with defaults → `vec-check` ok; X3 = identity). **Summary** - **做了什么**:在父节点 11 双层权重重抽样上,重新实现了节点 15 的外部成熟度轴 A_EXT(跨数据集基因级 delta、covered 掩码、屏蔽 mt-/核糖体家族、型内去均值,仅 proxy2 类视图激活),并新增 PLAN 的型内代谢分层配额抽样(K=5,最大余数配额 + 层内 E-S)。 - **查分**(8 次,A 半本地口径):提交配置 proxy 58.04(seed1 58.20)、proxy2 59.17(seed1 58.47)、X3 恒等 50.00;预期节点分 ≈ 55.7–56.0,优于父 55.13 与当前最佳节点 15(55.82 的 B 半构成中 proxy2 相同、proxy 略高)。A_EXT=0.2 复扫确认为峰(0.1/0.3/0.4/0.7 均更低)。PLAN 的分层假设部分证否:covariation 未提升(反而 −0.4~−1.2),但 cell_state 一致提升(mmd_u 变小),净分两视图各 +0.1/+0.0,噪声内方向为正,保留;K=10 更差。 - **下一步最值得试**:① A_EXT 的 delta 做心脏型匹配或按 |delta_z| 取稳健基因子集;② 解耦 de_recovery 与 direction——用更强投影(0.4)排序但分层配额保分布;③ proxy 单阶段侧引入 prior/ 通路资源定义更细的成熟度轴。 |
| 原始记录位置 | /home/spark-longxinyang/vec/runs/formal/20261002-034201-search-t1-abc-r1-A-era/nodes/23/engineer.jsonl 114 KB /home/spark-longxinyang/vec/runs/formal/20261002-034201-search-t1-abc-r1-A-era/nodes/23/engineer.stderr |
调研员
| 角色 | 调研员 alibaba-token-plan-cn/qwen3.8-max |
|---|---|
| 调用次数 | 1 次 |
| 轮数 | 1 |
| 工具调用 | 共 0 次:— |
| 用时 | 3 分 |
| token 数 | 输入 16,822 · 输出 749 · 思考 8,060 |
| 任务(第一行) | 为节点 n23(改进,父节点 n11)写改进计划 PLAN.json |
| 最后的回答(摘录) | ```json
{
"name": "型内代谢分层E-S抽样保协方差 + 继承A_EXT外部成熟度轴",
"motivation": "父节点11最弱组为de_recovery(53.16)、次弱covariation(54.37)。当前E-S抽样对高权重细胞过度集中,压缩型内表达多样性,损害基因共现结构。节点10曾在全局logw上做K=3分层(54.69,噪声内),但未在型内分层、且基底不同(节点8无类型层)。节点15的A_EXT在proxy2上给出+1.20一致弱正信号(3 seed全正),应继承。本方案用型内分层保协方差机制针对covariation,同时保留型内全代谢梯度分布以维持稀有DE基因表达细胞的代表性(针对de_recovery)。",
"approach": "基于节点15代码(含A_EXT=0.2、双权重、E-S抽样)做以下改动:\n1. 型内分层抽样:对每个细胞型,按z_met分K=5等频stratum;每stratum配额 = round(n_out_t × stratum权重和 / 型总权重和),用最大余数法凑整;stratum内部仍用E-S按原始权重无放回抽样。若某stratum细胞数<配额,全取并从相邻stratum补。\n2. A_EXT轴保持节点15逻辑不变(仅proxy2/≥2输入时激活,covered掩码、去型内均值、屏蔽mt-/Rpl*/Rps*)。\n3. 单输入退路(proxy/X3/final单阶段):A_EXT不激活,分层抽样正常执行;X3上n_out==池大小时退化为恒等(与父一致)。\n4. 查分策略(≤8次):先proxy seed0确认分层不伤分(预期≈57.7±1);再proxy2 seed0看A_EXT+分层联合效果;若proxy掉>2分则回退分层改纯E-S(=节点15);若proxy2≥59则再跑1个seed确认。\n5. 关键参数初值:K=5(不扫)、A_EXT=0.2(不扫)、类型层/细胞层系数与父一致(A_TP=-0.55,A_TA=0.25,A_CM=0.7)。",
"expected_groups": ["covariation", "de_recovery"],
"risks": "1. 型内分层可能削弱代谢选择强度(高z_met stratum配额被稀释),导致direction/cell_state掉1-2分——Engineer应在第一次proxy查分时观察direction组是否<55,若是则立即回退。2. 小细胞型(<10细胞)分层后stratum只有1-2个细胞,配额分配退化为全取——代码中需对n_cells_type<K的情况直接全取不分层。3. A_EXT+分层联合效果可能不叠加(A_EXT改变型内排序后分层边界变化)——若proxy2<58.5(低于节点15的58.90)则关闭分层只保留A_EXT。4. 预期增益在1-2分量级,接近噪声;需≥2次同配置查分确认方向一致。"
}
``` |
| 原始记录位置 | /home/spark-longxinyang/vec/runs/formal/20261002-034201-search-t1-abc-r1-A-era/nodes/23/researcher.jsonl 3 KB /home/spark-longxinyang/vec/runs/formal/20261002-034201-search-t1-abc-r1-A-era/nodes/23/researcher.stderr |
审查员
| 角色 | 审查员 alibaba-token-plan-cn/qwen3.8-max |
|---|---|
| 调用次数 | 1 次 |
| 轮数 | 6 |
| 工具调用 | 共 10 次:read 7、bash 2、write 1 |
| 用时 | 不到 1 分 |
| token 数 | 输入 20,279 · 输出 1,340 · 思考 944 |
| 任务(第一行) | 审查节点 n23 的程序是否越界读取、写死目标、钻评分器漏洞 |
| 最后的回答(摘录) | REVIEW.json written |
| 原始记录位置 | /home/spark-longxinyang/vec/runs/formal/20261002-034201-search-t1-abc-r1-A-era/nodes/23/reviewer.jsonl 92 KB /home/spark-longxinyang/vec/runs/formal/20261002-034201-search-t1-abc-r1-A-era/nodes/23/reviewer.stderr |