Source: scripts/plan_hypersim_expansion.py · Plain text

scripts/plan_hypersim_expansion.py

"""Create and size-check the official-split Hypersim expansion plan."""

from __future__ import annotations

import argparse
import json
from pathlib import Path

from mcss.data.hypersim_expansion import (
    build_expansion_plan,
    estimate_expansion_storage,
    write_expansion_plan,
)

GIB = 1024**3


def _parser() -> argparse.ArgumentParser:
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument(
        "--metadata",
        type=Path,
        default=Path("data/hypersim_raw/official_metadata/metadata_images_split_scene_v1.csv"),
    )
    parser.add_argument(
        "--observed-subset", type=Path, default=Path("configs/hypersim_subset_v1.csv")
    )
    parser.add_argument(
        "--partitions-output", type=Path, default=Path("configs/hypersim_er_partitions.csv")
    )
    parser.add_argument(
        "--exclusions-output",
        type=Path,
        default=Path("configs/hypersim_er_final_exclusions.csv"),
    )
    parser.add_argument("--raw-root", type=Path, default=Path("data/hypersim_raw"))
    parser.add_argument(
        "--baseline-prepared-root", type=Path, default=Path("data/hypersim_prepared")
    )
    parser.add_argument(
        "--target-prepared-root", type=Path, default=Path("data/hypersim_er_prepared")
    )
    parser.add_argument("--reserve-gib", type=float, default=100.0)
    parser.add_argument("--safety-factor", type=float, default=1.25)
    parser.add_argument("--dry-run", action="store_true")
    return parser


def main() -> int:
    args = _parser().parse_args()
    if args.reserve_gib < 0:
        raise ValueError("--reserve-gib must be non-negative")
    plan = build_expansion_plan(args.metadata, args.observed_subset)
    estimate = estimate_expansion_storage(
        plan,
        raw_root=args.raw_root,
        baseline_prepared_root=args.baseline_prepared_root,
        target_prepared_root=args.target_prepared_root,
        reserve_bytes=int(args.reserve_gib * GIB),
        safety_factor=args.safety_factor,
    )
    if not args.dry_run:
        write_expansion_plan(plan, args.partitions_output, args.exclusions_output)
    print(
        json.dumps(
            {
                "dry_run": args.dry_run,
                "metadata_sha256": plan.metadata_sha256,
                "official_scene_counts": plan.official_counts,
                "protocol_scene_counts": plan.counts,
                "storage": estimate.as_dict(),
                "outputs": None
                if args.dry_run
                else {
                    "partitions": str(args.partitions_output.resolve()),
                    "exclusions": str(args.exclusions_output.resolve()),
                },
            },
            indent=2,
            sort_keys=True,
        )
    )
    return 0 if estimate.fits_budget else 2


if __name__ == "__main__":
    raise SystemExit(main())