Spectral Diagnostics API

The spectral diagnostics subsystem provides tools for computing wavenumber spectra, spectral ratios, and multi-panel summaries.

Modules

Spectral Diagnostics Core Engine

This module implements the core spectral diagnostics used by both ufsda-spectra-ana-inc (CTRL vs EXP increment comparison) and ufsda-spectra-bkg-inc (background vs increment comparison).

The SpectraCore class provides:

  • FV3 cubed-sphere tile loading

  • Grid loading and corner → center conversion

  • Cubed-sphere → global lat/lon regridding

  • 1D isotropic spectra

  • Vertical variance profiles

  • 2D spectral ratios

This module contains no plotting and no CLI logic — it is a pure computational engine used by the two driver scripts.

class ufs_da_diagnostics.spectra.spectra_core.SpectraCore(varname='T_inc', grid_prefix='./C96_grid.tile', suffix='.nc')[source]

Bases: object

Core FV3-JEDI spectral diagnostics engine.

This class provides the computational backend for spectral analysis workflows, including:

  • Loading FV3 cubed-sphere tiles

  • Loading FV3 grid geometry and converting corner → center points

  • Regridding cubed-sphere tiles to a global lat/lon mesh

  • Computing isotropic 1D wavenumber spectra

  • Computing vertical variance profiles

  • Computing 2D spectral ratios (EXP / CTRL)

Parameters

varnamestr, optional

Name of the variable to extract from FV3 increment files. Default is "T_inc".

grid_prefixstr, optional

Prefix for FV3 grid files, e.g. "./C96_grid.tile".

suffixstr, optional

File suffix for both grid and data files (default ".nc").

Notes

This class does not perform any plotting. Plotting is handled by the driver modules:

  • spectra_analysis_tiles.py (ANA–INC)

  • spectra_analysis_bkg_inc.py (BKG–INC)

build_global(prefix, level)[source]

Regrid all six FV3 tiles to a global lat/lon mesh for one level.

Parameters

prefixstr

Tile file prefix, e.g. "/path/to/atminc.tile".

levelint

Vertical level index.

Returns

Lonnumpy.ndarray

2D longitude meshgrid (regular lat/lon grid).

Latnumpy.ndarray

2D latitude meshgrid.

field_interpnumpy.ndarray

2D field interpolated onto the global mesh.

Notes

  • Tile fields are flattened and concatenated.

  • scipy.interpolate.griddata performs nearest-neighbor interpolation onto a regular 1°×1° grid.

build_global_all_levels(prefix, nlevels)[source]

Regrid all vertical levels for a given experiment.

Parameters

prefixstr

Tile file prefix.

nlevelsint

Number of vertical levels.

Returns

Lonnumpy.ndarray

2D longitude meshgrid.

Latnumpy.ndarray

2D latitude meshgrid.

fieldsnumpy.ndarray

3D array of shape (nlevels, ny, nx) containing all levels.

isotropic_spectrum(field)[source]

Compute the 1D isotropic wavenumber spectrum of a 2D field.

Parameters

fieldnumpy.ndarray

2D field on a regular lat/lon grid.

Returns

numpy.ndarray

1D isotropic spectrum E(k).

Notes

  • Uses 2D FFT with fftshift.

  • Computes radial bins in wavenumber space.

  • Returns energy density averaged over annuli.

load_fields(ctrl_prefix, exp_prefix, nlevels=127)[source]

Load CTRL and EXP fields for all vertical levels and compute spectra.

Parameters

ctrl_prefixstr

File prefix for CTRL increment tiles.

exp_prefixstr

File prefix for EXP increment tiles.

nlevelsint, optional

Number of vertical levels to load (default 127).

Returns

None

Results are stored as attributes: - CTRL_3D : 3D array of CTRL fields - EXP_3D : 3D array of EXP fields - spec_ctrl_all : spectra for all CTRL levels - spec_exp_all : spectra for all EXP levels - spec_ratio_all : EXP/CTRL spectral ratio - k : wavenumber array

load_grid(tile)[source]

Load FV3 grid geometry and compute cell-center coordinates.

Parameters

tileint

Tile number (1–6).

Returns

lon_cnumpy.ndarray

2D array of cell-center longitudes.

