lunar_toolkit.reference
¶
Reference data for the Artemis III candidate regions: PGDA LOLA 5 m site DEMs and Bertone et al. SfS DEMs.
PS_SRS = '+proj=stere +lat_0=-90 +lat_ts=-90 +lon_0=0 +x_0=0 +y_0=0 +R=1737400 +units=m +no_defs'
module-attribute
¶
South polar stereographic on the 1737.4 km sphere (PGDA and Bertone et al. rasters).
ASP_CSV_FORMAT = '1:easting 2:northing 3:height_above_datum'
module-attribute
¶
--csv-format for write_asp_csv output (use with
--csv-srs PS_SRS).
NAC_FOCAL_MM = {'LEFT': 699.62, 'RIGHT': 701.57}
module-attribute
¶
LROC NAC focal lengths (mm) of the ISIS / ALE camera models, by name_sensor suffix.
PsBox(x0, y0, x1, y1)
dataclass
¶
Axis-aligned box in south polar stereographic metres (PS_SRS).
| Parameters: |
|
|---|
bounds
property
¶
(xmin, ymin, xmax, ymax).
projwin
property
¶
GDAL / ASP projwin order: (ulx, uly, lrx, lry).
center_latlon
property
¶
Centre as (lat, lon) degrees, lon in −180..180.
ring_lonlat(step_m=100.0)
¶
Closed (lon, lat) ring of the box edges, sampled every step_m metres.
aoi(step_m=100.0)
¶
wkt(step_m=100.0)
¶
POLYGON WKT of ring_lonlat (lon/lat degrees).
wkt_ps()
¶
POLYGON WKT of the corners in PS metres.
PgdaSite(name, description, extent)
dataclass
¶
A PGDA LOLA 5 m/px site DEM (Barker et al. 2021): name, description and PS extent.
Region(id, name, bbox, center, pgda_site, zenodo_file, zenodo_size, zenodo_md5)
dataclass
¶
A 2022 Artemis III candidate landing region as processed by Bertone et al. (2026).
bbox (min_lon, min_lat, max_lon, max_lat) and center
(lon, lat, the bbox midpoint) come from the Zenodo README; roi is
the polar stereographic square the SfS DEM covers, which is the extent of
the matching PGDA LOLA 5 m site DEM (pgda_site).
HttpRangeFile(url, timeout=60.0)
¶
Bases: RawIOBase
Read-only, seekable view of a remote file through HTTP Range requests.
Lets zipfile.ZipFile read a remote zip's central directory or a
single member without downloading the archive.
get_region(key)
¶
Look up a region by id, name, slug or PGDA site (case-insensitive).
11, "11", "Malapert Massif", "malapert-massif",
"malapert" and "Site23" all give region 11. A partial name must
match exactly one region.
regions_table()
¶
All regions as a table (one row per region).
bbox_ps_box(bbox, samples=200)
¶
PS envelope of a lon/lat (min_lon, min_lat, max_lon, max_lat) box (south).
crop_window(region, size_km=2.5, center=None, snap_m=5.0)
¶
Square PS window of size_km centred on a region.
| Parameters: |
|
|---|
| Returns: |
|
|---|
parse_pgda_index(html)
¶
site → kind → [url, ...] from the PGDA product page HTML.
Links may be absolute, root-relative or relative to PGDA_ROOT
(DM2/Clones/DM2_final_adj_5mpp_0001_err.tif); clones are sorted by
number.
pgda_index(refresh=False, cache_dir=REFERENCE_CACHE_DIR, html=None)
¶
PGDA LOLA 5 m file index, parsed from the product page and cached.
| Parameters: |
|
|---|
pgda_urls(site_or_region, kinds=('surf',), clones=None, index=None)
¶
kind → [url, ...] for one PGDA site.
| Parameters: |
|
|---|
fetch(url, dest, expected_md5=None, force=False, show_progress=True, retries=4)
¶
Resumable download of url to dest, skipped when dest exists.
Throttling replies (403 / 429) and server errors are retried with
back-off; the .part file is resumed each time.
download_pgda(site_or_region, kinds=('surf',), out_dir=Path('.'), clones=None, force=False, show_progress=True, index=None)
¶
Download PGDA LOLA 5 m files of one site by kind (sequentially; resumable).
Files land in out_dir/<site>/ (clones in out_dir/<site>/Clones/);
existing ones are kept unless force. Arguments as in pgda_urls.
| Returns: |
|
|---|
read_xyzi(path, box=None)
¶
Read a PGDA .xyzi LOLA point cloud.
The file is little-endian float64 rows of X, Y, Z, RDRid with X/Y the
polar stereographic coordinates and Z the height above the 1737.4 km
sphere, all in km (the same Z as the *_surf.tif metres), and RDRid the
LOLA RDR YYDOYHHMM.
| Parameters: |
|
|---|
| Returns: |
|
|---|
write_asp_csv(points, out, box=None)
¶
Write LOLA points as an ASP CSV of easting, northing, height_above_datum.
Use with --csv-format ASP_CSV_FORMAT and --csv-srs
PS_SRS (the 1737.4 km sphere is then the datum), e.g.
pc_align --csv-format '1:easting 2:northing 3:height_above_datum'
--csv-srs '+proj=stere +lat_0=-90 +lon_0=0 +R=1737400 +units=m' dem.tif lola.csv.
| Parameters: |
|---|
parse_zenodo_files(record)
¶
[{"key", "size", "md5", "url"}, ...] from a Zenodo record API response.
zenodo_files(refresh=False, cache_dir=REFERENCE_CACHE_DIR)
¶
Files of the Bertone et al. Zenodo record (fetched once, then cached).
download_sdem(region, out_dir=Path('.'), force=False, show_progress=True)
¶
Download a region's Bertone et al. zip (1–4 GB; resumable, MD5-checked).
sdem_members(source)
¶
Members of a Bertone et al. zip: a local path, or a region (remote, central directory only).
| Returns: |
|
|---|
select_members(names, patterns)
¶
Zip member names matching any pattern.
A pattern with *, ? or [ is a glob against the full name and
the base name ("SLOPE_MAPS/*_100.tif"); otherwise it is a
case-insensitive substring of the base name ("GLDELEV", "README").
extract_sdem(source, members=('GLDELEV',), out_dir=Path('.'), force=False)
¶
Extract selected members of a Bertone et al. zip.
| Parameters: |
|
|---|
| Returns: |
|
|---|
published_members(source, kind='GLDACAM')
¶
Per-image members of a Bertone et al. zip: cameras (GLDACAM) or mapprojected images (GLDIMGP).
| Returns: |
|
|---|
parse_image_status(text)
¶
Parse extra/image_status_*.csv: product_id and status.
Statuses are used_for_sfs (the SfS inputs, one GLDACAM camera
each), not_aligned (dropped by bundle adjustment) and
available_not_selected. The # key: value header lines go to
attrs["summary"] (counts as ints).
image_status(source, out_dir=REFERENCE_CACHE_DIR / 'published', force=False)
¶
A region's image status table (parse_image_status),
extracted once to out_dir.
parse_tiff_extent(head)
¶
Extent of a north-up GeoTIFF from its first bytes (header, IFD and georeferencing tags).
Reads ImageWidth / ImageLength with ModelPixelScale and
ModelTiepoint (or ModelTransformation) from a classic TIFF whose
IFD and tag values lie inside head (GDAL writes them first, so 16 KB
is plenty for the Bertone et al. GLDIMGP maps).
published_extents(source, cache=None, head_bytes=16384)
¶
PS extents of a region's mapprojected input images (LROC-NAC-maps/*_GLDIMGP_*.tif).
Only the start of each member is read (remotely: about 2 small HTTP Range requests per image), so this is a cheap way to find the images over a crop window. The maps are cropped to the valid pixels' bounding box within the ROI, so a diagonal strip's extent over-covers.
| Parameters: |
|
|---|
| Returns: |
|
|---|
images_covering(extents, box, min_fraction=0.0)
¶
Product IDs whose extent overlaps box by more than min_fraction of the box area.
published_cameras(region, out_dir, images=None, window=None, source=None, force=False)
¶
Extract the Bertone et al. bundle-adjusted NAC cameras (LROC-NAC-adjust/*_GLDACAM_*.json).
Each file is an ASP / USGS CSM linescan model state (model-name line,
then JSON) with the bundle adjustment and LOLA registration baked in.
It describes the full image ISIS-reduce-d by an integer factor to
about 5 m/px (see published_reduce_factor and
published_camera_native).
| Parameters: |
|
|---|
| Returns: |
|
|---|
published_reduce_factor(camera)
¶
reduce factor of a published camera: NAC focal length / its (scaled) m_focalLength.
published_camera_native(camera, native_size)
¶
Published camera re-mapped to the full-resolution image ((samples, lines) of the EDR / cube).
The published states keep the detector summing and divide the focal
length and detector-sample origin by the reduce factor f; their
m_nLines / m_nSamples are the native size divided by f**2
(not f), which only affects usgscsm's initial ground-to-image guess.
The result is a state for the native image with consistent sizes; use
lunar_toolkit.csm.camera_for_cube or
lunar_toolkit.csm.isis_reduce_with_csm to get any crop or
reduction of it.