Plotting Subsystem API

The plotting subsystem provides all figure-generation utilities used by the diagnostics drivers.

Modules

Base Plotter Utilities

This module defines BasePlotter, a lightweight helper class that standardizes figure creation and title placement across all diagnostics plots in the ufs_da_diagnostics package.

It provides:

  • Consistent Matplotlib styling (fonts, tick sizes, legend sizes)

  • A unified new_figure() method with controlled margins

  • A robust add_title() method using a dedicated title axis

All higher‑level plotters (increment maps, spectra, obs diagnostics, ATMS diagnostics, QC plots, etc.) inherit or use this class to ensure visual consistency across the entire diagnostics suite.

class ufs_da_diagnostics.plots.base_plotter.BasePlotter[source]

Bases: object

Base class providing consistent figure styling and layout helpers.

This class configures global Matplotlib parameters for uniform appearance across all diagnostics plots. It also provides helper methods for creating figures with standardized margins and adding top‑level titles using a dedicated axis.

Notes

  • plt.rcParams is updated at initialization to ensure consistent font sizes and label formatting.

  • new_figure() returns a figure with controlled margins suitable for multi‑panel layouts.

  • add_title() places a title in a fixed top region using an invisible axis, ensuring stable spacing regardless of subplot configuration.

add_title(fig, text)[source]

Add a top‑level title using a dedicated invisible axis.

Parameters

figmatplotlib.figure.Figure

Figure to which the title will be added.

textstr

Title text.

Notes

  • A dedicated axis is added above the subplot grid.

  • This avoids layout conflicts with suptitle() and ensures consistent vertical spacing across all diagnostics figures.

new_figure(width=18, height=6, top=0.9)[source]

Create a new figure with standardized margins.

Parameters

widthfloat, optional

Figure width in inches (default 18).

heightfloat, optional

Figure height in inches (default 6).

topfloat, optional

Top margin for subplot area (default 0.90).

Returns

matplotlib.figure.Figure

A new figure with predefined margins and spacing.

Notes

  • wspace is set to 0.25 for multi‑panel horizontal spacing.

  • left/right/bottom margins are tuned for diagnostics.

class ufs_da_diagnostics.plots.obs_diag_plotter.ObsDiagPlotter(config)[source]
run()[source]
ufs_da_diagnostics.plots.obs_diag_plotter.unified_histogram(omb, oma, qc, title_label, outpath, qc_label='QC', nbins=None)[source]

Generic histogram for scalar/vector/ATMS channels.

Spectral Diagnostics Plotting

This module provides the plotting backend for the spectral diagnostics subsystem. It generates a three‑panel spectral diagnostics figure for a given model level:

  1. 1D isotropic spectra - CTRL spectrum - EXP spectrum - Absolute difference

  2. Vertical variance profile - Ratio of EXP/CTRL variance as a function of model level

  3. 2D spectral ratio - EXP/CTRL ratio across (level × wavenumber)

The figure layout and styling are consistent with the rest of the diagnostics suite through inheritance from BasePlotter.

The module also includes a fixed FV3 pressure grid (PFULL_MBAR) used to annotate pressure levels in the title.

class ufs_da_diagnostics.plots.spectra_plots.SpectraPlotter[source]

Plotter for spectral diagnostics (1D spectra, variance profile, 2D ratio).

This class generates a three‑panel figure summarizing spectral differences between a control experiment and a test experiment.

Expected core object interface

The core argument must be an instance of SpectraCore and provide:

  • core.varname : variable name

  • core.k : wavenumber array

  • core.spec_ctrl_all[level] : 1D CTRL spectrum

  • core.spec_exp_all[level] : 1D EXP spectrum

  • core.variance_profile() : vertical variance ratio (EXP/CTRL)

  • core.spectral_ratio_2d() : 2D ratio (level × wavenumber)

  • core.nlevels : number of vertical levels

Notes

  • Pressure annotations use the fixed FV3 PFULL_MBAR grid.

  • return_fig=True allows the caller to embed the figure in multi‑page PDFs or composite layouts.

plot_spectra(core, level, ctrl_name, exp_name, fname=None, nicas_length_scale=None, return_fig=False)[source]

Generate a 3‑panel spectral diagnostics figure for a given level.

Parameters

coreSpectraCore

Spectral diagnostics engine providing spectra and ratios.

levelint

Model level index to plot.

ctrl_namestr

Label for the control experiment.

exp_namestr

Label for the experiment being compared.

fnamestr, optional

Output filename. If None, the figure is not saved.

nicas_length_scalefloat, optional

NICAS length scale (meters). If provided, displayed in the 1D spectra panel.

return_figbool, optional

If True, return the Matplotlib figure instead of saving.

Returns

matplotlib.figure.Figure or None

Returned only when return_fig=True. Otherwise, the figure is saved (if fname is provided) and closed.

Figure Panels

Panel 1 — 1D Spectra
  • CTRL spectrum

  • EXP spectrum

  • Absolute difference

  • Optional NICAS length scale annotation

Panel 2 — Variance Profile
  • EXP/CTRL variance ratio vs model level

  • Vertical axis inverted (top = surface)

Panel 3 — 2D Spectral Ratio
  • EXP/CTRL ratio across (level × wavenumber)

  • Log‑scaled wavenumber axis

  • Colorbar range fixed to [0.5, 1.5]

Notes

  • The figure uses a fixed 1×3 layout with equal aspect panels.

  • Pressure annotation is included in the title when available.

Scalar Observation Histograms

This module provides histogram diagnostics for scalar observation types (e.g., temperature, humidity, pressure). It supports two modes:

  1. Standard scalar diagnostics - OMB histogram (QC2 == 0) - Optional OMA overlay (if available)

  2. GNSSRO fallback mode - If OMB is missing, the histogram is generated from ObsValue only.

QC2 filtering is applied consistently, and all arrays are flattened before histogramming.

ufs_da_diagnostics.plots.scalar_hist.plot_scalar_hist(f, varname, label, outdir)[source]

Plot histogram diagnostics for scalar observations.

This function supports two workflows:

  1. GNSSRO fallback mode

    If OMB is missing, the function plots a histogram of ObsValue only. This matches the behavior of legacy GNSSRO diagnostics.

  2. Standard scalar mode

    If OMB exists, the function plots:

    • OMB histogram (QC2 == 0)

    • Optional OMA overlay (if available)

Parameters

fxarray.Dataset or dict-like

Observation diagnostics file containing QC, ObsValue, OMB, OMA.

varnamestr

Name of the scalar variable (e.g., "air_temperature").

labelstr

Short label used in plot titles and output filenames.

outdirstr

Directory where output PNG files will be written.

Notes

  • QC2 filtering is applied using load_qc_any.

  • All arrays are flattened before histogramming.

  • KDE is not used here (unlike unified histograms) to preserve legacy behavior.

  • One PNG file is produced per variable.

Returns

None

A PNG file is written to outdir.

Vector Observation Histograms

This module provides histogram diagnostics for vector observations such as:

  • SATWND (u/v wind components)

  • SCATWND

  • Any observation type stored as a 2‑component vector (u, v)

The diagnostics produce two histograms:

  1. U‑component (eastward wind)

  2. V‑component (northward wind)

Both histograms include:

  • OMB histogram (QC2==0)

  • KDE overlays for OMB and OMA

  • Adaptive bin selection

  • Assimilated‑count annotation

This module is used by the observation diagnostics orchestrator and mirrors the behavior of scalar and ATMS histogram routines.

ufs_da_diagnostics.plots.vector_hist.plot_vector_hist(f, varname, label, outdir)[source]

Plot U and V component histograms for vector wind observations.

This function generates a two‑panel figure:

  • Left panel: U‑component histogram

  • Right panel: V‑component histogram

Both panels include:

  • OMB histogram (QC2==0)

  • KDE overlays for OMB and OMA

  • Adaptive bin selection based on combined U/V spread

  • Assimilated‑count annotation

Parameters

fxarray.Dataset or dict-like

Observation diagnostics file containing OMB, OMA, QC.

varnamestr

Name of the vector variable (e.g., "windEastward" is not used here; instead, the file must store a 2‑component vector under varname).

labelstr

Short label used in plot titles and output filenames.

outdirstr

Directory where the output PNG file will be written.

Notes

  • Expected OMB/OMA shape is (nlocs, 2).

  • QC is assumed to be 1‑D (Location) for vector winds.

  • QC2 filtering is applied using load_qc_any.

  • One PNG file is produced: <label>_vector_hist.png.

Returns

None

A PNG file is written to outdir.

ATMS Per‑Channel Histograms

This module generates per‑channel histograms for ATMS radiance observations using the same logic as the original obs_diag_plots.py implementation.

The workflow:

  1. Load QC2 flags, OMB, and OMA for an ATMS variable

  2. Apply QC2==0 mask (assimilated observations only)

  3. Compute adaptive histogram bins based on OMB standard deviation

  4. Plot: - Grey histogram of OMB - KDE of OMB (dimgray) - KDE of OMA (red)

  5. Annotate assimilated count

  6. Save one PNG per channel

This module is used by the observation diagnostics subsystem and is typically invoked indirectly through higher‑level plot orchestrators.

ufs_da_diagnostics.plots.atms_hist.plot_hist_atms(f, varname, label, outdir)[source]

Plot per‑channel ATMS histograms for a given variable.

This function reproduces the original ATMS histogram behavior from obs_diag_plots.py. For each channel, it plots:

  • Grey histogram of OMB (QC2==0 only)

  • KDE of OMB (dimgray)

  • KDE of OMA (red)

  • Assimilated count annotation

Adaptive bin counts are selected based on the standard deviation of OMB for each channel.

Parameters

fxarray.Dataset or dict-like

Observation diagnostics file handle or structure containing OMB, OMA, and QC fields.

varnamestr

Name of the ATMS variable (e.g., "brightness_temperature", "atms_bt").

labelstr

Short label used in plot titles and output filenames.

outdirstr

Directory where output PNG files will be written.

Notes

  • Only QC2==0 observations are included.

  • If QC2 is missing or not 2‑D, the function prints a skip message.

  • One PNG file is produced per channel.

  • KDE plotting is wrapped in a try/except to avoid failures on degenerate distributions.

Returns

None

PNG files are written to outdir.

ATMS Latitude‑Binned Diagnostics

This module computes latitude‑binned OMB/OMA statistics for ATMS radiance observations using QC2 filtering. It reproduces the behavior of the original latitude‑binned diagnostics from obs_diag_plots.py, but in a cleaner, modular form.

Workflow

  1. Load OMB and OMA using loader utilities (supports ombg/oman groups)

  2. Load QC flags using load_qc_universal (Location × Channel)

  3. Broadcast latitude to match QC shape

  4. Apply QC2==0 mask and flatten arrays

  5. Compute: - Mean OMB / OMA per latitude bin - Std OMB / OMA per latitude bin - RMS OMB / OMA per latitude bin

  6. Produce a two‑panel figure: - Panel 1: Mean + Std (dual axis) - Panel 2: RMS

Output

A single PNG file:

atms_latbins_qc2.png

saved in the specified output directory.

ufs_da_diagnostics.plots.atms_latbins.plot_latbins_atms(f, var, label, outdir)[source]

Plot ATMS latitude‑binned OMB/OMA diagnostics (QC2‑filtered).

This function computes and plots: - Mean OMB / OMA vs latitude - Std OMB / OMA vs latitude - RMS OMB / OMA vs latitude

using QC2==0 observations only.

Parameters

fxarray.Dataset or dict-like

Observation diagnostics file containing OMB, OMA, QC, and MetaData/latitude.

varstr

Variable name for ATMS radiances (e.g., "brightness_temperature").

labelstr

Short label used in plot titles and output filenames.

outdirstr

Directory where the output PNG file will be saved.

Notes

  • QC mask is applied per (Location, Channel).

  • Latitude is broadcast to match QC shape before masking.

  • All arrays are flattened after masking.

  • RMS is computed explicitly even though it equals std for zero‑mean distributions; kept for clarity and compatibility with legacy plots.

Returns

None

A single PNG file is written to outdir.

ATMS Scan‑Position Diagnostics

This module computes scan‑position‑dependent OMB/OMA statistics for ATMS radiance observations using QC2 filtering. It reproduces the behavior of the original scan‑position diagnostics from obs_diag_plots.py but in a modular, maintainable form.

Workflow

  1. Load OMB and OMA using loader utilities (supports ombg/oman groups)

  2. Load QC flags using load_qc_universal (Location × Channel)

  3. Load scan position and channel number from MetaData group

  4. Broadcast scan position to match QC shape

  5. Apply QC2==0 mask and flatten arrays

  6. Compute, for each scan position: - Mean OMB / OMA - Std OMB / OMA - RMS OMB / OMA

  7. Produce a three‑panel figure: - Window channels - O₂ temperature channels - H₂O channels

Output

A single PNG file:

atms_scan_position_qc2.png

saved in the specified output directory.

ufs_da_diagnostics.plots.atms_scan_position.plot_scan_position_atms(f, var, label, outdir)[source]

Plot ATMS scan‑position OMB/OMA diagnostics (QC2‑filtered).

This function generates a three‑panel figure showing scan‑position statistics for:

  1. Window channels (1, 2, 16, 17)

  2. O₂ temperature channels (3–15)

  3. H₂O channels (18–22)

Parameters

fxarray.Dataset or dict-like

Observation diagnostics file containing OMB, OMA, QC, and MetaData/sensorScanPosition and MetaData/sensorChannelNumber.

varstr

Variable name for ATMS radiances.

labelstr

Short label used in log messages and output filenames.

outdirstr

Directory where the output PNG file will be saved.

Notes

  • QC mask is applied per (Location, Channel).

  • Scan position is broadcast to match QC shape before masking.

  • All arrays are flattened after masking.

  • One PNG file is produced containing all three channel groups.

Returns

None

A single PNG file is written to outdir.

ATMS Channel‑Wise OMB/OMA Statistics

This module computes per‑channel OMB/OMA mean and standard deviation for ATMS radiance observations using QC2 filtering. It reproduces the behavior of the original ATMS channel‑stats diagnostics from obs_diag_plots.py but in a modular, maintainable form.

Workflow

  1. Load OMB and OMA using loader utilities (supports ombg/oman groups)

  2. Load QC flags using load_qc_universal (Location × Channel)

  3. For each channel: - Apply QC2==0 mask - Compute mean OMB / OMA - Compute std OMB / OMA

  4. Plot: - Mean OMB/OMA (left y‑axis) - Std OMB/OMA (right y‑axis) - Shaded channel‑group bands (Window, O₂, H₂O) - Combined legend + channel‑group legend

Output

A single PNG file:

<label>_stats.png

saved in the specified output directory.

ufs_da_diagnostics.plots.atms_stats.plot_stats_atms(f, varname, label, outdir)[source]

Plot ATMS per‑channel OMB/OMA mean and standard deviation (QC2‑filtered).

This function computes and plots: - Mean OMB / OMA per channel - Std OMB / OMA per channel - Shaded channel groups (Window, O₂, H₂O) - Combined legend + channel‑group legend

Parameters

fxarray.Dataset or dict-like

Observation diagnostics file containing OMB, OMA, QC, and metadata.

varnamestr

Variable name for ATMS radiances (e.g., "brightness_temperature").

labelstr

Short label used in plot titles and output filenames.

outdirstr

Directory where the output PNG file will be saved.

Notes

  • QC mask is applied per (Location, Channel).

  • If QC is 1‑D, it is broadcast to match the number of channels.

  • Channels are assumed to be 1‑indexed for plotting.

  • One PNG file is produced.

Returns

None

A single PNG file is written to outdir.

Extended ATMS OMB/OMA diagnostics.

This module computes and visualizes channel-by-channel statistics for ATMS brightness temperature departures, including:

  • Mean OMB / OMA

  • RMS OMB / OMA

  • Bias-corrected RMS (BC-RMS)

  • Normalized RMS (RMS_n), using EffectiveError2 as σ_o

  • RMS_n^2 debug output for chi-square consistency checks

All computations use QC2==0 and EffectiveError2, matching the values used in the JEDI cost function. RMS_n^2 is mathematically equivalent to Jo/p for the same QC mask and σ_o.

ufs_da_diagnostics.plots.atms_stats_extended.channel_groups()[source]
ufs_da_diagnostics.plots.atms_stats_extended.plot_stats_atms_extended(f, varname, label, outdir)[source]

Generate extended ATMS OMB/OMA diagnostics.

QC Diagnostics Plotting

This module provides a simple bar‑chart visualization of QC pass/fail counts. It is used by various diagnostics workflows to summarize the number of assimilated (QC==0) and rejected (QC!=0) observations.

The QCPlotter class inherits from BasePlotter to ensure consistent styling and figure layout across the diagnostics suite.

class ufs_da_diagnostics.plots.qc_plots.QCPlotter[source]

Plotter for QC pass/fail summary charts.

This class extends BasePlotter and provides a single method, plot_qc_counts(), which generates a bar chart showing the number of observations that passed QC filtering versus those that failed.

Notes

  • This plot is intentionally simple and is typically used as a high‑level summary.

  • The figure uses the standardized styling defined in BasePlotter.

plot_qc_counts(qc_pass, qc_fail, fname=None)[source]

Plot a bar chart of QC pass/fail counts.

Parameters

qc_passint

Number of observations with QC==0 (assimilated).

qc_failint

Number of observations with QC!=0 (rejected).

fnamestr, optional

Output filename for saving the figure. If None, the figure is not saved.

Returns

None

The figure is displayed only if fname is not provided. When fname is given, the figure is saved and closed.

Notes

  • Bars are colored green (pass) and red (fail).

  • The top‑level title is added using BasePlotter.add_title().

Utility Functions for Plotting

This module contains small helper utilities used across the plotting subsystem. These functions are intentionally lightweight and focused on common numerical operations needed by diagnostics plots.

ufs_da_diagnostics.plots.utils.symmetric_limits(data)[source]

Compute symmetric colorbar limits around zero.

This function is typically used for increment maps or any plot requiring a diverging colormap centered at zero. It ensures that the minimum and maximum limits are symmetric, based on the largest absolute value in the data.

Parameters

datanumpy.ndarray

Input array from which to compute symmetric limits.

Returns

tuple of float

(vmin, vmax) where both are symmetric around zero.

Examples

>>> symmetric_limits(np.array([-3, 1, 2]))
(-3, 3)

Notes

  • data.min() and data.max() must be finite.

  • The function does not modify the input array.

Common Plotting Utilities for FV3-JEDI Observation Diagnostics

This module provides shared helper functions used across the plotting subsystem, including:

  • Filesystem helpers

  • Assimilated-count annotations

  • ATMS channel-group shading and legends

  • Safe KDE plotting

  • Channel tick formatting

These utilities ensure consistent styling and behavior across ATMS, scalar, vector, and spectra diagnostics.

ufs_da_diagnostics.plots.utils_common.annotate_assimilated(fig, N)[source]

Add a small annotation showing the number of assimilated observations.

Parameters

figmatplotlib.figure.Figure

Figure on which to place the annotation.

Nint

Number of assimilated observations (QC==0).

Notes

  • The annotation is placed in the lower-right corner of the figure.

  • Used by ATMS and scalar histogram diagnostics.

ufs_da_diagnostics.plots.utils_common.atms_group_legend(ax, loc='lower right', fontsize=9)[source]

Add an ATMS channel-group legend to an axis.

Parameters

axmatplotlib.axes.Axes

Axis to which the legend will be added.

locstr, optional

Legend location (default "lower right").

fontsizeint, optional

Legend font size.

Notes

  • Colors match those used in shade_atms.

  • Used by ATMS stats and extended stats plots.

ufs_da_diagnostics.plots.utils_common.clean_channel_ticks(ax, nchans)[source]

Set clean, readable x-axis ticks for channel-based plots.

Parameters

axmatplotlib.axes.Axes

Axis to modify.

nchansint

Number of channels.

Notes

  • For ≤22 channels, every channel is labeled.

  • For >22 channels, ticks are spaced every 2 channels.

  • Used by ATMS stats and extended stats plots.

ufs_da_diagnostics.plots.utils_common.kde_safe(ax, data, color='dimgray', linewidth=2, label=None)[source]

Safely draw a KDE curve if the data is valid and non-degenerate.

Parameters

axmatplotlib.axes.Axes

Axis on which to draw the KDE.

dataarray-like

Input data array.

colorstr, optional

Line color (default "dimgray").

linewidthfloat, optional

Line width (default 2).

labelstr, optional

Legend label.

Notes

  • KDE is skipped if: - fewer than 10 valid points exist - the data has zero variance - seaborn raises an exception

  • Used by unified histograms and ATMS histograms.

ufs_da_diagnostics.plots.utils_common.make_output_dir(path)[source]

Create an output directory if it does not already exist.

Parameters

pathstr

Directory path to create.

Returns

str

The same directory path, for convenience.

Notes

  • exist_ok=True ensures the function is safe to call repeatedly.

ufs_da_diagnostics.plots.utils_common.shade_atms(ax)[source]

Apply ATMS channel-group shading to an axis.

The shading follows NOAA’s standard ATMS grouping:

  • Window channels: 1–2 and 16–17

  • O₂ Temperature channels: 3–15

  • H₂O channels: 18–22

Parameters

axmatplotlib.axes.Axes

Axis on which to apply shading.

Notes

  • Assumes the x-axis corresponds to 1-based channel numbers.

  • Used by ATMS mean/std plots and extended diagnostics.

Universal Loader Utilities for Observation Diagnostics

This module provides robust, observation‑type‑agnostic loader functions for reading OMB, OMA, QC, ObsValue, and hofx fields from FV3‑JEDI / IODA‑formatted diagnostics files.

The loaders are designed to handle:

  • ATMS radiances

  • GNSSRO bending angles

  • SATWND / SCATWND winds

  • Conventional observations (e.g., PS, T, Q)

  • Legacy IODA formats (ombg/oman, innov1, DerivedMetaData/Innovation)

  • Masked arrays, object arrays, and missing groups

All returned arrays are converted to float64 with invalid entries replaced by NaN, ensuring downstream plotting code never crashes due to dtype inconsistencies.

This module is the foundation for all histogram, stats, and QC‑filtered diagnostics.

ufs_da_diagnostics.plots.utils_loaders.load_hofx(f, varname)[source]

Load hofx (hofx0 group).

Parameters

fnetCDF4.Dataset

Diagnostics file.

varnamestr

Variable name.

Returns

numpy.ndarray or None

Float64 hofx array, or None if missing.

ufs_da_diagnostics.plots.utils_loaders.load_obs_any(f, varname)

Load ObsValue for a given variable.

Parameters

fnetCDF4.Dataset

Diagnostics file.

varnamestr

Variable name.

Returns

numpy.ndarray or None

Float64 ObsValue array, or None if missing.

ufs_da_diagnostics.plots.utils_loaders.load_obsvalue(f, varname)[source]

Load ObsValue for a given variable.

Parameters

fnetCDF4.Dataset

Diagnostics file.

varnamestr

Variable name.

Returns

numpy.ndarray or None

Float64 ObsValue array, or None if missing.

ufs_da_diagnostics.plots.utils_loaders.load_oma_any(f, varname)

Universal OMA loader.

Priority

  1. oman/<varname> (ATMS, GNSSRO, SATWND, SCATWND, CONVENTIONAL_PS)

  2. ObsValue - hofx (fallback for formats without explicit OMA)

Parameters

fnetCDF4.Dataset

Diagnostics file.

varnamestr

Variable name.

Returns

numpy.ndarray or None

Float64 OMA array, or None if not computable.

ufs_da_diagnostics.plots.utils_loaders.load_oma_explicit(f, varname)[source]

Universal OMA loader.

