def get_values_on_grid(self, var, lon, lat, **kwargs): z = kwargs.get('z', None) t = kwargs.get('t', None) tinds = None zinds = None bbox = [np.min(np.min(lon)), np.min(np.min(lat)), np.max(np.max(lon)), np.max(np.max(lat))] if z is None: zbounds = z else: zbounds = (np.min(np.min(np.min(np.min(z)))), np.max(np.max(np.max(np.max(z)))),) if t is None: tbounds = t else: if True: tbounds = None timeinds = np.arange(t[0], t[-1]+1) else: tbounds = (t[0], t[-1]) method = kwargs.get('method', 'nearest') raw_vals = self.get_values(var, zbounds=zbounds, bbox=bbox, timeinds=tinds, zinds=zinds, timebounds=tbounds) coords_struct = self.sub_coords(var, zbounds=zbounds, bbox=bbox, timeinds=tinds, zinds=zinds, timebounds=tbounds) interpolator = CfGeoInterpolator(raw_vals, coords_struct.x, coords_struct.y, z=coords_struct.z, t=coords_struct.time, method=method) return interpolator.interpgrid(lon, lat, t=t, z=z)
def test_interpolator_2d(self): lonbounds = [-70, -60] latbounds = [40, 50] nx, ny = 50, 50 lon, lat = create_grid(lonbounds[0], lonbounds[1], latbounds[0], latbounds[1], nx=50, ny=50) data = np.random.rand(50, 50) i = CfGeoInterpolator(data, lon, lat, method='nearest') data2 = i.interpgrid(lon, lat) assert np.all(data==data2)
def test_interpolator_3d_3dz_1dll(self): lonbounds = [-70, -60] latbounds = [40, 50] nx, ny = 50, 50 lon, lat = create_grid(lonbounds[0], lonbounds[1], latbounds[0], latbounds[1], nx=50, ny=50) data = np.random.rand(10, 50, 50) z, dummy, dummy2 = np.meshgrid(np.arange(10), lon, lat, indexing='ij') i = CfGeoInterpolator(data, lon, lat, z=z, method='nearest') data2 = i.interpgrid(lon, lat, z=z) assert np.all(data==data2)
def test_interpolator_3d_1dt_1dz_1dll(self): lonbounds = [-70, -60] latbounds = [40, 50] nx, ny = 50, 50 lon, lat = create_grid(lonbounds[0], lonbounds[1], latbounds[0], latbounds[1], nx=50, ny=50) data = np.random.rand(9, 10, 50, 50) z = np.arange(10) t = np.arange(9) i = CfGeoInterpolator(data, lon, lat, z=z, t=t, method='nearest') data2 = i.interpgrid(lon, lat, z=z, t=t) assert np.all(data==data2)
def test_interpolator_2d(self): lonbounds = [-70, -60] latbounds = [40, 50] nx, ny = 50, 50 lon, lat = create_grid(lonbounds[0], lonbounds[1], latbounds[0], latbounds[1], nx=50, ny=50) data = np.random.rand(50, 50) i = CfGeoInterpolator(data, lon, lat, method='nearest') data2 = i.interpgrid(lon, lat) assert np.all(data == data2)
def test_interpolator_3d_3dz_1dll(self): lonbounds = [-70, -60] latbounds = [40, 50] nx, ny = 50, 50 lon, lat = create_grid(lonbounds[0], lonbounds[1], latbounds[0], latbounds[1], nx=50, ny=50) data = np.random.rand(10, 50, 50) z, dummy, dummy2 = np.meshgrid(np.arange(10), lon, lat, indexing='ij') i = CfGeoInterpolator(data, lon, lat, z=z, method='nearest') data2 = i.interpgrid(lon, lat, z=z) assert np.all(data == data2)
def test_interpolator_3d_1dt_1dz_1dll(self): lonbounds = [-70, -60] latbounds = [40, 50] nx, ny = 50, 50 lon, lat = create_grid(lonbounds[0], lonbounds[1], latbounds[0], latbounds[1], nx=50, ny=50) data = np.random.rand(9, 10, 50, 50) z = np.arange(10) t = np.arange(9) i = CfGeoInterpolator(data, lon, lat, z=z, t=t, method='nearest') data2 = i.interpgrid(lon, lat, z=z, t=t) assert np.all(data == data2)
def regrid_roms(newfile, filename, lon_new, lat_new, t=None, z=None): '''Function to regrid the entire roms datasets (all values on non-rho coords) onto an arbitrary grid to support regridding on to regular grids as well. ''' with pw.new(newfile) as new: with netCDF4.Dataset(filename) as nc: for key in nc.variables: try: if "since" in nc.variables[key].units: time = nc.variables[key][:] except AttributeError: pass # Identify the rho coordinates, and get them lon_rho = nc.variables["lon_rho"][:] lat_rho = nc.variables["lat_rho"][:] rho_y, rho_x = lat_rho.shape depth_rho = nc.variables["s_rho"][:] #depth_w = nc.variables["s_w"][:] if t == None: t = time # Put dimensions into the new netcdf file, should only be for # time, rhos, psis (not sure what to do about w yet) if len(depth_rho.shape) == 4: s_rho = depth_rho.shape[1] else: s_rho = depth_rho.shape[0] if len(lon_new.shape) == 2 and len(lon_new.shape) == 2: eta_new = lat_new.shape[0] xi_new = lon_new.shape[1] elif len(lon_new.shape) == 1 and len(lon_new.shape) == 1: eta_new = lat_new.shape[0] xi_new = lon_new.shape[0] else: raise ValueError("New lat and lon have invalid shapes or don't match in shape.") if z == None: z = depth_rho s_new = z.shape[0] time_new = t.shape[0] # [pw.add_attribute(new, at, new.getncattr(at)) for at in new.ncattrs()] pw.add_coordinates(new, OrderedDict([("time_new",time_new),("s_new",s_new),("eta_new",eta_new),("xi_new",xi_new)])) # print("Coordinates " + str([("time_new",time_new),("s_new",s_new),("eta_new",eta_new),("xi_new",xi_new)])) pw.add_variable(new, "ocean_time", t, ("time_new",)) pw.add_variable(new, "s_new", z, ("s_new",)) if len(lon_new.shape) == 2 and len(lat_new.shape) == 2: pw.add_variable(new, "lat_new", lat_new, ("eta_new", "xi_new",)) pw.add_variable(new, "lon_new", lon_new, ("eta_new", "xi_new",)) elif len(lon_new.shape) == 1 and len(lat_new.shape) == 1: pw.add_variable(new, "lat_new", lat_new, ("eta_new",)) pw.add_variable(new, "lon_new", lon_new, ("xi_new",)) # Identify variables that aren't coordinates, and their native grids, # convert non-rho variables to rho with `average_adjacents`. Create # sequence of rho-based variables in `roms_variables` object for key in nc.variables: var = nc.variables[key] try: if key == "w": if z == None: z = depth_w grid_type = "rho" else: if "_psi" in var.coordinates: grid_type = "psi" elif "_u" in var.coordinates: grid_type = "u" elif "_v" in var.coordinates: grid_type = "v" else: grid_type = "rho" except AttributeError: grid_type = None if grid_type != None and grid_type != "psi": if key in set([ "sustr", "bustr", "DU_avg1", "DU_avg2", "u", "w", "ubar", "mask_u", "mask_v", "mask_psi", "mask_rho" ]): pass elif grid_type == "v": var_dimensionality = len(var.shape) if "sv" in key or "bv" in key or "DV" in key or key == "vbar" or key == "v": paired_vector = {"svstr":"sustr", "bvstr":"bustr", "DV_avg1":"DU_avg1", "DV_avg2":"DU_avg2", "vbar":"ubar", "v":"u"} for i in range(var.shape[0]): if var_dimensionality == 3: complex_uv = _uv_to_rho(nc.variables[paired_vector[key]][i,:,:], var[i,:,:], nc.variables["angle"][:], rho_x, rho_y) uz, vz = complex_uv.real, complex_uv.imag elif var_dimensionality == 4: for j in range(var.shape[1]): complex_uv = _uv_to_rho(nc.variables["u"][i,j,:,:], var[i,j,:,:], nc.variables["angle"][:], rho_x, rho_y) if j == 0: uz, vz = complex_uv.real[np.newaxis,:], complex_uv.imag[np.newaxis,:] else: uz = np.vstack((uz, complex_uv.real[np.newaxis,:])) vz = np.vstack((vz, complex_uv.imag[np.newaxis,:])) if i == 0: u, v = uz[np.newaxis,:], vz[np.newaxis,:] else: u = np.vstack((u, uz[np.newaxis,:])) v = np.vstack((v, vz[np.newaxis,:])) values = {paired_vector[key]:u, key:v} for new_key in values: values_interp[:, np.where(nc.variables["mask_rho"]==0)] = np.nan if var_dimensionality == 3: interpolator = CfGeoInterpolator(values[new_key], lon_rho, lat_rho, t=time) values_interp = interpolator.interpgrid(lon_new, lat_new, t=t) coordtuple = ("time_new", "eta_new", "xi_new",) coordattr = "ocean_time lat_new lon_new" elif var_dimensionality == 4: interpolator = CfGeoInterpolator(values[new_key], lon_rho, lat_rho, t=time, z=depth_rho) values_interp = interpolator.interpgrid(lon_new, lat_new, t=t, z=z) coordtuple = ("time_new", "s_new", "eta_new", "xi_new",) coordattr = "ocean_time s_new lat_new lon_new" values_interp = np.ma.MaskedArray(values_interp, mask=values_interp==np.nan) pw.add_variable(new, new_key, values_interp, coordtuple) [pw.add_attribute(new, at, nc.variables[new_key].getncattr(at), var=new_key) for at in nc.variables[new_key].ncattrs()] pw.add_attribute(new, "coordinates", coordattr, var=new_key) else: var_dimensionality = len(var.shape) vartmp = var[:] if var_dimensionality == 4: vartmp[:,:, np.where(nc.variables["mask_rho"]==0)] = np.nan interpolator = CfGeoInterpolator(vartmp, lon_rho, lat_rho, t=time, z=depth_rho) values_interp = interpolator.interpgrid(lon_new, lat_new, t=t, z=z) pw.add_variable(new, key, values_interp, ("time_new", "s_new", "eta_new", "xi_new",)) [pw.add_attribute(new, at, nc.variables[key].getncattr(at), var=key) for at in nc.variables[key].ncattrs()] pw.add_attribute(new, "coordinates", "ocean_time s_new lat_new lon_new", var=key) elif var_dimensionality == 3: vartmp[:, np.where(nc.variables["mask_rho"]==0)] = np.nan if var.shape[0] == time.shape[0]: try: interpolator = CfGeoInterpolator(vartmp, lon_rho, lat_rho, t=time) values_interp = interpolator.interpgrid(lon_new, lat_new, t=t) values_interp = np.ma.MaskedArray(values_interp, mask=values_interp==np.nan) pw.add_variable(new, key, values_interp, ("time_new", "eta_new", "xi_new",)) [pw.add_attribute(new, at, nc.variables[key].getncattr(at), var=key) for at in nc.variables[key].ncattrs()] pw.add_attribute(new, "coordinates", "ocean_time lat_new lon_new", var=key) except: print(key, vartmp.shape, lon_rho.shape, lat_rho.shape, time.shape) elif var.shape[0] == depth_rho.shape[0]: interpolator = CfGeoInterpolator(vartmp, lon_rho, lat_rho, z=depth_rho) values_interp = interpolator.interpgrid(lon_new, lat_new, z=z) values_interp = np.ma.MaskedArray(values_interp, mask=values_interp==np.nan) pw.add_variable(new, key, values_interp, ("depth_new", "eta_new", "xi_new",)) [pw.add_attribute(new, at, nc.variables[key].getncattr(at), var=key) for at in nc.variables[key].ncattrs()] pw.add_attribute(new, "coordinates", "s_new lat_new lon_new", var=key) else: raise ValueError("unsure about what dimension this variable varies with in addition to lat/lon.") elif var_dimensionality == 2: vartmp[np.where(nc.variables["mask_rho"]==0)] = np.nan interpolator = CfGeoInterpolator(vartmp, lon_rho, lat_rho) values_interp = interpolator.interpgrid(lon_new, lat_new) values_interp = np.ma.MaskedArray(values_interp, mask=values_interp==np.nan) pw.add_variable(new, key, values_interp, ("eta_new", "xi_new",)) [pw.add_attribute(new, at, nc.variables[key].getncattr(at), var=key) for at in nc.variables[key].ncattrs()] pw.add_attribute(new, "coordinates", "lat_new lon_new", var=key) else: # todo if 1-d check for which dimension it matches and interp based on that... # if 5+ d, only interpolate to the 4d dimensions that we can specify i guess... raise ValueError("sort of confused about the dimensionality of the variable i am attempting to regrid...") elif grid_type == "psi": pass else: if len(var.dimensions) == 0: pw.add_scalar(new, key, var[:]) [pw.add_attribute(new, at, nc.variables[key].getncattr(at), var=key) for at in nc.variables[key].ncattrs()] # Add time attributes for key in nc.variables: var = nc.variables[key] if "time" in key: [pw.add_attribute(new, at, nc.variables[key].getncattr(at), var="ocean_time") for at in nc.variables[key].ncattrs()] # Add global attributes to the file [pw.add_attribute(new, at, nc.getncattr(at)) for at in nc.ncattrs()] try: new.history = new.history + ", regridded by Python tool 'paegan' at " + str(datetime.datetime.now()) except: new.history = "regridded by Python tool 'paegan' at " + str(datetime.datetime.now()) new.sync()
def regrid_roms(newfile, filename, lon_new, lat_new, t=None, z=None): '''Function to regrid the entire roms datasets (all values on non-rho coords) onto an arbitrary grid to support regridding on to regular grids as well. ''' with pw.new(newfile) as new: with netCDF4.Dataset(filename) as nc: for key in nc.variables: try: if "since" in nc.variables[key].units: time = nc.variables[key][:] except AttributeError: pass # Identify the rho coordinates, and get them lon_rho = nc.variables["lon_rho"][:] lat_rho = nc.variables["lat_rho"][:] rho_y, rho_x = lat_rho.shape depth_rho = nc.variables["s_rho"][:] #depth_w = nc.variables["s_w"][:] if t == None: t = time # Put dimensions into the new netcdf file, should only be for # time, rhos, psis (not sure what to do about w yet) if len(depth_rho.shape) == 4: s_rho = depth_rho.shape[1] else: s_rho = depth_rho.shape[0] if len(lon_new.shape) == 2 and len(lon_new.shape) == 2: eta_new = lat_new.shape[0] xi_new = lon_new.shape[1] elif len(lon_new.shape) == 1 and len(lon_new.shape) == 1: eta_new = lat_new.shape[0] xi_new = lon_new.shape[0] else: raise ValueError("New lat and lon have invalid shapes or don't match in shape.") if z == None: z = depth_rho s_new = z.shape[0] time_new = t.shape[0] #[pw.add_attribute(new, at, new.getncattr(at)) for at in new.ncattrs()] pw.add_coordinates(new, OrderedDict([("time_new",time_new),("s_new",s_new),("eta_new",eta_new),("xi_new",xi_new)])) #print "Coordinates " + str([("time_new",time_new),("s_new",s_new),("eta_new",eta_new),("xi_new",xi_new)]) pw.add_variable(new, "ocean_time", t, ("time_new",)) pw.add_variable(new, "s_new", z, ("s_new",)) if len(lon_new.shape) == 2 and len(lat_new.shape) == 2: pw.add_variable(new, "lat_new", lat_new, ("eta_new", "xi_new",)) pw.add_variable(new, "lon_new", lon_new, ("eta_new", "xi_new",)) elif len(lon_new.shape) == 1 and len(lat_new.shape) == 1: pw.add_variable(new, "lat_new", lat_new, ("eta_new",)) pw.add_variable(new, "lon_new", lon_new, ("xi_new",)) # Identify variables that arn't coordinates, and their native grids, # convert non-rho variables to rho with `average_adjacents`. Create # sequence of rho-based variables in `roms_variables` object for key in nc.variables: var = nc.variables[key] try: if key == "w": if z == None: z = depth_w grid_type = "rho" else: if "_psi" in var.coordinates: grid_type = "psi" elif "_u" in var.coordinates: grid_type = "u" elif "_v" in var.coordinates: grid_type = "v" else: grid_type = "rho" except AttributeError: grid_type = None if grid_type != None and grid_type != "psi": if key in set([ "sustr", "bustr", "DU_avg1", "DU_avg2", "u", "w", "ubar", "mask_u", "mask_v", "mask_psi", "mask_rho" ]): pass elif grid_type == "v": var_dimensionality = len(var.shape) if "sv" in key or "bv" in key or "DV" in key or key == "vbar" or key == "v": paired_vector = {"svstr":"sustr", "bvstr":"bustr", "DV_avg1":"DU_avg1", "DV_avg2":"DU_avg2", "vbar":"ubar", "v":"u"} for i in xrange(var.shape[0]): if var_dimensionality == 3: complex_uv = _uv_to_rho(nc.variables[paired_vector[key]][i,:,:], var[i,:,:], nc.variables["angle"][:], rho_x, rho_y) uz, vz = complex_uv.real, complex_uv.imag elif var_dimensionality == 4: for j in xrange(var.shape[1]): complex_uv = _uv_to_rho(nc.variables["u"][i,j,:,:], var[i,j,:,:], nc.variables["angle"][:], rho_x, rho_y) if j == 0: uz, vz = complex_uv.real[np.newaxis,:], complex_uv.imag[np.newaxis,:] else: uz = np.vstack((uz, complex_uv.real[np.newaxis,:])) vz = np.vstack((vz, complex_uv.imag[np.newaxis,:])) if i == 0: u, v = uz[np.newaxis,:], vz[np.newaxis,:] else: u = np.vstack((u, uz[np.newaxis,:])) v = np.vstack((v, vz[np.newaxis,:])) values = {paired_vector[key]:u, key:v} for new_key in values: values_interp[:, np.where(nc.variables["mask_rho"]==0)] = np.nan if var_dimensionality == 3: interpolator = CfGeoInterpolator(values[new_key], lon_rho, lat_rho, t=time) values_interp = interpolator.interpgrid(lon_new, lat_new, t=t) coordtuple = ("time_new", "eta_new", "xi_new",) coordattr = "ocean_time lat_new lon_new" elif var_dimensionality == 4: interpolator = CfGeoInterpolator(values[new_key], lon_rho, lat_rho, t=time, z=depth_rho) values_interp = interpolator.interpgrid(lon_new, lat_new, t=t, z=z) coordtuple = ("time_new", "s_new", "eta_new", "xi_new",) coordattr = "ocean_time s_new lat_new lon_new" values_interp = np.ma.MaskedArray(values_interp, mask=values_interp==np.nan) pw.add_variable(new, new_key, values_interp, coordtuple) [pw.add_attribute(new, at, nc.variables[new_key].getncattr(at), var=new_key) for at in nc.variables[new_key].ncattrs()] pw.add_attribute(new, "coordinates", coordattr, var=new_key) else: var_dimensionality = len(var.shape) vartmp = var[:] if var_dimensionality == 4: vartmp[:,:, np.where(nc.variables["mask_rho"]==0)] = np.nan interpolator = CfGeoInterpolator(vartmp, lon_rho, lat_rho, t=time, z=depth_rho) values_interp = interpolator.interpgrid(lon_new, lat_new, t=t, z=z) pw.add_variable(new, key, values_interp, ("time_new", "s_new", "eta_new", "xi_new",)) [pw.add_attribute(new, at, nc.variables[key].getncattr(at), var=key) for at in nc.variables[key].ncattrs()] pw.add_attribute(new, "coordinates", "ocean_time s_new lat_new lon_new", var=key) elif var_dimensionality == 3: vartmp[:, np.where(nc.variables["mask_rho"]==0)] = np.nan if var.shape[0] == time.shape[0]: try: interpolator = CfGeoInterpolator(vartmp, lon_rho, lat_rho, t=time) values_interp = interpolator.interpgrid(lon_new, lat_new, t=t) values_interp = np.ma.MaskedArray(values_interp, mask=values_interp==np.nan) pw.add_variable(new, key, values_interp, ("time_new", "eta_new", "xi_new",)) [pw.add_attribute(new, at, nc.variables[key].getncattr(at), var=key) for at in nc.variables[key].ncattrs()] pw.add_attribute(new, "coordinates", "ocean_time lat_new lon_new", var=key) except: print key, vartmp.shape, lon_rho.shape, lat_rho.shape, time.shape elif var.shape[0] == depth_rho.shape[0]: interpolator = CfGeoInterpolator(vartmp, lon_rho, lat_rho, z=depth_rho) values_interp = interpolator.interpgrid(lon_new, lat_new, z=z) values_interp = np.ma.MaskedArray(values_interp, mask=values_interp==np.nan) pw.add_variable(new, key, values_interp, ("depth_new", "eta_new", "xi_new",)) [pw.add_attribute(new, at, nc.variables[key].getncattr(at), var=key) for at in nc.variables[key].ncattrs()] pw.add_attribute(new, "coordinates", "s_new lat_new lon_new", var=key) else: raise valueerror("unsure about what dimension this varaible varies with in addition to lat/lon.") elif var_dimensionality == 2: vartmp[np.where(nc.variables["mask_rho"]==0)] = np.nan interpolator = CfGeoInterpolator(vartmp, lon_rho, lat_rho) values_interp = interpolator.interpgrid(lon_new, lat_new) values_interp = np.ma.MaskedArray(values_interp, mask=values_interp==np.nan) pw.add_variable(new, key, values_interp, ("eta_new", "xi_new",)) [pw.add_attribute(new, at, nc.variables[key].getncattr(at), var=key) for at in nc.variables[key].ncattrs()] pw.add_attribute(new, "coordinates", "lat_new lon_new", var=key) else: # todo if 1-d check for which dimension it matches and interp based on that... # if 5+ d, only interpolate to the 4d dimensions that we can specify i guess... raise valueerror("sort of confused about the dimensionality of the variable i am attempting to regrid...") elif grid_type == "psi": pass else: if len(var.dimensions) == 0: pw.add_scalar(new, key, var[:]) [pw.add_attribute(new, at, nc.variables[key].getncattr(at), var=key) for at in nc.variables[key].ncattrs()] # Add time attributes for key in nc.variables: var = nc.variables[key] if "time" in key: [pw.add_attribute(new, at, nc.variables[key].getncattr(at), var="ocean_time") for at in nc.variables[key].ncattrs()] # Add global attributes to the file [pw.add_attribute(new, at, nc.getncattr(at)) for at in nc.ncattrs()] try: new.history = new.history + ", regridded by Python tool 'paegan' at " + str(datetime.datetime.now()) except: new.history = "regridded by Python tool 'paegan' at " + str(datetime.datetime.now()) new.sync()