Skip to content

MDPDatastore.boundary_mask marks the entire domain as boundary when n_boundary_points=0 #727

Description

@AshNicolus

Description

MDPDatastore.boundary_mask (neural_lam/datastore/mdp.py) builds the interior region with:

ds_unstacked["boundary_mask"] = da_domain_allzero.isel(
    x=slice(self._n_boundary_points, -self._n_boundary_points),
    y=slice(self._n_boundary_points, -self._n_boundary_points),
)

For any n_boundary_points >= 1 this correctly selects the interior. But n_boundary_points=0 produces slice(0, -0), which in Python is slice(0, 0) - an empty selection, not "the whole array". The empty interior gets reindexed to the full domain as all-NaN when assigned back, and the subsequent .fillna(1) then marks every grid point as boundary instead of none.

Concretely: MDPDatastore(config_path=..., n_boundary_points=0).boundary_mask.sum() returns the full grid size (every point marked boundary) instead of 0. Verified against the danra example dataset (7680/7680 grid points incorrectly marked boundary).

This is silent - no error or warning - and would make ForecasterModule's interior mask empty, effectively zeroing out the loss over the whole domain for any config that sets n_boundary_points=0.

Note: this is unrelated to the global-domain boundary_mask semantics discussed in #445/#650 (whether a domain with no boundary concept should return None). This is purely a slice-arithmetic edge case in the existing LAM code path for an explicit n_boundary_points=0.

Fix

Guard the zero case, e.g. slice(n, -n) if n > 0 else slice(None).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions