- make test-tooling: planet-gen determinism guard + import_economics
--dry-run, wired into pre-push on TOOLING_CHANGED; ruff widened to
E4/E7/E9/F/W (90 safe auto-fixes applied; E402/E702/F841 ignored with
documented counts)
- one-generator reality fixed in DEVOPS.md, asset-pipeline rule, CLAUDE.md
(import_economics sole generator since #951/D-223); dead check-protocol
target deleted; DEVOPS hook/config sections rewritten from the actual
hook sources; team-patterns gate description updated (client+tooling)
- project.yaml: 0.2.0 → 0.4.0 per the 0.{phase}.{n} scheme, description
refreshed from the v0.1 Sova narration to cascade reality
- stale comment sweep: voxel.rs stub claims (all 8 families implemented),
cascade.rs TODO recited to T-1044, main.rs D-192 handshake claim,
relationships.rs/chunk_streaming.rs version targets → phase language
- gitignore: client/settings.db* e2e-run artifacts
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
127 lines
5.2 KiB
Python
127 lines
5.2 KiB
Python
"""
|
|
Venus (GJ0c) terrain builder.
|
|
|
|
Data source:
|
|
- Elevation: Magellan radar altimetry from USGS Astrogeology
|
|
Global topography at ~4.6 km/px, PDS format.
|
|
|
|
Venus properties:
|
|
- Surface: volcanic, extremely hot (~735K), dense CO2 atmosphere
|
|
- No liquid water, thick clouds
|
|
- Min elevation: ~-2000 m (lowlands)
|
|
- Max elevation: ~11000 m (Maxwell Montes on Ishtar Terra)
|
|
- planet_class: "volcanic", atmosphere: "toxic"
|
|
"""
|
|
|
|
import numpy as np
|
|
from pathlib import Path
|
|
|
|
from sol_data.download import ensure_cached
|
|
from sol_data.shared import (
|
|
GRID_W, GRID_H,
|
|
load_tiff_as_array, load_raw_binary, resample_to_grid, normalize_01,
|
|
compute_hillshade, assemble_terrain,
|
|
temperature_grid_analytical,
|
|
)
|
|
|
|
# Magellan topography — USGS GeoTIFF (reliable, PIL-loadable)
|
|
MAGELLAN_TIFF_URL = "https://planetarymaps.usgs.gov/mosaic/Venus_Magellan_Topography_Global_4641m_v02.tif"
|
|
MAGELLAN_TIFF_FILE = "Venus_Magellan_Topography_Global_4641m_v02.tif"
|
|
|
|
# PDS fallback (raw binary, dimensions may vary)
|
|
MAGELLAN_PDS_URL = "https://pds-geosciences.wustl.edu/mgn/mgn-v-rdrs-5-dim-v1/mg_3002/gedr/gtdr/gtdr_shtplt.img"
|
|
MAGELLAN_PDS_FILE = "venus_magellan_gtdr.img"
|
|
|
|
VENUS_MIN_ELEV_M = -2000.0
|
|
VENUS_MAX_ELEV_M = 11000.0
|
|
VENUS_SURFACE_TEMP_K = 735.0 # nearly uniform due to dense atmosphere
|
|
|
|
|
|
def _load_magellan() -> np.ndarray:
|
|
"""Load Magellan topography data."""
|
|
# Try USGS GeoTIFF first (reliable, well-defined format)
|
|
try:
|
|
path = ensure_cached(MAGELLAN_TIFF_URL, MAGELLAN_TIFF_FILE)
|
|
print(f" loading Magellan GeoTIFF: {path}")
|
|
arr = load_tiff_as_array(str(path))
|
|
# Handle nodata
|
|
arr[arr < -20000] = 0.0
|
|
arr[arr > 20000] = 0.0
|
|
print(f" Magellan shape: {arr.shape}, "
|
|
f"range: [{arr.min():.0f}, {arr.max():.0f}] m")
|
|
return arr
|
|
except Exception as e:
|
|
print(f" GeoTIFF failed ({e}), trying PDS binary...")
|
|
|
|
# PDS fallback — try common dimension/format combinations
|
|
try:
|
|
path = ensure_cached(MAGELLAN_PDS_URL, MAGELLAN_PDS_FILE)
|
|
print(f" loading Magellan PDS: {path}")
|
|
for w, h in [(4096, 2048), (2048, 1024), (8192, 4096)]:
|
|
try:
|
|
arr = load_raw_binary(str(path), w, h, dtype=">i2", offset=0)
|
|
arr[arr > 20000] = 0.0
|
|
arr[arr < -20000] = 0.0
|
|
print(f" Magellan PDS: {w}x{h}, range: [{arr.min():.0f}, {arr.max():.0f}]")
|
|
return arr
|
|
except ValueError:
|
|
continue
|
|
except Exception as e3:
|
|
print(f" PDS also failed ({e3})")
|
|
|
|
# All sources failed — fall through to procedural generation
|
|
print(" WARNING: all Magellan sources failed, using procedural")
|
|
return None
|
|
|
|
|
|
def build_terrain(body_def: dict) -> dict:
|
|
"""Build Venus terrain dict from Magellan data."""
|
|
import sys
|
|
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
|
|
from planet_simulation import compute_biome
|
|
|
|
print(" Venus: loading Magellan data...")
|
|
|
|
# ── 1. Elevation ────────────────────────────────────────────────────
|
|
raw = _load_magellan()
|
|
if raw is None:
|
|
# Fall back to procedural simulation
|
|
import sys
|
|
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
|
|
from planet_simulation import simulate
|
|
return simulate(body_def)
|
|
|
|
from sol_data.shared import greenwich_to_dateline
|
|
shifted = greenwich_to_dateline(raw)
|
|
elevation_m = resample_to_grid(shifted, GRID_H, GRID_W, order=1)
|
|
elevation = normalize_01(elevation_m, VENUS_MIN_ELEV_M, VENUS_MAX_ELEV_M)
|
|
|
|
sea_level = 0.0
|
|
surface_water = np.zeros((GRID_H, GRID_W), dtype=bool)
|
|
|
|
# ── 2. Temperature ──────────────────────────────────────────────────
|
|
# Venus has nearly uniform surface temperature due to dense atmosphere
|
|
temperature_K = temperature_grid_analytical(
|
|
base_T_K=VENUS_SURFACE_TEMP_K,
|
|
elevation=elevation,
|
|
lapse_rate_K_per_unit=50.0, # slight cooling at altitude
|
|
lat_gradient_K=5.0, # almost no lat variation (thick atmo)
|
|
)
|
|
|
|
# ── 3. Moisture ─────────────────────────────────────────────────────
|
|
moisture = np.zeros((GRID_H, GRID_W), dtype=np.float32)
|
|
|
|
# ── 4. Biome ────────────────────────────────────────────────────────
|
|
biome = compute_biome(body_def, elevation, sea_level, surface_water,
|
|
temperature_K, moisture)
|
|
|
|
# ── 5. Hillshade ────────────────────────────────────────────────────
|
|
hillshade = compute_hillshade(elevation)
|
|
|
|
return assemble_terrain(
|
|
elevation=elevation, temperature_K=temperature_K,
|
|
moisture=moisture, biome=biome,
|
|
surface_water=surface_water, hillshade=hillshade,
|
|
rivers=[], sea_level=sea_level,
|
|
)
|