总览 · ← 返回运行 20261003-105537-search-t2-heart-extrap-g24-D
节点 n3
T2HX-01 位移层:外推时优先用视图内"晚于末输入、不晚于目标"的外部样本按伪批量相关匹配细胞型做阻尼位移(保坐标);两输入速度回退在代理上验证有害、默认关;无可用方向时逐位等于 copy_last。
| 运行?一次完整的自动搜索或 Agent 会话,有自己的锁定配置和证据包。 | 20261003-105537-search-t2-heart-extrap-g24-D |
|---|---|
| 父节点 | n1 |
| 子节点 | n7、n9、n12 |
| 操作?种子:人写的起点;改进:在父节点上改;草稿:从头写;修复:修父节点的报错。 | 改进 |
| 状态 | 已打分 |
| 分数 | 搜索目标分 50.00(+0.0) · proxy_noscale 50.00(+0.0) · 3 次复测均分 50.00 |
| 审查 | 通过 1 越界读取:未发现问题。全部 I/O 都拼在 --data 视图根下:run.py:59 读 prior/go/gene_sets_bp.gmt(view_manifest.json prior 清单内的 id 'go'),run.py:99 只读 manifest['external'] 给出的 entry['path'](qiu2024_heart_early_v1/E8.75.h5ad);无绝对路径、'..'、/mnt、/home、data/raw、downloads、src/common/evaluation 的读取,全文无 requests/urllib/socket/subpr… |
| 用时?从运行开始到结束(或到现在)的挂钟时间。 | 18 分 |
| 程序版本 | a0271985a8e37de4a6303042b6ee8b12c2c65146 (programs.git) |
方法说明?节点程序自带的 METHOD.md:这个程序做了什么、为什么。
来自 programs.git a0271985a8:solution/METHOD.md
T2HX-01 位移层:外推时优先用视图内"晚于末输入、不晚于目标"的外部样本按伪批量相关匹配细胞型做阻尼位移(保坐标);两输入速度回退在代理上验证有害、默认关;无可用方向时逐位等于 copy_last。
方法
在父节点(copy_last)之上加一个位移层,管线(全部只读 manifest 的相对时间与区间字段,无绝对阶段/尺寸常数,伪装视图安全):
- 细胞选择与坐标和父节点完全相同:anchor=最后观测阶段,n≤max_cells 整份输出,超过则按型分层抽样;坐标一律不动(保 neighborhood_mmd 与结构门)。
- 位移方向按优先级:
- (a) 外部前向靶:
manifest.external中存在区间 (e_lo, e_hi) 满足 e_lo > 末输入时间且 e_hi ≤ 目标时间的样本时,加载并对齐到面板(<50 共有基因则放弃;X 若像原始计数则重算 log1p(CP10k));anchor 各细胞型与外部型在共有基因伪批量上算 Pearson r,r≥0.5 才配对;每细胞 shift = α·[β·型级差 + (1−β)·(匹配型内最近邻外部细胞 − 本细胞)],α=0.5、β=1(默认)。 - (b) 两输入速度回退:型级伪批量差 × α_vel × dt_ratio。默认 α_vel=0(关),理由见下。
- (c) 都没有 → 输出逐位等于 copy_last。
- (a) 外部前向靶:
- shift 逐基因截断在 ±2·std(基因 in anchor),X+shift 后截 0。异常时 (a) 路径 try/except 回退,绝不崩。
机制对照与验证(proxy_noscale,5 次查分)
- α=0 对照(mechanism_off_control):默认配置在代理上的输出与父节点逐位相同(X、坐标 array_equal 验证),vec-score 实测 50.00,四组全 50。✓
- 速度回退 (b) 的方向质量(这是代理上唯一可测的方向):
- 型级伪批量速度 α_eff=0.45/0.9/1.5:49.0 / 48.7 / 48.3。de_score 原始值 −0.056(低于 chance),de_direction ≈ −0.003~−0.007:E8.25→E8.75 的型级速度与真值 E8.75→E9.5 变化不相关甚至反相关,且 DE 两项对 α 近似不变(秩/符号指标),所以任何 α 都拿不到 DE 收益,只赔 variogram(skill 0.36–0.44)。与方法卡"α 网格单调低于地板"一致。
- 去掉增殖模块(GO BP 名字含 cell cycle/mitotic/DNA replication 等的 44 个面板基因置零,通用基因功能注释,来自视图 prior/go)α_eff=0.45:49.05。de_direction 转微正(+0.015,skill 0.504)但 de_score 更差(−0.139),variogram 仍赔 0.8 分。
- 结论:代理上速度外推方向无信号,(b) 默认关(α_vel=0);代理行为 = copy_last = 50.00。
- 外部路径 (a) 冒烟测试(把末输入时间假装提前以触发):加载 qiu E8.75、27883 基因对齐、33 个 anchor 型中 1 个(心脏谱系)r≥0.5 配对成功、shift 逐型非零——机械上可运行;代理视图内没有真正"晚于末输入"的外部样本,故该路径的科学效果未能在本地验证(这正是方法卡指出的外推盲区:本地尺子无法检验方向,且外推榜本地分历史上高估官网分)。
- vec-check 对本 board 返回 "not allowed for this client"(客户端限制,非格式问题);vec-score 正常接收并打分同一文件,格式合规。
知识来源
- GO BP 注释(视图 prior/go/gene_sets_bp.gmt):增殖模块(细胞周期/有丝分裂/DNA 复制)是瞬态程序,其早期轨迹不可靠外推——通用基因功能知识,非任何保留阶段测量。
- 细胞型配对用表达相关而非标签名(外部数据标签词汇可能不同)——PLAN T2HX-01 规定。
已知弱点 / 未验证
- (a) 路径在真实 final 视图(可能挂 MOSTA E9.5 等前向外部样本)上的效果无法在本地检验;若方向错会低于地板。终选护栏(proxy_noscale 种子均值需超 copy_last 1 分)在本节点上不会通过,正式提交会回落到基线预测。
- 未做:STRING/通路平滑速度、t 统计加权、逐细胞 OT 位移(方法卡已证 OT 伤邻域)。
调研员的计划
| 名称 | 表达匹配型伪批量位移外推(保坐标,T2HX-01) |
|---|---|
| 动机 | 父节点 1(copy_last)50.00,全部八项 skill=0.5 即地板,其中 de_score/de_direction 原始值为 0(被无变化保护击中:dp≡0,两项合计 12.5/25 分处于地板且毫无信息);兄弟节点 2 的朴素 damped_shift 49.51 反而低于地板,说明无方向的位移会伤 mmd_u(48.41)而不产生 DE 收益。外推榜的 dt = pb(E9.5)−pb(E8.5) 非零,唯一能拉开表达变化组的是让 dp 与真实变化同向同序。方向库 T2HX-01 正是为此:按表达匹配而非标签名做型间伪批量位移,并加收缩保住型内方差。坐标不动可保住 local_spatial(方法卡已证 OT 插值坐标会把邻域组砸到 23–41,而本榜邻域+结构门最多影响 50 分)。 |
| 做法 | 在父节点 run.py 上加位移层,管线:1) 读 anchor 阶段(外推榜=最后观测阶段)。2) 目标位移来源按优先级回退:(a) external/ 里选一个阶段不超过靶时间、且区间完全落在心脏保留窗 (8.25,8.75)、(9.5,13.5] 之外的外部样本(如 E9.5 心脏),用其作为靶;(b) 若视图给两个输入阶段(final 情形),用两阶段按型伪批量差/时间间隔作为速度外推;(c) 都没有则原样输出=copy_last(proxy 单阶段时的退路,输出逐位等于父节点)。程序只读 manifest 的相对时间与区间字段,不写任何绝对阶段常数,伪装视图安全。3) 细胞配对按表达而非标签名:输入型与外部型用共有面板基因(要求≥50 个共有基因)上的伪批量 Pearson 相关匹配,阈值 r≥0.5,匹配失败即回退 (c)。4) 每个输入细胞 i:shift_i = α·[(1−β)·(x_ext_matched(i) − pb_t(i)) + β·(pb_ext_T(i) − pb_t(i))];X_i ← X_i + shift_i,负值截 0,|shift| 按基因上限取该基因输入标准差的 2 倍(防极端值打爆 mmd_u/variogram)。坐标一律不动——这是保邻域、保 d2_shape/occupancy_dice 的关键。5) 参数初值 α=0.7、β=0.5;网格 α∈{0.3,0.5,0.7,1.0}×β∈{0.3,0.5,0.7}。6) 流程:先跑 α=0 对照复现父节点 50.00;检查 manifest 确认外部样本存在、面板重叠与区间合规;先在 30% 分层子样本上粗筛网格,再用全量 vec-score 复核,预算≤20 次查分;选定参数后用 seed 1 复跑确认 >1 分优势(T2 噪声约 1 分,终选护栏要求种子均值超基线 1 分)。 |
| 风险 | 1) 视图内可能没有可用外部样本,或外部面板/细胞类型与输入重叠太少 → 机制静默退化回 copy_last;Engineer 第一步就查 manifest 并打印匹配报告,尽早发现。2) 表达匹配把型配错 → 位移反向,DE 掉到 chance 附近;看 de_direction 是否低于 6.25 地板分即可发现。3) 过冲伤 mmd_u/neighborhood_mmd(重蹈节点 2 覆辙);每次查分都读 score_parts,邻域得分 <12.4/25 或 mmd_u 变差就降 α、增 β、收紧位移上限。4) 在 A 半过拟合参数;要求相邻网格点分数平滑、且 seed 1 复跑仍 >1 分。5) 本地小幅领先未必兑现,故只把目标定在 ≥52 而非贪大。 |
代码改动?这个节点的程序和父节点程序的逐行差别:绿色是新增,红色是删除。
对比:父节点版本 6b3812a495。改动的文件:solution/METHOD.md +32 −0、solution/run.py +228 −8
diff --git a/solution/METHOD.md b/solution/METHOD.mdnew file mode 100644index 0000000..6640572--- /dev/null+++ b/solution/METHOD.md@@ -0,0 +1,32 @@+T2HX-01 位移层:外推时优先用视图内"晚于末输入、不晚于目标"的外部样本按伪批量相关匹配细胞型做阻尼位移(保坐标);两输入速度回退在代理上验证有害、默认关;无可用方向时逐位等于 copy_last。++## 方法++在父节点(copy_last)之上加一个位移层,管线(全部只读 manifest 的相对时间与区间字段,无绝对阶段/尺寸常数,伪装视图安全):++1. 细胞选择与坐标和父节点完全相同:anchor=最后观测阶段,n≤max_cells 整份输出,超过则按型分层抽样;坐标一律不动(保 neighborhood_mmd 与结构门)。+2. 位移方向按优先级:+ - (a) **外部前向靶**:`manifest.external` 中存在区间 (e_lo, e_hi) 满足 e_lo > 末输入时间且 e_hi ≤ 目标时间的样本时,加载并对齐到面板(<50 共有基因则放弃;X 若像原始计数则重算 log1p(CP10k));anchor 各细胞型与外部型在共有基因伪批量上算 Pearson r,r≥0.5 才配对;每细胞 shift = α·[β·型级差 + (1−β)·(匹配型内最近邻外部细胞 − 本细胞)],α=0.5、β=1(默认)。+ - (b) 两输入速度回退:型级伪批量差 × α_vel × dt_ratio。**默认 α_vel=0(关)**,理由见下。+ - (c) 都没有 → 输出逐位等于 copy_last。+3. shift 逐基因截断在 ±2·std(基因 in anchor),X+shift 后截 0。异常时 (a) 路径 try/except 回退,绝不崩。++## 机制对照与验证(proxy_noscale,5 次查分)++- **α=0 对照(mechanism_off_control)**:默认配置在代理上的输出与父节点逐位相同(X、坐标 array_equal 验证),vec-score 实测 **50.00**,四组全 50。✓+- **速度回退 (b) 的方向质量**(这是代理上唯一可测的方向):+ - 型级伪批量速度 α_eff=0.45/0.9/1.5:**49.0 / 48.7 / 48.3**。de_score 原始值 −0.056(低于 chance),de_direction ≈ −0.003~−0.007:E8.25→E8.75 的型级速度与真值 E8.75→E9.5 变化**不相关甚至反相关**,且 DE 两项对 α 近似不变(秩/符号指标),所以任何 α 都拿不到 DE 收益,只赔 variogram(skill 0.36–0.44)。与方法卡"α 网格单调低于地板"一致。+ - 去掉增殖模块(GO BP 名字含 cell cycle/mitotic/DNA replication 等的 44 个面板基因置零,通用基因功能注释,来自视图 prior/go)α_eff=0.45:**49.05**。de_direction 转微正(+0.015,skill 0.504)但 de_score 更差(−0.139),variogram 仍赔 0.8 分。+- 结论:代理上速度外推方向无信号,(b) 默认关(α_vel=0);代理行为 = copy_last = 50.00。+- **外部路径 (a) 冒烟测试**(把末输入时间假装提前以触发):加载 qiu E8.75、27883 基因对齐、33 个 anchor 型中 1 个(心脏谱系)r≥0.5 配对成功、shift 逐型非零——机械上可运行;代理视图内没有真正"晚于末输入"的外部样本,故该路径的科学效果**未能在本地验证**(这正是方法卡指出的外推盲区:本地尺子无法检验方向,且外推榜本地分历史上高估官网分)。+- vec-check 对本 board 返回 "not allowed for this client"(客户端限制,非格式问题);vec-score 正常接收并打分同一文件,格式合规。++## 知识来源++- GO BP 注释(视图 prior/go/gene_sets_bp.gmt):增殖模块(细胞周期/有丝分裂/DNA 复制)是瞬态程序,其早期轨迹不可靠外推——通用基因功能知识,非任何保留阶段测量。+- 细胞型配对用表达相关而非标签名(外部数据标签词汇可能不同)——PLAN T2HX-01 规定。++## 已知弱点 / 未验证++- (a) 路径在真实 final 视图(可能挂 MOSTA E9.5 等前向外部样本)上的效果无法在本地检验;若方向错会低于地板。终选护栏(proxy_noscale 种子均值需超 copy_last 1 分)在本节点上不会通过,正式提交会回落到基线预测。+- 未做:STRING/通路平滑速度、t 统计加权、逐细胞 OT 位移(方法卡已证 OT 伤邻域)。diff --git a/solution/run.py b/solution/run.pyindex 0595dc9..196e6b2 100644--- a/solution/run.py+++ b/solution/run.py@@ -1,20 +1,181 @@ #!/usr/bin/env python3-"""copy_last (T2): the latest input at or before the target, with its own coordinates.+"""T2 extrapolation: expression-matched pseudobulk displacement on the anchor stage. -Interpolation boards take the lower bracket stage, extrapolation boards the-last input; this is the floor's reference stage on the proxy. Cells are drawn-stratified by cell type only when the stage exceeds the board's max_cells.-Expression and coordinates are unchanged.+Mechanism (family T2HX-01): shift each anchor-stage cell's expression toward a+forward target while keeping coordinates untouched (preserves local spatial+pairing). Target priority, computed only from view data and relative times:++ (a) an external sample whose whole stage interval lies strictly after the+ last input and at/before the target: per-cell type of the anchor is+ matched to external types by pseudobulk Pearson correlation on shared+ panel genes (r >= 0.5); shift blends the matched type-level difference+ (weight beta) with a nearest-neighbour cell-level difference (1 - beta).+ (b) else with >= 2 inputs: per-type pseudobulk velocity between the last two+ inputs, extrapolated over (target - last) time; type-level shift.+ (c) else: copy_last exactly (alpha also forces this when set to 0).++Shifts are per-gene capped at cap * std(gene in anchor), values clipped at 0.+No absolute stage names, times or sizes are hardcoded; only relative time+differences from the manifest are used, so the program is view-independent. """ from __future__ import annotations import argparse+import os+import sys import numpy as np from src.task2_spatial.sample import take-from src.task2_spatial.view_io import anchor_entry, load_manifest, panel_genes, read_stage, write_t2+from src.task2_spatial.view_io import (+ anchor_entry,+ extrap_step,+ load_manifest,+ panel_genes,+ read_stage,+ target_time,+ write_t2,+)++ALPHA = float(os.environ.get("VEC_ALPHA", "0.5")) # external-forward path+ALPHA_VEL = float(os.environ.get("VEC_ALPHA_VEL", "0.0")) # two-input velocity fallback (proxy-validated: harmful, kept off)+BETA = float(os.environ.get("VEC_BETA", "1.0"))+CAP = float(os.environ.get("VEC_CAP", "2.0"))+TIME_SCALE = bool(int(os.environ.get("VEC_TS", "1")))+CC_ZERO = bool(int(os.environ.get("VEC_CC", "0")))+MATCH_R = 0.5+MIN_SHARED = 50++_CC_KEYWORDS = ("cell cycle", "mitotic", "meiotic", "dna replication", "chromosome segregation", "cytokinesis")+++def _cell_cycle_genes(view: str) -> set[str]:+ """Genes in GO BP terms whose name indicates proliferation programs (generic+ gene-function annotation from the view's prior/; transient modules whose+ early trajectory is not trusted for forward extrapolation)."""+ out: set[str] = set()+ try:+ path = os.path.join(view, "prior", "go", "gene_sets_bp.gmt")+ with open(path) as fh:+ for line in fh:+ parts = line.rstrip("\n").split("\t")+ if len(parts) < 3:+ continue+ name = parts[1].lower()+ if any(k in name for k in _CC_KEYWORDS):+ out.update(parts[2:])+ except OSError:+ pass+ return out+++def _pb(X: np.ndarray, labels: np.ndarray) -> tuple[list[str], np.ndarray]:+ types = sorted(set(labels.tolist()))+ out = np.zeros((len(types), X.shape[1]), dtype=np.float64)+ for k, t in enumerate(types):+ m = labels == t+ if m.any():+ out[k] = X[m].mean(axis=0)+ return types, out+++def _external_forward_entry(manifest: dict, last_time: float, tt: float) -> dict | None:+ for e in manifest.get("external") or []:+ try:+ lo = float(e.get("e_lo", -np.inf))+ hi = float(e.get("e_hi", lo))+ except (TypeError, ValueError):+ continue+ if lo > last_time + 1e-6 and hi <= tt + 1e-6:+ return e+ return None+++def _load_external(view: str, entry: dict, genes: list[str]):+ import anndata as ad+ from scipy import sparse++ ad_obj = ad.read_h5ad(os.path.join(view, entry["path"]))+ ext_genes = [str(g) for g in ad_obj.var_names]+ pos = {g: i for i, g in enumerate(ext_genes)}+ shared = [g for g in genes if g in pos]+ if len(shared) < MIN_SHARED:+ return None, None+ cols = np.array([pos[g] for g in shared])+ X = ad_obj.X+ X = X.toarray() if sparse.issparse(X) else np.asarray(X)+ X = np.nan_to_num(np.asarray(X, dtype=np.float64))+ if "log1p" not in ad_obj.uns and X.max() > 30.0: # looks like raw counts+ tot = X.sum(axis=1, keepdims=True)+ tot[tot <= 0] = 1.0+ X = np.log1p(X / tot * 10000.0)+ X = X[:, cols]+ labels = (+ np.asarray(ad_obj.obs["celltype"]).astype(str)+ if "celltype" in ad_obj.obs+ else np.array(["ext"] * X.shape[0])+ )+ return shared, (X, labels)+++def _direction_external(view, manifest, genes, X_a, lab_a, pb_a, last_time, tt):+ entry = _external_forward_entry(manifest, last_time, tt)+ if entry is None:+ return None+ try:+ shared, loaded = _load_external(view, entry, genes)+ if loaded is None:+ return None+ X_e, lab_e = loaded+ gidx = np.array([genes.index(g) for g in shared])+ types_e, pb_e = _pb(X_e, lab_e)+ # match anchor types to external types by pseudobulk Pearson r on shared genes+ A = pb_a[:, gidx]+ B = pb_e+ A = A - A.mean(axis=1, keepdims=True)+ B = B - B.mean(axis=1, keepdims=True)+ na = np.linalg.norm(A, axis=1, keepdims=True)+ nb = np.linalg.norm(B, axis=1, keepdims=True)+ na[na == 0] = 1.0+ nb[nb == 0] = 1.0+ C = (A / na) @ (B / nb).T+ best = C.argmax(axis=1)+ ok = C[np.arange(len(best)), best] >= MATCH_R+ print(f"[diag] external target {entry.get('id')}: matched {ok.sum()}/{len(ok)} anchor types", file=sys.stderr)+ if not ok.any():+ return None+ # type-level difference on full panel (external genes only)+ diff_t = np.zeros_like(pb_a)+ for k in range(len(ok)):+ if ok[k]:+ diff_t[k, gidx] = pb_e[best[k]] - pb_a[k, gidx]+ # cell-level: nearest external neighbour within matched type+ from sklearn.neighbors import NearestNeighbors++ shift = np.zeros_like(X_a)+ d_sub = X_a[:, gidx]+ types_a = sorted(set(lab_a.tolist()))+ for k in range(len(ok)):+ if not ok[k]:+ continue+ m = lab_a == types_a[k]+ if not m.any():+ continue+ tgt_m = lab_e == types_e[best[k]]+ if not tgt_m.any():+ continue+ nn = NearestNeighbors(n_neighbors=1).fit(X_e[tgt_m][:, : len(shared)])+ _, ind = nn.kneighbors(d_sub[m])+ cell_diff = np.zeros((m.sum(), X_a.shape[1]))+ cell_diff[:, gidx] = X_e[tgt_m][ind[:, 0]] - d_sub[m]+ type_diff = np.zeros((m.sum(), X_a.shape[1]))+ type_diff[:, gidx] = diff_t[k, gidx]+ shift[m] = BETA * type_diff + (1.0 - BETA) * cell_diff+ return shift+ except Exception as exc: # never crash on the optional external path+ print(f"[diag] external path failed: {exc}", file=sys.stderr)+ return None def main() -> None:@@ -26,14 +187,73 @@ def main() -> None: manifest = load_manifest(args.data) genes = panel_genes(args.data, manifest)+ prev, last, dt_ratio = extrap_step(manifest)+ tt = target_time(manifest) stage = read_stage(args.data, anchor_entry(manifest), genes) n = int(np.clip(stage.n, manifest["min_cells"], manifest["max_cells"])) rng = np.random.default_rng(args.seed) if n <= stage.n: rows = np.sort(take(stage.labels, n, rng))- else: # fewer cells than min_cells: resample with replacement+ else: rows = np.sort(rng.choice(stage.n, size=n, replace=True))- write_t2(args.out, stage.X[rows].toarray(), stage.coords[rows], genes, seed=args.seed)++ X = stage.X[rows].toarray().astype(np.float32)+ coords = stage.coords[rows]++ if ALPHA > 0.0 or ALPHA_VEL > 0.0:+ lab = stage.labels[rows]+ types, pb_a = _pb(X.astype(np.float64), lab)+ shift = None+ src = "none"+ if ALPHA > 0.0:+ shift = _direction_external(+ args.data, manifest, genes, X.astype(np.float64), lab, pb_a, float(last["time"]), tt+ )+ if shift is not None:+ shift *= ALPHA+ src = "external"+ if shift is None and prev is not None and ALPHA_VEL > 0.0:+ src = "velocity"+ pstage = read_stage(args.data, prev, genes)+ Xp = pstage.X.toarray().astype(np.float64)+ _, pb_p = _pb(Xp, pstage.labels)+ tmap_p = {t: i for i, t in enumerate(_pb(Xp, pstage.labels)[0])}+ glob = pb_a.mean(axis=0) - Xp.mean(axis=0)+ v = np.tile(glob, (len(types), 1))+ for k, t in enumerate(types):+ if t in tmap_p:+ v[k] = pb_a[k] - pb_p[tmap_p[t]]+ scale = ALPHA_VEL * (dt_ratio if (TIME_SCALE and dt_ratio) else 1.0)+ per_type = {t: scale * v[k] for k, t in enumerate(types)}+ shift = np.zeros_like(X, dtype=np.float64)+ for t in types:+ m = lab == t+ if m.any():+ shift[m] = per_type[t]+ del Xp+ if shift is None:+ src = "copy_last(no usable forward direction)"+ if shift is not None:+ if CC_ZERO:+ cc = _cell_cycle_genes(args.data)+ idx = [i for i, g in enumerate(genes) if g in cc]+ if idx:+ shift[:, idx] = 0.0+ print(f"[diag] cc-zero: {len(idx)} genes zeroed", file=sys.stderr)+ sd = X.astype(np.float64).std(axis=0)+ capv = CAP * np.maximum(sd, 1e-3)+ shift = np.clip(shift, -capv, capv)+ X = np.clip(X.astype(np.float64) + shift, 0.0, None).astype(np.float32)+ norms = np.linalg.norm(shift, axis=1)+ print(f"[diag] src={src} shift norm mean/p50/p95: {norms.mean():.3f} "+ f"{np.percentile(norms,50):.3f} {np.percentile(norms,95):.3f}", file=sys.stderr)+ gmag = np.abs(shift).mean(axis=0)+ top = np.argsort(-gmag)[:20]+ print("[diag] top shifted genes: " + ", ".join(f"{genes[i]}({gmag[i]:.2f})" for i in top), file=sys.stderr)+ else:+ print(f"[diag] src={src}: no shift applied", file=sys.stderr)++ write_t2(args.out, X, coords, genes, seed=args.seed) if __name__ == "__main__":
调研来源?调研员查到并用到的知识条目和文献检索结果(只列标题和编号)。
用到的知识库条目
| 编号 | 标题 | 出处 |
|---|---|---|
| k016 | Degenerate-solution checks for population predictions | notes/handover/02_知识学习路线.md |
| k007 | Interval staging and held-out-window filtering of external data | notes/official/来件/virtualembryo.ai/rules.md |
| k003 | Fused Gromov-Wasserstein mapping for spatial snapshots | 10.1038/s41586-024-08453-2 |
分析结果?分析员写的 ANALYSIS.json:改了什么、各组分数怎么变、假设是否成立、经验和下一步建议。
| 改了什么 | 在父节点 copy_last 之上实现 T2HX-01 位移层(外部前向靶表达匹配位移 + 两输入速度回退),但代理视图内没有满足时间窗的外部样本、速度回退经验证有害而默认关(α_vel=0),实际提交的输出与父节点逐位相同。 |
|---|---|
| 各组分数的变化 | cell_state:噪声内(无变化):mmd_u 0.05832、variogram 0.05806 与父节点相同,得分各 6.25 expression_change:噪声内(无变化):de_score、de_direction 原始值均仍为 0,得分各 6.25,与父节点完全相同 local_spatial:噪声内(无变化):neighborhood_mmd 0.1126、得分 12.50,与父节点相同 shape_scale:噪声内(无变化):三项原始值与得分均与父节点相同(4.17×3) |
| family_id | T2HX-01 |
| 假设是否成立 | 否 |
| 经验 |
|
| mechanism_active | 否 |
| 下一步建议 |
|
对话摘要?每个角色和大模型对话的统计:轮数、工具调用、用时、token 数和最后的回答摘录;原始记录只给路径。
只给统计和最后回答的摘录;完整对话请到原始记录位置里列出的文件看。
分析员
| 角色?调研员写计划、工程师改代码、分析员解读分数、审查员检查作弊。 | 分析员 alibaba-token-plan-cn/qwen3.8-max |
|---|---|
| 调用次数 | 1 次 |
| 轮数?大模型一共回复了几轮(每轮可以调用多个工具)。 | 3 |
| 工具调用?大模型调用读文件、执行命令等工具的次数,按工具名统计。 | 共 2 次:bash 1、write 1 |
| 用时 | 不到 1 分 |
| token 数?输入 / 输出(含思考)的 token 数,来自接口返回的用量。 | 输入 13,632 · 输出 1,022 · 思考 549 |
| 任务(第一行) | 分析节点 n3 的打分结果,写 ANALYSIS.json |
| 最后的回答(摘录) | ANALYSIS.json written |
| 原始记录位置?完整对话记录在 Spark 上的文件路径;看板不复制原始内容。 | /home/spark-longxinyang/vec/runs/formal/20261003-105537-search-t2-heart-extrap-g24-D/nodes/3/analyst.jsonl 7 KB /home/spark-longxinyang/vec/runs/formal/20261003-105537-search-t2-heart-extrap-g24-D/nodes/3/analyst.stderr |
工程师
| 角色 | 工程师 alibaba-token-plan-cn/qwen3.8-max |
|---|---|
| 调用次数 | 1 次 |
| 轮数 | 29 |
| 工具调用 | 共 42 次:bash 31、edit 9、write 2 |
| 用时 | 14 分 |
| token 数 | 输入 69,086 · 输出 12,370 · 思考 17,778 |
| 任务(第一行) | 按计划修改程序:表达匹配型伪批量位移外推(保坐标,T2HX-01) |
| 最后的回答(摘录) | **做了什么**:在父节点(copy_last)上实现 PLAN 的 T2HX-01 位移层:优先用视图内"晚于末输入、不晚于目标"的外部样本做表达相关匹配(r≥0.5)的型级阻尼位移(坐标不动、逐基因 ±2σ 截断),两输入速度回退默认关,无可用方向时逐位等于 copy_last;含 α=0 对照与 GO 增殖模块过滤变体。 **查分结果**(proxy_noscale,用 5/20 次):默认输出 50.00(与父节点逐位相同,对照通过);型级速度 α_eff=0.45/0.9/1.5 → 49.0/48.7/48.3,de_score 原始 −0.056、de_direction ≈0——E8.25→E8.75 速度方向与真值不相关,任何 α 都无 DE 收益只赔 variogram;去掉增殖基因(44 个)后 49.05,de_direction 转微正但 de_score 更差。代理上速度外推确认无信号,故 (b) 默认关,节点行为 = 50.00 保底;外部前向路径 (a) 冒烟测试可运行(qiu E8.75 对齐、1/33 型配对成功),其效果本地不可验证。 **下一步最值得试**:代理无法检验外推方向(方法卡+本节点双重确认),本地继续调参没有出路;值得试的是不依赖"上一段速度"的方向来源——例如用 prior(Reactome/TF 调控)构造分化程序的定性方向约束,或在真实 final 视图上(若挂有前向外部样本如 MOSTA E9.5)直接评估 (a) 路径。 |
| 原始记录位置 | /home/spark-longxinyang/vec/runs/formal/20261003-105537-search-t2-heart-extrap-g24-D/nodes/3/engineer.jsonl 165 KB /home/spark-longxinyang/vec/runs/formal/20261003-105537-search-t2-heart-extrap-g24-D/nodes/3/engineer.stderr |
调研员
| 角色 | 调研员 alibaba-token-plan-cn/qwen3.8-max |
|---|---|
| 调用次数 | 1 次 |
| 轮数 | 1 |
| 工具调用 | 共 0 次:— |
| 用时 | 3 分 |
| token 数 | 输入 8,825 · 输出 1,410 · 思考 5,750 |
| 任务(第一行) | 为节点 n3(改进,父节点 n1)写改进计划 PLAN.json |
| 最后的回答(摘录) | atial(方法卡已证 OT 插值坐标会把邻域组砸到 23–41,而本榜邻域+结构门最多影响 50 分)。",
"approach": "在父节点 run.py 上加位移层,管线:1) 读 anchor 阶段(外推榜=最后观测阶段)。2) 目标位移来源按优先级回退:(a) external/ 里选一个阶段不超过靶时间、且区间完全落在心脏保留窗 (8.25,8.75)、(9.5,13.5] 之外的外部样本(如 E9.5 心脏),用其作为靶;(b) 若视图给两个输入阶段(final 情形),用两阶段按型伪批量差/时间间隔作为速度外推;(c) 都没有则原样输出=copy_last(proxy 单阶段时的退路,输出逐位等于父节点)。程序只读 manifest 的相对时间与区间字段,不写任何绝对阶段常数,伪装视图安全。3) 细胞配对按表达而非标签名:输入型与外部型用共有面板基因(要求≥50 个共有基因)上的伪批量 Pearson 相关匹配,阈值 r≥0.5,匹配失败即回退 (c)。4) 每个输入细胞 i:shift_i = α·[(1−β)·(x_ext_matched(i) − pb_t(i)) + β·(pb_ext_T(i) − pb_t(i))];X_i ← X_i + shift_i,负值截 0,|shift| 按基因上限取该基因输入标准差的 2 倍(防极端值打爆 mmd_u/variogram)。坐标一律不动——这是保邻域、保 d2_shape/occupancy_dice 的关键。5) 参数初值 α=0.7、β=0.5;网格 α∈{0.3,0.5,0.7,1.0}×β∈{0.3,0.5,0.7}。6) 流程:先跑 α=0 对照复现父节点 50.00;检查 manifest 确认外部样本存在、面板重叠与区间合规;先在 30% 分层子样本上粗筛网格,再用全量 vec-score 复核,预算≤20 次查分;选定参数后用 seed 1 复跑确认 >1 分优势(T2 噪声约 1 分,终选护栏要求种子均值超基线 1 分)。",
"expected_groups": ["expression_change", "cell_state"],
"risks": "1) 视图内可能没有可用外部样本,或外部面板/细胞类型与输入重叠太少 → 机制静默退化回 copy_last;Engineer 第一步就查 manifest 并打印匹配报告,尽早发现。2) 表达匹配把型配错 → 位移反向,DE 掉到 chance 附近;看 de_direction 是否低于 6.25 地板分即可发现。3) 过冲伤 mmd_u/neighborhood_mmd(重蹈节点 2 覆辙);每次查分都读 score_parts,邻域得分 <12.4/25 或 mmd_u 变差就降 α、增 β、收紧位移上限。4) 在 A 半过拟合参数;要求相邻网格点分数平滑、且 seed 1 复跑仍 >1 分。5) 本地小幅领先未必兑现,故只把目标定在 ≥52 而非贪大。",
"family_id": "T2HX-01",
"mechanism": "按表达相关把输入细胞型与外部(或更早阶段的)靶数据配对,计算型间伪批量差,逐细胞做 α 阻尼、β 型内收缩的位移,外推一天的心脏表达变化;坐标保持不动以维持表达—位置配对。",
"vs_constant_shift": "每细胞位移取决于其所在型与表达匹配到的靶细胞/型,幅度与方向逐型逐细胞不同,β 收缩保留型内方差;全局常数位移对全体细胞相同,会被无变化保护(std(dp)<1%·std(dt) 时 DE 记 0)击中、且坍缩型内离散度伤 mmd_u。节点 2 的朴素 damped_shift(49.51)正是无匹配、无收缩的反例。",
"mechanism_evidence": "打印诊断:逐细胞位移范数的分布(应远大于 0 且型间有差异,型内非零离散);位移最大的前 20 个基因与前几个细胞型;score_parts 前后对比——de_score/de_direction 原始值应脱离 0、mmd_u 原始值应下降;四组分中 expression_change 与 cell_state 上升而 local_spatial 保持 ≥50。若位移分布全零或各组纹丝不动,即机制未运行,先查匹配环节。",
"mechanism_off_control": "同一程序以 α=0 运行:所有位移归零,输出应逐位等于父节点 copy_last,vec-score 应复现 50.00 且四组全 50;同时打印的位移诊断应全零。若 α=0 时分数偏离 50.00,说明管线在位移之外引入了副作用(如抽样、截断顺序变化),必须先修。"}
``` |
| 原始记录位置 | /home/spark-longxinyang/vec/runs/formal/20261003-105537-search-t2-heart-extrap-g24-D/nodes/3/researcher.jsonl 6 KB /home/spark-longxinyang/vec/runs/formal/20261003-105537-search-t2-heart-extrap-g24-D/nodes/3/researcher.stderr |
审查员
| 角色 | 审查员 alibaba-token-plan-cn/qwen3.8-max |
|---|---|
| 调用次数 | 1 次 |
| 轮数 | 16 |
| 工具调用 | 共 15 次:bash 9、read 5、write 1 |
| 用时 | 2 分 |
| token 数 | 输入 28,424 · 输出 2,511 · 思考 4,217 |
| 任务(第一行) | 审查节点 n3 的程序是否越界读取、写死目标、钻评分器漏洞 |
| 最后的回答(摘录) | REVIEW.json written |
| 原始记录位置 | /home/spark-longxinyang/vec/runs/formal/20261003-105537-search-t2-heart-extrap-g24-D/nodes/3/reviewer.jsonl 101 KB /home/spark-longxinyang/vec/runs/formal/20261003-105537-search-t2-heart-extrap-g24-D/nodes/3/reviewer.stderr |