rustmatrix.hd_mix#

Hydrometeor mixtures.

Combine multiple hydrometeor species — each with its own PSD, scatterer configuration, orientation PDF, refractive index, and shape — and read the combined polarimetric radar observables through the existing rustmatrix.radar and rustmatrix.scatter helpers.

Why summing S and Z works#

Both the amplitude matrix S (forward, used by K_dp and A_i) and the phase matrix Z (backscatter intensities, used by Z_h, Z_dr, rho_hv, delta_hv, LDR) are linear functionals of the number concentration N(D). For a mixture of independent species,

S_mix(geom) = sum_i int S_i(D, geom) N_i(D) dD Z_mix(geom) = sum_i int Z_i(D, geom) N_i(D) dD

Every non-linear observable (Z_dr, rho_hv, delta_hv, LDR) is a rational function of the total S and Z. Summing across species and passing the combined matrices to radar.Zdr(), radar.rho_hv(), etc. is therefore the physically correct incoherent-mixture recipe — not an approximation.

Mixing fractions live inside each component’s N_i(D): scale Nw in a GammaPSD, N0 in an ExponentialPSD, etc. There is no separate weight scalar.

Example

>>> from rustmatrix import Scatterer, HydroMix, MixtureComponent
>>> from rustmatrix.psd import PSDIntegrator, GammaPSD, ExponentialPSD
>>> # Configure each species' scatterer with an initialised PSDIntegrator
>>> # that registers every geometry the mixture will query, then:
>>> mix = HydroMix([
...     MixtureComponent(rain_scatterer,  GammaPSD(D0=1.5, Nw=8e3, mu=4), "rain"),
...     MixtureComponent(ice_scatterer,   ExponentialPSD(N0=5e3, Lambda=2.5), "ice"),
... ])
>>> mix.set_geometry(geom_horiz_back)
>>> from rustmatrix import radar
>>> Zh, Zdr, rho = radar.refl(mix), radar.Zdr(mix), radar.rho_hv(mix)
class rustmatrix.hd_mix.MixtureComponent(scatterer, psd, label=None)[source]#

Bases: object

One hydrometeor species inside a HydroMix.

Parameters:
scatterer#

Species-specific scatterer. Must have psd_integrator attached and already initialised (init_scatter_table(...) called) with every geometry the mixture will query.

Type:

Scatterer

psd#

Number concentration N_i(D) for this species. Scale the PSD parameters (Nw, N0, …) to express the species’ share of the mixture.

Type:

PSD

label#

Human-readable name used in error messages.

Type:

str, optional

class rustmatrix.hd_mix.HydroMix(components=None, Kw_sqr=None)[source]#

Bases: object

Mixture of hydrometeor species with a Scatterer-shaped API.

The instance exposes the same attributes and methods that the radar and scatter helpers read on a Scattererwavelength, Kw_sqr, thet0/thet/phi0/phi/alpha/beta, set_geometry, get_geometry, get_S, get_Z, get_SZ — so existing helpers work on a HydroMix unchanged.

Parameters:
  • components (list of MixtureComponent, optional) – Initial components. More may be added later via add().

  • Kw_sqr (float, optional) – Reference |K_w|^2 used by radar.refl() to normalise reflectivity. Defaults to the first component’s Kw_sqr — typically the liquid-water value.

Notes

  • All components must share wavelength; a mismatch raises ValueError on add().

  • Each component’s PSDIntegrator must have been initialised with every geometry the mixture will query. Missing geometries raise ValueError on get_SZ().

  • psd_integrator is always None on the mixture so that scatter.ext_xsect() falls back to its optical-theorem path, which reads the summed forward S matrix via get_S().

set_geometry(geom)[source]#

Set (thet0, thet, phi0, phi, alpha, beta) on the mixture and propagate to every component.

get_SZ()[source]#

Summed (S, Z) across components at the current geometry.

Returns:

  • S (ndarray (2, 2) complex)

  • Z (ndarray (4, 4) float)