lat_cnumpy.ndarray

2D array of cell-center latitudes.

Notes

FV3 grid files store corner coordinates. This method converts them to cell centers using a 4-point average.

load_tile(prefix, tile, level)[source]

Load a single FV3 cubed-sphere tile for a given vertical level.

Parameters

prefixstr

File prefix for the tile, e.g. "/path/to/atminc.tile".

tileint

Tile number (1–6).

levelint

Vertical level index.

Returns

numpy.ndarray

2D array of the requested variable at the given level.

Notes

Assumes FV3-JEDI tile files follow the naming pattern:

<prefix><tile><suffix>
spectral_ratio_2d()[source]

Return the full 2D spectral ratio array (EXP / CTRL).

Returns

numpy.ndarray

2D array of shape (nlevels, nk) containing spectral ratios.

variance_profile()[source]

Compute vertical variance ratio (EXP / CTRL).

Returns

numpy.ndarray

1D array of variance ratios for each vertical level.

Notes

Variance is computed as the sum of the isotropic spectrum across all wavenumbers.

ANA–INC Spectral Diagnostics Driver

This script performs spectral diagnostics comparing analysis increments from two experiments (CTRL vs EXP). It is the backend for the CLI entry point:

ufsda-spectra-ana-inc –yaml spectra_ana_inc.yaml

The workflow:

  1. Read YAML configuration

  2. Load increment fields for CTRL and EXP

  3. Regrid cubed-sphere tiles → global lat/lon

  4. Compute isotropic spectra for selected variables and levels

  5. Generate comparison plots: - CTRL spectrum - EXP spectrum - CTRL vs EXP comparison - Spectral ratio (EXP / CTRL) - Optional NICAS length-scale overlay

This driver uses: - SpectraCore for computation - SpectraPlotter for visualization

ufs_da_diagnostics.spectra.spectra_analysis_tiles.main()[source]

Run ANA–INC spectral diagnostics from a YAML configuration file.

This function implements the full workflow for comparing analysis increments between two experiments (CTRL vs EXP). It is invoked by the CLI entry point ufsda-spectra-ana-inc.

YAML Configuration

Expected structure:

experiments:
  - name: ctrl
    prefix: "/path/to/ctrl/atminc.tile"
  - name: exp
    prefix: "/path/to/exp/atminc.tile"

grid:
  prefix: "/path/to/C96_grid.tile"

vars: [u_inc, v_inc, T_inc]
levels: [126, 75, 50]

output_dir: "./spectra_ana_inc"
nicas_length_scale: 120000  # optional

Parameters

None

Returns

None

All output is written to PNG files in the configured output directory.

Notes

  • This driver always loads 127 vertical levels internally, even if only a subset is plotted.

  • SpectraCore performs all computation; this script only orchestrates workflow and plotting.

  • The NICAS length scale (if provided) is passed through to the plotter for optional overlay.

BKG–INC Spectral Diagnostics Driver

This script performs spectral diagnostics comparing background fields against analysis increments for a single experiment. It is the backend for the CLI entry point:

ufsda-spectra-bkg-inc –yaml spectra_bkg_inc.yaml

The workflow:

  1. Read YAML configuration

  2. Load background fields from a single ATM file (all 6 tiles)

  3. Load increment fields using SpectraCore (tile → global lat/lon)

  4. Compute isotropic spectra for selected variables and levels

  5. Generate comparison plots: - Background spectrum - Increment spectrum - Overlay plot (BKG + INC) - Annotated percentage contribution of increments

This driver uses: - SpectraCore for increment processing - Local helper functions for background loading and plotting

ufs_da_diagnostics.spectra.spectra_analysis_bkg_inc.load_bkg_field_global(atm_file, varname, level)[source]

Load a background field from a single ATM file and regrid to lat/lon.

Parameters

atm_filestr

Path to the ATM background file containing all 6 tiles.

varnamestr

Variable name inside the ATM file (e.g., "T" or "u").

levelint

Vertical level index.

Returns

numpy.ndarray

2D field interpolated onto a regular global lat/lon grid.

Notes

  • Background fields are stored as (tile, y, x).

  • All tiles are flattened and concatenated.

  • Regridding uses nearest-neighbor interpolation, matching SpectraCore.build_global.

