Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 107 additions & 0 deletions .claude/commands/rockout.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# Rockout: End-to-End Issue-to-Implementation Workflow

Take the user's prompt describing an enhancement, bug, or suggestion and drive it
through all seven steps below. The prompt is: $ARGUMENTS

---

## Step 1 -- Create a GitHub Issue

1. Decide the issue type from the prompt:
- **enhancement** -- new feature or improvement
- **bug** -- something broken
- **suggestion / proposal** -- idea that needs design discussion
2. Pick labels from the repo's existing set. Always include the type label
(`enhancement`, `bug`). Add topical labels when they fit
(e.g. `documentation`, `GPU CI`).
3. Draft the title and body. Write a clear problem statement, motivation, and
proposed approach. For bugs, include reproduction steps and expected vs actual
behavior.
4. **Run the body text through the `/humanizer` skill** before creating the issue
to strip AI writing patterns.
5. Create the issue with `gh issue create` using the drafted title, body, and labels.
6. Capture the new issue number for later steps.

## Step 2 -- Create a Git Worktree

1. Create a new branch and worktree using the issue number:
```
git worktree add .claude/worktrees/issue-<NUMBER> -b issue-<NUMBER>
```
2. Switch the working directory to the new worktree for all remaining steps.

## Step 3 -- Implement the Change

1. Read the relevant source files to understand the existing code.
2. Follow the project's architecture patterns:
- **xarray accessor**: public API goes through `rtxpy/accessor.py` (`RTXAccessor`)
- **Engine/viewer**: interactive features in `rtxpy/engine.py` and `rtxpy/viewer/` subsystems
- **Analysis**: raster operations in `rtxpy/analysis/` with `prepare_mesh()` in `_common.py`
- **Mesh utils**: geometry operations in `rtxpy/mesh.py`
- **Data fetching**: `fetch_*` functions for remote data sources
3. When adding viewer features, use the key dispatch pattern:
add entries to `KEY_BINDINGS` / `SHIFT_BINDINGS` / `SPECIAL_BINDINGS` in
`rtxpy/viewer/keybindings.py`, then add thin action methods on `InteractiveViewer`.
4. When adding analysis functions, return standard xarray DataArrays.
5. Keep changes focused -- don't refactor surrounding code unnecessarily.

## Step 4 -- Add Test Coverage

1. Add or update tests in `rtxpy/tests/`.
2. Any temporary files must have unique names. Include the issue number in
the filename (e.g. `tmp_42_result.zarr`) to avoid collisions with
parallel test runs or other worktrees.
3. Cover:
- Correctness against known values or reference implementations
- Edge cases (NaN handling, empty input, single-cell rasters)
- GPU and CPU code paths where applicable
4. Run the tests with `pytest rtxpy/tests/` to verify they pass before moving on.

## Step 5 -- Update Documentation

1. Check `docs/` for the relevant markdown file:
- `docs/api-reference.md` -- method signatures and parameters
- `docs/user-guide.md` -- task-oriented workflows
- `docs/getting-started.md` -- installation and first steps
- `docs/examples.md` -- annotated walkthroughs
2. Add or update the entry for any new public functions or viewer features.
3. If a new data fetcher or analysis function was created, add it to the
appropriate section.

## Step 6 -- Create an Example

The project has an `examples/` directory with both `.py` scripts and `.ipynb` notebooks.

1. Choose the right format:
- `.py` script for CLI-oriented workflows or `explore()` demos
- `.ipynb` notebook for analysis workflows with inline visualization
2. Follow the established patterns from existing examples:
- Fetch data from a bounding box using `fetch_*` functions
- Show the analysis or placement pipeline
- End with `explore()` or a rendered image
3. Use `matplotlib` for static plots, consistent with existing notebooks.
4. Keep the example self-contained (no external data dependencies beyond fetch calls).

**Skip this step** if the change is a pure bug fix with no new user-facing API.

## Step 7 -- Commit, Push, and Create PR

1. Stage and commit changes with a clear message referencing the issue number
(e.g. `Add flood velocity function (#42)`).
2. Push the branch and create a pull request with `gh pr create`.
3. In the PR body, reference the issue (e.g. `Closes #42`) and summarize
what was done.
4. **Run the PR body text through the `/humanizer` skill** before creating.

---

## General Rules

- Work entirely within the worktree created in Step 2.
- Commit progress after each major step with a clear commit message referencing
the issue number.
- Run `/humanizer` on any text destined for GitHub (issue body, PR description)
to remove AI writing artifacts.
- If any step is not applicable (e.g. no docs update needed for a typo fix),
note why and skip it.
- At the end, print a summary of what was done and where the worktree lives.
9 changes: 9 additions & 0 deletions examples/bay_area_fire_risk.py
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,14 @@ def cluster_buildings(bldg_data, terrain_da):
except Exception as e:
print(f" Skipping wind: {e}")

