import { Paper, Skeleton, Stack, Table, Text, Title } from '@mantine/core' import type { Metrics } from '../types' import { HelpTip } from './HelpTip' interface Props { metrics: Metrics | null } function fmt(v: number, digits = 3): string { if (!Number.isFinite(v)) return '—' if (Math.abs(v) !== 0 && (Math.abs(v) < 1e-2 || Math.abs(v) >= 1e4)) { return v.toExponential(2) } return v.toFixed(digits) } const TIPS = { zh: ( <> Equivalent reflectivity factor at horizontal polarization (dBZ). In the Rayleigh limit it is proportional to the sixth moment of the drop-size distribution; at C/X and for hail the full T-matrix solution deviates from the D⁶ law due to Mie resonances. ), zv: ( <> Equivalent reflectivity factor at vertical polarization (dBZ). For oblate particles Zv < Zh because the vertical axis is shorter than the horizontal. ), zdr: ( <> Differential reflectivity, 10·log₁₀(Zh/Zv) in dB. Positive for horizontally-oriented oblate particles (large rain drops, aggregates), near zero for spheres (small rain, hail tumbling), negative for vertically-aligned prolate shapes (conical graupel, some crystals). ), ldr: ( <> Linear depolarization ratio (dB) — ratio of cross-polar to co-polar return when transmitting one polarization. Elevated by canting, irregular or mixed-phase particles. Spheres with zero canting give LDR → −∞. ), rhohv: ( <> Co-polar correlation coefficient between H and V returns. Close to 1 for uniform populations; depressed by size, shape, or phase diversity — useful for detecting mixed-phase layers, debris, and non-meteorological targets. ), delta: ( <> Backscatter differential phase shift (°). Non-zero when scattering is in the Mie regime — e.g., large drops at C/X band, wet hail. Contaminates ΦDP and can bias Kdp estimates if not removed. ), kdp: ( <> Specific differential phase (° km⁻¹) — propagation-based, half the range derivative of ΦDP. Proportional to the product of water content and drop oblateness. Immune to attenuation and calibration biases; the workhorse for rainfall estimation in heavy rain. ), ah: ( <> Specific attenuation at horizontal polarization (dB km⁻¹). Small at S band, significant at C and X. Kdp-based attenuation correction (e.g., ZPHI) relies on the near-linear Ah– Kdp relationship. ), adr: ( <> Specific differential attenuation (dB km⁻¹) — Ah minus Av. Biases Zdr in heavy-rain paths at C/X; commonly corrected using Adr ∝ Kdp. ), nt: ( <> Total number concentration (m⁻³) — the zeroth moment of the PSD, ∫N(D) dD. Equals the area under the PSD curve (in linear, not log, space). ), lwc: ( <> Liquid (or ice-mass-equivalent) water content (g m⁻³) — third moment of the PSD weighted by hydrometeor density. For snow presets this is the ice-mass content using the habit-specific ρ(D). ), } export function MetricsTable({ metrics }: Props) { const rows: Array<[React.ReactNode, string, React.ReactNode]> = metrics ? [ [<>Zh (dBZ), fmt(metrics.zh_dbz, 2), TIPS.zh], [<>Zv (dBZ), fmt(metrics.zv_dbz, 2), TIPS.zv], [<>Zdr (dB), fmt(metrics.zdr_db, 3), TIPS.zdr], ['LDR (dB)', fmt(metrics.ldr_db, 2), TIPS.ldr], [<>ρhv, fmt(metrics.rho_hv, 5), TIPS.rhohv], [<>δhv (deg), fmt(metrics.delta_deg, 3), TIPS.delta], [<>Kdp (° km⁻¹), fmt(metrics.kdp_deg_per_km, 4), TIPS.kdp], [<>Ah (dB km⁻¹), fmt(metrics.ah_db_per_km, 4), TIPS.ah], [<>Adr (dB km⁻¹), fmt(metrics.adr_db_per_km, 5), TIPS.adr], [<>NT (m⁻³), fmt(metrics.nt_per_m3, 2), TIPS.nt], ['LWC (g m⁻³)', fmt(metrics.lwc_g_per_m3, 4), TIPS.lwc], ] : [] return ( T-matrix scattering results {metrics ? ( {rows.map(([label, v, tip], i) => ( {label} {v} ))}
) : ( {Array.from({ length: 8 }).map((_, i) => ( ))} )}
) }