def test_interpolate_masked_units(): """Test interpolating with masked arrays with units.""" x = np.ma.array([1., 2., 3., 4.]) * units.m y = np.ma.array([50., 60., 70., 80.]) * units.degC x_interp = np.array([250., 350.]) * units.cm y_interp_truth = np.array([65., 75.]) * units.degC y_interp = interpolate_1d(x_interp, x, y) assert_array_almost_equal(y_interp, y_interp_truth, 7)
def test_interpolate_decrease_xp(): """Test interpolation with decreasing order.""" x = np.array([4., 3., 2., 1.]) y = x x_interp = np.array([3.5000000, 2.5000000]) y_interp_truth = np.array([3.5000000, 2.5000000]) y_interp = interpolate_1d(x_interp, x, y) assert_array_almost_equal(y_interp, y_interp_truth, 7)
def test_interpolate_end_point(): """Test interpolation with point at data endpoints.""" x = np.array([1., 2., 3., 4.]) y = x x_interp = np.array([1.0, 4.0]) y_interp_truth = np.array([1.0, 4.0]) y_interp = interpolate_1d(x_interp, x, y) assert_array_almost_equal(y_interp, y_interp_truth, 7)
def test_interpolate_decrease(): """Test interpolation with decreasing interpolation points.""" x = np.array([1., 2., 3., 4.]) y = x x_interp = np.array([3.5000000, 2.5000000]) y_interp_truth = np.array([3.5000000, 2.5000000]) y_interp = interpolate_1d(x_interp, x, y) assert_array_almost_equal(y_interp, y_interp_truth, 7)
def test_interpolate_2args(): """Test interpolation with 2 arguments.""" x = np.array([1., 2., 3., 4.]) y = x y2 = x x_interp = np.array([2.5000000, 3.5000000]) y_interp_truth = np.array([2.5000000, 3.5000000]) y_interp = interpolate_1d(x_interp, x, y, y2) assert_array_almost_equal(y_interp[0], y_interp_truth, 7) assert_array_almost_equal(y_interp[1], y_interp_truth, 7)
def interpolate_vertical(ml_file, inter_file, new_vertical_axis): """ Linearly interpolate all 4D variables of ml_file to the levels of new_vertical_axis and save it in inter_file """ with xr.load_dataset(inter_file) as interpolated: reference = [variable for variable in interpolated.variables if len(interpolated[variable].shape) == 4][0] with xr.open_dataset(ml_file) as ml: for variable in [variable for variable in ml.variables if variable not in interpolated.variables and len(ml[variable].dims) == 4 and "lev_2" in ml[variable].dims]: try: x = np.array(ml[new_vertical_axis].data) y = np.array(ml[variable].data) interpolated_data = interpolate_1d(interpolated["lev"].data, x, y, axis=1) attributes = ml[variable].attrs interpolated[variable] = interpolated[reference].copy(data=interpolated_data) interpolated[variable].attrs = ml[variable].attrs except Exception as e: print(variable, e) interpolated.to_netcdf(inter_file)
def process_tstep(f, itf, regridder, lay_height, fout, itout, z_levels, vars_remaining, filled, conversions, helpers): # Load helper vars for this timestep hlp = Helpers() for helper_name, helper in helpers: data = load_conversion(helper_name, f, (itf, slice(None), regridder.ys, regridder.xs), hlp, **helper) if data is not None: setattr(hlp, helper_name, data) # Load all usable vars for this timestep, regrid horizontally varmeta = [] vardata = [] for spc in list(vars_remaining): conv = conversions[spc] data = load_conversion(spc, f, (itf, slice(None), regridder.ys, regridder.xs), hlp, **conv) if data is None: continue data = regridder.regrid(data) vardata.append(np.r_[data[0:1], data]) #add peg below varmeta.append((spc, conv['output_unit'])) # Perform vertical interpolation on all currently loaded vars at once print('Interpolating vertically...') vinterp = interpolate_1d(z_levels, lay_height, *vardata) if len(vardata) == 1: # return_list_always=True argument is only in later versions of MetPy vinterp = [vinterp] del vardata for (vn, vu), vd in zip(varmeta, vinterp): v = fout.variables[vn] v[itout] = vd v.units = vu filled[vn][itout] = True
### add units ### #p_RS = p_RS * units.hPa #T_RS = T_RS * units.degC #T_d_RS = T_d_RS * units.degC # Variante 2) Interpolate T and Td to pressure levels p_RS = p_RS.values * units.hPa T_RS = T_RS.values * units.degC T_d_RS = T_d_RS.values * units.degC p_RS_original = p_RS_original.values * units.hPa T_RS_original = T_RS_original.values * units.degC T_d_RS_original = T_d_RS_original.values * units.degC T_RS = interpolate_1d(p_NUCAPS, p_RS, T_RS, axis=0) T_d_RS = interpolate_1d(p_NUCAPS, p_RS, T_d_RS, axis=0) p_RS = p_NUCAPS ########################################## ##### D) RALMO: Raman lidar ########################################### RA_data = xr.open_dataset(LIDAR_archive + '/RA_concat_wp').to_dataframe() Time_RA = RS_time + dt.timedelta(minutes=30) RA_data = RA_data[RA_data.time_YMDHMS == int( dt.datetime.strftime(Time_RA, "%Y%m%d%H%M%S"))] RA_data = RA_data[RA_data['temperature_K'] != 1e+07] RA_data = RA_data[[ 'time_YMDHMS', 'altitude_m', 'specific_humidity_gkg-1', 'temperature_K', 'pressure_hPa'
def palm_wrf_vertical_interp(infile, outfile, wrffile, z_levels, z_levels_stag, z_soil_levels, origin_z, terrain, wrf_hybrid_levs, vinterp_terrain_smoothing): zdim = len(z_levels) zwdim = len(z_levels_stag) zsoildim = len(z_soil_levels) dimnames = ['z', 'zw', 'zsoil'] # dimnames of palm vertical dims dimensions = [zdim, zwdim, zsoildim] print("infile: ", infile) print("outfile: ", outfile) try: os.remove(outfile) os.remove(infile + '_vinterp.log') except: pass nc_infile = netCDF4.Dataset(infile, 'r') nc_wrf = netCDF4.Dataset(wrffile, 'r') nc_outfile = netCDF4.Dataset(outfile, "w", format="NETCDF4") nc_outfile.createDimension('Time', None) for dimname in ['west_east', 'south_north', 'soil_layers_stag']: nc_outfile.createDimension(dimname, len(nc_infile.dimensions[dimname])) for i in range(len(dimnames)): nc_outfile.createDimension(dimnames[i], dimensions[i]) # Use hybrid ETA levels in WRF and stretch them so that the WRF terrain # matches either PALM terrain or flat terrain at requested height gpf = nc_infile.variables['PH'][0, :, :, :] + nc_infile.variables['PHB'][ 0, :, :, :] wrfterr = gpf[0] * (1. / g) if vinterp_terrain_smoothing is None: target_terrain = terrain else: print( 'Smoothing PALM terrain for the purpose of dynamic driver with sigma={0} grid points.' .format(vinterp_terrain_smoothing)) target_terrain = ndimage.gaussian_filter( terrain, sigma=vinterp_terrain_smoothing, order=0) print( 'Morphing WRF terrain ({0} ~ {1}) to PALM terrain ({2} ~ {3})'.format( wrfterr.min(), wrfterr.max(), target_terrain.min(), target_terrain.max())) print_dstat('terrain shift', wrfterr - target_terrain[:, :]) # Load original dry air column pressure mu = nc_infile.variables['MUB'][0, :, :] + nc_infile.variables['MU'][ 0, :, :] pht = nc_wrf.variables['P_TOP'][0] # Shift column pressure so that it matches PALM terrain t = wrf_t(nc_infile) mu2 = barom_pres(mu + pht, target_terrain * g, gpf[0, :, :], t[0, :, :]) - pht # Calculate original and shifted 3D dry air pressure if wrf_hybrid_levs: phf, phh = calc_ph_hybrid(nc_wrf, mu) phf2, phh2 = calc_ph_hybrid(nc_wrf, mu2) else: phf, phh = calc_ph_sigma(nc_wrf, mu) phf2, phh2 = calc_ph_sigma(nc_wrf, mu2) # Shift 3D geopotential according to delta dry air pressure tf = np.concatenate((t, t[-1:, :, :]), axis=0) # repeat highest layer gpf2 = barom_gp(gpf, phf2, phf, tf) # For half-levs, originate from gp full levs rather than less accurate gp halving gph2 = barom_gp(gpf[:-1, :, :], phh2, phf[:-1, :, :], t) zf = gpf2 * (1. / g) - origin_z zh = gph2 * (1. / g) - origin_z # Report gpdelta = gpf2 - gpf print('GP deltas by level:') for k in range(gpf.shape[0]): print_dstat(k, gpdelta[k]) # Because we require levels below the lowest level from WRF, we will always # add one layer at zero level with repeated values from the lowest level. # WRF-python had some special treatment for theta in this case. height = np.zeros((zh.shape[0] + 1, ) + zh.shape[1:], dtype=zh.dtype) height[0, :, :] = -999. #always below terrain height[1:, :, :] = zh heightw = np.zeros((zf.shape[0] + 1, ) + zf.shape[1:], dtype=zf.dtype) heightw[0, :, :] = -999. #always below terrain heightw[1:, :, :] = zf # ======================== SPECIFIC HUMIDITY ============================== qv_raw = nc_infile.variables['SPECHUM'][0] qv_raw = np.r_[qv_raw[0:1], qv_raw] # Vertical interpolation to grid height levels (specified in km!) # Levels start at 50m (below that the interpolation looks very sketchy) init_atmosphere_qv = interpolate_1d(z_levels, height, qv_raw) vdata = nc_outfile.createVariable( 'init_atmosphere_qv', "f4", ("Time", "z", "south_north", "west_east")) vdata[0, :, :, :] = init_atmosphere_qv del init_atmosphere_qv # !!!! bug3, save memory # ======================= POTENTIAL TEMPERATURE ========================== pt_raw = nc_infile.variables['T'][ 0] + 300. # from perturbation pt to standard pt_raw = np.r_[pt_raw[0:1], pt_raw] init_atmosphere_pt = interpolate_1d(z_levels, height, pt_raw) #plt.figure(); plt.contourf(pt[0]) ; plt.colorbar() ; plt.show() vdata = nc_outfile.createVariable( 'init_atmosphere_pt', "f4", ("Time", "z", "south_north", "west_east")) vdata[0, :, :, :] = init_atmosphere_pt del init_atmosphere_pt # !!!! bug3, save memory # ======================= Wind ========================================== u_raw = nc_infile.variables['U'][0] u_raw = np.r_[u_raw[0:1], u_raw] init_atmosphere_u = interpolate_1d(z_levels, height, u_raw) vdata = nc_outfile.createVariable( 'init_atmosphere_u', "f4", ("Time", "z", "south_north", "west_east")) vdata[0, :, :, :] = init_atmosphere_u del init_atmosphere_u # !!!! bug3, save memory v_raw = nc_infile.variables['V'][0] v_raw = np.r_[v_raw[0:1], v_raw] init_atmosphere_v = interpolate_1d(z_levels, height, v_raw) vdata = nc_outfile.createVariable( 'init_atmosphere_v', "f4", ("Time", "z", "south_north", "west_east")) #vdata.coordinates = "XLONG_V XLAT_V XTIME" vdata[0, :, :, :] = init_atmosphere_v del init_atmosphere_v # !!!! bug3, save memory w_raw = nc_infile.variables['W'][0] w_raw = np.r_[w_raw[0:1], w_raw] init_atmosphere_w = interpolate_1d(z_levels_stag, heightw, w_raw) vdata = nc_outfile.createVariable( 'init_atmosphere_w', "f4", ("Time", "zw", "south_north", "west_east")) #vdata.coordinates = "XLONG XLAT XTIME" vdata[0, :, :, :] = init_atmosphere_w del init_atmosphere_w # !!!! bug3, save memory # ===================== SURFACE PRESSURE ================================== surface_forcing_surface_pressure = nc_infile.variables['PSFC'] vdata = nc_outfile.createVariable('surface_forcing_surface_pressure', "f4", ("Time", "south_north", "west_east")) vdata[0, :, :] = surface_forcing_surface_pressure[0, :, :] del surface_forcing_surface_pressure # !!!! bug3, save memory # ======================== SOIL VARIABLES (without vertical interpolation) ============= # soil temperature init_soil_t = nc_infile.variables['TSLB'] vdata = nc_outfile.createVariable( 'init_soil_t', "f4", ("Time", "zsoil", "south_north", "west_east")) vdata[0, :, :, :] = init_soil_t[0, :, :, :] del init_soil_t # !!!! bug3, save memory # soil moisture init_soil_m = nc_infile.variables['SMOIS'] vdata = nc_outfile.createVariable( 'init_soil_m', "f4", ("Time", "zsoil", "south_north", "west_east")) vdata[0, :, :, :] = init_soil_m[0, :, :, :] del init_soil_m # !!!! bug3, save memory # zsoil zsoil = nc_wrf.variables[ 'ZS'] #ZS:description = "DEPTHS OF CENTERS OF SOIL LAYERS" ; vdata = nc_outfile.createVariable('zsoil', "f4", ("zsoil")) vdata[:] = zsoil[0, :] # coordinates z, zw vdata = nc_outfile.createVariable('z', "f4", ("z")) vdata[:] = list(z_levels) vdata = nc_outfile.createVariable('zw', "f4", ("zw")) vdata[:] = list(z_levels_stag) # zsoil is taken from wrf - not need to define it nc_infile.close() nc_wrf.close() nc_outfile.close()
station = "AMA" lapseC = 2 * units.kelvin / units.km height = False pFull, TFull = grabSounding(date, station) pInterp = np.arange(pFull[0].m, pFull[1].m, (pFull[1].m - pFull[0].m) / 10.0) * units.mbar for i in range(1, pFull.size - 1): if pFull[i + 1] - pFull[i] != 0: tmp = np.arange(pFull[i].m, pFull[i + 1].m, (pFull[i + 1].m - pFull[i].m) / 10.0) * units.mbar pInterp = np.concatenate((pInterp, tmp)) TInterp = interpolate_1d(pInterp, pFull, TFull) if calculateTrop: print("WMO: ", tropCalc(pFull, TFull, lapseC=lapseC, height=height, method="wmo")) print( "Birner: ", tropCalc(pFull, TFull, lapseC=lapseC, height=height, method="birner")) print("Coldest Point: ", tropCalc(pFull, TFull, lapseC=lapseC, height=height, method="cp")) print( "WMO (interp): ", tropCalc(pInterp, TInterp, lapseC=lapseC, height=height, method="wmo")) print( "Birner: (interp) ",