Skip to content

distance_localization⚓︎

Distance-based localization implementation.

DistanceLocalization ⚓︎

Bases: LocalizationBase

Distance-based localization strategy for sparse mask projection.

Follows the same init/call pattern as AutoAdaptiveLocalization: - All configuration is parsed and stored at __init__ time. - __call__ assembles and returns the sparse localization operator.

Parameters:

Name Type Description Default
info dict or list

Localization configuration. Must contain:

  • field: [nz, nx, ny] grid dimensions.
  • actnum: path to .npz file with active-cell mask (optional).
  • taper_func: kernel type -- "gc", "fb", or "region" (default: "region").

Plus one of: - a .csv key or comma-separated inline rows specifying entries, or - a .pkl / .p key pointing to a pre-built entries dict.

required
data DataFrame

Observed data with time indices as rows and data types as columns.

None
parameters list of str

State parameter names used as defaults in __call__.

None
ensemble_size int

Ensemble size; used by the Furrer-Bengtsson kernel.

None
prior_info dict

Per-parameter prior information (nx, ny, nz). Used to build zero masks for unconfigured parameters.

None

__call__(curr_data=None, curr_time=None, curr_param=None) ⚓︎

Build the sparse localization operator for the current assimilation step.

Parameters:

Name Type Description Default
curr_data list of str

Data types to include. Defaults to self.data_types.

None
curr_time list

Time indices to include. Defaults to self.data_indices.

None
curr_param list of str

State parameters to update. Defaults to self.parameters.

None

Returns:

Type Description
scipy.sparse matrix, shape (n_active_cells, n_obs)

Sparse localization operator.

__init__(info, data=None, parameters=None, ensemble_size=None, prior_info=None) ⚓︎

Initialize the DistanceLocalization instance.

Spatial localization entries — one per (data_type, time, parameter) combination — are supplied either via an external CSV file or as comma-separated inline rows embedded in the info dict key. All info keys map directly to the [dataassim.localization] table in a TOML config file.

Parameters:

Name Type Description Default
info dict or list

Localization configuration. Recognised keys:

field : list of int, required Grid dimensions [nz, nx, ny]. Used to size the spatial kernel arrays and to lay out the flattened cell vectors.

actnum : str, optional Path to a .npz file whose first array is a boolean mask of active cells. When supplied, only active cells appear in the output localization operator. Default: None.

taper_func : {"gc", "fb", "region"}, optional Spatial kernel applied at each observation location:

- ``"gc"`` — **Gaspari-Cohn** fifth-order piecewise
  polynomial. Compact support extends to ``2 × radius``
  grid cells. Values lie in [0, 1] with a smooth,
  differentiable profile. The standard choice for
  distance-based localization in geoscience DA.
- ``"fb"`` — **Furrer-Bengtsson** ensemble-size-aware
  taper. Weights are scaled by ensemble size *Ne* so
  that larger ensembles produce sharper localization.
  Values lie in [0, Ne/(Ne+2)]. Pass ``ensemble_size``
  to control *Ne* (default 50).
- ``"region"`` — Binary point kernel: weight 1 at the
  single nearest cell, 0 everywhere else. Equivalent to
  assigning one observation to exactly one grid cell.

Default: ``"region"``.

entries : str, list, or dict, optional Localization entries configuration. Three formats are supported:

- **str**: Path to a CSV file containing one entry per line
  (see *CSV row format* in Notes).
- **list**: List of entry dicts or CSV row strings. Dicts must
  contain ``"taper"``, ``"x"``, ``"y"``, ``"radius"``,
  ``"data_type"``, ``"time"``, ``"param"`` (plus optional
  ``"z"``, ``"z_range"``, ``"aniso"``, ``"rotation"``).
  Wildcard ``"*"`` can be used to expand entries across all
  known values for that field.
- **dict**: Pre-built ``{(data_type, time, param): LocalizationEntry}``
  dict (rarely used; prefer the other formats).

unlocalized : list of str, optional State parameters that every datum updates with weight one, i.e. that are not localized -- typically scalars, which have no position. A parameter that is neither here nor in an entry gets weight zero: it is not updated. Default: [].

required
data DataFrame

Observed data whose index contains the assimilation time steps (must match the time field in each CSV row) and whose columns are the data-type names (e.g. "WOPR PRO1"). Required for __call__ to produce output.

None
parameters list of str

Ordered list of state parameter names (e.g. ["permx", "poro"]). Determines which parameters receive a localization mask and the stacking order in the output.

None
ensemble_size int

Ensemble size Ne. Only affects the Furrer-Bengtsson kernel (taper_func = "fb"). Default: None ("fb" falls back to Ne = 50).

None
prior_info dict

Per-parameter grid sizes. Required only when a parameter appears in parameters but has no localization entry in the CSV; such parameters receive an all-zero weight column whose length is taken from this dict::

{"poro": {"nx": 20, "ny": 20, "nz": 1}}
None
Notes

