rustmatrix.psd#

Particle size distributions (PSDs) and size-distribution integration.

Port of pytmatrix.psd. The PSDIntegrator builds a lookup table S(D), Z(D) at a fixed set of diameters and scattering geometries, then integrates it against a PSD N(D) using the trapezoidal rule. The per-diameter evaluation calls through to the Rust T-matrix core.

Typical usage:

sca = Scatterer(wavelength=wl_C, m=complex(7.99, 2.21), axis_ratio=1/0.9)
sca.psd_integrator = PSDIntegrator()
sca.psd_integrator.D_max = 8.0
sca.psd_integrator.num_points = 256
sca.psd_integrator.init_scatter_table(sca)
sca.psd = GammaPSD(D0=2.0, Nw=1e3, mu=4)
S, Z = sca.get_SZ()
class rustmatrix.psd.PSD[source]#

Bases: object

Abstract PSD base class.

Subclasses override __call__(D) -> number density [mm⁻¹ m⁻³] and __eq__ (used by PSDIntegrator to decide when the cached PSD-weighted integrals are stale). The base class returns 0 for all diameters and never equals another PSD.

class rustmatrix.psd.ExponentialPSD(N0=1.0, Lambda=1.0, D_max=None)[source]#

Bases: PSD

Exponential (Marshall-Palmer-type) PSD.

N(D) = N0 · exp(-Λ·D) for D D_max and 0 beyond.

Parameters:
  • N0 (float) – Intercept parameter [mm⁻¹ m⁻³]. Default 1.0.

  • Lambda (float) – Slope parameter Λ [mm⁻¹]. Default 1.0.

  • D_max (float, optional) – Truncation diameter in mm. Defaults to 11 / Lambda (≈ 3·D0).

class rustmatrix.psd.UnnormalizedGammaPSD(N0=1.0, Lambda=1.0, mu=0.0, D_max=None)[source]#

Bases: ExponentialPSD

Unnormalised gamma PSD: N(D) = N0 · D^μ · exp(-Λ·D).

Parameters:

Notes

The D^μ term is evaluated in log-space to avoid overflow for large μ. Taking D = 0 returns 0.

class rustmatrix.psd.GammaPSD(D0=1.0, Nw=1.0, mu=0.0, D_max=None)[source]#

Bases: PSD

Normalised gamma PSD (Bringi & Chandrasekar convention).

N(D) = N_w · f(μ) · (D/D0)^μ · exp(-(3.67+μ) D/D0), with f(μ) = 6 / 3.67⁴ · (3.67+μ)^(μ+4) / Γ(μ+4).

Parameters:
  • D0 (float) – Median volume diameter in mm. Default 1.0.

  • Nw (float) – Intercept parameter [mm⁻¹ m⁻³]. Default 1.0.

  • mu (float) – Shape parameter μ. Default 0 (reduces to exponential).

  • D_max (float, optional) – Truncation diameter in mm. Defaults to 3 · D0.

References

Bringi, V. N., & Chandrasekar, V. (2001). Polarimetric Doppler Weather Radar, Cambridge University Press.

class rustmatrix.psd.BinnedPSD(bin_edges, bin_psd)[source]#

Bases: PSD

Step-function PSD specified by bin edges and per-bin number densities.

Parameters:
  • bin_edges (sequence of float, length n+1) – Monotonically increasing bin edges in mm.

  • bin_psd (sequence of float, length n) – Per-bin number densities [mm⁻¹ m⁻³]. bin_psd[i] applies to D in (bin_edges[i], bin_edges[i+1]].

class rustmatrix.psd.PSDIntegrator(**kwargs)[source]#

Bases: object

Integrate scattering properties over a particle-size distribution.

Usage#

Attach an instance to Scatterer.psd_integrator, configure num_points, D_max, optional axis_ratio_func/m_func, and geometries, then call init_scatter_table() once to build the diameter-indexed lookup tables. Thereafter setting Scatterer.psd to any PSD instance and calling Scatterer.get_SZ() (or the radar / scatter helpers) returns the PSD-integrated result via trapezoidal integration over the pre-tabulated S(D) and Z(D).

num_points#

Number of diameters sampled between D_max/num_points and D_max. Default 1024.

Type:

int

m_func#

m(D) -> complex — varies refractive index with diameter. None uses the scatterer’s scalar m.

Type:

callable, optional

axis_ratio_func#

eps(D) -> float — varies axis ratio with diameter (e.g. tmatrix_aux.dsr_thurai_2007()).

Type:

callable, optional

D_max#

Largest diameter to tabulate in mm. Must cover every PSD the table will be used with.

Type:

float

geometries#

(thet0, thet, phi0, phi, alpha, beta) scattering geometries to precompute. Typically includes both backscatter and forward geometries when K_dp / A_i are needed.

Type:

tuple of 6-tuples

Notes

init_scatter_table() dispatches to one of four parallel Rust fast paths (single orientation, fixed-orient-avg, adaptive-orient-avg, single-orient + angular integration); see the module docstring for details and the README Performance section for benchmarks.

get_SZ(psd, geometry)[source]#

PSD-integrated (S, Z) at the given geometry.

Parameters:
  • psd (PSD) – Particle-size distribution.

  • geometry (6-tuple) – One of the geometries registered when init_scatter_table() was called.

Returns:

S, Z – PSD-weighted trapezoidal integrals of the precomputed S(D) and Z(D) lookup tables.

Return type:

ndarray

get_angular_integrated(psd, geometry, property_name, h_pol=True)[source]#

PSD-integrated angular quantity (sca_xsect / ext_xsect / asym).

init_scatter_table(tm, angular_integration=False, verbose=False)[source]#

Populate the diameter-indexed S(D) / Z(D) lookup tables.

Parameters:
  • tm (Scatterer) – Template scatterer; its wavelength, m, ddelt, ndgs, shape, radius_type, orient, and or_pdf are copied.

  • angular_integration (bool) – If True, also tabulates the polarised scattering and extinction cross-sections and the asymmetry parameter at each diameter. Required before calling scatter.sca_xsect(), scatter.asym(), or their radar derivatives (radar.Ai()) on a PSD-integrated scatterer.

  • verbose (bool) – Print per-diameter progress when falling back to the Python loop (used only for combinations without a Rust fast path).

Notes

Dispatches into one of four Rust fast paths depending on tm.orient and angular_integration — see the README Performance section for benchmarks. All four release the GIL and parallelise across diameters via rayon.

save_scatter_table(fn, description='')[source]#

Pickle the lookup tables to disk.

Return type:

None

Parameters:
load_scatter_table(fn)[source]#

Load a pickled lookup table saved by save_scatter_table().

Parameters:

fn (str)