src.eval.raster.raster_grid_core

author:

Alberto M. Esmoris Pena

The raster_grid_core module hosts RasterGridCore, the Python helper that owns the multi-step orchestration behind RasterGridEvaluatorPP: spatial-frame construction (via GeoTiffIO.generate_raster()), per-tile dispatch to one of the four typed C++ entry points exposed by pyvl3dpp (evaluate_raster_grid_dd / _df / _fd / _ff()), application of the chained per-grid post-processors in the fixed legacy-compatible order (dem -> interpolator -> hillshading -> hillshade -> lrm -> resampling_filter -> vat -> msrm), and the final per-grid concatenation + (unconditional) row reversal.

Keeping the orchestration here keeps the Evaluator entry point RasterGridEvaluatorPP compact and aligns with the legacy RasterGridEvaluator.digest_grids() / RasterGridEvaluator.digest_grid() decomposition.

Classes

RasterGridCore(evaluator)

class src.eval.raster.raster_grid_core.RasterGridCore(evaluator)
Author:

Alberto M. Esmoris Pena

Python orchestrator for the C++-accelerated raster-grid evaluator.

A RasterGridCore is paired one-to-one with the calling RasterGridEvaluatorPP; the Evaluator holds the user- supplied hyperparameters (grid specs, resolutions, neighborhood radius expression, threading, precision bits, …) and this class consumes them through a back-reference. The class delegates the heavy lifting to pyvl3dpp (per-tile reducer sweep) and to the Python wrappers in src.eval.raster.raster_postproc (per- grid post-processors).

The six raising reducers (binary_mask, binary_mask_nofeats, recount, recount_nofeats, relative_recount, relative_recount_nofeats) enforce the legacy target_relational-required contract with a PP-prefixed byte- identical message; the four non-using reducers (mean, median, min, max) accept a missing target_relational.

Variables:

evaluator (RasterGridEvaluatorPP) – The RasterGridEvaluatorPP instance that provides the hyperparameters consumed by this orchestrator.

RELATIONAL_REQUIRED_REDUCERS = frozenset({'binary_mask', 'binary_mask_nofeats', 'recount', 'recount_nofeats', 'relative_recount', 'relative_recount_nofeats'})
HALO_CAP_FRACTION = 0.25
__init__(evaluator)

Initialize/instantiate a RasterGridCore.

Parameters:

evaluator (RasterGridEvaluatorPP) – The owning RasterGridEvaluatorPP providing hyperparameters via attribute access.

run(X, F, fnames)

Run the full PP raster-grid pipeline for the configured grid specifications.

Builds the spatial frame, validates the relational contract on the six raising reducers, dispatches the per-tile reducer sweep to the typed C++ entry point, applies the chained per- grid post-processors in the fixed legacy-compatible order, concatenates per-tile output cubes along the column axis, and reverses the rows (legacy verbatim; see CONTRACT_iter1.md sec. 2).

Parameters:
  • X (np.ndarray) – The structure space matrix of point-wise coordinates.

  • F (np.ndarray) – The feature space matrix of point-wise features.

  • fnames (list of str) – The feature names indexing the columns of F.

Returns:

A tuple (Fgrids, onames) with one grid (np.ndarray of shape (width, height, n_features_k)) per requested grid spec, together with the output name of each grid.

Return type:

tuple of (list of np.ndarray, list of str)

prepare_spatial_frame(X)

Build the spatial frame (cell centers, width, height, evaluated radius) mirroring legacy lines 228-238.

Xgrid is the per-cell coordinate cube with shape (width, height, 2) produced from a meshgrid of the xmin..xmax / ymin..ymax ranges. The radius is evaluated from RasterGridEvaluatorPP.radius_expr with l = max(xres, yres) exposed as a local variable.

Parameters:

X (np.ndarray) – The structure space matrix of point-wise coordinates.

Returns:

A tuple (Xgrid, width, height, radius).

Return type:

tuple of (np.ndarray, int, int, float)

validate_grid_spec(grid_spec)

Validate the relational contract for a single grid spec.

