def parse_date(year, datestr): months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'] month_lookup = {month : m + 1 for m, month in enumerate(months)} day, month = datestr.split() month = month_lookup[month] day = int(day) jday = atm.mmdd_to_jday(month, day, year) return jday
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
for nm in index_pts.data_vars: ind = index[nm].sel(year=index_pts['year']) pts_reg[nm] = atm.regress_field(index_pts[nm], ind, axis=0) pts_reg[nm]['pts_mask'] = (pts_reg[nm]['p'] >= 0.05) # Mask out grid points where CHP index is ill-defined def applymask(ds, mask_in): for nm in ds.data_vars: mask = atm.biggify(mask_in, ds[nm], tile=True) vals = np.ma.masked_array(ds[nm], mask=mask).filled(np.nan) ds[nm].values = vals return ds if ptsmaskfile is not None: fracmin = 0.5 day1 = atm.mmdd_to_jday(6, 1) day2 = atm.mmdd_to_jday(9, 30) with xray.open_dataset(ptsmaskfile) as ds: pcp = ds['PREC'].sel(lat=index_pts.lat).sel(lon=index_pts.lon).load() pcp_ssn = atm.subset(pcp, {'day' : (day1, day2)}) pcp_frac = pcp_ssn.sum(dim='day') / pcp.sum(dim='day') mask = pcp_frac < fracmin index_pts = applymask(index_pts, mask) for key in pts_reg: pts_reg[key] = applymask(pts_reg[key], mask) # MFC budget with xray.open_dataset(mfcbudget_file) as mfc_budget: mfc_budget.load() mfc_budget = mfc_budget.rename({'DWDT' : 'dw/dt'}) mfc_budget['P-E'] = mfc_budget['PRECTOT'] - mfc_budget['EVAP']