Analysis#

Computes a complete physical description for every detected cell: geometry, radar statistics, motion vectors, and projected future positions.

Extract statistical properties from labeled convective cells.

This module computes per-cell statistics (area, intensity, motion, projection) from segmented radar data. Output is a Pandas DataFrame with one row per cell, containing geometric centroids, reflectivity/velocity statistics, and cell motion information.

The analyzer handles: - Multiple centroid types: geometric (center-of-mass), mass-weighted, max reflectivity, projected - Multi-variable statistics: reflectivity, velocity, differential phase, spectrum width, etc. - Geographic coordinate conversion: pixel (x,y) to latitude/longitude - Cell motion: heading vectors and projection centroid evolution - Database-ready output: DataFrame suitable for SQL insertion

All centroids are stored in both pixel coordinates (x, y) and geographic coordinates (latitude, longitude) for flexibility in downstream analysis.

Author: Bhupendra Raut

class adapt.modules.analysis.module.RadarCellAnalyzer(config)#

Bases: object

Extract geometric and statistical properties from segmented radar cells.

This class computes per-cell statistics from segmented radar data to create a DataFrame suitable for machine learning, statistical analysis, or database storage. Input is a 2D xarray.Dataset with cell labels and radar fields; output is a Pandas DataFrame with one row per cell.

Features computed per cell:

  1. Geometric Centroids (in both pixel and geographic coordinates): - Geometric: center-of-mass of binary cell mask - Mass-weighted: reflectivity-weighted centroid - Max reflectivity: location of highest reflectivity - Projection: forward-projected motion centroids (0-5 steps)

  2. Area and Size: - Cell area in km2 (computed from grid spacing) - Grid point count

  3. Radar Statistics (per variable): - Mean, std, min, max, median - 25th/75th percentiles - Variables: reflectivity, velocity, spectrum width, differential phase, etc.

  4. Cell Motion: - Heading vectors (from projector) within cell region - Heading direction and speed statistics

  5. Metadata: - Scan time, z-level (altitude) - Dataset attributes preservation

Configuration#

Config dict structure:

  • globaldict, optional
    • tracking_fieldstr

      Canonical field the pipeline detects/tracks on (default: “reflectivity”)

  • radar_variableslist, optional

    Whitelist of variables to analyze (default: common radar fields). Only variables in this list AND present in dataset are included.

  • exclude_fieldslist, optional

    Variables to skip (metadata, projection, etc.). Takes precedence over whitelist.

  • projectordict, optional
    • max_projection_stepsint, default 5

      Number of forward projections to extract

Notes

  • Not thread-safe; create separate instances for concurrent processing

  • Requires pre-segmented input (cell_labels variable must exist)

  • Processing time: 100-500 ms per frame (depends on cell count)

  • Centroid naming is systematic: cell_centroid_<type>_{x,y,lat,lon}

  • Returns empty DataFrame if no cells found (all labels = 0)

  • All centroid coordinates are preserved in both coordinate systems

Examples

>>> config = {"radar_variables": ["reflectivity", "velocity"]}
>>> analyzer = RadarCellAnalyzer(config)
>>> df = analyzer.extract(ds_segmented)
>>> print(df.columns)  # centroid locations, area, reflectivity stats, etc.
>>> print(len(df))  # number of cells in this frame
extract(ds, z_level=None)#

Extract geometric and statistical properties from all labeled cells.

Computes per-cell statistics including centroids (geometric, mass-weighted, max reflectivity, projected), area, and multi-variable radar statistics. Output is a Pandas DataFrame suitable for machine learning, statistical analysis, or database insertion (one row = one cell).

Parameters:
  • ds (Dataset) – 2D segmented xarray.Dataset with: - Dimensions: (y, x) - Data variables: cell_labels, reflectivity, velocity (optional), etc. - Coordinates: x, y (pixel coordinates) - Optional coordinates: lat, lon (geographic) - Attributes: z_level_m (altitude), time, radar metadata

  • z_level (int | None) – Unused; kept for API compatibility with older versions.

Returns:

One row per cell (cells with label > 0). Columns include:

  • Cell Identity: - cell_label : int, unique cell ID

  • Geometric Centroids (all in both pixel and geographic coords): - cell_centroid_geom_{x,y,lat,lon} : Geometric centroid - cell_centroid_mass_{x,y,lat,lon} : Reflectivity-weighted - cell_centroid_maxdbz_{x,y,lat,lon} : Max reflectivity location - cell_centroid_projection_0_{x,y,lat,lon} to _4_… : Projections

  • Size: - cell_area_sqkm : Cell area in square kilometers - cell_area_npixels : Number of grid points

  • Radar Statistics (per variable: reflectivity, velocity, etc.): - radar_<variable>_mean, _std, _min, _max, _median : Aggregate stats - radar_<variable>_p25, _p75 : Percentiles

  • Motion (if heading vectors present): - cell_heading_<stat> : Direction/speed statistics

  • Metadata: - time : Timestamp of radar scan - z_level_m : Altitude of this slice

Return type:

DataFrame

Raises:

ValueError – If cell_labels variable is not present in dataset.

Notes

  • Processing time: 100-500 ms per frame (depends on cell count)

  • Returns empty DataFrame if no cells found (all labels = 0)

  • Only variables in radar_variables config AND present in dataset are analyzed (whitelist approach)

  • All centroid coordinates are in both pixel (x, y) and geographic (latitude, longitude) systems for flexibility

  • Suitable for direct insertion into SQL database via to_sql()

Examples

>>> analyzer = RadarCellAnalyzer(config)
>>> df = analyzer.extract(ds_segmented)
>>> print(f"Found {len(df)} cells")
>>> print(df[['cell_label', 'cell_area_sqkm', 'radar_reflectivity_mean']])
>>> df.to_sql('cells', conn, if_exists='append')  # Database storage
extract_adjacency(ds)#

Extract direct same-scan cell adjacency pairs from the label grid.

Adjacency definition: two positive labels are adjacent if they touch along a shared boundary with at least N touching boundary pixel-edges, where N is config-driven (analyzer.adjacency_min_touching_boundary_pixels).

Return type:

DataFrame

Parameters:

ds (Dataset)

static get_lat_lon(ix, iy, lat_grid, lon_grid)#

Extract lat–lon coordinates using integer pixel indices.

Parameters:
  • ix (int) – Integer x (column) index

  • iy (int) – Integer y (row) index

  • lat_grid (np.ndarray) – 2D latitude array [y, x]

  • lon_grid (np.ndarray) – 2D longitude array [y, x]

Returns:

(lat, lon) as floats, or (np.nan, np.nan) if out of bounds or invalid

Return type:

tuple