Optical#
easysnowdata.optical#
Optical (passive, visible through SWIR and thermal) imagery.
The name pairs with easysnowdata.sar (active microwave) and covers
every sensor in the theme, including thermal-only and hyperspectral products
that are not multispectral (plan §3.1). Band math, masks and composites live
in easysnowdata.processing.optical; the loaders here only add product
knowledge: collection ids, band aliases, nodata, scaling and citations.
easysnowdata.optical.hls#
Harmonized Landsat Sentinel-2 (HLS) v2.0.
Sources (companion file §B.3):
lpcloud-cmr-stac(default)NASA’s CMR-STAC
LPCLOUDcatalog:HLSL30_2.0(Landsat 8/9) andHLSS30_2.0(Sentinel-2), the archive of record, same-day with the LP DAAC. The search is open; the COG reads are behind Earthdata Login, so they go through theearthdataprovider’s GDAL environment (netrc plus a cookie jar, or a bearer token), which Dask workers inherit.planetary-computerhls2-l30/hls2-s30: a credential-free mirror, ids verified live on 2026-09-16 (the plan could not check them during the PC outage).
Scene metadata comes from STAC properties, not from the per-granule XML the
old HLS class fetched one request at a time:
import easysnowdata as esd
items = esd.optical.hls.search(aoi, "2023-08", cloud_cover=40)
hls = esd.optical.hls.load(aoi, "2023-08", mask="fmask-default")
load returns one Dataset with both products stacked on time and a
product coordinate (L30/S30) saying where each scene came from.
easysnowdata.optical.planetscope#
PlanetScope (and SkySat) imagery from Planet Labs.
Planet is the first key-gated commercial source in the package (plan §12 Q17, companion §B.11). Two routes, and the difference is quota:
orders-api(default)Search with the Data API, then order the scenes with the
cliptool so Planet delivers COGs cut to the AOI, optionallyharmonize``d to Sentinel-2. An order is charged for the clipped area only. Because an order spends quota it is never implicit: :func:`load` refuses to place one unless ``order=True, andorder()is the explicit entry point.data-apiActivate and read a whole scene’s asset directly. This is the quick-look route for a single scene; activation charges the full scene area, and the AOI is only applied after the bytes have been streamed.
import easysnowdata as esd
scenes = esd.optical.planetscope.search(aoi, "2023-07-01/2023-07-02")
order = esd.optical.planetscope.order(aoi, items=scenes.head(1)) # spends quota
ps = esd.optical.planetscope.load(aoi, order=order)
udm2 = esd.processing.decode_udm2(ps["udm2"]) # snow band
Planet imagery is not redistributable, so nothing in this repository contains a real scene: the tests run on synthetic deliveries and scrubbed Data API responses.
Search the Planet Data API and return the scenes as a |
|
Order scenes clipped to aoi and (by default) wait for and download them. |
|
Load PlanetScope imagery as an |
|
Open delivered Planet COGs (a directory, file list, or order result). |
easysnowdata.optical.sentinel2#
Sentinel-2 Level-2A surface reflectance.
Sources (companion file §B.2):
planetary-computer(default)sentinel-2-l2aon Microsoft Planetary Computer: credential-free (hrefs are signed for you), one catalog for Sentinel-1, Sentinel-2, the DEM and WorldCover. Its items historically carry noraster:bands, so the band aliases and dtypes come from astac_cfgfallback and the post-2022-01-25 baseline offset is undone by the date rule.earth-searchElement 84’s
sentinel-2-l2a,sentinel-2-c1-l2aandsentinel-2-pre-c1-l2aon AWS: unsigned S3, assets already named by common band name, and items that carryraster:bandswithscaleandoffset— so the baseline offset is applied from metadata rather than from a date.
import easysnowdata as esd
items = esd.optical.sentinel2.search(aoi, "2024-05", cloud_cover=30)
s2 = esd.optical.sentinel2.load(aoi, "2024-05", mask="scl-default")
ndsi = esd.processing.ndsi(s2)
load returns reflectance (scaled, harmonized to the pre-2022 baseline)
with dims time, y, x in the AOI’s UTM zone.