Example #1
0
def onset_TT(T, north=(5, 35, 40, 100), south=(-15, 5, 40, 100),
             yearnm='year', daynm='day'):
    """Return monsoon onset index based on tropospheric temperature.

    Parameters
    ----------
    T : xray.DataArray
        Air temperature 200-600 hPa vertical mean.
    north, south : 4-tuples of floats, optional
        Tuple of (lat1, lat2, lon1, lon2) defining northern and
        southern regions to average over.
    yearnm, daynm : str, optional
        Name of year and day dimensions in DataArray

    Returns
    -------
    tt : xray.Dataset
        TT daily timeseries for each year and monsoon onset day for
        each year.

    Reference
    ---------
    Goswami, B. N., Wu, G., & Yasunari, T. (2006). The annual cycle,
        intraseasonal oscillations, and roadblock to seasonal
        predictability of the Asian summer monsoon. Journal of Climate,
        19, 5078-5099.
    """

    ttn = atm.mean_over_geobox(T, north[0], north[1], north[2], north[3])
    tts = atm.mean_over_geobox(T, south[0], south[1], south[2], south[3])
    tseries = ttn - tts

    # Onset day is the first day that ttn-tts becomes positive
    years = tseries[yearnm]
    onset = np.zeros(years.shape)
    for y in range(len(years)):
        pos = (tseries.values[y] > 0)
        if not pos.any():
            onset[y] = np.nan
        else:
            onset[y] = tseries[daynm][pos.argmax()]

    tt = xray.Dataset()
    tt['ttn'] = ttn
    tt['tts'] = tts
    tt['tseries'] = tseries
    tt['onset'] = xray.DataArray(onset, coords={yearnm : years})
    tt.attrs['north'] = north
    tt.attrs['south'] = south

    return tt
Example #2
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
Example #3
0
# ----------------------------------------------------------------------
# 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)
    else:
season = 'jja'
lon1, lon2 = 0, 100
lat1, lat2 = -20, 50
u = load_daily_season(ustr, year, season, 'U', lat1, lat2, lon1, lon2)
plt.figure()
atm.pcolor_latlon(u.mean(dim='TIME'))

ds = load_daily_season(ustr, year, season, None, lat1, lat2, lon1, lon2)
u2 = ds['U']
print((u == u2).any())

season = 'ann'
lon1, lon2 = 20, 120
lat1, lat2 = -60, 60
n = 8   # Number of time points per day
days = np.arange(1, 366)
u = load_daily_season(ustr, year, season, 'U', lat1, lat2, lon1, lon2)
udaily = atm.daily_from_subdaily(u, n, dayvals=days)
plt.figure()
atm.pcolor_latlon(udaily.mean(axis=0), axlims=(lat1,lat2,lon1,lon2))

lat1, lat2 = 10, 30
lon1, lon2 = 60, 100
ubar = atm.mean_over_geobox(u, lat1, lat2, lon1, lon2)
ubar_daily = atm.mean_over_geobox(udaily, lat1, lat2, lon1, lon2)
plt.figure(figsize=(7,8))
plt.subplot(211)
plt.plot(ubar)
plt.subplot(212)
plt.plot(ubar_daily)
Example #5
0
def onset_SJKE(u, v, latlon = (-5, 20, 50, 70), ndays=3, yearnm='Year',
             daynm='Day', thresh_std=1.0):
    """Return monsoon onset based on Somali Jet kinetic energy.

    Parameters
    ----------
    u, v : xray.DataArray
        850 hPa zonal and meridional wind.
    latlon : 4-tuple of floats, optional
        Tuple of (lat1, lat2, lon1, lon2) defining Somali jet region
        to average over.
    ndays : int, optional
        Number of consecutive days threshold must be exceeded to
        define onset.
    yearnm, daynm : str, optional
        Name of year and day dimensions in DataArray
    thresh_std : float, optional
        Number of standard deviations excursion to use as onset threshold.

    Returns
    -------
    sjke : xray.Dataset
        Somali jet index daily timeseries for each year and monsoon
        onset day for each year.

    Reference
    ---------
    Boos, W. R., & Emanuel, K. A. (2009). Annual intensification of the
        Somali jet in a quasi-equilibrium framework : Observational
        composites. Quarterly Journal of the Royal Meteorological
        Society, 135, 319-335.
    """

    days = atm.get_coord(u, coord_name=daynm)
    years = atm.get_coord(u, coord_name=yearnm)
    nyears = len(years)

    # Kinetic energy index
    ke = np.sqrt(u**2 + v**2)

    # Average over Somali jet region
    lat1, lat2, lon1, lon2 = latlon
    ke = atm.mean_over_geobox(ke, lat1, lat2, lon1, lon2)
    ke.attrs['title'] = 'KE'
    ke.attrs['long_name'] = 'sqrt(u**2 + v**2)'

    # Threshold for onset date
    vals = ke.values.flatten()
    keclim = np.nanmean(vals)
    kestd = np.nanstd(vals)
    threshold = keclim + thresh_std * kestd

    # Find first day when KE exceeds threshold and stays above the
    # threshold for consecutive ndays
    def onset_day(tseries, threshold, ndays, daynm):
        above = (tseries.values > threshold)
        d0 = above.argmax()
        while not above[d0:d0+ndays].all():
            d0 += 1
        return tseries[daynm].values[d0]

    # Find onset day for each year
    onset = [onset_day(ke[y], threshold, ndays, daynm)
             for y in range(nyears)]

    # Pack into dataset
    sjke = xray.Dataset()
    sjke['tseries'] = ke
    sjke['onset'] = xray.DataArray(onset, coords={yearnm : years})
    sjke.attrs = {'latlon' : latlon, 'thresh_std' : thresh_std,
                  'threshold' : threshold, 'ndays' : ndays}

    return sjke
