CoolFace
Apppublic

rafmacalaba/data-use-annotate

sourceHugging Faceupdated 13d agoView on Hugging Face
0likes
build_passage_queue.py82 linesDownload Raw Back to root
1#!/usr/bin/env python32"""Group scored flat pool items into passage examples (multi-mention).3 4Reads the flat rescored queue (build_pool_queue.py → rescore_singlepass.py)5and emits one JSON object per distinct (origin, ctx):6 7    {queue, origin, ctx, n, band, scored_by,8     mentions: [{key, surface, start, end, head_score, band}...]}   # by start9 10Passages with one mention stay as-is; multi stays multi — the UI drives11them as one example with a per-mention ruling target. The passage-level12band is the most-informative mention state:13 14    unscored  any unscored15    confusion any confusion16    mixed     keep + drop, no confusion17    else      the single uniform band18 19    uv run python human_labeling/build_passage_queue.py \20        [--input human_labeling/queue.json] [--out human_labeling/queue_passages.json]21"""22 23import argparse24import json25from collections import defaultdict26from pathlib import Path27 28HERE = Path(__file__).resolve().parent29 30 31def passage_band(mentions: list[dict]) -> str:32    bands = {m.get("band") for m in mentions}33    if "unscored" in bands:34        return "unscored"35    if "confusion" in bands:36        return "confusion"37    if len(bands) == 1:38        return bands.pop()39    return "mixed"40 41 42def main() -> None:43    ap = argparse.ArgumentParser()44    ap.add_argument("--input", default=str(HERE / "queue.json"))45    ap.add_argument("--out", default=str(HERE / "queue_passages.json"))46    a = ap.parse_args()47 48    groups: dict[tuple, list[dict]] = defaultdict(list)49    for line in Path(a.input).read_text().splitlines():50        if not line.strip():51            continue52        r = json.loads(line)53        if r.get("ctx"):54            groups[(r.get("origin"), r["ctx"])].append(r)55 56    passages = []57    for (origin, ctx), rows in groups.items():58        mentions = sorted(59            ({"key": r["key"], "surface": r.get("surface"),60              "start": r.get("start"), "end": r.get("end"),61              "head_score": r.get("head_score"), "band": r.get("band")}62             for r in rows),63            key=lambda m: (m["start"] if isinstance(m["start"], int) else 0,64                           m["surface"] or ""))65        passages.append({66            "queue": "probe_candidates/passages",67            "origin": origin, "ctx": ctx, "n": len(mentions),68            "band": passage_band(mentions), "mentions": mentions,69            "scored_by": rows[0].get("scored_by"),70        })71 72    passages.sort(key=lambda p: (p["origin"] or "", p["ctx"] or ""))73    Path(a.out).write_text(74        "\n".join(json.dumps(p) for p in passages) + "\n")75    n_multi = sum(1 for p in passages if p["n"] > 1)76    from collections import Counter77    print(f"passages={len(passages)} multi={n_multi} "78          f"{Counter(p['band'] for p in passages)} -> {a.out}")79 80 81if __name__ == "__main__":82    main()