Module gdess.data_source.models.e3sm.calculation
Expand source code
__all__ = ['calc_change_in_mass', 'calc_global_weighted_means',
'calc_time_integrated_fluxes', 'calc_var_deltas', 'calc_time_deltas',
'add_global_mean_vars']
import numpy as np
import xarray as xr
import logging
_logger = logging.getLogger(__name__)
def calc_change_in_mass(dataset: xr.Dataset,
varname='glmean_TMCO2_FFF', prefix='deltas_'
) -> xr.Dataset:
"""Change in mass of \\(CO_2\\) from timestep to timestep
using backwards difference - \\(\\Delta{mass_{CO_2}}\\)
Parameters
----------
dataset : ``xarray.Dataset``
varname : `str`
prefix : `str`
Notes
-----
.. math::
\\Delta \\texttt{glmean_TMCO2}_{t} = \\texttt{glmean_TMCO2}_{t} - \\texttt{glmean_TMCO2}_{t-1} \\forall t
Returns
-------
``xarray.Dataset``
"""
dataset[prefix + varname] = xr.DataArray(calc_var_deltas(dataset[varname]),
coords={'time': dataset['time']},
dims=['time'])
return dataset
def calc_global_weighted_means(dataset: xr.Dataset,
variable_list=None,
prefix='glmean_',
weighting_var='area_p',
averaging_dims='ncol'
) -> xr.Dataset:
"""Global means with weighting by area
Parameters
----------
dataset
variable_list
prefix
weighting_var
averaging_dims
Notes
-----
xarray has recently introduced a weighting method
(http://xarray.pydata.org/en/stable/examples/area_weighted_temperature.html).
The area of each grid cell for the ne4pg2/ne30pg2 grids is called “area_p”.
For the ne4/ne30 grids it is just called “area”. Not sure why they changed it.
.. math::
\\texttt{glmean_CO2var}_{t}= \\frac{\\sum_{i=1}^{nlat}\\sum_{j=1}^{nlon} \\texttt{CO2var}_{i,j,t} * \\texttt{area}_{i,j}}{\\sum_{i=1}^{nlat}\\sum_{j=1}^{nlon} \\texttt{area}_{i,j}}
\\forall t,
with\\,units: \\{kg/m^2\\}_t= & \\frac{\\sum_{i=1}^{nlat}\\sum_{j=1}^{nlon} \\{kg/{m^2}\\}_{i,j,t} * \\{m^2/m^2\\}_{i,j}}{\\sum_{i=1}^{nlat}\\sum_{j=1}^{nlon} \\{m^2/m^2\\}_{i,j}}
\\forall t.
We would need to multiply by the radius of Earth (\\(R^2_{E}\\) in units of \\(\\{m^2\\}\\))
to get to \\(kg\\) because `area` is in steradians rather than \\(m^2\\).
The above multiplication by `area` (\\(m^2/m^2\\)) is taken care of in the xarray.DataArray.weighted() method.
Returns
-------
``xarray.Dataset``
"""
dataset = add_global_mean_vars(dataset, variable_list=variable_list, prefix=prefix,
weighting_var=weighting_var, averaging_dims=averaging_dims)
return dataset
def calc_time_integrated_fluxes(dataset: xr.Dataset,
prefix: str = 'timeint_'
) -> xr.Dataset:
"""Time-integrated flux of \\(CO_2\\) from surface emissions and aircraft
\\(\\int{flux_{CO_2}}\\)
.. math::
\\int_{t-1}^{t} \\texttt{SFCO2} \\approx \\texttt{glmean_SFCO2}_{t} * \\quad (time_t - time_{t-1})
\\forall t,
with\\,units: \\{kg/m^2\\}_t= \\{kg/m^2/s\\}_t * \\quad \\{s\\}_{t}
\\forall t.
Parameters
----------
dataset : ``xarray.Dataset``
prefix : str
Returns
-------
``xarray.Dataset``
"""
dtime = calc_time_deltas(dataset)
#
dataset[prefix + 'SFCO2'] = xr.DataArray(dataset['glmean_SFCO2'] * dtime,
coords={'time': dataset['time']}, dims=['time'])
#
dataset[prefix + 'TAFCO2'] = xr.DataArray(dataset['glmean_TAFCO2'] * dtime,
coords={'time': dataset['time']}, dims=['time'])
#
dataset[prefix + 'TOTALFLUX'] = xr.DataArray(dataset[prefix + 'SFCO2'] + dataset[prefix + 'TAFCO2'],
coords={'time': dataset['time']}, dims=['time'])
return dataset
def calc_var_deltas(xr_da_: xr.DataArray
) -> np.ndarray:
"""Backward difference calculation
"""
return np.insert(np.diff(xr_da_), 0, 0)
def calc_time_deltas(xr_ds_: xr.Dataset
) -> xr.DataArray:
"""Time deltas in seconds
"""
seconds_per_day = 24 * 60 * 60
return (xr_ds_['time_bnds'].diff('nbnd') * seconds_per_day).astype('float').isel(nbnd=0).round()
def add_global_mean_vars(xr_ds_: xr.Dataset,
variable_list,
prefix='glmean_', weighting_var='area_p', averaging_dims=('ncol')
) -> xr.Dataset:
""" For each variable in the input list, we add an accompanying variable that represents a global mean
"""
for var in variable_list:
xr_ds_[prefix + var] = xr_ds_[var].weighted(xr_ds_[weighting_var]).mean(averaging_dims)
xr_ds_[prefix + var].attrs["units"] = xr_ds_[var].units
xr_ds_[prefix + var].attrs['long_name'] = xr_ds_[var].long_name + ' (globally averaged)'
return xr_ds_
def getPMID(hyam, hybm, P0, PS):
PMID = P0 * hyam + PS * hybm
PMID.attrs.update({'units': 'Pa',
'long_name': 'Pressure'})
return PMID
def getPINT(hyai, hybi, P0, PS):
PMID = P0 * hyai + PS * hybi
PMID.attrs.update({'units': 'Pa',
'long_name': 'Pressure at interface levels'})
return PMID
Functions
def add_global_mean_vars(xr_ds_: xarray.core.dataset.Dataset, variable_list, prefix='glmean_', weighting_var='area_p', averaging_dims='ncol') -> xarray.core.dataset.Dataset-
For each variable in the input list, we add an accompanying variable that represents a global mean
Expand source code
def add_global_mean_vars(xr_ds_: xr.Dataset, variable_list, prefix='glmean_', weighting_var='area_p', averaging_dims=('ncol') ) -> xr.Dataset: """ For each variable in the input list, we add an accompanying variable that represents a global mean """ for var in variable_list: xr_ds_[prefix + var] = xr_ds_[var].weighted(xr_ds_[weighting_var]).mean(averaging_dims) xr_ds_[prefix + var].attrs["units"] = xr_ds_[var].units xr_ds_[prefix + var].attrs['long_name'] = xr_ds_[var].long_name + ' (globally averaged)' return xr_ds_ def calc_change_in_mass(dataset: xarray.core.dataset.Dataset, varname='glmean_TMCO2_FFF', prefix='deltas_') -> xarray.core.dataset.Dataset-
Change in mass of CO_2 from timestep to timestep using backwards difference - \Delta{mass_{CO_2}}
Parameters
dataset:xarray.Datasetvarname:strprefix:str
Notes
\Delta \texttt{glmean_TMCO2}_{t} = \texttt{glmean_TMCO2}_{t} - \texttt{glmean_TMCO2}_{t-1} \forall t Returns
xarray.DatasetExpand source code
def calc_change_in_mass(dataset: xr.Dataset, varname='glmean_TMCO2_FFF', prefix='deltas_' ) -> xr.Dataset: """Change in mass of \\(CO_2\\) from timestep to timestep using backwards difference - \\(\\Delta{mass_{CO_2}}\\) Parameters ---------- dataset : ``xarray.Dataset`` varname : `str` prefix : `str` Notes ----- .. math:: \\Delta \\texttt{glmean_TMCO2}_{t} = \\texttt{glmean_TMCO2}_{t} - \\texttt{glmean_TMCO2}_{t-1} \\forall t Returns ------- ``xarray.Dataset`` """ dataset[prefix + varname] = xr.DataArray(calc_var_deltas(dataset[varname]), coords={'time': dataset['time']}, dims=['time']) return dataset def calc_global_weighted_means(dataset: xarray.core.dataset.Dataset, variable_list=None, prefix='glmean_', weighting_var='area_p', averaging_dims='ncol') -> xarray.core.dataset.Dataset-
Global means with weighting by area
Parameters
datasetvariable_listprefixweighting_varaveraging_dims
Notes
xarray has recently introduced a weighting method (http://xarray.pydata.org/en/stable/examples/area_weighted_temperature.html). The area of each grid cell for the ne4pg2/ne30pg2 grids is called “area_p”. For the ne4/ne30 grids it is just called “area”. Not sure why they changed it.
\texttt{glmean_CO2var}_{t}= \frac{\sum_{i=1}^{nlat}\sum_{j=1}^{nlon} \texttt{CO2var}_{i,j,t} * \texttt{area}_{i,j}}{\sum_{i=1}^{nlat}\sum_{j=1}^{nlon} \texttt{area}_{i,j}} \forall t, with\,units: \{kg/m^2\}_t= & \frac{\sum_{i=1}^{nlat}\sum_{j=1}^{nlon} \{kg/{m^2}\}_{i,j,t} * \{m^2/m^2\}_{i,j}}{\sum_{i=1}^{nlat}\sum_{j=1}^{nlon} \{m^2/m^2\}_{i,j}} \forall t. We would need to multiply by the radius of Earth ((R^2_{E}) in units of \{m^2\}) to get to kg because
areais in steradians rather than m^2. The above multiplication byarea((m^2/m^2)) is taken care of in the xarray.DataArray.weighted() method.Returns
xarray.DatasetExpand source code
def calc_global_weighted_means(dataset: xr.Dataset, variable_list=None, prefix='glmean_', weighting_var='area_p', averaging_dims='ncol' ) -> xr.Dataset: """Global means with weighting by area Parameters ---------- dataset variable_list prefix weighting_var averaging_dims Notes ----- xarray has recently introduced a weighting method (http://xarray.pydata.org/en/stable/examples/area_weighted_temperature.html). The area of each grid cell for the ne4pg2/ne30pg2 grids is called “area_p”. For the ne4/ne30 grids it is just called “area”. Not sure why they changed it. .. math:: \\texttt{glmean_CO2var}_{t}= \\frac{\\sum_{i=1}^{nlat}\\sum_{j=1}^{nlon} \\texttt{CO2var}_{i,j,t} * \\texttt{area}_{i,j}}{\\sum_{i=1}^{nlat}\\sum_{j=1}^{nlon} \\texttt{area}_{i,j}} \\forall t, with\\,units: \\{kg/m^2\\}_t= & \\frac{\\sum_{i=1}^{nlat}\\sum_{j=1}^{nlon} \\{kg/{m^2}\\}_{i,j,t} * \\{m^2/m^2\\}_{i,j}}{\\sum_{i=1}^{nlat}\\sum_{j=1}^{nlon} \\{m^2/m^2\\}_{i,j}} \\forall t. We would need to multiply by the radius of Earth (\\(R^2_{E}\\) in units of \\(\\{m^2\\}\\)) to get to \\(kg\\) because `area` is in steradians rather than \\(m^2\\). The above multiplication by `area` (\\(m^2/m^2\\)) is taken care of in the xarray.DataArray.weighted() method. Returns ------- ``xarray.Dataset`` """ dataset = add_global_mean_vars(dataset, variable_list=variable_list, prefix=prefix, weighting_var=weighting_var, averaging_dims=averaging_dims) return dataset def calc_time_deltas(xr_ds_: xarray.core.dataset.Dataset) -> xarray.core.dataarray.DataArray-
Time deltas in seconds
Expand source code
def calc_time_deltas(xr_ds_: xr.Dataset ) -> xr.DataArray: """Time deltas in seconds """ seconds_per_day = 24 * 60 * 60 return (xr_ds_['time_bnds'].diff('nbnd') * seconds_per_day).astype('float').isel(nbnd=0).round() def calc_time_integrated_fluxes(dataset: xarray.core.dataset.Dataset, prefix: str = 'timeint_') -> xarray.core.dataset.Dataset-
Time-integrated flux of CO_2 from surface emissions and aircraft \int{flux_{CO_2}}
\int_{t-1}^{t} \texttt{SFCO2} \approx \texttt{glmean_SFCO2}_{t} * \quad (time_t - time_{t-1}) \forall t, with\,units: \{kg/m^2\}_t= \{kg/m^2/s\}_t * \quad \{s\}_{t} \forall t. Parameters
dataset:xarray.Datasetprefix:str
Returns
xarray.DatasetExpand source code
def calc_time_integrated_fluxes(dataset: xr.Dataset, prefix: str = 'timeint_' ) -> xr.Dataset: """Time-integrated flux of \\(CO_2\\) from surface emissions and aircraft \\(\\int{flux_{CO_2}}\\) .. math:: \\int_{t-1}^{t} \\texttt{SFCO2} \\approx \\texttt{glmean_SFCO2}_{t} * \\quad (time_t - time_{t-1}) \\forall t, with\\,units: \\{kg/m^2\\}_t= \\{kg/m^2/s\\}_t * \\quad \\{s\\}_{t} \\forall t. Parameters ---------- dataset : ``xarray.Dataset`` prefix : str Returns ------- ``xarray.Dataset`` """ dtime = calc_time_deltas(dataset) # dataset[prefix + 'SFCO2'] = xr.DataArray(dataset['glmean_SFCO2'] * dtime, coords={'time': dataset['time']}, dims=['time']) # dataset[prefix + 'TAFCO2'] = xr.DataArray(dataset['glmean_TAFCO2'] * dtime, coords={'time': dataset['time']}, dims=['time']) # dataset[prefix + 'TOTALFLUX'] = xr.DataArray(dataset[prefix + 'SFCO2'] + dataset[prefix + 'TAFCO2'], coords={'time': dataset['time']}, dims=['time']) return dataset def calc_var_deltas(xr_da_: xarray.core.dataarray.DataArray) -> numpy.ndarray-
Backward difference calculation
Expand source code
def calc_var_deltas(xr_da_: xr.DataArray ) -> np.ndarray: """Backward difference calculation """ return np.insert(np.diff(xr_da_), 0, 0)