Example #6
0
def onset_OCI(u, latlon = (5, 15, 40, 80), mmdd_thresh=(6,1),
              ndays=7, yearnm='Year', daynm='Day'):
    """Return monsoon Onset Circulation Index.

    Parameters
    ----------
    u : xray.DataArray
        850 hPa zonal wind.
    latlon : 4-tuple of floats, optional
        Tuple of (lat1, lat2, lon1, lon2) defining South Arabian Sea
        region to average over.
    mmdd_thres : 2-tuple of ints, optional
        Tuple of (month, day) defining climatological mean onset date
        to use for threshold value of u.
    ndays : int, optional
        Number of consecutive days threshold must be exceeded to
        define onset.
    yearnm, daynm : str, optional
        Name of year and day dimensions in DataArray

    Returns
    -------
    oci : xray.Dataset
        OCI daily timeseries for each year and monsoon onset day for
        each year.

    Reference
    ---------
    Wang, B., Ding, Q., & Joseph, P. V. (2009). Objective Definition
        of the Indian Summer Monsoon Onset. Journal of Climate, 22(12),
        3303-3316.
    """

    days = atm.get_coord(u, coord_name=daynm)
    years = atm.get_coord(u, coord_name=yearnm)
    nyears = len(years)

    # Average over South Arabian Sea region
    lat1, lat2, lon1, lon2 = latlon
    ubar = atm.mean_over_geobox(u, lat1, lat2, lon1, lon2)

    # Find values at climatological onset
    m0, d0 = mmdd_thresh
    d0 = [atm.mmdd_to_jday(m0, d0, year) for year in years]
    u0 = [ubar.sel(**{daynm : day, yearnm : year}).values
          for year, day in zip(years, d0)]
    u0 = np.array(u0).flatten()
    uthreshold = np.mean(u0)

    # Find first day when OCI exceeds threshold and stays above the
    # threshold for consecutive ndays
    def onset_day(tseries, uthreshold, ndays, daynm):
        above = (tseries.values > uthreshold)
        d0 = above.argmax()
        while not above[d0:d0+ndays].all():
            d0 += 1
        return tseries[daynm].values[d0]

    # Find onset day for each year
    onset = [onset_day(ubar[y], uthreshold, ndays, daynm)
             for y in range(nyears)]

    # Pack into dataset
    oci = xray.Dataset()
    oci['tseries'] = ubar
    oci['onset'] = xray.DataArray(onset, coords={yearnm : years})
    oci.attrs['latlon'] = latlon
    oci.attrs['mmdd_thresh'] = mmdd_thresh
    oci.attrs['ndays'] = ndays
    return oci
Example #7
0
    index['tseries'] = xray.DataArray(pcp_sm, dims=['year', 'day'],
                                      coords={'year' : years, 'day': days})
    index['onset'] = xray.DataArray(d_onset, coords={'year' : years})
    index['retreat'] = xray.DataArray(d_retreat, coords={'year' : years})
    index.attrs['title'] = titlestr
    return index


