TanagerSpec β Quick Walkthrough¶
A copy-paste reference for every TanagerSpec capability β one concise snippet per feature, in workflow order: load β preprocess β visualize β analyze β export.
| Want more depth? | |
|---|---|
| Full Walkthrough | Detailed parameters, return types, and before/after examples (interactive notebook) |
| API Reference | Complete method signatures and parameter tables |
| Crash Course | 8 hands-on lessons that teach when and why to connect these tools |
π°οΈ Load & orient¶
Pull a scene straight from Planet's Open Data STAC, peek inside the raw HDF5-EOS file, and load it into a single working object. .info() is your living dashboard β it reflects the current state of the cube at every step of the pipeline.
from tanagerspec import TanagerSpec, download_scene, inspect_hdf
download_scene(URL, output_path="scene.h5")
inspect_hdf("scene.h5") # pretty-print the file tree
scene = TanagerSpec.from_file("scene.h5", loader="TanagerLoader")
scene.info() # metadata, band layout, status
π§Ή Preprocess¶
Clean and prepare your data with a focused set of tools. Operations are applied in place to respect memory on large cubes, and are safe to re-run.
scene.drop_bands([(400, 500), (1000, 1250)]) # exclude noisy ranges (nm)
scene.preprocess(masking=True, clipping=True) # cloud/cirrus masks + clip to 0β1
scene.denoise(n_components=3) # PCA-based denoising
π Visualize & explore¶
A rich toolkit for seeing your data β from quick composites to interactive pixel hunting and animated spectral sweeps.
scene.plot.rgb(preset="true_color") # true/false-color composite
scene.plot.bands_gallery(target_wvls=[450, 850, 2200], cmap="viridis")
scene.plot.bands_histograms(target_wvls=[450, 850, 2200])
scene.plot.analyze_reflectance_band(target_wavelength=850) # map + histogram
scene.plot.hunt_pixels() # interactive coordinate finder
scene.plot.pixel_spectra(targets={"Veg1": (403, 495)}) # compare signatures
scene.plot.roi_spectral_variability(target_name="Canopy", coords=(350, 420), window_size=5)
scene.plot.animate_bands(start_wvl=400, end_wvl=1000, fps=8, filename="sweep.gif")
scene.plot.bands_correlation() # band-to-band heatmap
π Spectral indices (200+)¶
A built-in catalog bundles over 200 published spectral indices across many application domains β vegetation, water, soil, snow, burn, urban, and clouds β so you can compute a published index without tracking down its formula or matching wavelengths by hand.
from tanagerspec import IndexCatalog
cat = IndexCatalog()
cat.print_domains() # list all domains
cat.print_indices_by_domain("vegetation") # browse a domain
cat.print_index("EVI2") # formula, wavelengths, citation
cat.search(query="evi", domain="vegetation") # keyword search
# Compute and visualize in one call
ndvi = scene.analysis.calculate_index(
index_name="NDVI",
plot=True,
cmap="RdYlGn",
present_rgb="false_color_nir",
mask_threshold=0.7,
)
# Compare two index maps side by side
scene.analysis.compare_layers(
first_index=ndvi, second_index=evi2,
index1_name="NDVI", index2_name="EVI2",
)
π§ͺ Index Creator Lab¶
Built for scientists who want to design their own indices and exploit Tanager's contiguous bands. Prototype any f(RA, RB) formula β TanagerSpec handles the windowing, masking, and visualization for you.
# Default normalized-difference formula, (RA - RB) / (RA + RB)
result = scene.analysis.index_creator_lab(
target_dict={"Veg": (403, 495), "Soil": (400, 140)},
color_dict={"Veg": "green", "Soil": "sienna"},
band_x=("NIR", 760, 850, "firebrick"),
band_y=("Red", 650, 680, "seagreen"),
index_name="NDVI (reinvented)",
cmap="RdYlGn",
)
my_index = result["index_image"]
# ...or supply your own math
import numpy as np
def evi2_index(RA, RB):
return 2.5 * (RA - RB) / (RA + 2.4 * RB + 1.0)
scene.analysis.index_creator_lab(
target_dict={"Veg": (403, 495)},
color_dict={"Veg": "green"},
band_x=("NIR", 760, 850, "firebrick"),
band_y=("Red", 650, 680, "seagreen"),
index_func=evi2_index,
index_name="EVI2 (custom)",
)
A band-discovery funnel helps you find informative regions before you commit:
scene.plot.bands_correlation() # where is the contrast?
scene.analysis.compare_band_range(preset="red_edge", # rank pairs in a region
sort_by="mean_abs_normalized_difference")
scene.analysis.compare_bands(first_wavelength=701, # confirm separability
second_wavelength=746)
π€ Machine learning¶
Move from spectral understanding to unsupervised and supervised mapping β all from the same object, all able to export GIS-ready rasters with save_geotiff=.
# Dimensionality reduction (PCA / ICA / MNF)
pca = scene.analysis.dim_reduction(method="PCA", n_components=3, present_rgb="false_color_nir")
# Clustering (KMEANS / GMM)
clusters = scene.analysis.clustering(
dr_method="PCA", n_components=3,
clustering_method="KMEANS", n_clusters=5,
save_geotiff="clusters.tif",
)
# Build a spectral library from labeled points
library_stats, df_training = scene.build_spectral_library(
targets={"veg": (369, 364), "building": (294, 509), "water": (518, 451)},
window_size=5,
export_csv="training_set.csv",
)
# Classify with Spectral Angle Mapper, Random Forest, or a Neural Net
sam = scene.analysis.classify_scene(method="SAM",
library_means={k: v["mean"] for k, v in library_stats.items()},
save_geotiff="sam_classification.tif")
rf = scene.analysis.classify_scene(method="RF", df_training=df_training, rf_estimators=100)
nn = scene.analysis.classify_scene(method="NN", df_training=df_training,
nn_hidden_layer_sizes=(10, 10), nn_max_iter=1000)
πΊοΈ Export & interoperability¶
Take your cube anywhere. Export the main hyperspectral cube and its companion layers into standard remote-sensing formats β correctly georeferenced.
scene.convert_to.geotiff(output_path="scene.tif", include_extras=True) # multi-band GeoTIFF
scene.convert_to.envi_bil(output_path="scene.bil", include_extras=True) # ENVI .bil + .hdr
ds = scene.convert_to.xarray(include_secondary_cubes=False) # in-memory xarray.Dataset
ds.to_netcdf("scene.nc") # β NetCDF
For complete method signatures and parameter tables, see the API Reference.