Beispiel #1
0
def get_mfc_box(mfcfiles, precipfiles, evapfiles, years, nroll, lat1, lat2,
                lon1, lon2):
    """Return daily tseries MFC, precip and evap averaged over lat-lon box.
    """
    subset_dict = {'lat' : (lat1, lat2), 'lon' : (lon1, lon2)}

    databox = {}
    if mfcfiles is not None:
        mfc = atm.combine_daily_years('MFC', mfcfiles, years, yearname='year',
                                       subset_dict=subset_dict)
        databox['MFC'] = mfc
    if precipfiles is not None:
        pcp = atm.combine_daily_years('PRECTOT', precipfiles, years, yearname='year',
                                      subset_dict=subset_dict)
        databox['PCP'] = pcp
    if evapfiles is not None:
        evap = atm.combine_daily_years('EVAP', evapfiles, years, yearname='year',
                                        subset_dict=subset_dict)
        databox['EVAP'] = evap


    nms = databox.keys()
    for nm in nms:
        var = databox[nm]
        var = atm.precip_convert(var, var.attrs['units'], 'mm/day')
        var = atm.mean_over_geobox(var, lat1, lat2, lon1, lon2)
        databox[nm + '_UNSM'] = var
        databox[nm + '_ACC'] = np.cumsum(var, axis=1)
        if nroll is None:
            databox[nm] = var
        else:
            databox[nm] = atm.rolling_mean(var, nroll, axis=-1, center=True)

    tseries = xray.Dataset(databox)
    return tseries
Beispiel #2
0
def get_onset_indices(onset_nm, datafiles, years, data=None):
    """Return monsoon onset/retreat/length indices.
    """

    # Options for CHP_MFC and CHP_PCP
    lat1, lat2 = 10, 30
    lon1, lon2 = 60, 100
    chp_opts = [None, lat1, lat2, lon1, lon2]

    if onset_nm == 'HOWI':
        maxbreak = 10
        npts = 100
        ds = atm.combine_daily_years(['uq_int', 'vq_int'], datafiles, years,
                                     yearname='year')
        index, _ = indices.onset_HOWI(ds['uq_int'], ds['vq_int'], npts,
                                      maxbreak=maxbreak)
        index.attrs['title'] = 'HOWI (N=%d)' % npts
    elif onset_nm == 'CHP_MFC':
        if data is None:
            tseries = get_mfc_box(datafiles, None, None, years, *chp_opts)
            data = tseries['MFC_ACC']
            index['ts_daily'] = tseries['MFC']
        index = indices.onset_changepoint(data)
    elif onset_nm == 'CHP_PCP':
        if data is None:
            tseries = get_mfc_box(None, datafiles, None, years, *chp_opts)
            data = tseries['PCP_ACC']
        index = indices.onset_changepoint(data)
        index['ts_daily'] = tseries['PCP']

    # Monsoon retreat and length indices
    if 'retreat' in index:
        index['length'] = index['retreat'] - index['onset']
    else:
        index['retreat'] = np.nan * index['onset']
        index['length'] = np.nan * index['onset']

    return index
import numpy as np
import xray
import pandas as pd
import matplotlib.pyplot as plt

import atmos as atm
import merra
from indices import onset_SJKE, summarize_indices, plot_index_years

# ----------------------------------------------------------------------
# Compute SJ indices (Boos and Emmanuel 2009)
datadir = atm.homedir() + 'datastore/merra/daily/'
years = np.arange(1979, 2015)
filestr = 'merra_uv850_40E-120E_60S-60N_'
datafiles = [datadir + filestr + '%d.nc' % y for y in years]

# Read daily data from each year
ds = atm.combine_daily_years(['U', 'V'], datafiles, years)

# Remove extra dimension from data
u = atm.squeeze(ds['U'])
v = atm.squeeze(ds['V'])

# Calculate OCI index
sjke = onset_SJKE(u, v)

