Tutorial 1 — ASTER Mt. Rainier#

Reading this as a static page? To run the notebook, open this repo in a GitHub Codespace; ASP and asp-plot come pre-installed.

An end-to-end ASP run. A single ASTER L1A scene to a 30 m DEM, twice: first from the raw imagery, then orthorectified onto a Copernicus reference DEM, each with a diagnostic PDF report.

We chose ASTER for the first tutorial because:

  • The data is fully open. We use a Zenodo-hosted V003 archive; no Earthdata login.

  • A single L1A scene contains both the nadir-looking and back-looking views, so there’s no “finding a pair” step.

What we’ll do#

  1. Download the L1A archive from Zenodo.

  2. Run aster2asp to extract the nadir and back-looking imagery and camera files.

  3. Run parallel_stereo and point2dem on the raw imagery for a first 30 m DEM.

  4. Generate a PDF report with asp-plot.

  5. Clip a Copernicus DEM tile from AWS Open Data.

  6. Re-process with orthorectification (ASP calls it “mapprojection”) onto the Copernicus DEM.

  7. Generate a second report and compare.

Scene: ASTER L1A acquired 2017-07-31 over Mt. Rainier, WA.

Reference: ASP’s official ASTER example.

from pathlib import Path

DATA = "../data/aster_rainier"

!mkdir -p {DATA}

REF_DEM = f"{DATA}/ref/cop30_rainier.tif"

1. Download the scene#

We use the V003 archive on Zenodo (preserved for tutorials after NASA decommissioned V003 in Dec 2025). The download_aster.sh script handles fetch + unzip; if the data is already there it’s a no-op.

!bash ../scripts/download_aster.sh {DATA}
!ls -1 {DATA}/dataDir/ | head

2. Sensor prep — aster2asp#

aster2asp reads the L1A archive and writes out four files: a nadir-view image (out-Band3N.tif), a back-looking image (out-Band3B.tif), and an XML camera file for each. After this step the data is in the standard “image.tif + image.xml” pair that the rest of ASP works with.

if Path(f"{DATA}/out-Band3N.tif").exists():
    print(f"{DATA}/out-Band3N.tif exists — skipping aster2asp. Delete out-Band3*.* to reprocess.")
else:
    !aster2asp {DATA}/dataDir -o {DATA}/out

!ls -1 {DATA}/out-Band3*.tif {DATA}/out-Band3*.xml

3. Stereo — 30 m DEM from the raw imagery#

Run parallel_stereo directly on the raw imagery — no bundle adjustment, no orthorectification — and grid the result at 30 m.

  • -t aster selects the ASTER session (knows about ASTER cameras).

  • --stereo-algorithm asp_bm: plain block matching, fast.

  • --subpixel-mode 1: parabolic subpixel refinement, cheaper than Bayes-EM.

  • --processes 4 --threads-multiprocess 1 matches the 4-core Codespace floor. On a larger machine, bump --processes to your core count.

%%time
if Path(f"{DATA}/stereo/run-DEM.tif").exists():
    print(f"{DATA}/stereo/run-DEM.tif exists — skipping stereo. Delete {DATA}/stereo/ to reprocess.")
else:
    !parallel_stereo -t aster \
        --stereo-algorithm asp_bm \
        --subpixel-mode 1 \
        --processes 4 --threads-multiprocess 1 \
        {DATA}/out-Band3N.tif {DATA}/out-Band3B.tif \
        {DATA}/out-Band3N.xml {DATA}/out-Band3B.xml \
        {DATA}/stereo/run

    !point2dem --tr 30 -r earth --auto-proj-center --errorimage {DATA}/stereo/run-PC.tif

!ls -lh {DATA}/stereo/run-DEM.tif

4. First report#

The asp-plot CLI produces a PDF report: input scenes, disparity, hillshades, and an ICESat-2 ATL06-SR comparison with pc_align alignment.

We disable --plot_geometry because ASTER doesn’t have the per-scene XML metadata that DigitalGlobe/Vantor provides for the stereo-geometry skyplot.

Expect this cell to take a few minutes; it fetches ATL06-SR data via SlideRule and runs pc_align.

%%time
if Path(f"{DATA}/stereo/rainier_aster_report.pdf").exists():
    print(f"{DATA}/stereo/rainier_aster_report.pdf exists — skipping asp_plot CLI. Delete it to regenerate.")
