Metadata-Version: 2.3
Name: crgutils
Version: 0.1.1
Summary: CRG utility functions and tools
Author: coder
Author-email: coder <coder@timeintegral.ai>
Requires-Dist: numpy>=1.26
Requires-Python: >=3.11
Project-URL: Homepage, https://timeintegral.ai/crgutils/
Description-Content-Type: text/markdown

# crgutils

`crgutils` is a Python library for loading, validating, and evaluating ASAM OpenCRG road surface files.

Supported formats and capabilities:

- ASCII `.crg` inputs in `LRFI` and `LDFI` formats
- Binary `.crg` inputs in `KRBI` and `KDBI` formats
- Road-space queries `(u, v) → z`, `(u, v) → (x, y)`, `(u, v) → (phi, kappa)`
- World-space queries `(x, y) → z`, `(x, y) → (u, v)`, `(x, y) → (phi, kappa)`
- All five border modes: `NONE`, `EX_ZERO`, `EX_KEEP`, `REPEAT`, `REFLECT`
- Header-defined evaluation options and pending runtime modifiers

## Install

Core package:

```bash
uv sync
```

Core package with test dependencies:

```bash
uv sync --extra dev
```

If you also want the demo workspace members, especially the visualizer's extra dependencies:

```bash
uv sync --all-packages
```

Python 3.11+ is required.

## Quick Start

```python
import crgutils

ds = crgutils.read("samples/crg-txt/handmade_straight.crg")  # load + validate + apply modifiers
cp = ds.create_contact_point()                                 # default options

z = cp.eval_uv_to_z(10.0, 0.0)            # elevation at road (u=10, v=0)
x, y = cp.eval_uv_to_xy(10.0, 0.5)        # road → world coords
u, v = cp.eval_xy_to_uv(x, y)             # world → road coords
phi, kappa = cp.eval_uv_to_pk(10.0, 0.0)  # heading and curvature
```

Override evaluation options when creating the contact point:

```python
cp = ds.create_contact_point(border_mode_u=crgutils.BorderMode.REPEAT)
```

## API Surface

| Symbol | Purpose |
|---|---|
| `crgutils.read(path, **kwargs)` | Load, validate, and prepare a `.crg` file; returns `CRGDataset` |
| `dataset.create_contact_point(**options)` | Create a `ContactPoint` evaluation context |
| `crgutils.ContactPoint(dataset, **options)` | Stateful evaluation context (direct constructor) |

Exported types:

| Type | Description |
|---|---|
| `CRGDataset` | Parsed road surface (arrays + metadata) |
| `EvalOptions` | Frozen dataclass for evaluation parameters |
| `BorderMode` | `NONE / EX_ZERO / EX_KEEP / REPEAT / REFLECT` |
| `RefLineContinue` | `EXTRAPOLATE / CLOSE_TRACK` |
| `CurvMode` | `LATERAL / REF_LINE` |
| `GridNaNMode` | `KEEP / SET_ZERO / KEEP_LAST` |

### `ContactPoint` evaluation methods

```python
cp.eval_uv_to_z(u, v)       → float            # elevation from road coords
cp.eval_xy_to_z(x, y)       → float            # elevation from world coords
cp.eval_uv_to_xy(u, v)      → (float, float)   # road → world
cp.eval_xy_to_uv(x, y)      → (float, float)   # world → road
cp.eval_uv_to_pk(u, v)      → (float, float)   # heading, curvature
cp.eval_xy_to_pk(x, y)      → (float, float)   # heading, curvature
cp.eval_uv_to_z_grid(u, v)  → np.ndarray       # vectorised elevation
cp.eval_xy_to_z_grid(x, y)  → np.ndarray       # vectorised elevation
cp.with_options(**overrides) → ContactPoint     # new context, shared dataset
```

## Sample Data

Bundled sample files live in:

```text
samples/crg-txt/    ASCII CRG files (straight, curved, banked, sloped, circle, …)
samples/crg-bin/    Binary CRG files (Belgian block cobblestone, country road, …)
```

Both the demo scripts and the test suite load from these directories.

## Demos

The repository has two demo areas:

- `demo/c-api/` contains Python ports of the upstream OpenCRG C API demos
- `demo/viz/` contains interactive visualization tools with their own dependencies

### C-API Demo Ports

```bash
uv run python demo/c-api/simple.py                        # xy→z on a 2D grid
uv run python demo/c-api/reader.py                        # header / channel / road info
uv run python demo/c-api/curvature.py                     # curvature profile
uv run python demo/c-api/eval_z.py                        # uv→z, round-trip z, pk
uv run python demo/c-api/eval_xy_uv.py                    # uv→xy→uv round-trips
uv run python demo/c-api/eval_options.py                  # 29 option/modifier tests
```

Each script defaults to a file in `samples/crg-txt/` and accepts an explicit path:

```bash
uv run python demo/c-api/reader.py samples/crg-bin/belgian_block.crg
uv run python demo/c-api/eval_xy_uv.py samples/crg-txt/handmade_curved.crg
uv run python demo/c-api/eval_options.py -t 5   # run only test 5
```

Pass `--help` to any script for usage details.

### Visualizer

The visualizer lives in the `viz` workspace member and includes both a marimo app and a notebook:

```bash
uv sync --package viz
uv run --package viz marimo edit demo/viz/crg_viz.py
uv run --package viz jupyter notebook demo/viz/render.ipynb
```

The marimo app lets you browse bundled sample files or point it at any local `.crg` file.

## Tests

```bash
uv run pytest
```

The test suite covers the loader, all evaluation functions, all five border modes,
modifiers, `check()`, `ContactPoint` option inheritance, and round-trip accuracy.

## Repository Layout

```text
src/crgutils/   library source
samples/        bundled CRG sample files (crg-txt/ and crg-bin/)
demo/c-api/     Python ports of the OpenCRG C API demos
demo/viz/       visualization app and notebook
tests/          pytest test suite
```

## Notes

- The binary Belgian-block sample contains all-NaN edge channels that produce expected
  `RuntimeWarning`s from NumPy when computing array summaries; the file still loads and
  is fully covered by tests.
