pyrsig.emiss package¶
Module contents¶
- pyrsig.emiss.divergence(c, dy, dx, order=4, withdiag=True)[source]¶
calculate gradient of c in w-e and s-n directions and optionally in the ne-sw and se-nw diagonals
- Parameters:
c (array) – 2-dimensional array of column densities
dy (float or array) – pixel edge length in the y direction
dx (float or array) – pixel edge length in the x direction
- Returns:
dcdx, dcdy[, dcdr, dcds] – tuple of 2 or 4 divergence
- Return type:
tuple
Notes
- Adapted from https://github.com/Kang-Sun-CfA/Oversampling_matlab/blob
/v0.2/popy.py#L1711C1-L1732C1
- pyrsig.emiss.emg(x, alpha, x0, sigma, mu, beta, return_parts=False)[source]¶
Eq 1 of Goldberg et al.[1] as described
e = 1/x0 exp(mu/x0 + sigma^2 / (2 x0^2) - x / x0) G = F((x - mu)/sigma - sigma/x_o) f = e * G y = alpha f + beta
Note: F is the Gaussian cumulative distribution function”
[1] Goldberg et al. doi: 10.5194/acp-22-10875-2022
- Parameters:
x (array) – x0 is the e-folding distance downwind, representing the length scale of the NO2 decay
alpha (float) – Mass distributed across distance
sigma (float) – sigma is the standard deviation of the Gaussian function, representing the Gaussian smoothing length scale
mu (float) – mu is the location of the apparent source relative to the assumed pollution source center
beta (float) – Background line density
return_parts (bool) – If False (default), return final output. If True, return parts for further analysis
- Returns:
out – If False (default), return y (alpha * e * G + beta) If True, return alpha, e, G, beta and alpha * e * G + beta
- Return type:
array or tuple
Example
import numpy as np from pyrsig.emiss._emg import emg # Approximation of data in Goldberg[1] Figure 8a inset # g/y y/h * h molNOx/gNOx NO2/NOx [=] mol approx_alpha = 62e9 / 8760 * 1.7 / 46 / 1.32 approx_x0 = 20e3 # iteratively identified exparams = {
‘alpha’: approx_alpha, ‘x0’: approx_x0, ‘sigma’: 28e3, ‘mu’: -8000., ‘beta’: 2.2,
} x = np.arange(-75e3, 105e3, 5000) y = emg(x, **exparams) print(np.array2string(np.round(x / 1000, 1).astype(‘i’))) print(np.array2string(np.round(y, 1))) # [-75 -70 -65 -60 -55 -50 -45 -40 -35 -30 -25 -20 -15 -10 -5 0 5 10 # 15 20 25 30 35 40 45 50 55 60 65 70 75 80 85 90 95 100] # [2.3 2.3 2.3 2.4 2.5 2.6 2.7 2.9 3.1 3.3 3.6 3.8 4.1 4.3 4.4 4.5 4.6 4.6 # 4.6 4.4 4.3 4.1 3.9 3.7 3.5 3.3 3.1 2.9 2.8 2.7 2.6 2.5 2.4 2.4 2.4 2.3]
- pyrsig.emiss.fitemg(vcds, us=None, vs=None, degrees=False, dx=1, nxplume=None, verbose=0)[source]¶
- Parameters:
vcds (xr.DataArray) – Vertical column densities 3d (t, y, x) where (x, y) must be square (x == y). Units seem to work best when mol/m2. The area unit must match the length unit of dx.
us (array-like) – 1d (t,) U component of wind in the x direction at center x/y
vs (array-like) – 1d (t,) V component of wind in the y direction at center x/y
dx (float) – edge length in units commensurate with vcds (typically m)
nxplume (int) – Number of cells to sum in the cross-plume direction after rotation when calculating the line density (mol/m) along the plume. Defaults to the half width minus 1.
degrees (bool) – Perform calculations of wind direction in degrees (default=True)
- Returns:
fitresult – vldhat: best fit function ws: wind speeds wd: wind directions wsmean: mean of wind speeds rots: rotated rasters
- Return type:
dict
- pyrsig.emiss.fitemg1d(vld, dx, verbose=0, addvldhat=True)[source]¶
- Parameters:
vld (np.array) – shape (n,) is the line density assuming focal point at n // 2
dx (float) – Width in length units (consistent with units of b, eg, b [=] mol/m2 then dx [=] m)
addvldhat (bool) – If True (default), add the fit line (vldhat) to the output
- Returns:
out – x, vld, params (from fitemg1d), and (optionally) vldhat
- Return type:
dict
Example
from pyrsig.emiss import fitemg1d from scipy.stats import exponnorm # Approximation of data in Goldberg[1] Figure 8a inset # g/y y/h * h molNOx/gNOx NO2/NOx [=] mol approx_alpha = 62e9 / 8760 * 1.7 / 46 / 1.32 approx_x0 = 20e3 # iteratively identified alpha = 198155 x0 = 20e3 sigma = 28e3 mu = -8000. beta = 2.2 x = np.arange(-75e3, 156e3, 5e3) f = exponnorm(K=approx_x0 / sigma, loc=mu, scale=sigma).pdf(x) y = approx_alpha * f + beta yerr = np.random.normal(size=y.size) * 0.1 yfit = fitemg1d(y, dx=1e3) print(np.array2string(np.round(x / 1000, 1).astype(‘i’))) print(np.array2string(np.round(y, 1))) print(np.array2string(np.round(yfit[‘vldhat’], 1))) # [-75 -70 -65 -60 -55 -50 -45 -40 -35 -30 -25 -20 -15 -10 -5 0 5 10 # 15 20 25 30 35 40 45 50 55 60 65 70 75 80 85 90 95 100 # 105 110 115 120 125 130 135 140 145 150 155] # [2.3 2.3 2.3 2.4 2.5 2.6 2.7 2.9 3.1 3.3 3.6 3.8 4.1 4.3 4.4 4.5 4.6 4.6 # 4.6 4.4 4.3 4.1 3.9 3.7 3.5 3.3 3.1 2.9 2.8 2.7 2.6 2.5 2.4 2.4 2.4 2.3 # 2.3 2.3 2.3 2.2 2.2 2.2 2.2 2.2 2.2 2.2 2.2] # [2.3 2.3 2.3 2.4 2.5 2.6 2.7 2.9 3.1 3.3 3.6 3.8 4.1 4.3 4.4 4.5 4.6 4.6 # 4.6 4.4 4.3 4.1 3.9 3.7 3.5 3.3 3.1 2.9 2.8 2.7 2.6 2.5 2.4 2.4 2.4 2.3 # 2.3 2.3 2.3 2.2 2.2 2.2 2.2 2.2 2.2 2.2 2.2]