Raises an EvaluatorException with a PP-prefixed byte-identical legacy message when one of the six relational- using reducers is supplied without target_relational. The four non-using reducers (mean, median, min, max) accept a missing value.

Parameters:

grid_spec (dict) – The per-grid specification dict.

Returns:

Nothing.

dispatch_cpp(X, F, fnames, Xgrid_3d, radius, width, height)

Dispatch the per-tile reducer sweep to the typed C++ entry point selected from (structure_space_bits, feature_space_bits).

The four typed C++ entry points exposed by pyvl3dpp are evaluate_raster_grid_dd (64/64), evaluate_raster_grid_df (64/32), evaluate_raster_grid_fd (32/64), and evaluate_raster_grid_ff (32/32). Both bits default to 32 per RasterGridEvaluatorPP.

Three contract-pinned behaviors are honored here:

  1. The per-tile Xgrid slice is flattened from (chunk_width, height, 2) to (chunk_width * height, 2) before crossing the pybind boundary (CONTRACT_iter1.md sec. 6, mirrors legacy np.vstack).

  2. Per-grid conditions are evaluated in Python BEFORE the C++ call: grids sharing the same conditions dict are grouped into a single C++ call to amortize the KDTree build (CONTRACT_iter1.md sec. 4).

  3. DEM-only grids (those with a non-empty dem key) skip the C++ reducer sweep entirely and emit a zero-shape placeholder that apply_postprocessors() will replace with the DEM cube produced by DEMGenerator (CONTRACT_iter1.md sec. 5).

Parameters:
  • X (np.ndarray) – The structure space matrix of point-wise coordinates.

  • F (np.ndarray) – The feature space matrix of point-wise features.

  • fnames (list of str) – The feature names indexing the columns of F.

  • Xgrid_3d (np.ndarray) – The cell-center coordinate cube for the tile of shape (chunk_width, height, 2).

  • radius (float) – The neighborhood radius.

  • width (int) – Number of rows in the tile (chunk_width).

  • height (int) – Number of columns in the tile.

Returns:

One per-grid numpy array per grid spec, each shaped (width, height, n_features_k).

Return type:

list of np.ndarray

apply_postprocessors(grid, grid_spec, chunk_width, height, X, chunk_xgrid_3d)

Apply the chained per-grid post-processors in the fixed legacy-compatible order: dem -> interpolator -> hillshading -> hillshade -> lrm -> resampling_filter -> vat -> msrm.

Step dem materializes the DEM cube via DEMGenerator for grids that bypass the C++ reducer sweep (CONTRACT_iter1.md sec. 5). Steps hillshading and hillshade dispatch to the same C++ Horn kernel with different default parameter packs; steps lrm, resampling_filter, vat, msrm are new C++ post-processors. Each step is a no-op when the corresponding key is absent from the grid spec.

Parameters:
  • grid (np.ndarray) – The per-tile grid emitted by the C++ reducer sweep (or a placeholder for DEM-only grids), shaped (chunk_width, height, n_features_k).

  • grid_spec (dict) – The per-grid specification dict.

  • chunk_width (int) – Number of rows in the tile.

  • height (int) – Number of columns in the tile.

  • X (np.ndarray) – The (globally filtered) structure space, needed by DEMGenerator to materialize the DEM cube.

  • chunk_xgrid_3d (np.ndarray) – The per-tile cell-center cube (chunk_width, height, 2) produced by the spatial-frame slice. Needed by DEMGenerator to identify the tile’s footprint.

Returns:

The post-processed per-tile grid (same shape).

Return type:

np.ndarray

concatenate_and_reverse(grids_per_tile, reverse_rows)

Concatenate per-tile grid cubes and reverse the rows unconditionally, mirroring legacy RasterGridEvaluator.digest_grids() lines 261-266.

The C++ side returns per-tile grids in (chunk_width, height, n_features_k) orientation; this method transposes each tile to (n_features_k, height, chunk_width) (the legacy Fgrid.T contract), concatenates the tiles of each grid spec along the row axis (legacy axis=2), and ALWAYS reverses the height axis (legacy unconditional grid[:, ::-1, :], see CONTRACT_iter1.md sec. 2). The reverse_rows argument is accepted for legacy JSON compatibility but is a no-op.