# Threshold and smoothing parameters
threshold = 5.0
kmax = 12
nroll = {'CMAP' : 3, 'MERRA_MFC' : 7, 'MERRA_PRECIP' : 7}

# Read CMAP pentad precip
cmap = precipdat.read_cmap(cmapfile)
cmapbar = atm.mean_over_geobox(cmap, lat1, lat2, lon1, lon2)
cmapdays = [atm.pentad_to_jday(p, pmin=1) for p in cmap.pentad.values]

# MERRA moisture flux convergence
mfc = atm.combine_daily_years('MFC', mfcfiles, years, yearname='year')
mfcbar = atm.mean_over_geobox(mfc, lat1, lat2, lon1, lon2)

# MERRA precip
subset_dict = {'lon' : (lon1, lon2), 'lat' : (lat1, lat2)}
precip = atm.combine_daily_years('PRECTOT', precipfiles, years, yearname='year',
                                 subset_dict=subset_dict)
precip = atm.precip_convert(precip, precip.attrs['units'], 'mm/day')
precipbar = atm.mean_over_geobox(precip, lat1, lat2, lon1, lon2)

# Compute indices for each dataset
for name in ['CMAP', 'MERRA_MFC', 'MERRA_PRECIP']:
# ----------------------------------------------------------------------
# Read data

data = collections.OrderedDict()
for nm in datafiles:
    var, onset, retreat = utils.load_dailyrel(datafiles[nm])
    data[nm] = var

# ----------------------------------------------------------------------
# Test atm.regress_field

day = -60

# 1-d timeseries
var = data['U200'].sel(dayrel=day)
ts = atm.mean_over_geobox(var, 10, 30, 60, 100)
ts_reg = atm.Linreg(onset, ts)
ts_reg2 = atm.regress_field(ts, onset)
print(ts_reg.r, ts_reg2.r.values)
print(ts_reg.slope, ts_reg2.m.values)
print(ts_reg.p, ts_reg2.p.values)

# x-y data
regdays = [-60, -30, 0, 30, 60]
plotdays = [-60, -30]
clev_r = np.arange(-1.0, 1.01, 0.05)
for nm in varnms:
    print(nm)
    var = data[nm].sel(dayrel=regdays)
    reg_daily = atm.regress_field(var, onset, axis=0)
    for day in plotdays:
    if nm == 'PSI':
        nm0 = 'V_sector_%dE-%dE' % (lon1, lon2)
    elif nm == 'VFLXLQV':
        nm0 = 'VFLXQV'
    elif nm == dtheta_nm:
        nm0 = theta_nm
    else:
        nm0 = nm
    relfiles[nm] = filestr % (nm0, onset_nm, yearstr)

# ----------------------------------------------------------------------
# Read data and calculate indices

# Precipitation
precip = precipdat.read_cmap(pcpfile, yearmin=min(years), yearmax=max(years))
pcp_box = atm.mean_over_geobox(precip, lat1, lat2, lon1, lon2)
# -- Interpolate to daily resolution
days = np.arange(1, 367)
pcp_i = np.nan * np.ones((len(years), len(days)))
for y, year in enumerate(years):
    pcp_i[y] = np.interp(days, pcp_box['day'], pcp_box[y])
coords = {'day' : days, 'year' : years}
pcp = xray.DataArray(pcp_i, dims=['year', 'day'], coords=coords)

# Monsoon onset, retreat indices
index = utils.get_onset_indices(onset_nm, indfiles, years)
mfc = atm.rolling_mean(index['ts_daily'], nroll, center=True)
onset = index['onset']
ssn_length=index['length'].mean(dim='year')

data = {}
Example #10
0
enso = enso.loc[years]
for key in enso_keys:
    if key not in enso.columns:
        months = atm.season_months(key)
        month_names = [(atm.month_str(m)).capitalize() for m in months]
        enso[key] = enso[month_names].mean(axis=1)
enso = enso[enso_keys]
col_names = [enso_nm + ' ' + nm for nm in enso.columns]
enso.columns = col_names

# ----------------------------------------------------------------------
# Daily timeseries

