Skill Tracer
Skills › Scientific Agent Skills › pylabrobot › plan_transfers.py

plan_transfers.py

59 lines · skills/pylabrobot/scripts/plan_transfers.py at 5f2bc03

1#!/usr/bin/env python3
2"""Plan a deterministic volume ledger and one-use tip allocation."""
3
4from __future__ import annotations
5
6import argparse
7from typing import Sequence
8
9if __package__:
10 from ._common import (
11 ValidationError,
12 emit_error,
13 emit_json,
14 load_csv,
15 load_json,
16 plan_transfers,
17 validate_manifest,
18 validate_transfers,
19 )
20else:
21 from _common import (
22 ValidationError,
23 emit_error,
24 emit_json,
25 load_csv,
26 load_json,
27 plan_transfers,
28 validate_manifest,
29 validate_transfers,
30 )
33def build_parser() -> argparse.ArgumentParser:
34 parser = argparse.ArgumentParser(
35 description=(
36 "Validate transfer CSV rows, source/dead/destination volumes, tip capacity, "
37 "rates, heights, wells, channels, and one-use tip assignments. Planning "
38 "state is not physical liquid or tip detection."
39 )
40 )
41 parser.add_argument("--manifest", required=True, help="Local UTF-8 .json manifest")
42 parser.add_argument("--transfers", required=True, help="Local UTF-8 .csv transfer table")
43 return parser
46def main(argv: Sequence[str] | None = None) -> int:
47 args = build_parser().parse_args(argv)
48 try:
49 manifest = validate_manifest(load_json(args.manifest))
50 transfers = validate_transfers(load_csv(args.transfers))
51 report = plan_transfers(manifest, transfers)
52 except (OSError, ValidationError) as error:
53 return emit_error(error)
54 emit_json(report)
55 return 0
58if __name__ == "__main__":
59 raise SystemExit(main())