Skip to content

rslearn.dataset.window

window

rslearn windows.

WindowLayerData

Layer data for retrieved layers specifying relevant items in the data source.

This stores the outputs from dataset prepare for a given layer.

Source code in rslearn/dataset/window.py
class WindowLayerData:
    """Layer data for retrieved layers specifying relevant items in the data source.

    This stores the outputs from dataset prepare for a given layer.
    """

    def __init__(
        self,
        layer_name: str,
        serialized_item_groups: list[list[Any]],
        group_time_ranges: list[tuple[datetime, datetime] | None] | None = None,
        materialized: bool = False,
    ) -> None:
        """Initialize a new WindowLayerData.

        Args:
            layer_name: the layer name
            serialized_item_groups: the groups of items, where each item is serialized
                so it is JSON-encodable.
            group_time_ranges: optional request time range for each item group. When
                set, it must have one entry per item group.
            materialized: whether the items have been materialized
        """
        self.layer_name = layer_name
        self.serialized_item_groups = serialized_item_groups
        if group_time_ranges is not None and len(group_time_ranges) != len(
            serialized_item_groups
        ):
            raise ValueError(
                "group_time_ranges length must match serialized_item_groups length"
            )
        self.group_time_ranges = group_time_ranges
        self.materialized = materialized

    def serialize(self) -> dict:
        """Serialize a WindowLayerData is a JSON-encodable dict.

        Returns:
            the JSON-encodable dict
        """
        return {
            "layer_name": self.layer_name,
            "serialized_item_groups": self.serialized_item_groups,
            "group_time_ranges": (
                [
                    [time_range[0].isoformat(), time_range[1].isoformat()]
                    if time_range is not None
                    else None
                    for time_range in self.group_time_ranges
                ]
                if self.group_time_ranges is not None
                else None
            ),
            "materialized": self.materialized,
        }

    @staticmethod
    def deserialize(d: dict) -> "WindowLayerData":
        """Deserialize a WindowLayerData.

        Args:
            d: a JSON dict

        Returns:
            the WindowLayerData
        """
        group_time_ranges_data = d.get("group_time_ranges")
        group_time_ranges = None
        if group_time_ranges_data is not None:
            group_time_ranges = [
                (
                    datetime.fromisoformat(time_range[0]),
                    datetime.fromisoformat(time_range[1]),
                )
                if time_range is not None
                else None
                for time_range in group_time_ranges_data
            ]
        return WindowLayerData(
            layer_name=d["layer_name"],
            serialized_item_groups=d["serialized_item_groups"],
            group_time_ranges=group_time_ranges,
            materialized=d["materialized"],
        )

serialize

serialize() -> dict

Serialize a WindowLayerData is a JSON-encodable dict.

Returns:

Type Description
dict

the JSON-encodable dict

Source code in rslearn/dataset/window.py
def serialize(self) -> dict:
    """Serialize a WindowLayerData is a JSON-encodable dict.

    Returns:
        the JSON-encodable dict
    """
    return {
        "layer_name": self.layer_name,
        "serialized_item_groups": self.serialized_item_groups,
        "group_time_ranges": (
            [
                [time_range[0].isoformat(), time_range[1].isoformat()]
                if time_range is not None
                else None
                for time_range in self.group_time_ranges
            ]
            if self.group_time_ranges is not None
            else None
        ),
        "materialized": self.materialized,
    }

deserialize staticmethod

deserialize(d: dict) -> WindowLayerData

Deserialize a WindowLayerData.

Parameters:

Name Type Description Default
d dict

a JSON dict

required

Returns:

Type Description
WindowLayerData

the WindowLayerData

Source code in rslearn/dataset/window.py
@staticmethod
def deserialize(d: dict) -> "WindowLayerData":
    """Deserialize a WindowLayerData.

    Args:
        d: a JSON dict

    Returns:
        the WindowLayerData
    """
    group_time_ranges_data = d.get("group_time_ranges")
    group_time_ranges = None
    if group_time_ranges_data is not None:
        group_time_ranges = [
            (
                datetime.fromisoformat(time_range[0]),
                datetime.fromisoformat(time_range[1]),
            )
            if time_range is not None
            else None
            for time_range in group_time_ranges_data
        ]
    return WindowLayerData(
        layer_name=d["layer_name"],
        serialized_item_groups=d["serialized_item_groups"],
        group_time_ranges=group_time_ranges,
        materialized=d["materialized"],
    )

Window

A spatiotemporal window in an rslearn dataset.

