Lightweight lunar terrain analysis: DEM generation, terrain analysis, and rover landing safety.
Project description
lunadem ๐
Lightweight Lunar Terrain Analysis Toolkit
From image to landing site in one import.
lunadem transforms raw lunar images into Digital Elevation Models, terrain analysis, and rover-aware landing safety assessments โ all with a four-line install and a single import lunadem as ld.
No Kaguya. No ONNX. No internet. No configuration required.
Installation
pip install lunadem
For GeoTIFF export support:
pip install "lunadem[geo]"
Runtime dependencies: numpy, scipy, imageio, matplotlib โ nothing else.
Quick Start
import lunadem as ld
# 1. Load a packaged sample image (no internet required)
moon = ld.load_sample(1)
# 2. Convert format
moon = ld.transform(moon, to="png")
# 3. Describe the image
print(ld.describe(moon))
# 4. Estimate scene metadata
metadata = ld.load_metadata(moon)
# 5. Generate a Digital Elevation Model
dem = ld.generate_dem(moon, method="hybrid")
# 6. Visualise the DEM (2D heatmap + 3D surface)
ld.plot(dem)
# 7. Run terrain analysis
analysis = ld.analyze(dem)
print(analysis)
# 8. Evaluate landing safety for Pragyan rover
score = ld.safety_score(rover="pragyan", dem=dem, metadata=metadata)
print(score)
# 9. Find and mark the best landing site
marked = ld.mark_landing_spot(dem, rover="pragyan")
# 10. Visualise landing site
ld.plot(marked)
# 11. Export to PNG
ld.export(marked, "landing_result.png")
Features
| Feature | Description |
|---|---|
| 5 Sample Images | Packaged synthetic lunar terrain โ no download needed |
| 4 DEM Methods | SFS, Multi-scale SFS, ML prior, Hybrid blend |
| Terrain Analysis | Slope, roughness, curvature, histograms |
| Landing Safety | Rover-aware scoring with real physical constraints |
| 9 Rover Presets | Pragyan, Perseverance, Curiosity, Spirit, and more |
| Auto-plotting | One function, adapts to object type automatically |
| Export | PNG, JPEG, TIFF; GeoTIFF with optional rasterio |
| Zero config | All defaults are physically calibrated |
Architecture
lunadem/
โ
โโโ __init__.py โ 14 public names. Nothing else.
โ
โโโ models/ โ 6 public @dataclass types
โ โโโ MoonImage
โ โโโ Metadata
โ โโโ DEM
โ โโโ TerrainAnalysis
โ โโโ SafetyResult
โ โโโ LandingSite
โ
โโโ functions/ โ 1 public function per file
โ โโโ load.py load_sample(), load()
โ โโโ transform.py transform()
โ โโโ describe.py describe()
โ โโโ metadata.py load_metadata()
โ โโโ dem.py generate_dem()
โ โโโ analysis.py analyze()
โ โโโ landing.py safety_score(), mark_landing_spot(), available_rovers()
โ โโโ plotting.py plot()
โ โโโ export.py save(), export()
โ
โโโ internal/ โ All implementation detail (never import directly)
โ โโโ algorithms/ SFS, multi-scale, ML, hybrid
โ โโโ terrain/ slope, roughness, site-finding
โ โโโ image_processing/ loader, transforms
โ โโโ visualization/ matplotlib rendering
โ โโโ utils/ arrays, lighting
โ โโโ rovers.py rover preset registry
โ
โโโ sample_data/ โ 5 ร 256ร256 PNG lunar terrain images
moon1.png โฆ moon5.png
API Reference
Loading
| Function | Description |
|---|---|
ld.load_sample(n) |
Load packaged sample image (n = 1โ5) |
ld.load(path) |
Load external image from disk |
Image Operations
| Function | Description |
|---|---|
ld.transform(image, ...) |
Format, resize, rotate, flip, normalise |
ld.describe(image) |
Width, height, statistics, illumination |
ld.save(image, path) |
Save image to PNG/JPEG/TIFF |
Metadata
| Function | Description |
|---|---|
ld.load_metadata(image) |
Estimate sun angles, resolution, location |
DEM Generation
| Function | Description |
|---|---|
ld.generate_dem(image, method=) |
"sfs" / "multiscale" / "ml" / "hybrid" |
Terrain Analysis
| Function | Description |
|---|---|
ld.analyze(dem) |
Slope, roughness, curvature, histograms |
Landing Safety
| Function | Description |
|---|---|
ld.safety_score(rover=, dem=, metadata=) |
Overall + per-metric safety scores |
ld.mark_landing_spot(dem, rover=) |
Find + annotate the optimal landing site |
ld.available_rovers() |
List all rover preset names |
Output
| Function | Description |
|---|---|
ld.plot(obj) |
Auto-visualise any lunadem object |
ld.export(obj, path) |
Export any lunadem object to file |
Rover Presets
| Key | Display Name | Mission | Agency |
|---|---|---|---|
pragyan |
Pragyan (default) | Chandrayaan-3 | ISRO |
pragyan_prototype |
Pragyan Prototype | Chandrayaan-2 | ISRO |
future_indian_rover |
Future Indian Rover | ISRO Future Mission | ISRO |
viper |
VIPER | Volatiles Investigating Polar Exploration | NASA |
yutu |
Yutu | Chang'e 3 | CNSA |
yutu2 |
Yutu-2 | Chang'e 4 | CNSA |
lunokhod1 |
Lunokhod 1 | Luna 17 | Soviet space program |
lunokhod2 |
Lunokhod 2 | Luna 21 | Soviet space program |
perseverance |
Perseverance | Mars 2020 | NASA |
curiosity |
Curiosity | Mars Science Laboratory | NASA |
spirit |
Spirit | Mars Exploration Rover A | NASA |
opportunity |
Opportunity | Mars Exploration Rover B | NASA |
sojourner |
Sojourner | Mars Pathfinder | NASA |
ld.available_rovers()
# ['curiosity', 'future_indian_rover', 'lunokhod1', 'lunokhod2', 'opportunity',
# 'perseverance', 'pragyan', 'pragyan_prototype', 'sojourner', 'spirit',
# 'viper', 'yutu', 'yutu2']
Sample Images
Five synthetic-but-physically-realistic 256ร256 lunar terrain images are included:
| Sample | Scene |
|---|---|
ld.load_sample(1) |
Classic cratered terrain โ medium craters on rolling plain |
ld.load_sample(2) |
Highland ridges โ diagonal ridgeline with sparse craters |
ld.load_sample(3) |
Flat maria โ low-relief dark plain with long shadows |
ld.load_sample(4) |
Multi-crater overlap โ complex overlapping impact history |
ld.load_sample(5) |
Heavily shadowed terrain โ dramatic low-sun-angle scene |
Generated using Lambertian reflectance + directional lighting โ no real mission data required.
Return Types
All functions return typed dataclasses:
@dataclass
class MoonImage:
pixels: np.ndarray # float32, shape (H, W), values in [0, 1]
format: str # "png" | "jpg" | "tiff" | "grayscale"
source: str # file path or "sample:<n>"
width: int
height: int
@dataclass
class DEM:
elevation: np.ndarray # float32 metres, shape (H, W)
method: str # "sfs" | "multiscale" | "ml" | "hybrid"
pixel_scale_m: float
@dataclass
class SafetyResult:
overall_score: float # 0โ100
recommended: bool
slope_score: float
roughness_score: float
hazard_score: float
safe_fraction: float
rover: str
Roadmap
-
ld.compare(dem_a, dem_b)โ visual DEM difference map -
ld.export(dem, "surface.obj")โ 3-D mesh export - Custom rover specs via
ld.mark_landing_spot(dem, rover={"length_m": 1.2, ...}) - Real LROC/Chandrayaan image loader (optional plugin)
- Interactive Plotly rendering (optional
lunadem[interactive])
Contributing
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch (
git checkout -b feature/my-feature) - Follow the existing code style (Black + ruff)
- Add tests for new functionality
- Submit a pull request
# Development setup
pip install -e ".[dev]"
pytest tests/ -v
License
MIT ยฉ Kartavya Suryawanshi
See LICENSE for the full text.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file lunadem-1.0.1.tar.gz.
File metadata
- Download URL: lunadem-1.0.1.tar.gz
- Upload date:
- Size: 50.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1f3f8a0fc6b41d2a8814cd024aa923e3454e2fd3da906045d331cc6cbb5caa9a
|
|
| MD5 |
d15eaeef86ffa7dee4c0588886a1664e
|
|
| BLAKE2b-256 |
252c08d15c716fb036b371857b275ab58d29b2a5c161aacfa3bf3ad94b73a3f1
|
File details
Details for the file lunadem-1.0.1-py3-none-any.whl.
File metadata
- Download URL: lunadem-1.0.1-py3-none-any.whl
- Upload date:
- Size: 54.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a51762dbca1d0094f0be5909de05c6c4e156dfbf04399bcab09ac00b2b41a746
|
|
| MD5 |
3255c48d95f34471a5c3d8dfbc8a3293
|
|
| BLAKE2b-256 |
6d2e8b2e86d7e0f99476806b03e7c23d1a1aaa81cbaec05521a024380c5632d3
|