Grid mask
A grid mask flags individual grid nodes as invalid before resampling. Nodes marked invalid produce output samples set to nodata_out, and their validity is propagated to the output mask.
What you’ll learn
How to build and save a grid mask raster
How to pass it through
grid_mask_in_ds,grid_mask_in_unmasked_valueandgrid_mask_in_bandHow GridR supports alternative dtypes and validity conventions (
uint8vsint8, valid value other than1)
Setting things up
We reuse the source raster and grid file from the previous notebook. The grid mask itself is created below if not already present on disk.
uint8 grid mask (valid = 1, invalid = 0)
We build the mask in memory, marking as invalid any grid node whose source-frame coordinates fall inside a rectangular ROI, then write it to disk.
grid_mask_in_valid_value, grid_mask_in_invalid_value = 1, 0
roi = np.array(((10, 40), (5, 100)))
grid_mask = np.full(grid_row_f64.shape, grid_mask_in_valid_value, dtype=np.uint8)
grid_mask[
np.logical_and(
np.logical_and(grid_row_f64 >= roi[0][0], grid_row_f64 <= roi[0][1]),
np.logical_and(grid_col_f64 >= roi[1][0], grid_col_f64 <= roi[1][1]),
)
] = grid_mask_in_invalid_value
write_array(grid_mask, dtype=np.uint8, fileout=grid_mask_in_path)
The figure below shows the grid nodes coloured by mask status:
red = invalid (inside the ROI),
orange = out of the source raster domain (also treated as invalid during resampling),
blue = valid.

The mask is fed to the chain through three arguments:
grid_mask_in_ds– opened mask dataset,grid_mask_in_unmasked_value– the value that means valid,grid_mask_in_band– band index to read.
with rasterio.open(GRID_IN_F64, "r") as grid_in_ds, \
rasterio.open(RASTER_IN, "r") as array_src_ds, \
rasterio.open(grid_mask_in_path, "r") as grid_mask_in_ds, \
rasterio.open(output_raster_path, "w", **raster_out_open_args) as array_out_ds, \
rasterio.open(output_mask_path, "w", **mask_out_open_args) as mask_out_ds:
basic_grid_resampling_chain(
grid_ds = grid_in_ds,
grid_row_coords_band = 1,
grid_col_coords_band = 2,
grid_resolution = grid_resolution,
array_src_ds = array_src_ds,
array_src_bands = 1,
array_out_ds = array_out_ds,
interp = "cubic",
nodata_out = 400, # distinct value to make invalid areas visible
mask_out_ds = mask_out_ds,
grid_mask_in_ds = grid_mask_in_ds,
grid_mask_in_unmasked_value = grid_mask_in_valid_value,
grid_mask_in_band = 1,
)

Alternative convention: int8 (valid = 0, invalid = −10)
The chain supports any 8-bit integer dtype (uint8 or int8) and any valid value. Only grid_mask_in_unmasked_value needs to match the chosen convention.
grid_mask_in_valid_value_i8, grid_mask_in_invalid_value_i8 = 0, -10
grid_mask_i8 = np.full(grid_row_f64.shape, grid_mask_in_valid_value_i8, dtype=np.int8)
grid_mask_i8[
np.logical_and(
np.logical_and(grid_row_f64 >= roi[0][0], grid_row_f64 <= roi[0][1]),
np.logical_and(grid_col_f64 >= roi[1][0], grid_col_f64 <= roi[1][1]),
)
] = grid_mask_in_invalid_value_i8
write_array(grid_mask_i8, dtype=np.int8, fileout=grid_mask_in_path_i8)
with rasterio.open(GRID_IN_F64, "r") as grid_in_ds, \
rasterio.open(RASTER_IN, "r") as array_src_ds, \
rasterio.open(grid_mask_in_path_i8, "r") as grid_mask_in_ds, \
rasterio.open(output_raster_path, "w", **raster_out_open_args) as array_out_ds, \
rasterio.open(output_mask_path, "w", **mask_out_open_args) as mask_out_ds:
basic_grid_resampling_chain(
grid_ds = grid_in_ds,
grid_row_coords_band = 1,
grid_col_coords_band = 2,
grid_resolution = grid_resolution,
array_src_ds = array_src_ds,
array_src_bands = 1,
array_out_ds = array_out_ds,
interp = "cubic",
nodata_out = 0,
mask_out_ds = mask_out_ds,
grid_mask_in_ds = grid_mask_in_ds,
grid_mask_in_unmasked_value = grid_mask_in_valid_value_i8,
grid_mask_in_band = 1,
)