Priority

  1. oman/<varname> (ATMS, GNSSRO, SATWND, SCATWND, CONVENTIONAL_PS)

  2. ObsValue - hofx (fallback for formats without explicit OMA)

Parameters

fnetCDF4.Dataset

Diagnostics file.

varnamestr

Variable name.

Returns

numpy.ndarray or None

Float64 OMA array, or None if not computable.

ufs_da_diagnostics.plots.utils_loaders.load_omb(f, varname)[source]

Universal OMB loader.

Priority

  1. ombg/<varname> (ATMS, GNSSRO, SATWND, SCATWND, CONVENTIONAL_PS)

  2. innov1/<varname> (some IODA-v1 formats)

  3. DerivedMetaData/Innovation (fallback, e.g., ATMS)

Parameters

fnetCDF4.Dataset

Diagnostics file.

varnamestr

Variable name.

Returns

numpy.ndarray or None

Float64 OMB array, or None if not found.

ufs_da_diagnostics.plots.utils_loaders.load_omb_any(f, varname)

Universal OMB loader.

Priority

  1. ombg/<varname> (ATMS, GNSSRO, SATWND, SCATWND, CONVENTIONAL_PS)

  2. innov1/<varname> (some IODA-v1 formats)

  3. DerivedMetaData/Innovation (fallback, e.g., ATMS)

Parameters

fnetCDF4.Dataset

Diagnostics file.

varnamestr

Variable name.

Returns

numpy.ndarray or None

Float64 OMB array, or None if not found.

ufs_da_diagnostics.plots.utils_loaders.load_qc_any(f, varname)

Universal QC loader with multi-group fallback.

Priority order:
  1. EffectiveQC2

  2. EffectiveQC1

  3. EffectiveQC0

  4. EffectiveQC

  5. ObsDiag

  6. QualityControl

  7. FortranQC

Behavior

  • If a QC group exists but the variable is missing → return all-valid QC.

  • If no QC groups exist → return all-valid QC.

  • QC arrays are returned as int32.

Parameters

fnetCDF4.Dataset

Diagnostics file handle.

varnamestr

Observation variable name.

Returns

numpy.ndarray

QC array of shape (Location,) or broadcastable to (Location, Channel).

Notes

  • All-valid QC means QC == 0 everywhere.

  • This loader supports both IODA-v1 and IODA-v2 conventions.

ufs_da_diagnostics.plots.utils_loaders.load_qc_universal(f, varname)[source]

Universal QC loader with multi-group fallback.

Priority order:
  1. EffectiveQC2

  2. EffectiveQC1

  3. EffectiveQC0

  4. EffectiveQC

  5. ObsDiag

  6. QualityControl

  7. FortranQC

Behavior

  • If a QC group exists but the variable is missing → return all-valid QC.

  • If no QC groups exist → return all-valid QC.

  • QC arrays are returned as int32.

Parameters

fnetCDF4.Dataset

Diagnostics file handle.

varnamestr

Observation variable name.

Returns

numpy.ndarray

QC array of shape (Location,) or broadcastable to (Location, Channel).

Notes

  • All-valid QC means QC == 0 everywhere.

  • This loader supports both IODA-v1 and IODA-v2 conventions.

ufs_da_diagnostics.plots.utils_loaders.to_numeric_safe(arr)[source]

Convert any ObsValue/hofx/OMB/OMA array to float64 safely.

This function handles: - masked arrays (.filled(np.nan)) - object arrays (element‑wise conversion) - invalid entries (converted to NaN) - arbitrary shapes

Parameters

arrarray-like or None

Input array from diagnostics file.

Returns

numpy.ndarray or None

Float64 array with invalid entries replaced by NaN. Returns None if input is None.

Notes

  • This function is essential for GNSSRO, where some fields may be stored as object arrays.

  • Ensures downstream code can always call np.isfinite() safely.

Function Summary

to_numeric_safe

Convert any ObsValue/hofx/OMB/OMA array to float64 safely.

load_qc_universal

Universal QC loader with multi-group fallback.

load_obsvalue

Load ObsValue for a given variable.

load_hofx

Load hofx (hofx0 group).