"""Pack the two benchmark sets (start, end and reference TS structures) into data/inputs.tar.gz. python reproduce/pack_inputs.py --sets \ --structures Only the reactions listed in the two CSVs are packed. The archive is byte-reproducible (sorted entries, fixed timestamps and owners). Unpacked inside rerun/, it puts the set tables in sets/ and the structures in data/reaction_qm/, where the scripts look. """ from __future__ import annotations import argparse import csv import gzip import io import tarfile from pathlib import Path OUT = Path(__file__).resolve().parent.parent / "data" / "inputs.tar.gz" # source table -> name in the archive SETS = {"kaist_docked_500.csv": "reaction_qm_500.csv", "geodesic_gxtb.csv": "geodesic_66.csv"} def main() -> None: ap = argparse.ArgumentParser() ap.add_argument("--sets", type=Path, required=True) ap.add_argument("--structures", type=Path, required=True) a = ap.parse_args() files: dict[str, bytes] = {} for name, packed in SETS.items(): text = (a.sets / name).read_bytes() files[f"sets/{packed}"] = text for row in csv.DictReader(io.StringIO(text.decode())): for col in ("start_xyz", "end_xyz", "ts_reference_xyz"): files[f"data/reaction_qm/{row[col]}"] = (a.structures / row[col]).read_bytes() placement = (a.structures / row["start_xyz"]).parent / "placement.json" if placement.exists(): files[f"data/reaction_qm/{Path(row['start_xyz']).parent}/placement.json"] = placement.read_bytes() buf = io.BytesIO() with tarfile.open(fileobj=buf, mode="w", format=tarfile.PAX_FORMAT) as tar: for name in sorted(files): info = tarfile.TarInfo(name) info.size, info.mtime, info.mode = len(files[name]), 0, 0o644 tar.addfile(info, io.BytesIO(files[name])) with gzip.GzipFile(OUT, "wb", mtime=0) as gz: gz.write(buf.getvalue()) print(f"{OUT.name}: {len(files)} files, {OUT.stat().st_size / 1e6:.1f} MB") if __name__ == "__main__": main()