CSV row format

Each entry is a single space-separated line with 11 fields (or 12 if the data-type name contains a space)::

taper  x_pos  y_pos  z_pos  radius  z_range  aniso  rotation  data_type  time  param

For two-word data types (e.g. WOPR PRO1) use 12 fields::

taper  x_pos  y_pos  z_pos  radius  z_range  aniso  rotation  word1  word2  time  param

Field descriptions:

  • taper — kernel tag: gc, fb, or region.
  • x_pos — observation x-cell index on the grid (0-based), along the nx axis.
  • y_pos — observation y-cell index on the grid (0-based), along the ny axis.
  • z_pos — observation layer index on the grid (0-based).
  • radius — kernel half-radius in grid cells. For gc the full support spans 2 × radius cells from the center.
  • z_range — ":" to spread the kernel across all nz layers, or an integer to restrict it to that single layer.
  • aniso — anisotropy ratio (x-axis scaling factor). Use 1.0 for isotropic kernels; 2.0 compresses the kernel to half-width in the x-direction.
  • rotation — clockwise rotation of the kernel in degrees. Use 0.0 for axis-aligned kernels.
  • data_type — observation type name, case-insensitive. Must match a column in the data DataFrame.
  • time — assimilation time step; must match an index value of the data DataFrame.
  • param — state parameter name, case-insensitive. Must appear in the parameters list.

Examples:

TOML config using an external CSV file (recommended for many observation types or time steps):

[dataassim.localization]
name       = "distance_loc"
field      = [1, 20, 20]    # [nz, nx, ny]
taper_func = "gc"
"loc_entries.csv" = true    # key = filename; value is ignored

Example loc_entries.csv (Gaspari-Cohn, isotropic, all layers):

gc 10 10 0  6 : 1.0  0.0  pressure    400.0 permx
gc 10 10 0  6 : 1.0  0.0  pressure    800.0 permx
gc  5 15 0  4 : 1.0  0.0  wopr pro1   400.0 permx
gc  5 15 0  4 : 2.0 30.0  wopr pro1   800.0 permx

TOML config using the Furrer-Bengtsson kernel with active-cell mask and anisotropic entries in the CSV:

[dataassim.localization]
name       = "distance_loc"
field      = [2, 30, 40]    # two-layer, 30×40 lateral grid
taper_func = "fb"
actnum     = "active.npz"
"loc_entries.csv" = true

loc_entries.csv restricting each observation to layer 0 only (z_range = 0) with anisotropic, rotated kernel:

fb  8 12 0 6 0 2.0 45.0 wopr pro1 400.0 permx
fb 15  5 0 8 0 1.0  0.0 wwct pro2 400.0 permx

Python config using the entries key with a list of dicts (modern preferred approach):

info = {
    "field": [1, 20, 20],
    "taper_func": "gc",
    "entries": [
        {
            "taper": "gc",
            "x": 10, "y": 10, "z": 0,
            "radius": 6,
            "z_range": ":",
            "aniso": 1.0, "rotation": 0.0,
            "data_type": "pressure",
            "time": 400.0,
            "param": "permx",
        },
        {
            "taper": "gc",
            "x": 5, "y": 15, "z": 0,
            "radius": 4,
            "z_range": ":",
            "aniso": 1.0, "rotation": 0.0,
            "data_type": "wopr pro1",
            "time": 400.0,
            "param": "permx",
        },
    ]
}

Wildcard expansion in entries (apply one config to all data types):

info = {
    "field": [1, 20, 20],
    "taper_func": "gc",
    "entries": [
        {
            "taper": "gc",
            "x": 10, "y": 10, "z": 0,
            "radius": 6,
            "z_range": ":",
            "aniso": 1.0, "rotation": 0.0,
            "data_type": "*",      # expands to all data types
            "time": "*",           # expands to all times
            "param": "permx",
        },
    ]
}

FurrerBengtssonKernel ⚓︎

Furrer-Bengtsson ensemble-size-aware taper kernel.

build(radius, anisotropy_ratio, rotation_deg, field_shape, ensemble_size=None) ⚓︎

Taper weights around a datum: Furrer-Bengtsson decay over radius cells, adjusted for the ensemble size.

GaspariCohnKernel ⚓︎

Gaspari-Cohn compactly supported smooth taper kernel.

build(radius, anisotropy_ratio, rotation_deg, field_shape, ensemble_size=None) ⚓︎

Taper weights around a datum: smooth Gaspari-Cohn decay over radius cells, stretched by anisotropy_ratio.

LocalizationEntry ⚓︎

Configuration for a single (data_type, time, parameter) localization entry.

RegionKernel ⚓︎

Binary region kernel - full weight (1) everywhere within range.

build(radius=None, anisotropy_ratio=1.0, rotation_deg=0.0, field_shape=None, ensemble_size=None) ⚓︎

Weight 1 everywhere within radius (stretched by anisotropy_ratio), 0 outside.