"""Run the modal solver on a variant of a challenge for listening experiments (not submissions): overrides of the parameters, the strikes and the duration are applied to a copy of challenge.json written beside the outputs. Usage: python experiment.py [--set key=value ...] [--strikes t:x,t:x,...] [--seconds S] [--spacing 0.008] [--fmax 20000] [--m 4] [--device cuda] Example: python experiment.py crash.json ../../experiments thickbell --set thickness_center=0.002 --strikes 0:0.04,1.2:0.12,2.4:0.185 --seconds 3.6""" import json import subprocess import sys from pathlib import Path ch = json.load(open(sys.argv[1])) exp_dir = Path(sys.argv[2]) name = sys.argv[3] args = sys.argv[4:] passthrough = [] i = 0 while i < len(args): if args[i] == "--set": k, v = args[i + 1].split("=", 1) ch["parameters"][k] = json.loads(v) i += 2 elif args[i] == "--strikes": ch["strikes"] = [{"t": float(t), "x": float(x), "y": 0.0} for t, x in (s.split(":") for s in args[i + 1].split(","))] i += 2 elif args[i] == "--seconds": ch["output"]["num_samples"] = int(round(ch["output"]["sample_rate_hz"] * float(args[i + 1]))) ch["fields"]["shape"][0] = int(round(ch["fields"]["frame_rate_hz"] * float(args[i + 1]))) + 1 i += 2 else: passthrough.append(args[i]) i += 1 ch["challenge_id"] = f"{ch['challenge_id']}-{name}" out = exp_dir / name out.mkdir(parents=True, exist_ok=True) cj = out / "challenge.json" json.dump(ch, open(cj, "w"), indent=1) here = Path(__file__).resolve().parent cmd = [sys.executable, str(here / "modal_shell.py"), str(cj), str(out), "--tag", name, *passthrough] print(" ".join(cmd), flush=True) sys.exit(subprocess.call(cmd))