Source code in rslearn/dataset/window.py
class Window:
    """A spatiotemporal window in an rslearn dataset."""

    def __init__(
        self,
        storage: WindowStorage,
        group: str,
        name: str,
        projection: Projection,
        bounds: tuple[int, int, int, int],
        time_range: tuple[datetime, datetime] | None,
        options: dict[str, Any] = {},
        data_factory: WindowDataStorageFactory | None = None,
    ) -> None:
        """Creates a new Window instance.

        A window stores metadata about one spatiotemporal window in a dataset, that is
        stored in metadata.json.

        Args:
            storage: the metadata storage for the underlying rslearn dataset.
            group: the group the window belongs to
            name: the unique name for this window
            projection: the projection of the window
            bounds: the bounds of the window in pixel coordinates
            time_range: optional time range of the window
            options: additional options. This is typically used to store metadata on
                the window. Train, val, and test splits can filter for key-value pairs
                (called "tags" in DataInput) in this options dictionary.
            data_factory: optional factory to bind a WindowDataStorage to this window.
        """
        self.storage = storage
        self.group = group
        self.name = name
        self.projection = projection
        self.bounds = bounds
        self.time_range = time_range
        self.options = options
        self._data: WindowDataStorage | None = (
            data_factory.create(self) if data_factory else None
        )

    @property
    def data(self) -> WindowDataStorage:
        """The bound WindowDataStorage for materialized raster/vector data.

        Raises:
            RuntimeError: if no WindowDataStorage has been bound to this window.
        """
        if self._data is None:
            raise RuntimeError(
                "WindowDataStorage not bound to this window. "
                "Use a WindowDataStorageFactory to bind data storage, "
                "or set window._data directly."
            )
        return self._data

    def get_geometry(self) -> STGeometry:
        """Computes the STGeometry corresponding to this window."""
        return STGeometry(
            projection=self.projection,
            shp=shapely.geometry.box(*self.bounds),
            time_range=self.time_range,
        )

    @property
    def window_root(self) -> UPath:
        """The root directory of this window in its WindowStorage."""
        return self.storage.get_window_root(self.group, self.name)

    def load_layer_datas(self) -> dict[str, WindowLayerData]:
        """Load layer datas describing items in retrieved layers from items.json."""
        return self.storage.get_layer_datas(self.group, self.name)

    def save_layer_datas(self, layer_datas: dict[str, WindowLayerData]) -> None:
        """Save layer datas to items.json."""
        self.storage.save_layer_datas(self.group, self.name, layer_datas)

    def list_completed_layers(self) -> list[tuple[str, int]]:
        """List the completed (materialized) item groups for this window.

        Returns:
            a list of (layer_name, group_idx) tuples identifying completed item groups.
        """
        return self.storage.list_completed_layers(self.group, self.name)

    def get_layer_dir(self, layer_name: str, group_idx: int = 0) -> UPath:
        """Get the directory containing materialized data for the specified item group.

        .. deprecated::
            This returns the per-item-group layout used by
            :class:`rslearn.dataset.window_storage.PerItemGroupStorage`. It is
            not valid for other ``WindowDataStorage`` implementations. Read
            and write materialized data through ``WindowDataStorage`` instead.

        Args:
            layer_name: the layer name.
            group_idx: the item group index within the layer (default 0).

        Returns:
            the path where data for this item group is or should be materialized.
        """
        warnings.warn(
            "Window.get_layer_dir is deprecated; access materialized data via "
            "window.data (WindowDataStorage).",
            DeprecationWarning,
            stacklevel=2,
        )
        return per_item_group_layer_dir(self.window_root, layer_name, group_idx)

    def is_layer_completed(self, layer_name: str, group_idx: int = 0) -> bool:
        """Check whether the specified item group is completed (materialized).

        Args:
            layer_name: the layer name.
            group_idx: the item group index within the layer (default 0).

        Returns:
            whether the item group is completed.
        """
        return self.storage.is_layer_completed(
            self.group, self.name, layer_name, group_idx
        )

    def mark_layer_completed(self, layer_name: str, group_idx: int = 0) -> None:
        """Mark the specified item group completed.

        This must be done after the contents of the item group have been written. If a
        layer has multiple item groups, the caller should wait until the contents of all
        groups have been written before marking them completed; this is because, when
        materializing a window, we skip materialization if the first item group
        (group_idx=0) is marked completed.

        Args:
            layer_name: the layer name.
            group_idx: the item group index within the layer (default 0).
        """
        self.storage.mark_layer_completed(self.group, self.name, layer_name, group_idx)

    def get_raster_dir(
        self, layer_name: str, bands: list[str], group_idx: int = 0
    ) -> UPath:
        """Get the directory where the raster is materialized for a specific item group.

        .. deprecated::
            This returns the per-item-group layout used by
            :class:`rslearn.dataset.window_storage.PerItemGroupStorage`. It is
            not valid for other ``WindowDataStorage`` implementations. Read
            and write raster data through ``WindowDataStorage`` instead.

        Args:
            layer_name: the layer name.
            bands: the bands in the raster. It should match a band set defined for this
                layer.
            group_idx: the item group index within the layer (default 0).

        Returns:
            the directory containing the raster for this item group.
        """
        warnings.warn(
            "Window.get_raster_dir is deprecated; access raster data via "
            "window.data (WindowDataStorage).",
            DeprecationWarning,
            stacklevel=2,
        )
        return per_item_group_raster_dir(
            self.window_root,
            layer_name,
            bands,
            group_idx,
        )

    def get_metadata(self) -> dict[str, Any]:
        """Returns the window metadata dictionary."""
        return {
            "group": self.group,
            "name": self.name,
            "projection": self.projection.serialize(),
            "bounds": self.bounds,
            "time_range": (
                [self.time_range[0].isoformat(), self.time_range[1].isoformat()]
                if self.time_range
                else None
            ),
            "options": self.options,
        }

    def save(self) -> None:
        """Save the window metadata to its root directory."""
        self.storage.create_or_update_window(self)

    @staticmethod
    def from_metadata(
        storage: WindowStorage,
        metadata: dict[str, Any],
    ) -> "Window":
        """Create a Window from the WindowStorage and the window's metadata dictionary.

        Args:
            storage: the WindowStorage for the underlying dataset.
            metadata: the window metadata.

        Returns:
            the Window
        """
        bounds = (
            metadata["bounds"][0],
            metadata["bounds"][1],
            metadata["bounds"][2],
            metadata["bounds"][3],
        )

        return Window(
            storage=storage,
            group=metadata["group"],
            name=metadata["name"],
            projection=Projection.deserialize(metadata["projection"]),
            bounds=bounds,
            time_range=(
                (
                    datetime.fromisoformat(metadata["time_range"][0]),
                    datetime.fromisoformat(metadata["time_range"][1]),
                )
                if metadata["time_range"]
                else None
            ),
            options=metadata["options"],
        )

    @staticmethod
    def get_window_root(ds_path: UPath, group: str, name: str) -> UPath:
        """Gets the root directory of a window.

        Args:
            ds_path: the dataset root directory
            group: the group of the window
            name: the name of the window
        Returns:
            the path for the window
        """
        return ds_path / "windows" / group / name

