269 KiB
桃育种系统 · 统计引擎实施记录
版本:v1.4(2026-08-04 追加统计严谨·预测完整性与 MLOps 复现性:PA 落库 / 溯源 / germplasm_id 填充 / 砧木扩列 / Calo 相关校正 / 空间竞争协变量 + 组合得失漏斗) 定位:记录统计引擎多轮 P0/P1 落地 + 田间刚需(花粉档案)+ 决策正确性(无性系级指数)+ 统计严谨(配合力交配设计 / 相关校正 / 空间竞争)+ MLOps 复现性 + 组合得失漏斗的实现、验证与文件清单——G×E 交互引擎(2026-08-03)、性状方向标注(2026-08-04)、花粉档案(2026-08-04)、无性系级指数(2026-08-04)、配合力交配设计(2026-08-04)、统计严谨·MLOps 复现性(2026-08-04,①Calo②PA③溯源④germplasm_id⑤砧木⑥空间竞争)与组合得失漏斗(2026-08-04,⑧ v_combination_funnel)。本文档为持续追加的落地台账,与规格文档
桃育种系统模块扩展需求规格.md(v2.10)配套;规格管"应该长什么样",本文管"实际落地了什么、怎么验证的"。 相关探针:Temp/claude/e2e_gxe_20260803.py(G×E,5 场景)·Temp/claude/e2e_direction_20260804.py(方向标注,7 组)·Temp/claude/e2e_pollen_20260804.py(花粉档案)·Temp/claude/e2e_clone_index_20260804.py(无性系级指数,6 组)·Temp/claude/e2e_combining_design_20260804.py(配合力交配设计,5 组)·Temp/claude/e2e_prediction_rigor_20260804.py(②③④,4 组)·Temp/claude/e2e_rootstock_20260804.py(⑤)·Temp/claude/e2e_corr_spatial_20260804.py(①⑥,3 组)·Temp/claude/e2e_combination_funnel_20260804.py(组合得失漏斗,3 组)。
一、G×E 交互引擎 P0(2026-08-03)
1.1 背景与目标
复审清单第 2 条要求基因型×环境(G×E)交互随机效应显式建模。桃为多年生多年多点(MET)试验作物,同一克隆/家系在跨点、跨年表现往往相反(如 c1 在 A 站高、B 站低,c2 反之),若只估主效应会系统性误排 EBV。本轮在 run_ablup 上扩展 G×E 模式(method=GXEBLUP),并补齐可辨识性门禁与异步任务记录。
1.2 引擎能力(statistics/service.py::run_ablup)
| 参数 | 取值 | 行为 |
|---|---|---|
gxe |
True / False |
True 走 GXEBLUP(含 G×E 随机互作);False 回归纯 ABLUP(G×E 项关闭) |
gxe_env |
site / year |
环境维度。site 自动入固定效应 trial_study;year 自动入固定效应 year |
method |
GXEBLUP / ABLUP |
按 gxe 开关自动落库;model_name 形如 GXEBLUP_{trait}_{env}_{ts} |
fixed_effects |
列表 | 调用方显式指定时与自动效应合并 |
G×E 落库输出(breeding_prediction.note JSON):
sigma_gxe:G×E 方差分量 σ²gxe(>0 表示存在交互)gxe_ratio:σ²gxe 占比n_cross_env:跨环境基因型数(有多少基因型至少在 2 个环境中观测)skipped:跳过明细(如缺站点株数)
记录级 vs 基因型级:
- 家系分组(无 clone)时基因型=组合,G×E 记录逐树;
year模式记录级 = (树,年) 逐条(train_n 为记录数,EBV 行按树写)。 - 克隆坍缩(见 1.5)时基因型=clone,多株坍缩为基因型节点。
1.3 自动固定效应
| gxe_env | 自动固定效应 | 说明 |
|---|---|---|
site |
trial_study |
站点由 trial_study_id 解析(缺站点的株记录跳过并写 skipped) |
year |
year |
年份由观测 evaluate_year 解析 |
调用方仍可用 fixed_effects 显式追加(如 ["trial_study"]),引擎合并去重。
1.4 可辨识性门禁(G×E 不可辨识 → 409,拒绝运行)
| 门禁 | 触发 | 处置 |
|---|---|---|
| 无跨环境重复 | 没有任何基因型在 ≥2 个环境出现(n_cross_env == 0) |
G×E 不可辨识:无任何基因型跨环境重复。拒绝运行。 |
| 单元内无重复 | 每个(基因型×环境)单元仅 1 条观测,σ²gxe 与残差混杂 | 无任何基因型×环境单元内重复(每格仅 1 条观测…) |
| 无可分环境记录 | 所有记录缺站点/年份 | G×E 分析无可分环境的记录 |
门禁拒绝时在 StatisticsJobModel 落一条 status=FAILED + error_msg(同步 409 抛出,异步失败可查)。
1.5 克隆坍缩
同 clone 经扩繁的多株 tree 在 G×E 模式下坍缩为基因型节点 c{clone}:G×E 专用系谱 gxe_pedigree 以 c{clone} 为个体,父母指向组合亲本(或树亲本);record_map 全部映射到 c{clone}。同 clone 各株 EBV 一致(重复测量聚合,杜绝自由度虚高)。
1.6 异步任务记录(StatisticsJobModel)
| 字段 | 值 | 说明 |
|---|---|---|
job_type |
GXE / ABLUP(/ COMBINING 等) |
任务类型 |
status |
SUCCESS / FAILED |
任务状态 |
result_ref |
prediction id | 关联结果 |
error_msg |
文本 | 失败原因(可辨识性门禁消息亦落此) |
1.7 验证(Temp/claude/e2e_gxe_20260803.py,5 场景全过)
| 场景 | 数据 | 断言要点 |
|---|---|---|
| [1] site-G×E 家系分组 | 2 组合×2 站×3 株,无 clone | 自动 fixed={trial_study}、method=GXEBLUP、σ²gxe>0、n_cross_env=2、train_n=12、EBV 行=12、job_type=GXE SUCCESS |
| [2] 不可辨识门禁 | 各组合仅单站 | 409 G×E 不可辨识:无任何基因型跨环境重复、job FAILED + error_msg |
| [2b] 单元内无重复 | 2 基因型×2 站每格 1 株 | 409 含 单元内重复、job FAILED |
| [3] year-G×E | 2 clone×2 年交叉互作 | 自动 fixed={year}、train_n=16(记录级)、EBV 行=8(树级)、σ²gxe>0、n_cross_env=2 |
| [5] 克隆坍缩(site) | 2 clone×2 站×每格 2 株 | record_map 全为 c{clone}、同 clone EBV 相同、train_n=8、EBV 行=8 |
| [4] 回归 gxe=False | 同 [1] 数据 | method=ABLUP、显式 fixed_effects=["trial_study"]、EBV 行=12、job_type=ABLUP SUCCESS |
测试基座用 _spy_solve 包一层真引擎(monkeypatch blup.solve),捕获 fixed/record_map kwargs 后仍跑真解,验证引擎传参;GATE_RELAX=dict(min_clone_n=1, min_pedigree_rate=0.0, max_missing_rate=1.0) 放开数量门槛专注验证 G×E 逻辑。
二、性状方向标注 direction / into_ebv / default_h2(2026-08-04)
2.1 缺陷背景(科学正确性硬伤)
bre_trait 原仅 stage/is_core,无方向标注。选择指数与决策默认"高 EBV = 优",对低优性状(裂果率、病害级别、酸度——若目标是低酸)会选反:Smith-Hazel 的 b 与加权 Z 隐含"越大越好"。用户确认缺陷属实,拍板修复范围:
- 翻转范围:指数+决策+排行全翻转;
- into_ebv 范围:'0' 仅从选种相关候选剔除(指数/EBV 排行/决策预览/ABLUP 下拉),describe/correlation/trait_values 不受影响;
- default_h2 兜底:zsum + smith_hazel 都兜底(无实测 h² 用先验,两者皆无才报错)。
2.2 数据模型变更
bre_trait 新增三列(幂等 ALTER,backend/sql/weld_trait_direction.sql;create_all 只建新表,新列须手写 SQL):
| 列 | 类型 | 默认 | 说明 |
|---|---|---|---|
direction |
varchar(16) | 'desc' |
性状方向:desc=越大越好 / asc=越小越好 |
into_ebv |
varchar(1) | '1' |
是否选种目标:1=进 EBV/指数/决策候选 / 0=仅记录 |
default_h2 |
double precision | NULL | 先验遗传力 h²(指数无实测 h² 时兜底;桃经典先验,可在性状字典改) |
种子数据(backend/sql/bre_trait_seed.sql,INSERT 0 43,ON CONFLICT DO UPDATE 含三新列):
- 7 个数值 core 性状(max/avg_fruit_weight、longitudinal/transverse/lateral_dia、flesh_thickness、ssc):
direction='desc'、into_ebv='1'、default_h2取桃经典先验(果重/糖度 0.5、果径/肉厚 0.4/0.3); - 其余 categorical/date 性状:
into_ebv='0'、default_h2=NULL。
ORM/API 透传:TraitModel/TraitBaseSchema/TraitUpdateSchema/TraitOutSchema/TraitQueryParam 补齐三字段;batch_export mapping_dict、batch_import header_dict/fields(direction/into_ebv 缺省 'desc'/'1'、default_h2 _to_float;required_headers 仍只校验原 14 键,兼容旧模板)、import_template_download 选项同步。
2.3 后端翻转逻辑(statistics/service.py)
辅助 _trait_meta_map(codes=None):{trait_code: {direction, into_ebv, default_h2}},供指数/决策/排行共享方向语义。
| 模块 | 变更 |
|---|---|
list_traits(core_only, selection_only) |
select 新增三字段;selection_only=True → where(into_ebv == "1")(controller 加 selection_only query 参数) |
selection_index |
cols 剔除 into_ebv='0' 写入 extra["dropped"](用户可见提示) |
_weighted_z_index(zsum) |
z 标准化后对 asc 性状取负(z = -z),统一"越大越优";use_h2 兜底 h = herit.get(c) or default_h2 |
_smith_hazel_index |
h² 取 h_eff[c] = 实测 h² or default_h2;h_eff[c] is None 才 409(缺实测且无先验 default_h2: …);a 归一化后对 asc 元素取负 |
run_ablup |
写时 rank 排序 reverse=(direction != "asc")(EBV 排行即优度序) |
ebv_ranking |
读时重排(见 §三) |
clone_ranking |
按当前方向重排 ebv_mean(reverse=(direction != "asc")) |
decision_preview |
_top_n:into_ebv='0' 直接返回空集;ranked 按方向取最优前 N(asc 取 EBV 最小);op 缺省 <=(asc)/ >=(desc),pheno 与 ebv 共用 |
compare_predictions |
轮次对比 rank 排序方向感知(见 §三) |
2.4 前端
| 文件 | 变更 |
|---|---|
api/module_bre/statistics.ts |
listTraits(coreOnly, selectionOnly) 带 selection_only 参数 |
views/module_bre/statistics/index.vue |
selTraits(listTraits(true, true))仅用于指数权重/EBV 批次/ABLUP-G×E 性状下拉,与 describe/correlation 共享的 traitSel 解耦(后者保留全量);asc 性状标签加 '↓越小越优' 角标 |
views/module_bre/trait/index.vue |
表单/表格/详情/搜索四处加 direction el-select(desc/asc+文案)、into_ebv 开关、default_h2 输入 |
views/module_bre/selection_rule/index.vue |
conditions_json 文本框说明:"op 缺省按性状方向(desc≥ / asc≤),rank_top_n 按方向取最优前 N" |
2.5 验证(Temp/claude/e2e_direction_20260804.py,7 组全过)
基座 4 性状 dA(desc,1,0.5)/bB(asc,1,0.25)/cC(desc,0,None)/dD(desc,1,None) + 4 批次 pA(h²=0.5)/pB/pC/pD(h²=None) + 12 株 EBV=[10.0..32.0] 升序。
| 组 | 验证点 | 断言要点 |
|---|---|---|
| [1] | list_traits 三字段 + selection_only | 返回 direction/into_ebv/default_h2;selection_only=True 过滤 into_ebv='0' |
| [2] | zsum 方向翻转 | 同数据 desc→asc 排名精确互反(top2 从最高 EBV 2 株翻为最低 2 株) |
| [3] | into_ebv='0' 剔除 | 权重含 cC → 结果 traits 不含 cC、result_json.dropped 有提示 |
| [4a] | smith_hazel default_h2 兜底 | 批次 pD h²=None 但性状 dD 带 default_h2=0.25 → 成功 |
| [4b] | smith_hazel 无实测无先验 | 批次无 h² 且性状无 default_h2 → 409 缺实测且无先验 |
| [5] | decision rank_top_n 方向 | asc 命中 EBV 最低 2 株、desc 命中最高 2 株;无 op 时 asc 走 <= |
| [6] | ebv_ranking 读时重排 | 性状事后改方向后按当前方向重排(rank 按优度重编号) |
| [7] | compare_predictions 方向感知 | asc 反序两批 rank1=最低 EBV 株(cur_ebv=10.0);desc 反序两批 rank1=最高 EBV 株(32.0) |
三、本轮修复的结构性 bug(方向盲区家族)
同一缺陷模式——"高 EBV = 优"硬编码——在排行/对比链路还有两处遗留,本轮一并修复:
3.1 ebv_ranking 方向盲区(读时重排)
原实现只在 direction=="asc" 时重排,desc 信任写时持久化 rank。当性状事后改方向(如 bB 由 asc 改 desc),已落库批次 rank 仍是 asc 序 → 读回倒序、最低 EBV 排第一。修复:读时始终按 predicted_value + 当前 direction 重排并重编号 rank,且 self.db.expunge(r)——因为 GET 会话走 session.begin()(退出自动提交),不 expunge 会把重排后的 rank 写回库,破坏"GET 纯读"。
3.2 compare_predictions 硬编码降序
原实现两处排序 reverse=True(写死高 EBV=rank 1)。对 asc 性状展示的 rank 列会把最差株显示为第 1(Spearman 相关/位移量对反转不变量,但暴露的 rank 列是错的)。修复:读 trait direction,reverse = (direction != "asc") 同时用于 rank_cur 与 rank_prev;corr/flip 判定对反转不变量保持不变。
四、花粉档案 breeding_pollen(2026-08-04)
4.1 缺陷背景(田间刚需)
用户反馈:桃花期仅 3–7 天,父本花粉是杂交季命脉,但代码里没有 bre_pollen 表(仅在测试文件提及),bre_pollination 有花朵数/坐果数/去雄/套袋,却无花粉采集日期、贮藏方式(-20℃/液氮)、活力检测(TTC 染色率/离体萌发率%)、授粉窗口计划。后果:明年复盘"这批坐果为什么低"毫无抓手。核验属实(比描述更严重:一期文档规划的 pollination_method/pollen_source/pollen_viability 三字段也全未实现)。
4.2 架构决策(用户确认)
| 决策点 | 拍板 | 理由 |
|---|---|---|
| 父本锚点 | 树级 male_tree_id FK→bre_tree(与 pollination.male_tree_id 一致) |
单父本溯源;混合/外地采集时为空 + source_type 区分 |
| 活力建模 | 单值+方法(viability_method[ttc/germination]+viability_pct+viability_test_date) |
不建子表,够用且简单 |
| 窗口计划 | 派生有效期+校验(collect_date+expiry_date;窗口=[采集日,失效日] 由 pollination 校验) |
不建独立计划表;/bre/pollen/available_lots 提供"当前花期可用批次" |
4.3 数据模型(backend/sql/weld_pollen.sql,幂等 DDL + create_all 注册)
新表 bre_pollen(lot_code UNIQUE / male_tree_id FK SET NULL / source_type tree|mixed|external / collect_date / collect_method / quantity / storage_method fridge|minus20|minus80|liquid_n2 / viability_method ttc|germination / viability_pct / viability_test_date / expiry_date / remark)+ ALTER bre_pollination ADD pollen_lot_id integer REFERENCES bre_pollen(id) ON DELETE SET NULL + ADD pollination_method varchar(32)(补一期文档规划但遗漏的授粉方式)。
ORM:module_bre/pollen/ 五件套(model/schema/crud/service/controller),路由前缀 /bre/pollen;module_bre/__init__.py 注册 PollenRouter(create_all 经 import 链自动拾取新模型)。
4.4 服务层关键逻辑(pollen/service.py + pollination/service.py)
| 逻辑 | 实现 |
|---|---|
| 去重 | _check_code:批次号存在 → 409「已存在」(create/update/batch_import 均走) |
| FK 校验 | assert_parents_exist(父本树不存在→409;自动跳过 None,可空 male_tree_id 安全) |
| 标签填充 | _attach_fk_labels:male_tree_id→tree_no;授粉侧 pollen_lot_id→lot_code |
| 授粉窗口校验 | _validate_pollen_window:授粉日期须在批次 [collect_date,expiry_date] 内,否则 409「授粉日期 X 不在花粉批次 Y 的授粉窗口 [A ~ B] 内」;update 时字段未变沿用库内现值 |
| 可用批次 | available_lots(date_on):返回窗口内批次(label 含窗口区间+活力%),缺省今天 |
4.5 菜单/权限(backend/sql/bre_menu.sql)
| 项 | 值 |
|---|---|
| 菜单 | 900056 花粉档案(parent 900030 杂交配组,hidden,route /bre/pollen,component module_bre/pollen/index) |
| 按钮 E 段 | 900601-900608(module_bre:pollen:detail/query/create/update/delete/export/import/download) |
| 角色关联 | SUPER_ADMIN/ADMIN 范围扩至 900600-900699 |
4.6 前端
| 文件 | 变更 |
|---|---|
api/module_bre/pollen.ts |
PollenAPI 全套 + getAvailableLots(授粉窗口下拉) |
views/module_bre/pollen/index.vue |
花粉 CRUD 页(贮藏/活力/采集方式下拉、采集/测定/有效期日期、活力% 数字) |
views/module_bre/pollination/index.vue |
表单/表格/搜索加 pollen_lot_id(批次下拉)+ pollination_method(授粉方式下拉) |
views/module_bre/_shared/StageView.vue + stage_cross/index.vue |
杂交配组第三标签「花粉档案」 |
4.7 验证(Temp/claude/e2e_pollen_20260804.py 全过 + vue-tsc)
| 组 | 断言 |
|---|---|
| [pollen.create] | male_tree_no 标签=T015108、活力 85.5% 回填、窗口落库 |
| [dup] | 409「花粉批次号 … 已存在」 |
| [fk] | 409「采集父本树不存在或已被删除」 |
| [list/detail/options/available_lots] | 均含新批次;available_lots 返回窗口内批次 |
| [pollination 窗口内] | create 成功、pollen_lot_no 标签、授粉方式回填 |
| [window 窗口外] | 409 含「授粉窗口 [2026-07-01 ~ 2026-09-30]」 |
| [update/delete] | 授粉日期改窗口内仍通过;pollen update 活力/有效期生效;软删生效 |
五、选择指数·无性系级聚合(2026-08-04)
5.1 决策正确性背景
用户提出决策正确性缺陷:selection_index 对每个 tree_id 算指数并排名、apply_selection 写每株,但桃是无性繁殖——一个 clone 经扩繁的多株遗传同质,应聚合为一个遗传实体再排名。后果:同一个优系 3 株可能被拆成 3 个独立指数条目,可能只选中其中 1 株而漏掉该系其他株,也不利"系级决选"。用户拍板:指数前先按 clone 聚合 EBV(mean/max 由可靠性加权),在 clone 级算 Smith-Hazel,再决定入选 clone。
自株退化(工程补充):tree.clone_id 在实生苗阶段可空(v2.2/A1 决策),若把无 clone 的株全部剔除,实生苗阶段选择会塌缩。故未晋升 clone 的实生株退化为自株单元(key=-tree_id,每株独立参与指数与决选),入选命中规则 stage 时晋升建 clone。
5.2 数据模型变更
无表结构变更(复用 tree.clone_id + breeding_prediction_value 既有字段)。仅接口与计算层变更:
| 接口 | 变更 |
|---|---|
SelectionIndexIn.aggregate |
新增:clone(默认,无性系级)/ tree(旧单株级行为保留) |
selection_index 响应 |
每条 top 项含 clone_id/clone_code/n_trees/tree_ids(clone 级);tree 模式含 tree_id;整体 "aggregate" 回显 |
5.3 聚合与排名逻辑(statistics/service.py)
_clone_units(cols, tree_ids, ebv_by_trait, pheno_by_trait, rel_by_tree)——聚合单元构造:
- 查
tree.id/clone_id/tree_no(限定 tree_ids)→ 按clone_id分桶,空桶自株 key=-tree_id; - 单元
ebv_src[c][key]= 可靠性加权Σ(ebv×rel)/Σ(rel)(桶内每 trait 各算一份),全 rel=0 回退简单均值; - 单元
pheno_src[c][key]= 简单均值(smith_hazel 表型均值用); - 返回
[{key, clone_id, label, n_trees, tree_ids}]。
排名单位切换:zsum / Smith-Hazel 改为在单元 key 集上计算(ebv_src/pheno_src 取数),方向感知沿用 v2.3(统一越大越优);Smith-Hazel 的 G 矩阵 pair 相关仍由树级 ebv_by_trait 抽样估计,b = P⁻¹Ga 在 clone 单元上评分。响应组装把单元字段映射回每条 top(tree 模式还原 tree_id)。
apply_selection 按遗传实体写:
- top 项可能是 clone 级(
tree_ids)或旧树级(tree_id),统一构建units; - 每单元
rel = min(rel_by_tree.get(t, 1.0) for t in u_tids)(保守:最弱证据株门控全系); - 写一条
selection_result:clone_id指向全系(self 为 NULL)+tree_id溯源一株(优先已有记录株)+ reason 含「系内N株」; - 入选单元命中规则 stage →
_promote_tree_to_clone(首株, stage)幂等晋升建 clone(复用既有 clone、推进 stage),self 株由此回填clone_id。
5.4 前端
| 文件 | 变更 |
|---|---|
api/module_bre/statistics.ts |
selectionIndex data 类型加 `aggregate?: 'clone' |
views/module_bre/statistics/index.vue |
工具栏「聚合:无性系级/单株级」radio(默认无性系级)+ 说明文案(桃无性繁殖默认;未晋升实生株按单株参与);clone 模式结果表显示 clone_code/clone_id/n_trees/涉及单株 |
5.5 验证(Temp/claude/e2e_clone_index_20260804.py,6 组全过)
基座:目标/组合/2 clone(X=2株 T1T2、Y=2株 T3T4)+ 2 自株(T5T6)+ 2 性状 A(desc) B(asc) + 2 批次。A 系 EBV:T1=10(rel.1)/T2=30(rel.9) 加权 28;T3=20(rel.9)/T4=40(rel.1) 加权 22——可靠加权 X 排 Y 前,简单均值则 X20<Y30 反序,验证加权是有效差异而非巧合。
| 组 | 验证点 | 断言要点 |
|---|---|---|
| [1] | clone 聚合单元 + 可靠加权排名 | 6 株 → 4 单元;clone 单元 n_trees=2/tree_ids 正确;自株 key 独立;X(加权28) 排 Y(加权22) 前 |
| [2] | tree 模式兼容 | aggregate="tree" 返回 6 条含 tree_id,desc 首=EBV 最高株 T4 |
| [3] | 方向翻转 clone 级 | A 改 asc → top 精确互反,首=最低聚合 EBV 的 T5 自株 |
| [4] | smith_hazel clone 级 | b 含 A/B;top 含 clone 单元(n_trees/tree_ids 正确) |
| [5] | apply_selection clone 级写入 | top_n=2 → 写 2 条决选:cloneX 一条(clone_id + 溯源 T1/T2 之一 + reason「系内2株」)+ self T6 一条 |
| [6] | apply 晋升建 clone | top_n=4 含自株 → T5/T6 命中 sp 规则晋升建 clone(clone_id 回填);clone X 株 stage 推进 sp |
科学正确性收口:指数排名单位与决选写入单位统一为遗传实体——同一优系多株不会再被拆散、单株误选漏选;自株退化保住实生苗阶段选择能力,且入选即晋升、天然补上 clone 归属。
六、配合力交配设计 design_type(2026-08-04)
6.1 缺陷背景(统计严谨)
用户指出统计严谨缺陷:combining.solve 只实现 Griffing 对称全双列(model A),但 run_combining 与 bre_combining_ability 都没有 design_type 字段区分完全双列 / 部分双列 / line×tester(NCII) / NCIII。后果:用 line×tester 设计时,GCA/SCA 算法与 ANOVA 自由度都与全双列不同,当前一律按全双列算会算错(自由度错、GCA 含互反/自交效应)。用户拍板修复:bre_cross_combination / bre_combining_ability 加 design_type,combining.solve 按设计分支(line×tester 用 NCII 双因素模型)。
6.2 数据模型变更
bre_cross_combination 加 design_type varchar(16) NULL(缺省按 full_diallel 计);bre_combining_ability 同步落 design_type。取值硬编码校验(同 selection_index.method,非 sys_dict):full_diallel(完全双列,默认)/ partial_diallel(部分双列)/ line_tester(line×tester NCII)/ nciii(NCIII 测交)。DDL 见 backend/sql/weld_combining_design.sql(幂等 ALTER + COMMENT)。create/update 接受 code 或中文标签并归一化,非法值 409(交配设计取值不合法)。
6.3 求解器分支(scripts/breeding_stats/combining.py)
| 设计 | 模型 |
|---|---|
full_diallel / partial_diallel |
Griffing 对称全双列 model A:y_ij = μ + g_i + g_j + s_ij,Σg=0 约束,最小二乘 BLUE |
line_tester(NCII) |
双因素模型 model B:y_ij = μ + l_i + t_j + (lt)_ij;parent1=line(母本)、parent2=tester(父本),分别 Σl=0 / Σt=0;SCA = line×tester 互作 = 残差 |
nciii |
同一 model B,门槛 tester 恰好 2 个 |
工程要点:
- 可辨识性:tester 列从索引
1+n_l起 → 显式列选择(非连续切片);基线列切出后吸收剩余列。 - 顺序 ANOVA(SS 型):SS_line(intercept→line)→ SS_tester(→tester after line)→ SS_sca(残差);df_line=n_l-1、df_tester=n_t-1、df_sca=n-1-df_line-df_tester。输出
design/roles/df_line/df_tester/df_sca。 - 门禁:同亲本既作 line 又作 tester(角色重叠)→
ValueError→ 任务 FAILED + CustomException「角色重叠」;NCIII tester≠2 → 拒绝。 - gca_se 持久化:GCA 标准误内嵌
anova_json["gca_se"](避免 DB 迁移,gca_json/sca_json 形状稳定);前端 GCA 表加 SE 列。
6.4 运行过滤与持久化(statistics/service.py::run_combining)
run_combining 加 design_type 参数透传 combining.solve;按设计过滤组合——只纳入 cc.design_type or 'full_diallel' == dt 的组合,杜绝全双列标注组合混入 line×tester 运行(混算根因)。bre_combining_ability.design_type 随结果落库,anova_json 带 design 供前端分显示。
6.5 前端
| 文件 | 变更 |
|---|---|
api/module_bre/statistics.ts |
RunStatsPayload.design_type?: string(配合力运行时下发) |
api/module_bre/cross_combination.ts |
查询/表格/表单类型加 design_type |
views/module_bre/statistics/index.vue |
运行对话框「交配设计」radio(DESIGN_LABELS 四选项 + 说明);配合力批次表「设计」列;详情 ANOVA 按 a.design 分支——NCII/NCIII → line/tester/互作 F 与 p + roles 计数,双列 → GCA F;GCA 表 SE 列;SCA 表展示 |
views/module_bre/cross_combination/index.vue |
表单/表格/详情/搜索四处 design_type(radio + DESIGN_LABELS 中英映射,createInitialFormData 默认 full_diallel) |
6.6 验证(Temp/claude/e2e_combining_design_20260804.py,5 组全过 + vue-tsc)
基座:数值性状 + 目标 + 6 亲本;NCII 2×2(line_tester 4 组合)+ NCIII 2×2(nciii 4 组合)+ 1 条 full_diallel(应被 line_tester 运行排除)。
| 组 | 验证点 | 断言要点 |
|---|---|---|
| [1] | NCII line_tester 运行 | design_type 落库;anova.design=line_tester;df 1/1/1;roles.lines/testers 正确;平衡 2×2 精确解 gca{l1:-2,l2:+2,t1:-1,t2:+1};SCA 恰 4 条;E2EDTMIX(full_diallel)被排除;anova.gca_se 内嵌 |
| [2] | NCIII 分支 | 只纳入 nciii 标注组合;同一双因素模型;df_line/df_tester=1;SCA 4 条;gca{n1:-2,n2:+2} |
| [3] | 角色重叠 gate | 同亲本作 line 又作 tester → 任务 FAILED + CustomException 含「角色重叠」 |
| [4] | create/update 校验 | line_tester→原样、中文「完全双列」→归一化 full_diallel、bogus_design→409、update→nciii |
| [5] | 持久化复查 | commit 后新会话 design_type / anova.design / gca_se 均真实落库 |
科学正确性收口:配合力计算不再默认"一律全双列"——line×tester(NCII)/NCIII 走双因素模型,GCA/SCA 与 ANOVA 自由度按设计正确计算;运行层按
design_type过滤组合,杜绝混算;角色重叠直接拒绝,消除亲本角色语义错误。待办:partial_diallel(Griffing model 4,无互反)与 model 3(含互反、需单株表型)本轮未单独实现,随使用按需补。
七、统计严谨·预测完整性与 MLOps 复现性(v1.4,2026-08-04)
7.1 缺陷背景(七条复审逐条核实)
用户抛出七条统计严谨/完整性复核主张,逐条对照代码核实均为真缺陷后按优先级落地(便宜且值得马上补 ②④ → 中期 ③⑤ → 需新能力 ①⑥):
| # | 主张(核实) | 落地 |
|---|---|---|
| ② | bre_prediction_value 只存 reliability,未存预测准确度 PA |
加 pa = √reliability;批次 bre_prediction.accuracy 改填真 PA |
| ④ | PredictionValueModel.germplasm_id 永未填充(run_ablup 只写 tree_id) |
写 EBV 行时回填 tree.germplasm_id,亲本级 EBV 查询可用 |
| ③ | bre_prediction 无 data_version / 输入哈希 / 引擎版本,MLOps 溯源不全 |
加三字段 + 确定性输入哈希,同数据重跑一致、改观测必变 |
| ⑤ | bre_rootstock 仅 code/name/remark,无矮化类、砧穗亲和性 |
扩 dwarf_class + compatibility,全链路透传 |
| ① | Smith-Hazel 的 G 矩阵用"EBV 皮尔逊相关"近似(无真 MT-BLUP) | 改 Calo 可靠性校正 r_g = r_EBV/√(rel_i·rel_j)(真 MT-BLUP 记遗留) |
| ⑥ | 果园株间竞争 / 边缘效应未建模 | run_ablup 新增 covariate="competition"(Chebyshev 邻域株数) |
| ⑦ | 前端 D 层 _coming_soon 占位页 |
保持占位属预期(P2 远景,本轮不动) |
7.2 数据模型变更(backend/sql/weld_prediction_rigor.sql + weld_rootstock.sql)
| 表 | 列 | 类型 | 说明 |
|---|---|---|---|
bre_prediction_value |
pa |
double precision | 预测准确度 PA = √reliability(每株每性状) |
bre_prediction |
data_version |
varchar(32) | 数据版本(_DATA_VERSION="v2.7",service.py) |
bre_prediction |
input_hash |
varchar(64) | SHA256:{tree_id}:{均值表型} + {个体}|dam|sire 确定性序列化(数据漂移可检测) |
bre_prediction |
engine_version |
varchar(32) | 引擎版本(blup.ENGINE_VERSION="1.0.0") |
bre_rootstock |
dwarf_class |
varchar(32) | 矮化类:矮化/半矮化/乔化/柱状/其他 |
bre_rootstock |
compatibility |
varchar(16) | 砧穗亲和性:强/中/弱 |
accuracy语义正名:原误填"均值 EBV 的平方根"(量纲不符),现改填真 PA = √(批次内可靠性均值)(numeric(5,3),3 位小数),与bre_prediction_value.pa(每株)口径一致。
7.3 引擎逻辑(statistics/service.py + blup.py)
| 规格点 | 实现 |
|---|---|
| ② PA | run_ablup 写 EBV 行 pa = √reliability;批次 accuracy = √(均值 rel)。ebv_ranking 单株响应透出 pa |
| ④ germplasm_id | run_ablup 写 EBV 行 germplasm_id = tree.germplasm_id(晋升回填的种质;无种质株保持 NULL 合规) |
| ③ 溯源 | 批次级落 data_version / input_hash / engine_version;input_hash 覆盖全部参与树 × 全部观测(含 NULL 表型拼接),改 1 条观测哈希必变 |
| ① Calo | _smith_hazel_index G 非对角改 r_g = r_EBV/√(rel_i·rel_j)(rel 取配对树该性状均值),钳制 [−1,1];可靠性缺失/近零 → 0(保守);extra["g_corr"](性状对)+ extra["g_note"] 落 bre_selection_index.result_json 可审计;rel 数据即 ② 落库的 reliability |
| ⑥ 空间竞争 | run_ablup(covariate="competition"):同 (plot_id, block_no) 网格内 Chebyshev 距离 1(8 邻域,不含自身)株数作协变量;相邻越多竞争越强、边缘株相邻少隐式捕捉边缘效应;G×E 分支同步支持(三处 covariate == "crop_load" 泛化为 covariate 真值);全无 row/col → CustomException(显式数据需求);bre_tree.row_no/col_no 数据能力已全链路就位(模型/前端录入/表格/详情/导入导出) |
7.4 前端
| 文件 | 变更 |
|---|---|
api/module_bre/statistics.ts |
指数批次表/EBV 行类型加 germplasm_id/pa |
views/module_bre/statistics/index.vue |
指数批次表加 germplasm_id/pa 列;ABLUP 运行对话框协变量 el-checkbox 改 radio(无 / crop_load / competition)+ 说明文案 |
api/module_bre/rootstock.ts + views/module_bre/rootstock/index.vue |
dwarf_class/compatibility 全量:常量、搜索、表格、详情、表单、handleSearch/onResetSearch |
7.5 验证(三探针全过 + vue-tsc)
e2e_prediction_rigor_20260804.py(②③④,4 组)
| 组 | 断言 |
|---|---|
| [1] | 每株 pa = √rel 逐条一致;批次 accuracy = √(均值 rel);溯源三字段(data_version=v2.7 / engine=1.0.0 / acc=0.439);germplasm 级查询(按 gA 查得 2 条);ebv_ranking 透出 pa |
| [2] | 复现性:同数据重跑 input_hash 完全一致 |
| [3] | 数据漂移:改 1 条观测值后重跑哈希必变 |
| [4] | 跨会话持久化:commit 后新会话读取值/哈希仍在(全行扫描断言) |
e2e_rootstock_20260804.py(⑤):create/detail/update/list(搜索 dwarf_class)/options/export(含新列)/template(下拉选项)/DB 直查全过。
e2e_corr_spatial_20260804.py(①⑥,3 组)
| 组 | 断言 |
|---|---|
| [1] | Calo 校正值:g_corr 含性状对、g_note 含"可靠性校正";got_rg 与独立重算 clamp(r/√(rel_i·rel_j)) 一致(容差 1e-4),例 r=0.9966/rel 0.1925·0.1345 → r_g=1.0 |
| [2] | competition 消费验证:有坐标运行成功,EBV 与无协变量最大差异 0.5465(差分消费,非仅字段) |
| [3] | 数据需求判定:全无 row/col → CustomException 含 row_no/col_no |
7.6 遗留(已记账,不动引擎)
- 真 MT-BLUP:多性状 G 需全新多变量 REML 求解器(Kronecker 积 G/R + 方差分量迭代,数值收敛风险大)。本轮用 Calo 可靠性校正顶上(业界对"EBV 相关替代 G"的标准修正),
g_corr/g_note落库可审计。后续要做即按此接口替换。 2026-08-04 追加加固:逐对独立估计的 r_g 在 ≥3 性状时可能违反三角不等式使 G 非正定 →_smith_hazel_index构造 G 后做最近半正定投影(Higham 特征值截断,np.linalg.eigh),b=P⁻¹Ga 才良性;新增稳定性警示extra["warnings"](完整观测树 <30 / P 条件数 >1000 / G 非正定已投影 / r_g 钳到 [−1,1] 边界)随result_json落库可审计,不阻断。数值验证:0.9/0.9/−0.9 相关阵 det<0 → 投影触发;2 性状正定场景无警示。 - ⑦ 前端 D 层占位:分子育种/品种保护/AI 增强
_coming_soon保持占位,属 P2 远景预期。
7.7 组合得失漏斗 v_combination_funnel(v2.8,2026-08-04)
缺陷背景(逐条复审第 8 条,最贴业务):数据本已齐全——bre_pollination.flower_count/effective_count(花→果)、bre_seed_lot.seed_count/germination_rate(种→苗)、bre_seedling.seedling_count(出苗)——但无任何按 bre_cross_combination 汇总的派生指标:结实率/出苗率/选择强度未滚到组合层,配合力第一手证据(组合得失链路)字段在但没合成进配合力上下文。核实属实:全库无 结实率/出苗率/选择强度/funnel 实现;唯一"选择强度链"是 seed_lot.used_count 机械累加(账本非派生指标);run_combining 只取 func.avg(value_numeric) 组合均值、combining.solve 只认 combo/parent1/parent2/value。用户拍板:补视图/派生表即可,数据已齐、风险极低。
六级链路与派生指标:
| 环节 | 数据源(均按 combination_id 聚合) | 派生 |
|---|---|---|
| 花→果 | bre_pollination Σflower_count / Σeffective_count |
结实率 fruit_set_rate = Σeff/Σflower×100 |
| 果→种 | bre_seed_lot Σseed_count / AVG germination_rate |
出苗基数 |
| 种→苗 | bre_seedling Σseedling_count / Σstrong_seedling_count |
出苗率 emergence_rate = Σseedling/Σseed×100 |
| 苗→定植 | bre_planting Σtree_count |
定植数 |
| 定植→树 | bre_tree 非软删 COUNT |
树数(评价群体基数) |
| 树→入选 | bre_selection_result 非软删 COUNT |
选择强度 selection_rate = 入选数/树数×100 |
缺环节的组合比率列留 NULL(bre_cross_combination 主表 LEFT JOIN 六源,按组合一行)。
实现:
backend/sql/weld_combination_funnel.sql:v_combination_funnel普通 VIEW(DROP IF EXISTS + CREATE OR REPLACE 幂等,F2 决策保 fresh 不用 MV),psql 应用(create_all 只建 ORM 表,视图须手写 SQL)。statistics/service.py::combination_funnel():查视图返回{rows, n}(Numeric→int/float 归一),视图未就绪 CustomException 提示。statistics/controller.py:GET /statistics/combination-funnel(module_bre:statistics:query权限)。
验证(Temp/claude/e2e_combination_funnel_20260804.py,3 组全过):
| 组 | 断言 |
|---|---|
| [1] | 全六级组合:150 花/50 果→结实率 33.33%、100 种(发芽率均值90%)/80 苗→出苗率 80%、55 定植/3 树/2 入选→选择强度 66.67%,逐计数精确断言 |
| [2] | 仅授粉组合:fruit_set=50.0% 算得出,种/苗/定植/树/入选 全 NULL(LEFT JOIN 正确性) |
| [3] | 跨会话持久化:commit 后新会话读同值 |
工程教训:首跑清理阶段 FK 崩——helper 里
db.add()后未 flush 就取.id拿到 None,删除WHERE id IN (None,…)不命中留下孤儿行。修复:add 后先await db.flush()再取 id。此为探针自身 bug,非视图/端点缺陷。
八、分子育种「建数据能力」(2026-08-04)
分子层四表 DDL 早已在
backend/sql/bre_tables.sql(§3.7),但 module_bre 无 ORM/服务 → DNA 指纹/QTL/GWAS/GS 全 inert。用户拍板先建「数据能力」:四模块 CRUD + Excel 导入导出 + VCF 导入 + 指纹防错(无性系混杂检测)。GS/GWAS/GBLUP 引擎仍占位。菜单 900210-900213 由占位页切真实页面,900214 GWAS 保持_coming_soon。
8.1 DDL 缺口与补列
bre_genotype_sample 原 DDL 无样本名字段(只有 dataset_id/source_type/source_id/sample_type/sample_date/method/lab/remark)。VCF 表头映射、UI 展示、指纹报告都靠样本名 → 按 weld 惯例补列(create_all 只建新表、不改既有表):
ALTER TABLE bre_genotype_sample ADD COLUMN IF NOT EXISTS sample_name varchar(128);
COMMENT ON COLUMN bre_genotype_sample.sample_name IS '样本名称(VCF 表头/UI 展示,可空)';
CREATE INDEX IF NOT EXISTS ix_bre_genotype_sample_dataset_name ON bre_genotype_sample (dataset_id, sample_name);
8.2 四模块五件套
| 模块 | 表 | 关键列 / 约束 | 导入必填 |
|---|---|---|---|
| marker | bre_marker | marker_name UNIQUE;chromosome/position/marker_type/panel/assembly_version | marker_name |
| genotype_dataset | bre_genotyping_dataset | dataset_name/platform/panel/purpose/run_date/lab | dataset_name |
| genotype_sample | bre_genotype_sample | sample_name(weld 补);dataset_id FK→dataset | sample_name(dataset 名解析成 ID) |
| genotype_call | bre_genotype_call | sample_id/marker_id 双 FK + UNIQUE(sample_id,marker_id);allele 按 VCF/GP 编码 | sample_name/marker_name(解析成 ID)/allele |
- 五件套:model/schema/crud/service/controller,
module_bre/__init__.py注册。ORM 严格对齐 bre_tables.sql——分子表无status列,模型覆盖__table_args__(Index("ix_bre_<表>_created_deleted", "created_time", "is_deleted"))跳基类默认 status 索引。 - FK 存在性:sample/call create/update 前
assert_parents_exist(父级软删也拦截→409「XX不存在或已被删除」)。 - 名称透出:get_list/detail 后查 ref_map 填 dataset_name / sample_name / marker_name(seed_lot combination_name 同款
_attach_fk_labels)。 - Excel 导入导出:header_dict 中文头→列,名称解析成 ID;导入模板/导出 mapping_dict 含 created_by 名解析。
8.3 VCF 导入(POST /bre/genotype_call/import/vcf)
- 跳过
##行,定位#CHROM表头 → FORMAT 后为样本列,GT 在 FORMAT 子字段索引。 - marker:ID 非
.用 ID、否则CHROM:POS,按 UNIQUE 查重 → 缺失建号(marker_type=snp、panel=dataset.panel)。 - 样本:按
(dataset_id, sample_name)查重 → 缺失建号(sample_type=vcf、method=genotyping,source 留空)。 - GT:
|→/规范化;././././跳过;allele 存 GT 编码(0/0、0/1、1/1)。 - 内存 dict 以
(sample_id, marker_id)去重(文件内重复 last-wins);已存在分型跳过 → 重跑幂等;500/批批量 insert。 - 返回
{dataset_id, dataset_name, variants, samples, samples_created, markers_created, calls_inserted, skipped_missing}。
8.4 DNA 指纹防错(GET /bre/genotype_call/fingerprint/check)
纯数据层比对,无外部依赖:
- 取 dataset 内样本 + 分型结果,构建
{sample_id: {marker_id: allele}},allele 规范化。 - 两两比对:共同 marker
< min_markers跳过(信息量不足);否则identity = 匹配数/共同数。 - 判定:同源对(source_type+source_id 相同且非空)
identity < threshold→「同源指纹不一致(疑似样品污染/取错)」;异源对identity ≥ threshold→「异源指纹一致(疑似无性系混杂/标签互换)」。 - 返回按 identity 降序的 pair 行(样本名含来源、共同数、匹配数、identity、标记)。
8.5 菜单 / 权限 / 前端
bre_menu.sql:900210-900213 component_path 由_coming_soon/index切module_bre/{marker,genotype_dataset,genotype_sample,genotype_call}/index;F 段按钮id=900700+seq*10+border(八按钮:查看/查询/新增/编辑/删除/导出/导入/下载模板),ON CONFLICT (id) DO NOTHING幂等;SUPER_ADMIN/ADMIN 角色关联 64 行。- 前端:4 api .ts + 4 index.vue。genotype_sample 搜索/表单带 dataset 下拉;genotype_call 带 sample/marker 双下拉 +「导入 VCF」(dataset 下拉+文件上传,报计数)与「指纹检测」(dataset 下拉+min_markers+阈值,结果表两色标签:danger=同源不一致、warning=异源一致)两个自定义按钮/对话框。
8.6 e2e 验证(e2e_molecular_20260804.py)
| 组 | 断言 |
|---|---|
| [1] | 四模块 CRUD 闭环:dataset→marker→sample→call create/detail/update/list/options,FK 名称透出(sample.dataset_name、call.sample_name/marker_name) |
| [2] | 唯一键/父级:重复 (sample,marker)→409「已存在」;sample 引用不存在 dataset→409;重复 marker_name→409 |
| [1b] | 删除闭环:call→sample→marker→dataset 软删后 detail 不可见 |
| [3] | 指纹:6 样本 3 标记——同源对 1 处不一致→命中「同源指纹不一致」(identity 2/3);异源对全一致→2 对「异源指纹一致」(identity 1.0);同源全一致对不误报;共同 marker 不足(S-Y 仅 1 标记)对不出现 |
| [3b] | 空数据集指纹 samples=0/flagged=0 |
| [4] | VCF:6 variant × 3 样本——markers_created=5/samples_created=3/calls_inserted=13/skipped_missing=2;文件内重复标记 last-wins((P01,V100)=1/1);自动建号元数据(V500 chrom=2/pos=500/type=snp/panel=dataset.panel);重跑幂等(samples/markers/calls 均 0 新增) |
清理按 FK 逆序物理删(call→sample→marker→dataset,前缀 E2EM-),重跑幂等。
九、精修项落地:DUS 数据能力 + stage 感知 + k-fold CV + 公平性报告(2026-08-04)
9.1 缺陷背景(用户核实四条缺口,全部拍板落地)
用户核对后确认四条精修缺口属实并拍板「全部落地,更新文档,保留版本」:
- DUS/品种保护:无 DUS 模块、无 UPOV TG/53 描述符观测模板(菜单 900230 预留仍占位);档位=数据能力(三表)。
- stage 感知:
bre_trait.stage(v2.0 定义)存在但 BLUP/选择指数/决策无视,童期/成株性状混用无警示。 - 模型外部验证:可靠性仅 PEV 法(内部);档位=ABLUP + GXEBLUP 双支持 k-fold CV(外部预测准确度)。
- AI 伦理·分组偏差:G×E 引擎已覆盖互作,缺按 site 的系统性 EBV 偏差/公平性报告。
9.2 DUS 数据能力(三表)
| 表 | 业务列 | 约束 |
|---|---|---|
bre_dus_descriptor |
descriptor_no(UPOV TG/53 特性号)、trait_id→bre_trait(可空=自由描述符)、trait_code 快照、descriptor_name、expression_type(QN/PQ/QL)、method、example_varieties(标准品种)、test_stage、required | uq_descriptor_no |
bre_dus_test |
test_name、germplasm_id→bre_germplasm、trial_study_id→bre_trial_study、tester、test_date、status(planning/testing/completed/report)、conclusion(pending/distinct/not_distinct)、report_path | uq_test_name |
bre_dus_observation |
dus_test_id→bre_dus_test、dus_descriptor_id→bre_dus_descriptor、value_numeric、value_text、expression_note | uq(test,descriptor) |
- 表新建走 create_all(不在既有 DDL,无需 weld);五件套
module_bre/dus/注册/bre/dus_test/*(descriptor 9 端点含导入导出+模板,test 9,observation 6)。 - 种子
sql/bre_dus_seed.sql:UPOV TG/53 桃描述符 15 条,trait_code → bre_trait LEFT JOIN解析 trait_id(8 条关联),ON CONFLICT(descriptor_no) DO NOTHING幂等。 - 菜单
sql/bre_menu_refine.sql:900230 component 切真实页module_bre/dus/index;G 段按钮 900800-900808(permmodule_bre:dus_test:*,八按钮含导入/下载模板)+ SUPER_ADMIN/ADMIN 角色关联。 - FK 名称透出:trait_name / germplasm_name / trial_study_name / descriptor_no+descriptor_name;描述符导入按中文头「关联性状编码」→trait_id。
9.3 stage 感知
_trait_meta_map读入trait.stage(缺省 evaluation);PredictionModel.stage落库(sql/weld_refine.sql补列)+ 预测批次表展示(童期 warning / 成株 primary 标签)。selection_index加stage入参:传 juvenile/evaluation 只纳入该阶段性状(异阶段写入skipped_stage,同阶段无性状→409 带剔除清单);不传且横跨两阶段 →stage_warning(童期/成株性状清单 + 「证据来自不同发育阶段,需人工复核」)。decision_preview同理:传 stage 时异阶段规则条件跳过(matched=None、reasons 不出现);不传且规则引用性状横跨两阶段 →stage_warning。
9.4 k-fold CV(外部验证)
- 求解器
scripts/breeding_stats/blup.py::kfold_cv:sire 家系分层留出(同家系不进训练/测试双折避免乐观,无父本个体自成一系)、固定种子;每折训练子集重估方差组分 → 留出个体 EBV 由系谱预测(个体保留在 A 矩阵、仅掩蔽表型)→ pearson+RMSE;单折失败(train<2 / G×E 结构不可辨识)记 None+warning 不中断。 - 落库
bre_cv_result(method=KFCV/ABLUP|KFCV/GXE、k/n_total/n_individuals/mean/pooled pearson/RMSE/cv_accuracy/h2)+bre_cv_fold明细;MLOps 溯源 data_version/input_hash/engine_version 复用。 - 端点:
POST /bre/statistics/cv/run(trait_id/code/year/fixed/covariate/gxe/gxe_env/k 2~10,ABLUP 与 GXEBLUP 同入口)、GET /bre/statistics/cv(批次)、GET /bre/statistics/cv/{id}(含折明细)。
9.5 公平性报告(只读,不建表)
GET /bre/statistics/fairness?prediction_id=&group_by=site&threshold_sd=1.0:
site_summary:每 site n_trees/n_groups/n_individuals/EBV 分布(mean/sd/min/max)/mean_reliability/deviation=site_mean−grand_mean、flagged=|deviation|>threshold_sd×grand_sd。rank_consistency:site 内组合均值 EBV 排名 vs 全体组合排名,共享组合 ≥2 时手写 Spearman。gxe_pattern:组合×site 单元均值(单元 n≥2),暴露跨 site 排名翻转。
9.6 验证(e2e_refine_20260804.py 全过 + vue-tsc)
| 组 | 断言 |
|---|---|
| [1] | DUS:三表 CRUD + 种子命中(15 条、TG/53/5=果形、≥1 条关联 trait_id)+ FK/唯一键/子表阻断删除/软删全 409 路径 |
| [2] | stage:selection_index 无 stage→警示含两性状;juvenile→traits 只含童期 + skipped_stage=[成株];decision_preview juvenile→成株规则条件跳过(matched=None)、童期规则命中部分株;ABLUP 批次 stage 落库(juvenile/evaluation 各对) |
| [3] | CV:ABLUP k=3 折 pearson 全非 None(sire 家系留出→留出株 EBV 收缩到均值、pearson=0 为设计预期)+ GXE k=2 跨 site 跑通 + 幂等重跑新批次 + data_version=“v2.7”/engine/input_hash + job SUCCESS |
| [4] | fairness:2 site 9 株 site_summary 2 行(deviation 异号、flagged 布尔)+ rank_consistency 2 行(shared≥2、spearman 非 None)+ gxe_pattern n≥2 单元 |
清理按 FK 逆序物理删(前缀 E2ER-),TG/53 种子描述符与既有数据不动。
十一、六项能力完善:MT-BLUP + GBLUP/ssGBLUP + DUS 特异性检验 + AMMI/FW 稳定性 + MLOps 重训回滚 + BLUP stage 拆分(2026-08-04)
11.1 缺陷背景(用户两轮复核核实六条缺口、逐项拍板「全部落地」)
- MT-BLUP:Smith-Hazel 的 G 非对角仍用 Calo 校正 EBV 相关近似(
service.py已诚实文档化为回退),缺真遗传相关估计 → 拍板成对双性状 BLUP(非全多变量 REML)。 - GBLUP/ssGBLUP:分子层只有数据能力(四模块 CRUD + VCF + 指纹),无 VanRaden G / 基因组选择引擎 → item 明确两者都做。
- DUS 特异性统计检验:
conclusion纯人工(无判定端点)→ 拍板参照=同 trial_study 自动 + 可显式指定。 - AMMI/Finlay-Wilkinson 稳定性:G×E 随机效应已估 σ²gxe,无跨环境稳定性排名。
- MLOps 自动重训 + 版本回滚:APScheduler 在但统计无重训接线、无 is_active → 拍板漂移检测端点 + 手动触发,不注册 cron。
- BLUP stage 拆分:run_ablup 只打标签(model_name 后缀)不按 stage 取数。
11.2 MT-BLUP(scripts/breeding_stats/mtblup.py + statistics/service.py)
mtblup.solve_bivariate(pedigree, phenos, code1, code2)(ENGINE_VERSION=1.0.0):共享系谱复用blup._order_pedigree/_build_ainv建 A/A⁻¹;模型 y=[y1;y2] 堆叠、X/Z 块对角;Var(u)=G0⊗A(G0=Va1,ρ√(Va1Va2)],[·,Va2)、Var(e)=diag(Ve1,Ve2)⊗I。降维:Va1/Ve1、Va2/Ve2 取自各性状单性状 REML(=既有 herit 来源),仅对 ρ∈[−0.99,0.99] 1-D golden-max 最大化精确 REML ll(复用_golden_max+_solve_gxe的 V=Z(G0⊗A)Z'+R、slogdet+yPy 模板)。返回 r_g/σa 矩阵/n_common/n_iter/converged/warning;单性状观测 <2 → 该性状 NAN。run_genetic_corr(trait_ids, year):_gather_shared_phenosunion 树集 + 树级均值 + 共享系谱;两两 bivariate,对角=单性状 h²·P_ii、非对角=r_g·√(G_ii·G_jj) 组装 G0,Higham 特征值截断投影半正定;落bre_genetic_corr_result(trait_codes/matrix/sigma_a/heritability/pairs_json/n_common + data_version/input_hash/engine_version)+StatisticsJobModel(job_type="GENCORR");list_genetic_corr/genetic_corr_detail。_smith_hazel_index加g_method="calo"|"mtblup"(selection_index透传):mtblup 时逐对solve_bivariate填 G 非对角,单对不收敛回退 Calo + warning 清单(不阻断指数);≥3 性状 r_g 三角不等式违反 → 特征值截断投影半正定;extra["g_source"]="mtblup|calo"落库可审计。- 端点:
POST /statistics/genetic-corr/run(trait_ids 多选 + year)、GET /statistics/genetic-corr、GET /statistics/genetic-corr/{cid}。
11.3 GBLUP / ssGBLUP(scripts/breeding_stats/genomic.py + statistics/service.py)
build_g_matrix(genotypes, markers, *, maf_min, method=2, blend=0.02):dosage 0/1/2 样本×标记,缺格按列均值 2p 填充;MAF 过滤(maf>=maf_min,全滤 → ValueError);VanRaden method1 G=ZZ'/2Σp(1-p)(diag≈1)/ method2 G=ZDZ'(D=1/[2p(1-p)]);blend 岭G=(1−ω)G+ω·mean(diag)·I保证可逆。solve_gblup(pedigree, phenos, G, *, tol):仅基因型个体入模型,MME 用 G⁻¹ 替代 A⁻¹;σ²a 用_golden_maxprofile(仿blup.solve);返回 ebv/reliability(=1−PEV/σ²a)/h2/σa/σe/converged/warning。solve_ssgblup(pedigree, phenos, G, genotyped, *, tol):H⁻¹ = A⁻¹ + 0,0],[0, G⁻¹ − A22⁻¹(Aguilar et al. 2010);A22=A[genotyped,genotyped] 稠密子阵np.linalg.inv(病态加_RIDGE=1e-6);V 块必须用 H 协方差——按 Aguilar 块公式构造完整 H(D=G−A22:H=A+A12A22⁻¹DA22⁻¹A21, A12A22⁻¹D],[D·A22⁻¹A21, D;非基因型块 += L·D·L'、交叉块 += L·D、基因型块 = G),REML 似然 V=ZH[z,z]Z'+R,H⁻¹ 仅进 MME 系数矩阵。修复前 V 块误用Hinv[z,z]致似然失构。基因型+非基因型个体都出 EBV。run_gblup(dataset_id, trait_id, trait_code, year=None, method="gblup"|"ssgblup", maf_min=0.05):取数bre_genotype_calljoinbre_markerpivot sample×marker 剂量("0/0"→0/"0/1"→1/"1/1"→2,多等位跳过);样本→个体映射 source_type='tree' 直连 + sample_name↔tree.tree_no/germplasm.cultivar_name 名称兜底,未映射→跳过 + note warning 清单;genotyped = sorted(dosage)对齐build_g_matrix内部sorted(genotypes)行序(修复前用全部映射树,零有效调用树会错位 G 索引静默污染 EBV);input_hash 覆盖(基因型矩阵哈希 + phenos + ped);落 PredictionModel(method=GBLUP/ssGBLUP,engine_version 落库)+ PredictionValueModel(每树 EBV/rel/pa/rank)+ job_type="GBLUP";list_genotyping_datasets(genotyping_dataset 列表 + n_samples)。- 端点:
POST /statistics/gblup/run、GET /statistics/gblup/datasets;批次/EBV 复用list_predictions(按 method 过滤)+ebv_ranking。
11.4 DUS 特异性统计检验(dus/service.py + fdist.py)
fdist.f_icdf(p, d1, d2):F-CDF 二分反解;t_crit(alpha, df)=√f_icdf(alpha, 1, df)(t²=F(1,df))。dus.distinctness(candidate_rows, reference_rows, descriptor_meta, alpha=0.01):- QN:候选 vs 参照单因素 ANOVA → MSE,df →
LSD = t_crit(α,df)·√(MSE·(1/n_cand+1/n_ref));|cand_mean − ref_mean| > LSD→ 该描述符 distinct(逐参照比较,任一超 LSD 即 distinct)。 - PQ/QL:表达状态众数——候选众数 ∉ 参照众数集 → distinct。
- 汇总逐描述符 {descriptor_no, name, expression_type, candidate_value, ref_values, statistic, critical, distinct};总体建议=≥1 个 required 描述符 distinct → distinct,否则 not_distinct,数据不足→pending(不判)。
- QN:候选 vs 参照单因素 ANOVA → MSE,df →
test_distinctness(test_id, reference_test_ids=None, alpha=0.01):默认参照=同trial_study_id其他非软删 test(候选自身分组:同 germplasm_id 的测试合并为重复),可显式覆盖;取候选+参照观测+描述符 → 判定 → 落analysis_json(逐描述符表+建议+参照集+alpha+运行时间);conclusion当前 pending 时自动填建议(人工可改)。distinctness_report(test_id)读已存分析;DusTestOutSchema 加 analysis_json。- 端点:
POST /bre/dus_test/distinctness/{test_id}、GET /bre/dus_test/distinctness/{test_id}。
11.5 AMMI / Finlay-Wilkinson 稳定性(scripts/breeding_stats/stability.py + statistics/service.py)
finlay_wilkinson(table):每基因型对环境指数(该环境全基因型均值np.nanmean(Y, axis=0))回归 y_gj=b·I_j+a(lstsq)→ b/截距/R²/se_b/dev_ms;flag_stable = |b−1| ≤ 2·se_b,且完美拟合(dev_ms≤1e-12·max(1,ptp(y)²))时 se_b 无信息量 → b≈1(|b−1|≤1e-6)才判稳(修复前浮点 b 永不精确=1 且 se_b=0 → 误判不稳)。ammi(table, n_components=2):μ+g+e 两因素分解 → 残差 SVD(np.linalg.svd,首引)→ λ1/λ2、每基因型 IPC1/IPC2 得分、ASV=√((IPC1·SS_ipc2/SS_ipc1)²+IPC2²)(Purchase 2000,IPC1 按 SS 比例缩放)、Wricke ecovalence=Σ(y_ij−y_i.−y_.j+y..)²、ipc_variance(各 IPC 解释比例);rows 按 ASV 升序 + rank。run_stability(trait_id, trait_code, gxe_env="site"|"year", year=None, methods=("ammi","finlay")):两向表 genotype=clone(缺则 combination,再退 tree)× env=site(trial_study_id)/year(evaluate_year),每格多株均值(仿trait_values取数);有效格子 <2×2 → 409;落bre_stability_result(detail_json + data_version/input_hash/engine_version)+ job_type="STABILITY";list_stability/stability_detail。- 端点:
POST /statistics/stability/run、GET /statistics/stability、GET /statistics/stability/{sid}。
11.6 MLOps 自动重训 + 版本回滚(statistics/service.py + sql/weld_advanced.sql)
- weld:
bre_prediction.is_active boolean default false。run_ablup/GXE/GBLUP 落库:同 trait 无 active 批次 → 本批 active=true,否则 false(版本链语义)。 _gather_digest_inputs(trait_id, year):轻量抽取——仅组装进_input_digest的 phenos+pedigree(复用 run_ablup 的取数 SQL,不含 fixed/cov/门禁),供 drift 重算当前哈希(规避全量抽取风险)。GET /statistics/model/drift?prediction_id=:从该批次 job params_json 取 (trait_id,year,gxe,gxe_env) →_gather_digest_inputs重算 → {prediction_id, changed, current_hash, stored_hash, data_version}。POST /statistics/model/retrain?prediction_id=:漂移才重训——run_ablup(同 params) 建新批次并await model_activate(new_id)转移 active(修复前新批次默认 inactive——旧批次仍 active,重训后新批次卡在非生效态,破坏版本链语义)→ {retrained, old_id, new_id, new_hash};无漂移 → {retrained:false, reason}。POST /statistics/model/activate/{id}:trait 内标 active(回滚原语);list_predictions/PredictionOut 加 is_active。
11.7 BLUP stage 拆分(statistics/service.py + sql/weld_advanced.sql)
- weld:
bre_trait_observation.stage varchar(16)(观测级发育阶段,缺省继承 trait.stage)。TraitObservationModel + schema(create/update/out)+ 前端观测表单 stage 下拉(juvenile/evaluation)。 run_ablup(stage=None)+ RunStatsIn.stage:stage 给定 → 取数where(coalesce(obs.stage, trait.stage) == stage);过滤时 model_name 加_{stage}后缀 + PredictionModel.stage=生效 stage;未给定但数据 obs.stage 与 trait.stage 出现分歧 → note 警示("有 N 条观测标注了观测级 stage,但本次未按阶段拆分…",不阻断);GXE 分支同步应用;非法 stage → 409。
11.8 前端
statistics.ts:runGeneticCorr/listGeneticCorr/geneticCorrDetail + runStability/listStability/stabilityDetail + runGblup/getGblupDatasets + modelDrift/modelRetrain/modelActivate + 类型。statistics/index.vue:新「遗传相关 MT-BLUP」(性状多选→相关矩阵表格)、「稳定性 AMMI/FW」(性状+env+methods→FW b/R²/flag 表 + AMMI IPC/ASV/rank 表)、「基因组选择 GBLUP」(dataset+性状+method radio+maf→批次/EBV 表)三 tab;ABLUP 运行对话框加 stage 三态(全部/童期/成株);Smith-Hazel 对话框加 g 矩阵来源 radio(Calo/MT-BLUP);预测批次表加「当前版本」标签 + 漂移检测/自动重训/设为当前版本按钮。dus/index.vue:DUS 测试行加「特异性判定」按钮→对话框(alpha + 参照默认同点 + 逐描述符结果表 + 建议)→「应用判定」写 conclusion。vue-tsc --noEmit通过(EXIT=0)。
11.9 验证(Temp/claude/e2e_advanced_*.py 6 组全过)
- stability:3 组合×3 站点 FW b=2.0/1.0/−0.0、flag=F/T/F(C1 稳定)、r²=1/C2 None(常量响应 R² 无定义)、AMMI 9 格 IPC1≥IPC2 rank 升序、year 维度、非法 methods 409、list/detail。
- stage:juvenile/evaluation 各只含对应观测树 + model_name
_{stage}、不传含全部 4 株 + note 警示、非法 stage 409。 - mtblup:r_g=0.99(y2=2·y1 强正相关)对称、σa12>0、h²∈(0,1)、n_common=4、Smith-Hazel g_method=mtblup
g_source落库;顺带修_smith_hazel_index未定义变量tid真 bug。 - gblup:GBLUP 5 EBV 非基因型株=0 + ssGBLUP 非零 + solve_ssgblup(V 块用 H、g 亲本 EBV 有限、G method1 diag_mean≈1)+ 样本 4 直连+1 名称兜底+1 全多等位(回归 genotyped 对齐修复)+1 未映射 warning + list_genotyping_datasets n_samples=6。
- dus:自动参照同点 5 测试、D1 LSD=1.239 df=3 t_crit=5.8409 distinct、D2 PQ distinct、D3 非必测 not distinct、analysis_json+conclusion 自动建议、显式参照覆盖、无重复 pending+warning。
- mlops:首批 active → 改观测 drift changed → retrain 新批次 active 旧 inactive → 无新漂移幂等 {retrained:false} → activate 旧批次回滚(直接断言
model_retrain修复)。 - 后端重启 + openapi 确认 6 组新端点 + 2 新表(bre_genetic_corr_result / bre_stability_result)create_all;
weld_advanced.sqlpsql-w幂等。
11.10 本轮修的三处引擎级 bug(e2e 探针暴露)
- ssGBLUP V 块(genomic.py):REML 似然 V=ZH[z,z]Z'+R 必须用 H 协方差,
Hinv[z,z]是把逆矩阵喂给协方差位置 → 似然失构、h² 失真。H 按 Aguilar 块公式构造。 - genotyped 与 G 行序错位(service.py):
genotyped必须sorted(dosage)对齐build_g_matrix内部sorted(genotypes);用全部映射树时,零有效调用树(全多等位)会静默错位 G 索引污染 EBV。 _smith_hazel_index未定义tid(service.py):mtblup 分支取系谱树集的集合推导式引用未定义变量 → 首次走 g_method=mtblup 即 NameError。改{tid for tid, d in pheno_all.items() if any(c in d for c in cols)}。model_retrain不激活新批次(service.py):重训后补await model_activate(new_id),否则新批次默认 inactive 卡在旧批次下,版本链断裂。flag_stable完美拟合误判(stability.py):残差≈0 → se_b=0 →|b−1|≤2·se_b恒假(浮点 b≠1 精确)。改 dev_ms 阈值判定:完美拟合 →|b−1|≤1e-6判稳。
11.11 收尾修复:统计二级菜单深链(前端,用户反馈"4 个二级菜单页面都一样")
统计分析下 4 个二级菜单(统计计算/育种值/选择指数与决策/图形分析)的 component_path 均指向 module_bre/statistics/index,而该页是单页多 tab(activeTab 默认 batches)且不读路由 → 点谁都落在"模型批次"页。修复:statistics/index.vue 增 useRoute() + ROUTE_TAB_MAP,activeTab 初始值按路由取。关键坑:数据库 sys_menu.route_path 实为相对路径(statistics/prediction_value/selection_decision/statistics_chart),经父级 /breeding 拼接后实际 URL 是 /breeding/statistics/...,与 seed SQL 写的 /bre/... 绝对路径不一致——故必须按 route.name 匹配(StatisticsCalc→batches、PredictionValue→ebv、SelectionDecision→index、StatisticsChart→correlation),而非 route.path(首次按 path 匹配 /bre/... 全部落空,用户刷新仍默认页)。四个菜单路由 name 各异,RouterView 缓存键 name+params 不同 → 每次点击组件重挂载,深链可靠。图形分析无专属 tab,暂归"相关性"。pnpm type-check EXIT=0,vite(base=/web,端口 5666)HMR 生效。
十二、田间试验精度补强·砧木×接穗随机互作 G×R(2026-08-04)
12.1 缺陷背景(用户核实两条精度缺口,拍板先做 G×R)
用户核实田间试验设计精度两条缺口:① 无 R 侧空间协方差(行-列 AR1×AR1,当前 np.eye(m)*Ve 纯对角)——该项需先补 tree.row_no/col_no 数据与设计图,留待后续;② 无 scion×rootstock(G×R)随机互作——rootstock 当前仅作固定哑变量(v2.0 ⑤ 砧木建模铁律「BLUP 固定效应扣除」),无第三个随机效应槽。用户拍板先做 G×R 随机互作(探索到跑通真实数据档位成本可控)。
12.2 架构决策
- 结构同构、求解器零改动:G×E 分支
_solve_gxe(blup.py)的 Z₂ 已按(基因型,因子水平)分组配I·σ²交互,因子无关(pair-grouping 机制),G×R 只是把分组键换成(基因型, 砧木水平),MME/REML/输出键全部复用。 - Z₂ 单槽位 → G×E/G×R 必须互斥:
if gxe and gxr显式 409(文案「共用同一随机效应槽(Z₂)」),前端再加双向互斥 watcher 兜底。 - 克隆坍缩系谱共享:
gxe_pedigree(clone 树坍缩为c{clone}节点,父母本=组合/种质亲本)构建块从if gxe:内上移为 G×E/G×R 共享(纯构建、ABLUP 路径不执行)。 - rootstock 移出固定效应:
gxr=True时强制fixed_effects剥离rootstock,p_est 不再计入砧木水平,防与 Z₂ 共线。
12.3 求解器(backend/scripts/breeding_stats/blup.py)
_solve_gxe 加两个可选参数(默认值保现有 G×E 行为逐字节不变):
factor_label="G×E"——未收敛警告「{factor_label} 似然面可能极平/边界最优」;factor_name="环境"——方差归零警告「{factor_label} 方差分量收敛到 0(数据不支持基因型×{factor_name}互作)」。- 公开
solve()加参并透传_solve_gxe(服务端走的是solve(),首次探针即暴露漏传)。 ENGINE_VERSION"1.1.0"→"1.2.0"。
12.4 服务端(statistics/schema.py + controller.py + service.py)
RunStatsIn+run_ablup加gxr: bool;controller 透传。- 互斥门禁(job 创建前):
gxe and gxr→ 409。 - job_type=
"GXR" if gxr else ("GXE" if gxe else "ABLUP");params_json 落gxr。 elif gxr:分支镜像 G×E site 分支:- 遍历
phenotypes.items()(int tid),rid = f"t{tid}"(字符串键)查rootstock_map[rid](rs{rootstock}),缺砧木 →skipped++跳过并 note 警示;无任何可分砧木记录 → 409。 rec_gxr[rid] = (grp, rs):grp 优先c{clone_of[tid]}(克隆坍缩)、退f{combo_of[tid]};rec_map[rid]同理。- 门禁三件套镜像:
n_cross_rootstock=同基因型跨砧木数==0、max cell_counts<2、residual_df = m - q - p_est<1(p_est 含 intercept + trial_study 水平-1(若固定)+ covariate,rootstock 不计入)→「G×R 不可辨识」409。 rec_fixed(仅 trial_study,经fixed_map)+rec_cov(cov_map);rootstock 从fixed_effects剥离。- 求解:
blup.solve(gxe_pedigree, rec_phenos, gxe=rec_gxr, record_map=rec_map, fixed=..., covariate=..., factor_label="G×R", factor_name="砧木")。 method="GXRBLUP";model_nameGXRBLUP_{trait}+_{stage}?+_{ts}。- note:
stage/sigma_a/sigma_gxr(=sigma_gxe)/sigma_e/gxr_ratio(=gxe_ratio)/n_cross_rootstock(=n_cross_env)/n_genotypes/warning/skipped/stage_note。 - EBV 写入共用段 accuracy 个体集按 gxr 选
gxr_tree_ids。
- 遍历
_DATA_VERSION"v2.9"→"v2.10"。
12.5 前端(statistics.ts + statistics/index.vue)
RunStatsPayload.gxr。- G×E tab
gxeEnabled后加<el-checkbox v-model="gxrEnabled">启用砧木×接穗互作(G×R)随机效应</el-checkbox>;双向互斥 watcher;运行按钮文案「运行 MET / GxE / GxR」、辅助文案三分支。 - 批次表互作方差列 v-if 扩为
GXEBLUP || GXRBLUP;fmtGxeNote按n.sigma_gxr != null分支(σ²gxr/σ²gxe、gxr_ratio/gxe_ratio、跨砧木/跨环境基因型)。 runGxepayload 加gxr: gxrEnabled.value;vue-tsc通过(EXIT=0)。
12.6 验证(Temp/claude/e2e_gxr_20260804.py,4 组全过)
- 正例:2 基因型(clone)× 2 砧木 × 2 株 = 8 株,强交叉互作观测(clone1×R1 高/R2 低、clone2 相反)→ GXRBLUP、job_type=GXR、σ²gxr=74.8>0、n_cross_rootstock=2、n_genotypes=2、8 EBV 行。
- 门禁负例:同基因型仅跨 1 砧木 → CustomException「G×R 不可辨识」。
- 互斥负例:
gxe=True, gxr=True→ CustomException「Z₂」。 - rootstock 剥离:
gxr=True同时fixed_effects=["rootstock"]→ 剥离后不共线、正常出 σ²gxr。
- 后端重启(含孤儿 reloader worker 清理)后 openapi 确认
gxr: True入参;vue-tscEXIT=0。
十三、基因组选择(GS)实证严谨性·GBLUP/ssGBLUP 专用 k-fold 交叉验证(2026-08-04)
13.1 缺陷背景(用户核实两条 GS 实证缺口,拍板先做 k-fold)
用户核实 GS 实证严谨性两条缺口:
① GS 缺自身交叉验证——run_cv/kfold_cv(blup.py)是 A 矩阵系谱预测(ABLUP/GXE),GBLUP 落库的 accuracy=√mean(reliability) 是理论准确度(PEV 推导),对模型误设不敏感:G 算错/标记编码错/遗传力先验偏时 PEV 可靠性依然漂亮,真实预测能力却崩了,只有掩蔽留出「GEBV vs 表型 pearson」能测出实证预测能力。
② SSR panel 难构 VanRaden G——_dosage_from_gt 只吃 0/1 两段整数且 max≤1;SSR 片段编码(168/174)、多等位(0/1/2)、phasing(0|1)全部被丢弃 → SSR calls 静默变缺失 → m_after_maf→0 时 build_g_matrix 直接 ValueError「MAF≥0.05 的标记为 0」→ 409。这是"有引擎但数据接不进"的现实坑。
用户拍板先做 GS k-fold(①);SSR dummy 编码(②)留待后续。
13.2 架构决策
- 核心洞察——掩蔽留出已原生支持:
_profile_solve(genomic.py)已实现「仅观测子集进模型、全部个体出 EBV」——非观测个体 Z 行全 0、经 G⁻¹/H⁻¹ 的 cross-relationship 预测(e2e_advanced_gblup 已验证非基因型株 tree4 出非零 EBV)。所以 GS CV 掩蔽留出 = 传训练子集 phenos → 全个体 GEBV → 取留出个体与观测表型相关。G/H/Hinv 只建一次,逐折只换 z_train 子阵(折划分不改变关系矩阵)。 - 折划分差异(与 ABLUP 的本质区别):ABLUP 的
kfold_cv按 sire 家系分层留出(同一家系不跨训练/测试,防同家系信息泄漏)。GS 的候选是 genotyped∩phenos 的同世代样本、无系谱家系树,用固定种子随机分层(round-robin 到 k 折)即标准做法——文档明示该差异,将来要防近亲泄漏可加「按 G 关系分层」。 - 方法互通:
method="gblup"→ 关系矩阵 G(individuals=genotyped);method="ssgblup"→_build_h合并关系阵 H(individuals=order,含非基因型亲属)。两者共用一个输出 dict 形状(与 blup.kfold_cv 逐键对齐)。
13.3 求解器(backend/scripts/breeding_stats/genomic.py)
- 抽取
_build_h(pedigree, genotyped, G, *, ridge, extra_base):solve_ssgblup 的 base/non_base→_order_pedigree→A/Ainv→Hinv→H 构建提成 helper,返回(order, idx, H, Hinv)。solve_ssgblup 改调(行为不变)。- 缺失基因型个体按 base 补入系谱(原
if missing_gen: raise ValueError改for g in missing_gen: base.append(g))——无表型基因型树不再触发 ValueError,CV/ssGBLUP 更稳(与 phenos 兜底一致)。
- 缺失基因型个体按 base 补入系谱(原
- 新增
kfold_cv_genomic(phenos, G, genotyped, *, k=5, seed=20260804, method="gblup", pedigree=None, ridge):method="gblup":individuals = sorted(genotyped)(G 行序);relmat_inv = np.linalg.inv(G)(奇异回退 pinv);zmat_full = G。method="ssgblup":_build_h(pedigree, genotyped, G, extra_base=list(phenos))→ individuals = order;relmat_inv = Hinv;zmat_full = H。cand = sorted(genotyped ∩ phenos);n_total = len(cand);<2→ 空 folds + warning(对齐 blup.kfold_cv)。- 折划分:
rng = random.Random(seed),shuffle cand →bin_of = {c: i % k}。 - 逐折:
test_set = {c: b == fold};train_phenos = phenos − test_set;z_train = 观测个体索引;_profile_solve(zmat_full[ix_(z,z)], X, y, relmat_inv, n, z_train)→ 全 EBV → 留出个体 GEBV vs 表型blup._pearson+ RMSE;单折失败(训练<2/测试空/求解异常/未收敛/测试有效<2)→ error 记 warning 不中断。 - 输出 dict 与 blup.kfold_cv 逐键对齐(
k/n_total/n_individuals/folds/mean_pearson/mean_rmse/pooled_pearson/pooled_rmse/cv_accuracy/h2/warning)。
ENGINE_VERSION"1.0.0"→"1.1.0"。
13.4 服务端(statistics/schema.py + controller.py + service.py)
_gather_gblup_inputs(dataset_id, maf_min)提取:run_gblup 的 dataset→samples→call_rows→markers→sample→tree 映射→dosage→build_g_matrix→genotyped 装配(约 60 行)提成 helper,返回(dosage, marker_order, genotyped, G, g_meta, unmapped)。run_gblup 改调(行为逐字节不变),GS CV 复用。e2e_advanced_gblup.py 复跑兜底回归。run_cv签名扩展:加dataset_id: int | None = None, method: str | None = None, maf_min: float = 0.05;params_json 落三键。- GS 分支(公共表型/系谱装配后、
elif gxe:前,与 G×E/ABLUP 互斥——双开时 GS 优先):_gather_gblup_inputs(dataset_id, maf_min)→gs_phenos = {f"t{tid}": v}(键对齐 run_gblup "t{tid}" 约定)→kfold_cv_genomic(gs_phenos, G, genotyped, k=k, method=method, pedigree=pedigree)。- method 名
"KFCV/GBLUP"/"KFCV/ssGBLUP"(method varchar(16) 放得下)。 - input_hash = sha256(
_input_digest(pedigree, gs_phenos)+\n+ geno_str),geno_str 镜像 run_gblup(f"{s}|{mk}|{dosage[s].get(mk, '.')}"全排序)。 - engine_version 按分支:GS 用
genomic.ENGINE_VERSION,ABLUP/GXE 用blup.ENGINE_VERSION(cv_engine_version/method_name先默认后覆盖)。
- schema
CvRunIn+ controller run_cv 透传dataset_id/method/maf_min。 _DATA_VERSION"v2.10"→"v2.11"。
13.5 前端(statistics.ts + statistics/index.vue)
CvRunPayload加dataset_id?/method?/maf_min?。- CV tab 加 mode radio(ABLUP / GS):GS 模式显示基因型数据集下拉(复用已加载
gbDatasets)+ method radio(GBLUP/ssGBLUP)+ MAF≥ 输入;隐藏 G×E 控件;辅助文案分支「掩蔽留出 GEBV vs 表型 pearson(实证预测能力,固定种子随机分层)」。 submitCv按 mode 组装 payload(GS 传 dataset_id/method/maf_min);vue-tscEXIT=0。
13.6 验证(Temp/claude/e2e_gblup_cv_20260804.py,3 组全过 + 回归)
构造:5 家系 × 3 全同胞 = 15 株(每系独立组合+亲本种质),10 标记(MK0/MK1 为 QTL 效应 2.0,家系 QTL 剂量 [(2,2),(2,1),(1,2),(1,0),(0,0)]→遗传值 8/6/6/2/0,非 QTL 标记 (f*3+j)%3 家系特征化),表型 = 12 + 2·dose(MK0) + 2·dose(MK1) + 低噪(±0.3),家系内基因型一致 → 留出预测靠 G/H 同家系交叉关系,强信号。
- GBLUP 正例:
run_cv(trait, dataset_id, method="gblup", k=5)→ job SUCCESS;CvResultModel.method=="KFCV/GBLUP"、cv_accuracy=0.794 > 0.3、==mean_pearson、n_total/n_individuals=15/15、input_hash 64hex、engine_version=1.1.0、5 折 n_train/n_test≥1、CvFoldModel5 行。 - ssGBLUP 正例:
method="ssgblup"→"KFCV/ssGBLUP"、cv_accuracy=0.794 > 0.3(H 合并系谱+标记,家系内同基因型仍强预测)。 - 门禁负例:dataset 仅 1 个无映射样本(sample_name=NO_MATCH)→
CustomException「基因型样本均无法映射到单株」,FAILED job 落库。 - 回归:
e2e_advanced_gblup.py复跑全过(_gather_gblup_inputs提取后 run_gblup 行为不变:h²/5 条 EBV/非基因型株 EBV=0、note 未映射警示)。
- 后端重启(含孤儿 reloader worker 清理)后 openapi 确认
CvRunIn出现dataset_id/method/maf_min;vue-tscEXIT=0。
十四、现代桃育种领域覆盖·S-等位基因交配兼容性 + 抗病/需冷量性状字典(2026-08-04)
14.1 背景(用户核实四方向覆盖,拍板按建议次序做)
| 方向 | 核实结论 | 处置 |
|---|---|---|
| ① S-等位基因(自交不亲和)交配兼容性 | 完全未建模:bre_pollen/bre_pollination 无 S-allele 字段、bre_cross_combination 无兼容性校验、"配了不结"硬需求空白 |
落地(本批) |
| ② 需冷量/需热量 | 环境侧已建(bre_germplasm.chilling_requirement 属性 + bre_environment_condition.chilling_hours/GDD),选种性状侧 bre_trait 缺失(66 行字典无一条) |
落地(本批) |
| ③ 抗病性状(细菌性穿孔病/褐腐病/白粉病) | bre_germplasm.disease_resistance 仅自由文本,bre_trait 一条都没有 |
落地(本批) |
| ④ MAS/QTL/GWAS 闭环 | 900214 仍 _coming_soon,发现层(GWAS/QTL 定位→MAS)完全缺失 |
留待单独立项 |
关键事实:统计引擎 _trait_meta_map 仅消费 data_type='numeric' 的性状(EBV/选择指数/决策候选),故抗病/需冷量必须建 numeric 而非 categorical 分级;桃属配子体自交不亲和(S-RNase),Sf 等位为自交亲和型(SI 功能缺失),多数商业化品种携带。
14.2 ②③ 性状字典种子(backend/sql/bre_disease_chilling_traits.sql)
幂等 ON CONFLICT (trait_code) DO UPDATE,新增 5 条 numeric trait,全部 into_ebv='1'(选种目标)+ direction='asc'(低值优):
| trait_code | 名称 | category | unit | 说明 |
|---|---|---|---|---|
disease_shot_hole |
细菌性穿孔病 | 抗病性 | 级 | 0-5 级病情指数(0=免疫…5=高感),valid_min=0/valid_max=5,h²=0.3 |
disease_brown_rot |
褐腐病 | 抗病性 | 级 | 同上 |
disease_powdery_mildew |
白粉病 | 抗病性 | 级 | 同上 |
chilling_requirement |
需冷量 | 生态适应性 | h | 打破休眠 0~7.2℃ 低温累计小时(0-3000),h²=0.5 |
heat_requirement |
需热量 | 生态适应性 | GDD | 发芽前 >7.2℃ 有效积温(0-10000),h²=0.4 |
stage='evaluation' + method 测定说明;前端 trait 页 category 自由文本自动显示、0 改动。
14.3 ① S-等位基因建模(germplasm + cross_combination)
bre_germplasm.s_alleles(String(32),如S1/S3;Sf=自交亲和型):model + schema(Create/Update/Out)+ALTER TABLE+COMMENT。- 兼容校验(
cross_combination/service.py):_parse_s_alleles(raw):分隔符/ , ;→ 归一化小写等位集合;空白返回 None。_s_compat_check(female_s, male_s):任一亲本含sf→full 放行(Sf 不排斥);否则共享 2 个→none、1 个→half、0 个→full;缺 S 数据→unknown跳过。_check_s_compat(female_id, male_id):读亲本 s_alleles →none抛CustomException409「S-等位基因完全不相容(共享 …),该组合无法坐果」("配了不结"硬门禁);half返回警示文案。create/update在亲本存在性断言后调用;CrossCombinationOutSchema.s_compat(可选派生字段)落半兼容警示;同亲本自交共享 2 等位自然被 409 拦截(除非含 Sf)。
14.4 前端
- germplasm 表单加 S-等位基因 输入(type input,placeholder「如 S1/S3;Sf=自交亲和型」)+ 导出列;
germplasm.tsGermplasmForm/GermplasmTable加s_alleles?。 - cross_combination 组合提交包装 createApi/updateApi:响应含
s_compat则msg.warning展示(统一消息入口);409 由统一错误处理自动提示。
14.5 验证(Temp/claude/e2e_s_allele_20260804.py,6 组全过)
- 纯函数 8 例:S1/S3×S1/S3→none、×S2/S4→full、×S1/S2→half、S1/Sf×S1/S1→full、大小写/混合分隔→none、缺数据→unknown、
_parse_s_alleles归一化断言。 - service 层 create:共享 S1/S3→409「不相容」;共享 S1→
s_compat半兼容文案;0 共享→无警示;Sf 放行;缺 S 跳过。 - ②③ 落库核验:bre_trait 5 条 numeric+asc+into_ebv=1 已落库。
- openapi 核验:
BreedingGermplasm{Create/Update/Out}.s_alleles+CrossCombinationOut.s_compat。 vue-tscEXIT=0;后端重启后核验。
十五、GWAS/QTL/MAS 标记辅助选择闭环(2026-08-04)
v2.13 §十四 标记「④ GWAS/QTL/MAS 闭环留待后续单独立项」——本轮单独立项落地,补齐发现层:GWAS/QTL 定位 → 显著标记 → MAS 面板,900214 占位页翻真实页。桃在成熟期/果重等位点已有已知 QTL,MAS 让童期幼苗在无表型/无 EBV 时也能被标记辅助选择。
15.1 求解器 backend/scripts/breeding_stats/gwas.py(ENGINE_VERSION=1.0.0,纯 numpy 零 scipy)
- 模型:逐标记单标记回归
y ~ μ + PC1..PCn_pc + marker;加性效应=标记回归系数。 - 群体结构:标记剂量矩阵(缺失按列均值填)中心化 →
np.linalg.svd前 n_pc 个主成分得分(pc_scores = U[:,:n_pc]·s[:n_pc])作协变量。 - p 值:
t = coef/SE,p = fdist.f_pvalue(t², 1, df)(df = n − n_pc − 2)——复用 DUS LSD 已验证的正则不完全 beta,零 scipy 新依赖。 - 多重检验:
threshold_bonf = sig_level/m_after_maf;BH-FDR q(numpy argsort 自底向上保单调)。 - QTL 定位:sig_bonf 标记按 chromosome 排序,相邻间距 < qtl_window 合并簇,簇内最小 p 为峰标记(单显著标记也落 QTL 兜底)。
- 共线兜底(本轮关键修复):非 QTL 标记与 PC 共线时 XtX 奇异,
np.linalg.inv返回病态(负对角元 →sqrt域错)。改微小岭回归reg=1e-8·max(diag(XtX))兜底——共线方向 SE 大而有限 → t 小 → p≈1(效应被 PC 吸收,正确非显著);与群轴正交的 QTL 标记不受影响(1e-8 相对岭可忽略)。 - MLM 预留:method 参数(gwas/ssgwas),本轮仅实现 gwas。
15.2 数据装配与 5 张新表
_gather_gwas_inputs(dataset_id, maf_min)(service.py 新 helper,仿_gather_gblup_inputs但 marker 查询补 chromosome/position)→(dosage, marker_order, markers_meta, genotyped, unmapped)。独立 helper,run_gblup/run_cv 零回归。bre_gwas_result(批次:n_individuals/n_markers/m_after_maf/maf_min/n_pc/sig_level/threshold_bonf/n_sig_bonf/n_sig_fdr/n_qtl/data_version/input_hash/engine_version/remark)bre_gwas_snp(逐标记:marker_id/marker_name/chromosome/position/maf/effect/se/t_value/p_value/neg_log10p/q_value/sig_bonf/sig_fdr,FK CASCADE)bre_qtl(trait_id/chromosome/start_bp/end_bp/peak_marker_id/peak_marker_name/peak_p/n_markers/effect/source=known|gwas/gwas_result_id)bre_mas_panel+bre_mas_panel_marker(favorable_dose/direction=high|low/effect,UNIQUE(panel,marker))- ORM 于
statistics/model.py(ModelMixin 全套),create_all建表 +backend/sql/weld_gwas.sql幂等CREATE TABLE IF NOT EXISTS双保险。
15.3 服务端端点与 MAS 决策 hook
POST /bre/statistics/gwas/run(GwasRunIn: dataset_id/trait_id/trait_code/year/method/maf_min/n_pc/sig_level/qtl_window)→ job_type=GWAS,_gather_gwas_inputs+asyncio.to_thread(gwas.run_gwas)+ input_hash(系谱+表型+基因型确定性序列化)+ engine_version;成功落 bre_gwas_result + bre_gwas_snp 批量 + bre_qtl(source=gwas)。GET /bre/statistics/gwas/list+GET /bre/statistics/gwas/{id}(result + snps + qtls)。bre_qtlCRUD(已知 QTL 录入 source=known)+bre_mas_panelCRUD +POST /bre/statistics/mas-panel/{id}/markers(全量替换)。- decision_preview MAS hook:条件循环
("pheno","ebv")→("pheno","ebv","marker");_mas_hit_map按候选树批量查 call →_dosage_from_gt→ 有利剂量命中计数(direction=high: dose≥favorable_dose / low: ≤),conds["marker"]={panel_id:{min_hits}}—— 童期幼苗无表型/无 EBV 也能被标记辅助选中。 _DATA_VERSIONv2.12;端点权限复用module_bre:statistics:*(900071 已授 ADMIN,900214 翻转无需新增按钮)。
15.4 前端(gwas.ts + gwas/index.vue,900214 翻转)
- GWAS 结果 tab:批次表 + Manhattan 图(裸
echarts.init:x=染色体累加位置、逐染色体分组着色、显著点红色、Bonf 阈值 markLine、dataZoom)+ QQ 图(期望 −log10((i+.5)/m) vs 观测)+ SNP 表 + QTL 区间表。 - QTL 定位 tab:已知 QTL 录入 CRUD(trait/chromosome/区间/peak/effect/remark)。
- MAS 面板 tab:面板 CRUD + 标记选择对话框(marker/favorable_dose/direction/effect)。
- 运行对话框参数:dataset_id/trait_id/year/maf_min=0.05/n_pc=3/sig_level=0.05/qtl_window=1000000。
sys_menu 900214→component_path='module_bre/gwas/index'(bre_menu.sql§6d);vue-tscEXIT=0。
15.5 验证(Temp/claude/e2e_gwas_20260804.py,7 段全过 + 回归)
- run_gwas:job GWAS/SUCCESS;bre_gwas_result n=32/m=200→200/bonf=2/fdr=2/qtl=2/input_hash 64 位/engine_version=1.0.0/threshold_bonf=sig/m_after_maf。
- bre_gwas_snp:全字段(chromosome/position/neg_log10p/q_value);MK0/MK1 均 Bonf 显著且为所在染色体(chr1/chr3)最小 p(MK0 p=2.3e-05、MK1 p=5.4e-05)。
- QTL 定位:2 区间峰标记=MK0/MK1,source=gwas 落库且挂批次。
- 已知 QTL CRUD:create/update/list(source=known)全过。
- MAS:面板 2 标记(favorable_dose=2/high)→ decision_preview marker 条件(min_hits=1)命中 16 株 + 无表型童期幼苗 1 株,低剂量株不命中。
- 门禁:dataset 无映射样本 → CustomException「无法映射」。
- 清理:finally FK 逆序自动清理。
- 回归:
e2e_advanced_gblup.py+e2e_gblup_cv_20260804.py复跑零回归(GBLUP/ssGBLUP CV accuracy 0.794);openapi 核验 10 条 gwas/qtl/mas-panel 路径。
15.6 数据设计要点(避免 PC 吞噬 QTL 的实证教训)
- 标记数太少(如 20)且非 QTL 标记全为群轴共线时,标记矩阵秩塌缩,SVD 前 n_pc 个 PC 本身跨越因果标记 → 效应被 PC 吸收、SE 膨胀、无显著标记(实测 MK0 p=0.77)。
- 正确设计:2 群体结构(各 16 株)+ 200 标记,非 QTL 标记携带「群轴 + 组内独立伪随机变异」(PC1=群轴、PC2/3 与 QTL 标记低相关),QTL 标记剂量在群体内多重集一致(与群轴正交)→ PC 校正后效应保留、双 QTL Bonf 显著。
- 功效:n=32、m=200、QTL 效应 2.0 时 p
1e-5(Bonf 阈值 2.5e-4 余量 10×);n=24 则功效不足(p2.5e-4 擦线)。
十六、九缺口补齐:经典侧计算端点 + 分子侧严谨性 + 求解器核心(2026-08-04)
用户自 GWAS/QTL/MAS 闭环后重扫 12 项缺口,A1(S-等位)与 A4(G×R)已同日落地剔除,余 9 项拍板「全部补齐」,分三批独立 e2e + 回归。三批均 e2e 通过、回归零回归,后端重启 + openapi 核验 + HTTP smoke + 前端 vue-tsc EXIT=0。
16.1 批1 经典侧计算端点(纯计算不建表,statistics/controller.py + service.py + 前端 statistics/index.vue)
| 缺口 | 落地 |
|---|---|
| A5 数据质量 | POST /statistics/data-quality——data_quality_report(trait_id, site_id?, tree_ids?):tree 级观测装配(同 run_ablup)+ 缺失率 + CV + IQR 与 MAD 稳健 z-score 双法异常标记,输出 {trait, n_trees, missing_rate, cv, outliers, summary};前端「数据质量」对话框 |
| A3 遗传增益 | POST /statistics/genetic-gain——ΔG=k·r_g·σ_A:k 由 top_p 经 Acklam 有理近似 Φ⁻¹(纯 numpy 零 scipy)、r_g=批次 PA(√mean reliability)、σ_A=√h²·σ_P,逐轮 {round, current_mean, ΔG_units, ΔG_pct_mean, next_mean, cumulative} |
| A6 主动选配 | POST /statistics/mating-recommend——S-等位硬过滤(复用 cross_combination._s_compat_check:none 剔除/half flag)+ 亲缘 A 惩罚 score=w_ebv·mid_parent_EBV−w_kin·max(0,r−threshold),{pairs:[{female, male, ebv_mean, r, s_compat, score, flags}]};计算端点不落库(用户拍板) |
16.2 批2 分子侧严谨性(gwas.py / genomic.py / VCF 装配 / MAS 语义)
| 缺口 | 落地 |
|---|---|
| B1 EMMAX | gwas._emmax:零模型 y=Xβ+u+e(u~N(0,σ²g·K)),方差分量复用 genomic._profile_solve;eigh 对角化 K=QΛQ' → V⁻¹=Q(σ²Λ+σ²eI)⁻¹Q';逐标记 GLS t²→fdist.f_pvalue;run_gwas 后处理抽共享函数,GLM 逐字节不变;method="emmax"(gwas 1.1.0) |
| B2 SSR 多等位 | VCF 按 ALT 数定 marker_type;_allelic_from_gt 每等位 0/1/2;3 处装配按 marker_type 分支 SSR 展开每等位一列;build_g_matrix 多等位 VanRaden 推广(genomic 1.2.0) |
| B3 QTL×E | POST /statistics/gwas-qtl-x-e:分环境 run_gwas 合并 QTL → stable(≥2 环境同号)/ env-specific / 异号 G×QTL 警示,计算端点不建表 |
| B4 MAS 语义 | weld_mas_semantics.sql 幂等 ADD COLUMN:mode/favorable_allele/haplotype_group;_mas_hit_map additive/dominance/recessive/allele/haplotype 五语义 |
16.3 批3 求解器核心(blup.py,ENGINE_VERSION 1.3.0)
- A2 AR1×AR1 空间协方差
solve_spatial:e~N(0,σ²e·R)、R=AR1(ρ)⊗AR1(ρ)、R⁻¹ 纯 numpy eigh、REML 对 (h²,ρ) 坐标上升黄金搜索;run_ablup(spatial=True)→ method=AR1×AR1/model_name=SPATIAL_*,ρ/σ²a/σ²e/h² 落 note;与 G×E/G×R 互斥、缺 row/col 坐标 409;spatial=False逐字节不变。 - A7 稀疏 A⁻¹+共轭梯度:
_build_ainv_sparse(COO)+_cg_solve(max_iter=800/tol=1e-9);use_sparse = n_with_parents>0 and n>N_SPARSE(1000)阈值分派 →"solver":"sparse-cg"+cg_iter;Hutchinson k=100(固定种子 20260804)估 PEV 对角 →"reliability_approx":True;收敛失败回退稠密;稠密路径(n≤1000)逐字节不变。
16.4 版本与验证
_DATA_VERSIONv2.13;ENGINE_VERSION:blup 1.3.0 / genomic 1.2.0 / gwas 1.1.0。- 批1
Temp/claude/e2e_data_mating_gain_20260804.py:data-quality 命中离群株 / ΔG 自洽 / mating-recommend 剔除不相容对 + 亲缘惩罚生效 / 无观测 409 门禁。 - 批2
Temp/claude/e2e_molrigor_20260804.py五段:EMMAX 复现双 QTL + SSR 混合 GBLUP 全标记进入 + QTL×E stable/env-specific + dominance/haplotype 语义命中 + 门禁。 - 批3
Temp/claude/e2e_spatial_sparse_20260804.py三段:AR1×AR1 ρ=0.9796/h²=0.0013/method 标签 + 稀疏路径 EBV 3.49e-12 / h² 0.00 / CG 7 折 / Hutchinson mean-rel Δ0.054(n=20 最坏,文档标注近似)+ 默认稠密路径引擎级 0 差(落库 4.92e-05 为 numeric(12,4)/numeric(6,4) Postgres 量化,非回归)。 - 回归:e2e_gwas(7 段)/e2e_advanced_gblup/e2e_gblup_cv/e2e_gxr/e2e_refine/e2e_corr_spatial 全绿;openapi 核验 4 新端点 + RunStatsIn.spatial/gxe/gxr + GwasRunIn/GwasQtlXEIn.method=emmax + MasPanelMarkerIn 三字段;HTTP smoke(data-quality trait 28、genetic-gain top_p=0.2 得 k=1.3998、409 门禁);vue-tsc EXIT=0。
十七、十二项真缺口补齐:引擎三件 + 模块四件 + 底座五件(2026-08-05)
用户「全部补齐」后做全量现状盘点(2 个 Explore 代理 + 关键文件精读),发现总表大量「待建」标记过时——35 个 module_bre 后端模块 CRUD 全部齐全、数据字典四类已灌、描述统计/ANOVA 引擎已落地。真实缺口收敛为 12 件,用户拍板范围=只补这 12 件;移动端(V1.2)/品种登记 PVP(V3.0)/AI 三件套(V4.0)留波次不建。分三批独立 e2e + 回归,每批验收。三批均 e2e 通过、全量回归零回归,后端重启 + openapi 核验(631 路径)+ vue-tsc EXIT=0。完整台账见规格 §8.24–8.26。
17.1 批1 引擎三件(solver 扩展,独立新路径)
- ssGWAS(
scripts/breeding_stats/gwas.py,ENGINE_VERSION 1.2.0):run_gwasmethod="ssgwas"分支 →_ssgwas——genomic.build_g_matrix(blend 岭保正定)构 G →genomic.solve_gblup全样本 GEBV û;Wang et al. 单步 GWAS MEM 对角近似:ê_j=(M_j'Z'G⁻¹û)/(2Σp_j(1−p_j))、Var(ê_j)=σ²u/(2Σp_j(1−p_j)),Waldt=ê/SE、df=n−2 →fdist.f_pvalue;共享_finalize/_bh_qvalues/_cluster(GLM/EMMAX 逐字节不变);门禁无基因型样本报错、G⁻¹ 岭兜底;服务端 method 透传 + 前端 gwas 运行对话框下拉加 ssgwas。 - 全 MT-BLUP 多变量 REML(
scripts/breeding_stats/mtblup.py,ENGINE_VERSION 1.1.0):solve_multi——m 性状 y 堆叠、X/Z 块对角、Var(u)=G0⊗A、Var(e)=diag(ve_i·I);EM-REML 迭代(单性状 REML 初始、G0 非对角 0 → 迭代更新 G0/ve、特征值截断 + Higham 投影保正定、max_iter 兜底不收敛→converged=False+warning);输出 G0 全元素 + r_g 矩阵 + n_iter/converged/warning;run_genetic_corr加full_mtblup=True一次 m 性状给完整 G0(逐对 bivariate 路径保活)。 - AR1×AR1 双参 ρ(
scripts/breeding_stats/blup.py,ENGINE_VERSION 1.4.0):solve_spatial(aniso=False)——R_ij=ρ_row^|Δrow|·ρ_col^|Δcol|、内层_f_rho拆 ρ_row/ρ_col 交替坐标上升;run_ablup(spatial=True, spatial_aniso=True)→ method=AR1×AR1(aniso)、note 落 rho_row/rho_col;aniso=False 输出与 v1 逐字节一致(回归断言);门禁/互斥/缺坐标逻辑不变。
17.2 批2 模块四件(标准 CRUD 五件套 + 前端 + 菜单翻转)
- field_operation 农事操作 900051:
bre_field_operation(tree_id/plot_id/op_type/op_date/op_detail/operator_id);op_type 字典(施肥/喷药/修剪/灌溉/疏果/套袋/采收)bre_dict 灌入。 - observation 通用观测 900050:
bre_observationEAV 通用录入(可挂 plot 级、不强制 trait);obs_type numeric/text/date。 - breeding_report 育种报告 900075:
bre_reportCRUD +POST /report/generate(按 report_type 聚合 bre_prediction/bre_stability_result/bre_cv_result 成结构化报告 + doc_path);前端列表 + 生成对话框。 - analysis_dataset 分析数据集 900070:新表
bre_analysis_dataset(trait_codes/sample_ids/config jsonb + status,create_all + 幂等 weld 兜底);CRUD +「查看性状值」跳 statistics trait-values 复用既有视图。 - 菜单翻转 + 文案清理:幂等 UPDATE component_path→
module_bre/<name>/index、E 段按钮 900xxx;900014/900015/900021/900061/900063/900065 菜单 description 残留「待建」→ UPDATE 去除。
17.3 批3 底座五件
- 审计切面:
bre_audit_log(16 列已建零实现)→module_bre/audit/;base_crud.py三写方法事务内 flush 后追加 CREATE 记录级 / UPDATE 字段级 diff(每变更字段一行)/ DELETE 记录级;settings.AUDIT_BRE_ENABLED+ 模型__bre_audit__opt-in;批量导入会话标志抑制逐行、仅汇总 IMPORT 一条;GET /bre/audit/list|detail。 - 统一编号服务:
app/utils/number_gen.pyNumberGenService(前缀/日期/序列/回绕规则)+pg_advisory_xact_lock原子取号 +bre_sequence表;迁移 4 处(cross_combination YY+3位 / tree 组合-序号 / selection_result clone_code 扩位 / seedling batch_no YP-…),行为格式保持。 - 超期预警定时任务:每日 job 按
selection_rule扫描——树 N 年未决策(selection_result 无记录且定植超 N 年)/ pollen 批次过期(采集日+有效期)/ seed_lot 超期 → 写bre_alert(alert_type/entity_type/entity_id/message/status/created_id)+GET /bre/alert/list+ 前端「预警中心」页。 - 备份容灾:
backend/scripts/pg_backup.sh(pg_dump 自定义格式到Temp/backup/按日期 + N 天轮转)+pg_restore.sh;系统 job 每日 02:00(ap_scheduler 3 系统 job:operation 清理 Sun 03:00 / alert 扫描 08:37 / 备份 02:17)。 - BrAPI + MIAPPE:
module_bre/brapi/controller.py(app 根注册 prefix/brapi/v2,只读不建表):germplasm/observationvariables/studies/observations/miappe 五端点,BrAPI 2.xmetadata{pagination,status,datafiles}+result{data}包裹、0 基分页;bre_germplasm → germplasmDbId/germplasmName/PUI/accessionNumber/commonCropName=Peach/genus=Prunus/species=persica/subtaxa;bre_trait → observationVariableDbId/trait/method/scale(scale.dataType 映射 + validValues);observations 合并 bre_trait_observation + bre_observation(tree→germplasm join)。
17.4 版本与验证
_DATA_VERSIONv2.14;ENGINE_VERSION:gwas 1.2.0(ssGWAS)/ mtblup 1.1.0(solve_multi)/ blup 1.4.0(aniso)/ genomic 1.2.0。- 批1
Temp/claude/e2e_gaps_engines_20260804.py3 组 PASS:ssgwas 复现已知 QTL(与 EMMAX 同数据集显著标记一致)+ solve_multi 3 性状 G0 半正定、r_g 与逐对 bivariate 同号量级 + aniso 双参 ρ 合理、aniso=False 与 v1 逐字节一致。 - 批2
Temp/claude/e2e_gaps_modules_20260805.py15 组断言 PASS:四模块 CRUD + report generate 聚合 + 菜单翻转 + 文案清理。 - 批3
Temp/claude/e2e_gaps_base_20260804.py19 ok / 0 fail:审计三操作(CREATE 记录级 / UPDATE 字段级 diff / DELETE 记录级)+ 导入抑制仅汇总 + 8-session 并发取号 seq 1-8 唯一 + 三类预警命中(树超期/花粉过期/种子超期)、无负例误报、幂等去重、resolve→不再重复 + 备份脚本执行成功 + pg_restore --list 含 bre_alert/bre_sequence/bre_audit_log/bre_analysis_dataset + BrAPI 分页数学/germplasm/variable/study/observation 映射。 - 回归:e2e_spatial_sparse(3 段)/e2e_gwas(7 段)/e2e_molrigor(5 段)/e2e_advanced_gblup(4 段)/e2e_gblup_cv(3 段)/e2e_refine(8 段)/e2e_gxr(4 段)/e2e_corr_spatial(3 段)全复跑零回归;其间修复 1 处回归——
statistics.service._allelic_columns的 B2 SSR 兜底对 SNP 标记误把多等位调用(如 "1/2")当有效剂量 → 树 4 被误判基因型、破坏「非基因型株 GBLUP EBV=0」语义;修复:仅marker_type为空时走 SSR 每等位展开,SNP 标记 "1/2" 视为缺失(显式 SSR 分支不受影响,e2e_molrigor 全绿兜底)。 - openapi:重启后端后核验 631 路径(5 brapi +
/bre/breeding_report/report/generate+/bre/audit/list|detail|options+/bre/alert/list|detail|options|resolve全在);HTTP smoke(germplasm 37 / variables 71 / studies 3 / observations 107 / miappe 3 模板);前端 vue-tsc --noEmit EXIT=0。
十八、桃育种业务流全面完善:业务数据链 + 统计算法 + 前端体验(2026-08-05)
用户要求「对现有功能,结合桃育种实际业务流程与需求,进行全面测试分析,并完善」。三路审计(双代理并行 + 数据层性状字典探测 + 独立 grep/read 验证)收敛真实缺口 10 项(业务数据链 1-6 / 统计算法 7 / 前端 8-10),拍板全部实施 + 两裁决:导入按钮维持隐藏(23+ 页显式隐藏,导入弹窗/处理器/后端端点完整保留)、采收入口走农事操作(op_type=harvest 结构化产量表单 + 同步统计引擎,非独立模块)。批A 业务数据链(A1-A6)/ 批B 统计算法(B1-B4)/ 批C 前端(C1-C4),分三批独立 e2e + 全量回归零回归,后端重启 + openapi 核验 + vue-tsc EXIT=0。完整台账见规格 §8.27。
18.1 批A 业务数据链(A1-A6)
- A1 果实采收结构化入口(
field_operation/{model,service,schema}.py):bre_field_operation加yield_kg/fruit_count/avg_fruit_weight/marketable_rate4 可空列(backend/sql/weld_busflow.sqlADD COLUMN IF NOT EXISTS幂等,create_all 不建已有表新列);service create/update 当op_type=="harvest"且 tree_id 非空且有产量数据 → 按 trait_code(single_tree_yield/fruit_number/avg_fruit_weight/marketable_rate)查 trait_id 同步写bre_trait_observation(evaluate_year=op_date.year、trial_study_id 由 plot 继承),trait_code 缺失跳过不 409;plot 级采收只留 field_operation,不进树级统计。 - A2 性状种子(
backend/sql/bre_yield_phenology_traits.sql,ON CONFLICT(trait_code) DO UPDATE幂等):产量构成 5(单株产量/果数/均果重/好果率/裂果率 low)+ 物候 3 date 型(盛花期/果实成熟期/落叶期)+ 品质 3(可溶性固形物/可滴定酸 low/固酸比)+ 生长量 3(主干周长/树高/冠幅)+ 描述性 categorical 5(果形/茸毛/离核/果皮底色/着色类型,into_ebv=0)。 - A3 种质级观测:
bre_observation加可空germplasm_id(FK→bre_germplasm,weld ALTER + index);observation serviceassert_parents_exist扩展种质校验;前端表单种质选择器 + 搜索栏 germplasm 过滤。 - A4 授粉→收种→种子处理补链:
bre_seed_lot.pollination_id(FK→bre_pollination)+bre_seed_treatment.seed_lot_id(FK→bre_seed_lot,weld ALTER);前端 seed_lot 授粉选择器(按 combination 过滤)、seed_treatment 种子批次选择器。 - A5 EAV 观测校验(observation + trait_observation create/update):obs_type=numeric→parse float、obs_type=date→parse 日期,否则 409;trait 有 valid_min/valid_max 且 numeric → 越界 409;重复校验 同 (tree_id|plot_id|germplasm_id, trait_id, obs_year, obs_date) 已存在 → 409(精确到日,同日不同 trait / 不同日多次观测放行)。
- A6 阶段自动设置 + 成株门禁:tree.service create 当 stage 为空 → 按 breeding_generation 推断(F 代杂种→
juvenile、亲本/嫁接成株→evaluation);trait_observation create 门禁 trait.stage=evaluation 而 tree.stage=juvenile → 409「童期树不可录成株性状」;juvenile 性状录童期树仍允许;不影响 decision_preview 的 marker 辅助选入(非观测路径)。
18.2 批B 统计算法(B1-B4)
- B1 type-B 多环境遗传力(
statistics/service.py):_values_by_tree_env(按 trait_id + trial_study_id/evaluate_year 分环境聚合树→值)+run_type_b_heredity复用mtblup.solve_bivariate把环境当"性状"(phenos={"E1":{tree:v},"E2":{tree:v}} 同一系谱)精确 REML 估 r_g;method="calo"备选(分环境 EBV 相关/√rel);env_dim="site"|"year";共有树 <2 → 409;落bre_type_b_result(statistics/model.py新表,镜像 GENCORR)+ controllerPOST /statistics/type-b-heredity+GET /type-b+GET /type-b/{id};前端 type-B tab。 - B2 correlation genetic 模式:
correlation_matrix加mode="pheno"|"genetic"、g_method、year;pheno 分支逐字节不动;genetic 走新私有_genetic_corr_matrix逐对mtblup.solve_bivariate组装 G0(对角 1、非对角钳[-1,1]),不落库(对齐 data_quality 计算端点模式);schema CorrelationIn 加 mode/g_method/year。 - B3 selection_index 自动权重:
auto_weights: bool=False→ True 时权重=_trait_meta_map.default_h2(实测 h² 优先,兜底 0.1)、强制 use_h2=False(防双重相乘)、direction 由_weighted_z_indexasc 翻转处理;weights_json 记"__auto":true;into_ebv=0 剔除进 dropped。 - B4 UPGMA 聚类:
run_cluster(trait_ids/entity_type(tree|clone)/mode(pheno|genetic)/distance(1-|r| 或 euclidean 标准化)/k)输入矩阵复用_genetic_corr_matrix/correlation_matrix;UPGMA 纯 numpy(距离矩阵迭代合并,无 scipy);输出{clusters, merges, order};controllerPOST /statistics/cluster(不落库);前端 cluster 树状图 tab。
18.3 批C 前端(C1-C4,按用户裁决:不恢复导入按钮)
- C1 观测录入增强:observation 页搜索栏加 plot/trial_study(站点)/germplasm 过滤(ObservationQueryParam 加 tree_id/plot_id/germplasm_id/trial_study_id)+ germplasm 表单(A3);field_operation 页 op_type=harvest 动态显示产量结构化表单 + 表格 4 列。
- C2 统计可视化 ECharts:
echarts.ts注册 HeatmapChart + VisualMapComponent;statistics/index.vuecorrelation 热图(mode 切换)+ gblup 可靠性热图/EBV 趋势折线(per-batch 聚合)+ type-B tab(热图+明细)+ cluster 树状图;图表生命周期(activeTab→resize、window resize、onBeforeUnmount dispose)。 - C3 combination-funnel 前端入口:statistics 工具栏「组合得失漏斗」按钮 + 1080px 对话框调
GET /statistics/combination-funnel(后端已有、前端此前缺失)。 - C4 stage_phenotype 容器同步:
_shared/StageView.vuecompMap 注册 Observation/FieldOperation,stage_phenotype/index.vuetabs 通用观测/农事操作翻真实页。
18.4 版本与验证
_DATA_VERSIONv2.15(service.py:94);引擎版本不变(mtblup/blup/gwas/genomic 本轮未改)。- 批A
Temp/claude/e2e_busflow_20260805.py11 组断言 PASS(A1 采收同步 4 行观测/plot 级不写 + A2 性状种子齐全 + A3 种质观测回查 + A4 授粉→收种→处理全链路 + A5 非法/越界/重复 409 + A6 F1 自动 juvenile、童期录成株 409)。 - 批B
Temp/claude/e2e_statsflow_20260805.py15 组断言 PASS(type-B 矩阵对角 1/对称/r_g 范围/site·year 环境集不同/n_common 共有树/GET 回查 + correlation pheno 逐字节回归/genetic 对称对角 1/calo 回退 + index auto==手工 default_h2 权重/asc 翻转/into_ebv=0 剔除 + cluster 3 已知类还原/k 边界/clone 聚合)。 - 批C HTTP smoke
Temp/claude/smoke_busflow_c_20260805.py10 检查全过(observation 3 过滤对真实数据 n=1 全命中 + funnel n=21 + correlation pheno/genetic + type-b list + cluster POST + auto_weights);vue-tsc --noEmit EXIT=0。 - 回归:11 套件全复跑零回归——e2e_spatial_sparse / e2e_gwas / e2e_molrigor / e2e_advanced_gblup / e2e_gblup_cv / e2e_refine / e2e_gxr / e2e_corr_spatial / e2e_gaps_engines / e2e_gaps_modules / e2e_gaps_base(其间同步 e2e_spatial_sparse 两处
data_version断言 v2.14→v2.15,版本语义更新非回归)。 - openapi:后端重启核验
/statistics/type-b-heredity、/type-b、/type-b/{id}、/statistics/cluster、correlation?mode/genetic、/selection-index auto_weights全在;observation list 四过滤(tree/plot/germplasm/trial_study)经真实 HTTP 命中。
18.5 世代闭环修复:单株晋级同步落系谱(2026-08-05 跟进)
用户报告闭环断裂:
selection_result/service._promote_tree_to_clone晋升单株到品系(line/regional_trial/released)时仅BreedingGermplasmCRUD.create(cultivar_name=clone_code)建种质,未同步写bre_pedigree→ 新种质在统计引擎_build_pedigree(statistics/service.py:299,按bre_pedigree.child_code→germplasm.cultivar_name匹配祖先)里查不到亲本,被当 founder,跨世代系谱链断裂:A-BLUP / 亲缘矩阵 / 选配近交规避跨代失效、遗传增益滚雪球效应归零。
修复(selection_result/service.py):晋级到 _GERMPLASM_STAGES 且树未关联种质时,建 bre_germplasm 携带 generation/stage,并自动落一条 bre_pedigree:child_code=clone_code(品种名)、dam_id/sire_id=tree.dam_id/sire_id(为空回退组合 female_parent_id/male_parent_id)、combination_id、generation=tree.generation、remark「单株晋级自动落系谱(世代闭环)」;child_code 幂等查重(已存在不重复落)。附 combo=None 顶部初始化,消除"树已有 clone(ap/sp 晋级过)再晋级品系"路径的 UnboundLocalError 隐患。
引擎级验证(Temp/claude/e2e_pedigree_closure_20260805.py,11 组断言全过):① 晋升 line → 建种质携带 generation/stage + 自动落谱(dam/sire/combination/generation 齐);② _build_pedigree 对下一代树输出 g{晋升种质} 带 dam/sire(非 founder);③ A 矩阵跨代恢复——两棵仅经晋升种质共享祖先的下一代树,亲缘 A[T2,T3]=0(修复前,gT1 当 founder)→ 0.125(修复后,血缘推导 2·¼·f(gT1,gA)=2·¼·¼);A[gT1,gA]=0.5(亲子)佐证链条接通;④ tree.dam/sire 为空 → 组合亲本回退落谱;⑤ child_code 预置行不重复;⑥ 已有 clone(sp 晋级过)再晋级品系 → else 分支回退组合亲本落谱(combo=None 初始化防 UnboundLocalError 的回归用例)。
回归:e2e_batch_selection(晋级主线,含新建谱行被 combo CASCADE 清理无残留)/ e2e_gaps_base(19 ok)/ e2e_spatial_sparse / e2e_advanced_gblup / e2e_gaps_modules(15 组)全过零回归。
18.6 近交惩罚「静默关闭」修复:亲缘矩阵多源解析 + 显式告警(2026-08-05 跟进)
用户报告最隐蔽的坑:
mating_recommend的亲缘矩阵靠_germplasm_pedigree(statistics/service.py)用bre_pedigree.child_code与种质cultivar_name/accession_no精确字符串匹配来建。一旦名称不完全一致(大小写/空格/代号),pedigree 返回空 →rmat={}→ 所有配对r=0→kin_pen=max(0,0−thr)=0→ 近交规避整体失效,且无任何告警——用户以为系统在避近交,实际没避。用户提出三点修复方向:① 匹配失败显式告警;② 优先用种质实体自带 dam/sire 或 clone/tree 聚合,而非名称反查;③ 绝不静默 no-op。核实确认,并额外发现:候选既是 child 又是祖先时g{id}被重复追加 →blup.relationship_matrix抛『系谱个体重复』→ 端点崩溃。
修复(statistics/service.py)——重写 _germplasm_pedigree 为多源级联(返回 (pedigree, coverage),coverage={total,resolved,resolved_ids,founder,matched_rows,orphan_rows,fk_sources}):
- ① 显式系谱(权威):
bre_pedigree.child_code规范化(strip+casefold)命中cultivar_name/accession_no索引——保留手录系谱语义,并直接修复大小写/空格错配; - ② FK 兜底:
tree.germplasm_id == 该种质的树 → 其dam_id/sire_id全集去重后唯一一致才采纳(升种质=升谱树自带种质级亲本,消除名称反查对代号错配的脆弱性);多对歧义(trial 树挂冲突亲本)→ 视为无回退 founder,不武断选取; - ③ founder。祖先以同级联 BFS 展开 + 去重(修复重复抛错崩溃 + 打通跨代系谱链)。
mating_recommend 新增显式告警:kinship_status=ok|partial|none + kinship_warning(none→「候选亲本均未解析到系谱…近交惩罚已禁用:所有配对 r 按 0 计」;partial→列未解析亲本名单;ok 但有孤儿行→「bre_pedigree 有 N 条 child_code 未匹配任何种质名称(孤儿记录),跨代亲缘可能低估」)+ 逐对 flags 加「亲缘未解析(r 按 0 计)」;返回体新增 kinship(resolved/founder/matched_rows/orphan_rows/fk_sources)。设计红线:FK 只做兜底、绝不覆盖显式系谱(A6 回归保真:trial 树 FK 挂 FM/MM 与显式系谱 dam=G0 冲突 → r(G0,G4)=0.5 保持)。
验证(Temp/claude/e2e_mating_kinship_20260805.py,14 组断言全过):① FK 兜底恢复(无 ped 行升种质树直连 → r(GX,GA)=0.5,修复前为 0);② 孤儿行告警(全解析 status=ok + orphan 警告);③ 规范化匹配(child_code 大小写变体仍命中显式系谱);④ 三代链不崩 + r(GX,GW)=0.5 / r(GA,GW)=0.25;⑤ 全 founder → status=none + 显式告警 + 逐对旗标;⑥ partial → 未解析亲本名单。回归:e2e_data_mating_gain(A6,r=0.5 保真)/ e2e_batch_selection / e2e_gaps_base 全过零回归。HTTP 核验:后端重启后 /bre/statistics/mating-recommend 真实数据 32/33 → kinship_status=none + kinship_warning 含「近交惩罚已禁用」+ kinship={resolved:0,founder:2,orphan_rows:2} + 逐对旗标(顺带暴露 2 条真实孤儿系谱行——数据质量信号)。
18.7 选配「亲本 EBV」回退逻辑方法学修复:direct 优先 + 子代测验降权 + 双侧去重(2026-08-05 跟进)
用户报告方法学错误:
mating_recommend旧实现对无直接 EBV 行(ABLUP/GBLUP 按树写、germplasm_id为空)的候选种质,用**「其子代树 EBV 均值」回退代表该亲本育种值**。三条质疑核实成立:① 这是 progeny-test 值(子代世代预测值 ≈½亲本BV+共亲本渗入+孟德尔抽样),不是亲本自身育种值;② 同一子代树若双亲都缺直接 EBV,被等权计入 dam 与 sire 两侧,稀释严重;③ 跨组合混合无区分。会误导选配排序。用户提出修复方向:优先用亲本自身预测值;回退值必须显式标注「基于子代测验的近似」并降权参与打分。
修复(statistics/service.py mating_recommend):
- direct 优先:种质级 EBV 行(
germplasm_id直连)=亲本自身预测值,无条件最优先;有 direct 的候选绝不被其子代树值污染(回退仅对missing集生效,杜绝树级 99.0 泄漏进亲本)。 - 回退显式标注 + 降权:新增
_EBV_SOURCE_FACTOR = {direct:1.0, progeny:0.5, missing:0.0};打分改mid=(f_a·ebv_a+f_b·ebv_b)/2、score=w_ebv·mid−w_kin·pen——progeny 近似按半权参与,绝不冒充亲本自身值、不掩盖 direct;missing 按 0 计(与旧行为一致,全缺失时排序不变)。 - 双侧等权稀释修复:子代树双亲均在
missing集(如 FM×MM 双亲均无 direct)→ 剔除(该树均值无法归属,防止同值计入两侧);仅单侧可归属的树才计入对应亲本。 - 跨组合辨别:回退亲本记
n_progeny(子代数)/n_combos(跨组合数),供调用方判断子代测验近似的稳健性。 - 显式可查,绝不静默降级:返回体新增
candidate_ebv(每候选germplasm_id/name/value/source/n_progeny/n_combos,missing 的 value=None)+ebv_source.coverage(direct/progeny/missing 计数)+ 逐对flags加「亲本EBV为子代测验近似(降权0.5)」/「亲本无EBV(按0计)」。
验证(Temp/claude/e2e_mating_ebv_20260805.py,5 组断言全过):① candidate_ebv 来源可查——P0=direct/10.0(子代树值 99.0 未泄漏)、P1=progeny/8.0(n_progeny=3、n_combos=2)、P2/P3/P4=missing/None;② ebv_source.coverage={direct:1,progeny:1,missing:3};③ 降权打分——P0×P1 ebv_mid=7.0=(1.0·10+0.5·8)/2(≠9.0 原始均值)+「子代测验近似」旗标、P0×P2 ebv_mid=5.0+「无EBV」旗标;④ 双侧去重——P3×P4 双亲均缺 → 子代树剔除 → source=missing、ebv_mid=0.0(旧代码会 progeny=7.0);⑤ score 降序、榜首 P0×P1(加权 EBV 互补最高)。回归:e2e_data_mating_gain(A6 无 Prediction 行 → 全 missing → 排序不变)/ e2e_mating_kinship(ok=14)/ e2e_batch_selection / e2e_gaps_base(19 ok)全过零回归。HTTP 核验:后端重启后 /bre/statistics/mating-recommend 真实数据返回 candidate_ebv(12 候选全 source=missing/value=None)+ ebv_source.coverage={direct:0,progeny:0,missing:12} + 逐对旗标。
18.8 数据质量「离群值」方向语义错位修复:同向=极值候选(精英)/ 反向=疑似录入错误(2026-08-05 跟进)
用户报告语义错位:
data_quality_report(§8.17①/§8.23① 的 A5 数据质量端点)旧实现用 IQR(Q1−1.5IQR/Q3+1.5IQR) 超界 + MAD 稳健 z-score(>3.5) 双通道把任何偏离分布的值都标为「离群株(疑似异常)」。但桃育种按选育目标选极端表型——果重/固酸比/可溶性固形物要高的、裂果率/病指要低的——正向偏离恰恰是育种家要选的精英单株(与高 EBV 高度相关),把精英候选标成「疑似录入错误」会诱导弃选、误导决策。用户提出修复方向:仅当偏离方向与选育目标相反才提示疑似录入错误;同向偏离标为「极值候选(精英)」。
修复(statistics/service.py data_quality_report):
- 方向感知:
trait_row = await self._numeric_trait(trait_id)后取direction = (trait_row.direction or "desc").lower();desirable_high = direction != "asc"(desc/None → 高值优;asc → 低值优)。判定标准与 v2.3 性状方向标注链路一致,低优性状(裂果率/病指)反向侧为高值。 - 双通道分流:IQR/MAD 命中的株再按偏离侧分类——
is_high = v > med;is_elite = is_high == desirable_high:同向偏离 →extreme_candidates(class="extreme_candidate",side=high/low,极值候选·精英);反向偏离 →outliers(class="outlier",疑似录入错误)。两表互斥,精英绝不进错误表。 - 返回体:新增
direction、extreme_candidates(tree_id/value/z/side/class/reasons)、summary.n_extreme_candidates;summary.has_warning/n_outliers/outlier_rate语义收紧为疑似录入错误计数(不再把精英株计入告警)。is_high = v > med而非 >0,中位对称稳健。 - 前端(
statistics/index.vue数据质量 tab):选育方向指示条(高值优 desc / 低值优 asc)+ 双表——「极值候选(精英)」success 标签表 + 「疑似录入错误」danger 标签表;hint 说明同向=精英/反向=错误;无错误时绿色 info alert「未发现疑似录入错误」而非黄色警告。
验证(Temp/claude/e2e_data_mating_gain_20260804.py [1] 17 株断言全过):15 正常树 + 精英树({PREFIX}-HI,值 16.0,G3)+ 错误树({PREFIX}-LO,值 2.0,G3),direction=desc——精英树进 extreme_candidates(class=extreme_candidate/side=high)且不在 outliers;错误树进 outliers(class=outlier/side=low);n_trees=17、n_extreme_candidates=1、n_outliers=1、missing_rate=0。回归:e2e_mating_kinship(ok=14)/ e2e_batch_selection / e2e_gaps_base(19 ok)全过零回归。HTTP 核验:后端重启后 POST /bre/statistics/data-quality 对 asc 裂果率(bB_DIR5668)与 desc 果重(dA_DIR5668)两真实性状返回 direction/extreme_candidates/outliers/summary.n_extreme_candidates 全部正确——真实数据无极端偏离 → 双表空(无误报)。
18.9 ΔG 投影假设声明 + 工程健壮性打磨:note 假设 + spatial 缺坐标降级 + numpy 收敛(2026-08-05 跟进)
用户报告两点,均非功能 bug(核实确认后拍板落地):①
genetic_gain(§8.23① A3 遗传增益端点)的next_pheno_mean = pheno_mean ± dg隐含「环境均值恒定」假设——若年际气候漂移,投影会偏;属投影演示性质,应显式标注假设。② 工程健壮性细节——spatial 模型要求所有观测树都有 row/col,否则整批 ValueError(门禁合理但无「剔除缺坐标者继续」的优雅降级);data_quality_report/genetic_gain函数体内重复import numpy;多处 numpy 计算未利用托管 venv 向量化优势。
修复(statistics/service.py + statistics/index.vue):
- ① ΔG 投影假设显式声明:
genetic_gain返回体新增note静态常量——投影假设环境均值恒定(未计入年际气候漂移与栽培措施变化);ΔG=k·r_g·σ_A 仅含遗传增益分量,next_pheno_mean 为投影演示值而非实测预测。(同性状/同数据重跑不变,探针断言稳定)。前端 gain tab 在描述区后、轮次表前展示el-alert type="info"提示假设边界。 - ② spatial 缺坐标优雅降级:
run_ablup(spatial=True)坐标收集循环把row_no/col_no为空的观测树记入missing_coord_ids,剔除其表型但保留系谱——blup.solve_spatial本就对所有个体(含无表型)输出 EBV,故缺坐标株 EBV 仍由系谱预测;剔除数显式写入批次 note「缺坐标剔除N株表型(EBV由系谱预测)」;仅当全部观测树都缺坐标(coords 空)才整批 409(提示先在单株录入填行号/列号)。input_hash随剔除后的表型子集计算(同数据可复现)。设计红线:缺坐标仅剔除该株表型、绝不剔除系谱——系谱是空间 EBV 的预测基础。 - ③ numpy 工程清理:
data_quality_report/genetic_gain及另 5 处(genetic_corr/selection_index/bivariate/genetic/type-B/UPGMA)函数体内重复import numpy全部收敛为模块级单次import numpy as np(service.py:24);data_quality_report逐株 flag 循环改 numpy 布尔掩码向量化——z_robust_all = np.where(mad>1e-9, 0.6745·(a−med)/mad, 0)、iqr_flag_all = (a<q1−1.5iqr)|(a>q3+1.5iqr)、z_flag_all = |z_robust|>3.5,flagged_idx = np.nonzero(iqr|z)[0]一次性定位命中株,输出逐字节不变(精英/错误分流逻辑不变)。
验证(Temp/claude/e2e_spatial_sparse_20260804.py 降级场景断言全过):5 株(前 4 株 2×2 网格带 row/col + 第 5 株 row_no=None)观测 [10.0,10.5,11.0,11.5,9.0] → method=AR1×AR1、train_n=4、note 含「缺坐标剔除1株」、5 株全部有 EBV 行(缺坐标株由系谱预测);全缺坐标场景仍整批 409 且报错含 row_no/col_no 数据需求。A6 探针 [2] 新增 note 断言:note 含「环境均值恒定」且两性状稳定一致。回归:e2e_spatial_sparse / e2e_data_mating_gain / e2e_mating_kinship(ok=14)/ e2e_batch_selection / e2e_gaps_base(19 ok)五套零回归。vue-tsc EXIT=0。HTTP 核验:后端重启后 POST /bre/statistics/genetic-gain(真实性状 dA_DIR5668)返回 note(含「环境均值恒定」);POST /bre/statistics/data-quality 返回 direction: asc、双表空无误报。
18.10 A–F 六项功能级缺口·批1 父本验证 + 近交衰退:一致性校验 + F→表型回归(2026-08-05 跟进)
用户全模块 grep 实证 A–F 六项功能级缺口(「有无/深度」问题,非正确性 bug),逐项复核确认 + 拍板「全部六项分批落地」。批1 = A 父本验证(pollination 花粉来源一致性 / tree 显式亲本警示 / cross_combination 自交门禁)+ C 近交衰退(
_DATA_VERSIONv2.22)。
A 父本验证(consistency,不落库):
- A1 pollination 花粉来源父本一致性(
pollination/service.py新增_validate_pollen_parent):批次pollen_lot.male_tree_id声明采集父本树时,授粉声明male_tree_id须一致,否则 409「花粉批次 {lot_code} 采集自父本树 {X},与授粉声明父本树 {Y} 不一致,请确认花粉来源」;批次无采集父本(混合/外地采集)或授粉未声明父本 → 放行。create/update 统一在_validate_pollen_window后调用(update 取existing回退)。 - A2 tree 显式亲本 vs 组合父母本警示(
tree/service.py_resolve_parents改返回(dam, sire, warning)):显式 dam/sire 与组合 female/male_parent 不一致时聚合「显式母本与组合母本不一致;显式父本与组合父本不一致(以显式为准)」;warning 不阻断(tree 可独立建,武断 409 会误伤);tree/schema.py加只读warning字段(仅返回体,不落库)。 - A3 cross_combination 同质自交门禁(
cross_combination/service.py_check_parent_roles角色解析后追加):female_parent_id == male_parent_id→ 409「母本与父本同为「{名}」,自交组合请确认」;create/update 生效亲本统一触发(与既有 S-等位 409 语义一致不冲突)。
C 近交衰退分析(statistics/ 三件套 + 前端,计算端点不建表):
POST /statistics/inbreeding-depression(InbreedingDepressionIn:trait_id/trait_code + year/trial_study_id 可选 + min_n=10)——inbreeding_depression:tree 系谱(t{tree_id}个体 +g{germplasm_id}founder)→blup.relationship_matrix取 F=A_ii−1;关键洞见:inbreedingdict 仅含 F>0,非近交树须从individuals默认 F=0 兜底,否则非近交株被排除出回归;trait 树级表型select(obs.tree_id, func.avg(value_numeric)).group_by(tree_id)聚合(按 year/trial_study_id 可选过滤)→ 交集树 → 纯 numpynp.linalg.lstsq线性回归 phenotype ~ F。返回{sufficient, reason, n_obs, mean_F, max_F, direction, regression:{intercept, slope, r2, t_slope, depression_rate, has_depression, interpretation}, high_inbreeding:[{tree_id, tree_no, F, value}]};has_depression = slope<0 且 t_slope≤−1.645(单侧 95% 大样本近似);high_inbreeding按 F 降序取前 10;n<min_n 优雅降级sufficient=False+ reason(不 409)。- 前端「亲缘/近交」tab 加「近交衰退(F → 表型)」区:trait select + year input + 运行;
el-alert(insufficient=warning / has_depression=error / 无衰退=success)+el-descriptions+high_inbreeding表。修 vue-tsc TS2322:el-alert :type无 danger 合法值,改'error'。
验证:Temp/claude/e2e_parent_validation_20260805.py 10 断言全过——A1 不一致 409(含「不一致」)/一致放行/混合批次放行/update 同门禁;A2 双侧警示(含「以显式为准」、dam/sire=显式)/单侧仅父本/一致无警示/update 警示;A3 create/update 同质 409(含「自交」)。Temp/claude/e2e_inbreeding_depression_20260805.py 4 断言全过——12 树(6×F=0 + 6×F=0.5 自交)衰退性状 y=100−60F+ε → slope≈−60/t 显著负/r²>0.9/has_depression=true/depression_rate<0/max_F≈0.5/mean_F≈0.25/high_inbreeding 前 6 全为 S-自交 F=0.5、后 4 F=0;无衰退 y≈100 → slope≈0/「未检出」;min_n=20 → insufficient 含「12 棵」「≥20」;trait_id=99999999 → 409。回归:e2e_spatial_sparse(v2.22 断言同步)/ e2e_statsflow / e2e_data_mating_gain / e2e_mating_kinship / e2e_batch_selection / e2e_gaps_base 六套零回归。vue-tsc EXIT=0。HTTP 核验:后端重启后 POST /bre/statistics/inbreeding-depression(真实稀疏数据)返回 code=0、sufficient=false、n_obs=2、reason「同时具备系谱近交系数 F 与表型的树仅 2 棵(需 ≥10)」、mean_F/max_F/regression=null、high_inbreeding=[]。
18.11 A–F 六项功能级缺口·批2 GS 家系 CV + 试验设计深度:家系阻塞折 + RCBD 生成/区组 ANOVA(2026-08-05 跟进)
A–F 六项缺口批2 = B GS 家系 CV(深度:随机分层 → 家系阻塞折)+ F 试验设计深度(RCBD 生成 + 设计基 ANOVA)。批1 已落地 §18.10(v2.22);本批
_DATA_VERSIONv2.23。
B GS 家系 CV(genomic.py + statistics/service.py + 前端):
- 引擎
genomic.kfold_cv_genomic加split: str = "random"+family_of: dict[str, str] | None = None:split="random"→ 现有 round-robinbin_of = {c: i % k}逐字节不变(回归零变化);split="family"→ 照blup.kfold_cv的 sire 家系留出模式——fam_of = {ind: (family_of or {}).get(ind, ("self", ind))}(无家系个体自成一族)→fams去重 →rng.shuffle(fams)→fam_bin = {f: i % k}→bin_of = {c: fam_bin[fam_of[c]]},同家系个体同折(防亲缘泄漏高估准确度);家系数 < 折数 k → 折叠为 n_families 折 + warning「家系数 {n} < 请求折数,折叠为 {k} 折(family-blocked)」;单家系(n_families<2)→ folds=[] + warning「可验证个体仅构成 1 个家系,无法家系阻塞交叉验证(请改用随机分层)」。输出加n_families(逐键对齐 blup.kfold_cv)。 - 服务
run_cv加split="random"|"family"透传(controller/schema,job params_json 记 split):GS 分支split=="family"时用既有ped_rows(select 顺序 id/dam_id/sire_id/trial_study_id/rootstock_id/female_parent_id/male_parent_id/combination_id/clone_id/germplasm_id)构建family_of = {f"t{tid}": f"s{s}"}(s = sire if sire is not None else cm,sire 缺失回退组合 male_parent);落库CvResultModel.note记split=family · n_families={N}(+ 引擎 warning 拼接)。 - 前端「交叉验证」tab runCv 参数区加 split 下拉(random=随机分层/family=家系阻塞)+ 结果表 n_families 列。
F 试验设计深度(trial_study_entry/model.py + weld_trial_study_entry.sql + statistics/ 三件 + anova.py + 前端):
- F1 RCBD 生成器:
bre_trial_study_entry加可空block_no integer(model 列block_no: Mapped[int | None]+sql/weld_trial_study_entry.sqlALTER TABLE ... ADD COLUMN IF NOT EXISTS,create_all 只建新表故 weld 幂等兜底);新端点POST /statistics/trial-design(TrialDesignIn:trial_study_id + design_type="rcbd" + seed 可选)——trial_design:db.get(TrialStudyModel)409、design_type≠rcbd 409、block_count=study.block_count or 1、按 entry_number 取参试条目(空 409「无参试条目」)→random.Random(seed)洗牌 + round-robin 分进区组(均分 + 组内随机 = 田间布局)→update(...).values(block_no=case(block_of, value=TrialStudyEntryModel.id, else_=None))批量落库 + flush;返回{trial_study_id, design_type, block_count, seed, n_entries, blocks:{str(b): [entry_number…]}}。 - F2 设计基 ANOVA:
anova.solve_rcbd(rows)(rows={"group","block","value"})RCBD 双因素 Type I 顺序(X1→Xg→Xgb dummy 矩阵:SS_group=rss(X1)−rss(Xg)、SS_block=rss(Xg)−rss(Xgb)、SS_error=rss(Xgb),纯 numpy +fdist.f_pvalue),输出含 f_block/p_block/groups/blocks/warning(<2 组合或 <2 区组 ValueError;df_error≤0 → warning「区组设计过饱和」);anova.solve单因素逐字节不变。run_anova加block: bool=False:block=False → 原单因素路径不变;block=True → 查bre_tree.block_no组 rows、过滤空 block、<2 区组 → 409「区组数据不足:需 ≥2 个区组(请先运行 /statistics/trial-design 生成设计并落库 block_no)」,method=ANOVA/H2/RCBD。 - 前端 statistics ANOVA tab 重构:顶部「生成 RCBD 设计」工具条(trial_study select + seed input + warning button)+ 设计区组表 + trait select + year +
el-checkbox anovaBlock「RCBD 区组校正」+ 提交;结果加 n_blocks/f_block/p_block 条件 v-if + 区组均值表。statistics.ts加trialDesign()+TrialDesignResult。
验证:
Temp/claude/e2e_trial_design_20260805.py5 组断言全过——[1] RCBD 生成(block_count=3/n_entries=9/3 区组×3 均分/9 条目齐全/seed·design_type 回显);[2] block_no 落库核验(紧随首次生成避免复现覆盖;落库区组集合==返回设计集合);[1b] seed=42 复现同一设计 / seed=43 异动;[3] block=False → method=ANOVA/H2、无 f_block/n_blocks/blocks 键(单因素逐字节不变);[4] block=True → method=ANOVA/H2/RCBD、n_blocks=3、ss_block>0、f_block>1、p_block 存在、区组均值随 +3/0/−3 递减;[5] 空研究点 409「无参试条目」。Temp/claude/e2e_gs_family_cv_20260805.py5 组断言全过——[1] 5 家系×3 全同胞 k=3 → method=KFCV/GBLUP、note「split=family · n_families=5」、家系阻塞折 n_test=[3,6,6];[2] k=5 → 每折恰 1 家系 n_test 全 3;[3] random k=3 → note 无 split=family、n_test=[5,5,5](随机分层回归零变化);[4] 引擎级 6 家系<请求 8 → 折叠 6 折 + warning;[5] 单家系 → folds=[] + warning。注:探针树创建曾漏db.add_all([fm, mm])致 germplasm.id=None → 组合父母本全空 → sire 全空 → n_families=15,补 add 后修正为 5(服务侧代码位置核实无误)。- 回归:e2e_gblup_cv / e2e_statsflow / e2e_spatial_sparse / e2e_busflow / e2e_mating_kinship / e2e_gaps_base / e2e_molrigor 七套零回归。vue-tsc EXIT=0。HTTP 核验:后端重启后
POST /bre/statistics/trial-design+POST /bre/statistics/anova/run(block=true)经真实端点返回。
18.12 A–F 六项功能级缺口·批3 OCS 最优贡献选择 + MABC 标记辅助回交:投影梯度求解器 + 前景/背景选择工作流(2026-08-05 跟进)
A–F 六项缺口批3(收官)= D OCS 最优贡献选择 + E MABC 标记辅助回交。批1 §18.10(v2.22)、批2 §18.11(v2.23);本批
_DATA_VERSIONv2.24。两端点纯计算不落库(对齐 data_quality 惯例);前端同批交付(选配推荐 tab OCS 运行区 + 独立回交 MABC tab,vue-tsc EXIT=0)。
共享 helper 抽取 _candidate_ebv_map(statistics/service.py:3429-3531):
mating_recommend内联 EBV 解析块原样抽取为_candidate_ebv_map(prediction, tree_ids)→{germplasm_id → ebv}:prediction batch ABLUP/GXEBLUP/GXRBLUP/GBLUP/ssGBLUP 全支持;direct germplasm_id 先取,缺失走 progeny 子代均值并_EBV_SOURCE_FACTOR={direct:1.0, progeny:0.5, missing:0.0}降权;返回ebv_map/source/status/warning/cover/n_progeny/n_combos/ebv_mid。- 「双亲均缺直接 EBV → 子代树剔除(双侧去重)」规则随抽取原样保留——经 transcript 抽取前内联块 old_string 实证该规则已存在于抽取前代码(v2.19 方法论),非抽取回归;
e2e_mating_ebv[4] P3×P4=0.0 权威验证、e2e_audit_fix_20260804④ 已同步语义。 - OCS 端点复用
_candidate_ebv_map(candidate germplasm 直接取)+mating_recommend保留原内联调用(行为不变)——mating 回归 14/14 零变化证明抽取无副作用。
D OCS 最优贡献选择(POST /statistics/ocs):
_proj_simplex:欧氏投影到单纯形(numpy sort/arange 解析投影,无 scipy),_solve_ocs投影梯度 + 回溯线搜索:max Σc_i·ebv_i − λ·c'Ac,s.t. Σc=n_select、c≥0;A 由_germplasm_pedigree+blup.relationship_matrixrmat 组装(对角=1、非对角候选对 r,覆盖<100% → kinship_status="partial" + warning)。- 输出:
contributions(c 降序 + ebv/source/可选 n_progeny/n_combos)、mean_ebv、avg_kinship(c'Ac)、kinship_quad、vs_top_n(同 n 贪心 top-n 对照:mean_ebv 相当 + kinship_reduction,量化 OCS 亲缘控制价值)、ebv_source/kinship_status/kinship_warning。 - 门禁:空候选 / n_select>候选数 / λ<0 → 409。
E MABC 标记辅助回交(POST /statistics/mabc-progress):
- 前景选择:复用
_mas_hit_map/_mas_marker_hit(additive/dominance/recessive/allele/haplotype 五语义),foreground_pass= 命中 ≥foreground_min_hits(stage 无关、童期幼苗即可)。 - 背景基因组恢复率:background 面板逐标记候选 vs 轮回亲本「纯合剂量一致」比例(
_pure_homologous:候选纯合且等位∈轮回亲本等位集;杂合不计),标记均值 = 恢复率 %(round 2)。 - 回交代建议:
_BC_LADDER=["F1","BC1","BC2","BC3","BC4","BC5"]+_MABC_GENERATIONS={"F1","BC1","BC2","BC3"};晋级 / 再回交 / 补测后判定 / 前景未通过 四分支 reason;recommended前景通过按恢复率降序(None 排尾)。 - 门禁:空候选 / 空前景或背景面板 / generation∉
_MABC_GENERATIONS/ background_target∉(0,100] / 轮回亲本不存在 → 409。
验证:
Temp/claude/e2e_ocs_20260805.py17 断言全过——[1] Σc=3、c≥0、coverage=direct 5/5、c 降序、最高=A;[2] mean_ebv 与 vs_top_n 相当 + kinship_reduction=0.0398 + kinship_quad≈4.641;[3] λ↑(0→0.5→1→10)→ avg_kinship 单调非增(1.0→0.5157→0.3211→0.2685);[4] λ=0 退化=贪心 top-n(满额投最高 EBV 单亲);[5] A 缺失 → kinship_status=partial + warning;[6] 三 409。清理干净。Temp/claude/e2e_mabc_20260805.py23 断言全过——[1] 前景 5 pass/1 fail;[2] 恢复复算 100/75/75/0;[3] reason 晋级 BC2/再回交/前景未通过;[4] recommended 恢复率降序 [100,100,100,75,0];[5] 童期 C6 前景通过+晋级;[6] 轮回亲本缺背景基因型 → None + warning;[7] 六 409。清理干净。- 回归:e2e_molrigor / e2e_gwas / e2e_mating_kinship(14/14)/ e2e_mating_ebv / e2e_gblup_cv / e2e_statsflow / e2e_spatial_sparse / e2e_busflow / e2e_gaps_base / e2e_b8_seed_lot / e2e_prediction_rigor / e2e_audit_fix 全套零回归(
_candidate_ebv_map抽取 + mating 语义双核对)。vue-tsc EXIT=0。HTTP 核验:后端重启后POST /bre/statistics/ocs(最小正例)+POST /bre/statistics/mabc-progress(成功 + 空面板 409 + 非法 generation 409)经真实端点返回。环境性 b34(G1 门禁)为探针脆弱非本批回归。
18.13 近交衰退两处正确性修复:方向感知检测 + 深层系谱近交系数(2026-08-05 跟进)
用户实证复查
inbreeding_depression(v2.22,§18.10)两处缺陷,本会话核实成立后修复:① 方向盲目判据——无条件slope<0 且 t≤−1.645判衰退,对「越低越好」的 asc 性状(如病指)F↑→指标↑=恶化却误报「未检出」;② 浅层近交系数——系谱只取树级 dam/sire 把每个引用种质当 founder,未走深层系谱,多世代项目(半同胞共享祖亲)低估 F(OCS/mating 已用_germplasm_pedigree深层解析,故仅近交衰退受影响)。版本仍 v2.24(正确性修复不升版,避免批3 版本断言连锁)。
① 方向感知检测(statistics/service.py inbreeding_depression):
- 读
direction(此前读取未用)得desirable_high = direction != "asc"; - 高优性状(desc/None)衰退 =
slope<0 且 t≤−1.645;低优性状(asc)衰退 =slope>0 且 t≥+1.645; interpretation方向化——asc 衰退「F 每升 0.1,{trait} 表型平均上升(恶化) …%」/ 未达显著「斜率偏正…」/ 未检出「F 对表型无**上升(恶化)**影响」。对齐data_quality_report既有desirable_high方向语义。
② 深层系谱近交系数:
- 系谱构建改复用
_germplasm_pedigree(bre_pedigree 名称反查 + tree FK 兜底 + BFS 祖先展开,与 OCS/mating 同源)展开全部被引用种质祖先 + 树节点 + 未解析种质 founder 兜底(软删引用不悬空);_germplasm_pedigree本体零改动。 - 多世代半同胞共享祖亲 → F 正确 >0(旧浅层把 G7/G8 当 founder → F=0 低估)。
验证:
Temp/claude/e2e_inbreeding_depression_20260805.py6 组断言全过——原 [1] 衰退 / [2] 无衰退 / [3] 样本不足保持,新增 [4] asc 病指(12 树同 F 结构 y=10+40F → slope=+40、t 显著正、has_depression=true、文案含「上升(恶化)」、高近交前 6 仍 F=0.5 自交株;旧判据误报未检出)+ [5] 深层系谱 F(P→G7/G8 tree FK 升谱、6 候选树 dam=G7 sire=G8 半同胞近交 + 6 对照 F=0,y=100−60F → max_F=0.125/mean_F=0.0625、slope≈−61、has_depression=true、高近交前 6 全为 H 半同胞株;旧浅层 F=0)+ [x] trait 不存在 409 保持。清理干净(26 树 48 观测 + 4 性状全删)。- 回归:e2e_ocs / e2e_mabc / e2e_mating_ebv / e2e_mating_kinship / e2e_statsflow / e2e_spatial_sparse / e2e_gs_family_cv / e2e_trial_design / e2e_parent_validation / e2e_batch_selection / e2e_gaps_base / e2e_gaps_engines / e2e_gaps_modules 全套零回归。vue-tsc EXIT=0(前端仅提示文案方向化一行)。HTTP 核验沿用批3(后端未重启)。
18.14 分子亲本验证(孟德尔一致性)+ 试验设计深度(增广 + α-格子)(2026-08-05,v2.25)
用户实证复查指出两处遗留缺口,本会话核实全部成立:①
genotype_call对 mendelian/parentage 零命中(仅有fingerprint_check无性系混杂/标签互换检测);②trial_design仅 RCBD。α-格子范围用户拍板:平方格子(v=k²,闭式构造,平衡可证)+ 一般 v 贪心回退(balance_warning 诚实标注)。_DATA_VERSIONv2.25,同步 3 处探针版本断言(e2e_prediction_rigor / e2e_spatial_sparse / e2e_statsflow)。
批4-A 孟德尔/亲本一致性检验(genotype_call/service.py mendelian_check(dataset_id, compat_threshold=0.98) + controller.py GET /bre/genotype_call/mendelian/check,镜像 fingerprint/check 模式,纯计算不落库):
- 数据解析(跨数据集):子代样本 =
GenotypeSampleModel.source_type=="tree"且 source_id∈dataset → tree 集合;声明亲本 =tree.dam_id/sire_id→germplasm(两亲皆空 →no_declared_parents+ reason「未声明亲本」);亲本基因型 =source_type=="germplasm"样本跨数据集解析(同数据集优先,否则其他数据集最低 id 兜底)——探针验证子代样本 D1、亲本样本 D2 跨数据集解析成功;亲本声明但无 germplasm 基因型 →missing_parent_genotype(不 409,reason 标注「母本/父本」缺哪个)。 - 孟德尔规则:逐标记
_allele_set("/" 分割去空白/缺失)得子代/母本/父本等位集;子代等位集 ⊆ dam∪sire 并集即兼容(union 规则);任亲本空白/缺失 → 非信息位点不计分母。单株兼容率 = 兼容/信息位点,flag = rate < compat_threshold(0.98 对齐 fingerprint)。 - 输出:
{dataset_id, compat_threshold, trees_checked, trees_flagged, trees_no_parents, trees_missing_parent_genotype, summary{informative_markers/incompatible_markers}, trees:[{tree_id, tree_no, dam, sire, status, informative_markers, compatible, incompatible, compatibility_rate, flag, incompatible_markers:[{marker_id, allele, dam, sire}], reason?}]};数据集无样本 → 零值返回 summary=None(不 409)。
批4-B 试验设计深度(statistics/service.py trial_design 分派 rcbd/augmented/alpha;rcbd 路径逐字节不变;schema.py TrialDesignIn 加 check_germplasm_ids: list[int]=[] / block_size: int|None / reps: int|None,extra="ignore"):
- augmented(增广):对照
check_germplasm_ids须为参试条目种质 id 子集(否则 409「对照种质不在参试条目中」)、至少 1 对照 + 1 新品系(否则 409「增广设计需至少 1 个对照种质」);对照每区组重复(anchors,check_reps=block_count)、新品系rng.shuffle+ round-robin 均分区组(不重复);对照条目block_no不落库(None)、新品系落 1..block_count。输出加checks:[{entry_number,germplasm_id}]/n_new_entries/n_checks/check_reps。 - alpha(α-格子):
block_size=k(v%k==0 否则 409「α-格子条目数 {v} 须能被 block_size {k} 整除」;k 缺省 v 完全平方自动 k=√v,否则 409「α-格子需指定 block_size(当前 {v} 条目非完全平方)」);reps=r(缺省平方 k+1/一般 s;r<2 → 409「α-格子重复数需 ≥2」;平方 r>k+1 → 409「完全平方格子(v={v}=k²)重复数最多 {r_full}」)。平方 v=k² → 闭式格子:rng.shuffle打标 (x,y),rep m∈{0..k} 直线 y≡m·x+(b−1) mod k(m=k=竖列),完全格子 r=k+1 任一对至多同块一次 λ≤1;k 素数(_is_prime)完全平衡 balance_warning=False,非素数 → balance_warning=True(保守告警,可分解不保证平衡)。非平方 v → 贪心可分解构造:逐 rep 贪心填 s 块×k,used_pairs集避免同块对重复,卡死则余下允许复用 + balance_warning=True;rng(seed) 确定性。block_no 复合编码 rep*100+block(rep 1..r、block 1..k)落库。 - 探针抓出的真 bug:平方分支初版 block_no 编码
m*100+b(0-based m)致 rep1 落库b(1..3)与贪心分支/文档的rep*100+block不一致 → 修正(m+1)*100+b(401/402…)。探针 [2] 落库断言由 301/302 → 401/402 验证。
验证:
Temp/claude/e2e_mendelian_check_20260805.py8 断言全过——跨数据集解析(子代 D1/亲本 D2):T1 全 0/1 唯 M5=2/2(亲本均无该等位)→ informative=5/compatible=4/incompatible=1/rate=0.8/flag + incompatible_markers[0]={M5,2/2,dam=0/0,sire=1/1};T2 全兼容 rate=1.0/flag=false;T3 双亲空 → no_declared_parents + reason;T4 dam=G3 无基因型 → missing_parent_genotype + reason「母本」不 409;summary informative=10/incompatible=1;D3 空数据集零值 summary=None 不 409。清理干净(call→sample→marker→dataset→tree→germ→combo→target 全删)。Temp/claude/e2e_trial_design_ext_20260805.py19 断言全过——[1] augmented 12 条目 3 对照×3 区组:n_new=9/n_checks=3/check_reps=3、新品系 block_no∈{1,2,3} 不重复、对照 block_no=None、checks 结构;[2] v=9=k² k=3 素数 r=4 完全格子:4 rep×3 块×3 条、每 rep 覆盖 9、任一对至多同块一次(maxλ≤1 恰 36 对)、balance_warning=False、block_no 复合编码落库;[3] 部分 r=3 仍平衡;[4] v=16 k=4 非素数 r=5 + balance_warning=True;[5] v=12 一般贪心 s=4/r 缺省=s + block_no 落库;[6] 四 409(对照非条目子集/增广无对照/v 不被 k 整除/非平方缺 block_size)。清理干净(entry→study→trial→germ→combo→target 全删)。- 回归:rcbd 由
e2e_trial_design_20260805.py回归零变化兜底;全量套件 e2e_molrigor / e2e_gwas / e2e_mating_kinship / e2e_mating_ebv / e2e_gblup_cv / e2e_statsflow / e2e_spatial_sparse / e2e_gs_family_cv / e2e_batch_selection / e2e_ocs / e2e_mabc / e2e_gaps_base / e2e_gaps_engines / e2e_gaps_modules / e2e_prediction_rigor / e2e_inbreeding_depression / e2e_parent_validation 全套零回归。vue-tsc EXIT=0。HTTP 核验:后端重启(PID 更换)后GET /bre/genotype_call/mendelian/check?dataset_id=999999→ 200 零值结构;POST /bre/statistics/trial-designaugmented/alpha → 409「该研究点无参试条目」(分派+参数链路通)、design_type=latin → 409「暂不支持设计类型 latin(可用: rcbd=随机完全区组、augmented=增广、alpha=α-格子)」。 - 方法学保留:mendelian_check 与
fingerprint_check互补(样本一致性 vs 子代-亲本孟德尔规则);augmented 对照 anchoring + alpha 平衡性显式告警与 RCBD 随机化并存;亲本基因型缺失/双亲空归状态不 409(数据现状透明化)。
18.15 批5 区组随机效应 ABLUP(N3)+ 孟德尔检验落库/隔离/进报告(N1)+ 统计引擎全量数值校验(N2)(2026-08-05,v2.26)
用户实证复查提出三项,本会话逐项核实全部成立,用户拍板范围:① N3(中-高,真实断点)——
trial_design已给增广/α-格子落库block_no不完全区组结构,但run_ablup只把 block_no 当空间竞争协变量网格 key,未作随机效应(service.py:651)→ 用户选「显式 block 开关」;② N1(中)——mendelian_check只读不落库、不进数据质量报告、不自动隔离可疑树,错配亲本仍污染系谱 → 用户选「断开错误亲本链」;③ N2(中)——run_gblup/ssGBLUP、genetic_corr、type_b、run_cluster、stability 等大体量新模块只有结构性断言,缺逐文件数值真值校验 → 用户选「全量统计引擎」。_DATA_VERSIONv2.25→v2.26(同步 3 处探针版本断言:e2e_prediction_rigor / e2e_spatial_sparse×2 / e2e_statsflow);blup.ENGINE_VERSION1.4.0→1.5.0。
批5-A(N3):ABLUP 区组随机效应:
- 引擎
blup.py:solve加block: dict|None分派_solve_block(pedigree, phenotypes, *, fixed, covariate, block_of, record_map, tol)(镜像_solve_gxe,blup.py:1006-1205)——Z₂ 按block_of: {记录id: 区组水平}分组(G×E 的 (g,e) 复合键退化为单区块水平),剖面 REML 坐标上升估 (σ²a/σ²e, σ²block/σ²e)、MME、PEV 可靠性;输出键sigma_block/block_ratio/block_effects/n_blocks、factor_label=「区组」;区组方差收敛到 0 / 无系谱 / 未收敛三警告。ENGINE_VERSION→ 1.5.0。 - 服务
run_ablup:新参block: bool=False。互斥并入 L491-494:block与gxe/gxr(共用 Z₂ 槽)409、block与spatial(残差结构与第二随机效应槽)409。新分支:读select(TreeModel.id, TreeModel.block_no)→block_of={f"t{tid}": int(blk)};无 block_no 的树降级剔除表型保留系谱(镜像 spatial 缺坐标降级,note 记剔除数);len(set(block_of))<2→ 409「区组数据不足:需 ≥2 个区组(请先运行 /statistics/trial-design 生成设计并落库 block_no)」;method="ABLUP-BLOCK"、model_name 前缀ABLUP_BLOCK_、note_payload 含sigma_block/block_ratio/n_blocks/warning;accuracy 按 block 树均值可靠性。 - Schema/控制器/前端:
RunAblupIn加block: bool=False;controller/ablup/run透传;前端 statistics「多环境 GxE」tab 加blockEnabled复选框 + 互斥 watch(block↔gxe/gxr/spatial)+ payload.block + 成功文案/说明三元。 - 探针
Temp/claude/e2e_ablup_block_20260805.py3 批次落库全过——[1] 3 区组×5 株已知 σ²block>0 → method/n_blocks/σ²block/block_ratio + EBV 独立矩阵解一致;[2] 单区组 409;[3] 无 block_no 409;[4] block+gxe/block+spatial 409 互斥;[5] 部分缺 block_no 降级剔除 + note 含剔除数;[6] 全收敛数据无区组归零警告。
批5-B(N1):孟德尔检验落库 + 自动隔离 + 进数据质量报告:
- 新表(create_all 自动建):
MendelianCheckModel→bre_mendelian_check(dataset_id/compat_threshold/计数/summary_json/data_version/input_hash/engine_version/note)+ 子表MendelianCheckTreeModel→bre_mendelian_check_tree(FK check_id CASCADE;tree_id/dam_id/sire_id/status/信息位点/兼容/不兼容/rate/flag/reason/incompatible_markers_json);TreePedigreeExclusionModel→bre_pedigree_exclusion(tree_id 唯一、reason/source_type="mendelian"/source_check_id/created_id)。 - 服务:
mendelian_check纯计算核心抽共享_compute_mendelian(dataset_id, compat_threshold)(GET 预览与 POST 逐字节同源);新run_mendelian_check计算→落库主表+每树子行→自动隔离:flag=true 树 upsertbre_pedigree_exclusion,本次未 flag 但此前隔离(同 dataset 范围)删除隔离行(注册表=最新检验结论、可逆)。 - 控制器:新
POST /bre/genotype_call/mendelian/check/run(Authmodule_bre:genotype_call:edit,写操作),GET 只读预览保留。 - 进数据质量报告:
data_quality_report加可选dataset_id,提供时追加mendelian段(最新bre_mendelian_check计数 + flagged 树列表 + 当前隔离状态);flagged>0 → summary.has_warning=True;无检验记录 →mendelian: None。DataQualityIn加dataset_id透传。 - 系谱消费方断开亲本链(共享
_excluded_tree_ids()读注册表,树级 dam/sire 置 None + note):_build_pedigree(genetic_corr/index/type_b/gblup/ssgblup/gwas)、run_ablup内联系谱循环、inbreeding_depression、kinship_matrix、run_cv、_germplasm_pedigree(树→种质亲本链)。GBLUP/ssGBLUP 基因型样本不过滤(错配是亲本声明非基因型)。 - 前端:genotype_call 孟德尔对话框主按钮改 POST
mendelianCheckRun(展示 check_id + 隔离树数 + 新类型);statistics「数据质量」tab 加 dataset 选择器 + mendelian 段(flag 计数 alert + 隔离树表)。 - 探针
Temp/claude/e2e_mendelian_persist_20260805.pyok=19 fail=0——[1] 落库(主表行/计数/子表行/check_id);[2] 隔离生效 + EBV 断开(隔离树与声明亲本亲缘=0);[3] 再跑未 flag → 隔离行清除(可逆);[4] data_quality_report(dataset_id) mendelian 段 + has_warning=True、无检验 None;[5] run_ablup note 含隔离剔除数、genetic_corr 亲缘=0;[6] GET 只读预览 8 断言零回归。
批5-C(N2):统计引擎全量数值真值校验(Temp/claude/e2e_stats_numerics_20260805.py,ok=101 fail=0):
- 14 个引擎段 + 4 服务端点段全过:
blup.solve普通(独立 V⁻¹ BLUP≡MME + 网格 REML 表面一致)、_solve_gxe(MME 恒等 + 方差分解)、_solve_block(MME 恒等 + 区组效应恢复)、solve_spatial(_aniso)(R 重构 + MME 恒等 + ρ_row/ρ_col 恢复)、build_g_matrix(手算 VanRaden method2)、solve_gblup(MME 恒等 + 可靠性公式)、_build_h(教科书 H⁻¹ 含 Christensen 缩放 + 岭)、ssGBLUP MME 恒等 + 非基因型株 EBV≠0、solve_bivariate(完全正相关 r_g→1 / 独立 r_g≈0)、solve_multi(已知 G0 恢复 + PSD)、finlay_wilkinson(独立 OLS)、ammi(解析 2×2 SVD)、solve_rcbd(手算 SS/MS/F)、_solve_diallel(手算 GCA/SCA)、_proj_simplex/_solve_ocs/_selection_intensity、服务端run_cluster(UPGMA 首次合并=最小距离对)、genetic_gain(ΔG=k·r_g·σ_A 复算)、data_quality_report(IQR/MAD 手算边界)、kinship_matrix(3 节点 A 手算)。 - 探针自身两处 fixture 缺陷修复(引擎本体零缺陷):① A8.4 独立性状 r_g 假收敛 -0.99 / A9 G0 恢复不可靠——根因是 4 创始人+10 子代低 h²(h²≈0.43)小样本 REML 面平坦/近边界(单性状 ve 塌缩、EM 起点被毒化),换高遗传力(va=[4,3,2.5]、ve=[0.5,0.4,0.35],h²≈0.87-0.9)+ 高真相关(0.95/0.90/0.85)+ 10 全同胞家系×3 株(n=54,24 创始人)良态设计 → r_g 恢复误差 ≤0.06(11.1s 收敛);② B4.2 硬编码
tree_id==4(fixture 树真实自增 id 5664 非 4)→ 改trees[3](值 9.0 精英株)。逐项核实 EM-REML/M-step/固定点/MME/剖面均教科书正确,非引擎 bug 不误报。 - runtime 约束记录:
solve_multi3 性状 n≥100 时每次迭代 MMEsolve+inv0.7s(n=100)超 2 分钟,数值探针 fixture 保持 n≤54。
验证:
- 三新探针(e2e_ablup_block / e2e_mendelian_persist / e2e_stats_numerics)全过;27 套件全量回归零回归(含 e2e_mendelian_check / e2e_trial_design / e2e_trial_design_ext / e2e_gxe / e2e_gxr / e2e_molrigor / e2e_gwas / e2e_mating_kinship / e2e_mating_ebv / e2e_gblup_cv / e2e_statsflow / e2e_spatial_sparse / e2e_gs_family_cv / e2e_batch_selection / e2e_ocs / e2e_mabc / e2e_gaps_base / e2e_gaps_engines / e2e_gaps_modules / e2e_prediction_rigor / e2e_inbreeding_depression / e2e_parent_validation / e2e_advanced_gblup / e2e_corr_spatial)。
- vue-tsc EXIT=0(前端 statistics/statistics.ts/genotype_call/index.vue 类型检查通过)。
- HTTP 核验(后端重启):
POST /bre/genotype_call/mendelian/check/run、POST /bre/statistics/data-quality(dataset_id)mendelian 段、POST /bre/statistics/ablup/run(block=True / block+gxe 409)、POST /bre/statistics/ocs。 - 备份镜像
Temp/claude/backup_block_mendelian_numerics_20260805/(18 文件按相对路径,收尾补 2 文件 → 20:更新版e2e_gaps_engines_20260804.py+http_v226.py)。 - 方法学保留:block 与 gxe/gxr 共用 Z₂ 槽故互斥(同一数据既跨环境又跨区组时用户二选一);孟德尔隔离可逆(数据修正/阈值提高再 run 自动解除);N2 探针与既有结构性探针互补(真值段独立 numpy 实现对照,fixture 良态设计避开小样本 REML 退化区)。
批5 跟进(2026-08-05,收尾):
- 回归首轮抓 1 处探针陈旧断言(非引擎回归):
e2e_gaps_engines_20260804.py:141断言blup.ENGINE_VERSION == "1.4.0",批5 已升 1.5.0 → 改断言1.5.0复跑通过(与批5 三处_DATA_VERSION同步同类机械性版本断言更新)。27 套件全量回归最终全部 exit=0。 - HTTP 核验完成(
Temp/claude/http_v226.py,后端重启后真实端点,ok=14 fail=0):POST /bre/genotype_call/mendelian/check/run200(check_id + isolated=1);GET /bre/genotype_call/mendelian/check只读预览零回归;POST /bre/statistics/data-quality(trait+dataset_id)mendelian 段 flagged=1 +summary.has_warning=True;POST /bre/statistics/ablup/run(block=True)200 → predictionmethod=ABLUP-BLOCK、model_name 前缀ABLUP_BLOCK_、note 含sigma_block/n_blocks=2;block+gxe / block+spatial 均 409(Z₂/残差互斥文案);POST /bre/statistics/ocs200(contributions 4 条和=2)。fixture 运行后自动清理(bre_mendelian_check/tree/pedigree_exclusion 0 残留)。 - 核验前需换新 token:
dpb_token.txt旧 token 过期(401「认证已失效」)→ 经POST /system/auth/login(super/123456)刷新(登录在 /system 前缀,不在 /bre)。
18.16 批6 规划↔目标↔试验 可追溯性闭环:plan/target/trial 三 FK + trace 端点 + 双删除守卫(2026-08-05,v2.27)
用户全代码库 grep 实证可追溯性缺口成立:
bre_plan是彻底孤立的根表(零传入外键,bre_trial无plan_id/target_id,无 project/program 表)。用户拍板「加试验挂目标」最小双链:bre_target.plan_id+bre_trial.plan_id(双链),另加bre_trial.target_id(试验挂目标)。_DATA_VERSIONv2.26→v2.27(statistics/service.py:97+genotype_call/service.py:45;5 处探针版本断言同步:e2e_prediction_rigor:102 / e2e_spatial_sparse:175+229 / e2e_statsflow:174 / e2e_mendelian_persist:207)。
- DB:新
backend/sql/weld_plan_trace.sql(幂等 ALTER 三列 + FK,已应用验证):bre_target.plan_idFK→bre_plan、bre_trial.plan_idFK→bre_plan、bre_trial.target_idFK→bre_target,均可空(历史孤目标/独立试验不受影响,可追溯性渐进式)。 - target 三件套:
TargetModel.plan_id+ relationship;schemaplan_id透传;get_list outerjoin 解析plan_name;create 父校验(plan_id 不存在 → 409,None 跳过);deleteassert_no_children(有 combo 子 → 409)。 - trial 三件套:
TrialModel.plan_id/target_id+ 双 relationship;schema 双字段透传;get_list 解析plan_name+target_name;create 双父校验(不存在 → 409,None 跳过);deleteassert_no_children(有 trial_study 子 → 409)。 - plan trace 端点:新
trace(plan_id)服务方法 +GET /bre/plan/trace/{id}——{plan, targets:[{…,n_combinations,n_trees,combinations:[{…,trees}]}], trials:[{…,target_name,n_trial_studies,n_trees,trial_studies:[{…,trees}]}], totals};组合/试验点软删过滤;孤目标不入链;不存在计划 409;plan.deleteassert_no_children(有 target/trial 子 → 409)。 - 前端:target/trial 表单「所属计划/目标」select(
res.data.data ?? [])+ 表格/详情列;plan 页「追溯」行操作弹窗(ElCollapse 目标链/试验链 + ElTags)。 - 探针
Temp/claude/e2e_plan_trace_20260805.py17 断言全过(目标链/试验链/totals/软删过滤/孤目标不入链/三父校验 409/双删除守卫 409/标签解析),自清理(含 bre_target 审计行)。 - 审计探针根治(本批排查修复):
e2e_audit_20260805.py残留检查原entity_id.in_(CREATED_TARGET_IDS)未限定entity_type,而entity_id按实体表各自序列非全局唯一(breeding_target_id_seq推进到 691 后,target id 与既有bre_cross_combination(669/685)/bre_germplasm(675) 审计行撞 id → 间歇误报「仍有残留 id=…」)→ 残留检查限定entity_type=='bre_target'(与 clean() 删除范围一致),连续 5 轮 13/13 稳定。
验证:新探针 17/17 + 全量回归零回归(60 套件,含批5 三探针零变化)+ vue-tsc EXIT=0。HTTP 核验(后端重启,Temp/claude/http_v227.py):GET /bre/plan/trace/{id}、target/trial create 带 plan_id/target_id、三父校验 409、双删除守卫 409。备份镜像 Temp/claude/backup_plan_trace_20260805/(按相对路径)。
18.17 批7 统计引擎全量十模块 golden 复查·系谱键空间错位修复(2026-08-05,v2.28)
用户质疑「GBLUP/ssGBLUP、genetic_corr、type_b、cluster、stability、OCS、MABC、inbreeding_depression、trial_design、mendelian 这批新建模块还没逐一数值校验(golden-test 缺失)。历史上 G–L 的静默失效都是靠校验才暴露的」。拍板「全量十项逐一复查」。复查确认 8/10 已 golden(GBLUP/ssGBLUP、cluster、stability、OCS、MABC、inbreeding_depression、trial_design、mendelian 既有探针已具严格数值断言),type_b 与 genetic_corr 补齐 golden 缺口——审计深处抓到真 bug 就地修 + 探针加回归。
_DATA_VERSIONv2.27→v2.28(statistics/service.py:97+genotype_call/service.py:45同步;4 处探针版本断言同步:e2e_spatial_sparse:175+229 / e2e_statsflow:174 / e2e_prediction_rigor:102 / e2e_mendelian_persist:207)。
根因(THE BUG):服务层把 int tree_id 表型键 传给 mtblup.solve_bivariate,而 _build_pedigree 系谱用 str "t{tree_id}"。blup.solve 的鲁棒逻辑(L382-385)把系谱外个体自动并入 base(视作无关 founder)→ 系谱被静默丢弃。平衡数据(同株跨环境提供协方差)掩盖;分裂家系数据(无同株跨环境、全同胞链跨站点桥接)暴露——int 键 → r_B/r_g 锁死 ±0.99(平剖面端点假收敛、假阴性负相关)。run_ablup 正确(L1020 phenos_keyed={f"t{tid}": v}),四个 mtblup 消费路径受影响。
修复:新增共享 helper _tree_individual_keys(d)(service.py:163,{tree_id:值}→{"t{tree_id}":值})收口四个调用点——_genetic_corr_matrix(L2214)/ _smith_hazel_index mtblup 分支(L2754)/ run_genetic_corr(L5122,喂 solve_multi 与 solve_bivariate,类型注解同步改 dict[str, dict[str, float]])/ run_type_b_heredity(L5294)。
探针 Temp/claude/e2e_rg_golden_20260805.py ok=21 fail=0——20 founder(10 母×10 父)、10 全同胞家系×3 同胞=30 株、3 站点、高遗传力良态设计(VA=4.0/VE=0.5,h²≈0.89,与批5-N2 良态设计经验一致);tY 分裂家系(站1=同胞0,1/站2=同胞2/站3=全株,真 r_B=0.8)+ tA/tB/tC 平衡(真 r_g AB=0.95、AC=BC=0)+ tS1/tS2 分裂家系(真 r_g=0.8):
- [P0 诊断]
solve_bivariate直接调用:str 键恢复 r_B=0.7+、int 键锁死 −0.99(RED 实证); - [P1 type_b golden] 服务端点 r_B(1,2)>0.5 + n_common=0(三站无共有树、靠全同胞系谱桥接——系谱生效的直接证据)+ 全正 min>0.3;
- [P2 correlation golden] r_g(A,B)>0.65、|r_g(AC/BC)|<0.4、判别间隙>0.3、h²∈(0,1);
- [P2b discriminator] r_g(S1,S2)>0.5(分裂家系无共有树,RED 下锁死 −0.99)。
探针自身缺陷修复:_simulate 初版 int 键 vs 观测循环 str 键 KeyError(统一 str 键)、种子扫描键错位(E0/E1/E2 vs E1/E2/E3 查键致 p2 空)、P2 间隙阈值过紧(r_g(B,C)=0.374 高抽样波动,阈值 0.4→0.3 重校准)、死 _build_ainv 占位行删除、exit-code 通道 bug(return ok==0 and fail==0 恒假,改 fail==0,断言 21/21 本就全过)。
验证:新探针 21/21 + e2e_statsflow(B1/B2,单家系 fixture 对键 bug 不敏感,15 断言零变化)+ e2e_advanced_mtblup(r_g=0.99/n_common=4/smith-hazel mtblup)回归通过 + 全量回归零回归(batches 1–3 + final,60 套件,含版本断言同步)+ vue-tsc EXIT=0。HTTP 核验(后端重启,Temp/claude/http_v228.py):POST /statistics/type-b-heredity(分裂家系 r_B(1,2)>0.5 + n_common=0 + data_version=v2.28)、POST /statistics/genetic-corr/run(tS1,tS2 分裂家系 r_g>0.5 + 平衡 tA,tB r_g>0.65)。备份镜像 Temp/claude/backup_keyspace_20260805/(按相对路径)。方法学保留:四个 mtblup 消费路径统一 str 键对齐系谱;探针 fixture 高遗传力 + 分裂家系结构保证判别力;run_ablup 正确路径不受影响。
18.18 回归基建:run_regression.py 统一回归 + 高风险模块正式 tc 套件(ssGBLUP/OCS/MABC/孟德尔)(2026-08-05,测试基建,不 bump 版本)
用户对批7 提出三点质疑,逐项核实全部成立,拍板「两者都要」——先建统一回归脚本把所有探针纳入(立即止血),再抽正式 tc 套件。纯测试基建,无后端代码改动,
_DATA_VERSION保持 v2.28:
- 全库
test_bre_*_tc.py(08-03)只覆盖「数据建链/导入导出/多波次」,对 GBLUP/ssGBLUP、OCS、MABC、近交衰退、试验设计、孟德尔检验这些新建分析模块零命中(full_tc 的 correlation 只是 GET 200 冒烟);- 19:55 改动(批7)未补 golden 测试——批7 探针建在 Temp/claude 一次性目录、无统一回归脚本;
- 风险:新模块若算偏(ssGBLUP 的 H⁻¹ 拼接、OCS 投影梯度收敛)会当「正常结果」输出——正是当年 G/I 静默失效的同款隐患(int-key bug 即活证据)。
统一回归脚本 run_regression.py(仓库根):glob Temp/claude/e2e_*.py(排除 e2e_probe* 探查工具)+ backend/scripts/test_bre_analysis_*_tc.py = 63 测试;顺序串跑不并发(历史 RC=124 机器争用超时前科);每测试独立子进程(cwd=os.path.dirname(p)、timeout=1800s)完整输出写 Temp/claude/regression_logs/<name>.log,控制台回显尾部 + EXIT;EXIT 汇总任一失败整体 exit≠0(供交付流程判断);DPB_PYTHON 环境变量覆盖解释器(须 dpb env python,基础 miniconda 缺 PEP 695 generics SyntaxError);sys.stdout.reconfigure(encoding="utf-8") 防 GBK 崩溃;过滤器 python run_regression.py gwas ocs;--keep-logs 保留日志。验证:全量 58/59 通过,唯一失败 gaps_engines 批量卡死(10 分钟无输出)单跑 RC=0 确认通过——机器争用非探针问题。
4 个正式 tc 套件(backend/scripts/,TestClient 走真实 API + lifespan,URL 带 /api/v1/bre/... 前缀,登录 super/123456 form)——高风险模块必测,fixture 自带清理:
test_bre_analysis_ssgblup_tc.pyok=14 fail=0:GBLUP vs ssGBLUP 同 fixture(5 株表型 + 基因型数据集:树0/1/3 直连、树2 名称兜底、树4 全多等位无有效剂量)。H⁻¹ 拼接判别核心——非基因型株(树4)GBLUP EBV=0 / ssGBLUP EBV≠0(若 H⁻¹=A⁻¹+[0;G⁻¹−A22⁻¹] 拼接错,非基因型亲属 EBV 为 0 或爆炸);h²∈(0,1)、5 条 EBV、全部有限。test_bre_analysis_ocs_tc.pyok=23 fail=0:8 种质(F1/F2/F3/D/E + A/B 全同胞 + C 半同胞)EBV 全 direct。Σc=3/c≥0/coverage direct 5/最高贡献 A≈1.419、vs_top_n mean_ebv 9.7667/avg_kinship 0.5556/c'Ac≈4.641、λ↑→avg_kinship 单调非增 [1.0,0.5157,0.3211,0.2685]、λ=0 满额投 A、kinship_status=partial+告警 D/E、n_select>候选/空候选→409、λ<0→422(schema 层 Pydantic ge=0 拦截)。test_bre_analysis_mabc_tc.pyok=24 fail=0:轮回亲本 + 6 候选(C6 童期)、前景 F1/F2 + 背景 M1-M4。前景命中/背景恢复率 100/75/0 复算、回交建议(晋级 BC2/再回交/维持)降序、童期 C6 晋级、轮回亲本无基因型 warning、target 越界→422(le=100 schema 校验)、其余 409。test_bre_analysis_mendelian_tc.pyok=9 fail=0:P1/P2 全 0/1→T1、P3/P4 全 0/0→T2(5 标记)。POST/bre/genotype_call/mendelian/check/run(下划线genotype_call,非连字符)落库 + T2 flag 进隔离注册表bre_pedigree_exclusion(source=mendelian/source_check_id)+ 阈值 0.0 重跑可逆(隔离行清除)+ GET 只读预览零回归;data_version=v2.28 落库。
tc 套件关键教训(写进探针防再犯):
- HTTP 语义差异:schema 层 Pydantic 校验(ge/le 约束)拦截 → 422;服务层 CustomException → 409(e2e 直调只见 409,tc 走 HTTP 见 422)——断言错误码须按路径定;
- Mapper 注册:
PlantingModel等 relationship 引用UserModel,tc 套件必须显式from app.api.v1.module_system.user.model import UserModel注册,否则 SQLAlchemyInvalidRequestError: expression 'UserModel' failed to locate a name; - 时序验证:孟德尔 tc 的隔离注册表断言必须在 run1 落库后、run2(阈值 0.0 清除)之前验证,否则必然 n=0 假失败;
- 启动残留预清理:
_wipe()按前缀清残留(防上次进程被杀/建 fixture 中途失败留下uq_bre_trait_code等唯一键脏数据),套件可重复跑。
验证:4 个 tc 套件 EXIT=0(14/23/24/9)+ 全量回归 58/59(gaps_engines 单跑确认)。备份镜像 Temp/claude/backup_test_rigor_20260805/(root/run_regression.py + backend/scripts 4 tc 套件)。交付流程:凡改动统计引擎/业务链后端代码,跑 python run_regression.py(dpb env 解释器)全量回归 EXIT=0 后方可交付;新 tc 套件命名 test_bre_analysis_<模块>_tc.py 由驱动自动纳入。
18.19 回归基建 2:分析模块 tc 补齐(5 套)+ pytest 接入 + 本机 CI stage(2026-08-05,测试基建,不 bump 版本)
用户对 §18.18 的 4 套 tc 认可后,继续补齐 5 个静默失效风险较低但属相关性/回归/生成器类的分析模块(genetic_corr / type_b_heredity / inbreeding_depression / trial_design / run_stability),并把 v8 验收标准定为「CI 跑通 pytest 全绿」。两条硬约束:① 基于真实 PostgreSQL 16 + Redis(工程无 SQLite,tc 全部在真实 PG+Redis 实跑);② 不做 GitHub Actions / 不登录 GitHub(全工程无 git 仓库,GitHub Actions 云端本机用不上)——CI stage 落地为本机驱动脚本
run_ci.py。纯测试基建,无后端代码改动,_DATA_VERSION保持 v2.28。
补齐 5 套 tc(backend/scripts/,TestClient 真实 API + -X utf8 + _wipe() 残留预清理 + 自带清理):
test_bre_analysis_genetic_corr_tc.pyok=19:平衡 3 性状(VA=4/VE=0.5,真 r_g AB=0.95/AC=BC=0,h²≈0.89)——matrix_json 对角 1/对称/r_g(AB)>0.65/|r_g(AC,BC)|<0.4/判别间隙>0.3/h²∈(0,1);分裂家系判别 tS1(测同胞 0/1)+tS2(测同胞 2):r_g(S1,S2)>0.5 且 n_common=0(无共有树,全同胞系谱桥接生效;rng 消耗序敏感性——S1/S2 用独立种子SEED_S=3(扫描 0-39 验证 r≈0.99)解耦自探针 tY-first 顺序);409×3。test_bre_analysis_type_b_tc.pyok=18:3 站点分裂家系(站1=同胞0/1×20 株/站2=同胞2×10/站3=全株×30):3 环境 envs_json 20/10/30、r_B(1,2)/r_B(1,3)/r_B(2,3)>0.5、min>0.3、n_common=0;复刻探针 tY-first rng 消耗序 → r=0.990;409×3(坏 trait/env_dim/method)。test_bre_analysis_inbreeding_tc.pyok=44:12 树(6×F=0 + 6 自交 dam==sire F=0.5),y=100−60F+ε → slope<−40/t<−3/r²>0.9/has_depression=true/高 F 前 6 自交株;无衰退 slope≈0 未检出;方向感知 asc 病指 y=10+40F slope>30(上升=指数型);deep 系谱 GP→G7/G8→H 树 F=0.125(mean_F≈0.0625);min_n=20 insufficient("12 棵"/"≥20")不 409;409+422。test_bre_analysis_trial_design_tc.pyok=25:增广 12 条目(9 新品系+3 对照)——新品系 3 区组×3 条不重复、对照 block_no=None 不落库(check_reps=3);α-格子平方 v=9 k=3 r=4(λ≤1、每 rep 可分解、warn=False)/ 部分 r=3 仍平衡 / v=16 k=4 非素数 warn=True / 一般 v=12 贪心(r 缺省=s=4);block_no=rep*100+block 复合编码 DB 读回(TestClient 退出后单一 asyncio.run 防嵌套 loop);409×4;教训:α-格子 r=4 会 case() 整表覆写 block_no——部分 r=3 重跑须在 r=4 之前,否则 DB 读回是部分态。test_bre_analysis_stability_tc.pyok=16:3 组合×3 站点 cell means C0=[0,6,12]/C1=[2,5,8]/C2=[4,4,4] → FW b≈2.0/1.0/−0.0、flag_stable C1=True 其余 False(|b−1|≤2se)、r²≈1(常量响应基因型 r²=None 合法);AMMI n=9、rank 按 ASV 升序、IPC1 占比 1.0≥IPC2、ss_interaction=36>0;engine_version 落库断言;year 维度 + 409×2(坏 methods/gxe_env)。
pytest 包装层 backend/tests/test_stat_analysis_tc.py:9 套 tc 各一个 pytest 测试(@pytest.mark.pg + parametrize),subprocess 顺序串跑真实脚本(镜像 run_regression 契约:DPB_PYTHON 覆盖、-X utf8、timeout=1800)。环境控制关键——包装层不 import 任何 app 模块(防 conftest sqlite 污染);subprocess env 显式构建:剥掉 conftest 注入的 DATABASE_TYPE/DATABASE_NAME/POOL_SIZE/MAX_OVERFLOW/CAPTCHA_ENABLE,置 ENVIRONMENT=dev/DATABASE_TYPE=postgres/PYTHONPATH=backend/PYTHONUTF8=1,再并入从 backend/env/.env.dev 解析的真实连接值(TC_CI_* 可覆盖验证 skipif 路径)。skipif 探测:asyncpg 连 PG + redis.asyncio ping;protocol=2 必须显式——redis-py 7.x 默认 RESP3,本机 WSL redis-server 版本较老 hello 报 ResponseError,与 app.core.database.redis_connect(Redis.from_url(...protocol=2))对齐即通;任一失败 pytest.skip。pyproject.toml 注册 pg marker(消 PytestUnknownMarkWarning);conftest.py 加 collect_ignore_glob=["../scripts/test_*.py"] 防收集 import 独立脚本污染 sqlite 环境。
本机 CI stage run_ci.py(仓库根):step 0 探测真实 PG16+Redis(asyncpg + redis.asyncio protocol=2,失败给明确指引并 exit≠0);step 1 pytest -m pg(dpb python + -X utf8,cwd=backend)跑 9 套;step 2 汇总 EXIT=0 →「✅ CI 全绿」;日志写 Temp/claude/ci_logs/。与 run_regression 并存(run_regression=手动全量回归 / run_ci=验收门)。
验证:5 套逐个 EXIT=0(19+18+44+25+16=122 断言);pytest -m pg 9 passed(真实 PG+Redis,146s,含既有 4 套零回归);skipif 路径(TC_CI_DB_PORT=1 指错端口)9 skipped 不红、无 unknown-marker 警告、scripts 未被收集(88 collected/79 deselected/9 pg);run_ci.py EXIT=0「CI 全绿」;run_regression.py test_bre_analysis glob 自动纳入 9 套。备份镜像 Temp/claude/backup_analysis_tc2_20260805/。交付流程:v8 验收 = python run_ci.py EXIT=0(或 cd backend && pytest -m pg 全绿);改动统计引擎/业务链后端仍跑 python run_regression.py 全量。
18.20 O2–O4 统计方法学广度:幼年–成年遗传相关 + 非线性基因组预测 + 约束选择指数(2026-08-05,v2.29)
用户系统核对统计引擎能力后确认三项 P2 方法学缺口(均零命中、不影响当前业务正确性,属统计方法库广度),拍板「O2–O4 先落地」+ 两项决策:① O4 用经典 Kempthorne–Nordskog =0 闭式解(纯 numpy 不迭代);② 前后端同步扩展。方法学扩展 →
_DATA_VERSIONv2.28 → v2.29、genomic.ENGINE_VERSION1.3.0 → 1.4.0。无新表:O2 复用bre_type_b_result(env_dim 自由字段)、O3 复用bre_prediction/bre_prediction_value(method 标签扩展)、O4 复用bre_selection_index(result_json 已含 extra)。
O2 幼年–成年遗传相关(env_dim="stage"):_values_by_tree_env(service.py:324)加 stage 分支——coalesce(obs.stage, TraitModel.stage) 分组(观测缺省继承 bre_trait.stage)、group_by 含 coalesce 表达式、同树同阶段多次观测取均值;run_type_b_heredity env_dim 校验扩 ("site","year","stage")。发育阶段当"环境"→ 逐对 mtblup.solve_bivariate REML 精确估幼-成遗传相关 r_g(>0.5 表示童期可借力成株、早期间接选择有效)。前端 Type-B 页签 env_dim 下拉加「stage=发育阶段(幼/成)」。
O3 非线性基因组预测(genomic 1.4.0):
solve_rrblup(service 5774 分派):岭回归逐标记 y=μ+Xu+e,u=(Xc'Xc+λI)⁻¹Xc'yc,λ 由剖面 REML σa²/σe² 定(σu²=σa²/c、c=2Σp(1-p)),EBV=Xc·u+μ —— 与 GBLUP 数学对偶(G=XcXc'/c 时闭式解 ĝ=G(G+λa·I)⁻¹yc+μ 逐位吻合,探针 1.42e-13);输出 marker effects(GBLUP 无的解释能力)+ PEV 可靠性近似。solve_bayesb:BayesB Gibbs 可变选择——δ_jBernoulli(1−π)+方差尺度混合、σ²jinv-χ²(df_s+1,(df_s·scale0+u_j²)/(df_s+1))、σe²~inv-χ²(df_e+m,...),numpy.random.default_rng(seed)确定性(MLOps 铁律:同 seed 两次 EBV 逐位一致);π 默认 0.95、稀疏 QTL 场景取 0.7 更贴合 30% QTL 真值。kfold_cv_genomic加 dosage/markers 分派:rrblup/bayesb 折内走对应求解器(实证 CV);run_cvGS 分支透传 seed + genotypes + markers,method_name=KFCV/RRBLUP·KFCV/BayesB。run_gblupmethod 扩("gblup","ssgblup","rrblup","bayesb")+ seed 透传,rrblup/bayesb 从_gather_gblup_inputsdosage 构 X →asyncio.to_thread引擎,落PredictionModel(method=RRBLUP/BayesB)+PredictionValueModel(EBV/rel/pa/rank)、engine_version=1.4.0。前端 GBLUP/CV 页签 method radio 加 RRBLUP/BayesB + seed 输入。
O4 约束选择指数(restricted 闭式解 + economic weights):
_smith_hazel_index加restricted_traits/economic_weights。受限时 Kempthorne-Nordskog Lagrange 闭式投影:C(第 j 行=第 j 个受限性状单位向量)、M = C'(C·G·P⁻¹·G·C')⁻¹·C·G·P⁻¹·G、b = P⁻¹·G·(I−M)·a → 约束 C·G·b=0 ⇔ 受限性状 ΔG=0(纯 numpy pinv,不迭代)。对照旧公式 M=C'(C·P⁻¹·C')⁻¹·C·P⁻¹ 实测 ΔG=4.46 不满足 → 修正必要(e2e O4-1c 断言锁定)。- economic_weights 直接作 a(绝对尺度、不归一化统计权重、未列性状按 0 不进聚合基因型),可与 restricted 叠加;
direction=asc仍翻转 a[i](b=P⁻¹Ga 线性于 a → 保证该性状 b 相对下降,(P⁻¹G)₀₀>0 保号,非必 sign flip——tc 断言用严格下降)。 - extra 落
restricted/constraint_mode=ΔG=0/economic+ warnings;method 校验扩("zsum","smith_hazel","restricted")、缺 restricted_traits 409、restricted_traits ⊆ cols(越界 409)、economic_weights 性状 ⊆ tmap。落库 method=SI_RES。前端指数页 method radio 加 restricted + restricted_traits 多选 + 每性状经济权重输入。
顺手修复(tc 暴露的既有缺口):cv_detail 折明细 dict 缺 cv_result_id(CvFoldOut 必填字段)→ 任意 GET /cv/{id} 400(既有 tc 均未触达该端点,静默失效风险同款);补 "cv_result_id": cv_id 后 rrblup/bayesb CV 详情可查。
验证:e2e_o234_20260805.py 探针 19 断言(O3 对偶逐位 1.42e-13 + marker effects + BayesB 可复现 + kfold 5 折;O4 受限 ΔG=0 机器精度 + 旧公式失败 + economic asc 翻转;O2 真实 PG 16 树 r_g=0.6145);正式 tc test_bre_analysis_o234_tc.py ok=41 fail=0(TestClient 真实 API + golden:O2 env_dim=stage r_g=0.8995/n_common=12/双阶段 12 株/data_version=v2.29;O3 落库 method+engine_version 1.4.0/bayesb 同 seed 两次逐位一致/rrblup·GBLUP EBV 相关 1.000/CV 折数=5/非法 method 409;O4 restricted b_受限=0.0/economic desc>0·asc<0/缺 restricted_traits 409)+ TC_SCRIPTS 注册第 10 套 + 全量回归零回归(61 e2e + 10 tc)+ run_ci.py EXIT=0「CI 全绿」。备份镜像 Temp/claude/backup_o234_20260805/。
十、文件清单与备份
新增/修改文件(2026-08-03)
| 文件 | 说明 |
|---|---|
backend/app/api/v1/module_bre/statistics/service.py |
G×E 引擎 + 异步任务 + 门禁(含 blup.solve 传参) |
backend/app/api/v1/module_bre/statistics/model.py |
StatisticsJobModel(job_type/status/error_msg/result_ref) |
Temp/claude/e2e_gxe_20260803.py |
G×E e2e 探针(5 场景) |
新增/修改文件(2026-08-04)
| 文件 | 说明 |
|---|---|
backend/sql/weld_trait_direction.sql |
幂等 ALTER 三列 |
backend/sql/bre_trait_seed.sql |
种子数据含三新列(43 行) |
backend/app/api/v1/module_bre/trait/model.py / schema.py / service.py |
三字段透传 + 批量导入导出兼容 |
backend/app/api/v1/module_bre/statistics/service.py |
方向翻转 + into_ebv 剔除 + default_h2 兜底 + 排行/对比方向修复 |
backend/app/api/v1/module_bre/statistics/controller.py |
selection_only query 参数 |
frontend/web/src/api/module_bre/statistics.ts |
listTraits 带 selection_only |
frontend/web/src/views/module_bre/statistics/index.vue |
selTraits 解耦 + asc 角标 |
frontend/web/src/views/module_bre/trait/index.vue |
三字段表单/表格/详情/搜索 |
frontend/web/src/views/module_bre/selection_rule/index.vue |
规则 JSON 说明 |
Temp/claude/e2e_direction_20260804.py |
方向标注 e2e 探针(7 组) |
新增/修改文件(2026-08-04 无性系级指数)
| 文件 | 说明 |
|---|---|
backend/app/api/v1/module_bre/statistics/schema.py |
SelectionIndexIn.aggregate(clone 默认 / tree)+ 文件头补 UTF-8 编码声明 |
backend/app/api/v1/module_bre/statistics/controller.py |
selection_index 透传 data.aggregate |
backend/app/api/v1/module_bre/statistics/service.py |
_clone_units 可靠加权聚合 + 自株退化;zsum/Smith-Hazel 改单元 key 排名;apply_selection 按遗传实体写(clone_id + 溯源株 + 系内N株)+ 幂等晋升建 clone |
frontend/web/src/api/module_bre/statistics.ts |
selectionIndex data 加 aggregate |
frontend/web/src/views/module_bre/statistics/index.vue |
聚合粒度 radio + clone 结果列 |
Temp/claude/e2e_clone_index_20260804.py |
无性系级指数 e2e 探针(6 组) |
新增/修改文件(2026-08-04 配合力交配设计)
| 文件 | 说明 |
|---|---|
backend/sql/weld_combining_design.sql |
幂等 ALTER:bre_cross_combination / bre_combining_ability 加 design_type |
backend/app/api/v1/module_bre/cross_combination/model.py / schema.py / service.py |
design_type 字段 + create/update 校验归一化 + 导出/导入/模板兼容 |
backend/scripts/breeding_stats/combining.py |
solve(rows, design_type) 按设计分支:双列 model A / line_tester+NCIII model B(双因素、顺序 ANOVA、角色重叠/NCIII 门禁、gca_se) |
backend/app/api/v1/module_bre/statistics/controller.py / schema.py / service.py |
run_combining 透传 design_type + 按设计过滤 + 落库 + anova.gca_se |
frontend/web/src/api/module_bre/statistics.ts / cross_combination.ts |
design_type 类型透传 |
frontend/web/src/views/module_bre/statistics/index.vue / cross_combination/index.vue |
运行对话框设计选择 + 结果分显示 + CRUD 四处支持 |
Temp/claude/e2e_combining_design_20260804.py |
配合力交配设计 e2e 探针(5 组) |
新增/修改文件(2026-08-04 统计严谨·预测完整性与 MLOps 复现性)
| 文件 | 说明 |
|---|---|
backend/sql/weld_prediction_rigor.sql |
幂等 ALTER:bre_prediction_value.pa + bre_prediction.data_version/input_hash/engine_version |
backend/sql/weld_rootstock.sql |
幂等 ALTER:bre_rootstock.dwarf_class/compatibility |
backend/app/api/v1/module_bre/statistics/model.py / schema.py |
pa/data_version/input_hash/engine_version 字段 + OutSchema 透出 |
backend/app/api/v1/module_bre/statistics/service.py |
_DATA_VERSION="v2.7";PA 落库 + 批次真 PA;输入哈希(确定性序列化);germplasm_id 回填;Calo 相关校正(rel_by_trait + g_corr/g_note);covariate="competition"(Chebyshev 邻域 + G×E 泛化 + 无坐标报错) |
backend/scripts/breeding_stats/blup.py |
ENGINE_VERSION="1.0.0" |
backend/app/api/v1/module_bre/rootstock/model.py / schema.py / service.py |
dwarf_class/compatibility 字段 + 导入导出/模板下拉 |
frontend/web/src/api/module_bre/statistics.ts |
指数批次表/EBV 行类型加 germplasm_id/pa |
frontend/web/src/views/module_bre/statistics/index.vue |
批次表新列 + 协变量 radio(无/crop_load/competition) |
frontend/web/src/api/module_bre/rootstock.ts |
Rootstock 类型加两字段 |
frontend/web/src/views/module_bre/rootstock/index.vue |
两字段全量(常量/搜索/表格/详情/表单) |
Temp/claude/e2e_prediction_rigor_20260804.py |
②③④ e2e 探针(4 组) |
Temp/claude/e2e_rootstock_20260804.py |
⑤ e2e 探针 |
Temp/claude/e2e_corr_spatial_20260804.py |
①⑥ e2e 探针(3 组) |
backend/sql/weld_combination_funnel.sql |
幂等建 v_combination_funnel(六级聚合普通 VIEW) |
backend/app/api/v1/module_bre/statistics/service.py / controller.py |
combination_funnel() 查视图 + GET /statistics/combination-funnel |
Temp/claude/e2e_combination_funnel_20260804.py |
组合得失漏斗 e2e 探针(3 组) |
新增/修改文件(2026-08-04 分子育种建数据能力)
| 文件 | 说明 |
|---|---|
backend/sql/weld_molecular.sql |
幂等补 bre_genotype_sample.sample_name + (dataset_id, sample_name) 索引 |
backend/sql/bre_menu.sql |
900210-900213 切真实页面 + F 段按钮 900700-900799 + 角色关联 |
backend/app/api/v1/module_bre/marker/ |
五件套(marker_name UNIQUE 校验、CRUD/导入导出/模板) |
backend/app/api/v1/module_bre/genotype_dataset/ |
五件套(v1.4 规划表首次建服务) |
backend/app/api/v1/module_bre/genotype_sample/ |
五件套(dataset FK 校验 + dataset_name 透出) |
backend/app/api/v1/module_bre/genotype_call/ |
五件套 + import_vcf + fingerprint_check 两个专属端点 |
backend/app/api/v1/module_bre/__init__.py |
注册 4 组路由 |
frontend/web/src/api/module_bre/marker.ts |
MarkerAPI |
frontend/web/src/api/module_bre/genotype_dataset.ts |
GenotypingDatasetAPI |
frontend/web/src/api/module_bre/genotype_sample.ts |
GenotypeSampleAPI |
frontend/web/src/api/module_bre/genotype_call.ts |
GenotypeCallAPI + VCF/指纹接口与结果类型 |
frontend/web/src/views/module_bre/marker/index.vue |
标记 CRUD 页 |
frontend/web/src/views/module_bre/genotype_dataset/index.vue |
数据集 CRUD 页 |
frontend/web/src/views/module_bre/genotype_sample/index.vue |
样本 CRUD 页(dataset 下拉) |
frontend/web/src/views/module_bre/genotype_call/index.vue |
分型 CRUD 页 + 导入 VCF / 指纹检测对话框 |
Temp/claude/e2e_molecular_20260804.py |
分子育种 e2e 探针(CRUD/唯一键/父级/指纹/VCF/幂等) |
新增/修改文件(2026-08-04 精修项四连发:DUS 数据能力 + stage 感知 + k-fold CV + 公平性报告)
| 文件 | 说明 |
|---|---|
backend/sql/weld_refine.sql |
幂等 ALTER:bre_prediction.stage varchar(16) + COMMENT |
backend/sql/bre_dus_seed.sql |
UPOV TG/53 桃描述符 15 条种子(trait_code LEFT JOIN 解析 trait_id,ON CONFLICT DO NOTHING) |
backend/sql/bre_menu_refine.sql |
900230 切真实页 + G 段按钮 900800-900808 + 角色关联 |
backend/app/api/v1/module_bre/dus/ |
五件套 ×3 资源(descriptor 9 端点含导入导出模板 / test 9 / observation 6),注册 /bre/dus_test/* |
backend/app/api/v1/module_bre/statistics/model.py |
PredictionModel.stage + CvResultModel + CvFoldModel(create_all 建表) |
backend/app/api/v1/module_bre/statistics/schema.py |
PredictionOut.stage + CvRunIn/CvResultOut/CvFoldOut + SelectionIndexIn/DecisionPreviewIn.stage |
backend/app/api/v1/module_bre/statistics/service.py |
_trait_meta_map 取 stage;run_ablup 落 stage;run_cv/list_cv/cv_detail;fairness_report;selection_index/decision_preview stage 过滤 + stage_warning/skipped_stage |
backend/app/api/v1/module_bre/statistics/controller.py |
/statistics/cv/run /statistics/cv /statistics/cv/{id} /statistics/fairness + 指数/决策 stage 透传 |
backend/scripts/breeding_stats/blup.py |
kfold_cv:sire 家系分层留出 + 逐折 try/except + 留出 EBV 系谱预测 |
frontend/web/src/api/module_bre/dus.ts |
三组 API + 类型 |
frontend/web/src/api/module_bre/statistics.ts |
runCv/listCv/cvDetail/fairnessReport + listTraits 补 stage |
frontend/web/src/views/module_bre/dus/index.vue |
单页三 tab(描述符模板/DUS 测试/观测录入) |
frontend/web/src/views/module_bre/statistics/index.vue |
「交叉验证」「公平性报告」双 tab + 指数/决策 stage 三态 + stage_warning ElAlert |
Temp/claude/e2e_refine_20260804.py |
精修项四连发 e2e 探针(4 组,ABLUP/GXE CV + 2 site 公平性) |
新增/修改文件(2026-08-04 六项能力完善:MT-BLUP + GBLUP/ssGBLUP + DUS 特异性 + AMMI/FW 稳定性 + MLOps 重训 + stage 拆分)
| 文件 | 说明 |
|---|---|
backend/sql/weld_advanced.sql |
幂等 ALTER:bre_prediction.is_active + bre_trait_observation.stage + bre_dus_test.analysis_json(jsonb)+ COMMENT |
backend/app/api/v1/module_bre/statistics/model.py |
PredictionModel.is_active + GeneticCorrResultModel + StabilityResultModel(create_all 建 2 新表) |
backend/app/api/v1/module_bre/statistics/schema.py |
GeneticCorrIn/GeneticCorrResultOut/StabilityRunIn/StabilityResultOut/GblupRunIn + SelectionIndexIn.g_method + RunStatsIn.stage + PredictionOut.is_active/stage |
backend/app/api/v1/module_bre/statistics/service.py |
run_genetic_corr/list/detail、run_stability/list/detail、run_gblup/list_genotyping_datasets、model_drift/retrain/activate、run_ablup(stage)、_gather_digest_inputs、_smith_hazel_index(g_method);修复未定义 tid、retrain 不激活新批次 |
backend/app/api/v1/module_bre/statistics/controller.py |
6 组新端点(genetic-corr×3 / stability×3 / gblup×2 / model drift·retrain·activate×3)+ 透传 g_method/stage |
backend/app/api/v1/module_bre/dus/service.py |
distinctness 求解器 + test_distinctness/distinctness_report(落 analysis_json + conclusion 自动建议) |
backend/app/api/v1/module_bre/dus/controller.py / schema.py |
POST/GET /bre/dus_test/distinctness/{test_id} + DusTestOutSchema.analysis_json |
backend/app/api/v1/module_bre/trait_observation/model.py / schema.py / service.py |
stage 字段(model 列 + create/update/out schema 透传 + 导入/导出映射,schema 暴露为收尾补丁) |
backend/scripts/breeding_stats/mtblup.py |
solve_bivariate(成对双性状 REML,ENGINE_VERSION=1.0.0) |
backend/scripts/breeding_stats/genomic.py |
build_g_matrix/solve_gblup/solve_ssgblup(ENGINE_VERSION=1.0.0;修复 V 块用 H 协方差) |
backend/scripts/breeding_stats/stability.py |
finlay_wilkinson/ammi(ENGINE_VERSION=1.0.0;修复完美拟合 flag_stable) |
backend/scripts/breeding_stats/fdist.py |
f_icdf(二分反解)+ t_crit |
backend/scripts/breeding_stats/blup.py |
ENGINE_VERSION="1.1.0" |
frontend/web/src/api/module_bre/statistics.ts |
三 tab 组 API + modelDrift/Retrain/Activate + g_method/stage 类型 |
frontend/web/src/views/module_bre/statistics/index.vue |
「遗传相关 MT-BLUP」「稳定性 AMMI/FW」「基因组选择 GBLUP」三 tab + stage 三态 + g 矩阵来源 radio + 当前版本标签/漂移/重训/回滚按钮 |
frontend/web/src/views/module_bre/dus/index.vue |
测试行「特异性判定」对话框 |
frontend/web/src/api/module_bre/tree_evaluation.ts / views/module_bre/tree_evaluation/index.vue |
观测表单「观测阶段」下拉(juvenile/evaluation,写入每条观测 stage) |
Temp/claude/e2e_advanced_stability.py / stage.py / mtblup.py / gblup.py / dus.py / mlops.py |
6 组 e2e 探针(运行后自动清理) |
doc/桃育种系统模块扩展需求规格.md |
v2.10 版本行 + §8.18 台账 |
doc/桃育种系统模块扩展需求规格.v2.10.md |
冻结快照 |
doc/桃育种系统统计引擎实施记录.md |
§十一 六项能力完善 + 文件清单/备份/复跑 |
doc/桃育种系统规划对照总表.md |
header ⑨ + EBV/分子行更新 |
新增/修改文件(2026-08-04 田间试验精度补强:砧木×接穗随机互作 G×R)
| 文件 | 说明 |
|---|---|
backend/scripts/breeding_stats/blup.py |
_solve_gxe 加 factor_label/factor_name 参数(仅喂警告文案,默认保 G×E 不变)+ 公开 solve() 透传 + ENGINE_VERSION 1.2.0 |
backend/app/api/v1/module_bre/statistics/schema.py |
RunStatsIn.gxr |
backend/app/api/v1/module_bre/statistics/controller.py |
run_ablup 透传 gxr |
backend/app/api/v1/module_bre/statistics/service.py |
run_ablup(gxr):互斥门禁 + job_type=GXR + elif gxr: 分支(rootstock 剥离/门禁三件套/GXRBLUP/note σ²gxr)+ 克隆坍缩系谱上移共享 + _DATA_VERSION v2.10 |
frontend/web/src/api/module_bre/statistics.ts |
RunStatsPayload.gxr |
frontend/web/src/views/module_bre/statistics/index.vue |
G×R 复选框 + 互斥 watcher + fmtGxeNote σ²gxr 分支 + 批次表 v-if |
Temp/claude/e2e_gxr_20260804.py |
e2e 探针(4 组断言,运行后自动清理) |
doc/桃育种系统模块扩展需求规格.md |
v2.11 版本行 + §8.19 台账 |
doc/桃育种系统模块扩展需求规格.v2.11.md |
冻结快照 |
doc/桃育种系统统计引擎实施记录.md |
§十二 G×R 落地 + 文件清单/备份/复跑 |
doc/桃育种系统规划对照总表.md |
header ⑩ + EBV/田间试验精度行补 G×R |
新增/修改文件(2026-08-04 基因组选择实证严谨性:GS 专用 k-fold CV)
| 文件 | 说明 |
|---|---|
backend/scripts/breeding_stats/genomic.py |
抽取 _build_h(缺失基因型补 base)+ 新增 kfold_cv_genomic(掩蔽留出 pearson/RMSE,输出对齐 blup.kfold_cv)+ ENGINE_VERSION 1.1.0 |
backend/app/api/v1/module_bre/statistics/service.py |
_gather_gblup_inputs 提取(run_gblup↔GS CV 复用);run_cv 加 dataset_id/method/maf_min + GS 分支(与 gxe/ABLUP 互斥)+ engine_version 按分支 + _DATA_VERSION v2.11 |
backend/app/api/v1/module_bre/statistics/schema.py |
CvRunIn.dataset_id/method/maf_min |
backend/app/api/v1/module_bre/statistics/controller.py |
run_cv 透传三参 |
frontend/web/src/api/module_bre/statistics.ts |
CvRunPayload.dataset_id/method/maf_min |
frontend/web/src/views/module_bre/statistics/index.vue |
CV tab mode radio(ABLUP/GS)+ dataset/method/MAF + 隐藏 G×E + submitCv 按 mode |
Temp/claude/e2e_gblup_cv_20260804.py |
GS CV e2e 探针(3 组:GBLUP/ssGBLUP 正例 + 门禁,运行后自动清理) |
doc/桃育种系统模块扩展需求规格.md |
v2.12 版本行 + §8.20 台账 |
doc/桃育种系统模块扩展需求规格.v2.12.md |
冻结快照 |
doc/桃育种系统统计引擎实施记录.md |
§十三 GS k-fold 落地 + 文件清单/备份/复跑 |
doc/桃育种系统规划对照总表.md |
header ⑪ + EBV/GS 行补「GS k-fold 实证验证」 |
新增/修改文件(2026-08-04 现代桃育种领域覆盖:S-allele + 抗病/需冷量性状)
| 文件 | 说明 |
|---|---|
backend/sql/bre_disease_chilling_traits.sql |
5 条 numeric trait 种子(3 抗病 0-5 级病情指数 + 需冷量 h + 需热量 GDD,into_ebv=1、direction=asc,幂等 ON CONFLICT) |
backend/app/api/v1/module_bre/germplasm/model.py |
s_alleles 列(String(32),Sf=自交亲和型) |
backend/app/api/v1/module_bre/germplasm/schema.py |
Create/Update 加 s_alleles(Out 继承 Create) |
backend/app/api/v1/module_bre/cross_combination/schema.py |
CrossCombinationOutSchema.s_compat(可选派生字段) |
backend/app/api/v1/module_bre/cross_combination/service.py |
_parse_s_alleles/_s_compat_check/_check_s_compat + create/update 校验(Sf 放行、共享 2→409、共享 1→半兼容警示) |
frontend/web/src/api/module_bre/germplasm.ts |
GermplasmForm/GermplasmTable.s_alleles? |
frontend/web/src/views/module_bre/germplasm/index.vue |
表单加 S-等位基因输入 + 导出列 |
frontend/web/src/views/module_bre/cross_combination/index.vue |
包装 createApi/updateApi 展示 s_compat 警示 |
Temp/claude/e2e_s_allele_20260804.py |
S-allele 兼容校验探针(纯函数 8 例 + service 层 5 组,运行后自动清理) |
doc/桃育种系统模块扩展需求规格.md |
v2.13 版本行 + §8.21 台账 |
doc/桃育种系统模块扩展需求规格.v2.13.md |
冻结快照 |
doc/桃育种系统统计引擎实施记录.md |
§十四 落地 + 文件清单/备份/复跑 |
doc/桃育种系统规划对照总表.md |
header ⑫ + 相关行补「S-allele 兼容 + 抗病/需冷量性状字典」 |
新增/修改文件(2026-08-04 GWAS/QTL/MAS 标记辅助选择闭环)
| 文件 | 说明 |
|---|---|
backend/scripts/breeding_stats/gwas.py |
GWAS 求解器(GLM+PC:SVD 群体结构 + fdist.f_pvalue p 值 + Bonferroni/BH-FDR + QTL 合并 + 岭回归共线兜底,ENGINE_VERSION=1.0.0,纯 numpy) |
backend/sql/weld_gwas.sql |
幂等 CREATE TABLE IF NOT EXISTS:bre_gwas_result/bre_gwas_snp/bre_qtl/bre_mas_panel/bre_mas_panel_marker(5 新表兜底) |
backend/sql/bre_menu.sql |
§6d:sys_menu 900214 component_path 翻转为 module_bre/gwas/index |
backend/app/api/v1/module_bre/statistics/model.py |
GwasResultModel/GwasSnpModel/QtlModel/MasPanelModel/MasPanelMarkerModel |
backend/app/api/v1/module_bre/statistics/schema.py |
GwasRunIn/GwasResultOut/GwasSnpOut/QtlIn/QtlOut/MasPanelIn/MasPanelOut/MasPanelMarkerIn/MasPanelSetMarkersIn |
backend/app/api/v1/module_bre/statistics/controller.py |
gwas×3 + qtl×5 + mas-panel×4 端点(复用 module_bre:statistics:* 权限) |
backend/app/api/v1/module_bre/statistics/service.py |
_gather_gwas_inputs + run_gwas/list_gwas/gwas_detail + qtl/mas_panel CRUD + mas_panel_set_markers + _mas_hit_map + decision_preview marker 条件 + _DATA_VERSION v2.12 |
frontend/web/src/api/module_bre/gwas.ts |
runGwas/listGwas/gwasDetail + Qtl/MasPanel/MasPanelMarker API |
frontend/web/src/views/module_bre/gwas/index.vue |
三 tab(GWAS 结果 Manhattan/QQ 裸 echarts + QTL 定位 + MAS 面板)+ 运行对话框 |
Temp/claude/e2e_gwas_20260804.py |
GWAS/QTL/MAS 闭环探针(7 段断言,运行后自动清理;含数据设计要点避免 PC 吞噬 QTL) |
doc/桃育种系统模块扩展需求规格.md |
v2.14 版本行 + §8.22 台账 |
doc/桃育种系统模块扩展需求规格.v2.14.md |
冻结快照 |
doc/桃育种系统统计引擎实施记录.md |
§十五 落地 + 文件清单/备份/复跑 |
doc/桃育种系统规划对照总表.md |
header ⑬ + 900214 行「GWAS/QTL 已落地」 |
新增/修改文件(2026-08-04 九缺口补齐:经典侧计算端点 + 分子侧严谨性 + 求解器核心)
| 文件 | 说明 |
|---|---|
backend/app/api/v1/module_bre/statistics/controller.py |
POST /data-quality + POST /genetic-gain + POST /mating-recommend + POST /gwas-qtl-x-e |
backend/app/api/v1/module_bre/statistics/service.py |
data_quality_report/genetic_gain/mating_recommend/qtl_x_e + _allelic_from_gt/装配 marker_type 分支 + _DATA_VERSION v2.13 |
backend/app/api/v1/module_bre/statistics/schema.py |
4 新端点入参出参 + RunStatsIn.spatial 等 |
backend/scripts/breeding_stats/blup.py |
solve_spatial(AR1×AR1,ENGINE_VERSION 1.3.0)+ _build_ainv_sparse/_cg_solve/Hutchinson(N_SPARSE=1000 阈值分派稀疏-CG 路径,稠密路径逐字节不变) |
backend/scripts/breeding_stats/gwas.py |
_emmax + 后处理抽共享 _bh_qvalues/_finalize/_cluster(GLM 逐字节不变,ENGINE_VERSION 1.1.0) |
backend/scripts/breeding_stats/genomic.py |
build_g_matrix 多等位 VanRaden 推广(ENGINE_VERSION 1.2.0) |
backend/app/api/v1/module_bre/genotype_call/service.py |
VCF 导入按 ALT 数定 marker_type(ssr/snp) |
backend/sql/weld_mas_semantics.sql |
幂等 ADD COLUMN:bre_mas_panel_marker.mode / favorable_allele / haplotype_group |
frontend/web/src/views/module_bre/statistics/index.vue |
数据质量/遗传增益/选配 3 入口 + spatial 复选框 |
frontend/web/src/api/module_bre/statistics.ts |
3 新端点 + spatial 参数 |
frontend/web/src/views/module_bre/gwas/index.vue |
method 下拉(gwas/emmax)+ QTL×E tab + 面板标记编辑器三控件(xeForm 类型断言修复 vue-tsc) |
frontend/web/src/api/module_bre/gwas.ts |
GwasQtlXEIn + method 枚举 |
Temp/claude/e2e_data_mating_gain_20260804.py |
批1 探针(数据质量/遗传增益/选配,运行后自动清理) |
Temp/claude/e2e_molrigor_20260804.py |
批2 探针(EMMAX/SSR/QTL×E/MAS 语义,运行后自动清理) |
Temp/claude/e2e_spatial_sparse_20260804.py |
批3 探针(AR1×AR1/稀疏-CG/Hutchinson,运行后自动清理) |
doc/桃育种系统模块扩展需求规格.md |
v2.15 版本行 + §8.23 台账(+ 补 v2.13 缺失版本行) |
doc/桃育种系统模块扩展需求规格.v2.15.md |
冻结快照 |
doc/桃育种系统统计引擎实施记录.md |
§十六 落地 + 文件清单/备份/复跑 |
doc/桃育种系统规划对照总表.md |
header ⑭ + EBV/ABLUP 行、GWAS/QTL/MAS 行补注 |
新增/修改文件(2026-08-05 十二项真缺口补齐:引擎三件 + 模块四件 + 底座五件)
| 文件 | 说明 |
|---|---|
backend/scripts/breeding_stats/blup.py |
solve_spatial 加 aniso(ρ_row/ρ_col 双参,ENGINE_VERSION 1.4.0) |
backend/scripts/breeding_stats/mtblup.py |
solve_multi 全多变量 EM-REML(ENGINE_VERSION 1.1.0) |
backend/scripts/breeding_stats/gwas.py |
_ssgwas 单步 GWAS MEM 对角近似(ENGINE_VERSION 1.2.0) |
backend/app/api/v1/module_bre/statistics/service.py |
full_mtblup=True 模式 + _DATA_VERSION v2.14 + _allelic_columns SSR 兜底限定空 marker_type(回归修复) |
backend/app/api/v1/module_bre/field_operation/{model,crud,service,controller,schema}.py |
农事操作 900051 五件套 |
backend/app/api/v1/module_bre/observation/{model,crud,service,controller,schema}.py |
通用观测 900050 五件套 |
backend/app/api/v1/module_bre/breeding_report/{model,crud,service,controller,schema}.py |
育种报告 900075 五件套 + POST /report/generate |
backend/app/api/v1/module_bre/analysis_dataset/{model,crud,service,controller,schema}.py |
分析数据集 900070 五件套 + 新表 bre_analysis_dataset |
backend/app/api/v1/module_bre/audit/{model,crud,service,controller,schema}.py |
审计切面 + `GET /bre/audit/list |
backend/app/api/v1/module_bre/alert/{model,crud,service,controller,schema,job}.py |
超期预警 + `GET /bre/alert/list |
backend/app/api/v1/module_bre/brapi/controller.py |
BrAPI 2.x /brapi/v2 五只读端点 + MIAPPE |
backend/app/utils/number_gen.py |
NumberGenService + pg_advisory_xact_lock 原子取号 |
backend/app/api/v1/module_bre/sequence/model.py |
bre_sequence 表 |
backend/app/api/v1/module_bre/{cross_combination,tree,selection_result,seedling}/service.py |
4 处编号迁移(YY+3位/组合-序号/clone_code 扩位/batch_no YP-…) |
backend/app/core/ap_scheduler.py |
3 系统 job(cleanup Sun 03:00 / alert 08:37 / backup 02:17) |
backend/app/utils/backup_job.py |
每日备份 job 包装 pg_backup.sh(Git Bash + MSYS 路径) |
backend/scripts/pg_backup.sh / pg_restore.sh |
pg_dump 自定义格式 + N 天轮转 / 恢复脚本 |
backend/app/init_app.py |
brapi_router 根注册(/brapi/v2 非 /bre 前缀) |
backend/sql/weld_*.sql(op_type 字典/菜单翻转/文案清理/bre_alert/bre_sequence/bre_analysis_dataset) |
幂等 weld 兜底 |
frontend/web/src/views/module_bre/{field_operation,observation,breeding_report,analysis_dataset,alert}/index.vue |
4 新模块页 + 预警中心 |
frontend/web/src/api/module_bre/{field_operation,observation,breeding_report,analysis_dataset,alert}.ts |
5 新 API |
frontend/web/src/views/module_bre/statistics/index.vue |
spatial aniso 复选框 + gwas method=ssgwas 下拉 |
Temp/claude/e2e_gaps_engines_20260804.py |
批1 探针(ssgwas/solve_multi/aniso,运行后自动清理) |
Temp/claude/e2e_gaps_modules_20260805.py |
批2 探针(四模块 CRUD + report generate + 菜单翻转,运行后自动清理) |
Temp/claude/e2e_gaps_base_20260804.py |
批3 探针(审计/编号并发/预警/备份/BrAPI,运行后自动清理) |
Temp/claude/regress_logs/ |
全量回归日志(8 旧探针 + 3 批探针) |
doc/桃育种系统模块扩展需求规格.md |
v2.16 版本行 + §8.24/8.25/8.26 台账 |
doc/桃育种系统模块扩展需求规格.v2.16.md |
冻结快照 |
doc/桃育种系统统计引擎实施记录.md |
§十七 落地 + 文件清单/备份/复跑 |
doc/桃育种系统规划对照总表.md |
header ⑮ + 相关行补注 + 过时「待建」标记修正 |
新增/修改文件(2026-08-05 桃育种业务流全面完善:批A 业务数据链 + 批B 统计算法 + 批C 前端)
| 文件 | 说明 |
|---|---|
backend/app/api/v1/module_bre/field_operation/model.py |
4 采收列 yield_kg/fruit_count/avg_fruit_weight/marketable_rate |
backend/app/api/v1/module_bre/field_operation/{service,schema}.py |
harvest 结构化产量同步 bre_trait_observation(A1)+ 表单 4 字段 |
backend/app/api/v1/module_bre/observation/model.py |
germplasm_id 可空 FK(A3) |
backend/app/api/v1/module_bre/observation/{service,schema}.py |
种质校验 + EAV 校验(A5)+ 4 查询过滤 tree/plot/germplasm/trial_study + germplasm 表单字段 |
backend/app/api/v1/module_bre/seed_lot/{model,schema}.py |
pollination_id FK(A4) |
backend/app/api/v1/module_bre/seed_treatment/{model,schema}.py |
seed_lot_id FK(A4) |
backend/app/api/v1/module_bre/tree/service.py |
create 阶段自动设置(A6,breeding_generation→juvenile/evaluation) |
backend/app/api/v1/module_bre/trait_observation/service.py |
EAV 校验(numeric/date parse + valid_min/max + 重复)+ 成株性状门禁(A5/A6) |
backend/app/api/v1/module_bre/statistics/service.py |
_values_by_tree_env + run_type_b_heredity(B1)+ _genetic_corr_matrix(B2)+ auto_weights(B3)+ run_cluster(B4)+ _DATA_VERSION v2.15 |
backend/app/api/v1/module_bre/statistics/controller.py |
POST /type-b-heredity + GET /type-b + GET /type-b/{id} + POST /cluster + correlation mode/g_method/year 透传 |
backend/app/api/v1/module_bre/statistics/schema.py |
TypeBIn/Out + CorrelationIn mode/g_method/year + SelectionIndexIn auto_weights + ClusterIn |
backend/app/api/v1/module_bre/statistics/model.py |
bre_type_b_result 新表(TypeBResultModel) |
backend/sql/weld_busflow.sql |
A1/A3/A4 四处 ALTER ADD COLUMN IF NOT EXISTS + index(幂等) |
backend/sql/bre_yield_phenology_traits.sql |
A2 产量/物候/品质/生长量/描述性状种子 19 条(ON CONFLICT 幂等) |
frontend/web/src/plugins/echarts.ts |
注册 HeatmapChart + VisualMapComponent |
frontend/web/src/api/module_bre/statistics.ts |
type-b/cluster/correlation mode/funnel/auto_weights 类型 |
frontend/web/src/api/module_bre/observation.ts |
ObservationPageQuery 四过滤 + ObservationForm germplasm_id |
frontend/web/src/api/module_bre/field_operation.ts |
FieldOperationTable/Form 四采收字段 |
frontend/web/src/views/module_bre/observation/index.vue |
plot/站点/germplasm 过滤 + germplasm 表单(C1) |
frontend/web/src/views/module_bre/field_operation/index.vue |
harvest 结构化表单/表格 4 列(C1) |
frontend/web/src/views/module_bre/statistics/index.vue |
correlation/gblup 热图折线 + type-B tab + cluster 树状图 + funnel 对话框(C2/C3) |
frontend/web/src/views/module_bre/stage_phenotype/index.vue |
tabs 通用观测/农事操作翻真实页(C4) |
frontend/web/src/views/module_bre/_shared/StageView.vue |
compMap 注册 Observation/FieldOperation(C4) |
Temp/claude/e2e_busflow_20260805.py |
批A 探针(A1-A6,11 组断言,运行后自动清理) |
Temp/claude/e2e_statsflow_20260805.py |
批B 探针(B1-B4,15 组断言,运行后自动清理) |
Temp/claude/smoke_busflow_c_20260805.py |
批C HTTP smoke(10 检查,不建数据) |
doc/桃育种系统模块扩展需求规格.md |
v2.17 版本行 + §8.27 台账 |
doc/桃育种系统模块扩展需求规格.v2.17.md |
冻结快照 |
doc/桃育种系统统计引擎实施记录.md |
§十八 落地 + 文件清单/备份/复跑 |
doc/桃育种系统规划对照总表.md |
header ⑯ + 相关行补注 |
新增/修改文件(2026-08-05 世代闭环:单株晋级落系谱)
| 文件 | 说明 |
|---|---|
backend/app/api/v1/module_bre/selection_result/service.py |
_promote_tree_to_clone 建种质时同步落 bre_pedigree(child_code=品种名、dam/sire=tree.dam/sire 回退组合 female/male_parent_id、combination_id、generation,child_code 幂等)+ 种质携带 generation/stage + combo=None 初始化防 UnboundLocalError |
Temp/claude/e2e_pedigree_closure_20260805.py |
世代闭环探针(11 组断言,运行后自动清理) |
Temp/claude/cleanup_pedigree_test.py |
前缀清理脚本(幂等,探针残留兜底) |
新增/修改文件(2026-08-05 近交惩罚静默关闭修复:亲缘矩阵多源解析)
| 文件 | 说明 |
|---|---|
backend/app/api/v1/module_bre/statistics/service.py |
重写 _germplasm_pedigree 多源级联(① 规范化名称反查显式系谱 → ② tree FK 兜底唯一一致 → ③ founder;BFS 祖先展开去重;返回 (pedigree, coverage));mating_recommend 加 kinship_status/kinship_warning/kinship + 逐对「亲缘未解析(r 按 0 计)」旗标 |
Temp/claude/e2e_mating_kinship_20260805.py |
近交惩罚静默关闭修复探针(14 组断言,运行后自动清理) |
新增/修改文件(2026-08-05 EBV 回退方法学修复:direct 优先 + 子代测验降权)
| 文件 | 说明 |
|---|---|
backend/app/api/v1/module_bre/statistics/service.py |
mating_recommend EBV 回退重写——direct 优先(有 direct 绝不被树级值污染);回退显式标注 progeny + _EBV_SOURCE_FACTOR 降权 0.5 参与打分(mid=(f_a·ebv_a+f_b·ebv_b)/2);双亲均缺直接值的子代树剔除(防双侧等权重复计);记 n_progeny/n_combos;返回体加 candidate_ebv + ebv_source.coverage + 逐对旗标 |
Temp/claude/e2e_mating_ebv_20260805.py |
EBV 回退方法学修复探针(5 组断言,运行后自动清理) |
新增/修改文件(2026-08-05 数据质量离群值方向语义错位修复:同向=精英 / 反向=疑似错误)
| 文件 | 说明 |
|---|---|
backend/app/api/v1/module_bre/statistics/service.py |
data_quality_report 方向感知分流——取 trait_row.direction(desc/None→desirable_high=True 高值优;asc→False);IQR/MAD 命中的株按偏离侧双通道分类(is_high=v>med、is_elite=is_high==desirable_high):同向→extreme_candidates(class=extreme_candidate)/ 反向→outliers(class=outlier);返回体加 direction + extreme_candidates + summary.n_extreme_candidates;has_warning/n_outliers/outlier_rate 语义收紧为疑似录入错误计数 |
frontend/web/src/views/module_bre/statistics/index.vue |
数据质量 tab 改双表——「极值候选(精英)」success 标签表 + 「疑似录入错误」danger 标签表 + 选育方向指示条 + 无错误绿色 info alert(提示文案改方向语义) |
Temp/claude/e2e_data_mating_gain_20260804.py |
A6 探针 [1] 扩展——17 株(15 正常 + 精英高值 16.0 + 错误低值 2.0):精英进 extreme_candidates/class=extreme_candidate/side=high 且不在 outliers;错误进 outliers/class=outlier/side=low;n_extreme_candidates=1 |
新增/修改文件(2026-08-05 ΔG 投影假设声明 + 工程健壮性打磨:note 假设 + spatial 缺坐标降级 + numpy 收敛)
| 文件 | 说明 |
|---|---|
backend/app/api/v1/module_bre/statistics/service.py |
① genetic_gain 返回体加 note 投影假设声明(环境均值恒定/演示值);② run_ablup(spatial=True) 缺坐标株记 missing_coord_ids → 剔除表型保留系谱(EBV 由系谱预测)、剔除数写批次 note「缺坐标剔除N株表型(EBV由系谱预测)」、全缺才整批 409、input_hash 用剔除后子集;③ 模块级 import numpy as np(:24)+ 移除 7 处局部 import;data_quality_report 逐株 flag 循环改 numpy 布尔掩码向量化(输出逐字节不变) |
frontend/web/src/views/module_bre/statistics/index.vue |
gain tab 描述区后、轮次表前加 el-alert type="info" 展示 gainData.note(投影假设边界) |
Temp/claude/e2e_spatial_sparse_20260804.py |
spatial 探针新增强健降级场景——5 株(4 株 2×2 网格 + 1 株无坐标):method=AR1×AR1/train_n=4/note 含剔除标注/5 株均有 EBV 行;全缺坐标仍整批 409;trait 清理含 tD_{P} |
Temp/claude/e2e_data_mating_gain_20260804.py |
A6 探针 [2] 加 note 断言——含「环境均值恒定」且两性状稳定一致 |
新增/修改文件(2026-08-05 A–F 六项功能级缺口·批1 父本验证 + 近交衰退)
| 文件 | 说明 |
|---|---|
backend/app/api/v1/module_bre/pollination/service.py |
A1 _validate_pollen_parent(create/update 统一:批次采集父本≠授粉父本 409,混合/未声明放行) |
backend/app/api/v1/module_bre/tree/service.py |
A2 _resolve_parents 改返回 (dam, sire, warning) + create/update 返回体 warning(以显式为准,不阻断) |
backend/app/api/v1/module_bre/tree/schema.py |
`warning: str |
backend/app/api/v1/module_bre/cross_combination/service.py |
A3 _check_parent_roles 同质自交 409(create/update 生效亲本统一) |
backend/app/api/v1/module_bre/statistics/schema.py |
InbreedingDepressionIn(trait_id/trait_code + year/trial_study_id + min_n) |
backend/app/api/v1/module_bre/statistics/controller.py |
POST /bre/statistics/inbreeding-depression |
backend/app/api/v1/module_bre/statistics/service.py |
inbreeding_depression(F=A_ii−1 + 树级表型均值 → numpy lstsq 回归,F=0 兜底)+ _DATA_VERSION v2.22 |
frontend/web/src/api/module_bre/statistics.ts |
inbreedingDepression API |
frontend/web/src/views/module_bre/statistics/index.vue |
亲缘/近交 tab 近交衰退区(trait/year + el-alert + el-descriptions + 高 F 株表;el-alert 'error' 修复 TS2322) |
Temp/claude/e2e_parent_validation_20260805.py |
批1-A 父本验证探针(10 断言,运行后自动清理) |
Temp/claude/e2e_inbreeding_depression_20260805.py |
批1-C 近交衰退探针(4 断言,运行后自动清理) |
doc/桃育种系统模块扩展需求规格.md |
v2.22 版本行 + §8.32 台账 |
doc/桃育种系统模块扩展需求规格.v2.22.md |
冻结快照 |
doc/桃育种系统统计引擎实施记录.md |
§18.10 落地 + 文件清单/备份/复跑 |
doc/桃育种系统规划对照总表.md |
header ⑳ + 相关行补注 |
新增/修改文件(2026-08-05 A–F 六项功能级缺口·批2 GS 家系 CV + 试验设计深度)
| 文件 | 说明 |
|---|---|
backend/scripts/breeding_stats/genomic.py |
B kfold_cv_genomic 加 `split="random" |
backend/app/api/v1/module_bre/statistics/schema.py |
AnovaIn.block(RCBD 区组校正开关)+ TrialDesignIn(trial_study_id/design_type/seed) |
backend/app/api/v1/module_bre/statistics/controller.py |
POST /bre/statistics/trial-design + run_anova 透传 block |
backend/app/api/v1/module_bre/statistics/service.py |
run_cv 加 split 透传 + GS family_of 构建 + note 记 n_families;trial_design RCBD 生成器(random.Random(seed) 洗牌 + case() 批量落库);run_anova 加 block 分支(solve_rcbd);_DATA_VERSION v2.23 |
backend/scripts/breeding_stats/anova.py |
F2 solve_rcbd(RCBD 双因素 Type I 顺序,SS_group/SS_block/SS_error + f_block/p_block + 区组均值;solve 单因素逐字节不变) |
backend/app/api/v1/module_bre/trial_study_entry/model.py |
F1 block_no 列(可空 integer) |
backend/sql/weld_trial_study_entry.sql |
F1 ALTER TABLE bre_trial_study_entry ADD COLUMN IF NOT EXISTS block_no integer(幂等) |
frontend/web/src/api/module_bre/statistics.ts |
runAnova 加 block + trialDesign() + TrialDesignResult |
frontend/web/src/views/module_bre/statistics/index.vue |
ANOVA tab 重构(生成 RCBD 设计工具条 + 设计区组表 + anovaBlock checkbox + 区组均值/block 结果 v-if) |
Temp/claude/e2e_trial_design_20260805.py |
批2-F 探针(5 组断言,运行后自动清理) |
Temp/claude/e2e_gs_family_cv_20260805.py |
批2-B 探针(5 组断言,运行后自动清理) |
doc/桃育种系统模块扩展需求规格.md |
v2.23 版本行 + §8.33 台账 |
doc/桃育种系统模块扩展需求规格.v2.23.md |
冻结快照 |
doc/桃育种系统统计引擎实施记录.md |
§18.11 落地 + 文件清单/备份/复跑 |
doc/桃育种系统规划对照总表.md |
header ㉒ + 相关行补注 |
新增/修改文件(2026-08-05 A–F 六项功能级缺口·批3 OCS 最优贡献选择 + MABC 标记辅助回交)
| 文件 | 说明 |
|---|---|
backend/app/api/v1/module_bre/statistics/service.py |
D _proj_simplex/_solve_ocs + ocs(投影梯度,A=pedigree+rmat 组装,vs_top_n 对比);共享 helper _candidate_ebv_map 抽取(mating_recommend 内联原样提取,direct/progeny 降权 0.5/双侧去重保留);E _pure_homologous + mabc_progress(前景 _mas_hit_map + 背景恢复率 + _BC_LADDER 晋级建议);_DATA_VERSION v2.24 |
backend/app/api/v1/module_bre/statistics/controller.py |
POST /bre/statistics/ocs + POST /bre/statistics/mabc-progress |
backend/app/api/v1/module_bre/statistics/schema.py |
OcsIn(candidate_germplasm_ids/n_select/lam/prediction_id)+ MabcIn(candidate_tree_ids/foreground_panel_ids/background_panel_ids/recurrent_parent_tree_id/foreground_min_hits/generation/background_target)均 extra="ignore" |
frontend/web/src/api/module_bre/statistics.ts |
ocs() + mabcProgress() API |
frontend/web/src/views/module_bre/statistics/index.vue |
「选配推荐」tab OCS 运行区(n_select + λ 滑杆 + contribution 表 + vs_top_n 对比)+ 独立「回交 MABC」tab(面板/轮回亲本/候选树 + 参数 + 逐株结果 + recommended 降序表) |
Temp/claude/e2e_ocs_20260805.py |
批3-D OCS 探针(17 断言,运行后自动清理;λ 梯度/退化/partial 告警/三 409) |
Temp/claude/e2e_mabc_20260805.py |
批3-E MABC 探针(23 断言,运行后自动清理;前景/背景复算/reason/童期/六 409) |
doc/桃育种系统模块扩展需求规格.md |
v2.24 版本行 + §8.34 台账 |
doc/桃育种系统模块扩展需求规格.v2.24.md |
冻结快照 |
doc/桃育种系统统计引擎实施记录.md |
§18.12 落地 + 文件清单/备份/复跑 |
doc/桃育种系统规划对照总表.md |
header ㉓ + 相关行补注 |
新增/修改文件(2026-08-05 近交衰退两处正确性修复:方向感知 + 深层系谱)
| 文件 | 说明 |
|---|---|
backend/app/api/v1/module_bre/statistics/service.py |
inbreeding_depression 方向感知检测(desirable_high=direction!="asc",asc 衰退=slope>0 且 t≥+1.645,interpretation 方向化)+ 深层系谱 F(复用 _germplasm_pedigree BFS + 树节点 + 未解析 founder 兜底;_germplasm_pedigree 本体零改动) |
frontend/web/src/views/module_bre/statistics/index.vue |
近交衰退提示文案方向化(「高优性状显著负斜率 / 低优性状(如病指)显著正斜率 = 近交衰退」) |
Temp/claude/e2e_inbreeding_depression_20260805.py |
批1-C 近交衰退探针扩展 4→6 组断言(新增 [4] asc 病指方向感知 + [5] 深层系谱 F 多世代;原 [1][2][3][x] 保持) |
doc/桃育种系统模块扩展需求规格.md |
§8.35 跟进台账 |
doc/桃育种系统统计引擎实施记录.md |
§18.13 跟进 + 文件清单/备份/复跑 |
新增/修改文件(2026-08-05 分子亲本验证 + 试验设计深度·批4)
| 文件 | 说明 |
|---|---|
backend/app/api/v1/module_bre/genotype_call/service.py |
mendelian_check(子代 vs 声明亲本 union 规则、跨数据集亲本基因型解析、no_declared_parents/missing_parent_genotype 状态、incompatible_markers 明细)+ _allele_set 复用 + import TreeModel |
backend/app/api/v1/module_bre/genotype_call/controller.py |
GET /bre/genotype_call/mendelian/check(Auth module_bre:genotype_call:query,Query dataset_id + compat_threshold=0.98,镜像 fingerprint/check) |
backend/app/api/v1/module_bre/statistics/service.py |
trial_design 分派 rcbd/augmented/alpha(rcbd 逐字节不变)+ _trial_design_augmented(对照 anchoring/新品系 round-robin/对照 block_no 不落库)+ _trial_design_alpha(平方闭式格子 + 一般贪心可分解 + _is_prime + balance_warning + block_no 复合编码)+ _DATA_VERSION v2.25 |
backend/app/api/v1/module_bre/statistics/schema.py |
TrialDesignIn 加 check_germplasm_ids: list[int]=[] / block_size: int|None / reps: int|None(extra="ignore")+ design_type 描述改 rcbd/augmented/alpha |
backend/app/api/v1/module_bre/statistics/controller.py |
trial_design 透传三新参 + summary 更新「RCBD/增广/α-格子(落库 block_no)」 |
frontend/web/src/api/module_bre/genotype_call.ts |
mendelianCheck() + GenotypeCallMendelianParams/Result/Tree/IncompatMarker 类型 |
frontend/web/src/views/module_bre/genotype_call/index.vue |
工具栏「孟德尔/亲本一致性」按钮 + FaDialog(dataset select + compat_threshold + summary 计数 + trees 表 tree_no/dam/sire/informative/rate/flag/incompatible_markers 展开) |
frontend/web/src/api/module_bre/statistics.ts |
trialDesign design_type 枚举扩 augmented/alpha + check_germplasm_ids/block_size/reps + TrialDesignResult 加 checks/n_new_entries/n_checks/check_reps/block_size/reps/balance_warning + blocks 联合类型 |
frontend/web/src/views/module_bre/statistics/index.vue |
DESIGN_TYPE_LABELS 补 增广/α-格子 + 条件参数(augmented 对照多选 / alpha block_size+reps)+ α-格子平衡性 el-alert + alpha 块渲染「重复{rep}·块{blk}」 |
Temp/claude/e2e_mendelian_check_20260805.py |
批4-A 探针(8 断言:跨数据集解析/alien 等位/rate/状态/空数据集零值,运行后自动清理) |
Temp/claude/e2e_trial_design_ext_20260805.py |
批4-B 探针(19 断言:增广/平方格子/部分 r/非素数告警/一般贪心/四 409,运行后自动清理) |
doc/桃育种系统模块扩展需求规格.md |
v2.25 版本行 + §8.36 台账 |
doc/桃育种系统统计引擎实施记录.md |
§18.14 落地 + 文件清单/备份/复跑 |
doc/桃育种系统规划对照总表.md |
相关行补注(分子育种 mendelian + 试验设计行增广/α-格子) |
新增/修改文件(2026-08-05 批5 区组随机效应 + 孟德尔落库隔离 + 统计引擎数值校验)
| 文件 | 说明 |
|---|---|
backend/scripts/breeding_stats/blup.py |
solve 加 block 参数分派新 _solve_block(区组第二随机效应,镜像 _solve_gxe)+ ENGINE_VERSION 1.5.0 |
backend/app/api/v1/module_bre/statistics/service.py |
run_ablup block 开关 + block 分支(block_no 读取/降级剔除/≥2 区组 409)+ 互斥(block×gxe/gxr/spatial)+ data_quality_report dataset_id 可选 + mendelian 段 + _excluded_tree_ids 系谱消费方断链(_build_pedigree/run_ablup/inbreeding/kinship/cv/_germplasm_pedigree)+ _DATA_VERSION v2.26 |
backend/app/api/v1/module_bre/statistics/schema.py |
RunAblupIn.block + DataQualityIn.dataset_id |
backend/app/api/v1/module_bre/statistics/controller.py |
run_ablup block 透传 + data-quality dataset_id 透传 |
backend/app/api/v1/module_bre/genotype_call/model.py |
MendelianCheckModel→bre_mendelian_check + MendelianCheckTreeModel→bre_mendelian_check_tree(FK CASCADE) |
backend/app/api/v1/module_bre/genotype_call/service.py |
纯计算核心抽共享 _compute_mendelian + 新 run_mendelian_check(落库 + flag upsert 隔离/未 flag 清除,可逆) |
backend/app/api/v1/module_bre/genotype_call/controller.py |
新 POST /bre/genotype_call/mendelian/check/run(Auth edit,GET 只读预览保留) |
backend/app/api/v1/module_bre/tree/model.py |
TreePedigreeExclusionModel→bre_pedigree_exclusion(tree_id 唯一) |
frontend/web/src/api/module_bre/statistics.ts |
RunAblupPayload.block + DataQualityPayload.dataset_id |
frontend/web/src/api/module_bre/genotype_call.ts |
mendelianCheckRun + GenotypeCallMendelianRunResult(check_id/isolated/cleared) |
frontend/web/src/views/module_bre/statistics/index.vue |
GxE tab block 开关 + 互斥 + 数据质量 tab dataset 选择器 + mendelian 段(flag alert + 隔离树表) |
frontend/web/src/views/module_bre/genotype_call/index.vue |
孟德尔对话框主按钮改 POST run + check_id/隔离树数展示 |
Temp/claude/e2e_ablup_block_20260805.py |
批5-A 探针(6 场景:已知 σ²block 恢复/409 门禁/互斥/降级/无归零警告) |
Temp/claude/e2e_mendelian_persist_20260805.py |
批5-B 探针(ok=19 fail=0:落库/隔离断开 EBV/可逆清除/data-quality 段/只读零回归) |
Temp/claude/e2e_stats_numerics_20260805.py |
批5-C 探针(ok=101 fail=0:全量统计引擎逐段 ground-truth 真值) |
doc/桃育种系统模块扩展需求规格.md |
v2.26 版本行 + §8.37 台账 |
doc/桃育种系统统计引擎实施记录.md |
§18.15 落地 + 文件清单/备份/复跑 |
doc/桃育种系统规划对照总表.md |
相关行补注(孟德尔落库隔离 + block 随机效应 + 统计引擎数值校验) |
新增/修改文件(2026-08-05 批6 规划↔目标↔试验 可追溯性闭环)
| 文件 | 说明 |
|---|---|
backend/sql/weld_plan_trace.sql |
幂等 ALTER 三列 + FK:bre_target.plan_id、bre_trial.plan_id、bre_trial.target_id(均可空) |
backend/app/api/v1/module_bre/target/model.py |
TargetModel.plan_id + relationship |
backend/app/api/v1/module_bre/target/schema.py |
TargetCreateSchema/TargetUpdateSchema.plan_id 透传 |
backend/app/api/v1/module_bre/target/service.py |
get_list outerjoin 解析 plan_name + create 父校验(坏 plan_id 409)+ delete assert_no_children |
backend/app/api/v1/module_bre/trial/model.py |
TrialModel.plan_id/target_id + 双 relationship |
backend/app/api/v1/module_bre/trial/schema.py |
双字段透传 |
backend/app/api/v1/module_bre/trial/service.py |
get_list 解析 plan_name+target_name + create 双父校验 + delete assert_no_children |
backend/app/api/v1/module_bre/plan/service.py |
新 trace(plan_id)(目标链/试验链/软删过滤/totals)+ delete assert_no_children |
backend/app/api/v1/module_bre/plan/controller.py |
新 GET /bre/plan/trace/{id} |
frontend/web/src/api/module_bre/plan.ts |
PlanTrace 类型 + getPlanTrace |
frontend/web/src/api/module_bre/target.ts |
getTargetOptions |
frontend/web/src/views/module_bre/target/index.vue |
「所属计划」select + 表格/详情列 |
frontend/web/src/views/module_bre/trial/index.vue |
「所属计划/目标」select + 表格/详情列 |
frontend/web/src/views/module_bre/plan/index.vue |
「追溯」行操作弹窗(ElCollapse 目标链/试验链) |
Temp/claude/e2e_plan_trace_20260805.py |
批6 探针(17 断言:目标链/试验链/totals/软删/孤目标/父校验/删除守卫/标签解析) |
Temp/claude/e2e_audit_20260805.py |
残留检查限定 entity_type=='bre_target'(跨表撞 id 误报根治) |
doc/桃育种系统模块扩展需求规格.md |
v2.27 版本行 + §8.38 台账 |
doc/桃育种系统统计引擎实施记录.md |
§18.16 落地 + 文件清单/备份/复跑 |
doc/桃育种系统规划对照总表.md |
㉖ 批6 可追溯性闭环补注 |
新增/修改文件(2026-08-05 批7 统计引擎全量十模块 golden 复查·系谱键空间错位修复)
| 文件 | 说明 |
|---|---|
backend/app/api/v1/module_bre/statistics/service.py |
新增共享 helper _tree_individual_keys(int→"t{id}" 对齐系谱键空间)+ 四个调用点收口(_genetic_corr_matrix/_smith_hazel_index mtblup 分支/run_genetic_corr/run_type_b_heredity)+ _DATA_VERSION v2.28 |
backend/app/api/v1/module_bre/genotype_call/service.py |
GENOTYPE_DATA_VERSION v2.28 |
Temp/claude/e2e_rg_golden_20260805.py |
批7 探针(ok=21 fail=0:type_b 分裂家系 golden + correlation 平衡 golden + 分裂家系 discriminator + str/int 键诊断;含 exit-code 通道修复 fail==0) |
Temp/claude/e2e_spatial_sparse_20260804.py |
版本断言 v2.27→v2.28(×2) |
Temp/claude/e2e_statsflow_20260805.py |
版本断言 v2.27→v2.28 |
Temp/claude/e2e_prediction_rigor_20260804.py |
版本断言 v2.27→v2.28 |
Temp/claude/e2e_mendelian_persist_20260805.py |
版本断言 v2.27→v2.28 |
Temp/claude/http_v228.py |
批7 HTTP 核验(type-b-heredity 分裂家系 r_B>0.5/n_common=0 + genetic-corr/run 分裂家系 r_g>0.5 + 平衡 r_g>0.65) |
doc/桃育种系统模块扩展需求规格.md |
v2.28 版本行 + §8.39 台账 |
doc/桃育种系统统计引擎实施记录.md |
§18.17 落地 + 文件清单/备份/复跑 |
doc/桃育种系统规划对照总表.md |
㉗ 批7 系谱键空间错位修复补注 |
新增/修改文件(2026-08-05 回归基建:统一回归 + 高风险模块 tc 套件,无后端代码改动)
| 文件 | 说明 |
|---|---|
run_regression.py |
统一回归驱动:顺序串跑 Temp/claude/e2e_.py(排除 e2e_probe)+ backend/scripts/test_bre_analysis_*_tc.py = 63 测试,每测试独立子进程 log 到 regression_logs/,EXIT 汇总;DPB_PYTHON 覆盖解释器;utf-8 reconfigure 防 GBK;过滤器 + --keep-logs |
backend/scripts/test_bre_analysis_ssgblup_tc.py |
正式 tc 套件(ok=14):GBLUP/ssGBLUP H⁻¹ 拼接判别——非基因型株 GBLUP EBV=0 / ssGBLUP EBV≠0(算偏当正常输出的同款隐患判别) |
backend/scripts/test_bre_analysis_ocs_tc.py |
正式 tc 套件(ok=23):OCS 投影梯度 golden(Σc/c≥0/λ 单调/c'Ac/λ=0 退化/409+422) |
backend/scripts/test_bre_analysis_mabc_tc.py |
正式 tc 套件(ok=24):MABC 前景/背景恢复率/晋级/童期 C6/422+409 |
backend/scripts/test_bre_analysis_mendelian_tc.py |
正式 tc 套件(ok=9):孟德尔 POST run 落库/隔离注册表/阈值 0.0 可逆/GET 零回归(URL 下划线 genotype_call + 启动残留预清理 _wipe + 隔离验证时序) |
Temp/claude/backup_test_rigor_20260805/ |
备份镜像(root/run_regression.py + backend/scripts 4 tc 套件最新修复版) |
新增/修改文件(2026-08-05 回归基建 2:分析模块 tc 补齐 + pytest 接入 + run_ci,无后端代码改动)
| 文件 | 说明 |
|---|---|
backend/scripts/test_bre_analysis_genetic_corr_tc.py |
正式 tc 套件(ok=19):平衡 3 性状 r_g 判别 + 分裂家系 r_g(S1,S2)>0.5 且 n_common=0(独立种子 SEED_S=3) |
backend/scripts/test_bre_analysis_type_b_tc.py |
正式 tc 套件(ok=18):Type-B 3 站点分裂家系 r_B>0.5 且 n_common=0(复刻 tY-first rng 序 → 0.990)+ 三 409 |
backend/scripts/test_bre_analysis_inbreeding_tc.py |
正式 tc 套件(ok=44):近交衰退方向感知(衰退/无/上升)+ deep 系谱 F=0.125 + min_n insufficient + 422/409 |
backend/scripts/test_bre_analysis_trial_design_tc.py |
正式 tc 套件(ok=25):增广(对照 block_no=None 不落库)+ α-格子(平方 λ≤1/非素数告警/一般贪心)+ block_no=rep*100+block DB 读回 + 四 409 |
backend/scripts/test_bre_analysis_stability_tc.py |
正式 tc 套件(ok=16):AMMI/FW b 斜坡 + flag_stable + ASV rank + engine_version 落库 + year 维度 + 二 409 |
backend/tests/test_stat_analysis_tc.py |
pytest 包装层:9 套 tc @pytest.mark.pg + subprocess 串跑 + skipif 探测真实 PG16+Redis(protocol=2)+ env 显式构建(剥 conftest 污染、解析 .env.dev、TC_CI_* 覆盖) |
backend/pyproject.toml |
[tool.pytest.ini_options] 注册 pg marker(消 PytestUnknownMarkWarning) |
backend/tests/conftest.py |
加 collect_ignore_glob=["../scripts/test_*.py"] 防 pytest 收集独立脚本污染 sqlite 环境 |
run_ci.py |
本机 CI stage:step 0 探测 PG16+Redis(失败指引+exit≠0)→ step 1 pytest -m pg → step 2 EXIT=0「CI 全绿」,日志 Temp/claude/ci_logs/ |
Temp/claude/backup_analysis_tc2_20260805/ |
备份镜像(root/run_ci.py + backend/scripts 9 tc 套件 + backend/tests/test_stat_analysis_tc.py + pyproject/conftest diff) |
新增/修改文件(2026-08-05 O2–O4 统计方法学广度,v2.29)
| 文件 | 说明 |
|---|---|
backend/scripts/breeding_stats/genomic.py |
ENGINE_VERSION 1.4.0:solve_rrblup(岭回归逐标记 + marker effects + 对偶)+ solve_bayesb(BayesB Gibbs,确定性 seed 可复现)+ kfold_cv_genomic dosage/markers 分派 rrblup/bayesb |
backend/app/api/v1/module_bre/statistics/service.py |
_values_by_tree_env env_dim=stage 分支(coalesce(obs.stage, TraitModel.stage) 分组)+ run_type_b_heredity env_dim 校验扩 stage + run_gblup method 扩 rrblup/bayesb + seed 透传 + run_cv GS 分支 dosage/seed 透传 + _smith_hazel_index restricted 投影(Kempthorne-Nordskog 闭式解)/economic_weights + selection_index 透传 + cv_detail 补 cv_result_id(顺手修复)+ _DATA_VERSION v2.29 |
backend/app/api/v1/module_bre/statistics/schema.py |
TypeBIn.env_dim 描述扩 stage + GblupRunIn/CvRunIn method 描述扩 rrblup/bayesb + seed + SelectionIndexIn.method 描述扩 restricted + restricted_traits/economic_weights |
backend/app/api/v1/module_bre/statistics/controller.py |
run_gblup 透传 seed + selection_index 透传 restricted_traits/economic_weights |
backend/app/api/v1/module_bre/genotype_call/service.py |
GENOTYPE_DATA_VERSION v2.29 |
frontend/web/src/views/module_bre/statistics/index.vue |
Type-B env_dim 下拉加 stage + GBLUP/CV method radio 加 RRBLUP/BayesB + seed 输入 + 指数页 restricted 单选/restricted_traits 多选/每性状经济权重输入 + SI_RES 结果表与警示 |
frontend/web/src/api/module_bre/statistics.ts |
selectionIndex/runGblup/runCv method 类型扩 + restricted_traits/economic_weights/seed |
backend/scripts/test_bre_analysis_o234_tc.py |
正式 tc 套件第 10 套(ok=41):O2 stage 幼成相关 / O3 rrblup+bayesb 落库与对偶可复现 / O4 restricted+economic |
backend/tests/test_stat_analysis_tc.py |
TC_SCRIPTS 注册 ("o234", "test_bre_analysis_o234_tc.py")(9 → 10 套) |
Temp/claude/e2e_o234_20260805.py |
O2–O4 e2e 探针(19 断言,纯计算 golden + 真实 PG) |
Temp/claude/backup_o234_20260805/ |
备份镜像(后端 service/schema/controller/genomic + 前端 vue/ts + tc + e2e) |
备份(无 git,批量编辑前手动镜像)
- 2026-08-03 引擎改动 →
Temp/claude/backup_gxe_20260803/ - 2026-08-04 方向改动(13 文件,按相对路径镜像)→
Temp/claude/backup_direction_20260804/ - 2026-08-04 规范文档 →
Temp/claude/backup_docs_20260804/+doc/桃育种系统模块扩展需求规格.v2.2.md(旧版本快照) - 2026-08-04 无性系级指数改动(controller/schema/service/statistics.ts/index.vue/e2e)→
Temp/claude/backup_clone_index_20260804/ - 2026-08-04 配合力交配设计改动(13 文件,按模块相对路径镜像)→
Temp/claude/backup_combining_design_20260804/ - 2026-08-04 统计严谨·MLOps 复现性改动(weld SQL×2 + statistics 三件套 + blup.py + rootstock 三件套 + 前端四文件 + 三探针)→
Temp/claude/backup_rigor_20260804/ - 2026-08-04 组合得失漏斗改动(
weld_combination_funnel.sql+ statistics service/controller + e2e)→Temp/claude/backup_combination_funnel_20260804/ - 2026-08-04 分子育种改动(weld SQL + bre_menu.sql + module_bre 四模块五件套 + __init__.py + 前端四 api 四页面 + e2e)→
Temp/claude/backup_molecular_20260804/ - 2026-08-04 精修项四连发改动(DUS 模块六件套 + statistics 四件套 + blup.py + weld/种子/菜单 SQL×3 + 前端 dus/statistics 两页两 api + e2e_refine)→
Temp/claude/backup_refine_20260804/ - 2026-08-04 六项能力完善改动(weld_advanced.sql + statistics 四件套 + dus 六件套 + trait_observation 三件套 + mtblup/genomic/stability/fdist/blup 求解器 + 前端 statistics/dus/tree_evaluation 三页四 api(含 trait_observation.ts)+ 六探针 + 文档四件,37 文件)→
Temp/claude/backup_advanced_20260804/ - 2026-08-04 砧木×接穗随机互作改动(blup.py + statistics 三件套 + 前端 statistics.ts/index.vue + e2e_gxr)→
Temp/claude/backup_gxr_20260804/ - 2026-08-04 基因组选择实证严谨性改动(genomic.py + statistics 三件套 + 前端 statistics.ts/index.vue + e2e_gblup_cv + 文档三件)→
Temp/claude/backup_gblup_cv_20260804/ - 2026-08-04 现代桃育种领域覆盖改动(germplasm 三件套 + cross_combination 二件套 + bre_disease_chilling_traits.sql + 前端 germplasm/cross_combination 两页 + germplasm.ts + e2e_s_allele + 文档三件 + 规格快照 v2.13)→
Temp/claude/backup_s_allele_traits_20260804/ - 2026-08-04 GWAS/QTL/MAS 闭环改动(gwas.py + weld_gwas.sql + statistics 四件套 + bre_menu.sql + 前端 gwas.ts/index.vue + e2e_gwas + 文档三件 + 规格快照 v2.14)→
Temp/claude/backup_gwas_20260804/ - 2026-08-04 九缺口补齐改动(blup/gwas/genomic + statistics 四件套 + genotype_call + weld_mas_semantics.sql + 前端 statistics/gwas 两页两 ts + e2e×3 + 文档三件 + 规格快照 v2.15)→
Temp/claude/backup_complete_20260804/ - 2026-08-05 十二项真缺口补齐改动(批1 blup/mtblup/gwas 引擎 + statistics;批2 field_operation/observation/breeding_report/analysis_dataset 四模块五件套 + 前端四页四 ts;批3 audit/alert/brapi/sequence 模块 + number_gen + ap_scheduler + backup_job + pg_backup/pg_restore.sh + init_app + weld SQL 多枚 + 前端 alert 页/statistics;e2e×3 + 文档三件 + 规格快照 v2.16)→
Temp/claude/backup_gaps3_20260804/ - 2026-08-05 桃育种业务流全面完善改动(批A field_operation/observation/seed_lot/seed_treatment/tree/trait_observation + weld_busflow.sql + bre_yield_phenology_traits.sql;批B statistics service/controller/schema/model + bre_type_b_result;批C echarts.ts + statistics/observation/field_operation 三 ts + statistics/observation/field_operation/stage_phenotype/StageView 五 vue;e2e×2 + smoke + 文档三件 + 规格快照 v2.17)→
Temp/claude/backup_busflow3_20260805/ - 2026-08-05 世代闭环改动(selection_result/service.py 晋级落谱 + 探针)→
Temp/claude/backup_pedigree_closure_20260805/ - 2026-08-05 近交惩罚静默关闭修复改动(statistics/service.py 亲缘多源解析 + 探针)→
Temp/claude/backup_kinship_20260805/ - 2026-08-05 EBV 回退方法学修复改动(statistics/service.py 打分降权 + 探针)→
Temp/claude/backup_ebv_20260805/ - 2026-08-05 数据质量离群值方向语义修复改动(statistics/service.py 方向分流 + 前端 statistics/index.vue 双表 + A6 探针 + 文档三件 + 规格快照 v2.20)→
Temp/claude/backup_dq_semantics_20260805/ - 2026-08-05 ΔG 投影假设 + 工程健壮性打磨改动(statistics/service.py note 假设 + spatial 降级 + numpy 收敛向量化 + 前端 statistics/index.vue gain alert + spatial/A6 探针 + 文档三件 + 规格快照 v2.21)→
Temp/claude/backup_dq_robust_20260805/ - 2026-08-05 回归基建改动(run_regression.py + backend/scripts 4 tc 套件,无后端代码改动)→
Temp/claude/backup_test_rigor_20260805/ - 2026-08-05 A–F 六项缺口·批1 父本验证 + 近交衰退改动(pollination/tree/cross_combination service + tree schema + statistics 三件套 + 前端 statistics.ts/index.vue + e2e×2 + 文档三件 + 规格快照 v2.22)→
Temp/claude/backup_parent_validation_20260805/ - 2026-08-05 A–F 六项缺口·批2 GS 家系 CV + 试验设计深度改动(genomic.py + anova.py + statistics 三件套 + trial_study_entry model + weld_trial_study_entry.sql + 前端 statistics.ts/index.vue + e2e×2 + 文档三件 + 规格快照 v2.23)→
Temp/claude/backup_gs_family_trial_design_20260805/ - 2026-08-05 A–F 六项缺口·批3 OCS + MABC 改动(statistics service/controller/schema 三件套
_candidate_ebv_map抽取 + ocs + mabc_progress + 前端 statistics.ts/index.vue OCS 运行区 + MABC tab + e2e×2 + 文档三件 + 规格快照 v2.24)→Temp/claude/backup_ocs_mabc_20260805/ - 2026-08-05 近交衰退正确性修复改动(statistics/service.py 方向感知 + 深层系谱 + 前端 statistics/index.vue 提示文案 + e2e_inbreeding_depression 扩展 + 文档二件 规格/实施记录)→
Temp/claude/backup_inbreeding_fix_20260805/ - 2026-08-05 分子亲本验证 + 试验设计深度·批4 改动(genotype_call 二件套
mendelian_check+ statistics 三件套trial_designaugmented/alpha 分派 + 前端 genotype_call/statistics 两页两 ts + e2e×2 + 文档三件 规格/实施记录/对照总表,14 文件按相对路径镜像)→Temp/claude/backup_mendelian_design_20260805/ - 2026-08-05 批5 区组随机效应 + 孟德尔落库隔离 + 统计引擎数值校验改动(blup.py + statistics 四件套 + genotype_call 三件套 + tree/model.py + 前端 statistics/genotype_call 两页两 ts + 三探针 + 文档三件,18 文件按相对路径镜像)→
Temp/claude/backup_block_mendelian_numerics_20260805/ - 2026-08-05 批6 规划↔目标↔试验 可追溯性闭环改动(weld_plan_trace.sql + target 三件套 + trial 三件套 + plan 二件套 + 前端 plan/target/trial 三页三 ts + 新探针 e2e_plan_trace + 文档三件,按相对路径镜像)→
Temp/claude/backup_plan_trace_20260805/ - 2026-08-05 批7 系谱键空间错位修复改动(statistics/service.py
_tree_individual_keys+ 四调用点 + genotype_call/service.py 版本 + 新探针 e2e_rg_golden + http_v228 + 版本断言探针×4 + 文档三件,按相对路径镜像)→Temp/claude/backup_keyspace_20260805/
复跑验证
# 后端(GBK 控制台需 UTF-8,worship() ASCII 画报会崩)
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python main.py run --env=dev
# 探针(真引擎 + spy 捕获 kwargs / 真引擎直跑)
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_gxe_20260803.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_direction_20260804.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_clone_index_20260804.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_combining_design_20260804.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_prediction_rigor_20260804.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_rootstock_20260804.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_corr_spatial_20260804.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_combination_funnel_20260804.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_refine_20260804.py
# 砧木×接穗随机互作(G×R)探针(真引擎直跑,运行后自动清理):
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_gxr_20260804.py
# 基因组选择(GS)专用 k-fold CV 探针(真引擎直跑,运行后自动清理)+ GBLUP 回归:
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_gblup_cv_20260804.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_advanced_gblup.py
# GWAS/QTL/MAS 闭环探针(真引擎直跑 7 段断言,运行后自动清理)+ GBLUP/ssGBLUP 回归:
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_gwas_20260804.py
# 九缺口补齐三探针(真引擎直跑,运行后自动清理):
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_data_mating_gain_20260804.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_molrigor_20260804.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_spatial_sparse_20260804.py
# 九缺口补齐:MAS 面板语义三列(幂等,可重跑):
PGPASSWORD=dpb psql -h localhost -p 5432 -U dpb -d dpb -w -f backend/sql/weld_mas_semantics.sql
# 组合得失漏斗视图(幂等,可重跑):
PGPASSWORD=dpb psql -h localhost -p 5432 -U dpb -d dpb -w -f backend/sql/weld_combination_funnel.sql
# 精修项三 SQL(幂等,可重跑;bre_dus_seed 依赖 bre_dus_descriptor 已由 create_all 建出):
PGPASSWORD=dpb psql -h localhost -p 5432 -U dpb -d dpb -w -f backend/sql/weld_refine.sql
PGPASSWORD=dpb psql -h localhost -p 5432 -U dpb -d dpb -w -f backend/sql/bre_dus_seed.sql
PGPASSWORD=dpb psql -h localhost -p 5432 -U dpb -d dpb -w -f backend/sql/bre_menu_refine.sql
# 六项能力完善:weld_advanced(幂等,2 表 + 2 列 + 1 jsonb;新表 bre_genetic_corr_result/bre_stability_result 由 create_all 建出):
PGPASSWORD=dpb psql -h localhost -p 5432 -U dpb -d dpb -w -f backend/sql/weld_advanced.sql
# GWAS/QTL/MAS:weld_gwas(幂等,5 新表 bre_gwas_result/bre_gwas_snp/bre_qtl/bre_mas_panel/bre_mas_panel_marker 兜底;正常已由 create_all 建出)+ 900214 菜单翻转:
PGPASSWORD=dpb psql -h localhost -p 5432 -U dpb -d dpb -w -f backend/sql/weld_gwas.sql
PGPASSWORD=dpb psql -h localhost -p 5432 -U dpb -d dpb -w -f backend/sql/bre_menu.sql
# 六探针(真引擎直跑,运行后自动清理):
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_advanced_stability.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_advanced_stage.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_advanced_mtblup.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_advanced_gblup.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_advanced_dus.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_advanced_mlops.py
# 十二项真缺口:批1/批2/批3 探针(真引擎直跑,运行后自动清理)+ 全量回归:
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_gaps_engines_20260804.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_gaps_modules_20260805.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_gaps_base_20260804.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_spatial_sparse_20260804.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_gwas_20260804.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_molrigor_20260804.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_advanced_gblup.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_gblup_cv_20260804.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_refine_20260804.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_gxr_20260804.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_corr_spatial_20260804.py
# 桃育种业务流全面完善:批A/批B 探针(真引擎直跑,运行后自动清理)+ 批C HTTP smoke + 全量回归:
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_busflow_20260805.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_statsflow_20260805.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/smoke_busflow_c_20260805.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_gaps_engines_20260804.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_gaps_modules_20260805.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_gaps_base_20260804.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_spatial_sparse_20260804.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_gwas_20260804.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_molrigor_20260804.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_advanced_gblup.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_gblup_cv_20260804.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_refine_20260804.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_gxr_20260804.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_corr_spatial_20260804.py
# 世代闭环:晋级落谱探针(真引擎直跑 11 组断言,运行后自动清理)+ 晋级主线回归:
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_pedigree_closure_20260805.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_batch_selection_20260803.py
# 近交惩罚静默关闭修复:亲缘多源解析探针(真引擎直跑 14 组断言,运行后自动清理)+ A6 亲缘回归:
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_mating_kinship_20260805.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_data_mating_gain_20260804.py
# EBV 回退方法学修复:direct 优先/子代测验降权/双侧去重探针(真引擎直跑 5 组断言,运行后自动清理)+ 亲缘/批次回归:
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_mating_ebv_20260805.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_mating_kinship_20260805.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_batch_selection_20260803.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_gaps_base_20260804.py
# 数据质量离群值方向语义修复:A6 探针(真引擎直跑,运行后自动清理)+ 回归:
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_data_mating_gain_20260804.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_mating_kinship_20260805.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_batch_selection_20260803.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_gaps_base_20260804.py
# ΔG 投影假设 + 工程健壮性打磨:spatial 降级场景探针(真引擎直跑,运行后自动清理)+ A6 note 断言 + 回归:
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_spatial_sparse_20260804.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_data_mating_gain_20260804.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_mating_kinship_20260805.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_batch_selection_20260803.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_gaps_base_20260804.py
# A–F 六项缺口·批1 父本验证 + 近交衰退:双探针(真引擎直跑,运行后自动清理)+ 全量回归:
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_parent_validation_20260805.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_inbreeding_depression_20260805.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_spatial_sparse_20260804.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_statsflow_20260805.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_data_mating_gain_20260804.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_mating_kinship_20260805.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_batch_selection_20260803.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_gaps_base_20260804.py
# A–F 六项缺口·批2 GS 家系 CV + 试验设计深度:双探针(真引擎直跑,运行后自动清理)+ 全量回归:
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_trial_design_20260805.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_gs_family_cv_20260805.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_gblup_cv_20260804.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_statsflow_20260805.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_spatial_sparse_20260804.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_busflow_20260805.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_mating_kinship_20260805.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_gaps_base_20260804.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_molrigor_20260804.py
# A–F 六项缺口·批3 OCS + MABC:双探针(真引擎直跑,运行后自动清理)+ 全量回归(含 _candidate_ebv_map 抽取后 mating/audit 双核对):
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_ocs_20260805.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_mabc_20260805.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_molrigor_20260804.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_gwas_20260804.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_mating_kinship_20260805.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_mating_ebv_20260805.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_gblup_cv_20260804.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_statsflow_20260805.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_spatial_sparse_20260804.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_busflow_20260805.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_gaps_base_20260804.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_b8_seed_lot.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_prediction_rigor_20260804.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_audit_fix_20260805.py
# 近交衰退正确性修复(6 组断言:方向感知 asc 病指 + 深层系谱多世代 F)+ 全量回归(13 套):
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_inbreeding_depression_20260805.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_ocs_20260805.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_mabc_20260805.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_mating_ebv_20260805.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_mating_kinship_20260805.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_statsflow_20260805.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_spatial_sparse_20260804.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_gs_family_cv_20260805.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_trial_design_20260805.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_parent_validation_20260805.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_batch_selection_20260803.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_gaps_base_20260804.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_gaps_engines_20260804.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_gaps_modules_20260805.py
# A–F 六项缺口·批4 分子亲本验证 + 试验设计深度:双探针(真引擎直跑,运行后自动清理)+ 全量回归(rcbd 路径零变化 + 13 套):
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_mendelian_check_20260805.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_trial_design_ext_20260805.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_trial_design_20260805.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_molrigor_20260804.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_gwas_20260804.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_mating_kinship_20260805.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_mating_ebv_20260805.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_gblup_cv_20260804.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_statsflow_20260805.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_spatial_sparse_20260804.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_gs_family_cv_20260805.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_batch_selection_20260803.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_ocs_20260805.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_mabc_20260805.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_gaps_base_20260804.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_gaps_engines_20260804.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_gaps_modules_20260805.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_prediction_rigor_20260804.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_inbreeding_depression_20260805.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_parent_validation_20260805.py
批5 区组随机效应 + 孟德尔落库隔离 + 统计引擎数值校验:三探针(真引擎直跑,运行后自动清理)+ 27 套全量回归(含 gxe/gxr/mendelian_check/trial_design 零变化):
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_ablup_block_20260805.py PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_mendelian_persist_20260805.py PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_stats_numerics_20260805.py PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_mendelian_check_20260805.py PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_trial_design_20260805.py PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_trial_design_ext_20260805.py PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_gxe_20260803.py PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_gxr_20260804.py PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_molrigor_20260804.py PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_gwas_20260804.py PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_mating_kinship_20260805.py PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_mating_ebv_20260805.py PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_gblup_cv_20260804.py PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_statsflow_20260805.py PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_spatial_sparse_20260804.py PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_gs_family_cv_20260805.py PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_batch_selection_20260803.py PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_ocs_20260805.py PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_mabc_20260805.py PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_gaps_base_20260804.py PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_gaps_engines_20260804.py PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_gaps_modules_20260805.py PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_prediction_rigor_20260804.py PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_inbreeding_depression_20260805.py PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_parent_validation_20260805.py PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_advanced_gblup.py PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_corr_spatial_20260804.py
# 批6 规划↔目标↔试验 可追溯性闭环:新探针(真引擎直跑 17 断言,运行后自动清理)+ weld SQL(幂等,可重跑)+ 全量回归:
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_plan_trace_20260805.py
PGPASSWORD=dpb psql -h localhost -p 5432 -U dpb -d dpb -w -f backend/sql/weld_plan_trace.sql
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_plan_trace_20260805.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_audit_20260805.py
# 批7 统计引擎十模块 golden 复查·系谱键空间错位修复:新探针(真引擎直跑 21 断言,运行后自动清理)+ 回归(版本断言已同步 v2.28):
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_rg_golden_20260805.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_statsflow_20260805.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_advanced_mtblup.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_spatial_sparse_20260804.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_prediction_rigor_20260804.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_mendelian_persist_20260805.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_statsflow_20260805.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_spatial_sparse_20260804.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_prediction_rigor_20260804.py
PYTHONIOENCODING=utf-8 ENVIRONMENT=dev PYTHONPATH=backend python Temp/claude/e2e_mendelian_persist_20260805.py
科学正确性收口:方向标注后,低优性状(裂果率/病害级别/酸度等 asc)在指数、EBV 排行、决策预览、轮次对比中一律按"越小越优"参与,与育种目标语义一致;Smith-Hazel 的 b 符号、加权 Z 的贡献方向均按 direction 归一,不再存在"高 EBV=优"的隐含假设。可追溯性收口:bre_plan 不再孤立——plan→target→cross_combination→tree(目标链)与 plan→trial→trial_study→tree(试验链)双链闭合,
GET /bre/plan/trace/{id}一查到底;三 FK 均可空,存量孤目标/独立试验不受影响,新数据挂链即可查(渐进式,不强制回填)。
18.21 前端 TAB 陈旧数据修复:KeepAlive 切回自动重拉真实数据(2026-08-05,前端框架级,无版本变更)
用户反馈:授粉管理、花粉档案等「第2、3个 TAB」页面,切换过来后列表仍是旧数据,点刷新才变真实数据。根因:
fa-page-content默认 KeepAlive 缓存页面,切换 workbar 标签时组件不重新 mounted →onMounted不重跑 → 列表停留旧快照。框架级修复(覆盖全部 useTable 页面,而非逐页打补丁)。
根因链(两层):① hooks/core/useTable.ts 的 onActivated 只置 tableViewActive=true(fetch 内 guard 防失活期拉数据),从不主动重拉;onDeactivated 又 cancelRequest()。KeepAlive 切回 → data.value 仍是旧快照。约 30 个 module_bre CRUD 页共用 useTable,仅 3 页有手动 onActivated(tree 的 refreshData()、pollination/pollen 的下拉重载),故框架层修一处全覆盖。② 跨实例去重键不含 API 身份:globalListNetworkInflight 的 dedupeKey 仅由 stableDedupeKeyFromParams(requestParams) 生成(跳过 undefined 字段),而所有 module_bre 列表页默认参数形状相同({page_no:1, page_size:10})→ 硬刷新后多个 tab 并发挂载,各页 onMounted 并发发请求,页面 A 复用页面 B 的 in-flight 响应(字段与 prop 不匹配 → 列表只剩序号列有值,其它列空;这正是用户硬刷新后看到的"只有序号列")。点刷新(refreshData)时该 key 已无 in-flight,走自己的 HTTP → 正常。此 bug 既存,但激活重拉后并发概率骤增而被暴露。
改动:
frontend/web/src/hooks/core/useTable.ts:新增tableActivatedOnce标志;onActivated首次(与 mounted 重合)跳过,之后每次恢复激活 →debouncedGetDataByPage.cancel()+clearCache(CLEAR_CURRENT, "恢复激活刷新")+getData()(强制 HTTP 重拉,in-flight 去重仍生效)。守卫(immediate || data.value.length > 0)保持immediate:false页面(cronjob 定时页)"不自动加载"语义不变。另修去重键:新增apiIdentity = apiFn.toString(),dedupeKey = \${apiIdentity}::${stableDedupeKeyFromParams(requestParams)}`——跨实例去重仅在**同一接口**间合并,不同页面的同形参数不再错配(globalListNetworkInflight` Map 全局共享,两处 in-flight key 均带上接口身份)。frontend/web/src/views/module_bre/statistics/index.vue:抽取refreshPageLists()(onMounted 全部 15 个 load 调用),onActivated经pageActivatedOnce守卫后续激活重载(统计页多数据区整体刷新)。frontend/web/src/views/module_bre/pollination/index.vue:onActivated重载 5 个下拉(cross_combination/plot/personnel/tree/pollen 选项),表格由框架处理。frontend/web/src/views/module_bre/pollen/index.vue:onActivated重载采集父本树下拉。frontend/web/src/views/module_bre/tree/index.vue:移除冗余手动onActivated(() => refreshData())(由 useTable 框架覆盖,避免双重重拉)。
验证:vue-tsc EXIT=0(无类型回归);vite dev(:5666,base /web)热更新模块均 200 + 关键字符串存在;后端 /bre/pollination/list 实测返回字段完整(combination_name/pollination_date 等有值,确认非后端问题);浏览器行为需硬刷新(Ctrl+Shift+R,重建 KeepAlive 缓存与 HMR 旧实例)后实跑确认。备份镜像 Temp/claude/backup_tab_stale_20260805/。
18.22 O1 花期数据消费补强:结构化花期区间 + 配对花期软警示 + 授粉窗口规划(2026-08-06,v2.30)
用户反馈 O1 花期字段(flowering_period 5 档字典)零消费属真实数据盲点,但定性为 P1 数据消费补强 + 辅助信息(非与 S-等位同量级的正确性硬防呆)。拍板三个落地档位:① 花期数据建模升级(结构化区间,前置);②
mating_recommend返回体加花期重叠软警示(重叠/错开/需采粉贮藏,不硬阻断);③ 授粉窗口规划消费bre_pollen(新端点GET /bre/pollen/window-plan)。花期建模新增列 →_DATA_VERSIONv2.29 → v2.30。
① 花期建模升级(germplasm 双 Date 列):bre_germplasm 新增 bloom_start_date/bloom_end_date(Date 可空,年际重复物候——比较/投影时取月日、忽略年份;flowering_period 5 档字典保留作粗粒度 fallback)。weld 幂等 SQL(backend/sql/weld_flowering.sql)+ 双处版本 bump。连锁全链:model.py / schema(Create+Update)/ service(export mapping_dict + import header_dict + fields 解析 + 模板 header_list)/ 前端 germplasm 表单两个 date-picker、表格列、详情项。前端设计取舍:useCrudForm 无提交前 transform hook → 弃 daterange(需 bloomStartRange↔两字段双向映射),改用两个独立 date 字段直绑 bloom_start_date/bloom_end_date(与 acquisition_date 同模式,零转换)。
② mating_recommend 花期软警示:新模块级 helper _bloom_overlap(female, male)(statistics/service.py,_md() 月日→年序日 1..366)——优先结构化区间(月日年际比较),缺区间 fallback 到 _BLOOM_TIER_ORDER 5 档字典序号(相邻/同档视为重叠)。四态返回 (status, msg):overlap「花期重叠,可同期授粉」/ store「父本先开花,需采粉贮藏至母本花期授粉」(me_d < fs_d)/ offset「母本先开花,父本花期在后,注意母本柱头可授期」(fe_d < ms_d)/ unknown「花期未知(缺结构化区间与档位)」。pairs 循环(female=gs[i], male=gs[j] 语义)在 s_compat 旁加 bloom_status/bloom_msg;非重叠三态追加进 flags[](前端红色 tag 自动渲染),overlap 不进 flags——软警示不硬阻断。前端 pairs 表加「花期」列(重叠=success tag / 需采粉贮藏·错开=warning tag / 未知=info tag)。
③ 授粉窗口规划(window-plan):新端点 GET /bre/pollen/window-plan?window_start=&window_end=(controller + service.window_plan,纯计算不落库)。_project_bloom(g, ref_year) 把花期投影到窗口起始年:结构化区间按年际月日(桃花期 3-4 月单年窗口假设),缺区间 fallback _BLOOM_TIER_SPAN(5 档 → 代表区间,粗粒度标注)。花期种质给花粉覆盖三态 covered(整段有批次 collect<=bs and expiry>=be)/partial/none(无覆盖 → n_need_pollen + 提示需采粉贮藏或同期授粉);库存侧给批次窗口状态 full(全程覆盖)/expiring(窗口内到期)/entering(窗口内采集、有效期出窗)/expired(窗口前失效)/not_started(窗口后采集)。窗口反向 409。前端 pollen 页顶部「授粉窗口规划」卡片:daterange 默认本年度/次年花期(3-4 月在当年、否则次年 03-01~04-30)+ 生成按钮 + 缺粉 alert + 花期覆盖表 + 库存状态表;pollen.ts 加 getWindowPlan + PollenWindowPlan/PollenBloomItem/PollenInventoryItem/PollenLotRef 类型。
验证:e2e_o1_bloom_20260805.py 探针全过——① CreateSchema→CRUD 双 Date 列落库;② 6 种质 15 对(重叠/错开/需采粉贮藏三类 + 档位 fallback mid×very_early→store + 区间×档位混合对→unknown,flags 仅非重叠进警示);③ 窗口 A(03-0504-08)花期覆盖三态 covered/partial/none + 档位投影种质、窗口 B(03-1003-30)库存五态 full/expiring/entering/expired/not_started + 窗口反向 409。vue-tsc EXIT=0。全量回归 + run_ci.py EXIT=0 零回归。版本连锁:4 e2e 探针(statsflow/spatial_sparse×2/prediction_rigor/mendelian_persist)+ o234 tc 断言 v2.29→v2.30。备份镜像 Temp/claude/backup_o1_bloom_20260805/。