Parameters:
  • grids_per_tile (list of list of np.ndarray) – Outer list indexed by tile, inner list indexed by grid spec.

  • reverse_rows (bool) – Kept for legacy-JSON compatibility (see CONTRACT sec. 2); the reversal is ALWAYS applied.

Returns:

One per-spec grid array, after transpose, concatenation, and unconditional row reversal.

Return type:

list of np.ndarray

apply_2d_postproc(grid, spec, fn, bits, chunk_width, height)

Apply a single 2D post-processor to the FIRST channel of a per-tile grid cube, returning the cube with the post- processed result placed back into a single-channel slot.

The input to the post-processor is grid[:, :, 0] (the first channel of the multi-channel reducer output); the output is a single-channel (chunk_width, height, 1) cube. This matches the legacy hillshading reshape contract and is shared by every 2D post-processor (LRM, resampling, VAT, MSRM).

Parameters:
  • grid (np.ndarray) – The per-tile grid cube.

  • spec (dict or None) – The post-processor spec dict, or None to return the input unchanged.

  • fn (callable) – The callable forwarded to with (z2d, spec, bits). xres/yres are baked in by the caller through a closure when needed (hillshade / VAT / MSRM); kernels that DO NOT take xres/yres (LRM / resampling) bind fn directly to the wrapper.

  • bits (int) – The feature-space bits selector (32 or 64).

  • chunk_width (int) – Number of rows in the tile.

  • height (int) – Number of columns in the tile.

Returns:

The (possibly post-processed) tile cube, with a single channel along the last axis.

Return type:

np.ndarray

apply_dem_postproc(grid, dem_spec, chunk_width, height, X, chunk_xgrid_3d)

Materialize the DEM cube for a grid that bypassed the C++ reducer sweep (CONTRACT_iter1.md sec. 5). Mirrors the legacy RasterGridEvaluator.digest_grid() DEM branch (lines 297-305).

Parameters:
  • grid (np.ndarray) – The per-tile placeholder grid cube (zeros).

  • dem_spec (dict) – The DEM spec dict carrying interpolation.

  • chunk_width (int) – Number of rows in the tile.

  • height (int) – Number of columns in the tile.

  • X (np.ndarray) – The (globally filtered) structure space.

  • chunk_xgrid_3d (np.ndarray) – The per-tile cell-center cube (chunk_width, height, 2) for the current chunk.

Returns:

The materialized per-tile DEM cube of shape (chunk_width, height, 1).

Return type:

np.ndarray

static select_cpp_entry_point(structure_bits, feature_bits)

Select the pyvl3dpp C++ entry-point name for the (structure_space_bits, feature_space_bits) pair.

Parameters:
  • structure_bits (int) – The structure-space bits (32 or 64).

  • feature_bits (int) – The feature-space bits (32 or 64).

Returns:

The name of the matching C++ entry point on pyvl3dpp.

Return type:

str

build_cpp_grid_specs(fnames)

Marshal the user-supplied per-grid specifications into a list of dictionaries digestible by the C++ side.

Per CONTRACT_iter1.md sec. 3, the emitted dicts have EXACTLY these keys: reduce_kind (int enum), relational_kind (int enum), feature_idxs (list of int), target_double_val (float), target_int_val (int), use_double_target (bool), target_in_vals (list of float), threshold (int), empty_val_is_nan (bool), and empty_val_double (float). The conditions and dem keys are NOT included: conditions are pre-filtered in Python by dispatch_cpp() and DEM grids skip the C++ sweep entirely.

Parameters:

fnames (list of str) – The feature names indexing the columns of the feature space matrix.

Returns:

A list of per-grid dictionaries with the keys consumed by the C++ side.

Return type:

list of dict

static resolve_feature_indices(grid_spec, fnames)

Resolve the column indices in F for the features listed under grid_spec['fnames'] (mirrors legacy lines 374-388).

Parameters:
  • grid_spec (dict) – The per-grid specification dict.

  • fnames (list of str) – The feature names indexing the columns of the feature space matrix.

Returns:

The resolved per-feature column indices.

Return type:

list of int