ufs_da_diagnostics.spectra.spectra_analysis_bkg_inc.main()[source]

Run BKG–INC spectral diagnostics from a YAML configuration file.

This function implements the workflow for comparing background fields against analysis increments for a single experiment. It is invoked by the CLI entry point ufsda-spectra-bkg-inc.

YAML Configuration

Expected structure:

background:
  atm_file: "/path/to/atm_background.nc"

increments:
  prefix: "/path/to/atminc.tile"
  grid_prefix: "/path/to/C96_grid.tile"

mapping:
  - bkg: T
    inc: T_inc
    long_name: Temperature increment

spectra:
  levels: [126, 75]
  output_dir: "./spectra_bkg_inc"

Workflow

  1. Load background fields from a single ATM file

  2. Load increment fields using SpectraCore.build_global

  3. Compute isotropic spectra for both fields

  4. Compute increment percentage contribution

  5. Generate overlay plots

Returns

None

All output is written to PNG files in the configured output directory.

ufs_da_diagnostics.spectra.spectra_analysis_bkg_inc.plot_bkg_overlay(k, Ek_bkg, Ek_inc, long_name, level, outname, pct_text)[source]

Plot background and increment spectra with annotation.

Parameters

knumpy.ndarray

Wavenumber array.

Ek_bkgnumpy.ndarray

Background isotropic spectrum.

Ek_incnumpy.ndarray

Increment isotropic spectrum.

long_namestr

Human-readable variable name for plot title.

levelint

Vertical level index.

outnamestr

Output PNG filename.

pct_textstr

Text describing increment percentage contribution.

Notes

The plot includes: - Background spectrum (black) - Increment spectrum (red) - Annotated DA contribution ranges

Function Summary

SpectraCore

Core FV3-JEDI spectral diagnostics engine.

main

Run BKG–INC spectral diagnostics from a YAML configuration file.

Detailed API

class ufs_da_diagnostics.spectra.spectra_core.SpectraCore(varname='T_inc', grid_prefix='./C96_grid.tile', suffix='.nc')[source]

Bases: object

Core FV3-JEDI spectral diagnostics engine.

This class provides the computational backend for spectral analysis workflows, including:

  • Loading FV3 cubed-sphere tiles

  • Loading FV3 grid geometry and converting corner → center points

  • Regridding cubed-sphere tiles to a global lat/lon mesh

  • Computing isotropic 1D wavenumber spectra

  • Computing vertical variance profiles

  • Computing 2D spectral ratios (EXP / CTRL)

Parameters

varnamestr, optional

Name of the variable to extract from FV3 increment files. Default is "T_inc".

grid_prefixstr, optional

Prefix for FV3 grid files, e.g. "./C96_grid.tile".

suffixstr, optional

File suffix for both grid and data files (default ".nc").

Notes

This class does not perform any plotting. Plotting is handled by the driver modules:

  • spectra_analysis_tiles.py (ANA–INC)

  • spectra_analysis_bkg_inc.py (BKG–INC)

build_global(prefix, level)[source]

Regrid all six FV3 tiles to a global lat/lon mesh for one level.

Parameters

prefixstr

Tile file prefix, e.g. "/path/to/atminc.tile".

levelint

Vertical level index.

Returns

Lonnumpy.ndarray

2D longitude meshgrid (regular lat/lon grid).

Latnumpy.ndarray

2D latitude meshgrid.

field_interpnumpy.ndarray

2D field interpolated onto the global mesh.

Notes

  • Tile fields are flattened and concatenated.

  • scipy.interpolate.griddata performs nearest-neighbor interpolation onto a regular 1°×1° grid.

build_global_all_levels(prefix, nlevels)[source]

Regrid all vertical levels for a given experiment.

Parameters

prefixstr

Tile file prefix.

nlevelsint

Number of vertical levels.

Returns

Lonnumpy.ndarray

2D longitude meshgrid.

Latnumpy.ndarray

2D latitude meshgrid.

fieldsnumpy.ndarray

3D array of shape (nlevels, ny, nx) containing all levels.

isotropic_spectrum(field)[source]

Compute the 1D isotropic wavenumber spectrum of a 2D field.

Parameters

fieldnumpy.ndarray

2D field on a regular lat/lon grid.

