Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -182,13 +182,17 @@ The package is organized by functionality, with each module focused on a specifi
- `plot_detailed_hillshade()` auto-selects three subset clips from intersection-error variance (low/medium/high) via `_auto_hillshade_clip_offsets()`. Accepts `clip_windows` (DEM-CRS bboxes) + `clip_windows_crs` to pin/replay clips for run-to-run comparison (issue #121); records the boxes it drew on `self.detailed_hillshade_clips`. Out-of-bounds pinned boxes warn and fall back to auto.
- Key methods: `plot_dem_results()`, `plot_disparity()`, `plot_match_points()`, `plot_detailed_hillshade()`

**`bundle_adjust.py`** - Two main classes
**`bundle_adjust.py`** - Four main classes
- `ReadBundleAdjustFiles`: Reads bundle adjustment CSV outputs (residual pointmaps)
- `get_initial_final_residuals_gdfs()`: Returns initial and final residual GeoDataFrames
- `get_initial_final_geodiff_gdfs()`: Returns geodiff comparison GeoDataFrames (requires `--mapproj-dem` flag in bundle_adjust)
- `get_mapproj_residuals_gdf()`: Returns map-projected residual GeoDataFrame
- `PlotBundleAdjustFiles` (inherits from `Plotter`): Visualizes bundle adjustment residuals before/after optimization
- Plots include map views of residuals, histograms, and geodiff comparisons
- **Camera before/after position/orientation (issues #95, #43)** — visualizes where each camera *moved*, not just the ground residuals. Unlike `csm_camera.py` (which needs the user to pass original + optimized cameras), this is **self-contained on a bundle_adjust output folder** — the pre-BA original cameras are not co-located there.
- `ReadBundleAdjustCameras`: discovery is driven by the `*.adjust` files (rigid ECEF translation `T` + rotation quaternion). Each camera's absolute center is anchored at the **center image line** (sub-satellite point at mid-acquisition, more meaningful than the trajectory mean when the ephemeris is padded beyond the image; falls back to the mean if the timing can't be computed). It comes from its `*.adjusted_state.json` (WorldView/CSM + jitter runs; via `getTimeAtLine` + ephemeris interp) or, for DigitalGlobe runs that write only `.adjust` deltas, from the original camera `.xml` ephemeris (`<EPHEMLIST>` interpolated at `FIRSTLINETIME + (NUMROWS/2)/AVGLINERATE`, via `get_xml_tag`; the XMLs are auto-found in the BA dir + its parent, or via `original_cameras_directory` / CLI `--original_cameras_directory`). The two paths agree to <1 m on the same scenes. `get_camera_optimization_gdf(map_crs, original_cameras_directory)` returns one row per camera with the translation decomposed into local ENU (`t_east/t_north/t_up`, `t_horizontal`), the adjustment `adj_roll/adj_pitch/adj_yaw`, and `horizontal_offset_m/vertical_offset_m` (from `camera_offsets.txt` when present — authoritative, folds in the rotation lever-arm — else derived from `T`; flagged by `offsets_from_asp`). The offsets are associated to cameras **positionally** by zipping `camera_offsets.txt` with `camera_list.txt` (both written per input image, in the same order) and keying by the camera-file basename — no `run-`/`_corr` filename-string guessing (`_camera_label` strips only deterministic file extensions for display). Cameras whose center cannot be located (no state file and no matching XML) are warned and skipped.
- Per ASP's `.adjust` convention (a world point projects the same in the original camera as `R*(P−C)+C+T` in the adjusted, `C` = camera center for pixel (0,0)), `T` is the exact bulk camera-center shift at the anchor pixel; the rotation only adds a lever-arm shift for other lines. `.adjust` naming is matched as both `<base>.adjust` and `<base>.adjusted_state.adjust` (ASTER jitter).
- `PlotBundleAdjustCameras` (inherits from `Plotter`): `plot_center_offset_bars()` (per-camera horizontal + vertical center change; numeric x-labels in the summary), `plot_orientation_cartoons()` (a per-camera satellite cartoon — body + solar panels + nadir sensor frustum — with black body-frame X/Y/Z axes overlaid and a colored rotation arc around each: roll about X, pitch about Y, yaw about Z; degrees printed below; fixed-size arcs so ~1e-4° noise isn't visually exaggerated; `_draw_satellite` draws one cell), and `summary_plot()` stacking bars over the cartoon grid. The earlier map-view/orientation quivers were dropped as misleading (sub-meter shifts can't be drawn to scale on a ~400 km map; a camera-index x-axis gave quiver direction no meaning). CLI: `bundle_adjust_cameras`.

**CSM camera model comparison** — split into three layers by issue #131 (was one 1541-LOC `csm_camera.py`):

Expand Down Expand Up @@ -308,6 +312,11 @@ All CLI tools are in `asp_plot/cli/` and use Click for argument parsing:
- Compares original and optimized CSM camera models
- Visualizes position/angle differences and camera footprints

**`bundle_adjust_cameras.py`** - Self-contained camera before/after position tool (`bundle_adjust_cameras` command)
- Wrapper for `ReadBundleAdjustCameras` + `PlotBundleAdjustCameras` in `bundle_adjust.py`
- Takes a single `--directory` = the bundle_adjust output folder (split internally into the reader's root+subdir); no original cameras needed. `--save_dir` defaults to that same folder
- Renders the three-panel `summary_plot()` (position-change quiver, center-displacement bars, orientation-change quiver)

**`request_planetary_altimetry.py`** - Planetary altimetry data request tool (`request_planetary_altimetry` command)
- Submits async LOLA (Moon) or MOLA (Mars) queries to the ODE GDS REST API
- Auto-detects planetary body from DEM CRS via `detect_planetary_body()`
Expand Down
Loading
Loading