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_value and grid_mask_in_band

  • How GridR supports alternative dtypes and validity conventions (uint8 vs int8, valid value other than 1)

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.

grid_mask_input.png

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,
    )

grid_mask_output.png

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,
    )

grid_mask_out_int8.png