diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..5ba8647 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,43 @@ +# PyGenRay + +Python package for simulated 2D ray-based acoustic propagation modeling in underwater environments, designed for acoustic tomography applications. + +## Environment + +Use `uv` for all environment and package management — never `pip` or `python` directly. + +```bash +uv sync --group dev # install with dev dependencies +uv run pytest tests/ # run tests +``` + +## Testing + +```bash +uv run pytest tests/ # full suite +uv run pytest tests/ --cov=pygenray # with coverage +uv run pytest --regenerate-physics tests/ # regenerate physics regression fixtures +``` + +## Architecture + +Source lives in `src/pygenray/`. Key modules: + +- `environment.py` — `OceanEnvironment2D`, sound speed profiles (e.g. `munk_ssp()`) +- `launch_rays.py` — `shoot_rays()` (fan, parallel), `shoot_ray()` (single) +- `ray_objects.py` — `Ray` and `RayFan` data classes with plotting methods +- `eigenrays.py` — `find_eigenrays()` using regula falsi root-finding +- `integration_processes.py` — core ray ODEs (`derivsrd()`), Numba JIT-compiled + +## Coordinate Convention + +There is a sign flip between the user-facing API and internal ODE integration: + +- **User-facing:** positive `z` = downward (ocean depth), positive launch angle = toward surface +- **Internal ODE:** negative `z` convention + +Respect this distinction when modifying ray integration or `Ray`/`RayFan` attribute handling. + +## Performance + +`derivsrd()` in `integration_processes.py` is JIT-compiled with Numba (`fastmath=True`). Avoid introducing pure-Python loops in hot paths. `shoot_rays()` uses multiprocessing — be careful with shared state.