data property

The bound WindowDataStorage for materialized raster/vector data.

Raises:

Type Description
RuntimeError

if no WindowDataStorage has been bound to this window.

window_root property

window_root: UPath

The root directory of this window in its WindowStorage.

get_geometry

get_geometry() -> STGeometry

Computes the STGeometry corresponding to this window.

Source code in rslearn/dataset/window.py
def get_geometry(self) -> STGeometry:
    """Computes the STGeometry corresponding to this window."""
    return STGeometry(
        projection=self.projection,
        shp=shapely.geometry.box(*self.bounds),
        time_range=self.time_range,
    )

load_layer_datas

load_layer_datas() -> dict[str, WindowLayerData]

Load layer datas describing items in retrieved layers from items.json.

Source code in rslearn/dataset/window.py
def load_layer_datas(self) -> dict[str, WindowLayerData]:
    """Load layer datas describing items in retrieved layers from items.json."""
    return self.storage.get_layer_datas(self.group, self.name)

save_layer_datas

save_layer_datas(layer_datas: dict[str, WindowLayerData]) -> None

Save layer datas to items.json.

Source code in rslearn/dataset/window.py
def save_layer_datas(self, layer_datas: dict[str, WindowLayerData]) -> None:
    """Save layer datas to items.json."""
    self.storage.save_layer_datas(self.group, self.name, layer_datas)

list_completed_layers

list_completed_layers() -> list[tuple[str, int]]

List the completed (materialized) item groups for this window.

Returns:

Type Description
list[tuple[str, int]]

a list of (layer_name, group_idx) tuples identifying completed item groups.