# === Fetch weather data (clouds + rain via Shift+N) =======================
weather = None
try:
from rtxpy import fetch_weather
weather = fetch_weather(BOUNDS, grid_size=15)
except Exception as e:
print(f" Skipping weather: {e}")

print("\n--- Interpolating wind onto DEM grid ---")
wind_speed_gpu, wind_u_gpu, wind_v_gpu = interpolate_wind(wind, terrain)
ds['wind_speed'] = xr.DataArray(
Expand Down Expand Up @@ -695,6 +703,7 @@ def cluster_buildings(bldg_data, terrain_da):
color_stretch='cbrt',
subsample=1,
wind_data=wind,
weather_data=weather,
ao_samples=1,
repl=True,
)
Expand Down
1 change: 1 addition & 0 deletions examples/new_york_city.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
bounds=(-74.26, 40.49, -73.70, 40.92),
crs='EPSG:32618',
features=['buildings', 'roads', 'water', 'fire', 'restaurant_grades', 'gtfs'],
weather=True,
ao_samples=1,
tour=tour,
)
10 changes: 9 additions & 1 deletion examples/nyc_lidar.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,16 @@ def main():
# Save all meshes (buildings + lidar) to zarr for next run
terrain.rtx.save_meshes(zarr_path)

# Fetch weather for cloud + rain overlay (Shift+N)
weather = None
try:
from rtxpy import fetch_weather
weather = fetch_weather(dem_bounds, grid_size=15)
except Exception as e:
print(f"Skipping weather: {e}")

# Launch interactive viewer
terrain.rtx.explore(width=1600, height=1200)
terrain.rtx.explore(width=1600, height=1200, weather_data=weather)


if __name__ == '__main__':
Expand Down
11 changes: 10 additions & 1 deletion examples/playground.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,14 @@ def load_terrain():
except Exception as e:
print(f"Skipping wind: {e}")

# --- Weather data (clouds + rain via Shift+N) -------------------------
weather = None
try:
from rtxpy import fetch_weather
weather = fetch_weather(BOUNDS, grid_size=15)
except Exception as e:
print(f"Skipping weather: {e}")

# --- Hydro flow data (off by default, Shift+Y to toggle) ---------------
hydro = None
try:
Expand Down Expand Up @@ -317,7 +325,7 @@ def load_terrain():
print(f"Skipping hydro: {e}")

print("\nLaunching explore (press G to cycle layers, "
"Shift+W for wind, Shift+Y for hydro)...\n")
"Shift+W for wind, Shift+N for clouds, Shift+Y for hydro)...\n")
ds.rtx.explore(
z='elevation',
scene_zarr=ZARR,
Expand All @@ -326,6 +334,7 @@ def load_terrain():
height=768,
render_scale=0.5,
wind_data=wind,
weather_data=weather,
hydro_data=hydro,
fog_density=3.0,
repl=True,
Expand Down
1 change: 1 addition & 0 deletions examples/port_jefferson.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
source='usgs_1m',
features=['buildings', 'roads', 'water'],
tiles='satellite',
tile_zoom=18,
hydro=True,
wind=True,
weather=True,
Expand Down
10 changes: 10 additions & 0 deletions examples/trinidad_tobago_coastal_resilience.py
Original file line number Diff line number Diff line change
Expand Up @@ -381,13 +381,22 @@ def classify_roads(road_data, raw_elev):
except Exception as e:
print(f"Skipping wind: {e}")

# --- Weather (clouds + rain via Shift+N) -------------------------------
weather = None
try:
from rtxpy import fetch_weather
weather = fetch_weather(BOUNDS, grid_size=15)
except Exception as e:
print(f"Skipping weather: {e}")

# --- Launch explorer ---------------------------------------------------
print("\n" + "=" * 60)
print("COASTAL RESILIENCE EXPLORER")
print("=" * 60)
print(" G cycle layers (elevation → slope → surge_risk → flood maps)")
print(" U toggle satellite overlay")
print(" Shift+W toggle wind particles (storm simulation)")
print(" Shift+N toggle clouds + rain")
print(" O / V set observer / toggle viewshed")
print(" M minimap")
print(" H full help overlay")
Expand All @@ -414,6 +423,7 @@ def classify_roads(road_data, raw_elev):
color_stretch='cbrt',
subsample=1,
wind_data=wind,
weather_data=weather,
minimap_style='cyberpunk',
minimap_layer='surge_risk',
minimap_colors=RISK_COLORS,
Expand Down
Loading
Loading