Skip to content

Planetary altimetry fixes: MOLA datum, pc_align, MOC + LROC reprocessing#119

Merged
bpurinton merged 8 commits intomainfrom
planetary-fixes
Apr 29, 2026
Merged

Planetary altimetry fixes: MOLA datum, pc_align, MOC + LROC reprocessing#119
bpurinton merged 8 commits intomainfrom
planetary-fixes

Conversation

@bpurinton
Copy link
Copy Markdown
Contributor

@bpurinton bpurinton commented Apr 28, 2026

Closes the four planetary-altimetry feedback items from review:

  • There is a MOLA datum issue seen for the MOC examples. The offset between MOLA and the DEMs is huge.
  • Both MOC examples are from MOC NA camera. Looks like one is map-projected and one is not — should use same structure as ASTER. (One of the mapprojected MOC NA inputs has nodata issue / black border — deferred.)
  • It would be good to do a larger crop of LROC NA example with the full image width (and roughly equivalent height), to mirror some of the WV examples — should bring out the jitter and include more LOLA points.
  • Add a pc_align step for MOLA / LOLA to the ASP outputs, similar to what we do for WorldView and ASTER. Reference: https://asap-stereo.readthedocs.io/en/main/step_by_step_ctx.html

Summary of changes

1. MOLA datum — root cause + fix

The reported "huge offset" was not a stereo error. ASP DEMs store height above the spherical IAU 2000 Mars sphere (3,396,190 m, constant at all latitudes), while MOLA TOPOGRAPHY is referenced to the oblate MOLA areoid. Mars's IAU 2000 ellipsoid drops from 3,396,190 m at the equator to 3,376,200 m at the pole — at lat 34°N (the MOC tutorial scene) the ellipsoid is ~6.2 km below the sphere purely from oblateness, and that's almost exactly the offset the user observed.

The original _load_mola_csv preferred TOPOGRAPHY and had a broken radius branch that subtracted only 190 m. The fix:

  • Read PLANET_RAD (absolute planetary radius from Mars center) from the ODE GDS *_pts_csv.csv and compute height = PLANET_RAD - 3,396,190.
  • Reject the *_topo_csv.csv with an explanatory error pointing the user at the _pts_csv.csv file from the same download (no extra request needed; both come bundled).
  • Verified on the MOC NA tutorial scene: signed median dh dropped from +6,000 m (TOPOGRAPHY path) → +99.74 m (PLANET_RAD path) → +3.13 m (after pc_align).

A separate issue surfaced for LOLA: the Point-per-Row CSV (results=p) carries Pt_Radius in kilometers, not meters like MOLA. The loader now auto-detects km by magnitude (< 10 000) and converts to meters.

2. pc_align for MOLA / LOLA

