Atmosphere¶
Atmospheric physics on CF datasets. The design rule still holds: only
true physics lives here; anything domain-agnostic belongs in
cf. Trace-gas (methane) physics sits under
xrops.atm.gas.ch4.
WRF¶
open_wrfout turns a WRF-ARW wrfout file into a CF Dataset on
(time, level, y, x): the Times char rows (or XTIME minutes) become a
datetime64[s] axis, U / V / W are destaggered to mass points
(U / V rotated from grid- to earth-relative when the file carries
COSALPHA / SINALPHA), and the split base + perturbation fields are
recombined,
Everything stays lazy, so chunks={"time": 1} keeps the file dask backed.
atm
¶
Atmospheric physics operators.
Layer-0 primitives are implemented in :mod:xrops.atm._src and
re-exported here.
Content:
open_wrfout: WRF-ARWwrfout→ CF Dataset on(time, level, y, x)(time decode, destagger, physical temperature / pressure, height above ground), with thedestagger/wrf_time/wrf_wind/wrf_height_agl/wrf_temperaturehelpers it is built from.- Wind diagnostics:
wind_speed,wind_direction(meteorological "from" bearing by default) and their inversewind_components. - Vertical-column diagnostics:
column_integral(trapezoid or cell-width sum),hypsometric_height(pressure levels → geopotential height) andpbl_height_bulk_richardson. - Layer-1
Operatorwrappers (:mod:xrops.atm.operators), all re-exported here.
Trace-gas physics lives under :mod:xrops.atm.gas. Potential
temperature is still planned (see docs/design/).
open_wrfout
¶
open_wrfout(path: str | Path, *, times: slice | None = None, variables: str | Sequence[str] | None = None, chunks: Mapping[str, int] | None = None) -> Dataset
Open a wrfout file as a CF-conformant Dataset.
Returns dims (time, level, y, x) with:
- coords:
time(datetime64[s]),x/y(metres from the south-west mass point, fromDX/DY),level(int index),z_agl(time, level, y, x)(m above ground), and 2-Dlon/latfromXLONG/XLATwhen present. - data_vars (all on mass points):
u,v(m s⁻¹, destaggered and rotated to earth-relative whenCOSALPHA/SINALPHAare in the file — see :func:wrf_wind),w(m s⁻¹, destaggered),temperature(K),pressure(Pa),pbl_height(m, fromPBLH),terrain(m, fromHGT), plus any raw variable named invariables(dims renamed, otherwise untouched). - attrs:
DX,DY,MAP_PROJ,CEN_LAT,CEN_LON,TRUELAT1/2,STAND_LONcopied through for CRS work.
HGT, XLONG and XLAT lose their time axis only when they
are the same at every step; on a moving nest they keep it. CF
standard_name / units are stamped via
:func:xrproducts.apply_cf_attrs. Nothing is materialised, so
chunks={"time": 1} keeps every variable dask backed. The returned
Dataset owns the file handle: closing it (or leaving a with block)
closes the file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str | Path
|
|
required |
times
|
slice | None
|
Optional |
None
|
variables
|
str | Sequence[str] | None
|
Raw WRF variable name(s) to pass through (e.g.
|
None
|
chunks
|
Mapping[str, int] | None
|
Dask chunks keyed by the output dimension names. |
None
|
Returns:
| Type | Description |
|---|---|
Dataset
|
The CF Dataset. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If no time axis can be built (see :func: |
KeyError
|
If a name in |
Source code in packages/xrtoolz-ops/src/xrops/atm/_src/wrf.py
289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 | |
destagger
¶
Average a face-staggered variable onto cell centres along dim.
out[..., i, ...] = 0.5 * (da[..., i, ...] + da[..., i + 1, ...]), so
the output has da.sizes[dim] - 1 entries along new_dim. Numeric
coordinates carrying dim are averaged the same way (non-numeric ones
are dropped); other coordinates and attrs are preserved. Exact for
fields linear in the staggered coordinate.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
da
|
DataArray
|
Staggered variable (eager or dask backed; stays lazy). |
required |
dim
|
str
|
Staggered dimension to average over. |
required |
new_dim
|
str | None
|
Name of the output dimension; defaults to |
None
|
Returns:
| Type | Description |
|---|---|
DataArray
|
The cell-centred variable. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in packages/xrtoolz-ops/src/xrops/atm/_src/wrf.py
wrf_time
¶
Time axis of a wrfout Dataset as datetime64[s].
Decodes the Times char rows (YYYY-MM-DD_HH:MM:SS) when present;
otherwise uses XTIME — raw minutes since the SIMULATION_START_DATE
global attribute, or datetimes if a caller already decoded it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ds
|
Dataset
|
Raw |
required |
Returns:
| Type | Description |
|---|---|
DataArray
|
1-D |
DataArray
|
time dimension. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If neither |
Source code in packages/xrtoolz-ops/src/xrops/atm/_src/wrf.py
wrf_wind
¶
Horizontal wind on mass points, earth-relative where possible.
U / V are destaggered onto mass points. When the file carries
the map-rotation fields COSALPHA / SINALPHA the components are
rotated from grid-relative to earth-relative,
u_e = u cos α − v sin α, v_e = v cos α + u sin α, and stamped
with the CF eastward_wind / northward_wind names. Otherwise the
grid-relative components are returned with no standard_name and the
attr grid_relative = "true".
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ds
|
Dataset
|
Raw |
required |
Returns:
| Type | Description |
|---|---|
tuple[DataArray, DataArray]
|
|
Source code in packages/xrtoolz-ops/src/xrops/atm/_src/wrf.py
wrf_height_agl
¶
Height above ground on mass levels.
z_stag = (PH + PHB) / GRAVITY on the staggered levels, averaged to
mass levels and reduced by the terrain height:
z_agl = 0.5 * (z_stag[k] + z_stag[k + 1]) - HGT. HGT may carry a
time axis or not.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ds
|
Dataset
|
Raw |
required |
Returns:
| Type | Description |
|---|---|
DataArray
|
|
Source code in packages/xrtoolz-ops/src/xrops/atm/_src/wrf.py
wrf_temperature
¶
Air temperature from WRF's perturbation potential temperature.
T = (T' + THETA_BASE) * ((P + PB) / P_REFERENCE) ** KAPPA [K].
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ds
|
Dataset
|
Raw |
required |
Returns:
| Type | Description |
|---|---|
DataArray
|
Air temperature on mass points [K]. |
Source code in packages/xrtoolz-ops/src/xrops/atm/_src/wrf.py
Met diagnostics¶
Wind in the meteorological convention (bearing the wind blows from, degrees clockwise from north),
the column integral (trapezoid on the coordinate, or \(\sum_k f_k\,\Delta z_k\) with cell widths from the coordinate), the hypsometric equation \(z_{k+1}=z_k+\frac{R_d\,\bar T_{v,k}}{g}\ln\frac{p_k}{p_{k+1}}\), and the bulk-Richardson boundary-layer height \(Ri_b(z)=\frac{g\,(\theta_v-\theta_{v,s})(z-z_s)}{\theta_{v,s}\,(u^2+v^2)}\).
atm
¶
Atmospheric physics operators.
Layer-0 primitives are implemented in :mod:xrops.atm._src and
re-exported here.
Content:
open_wrfout: WRF-ARWwrfout→ CF Dataset on(time, level, y, x)(time decode, destagger, physical temperature / pressure, height above ground), with thedestagger/wrf_time/wrf_wind/wrf_height_agl/wrf_temperaturehelpers it is built from.- Wind diagnostics:
wind_speed,wind_direction(meteorological "from" bearing by default) and their inversewind_components. - Vertical-column diagnostics:
column_integral(trapezoid or cell-width sum),hypsometric_height(pressure levels → geopotential height) andpbl_height_bulk_richardson. - Layer-1
Operatorwrappers (:mod:xrops.atm.operators), all re-exported here.
Trace-gas physics lives under :mod:xrops.atm.gas. Potential
temperature is still planned (see docs/design/).
WindSpeed
¶
Bases: Operator
Horizontal wind speed sqrt(u² + v²).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
u
|
str
|
Name of the eastward wind component. |
'u'
|
v
|
str
|
Name of the northward wind component. |
'v'
|
name
|
str
|
Name of the output variable. |
'wind_speed'
|
Returns:
| Type | Description |
|---|---|
|
The input dataset with |
Source code in packages/xrtoolz-ops/src/xrops/atm/operators.py
WindDirection
¶
WindDirection(u: str = 'u', v: str = 'v', name: str = 'wind_direction', convention: Literal['from', 'to'] = 'from')
Bases: Operator
Wind direction in degrees clockwise from north.
Meteorological "from" bearing by default,
θ = (270° − atan2(v, u)) mod 360°; convention="to" adds 180°.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
u
|
str
|
Name of the eastward wind component. |
'u'
|
v
|
str
|
Name of the northward wind component. |
'v'
|
name
|
str
|
Name of the output variable. |
'wind_direction'
|
convention
|
Literal['from', 'to']
|
|
'from'
|
Returns:
| Type | Description |
|---|---|
|
The input dataset with |
Source code in packages/xrtoolz-ops/src/xrops/atm/operators.py
WindComponents
¶
WindComponents(speed: str = 'wind_speed', direction: str = 'wind_direction', convention: Literal['from', 'to'] = 'from', u: str = 'u', v: str = 'v')
Bases: Operator
Eastward / northward components from speed and direction.
Inverse of :class:WindSpeed + :class:WindDirection:
u = −|V| sin θ, v = −|V| cos θ for a "from" bearing.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
speed
|
str
|
Name of the wind-speed variable. |
'wind_speed'
|
direction
|
str
|
Name of the direction variable (degrees from north). |
'wind_direction'
|
convention
|
Literal['from', 'to']
|
Whether |
'from'
|
u
|
str
|
Name of the eastward output component. |
'u'
|
v
|
str
|
Name of the northward output component. |
'v'
|
Returns:
| Type | Description |
|---|---|
|
The input dataset with |
Source code in packages/xrtoolz-ops/src/xrops/atm/operators.py
ColumnIntegral
¶
ColumnIntegral(variable: str, *, dim: str = 'z', coord: str | None = None, method: Literal['trapezoid', 'sum'] = 'trapezoid', name: str | None = None)
Bases: Operator
Integrate a variable along its vertical coordinate.
"trapezoid" applies the trapezoid rule on the coordinate values;
"sum" is Σ f_k Δz_k with cell widths from the coordinate. See
:func:xrops.atm.column_integral.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
variable
|
str
|
Name of the variable to integrate. |
required |
dim
|
str
|
Vertical dimension. |
'z'
|
coord
|
str | None
|
Name of the coordinate locating the levels, or |
None
|
method
|
Literal['trapezoid', 'sum']
|
|
'trapezoid'
|
name
|
str | None
|
Name of the output variable; defaults to
|
None
|
Returns:
| Type | Description |
|---|---|
|
The input dataset with |
Source code in packages/xrtoolz-ops/src/xrops/atm/operators.py
HypsometricHeight
¶
HypsometricHeight(pressure: str = 'pressure', temperature: str = 'temperature', specific_humidity: str | None = None, surface_pressure: str = 'sp', surface_height: str | None = None, level: str = 'level', name: str = 'height')
Bases: Operator
Geopotential height of pressure levels (hypsometric equation).
z_{k+1} = z_k + (R_d T̄_v / g) ln(p_k / p_{k+1}) integrated upward
from the surface. See :func:xrops.atm.hypsometric_height.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
pressure
|
str
|
Pressure per level. |
'pressure'
|
temperature
|
str
|
Air temperature per level [K]. |
'temperature'
|
specific_humidity
|
str | None
|
Optional specific humidity for |
None
|
surface_pressure
|
str
|
Surface pressure. |
'sp'
|
surface_height
|
str | None
|
Optional terrain height added to every level. |
None
|
level
|
str
|
Vertical dimension. |
'level'
|
name
|
str
|
Name of the output variable. |
'height'
|
Returns:
| Type | Description |
|---|---|
|
The input dataset with |
Source code in packages/xrtoolz-ops/src/xrops/atm/operators.py
PBLHeightBulkRichardson
¶
PBLHeightBulkRichardson(theta_v: str, u: str = 'u', v: str = 'v', height: str = 'z_agl', ri_crit: float = 0.25, level: str = 'level', name: str = 'pbl_height')
Bases: Operator
Boundary-layer height from the bulk Richardson number.
First height where Ri_b = g (θ_v − θ_{v,s}) (z − z_s) / (θ_{v,s}
(u² + v²)) reaches ri_crit, interpolated between levels; NaN
when no level crosses. See
:func:xrops.atm.pbl_height_bulk_richardson.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
theta_v
|
str
|
Virtual potential temperature per level [K]. |
required |
u
|
str
|
Eastward wind per level. |
'u'
|
v
|
str
|
Northward wind per level. |
'v'
|
height
|
str
|
Height above ground per level [m]. |
'z_agl'
|
ri_crit
|
float
|
Critical bulk Richardson number. |
0.25
|
level
|
str
|
Vertical dimension. |
'level'
|
name
|
str
|
Name of the output variable. |
'pbl_height'
|
Returns:
| Type | Description |
|---|---|
|
The input dataset with |
Source code in packages/xrtoolz-ops/src/xrops/atm/operators.py
wind_speed
¶
Horizontal wind speed |V| = sqrt(u² + v²).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ds
|
Dataset
|
Dataset holding the eastward and northward wind components. |
required |
u
|
str
|
Name of the eastward component. |
'u'
|
v
|
str
|
Name of the northward component. |
'v'
|
name
|
str
|
Name of the output variable. |
'wind_speed'
|
Returns:
| Type | Description |
|---|---|
Dataset
|
|
Dataset
|
components). |
Source code in packages/xrtoolz-ops/src/xrops/atm/_src/wind.py
wind_direction
¶
wind_direction(ds: Dataset, *, u: str = 'u', v: str = 'v', name: str = 'wind_direction', convention: Literal['from', 'to'] = 'from') -> Dataset
Wind direction in degrees clockwise from north.
θ_from = (270° − atan2(v, u)·180/π) mod 360° is the bearing the wind
blows from (meteorological convention); convention="to" returns
θ_to = (θ_from + 180°) mod 360°. Calm air (u = v = 0) maps to
270° under "from" (atan2(0, 0) = 0).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ds
|
Dataset
|
Dataset holding the wind components. |
required |
u
|
str
|
Name of the eastward component. |
'u'
|
v
|
str
|
Name of the northward component. |
'v'
|
name
|
str
|
Name of the output variable. |
'wind_direction'
|
convention
|
Literal['from', 'to']
|
|
'from'
|
Returns:
| Type | Description |
|---|---|
Dataset
|
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in packages/xrtoolz-ops/src/xrops/atm/_src/wind.py
wind_components
¶
wind_components(ds: Dataset, *, speed: str = 'wind_speed', direction: str = 'wind_direction', convention: Literal['from', 'to'] = 'from', u: str = 'u', v: str = 'v') -> Dataset
Eastward / northward components from speed and direction.
Inverse of :func:wind_speed + :func:wind_direction. With the
meteorological "from" bearing θ:
u = −|V| sin θ, v = −|V| cos θ; under "to" the signs flip.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ds
|
Dataset
|
Dataset holding the speed and direction. |
required |
speed
|
str
|
Name of the wind-speed variable. |
'wind_speed'
|
direction
|
str
|
Name of the direction variable (degrees from north). |
'wind_direction'
|
convention
|
Literal['from', 'to']
|
Whether |
'from'
|
u
|
str
|
Name of the eastward output component. |
'u'
|
v
|
str
|
Name of the northward output component. |
'v'
|
Returns:
| Type | Description |
|---|---|
Dataset
|
|
Dataset
|
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in packages/xrtoolz-ops/src/xrops/atm/_src/wind.py
column_integral
¶
column_integral(da: DataArray, *, dim: str = 'z', coord: str | DataArray | None = None, method: Literal['trapezoid', 'sum'] = 'trapezoid') -> DataArray
Integrate da along the vertical coordinate.
method="trapezoid" applies the trapezoid rule on the coordinate
values (exact for fields linear in z, the right choice for
endpoint-inclusive level grids):
∫ f dz ≈ Σ_k ½ (f_k + f_{k+1}) (z_{k+1} − z_k)
method="sum" is the cell-centred Riemann sum Σ_k f_k Δz_k with
Δz_k the cell width around level k (half-way to each neighbour,
half a spacing at the ends). Both methods give c (z_1 − z_0) for a
uniform field c on [z_0, z_1] — unlike sum · dz with a
constant dz, which over-counts an endpoint-inclusive grid by
n_z / (n_z − 1). The sign follows the coordinate's orientation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
da
|
DataArray
|
Field to integrate (any dims, must include |
required |
dim
|
str
|
Vertical dimension. |
'z'
|
coord
|
str | DataArray | None
|
Coordinate giving the position of each level: |
None
|
method
|
Literal['trapezoid', 'sum']
|
|
'trapezoid'
|
Returns:
| Type | Description |
|---|---|
DataArray
|
|
DataArray
|
units. A NaN at any level makes the whole column NaN. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in packages/xrtoolz-ops/src/xrops/atm/_src/vertical.py
hypsometric_height
¶
hypsometric_height(ds: Dataset, *, pressure: str = 'pressure', temperature: str = 'temperature', specific_humidity: str | None = None, surface_pressure: str = 'sp', surface_height: str | None = None, level: str = 'level', name: str = 'height') -> Dataset
Geopotential height of pressure levels from the hypsometric equation.
Integrates layer by layer upward from the surface with the virtual
temperature T_v = T (1 + 0.61 q):
z_{k+1} = z_k + (R_d T̄_{v,k} / g) ln(p_k / p_{k+1})
where T̄_{v,k} is the mean of the two bounding levels. The first
level is anchored to the surface, z_0 = z_s + (R_d T_{v,0} / g)
ln(p_s / p_0), using that level's virtual temperature for the
surface layer. For an isothermal column this reduces to
z = (R_d T / g) ln(p_s / p) exactly. Levels with p > p_s get
negative heights (extrapolated below ground). A NaN temperature at a
level invalidates that level and every level above it.
pressure and surface_pressure must share units (only ratios
enter). A 1-D pressure coordinate may be ordered either way; a
multi-dimensional pressure field must be ordered surface first.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ds
|
Dataset
|
Dataset with the pressure, temperature and surface-pressure
fields ( |
required |
pressure
|
str
|
Pressure per level. |
'pressure'
|
temperature
|
str
|
Air temperature per level [K]. |
'temperature'
|
specific_humidity
|
str | None
|
Optional specific humidity [kg kg⁻¹] for the
virtual-temperature correction; |
None
|
surface_pressure
|
str
|
Surface pressure (no |
'sp'
|
surface_height
|
str | None
|
Optional terrain height [m] added to every level;
|
None
|
level
|
str
|
Vertical dimension. |
'level'
|
name
|
str
|
Name of the output variable. |
'height'
|
Returns:
| Type | Description |
|---|---|
Dataset
|
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in packages/xrtoolz-ops/src/xrops/atm/_src/vertical.py
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 | |
pbl_height_bulk_richardson
¶
pbl_height_bulk_richardson(ds: Dataset, *, theta_v: str, u: str = 'u', v: str = 'v', height: str = 'z_agl', ri_crit: float = 0.25, level: str = 'level', name: str = 'pbl_height') -> Dataset
Boundary-layer height from the bulk Richardson number.
Vogelezang & Holtslag (1996) form without the surface-friction term,
with the surface values taken from the lowest level s:
Ri_b(z) = g (θ_v(z) − θ_{v,s}) (z − z_s)
/ (θ_{v,s} ((u(z) − u_s)² + (v(z) − v_s)²))
h is the first height (scanning upward from the level above the
surface) where Ri_b ≥ Ri_crit, linearly interpolated between the
bracketing levels. Columns that never reach Ri_crit get NaN rather
than the top level. The surface level itself is assigned Ri_b = 0;
a level aloft with no shear relative to the surface (u = u_s,
v = v_s) takes the sign of the numerator: +∞ when stably
stratified (so h stops at the level below it), −∞ when
unstable (never a crossing) and 0 when θ_v = θ_{v,s}.
The vertical ordering is read from height: profiles may be surface
first or top first (they are flipped internally), but every column must
share one orientation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ds
|
Dataset
|
Dataset with virtual potential temperature, wind components and height per level. |
required |
theta_v
|
str
|
Virtual potential temperature [K]. |
required |
u
|
str
|
Eastward wind [m s⁻¹]. |
'u'
|
v
|
str
|
Northward wind [m s⁻¹]. |
'v'
|
height
|
str
|
Height above ground per level [m] (may be a coordinate, 1-D or per column). |
'z_agl'
|
ri_crit
|
float
|
Critical bulk Richardson number. |
0.25
|
level
|
str
|
Vertical dimension. |
'level'
|
name
|
str
|
Name of the output variable. |
'pbl_height'
|
Returns:
| Type | Description |
|---|---|
Dataset
|
|
Dataset
|
|
Dataset
|
reduced away. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in packages/xrtoolz-ops/src/xrops/atm/_src/vertical.py
229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 | |
Methane columns¶
Column averaging kernel in the TROPOMI / OCO convention, \(\hat y=\mathbf h^\top\mathbf x_a+\sum_l h_l A_l (x_l-x_{a,l})\), the hydrostatic dry-air column \(N_\text{dry}=\frac{N_A}{g\,M_\text{dry}}\int_0^{p_s}(1-q)\,dp\), the mixing-ratio column \(\Omega=\frac{N_A}{g\,M_\text{dry}}\int\chi\,(1-q)\,dp\), and the single-layer column mass to \(\Delta\chi\) conversion \(\Delta\chi=\frac{m\,N_A/M_\text{gas}}{n_\text{air}\,L}\) with \(n_\text{air}=p/(k_B T)\).
ch4
¶
Methane-specific physics operators.
Layer-0 primitives are implemented in :mod:xrops.atm.gas.ch4._src
and re-exported here.
Content:
apply_column_averaging_kernel: TROPOMI / OCO-style smoothing of a model profile with a column averaging kernel and pressure weights.dry_air_column: dry-air column number density from surface pressure (and optional total column water vapour).mixing_ratio_to_column: dry-air mole-fraction profile → column number density;column_mass_to_delta_vmr: column mass enhancement → mixing-ratio enhancement over a well-mixed layer.- Layer-1
Operatorwrappers (:mod:xrops.atm.gas.ch4.operators), all re-exported here.
ApplyColumnAveragingKernel
¶
ApplyColumnAveragingKernel(profile: str, prior: str, averaging_kernel: str, pressure_weights: str, level: str = 'layer', name: str = 'xch4_smoothed')
Bases: Operator
Smooth a model profile with a satellite column averaging kernel.
ŷ = hᵀ x_a + Σ_l h_l A_l (x_l − x_{a,l}). See
:func:xrops.atm.gas.ch4.apply_column_averaging_kernel.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
profile
|
str
|
Model profile |
required |
prior
|
str
|
Retrieval prior |
required |
averaging_kernel
|
str
|
Column averaging kernel |
required |
pressure_weights
|
str
|
Pressure weights |
required |
level
|
str
|
Layer dimension. |
'layer'
|
name
|
str
|
Name of the output variable. |
'xch4_smoothed'
|
Returns:
| Type | Description |
|---|---|
|
The input dataset with |
Source code in packages/xrtoolz-ops/src/xrops/atm/gas/ch4/operators.py
DryAirColumn
¶
DryAirColumn(surface_pressure: str = 'sp', water_vapour_column: str | None = None, name: str = 'dry_air_column')
Bases: Operator
Dry-air column number density N_A (p_s / g − W) / M_dry.
See :func:xrops.atm.gas.ch4.dry_air_column.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
surface_pressure
|
str
|
Surface pressure [Pa]. |
'sp'
|
water_vapour_column
|
str | None
|
Optional total column water vapour [kg m⁻²]. |
None
|
name
|
str
|
Name of the output variable. |
'dry_air_column'
|
Returns:
| Type | Description |
|---|---|
|
The input dataset with |
Source code in packages/xrtoolz-ops/src/xrops/atm/gas/ch4/operators.py
MixingRatioToColumn
¶
MixingRatioToColumn(vmr: str, pressure: str = 'pressure', specific_humidity: str | None = None, level: str = 'level', name: str = 'column')
Bases: Operator
Column number density Ω = N_A / (g M_dry) ∫ χ (1 − q) dp.
See :func:xrops.atm.gas.ch4.mixing_ratio_to_column.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
vmr
|
str
|
Dry-air mole fraction per level. |
required |
pressure
|
str
|
Pressure per level [Pa]. |
'pressure'
|
specific_humidity
|
str | None
|
Optional specific humidity per level. |
None
|
level
|
str
|
Vertical dimension. |
'level'
|
name
|
str
|
Name of the output variable. |
'column'
|
Returns:
| Type | Description |
|---|---|
|
The input dataset with |
Source code in packages/xrtoolz-ops/src/xrops/atm/gas/ch4/operators.py
apply_column_averaging_kernel
¶
apply_column_averaging_kernel(ds: Dataset, *, profile: str, prior: str, averaging_kernel: str, pressure_weights: str, level: str = 'layer', name: str = 'xch4_smoothed') -> Dataset
Smooth a model profile with a satellite column averaging kernel.
TROPOMI / OCO convention, with pressure weights h summing to one,
column averaging kernel A per layer and retrieval prior x_a:
ŷ = hᵀ x_a + Σ_l h_l A_l (x_l − x_{a,l})
A ≡ 1 reduces to the column average hᵀ x; x = x_a returns
the prior column hᵀ x_a.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ds
|
Dataset
|
Dataset with the four per-layer fields. |
required |
profile
|
str
|
Model profile |
required |
prior
|
str
|
Retrieval prior |
required |
averaging_kernel
|
str
|
Column averaging kernel |
required |
pressure_weights
|
str
|
Pressure weights |
required |
level
|
str
|
Layer dimension. |
'layer'
|
name
|
str
|
Name of the output variable. |
'xch4_smoothed'
|
Returns:
| Type | Description |
|---|---|
Dataset
|
|
Dataset
|
|
Dataset
|
|
Dataset
|
(e.g. a QA-masked pixel) makes the result NaN. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in packages/xrtoolz-ops/src/xrops/atm/gas/ch4/_src/column.py
dry_air_column
¶
dry_air_column(ds: Dataset, *, surface_pressure: str = 'sp', water_vapour_column: str | None = None, name: str = 'dry_air_column') -> Dataset
Dry-air column number density from surface pressure.
Hydrostatic balance gives the total-air column as p_s / g kg m⁻²;
removing the water-vapour mass column W (total column water vapour,
kg m⁻²) and converting to molecules with N_A / M_dry:
N_dry = N_A / (g M_dry) ∫₀^{p_s} (1 − q) dp = N_A (p_s / g − W) / M_dry
With W = 0 and p_s = 10⁵ Pa this is ≈ 2.12 × 10²⁹ m⁻².
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ds
|
Dataset
|
Dataset with the surface pressure (and optional water column). |
required |
surface_pressure
|
str
|
Surface pressure [Pa]. |
'sp'
|
water_vapour_column
|
str | None
|
Optional total column water vapour [kg m⁻²]
(CF |
None
|
name
|
str
|
Name of the output variable. |
'dry_air_column'
|
Returns:
| Type | Description |
|---|---|
Dataset
|
|
Source code in packages/xrtoolz-ops/src/xrops/atm/gas/ch4/_src/column.py
mixing_ratio_to_column
¶
mixing_ratio_to_column(ds: Dataset, *, vmr: str, pressure: str = 'pressure', specific_humidity: str | None = None, level: str = 'level', name: str = 'column') -> Dataset
Column number density of a gas from its dry-air mole-fraction profile.
Trapezoid integral over the pressure levels provided (hydrostatic):
Ω = N_A / (g M_dry) ∫ χ (1 − q) dp
so a uniform profile χ ≡ c over the full column gives
Ω = c N_dry. The integral spans the levels present in ds only —
include p = 0 and p = p_s levels to cover the whole column. The
result is orientation-independent (absolute value).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ds
|
Dataset
|
Dataset with the mole-fraction profile and pressure per level. |
required |
vmr
|
str
|
Dry-air mole fraction |
required |
pressure
|
str
|
Pressure per level [Pa]; may be the |
'pressure'
|
specific_humidity
|
str | None
|
Optional specific humidity [kg kg⁻¹] per level;
|
None
|
level
|
str
|
Vertical dimension. |
'level'
|
name
|
str
|
Name of the output variable. |
'column'
|
Returns:
| Type | Description |
|---|---|
Dataset
|
|
Dataset
|
|
Dataset
|
the |
Source code in packages/xrtoolz-ops/src/xrops/atm/gas/ch4/_src/column.py
column_mass_to_delta_vmr
¶
column_mass_to_delta_vmr(column_mass: DataArray, *, pressure_pa: float | DataArray, temperature_k: float | DataArray, path_length_m: float | DataArray, molar_mass_kg_mol: float = M_CH4) -> DataArray
Column mass enhancement → volume-mixing-ratio enhancement.
Spreads the column mass m [kg m⁻²] over a single well-mixed layer
of length L at the ideal-gas number density n_air = p / (k_B T):
Δχ = (m N_A / M_gas) / (n_air L)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
column_mass
|
DataArray
|
Column mass enhancement [kg m⁻²]. |
required |
pressure_pa
|
float | DataArray
|
Layer pressure [Pa]. |
required |
temperature_k
|
float | DataArray
|
Layer temperature [K]. |
required |
path_length_m
|
float | DataArray
|
Vertical path length |
required |
molar_mass_kg_mol
|
float
|
Molar mass of the gas [kg mol⁻¹] (methane). |
M_CH4
|
Returns:
| Type | Description |
|---|---|
DataArray
|
Dimensionless mixing-ratio enhancement, same shape as |
DataArray
|
|