# Summary plot and timeseries in individual years
summarize_indices(years, sjke['onset'])
plot_index_years(sjke, suptitle='SJ', yearnm='Year', daynm='Day')
            ds_rel[nm] = utils.daily_rel2onset(var, d_onset, npre, npost)
        ds_rel.attrs['d_onset'] = d_onset
        ds_rel.attrs['d_retreat'] = d_retreat
        savefile = savefiles[plev][y]
        print('Saving to ' + savefile)
        ds_rel.to_netcdf(savefile)


# ----------------------------------------------------------------------
# Compute climatologies and save

yearstr = '%d-%d' % (years.min(), years.max())
for plev in plevs:
    relfiles = savefiles[plev]
    savefile = savestr % plev + '_' + yearstr + '.nc'
    ds = atm.combine_daily_years(None, relfiles, years, yearname='year')
    ds = ds.mean(dim='year')
    ds.attrs['years'] = years
    print('Saving to ' + savefile)
    ds.to_netcdf(savefile)

# ----------------------------------------------------------------------
# Concatenate plevels in climatology and save

files = [savestr % plev + '_' + yearstr + '.nc' for plev in plevs]
ubudget = xray.Dataset()
pname, pdim = 'Height', 1
subset_dict = {'lat' : (-60, 60), 'lon' : (40, 120)}
for i, plev in enumerate(plevs):
    filenm = files[i]
    print('Loading ' + filenm)
Beispiel #5
0
latlonstr = '%d-%dE, %d-%dN' % (lon1, lon2, lat1, lat2)

# ----------------------------------------------------------------------
# Read data

nroll = 7
days_ssn = atm.season_days('JJAS')
subset_dict = {'lat' : (lat1, lat2), 'lon' : (lon1, lon2)}

ts = xray.Dataset()
ssn = xray.Dataset()
varnms = {'PCP' : 'PRECTOT', 'MFC' : 'MFC', 'EVAP' : 'EVAP', 'W' : 'TQV',
          'ANA' : 'DQVDT_ANA'}

for nm in files:
    var = atm.combine_daily_years(varnms[nm], files[nm], years, yearname='year',
                                  subset_dict=subset_dict)
    var = atm.mean_over_geobox(var, lat1, lat2, lon1, lon2)
    units = var.attrs.get('units')
    if units in ['kg/m2/s', 'kg m-2 s-1']:
        var = atm.precip_convert(var, units, 'mm/day')
    var_sm = atm.rolling_mean(var, nroll, axis=-1, center=True)
    ts[nm] = var_sm
    if nm == 'W':
        # Difference in precipitable water from beginning to end of season
        var_ssn = var_sm.sel(day=days_ssn)
        ssn['d' + nm] = (var_ssn[:,-1] - var_ssn[:, 0]) / len(days_ssn)
        # dW/dt
        dvar = np.nan * np.ones(var.shape)
        for y, year in enumerate(years):
            dvar[y] = np.gradient(var[y])
        ts['d%s/dt' % nm] = xray.DataArray(dvar, coords=var.coords)
                if m == 0:
                    dsyr = ds
                else:
                    dsyr = xray.concat((dsyr, ds), dim='day')
        savefile = datafiles[y]
        print('Saving to ' + savefile)
        dsyr.to_netcdf(savefile)


# Read daily data from each year
plist = [200, 400, 600]
if plev is not None:
    plist = np.union1d(plist, [plev])
T_p = {}
for p in plist:
    T1 = atm.combine_daily_years('T', datafiles, years, yearname='year',
                              subset_dict={'plev' : (p, p)})
    T_p[p] = atm.squeeze(T1)
Tbar = atm.combine_daily_years('Tbar', datafiles, years, yearname='year')

if plev is None:
    T = Tbar
    varname = 'TT200-600'
else:
    T = T_p[plev]
    varname = 'TT%d' % plev

# Calculate TT index
# The north region should go up to 35 N but there is some weirdness
# with the topography so I'm setting it to 30 N for now
north=(5, 30, 40, 100)
south=(-15, 5, 40, 100)
          'CHP_MFC' : 'CHP_M',
          'CHP_PCP' : 'CHP_P'}

short_inv = {v : k for k, v in short.items()}

# ----------------------------------------------------------------------
def saveclose(name, isave, exts):
    if isave:
        for ext in exts:
            atm.savefigs(name, ext)
    plt.close('all')

# ----------------------------------------------------------------------
# HOWI index (Webster and Fasullo 2003)
maxbreak = 10
ds = atm.combine_daily_years(['uq_int', 'vq_int'], vimtfiles, years,
                             yearname='year')
ds_howi = {}
for npts in [50, 100]:
    howi, ds_howi[npts] = indices.onset_HOWI(ds['uq_int'], ds['vq_int'], npts,
                                             maxbreak=maxbreak)
    howi.attrs['title'] = 'HOWI (N=%d)' % npts
    index['HOWI_%d' % npts] = howi

# ----------------------------------------------------------------------
# Wang & LinHo method

def get_onset_WLH(years, days, pcp_sm, threshold, titlestr, pentad=True,
                  pcp_jan=None):
    nyears = len(years)
    i_onset = np.zeros(nyears)
    i_retreat = np.zeros(nyears)
Beispiel #8
0
def get_daily_data(varid, plev, years, datafiles, data, daymin=1,
                   daymax=366, yearnm='year'):
    """Return daily data (basic variable or calculated variable).

    Data is read from datafiles if varnm is a basic variable.
    If varnm is a calculated variable (e.g. potential temperature),
    the base variables for calculation are provided in the dict data.
    """

    years = atm.makelist(years)
    datafiles = atm.makelist(datafiles)

    if isinstance(plev, int) or isinstance(plev, float):
        pres = atm.pres_convert(plev, 'hPa', 'Pa')
    elif plev == 'LML' and 'PS' in data:
        pres = data['PS']
    else:
        pres = None

    def get_var(data, varnm, plev=None):
        if plev is None:
            plev = ''
        elif plev == 'LML' and varnm == 'QV':
            varnm = 'Q'
        return data[varnm + str(plev)]

    if var_type(varid) == 'calc':
        print('Computing ' + varid)
        if varid == 'THETA':
            var = atm.potential_temp(get_var(data, 'T', plev), pres)
        elif varid == 'THETA_E':
            var = atm.equiv_potential_temp(get_var(data, 'T', plev), pres,
                                           get_var(data, 'QV', plev))
        elif varid == 'DSE':
            var = atm.dry_static_energy(get_var(data, 'T', plev),
                                        get_var(data, 'H', plev))
        elif varid == 'MSE':
            var = atm.moist_static_energy(get_var(data, 'T', plev),
                                          get_var(data, 'H', plev),
                                          get_var(data, 'QV', plev))
        elif varid == 'VFLXMSE':
            Lv = atm.constants.Lv.values
            var = data['VFLXCPT'] + data['VFLXPHI'] + data['VFLXQV'] * Lv
            var.attrs['units'] = data['VFLXCPT'].attrs['units']
            var.attrs['long_name'] = 'Vertically integrated MSE meridional flux'
    else:
        with xray.open_dataset(datafiles[0]) as ds:
            if varid not in ds.data_vars:
                varid = varid + str(plev)
        var = atm.combine_daily_years(varid, datafiles, years, yearname=yearnm,
                                      subset_dict={'day' : (daymin, daymax)})
        var = atm.squeeze(var)

        # Make sure year dimension is included for single year
        if len(years) == 1 and 'year' not in var.dims:
            var = atm.expand_dims(var, yearnm, years[0], axis=0)

        # Wrap years for extended day ranges
        if daymin < 1 or daymax > 366:
            var = wrapyear_all(var, daymin, daymax)

    # Convert precip and evap to mm/day
    if varid in ['precip', 'PRECTOT', 'EVAP']:
        var = atm.precip_convert(var, var.attrs['units'], 'mm/day')

    return var
    index.load()
