#!/usr/bin/env python3 """ gallery_coverage_per_film.py — fraction of each film's X-Ray credited cast that has a reference embedding in the gallery, computed per film rather than as a single benchmark-wide average. Usage: python3 scripts/docs/gallery_coverage_per_film.py --out docs_data/gallery_coverage_per_film.json """ import argparse import csv import json import sys from pathlib import Path import h5py REPO = Path(__file__).resolve().parent.parent.parent sys.path.insert(0, str(REPO / "scripts" / "validation")) from identity import keys_for # noqa: E402 def main(): p = argparse.ArgumentParser() p.add_argument("--gallery", default=str(REPO / "experiments/galleries/gallery_LVFace-B_Glint360K.h5")) p.add_argument("--films", default=str(REPO / "experiments/manifests/films.json")) p.add_argument("--out", required=True) args = p.parse_args() films = json.load(open(args.films)) with h5py.File(args.gallery, "r") as f: names = [n.decode() if isinstance(n, bytes) else n for n in f["name"][:]] jids = [j.decode() if isinstance(j, bytes) else j for j in f["jellyfin_id"][:]] imdbs = [j.decode() if isinstance(j, bytes) else j for j in f["imdb_id"][:]] gallery_keys = set() for n, j, im in zip(names, jids, imdbs): gallery_keys |= keys_for(imdb_id=im, name=n, jellyfin_id=j) out = [] for film in films: xray_dir = REPO / film["xray"] id_to_name = {} with open(xray_dir / "people.csv", newline="", encoding="utf-8") as fh: for r in csv.DictReader(fh): nm = (r.get("name_id") or "").strip() if nm: id_to_name[nm] = (r.get("person") or "").strip() cast_keys = [keys_for(imdb_id=nm, name=name) for nm, name in id_to_name.items()] covered = sum(1 for ck in cast_keys if ck & gallery_keys) total = len(cast_keys) out.append({"film": film["name"], "cast_total": total, "covered": covered, "coverage_pct": round(covered / total * 100, 1) if total else 0.0}) out.sort(key=lambda x: x["coverage_pct"]) Path(args.out).parent.mkdir(parents=True, exist_ok=True) json.dump(out, open(args.out, "w"), indent=1) for o in out: print(f"{o['film']:45s} {o['covered']:3d}/{o['cast_total']:3d} ({o['coverage_pct']}%)", file=sys.stderr) if __name__ == "__main__": main()