The existing --pc_align flag was Earth/ICESat-2 only. Extended to planetary:

  • Altimetry.align_and_evaluate_planetary() — sibling of the Earth align_and_evaluate, returning the same AlignmentResult dataclass. Defaults max_displacement=500 m (per ASAP-Stereo's CTX cookbook) and minimum_points=20 (planetary tracks are sparse).
  • Alignment.pc_align_dem_to_planetary_csv() — invokes ASP pc_align with --csv-format '1:lon 2:lat 3:radius_m' and --datum D_MARS/D_MOON, matching the ASP next_steps documentation and the ASAP-Stereo CTX cookbook.
  • Alignment.apply_dem_translation() is now body-aware — picks the right body-centered geocentric "ECEF-equivalent" CRS via a new _GEOCENTRIC_PROJ dict. PROJ refuses to convert across celestial bodies, so Earth uses EPSG:4978 while Mars/Moon use PROJ strings (+proj=geocent +R=...). Without this fix, applying a translation to a Mars/Moon DEM raised RuntimeError: Source and target ellipsoid do not belong to the same celestial body.
  • mapview_plot_planetary_to_dem(plot_aligned=…) and histogram_planetary_to_dem(plot_aligned=…) — pre/post panels share color/bin scales when an aligned DEM is available.
  • CLI: --pc_align now triggers the planetary alignment too. The success path adds an alignment-report page + pre/post mapview + pre/post histogram (mirrors the Earth path's three additional pages); insufficient_points and no_improvement outcomes emit a single alignment-report page instead.

3. MOC notebook consolidated

Two MOC notebooks for different scene pairs were collapsed into one notebook (notebooks/Mars_MGS/mars_mgs_orbital_camera.ipynb) covering both stereo variants of the same M0100115 / E0201461 pair, mirroring the ASTER mapproj/non-mapproj layout. The other notebook + its report were deleted.

Stereo commands match this repo's WorldView convention (parallel_stereo --stereo-algorithm asp_mgm --subpixel-mode 9 --processes 2 --threads 4, --alignment-method affineepipolar for non-mapprojected, --alignment-method none for mapprojected via cam2map4stereo.py).

The intro now contains a callout explaining the spherical-vs-oblate elevation-range surprise — readers familiar with MOLA topography see ~−4 km in northern Elysium, but the ASP DEM Summary table reports ~−10 km because of the geometric oblateness offset.

Reports: MOC-asp-plot-report.pdf (non-mapprojected), MOC_mapproj-asp-plot-report.pdf (mapprojected).

4. LRO NAC reprocessed on a much larger crop

Reprocessed the LRONAC_example.tar pair on the full 5000×5000 cubes instead of the 900×973 sub-window the ASP "lightning fast" tutorial uses. Same conservative threading as the WV pattern (--processes 2 --threads 4), --alignment-method local_epipolar, --stereo-algorithm asp_mgm --subpixel-mode 9.

Resulting DEM is 4720×4510 at 1.04 m GSD (~4.7 km × 4.7 km, vs the old ~1 km × 1 km), 95.88% valid pixels. 1539 of 2044 LOLA points overlap the DEM (vs 12 of 19 on the old crop) — enough for a meaningful pc_align and to bring out spacecraft jitter in the disparity panels.

The notebook (notebooks/LRO_NAC/lunar_recon_orbiter.ipynb) explicitly notes the divergence from the ASP docs and its rationale.

5. Other

  • Black border issue (MOC NA mapproj) — deferred per review request, will revisit after the rest of this work lands.
  • CLAUDE.md / reports/regenerate_reports.sh — updated locally; both are gitignored.

Version

  • pyproject.toml bumped 1.13.0 → 1.14.0
  • CHANGELOG.md entry added at the top with Added / Changed / Documentation sections

References used during the work

Test plan

  • pytest tests/ — all 156 tests pass (4 new tests for the planetary pc_align paths and LOLA km conversion)
  • End-to-end report generation verified for MOC (both variants) and LRO NAC, including the pc_align success branch
  • Verified that pre-existing Earth align_and_evaluate path still passes its existing tests unchanged

MOLA TOPOGRAPHY is referenced to the oblate MOLA areoid, while ASP
DEMs use the IAU 2000 spherical Mars datum (3,396,190 m). The
oblateness alone produces a latitude-dependent offset of up to ~10
km — at lat 34°N the IAU ellipsoid sits ~6.2 km below the IAU
sphere, which matches the previously-reported ~6 km MOC residual.

Switch _load_mola_csv to read PLANET_RAD from the *_pts_csv.csv and
compute height = PLANET_RAD - 3,396,190. The *_topo_csv.csv path is
now rejected with an explanatory error (it cannot be made consistent
without the MOLA areoid grid). The previously-broken radius branch
(subtracted only 190 m instead of the full sphere radius) is gone.

LOLA is unchanged in dh values (Moon is essentially spherical so
TOPOGRAPHY ≈ height-above-1737.4-km-sphere to <1 m), but Pt_Radius
is now preferred when available and a radius_m column is always
populated for use with pc_align downstream.

Verified against mars_MOC_1: dh now ~tens of meters instead of +6000.
Mirror the ICESat-2 align_and_evaluate flow for planetary DEMs.

* Alignment.pc_align_dem_to_planetary_csv runs ASP pc_align with
  --csv-format '1:lon 2:lat 3:radius_m' and --datum D_MARS / D_MOON
  per ASAP-Stereo's CTX cookbook.
* Alignment.apply_dem_translation now picks the correct body-centered
  geocentric CRS (PROJ +proj=geocent +R=...) for Mars/Moon. PROJ
  refuses to convert between celestial bodies, so EPSG:4978 (Earth
  ECEF) only works for Earth.
* Altimetry.to_csv_for_pc_align_planetary writes lon/lat/radius_m
  directly from planetary_points (radius_m is populated by both the
  MOLA and LOLA loaders).
* Altimetry.align_and_evaluate_planetary runs pc_align, evaluates the
  improvement, and on success re-samples the aligned DEM via
  planetary_to_dem_dh. Returns the same AlignmentResult the ICESat-2
  path produces.
* planetary_to_dem_dh now also samples self.aligned_dem_fn when set so
  altimetry_minus_aligned_dem is available for plotting.
* mapview_plot_planetary_to_dem and histogram_planetary_to_dem grow a
  plot_aligned flag — pre/post panels share color/bin scales.
* CLI --pc_align now triggers the planetary alignment too. The
  resulting alignment-report page + map / histogram with aligned-DEM
  overlay are appended to the report just like the Earth path.

Verified on mars_MOC_1: signed median dh dropped from +99.74 m
(unaligned) to +3.13 m (aligned), p50 abs residual 103.76 → 59.65 m.
The two prior MOC notebooks ran different scene pairs through the two
ASP MOC code paths (non-mapprojected affine-epipolar in the tutorial,
mapprojected cam2map4stereo in Section 8.4 of the docs). Re-process
the same M0100115 / E0201461 pair both ways so the comparison is
fair, and keep them in a single notebook that mirrors the ASTER
mapproj/non-mapproj layout.

Stereo commands match the WorldView notebook conventions in this
repo: parallel_stereo with --stereo-algorithm asp_mgm
--subpixel-mode 9 --processes 2 --threads 4. The mapprojected pair
runs cam2map4stereo first and then stereo with --alignment-method
none; the non-mapprojected pair uses --alignment-method affineepipolar
straight on the cubes (the ASP tutorial path).

Reports re-generated:
- MOC-asp-plot-report.pdf — non-mapprojected, with MOLA dh + pc_align
- MOC_mapproj-asp-plot-report.pdf — mapprojected, with MOLA dh + pc_align

Drop the duplicate MOC_NA notebook and report; update docs index/reports.
LOLA RDR's "Point per Row" CSV (results=p) carries Pt_Radius in
**kilometers** (~1737.66) per the ODE GDS schema, while MOLA PEDR's
PLANET_RAD is in **meters** (~3,386,065). The shared loader detected
the radius column either way but produced bogus heights for LOLA Pt
CSVs. Detect units by magnitude (< 10000 → km) and normalize to m.

Also re-render MOC reports at --subset_km 0.5 so the detailed
hillshade panel covers a more representative 0.5 km square instead of
the 0.1 km used while sanity-checking the new pc_align flow.
Mirror the Mars MOC notebook structure: clean docs explaining why we
diverge from the ASP "lightning fast" tutorial (drop the
--left-image-crop-win/--right-image-crop-win sub-window so the full
extent of the 5000x5000 cubes in LRONAC_example.tar is processed),
new directory paths (lunar_lro_nac/out_stereo/), and an automatic
pc_align-against-LOLA section using the same align_and_evaluate_planetary
flow added in the prior commit.

Stereo command matches the WorldView notebooks' threading pattern
(--processes 2 --threads 4) plus --stereo-algorithm asp_mgm
--subpixel-mode 9 --alignment-method local_epipolar (the ASP
recommendation for non-mapprojected lunar pairs with CSM cameras).
The DEM Summary on the MOC report title page reports elevations
around -10,300 to -10,000 m, which is jarring for anyone familiar
with MOLA topography (the same area reads ~-4 km against the MOLA
areoid). The two reference surfaces are different by ~6.2 km at lat
34 deg N purely from Mars's oblateness:

  ASP DEM    -> height above the IAU 2000 sphere (3,396,190 m,
               constant at all latitudes)
  MOLA topo  -> height above the oblate MOLA areoid (radius drops
               ~20 km from equator to pole)

Add a callout in the notebook intro that explains the offset and
points to the next_steps page in the ASP docs. The dh computed by
this repo against PLANET_RAD remains correct (subtracting the
spherical IAU radius produces a signed median dh of ~+100 m on this
scene, dropping to ~+3 m after pc_align), but the elevation range on
the title page is the part that surprises readers.
Reprocess the LRONAC_example pair on the full extent of the cubes in
the ASP example tar (drop --left-image-crop-win/--right-image-crop-win
sub-windowing). Resulting DEM is 4720x4510 at 1.04 m GSD (~4.7 km x
4.7 km, vs the old 842x841 ~1 km x 1 km), 95.88% valid pixels.

LOLA query expanded to match: 1539 of 2044 LOLA points overlap the
DEM (vs 12 of 19 on the old crop). The pc_align step against LOLA is
now meaningful enough to include in the report by default.
Adds the planetary pc_align workflow (MOLA/LOLA), MOLA datum fix,
LOLA km auto-conversion, and refreshed MOC + LRO NAC examples. See
CHANGELOG.md for the full breakdown.
@bpurinton bpurinton merged commit 733d71c into main Apr 29, 2026
1 check passed
@bpurinton bpurinton deleted the planetary-fixes branch April 29, 2026 00:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant