# Getting started with the GridR resampling chain This tutorial introduces `basic_grid_resampling_chain`, the file-oriented wrapper around `array_grid_resampling`. The core function works on in-memory NumPy arrays; the chain layer manages all I/O against rasterio datasets and processes the output in memory-efficient strips and tiles. This first notebook shows the minimal call: open a source raster, open a grid file, open a destination file, and let the chain do the rest. **What you'll learn** - How to prepare on-disk inputs for the chain (raster + grid) - How to open input/output rasterio datasets in a `with` block - How to call `basic_grid_resampling_chain` with minimal arguments - How `grid_resolution` controls the output size ## Setting things up The chain reads from rasterio `DatasetReader` and writes to `DatasetWriter` objects opened by the caller. Before calling it we need: 1. A **source raster** on disk -- here, the mandrill image. 2. A **grid file** on disk -- a two-band GeoTIFF where band 1 holds row coordinates and band 2 holds column coordinates. Both files are created above by the tutorial setup cell using the `write_array` and `create_grid` helpers from `chain_notebook_utils`. The grid is an affine-parameterised regular grid of shape `(50, 40)` mapped onto the source raster's coordinate frame. The figure below overlays its nodes on the source image. ![grid_on_image.png](grid_resampling_chain_001_getting_started_files/grid_on_image.png) ## First call: identity resolution At `grid_resolution=(1, 1)` the output has exactly as many pixels as there are grid nodes (`50 × 40`). The output dataset must be opened with matching dimensions. ```python output_shape_1_1 = grid_row_f64.shape raster_out_open_args_1_1 = { "driver": "GTiff", "dtype": np.float64, "height": output_shape_1_1[0], "width": output_shape_1_1[1], "count": 1, } with rasterio.open(GRID_IN_F64, "r") as grid_in_ds, \ rasterio.open(RASTER_IN, "r") as array_src_ds, \ rasterio.open(output_raster_path, "w", **raster_out_open_args_1_1) as array_out_ds: basic_grid_resampling_chain( grid_ds = grid_in_ds, grid_row_coords_band = 1, grid_col_coords_band = 2, grid_resolution = (1, 1), array_src_ds = array_src_ds, array_src_bands = 1, array_out_ds = array_out_ds, interp = "cubic", nodata_out = 0, ) ``` ![resampling_1_1.png](grid_resampling_chain_001_getting_started_files/resampling_1_1.png) The output is small because the grid subsamples the source raster heavily (each node is several source pixels apart). Out-of-domain nodes are filled with `nodata_out`. ## Zooming with `grid_resolution` `grid_resolution` inserts additional output samples between adjacent grid nodes by bilinear interpolation of the node coordinates. Setting it to `(8, 8)` multiplies the output dimensions by 8 in each direction. The output shape must be sized accordingly using `grid_full_resolution_shape`. ```python from gridr.core.grid.grid_commons import grid_full_resolution_shape grid_resolution = (8, 8) output_shape = grid_full_resolution_shape( shape=grid_row_f64.shape, resolution=grid_resolution, ) raster_out_open_args = { "driver": "GTiff", "dtype": np.float64, "height": output_shape[0], "width": output_shape[1], "count": 1, } print(f"output shape: {output_shape}") ``` output shape: (393, 313) ```python with rasterio.open(GRID_IN_F64, "r") as grid_in_ds, \ rasterio.open(RASTER_IN, "r") as array_src_ds, \ rasterio.open(output_raster_path, "w", **raster_out_open_args) as array_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, ) ``` ![resampling_8_8.png](grid_resampling_chain_001_getting_started_files/resampling_8_8.png) The next notebooks build on this minimal call by adding masks, geometry constraints, coordinate shifts and I/O controls one at a time.