isistools 0.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- isistools-0.4.0/.gitignore +58 -0
- isistools-0.4.0/CHANGELOG.md +159 -0
- isistools-0.4.0/CLAUDE.md +78 -0
- isistools-0.4.0/LICENSE +21 -0
- isistools-0.4.0/PKG-INFO +139 -0
- isistools-0.4.0/README.md +106 -0
- isistools-0.4.0/default.profraw +0 -0
- isistools-0.4.0/pyproject.toml +57 -0
- isistools-0.4.0/src/isistools/__init__.py +3 -0
- isistools-0.4.0/src/isistools/apps/__init__.py +1 -0
- isistools-0.4.0/src/isistools/apps/components.py +175 -0
- isistools-0.4.0/src/isistools/apps/mosaic_review.py +238 -0
- isistools-0.4.0/src/isistools/apps/tiepoint_review.py +252 -0
- isistools-0.4.0/src/isistools/cli.py +231 -0
- isistools-0.4.0/src/isistools/geo/__init__.py +1 -0
- isistools-0.4.0/src/isistools/geo/projections.py +81 -0
- isistools-0.4.0/src/isistools/io/__init__.py +1 -0
- isistools-0.4.0/src/isistools/io/cache.py +20 -0
- isistools-0.4.0/src/isistools/io/controlnet.py +146 -0
- isistools-0.4.0/src/isistools/io/cubes.py +178 -0
- isistools-0.4.0/src/isistools/io/footprints.py +268 -0
- isistools-0.4.0/src/isistools/plotting/__init__.py +1 -0
- isistools-0.4.0/src/isistools/plotting/cnet_overlay.py +430 -0
- isistools-0.4.0/src/isistools/plotting/footprint_map.py +117 -0
- isistools-0.4.0/src/isistools/plotting/footprint_mpl.py +209 -0
- isistools-0.4.0/src/isistools/plotting/image_viewer.py +196 -0
- isistools-0.4.0/src/isistools/plotting/styles.py +101 -0
- isistools-0.4.0/tests/test_io.py +36 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*.egg-info/
|
|
5
|
+
*.egg
|
|
6
|
+
dist/
|
|
7
|
+
build/
|
|
8
|
+
*.whl
|
|
9
|
+
.venv/
|
|
10
|
+
venv/
|
|
11
|
+
|
|
12
|
+
# Testing / linting
|
|
13
|
+
.ruff_cache/
|
|
14
|
+
.pytest_cache/
|
|
15
|
+
.coverage
|
|
16
|
+
htmlcov/
|
|
17
|
+
.mypy_cache/
|
|
18
|
+
|
|
19
|
+
# Jupyter
|
|
20
|
+
.ipynb_checkpoints/
|
|
21
|
+
|
|
22
|
+
# Quarto output
|
|
23
|
+
/.quarto/
|
|
24
|
+
**/*.quarto_ipynb
|
|
25
|
+
*_files/
|
|
26
|
+
*.html
|
|
27
|
+
_site/
|
|
28
|
+
_freeze/
|
|
29
|
+
|
|
30
|
+
# Bokeh / Panel / HoloViews artifacts
|
|
31
|
+
.panel_cache/
|
|
32
|
+
|
|
33
|
+
# Datashader / dask
|
|
34
|
+
dask-worker-space/
|
|
35
|
+
|
|
36
|
+
# ISIS data files (large binaries)
|
|
37
|
+
*.cub
|
|
38
|
+
*.net
|
|
39
|
+
*.lis
|
|
40
|
+
|
|
41
|
+
# Screenshots / test artifacts
|
|
42
|
+
*.png
|
|
43
|
+
|
|
44
|
+
# OS
|
|
45
|
+
.DS_Store
|
|
46
|
+
Thumbs.db
|
|
47
|
+
|
|
48
|
+
# Claude Code
|
|
49
|
+
.claude/
|
|
50
|
+
|
|
51
|
+
# Editor
|
|
52
|
+
.vscode/
|
|
53
|
+
.idea/
|
|
54
|
+
*.swp
|
|
55
|
+
*~
|
|
56
|
+
|
|
57
|
+
# Playwright
|
|
58
|
+
.playwright-mcp/
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [0.4.0] - 2026-03-10
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **`footprintinit` CLI command**: batch-run ISIS `footprintinit` on all cubes
|
|
15
|
+
in a list file with parallel execution (`-j` flag, default 4 workers).
|
|
16
|
+
- **Static PNG export for footprints** (`--png` flag): publication-ready
|
|
17
|
+
footprint overview images via headless matplotlib (Agg backend). Defaults to
|
|
18
|
+
`footprints_overview.png`; override with `--png-path`. Supports `--dpi` and
|
|
19
|
+
`--title` options.
|
|
20
|
+
- New `footprint_png()` function in `plotting.footprint_mpl` for programmatic
|
|
21
|
+
PNG export.
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
|
|
25
|
+
- Refactored `footprint_mpl.py`: extracted shared `_plot_footprints()` core
|
|
26
|
+
used by both the interactive window viewer and the new PNG exporter.
|
|
27
|
+
`mplcursors` and `QtAgg` backend are now only imported in the interactive
|
|
28
|
+
`footprint_window()` path.
|
|
29
|
+
- `footprints` CLI command accepts `--title` option (defaults to cubelist stem).
|
|
30
|
+
|
|
31
|
+
## [0.3.0] - 2025-02-12
|
|
32
|
+
|
|
33
|
+
### Added
|
|
34
|
+
|
|
35
|
+
- **Disk caching via `diskcache`**: repeated runs skip expensive I/O when
|
|
36
|
+
source files are unchanged. Cached items (at `~/.cache/isistools/`):
|
|
37
|
+
- Per-cube footprint records (PVL parsing + polygon blob reading)
|
|
38
|
+
- Control network DataFrames (protobuf decoding + status classification)
|
|
39
|
+
- Per-cube campt coordinate conversions (subprocess calls)
|
|
40
|
+
- Cache keys include file `mtime_ns` so entries auto-invalidate on
|
|
41
|
+
source file changes.
|
|
42
|
+
- New module `isistools.io.cache` with `get_cache()` accessor.
|
|
43
|
+
- New dependency: `diskcache>=5.6`.
|
|
44
|
+
|
|
45
|
+
### Changed
|
|
46
|
+
|
|
47
|
+
- `load_cnet()` now returns a plain `pd.DataFrame` (stripped of plio's
|
|
48
|
+
`IsisControlNetwork` protobuf internals) for cache compatibility and
|
|
49
|
+
reduced memory footprint.
|
|
50
|
+
|
|
51
|
+
## [0.2.2] - 2025-02-12
|
|
52
|
+
|
|
53
|
+
### Changed
|
|
54
|
+
|
|
55
|
+
- **Eliminated triple PVL parsing**: cube labels are now parsed once in
|
|
56
|
+
`load_footprints()` and reused for footprint extraction and serial lookup.
|
|
57
|
+
`read_footprint()` accepts an optional pre-parsed `label` parameter.
|
|
58
|
+
`load_footprints()` now extracts `SpacecraftClockCount` during the single
|
|
59
|
+
parse, stored in the `clock` column of the GeoDataFrame.
|
|
60
|
+
- **Parallelized campt calls**: `_lonlat_from_campt()` now runs all per-cube
|
|
61
|
+
campt subprocess calls concurrently via `ThreadPoolExecutor`. With N cubes,
|
|
62
|
+
coordinate conversion is roughly N times faster.
|
|
63
|
+
- `cnet_to_geodataframe()` accepts optional `clock_lookup` dict to skip
|
|
64
|
+
rebuilding the serial-number-to-cube mapping from labels.
|
|
65
|
+
|
|
66
|
+
## [0.2.1] - 2025-02-12
|
|
67
|
+
|
|
68
|
+
### Changed
|
|
69
|
+
|
|
70
|
+
- Browser footprint map simplified to single hvplot call with `c="short_pid"`
|
|
71
|
+
color mapping instead of per-filename overlay loop.
|
|
72
|
+
- Added `ctx_short_pid()` utility in `styles.py`, used by both browser and
|
|
73
|
+
`--win` code paths for consistent 18-char CTX product ID display.
|
|
74
|
+
- Registered control points now use black crosses in browser map (matching
|
|
75
|
+
`--win` path); hover disabled on cnet points.
|
|
76
|
+
- Plot enlarged to 1200x800 with larger axis labels (20pt), tick labels (14pt),
|
|
77
|
+
and legend text (15pt). Legend below plot in 3 columns with spacing.
|
|
78
|
+
- Removed `geo=True` from footprint map; using `data_aspect=1` with free-form
|
|
79
|
+
`BoxZoomTool` for undistorted footprints with flexible zoom.
|
|
80
|
+
- Cleaned up footprint hover: removed instrument, target, and filename fields;
|
|
81
|
+
shortened start_time to seconds.
|
|
82
|
+
|
|
83
|
+
### Fixed
|
|
84
|
+
|
|
85
|
+
- `FileNotFoundError` on `import panel` in non-`--win` path: added `_ensure_cwd()`
|
|
86
|
+
guard in CLI before any panel/holoviews import.
|
|
87
|
+
|
|
88
|
+
## [0.2.0] - 2025-02-12
|
|
89
|
+
|
|
90
|
+
### Added
|
|
91
|
+
|
|
92
|
+
- **Native matplotlib footprint viewer** (`--win` flag): lightweight alternative
|
|
93
|
+
to the browser-based Panel/Bokeh viewer. Launches a native window with
|
|
94
|
+
zoom/pan toolbar, hover tooltips showing CTX product ID, and a right-side
|
|
95
|
+
legend with per-filename colors.
|
|
96
|
+
- **Precise campt coordinate conversion**: pre-jigsaw control networks without
|
|
97
|
+
ground coordinates are converted from sample/line to lon/lat using ISIS
|
|
98
|
+
`campt` in batch mode via kalasiris, providing camera-model-accurate positions.
|
|
99
|
+
- Control point overlay on matplotlib footprint viewer: registered points shown
|
|
100
|
+
as black crosses, unregistered as red circles, ignored as gray circles.
|
|
101
|
+
- Window centering support for Qt and Tk matplotlib backends.
|
|
102
|
+
- New dependencies: `matplotlib`, `mplcursors`, `kalasiris`, `PyQt6`.
|
|
103
|
+
|
|
104
|
+
### Changed
|
|
105
|
+
|
|
106
|
+
- Serial lookup utilities (`build_serial_lookup`, `match_serials_to_cubes`)
|
|
107
|
+
moved from `apps.tiepoint_review` to `io.cubes` for reuse without heavy
|
|
108
|
+
imports.
|
|
109
|
+
- Holoviews/hvplot/panel imports made lazy in `cnet_overlay.py` — the `--win`
|
|
110
|
+
path no longer loads browser-plotting machinery, fixing startup crashes and
|
|
111
|
+
improving load time.
|
|
112
|
+
- `cnet_to_geodataframe()` now accepts optional `cube_paths` parameter for
|
|
113
|
+
campt-based coordinate conversion on level-1 networks.
|
|
114
|
+
|
|
115
|
+
### Fixed
|
|
116
|
+
|
|
117
|
+
- `NameError` in `mosaic_review.py` where `_build_serial_lookup` was called but
|
|
118
|
+
never imported.
|
|
119
|
+
- `FileNotFoundError` on startup caused by `os.getcwd()` in `param` triggered
|
|
120
|
+
via transitive holoviews imports in the matplotlib code path.
|
|
121
|
+
|
|
122
|
+
## [0.1.1] - 2025-02-11
|
|
123
|
+
|
|
124
|
+
### Fixed
|
|
125
|
+
|
|
126
|
+
- Control network loading: renamed plio columns (`id`→`pointId`,
|
|
127
|
+
`sampleResidual`→`residualSample`, `lineResidual`→`residualLine`) to
|
|
128
|
+
match isistools conventions.
|
|
129
|
+
- Serial number matching: replaced broken filename-based heuristic with
|
|
130
|
+
`SpacecraftClockCount` lookup from cube labels, fixing "Could not find
|
|
131
|
+
cube files for this pair" in tiepoint review.
|
|
132
|
+
- Duplicate toolbar buttons (wheel_zoom, pan, reset) in image viewer
|
|
133
|
+
resolved via a Bokeh post-render deduplication hook.
|
|
134
|
+
|
|
135
|
+
## [0.1.0] - 2025-02-11
|
|
136
|
+
|
|
137
|
+
### Added
|
|
138
|
+
|
|
139
|
+
- Initial release.
|
|
140
|
+
- I/O layer: cube loading (`load_cube`), footprint reading
|
|
141
|
+
(`read_footprint`, `load_footprints`), control network I/O
|
|
142
|
+
(`load_cnet`, `save_cnet`) via plio.
|
|
143
|
+
- Plotting layer: rasterized image viewer with percentile contrast
|
|
144
|
+
stretch, footprint map with per-filename Category20 colors and
|
|
145
|
+
clickable mute legend, control network point overlays in both image
|
|
146
|
+
and map space.
|
|
147
|
+
- App layer: `MosaicReview` (Qmos replacement) and `TiepointReview`
|
|
148
|
+
(Qnet replacement) as Panel apps.
|
|
149
|
+
- Typer CLI with commands: `mosaic`, `tiepoints`, `footprints`,
|
|
150
|
+
`cnet-info`.
|
|
151
|
+
|
|
152
|
+
[Unreleased]: https://github.com/michaelaye/isistools/compare/v0.4.0...HEAD
|
|
153
|
+
[0.4.0]: https://github.com/michaelaye/isistools/compare/v0.3.0...v0.4.0
|
|
154
|
+
[0.3.0]: https://github.com/michaelaye/isistools/compare/v0.2.2...v0.3.0
|
|
155
|
+
[0.2.2]: https://github.com/michaelaye/isistools/compare/v0.2.1...v0.2.2
|
|
156
|
+
[0.2.1]: https://github.com/michaelaye/isistools/compare/v0.2.0...v0.2.1
|
|
157
|
+
[0.2.0]: https://github.com/michaelaye/isistools/compare/v0.1.1...v0.2.0
|
|
158
|
+
[0.1.1]: https://github.com/michaelaye/isistools/compare/v0.1.0...v0.1.1
|
|
159
|
+
[0.1.0]: https://github.com/michaelaye/isistools/releases/tag/v0.1.0
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## What This Is
|
|
6
|
+
|
|
7
|
+
isistools replaces ISIS3's Qmos and Qnet with Python-based interactive review tools for planetary image coregistration workflows. It reads ISIS .cub files and binary control networks, visualizing footprints, images, and tie points using HoloViews/Panel/Bokeh served in a browser.
|
|
8
|
+
|
|
9
|
+
## Commands
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
pip install -e . # Install in development mode
|
|
13
|
+
pytest tests/ # Run all tests
|
|
14
|
+
pytest tests/test_io.py::TestClassifyPointStatus::test_ignored_point # Single test
|
|
15
|
+
ruff check src/ # Lint
|
|
16
|
+
ruff format src/ # Format
|
|
17
|
+
|
|
18
|
+
# CLI (requires ISIS cubes with footprintinit already run)
|
|
19
|
+
isistools mosaic cubes.lis --cnet control.net
|
|
20
|
+
isistools tiepoints cubes.lis control.net
|
|
21
|
+
isistools footprints cubes.lis
|
|
22
|
+
isistools cnet-info control.net
|
|
23
|
+
|
|
24
|
+
# Quarto docs (front matter in README.md, no _quarto.yml needed)
|
|
25
|
+
quarto render README.md
|
|
26
|
+
quarto preview README.md
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Architecture
|
|
30
|
+
|
|
31
|
+
The codebase follows a three-layer pattern: **I/O → Plotting → Apps**
|
|
32
|
+
|
|
33
|
+
### I/O layer (`io/`)
|
|
34
|
+
- `footprints.py` — Reads footprint polygons from ISIS cubes. The polygon is stored as a WKT/GML blob at a byte offset specified by the `Object = Polygon` block in the PVL label (`StartByte`/`Bytes` fields). **Not** a `^Polygon` pointer.
|
|
35
|
+
- `controlnet.py` — Wraps plio's `from_isis()`/`to_isis()` (not `read_network`/`write_network`, those don't exist). Adds `residual_magnitude` and `status` columns.
|
|
36
|
+
- `cubes.py` — Loads .cub files as xarray DataArrays via rioxarray/GDAL. Normalizes orientation to north-up for level-2 cubes.
|
|
37
|
+
|
|
38
|
+
### Plotting layer (`plotting/`)
|
|
39
|
+
- `footprint_map.py` — Per-filename colored polygons with Category20 palette, clickable mute legend via `legend_opts`. Each filename is a separate hvplot overlay.
|
|
40
|
+
- `image_viewer.py` — Datashader-rasterized image display with percentile contrast stretch.
|
|
41
|
+
- `cnet_overlay.py` — Control points in both image space (sample/line) and map space (lon/lat), with status-based coloring (registered=green, unregistered=red, ignored=gray).
|
|
42
|
+
- `styles.py` — All visual constants: point colors/sizes by status, footprint colors.
|
|
43
|
+
|
|
44
|
+
### App layer (`apps/`)
|
|
45
|
+
- `mosaic_review.py` — MosaicReview class: footprint map + image browser + cnet overlay. Qmos replacement.
|
|
46
|
+
- `tiepoint_review.py` — TiepointReview class: side-by-side image pairs with shared tie points. Qnet replacement.
|
|
47
|
+
- `components.py` — Reusable Panel widgets (cube list selector, cnet selector, info panels).
|
|
48
|
+
|
|
49
|
+
### CLI (`cli.py`)
|
|
50
|
+
Typer-based. Each command constructs an app object and calls `.serve()`. Entry point: `isistools = "isistools.cli:app"`.
|
|
51
|
+
|
|
52
|
+
## Versioning and Releases
|
|
53
|
+
|
|
54
|
+
Single source of truth: `__init__.py` defines `__version__`. `pyproject.toml` reads it dynamically via `[tool.hatch.version]`. **Only edit `__init__.py` when bumping versions.**
|
|
55
|
+
|
|
56
|
+
When releasing a new version, always do all three:
|
|
57
|
+
1. Bump `__version__` in `src/isistools/__init__.py`
|
|
58
|
+
2. Update `CHANGELOG.md` following [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) format (move Unreleased items to the new version section, add comparison links)
|
|
59
|
+
3. Tag the commit as `v{version}`
|
|
60
|
+
|
|
61
|
+
## Key Dependencies and Gotchas
|
|
62
|
+
|
|
63
|
+
- **plio**: API is `from_isis(path)` and `to_isis(df, path)`. Older names like `read_network`/`write_network` do not exist. Plio columns are renamed in `load_cnet()`: `id`→`pointId`, `sampleResidual`→`residualSample`, `lineResidual`→`residualLine`.
|
|
64
|
+
- **Serial numbers**: ISIS serial numbers (e.g., `MRO/CTX/0910464726:234`) use spacecraft clock counts, not product IDs. Match cubes via `SpacecraftClockCount` from the label's Instrument group.
|
|
65
|
+
- **pvl**: ISIS labels are parsed as `PVLModule`. The `Polygon` object has `StartByte` (1-based) and `Bytes`.
|
|
66
|
+
- **hvplot**: `active_tools` and `default_tools` are not valid parameters for hvplot plots — they produce warnings. Use Bokeh hooks or `legend_opts` instead.
|
|
67
|
+
- **hvplot `by=` with `cmap=`**: Does not reliably apply fill/line colors to polygons. Use explicit per-group overlays with `fill_color`/`line_color` instead.
|
|
68
|
+
- **Bokeh legend**: Use `legend_opts={"click_policy": "mute"}` on `hv.opts.Overlay` for clickable legends. No Bokeh hooks needed.
|
|
69
|
+
- **ISIS cubes**: Require GDAL with ISIS3 driver support. Cubes must have `footprintinit` run before footprints can be read.
|
|
70
|
+
- **rioxarray**: Import `rioxarray` to register the `.rio` accessor, even if not called directly.
|
|
71
|
+
|
|
72
|
+
## Style
|
|
73
|
+
|
|
74
|
+
- Line length: 99 (configured in `[tool.ruff]`)
|
|
75
|
+
- Lint rules: E, F, I, W
|
|
76
|
+
- Uses `from __future__ import annotations` throughout
|
|
77
|
+
- Type hints on all public functions
|
|
78
|
+
- src layout: package lives under `src/isistools/`
|
isistools-0.4.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Michael Aye
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
isistools-0.4.0/PKG-INFO
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: isistools
|
|
3
|
+
Version: 0.4.0
|
|
4
|
+
Summary: Python-based review tools for ISIS3 coregistration workflows
|
|
5
|
+
Author: Michael Aye
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
Requires-Python: >=3.10
|
|
9
|
+
Requires-Dist: bokeh>=3.3
|
|
10
|
+
Requires-Dist: datashader>=0.16
|
|
11
|
+
Requires-Dist: diskcache>=5.6
|
|
12
|
+
Requires-Dist: geopandas>=0.14
|
|
13
|
+
Requires-Dist: holoviews>=1.18
|
|
14
|
+
Requires-Dist: hvplot>=0.9
|
|
15
|
+
Requires-Dist: kalasiris>=1.11
|
|
16
|
+
Requires-Dist: matplotlib>=3.7
|
|
17
|
+
Requires-Dist: mplcursors>=0.5
|
|
18
|
+
Requires-Dist: numpy>=1.24
|
|
19
|
+
Requires-Dist: pandas>=2.0
|
|
20
|
+
Requires-Dist: panel>=1.3
|
|
21
|
+
Requires-Dist: plio>=1.5
|
|
22
|
+
Requires-Dist: pvl>=1.3
|
|
23
|
+
Requires-Dist: pyqt6>=6.5
|
|
24
|
+
Requires-Dist: rioxarray>=0.15
|
|
25
|
+
Requires-Dist: shapely>=2.0
|
|
26
|
+
Requires-Dist: typer>=0.9
|
|
27
|
+
Requires-Dist: xarray>=2024.1
|
|
28
|
+
Provides-Extra: dev
|
|
29
|
+
Requires-Dist: pytest; extra == 'dev'
|
|
30
|
+
Requires-Dist: pytest-cov; extra == 'dev'
|
|
31
|
+
Requires-Dist: ruff; extra == 'dev'
|
|
32
|
+
Description-Content-Type: text/markdown
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
format:
|
|
36
|
+
html:
|
|
37
|
+
theme: solar
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
# isistools
|
|
41
|
+
|
|
42
|
+
Python-based review tools for ISIS3 coregistration workflows. Replaces Qmos and Qnet with modern, interactive visualization using HoloViews, Panel, and datashader.
|
|
43
|
+
|
|
44
|
+
## Why?
|
|
45
|
+
|
|
46
|
+
ISIS's Qmos and Qnet have several pain points:
|
|
47
|
+
|
|
48
|
+
- **Qmos** requires level-1 unprojected images but displays footprints in map projection (confusing), and renders image content very slowly.
|
|
49
|
+
- **Qnet** requires level-2 map-projected images but displays them flipped in detector readout order (makes comparison difficult).
|
|
50
|
+
- **Both** use a color scheme where registered control points are nearly invisible while unregistered points are prominent — the opposite of what you want during review.
|
|
51
|
+
|
|
52
|
+
**isistools** fixes all of these by building on the Python geospatial stack.
|
|
53
|
+
|
|
54
|
+
## Features
|
|
55
|
+
|
|
56
|
+
- **Footprint map**: Interactive map of image footprints using geopandas + hvplot, with hover info and click-to-select.
|
|
57
|
+
- **Image viewer**: Fast rasterized image display via rioxarray + datashader. Images always shown in correct (north-up) orientation.
|
|
58
|
+
- **Control network overlay**: Tie points with sensible colors (registered = bright green, unregistered = red, ignored = gray). Residual vectors. Point detail on click.
|
|
59
|
+
- **Dual interface**: Same code works in Jupyter notebooks and as standalone Panel apps in the browser.
|
|
60
|
+
- **CLI**: `isistools mosaic`, `isistools tiepoints`, `isistools footprints` commands that launch Panel apps.
|
|
61
|
+
|
|
62
|
+
## Installation
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
pip install -e .
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Usage
|
|
69
|
+
|
|
70
|
+
### CLI
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
# Mosaic review (Qmos replacement)
|
|
74
|
+
isistools mosaic cubes.lis --cnet control.net
|
|
75
|
+
|
|
76
|
+
# Tiepoint review (Qnet replacement)
|
|
77
|
+
isistools tiepoints cubes.lis control.net
|
|
78
|
+
|
|
79
|
+
# Quick footprint map
|
|
80
|
+
isistools footprints cubes.lis
|
|
81
|
+
|
|
82
|
+
# Control network summary stats
|
|
83
|
+
isistools cnet-info control.net
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Notebook
|
|
87
|
+
|
|
88
|
+
```python
|
|
89
|
+
from isistools.apps.mosaic_review import MosaicReview
|
|
90
|
+
|
|
91
|
+
app = MosaicReview("cubes.lis", cnet_path="control.net")
|
|
92
|
+
app.panel() # renders inline
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
```python
|
|
96
|
+
from isistools.apps.tiepoint_review import TiepointReview
|
|
97
|
+
|
|
98
|
+
app = TiepointReview("cubes.lis", "control.net")
|
|
99
|
+
app.panel()
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Low-level API
|
|
103
|
+
|
|
104
|
+
```python
|
|
105
|
+
from isistools.io.footprints import load_footprints
|
|
106
|
+
from isistools.io.controlnet import load_cnet
|
|
107
|
+
from isistools.io.cubes import load_cube
|
|
108
|
+
from isistools.plotting.footprint_map import footprint_map
|
|
109
|
+
from isistools.plotting.image_viewer import image_plot, image_with_cnet
|
|
110
|
+
from isistools.plotting.cnet_overlay import cnet_to_geodataframe
|
|
111
|
+
|
|
112
|
+
# Load data
|
|
113
|
+
gdf = load_footprints("cubes.lis")
|
|
114
|
+
cnet = load_cnet("control.net")
|
|
115
|
+
da = load_cube("image.cub")
|
|
116
|
+
|
|
117
|
+
# Plot footprints
|
|
118
|
+
footprint_map(gdf)
|
|
119
|
+
|
|
120
|
+
# Plot image with control points
|
|
121
|
+
image_with_cnet(da, cnet, serial_number="MRO/HIRISE/...")
|
|
122
|
+
|
|
123
|
+
# Convert cnet to GeoDataFrame for map overlay
|
|
124
|
+
cnet_gdf = cnet_to_geodataframe(cnet)
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## Requirements
|
|
128
|
+
|
|
129
|
+
- Cubes must have `footprintinit` already run for footprint display
|
|
130
|
+
- Control networks in ISIS3 binary format (compatible with jigsaw)
|
|
131
|
+
- GDAL with ISIS3 driver support (for reading .cub files via rioxarray)
|
|
132
|
+
|
|
133
|
+
## Dependencies
|
|
134
|
+
|
|
135
|
+
Core: geopandas, hvplot, holoviews, datashader, panel, rioxarray, plio, pvl, typer
|
|
136
|
+
|
|
137
|
+
## License
|
|
138
|
+
|
|
139
|
+
MIT
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
---
|
|
2
|
+
format:
|
|
3
|
+
html:
|
|
4
|
+
theme: solar
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# isistools
|
|
8
|
+
|
|
9
|
+
Python-based review tools for ISIS3 coregistration workflows. Replaces Qmos and Qnet with modern, interactive visualization using HoloViews, Panel, and datashader.
|
|
10
|
+
|
|
11
|
+
## Why?
|
|
12
|
+
|
|
13
|
+
ISIS's Qmos and Qnet have several pain points:
|
|
14
|
+
|
|
15
|
+
- **Qmos** requires level-1 unprojected images but displays footprints in map projection (confusing), and renders image content very slowly.
|
|
16
|
+
- **Qnet** requires level-2 map-projected images but displays them flipped in detector readout order (makes comparison difficult).
|
|
17
|
+
- **Both** use a color scheme where registered control points are nearly invisible while unregistered points are prominent — the opposite of what you want during review.
|
|
18
|
+
|
|
19
|
+
**isistools** fixes all of these by building on the Python geospatial stack.
|
|
20
|
+
|
|
21
|
+
## Features
|
|
22
|
+
|
|
23
|
+
- **Footprint map**: Interactive map of image footprints using geopandas + hvplot, with hover info and click-to-select.
|
|
24
|
+
- **Image viewer**: Fast rasterized image display via rioxarray + datashader. Images always shown in correct (north-up) orientation.
|
|
25
|
+
- **Control network overlay**: Tie points with sensible colors (registered = bright green, unregistered = red, ignored = gray). Residual vectors. Point detail on click.
|
|
26
|
+
- **Dual interface**: Same code works in Jupyter notebooks and as standalone Panel apps in the browser.
|
|
27
|
+
- **CLI**: `isistools mosaic`, `isistools tiepoints`, `isistools footprints` commands that launch Panel apps.
|
|
28
|
+
|
|
29
|
+
## Installation
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
pip install -e .
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Usage
|
|
36
|
+
|
|
37
|
+
### CLI
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
# Mosaic review (Qmos replacement)
|
|
41
|
+
isistools mosaic cubes.lis --cnet control.net
|
|
42
|
+
|
|
43
|
+
# Tiepoint review (Qnet replacement)
|
|
44
|
+
isistools tiepoints cubes.lis control.net
|
|
45
|
+
|
|
46
|
+
# Quick footprint map
|
|
47
|
+
isistools footprints cubes.lis
|
|
48
|
+
|
|
49
|
+
# Control network summary stats
|
|
50
|
+
isistools cnet-info control.net
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Notebook
|
|
54
|
+
|
|
55
|
+
```python
|
|
56
|
+
from isistools.apps.mosaic_review import MosaicReview
|
|
57
|
+
|
|
58
|
+
app = MosaicReview("cubes.lis", cnet_path="control.net")
|
|
59
|
+
app.panel() # renders inline
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
```python
|
|
63
|
+
from isistools.apps.tiepoint_review import TiepointReview
|
|
64
|
+
|
|
65
|
+
app = TiepointReview("cubes.lis", "control.net")
|
|
66
|
+
app.panel()
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Low-level API
|
|
70
|
+
|
|
71
|
+
```python
|
|
72
|
+
from isistools.io.footprints import load_footprints
|
|
73
|
+
from isistools.io.controlnet import load_cnet
|
|
74
|
+
from isistools.io.cubes import load_cube
|
|
75
|
+
from isistools.plotting.footprint_map import footprint_map
|
|
76
|
+
from isistools.plotting.image_viewer import image_plot, image_with_cnet
|
|
77
|
+
from isistools.plotting.cnet_overlay import cnet_to_geodataframe
|
|
78
|
+
|
|
79
|
+
# Load data
|
|
80
|
+
gdf = load_footprints("cubes.lis")
|
|
81
|
+
cnet = load_cnet("control.net")
|
|
82
|
+
da = load_cube("image.cub")
|
|
83
|
+
|
|
84
|
+
# Plot footprints
|
|
85
|
+
footprint_map(gdf)
|
|
86
|
+
|
|
87
|
+
# Plot image with control points
|
|
88
|
+
image_with_cnet(da, cnet, serial_number="MRO/HIRISE/...")
|
|
89
|
+
|
|
90
|
+
# Convert cnet to GeoDataFrame for map overlay
|
|
91
|
+
cnet_gdf = cnet_to_geodataframe(cnet)
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Requirements
|
|
95
|
+
|
|
96
|
+
- Cubes must have `footprintinit` already run for footprint display
|
|
97
|
+
- Control networks in ISIS3 binary format (compatible with jigsaw)
|
|
98
|
+
- GDAL with ISIS3 driver support (for reading .cub files via rioxarray)
|
|
99
|
+
|
|
100
|
+
## Dependencies
|
|
101
|
+
|
|
102
|
+
Core: geopandas, hvplot, holoviews, datashader, panel, rioxarray, plio, pvl, typer
|
|
103
|
+
|
|
104
|
+
## License
|
|
105
|
+
|
|
106
|
+
MIT
|
|
File without changes
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "isistools"
|
|
7
|
+
dynamic = ["version"]
|
|
8
|
+
description = "Python-based review tools for ISIS3 coregistration workflows"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = "MIT"
|
|
11
|
+
requires-python = ">=3.10"
|
|
12
|
+
authors = [
|
|
13
|
+
{ name = "Michael Aye" },
|
|
14
|
+
]
|
|
15
|
+
dependencies = [
|
|
16
|
+
"geopandas>=0.14",
|
|
17
|
+
"holoviews>=1.18",
|
|
18
|
+
"hvplot>=0.9",
|
|
19
|
+
"datashader>=0.16",
|
|
20
|
+
"panel>=1.3",
|
|
21
|
+
"bokeh>=3.3",
|
|
22
|
+
"rioxarray>=0.15",
|
|
23
|
+
"xarray>=2024.1",
|
|
24
|
+
"plio>=1.5",
|
|
25
|
+
"pvl>=1.3",
|
|
26
|
+
"shapely>=2.0",
|
|
27
|
+
"numpy>=1.24",
|
|
28
|
+
"pandas>=2.0",
|
|
29
|
+
"typer>=0.9",
|
|
30
|
+
"matplotlib>=3.7",
|
|
31
|
+
"mplcursors>=0.5",
|
|
32
|
+
"kalasiris>=1.11",
|
|
33
|
+
"PyQt6>=6.5",
|
|
34
|
+
"diskcache>=5.6",
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
[project.optional-dependencies]
|
|
38
|
+
dev = [
|
|
39
|
+
"pytest",
|
|
40
|
+
"pytest-cov",
|
|
41
|
+
"ruff",
|
|
42
|
+
]
|
|
43
|
+
|
|
44
|
+
[project.scripts]
|
|
45
|
+
isistools = "isistools.cli:app"
|
|
46
|
+
|
|
47
|
+
[tool.hatch.version]
|
|
48
|
+
path = "src/isistools/__init__.py"
|
|
49
|
+
|
|
50
|
+
[tool.hatch.build.targets.wheel]
|
|
51
|
+
packages = ["src/isistools"]
|
|
52
|
+
|
|
53
|
+
[tool.ruff]
|
|
54
|
+
line-length = 99
|
|
55
|
+
|
|
56
|
+
[tool.ruff.lint]
|
|
57
|
+
select = ["E", "F", "I", "W"]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Panel-based interactive applications for ISIS data review."""
|