else:
    !asp_plot \
        --directory {DATA} \
        --stereo_directory stereo \
        --plot_altimetry True \
        --plot_geometry False \
        --subset_km 5 \
        --report_filename rainier_aster_report.pdf

The report is at: data/aster_rainier/stereo/rainier_aster_report.pdf.

5. Reference DEM from AWS Copernicus DEM#

Orthorectification needs a reference DEM. Copernicus GLO-30 is on AWS Open Data; no API key, no auth.

scene_bbox runs ASP’s camera_footprint on each view and unions the results; utm_epsg picks the UTM zone at the bbox center. fetch_cop_dem.py then clips, mosaics, and reprojects the matching COP30 tiles.

from utils import scene_bbox, utm_epsg

BBOX = scene_bbox(
    (f"{DATA}/out-Band3N.tif", f"{DATA}/out-Band3N.xml"),
    (f"{DATA}/out-Band3B.tif", f"{DATA}/out-Band3B.xml"),
    session="aster",
)
T_SRS = utm_epsg(BBOX)
print(f"Scene bbox: {BBOX}  UTM: {T_SRS}")

Path(f"{DATA}/ref").mkdir(exist_ok=True)

if Path(REF_DEM).exists():
    print(f"{REF_DEM} exists — skipping COP30 fetch. Delete it to redownload.")
else:
    !python ../scripts/fetch_cop_dem.py \
        --bbox {BBOX} \
        --t-srs {T_SRS} \
        --tr 30 \
        --out {REF_DEM}

!ls -lh {REF_DEM}

6. Orthorectified pass#

Run mapproject to orthorectify both images onto the Copernicus DEM at 15 m, and re-run stereo on the orthorectified pair. The matcher’s search range is much smaller because the inputs are already aligned to the terrain.

%%time
if Path(f"{DATA}/stereo_ortho/run-DEM.tif").exists():
    print(f"{DATA}/stereo_ortho/run-DEM.tif exists — skipping mapprojected pass. Delete {DATA}/stereo_ortho/ to reprocess.")
else:
    !mapproject --t_srs {T_SRS} --tr 15 \
        {REF_DEM} \
        {DATA}/out-Band3N.tif {DATA}/out-Band3N.xml \
        {DATA}/out-Band3N_ortho.tif

    !mapproject --t_srs {T_SRS} --tr 15 \
        {REF_DEM} \
        {DATA}/out-Band3B.tif {DATA}/out-Band3B.xml \
        {DATA}/out-Band3B_ortho.tif

    !parallel_stereo -t aster \
        --stereo-algorithm asp_mgm \
        --subpixel-mode 9 \
        --dem {REF_DEM} \
        --processes 1 --threads-multiprocess 4 \
        {DATA}/out-Band3N_ortho.tif {DATA}/out-Band3B_ortho.tif \
        {DATA}/out-Band3N.xml {DATA}/out-Band3B.xml \
        {DATA}/stereo_ortho/run

    !point2dem --tr 30 -r earth --auto-proj-center --errorimage {DATA}/stereo_ortho/run-PC.tif

!ls -lh {DATA}/stereo_ortho/run-DEM.tif

7. Second report#

Same report against the orthorectified DEM, now with the Copernicus DEM as the reference for difference maps.

--reuse_selections points at the sidecar the first report left behind and replays its figure choices — the same ICESat-2 sample points, profile track, and hillshade crops. The two reports then line up panel for panel, so the comparison reflects the processing change rather than different figure selections.

%%time
if Path(f"{DATA}/stereo_ortho/rainier_aster_ortho_report.pdf").exists():
    print(f"{DATA}/stereo_ortho/rainier_aster_ortho_report.pdf exists — skipping asp_plot CLI. Delete it to regenerate.")
else:
    prior = f"{DATA}/stereo/rainier_aster_report_figure_selections.yml"
    reuse = f"--reuse_selections {prior}" if Path(prior).exists() else ""
    !asp_plot \
        --directory {DATA} \
        --stereo_directory stereo_ortho \
        --reference_dem {REF_DEM} \
        --plot_altimetry True \
        --plot_geometry False \
        --subset_km 5 \
        {reuse} \
        --report_filename rainier_aster_ortho_report.pdf

The reports are at:

What’s next#

Tutorial 2: WorldView-3 UCSD adds high-resolution commercial imagery, cropping, and ICESat-2 alignment. Tutorial 3 adds bundle adjustment on top of it.

→ For deeper ASTER processing (jitter correction, full bundle adjust), see asp-plot’s ASTER notebooks.