ts = xray.Dataset()
for nm in ['GPCP', 'PRECTOT']:
    ts[nm] = atm.mean_over_geobox(data[nm], lat1, lat2, lon1, lon2)
ts['MFC'] = utils.daily_rel2onset(index_all['CHP_MFC']['daily_ts'],
                                  index[ind_nm], npre, npost)
ts['CMFC'] = utils.daily_rel2onset(index_all['CHP_MFC']['tseries'],
                                   index[ind_nm], npre, npost)


# Extract variables at specified latitudes
for nm, lat0 in lat_extract.iteritems():
    var = atm.dim_mean(data[nm], 'lon', lon1, lon2)
    lat = atm.get_coord(var, 'lat')
    lat0_str = atm.latlon_labels(lat0, 'lat', deg_symbol=False)
    # key = nm + '_' + lat0_str
    key = nm
    lat_closest, _ = atm.find_closest(lat, lat0)
    print '%s %.2f %.2f' % (nm, lat0, lat_closest)
        else:
            plot_single_WLH(pcp[y], pcp_sm[y], label_sm[y], i_onset[y],
                            i_retreat[y], i_peak[y], titlestr + str(years[y]))
        if iplot < 4:
            plt.xticks(np.arange(0, 74, 4), [])
        else:
            plt.xticks(np.arange(0, 74, 4))
            plt.xlabel('Pentad')


# Read data and average over box
lon1, lon2 = 60, 100
lat1, lat2 = 10, 30
titlestr = 'CMAP %d-%dE, %d-%dN ' % (lon1, lon2, lat1, lat2)
precip = precipdat.read_cmap(cmap_file)
precipbar = atm.mean_over_geobox(precip, lat1, lat2, lon1, lon2)
nyears, npentad = precipbar.shape
years = precipbar.year.values
nyears = len(years)
pentads = precipbar.pentad
onset = {}

# Threshold for onset criteria
threshold = 5.0

# Smooth with truncated Fourier series
kmax = 12
kann = 4
pcp_sm, Rsq = atm.fourier_smooth(precipbar, kmax)
pcp_ann, Rsq_ann = atm.fourier_smooth(precipbar, kann)
label_sm, label_ann = [], []
Example #12
0
# ----------------------------------------------------------------------
# Read data

data = collections.OrderedDict()
for nm in datafiles:
    var, onset, retreat = utils.load_dailyrel(datafiles[nm])
    data[nm] = var

# ----------------------------------------------------------------------
# Test atm.regress_field

day = -60

# 1-d timeseries
var = data['U200'].sel(dayrel=day)
ts = atm.mean_over_geobox(var, 10, 30, 60, 100)
ts_reg = atm.Linreg(onset, ts)
ts_reg2 = atm.regress_field(ts, onset)
print(ts_reg.r, ts_reg2.r.values)
print(ts_reg.slope, ts_reg2.m.values)
print(ts_reg.p, ts_reg2.p.values)

# x-y data
regdays = [-60, -30, 0, 30, 60]
plotdays = [-60, -30]
clev_r = np.arange(-1.0, 1.01, 0.05)
for nm in varnms:
    print(nm)
    var = data[nm].sel(dayrel=regdays)
    reg_daily = atm.regress_field(var, onset, axis=0)
    for day in plotdays:
Example #13
0
import atmos as atm

datadir = "/home/jennifer/datastore/merra/daily/"

filestr = "merra_uv200_40E-120E_60S-60N_"
year = 1980
lon1, lon2 = 60, 100
lat1, lat2 = 10, 30

filename = "%s%s%d.nc" % (datadir, filestr, year)
ds = atm.ncload(filename)

iplot = {"U": 1, "V": 2, "rel_vort": 3, "Ro": 4}

plt.figure(figsize=(12, 9))
for var in ds.data_vars:
    plt.subplot(2, 2, iplot[var])
    atm.pcolor_latlon(ds[var].mean(axis=0))
    plt.title(var)

dsbar = xray.Dataset()
for var in ds.data_vars:
    print(var)
    dsbar[var] = atm.mean_over_geobox(ds[var], lat1, lat2, lon1, lon2)

plt.figure(figsize=(12, 9))
for var in dsbar.data_vars:
    plt.subplot(2, 2, iplot[var])
    plt.plot(dsbar.Day, dsbar[var])
    plt.title(var)
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 = {}
for varnm in varnms: