Team Ai
Datasetpublic

ZZoutian/figure2data-database-v2

figure2data databasev2 — 40K v6 合成科研图表数据集(最终交付版) 生成日期:2026-09-17 生成器:generator 1.6.0 / dataset_generation_revision v6(含两次 hotfix) 规模:40,000 样本(10 图族 / 33 亚型;area、matrix 冻结不生成,set_relation 已删除) 目录结构 databasev2/ ├── figure2data.sqlite3 # 主数据库(2.0 GB:40,000 samples / 280,000 documents) ├── schema/ # sqlite schema ├── shards/ # 数据资产(shard = (样本序号-1)//1000) │ └── shard_000 .. shard_039/ │ ├── images/ # PNG… See the full description on the dataset page: https://huggingface.co/datasets/ZZoutian/figure2data-database-v2.

sourceHugging Faceupdated 24d agoView on Hugging Face
0likes6.3kdownloads
test_estimation_renderer_contract.py118 linesDownload Raw Back to tests
1"""database_yh2 §5.1 / §13.S1:estimation renderer 语义契约(Tier A + Tier B)。2 3- raw observations / bootstrap means 必须散点绘制(geometry kind=points,绝不 polyline);4- paired 连接线:从 data.pairs 经 CategoryMapper 锚点绘制,端点数 == 2×n_pairs;5- estimation 系列必须有合法 CI(ci_low ≤ estimate ≤ ci_high,ci_high > ci_low);6- 固定种子回归:dbv01_0017 / dbv01_0035 / dbv01_0052(v6 scope 后重定位)。7"""8 9from __future__ import annotations10 11import numpy as np12import pytest13 14pytestmark = pytest.mark.usefixtures("tmp_staging")15 16 17def _estimation_series(docs):18    panels = {p["panel_id"]: p for p in docs["truth"]["figure"]["panels"]}19    geo = {g["series_id"]: g for g in docs["geometry"]["series"]}20    out = []21    for s in docs["truth"]["series"]:22        p = panels.get(s["panel_id"], {})23        if p.get("chart_subtype") == "estimation":24            out.append((s, p.get("param_variant"), geo.get(s["series_id"], {})))25    return out26 27 28class TestEstimationRendererContract:29    @pytest.mark.parametrize("variant", ["paired", "unpaired", "bootstrap_interval", "small_effect"])30    def test_raw_observations_never_polyline(self, make_docs, variant):31        """§5.1 ESTIMATION_RAW_POLYLINE:raw xy 观测几何必须是 points。"""32        docs, _ = make_docs("statistical", "estimation", variant=variant, seed=11)33        n_raw = 034        for s, var, sg in _estimation_series(docs):35            if s["data"].get("kind") == "xy":36                n_raw += 137                assert sg.get("kind") != "polyline" and not sg.get("points_px"), \38                    f"{s.get('label')} 几何为 polyline(观测被连接)"39                assert sg.get("centers_px") or sg.get("bboxes_px"), "raw 观测无点几何"40        assert n_raw >= 141 42    def test_bootstrap_not_connected(self, make_docs):43        """§5.1 BOOTSTRAP_CONNECTED_SEQUENCE:bootstrap 分布几何必须是 points。"""44        docs, _ = make_docs("statistical", "estimation", variant="bootstrap_interval", seed=12)45        found = False46        for s, var, sg in _estimation_series(docs):47            if "Bootstrap" in (s.get("label") or ""):48                found = True49                assert sg.get("kind") == "points"50                assert sg.get("points_px") is None51        assert found, "缺 Bootstrap means 系列"52 53    def test_pair_links_from_pairs(self, make_docs):54        """§5.1 ESTIMATION_PAIR_COUNT_MISMATCH:连接线段端点 == 2×n_pairs,且成对语义正确。"""55        docs, _ = make_docs("statistical", "estimation", variant="paired", seed=13)56        found = False57        for s, var, sg in _estimation_series(docs):58            if s["data"].get("kind") == "paired":59                found = True60                pairs = s["data"]["pairs"]61                pts = sg.get("points_px") or []62                assert len(pts) == 2 * len(pairs), f"{len(pts)} != 2×{len(pairs)}"63                ids = [p["pair_id"] for p in pairs]64                assert len(set(ids)) == len(ids), "pair_id 重复"65                for pr in pairs:66                    assert set(pr) >= {"pair_id", "condition_a_value", "condition_b_value"}67        assert found, "paired 变体缺 pairs 系列"68 69    @pytest.mark.parametrize("variant", ["unpaired", "bootstrap_interval", "small_effect"])70    def test_estimation_ci_present_and_valid(self, make_docs, variant):71        """§5.1 ESTIMATION_CI_MISSING:point+interval CI 必备且合法。"""72        docs, _ = make_docs("statistical", "estimation", variant=variant, seed=14)73        found = False74        for s, var, sg in _estimation_series(docs):75            d = s["data"]76            if d.get("kind") == "estimation":77                found = True78                est, lo, hi = d["estimate"], d["ci_low"], d["ci_high"]79                assert lo <= est <= hi and hi > lo, f"CI 非法 [{lo},{est},{hi}]"80                assert sg.get("bboxes_px") or sg.get("centers_px"), "CI 无渲染几何"81        assert found, f"{variant} 缺 estimation 系列"82 83    def test_truth_linestyle_none_for_observations(self, make_docs):84        """§3.5 元数据一致:观测系列 truth line_style 必须为 none(不误导下游)。"""85        docs, _ = make_docs("statistical", "estimation", variant="unpaired", seed=15)86        for s in docs["truth"]["series"]:87            if s["data"].get("kind") == "xy":88                assert s.get("style", {}).get("line") in (None, "none"), \89                    f"{s.get('label')} line_style={s.get('style', {}).get('line')}"90 91 92class TestEstimationFixtures:93    """Tier B:固定种子渲染回归(yh2 §2 fixtures)。"""94 95    # v6 重钉(2026-09-16):审核批对齐 active scope 后轮转变化——96    # unpaired 在 100 行内不再有主 panel 行(Tier A 单测仍直接覆盖 unpaired/small_effect)。97    @pytest.mark.parametrize("sid,variant", [98        ("dbv01_0015", "paired"),99        ("dbv01_0046", "bootstrap_interval"),100    ])101    def test_fixture_clean(self, sid, variant, audit):102        from databasev1.adapter import build_documents, panel_view103        from databasev1.adapter.truth import build as build_truth104        from databasev1.review_batch import build_review_rows105        from databasev1.scheduler import generate_one106        from databasev1.storage.hashes import sha256_bytes, sha256_json107 108        rows = {r.sample_id: r for r in build_review_rows(100)}109        row = rows[sid]110        assert row.param_variant == variant, f"{sid} 变体漂移:{row.param_variant}"111        gcfg = {"max_attempts": 8,112                "image": {"min_long_px": 700, "max_long_px": 1800, "min_short_px": 500}}113        rendered = generate_one(row, gcfg)114        docs = build_documents(rendered, image_sha256=sha256_bytes(rendered["png_bytes"]),115                               truth_sha256=sha256_json(build_truth(rendered, panel_view(rendered))))116        issues = audit(sid, docs)117        assert issues == [], f"{sid} 审计未过:{issues}"118 
ZZoutian/figure2data-database-v2 · Team Ai