#!/usr/bin/env python3 """Find open SurfaceWorld columns below the resolved transition ceiling.""" import argparse import csv import subprocess from pathlib import Path def main(): parser = argparse.ArgumentParser() parser.add_argument("probe") parser.add_argument("owner") parser.add_argument("output") parser.add_argument("--z", type=float, default=-130.0) parser.add_argument("--minimum", type=float, default=-96.0) parser.add_argument("--maximum", type=float, default=96.0) parser.add_argument("--spacing", type=float, default=16.0) args = parser.parse_args() probe = str(Path(args.probe).resolve()) owner = str(Path(args.owner).resolve()) output = Path(args.output) output.parent.mkdir(parents=True, exist_ok=True) rows = [] count = round((args.maximum - args.minimum) / args.spacing) for iy in range(count + 1): y = args.minimum + iy * args.spacing for ix in range(count + 1): x = args.minimum + ix * args.spacing command = ["taskset", "-c", "0-11", "prlimit", "--as=6442450944", "--", probe, owner, "surface-world", str(x), str(y), str(args.z - 2.0), str(args.z + 2.0), "0.25"] result = subprocess.run(command, capture_output=True, text=True, timeout=1800, check=False) samples = [line for line in result.stdout.splitlines() if line.startswith(f"{args.z:.6f},")] density = float(samples[0].split(",")[1]) if result.returncode == 0 and samples else float("nan") rows.append((x, y, args.z, density, result.returncode)) print(f"[SurfaceWorldAirScan] x_m={x:.1f} y_m={y:.1f} z_m={args.z:.2f} " f"density_vox={density:.6f} exit={result.returncode}", flush=True) with output.open("w", newline="", encoding="utf-8") as stream: writer = csv.writer(stream) writer.writerow(("x_m", "y_m", "z_m", "density_vox", "exit_code")) writer.writerows(rows) open_samples = [row for row in rows if row[3] > 0.0] print(f"[SurfaceWorldAirScanSummary] samples={len(rows)} open={len(open_samples)} " f"output={output} status={'PASS' if open_samples else 'FAIL'}") return 0 if open_samples else 1 if __name__ == "__main__": raise SystemExit(main())