Skip to content

Find and open

find_products

find_products(paths: Union[str, Path, Iterable[Union[str, Path]]], *, frame_id: Optional[int] = None, min_version: Optional[str] = None, allow_unsupported: bool = False) -> pd.DataFrame

Return one row per DISP granule, deduplicated and sorted by date.

When the same frame and date pair appears more than once, the highest product version is kept, then the latest production time. The dropped rows are in df.attrs["dropped"]. Versions are checked against the product spec after this deduplication.

Parameters:

Name Type Description Default
paths str, Path or iterable of them

A directory or remote prefix (s3://, https://, any fsspec URL; searched recursively for *.nc), one file, or a list of files. Remote access needs the aws extra and credentials (see :mod:disp_xr._remote).

required
frame_id int

Keep only this frame. Required when the granules span several frames.

None
min_version str

Keep only granules with at least this product version.

None
allow_unsupported bool

Keep granules whose version the product spec does not support, instead of raising.

False

Returns:

Type Description
DataFrame

Columns product, frame_id, reference_time, secondary_time, version, production_time, polarization, mode, path.

Raises:

Type Description
ValueError

If no granule is found, or the granules span several frames and frame_id is not given.

UnsupportedProductVersionError

If a granule's version is outside its product's supported versions.

Examples:

>>> find_products([])
Traceback (most recent call last):
...
ValueError: No DISP granules found

open_disp

open_disp(paths: PathsLike, *, layers: Optional[Sequence[str]] = None, corrections: bool = False, chunks: ChunkSpec = 'native', frame_id: Optional[int] = None, min_version: Optional[str] = None, check: bool = True) -> xr.Dataset

Open DISP granules of one frame as a lazy dataset.

Displacement is returned as stored: relative to each granule's reference date (reference_time). Chaining across ministacks is a separate step.

Parameters:

Name Type Description Default
paths str, Path, iterable of paths, or DataFrame

A directory, files, or the output of :func:disp_xr.product.find_products.

required
layers sequence of str

Layers to keep. Defaults to all displacement and quality layers.

None
corrections bool

Also open the /corrections group layers.

False
chunks ('native', 'timeseries', 'maps')

Dask chunks. "native" (default) keeps the file layout, one epoch and one read block per chunk, so any selection reads only what it needs; functions that work along time rechunk for themselves. "timeseries" and "maps" are sized from config["chunks.target_mb"]; a dict gives {"time", "y", "x"} sizes (-1 means the whole axis). See :func:disp_xr.rechunk.

"native"
frame_id int

Frame to keep when paths holds several.

None
min_version str

Lowest product version to keep.

None
check bool

Refuse granules of mixed productions (see :func:disp_xr.product.check_granules). Productions that differ only in the precision of a float layer (DISP-S1 displacement is float32 before November 2025 and float64 after) are read together with a :class:~disp_xr.product.MixedPrecisionWarning; those layers are cast to float32 and listed in attrs["mixed_precision"].

True

Returns:

Type Description
Dataset

Dims (time, y, x); coordinates time, reference_time, x, y and spatial_ref (times to the second, as in granule names); one variable per layer, each with grid_mapping. No pixel is read until computed. Layers keep their stored dtype: float layers use NaN for no data, integer layers (masks, labels, counts) keep the product's nodata value, given in their _FillValue attribute.

Raises:

Type Description
ValueError

If a requested layer does not exist in the product.

Examples:

>>> ds = dxr.open_disp("F11116/")
>>> ds = dxr.open_disp(
...     "F11116/", layers=["displacement", "temporal_coherence"]
... )
>>> ds = dxr.open_disp(list(search_table["filename"]))

open_disp_tree

open_disp_tree(paths: PathsLike, *, layers: Optional[Sequence[str]] = None, chunks: ChunkSpec = 'native', frame_id: Optional[int] = None, min_version: Optional[str] = None, check: bool = True) -> xr.DataTree

Open a frame as a DataTree that mirrors the granule groups.

Nodes: the root holds the displacement and quality layers (as :func:open_disp), /corrections the correction layers, and /identification and /metadata hold the first granule's scalar values as attributes (xarray cannot decode their byte strings). Values that change per granule, such as the dates, are in the time and reference_time coordinates.

Parameters:

Name Type Description Default
paths PathsLike

As for :func:open_disp.

required
layers PathsLike

As for :func:open_disp.

required
chunks PathsLike

As for :func:open_disp.

required
frame_id PathsLike

As for :func:open_disp.

required
min_version PathsLike

As for :func:open_disp.

required
check PathsLike

As for :func:open_disp.

required

Returns:

Type Description
DataTree

Examples:

>>> tree = dxr.open_disp_tree("F11116/")
>>> tree["corrections"].ds

open_static

open_static(like: Dataset, *, static_dir: Optional[Union[str, Path]] = None, files: Optional[Mapping[str, Union[str, Path]]] = None, download: bool = True) -> xr.Dataset

Open the static layers of a DISP frame on the grid of like.

Parameters:

Name Type Description Default
like Dataset

A DISP dataset (from :func:disp_xr.open_disp), possibly subset; its frame_id attribute picks the static granule and its grid is the output grid.

required
static_dir str or Path

Where DISP-S1-STATIC files are, or are downloaded to.

None
files mapping

Explicit {"line_of_sight_enu" | "dem" | "layover_shadow_mask": path}.

None
download bool

Download missing files (aws extra, Earthdata credentials).

True

Returns:

Type Description
Dataset

Lazy (y, x) layers: los_east, los_north, los_up, incidence_angle, azimuth_angle (degrees), dem and layover_shadow_mask. LOS points from the ground to the satellite.

Raises:

Type Description
FileNotFoundError

If no static file is found or downloadable for the frame.

Examples:

>>> static = dxr.open_static(ds)
>>> static.incidence_angle.plot.imshow()
>>> static = dxr.open_static(
...     ds, files={"line_of_sight_enu": "los_enu.tif"}
... )

open_zarr

open_zarr(store: Union[str, Path, Any], *, chunks: Any = 'shards', group: Optional[str] = None, storage_options: Optional[Mapping[str, Any]] = None, mask_and_scale: bool = False, **kwargs: Any) -> xr.Dataset

Open a Zarr store lazily, one dask chunk per shard.

:func:xarray.open_zarr makes one dask chunk per stored chunk, which for a :func:to_zarr store is the 64 x 64 read chunk inside each shard: a full DISP-S1 frame then opens as about 16,000 chunks per variable and every graph built on it carries them (issue #93: 147,000 tasks for an OLS fit of five epochs, 217 with one chunk per shard). One chunk per shard is also the unit :func:to_zarr and region jobs write.

Parameters:

Name Type Description Default
store str, Path or zarr store

Local path, URL (with storage_options) or any zarr Store.

required
chunks "shards" or any :func:`xarray.open_zarr` value

"shards" (default): each variable chunked by its shard, or by its stored chunk when it is not sharded. Anything else is passed on.

'shards'
group str

Group of the store to open instead of the root.

None
storage_options mapping

fsspec options for a URL store.

None
mask_and_scale bool

Decode fill values to NaN. Off by default, so integer layers keep their dtype, as :func:disp_xr.open_disp does.

False
**kwargs Any

Passed to :func:xarray.open_zarr.

{}

Examples:

>>> cube = dxr.open_zarr("F11116.zarr")
>>> velocity = dxr.fit_velocity(cube, "midas")

dxr.search_granules is :func:disp_xr.search.search at the top level (it needs the aws extra, so it is imported on first use):

search

search(frame_id: int | None = None, product_version: str | None = '1.0', start_datetime: datetime | None = None, end_datetime: datetime | None = None, url_type: UrlType = UrlType.HTTPS, use_uat: bool = False, short_name: str = DISP_S1_SHORT_NAME, session: Session | None = None) -> pd.DataFrame

Query the CMR for granules matching the given frame ID and product version.

Parameters:

Name Type Description Default
frame_id int

The frame ID to search for

None
product_version str

The product version to search for

'1.0'
start_datetime datetime

The start of the temporal range in UTC.

None
end_datetime datetime

The end of the temporal range in UTC.

None
url_type UrlType

The protocol to use for downloading, either "s3" or "https".

HTTPS
use_uat bool

Whether to use the UAT environment instead of main Earthdata endpoint.

False
short_name str

CMR collection short name. Defaults to DISP-S1.

DISP_S1_SHORT_NAME
session Session

HTTP session to use; a new one is created when omitted.

None

Returns:

Type Description
DataFrame

One row per granule found, filtered to the requested time range.

Examples:

>>> table = search(frame_id=11116)
>>> table = search(frame_id=11116, url_type="s3")