Returns

numpy.ndarray

1D isotropic spectrum E(k).

Notes

  • Uses 2D FFT with fftshift.

  • Computes radial bins in wavenumber space.

  • Returns energy density averaged over annuli.

load_fields(ctrl_prefix, exp_prefix, nlevels=127)[source]

Load CTRL and EXP fields for all vertical levels and compute spectra.

Parameters

ctrl_prefixstr

File prefix for CTRL increment tiles.

exp_prefixstr

File prefix for EXP increment tiles.

nlevelsint, optional

Number of vertical levels to load (default 127).

Returns

None

Results are stored as attributes: - CTRL_3D : 3D array of CTRL fields - EXP_3D : 3D array of EXP fields - spec_ctrl_all : spectra for all CTRL levels - spec_exp_all : spectra for all EXP levels - spec_ratio_all : EXP/CTRL spectral ratio - k : wavenumber array

load_grid(tile)[source]

Load FV3 grid geometry and compute cell-center coordinates.

Parameters

tileint

Tile number (1–6).

Returns

lon_cnumpy.ndarray

2D array of cell-center longitudes.

lat_cnumpy.ndarray

2D array of cell-center latitudes.

Notes

FV3 grid files store corner coordinates. This method converts them to cell centers using a 4-point average.

load_tile(prefix, tile, level)[source]

Load a single FV3 cubed-sphere tile for a given vertical level.

Parameters

prefixstr

File prefix for the tile, e.g. "/path/to/atminc.tile".

tileint

Tile number (1–6).

levelint

Vertical level index.

Returns

numpy.ndarray

2D array of the requested variable at the given level.

Notes

Assumes FV3-JEDI tile files follow the naming pattern:

<prefix><tile><suffix>
spectral_ratio_2d()[source]

Return the full 2D spectral ratio array (EXP / CTRL).

Returns

numpy.ndarray

2D array of shape (nlevels, nk) containing spectral ratios.

variance_profile()[source]

Compute vertical variance ratio (EXP / CTRL).

Returns

numpy.ndarray

1D array of variance ratios for each vertical level.

Notes

Variance is computed as the sum of the isotropic spectrum across all wavenumbers.

ufs_da_diagnostics.spectra.spectra_analysis_tiles.main()[source]

Run ANA–INC spectral diagnostics from a YAML configuration file.

This function implements the full workflow for comparing analysis increments between two experiments (CTRL vs EXP). It is invoked by the CLI entry point ufsda-spectra-ana-inc.

YAML Configuration

Expected structure:

experiments:
  - name: ctrl
    prefix: "/path/to/ctrl/atminc.tile"
  - name: exp
    prefix: "/path/to/exp/atminc.tile"

grid:
  prefix: "/path/to/C96_grid.tile"

vars: [u_inc, v_inc, T_inc]
levels: [126, 75, 50]

output_dir: "./spectra_ana_inc"
nicas_length_scale: 120000  # optional

Parameters

None

Returns

None

All output is written to PNG files in the configured output directory.

Notes

  • This driver always loads 127 vertical levels internally, even if only a subset is plotted.

  • SpectraCore performs all computation; this script only orchestrates workflow and plotting.

  • The NICAS length scale (if provided) is passed through to the plotter for optional overlay.

ufs_da_diagnostics.spectra.spectra_analysis_bkg_inc.main()[source]

Run BKG–INC spectral diagnostics from a YAML configuration file.

This function implements the workflow for comparing background fields against analysis increments for a single experiment. It is invoked by the CLI entry point ufsda-spectra-bkg-inc.

YAML Configuration

Expected structure:

background:
  atm_file: "/path/to/atm_background.nc"

increments:
  prefix: "/path/to/atminc.tile"
  grid_prefix: "/path/to/C96_grid.tile"

mapping:
  - bkg: T
    inc: T_inc
    long_name: Temperature increment

spectra:
  levels: [126, 75]
  output_dir: "./spectra_bkg_inc"

Workflow

  1. Load background fields from a single ATM file

  2. Load increment fields using SpectraCore.build_global

  3. Compute isotropic spectra for both fields

  4. Compute increment percentage contribution

  5. Generate overlay plots

Returns

None

All output is written to PNG files in the configured output directory.