Source code in rslearn/dataset/window.py
def list_completed_layers(self) -> list[tuple[str, int]]:
    """List the completed (materialized) item groups for this window.

    Returns:
        a list of (layer_name, group_idx) tuples identifying completed item groups.
    """
    return self.storage.list_completed_layers(self.group, self.name)

get_layer_dir

get_layer_dir(layer_name: str, group_idx: int = 0) -> UPath

Get the directory containing materialized data for the specified item group.

.. deprecated:: This returns the per-item-group layout used by :class:rslearn.dataset.window_storage.PerItemGroupStorage. It is not valid for other WindowDataStorage implementations. Read and write materialized data through WindowDataStorage instead.

Parameters:

Name Type Description Default
layer_name str

the layer name.

required
group_idx int

the item group index within the layer (default 0).

0

Returns:

Type Description
UPath

the path where data for this item group is or should be materialized.

Source code in rslearn/dataset/window.py
def get_layer_dir(self, layer_name: str, group_idx: int = 0) -> UPath:
    """Get the directory containing materialized data for the specified item group.

    .. deprecated::
        This returns the per-item-group layout used by
        :class:`rslearn.dataset.window_storage.PerItemGroupStorage`. It is
        not valid for other ``WindowDataStorage`` implementations. Read
        and write materialized data through ``WindowDataStorage`` instead.

    Args:
        layer_name: the layer name.
        group_idx: the item group index within the layer (default 0).

    Returns:
        the path where data for this item group is or should be materialized.
    """
    warnings.warn(
        "Window.get_layer_dir is deprecated; access materialized data via "
        "window.data (WindowDataStorage).",
        DeprecationWarning,
        stacklevel=2,
    )
    return per_item_group_layer_dir(self.window_root, layer_name, group_idx)

is_layer_completed

is_layer_completed(layer_name: str, group_idx: int = 0) -> bool

Check whether the specified item group is completed (materialized).

Parameters:

Name Type Description Default
layer_name str

the layer name.

required
group_idx int

the item group index within the layer (default 0).

0

Returns:

Type Description
bool

whether the item group is completed.

Source code in rslearn/dataset/window.py
def is_layer_completed(self, layer_name: str, group_idx: int = 0) -> bool:
    """Check whether the specified item group is completed (materialized).

    Args:
        layer_name: the layer name.
        group_idx: the item group index within the layer (default 0).

    Returns:
        whether the item group is completed.
    """
    return self.storage.is_layer_completed(
        self.group, self.name, layer_name, group_idx
    )

mark_layer_completed

mark_layer_completed(layer_name: str, group_idx: int = 0) -> None

Mark the specified item group completed.

This must be done after the contents of the item group have been written. If a layer has multiple item groups, the caller should wait until the contents of all groups have been written before marking them completed; this is because, when materializing a window, we skip materialization if the first item group (group_idx=0) is marked completed.

Parameters:

Name Type Description Default
layer_name str

the layer name.

required
group_idx int

the item group index within the layer (default 0).

0
Source code in rslearn/dataset/window.py
def mark_layer_completed(self, layer_name: str, group_idx: int = 0) -> None:
    """Mark the specified item group completed.

    This must be done after the contents of the item group have been written. If a
    layer has multiple item groups, the caller should wait until the contents of all
    groups have been written before marking them completed; this is because, when
    materializing a window, we skip materialization if the first item group
    (group_idx=0) is marked completed.

    Args:
        layer_name: the layer name.
        group_idx: the item group index within the layer (default 0).
    """
    self.storage.mark_layer_completed(self.group, self.name, layer_name, group_idx)

get_raster_dir

get_raster_dir(layer_name: str, bands: list[str], group_idx: int = 0) -> UPath

Get the directory where the raster is materialized for a specific item group.

.. deprecated:: This returns the per-item-group layout used by :class:rslearn.dataset.window_storage.PerItemGroupStorage. It is not valid for other WindowDataStorage implementations. Read and write raster data through WindowDataStorage instead.

Parameters:

Name Type Description Default
layer_name str

the layer name.

required
bands list[str]

the bands in the raster. It should match a band set defined for this layer.

required
group_idx int

the item group index within the layer (default 0).

0

Returns:

Type Description
UPath

the directory containing the raster for this item group.

Source code in rslearn/dataset/window.py
def get_raster_dir(
    self, layer_name: str, bands: list[str], group_idx: int = 0
) -> UPath:
    """Get the directory where the raster is materialized for a specific item group.

    .. deprecated::
        This returns the per-item-group layout used by
        :class:`rslearn.dataset.window_storage.PerItemGroupStorage`. It is
        not valid for other ``WindowDataStorage`` implementations. Read
        and write raster data through ``WindowDataStorage`` instead.

    Args:
        layer_name: the layer name.
        bands: the bands in the raster. It should match a band set defined for this
            layer.
        group_idx: the item group index within the layer (default 0).

    Returns:
        the directory containing the raster for this item group.
    """
    warnings.warn(
        "Window.get_raster_dir is deprecated; access raster data via "
        "window.data (WindowDataStorage).",
        DeprecationWarning,
        stacklevel=2,
    )
    return per_item_group_raster_dir(
        self.window_root,
        layer_name,
        bands,
        group_idx,
    )

get_metadata

get_metadata() -> dict[str, Any]

Returns the window metadata dictionary.

Source code in rslearn/dataset/window.py
def get_metadata(self) -> dict[str, Any]:
    """Returns the window metadata dictionary."""
    return {
        "group": self.group,
        "name": self.name,
        "projection": self.projection.serialize(),
        "bounds": self.bounds,
        "time_range": (
            [self.time_range[0].isoformat(), self.time_range[1].isoformat()]
            if self.time_range
            else None
        ),
        "options": self.options,
    }

save

save() -> None

Save the window metadata to its root directory.

Source code in rslearn/dataset/window.py
def save(self) -> None:
    """Save the window metadata to its root directory."""
    self.storage.create_or_update_window(self)

from_metadata staticmethod

from_metadata(storage: WindowStorage, metadata: dict[str, Any]) -> Window

Create a Window from the WindowStorage and the window's metadata dictionary.

Parameters:

Name Type Description Default
storage WindowStorage

the WindowStorage for the underlying dataset.

required
metadata dict[str, Any]

the window metadata.

required

Returns:

Type Description
Window

the Window

Source code in rslearn/dataset/window.py
@staticmethod
def from_metadata(
    storage: WindowStorage,
    metadata: dict[str, Any],
) -> "Window":
    """Create a Window from the WindowStorage and the window's metadata dictionary.

    Args:
        storage: the WindowStorage for the underlying dataset.
        metadata: the window metadata.

    Returns:
        the Window
    """
    bounds = (
        metadata["bounds"][0],
        metadata["bounds"][1],
        metadata["bounds"][2],
        metadata["bounds"][3],
    )

    return Window(
        storage=storage,
        group=metadata["group"],
        name=metadata["name"],
        projection=Projection.deserialize(metadata["projection"]),
        bounds=bounds,
        time_range=(
            (
                datetime.fromisoformat(metadata["time_range"][0]),
                datetime.fromisoformat(metadata["time_range"][1]),
            )
            if metadata["time_range"]
            else None
        ),
        options=metadata["options"],
    )

get_window_root staticmethod

get_window_root(ds_path: UPath, group: str, name: str) -> UPath

Gets the root directory of a window.

Parameters:

Name Type Description Default
ds_path UPath

the dataset root directory

required
group str

the group of the window

required
name str

the name of the window

required

Returns: the path for the window

Source code in rslearn/dataset/window.py
@staticmethod
def get_window_root(ds_path: UPath, group: str, name: str) -> UPath:
    """Gets the root directory of a window.

    Args:
        ds_path: the dataset root directory
        group: the group of the window
        name: the name of the window
    Returns:
        the path for the window
    """
    return ds_path / "windows" / group / name

get_layer_and_group_from_dir_name

get_layer_and_group_from_dir_name(layer_dir_name: str) -> tuple[str, int]

Parse a layer directory name (item group specifier) into layer name and group index.

Parameters:

Name Type Description Default
layer_dir_name str

the item group specifier to parse.

required

Returns:

Type Description
tuple[str, int]

a tuple (layer_name, group_idx).

Source code in rslearn/dataset/window.py
def get_layer_and_group_from_dir_name(layer_dir_name: str) -> tuple[str, int]:
    """Parse a layer directory name (item group specifier) into layer name and group index.

    Args:
        layer_dir_name: the item group specifier to parse.

    Returns:
        a tuple (layer_name, group_idx).
    """
    if "." in layer_dir_name:
        parts = layer_dir_name.split(".")
        if len(parts) != 2:
            raise ValueError(
                f"expected layer directory name {layer_dir_name} to only contain one '.'"
            )
        return (parts[0], int(parts[1]))
    else:
        return (layer_dir_name, 0)