Skip to content

Source Layout

This page maps the tanagerspec package for contributors: what each part of the source tree does, and where new code should go. For why the package is shaped this way, read Architecture first. End users should start with the Quick Walkthrough and the API Reference.

The same orientation is mirrored in two in-repo files next to the code: src/tanagerspec/README.md and, for the analysis subtree, src/tanagerspec/analysis/README.md.

Repository layout

Path Purpose
src/tanagerspec/ Installable package
tests/ Unit and integration tests; HDF5 fixtures in tests/data/tanager/
docs/ MkDocs site (this directory)
notebooks/ Demo notebooks

Package modules

Module User-facing? Notes
tanagerspec.py (TanagerSpec) Yes Scene object; owns dataset and processing state
config.py Internal Centralized constants/defaults; imported as from tanagerspec import config (see Configuration & Constants)
core/ Internal Frozen models (ProductType, CubeMetadata, SpectralCube, LoadedProduct) and the TanagerSpecChild base for namespaces
io/ Internal HDF5-EOS loading (TanagerLoader), shape/dtype introspection, and grid extraction (tanager_grid.py)
process/ Via scene methods preprocess, drop_bands, denoise
viz/ Via scene.plot Matplotlib / Plotly backends
analysis/ Via scene.analysis Exploration, indices, unsupervised, and classification subpackages
converters/ Via scene.convert_to GeoTIFF, ENVI-BIL, and xarray() export
utils/ Mixed IndexCatalog, inspect_hdf, download_scene are public; others are internal helpers
data/ Internal Packaged assets (e.g. indices_bank/tanager_indices.json)

The class-level relationships between these modules — the loader, the frozen models, the scene object, and the three namespaces — are diagrammed and explained on the Architecture page.

Data contract

  • In-memory cube — a NumPy array with shape (bands, rows, cols); the spectral dimension is axis 0.
  • Loader output — a frozen LoadedProduct containing a SpectralCube, per-pixel masks, an optional grid_info, and a ProductType.
  • In-place mutationspreprocess, drop_bands, and denoise update the parent scene; the namespaces see the latest state automatically via TanagerSpecChild.
  • Labeled arrays — for labeled dimensions and interoperability, use scene.convert_to.xarray() (see Conventions).

Where to add new code

Feature type Implement in Expose via
New plot viz/<module>.py A method on Plotting in viz/plot_class.py
New analysis The appropriate analysis/<subpkg>/ module A method on Analysis in analysis/analysis_class.py
New export format converters/<module>.py A method on HDF5Converters in converters/converters_class.py
New loader / sensor io/ + mapping into core.models TanagerSpec.from_file(..., loader=...)
New spectral index data/indices_bank/ JSON + catalog utils scene.analysis.calculate_index()
Shared helper (one domain) The same package as the feature A private import from the namespace class
Shared helper (everywhere) utils/ (keep it small) Re-export from tanagerspec only if it is public API
Shared constant / default config.py from tanagerspec import config; reference as config.NAME instead of an inline literal

Keep the namespace classes (Plotting, Analysis, HDF5Converters) as thin facades: validate inputs, forward to backend functions, and document parameters in the namespace method's docstring.

Steps to add a feature

  1. Implement the logic in the appropriate backend module (viz/,analysis/<subpkg>/, converters/, or process/).
  2. Add a method on Plotting, Analysis, or HDF5Converters that forwards to the backend.
  3. Document the namespace method in its docstring, and update the API Reference for any user-visible API change.
  4. Add tests under tests/, using fixtures from tests/data/tanager/.