index = index.sel(year=years)
d0 = index[ind_nm].values

# Precip data
if pcp_nm == 'cmap':
    pcp = precipdat.read_cmap(pcpfiles, yearmin=min(years), yearmax=max(years))

    # Interpolate to daily resolution
    name, attrs, coords, dimnames = atm.meta(pcp)
    days = np.arange(3, 364)
    interp_func = scipy.interpolate.interp1d(pcp['day'], pcp, axis=1)
    vals = interp_func(days)
    coords['day'] = xray.DataArray(days, coords={'day' : days})
    pcp = xray.DataArray(vals, dims=dimnames, coords=coords, name=name,
                         attrs=attrs)
else:
    pcp = atm.combine_daily_years(None, pcpfiles, years, yearname='year',
                                  subset_dict=subset_dict)


# Wrap from following year to get extended daily range
daymin = min(d0) - npre
daymax = max(d0) + npost
pcp = utils.wrapyear_all(pcp, daymin=daymin, daymax=daymax)

# Daily relative to onset/withdrawal
pcp_rel = utils.daily_rel2onset(pcp, d0, npre, npost)
print('Saving to ' + savefile)
atm.save_nc(savefile, pcp_rel)
varnms = ["MFC", "precip"]
datadir = atm.homedir() + "datastore/merra/daily/"
savedir = atm.homedir() + "datastore/merra/analysis/"
icalc = False
isavefigs = True

if icalc:
    subset_dict = {"lat": (lat1, lat2), "lon": (lon1, lon2)}
    for varnm in varnms:
        if varnm == "MFC":
            varid, filestr = "MFC", "MFC_ps-300mb"
        elif varnm == "precip":
            varid, filestr = "PRECTOT", "precip"

        files = [datadir + "merra_%s_%d.nc" % (filestr, year) for year in years]
        data = atm.combine_daily_years(varid, files, years, yearname="year", subset_dict=subset_dict)
        data = atm.mean_over_geobox(data, lat1, lat2, lon1, lon2)
        data = atm.precip_convert(data, data.attrs["units"], "mm/day")

        # Accumulated precip or MFC
        data_acc = np.cumsum(data, axis=1)

        # Compute onset and retreat days
        chp = onset_changepoint_merged(data_acc)

        # Save to file
        savefile = savedir + "merra_onset_changepoint_merged_%s.nc" % varnm.upper()
        print("Saving to " + savefile)
        chp.to_netcdf(savefile)

chp = {}
datadir2 = atm.homedir() + 'datastore/merra/analysis/'
isave = True
incl_merged = True

data = {}
data_acc = {}
chp = {}
subset_dict = {'lat' : (lat1, lat2), 'lon' : (lon1, lon2)}
for varnm in varnms:
    if varnm == 'MFC':
        varid, filestr = 'MFC', 'MFC_ps-300mb'
    elif varnm == 'precip':
        varid, filestr = 'PRECTOT', 'precip'

    files = [datadir + 'merra_%s_%d.nc' % (filestr, year) for year in years]
    data[varnm] = atm.combine_daily_years(varid, files, years, yearname='year',
                                          subset_dict=subset_dict)
    data[varnm] = atm.mean_over_geobox(data[varnm], lat1, lat2, lon1, lon2)
    data[varnm] = atm.precip_convert(data[varnm], data[varnm].attrs['units'],
                                    'mm/day')

    # Accumulated precip or MFC
    data_acc[varnm] = np.cumsum(data[varnm], axis=1)

    # Compute onset and retreat days
    chp[varnm] = onset_changepoint(data_acc[varnm])

if incl_merged:
    chpm = {}
    for varnm in varnms:
        datafile = datadir2 + 'merra_onset_changepoint_merged_%s.nc' % varnm.upper()
        print('Reading ' + datafile)