I/O¶
Readers for the three inputs DEBRA needs: calibrated L1b imagery, MERRA-2 skin
temperature, and the surface emissivity climatology. None of this is on the
import shachen path — each function needs the satellite or data extra.
Satellite imagery¶
Satellite L1b -> calibrated BT/reflectance fields on the 2-km IR grid.
satpy does the radiance -> BT / reflectance calibration and the native down-sampling of the VIS/NIR bands onto the coarsest (2 km) grid, so ABI netCDF and Himawari AHI HSD share one code path.
- shachen.io.satellite.load_scene(files: Iterable[str | Path], reader: str = 'abi_l1b', roles: Iterable[Band] | None = None, bbox: tuple[float, float, float, float] | None = None) Dataset[source]¶
Load L1b files and return a Dataset on the sensor’s 2-km fixed grid.
Variables are named by DEBRA role:
bt_tir_104etc. for emissive bands (K),refl_vis_064etc. for reflective bands (%). The pyresample AreaDefinition is attached asds.attrs["area"]and the scan start time asds.attrs["start_time"].rolesrestricts loading to a subset of DEBRA bands (e.g.shachen.composite.COMPOSITE_BANDSfor TIR-only composite days, whose directories hold only those bands’ files);Noneloads all seven.bbox=(lon_min, lat_min, lon_max, lat_max)in degrees crops the scene (satpyScene.crop(ll_bbox=...)) after the native resample, so every variable andattrs["area"]describe the cropped grid — This trims AHI full disks (5500 x 5500 at 2 km) to the domain of interest.Nonekeeps the full scene.
MERRA-2 reanalysis¶
MERRA-2 hourly surface skin temperature (TS from M2T1NXSLV).
Downloads via earthaccess using the Earthdata login in ~/.netrc. The
full tavg1_2d_slv_Nx day file is large, so it is stripped after download to a
small TS-only netCDF cache, which the pipeline regrids onto the satellite grid.
- shachen.io.merra.SURFACE_MET_SLV_VARS = ('T2M', 'QV2M', 'PS', 'U10M', 'V10M')¶
Single-level variables the dust-PM10 matchup keeps from M2T1NXSLV.
- shachen.io.merra.FLX_SHORT_NAME = 'M2T1NXFLX'¶
Boundary-layer height comes from the surface-flux collection.
- shachen.io.merra.fetch_skin_temperature(day: date, out_dir: Path) Path[source]¶
Download MERRA-2 TS for
day; return path to a TS-only netCDF.
- shachen.io.merra.fetch_surface_meteorology(day: date, out_dir: Path) Path[source]¶
Download the dust-PM10 met covariates for
day; return a cache path.The cache
merra2_met_<%Y%m%d>.ncmergesSURFACE_MET_SLV_VARSfrom M2T1NXSLV withSURFACE_MET_FLX_VARS(PBLH) from M2T1NXFLX, both hourly on the native 0.5 x 0.625 degree grid.
Surface emissivity¶
IR surface emissivity climatology, interpolated to sensor band centers.
The paper uses the monthly UW Baseline Fit (UWBF, CIMSS) 0.05-degree climatology, which needs a separate CIMSS registration. The default here is its successor, CAMEL (CAM5K30EM on NASA LP DAAC), reachable with the same Earthdata credentials as MERRA-2. A downloaded UWBF file works too: both formats carry an emissivity cube on labelled hinge-point wavelengths, and interpolation is linear in wavelength, as the paper implies.
- shachen.io.emissivity.EMISSIVE_BANDS = (Band.SWIR_39, Band.WV_62, Band.TIR_86, Band.TIR_104, Band.TIR_123)¶
DEBRA only needs emissivity for the emissive bands used by the background.
- shachen.io.emissivity.fetch_emissivity(month: date, out_dir: Path, fallback_years: int = 8) Path[source]¶
Download the CAMEL monthly emissivity file covering
month.CAM5K30EM V003 stops at 2023-12, so a scene after that has no emissivity file of its own. Rather than fail, fall back to the same calendar month of the most recent year that does have one, up to
fallback_yearsback, and warn which file was used.The substitution is smaller than it looks. What the paper actually uses is the UWBF monthly climatology, which carries no year at all: land emissivity in the thermal window is set by land cover and its seasonal cycle, and April over the Gobi looks much the same from one year to the next. Reading April 2023 for an April 2025 scene is the same kind of approximation the paper makes on purpose – what would not be acceptable is reading a different month, which is why the search only ever walks back in whole years.
- shachen.io.emissivity.load_band_emissivity(path: Path, bands: tuple[Band, ...] = (Band.SWIR_39, Band.WV_62, Band.TIR_86, Band.TIR_104, Band.TIR_123)) Dataset[source]¶
Load hinge-point emissivity and interpolate to DEBRA band centers.
Returns a Dataset with one
emis_<band>variable per requested band on the climatology’s native lat/lon grid, values masked where the file has no retrieval (ocean/fill).