def test_two(self): data01_mod = data01.copy() data = climapy.cesm_time_from_bnds(data01_mod, min_year=2001) assert np.array_equal( data['time'].values[[0, -1]], np.array(['2003-01-16T11:00:00', '2007-12-16T11:00:00'], dtype='datetime64'))
def load_output(variable, scenario='p16a_F_Hist_2000', season='annual', apply_sf=True): """ Load annual/seasonal data for a specific variable and scenario. Args: variable: string of variable name to load (e.g. 'SWCF_d1', or 'FSNTOA+LWCF') scenario: string scenario (default 'p16a_F_Hist_2000') season: 'annual' (default) or name of season (e.g 'DJF') apply_sf: apply scale factor? (default True) Returns: xarray DataArray """ # Check if data have been loaded previously try: data = _output_dict[(variable, scenario, season, apply_sf)] except KeyError: # Case 1: if '+' in variable name, call recursively if '+' in variable: variable1, variable2 = variable.split('+') data1 = load_output(variable1, scenario=scenario, season=season, apply_sf=apply_sf) data2 = load_output(variable2, scenario=scenario, season=season, apply_sf=apply_sf) data = data1 + data2 # Case 2: if '-' in variable name, call recursively elif '-' in variable: variable1, variable2 = variable.split('-') data1 = load_output(variable1, scenario=scenario, season=season, apply_sf=apply_sf) data2 = load_output(variable2, scenario=scenario, season=season, apply_sf=apply_sf) data = data1 - data2 # Case 3: variable name is a single variable else: # Read data in_filename = '{}/{}.cam.h0.{}.nc'.format(output_dir, scenario, variable) ds = xr.open_dataset(in_filename, decode_times=False) # Convert time coordinates ds = climapy.cesm_time_from_bnds(ds, min_year=1701) # Annual/seasonal mean for each year (Jan-Dec), using arithmetic mean across months if season == 'annual': data = ds[variable].groupby('time.year').mean(dim='time') else: data = ds[variable].where(ds['time.season'] == season, drop=True).groupby('time.year').mean(dim='time') # Discard first two years as spin-up data = data.where(data['year'] >= 1703, drop=True) # Limit time period to max of 60 years data = data.where(data['year'] <= 1762, drop=True) # Apply scale factor? if apply_sf: try: data = data * _variable_sf_dict[variable] except KeyError: pass # Average across level dimension if it exists try: data = data.mean(dim='lev') except ValueError: pass # Save data for future reference _output_dict[(variable, scenario, season, apply_sf)] = data return data
def load_landfrac(): """ Load land fraction (LANDFRAC). LANDFRAC is invariant across time and scenarios. Returns: xarray DataArray """ # Read data in_filename = '{}/LANDFRAC/p17d_f_000.cam.h0.LANDFRAC.nc'.format(output_dir) ds = xr.open_dataset(in_filename, decode_times=False) # Convert time coordinates ds = climapy.cesm_time_from_bnds(ds, min_year=1701) # Collapse time dimension (by calculating mean across time) data = ds['LANDFRAC'].mean(dim='time') return data
def test_one(self): data = climapy.cesm_time_from_bnds(data01) # by default, min_year=1701 assert np.array_equal( data['time'].values[[0, -1]], np.array(['1703-01-16T11:00:00', '1707-12-16T11:00:00'], dtype='datetime64'))
def load_output_monthly(variable='TS', scenario='eas0c', f_or_b='b', apply_sf=True): """ Load monthly data for a specific variable and scenario. Args: variable: string of variable name to load (default 'TS') scenario: string scenario name (default 'eas0c') f_or_b: 'f' (prescribed-SST) or 'b' (coupled atmosphere-ocean; default) apply_sf: apply scale factor? (default True) Returns: xarray DataArray """ # Check if monthly outout has been loaded previously try: data = _output_monthly_dict[(variable, scenario, f_or_b, apply_sf)] except KeyError: # If + or - in variable and the scenario is not a G16 scenario, call function recursively if ('+' in variable or '-' in variable) and scenario in ['2000', 'eas0b', 'eas0c']: variable1, variable2 = re.split('[+\-]', variable) data1 = load_output_monthly(variable1, scenario=scenario, f_or_b=f_or_b, apply_sf=apply_sf) data2 = load_output_monthly(variable2, scenario=scenario, f_or_b=f_or_b, apply_sf=apply_sf) if '+' in variable: data = data1 + data2 elif '-' in variable: data = data1 - data2 elif scenario in ['2000', 'eas0b', 'eas0c']: # p17d simulations # Read data in_filename = '{}/p17d_{}_{}.cam.h0.{}.nc'.format(output_dir, f_or_b, scenario, variable) ds = xr.open_dataset(in_filename, decode_times=False) # Convert time coordinates ds = climapy.cesm_time_from_bnds(ds, min_year=1701) # Select variable data = ds[variable] # Split time into separate year and month dimensions d_list = [] for m in range(1, 13): # loop over months d = data.where(data['time.month'] == m, drop=True).groupby('time.year').mean(dim='time') d['month'] = m # add month coordinate d_list.append(d) data = xr.concat(d_list, dim='month') # Discard spin-up if f_or_b == 'f': # discard two years for 'f' simulations data = data.where(data['year'] >= 1703, drop=True) elif f_or_b == 'b': # discard 40 years for 'b' simulations data = data.where(data['year'] >= 1741, drop=True) elif scenario in ['pA2x', 'pR45']: # G16 prescribed-SST simulations raise NotImplementedError('G16 prescribed-SST simulations not supported') else: # G16 transient simulations # Get G16 equivalent variable name variable_g16 = load_variable_g16_dict()[variable] # Get data for three ensemble members da_list = [] for ic in ['f1', 'h1', 'h2']: # Read data in_filename = '{}/{}_{}.nc'.format(g16_dir, scenario, ic) ds = xr.open_dataset(in_filename, decode_times=False) # Convert time coordinates ds = climapy.cesm_time_from_bnds(ds, min_year=1701) # Select variable da = ds[variable_g16] # Split time into separate year and month dimensions d_list = [] for m in range(1, 13): # loop over months d = da.where(da['time.month'] == m, drop=True).groupby('time.year').mean(dim='time') d['month'] = m # add month coordinate d_list.append(d) da = xr.concat(d_list, dim='month') # Select 2080-2099 da = da.where(da['year'] >= 2080, drop=True) # Shift time dimension to facilitate concatenation if ic == 'h1': da['year'] += 20 elif ic == 'h2': da['year'] += 40 # Append to list da_list.append(da) # Concatenate data from three ensemble members data = xr.concat(da_list, dim='year') # Apply scale factor? if apply_sf: try: data = data * load_variable_sf_dict()[variable] except KeyError: pass # Save result for future reference _output_monthly_dict[(variable, scenario, f_or_b, apply_sf)] = data return data
def load_output(variable='TS', scenario='eas0c', f_or_b='b', season='annual', apply_sf=True): """ Load annual/seasonal data for a specific variable and scenario. Args: variable: string of variable name to load (default 'TS') scenario: string scenario name (default 'eas0c') f_or_b: 'f' (prescribed-SST) or 'b' (coupled atmosphere-ocean; default) season: 'annual' (default) or name of season (e.g 'DJF') apply_sf: apply scale factor? (default True) Returns: xarray DataArray """ # If + or - in variable and the scenario is not a G16 scenario, call function recursively if ('+' in variable or '-' in variable) and scenario in ['2000', 'eas0b', 'eas0c']: variable1, variable2 = re.split('[+\-]', variable) data1 = load_output(variable1, scenario=scenario, f_or_b=f_or_b, season=season, apply_sf=apply_sf) data2 = load_output(variable2, scenario=scenario, f_or_b=f_or_b, season=season, apply_sf=apply_sf) if '+' in variable: data = data1 + data2 elif '-' in variable: data = data1 - data2 elif scenario in ['2000', 'eas0b', 'eas0c']: # p17d simulations # Read data in_filename = '{}/p17d_{}_{}.cam.h0.{}.nc'.format(output_dir, f_or_b, scenario, variable) ds = xr.open_dataset(in_filename, decode_times=False) # Convert time coordinates ds = climapy.cesm_time_from_bnds(ds, min_year=1701) # Calculate annual/seasonal mean for each year (Jan-Dec), using arithmetic mean if season == 'annual': data = ds[variable].groupby('time.year').mean(dim='time') else: data = ds[variable].where(ds['time.season'] == season, drop=True).groupby('time.year').mean(dim='time') # Discard spin-up if f_or_b == 'f': # discard two years for 'f' simulations data = data.where(data['year'] >= 1703, drop=True) elif f_or_b == 'b': # discard 40 years for 'b' simulations data = data.where(data['year'] >= 1741, drop=True) elif scenario in ['pA2x', 'pR45']: # G16 prescribed-SST simulations # Get G16 equivalent variable name variable_g16 = load_variable_g16_dict()[variable] # Read data in_filename = '{}/{}.nc'.format(g16_dir, scenario) ds = xr.open_dataset(in_filename, decode_times=False) # Convert time coordinates ds = climapy.cesm_time_from_bnds(ds, min_year=1701) # Calculate annual/seasonal mean for each year (Jan-Dec), using arithmetic mean if season == 'annual': data = ds[variable_g16].groupby('time.year').mean(dim='time') else: data = ds[variable_g16].where(ds['time.season'] == season, drop=True).groupby('time.year').mean(dim='time') # Discard two years spin-up (diff from G16, where 2 years 11 months were discarded) data = data.where(data['year'] >= 1703, drop=True) else: # G16 transient simulations # Get G16 equivalent variable name variable_g16 = load_variable_g16_dict()[variable] # Get data for three ensemble members da_list = [] for ic in ['f1', 'h1', 'h2']: # Read data in_filename = '{}/{}_{}.nc'.format(g16_dir, scenario, ic) ds = xr.open_dataset(in_filename, decode_times=False) # Convert time coordinates ds = climapy.cesm_time_from_bnds(ds, min_year=1701) # Calculate annual/seasonal mean for each year (Jan-Dec), using arithmetic mean if season == 'annual': da = ds[variable_g16].groupby('time.year').mean(dim='time') else: da = ds[variable_g16].where(ds['time.season'] == season, drop=True).groupby('time.year').mean(dim='time') # Select 2080-2099 da = da.where(da['year'] >= 2080, drop=True) # Shift time dimension to facilitate concatenation if ic == 'h1': da['year'] += 20 elif ic == 'h2': da['year'] += 40 # Append to list da_list.append(da) # Concatenate data from three ensemble members data = xr.concat(da_list, dim='year') # Apply scale factor? if apply_sf: try: data = data * load_variable_sf_dict()[variable] except KeyError: pass return data