def test_cross_section_error_on_missing_coordinate(test_ds_lonlat): """Test that the proper error is raised with missing coordinate.""" # Use a variable with no crs coordinate data_bad = test_ds_lonlat['temperature'].copy() del data_bad['crs'] start, end = (30.5, 255.5), (44.5, 274.5) with pytest.raises(ValueError): cross_section(data_bad, start, end)
def test_cross_section_dataarray_and_linear_interp(test_ds_xy): """Test the cross_section function with a data array and linear interpolation.""" data = test_ds_xy['temperature'] start, end = ((36.46, -112.45), (42.95, -68.74)) data_cross = cross_section(data, start, end, steps=7) truth_values = np.array([[[250.00095489, 251.53646673, 253.11586664, 254.73477364, 256.38991013, 258.0794356, 259.80334269], [260.04880178, 261.58431362, 263.16371353, 264.78262053, 266.43775702, 268.12728249, 269.85118958], [270.09664867, 271.63216051, 273.21156042, 274.83046742, 276.48560391, 278.17512938, 279.89903647], [280.14449556, 281.6800074, 283.25940731, 284.87831431, 286.5334508, 288.22297627, 289.94688336], [290.19234245, 291.72785429, 293.3072542, 294.9261612, 296.58129769, 298.27082316, 299.99473025]]]) truth_values_x = np.array([-499495.71907062, 98404.43537514, 688589.09865512, 1272690.44926197, 1852009.73516881, 2427525.45740665, 2999932.89862589]) truth_values_y = np.array([-1499865.98780602, -1268717.36799267, -1029139.66048478, -782037.60343652, -528093.95678826, -267710.32566917, -939.10769171]) index = xr.DataArray(range(7), name='index', dims=['index']) data_truth_x = xr.DataArray( truth_values_x, name='x', coords={ 'crs': data['crs'], 'y': (['index'], truth_values_y), 'x': (['index'], truth_values_x), 'index': index, }, dims=['index'] ) data_truth_y = xr.DataArray( truth_values_y, name='y', coords={ 'crs': data['crs'], 'y': (['index'], truth_values_y), 'x': (['index'], truth_values_x), 'index': index, }, dims=['index'] ) data_truth = xr.DataArray( truth_values * units.kelvin, name='temperature', coords={ 'time': data['time'], 'isobaric': data['isobaric'], 'index': index, 'crs': data['crs'], 'y': data_truth_y, 'x': data_truth_x }, dims=['time', 'isobaric', 'index'] ) xr.testing.assert_allclose(data_truth, data_cross)
def test_cross_section_dataset_and_nearest_interp(test_ds_lonlat): """Test the cross_section function with a dataset and nearest interpolation.""" start, end = (30.5, 255.5), (44.5, 274.5) data_cross = cross_section(test_ds_lonlat, start, end, steps=7, interp_type='nearest') nearest_values = test_ds_lonlat.isel(lat=xr.DataArray([0, 1, 2, 3, 3, 4, 5], dims='index'), lon=xr.DataArray(range(7), dims='index')) truth_temp = nearest_values['temperature'].metpy.unit_array truth_rh = nearest_values['relative_humidity'].metpy.unit_array truth_values_lon = np.array([255.5, 258.20305939, 261.06299342, 264.10041516, 267.3372208, 270.7961498, 274.5]) truth_values_lat = np.array([30.5, 33.02800969, 35.49306226, 37.88512911, 40.19271688, 42.40267088, 44.5]) index = xr.DataArray(range(7), name='index', dims=['index']) data_truth = xr.Dataset( { 'temperature': (['isobaric', 'index'], truth_temp), 'relative_humidity': (['isobaric', 'index'], truth_rh) }, coords={ 'isobaric': test_ds_lonlat['isobaric'], 'index': index, 'crs': test_ds_lonlat['crs'], 'lat': (['index'], truth_values_lat), 'lon': (['index'], truth_values_lon) }, ) xr.testing.assert_allclose(data_truth, data_cross)
def plot_rh(ds, model): data = ds.metpy.parse_cf() data['lon'] = np.mod(ds.lon - 180.0, 360.0) - 180.0 start = (35., -120) end = (35., -90) cross = cross_section(data, start, end) fig = plt.figure(1, figsize=(10., 10.)) ax = plt.axes() cf = ax.contourf(cross['lon'], cross['isobaric'], cross['Relative_humidity_isobaric'], levels=np.arange(-18, 20, 2), cmap='Spectral_r') # Contour Fill the RH Values cb = plt.colorbar(cf, orientation='vertical') cb.set_label('Change in RH (%)') # Contour the U-Component of Wind clevs_500_hght = np.arange(4, 10, .5) cs = ax.contour(cross['lon'], cross['isobaric'], cross['air_temperature'], clevs_500_hght, colors='black') plt.clabel(cs, fmt='%d') ax.set_yscale('symlog') ax.set_yticklabels([1000, 850, 700, 500, 400, 300, 250, 200]) ax.set_ylim(1000, 200) ax.set_yticks([1000, 850, 700, 500, 400, 300, 250, 200]) ax.set_xlim(cross['lon'].min(), cross['lon'].max()) plt.title('Delta RH (Filled) and Delta Temperature (Contoured) ' + model) plt.savefig('RH_Delta_' + model + '.png', dpi=200) return plt.show()
def test_cross_lonlat(): """Return cross section on a lon/lat grid with no time coordinate for use in tests.""" data_u = np.linspace(-40, 40, 5 * 6 * 7).reshape((5, 6, 7)) data_v = np.linspace(40, -40, 5 * 6 * 7).reshape((5, 6, 7)) ds = xr.Dataset( { 'u_wind': (['isobaric', 'lat', 'lon'], data_u), 'v_wind': (['isobaric', 'lat', 'lon'], data_v) }, coords={ 'isobaric': xr.DataArray( np.linspace(1000, 500, 5), name='isobaric', dims=['isobaric'], attrs={'units': 'hPa'} ), 'lat': xr.DataArray( np.linspace(30, 45, 6), name='lat', dims=['lat'], attrs={'units': 'degrees_north'} ), 'lon': xr.DataArray( np.linspace(255, 275, 7), name='lon', dims=['lon'], attrs={'units': 'degrees_east'} ) } ) ds['u_wind'].attrs['units'] = 'knots' ds['v_wind'].attrs['units'] = 'knots' start, end = (30.5, 255.5), (44.5, 274.5) return cross_section(ds.metpy.parse_cf(), start, end, steps=7, interp_type='nearest')
def test_cross_lonlat(): """Return cross section on a lon/lat grid with no time coordinate for use in tests.""" data_u = np.linspace(-40, 40, 5 * 6 * 7).reshape((5, 6, 7)) * units.knots data_v = np.linspace(40, -40, 5 * 6 * 7).reshape((5, 6, 7)) * units.knots ds = xr.Dataset( { 'u_wind': (['isobaric', 'lat', 'lon'], data_u), 'v_wind': (['isobaric', 'lat', 'lon'], data_v) }, coords={ 'isobaric': xr.DataArray( np.linspace(1000, 500, 5), name='isobaric', dims=['isobaric'], attrs={'units': 'hPa'} ), 'lat': xr.DataArray( np.linspace(30, 45, 6), name='lat', dims=['lat'], attrs={'units': 'degrees_north'} ), 'lon': xr.DataArray( np.linspace(255, 275, 7), name='lon', dims=['lon'], attrs={'units': 'degrees_east'} ) } ) start, end = (30.5, 255.5), (44.5, 274.5) return cross_section(ds.metpy.parse_cf(), start, end, steps=7, interp_type='nearest')
def test_cross_section_dataset_and_nearest_interp(test_ds_lonlat): """Test the cross_section function with a dataset and nearest interpolation.""" start, end = (30.5, 255.5), (44.5, 274.5) data_cross = cross_section(test_ds_lonlat, start, end, steps=7, interp_type='nearest') nearest_values = test_ds_lonlat.isel(lat=xr.DataArray([0, 1, 2, 3, 3, 4, 5], dims='index'), lon=xr.DataArray(range(7), dims='index')) truth_temp = nearest_values['temperature'].values truth_rh = nearest_values['relative_humidity'].values truth_values_lon = np.array([255.5, 258.20305939, 261.06299342, 264.10041516, 267.3372208, 270.7961498, 274.5]) truth_values_lat = np.array([30.5, 33.02800969, 35.49306226, 37.88512911, 40.19271688, 42.40267088, 44.5]) index = xr.DataArray(range(7), name='index', dims=['index']) data_truth = xr.Dataset( { 'temperature': (['isobaric', 'index'], truth_temp), 'relative_humidity': (['isobaric', 'index'], truth_rh) }, coords={ 'isobaric': test_ds_lonlat['isobaric'], 'index': index, 'crs': test_ds_lonlat['crs'], 'lat': (['index'], truth_values_lat), 'lon': (['index'], truth_values_lon) }, ) xr.testing.assert_allclose(data_truth, data_cross)
def interpolate_csec(self, plevs, start, end, steps=100): start = (start['lat'], start['lon']) end = (end['lat'], end['lon']) xp_interp = cross_section(self.__press_inter, start, end, steps=steps) for name, (d_arr, conf) in list(self.var_conf.items()): d_arr = cross_section(d_arr, start, end, steps=steps) d_arr_interp = log_interpolate_1d(plevs, xp_interp, d_arr) # Back to DataArray: d_arr_interp = xr.DataArray(data=d_arr_interp, dims=['plevs', 'index'], coords={'lat': ('index', d_arr['lat']), 'lon': ('index', d_arr['lon']), 'plevs': ('plevs', plevs), 'index': ('index', d_arr['index'])}, attrs=d_arr.attrs) # Anpassen, nicht identisch # Change dict entry for interpolated values self.var_conf[name] = (d_arr_interp, conf)
def test_cross_xy(): """Return cross section on a x/y grid with a time coordinate for use in tests.""" data_u = np.linspace(-25, 25, 5 * 6 * 7).reshape((1, 5, 6, 7)) data_v = np.linspace(25, -25, 5 * 6 * 7).reshape((1, 5, 6, 7)) ds = xr.Dataset( { 'u_wind': (['time', 'isobaric', 'y', 'x'], data_u), 'v_wind': (['time', 'isobaric', 'y', 'x'], data_v), 'lambert_conformal': ([], '') }, coords={ 'time': xr.DataArray( np.array([np.datetime64('2018-07-01T00:00')]), name='time', dims=['time'] ), 'isobaric': xr.DataArray( np.linspace(1000, 500, 5), name='isobaric', dims=['isobaric'], attrs={'units': 'hPa'} ), 'y': xr.DataArray( np.linspace(-1500, 0, 6), name='y', dims=['y'], attrs={'units': 'km'} ), 'x': xr.DataArray( np.linspace(-500, 3000, 7), name='x', dims=['x'], attrs={'units': 'km'} ) } ) ds['u_wind'].attrs = ds['v_wind'].attrs = { 'units': 'm/s', 'grid_mapping': 'lambert_conformal' } ds['lambert_conformal'].attrs = { 'grid_mapping_name': 'lambert_conformal_conic', 'standard_parallel': 50.0, 'longitude_of_central_meridian': -107.0, 'latitude_of_projection_origin': 50.0, 'earth_shape': 'spherical', 'earth_radius': 6367470.21484375 } start, end = ((36.46, -112.45), (42.95, -68.74)) return cross_section(ds.metpy.parse_cf(), start, end, steps=7)
def test_absolute_momentum_xarray_units_attr(): """Test absolute momentum when `u` and `v` are DataArrays with a `units` attribute.""" data = xr.open_dataset(get_test_data('narr_example.nc', False)) data = data.metpy.parse_cf().squeeze() start = (37.0, -105.0) end = (35.5, -65.0) cross = cross_section(data, start, end) u = cross['u_wind'][0].sel(index=slice(0, 2)) v = cross['v_wind'][0].sel(index=slice(0, 2)) momentum = absolute_momentum(u, v) true_momentum_values = np.array([137.46164031, 134.11450232, 133.85196023]) true_momentum = xr.DataArray(units.Quantity(true_momentum_values, 'm/s'), coords=u.coords) assert_xarray_allclose(momentum, true_momentum)
def Crosssection_Wind_Temp_RH( initial_time=None, fhour=24, levels=[1000, 950, 925, 900, 850, 800, 700, 600, 500, 400, 300, 200], day_back=0, model='ECMWF', output_dir=None, st_point=[43.5, 111.5], ed_point=[33, 125.0], map_extent=[70, 140, 15, 55], h_pos=[0.125, 0.665, 0.25, 0.2]): # micaps data directory try: data_dir = [ utl.Cassandra_dir(data_type='high', data_source=model, var_name='RH', lvl=''), utl.Cassandra_dir(data_type='high', data_source=model, var_name='UGRD', lvl=''), utl.Cassandra_dir(data_type='high', data_source=model, var_name='VGRD', lvl=''), utl.Cassandra_dir(data_type='high', data_source=model, var_name='TMP', lvl=''), utl.Cassandra_dir(data_type='high', data_source=model, var_name='HGT', lvl='500'), utl.Cassandra_dir(data_type='surface', data_source=model, var_name='PSFC') ] except KeyError: raise ValueError('Can not find all directories needed') # get filename if (initial_time != None): filename = utl.model_filename(initial_time, fhour) else: filename = utl.filename_day_back_model(day_back=day_back, fhour=fhour) # retrieve data from micaps server rh = get_model_3D_grid(directory=data_dir[0][0:-1], filename=filename, levels=levels, allExists=False) if rh is None: return rh = rh.metpy.parse_cf().squeeze() u = get_model_3D_grid(directory=data_dir[1][0:-1], filename=filename, levels=levels, allExists=False) if u is None: return u = u.metpy.parse_cf().squeeze() v = get_model_3D_grid(directory=data_dir[2][0:-1], filename=filename, levels=levels, allExists=False) if v is None: return v = v.metpy.parse_cf().squeeze() v2 = get_model_3D_grid(directory=data_dir[2][0:-1], filename=filename, levels=levels, allExists=False) if v2 is None: return v2 = v2.metpy.parse_cf().squeeze() t = get_model_3D_grid(directory=data_dir[3][0:-1], filename=filename, levels=levels, allExists=False) if t is None: return t = t.metpy.parse_cf().squeeze() gh = get_model_grid(data_dir[4], filename=filename) psfc = get_model_grid(data_dir[5], filename=filename) psfc = psfc.metpy.parse_cf().squeeze() mask1 = ((psfc['lon'] >= t['lon'].values.min()) & (psfc['lon'] <= t['lon'].values.max()) & (psfc['lat'] >= t['lat'].values.min()) & (psfc['lat'] <= t['lat'].values.max())) t2, psfc_bdcst = xr.broadcast(t['data'], psfc['data'].where(mask1, drop=True)) mask2 = (psfc_bdcst > -10000) psfc_bdcst = psfc_bdcst.where(mask2, drop=True) #psfc_bdcst=psfc_bdcst.metpy.parse_cf().squeeze() if t is None: return resolution = u['lon'][1] - u['lon'][0] x, y = np.meshgrid(u['lon'], u['lat']) dx, dy = mpcalc.lat_lon_grid_deltas(u['lon'], u['lat']) #rh=rh.rename(dict(lat='latitude',lon='longitude')) cross = cross_section(rh, st_point, ed_point) cross_rh = cross.set_coords(('lat', 'lon')) cross = cross_section(u, st_point, ed_point) cross_u = cross.set_coords(('lat', 'lon')) cross = cross_section(v, st_point, ed_point) cross_v = cross.set_coords(('lat', 'lon')) cross_psfc = cross_section(psfc_bdcst, st_point, ed_point) #cross_psfc=cross.set_coords(('lat', 'lon')) cross_u['data'].attrs['units'] = units.meter / units.second cross_v['data'].attrs['units'] = units.meter / units.second cross_u['t_wind'], cross_v['n_wind'] = mpcalc.cross_section_components( cross_u['data'], cross_v['data']) cross = cross_section(t, st_point, ed_point) cross_Temp = cross.set_coords(('lat', 'lon')) cross_Td = mpcalc.dewpoint_rh(cross_Temp['data'].values * units.celsius, cross_rh['data'].values * units.percent) rh, pressure = xr.broadcast(cross_rh['data'], cross_Temp['level']) cross_terrain = pressure - cross_psfc crossection_graphics.draw_Crosssection_Wind_Temp_RH( cross_rh=cross_rh, cross_Temp=cross_Temp, cross_u=cross_u, cross_v=cross_v, cross_terrain=cross_terrain, gh=gh, h_pos=h_pos, st_point=st_point, ed_point=ed_point, levels=levels, map_extent=map_extent, model=model, output_dir=output_dir)
def Crosssection_Wind_Temp_RH( initTime=None, fhour=24, levels=[1000, 950, 925, 900, 850, 800, 700,600,500,400,300,200], day_back=0,model='ECMWF',data_source='MICAPS', output_dir=None, st_point = [43.5, 111.5], ed_point = [33, 125.0], map_extent=[70,140,15,55], lw_ratio=[16,9], h_pos=[0.125, 0.665, 0.25, 0.2],**kwargs ): if(data_source == 'MICAPS'): try: data_dir = [utl.Cassandra_dir(data_type='high',data_source=model,var_name='RH',lvl=''), utl.Cassandra_dir(data_type='high',data_source=model,var_name='UGRD',lvl=''), utl.Cassandra_dir(data_type='high',data_source=model,var_name='VGRD',lvl=''), utl.Cassandra_dir(data_type='high',data_source=model,var_name='TMP',lvl=''), utl.Cassandra_dir(data_type='high',data_source=model,var_name='HGT',lvl='500'), utl.Cassandra_dir(data_type='surface',data_source=model,var_name='PSFC')] except KeyError: raise ValueError('Can not find all directories needed') if(initTime != None): filename = utl.model_filename(initTime, fhour) else: filename=utl.filename_day_back_model(day_back=day_back,fhour=fhour) rh=get_model_3D_grid(directory=data_dir[0][0:-1],filename=filename,levels=levels, allExists=False) u=get_model_3D_grid(directory=data_dir[1][0:-1],filename=filename,levels=levels, allExists=False) v=get_model_3D_grid(directory=data_dir[2][0:-1],filename=filename,levels=levels, allExists=False) t=get_model_3D_grid(directory=data_dir[3][0:-1],filename=filename,levels=levels, allExists=False) gh=get_model_grid(data_dir[4], filename=filename) psfc=get_model_grid(data_dir[5], filename=filename) if(data_source == 'CIMISS'): if(initTime != None): filename = utl.model_filename(initTime, fhour,UTC=True) else: filename=utl.filename_day_back_model(day_back=day_back,fhour=fhour,UTC=True) try: rh=CMISS_IO.cimiss_model_3D_grid(init_time_str='20'+filename[0:8],valid_time=fhour, data_code=utl.CMISS_data_code(data_source=model,var_name='RHU'), fcst_levels=levels, fcst_ele="RHU", units='%') u=CMISS_IO.cimiss_model_3D_grid(init_time_str='20'+filename[0:8],valid_time=fhour, data_code=utl.CMISS_data_code(data_source=model,var_name='WIU'), fcst_levels=levels, fcst_ele="WIU", units='m/s') v=CMISS_IO.cimiss_model_3D_grid(init_time_str='20'+filename[0:8],valid_time=fhour, data_code=utl.CMISS_data_code(data_source=model,var_name='WIV'), fcst_levels=levels, fcst_ele="WIV", units='m/s') t=CMISS_IO.cimiss_model_3D_grid(init_time_str='20'+filename[0:8],valid_time=fhour, data_code=utl.CMISS_data_code(data_source=model,var_name='TEM'), fcst_levels=levels, fcst_ele="TEM", units='K') t['data'].values=t['data'].values-273.15 gh=CMISS_IO.cimiss_model_by_time('20'+filename[0:8],valid_time=fhour, data_code=utl.CMISS_data_code(data_source=model,var_name='GPH'), fcst_level=500, fcst_ele="GPH", units='gpm') gh['data'].values=gh['data'].values/10. psfc=CMISS_IO.cimiss_model_by_time('20'+filename[0:8], valid_time=fhour, data_code=utl.CMISS_data_code(data_source=model,var_name='PRS'), fcst_level=0, fcst_ele="PRS", units='Pa') psfc['data']=psfc['data']/100. except KeyError: raise ValueError('Can not find all data needed') rh = rh.metpy.parse_cf().squeeze() u = u.metpy.parse_cf().squeeze() v = v.metpy.parse_cf().squeeze() t = t.metpy.parse_cf().squeeze() psfc=psfc.metpy.parse_cf().squeeze() #if(psfc['lon'].values[0] != t['lon'].values[0]): mask1 = ( (psfc['lon']>=t['lon'].values.min())& (psfc['lon']<=t['lon'].values.max())& (psfc['lat']>=t['lat'].values.min())& (psfc['lat']<=t['lat'].values.max()) ) t2,psfc_bdcst=xr.broadcast(t['data'],psfc['data'].where(mask1, drop=True)) mask2=(psfc_bdcst > -10000) psfc_bdcst=psfc_bdcst.where(mask2, drop=True) #else: # psfc_bdcst=psfc['data'].copy resolution=u['lon'][1]-u['lon'][0] x,y=np.meshgrid(u['lon'], u['lat']) dx,dy=mpcalc.lat_lon_grid_deltas(u['lon'],u['lat']) cross = cross_section(rh, st_point, ed_point) cross_rh=cross.set_coords(('lat', 'lon')) cross = cross_section(u, st_point, ed_point) cross_u=cross.set_coords(('lat', 'lon')) cross = cross_section(v, st_point, ed_point) cross_v=cross.set_coords(('lat', 'lon')) cross_psfc = cross_section(psfc_bdcst, st_point, ed_point) cross_u['data'].attrs['units']=units.meter/units.second cross_v['data'].attrs['units']=units.meter/units.second cross_u['t_wind'], cross_v['n_wind'] = mpcalc.cross_section_components(cross_u['data'],cross_v['data']) cross = cross_section(t, st_point, ed_point) cross_Temp=cross.set_coords(('lat', 'lon')) cross_Td = mpcalc.dewpoint_rh(cross_Temp['data'].values*units.celsius, cross_rh['data'].values* units.percent) rh,pressure = xr.broadcast(cross_rh['data'],cross_Temp['level']) cross_terrain=pressure-cross_psfc crossection_graphics.draw_Crosssection_Wind_Temp_RH( cross_rh=cross_rh, cross_Temp=cross_Temp, cross_u=cross_u, cross_v=cross_v,cross_terrain=cross_terrain,gh=gh, h_pos=h_pos,st_point=st_point,ed_point=ed_point,lw_ratio=lw_ratio, levels=levels,map_extent=map_extent,model=model, output_dir=output_dir)
def Crosssection_Wind_Theta_e_Qv( initial_time=None, fhour=24, levels=[1000, 950, 925, 900, 850, 800, 700, 600, 500, 400, 300, 200], day_back=0, model='ECMWF', output_dir=None, st_point=[20, 120.0], ed_point=[50, 130.0], map_extent=[70, 140, 15, 55], h_pos=[0.125, 0.665, 0.25, 0.2]): # micaps data directory try: data_dir = [ utl.Cassandra_dir(data_type='high', data_source=model, var_name='RH', lvl=''), utl.Cassandra_dir(data_type='high', data_source=model, var_name='UGRD', lvl=''), utl.Cassandra_dir(data_type='high', data_source=model, var_name='VGRD', lvl=''), utl.Cassandra_dir(data_type='high', data_source=model, var_name='TMP', lvl=''), utl.Cassandra_dir(data_type='high', data_source=model, var_name='HGT', lvl='500') ] except KeyError: raise ValueError('Can not find all directories needed') # get filename if (initial_time != None): filename = utl.model_filename(initial_time, fhour) else: filename = utl.filename_day_back_model(day_back=day_back, fhour=fhour) # retrieve data from micaps server rh = get_model_3D_grid(directory=data_dir[0][0:-1], filename=filename, levels=levels, allExists=False) if rh is None: return rh = rh.metpy.parse_cf().squeeze() u = get_model_3D_grid(directory=data_dir[1][0:-1], filename=filename, levels=levels, allExists=False) if u is None: return u = u.metpy.parse_cf().squeeze() v = get_model_3D_grid(directory=data_dir[2][0:-1], filename=filename, levels=levels, allExists=False) if v is None: return v = v.metpy.parse_cf().squeeze() v2 = get_model_3D_grid(directory=data_dir[2][0:-1], filename=filename, levels=levels, allExists=False) if v2 is None: return v2 = v2.metpy.parse_cf().squeeze() t = get_model_3D_grid(directory=data_dir[3][0:-1], filename=filename, levels=levels, allExists=False) if t is None: return t = t.metpy.parse_cf().squeeze() gh = get_model_grid(data_dir[4], filename=filename) if t is None: return resolution = u['lon'][1] - u['lon'][0] x, y = np.meshgrid(u['lon'], u['lat']) dx, dy = mpcalc.lat_lon_grid_deltas(u['lon'], u['lat']) for ilvl in levels: u2d = u.sel(level=ilvl) #u2d['data'].attrs['units']=units.meter/units.second v2d = v.sel(level=ilvl) #v2d['data'].attrs['units']=units.meter/units.second absv2d = mpcalc.absolute_vorticity( u2d['data'].values * units.meter / units.second, v2d['data'].values * units.meter / units.second, dx, dy, y * units.degree) if (ilvl == levels[0]): absv3d = v2 absv3d['data'].loc[dict(level=ilvl)] = np.array(absv2d) else: absv3d['data'].loc[dict(level=ilvl)] = np.array(absv2d) absv3d['data'].attrs['units'] = absv2d.units #rh=rh.rename(dict(lat='latitude',lon='longitude')) cross = cross_section(rh, st_point, ed_point) cross_rh = cross.set_coords(('lat', 'lon')) cross = cross_section(u, st_point, ed_point) cross_u = cross.set_coords(('lat', 'lon')) cross = cross_section(v, st_point, ed_point) cross_v = cross.set_coords(('lat', 'lon')) cross_u['data'].attrs['units'] = units.meter / units.second cross_v['data'].attrs['units'] = units.meter / units.second cross_u['t_wind'], cross_v['n_wind'] = mpcalc.cross_section_components( cross_u['data'], cross_v['data']) cross = cross_section(t, st_point, ed_point) cross_t = cross.set_coords(('lat', 'lon')) cross = cross_section(absv3d, st_point, ed_point) cross_Td = mpcalc.dewpoint_rh(cross_t['data'].values * units.celsius, cross_rh['data'].values * units.percent) rh, pressure = xr.broadcast(cross_rh['data'], cross_t['level']) Qv = mpcalc.specific_humidity_from_dewpoint(cross_Td, pressure) cross_Qv = xr.DataArray(np.array(Qv) * 1000., coords=cross_rh['data'].coords, dims=cross_rh['data'].dims, attrs={'units': units('g/kg')}) Theta_e = mpcalc.equivalent_potential_temperature( pressure, cross_t['data'].values * units.celsius, cross_Td) cross_Theta_e = xr.DataArray(np.array(Theta_e), coords=cross_rh['data'].coords, dims=cross_rh['data'].dims, attrs={'units': Theta_e.units}) crossection_graphics.draw_Crosssection_Wind_Theta_e_Qv( cross_Qv=cross_Qv, cross_Theta_e=cross_Theta_e, cross_u=cross_u, cross_v=cross_v, gh=gh, h_pos=h_pos, st_point=st_point, ed_point=ed_point, levels=levels, map_extent=map_extent, output_dir=output_dir)
'https://thredds.met.no/thredds/dodsC/mepslatest/meps_det_2_5km_%sT%sZ.ncml' % (date, ini_time), decode_times=True, use_cftime=True) data = fnx.metpy.parse_cf().squeeze() # Cross section along 69.3 latitude and between 1 and 25 longitude # Andenes = 16deg longitude start = (69.3, 1) end = (69.3, 25) cross_data = data[[ 'cloud_area_fraction_pl', 'air_temperature_pl', 'relative_humidity_pl' ]] cross = cross_section(cross_data, start, end).set_coords( ('latitude', 'longitude')) # Inverse the pressure axes (doesn't work as intended) # cross = cross.reindex(pressure=list(reversed(cross.pressure))) temperature, clouds, relative_humidity = xr.broadcast( cross['air_temperature_pl'], cross['cloud_area_fraction_pl'], cross['relative_humidity_pl']) # Plot the cross section fig, axs = plt.subplots(nrows=3, ncols=3, sharey=True, sharex=True, figsize=(14, 10)) ax = axs.ravel().tolist() j = 0
# dimension. data = xr.open_dataset(get_test_data('narr_example.nc', False)) data = data.metpy.parse_cf().squeeze() print(data) ############################## # Define start and end points: start = (37.0, -105.0) end = (35.5, -65.0) ############################## # Get the cross section, and convert lat/lon to supplementary coordinates: cross = cross_section(data, start, end) cross.set_coords(('lat', 'lon'), True) print(cross) ############################## # For this example, we will be plotting potential temperature, relative humidity, and # tangential/normal winds. And so, we need to calculate those, and add them to the dataset: temperature, pressure, specific_humidity = xr.broadcast( cross['Temperature'], cross['isobaric'], cross['Specific_humidity']) theta = mpcalc.potential_temperature(pressure, temperature) rh = mpcalc.relative_humidity_from_specific_humidity(specific_humidity, temperature, pressure) # These calculations return unit arrays, so put those back into DataArrays in our Dataset
# dimension. data = xr.open_dataset(get_test_data('narr_example.nc', False)) data = data.metpy.parse_cf().squeeze() print(data) ############################## # Define start and end points: start = (37.0, -105.0) end = (35.5, -65.0) ############################## # Get the cross section, and convert lat/lon to supplementary coordinates: cross = cross_section(data, start, end) cross.set_coords(('lat', 'lon'), True) print(cross) ############################## # For this example, we will be plotting potential temperature, relative humidity, and # tangential/normal winds. And so, we need to calculate those, and add them to the dataset: temperature, pressure, specific_humidity = xr.broadcast(cross['Temperature'], cross['isobaric'], cross['Specific_humidity']) theta = mpcalc.potential_temperature(pressure, temperature) rh = mpcalc.relative_humidity_from_specific_humidity(specific_humidity, temperature, pressure) # These calculations return unit arrays, so put those back into DataArrays in our Dataset
data = xr.open_dataset('./CFile.nc') data["rhum"] = (['time', 'level', 'lat', 'lon'], c) data = data.metpy.parse_cf().squeeze() print(data) ############################## # Define start and end points: start = (5.0, 75.0) end = (15.0, 80.0) ############################## # Get the cross section, and convert lat/lon to supplementary coordinates: cross = cross_section(data, start, end).set_coords(('lat', 'lon')) ############################## # For this example, we will be plotting potential temperature, relative humidity, and # tangential/normal winds. And so, we need to calculate those, and add them to the dataset: cross['rhum'].metpy.convert_units('percent') temperature, pressure, relative_humidity = xr.broadcast( cross['air'], cross['level'], cross['rhum']) theta = mpcalc.potential_temperature(pressure, temperature) print(max(theta.flatten())) print(min(theta.flatten())) # These calculations return unit arrays, so put those back into DataArrays in our Dataset
def test_cross_section_dataarray_and_linear_interp(test_ds_xy): """Test the cross_section function with a data array and linear interpolation.""" data = test_ds_xy['temperature'] start, end = ((36.46, -112.45), (42.95, -68.74)) data_cross = cross_section(data, start, end, steps=7) truth_values = np.array([[[250.00095489, 251.53646673, 253.11586664, 254.73477364, 256.38991013, 258.0794356, 259.80334269], [260.04880178, 261.58431362, 263.16371353, 264.78262053, 266.43775702, 268.12728249, 269.85118958], [270.09664867, 271.63216051, 273.21156042, 274.83046742, 276.48560391, 278.17512938, 279.89903647], [280.14449556, 281.6800074, 283.25940731, 284.87831431, 286.5334508, 288.22297627, 289.94688336], [290.19234245, 291.72785429, 293.3072542, 294.9261612, 296.58129769, 298.27082316, 299.99473025]]]) truth_values_x = np.array([-499495.71907062, 98404.43537514, 688589.09865512, 1272690.44926197, 1852009.73516881, 2427525.45740665, 2999932.89862589]) truth_values_y = np.array([-1499865.98780602, -1268717.36799267, -1029139.66048478, -782037.60343652, -528093.95678826, -267710.32566917, -939.10769171]) index = xr.DataArray(range(7), name='index', dims=['index']) data_truth_x = xr.DataArray( truth_values_x, name='x', coords={ 'crs': data['crs'], 'y': (['index'], truth_values_y), 'x': (['index'], truth_values_x), 'index': index, }, dims=['index'] ) data_truth_y = xr.DataArray( truth_values_y, name='y', coords={ 'crs': data['crs'], 'y': (['index'], truth_values_y), 'x': (['index'], truth_values_x), 'index': index, }, dims=['index'] ) data_truth = xr.DataArray( truth_values, name='temperature', coords={ 'time': data['time'], 'isobaric': data['isobaric'], 'index': index, 'crs': data['crs'], 'y': data_truth_y, 'x': data_truth_x }, dims=['time', 'isobaric', 'index'], attrs={'units': 'kelvin'} ) xr.testing.assert_allclose(data_truth, data_cross)
def test_cross_section_dataarray_projection_noop(test_ds_xy): """Test the cross_section function with a projection dataarray.""" data = test_ds_xy['lambert_conformal'] start, end = ((36.46, -112.45), (42.95, -68.74)) data_cross = cross_section(data, start, end, steps=7) xr.testing.assert_identical(data, data_cross)
def metpy_read_wrf_cross(fname, plevels, tidx_in, lons_out, lats_out, start, end): ds = xr.open_dataset(fname).metpy.parse_cf().squeeze() ds = ds.isel(Time=tidx) print(ds) ds1 = xr.Dataset() p = units.Quantity(to_np(ds.p), 'hPa') z = units.Quantity(to_np(ds.z), 'meter') u = units.Quantity(to_np(ds.u), 'm/s') v = units.Quantity(to_np(ds.v), 'm/s') w = units.Quantity(to_np(ds.w), 'm/s') tk = units.Quantity(to_np(ds.tk), 'kelvin') th = units.Quantity(to_np(ds.th), 'kelvin') eth = units.Quantity(to_np(ds.eth), 'kelvin') wspd = units.Quantity(to_np(ds.wspd), 'm/s') omega = units.Quantity(to_np(ds.omega), 'Pa/s') plevels_unit = plevels * units.hPa z, u, v, w, tk, th, eth, wspd, omega = log_interpolate_1d(plevels_unit, p, z, u, v, w, tk, th, eth, wspd, omega, axis=0) coords, dims = [plevs, ds.lat.values, ds.lon.values], ["level", "lat", "lon"] for name, var in zip( ['z', 'u', 'v', 'w', 'tk', 'th', 'eth', 'wspd', 'omega'], [z, u, v, w, tk, th, eth, wspd, omega]): #g = ndimage.gaussian_filter(var, sigma=3, order=0) ds1[name] = xr.DataArray(to_np(mpcalc.smooth_n_point(var, 9)), coords=coords, dims=dims) dx, dy = mpcalc.lat_lon_grid_deltas(ds.lon.values * units('degrees_E'), ds.lat.values * units('degrees_N')) # Calculate temperature advection using metpy function for i, plev in enumerate(plevs): adv = mpcalc.advection(eth[i, :, :], [u[i, :, :], v[i, :, :]], (dx, dy), dim_order='yx') * units('K/sec') adv = ndimage.gaussian_filter(adv, sigma=3, order=0) * units('K/sec') ds1['eth_adv_{:03d}'.format(plev)] = xr.DataArray( np.array(adv), coords=[ds.lat.values, ds.lon.values], dims=["lat", "lon"]) div = mpcalc.divergence(u[i, :, :], v[i, :, :], dx, dy, dim_order='yx') div = ndimage.gaussian_filter(div, sigma=3, order=0) * units('1/sec') ds1['div_{:03d}'.format(plev)] = xr.DataArray( np.array(div), coords=[ds.lat.values, ds.lon.values], dims=["lat", "lon"]) ds1['accrain'] = xr.DataArray(ds.accrain.values, coords=[ds.lat.values, ds.lon.values], dims=["lat", "lon"]) eth2 = mpcalc.equivalent_potential_temperature( ds.slp.values * units.hPa, ds.t2m.values * units('K'), ds.td2.values * units('celsius')) ds1['eth2'] = xr.DataArray(eth2, coords=[ds.lat.values, ds.lon.values], dims=["lat", "lon"]) #ds1['sst'] = xr.DataArray(ndimage.gaussian_filter(ds.sst.values, sigma=3, order=0)-273.15, coords=[ds.lat.values,ds.lon.values], dims=["lat","lon"]) ds1 = ds1.metpy.parse_cf().squeeze() cross = cross_section(ds1, start, end).set_coords(('lat', 'lon')) cross.u.attrs['units'] = 'm/s' cross.v.attrs['units'] = 'm/s' cross['t_wind'], cross['n_wind'] = mpcalc.cross_section_components( cross['u'], cross['v']) weights = np.cos(np.deg2rad(ds.lat)) ds_weighted = ds.weighted(weights) weighted = ds_weighted.mean(("lat")) return ds1, cross, weighted
def Crosssection_Wind_Theta_e_Qv( initTime=None, fhour=24, levels=[1000, 950, 925, 900, 850, 800, 700,600,500,400,300,200], day_back=0,model='GRAPES_GFS',data_source='MICAPS', lw_ratio=[16,9], output_dir=None, st_point = [20, 120.0], ed_point = [50, 130.0], map_extent=[70,140,15,55], h_pos=[0.125, 0.665, 0.25, 0.2],**kwargs ): if(data_source == 'MICAPS'): try: data_dir = [utl.Cassandra_dir(data_type='high',data_source=model,var_name='RH',lvl=''), utl.Cassandra_dir(data_type='high',data_source=model,var_name='UGRD',lvl=''), utl.Cassandra_dir(data_type='high',data_source=model,var_name='VGRD',lvl=''), utl.Cassandra_dir(data_type='high',data_source=model,var_name='TMP',lvl=''), utl.Cassandra_dir(data_type='high',data_source=model,var_name='HGT',lvl='500'), utl.Cassandra_dir(data_type='surface',data_source=model,var_name='PSFC')] except KeyError: raise ValueError('Can not find all directories needed') # get filename if(initTime != None): filename = utl.model_filename(initTime, fhour) else: filename=utl.filename_day_back_model(day_back=day_back,fhour=fhour) # retrieve data from micaps server rh=get_model_3D_grid(directory=data_dir[0][0:-1],filename=filename,levels=levels, allExists=False) u=get_model_3D_grid(directory=data_dir[1][0:-1],filename=filename,levels=levels, allExists=False) v=get_model_3D_grid(directory=data_dir[2][0:-1],filename=filename,levels=levels, allExists=False) v2=get_model_3D_grid(directory=data_dir[2][0:-1],filename=filename,levels=levels, allExists=False) t=get_model_3D_grid(directory=data_dir[3][0:-1],filename=filename,levels=levels, allExists=False) gh=get_model_grid(data_dir[4], filename=filename) psfc=get_model_grid(data_dir[5], filename=filename) if(data_source == 'CIMISS'): # get filename if(initTime != None): filename = utl.model_filename(initTime, fhour,UTC=True) else: filename=utl.filename_day_back_model(day_back=day_back,fhour=fhour,UTC=True) try: rh=CMISS_IO.cimiss_model_3D_grid(init_time_str='20'+filename[0:8],valid_time=fhour, data_code=utl.CMISS_data_code(data_source=model,var_name='RHU'), fcst_levels=levels, fcst_ele="RHU", units='%') u=CMISS_IO.cimiss_model_3D_grid(init_time_str='20'+filename[0:8],valid_time=fhour, data_code=utl.CMISS_data_code(data_source=model,var_name='WIU'), fcst_levels=levels, fcst_ele="WIU", units='m/s') v=CMISS_IO.cimiss_model_3D_grid(init_time_str='20'+filename[0:8],valid_time=fhour, data_code=utl.CMISS_data_code(data_source=model,var_name='WIV'), fcst_levels=levels, fcst_ele="WIV", units='m/s') v2=CMISS_IO.cimiss_model_3D_grid(init_time_str='20'+filename[0:8],valid_time=fhour, data_code=utl.CMISS_data_code(data_source=model,var_name='WIV'), fcst_levels=levels, fcst_ele="WIV", units='m/s') t=CMISS_IO.cimiss_model_3D_grid(init_time_str='20'+filename[0:8],valid_time=fhour, data_code=utl.CMISS_data_code(data_source=model,var_name='TEM'), fcst_levels=levels, fcst_ele="TEM", units='K') t['data'].values=t['data'].values-273.15 gh=CMISS_IO.cimiss_model_by_time('20'+filename[0:8],valid_time=fhour, data_code=utl.CMISS_data_code(data_source=model,var_name='GPH'), fcst_level=500, fcst_ele="GPH", units='gpm') gh['data'].values=gh['data'].values/10. psfc=CMISS_IO.cimiss_model_by_time('20'+filename[0:8], valid_time=fhour, data_code=utl.CMISS_data_code(data_source=model,var_name='PRS'), fcst_level=0, fcst_ele="PRS", units='Pa') psfc['data']=psfc['data']/100. except KeyError: raise ValueError('Can not find all data needed') rh = rh.metpy.parse_cf().squeeze() u = u.metpy.parse_cf().squeeze() v = v.metpy.parse_cf().squeeze() v2 = v2.metpy.parse_cf().squeeze() psfc=psfc.metpy.parse_cf().squeeze() t = t.metpy.parse_cf().squeeze() resolution=u['lon'][1]-u['lon'][0] x,y=np.meshgrid(u['lon'], u['lat']) # +form 3D psfc mask1 = ( (psfc['lon']>=t['lon'].values.min())& (psfc['lon']<=t['lon'].values.max())& (psfc['lat']>=t['lat'].values.min())& (psfc['lat']<=t['lat'].values.max()) ) t2,psfc_bdcst=xr.broadcast(t['data'],psfc['data'].where(mask1, drop=True)) mask2=(psfc_bdcst > -10000) psfc_bdcst=psfc_bdcst.where(mask2, drop=True) # -form 3D psfc dx,dy=mpcalc.lat_lon_grid_deltas(u['lon'],u['lat']) #rh=rh.rename(dict(lat='latitude',lon='longitude')) cross = cross_section(rh, st_point, ed_point) cross_rh=cross.set_coords(('lat', 'lon')) cross = cross_section(u, st_point, ed_point) cross_u=cross.set_coords(('lat', 'lon')) cross = cross_section(v, st_point, ed_point) cross_v=cross.set_coords(('lat', 'lon')) cross_psfc = cross_section(psfc_bdcst, st_point, ed_point) cross_u['data'].attrs['units']=units.meter/units.second cross_v['data'].attrs['units']=units.meter/units.second cross_u['t_wind'], cross_v['n_wind'] = mpcalc.cross_section_components(cross_u['data'],cross_v['data']) cross = cross_section(t, st_point, ed_point) cross_t=cross.set_coords(('lat', 'lon')) cross_Td = mpcalc.dewpoint_rh(cross_t['data'].values*units.celsius, cross_rh['data'].values* units.percent) rh,pressure = xr.broadcast(cross_rh['data'],cross_t['level']) pressure.attrs['units']='hPa' Qv = mpcalc.specific_humidity_from_dewpoint(cross_Td, pressure) cross_Qv = xr.DataArray(np.array(Qv)*1000., coords=cross_rh['data'].coords, dims=cross_rh['data'].dims, attrs={'units': units('g/kg')}) Theta_e=mpcalc.equivalent_potential_temperature(pressure, cross_t['data'].values*units.celsius, cross_Td) cross_terrain=pressure-cross_psfc cross_Theta_e = xr.DataArray(np.array(Theta_e), coords=cross_rh['data'].coords, dims=cross_rh['data'].dims, attrs={'units': Theta_e.units}) crossection_graphics.draw_Crosssection_Wind_Theta_e_Qv( cross_Qv=cross_Qv, cross_Theta_e=cross_Theta_e, cross_u=cross_u, cross_v=cross_v,cross_terrain=cross_terrain,gh=gh, h_pos=h_pos,st_point=st_point,ed_point=ed_point, levels=levels,map_extent=map_extent,lw_ratio=lw_ratio, output_dir=output_dir)