def demo_arctic_proj(): rll = RotatedLatLon(lon1=60, lat1=90, lon2=-30, lat2=0) print(rll.get_north_pole_coords(), rll.get_true_pole_coords_in_rotated_system()) pass
def __get_lons_lats_basemap_from_rpn(path=DEFAULT_PATH_FOR_GEO_DATA, vname="STBM", region_of_interest_shp=None, **bmp_kwargs): """ :param path: :param vname: :return: get basemap object for the variable in the given file """ with RPN(str(path)) as r: _ = r.variables[vname][:] proj_params = r.get_proj_parameters_for_the_last_read_rec() lons, lats = r.get_longitudes_and_latitudes_for_the_last_read_rec() rll = RotatedLatLon(**proj_params) if region_of_interest_shp is not None: mask = get_mask(lons, lats, region_of_interest_shp) delta_points = 10 i_arr, j_arr = np.where(mask >= 0.5) i_min, i_max = i_arr.min() - delta_points, i_arr.max() + delta_points j_min, j_max = j_arr.min() - delta_points, j_arr.max() + delta_points slices = (slice(i_min, i_max + 1), slice(j_min, j_max + 1)) bmp = rll.get_basemap_object_for_lons_lats(lons2d=lons[slices], lats2d=lats[slices], **bmp_kwargs) else: bmp = rll.get_basemap_object_for_lons_lats(lons2d=lons, lats2d=lats, **bmp_kwargs) return lons, lats, bmp
def plot_only_vegetation_fractions( data_path="/RESCUE/skynet3_rech1/huziy/geof_lake_infl_exp/geophys_Quebec_0.1deg_260x260_with_dd_v6_with_ITFS", canopy_name="VF", label="QC_10km"): r = RPN(data_path) veg_fractions = r.get_2D_field_on_all_levels(name=canopy_name) print(list(veg_fractions.keys())) proj_params = r.get_proj_parameters_for_the_last_read_rec() lons, lats = r.get_longitudes_and_latitudes_for_the_last_read_rec() print(lons.shape) rll = RotatedLatLon(lon1=proj_params["lon1"], lat1=proj_params["lat1"], lon2=proj_params["lon2"], lat2=proj_params["lat2"]) lon0, lat0 = rll.get_true_pole_coords_in_rotated_system() plon, _ = rll.get_north_pole_coords() b = Basemap(projection="rotpole", llcrnrlon=lons[0, 0], llcrnrlat=lats[0, 0], urcrnrlon=lons[-1, -1], urcrnrlat=lats[-1, -1], lon_0=lon0 - 180, o_lon_p=lon0, o_lat_p=lat0) lons[lons > 180] -= 360 for lev in list(veg_fractions.keys()): veg_fractions[lev] = maskoceans(lons, lats, veg_fractions[lev], inlands=False) x, y = b(lons, lats) plot_veg_fractions(x, y, b, veg_fractions, out_image=os.path.join(os.path.dirname(data_path), "veg_fractions_{0}.png".format(label)))
def get_lons_lats_basemap(rpnfile_path="", varname=None, index_subset=None): """ Get longitudes, latitudes and the basemap object corresponding to the rpn file :param rpnfile_path: :param varname: :return: """ with RPN(rpnfile_path) as r: assert isinstance(r, RPN) if varname is None: varname = next(v for v in r.get_list_of_varnames() if v not in [">>", "^^", "HY"]) r.get_first_record_for_name(varname) lons, lats = r.get_longitudes_and_latitudes_for_the_last_read_rec() nx, ny = lons.shape if index_subset is None: index_subset = IndexSubspace(i_start=0, i_end=nx - 1, j_start=0, j_end=ny - 1) rll = RotatedLatLon(**r.get_proj_parameters_for_the_last_read_rec()) bmp = rll.get_basemap_object_for_lons_lats( lons2d=lons[index_subset.get_islice(), index_subset.get_jslice()], lats2d=lats[index_subset.get_islice(), index_subset.get_jslice()]) return lons, lats, bmp
def __get_lons_lats_basemap_from_rpn(path=DEFAULT_PATH_FOR_GEO_DATA, vname="STBM", region_of_interest_shp=None, **bmp_kwargs): """ :param path: :param vname: :return: get basemap object for the variable in the given file """ with RPN(str(path)) as r: _ = r.variables[vname][:] proj_params = r.get_proj_parameters_for_the_last_read_rec() lons, lats = r.get_longitudes_and_latitudes_for_the_last_read_rec() rll = RotatedLatLon(**proj_params) if region_of_interest_shp is not None: mask = get_mask(lons, lats, region_of_interest_shp) delta_points = 10 i_arr, j_arr = np.where(mask >= 0.5) i_min, i_max = i_arr.min() - delta_points, i_arr.max() + delta_points j_min, j_max = j_arr.min() - delta_points, j_arr.max() + delta_points slices = (slice(i_min,i_max + 1), slice(j_min,j_max + 1)) bmp = rll.get_basemap_object_for_lons_lats(lons2d=lons[slices], lats2d=lats[slices], **bmp_kwargs) else: bmp = rll.get_basemap_object_for_lons_lats(lons2d=lons, lats2d=lats, **bmp_kwargs) return lons, lats, bmp
def main( path="/skynet3_rech1/huziy/geof_lake_infl_exp/geophys_Quebec_0.1deg_260x260_with_dd_v6_with_ITFS" ): r = RPN(path) varnames = ["ITFS"] ncols = 3 nrows = len(varnames) // 3 fig = plt.figure() varname_to_field = {} for vname in varnames: data = r.get_first_record_for_name(vname) varname_to_field[vname] = data data = np.ma.masked_where(data < 0, data) lons2d, lats2d = r.get_longitudes_and_latitudes_for_the_last_read_rec() params = r.get_proj_parameters_for_the_last_read_rec() print(params) rll = RotatedLatLon(**params) b = rll.get_basemap_object_for_lons_lats(lons2d, lats2d) x, y = b(lons2d, lats2d) b.drawcoastlines() img = b.pcolormesh(x, y, data) b.colorbar() fig = plt.figure() itfs = varname_to_field["ITFS"] plt.hist(itfs[itfs >= 0], bins=100) plt.show() r.close() pass
def __init__(self, **kwargs): self.dx = self.dy = kwargs.get("dx", -1) self.iref, self.jref = kwargs.get("iref", -1), kwargs.get("jref", -1) self.xref, self.yref = kwargs.get("xref", -1), kwargs.get("yref", -1) self.ni, self.nj = kwargs.get("ni", -1), kwargs.get("nj", -1) # interpolated driving data (width of the outer band in number of gridpoints) self.halo = 10 # size of the blending zone in grid points self.blendig = 10 self.rll = None if "rll" not in kwargs: self.lon1, self.lat1 = kwargs.get("lon1", None), kwargs.get("lat1", None) self.lon2, self.lat2 = kwargs.get("lon2", None), kwargs.get("lat2", None) if None not in (self.lon1, self.lon2, self.lat1, self.lat2): self.rll = RotatedLatLon(lon1=self.lon1, lon2=self.lon2, lat1=self.lat1, lat2=self.lat2) else: self.rll = kwargs.get("rll") # private fields self._center_lons_2d = None self._center_lats_2d = None
def get_lons_lats_basemap(rpnfile_path="", varname=None, index_subset=None): """ Get longitudes, latitudes and the basemap object corresponding to the rpn file :param rpnfile_path: :param varname: :return: """ with RPN(rpnfile_path) as r: assert isinstance(r, RPN) if varname is None: varname = next(v for v in r.get_list_of_varnames() if v not in [">>", "^^", "HY"]) r.get_first_record_for_name(varname) lons, lats = r.get_longitudes_and_latitudes_for_the_last_read_rec() nx, ny = lons.shape if index_subset is None: index_subset = IndexSubspace(i_start=0, i_end=nx - 1, j_start=0, j_end=ny - 1) rll = RotatedLatLon(**r.get_proj_parameters_for_the_last_read_rec()) bmp = rll.get_basemap_object_for_lons_lats(lons2d=lons[index_subset.get_islice(), index_subset.get_jslice()], lats2d=lats[index_subset.get_islice(), index_subset.get_jslice()]) return lons, lats, bmp
def main(base_folder="/skynet3_rech1/huziy/veg_fractions/", fname="pm1983120100_00000000p", canopy_name="Y2C", label="USGS", depth_to_bedrock_name="8L" ): data_path = os.path.join(base_folder, fname) r = RPN(data_path) veg_fractions = r.get_2D_field_on_all_levels(name=canopy_name) print(list(veg_fractions.keys())) sand = r.get_first_record_for_name("SAND") clay = r.get_first_record_for_name("CLAY") dpth_to_bedrock = r.get_first_record_for_name(depth_to_bedrock_name) proj_params = r.get_proj_parameters_for_the_last_read_rec() lons, lats = r.get_longitudes_and_latitudes_for_the_last_read_rec() print(lons.shape) rll = RotatedLatLon(lon1=proj_params["lon1"], lat1=proj_params["lat1"], lon2=proj_params["lon2"], lat2=proj_params["lat2"]) lon0, lat0 = rll.get_true_pole_coords_in_rotated_system() plon, _ = rll.get_north_pole_coords() b = Basemap(projection="rotpole", llcrnrlon=lons[0, 0], llcrnrlat=lats[0, 0], urcrnrlon=lons[-1, -1], urcrnrlat=lats[-1, -1], lon_0=lon0 - 180, o_lon_p=lon0, o_lat_p=lat0) lons[lons > 180] -= 360 for lev in list(veg_fractions.keys()): veg_fractions[lev] = maskoceans(lons, lats, veg_fractions[lev], inlands=False) sand = maskoceans(lons, lats, sand) clay = maskoceans(lons, lats, clay) dpth_to_bedrock = maskoceans(lons, lats, dpth_to_bedrock) x, y = b(lons, lats) plot_veg_fractions(x, y, b, veg_fractions, out_image=os.path.join(base_folder, "veg_fractions_{0}.jpeg".format(label))) plot_sand_and_clay(x, y, b, sand, clay, out_image=os.path.join(base_folder, "sand_clay_{0}.jpeg".format(label))) # set relation between vegetation frsction fields and names veg_fract_dict = {} for lev, the_field in veg_fractions.items(): lev = int(lev) if lev not in y2c_level_to_title: continue veg_fract_dict[y2c_level_to_title[lev]] = the_field data = { "SAND": sand, "CLAY": clay, "BDRCK_DEPTH": dpth_to_bedrock } data.update(veg_fract_dict) return b, lons, lats, data, label
def get_default_basemap_for_glk(lons, lats, resolution = "c"): rll = RotatedLatLon(lon1=domprops.lon1, lat1 = domprops.lat1, lon2=domprops.lon2, lat2=domprops.lat2) lonp, latp = rll.get_north_pole_coords() lon0, _ = rll.get_true_pole_coords_in_rotated_system() return Basemap( projection="rotpole", llcrnrlon=lons[0, 0], llcrnrlat=lats[0, 0], urcrnrlon=lons[-1, -1], urcrnrlat=lats[-1, -1], lon_0=lon0 - 180, o_lon_p = lonp, o_lat_p = latp, resolution=resolution )
def get_arctic_basemap(lons2d, lats2d, lon1=60, lat1=90, lon2=-30, lat2=0, resolution="l"): rll = RotatedLatLon(lon1=lon1, lat1=lat1, lon2=lon2, lat2=lat2) rplon, rplat = rll.get_north_pole_coords() lon_0, lat_0 = rll.get_true_pole_coords_in_rotated_system() basemap = Basemap(projection="rotpole", o_lon_p=rplon, o_lat_p=rplat, lon_0=lon_0 - 180, llcrnrlon=lons2d[0, 0], llcrnrlat=lats2d[0, 0], urcrnrlon=lons2d[-1, -1], urcrnrlat=lats2d[-1, -1], resolution=resolution, round=True) return basemap
def get_basemap_glaciers_nw_america(): r = RPN("/RESCUE/skynet3_rech1/huziy/CNRCWP/C3/Depth_to_bedrock_WestNA_0.25") r.get_first_record_for_name("8L") proj_params = r.get_proj_parameters_for_the_last_read_rec() lons, lats = r.get_longitudes_and_latitudes_for_the_last_read_rec() bsmp = RotatedLatLon(**proj_params).get_basemap_object_for_lons_lats(lons2d=lons, lats2d=lats) return bsmp
def gridconfig_from_grid_nml(nml_str): """ Parse the copy-pasted string nml_str and construct the gridconfig object :param nml_str: """ import re nml_str = nml_str.lower() gc = GridConfig() def get_val_of(par_name, parser_func=float): return parser_func( re.search("grd_{}".format(par_name) + "\s*=\s*(-?\s*\d*\.?\d*)", nml_str).group(1)) gc.dx = get_val_of("dx") gc.dy = get_val_of("dy") gc.ni = get_val_of("ni", int) gc.nj = get_val_of("nj", int) gc.iref = get_val_of("iref", int) gc.jref = get_val_of("jref", int) gc.xref = get_val_of("lonr") gc.yref = get_val_of("latr") parnames = ["xlat1", "xlat2", "xlon1", "xlon2"] pardict = {pn[1:]: get_val_of(pn) for pn in parnames} gc.rll = RotatedLatLon(**pardict) return gc
def main(inout_paths): tiff_path, rpn_path = inout_paths print("tif path = {0}".format(tiff_path)) print("rpn path = {0}".format(rpn_path)) outGrid = RotatedLatLon(lon1=-90.0, lat1=50.0, lon2=0.0, lat2=0.0) Grd_dx = 0.5 Grd_dy = 0.5 Grd_ni = 170 Grd_nj = 158 Grd_iref = 11 Grd_jref = 11 Grd_latr = -33.5 Grd_lonr = 140.5 lons1d = np.array( [Grd_lonr + (i - Grd_iref + 1) * Grd_dx for i in range(Grd_ni)]) lats1d = np.array( [Grd_latr + (j - Grd_jref + 1) * Grd_dy for j in range(Grd_nj)]) lats2d, lons2d = np.meshgrid(lats1d, lons1d) lonlats = np.array( list( map(lambda x, y: outGrid.toGeographicLonLat(x, y), lons2d.flatten(), lats2d.flatten()))) print(lonlats.shape) rObj = RPN(rpn_path, mode="w") data = convert(tiff_path, lonlats) print("interpolated data") data.shape = lons2d.shape fieldName = os.path.basename(tiff_path).split("_")[0].lower() #write coordinates ig = outGrid.write_coords_to_rpn(rObj, lons1d, lats1d) rObj.write_2D_field(name=fieldName, data=data, grid_type="Z", ig=ig, label=fieldName) rObj.close() return 0 pass
def plot_only_vegetation_fractions( data_path="/RESCUE/skynet3_rech1/huziy/geof_lake_infl_exp/geophys_Quebec_0.1deg_260x260_with_dd_v6_with_ITFS", canopy_name="VF", label="QC_10km"): r = RPN(data_path) veg_fractions = r.get_2D_field_on_all_levels(name=canopy_name) print(list(veg_fractions.keys())) proj_params = r.get_proj_parameters_for_the_last_read_rec() lons, lats = r.get_longitudes_and_latitudes_for_the_last_read_rec() print(lons.shape) rll = RotatedLatLon(lon1=proj_params["lon1"], lat1=proj_params["lat1"], lon2=proj_params["lon2"], lat2=proj_params["lat2"]) lon0, lat0 = rll.get_true_pole_coords_in_rotated_system() plon, _ = rll.get_north_pole_coords() b = Basemap(projection="rotpole", llcrnrlon=lons[0, 0], llcrnrlat=lats[0, 0], urcrnrlon=lons[-1, -1], urcrnrlat=lats[-1, -1], lon_0=lon0 - 180, o_lon_p=lon0, o_lat_p=lat0) lons[lons > 180] -= 360 for lev in list(veg_fractions.keys()): veg_fractions[lev] = maskoceans(lons, lats, veg_fractions[lev], inlands=False) x, y = b(lons, lats) plot_veg_fractions(x, y, b, veg_fractions, out_image=os.path.join( os.path.dirname(data_path), "veg_fractions_{0}.png".format(label)))
def get_basemap_and_coords_improved( file_path="data/CORDEX/NorthAmerica_0.44deg_CanHistoE1/Samples/NorthAmerica_0.44deg_CanHistoE1_198101/pm1950010100_00816912p", field_name="PR"): rpnobj = RPN(file_path) the_mask = rpnobj.get_first_record_for_name(field_name) # plt.figure() # plt.pcolormesh(the_mask.transpose()) # plt.show() proj_params = rpnobj.get_proj_parameters_for_the_last_read_rec() rll = RotatedLatLon(**proj_params) lons2d, lats2d = rpnobj.get_longitudes_and_latitudes_for_the_last_read_rec() basemap = rll.get_basemap_object_for_lons_lats(lons2d=lons2d, lats2d=lats2d) rpnobj.close() return basemap, lons2d, lats2d
def main(path="/skynet3_rech1/huziy/gemclim_settings.nml"): params = _parse_parameters(path) print(params) ni, nj = 140, 140 # params[Grd_ni_name], params[Grd_nj_name] dx, dy = params[Grd_dx_name], params[Grd_dy_name] iRef, jRef = params[Grd_iref_name] - 1, params[Grd_jref_name] - 1 lonRef, latRef = params[Grd_lonr_name], params[Grd_latr_name] lon1, lat1 = params[Grd_xlon1_name], params[Grd_xlat1_name] lon2, lat2 = params[Grd_xlon2_name], params[Grd_xlat2_name] lons_rot = np.arange(lonRef + (0 - iRef) * dx, lonRef + (ni - iRef) * dx, dx) lats_rot = np.arange(latRef + (0 - jRef) * dy, latRef + (nj - jRef) * dy, dy) lats_rot, lons_rot = np.meshgrid(lats_rot, lons_rot) print(lats_rot.shape) # lons_rot[lons_rot > 180] -= 360 rll = RotatedLatLon(lon1=lon1, lat1=lat1, lon2=lon2, lat2=lat2) truepole_lonr, truepole_latr = rll.get_true_pole_coords_in_rotated_system() rotpole_lon, rotpole_lat = rll.get_north_pole_coords() llcrnrlon, llcrnrlat = rll.toGeographicLonLat(lons_rot[0, 0], lats_rot[0, 0]) urcrnrlon, urcrnrlat = rll.toGeographicLonLat(lons_rot[-1, -1], lats_rot[-1, -1]) b = Basemap( projection="rotpole", lon_0=truepole_lonr - 180, o_lat_p=rotpole_lat, o_lon_p=rotpole_lon, llcrnrlon=llcrnrlon, llcrnrlat=llcrnrlat, urcrnrlon=urcrnrlon, urcrnrlat=urcrnrlat, ) print(lons_rot[0, 0], lats_rot[0, 0], lons_rot[-1, -1], lats_rot[-1, -1]) b.contourf(lons_rot, lats_rot, lons_rot) b.colorbar() b.drawcoastlines() # b.drawmeridians(np.arange(160, 200, 10)) plt.show()
def main(inout_paths): tiff_path, rpn_path = inout_paths print("tif path = {0}".format(tiff_path)) print("rpn path = {0}".format(rpn_path)) outGrid = RotatedLatLon(lon1=-90.0, lat1=50.0, lon2=0.0, lat2=0.0) Grd_dx = 0.5 Grd_dy = 0.5 Grd_ni = 170 Grd_nj = 158 Grd_iref = 11 Grd_jref = 11 Grd_latr = -33.5 Grd_lonr = 140.5 lons1d = np.array([Grd_lonr + (i - Grd_iref + 1) * Grd_dx for i in range(Grd_ni)]) lats1d = np.array([Grd_latr + (j - Grd_jref + 1) * Grd_dy for j in range(Grd_nj)]) lats2d, lons2d = np.meshgrid(lats1d, lons1d) lonlats = np.array( list(map( lambda x, y: outGrid.toGeographicLonLat(x, y), lons2d.flatten(), lats2d.flatten() )) ) print(lonlats.shape) rObj = RPN(rpn_path, mode = "w") data = convert(tiff_path, lonlats) print("interpolated data") data.shape = lons2d.shape fieldName = os.path.basename(tiff_path).split("_")[0].lower() #write coordinates ig = outGrid.write_coords_to_rpn(rObj, lons1d, lats1d) rObj.write_2D_field(name = fieldName, data=data, grid_type="Z", ig = ig, label = fieldName) rObj.close() return 0 pass
def get_cartopy_proj_and_coords(self): """ :return: lons2d, lats2d, basemap [based on the bathymetry file and gemclim_settings.nml] """ from cartopy import crs # Read longitudes and latitudes and create the basemap only if they are not initialized if self.ccrs is None: with Dataset(os.path.join(self.data_folder, self.bathymetry_file)) as ds: self.lons, self.lats = ds.variables["nav_lon"][:].transpose( ), ds.variables["nav_lat"][:].transpose() import re lon1, lat1 = None, None lon2, lat2 = None, None with open(os.path.join(self.data_folder, self.proj_file)) as f: for line in f: if "Grd_xlat1" in line and "Grd_xlon1" in line: groups = re.findall(r"-?\b\d+.?\d*\b", line) lat1, lon1 = [float(s) for s in groups] if "Grd_xlat2" in line and "Grd_xlon2" in line: groups = re.findall(r"-?\b\d+.?\d*\b", line) lat2, lon2 = [float(s) for s in groups] rll = RotatedLatLon(lon1=lon1, lat1=lat1, lon2=lon2, lat2=lat2) # self.basemap = rll.get_basemap_object_for_lons_lats(lons2d=self.lons, lats2d=self.lats) lon0, _ = rll.get_true_pole_coords_in_rotated_system() o_lon_p, o_lat_p = rll.get_north_pole_coords() print(lon0, o_lat_p) self.ccrs = crs.RotatedPole(pole_longitude=lon0, pole_latitude=o_lat_p) self.lons[self.lons > 180] -= 360 return self.lons, self.lats, self.ccrs
def get_rotpole_for_na_glaciers(): """ Glacier grid Grd_typ_S = 'LU' , Grd_ni = 196 , Grd_nj = 140 , Grd_dx = 0.1375, Grd_dy = 0.1375, Grd_iref = 106 , Grd_jref = 70 , Grd_latr = 0.0 , Grd_lonr = 180.0 , Grd_xlat1 = 57.5 , Grd_xlon1 = -130. , Grd_xlat2 = 0. , Grd_xlon2 = -40. , :return: """ params = dict(lon1=-130, lat1=57.5, lon2=-40.0, lat2=0.0) return RotatedLatLon(**params)
def get_coords_and_basemap(self): """ :return: lons2d, lats2d, basemap [based on the bathymetry file and gemclim_settings.nml] """ # Read longitudes and latitudes and create the basemap only if they are not initialized if self.lons is None: with Dataset(os.path.join(self.data_folder, self.bathymetry_file)) as ds: self.lons, self.lats = ds.variables["nav_lon"][:].transpose(), ds.variables["nav_lat"][:].transpose() import re lon1, lat1 = None, None lon2, lat2 = None, None with open(os.path.join(self.data_folder, self.proj_file)) as f: for line in f: if "Grd_xlat1" in line and "Grd_xlon1" in line: groups = re.findall(r"-?\b\d+.?\d*\b", line) lat1, lon1 = [float(s) for s in groups] if "Grd_xlat2" in line and "Grd_xlon2" in line: groups = re.findall(r"-?\b\d+.?\d*\b", line) lat2, lon2 = [float(s) for s in groups] rll = RotatedLatLon(lon1=lon1, lat1=lat1, lon2=lon2, lat2=lat2) self.basemap = rll.get_basemap_object_for_lons_lats(lons2d=self.lons, lats2d=self.lats) print(lon1, lat1, lon2, lat2) # self.basemap.drawcoastlines() # xx, yy = self.basemap(self.lons, self.lats) # self.basemap.pcolormesh(xx, yy, ds.variables["Bathymetry"][:].transpose()) # plt.show() self.lons[self.lons > 180] -= 360 return self.lons, self.lats, self.basemap
def get_cartopy_proj_and_coords(self): """ :return: lons2d, lats2d, basemap [based on the bathymetry file and gemclim_settings.nml] """ from cartopy import crs # Read longitudes and latitudes and create the basemap only if they are not initialized if self.ccrs is None: with Dataset(os.path.join(self.data_folder, self.bathymetry_file)) as ds: self.lons, self.lats = ds.variables["nav_lon"][:].transpose(), ds.variables["nav_lat"][:].transpose() import re lon1, lat1 = None, None lon2, lat2 = None, None with open(os.path.join(self.data_folder, self.proj_file)) as f: for line in f: if "Grd_xlat1" in line and "Grd_xlon1" in line: groups = re.findall(r"-?\b\d+.?\d*\b", line) lat1, lon1 = [float(s) for s in groups] if "Grd_xlat2" in line and "Grd_xlon2" in line: groups = re.findall(r"-?\b\d+.?\d*\b", line) lat2, lon2 = [float(s) for s in groups] rll = RotatedLatLon(lon1=lon1, lat1=lat1, lon2=lon2, lat2=lat2) # self.basemap = rll.get_basemap_object_for_lons_lats(lons2d=self.lons, lats2d=self.lats) lon0, _ = rll.get_true_pole_coords_in_rotated_system() o_lon_p, o_lat_p = rll.get_north_pole_coords() print(lon0, o_lat_p) self.ccrs = crs.RotatedPole(pole_longitude=lon0, pole_latitude=o_lat_p) self.lons[self.lons > 180] -= 360 return self.lons, self.lats, self.ccrs
def main(path = "/skynet3_rech1/huziy/geof_lake_infl_exp/geophys_Quebec_0.1deg_260x260_with_dd_v6_with_ITFS"): r = RPN(path) varnames = ["ITFS"] ncols = 3 nrows = len(varnames) // 3 fig = plt.figure() varname_to_field = {} for vname in varnames: data = r.get_first_record_for_name(vname) varname_to_field[vname] = data data = np.ma.masked_where(data < 0, data) lons2d, lats2d = r.get_longitudes_and_latitudes_for_the_last_read_rec() params = r.get_proj_parameters_for_the_last_read_rec() print(params) rll = RotatedLatLon(**params) b = rll.get_basemap_object_for_lons_lats(lons2d, lats2d) x, y = b(lons2d, lats2d) b.drawcoastlines() img = b.pcolormesh(x, y, data) b.colorbar() fig = plt.figure() itfs = varname_to_field["ITFS"] plt.hist(itfs[itfs >= 0], bins = 100) plt.show() r.close() pass
def gridconfig_from_dict(param_dict): gc = GridConfig() gc.dx = param_dict["dx"] gc.dy = param_dict["dy"] gc.ni = param_dict["ni"] gc.nj = param_dict["nj"] gc.iref = param_dict["iref"] gc.jref = param_dict["jref"] gc.xref = param_dict["lonr"] gc.yref = param_dict["latr"] parnames = ["xlat1", "xlat2", "xlon1", "xlon2"] proj_pardict = {pn[1:]: param_dict[pn] for pn in parnames} gc.rll = RotatedLatLon(**proj_pardict) return gc
def main(path="/skynet3_rech1/huziy/gemclim_settings.nml"): params = _parse_parameters(path) print(params) ni, nj = 140, 140 # params[Grd_ni_name], params[Grd_nj_name] dx, dy = params[Grd_dx_name], params[Grd_dy_name] iRef, jRef = params[Grd_iref_name] - 1, params[Grd_jref_name] - 1 lonRef, latRef = params[Grd_lonr_name], params[Grd_latr_name] lon1, lat1 = params[Grd_xlon1_name], params[Grd_xlat1_name] lon2, lat2 = params[Grd_xlon2_name], params[Grd_xlat2_name] lons_rot = np.arange(lonRef + (0 - iRef) * dx, lonRef + (ni - iRef) * dx, dx) lats_rot = np.arange(latRef + (0 - jRef) * dy, latRef + (nj - jRef) * dy, dy) lats_rot, lons_rot = np.meshgrid(lats_rot, lons_rot) print(lats_rot.shape) # lons_rot[lons_rot > 180] -= 360 rll = RotatedLatLon(lon1=lon1, lat1=lat1, lon2=lon2, lat2=lat2) truepole_lonr, truepole_latr = rll.get_true_pole_coords_in_rotated_system() rotpole_lon, rotpole_lat = rll.get_north_pole_coords() llcrnrlon, llcrnrlat = rll.toGeographicLonLat(lons_rot[0, 0], lats_rot[0, 0]) urcrnrlon, urcrnrlat = rll.toGeographicLonLat(lons_rot[-1, -1], lats_rot[-1, -1]) b = Basemap(projection="rotpole", lon_0=truepole_lonr - 180, o_lat_p=rotpole_lat, o_lon_p=rotpole_lon, llcrnrlon=llcrnrlon, llcrnrlat=llcrnrlat, urcrnrlon=urcrnrlon, urcrnrlat=urcrnrlat) print(lons_rot[0, 0], lats_rot[0, 0], lons_rot[-1, -1], lats_rot[-1, -1]) b.contourf(lons_rot, lats_rot, lons_rot) b.colorbar() b.drawcoastlines() # b.drawmeridians(np.arange(160, 200, 10)) plt.show()
def get_coords_and_basemap(self, subregion=None, reload=True, **basemap_kwargs): """ :return: lons2d, lats2d, basemap [based on the bathymetry file and gemclim_settings.nml] if reload is True, do not use cached arrays even if they are available """ # Read longitudes and latitudes and create the basemap only if they are not initialized if self.basemap is None or reload: with Dataset(os.path.join(self.data_folder, self.bathymetry_file)) as ds: if "nav_lon" in ds.variables: self.lons, self.lats = ds.variables[ "nav_lon"][:].transpose( ), ds.variables["nav_lat"][:].transpose() else: for vname, v in ds.variables.items(): if "lon" in vname.lower(): self.lons = v[:].T continue if "lat" in vname.lower(): self.lats = v[:].T continue if self.lons is not None and self.lats is not None: break import re lon1, lat1 = None, None lon2, lat2 = None, None with open(os.path.join(self.data_folder, self.proj_file)) as f: for line in f: if "Grd_xlat1" in line and "Grd_xlon1" in line: groups = re.findall(r"-?\b\d+.?\d*\b", line) lat1, lon1 = [float(s) for s in groups] if "Grd_xlat2" in line and "Grd_xlon2" in line: groups = re.findall(r"-?\b\d+.?\d*\b", line) lat2, lon2 = [float(s) for s in groups] rll = RotatedLatLon(lon1=lon1, lat1=lat1, lon2=lon2, lat2=lat2) nx, ny = self.lons.shape if subregion is not None: ill, iur, jll, jur = int(nx * subregion[0]), int( nx * subregion[1]), int(ny * subregion[2]), int( ny * subregion[3]) else: ill, iur, jll, jur = 0, self.lons.shape[ 0], 0, self.lons.shape[1] self.basemap = rll.get_basemap_object_for_lons_lats( lons2d=self.lons[ill:iur, jll:jur], lats2d=self.lats[ill:iur, jll:jur], **basemap_kwargs) print(lon1, lat1, lon2, lat2) # self.basemap.drawcoastlines() # xx, yy = self.basemap(self.lons, self.lats) # self.basemap.pcolormesh(xx, yy, ds.variables["Bathymetry"][:].transpose()) # plt.show() self.lons[self.lons > 180] -= 360 return self.lons, self.lats, self.basemap
def plot_acc_area_with_glaciers( gmask_vname: str = "VF", gmask_level=2, gmask_path="/RESCUE/skynet3_rech1/huziy/CNRCWP/C3/geophys_West_NA_0.25deg_144x115_GLNM_PRSF_CanHR85", route_data_path="/RESCUE/skynet3_rech1/huziy/CNRCWP/C3/directions_north_america_0.25deg_glaciers.nc", lons_target=None, lats_target=None, basin_shape_files=None): plot_scatter = False # stab reading of the glacier mask with RPN(gmask_path) as r: gmask = r.get_first_record_for_name_and_level(varname=gmask_vname, level=gmask_level) # r = RPN("/RESCUE/skynet3_rech1/huziy/CNRCWP/Calgary_flood/pm2013061400_00000000p") r.get_first_record_for_name( "VF") # Because I almost sure that PR is there proj_params = r.get_proj_parameters_for_the_last_read_rec() rll = RotatedLatLon(**proj_params) lons_gmask, lats_gmask = r.get_longitudes_and_latitudes_for_the_last_read_rec( ) gl_fraction_limit = 0.01 gmask = np.ma.masked_where(gmask < gl_fraction_limit, gmask) mask_value = 0.25 gmask[~gmask.mask] = mask_value if str(route_data_path).endswith(".nc"): print("route_data_path ends with .nc => assuming netcdf format: {}". format(route_data_path)) with Dataset(route_data_path) as ds: var_name = "accumulation_area" data = ds.variables[var_name][:] # flow directions fldr = ds.variables["flow_direction_value"][:] coord_names = ["lon", "lat"] if "lon" in ds.variables else [ "longitudes", "latitudes" ] lons_route, lats_route = [ds.variables[k] for k in coord_names] else: print( "route_data_path does not end with .nc => assuming rpn format: {}". format(route_data_path)) with RPN(route_data_path) as r: data = r.get_first_record_for_name("FACC") fldr = r.get_first_record_for_name("FLDR") lons_route, lats_route = r.get_longitudes_and_latitudes_for_the_last_read_rec( ) # do the spatial interpolation if required xg, yg, zg = lat_lon.lon_lat_to_cartesian(lons_gmask.flatten(), lats_gmask.flatten()) xr, yr, zr = lat_lon.lon_lat_to_cartesian(lons_route.flatten(), lats_route.flatten()) if lons_target is None or lats_target is None: lons_target, lats_target = lons_route, lats_route xt, yt, zt = xr, yr, zr else: xt, yt, zt = lat_lon.lon_lat_to_cartesian(lons_target.flatten(), lats_target.flatten()) basemap = rll.get_basemap_object_for_lons_lats(lons2d=lons_target, lats2d=lats_target, resolution="i") ktree_route = KDTree(list(zip(xr, yr, zr))) dists_route, inds_route = ktree_route.query(list(zip(xt, yt, zt))) data = data.flatten()[inds_route].reshape(lons_target.shape) fldr = fldr.flatten()[inds_route].reshape(lons_target.shape) ktree_gmask = KDTree(list(zip(xg, yg, zg))) dists_gmask, inds_gmask = ktree_gmask.query(list(zip(xt, yt, zt))) gmask = gmask.flatten()[inds_gmask].reshape(lons_target.shape) data = np.ma.masked_where(data <= 0, data) i_shifts, j_shifts = direction_and_value.flowdir_values_to_shift(fldr) xx, yy = basemap(lons_target, lats_target) fig = plt.figure(figsize=(15, 15)) dx = (xx[-1, -1] - xx[0, 0]) / float(xx.shape[0]) dy = (yy[-1, -1] - yy[0, 0]) / float(yy.shape[1]) x1 = xx - dx / 2.0 y1 = yy - dy / 2.0 # Uncomment to plot the accumulation areas im = basemap.pcolormesh(x1, y1, data, norm=LogNorm(vmin=1e3, vmax=1e7), cmap=cm.get_cmap("jet", 12)) cb = basemap.colorbar(im) cmap = cm.get_cmap("gray_r", 10) basemap.pcolormesh(x1, y1, gmask, cmap=cmap, vmin=0., vmax=1.) nx, ny = xx.shape inds_j, inds_i = np.meshgrid(range(ny), range(nx)) inds_i_next = inds_i + i_shifts inds_j_next = inds_j + j_shifts inds_i_next = np.ma.masked_where((inds_i_next == nx) | (inds_i_next == -1), inds_i_next) inds_j_next = np.ma.masked_where((inds_j_next == ny) | (inds_j_next == -1), inds_j_next) u = np.ma.masked_all_like(xx) v = np.ma.masked_all_like(xx) good = (~inds_i_next.mask) & (~inds_j_next.mask) u[good] = xx[inds_i_next[good], inds_j_next[good]] - xx[inds_i[good], inds_j[good]] v[good] = yy[inds_i_next[good], inds_j_next[good]] - yy[inds_i[good], inds_j[good]] basemap.quiver(xx, yy, u, v, pivot="tail", width=0.0005, scale_units="xy", headlength=20, headwidth=15, scale=1) basemap.drawcoastlines(linewidth=0.5, zorder=5) basemap.drawrivers(color="lightcoral", zorder=5, linewidth=3) plt.legend([ Rectangle((0, 0), 5, 5, fc=cmap(mask_value)), ], [ r"Glacier ($\geq {}\%$)".format(gl_fraction_limit * 100), ], loc=3) watershed_bndry_width = 4 if basin_shape_files is not None: for i, the_shp in enumerate(basin_shape_files): basemap.readshapefile(the_shp[:-4], "basin_{}".format(i), zorder=2, color="m", linewidth=watershed_bndry_width) # basemap.readshapefile("/RESCUE/skynet3_rech1/huziy/CNRCWP/C3/lat_lon/athabasca/athabasca_dissolved", "atabaska", # zorder=2, linewidth=watershed_bndry_width, color="m") # # basemap.readshapefile("/RESCUE/skynet3_rech1/huziy/CNRCWP/C3/lat_lon/fraizer/fraizer", "frazier", # zorder=2, linewidth=watershed_bndry_width, color="m") # # basemap.readshapefile("/RESCUE/skynet3_rech1/huziy/CNRCWP/C3/lat_lon/South_sas/South_sas_dissolved", "south_sask", # zorder=2, linewidth=watershed_bndry_width, color="m") # # basemap.readshapefile("/RESCUE/skynet3_rech1/huziy/CNRCWP/C3/lat_lon/north_sas/north_sas", "north_sask", # zorder=2, linewidth=watershed_bndry_width, color="m") # basemap.readshapefile("/RESCUE/skynet3_rech1/huziy/CNRCWP/C3/lat_lon/watersheds_up_sas/watershed_up_sas_proj", # "upsas", # zorder=2, linewidth=3, color="m") # basemap.readshapefile("/RESCUE/skynet3_rech1/huziy/CNRCWP/C3/lat_lon/network/network", "rivers", # zorder=2, linewidth=0.5, color="b") # basemap.readshapefile("/RESCUE/skynet3_rech1/huziy/CNRCWP/C3/lat_lon/network_up_sas/network_up_sout_sas_proj", "network", # zorder=2, linewidth=0.5, color="b") if plot_scatter: points_lat = [51.54, 49.2476] points_lon = [-122.277, -122.784] point_x, point_y = basemap(points_lon, points_lat) basemap.scatter(point_x, point_y, c="g", s=20, zorder=3) plt.savefig("/RESCUE/skynet3_rech1/huziy/CNRCWP/C3/directions_only.png", bbox_inches="tight", dpi=300) # plt.savefig("/RESCUE/skynet3_rech1/huziy/CNRCWP/Calgary_flood/directions.png", bbox_inches="tight") plt.show()
def plot_domain_using_coords_from_file(path=""): fig = plt.figure() assert isinstance(fig, Figure) rpnObj = RPN(path) lons2d, lats2d = rpnObj.get_longitudes_and_latitudes() basemap = Basemap(projection="omerc", lon_1=-68, lat_1=52, lon_2=16.65, lat_2=0.0, llcrnrlon=lons2d[0, 0], llcrnrlat=lats2d[0, 0], urcrnrlon=lons2d[-1, -1], urcrnrlat=lats2d[-1, -1], no_rot=True) # basemap.drawcoastlines() rot_lat_lon_proj = RotatedLatLon(lon1=-68, lat1=52, lon2=16.65, lat2=0.0) g_params = GridParams(lonr=180, latr=0, iref=45, jref=41, dx=0.5, dy=0.5, nx=86, ny=86) lons2d_1, lats2d_1 = get_lons_lats_using_grid_params(g_params, rot_lat_lon_proj) basemap = Basemap(projection="omerc", lon_1=-68, lat_1=52, lon_2=16.65, lat_2=0.0, llcrnrlon=lons2d_1[18, 18], llcrnrlat=lats2d_1[18, 18], urcrnrlon=lons2d_1[-1, -1], urcrnrlat=lats2d_1[-1, -1], no_rot=True, resolution="i") basemap.drawcoastlines(linewidth=0.4) basemap.drawrivers() # basemap.drawmeridians(np.arange(-180, 0, 20)) x, y = basemap(lons2d, lats2d) basemap.scatter(x, y, c="r", linewidths=0, s=1.0) print(x.shape) xll_big, yll_big = g_params.get_ll_point(marginx=20, marginy=20) xll_big -= g_params.dx / 2.0 yll_big -= g_params.dy / 2.0 xll_big, yll_big = rot_lat_lon_proj.toGeographicLonLat(xll_big, yll_big) xll_big, yll_big = basemap(xll_big, yll_big) xur_big, yur_big = g_params.get_ur_point(marginx=20, marginy=20) xur_big += g_params.dx / 2.0 yur_big += g_params.dy / 2.0 xur_big, yur_big = rot_lat_lon_proj.toGeographicLonLat(xur_big, yur_big) xur_big, yur_big = basemap(xur_big, yur_big) margin = 20 # plot 0.25 degree grid g_params = GridParams(lonr=180, latr=0, iref=71, jref=63, dx=0.25, dy=0.25, nx=133, ny=133) lons2d_2, lats2d_2 = get_lons_lats_using_grid_params(g_params, rot_lat_lon_proj) x2, y2 = basemap(lons2d_2[margin:-margin, margin:-margin], lats2d_2[margin:-margin, margin:-margin]) basemap.scatter(x2, y2, c="g", linewidth=0, marker="s", s=7.5) # plot 0.5 degree grid using the output file # debug rObj1 = RPN("/home/huziy/skynet3_exec1/from_guillimin/quebec_86x86_0.5deg_without_lakes/pm1985010100_00000000p") lons2d_1, lats2d_1 = rObj1.get_longitudes_and_latitudes() # x1, y1 = basemap(lons2d_1[margin:-margin,margin:-margin], lats2d_1[margin:-margin,margin:-margin]) x1, y1 = basemap(lons2d_1, lats2d_1) print(x1.shape, lons2d_1[0, 0], lats2d_1[0, 0]) basemap.scatter(x1, y1, c="b", linewidths=0, s=10) dx1 = (x1[1, 0] - x1[0, 0]) / 2.0 dy1 = (y1[0, 1] - y1[0, 0]) / 2.0 rbig = Rectangle((xll_big, yll_big), xur_big - xll_big, yur_big - yll_big, linewidth=2, edgecolor="b", facecolor="none" ) ax = plt.gca() assert isinstance(ax, Axes) # ax.add_patch(rsmall) ax.add_patch(rbig) # draw north arrow plot_north_cross(-45, 45, basemap, ax=ax) # zoom to a region axins = zoomed_inset_axes(ax, 4, loc=1) # zoom = 6 basemap.drawcoastlines(ax=axins) basemap.drawrivers(ax=axins) basemap.scatter(x, y, c="r", linewidths=0, s=5, ax=axins) basemap.scatter(x2, y2, c="g", marker="s", linewidth=0, s=15, ax=axins) basemap.scatter(x1, y1, c="b", linewidths=0, s=25, ax=axins) # subregion to zoom in nx, ny = lons2d.shape part = 3 xins_ll = lons2d[nx / part, ny / part] yins_ll = lats2d[nx / part, ny / part] xins_ur = lons2d[nx / part + 40, ny / part + 40] yins_ur = lats2d[nx / part + 40, ny / part + 40] xins_ll, yins_ll = basemap(xins_ll, yins_ll) xins_ur, yins_ur = basemap(xins_ur, yins_ur) axins.set_xlim(xins_ll, xins_ur) axins.set_ylim(yins_ll, yins_ur) # draw a bbox of the region of the inset axes in the parent axes and # connecting lines between the bbox and the inset axes area mark_inset(ax, axins, loc1=2, loc2=4, fc="none", linewidth=2) fig.tight_layout(pad=0.8) fig.savefig("high_low_res_domains.png") pass
def main(): swe_obs_manager = SweDataManager(var_name="SWE") data_path = "/home/huziy/skynet3_exec1/from_guillimin/quebec_86x86_0.5deg_without_lakes_v3" coord_file = os.path.join(data_path, "pm1985050100_00000000p") managerLowRes = Crcm5ModelDataManager(samples_folder_path=data_path, file_name_prefix="pm", all_files_in_samples_folder=True, need_cell_manager=True) data_path = "/home/huziy/skynet3_exec1/from_guillimin/quebec_highres_spinup_12_month_without_lakes_v3" coord_file = os.path.join(data_path, "pm1985050100_00000000p") managerHighRes = Crcm5ModelDataManager(samples_folder_path=data_path, file_name_prefix="pm", all_files_in_samples_folder=True, need_cell_manager=True) start_year = 1987 end_year = 1987 months = [1, 2, 12] rot_lat_lon = RotatedLatLon(lon1=-68, lat1=52, lon2=16.65, lat2=0.0) basemap = Basemap(projection="omerc", llcrnrlon=managerHighRes.lons2D[0, 0], llcrnrlat=managerHighRes.lats2D[0, 0], urcrnrlon=managerHighRes.lons2D[-1, -1], urcrnrlat=managerHighRes.lats2D[-1, -1], lat_1=rot_lat_lon.lat1, lat_2=rot_lat_lon.lat2, lon_1=rot_lat_lon.lon1, lon_2=rot_lat_lon.lon2, no_rot=True) swe_obs = swe_obs_manager.get_mean(start_year, end_year, months=months) obs_ihr = swe_obs_manager.interpolate_data_to(swe_obs, managerHighRes.lons2D, managerHighRes.lats2D, nneighbours=1) obs_ilr = swe_obs_manager.interpolate_data_to(swe_obs, managerLowRes.lons2D, managerLowRes.lats2D, nneighbours=1) lowResSwe = managerLowRes.get_mean_field(start_year, end_year, months=months, var_name="I5") lowResErr = (lowResSwe - obs_ilr) lowResErr[obs_ilr > 0] /= obs_ilr[obs_ilr > 0] lowResErr = np.ma.masked_where(obs_ilr <= 0, lowResErr) highResSwe = managerHighRes.get_mean_field(start_year, end_year, months=months, var_name="I5") highResErr = (highResSwe - obs_ihr) highResErr[obs_ihr > 0] /= obs_ihr[obs_ihr > 0] highResErr = np.ma.masked_where(obs_ihr <= 0, highResErr) upscaledHighResSwe = upscale(managerHighRes, managerLowRes, highResSwe) upscaledHighResErr = upscaledHighResSwe - obs_ilr good_points = obs_ilr > 0 upscaledHighResErr[good_points] /= obs_ilr[good_points] upscaledHighResErr = np.ma.masked_where(~good_points, upscaledHighResErr) plot_and_compare_2fields(lowResSwe, "low res", upscaledHighResSwe, "high res (upscaled)", basemap=basemap, manager1=managerLowRes, manager2=managerLowRes) plot_and_compare_2fields(lowResErr, "low res err", upscaledHighResErr, "high res (upscaled) err", basemap=basemap, manager1=managerLowRes, manager2=managerLowRes, clevs=np.arange(-1, 1.2, 0.2)) plot_and_compare_2fields(lowResSwe, "low res", highResSwe, "high res", basemap=basemap, manager1=managerLowRes, manager2=managerHighRes) plot_and_compare_2fields(lowResErr, "low res err", highResErr, "high res err", basemap=basemap, manager1=managerLowRes, manager2=managerHighRes, clevs=np.arange(-1, 1.2, 0.2)) plt.show()
def main(): #path = "/RECH/data/Simulations/CRCM5/North_America/NorthAmerica_0.44deg_ERA40-Int_B1/Diagnostics/NorthAmerica_0.44deg_ERA40-Int_B1_2007{:02d}" path = "/RESCUE/skynet3_rech1/huziy/from_guillimin/new_outputs/current_climate_30_yr_sims/quebec_0.1_crcm5-hcd-rl-intfl_ITFS/Samples/quebec_crcm5-hcd-rl-intfl_1988{:02d}" months = [6, 7, 8] pm_list = [] dm_list = [] for m in months: print(path.format(m)) month_folder = path.format(m) for fn in os.listdir(month_folder): # if not fn.endswith("moyenne"): # continue if fn.startswith("pm"): pm_list.append(os.path.join(month_folder, fn)) elif fn.startswith("dm"): dm_list.append(os.path.join(month_folder, fn)) pm = MultiRPN(pm_list) dm = MultiRPN(dm_list) tsurf_mean = np.mean([ field for field in pm.get_all_time_records_for_name_and_level( varname="J8").values() ], axis=0) tair_mean = np.mean([ field for field in dm.get_all_time_records_for_name_and_level( varname="TT", level=1, level_kind=level_kinds.HYBRID).values() ], axis=0) lons, lats = pm.get_longitudes_and_latitudes_of_the_last_read_rec() projparams = pm.linked_robj_list[ 0].get_proj_parameters_for_the_last_read_rec() rll = RotatedLatLon(**projparams) bmp = rll.get_basemap_object_for_lons_lats(lons2d=lons, lats2d=lats) xx, yy = bmp(lons, lats) plt.figure() cs = bmp.contourf(xx, yy, tsurf_mean - 273.15, 40) bmp.drawcoastlines() plt.title("Tsurf") plt.colorbar() plt.figure() bmp.contourf(xx, yy, tair_mean, levels=cs.levels, norm=cs.norm, cmap=cs.cmap) bmp.drawcoastlines() plt.title("Tair") plt.colorbar() plt.figure() bmp.contourf(xx, yy, tsurf_mean - 273.15 - tair_mean, levels=np.arange(-2, 2.2, 0.2), cmap=cs.cmap) bmp.drawcoastlines() plt.title("Tsurf - Tair") plt.colorbar() pm.close() dm.close() plt.show()
def plot_acc_area_with_glaciers(): gmask_vname = "VF" gmask_level = 2 # gmask_path = "/RESCUE/skynet3_rech1/huziy/CNRCWP/C3/geophys_West_NA_0.25deg_144x115_GLNM_PRSF_CanHR85" gmask_path = "/RESCUE/skynet3_rech1/huziy/CNRCWP/Calgary_flood/geophys_CORDEX_NA_0.11deg_695x680_filled_grDes_barBor_Crop2Gras_peat" # stab reading of the glacier mask # r = RPN(gmask_path) # gmask = r.get_first_record_for_name_and_level(varname=gmask_vname, # level=gmask_level) r = RPN("/RESCUE/skynet3_rech1/huziy/CNRCWP/Calgary_flood/pm2013061400_00000000p") r.get_first_record_for_name("PR") # Because I almost sure that PR is there proj_params = r.get_proj_parameters_for_the_last_read_rec() rll = RotatedLatLon(**proj_params) lons, lats = r.get_longitudes_and_latitudes_for_the_last_read_rec() basemap = rll.get_basemap_object_for_lons_lats(lons2d=lons, lats2d=lats, resolution="i") # gmask = np.ma.masked_where(gmask < 0.01, gmask) gmask = np.ma.masked_all(lons.shape) mask_value = 0.25 gmask[~gmask.mask] = mask_value path = "/RESCUE/skynet3_rech1/huziy/Netbeans Projects/Java/DDM/directions_WestCaUs_dx0.11deg.nc" # path = "/RESCUE/skynet3_rech1/huziy/CNRCWP/C3/infocell_West_NA_0.25deg_104x75_GLNM_PRSF_CanHR85_104x75.nc" ds = Dataset(path) margin = 20 var_name = "accumulation_area" data = ds.variables[var_name][margin:-margin, margin:-margin] data = np.ma.masked_where(data <= 0, data) # flow directions fldr = ds.variables["flow_direction_value"][:][margin:-margin, margin:-margin] i_shifts, j_shifts = direction_and_value.flowdir_values_to_shift(fldr) x, y = basemap(lons, lats) fig = plt.figure(figsize=(15, 15)) dx = (x[-1, -1] - x[0, 0]) / float(x.shape[0]) dy = (y[-1, -1] - y[0, 0]) / float(y.shape[1]) x1 = x - dx / 2.0 y1 = y - dy / 2.0 # im = basemap.pcolormesh(x1, y1, data, norm=LogNorm(vmin=1e3, vmax=1e7), cmap=cm.get_cmap("jet", 12)) # cb = basemap.colorbar(im) # cb.ax.tick_params(labelsize=25) cmap = cm.get_cmap("gray_r", 10) basemap.pcolormesh(x1, y1, gmask, cmap=cmap, vmin=0., vmax=1.) nx, ny = x.shape inds_j, inds_i = np.meshgrid(range(ny), range(nx)) inds_i_next = inds_i + i_shifts inds_j_next = inds_j + j_shifts inds_i_next = np.ma.masked_where((inds_i_next == nx) | (inds_i_next == -1), inds_i_next) inds_j_next = np.ma.masked_where((inds_j_next == ny) | (inds_j_next == -1), inds_j_next) u = np.ma.masked_all_like(x) v = np.ma.masked_all_like(x) good = (~inds_i_next.mask) & (~inds_j_next.mask) u[good] = x[inds_i_next[good], inds_j_next[good]] - x[inds_i[good], inds_j[good]] v[good] = y[inds_i_next[good], inds_j_next[good]] - y[inds_i[good], inds_j[good]] basemap.quiver(x, y, u, v, pivot="tail", width=0.0005, scale_units="xy", headlength=20, headwidth=15, scale=1) basemap.drawcoastlines(linewidth=0.5) basemap.drawrivers(color="b") # plt.legend([Rectangle((0, 0), 5, 5, fc=cmap(mask_value)), ], ["Glaciers", ], loc=3) # basemap.readshapefile("/RESCUE/skynet3_rech1/huziy/CNRCWP/C3/lat_lon/athabasca/athabasca_dissolved", "atabaska", # zorder=2, linewidth=3, color="m") # basemap.readshapefile("/RESCUE/skynet3_rech1/huziy/CNRCWP/C3/lat_lon/fraizer/fraizer", "frazier", # zorder=2, linewidth=3, color="m") # basemap.readshapefile("/RESCUE/skynet3_rech1/huziy/CNRCWP/C3/lat_lon/South_sas/South_sas_dissolved", "south_sask", # zorder=2, linewidth=3, color="m") # basemap.readshapefile("/RESCUE/skynet3_rech1/huziy/CNRCWP/C3/lat_lon/north_sas/north_sas", "north_sask", # zorder=2, linewidth=3, color="m") # basemap.readshapefile("/RESCUE/skynet3_rech1/huziy/CNRCWP/C3/lat_lon/watersheds_up_sas/watershed_up_sas_proj", # "upsas", # zorder=2, linewidth=3, color="m") # basemap.readshapefile("/RESCUE/skynet3_rech1/huziy/CNRCWP/C3/lat_lon/network/network", "rivers", # zorder=2, linewidth=0.5, color="b") # basemap.readshapefile("/RESCUE/skynet3_rech1/huziy/CNRCWP/C3/lat_lon/network_up_sas/network_up_sout_sas_proj", "network", # zorder=2, linewidth=0.5, color="b") basemap.readshapefile("/skynet3_exec2/aganji/NE_can/bow_river/bow_projected", "basin", color="m", linewidth=2) # plt.savefig("/RESCUE/skynet3_rech1/huziy/CNRCWP/C3/directions.png", bbox_inches="tight") plt.savefig("/RESCUE/skynet3_rech1/huziy/CNRCWP/Calgary_flood/directions.png", bbox_inches="tight") plt.show()
def main(): """ """ # s_lons = [-3.38, 3.40, -12.45, -11.04,-2.92, 0.1,32.55,30.48,23.6,31.27,15.31,23.91,17.51,21.08] # s_lats = [16.26,11.88,14.9,13.91,10.57,6.2,15.61,19.18,-14.02,-21.13,-4.26,4.97,-28.71,-28.69] # assert len(s_lons) == len(s_lats) #path = "data/directions_Africa_Bessam_0.44/infocell_Africa.nc" #path = "/home/huziy/skynet3_exec1/for_offline_routing/directions_africa_dx0.44deg_2.nc" path = "/skynet3_rech1/huziy/for_Arman_routing_data/infocell_na_0.44deg_arman.nc" ds = Dataset(path) dirs = ds.variables["flow_direction_value"][:] acc_area = ds.variables["accumulation_area"][:] lons2d = ds.variables["lon"][:] lats2d = ds.variables["lat"][:] lon_1, lat_1 = -97, 47.5 lon_2, lat_2 = -7, 0 lons2d[lons2d >= 180] -= 360 #min_lon = lons2d[0,0] #max_lon = lons2d[-1,-1] #min_lat = lats2d[0, 0] #max_lat = lats2d[-1,-1] #plot_utils.apply_plot_params(width_pt=None, width_cm=80) #print max_lon fig = plt.figure(dpi=800) #TODO: change projection to rotpole (it will require params) #b = Basemap(projection="rotpole", llcrnrlon=min_lon, # llcrnrlat=min_lat, # urcrnrlon=max_lon, urcrnrlat=max_lat, resolution="i") myproj = RotatedLatLon(lon1=lon_1, lat1=lat_1, lon2=lon_2, lat2=lat_2) print(lons2d.shape) b = myproj.get_basemap_object_for_lons_lats(lons2d[100:150, 70:132], lats2d[100:150, 70:132]) x, y = b(lons2d, lats2d) b.drawcoastlines(linewidth=0.2, color="0.5") # b.pcolormesh(x, y, np.ma.masked_where(dirs <= 0, dirs )) # plt.colorbar() di_list = np.array([1, 1, 0, -1, -1, -1, 0, 1]) dj_list = np.array([0, -1, -1, -1, 0, 1, 1, 1]) delta_indices = np.log2(dirs[dirs > 0]) delta_indices = delta_indices.astype(int) di = di_list[delta_indices] dj = dj_list[delta_indices] acc_area = np.ma.masked_where(acc_area < 0, acc_area) #img = b.pcolormesh(x, y, np.ma.log(acc_area)) ax = plt.gca() #divider = make_axes_locatable(ax) #cax = divider.append_axes("right", "5%", pad="3%") #plt.colorbar(img, cax = cax) i_indices_1d = list(range(dirs.shape[0])) j_indices_1d = list(range(dirs.shape[1])) j_indices_2d, i_indices_2d = np.meshgrid(j_indices_1d, i_indices_1d) i_indices_2d_next = np.zeros_like(i_indices_2d) j_indices_2d_next = np.zeros_like(i_indices_2d) i_indices_2d_next[dirs > 0] = i_indices_2d[dirs > 0] + di j_indices_2d_next[dirs > 0] = j_indices_2d[dirs > 0] + dj for i, j, i_next, j_next in zip(i_indices_2d[dirs > 0], j_indices_2d[dirs > 0], i_indices_2d_next[dirs > 0], j_indices_2d_next[dirs > 0]): # ax.add_line(Line2D([x[i,j], x[i_next, j_next]], [y[i,j], y[i_next, j_next]], linewidth=0.5)) if i == i_next and j == j_next: continue p1 = [x[i, j], y[i, j]] p2 = [x[i_next, j_next], y[i_next, j_next]] dr = [p2[0] - p1[0], p2[1] - p1[1]] ax.add_patch( FancyArrow(p1[0], p1[1], dr[0], dr[1], linewidth=0.5, fc="k", head_width=0.1, length_includes_head=True)) # x1, y1 = b(s_lons, s_lats) # b.scatter(x1, y1, c="r", linewidth=0, zorder = 7, ax = ax) # b.drawrivers(linewidth=0.5, color="#0cf5f8", zorder=8, ax=ax) # b.drawmeridians(np.arange(-10, 90,30)) # b.drawparallels(np.arange(-50, 40, 5), labels=[1,1,1,1], linewidth=0.1) plt.tight_layout() # plt.show() #b.readshapefile("/home/huziy/skynet3_exec1/other_shape/af_major_basins/af_basins", "basin", # linewidth=3, zorder=9, ax=ax #) plt.savefig("with_station_riv_af_dirs_basin_1.0.eps") pass
def plot_lake_fraction_field(): folder = "/home/huziy/skynet3_rech1/geof_lake_infl_exp" fName = "geophys_Quebec_0.1deg_260x260_with_dd_v6" path = os.path.join(folder, fName) rObj = RPN(path) lkf = rObj.get_first_record_for_name_and_level(varname="VF", level=3, level_kind=level_kinds.ARBITRARY) proj_params = rObj.get_proj_parameters_for_the_last_read_rec() lons2d, lats2d = rObj.get_longitudes_and_latitudes_for_the_last_read_rec() lons2d[lons2d >= 180] -= 360 rObj.close() rll = RotatedLatLon(**proj_params) margin = 20 lons2d = lons2d[margin:-margin, margin:-margin] lats2d = lats2d[margin:-margin, margin:-margin] lkf = lkf[margin:-margin, margin:-margin] basemap = rll.get_basemap_object_for_lons_lats(lons2d=lons2d, lats2d=lats2d, resolution="l") x, y = basemap(lons2d, lats2d) fig = plt.figure() gs = GridSpec(1, 2, width_ratios=[1, 1]) ax = fig.add_subplot(gs[0, 0]) df = 0.1 levels = np.arange(0, 1.1, df) cMap = get_cmap("gist_ncar_r", len(levels) - 1) bn = BoundaryNorm(levels, cMap.N) basemap.drawmapboundary(fill_color="0.75") lkf_plot = maskoceans(lons2d, lats2d, lkf, inlands=False) print("Percentage of lakes in the sim domain: {}".format(lkf_plot.mean() * 100)) img = basemap.pcolormesh(x, y, lkf_plot, norm=bn, cmap=cMap) basemap.drawcoastlines() divider = make_axes_locatable(ax) cax = divider.append_axes("bottom", "5%", pad="3%") cb = fig.colorbar(img, cax=cax, ticks=levels, orientation="horizontal") ax = fig.add_subplot(gs[0, 1]) df1 = df levels1 = np.arange(0, 1.1, df1) cell_numms = np.zeros((len(levels1) - 1,)) left = levels[0] right = levels[1] lefts = [] rights = [] lkf_land = lkf[lkf > 0.01] for i in range(len(cell_numms)): cell_numms[i] = ((lkf_land > left) & (lkf_land <= right)).astype(int).sum() lefts.append(left) rights.append(right) left += df1 right += df1 assert isinstance(ax, Axes) ax.bar(lefts, cell_numms, width=df1) # ax.semilogy(rights, cell_numms) ax.xaxis.set_ticks(levels) ax.yaxis.set_ticks(np.arange(1000, 10000, 1000)) sf = ScalarFormatter(useMathText=True) sf.set_powerlimits([-2, 1]) ax.yaxis.set_major_formatter(sf) ax.grid("on") ax.set_xlabel("fraction") ax.set_ylabel("# gridcells") plt.show() fig.tight_layout() fig.savefig("lake_fractions_220x220_0.1deg.jpeg") plt.show() pass
def plot_acc_area_with_glaciers(): gmask_vname = "VF" gmask_level = 2 # gmask_path = "/RESCUE/skynet3_rech1/huziy/CNRCWP/C3/geophys_West_NA_0.25deg_144x115_GLNM_PRSF_CanHR85" gmask_path = "/RESCUE/skynet3_rech1/huziy/CNRCWP/Calgary_flood/geophys_CORDEX_NA_0.11deg_695x680_filled_grDes_barBor_Crop2Gras_peat" # stab reading of the glacier mask # r = RPN(gmask_path) # gmask = r.get_first_record_for_name_and_level(varname=gmask_vname, # level=gmask_level) r = RPN( "/RESCUE/skynet3_rech1/huziy/CNRCWP/Calgary_flood/pm2013061400_00000000p" ) r.get_first_record_for_name("PR") # Because I almost sure that PR is there proj_params = r.get_proj_parameters_for_the_last_read_rec() rll = RotatedLatLon(**proj_params) lons, lats = r.get_longitudes_and_latitudes_for_the_last_read_rec() basemap = rll.get_basemap_object_for_lons_lats(lons2d=lons, lats2d=lats, resolution="i") # gmask = np.ma.masked_where(gmask < 0.01, gmask) gmask = np.ma.masked_all(lons.shape) mask_value = 0.25 gmask[~gmask.mask] = mask_value path = "/RESCUE/skynet3_rech1/huziy/Netbeans Projects/Java/DDM/directions_WestCaUs_dx0.11deg.nc" # path = "/RESCUE/skynet3_rech1/huziy/CNRCWP/C3/infocell_West_NA_0.25deg_104x75_GLNM_PRSF_CanHR85_104x75.nc" ds = Dataset(path) margin = 20 var_name = "accumulation_area" data = ds.variables[var_name][margin:-margin, margin:-margin] data = np.ma.masked_where(data <= 0, data) # flow directions fldr = ds.variables["flow_direction_value"][:][margin:-margin, margin:-margin] i_shifts, j_shifts = direction_and_value.flowdir_values_to_shift(fldr) x, y = basemap(lons, lats) fig = plt.figure(figsize=(15, 15)) dx = (x[-1, -1] - x[0, 0]) / float(x.shape[0]) dy = (y[-1, -1] - y[0, 0]) / float(y.shape[1]) x1 = x - dx / 2.0 y1 = y - dy / 2.0 # im = basemap.pcolormesh(x1, y1, data, norm=LogNorm(vmin=1e3, vmax=1e7), cmap=cm.get_cmap("jet", 12)) # cb = basemap.colorbar(im) # cb.ax.tick_params(labelsize=25) cmap = cm.get_cmap("gray_r", 10) basemap.pcolormesh(x1, y1, gmask, cmap=cmap, vmin=0., vmax=1.) nx, ny = x.shape inds_j, inds_i = np.meshgrid(range(ny), range(nx)) inds_i_next = inds_i + i_shifts inds_j_next = inds_j + j_shifts inds_i_next = np.ma.masked_where((inds_i_next == nx) | (inds_i_next == -1), inds_i_next) inds_j_next = np.ma.masked_where((inds_j_next == ny) | (inds_j_next == -1), inds_j_next) u = np.ma.masked_all_like(x) v = np.ma.masked_all_like(x) good = (~inds_i_next.mask) & (~inds_j_next.mask) u[good] = x[inds_i_next[good], inds_j_next[good]] - x[inds_i[good], inds_j[good]] v[good] = y[inds_i_next[good], inds_j_next[good]] - y[inds_i[good], inds_j[good]] basemap.quiver(x, y, u, v, pivot="tail", width=0.0005, scale_units="xy", headlength=20, headwidth=15, scale=1) basemap.drawcoastlines(linewidth=0.5) basemap.drawrivers(color="b") # plt.legend([Rectangle((0, 0), 5, 5, fc=cmap(mask_value)), ], ["Glaciers", ], loc=3) # basemap.readshapefile("/RESCUE/skynet3_rech1/huziy/CNRCWP/C3/lat_lon/athabasca/athabasca_dissolved", "atabaska", # zorder=2, linewidth=3, color="m") # basemap.readshapefile("/RESCUE/skynet3_rech1/huziy/CNRCWP/C3/lat_lon/fraizer/fraizer", "frazier", # zorder=2, linewidth=3, color="m") # basemap.readshapefile("/RESCUE/skynet3_rech1/huziy/CNRCWP/C3/lat_lon/South_sas/South_sas_dissolved", "south_sask", # zorder=2, linewidth=3, color="m") # basemap.readshapefile("/RESCUE/skynet3_rech1/huziy/CNRCWP/C3/lat_lon/north_sas/north_sas", "north_sask", # zorder=2, linewidth=3, color="m") # basemap.readshapefile("/RESCUE/skynet3_rech1/huziy/CNRCWP/C3/lat_lon/watersheds_up_sas/watershed_up_sas_proj", # "upsas", # zorder=2, linewidth=3, color="m") # basemap.readshapefile("/RESCUE/skynet3_rech1/huziy/CNRCWP/C3/lat_lon/network/network", "rivers", # zorder=2, linewidth=0.5, color="b") # basemap.readshapefile("/RESCUE/skynet3_rech1/huziy/CNRCWP/C3/lat_lon/network_up_sas/network_up_sout_sas_proj", "network", # zorder=2, linewidth=0.5, color="b") basemap.readshapefile( "/skynet3_exec2/aganji/NE_can/bow_river/bow_projected", "basin", color="m", linewidth=2) # plt.savefig("/RESCUE/skynet3_rech1/huziy/CNRCWP/C3/directions.png", bbox_inches="tight") plt.savefig( "/RESCUE/skynet3_rech1/huziy/CNRCWP/Calgary_flood/directions.png", bbox_inches="tight") plt.show()
class GridConfig(object): projection = "rotpole" def __init__(self, **kwargs): self.dx = self.dy = kwargs.get("dx", -1) self.iref, self.jref = kwargs.get("iref", -1), kwargs.get("jref", -1) self.xref, self.yref = kwargs.get("xref", -1), kwargs.get("yref", -1) self.ni, self.nj = kwargs.get("ni", -1), kwargs.get("nj", -1) # interpolated driving data (width of the outer band in number of gridpoints) self.halo = 10 # size of the blending zone in grid points self.blendig = 10 self.rll = None if "rll" not in kwargs: self.lon1, self.lat1 = kwargs.get("lon1", None), kwargs.get("lat1", None) self.lon2, self.lat2 = kwargs.get("lon2", None), kwargs.get("lat2", None) if None not in (self.lon1, self.lon2, self.lat1, self.lat2): self.rll = RotatedLatLon(lon1=self.lon1, lon2=self.lon2, lat1=self.lat1, lat2=self.lat2) else: self.rll = kwargs.get("rll") # private fields self._center_lons_2d = None self._center_lats_2d = None @classmethod def get_default_for_resolution(cls, res=0.5): """ :param res: :rtype GridConfig """ obj = GridConfig() obj.dx = obj.dy = res if res == 0.5: obj.iref = 46 # starts from 1 not 0!! obj.jref = 42 # starts from 1 not 0!! obj.ni = 86 obj.nj = 86 elif res == 0.1: obj.iref = 142 # no need to do -1, doing it later in the formulas obj.jref = 122 obj.xref = 180 # rotated longitude obj.yref = 0 # rotated latitude # projection parameters obj.lon1 = -68.0 obj.lat1 = 52.0 obj.lon2 = 16.65 obj.lat2 = 0.0 obj.ni = 260 obj.nj = 260 return obj def export_to_shape(self, shp_folder="", shp_filename="", free_zone_only=True, export_mask=None, shape_fields=None): """ export the grid to the shape file :param export_mask: Mask to specify exactly which gridcells should be exported :param free_zone_only: :param shp_folder: :param shp_filename: """ import shapefile as shp w = shp.Writer(shp.POLYGON) w.field("i", fieldType="I") w.field("j", fieldType="I") field_names_in_order = ["i", "j"] if shape_fields is not None: for field_name, field in shape_fields.items(): w.field(field_name, *field.type_of_shp_field) field_names_in_order.append(field_name) if isinstance(shp_folder, str): folder = Path(shp_folder) else: folder = shp_folder # create the directory if does not exist if not folder.is_dir(): folder.mkdir() lonr = [(i - (self.iref - 1)) * self.dx + self.xref for i in range(self.ni)] latr = [(j - (self.jref - 1)) * self.dy + self.yref for j in range(self.nj)] margin = 0 if free_zone_only: margin = self.blendig + self.halo start_i = margin start_j = margin end_i = self.ni - margin - 1 end_j = self.nj - margin - 1 if export_mask is None: export_mask = np.ones((self.ni, self.nj), dtype=bool) for i in range(start_i, end_i + 1): x = lonr[i] for j in range(start_j, end_j + 1): y = latr[j] if not export_mask[i, j]: continue p00 = self.rll.toGeographicLonLat(x - self.dx / 2.0, y - self.dy / 2.0) p01 = self.rll.toGeographicLonLat(x - self.dx / 2.0, y + self.dy / 2.0) p11 = self.rll.toGeographicLonLat(x + self.dx / 2.0, y + self.dy / 2.0) p10 = self.rll.toGeographicLonLat(x + self.dx / 2.0, y - self.dy / 2.0) w.poly(parts=[[p00, p01, p11, p10]]) if shape_fields is None: w.record(i + 1, j + 1) else: record_fields = {} record_fields["i"] = i + 1 record_fields["j"] = j + 1 for field_name, field in shape_fields.items(): record_fields[field_name] = field[i, j] w.record( *[record_fields[key] for key in field_names_in_order]) # w.poly(parts=[[[-20, -20], [-20, 20], [20, 20], [20, -20]],]) # w.record(1, 1) w.save(str(folder.joinpath(shp_filename))) def export_to_shape_fiona(self, shp_folder="", shp_filename="", free_zone_only=True, export_mask=None, shape_fields=None): """ export the grid to the shape file using fiona since pyshp was not compatible with arcgis :param export_mask: Mask to specify exactly which gridcells should be exported :param free_zone_only: :param shp_folder: :param shp_filename: """ from fiona.crs import from_epsg, from_string import fiona proj = from_epsg(4326) # proj = from_epsg(4269) # proj = from_string("+units=m +lon_0=-97.0 +o_lon_p=180.0 +R=6370997.0 +o_proj=longlat +proj=ob_tran +o_lat_p=42.5") print(proj) print(dir(proj)) # proj = from_epsg(900913) if isinstance(shp_folder, str): folder = Path(shp_folder) else: folder = shp_folder # create the directory if does not exist if not folder.is_dir(): folder.mkdir() schema = { "geometry": "Polygon", "properties": OrderedDict([("i", "int"), ("j", "int")]) } if shape_fields is not None: # additional fields for field_name, field in shape_fields.items(): schema["properties"][field_name] = field.type_of_shp_field with fiona.open(str(folder.joinpath(shp_filename)), mode="w", driver="ESRI Shapefile", crs=proj, schema=schema) as output: lonr = [(i - (self.iref - 1)) * self.dx + self.xref for i in range(self.ni)] latr = [(j - (self.jref - 1)) * self.dy + self.yref for j in range(self.nj)] margin = 0 if free_zone_only: margin = self.blendig + self.halo start_i = margin start_j = margin end_i = self.ni - margin - 1 end_j = self.nj - margin - 1 if export_mask is None: export_mask = np.ones((self.ni, self.nj), dtype=bool) polygons = [] lake_fractions = [] for i in range(start_i, end_i + 1): x = lonr[i] for j in range(start_j, end_j + 1): y = latr[j] if not export_mask[i, j]: continue p00 = self.rll.toGeographicLonLat(x - self.dx / 2.0, y - self.dy / 2.0) p01 = self.rll.toGeographicLonLat(x - self.dx / 2.0, y + self.dy / 2.0) p11 = self.rll.toGeographicLonLat(x + self.dx / 2.0, y + self.dy / 2.0) p10 = self.rll.toGeographicLonLat(x + self.dx / 2.0, y - self.dy / 2.0) # p00 = (x - self.dx / 2.0, y - self.dy / 2.0) # p01 = (x - self.dx / 2.0, y + self.dy / 2.0) # p11 = (x + self.dx / 2.0, y + self.dy / 2.0) # p10 = (x + self.dx / 2.0, y - self.dy / 2.0) poly = Polygon(shell=[p00, p01, p11, p10, p00]) props = OrderedDict([("i", i + 1), ("j", j + 1)]) polygons.append(PolygonPatch(poly)) if shape_fields is not None: lake_fractions.append(shape_fields["lkfr"][i, j]) for field_name, field in shape_fields.items(): converter = float if field.type_of_shp_field.startswith( "float") else int props[field_name] = converter(field[i, j]) output.write({ "geometry": mapping(poly), "properties": props }) # plot the gridcells with basemap # pcol = PatchCollection(polygons, cmap="bone_r") # pcol.set_array(np.array(lake_fractions)) # import matplotlib.pyplot as plt # bmp = self.get_basemap_for_free_zone(resolution="l") # fig = plt.figure() # ax = fig.add_subplot(111) # bmp.ax = ax # ax.add_collection(pcol) # bmp.drawcoastlines(ax=ax) # plt.show() def export_to_shape_ogr(self, shp_folder="", shp_filename="", free_zone_only=True): """ export the grid to the shape file :param free_zone_only: :param shp_folder: :param shp_filename: """ from osgeo import ogr, osr folder = Path(shp_folder) # create the directory if does not exist if not folder.is_dir(): folder.mkdir() # set up the shapefile driver driver = ogr.GetDriverByName("ESRI Shapefile") if not shp_filename.lower().endswith(".shp"): shp_filename += ".shp" # create the data source data_source = driver.CreateDataSource( str(folder.joinpath(shp_filename))) srs = osr.SpatialReference() srs.ImportFromWkt(osr.SRS_WKT_WGS84) print(srs) print(srs.ExportToPrettyWkt()) # create the layer layer = data_source.CreateLayer("grid", srs, ogr.wkbPolygon) layer.CreateField(ogr.FieldDefn("i", ogr.OFTInteger)) layer.CreateField(ogr.FieldDefn("j", ogr.OFTInteger)) lonr = [(i - (self.iref - 1)) * self.dx + self.xref for i in range(self.ni)] latr = [(j - (self.jref - 1)) * self.dy + self.yref for j in range(self.nj)] margin = 0 if free_zone_only: margin = self.blendig + self.halo start_i = margin start_j = margin end_i = self.ni - margin - 1 end_j = self.nj - margin - 1 for i in range(start_i, end_i + 1): x = lonr[i] for j in range(start_j, end_j + 1): y = latr[j] # create the feature feature = ogr.Feature(layer.GetLayerDefn()) p00 = self.rll.toGeographicLonLat(x - self.dx / 2.0, y - self.dy / 2.0) p01 = self.rll.toGeographicLonLat(x - self.dx / 2.0, y + self.dy / 2.0) p11 = self.rll.toGeographicLonLat(x + self.dx / 2.0, y + self.dy / 2.0) p10 = self.rll.toGeographicLonLat(x + self.dx / 2.0, y - self.dy / 2.0) ring = ogr.Geometry(ogr.wkbLinearRing) ring.AddPoint(*p00) ring.AddPoint(*p01) ring.AddPoint(*p11) ring.AddPoint(*p10) poly = ogr.Geometry(ogr.wkbPolygon) poly.AddGeometry(ring) feature.SetField("i", i + 1) feature.SetField("j", j + 1) feature.SetGeometry(poly) layer.CreateFeature(feature) feature.Destroy() # w.poly(parts=[[[-20, -20], [-20, 20], [20, 20], [20, -20]],]) # w.record(1, 1) data_source.Destroy() def export_to_shape_native_grid(self, shp_folder="", shp_filename="", free_zone_only=True): """ export the grid to the shape file :param free_zone_only: :param shp_folder: :param shp_filename: """ from osgeo import ogr, osr folder = Path(shp_folder) # create the directory if does not exist if not folder.is_dir(): folder.mkdir() # set up the shapefile driver driver = ogr.GetDriverByName("ESRI Shapefile") if not shp_filename.lower().endswith(".shp"): shp_filename += ".shp" # create the data source data_source = driver.CreateDataSource( str(folder.joinpath(shp_filename))) # Projection srs = osr.SpatialReference() bmp = self.get_basemap_for_free_zone() srs.ImportFromProj4(bmp.proj4string) print(srs) print(srs.ExportToPrettyWkt()) # create the layer layer = data_source.CreateLayer("grid", srs, ogr.wkbPolygon) layer.CreateField(ogr.FieldDefn("i", ogr.OFTInteger)) layer.CreateField(ogr.FieldDefn("j", ogr.OFTInteger)) lonr = [(i - (self.iref - 1)) * self.dx + self.xref for i in range(self.ni)] latr = [(j - (self.jref - 1)) * self.dy + self.yref for j in range(self.nj)] margin = 0 if free_zone_only: margin = self.blendig + self.halo start_i = margin start_j = margin end_i = self.ni - margin - 1 end_j = self.nj - margin - 1 for i in range(start_i, end_i + 1): x = lonr[i] for j in range(start_j, end_j + 1): y = latr[j] # create the feature feature = ogr.Feature(layer.GetLayerDefn()) p00 = (x - self.dx / 2.0, y - self.dy / 2.0) p01 = (x - self.dx / 2.0, y + self.dy / 2.0) p11 = (x + self.dx / 2.0, y + self.dy / 2.0) p10 = (x + self.dx / 2.0, y - self.dy / 2.0) ring = ogr.Geometry(ogr.wkbLinearRing) ring.AddPoint(*p00) ring.AddPoint(*p01) ring.AddPoint(*p11) ring.AddPoint(*p10) poly = ogr.Geometry(ogr.wkbPolygon) poly.AddGeometry(ring) feature.SetField("i", i + 1) feature.SetField("j", j + 1) feature.SetGeometry(poly) layer.CreateFeature(feature) feature.Destroy() # w.poly(parts=[[[-20, -20], [-20, 20], [20, 20], [20, -20]],]) # w.record(1, 1) data_source.Destroy() def get_basemap_for_free_zone(self, halo=None, blending=None, **kwargs): if halo is None: halo = self.halo if blending is None: blending = self.blendig lons_c, lats_c = self.get_free_zone_corners(halo=halo, blending=blending) return self.get_basemap(lons=lons_c, lats=lats_c, **kwargs) def get_basemap_using_shape_with_polygons_of_interest( self, lons, lats, shp_path=None, mask_margin=5, **kwargs): if shp_path is None: return self.get_basemap(lons=lons, lats=lats, **kwargs) reg_of_interest = get_mask(lons, lats, shp_path=shp_path) > 0 i_list, j_list = np.where(reg_of_interest) i_min = min(i_list) - mask_margin i_max = max(i_list) + mask_margin j_min = min(j_list) - mask_margin j_max = max(j_list) + mask_margin bsmap = self.get_basemap(lons=lons[i_min:i_max + 1, j_min:j_max + 1], lats=lats[i_min:i_max + 1, j_min:j_max + 1], **kwargs) return bsmap, reg_of_interest def get_basemap(self, lons=None, lats=None, **kwargs): if lons is None: lonr = [(i - (self.iref - 1)) * self.dx + self.xref for i in [0, self.ni - 1]] latr = [(j - (self.jref - 1)) * self.dy + self.yref for j in [0, self.nj - 1]] latr, lonr = np.meshgrid(latr, lonr) lons = np.zeros((2, 2)) lats = np.zeros((2, 2)) for i in [-1, 0]: for j in [-1, 0]: shiftx = self.dx / 2.0 shifty = self.dy / 2.0 shiftx = -shiftx if i == 0 else shiftx shifty = -shifty if i == 0 else shifty lons[i, j], lats[i, j] = self.rll.toGeographicLonLat( lonr[i, j] + shiftx, latr[i, j] + shifty) return self.get_rot_latlon_proj_obj().get_basemap_object_for_lons_lats( lons2d=lons, lats2d=lats, **kwargs) def get_corners_in_proj_coords(self): """ :return: xxcorners, yycorners xxcorners = [[xll, xur], [xll, xur]] yycorners = [[yll, yll], [yur, yur]] """ lonr = [(i - (self.iref - 1)) * self.dx + self.xref for i in [0, self.ni - 1]] latr = [(j - (self.jref - 1)) * self.dy + self.yref for j in [0, self.nj - 1]] latr, lonr = np.meshgrid(latr, lonr) return lonr, latr def get_free_zone_corners(self, halo=10, blending=10): margin = halo + blending lonr = [(i - (self.iref - 1)) * self.dx + self.xref for i in [margin, self.ni - margin - 1]] latr = [(j - (self.jref - 1)) * self.dy + self.yref for j in [margin, self.nj - margin - 1]] latr, lonr = np.meshgrid(latr, lonr) lons = np.zeros((2, 2)) lats = np.zeros((2, 2)) for i in [-1, 0]: mulx = -1 if i >= 0 else 1 shiftx = mulx * self.dx / 2.0 for j in [-1, 0]: muly = -1 if j >= 0 else 1 shifty = muly * self.dy / 2.0 lons[i, j], lats[i, j] = self.rll.toGeographicLonLat( lonr[i, j] + shiftx, latr[i, j] + shifty) return lons, lats def get_rot_latlon_proj_obj(self): return self.rll def subgrid(self, i0, j0, di=-1, dj=-1): """ :param i0: 0-based i-index of the lower left corner of the domain :param j0: :param di: number of grid points in i direction :param dj: number of grid points in j direction """ subgr = GridConfig(rll=self.rll, dx=self.dx, dy=self.dy, xref=self.xref, yref=self.yref) if di > 0: subgr.ni = di else: subgr.ni = self.ni - i0 if dj > 0: subgr.nj = dj else: subgr.nj = self.nj - j0 subgr.iref = self.iref - i0 subgr.jref = self.jref - j0 return subgr def copy(self): return self.subgrid(0, 0, di=self.ni, dj=self.nj) def double_resolution(self): gc = GridConfig(rll=self.rll, dx=self.dx / 2.0, dy=self.dy / 2.0, xref=self.xref, yref=self.yref) gc.ni = 2 * self.ni gc.nj = 2 * self.nj gc.iref = 2 * self.iref gc.jref = 2 * self.jref gc.xref -= gc.dx / 2.0 gc.yref -= gc.dy / 2.0 return gc def double_resolution_keep_free_domain_same(self, halo_pts=10, blending_pts=10): gc = GridConfig(rll=self.rll, dx=self.dx / 2.0, dy=self.dy / 2.0, xref=self.xref, yref=self.yref) margin_pts = halo_pts + blending_pts gc.ni = 2 * (self.ni - 2 * margin_pts) + 2 * margin_pts gc.nj = 2 * (self.nj - 2 * margin_pts) + 2 * margin_pts gc.iref = 2 * (self.iref - margin_pts) + margin_pts gc.jref = 2 * (self.jref - margin_pts) + margin_pts gc.xref -= gc.dx / 2.0 gc.yref -= gc.dy / 2.0 return gc def decrease_resolution_keep_free_domain_same(self, factor, halo_pts=10, blending_pts=10): gc = GridConfig(rll=self.rll, dx=self.dx * factor, dy=self.dy * factor, xref=self.xref, yref=self.yref) margin_pts = halo_pts + blending_pts gc.ni = (self.ni - 2 * margin_pts) / factor + 2 * margin_pts gc.nj = (self.nj - 2 * margin_pts) / factor + 2 * margin_pts # Change the reference point if the new iref and jref cannot be the same new_iref = self.iref - margin_pts new_jref = self.jref - margin_pts new_iref = new_iref // factor + (new_iref % factor != 0) x00 = self.xref + self.dx * (margin_pts + 1 - self.iref) - self.dx / 2.0 new_xref = x00 + new_iref * self.dx * factor - self.dx * factor / 2.0 new_jref = new_jref // factor + (new_jref % factor != 0) y00 = self.yref + self.dy * (margin_pts + 1 - self.jref) - self.dy / 2.0 new_yref = y00 + new_jref * self.dy * factor - self.dy * factor / 2.0 gc.iref = new_iref + margin_pts gc.jref = new_jref + margin_pts gc.xref = new_xref gc.yref = new_yref gc.ni = int(gc.ni) gc.nj = int(gc.nj) return gc def move(self, di=0, dj=0): gc = GridConfig(rll=self.rll, dx=self.dx, dy=self.dy, xref=self.xref, yref=self.yref, ni=self.ni, nj=self.nj) gc.iref -= di gc.jref -= dj return gc def expand(self, di=0, dj=0): gc = GridConfig(rll=self.rll, dx=self.dx, dy=self.dy, xref=self.xref, yref=self.yref, ni=self.ni + di, nj=self.nj + dj) gc.iref = self.iref gc.jref = self.jref return gc def __str__(self): s = """ Grd_ni = {ni} , Grd_nj = {nj} , Grd_dx = {dx} , Grd_dy = {dy}, Grd_iref = {iref} , Grd_jref = {jref} , Grd_latr = {latref} , Grd_lonr = {lonref} , Grd_xlat1 = {lat1} , Grd_xlon1 = {lon1} , Grd_xlat2 = {lat2} , Grd_xlon2 = {lon2} , """.format(ni=self.ni, nj=self.nj, dx=self.dx, dy=self.dy, iref=self.iref, jref=self.jref, latref=self.yref, lonref=self.xref, lat1=self.rll.lat1, lon1=self.rll.lon1, lat2=self.rll.lat2, lon2=self.rll.lon2) return s def __hash__(self): return hash(str(self).lower()) def __eq__(self, other): if other is None: return False return str(self).lower() == str(other).lower() def get_lons_and_lats_of_gridpoint_centers(self): """ :return: lons and lats corresponding to the gridpoint centers """ if self._center_lons_2d is not None: return self._center_lons_2d, self._center_lats_2d lonr = [(i - (self.iref - 1)) * self.dx + self.xref for i in range(self.ni)] latr = [(j - (self.jref - 1)) * self.dy + self.yref for j in range(self.nj)] lons = np.zeros((self.ni, self.nj)) lats = np.zeros_like(lons) for i, lonri in enumerate(lonr): for j, latrj in enumerate(latr): lons[i, j], lats[i, j] = self.rll.toGeographicLonLat(lonri, latrj) # Save for re-use self._center_lons_2d = lons self._center_lats_2d = lats return lons, lats
def get_coords_and_basemap(self, subregion=None, reload=True, **basemap_kwargs): """ :return: lons2d, lats2d, basemap [based on the bathymetry file and gemclim_settings.nml] if reload is True, do not use cached arrays even if they are available """ # Read longitudes and latitudes and create the basemap only if they are not initialized if self.basemap is None or reload: with Dataset(os.path.join(self.data_folder, self.bathymetry_file)) as ds: if "nav_lon" in ds.variables: self.lons, self.lats = ds.variables["nav_lon"][:].transpose(), ds.variables["nav_lat"][:].transpose() else: for vname, v in ds.variables.items(): if "lon" in vname.lower(): self.lons = v[:].T continue if "lat" in vname.lower(): self.lats = v[:].T continue if self.lons is not None and self.lats is not None: break import re lon1, lat1 = None, None lon2, lat2 = None, None with open(os.path.join(self.data_folder, self.proj_file)) as f: for line in f: if "Grd_xlat1" in line and "Grd_xlon1" in line: groups = re.findall(r"-?\b\d+.?\d*\b", line) lat1, lon1 = [float(s) for s in groups] if "Grd_xlat2" in line and "Grd_xlon2" in line: groups = re.findall(r"-?\b\d+.?\d*\b", line) lat2, lon2 = [float(s) for s in groups] rll = RotatedLatLon(lon1=lon1, lat1=lat1, lon2=lon2, lat2=lat2) nx, ny = self.lons.shape if subregion is not None: ill, iur, jll, jur = int(nx * subregion[0]), int(nx * subregion[1]), int(ny * subregion[2]), int(ny * subregion[3]) else: ill, iur, jll, jur = 0, self.lons.shape[0], 0, self.lons.shape[1] self.basemap = rll.get_basemap_object_for_lons_lats(lons2d=self.lons[ill:iur, jll:jur], lats2d=self.lats[ill:iur, jll:jur], **basemap_kwargs) print(lon1, lat1, lon2, lat2) # self.basemap.drawcoastlines() # xx, yy = self.basemap(self.lons, self.lats) # self.basemap.pcolormesh(xx, yy, ds.variables["Bathymetry"][:].transpose()) # plt.show() self.lons[self.lons > 180] -= 360 return self.lons, self.lats, self.basemap
def main(): # plot_utils.apply_plot_params(20) folder = "/home/huziy/skynet3_rech1/from_guillimin" fname = "geophys_Quebec_0.1deg_260x260_with_dd_v6" path = os.path.join(folder, fname) rObj = RPN(path) mg = rObj.get_first_record_for_name_and_level("MG", level=0, level_kind=level_kinds.PRESSURE) # j2 = rObj.get_first_record_for_name("J2") levs = [0, 100, 200, 300, 500, 700, 1000, 1500, 2000, 2800] norm = BoundaryNorm(levs, len(levs) - 1) me = rObj.get_first_record_for_name_and_level("ME", level=0, level_kind=level_kinds.ARBITRARY) proj_params = rObj.get_proj_parameters_for_the_last_read_rec() print(me.shape) lons2d, lats2d = rObj.get_longitudes_and_latitudes_for_the_last_read_rec() lons2d[lons2d > 180] -= 360 # me_to_plot = np.ma.masked_where(mg < 0.4, me) me_to_plot = me # print me_to_plot.min(), me_to_plot.max() rll = RotatedLatLon(**proj_params) basemap = rll.get_basemap_object_for_lons_lats(lons2d=lons2d, lats2d=lats2d) rObj.close() x, y = basemap(lons2d, lats2d) plt.figure() ax = plt.gca() # the_cmap = cm.get_cmap(name = "gist_earth", lut=len(levs) -1) # the_cmap = my_colormaps.get_cmap_from_ncl_spec_file(path="colormap_files/topo_15lev.rgb") the_cmap = my_colormaps.get_cmap_from_ncl_spec_file( path="colormap_files/OceanLakeLandSnow.rgb", ncolors=len(levs) - 1 ) # new_cm = matplotlib.colors.LinearSegmentedColormap('colormap',new_dict,len(levs) - 1) me_to_plot = maskoceans(lons2d, lats2d, me_to_plot, resolution="l") basemap.contourf(x, y, me_to_plot, cmap=the_cmap, levels=levs, norm=norm) # basemap.fillcontinents(color = "none", lake_color="aqua") basemap.drawmapboundary(fill_color="#479BF9") basemap.drawcoastlines(linewidth=0.5) basemap.drawmeridians(np.arange(-180, 180, 20), labels=[1, 0, 0, 1]) basemap.drawparallels(np.arange(45, 75, 15), labels=[1, 0, 0, 1]) basemap.readshapefile("data/shape/contour_bv_MRCC/Bassins_MRCC_latlon", name="basin", linewidth=1) divider = make_axes_locatable(ax) cax = divider.append_axes("right", "5%", pad="3%") plt.colorbar(ticks=levs, cax=cax) # basemap.scatter(x, y, color="k", s=1, linewidths=0, ax=ax, zorder=2) margin = 20 x1 = x[margin, margin] x2 = x[-margin, margin] y1 = y[margin, margin] y2 = y[margin, -margin] pol_corners = ((x1, y1), (x2, y1), (x2, y2), (x1, y2)) ax.add_patch(Polygon(xy=pol_corners, fc="none", ls="dashed", lw=3)) # plt.tight_layout() # plt.show() plt.savefig("free_domain_260x260.png", dpi=cpp.FIG_SAVE_DPI) pass
def main(): """ """ # s_lons = [-3.38, 3.40, -12.45, -11.04,-2.92, 0.1,32.55,30.48,23.6,31.27,15.31,23.91,17.51,21.08] # s_lats = [16.26,11.88,14.9,13.91,10.57,6.2,15.61,19.18,-14.02,-21.13,-4.26,4.97,-28.71,-28.69] # assert len(s_lons) == len(s_lats) #path = "data/directions_Africa_Bessam_0.44/infocell_Africa.nc" #path = "/home/huziy/skynet3_exec1/for_offline_routing/directions_africa_dx0.44deg_2.nc" path = "/skynet3_rech1/huziy/for_Arman_routing_data/infocell_na_0.44deg_arman.nc" ds = Dataset(path) dirs = ds.variables["flow_direction_value"][:] acc_area = ds.variables["accumulation_area"][:] lons2d = ds.variables["lon"][:] lats2d = ds.variables["lat"][:] lon_1, lat_1 = -97, 47.5 lon_2, lat_2 = -7, 0 lons2d[lons2d >= 180] -= 360 #min_lon = lons2d[0,0] #max_lon = lons2d[-1,-1] #min_lat = lats2d[0, 0] #max_lat = lats2d[-1,-1] #plot_utils.apply_plot_params(width_pt=None, width_cm=80) #print max_lon fig = plt.figure(dpi=800) #TODO: change projection to rotpole (it will require params) #b = Basemap(projection="rotpole", llcrnrlon=min_lon, # llcrnrlat=min_lat, # urcrnrlon=max_lon, urcrnrlat=max_lat, resolution="i") myproj = RotatedLatLon(lon1=lon_1, lat1=lat_1, lon2=lon_2, lat2=lat_2) print(lons2d.shape) b = myproj.get_basemap_object_for_lons_lats(lons2d[100:150, 70:132], lats2d[100:150, 70:132]) x, y = b(lons2d, lats2d) b.drawcoastlines(linewidth=0.2, color="0.5") # b.pcolormesh(x, y, np.ma.masked_where(dirs <= 0, dirs )) # plt.colorbar() di_list = np.array([1, 1, 0, -1, -1, -1, 0, 1]) dj_list = np.array([0, -1, -1, -1, 0, 1, 1, 1]) delta_indices = np.log2(dirs[dirs > 0]) delta_indices = delta_indices.astype(int) di = di_list[delta_indices] dj = dj_list[delta_indices] acc_area = np.ma.masked_where(acc_area < 0, acc_area) #img = b.pcolormesh(x, y, np.ma.log(acc_area)) ax = plt.gca() #divider = make_axes_locatable(ax) #cax = divider.append_axes("right", "5%", pad="3%") #plt.colorbar(img, cax = cax) i_indices_1d = list(range(dirs.shape[0])) j_indices_1d = list(range(dirs.shape[1])) j_indices_2d, i_indices_2d = np.meshgrid(j_indices_1d, i_indices_1d) i_indices_2d_next = np.zeros_like(i_indices_2d) j_indices_2d_next = np.zeros_like(i_indices_2d) i_indices_2d_next[dirs > 0] = i_indices_2d[dirs > 0] + di j_indices_2d_next[dirs > 0] = j_indices_2d[dirs > 0] + dj for i, j, i_next, j_next in zip(i_indices_2d[dirs > 0], j_indices_2d[dirs > 0], i_indices_2d_next[dirs > 0], j_indices_2d_next[dirs > 0]): # ax.add_line(Line2D([x[i,j], x[i_next, j_next]], [y[i,j], y[i_next, j_next]], linewidth=0.5)) if i == i_next and j == j_next: continue p1 = [x[i, j], y[i, j]] p2 = [x[i_next, j_next], y[i_next, j_next]] dr = [p2[0] - p1[0], p2[1] - p1[1]] ax.add_patch(FancyArrow(p1[0], p1[1], dr[0], dr[1], linewidth=0.5, fc="k", head_width=0.1, length_includes_head=True)) # x1, y1 = b(s_lons, s_lats) # b.scatter(x1, y1, c="r", linewidth=0, zorder = 7, ax = ax) # b.drawrivers(linewidth=0.5, color="#0cf5f8", zorder=8, ax=ax) # b.drawmeridians(np.arange(-10, 90,30)) # b.drawparallels(np.arange(-50, 40, 5), labels=[1,1,1,1], linewidth=0.1) plt.tight_layout() # plt.show() #b.readshapefile("/home/huziy/skynet3_exec1/other_shape/af_major_basins/af_basins", "basin", # linewidth=3, zorder=9, ax=ax #) plt.savefig("with_station_riv_af_dirs_basin_1.0.eps") pass
def main(base_folder="/skynet3_rech1/huziy/veg_fractions/", fname="pm1983120100_00000000p", canopy_name="Y2C", label="USGS", depth_to_bedrock_name="8L"): data_path = os.path.join(base_folder, fname) r = RPN(data_path) veg_fractions = r.get_2D_field_on_all_levels(name=canopy_name) print(list(veg_fractions.keys())) sand = r.get_first_record_for_name("SAND") clay = r.get_first_record_for_name("CLAY") dpth_to_bedrock = r.get_first_record_for_name(depth_to_bedrock_name) proj_params = r.get_proj_parameters_for_the_last_read_rec() lons, lats = r.get_longitudes_and_latitudes_for_the_last_read_rec() print(lons.shape) rll = RotatedLatLon(lon1=proj_params["lon1"], lat1=proj_params["lat1"], lon2=proj_params["lon2"], lat2=proj_params["lat2"]) lon0, lat0 = rll.get_true_pole_coords_in_rotated_system() plon, _ = rll.get_north_pole_coords() b = Basemap(projection="rotpole", llcrnrlon=lons[0, 0], llcrnrlat=lats[0, 0], urcrnrlon=lons[-1, -1], urcrnrlat=lats[-1, -1], lon_0=lon0 - 180, o_lon_p=lon0, o_lat_p=lat0) lons[lons > 180] -= 360 for lev in list(veg_fractions.keys()): veg_fractions[lev] = maskoceans(lons, lats, veg_fractions[lev], inlands=False) sand = maskoceans(lons, lats, sand) clay = maskoceans(lons, lats, clay) dpth_to_bedrock = maskoceans(lons, lats, dpth_to_bedrock) x, y = b(lons, lats) plot_veg_fractions(x, y, b, veg_fractions, out_image=os.path.join( base_folder, "veg_fractions_{0}.jpeg".format(label))) plot_sand_and_clay(x, y, b, sand, clay, out_image=os.path.join( base_folder, "sand_clay_{0}.jpeg".format(label))) # set relation between vegetation frsction fields and names veg_fract_dict = {} for lev, the_field in veg_fractions.items(): lev = int(lev) if lev not in y2c_level_to_title: continue veg_fract_dict[y2c_level_to_title[lev]] = the_field data = {"SAND": sand, "CLAY": clay, "BDRCK_DEPTH": dpth_to_bedrock} data.update(veg_fract_dict) return b, lons, lats, data, label
class GridConfig(object): projection = "rotpole" def __init__(self, **kwargs): self.dx = self.dy = kwargs.get("dx", -1) self.iref, self.jref = kwargs.get("iref", -1), kwargs.get("jref", -1) self.xref, self.yref = kwargs.get("xref", -1), kwargs.get("yref", -1) self.ni, self.nj = kwargs.get("ni", -1), kwargs.get("nj", -1) # interpolated driving data (width of the outer band in number of gridpoints) self.halo = 10 # size of the blending zone in grid points self.blendig = 10 self.rll = None if "rll" not in kwargs: self.lon1, self.lat1 = kwargs.get("lon1", None), kwargs.get("lat1", None) self.lon2, self.lat2 = kwargs.get("lon2", None), kwargs.get("lat2", None) if None not in (self.lon1, self.lon2, self.lat1, self.lat2): self.rll = RotatedLatLon(lon1=self.lon1, lon2=self.lon2, lat1=self.lat1, lat2=self.lat2) else: self.rll = kwargs.get("rll") @classmethod def get_default_for_resolution(cls, res=0.5): """ :param res: :rtype GridConfig """ obj = GridConfig() obj.dx = obj.dy = res if res == 0.5: obj.iref = 46 # starts from 1 not 0!! obj.jref = 42 # starts from 1 not 0!! obj.ni = 86 obj.nj = 86 elif res == 0.1: obj.iref = 142 # no need to do -1, doing it later in the formulas obj.jref = 122 obj.xref = 180 # rotated longitude obj.yref = 0 # rotated latitude # projection parameters obj.lon1 = -68.0 obj.lat1 = 52.0 obj.lon2 = 16.65 obj.lat2 = 0.0 obj.ni = 260 obj.nj = 260 return obj def export_to_shape(self, shp_folder="", shp_filename="", free_zone_only=True, export_mask=None, shape_fields=None): """ export the grid to the shape file :param export_mask: Mask to specify exactly which gridcells should be exported :param free_zone_only: :param shp_folder: :param shp_filename: """ import shapefile as shp w = shp.Writer(shp.POLYGON) w.field("i", fieldType="I") w.field("j", fieldType="I") field_names_in_order = ["i", "j"] if shape_fields is not None: for field_name, field in shape_fields.items(): w.field(field_name, *field.type_of_shp_field) field_names_in_order.append(field_name) if isinstance(shp_folder, str): folder = Path(shp_folder) else: folder = shp_folder # create the directory if does not exist if not folder.is_dir(): folder.mkdir() lonr = [(i - (self.iref - 1)) * self.dx + self.xref for i in range(self.ni)] latr = [(j - (self.jref - 1)) * self.dy + self.yref for j in range(self.nj)] margin = 0 if free_zone_only: margin = self.blendig + self.halo start_i = margin start_j = margin end_i = self.ni - margin - 1 end_j = self.nj - margin - 1 if export_mask is None: export_mask = np.ones((self.ni, self.nj), dtype=bool) for i in range(start_i, end_i + 1): x = lonr[i] for j in range(start_j, end_j + 1): y = latr[j] if not export_mask[i, j]: continue p00 = self.rll.toGeographicLonLat(x - self.dx / 2.0, y - self.dy / 2.0) p01 = self.rll.toGeographicLonLat(x - self.dx / 2.0, y + self.dy / 2.0) p11 = self.rll.toGeographicLonLat(x + self.dx / 2.0, y + self.dy / 2.0) p10 = self.rll.toGeographicLonLat(x + self.dx / 2.0, y - self.dy / 2.0) w.poly(parts=[ [p00, p01, p11, p10] ]) if shape_fields is None: w.record(i + 1, j + 1) else: record_fields = {} record_fields["i"] = i + 1 record_fields["j"] = j + 1 for field_name, field in shape_fields.items(): record_fields[field_name] = field[i, j] w.record(*[record_fields[key] for key in field_names_in_order]) # w.poly(parts=[[[-20, -20], [-20, 20], [20, 20], [20, -20]],]) # w.record(1, 1) w.save(str(folder.joinpath(shp_filename))) def export_to_shape_fiona(self, shp_folder="", shp_filename="", free_zone_only=True, export_mask=None, shape_fields=None): """ export the grid to the shape file using fiona since pyshp was not compatible with arcgis :param export_mask: Mask to specify exactly which gridcells should be exported :param free_zone_only: :param shp_folder: :param shp_filename: """ from fiona.crs import from_epsg, from_string import fiona proj = from_epsg(4326) # proj = from_epsg(4269) # proj = from_string("+units=m +lon_0=-97.0 +o_lon_p=180.0 +R=6370997.0 +o_proj=longlat +proj=ob_tran +o_lat_p=42.5") print(proj) print(dir(proj)) # proj = from_epsg(900913) if isinstance(shp_folder, str): folder = Path(shp_folder) else: folder = shp_folder # create the directory if does not exist if not folder.is_dir(): folder.mkdir() schema = { "geometry": "Polygon", "properties": OrderedDict( [("i", "int"), ("j", "int")] ) } if shape_fields is not None: # additional fields for field_name, field in shape_fields.items(): schema["properties"][field_name] = field.type_of_shp_field with fiona.open(str(folder.joinpath(shp_filename)), mode="w", driver="ESRI Shapefile", crs=proj, schema=schema) as output: lonr = [(i - (self.iref - 1)) * self.dx + self.xref for i in range(self.ni)] latr = [(j - (self.jref - 1)) * self.dy + self.yref for j in range(self.nj)] margin = 0 if free_zone_only: margin = self.blendig + self.halo start_i = margin start_j = margin end_i = self.ni - margin - 1 end_j = self.nj - margin - 1 if export_mask is None: export_mask = np.ones((self.ni, self.nj), dtype=bool) polygons = [] lake_fractions = [] for i in range(start_i, end_i + 1): x = lonr[i] for j in range(start_j, end_j + 1): y = latr[j] if not export_mask[i, j]: continue p00 = self.rll.toGeographicLonLat(x - self.dx / 2.0, y - self.dy / 2.0) p01 = self.rll.toGeographicLonLat(x - self.dx / 2.0, y + self.dy / 2.0) p11 = self.rll.toGeographicLonLat(x + self.dx / 2.0, y + self.dy / 2.0) p10 = self.rll.toGeographicLonLat(x + self.dx / 2.0, y - self.dy / 2.0) # p00 = (x - self.dx / 2.0, y - self.dy / 2.0) # p01 = (x - self.dx / 2.0, y + self.dy / 2.0) # p11 = (x + self.dx / 2.0, y + self.dy / 2.0) # p10 = (x + self.dx / 2.0, y - self.dy / 2.0) poly = Polygon(shell=[p00, p01, p11, p10, p00]) props = OrderedDict([("i", i + 1), ("j", j + 1)]) polygons.append(PolygonPatch(poly)) if shape_fields is not None: lake_fractions.append(shape_fields["lkfr"][i, j]) for field_name, field in shape_fields.items(): converter = float if field.type_of_shp_field in ["float"] else int props[field_name] = converter(field[i, j]) output.write({"geometry": mapping(poly), "properties": props}) # plot the gridcells with basemap # pcol = PatchCollection(polygons, cmap="bone_r") # pcol.set_array(np.array(lake_fractions)) # import matplotlib.pyplot as plt # bmp = self.get_basemap_for_free_zone(resolution="l") # fig = plt.figure() # ax = fig.add_subplot(111) # bmp.ax = ax # ax.add_collection(pcol) # bmp.drawcoastlines(ax=ax) # plt.show() def export_to_shape_ogr(self, shp_folder="", shp_filename="", free_zone_only=True): """ export the grid to the shape file :param free_zone_only: :param shp_folder: :param shp_filename: """ from osgeo import ogr, osr folder = Path(shp_folder) # create the directory if does not exist if not folder.is_dir(): folder.mkdir() # set up the shapefile driver driver = ogr.GetDriverByName("ESRI Shapefile") if not shp_filename.lower().endswith(".shp"): shp_filename += ".shp" # create the data source data_source = driver.CreateDataSource(str(folder.joinpath(shp_filename))) srs = osr.SpatialReference() srs.ImportFromWkt(osr.SRS_WKT_WGS84) print(srs) print(srs.ExportToPrettyWkt()) # create the layer layer = data_source.CreateLayer("grid", srs, ogr.wkbPolygon) layer.CreateField(ogr.FieldDefn("i", ogr.OFTInteger)) layer.CreateField(ogr.FieldDefn("j", ogr.OFTInteger)) lonr = [(i - (self.iref - 1)) * self.dx + self.xref for i in range(self.ni)] latr = [(j - (self.jref - 1)) * self.dy + self.yref for j in range(self.nj)] margin = 0 if free_zone_only: margin = self.blendig + self.halo start_i = margin start_j = margin end_i = self.ni - margin - 1 end_j = self.nj - margin - 1 for i in range(start_i, end_i + 1): x = lonr[i] for j in range(start_j, end_j + 1): y = latr[j] # create the feature feature = ogr.Feature(layer.GetLayerDefn()) p00 = self.rll.toGeographicLonLat(x - self.dx / 2.0, y - self.dy / 2.0) p01 = self.rll.toGeographicLonLat(x - self.dx / 2.0, y + self.dy / 2.0) p11 = self.rll.toGeographicLonLat(x + self.dx / 2.0, y + self.dy / 2.0) p10 = self.rll.toGeographicLonLat(x + self.dx / 2.0, y - self.dy / 2.0) ring = ogr.Geometry(ogr.wkbLinearRing) ring.AddPoint(*p00) ring.AddPoint(*p01) ring.AddPoint(*p11) ring.AddPoint(*p10) poly = ogr.Geometry(ogr.wkbPolygon) poly.AddGeometry(ring) feature.SetField("i", i + 1) feature.SetField("j", j + 1) feature.SetGeometry(poly) layer.CreateFeature(feature) feature.Destroy() # w.poly(parts=[[[-20, -20], [-20, 20], [20, 20], [20, -20]],]) # w.record(1, 1) data_source.Destroy() def export_to_shape_native_grid(self, shp_folder="", shp_filename="", free_zone_only=True): """ export the grid to the shape file :param free_zone_only: :param shp_folder: :param shp_filename: """ from osgeo import ogr, osr folder = Path(shp_folder) # create the directory if does not exist if not folder.is_dir(): folder.mkdir() # set up the shapefile driver driver = ogr.GetDriverByName("ESRI Shapefile") if not shp_filename.lower().endswith(".shp"): shp_filename += ".shp" # create the data source data_source = driver.CreateDataSource(str(folder.joinpath(shp_filename))) # Projection srs = osr.SpatialReference() bmp = self.get_basemap_for_free_zone() srs.ImportFromProj4(bmp.proj4string) print(srs) print(srs.ExportToPrettyWkt()) # create the layer layer = data_source.CreateLayer("grid", srs, ogr.wkbPolygon) layer.CreateField(ogr.FieldDefn("i", ogr.OFTInteger)) layer.CreateField(ogr.FieldDefn("j", ogr.OFTInteger)) lonr = [(i - (self.iref - 1)) * self.dx + self.xref for i in range(self.ni)] latr = [(j - (self.jref - 1)) * self.dy + self.yref for j in range(self.nj)] margin = 0 if free_zone_only: margin = self.blendig + self.halo start_i = margin start_j = margin end_i = self.ni - margin - 1 end_j = self.nj - margin - 1 for i in range(start_i, end_i + 1): x = lonr[i] for j in range(start_j, end_j + 1): y = latr[j] # create the feature feature = ogr.Feature(layer.GetLayerDefn()) p00 = (x - self.dx / 2.0, y - self.dy / 2.0) p01 = (x - self.dx / 2.0, y + self.dy / 2.0) p11 = (x + self.dx / 2.0, y + self.dy / 2.0) p10 = (x + self.dx / 2.0, y - self.dy / 2.0) ring = ogr.Geometry(ogr.wkbLinearRing) ring.AddPoint(*p00) ring.AddPoint(*p01) ring.AddPoint(*p11) ring.AddPoint(*p10) poly = ogr.Geometry(ogr.wkbPolygon) poly.AddGeometry(ring) feature.SetField("i", i + 1) feature.SetField("j", j + 1) feature.SetGeometry(poly) layer.CreateFeature(feature) feature.Destroy() # w.poly(parts=[[[-20, -20], [-20, 20], [20, 20], [20, -20]],]) # w.record(1, 1) data_source.Destroy() def get_basemap_for_free_zone(self, halo=None, blending=None, **kwargs): if halo is None: halo = self.halo if blending is None: blending = self.blendig lons_c, lats_c = self.get_free_zone_corners(halo=halo, blending=blending) return self.get_basemap(lons=lons_c, lats=lats_c, **kwargs) def get_basemap_using_shape_with_polygons_of_interest(self, lons, lats, shp_path=None, mask_margin=5, **kwargs): if shp_path is None: return self.get_basemap(lons=lons, lats=lats, **kwargs) reg_of_interest = get_mask(lons, lats, shp_path=shp_path) > 0 i_list, j_list = np.where(reg_of_interest) i_min = min(i_list) - mask_margin i_max = max(i_list) + mask_margin j_min = min(j_list) - mask_margin j_max = max(j_list) + mask_margin bsmap = self.get_basemap(lons=lons[i_min:i_max + 1, j_min:j_max + 1], lats=lats[i_min:i_max + 1, j_min:j_max + 1]) return bsmap, reg_of_interest def get_basemap(self, lons=None, lats=None, **kwargs): if lons is None: lonr = [(i - (self.iref - 1)) * self.dx + self.xref for i in [0, self.ni - 1]] latr = [(j - (self.jref - 1)) * self.dy + self.yref for j in [0, self.nj - 1]] latr, lonr = np.meshgrid(latr, lonr) lons = np.zeros((2, 2)) lats = np.zeros((2, 2)) for i in [-1, 0]: for j in [-1, 0]: shiftx = self.dx / 2.0 shifty = self.dy / 2.0 shiftx = -shiftx if i == 0 else shiftx shifty = -shifty if i == 0 else shifty lons[i, j], lats[i, j] = self.rll.toGeographicLonLat(lonr[i, j] + shiftx, latr[i, j] + shifty) return self.get_rot_latlon_proj_obj().get_basemap_object_for_lons_lats(lons2d=lons, lats2d=lats, **kwargs) def get_corners_in_proj_coords(self): """ :return: xxcorners, yycorners xxcorners = [[xll, xur], [xll, xur]] yycorners = [[yll, yll], [yur, yur]] """ lonr = [(i - (self.iref - 1)) * self.dx + self.xref for i in [0, self.ni - 1]] latr = [(j - (self.jref - 1)) * self.dy + self.yref for j in [0, self.nj - 1]] latr, lonr = np.meshgrid(latr, lonr) return lonr, latr def get_free_zone_corners(self, halo=10, blending=10): margin = halo + blending lonr = [(i - (self.iref - 1)) * self.dx + self.xref for i in [margin, self.ni - margin - 1]] latr = [(j - (self.jref - 1)) * self.dy + self.yref for j in [margin, self.nj - margin - 1]] latr, lonr = np.meshgrid(latr, lonr) lons = np.zeros((2, 2)) lats = np.zeros((2, 2)) for i in [-1, 0]: mulx = -1 if i >= 0 else 1 shiftx = mulx * self.dx / 2.0 for j in [-1, 0]: muly = -1 if j >= 0 else 1 shifty = muly * self.dy / 2.0 lons[i, j], lats[i, j] = self.rll.toGeographicLonLat(lonr[i, j] + shiftx, latr[i, j] + shifty) return lons, lats def get_rot_latlon_proj_obj(self): return self.rll def subgrid(self, i0, j0, di=-1, dj=-1): """ :param i0: 0-based i-index of the lower left corner of the domain :param j0: :param di: number of grid points in i direction :param dj: number of grid points in j direction """ subgr = GridConfig(rll=self.rll, dx=self.dx, dy=self.dy, xref=self.xref, yref=self.yref) if di > 0: subgr.ni = di else: subgr.ni = self.ni - i0 if dj > 0: subgr.nj = dj else: subgr.nj = self.nj - j0 subgr.iref = self.iref - i0 subgr.jref = self.jref - j0 return subgr def copy(self): return self.subgrid(0, 0, di=self.ni, dj=self.nj) def double_resolution(self): gc = GridConfig(rll=self.rll, dx=self.dx / 2.0, dy=self.dy / 2.0, xref=self.xref, yref=self.yref) gc.ni = 2 * self.ni gc.nj = 2 * self.nj gc.iref = 2 * self.iref gc.jref = 2 * self.jref gc.xref -= gc.dx / 2.0 gc.yref -= gc.dy / 2.0 return gc def double_resolution_keep_free_domain_same(self, halo_pts=10, blending_pts=10): gc = GridConfig(rll=self.rll, dx=self.dx / 2.0, dy=self.dy / 2.0, xref=self.xref, yref=self.yref) margin_pts = halo_pts + blending_pts gc.ni = 2 * (self.ni - 2 * margin_pts) + 2 * margin_pts gc.nj = 2 * (self.nj - 2 * margin_pts) + 2 * margin_pts gc.iref = 2 * (self.iref - margin_pts) + margin_pts gc.jref = 2 * (self.jref - margin_pts) + margin_pts gc.xref -= gc.dx / 2.0 gc.yref -= gc.dy / 2.0 return gc def decrease_resolution_keep_free_domain_same(self, factor, halo_pts=10, blending_pts=10): gc = GridConfig(rll=self.rll, dx=self.dx * factor, dy=self.dy * factor, xref=self.xref, yref=self.yref) margin_pts = halo_pts + blending_pts gc.ni = (self.ni - 2 * margin_pts) / factor + 2 * margin_pts gc.nj = (self.nj - 2 * margin_pts) / factor + 2 * margin_pts # Change the reference point if the new iref and jref cannot be the same new_iref = self.iref - margin_pts new_jref = self.jref - margin_pts new_iref = new_iref // factor + (new_iref % factor != 0) x00 = self.xref + self.dx * (margin_pts + 1 - self.iref) - self.dx / 2.0 new_xref = x00 + new_iref * self.dx * factor - self.dx * factor / 2.0 new_jref = new_jref // factor + (new_jref % factor != 0) y00 = self.yref + self.dy * (margin_pts + 1 - self.jref) - self.dy / 2.0 new_yref = y00 + new_jref * self.dy * factor - self.dy * factor / 2.0 gc.iref = new_iref + margin_pts gc.jref = new_jref + margin_pts gc.xref = new_xref gc.yref = new_yref gc.ni = int(gc.ni) gc.nj = int(gc.nj) return gc def move(self, di=0, dj=0): gc = GridConfig(rll=self.rll, dx=self.dx, dy=self.dy, xref=self.xref, yref=self.yref, ni=self.ni, nj=self.nj) gc.iref -= di gc.jref -= dj return gc def expand(self, di=0, dj=0): gc = GridConfig(rll=self.rll, dx=self.dx, dy=self.dy, xref=self.xref, yref=self.yref, ni=self.ni + di, nj=self.nj + dj) gc.iref = self.iref gc.jref = self.jref return gc def __str__(self): s = """ Grd_ni = {ni} , Grd_nj = {nj} , Grd_dx = {dx} , Grd_dy = {dy}, Grd_iref = {iref} , Grd_jref = {jref} , Grd_latr = {latref} , Grd_lonr = {lonref} , Grd_xlat1 = {lat1} , Grd_xlon1 = {lon1} , Grd_xlat2 = {lat2} , Grd_xlon2 = {lon2} , """.format(ni=self.ni, nj=self.nj, dx=self.dx, dy=self.dy, iref=self.iref, jref=self.jref, latref=self.yref, lonref=self.xref, lat1=self.rll.lat1, lon1=self.rll.lon1, lat2=self.rll.lat2, lon2=self.rll.lon2) return s
def plot_lake_fraction_field(): folder = "/home/huziy/skynet3_rech1/geof_lake_infl_exp" fName = "geophys_Quebec_0.1deg_260x260_with_dd_v6" path = os.path.join(folder, fName) rObj = RPN(path) lkf = rObj.get_first_record_for_name_and_level( varname="VF", level=3, level_kind=level_kinds.ARBITRARY) proj_params = rObj.get_proj_parameters_for_the_last_read_rec() lons2d, lats2d = rObj.get_longitudes_and_latitudes_for_the_last_read_rec() lons2d[lons2d >= 180] -= 360 rObj.close() rll = RotatedLatLon(**proj_params) margin = 20 lons2d = lons2d[margin:-margin, margin:-margin] lats2d = lats2d[margin:-margin, margin:-margin] lkf = lkf[margin:-margin, margin:-margin] basemap = rll.get_basemap_object_for_lons_lats(lons2d=lons2d, lats2d=lats2d, resolution="l") x, y = basemap(lons2d, lats2d) fig = plt.figure() gs = GridSpec(1, 2, width_ratios=[1, 1]) ax = fig.add_subplot(gs[0, 0]) df = 0.1 levels = np.arange(0, 1.1, df) cMap = get_cmap("gist_ncar_r", len(levels) - 1) bn = BoundaryNorm(levels, cMap.N) basemap.drawmapboundary(fill_color="0.75") lkf_plot = maskoceans(lons2d, lats2d, lkf, inlands=False) print("Percentage of lakes in the sim domain: {}".format(lkf_plot.mean() * 100)) img = basemap.pcolormesh(x, y, lkf_plot, norm=bn, cmap=cMap) basemap.drawcoastlines() divider = make_axes_locatable(ax) cax = divider.append_axes("bottom", "5%", pad="3%") cb = fig.colorbar(img, cax=cax, ticks=levels, orientation="horizontal") ax = fig.add_subplot(gs[0, 1]) df1 = df levels1 = np.arange(0, 1.1, df1) cell_numms = np.zeros((len(levels1) - 1, )) left = levels[0] right = levels[1] lefts = [] rights = [] lkf_land = lkf[lkf > 0.01] for i in range(len(cell_numms)): cell_numms[i] = ((lkf_land > left) & (lkf_land <= right)).astype(int).sum() lefts.append(left) rights.append(right) left += df1 right += df1 assert isinstance(ax, Axes) ax.bar(lefts, cell_numms, width=df1) # ax.semilogy(rights, cell_numms) ax.xaxis.set_ticks(levels) ax.yaxis.set_ticks(np.arange(1000, 10000, 1000)) sf = ScalarFormatter(useMathText=True) sf.set_powerlimits([-2, 1]) ax.yaxis.set_major_formatter(sf) ax.grid("on") ax.set_xlabel("fraction") ax.set_ylabel("# gridcells") plt.show() fig.tight_layout() fig.savefig("lake_fractions_220x220_0.1deg.jpeg") plt.show() pass
def diagnose(station_ids=None, model_data_path=None): manager = Crcm5ModelDataManager(samples_folder_path=model_data_path, file_name_prefix="pm", all_files_in_samples_folder=True, need_cell_manager=True) nx, ny = manager.lons2D.shape rot_lat_lon = RotatedLatLon(lon1=-68, lat1=52, lon2=16.65, lat2=0.0) x00, y00 = rot_lat_lon.toProjectionXY(manager.lons2D[0, 0], manager.lats2D[0, 0]) x10, y10 = rot_lat_lon.toProjectionXY(manager.lons2D[1, 0], manager.lats2D[1, 0]) x01, y01 = rot_lat_lon.toProjectionXY(manager.lons2D[0, 1], manager.lats2D[0, 1]) dx = x10 - x00 dy = y01 - y00 print("dx, dy = {0}, {1}".format(dx, dy)) areas = rot_lat_lon.get_areas_of_gridcells( dx, dy, nx, ny, y00, 1) #1 -since the index is starting from 1 print(areas[0, 0]) start_date = datetime(1986, 1, 1) end_date = datetime(1986, 12, 31) stations = cehq_station.read_station_data(selected_ids=station_ids, start_date=start_date, end_date=end_date) stations.sort(key=lambda x: x.latitude, reverse=True) for i, s in enumerate(stations): fig = plt.figure() #3 columns gs = GridSpec(5, 3, hspace=0.2, wspace=0.2, right=0.98, left=0.1, top=0.98) model_ts = manager.get_streamflow_timeseries_for_station( s, start_date=start_date, end_date=end_date, nneighbours=9) print(model_ts.time[0], model_ts.time[-1]) i_model0, j_model0 = model_ts.metadata["ix"], model_ts.metadata["jy"] mask = manager.get_mask_for_cells_upstream(i_model0, j_model0) #hydrographs ax = fig.add_subplot(gs[0, 0]) plot_streamflows(ax, s, model_ts) #relative error ax = fig.add_subplot(gs[1, 0]) plot_streamflow_re(ax, s, model_ts) #directions plot_directions_and_positions(fig.add_subplot(gs[:2, 1]), s, model_ts, manager, rot_lat_lon, mask=mask) #runoff ax = fig.add_subplot(gs[2, 0]) plot_runoff(ax, manager, areas, model_ts, mask=mask) #runoff from gldas ax = fig.add_subplot(gs[2, 1]) #plot_gldas_runoff(ax, manager, areas, model_ts, mask = mask) #temperature ax_temp = fig.add_subplot(gs[3, 0]) ax_prec = fig.add_subplot(gs[4, 0]) plot_total_precip_and_temp_re_1d(ax_prec, ax_temp, manager, rot_lat_lon, areas, model_ts, mask=mask) #swe timeseries ax = fig.add_subplot(gs[3, 1]) plot_swe_timeseries(ax, manager, areas, model_ts, mask=mask) #print np.where(mask == 1) print("(i, j) = ({0}, {1})".format(model_ts.metadata["ix"], model_ts.metadata["jy"])) fig.savefig("diagnose_{0}_{1:.2f}deg.pdf".format(s.id, dx))
def main(): # plot_utils.apply_plot_params(20) folder = "/home/huziy/skynet3_rech1/from_guillimin" fname = "geophys_Quebec_0.1deg_260x260_with_dd_v6" path = os.path.join(folder, fname) rObj = RPN(path) mg = rObj.get_first_record_for_name_and_level( "MG", level=0, level_kind=level_kinds.PRESSURE) # j2 = rObj.get_first_record_for_name("J2") levs = [0, 100, 200, 300, 500, 700, 1000, 1500, 2000, 2800] norm = BoundaryNorm(levs, len(levs) - 1) me = rObj.get_first_record_for_name_and_level( "ME", level=0, level_kind=level_kinds.ARBITRARY) proj_params = rObj.get_proj_parameters_for_the_last_read_rec() print(me.shape) lons2d, lats2d = rObj.get_longitudes_and_latitudes_for_the_last_read_rec() lons2d[lons2d > 180] -= 360 # me_to_plot = np.ma.masked_where(mg < 0.4, me) me_to_plot = me # print me_to_plot.min(), me_to_plot.max() rll = RotatedLatLon(**proj_params) basemap = rll.get_basemap_object_for_lons_lats(lons2d=lons2d, lats2d=lats2d) rObj.close() x, y = basemap(lons2d, lats2d) plt.figure() ax = plt.gca() # the_cmap = cm.get_cmap(name = "gist_earth", lut=len(levs) -1) # the_cmap = my_colormaps.get_cmap_from_ncl_spec_file(path="colormap_files/topo_15lev.rgb") the_cmap = my_colormaps.get_cmap_from_ncl_spec_file( path="colormap_files/OceanLakeLandSnow.rgb", ncolors=len(levs) - 1) # new_cm = matplotlib.colors.LinearSegmentedColormap('colormap',new_dict,len(levs) - 1) me_to_plot = maskoceans(lons2d, lats2d, me_to_plot, resolution="l") basemap.contourf(x, y, me_to_plot, cmap=the_cmap, levels=levs, norm=norm) # basemap.fillcontinents(color = "none", lake_color="aqua") basemap.drawmapboundary(fill_color='#479BF9') basemap.drawcoastlines(linewidth=0.5) basemap.drawmeridians(np.arange(-180, 180, 20), labels=[1, 0, 0, 1]) basemap.drawparallels(np.arange(45, 75, 15), labels=[1, 0, 0, 1]) basemap.readshapefile("data/shape/contour_bv_MRCC/Bassins_MRCC_latlon", name="basin", linewidth=1) divider = make_axes_locatable(ax) cax = divider.append_axes("right", "5%", pad="3%") plt.colorbar(ticks=levs, cax=cax) # basemap.scatter(x, y, color="k", s=1, linewidths=0, ax=ax, zorder=2) margin = 20 x1 = x[margin, margin] x2 = x[-margin, margin] y1 = y[margin, margin] y2 = y[margin, -margin] pol_corners = ((x1, y1), (x2, y1), (x2, y2), (x1, y2)) ax.add_patch(Polygon(xy=pol_corners, fc="none", ls="dashed", lw=3)) # plt.tight_layout() # plt.show() plt.savefig("free_domain_260x260.png", dpi=cpp.FIG_SAVE_DPI) pass
from mpl_toolkits.basemap import Basemap from domains.grid_config import GridConfig, gridconfig_from_grid_nml from domains.rotated_lat_lon import RotatedLatLon default_projection = RotatedLatLon(lon1=-97.0, lat1=47.5, lon2=-7.0, lat2=0.) # iref and jref are 1-based indices coming from gemclim_settings.nml gc_cordex_na_011 = GridConfig(rll=default_projection, dx=0.11, dy=0.11, ni=695, nj=680, iref=21, jref=580, xref=145.955, yref=28.525) gc_cordex_na_022 = GridConfig(rll=default_projection, dx=0.22, dy=0.22, ni=380, nj=360, iref=21, jref=300, xref=146.01, yref=28.47) gc_cordex_na_044 = GridConfig(rll=default_projection, dx=0.44, dy=0.44, ni=212, nj=200, iref=21, jref=160, xref=146.12, yref=28.36) gc_cordex_caio_subdomain = GridConfig(rll=default_projection, dx=0.22, dy=0.22, ni=276, nj=212, iref=35, jref=153, xref=151.51, yref=28.25) cordex_arctic_proj = RotatedLatLon(lon1=180, lat1=83.45, lon2=270, lat2=0.) gc_cordex_Arctic_044 = GridConfig( rll=cordex_arctic_proj, dx=0.44, dy=0.44, ni=164, nj=180, iref=21, jref=153, xref=157.12, yref=33.88 ) cordex_na_proj = RotatedLatLon(lon1=-97, lat1=47.5, lon2=-7.0, lat2=0.0) gc_panarctic_05 = gridconfig_from_grid_nml( """
def plot_domain_for_different_margins(path, margins=None): if not margins: margins = [20, 40, 60] rpnObj = RPN(path) lons2d, lats2d = rpnObj.get_longitudes_and_latitudes() # projection parameters lon_1 = -68 lat_1 = 52 lon_2 = 16.65 lat_2 = 0.0 rot_lat_lon = RotatedLatLon(lon1=lon_1, lat1=lat_1, lon2=lon_2, lat2=lat_2) xll, yll = rot_lat_lon.toProjectionXY(lons2d[0, 0], lats2d[0, 0]) xur, yur = rot_lat_lon.toProjectionXY(lons2d[-1, -1], lats2d[-1, -1]) if xll < 0: xll += 360.0 if xur < 0: xur += 360.0 nx, ny = lons2d.shape dx = (xur - xll) / float(nx - 1) dy = (yur - yll) / float(ny - 1) print(dx, dy) print(xur, yur, xll, yll) x1 = xll - dx / 2.0 y1 = yll - dy / 2.0 x2 = xur + dx / 2.0 y2 = yur + dy / 2.0 x1lon, y1lat = rot_lat_lon.toGeographicLonLat(x1, y1) x2lon, y2lat = rot_lat_lon.toGeographicLonLat(x2, y2) llcrnrlon, llcrnrlat = rot_lat_lon.toGeographicLonLat(x1 - dx, y1 - dx) urcrnrlon, urcrnrlat = rot_lat_lon.toGeographicLonLat(x2 + dx, y2 + dx) basemap = Basemap(projection="omerc", lon_1=lon_1, lat_1=lat_1, lon_2=lon_2, lat_2=lat_2, llcrnrlon=llcrnrlon, llcrnrlat=llcrnrlat, urcrnrlon=urcrnrlon, urcrnrlat=urcrnrlat, no_rot=True, resolution="l") basemap.drawcoastlines() basemap.drawrivers() x1, y1 = basemap(x1lon, y1lat) x2, y2 = basemap(x2lon, y2lat) # add rectangle for the grid 220x220 # r1 = Rectangle((x1, y1), x2-x1, y2-y1, facecolor="none", edgecolor="r", linewidth=5 ) ax = plt.gca() assert isinstance(ax, Axes) # xr1_label, yr1_label = rot_lat_lon.toGeographicLonLat(xur - 2 * dx, yll + 2 * dy) # xr1_label, yr1_label = basemap( xr1_label, yr1_label ) # ax.annotate("{0}x{1}".format(nx, ny), xy = (xr1_label, yr1_label), va = "bottom", ha = "right", color = "r") # assert isinstance(ax, Axes) # ax.add_patch(r1) margins_all = [0] + margins for margin in margins_all: # mfree = margin - 20 xlli = xll + margin * dx ylli = yll + margin * dy xuri = xur - margin * dx yuri = yur - margin * dy x1lon, y1lat = rot_lat_lon.toGeographicLonLat(xlli, ylli) x2lon, y2lat = rot_lat_lon.toGeographicLonLat(xuri, yuri) x1, y1 = basemap(x1lon, y1lat) x2, y2 = basemap(x2lon, y2lat) ri = Rectangle((x1, y1), x2 - x1, y2 - y1, facecolor="none", edgecolor="r", linewidth=5) ax.add_patch(ri) xri_label, yri_label = rot_lat_lon.toGeographicLonLat(xlli + 2 * dx, yuri - 2 * dy) xri_label, yri_label = basemap(xri_label, yri_label) ax.annotate("{0}x{1}\nmarg. = {2}".format(nx - margin * 2, ny - margin * 2, margin + 20), xy=(xri_label, yri_label), va="top", ha="left", color="k", backgroundcolor="w") plt.show()
def main(): #path = "/RECH/data/Simulations/CRCM5/North_America/NorthAmerica_0.44deg_ERA40-Int_B1/Diagnostics/NorthAmerica_0.44deg_ERA40-Int_B1_2007{:02d}" path = "/RESCUE/skynet3_rech1/huziy/from_guillimin/new_outputs/current_climate_30_yr_sims/quebec_0.1_crcm5-hcd-rl-intfl_ITFS/Samples/quebec_crcm5-hcd-rl-intfl_1988{:02d}" months = [6, 7, 8] pm_list = [] dm_list = [] for m in months: print(path.format(m)) month_folder = path.format(m) for fn in os.listdir(month_folder): # if not fn.endswith("moyenne"): # continue if fn.startswith("pm"): pm_list.append(os.path.join(month_folder, fn)) elif fn.startswith("dm"): dm_list.append(os.path.join(month_folder, fn)) pm = MultiRPN(pm_list) dm = MultiRPN(dm_list) tsurf_mean = np.mean([field for field in pm.get_all_time_records_for_name_and_level(varname="J8").values()], axis=0) tair_mean = np.mean([field for field in dm.get_all_time_records_for_name_and_level(varname="TT", level=1, level_kind=level_kinds.HYBRID).values()], axis=0) lons, lats = pm.get_longitudes_and_latitudes_of_the_last_read_rec() projparams = pm.linked_robj_list[0].get_proj_parameters_for_the_last_read_rec() rll = RotatedLatLon(**projparams) bmp = rll.get_basemap_object_for_lons_lats(lons2d=lons, lats2d=lats) xx, yy = bmp(lons, lats) plt.figure() cs = bmp.contourf(xx, yy, tsurf_mean - 273.15, 40) bmp.drawcoastlines() plt.title("Tsurf") plt.colorbar() plt.figure() bmp.contourf(xx, yy, tair_mean, levels=cs.levels, norm=cs.norm, cmap=cs.cmap) bmp.drawcoastlines() plt.title("Tair") plt.colorbar() plt.figure() bmp.contourf(xx, yy, tsurf_mean - 273.15 - tair_mean, levels=np.arange(-2, 2.2, 0.2), cmap=cs.cmap) bmp.drawcoastlines() plt.title("Tsurf - Tair") plt.colorbar() pm.close() dm.close() plt.show()
def plot_domain_using_coords_from_file(path=""): fig = plt.figure() assert isinstance(fig, Figure) rpnObj = RPN(path) lons2d, lats2d = rpnObj.get_longitudes_and_latitudes() basemap = Basemap(projection="omerc", lon_1=-68, lat_1=52, lon_2=16.65, lat_2=0.0, llcrnrlon=lons2d[0, 0], llcrnrlat=lats2d[0, 0], urcrnrlon=lons2d[-1, -1], urcrnrlat=lats2d[-1, -1], no_rot=True) # basemap.drawcoastlines() rot_lat_lon_proj = RotatedLatLon(lon1=-68, lat1=52, lon2=16.65, lat2=0.0) g_params = GridParams(lonr=180, latr=0, iref=45, jref=41, dx=0.5, dy=0.5, nx=86, ny=86) lons2d_1, lats2d_1 = get_lons_lats_using_grid_params( g_params, rot_lat_lon_proj) basemap = Basemap(projection="omerc", lon_1=-68, lat_1=52, lon_2=16.65, lat_2=0.0, llcrnrlon=lons2d_1[18, 18], llcrnrlat=lats2d_1[18, 18], urcrnrlon=lons2d_1[-1, -1], urcrnrlat=lats2d_1[-1, -1], no_rot=True, resolution="i") basemap.drawcoastlines(linewidth=0.4) basemap.drawrivers() # basemap.drawmeridians(np.arange(-180, 0, 20)) x, y = basemap(lons2d, lats2d) basemap.scatter(x, y, c="r", linewidths=0, s=1.0) print(x.shape) xll_big, yll_big = g_params.get_ll_point(marginx=20, marginy=20) xll_big -= g_params.dx / 2.0 yll_big -= g_params.dy / 2.0 xll_big, yll_big = rot_lat_lon_proj.toGeographicLonLat(xll_big, yll_big) xll_big, yll_big = basemap(xll_big, yll_big) xur_big, yur_big = g_params.get_ur_point(marginx=20, marginy=20) xur_big += g_params.dx / 2.0 yur_big += g_params.dy / 2.0 xur_big, yur_big = rot_lat_lon_proj.toGeographicLonLat(xur_big, yur_big) xur_big, yur_big = basemap(xur_big, yur_big) margin = 20 # plot 0.25 degree grid g_params = GridParams(lonr=180, latr=0, iref=71, jref=63, dx=0.25, dy=0.25, nx=133, ny=133) lons2d_2, lats2d_2 = get_lons_lats_using_grid_params( g_params, rot_lat_lon_proj) x2, y2 = basemap(lons2d_2[margin:-margin, margin:-margin], lats2d_2[margin:-margin, margin:-margin]) basemap.scatter(x2, y2, c="g", linewidth=0, marker="s", s=7.5) # plot 0.5 degree grid using the output file # debug rObj1 = RPN( "/home/huziy/skynet3_exec1/from_guillimin/quebec_86x86_0.5deg_without_lakes/pm1985010100_00000000p" ) lons2d_1, lats2d_1 = rObj1.get_longitudes_and_latitudes() # x1, y1 = basemap(lons2d_1[margin:-margin,margin:-margin], lats2d_1[margin:-margin,margin:-margin]) x1, y1 = basemap(lons2d_1, lats2d_1) print(x1.shape, lons2d_1[0, 0], lats2d_1[0, 0]) basemap.scatter(x1, y1, c="b", linewidths=0, s=10) dx1 = (x1[1, 0] - x1[0, 0]) / 2.0 dy1 = (y1[0, 1] - y1[0, 0]) / 2.0 rbig = Rectangle((xll_big, yll_big), xur_big - xll_big, yur_big - yll_big, linewidth=2, edgecolor="b", facecolor="none") ax = plt.gca() assert isinstance(ax, Axes) # ax.add_patch(rsmall) ax.add_patch(rbig) # draw north arrow plot_north_cross(-45, 45, basemap, ax=ax) # zoom to a region axins = zoomed_inset_axes(ax, 4, loc=1) # zoom = 6 basemap.drawcoastlines(ax=axins) basemap.drawrivers(ax=axins) basemap.scatter(x, y, c="r", linewidths=0, s=5, ax=axins) basemap.scatter(x2, y2, c="g", marker="s", linewidth=0, s=15, ax=axins) basemap.scatter(x1, y1, c="b", linewidths=0, s=25, ax=axins) # subregion to zoom in nx, ny = lons2d.shape part = 3 xins_ll = lons2d[nx / part, ny / part] yins_ll = lats2d[nx / part, ny / part] xins_ur = lons2d[nx / part + 40, ny / part + 40] yins_ur = lats2d[nx / part + 40, ny / part + 40] xins_ll, yins_ll = basemap(xins_ll, yins_ll) xins_ur, yins_ur = basemap(xins_ur, yins_ur) axins.set_xlim(xins_ll, xins_ur) axins.set_ylim(yins_ll, yins_ur) # draw a bbox of the region of the inset axes in the parent axes and # connecting lines between the bbox and the inset axes area mark_inset(ax, axins, loc1=2, loc2=4, fc="none", linewidth=2) fig.tight_layout(pad=0.8) fig.savefig("high_low_res_domains.png") pass
def main(): # stations = cehq_station.read_grdc_stations(st_id_list=["2903430", "2909150", "2912600", "4208025"]) selected_ids = [ "08MH001", "08NE074", "08NG065", "08NJ013", "08NK002", "08NK016", "08NL004", "08NL007", "08NL024", "08NL038", "08NN002" ] stations = cehq_station.load_from_hydat_db(natural=True, province="BC", selected_ids=selected_ids) stations_to_mp = None import matplotlib.pyplot as plt # labels = ["CanESM", "MPI"] # paths = ["/skynet3_rech1/huziy/offline_stfl/canesm/discharge_1958_01_01_00_00.nc", # "/skynet3_rech1/huziy/offline_stfl/mpi/discharge_1958_01_01_00_00.nc"] # # colors = ["r", "b"] # labels = ["ERA", ] # colors = ["r", ] # paths = ["/skynet3_rech1/huziy/arctic_routing/era40/discharge_1958_01_01_00_00.nc"] labels = ["Glacier-only", "All"] colors = ["r", "b"] paths = [ "/skynet3_exec2/aganji/glacier_katja/watroute_gemera/discharge_stat_glac_00_99_2000_01_01_00_00.nc", "/skynet3_exec2/aganji/glacier_katja/watroute_gemera/discharge_stat_both_00_992000_01_01_00_00.nc" ] start_year_current = 2000 end_year_current = 2013 plot_future = False start_year_future = 2071 # ignored when plot future is false end_year_future = 2100 if not plot_future: start_year = start_year_current end_year = end_year_current else: start_year = start_year_future end_year = end_year_future stations_filtered = [] for s in stations: # Also filter out stations with small accumulation areas if s.drainage_km2 < 1000: continue if s.latitude > 49.4: continue # Filter stations with data out of the required time frame year_list = s.get_list_of_complete_years() if max(year_list) < start_year or min(year_list) > end_year: continue stations_filtered.append(s) stations = stations_filtered min_lon = min(s.longitude for s in stations) stations = [s for s in stations if s.longitude == min_lon] print("Retained {} stations.".format(len(stations))) sim_to_time = {} monthly_dates = [datetime(2001, m, 15) for m in range(1, 13)] fmt = FuncFormatter(lambda x, pos: num2date(x).strftime("%b")[0]) locator = MonthLocator() fig = plt.figure() axes = [] row_indices = [] col_indices = [] ncols = 1 shiftrow = 0 if len(stations) % ncols == 0 else 1 nrows = len(stations) // ncols + shiftrow shared_ax = None gs = gridspec.GridSpec(ncols=ncols, nrows=nrows) for i, s in enumerate(stations): row = i // ncols col = i % ncols row_indices.append(row) col_indices.append(col) if shared_ax is None: ax = fig.add_subplot(gs[row, col]) shared_ax = ax assert isinstance(shared_ax, Axes) else: ax = fig.add_subplot(gs[row, col]) ax.xaxis.set_major_locator(locator) ax.yaxis.set_major_locator(MaxNLocator(nbins=4)) ax.xaxis.set_major_formatter(fmt) sfmt = ScalarFormatter(useMathText=True) sfmt.set_powerlimits((-3, 4)) ax.yaxis.set_major_formatter(sfmt) assert isinstance(ax, Axes) axes.append(ax) # generate daily stamp dates d0 = datetime(2001, 1, 1) stamp_dates = [d0 + timedelta(days=i) for i in range(365)] # plot a panel for each station for s, ax, row, col in zip(stations, axes, row_indices, col_indices): assert isinstance(s, Station) assert isinstance(ax, Axes) if s.grdc_monthly_clim_max is not None: ax.fill_between(monthly_dates, s.grdc_monthly_clim_min, s.grdc_monthly_clim_max, color="0.6", alpha=0.5) avail_years = s.get_list_of_complete_years() print("{}: {}".format(s.id, ",".join([str(y) for y in avail_years]))) years = [y for y in avail_years if start_year <= y <= end_year] _, obs_clim_stfl = s.get_daily_climatology_for_complete_years_with_pandas( stamp_dates=stamp_dates, years=years) if obs_clim_stfl is None: continue ax.plot(stamp_dates, obs_clim_stfl, "k", lw=3, label="Obs") if s.river_name is not None and s.river_name != "": ax.set_title(s.river_name) else: ax.set_title(s.id) for path, sim_label, color in zip(paths, labels, colors): ds = Dataset(path) if stations_to_mp is None: acc_area_2d = ds.variables["accumulation_area"][:] lons2d, lats2d = ds.variables["longitude"][:], ds.variables[ "latitude"][:] x_index, y_index = ds.variables["x_index"][:], ds.variables[ "y_index"][:] stations_to_mp = get_dataless_model_points_for_stations( stations, acc_area_2d, lons2d, lats2d, x_index, y_index) # read dates only once for a given simulation if sim_label not in sim_to_time: time_str = ds.variables["time"][:].astype(str) times = [ datetime.strptime("".join(t_s), TIME_FORMAT) for t_s in time_str ] sim_to_time[sim_label] = times mp = stations_to_mp[s] data = ds.variables["water_discharge_accumulated"][:, mp.cell_index] print(path) df = DataFrame(data=data, index=sim_to_time[sim_label], columns=["value"]) df["year"] = df.index.map(lambda d: d.year) df = df.ix[df.year.isin(years), :] df = df.select(lambda d: not (d.month == 2 and d.day == 29)) df = df.groupby(lambda d: datetime(stamp_dates[0].year, d.month, d. day)).mean() daily_model_data = [df.ix[d, "value"] for d in stamp_dates] # print np.mean( monthly_model ), s.river_name, sim_label ax.plot(stamp_dates, daily_model_data, color, lw=3, label=sim_label + "(C)") if plot_future: ax.plot(stamp_dates, daily_model_data, color + "--", lw=3, label=sim_label + "(F2)") ds.close() if row < nrows - 1: ax.set_xticklabels([]) axes[0].legend(fontsize=17, loc=2) plt.tight_layout() plt.savefig("offline_validation.png", dpi=400) plt.close(fig) r = RPN( "/RESCUE/skynet3_rech1/huziy/CNRCWP/C3/Depth_to_bedrock_WestNA_0.25") r.get_first_record_for_name("8L") proj_params = r.get_proj_parameters_for_the_last_read_rec() lons, lats = r.get_longitudes_and_latitudes_for_the_last_read_rec() bsmp = RotatedLatLon(**proj_params).get_basemap_object_for_lons_lats( lons2d=lons, lats2d=lats) plot_utils.apply_plot_params(width_pt=None, width_cm=19, height_cm=19, font_size=12) plot_station_positions(manager=None, station_list=stations, bsmp=bsmp)
def plot_domain_for_different_margins(path, margins=None): if not margins: margins = [20, 40, 60] rpnObj = RPN(path) lons2d, lats2d = rpnObj.get_longitudes_and_latitudes() # projection parameters lon_1 = -68 lat_1 = 52 lon_2 = 16.65 lat_2 = 0.0 rot_lat_lon = RotatedLatLon(lon1=lon_1, lat1=lat_1, lon2=lon_2, lat2=lat_2) xll, yll = rot_lat_lon.toProjectionXY(lons2d[0, 0], lats2d[0, 0]) xur, yur = rot_lat_lon.toProjectionXY(lons2d[-1, -1], lats2d[-1, -1]) if xll < 0: xll += 360.0 if xur < 0: xur += 360.0 nx, ny = lons2d.shape dx = (xur - xll) / float(nx - 1) dy = (yur - yll) / float(ny - 1) print(dx, dy) print(xur, yur, xll, yll) x1 = xll - dx / 2.0 y1 = yll - dy / 2.0 x2 = xur + dx / 2.0 y2 = yur + dy / 2.0 x1lon, y1lat = rot_lat_lon.toGeographicLonLat(x1, y1) x2lon, y2lat = rot_lat_lon.toGeographicLonLat(x2, y2) llcrnrlon, llcrnrlat = rot_lat_lon.toGeographicLonLat(x1 - dx, y1 - dx) urcrnrlon, urcrnrlat = rot_lat_lon.toGeographicLonLat(x2 + dx, y2 + dx) basemap = Basemap(projection="omerc", lon_1=lon_1, lat_1=lat_1, lon_2=lon_2, lat_2=lat_2, llcrnrlon=llcrnrlon, llcrnrlat=llcrnrlat, urcrnrlon=urcrnrlon, urcrnrlat=urcrnrlat, no_rot=True, resolution="l") basemap.drawcoastlines() basemap.drawrivers() x1, y1 = basemap(x1lon, y1lat) x2, y2 = basemap(x2lon, y2lat) # add rectangle for the grid 220x220 # r1 = Rectangle((x1, y1), x2-x1, y2-y1, facecolor="none", edgecolor="r", linewidth=5 ) ax = plt.gca() assert isinstance(ax, Axes) # xr1_label, yr1_label = rot_lat_lon.toGeographicLonLat(xur - 2 * dx, yll + 2 * dy) # xr1_label, yr1_label = basemap( xr1_label, yr1_label ) # ax.annotate("{0}x{1}".format(nx, ny), xy = (xr1_label, yr1_label), va = "bottom", ha = "right", color = "r") # assert isinstance(ax, Axes) # ax.add_patch(r1) margins_all = [0] + margins for margin in margins_all: # mfree = margin - 20 xlli = xll + margin * dx ylli = yll + margin * dy xuri = xur - margin * dx yuri = yur - margin * dy x1lon, y1lat = rot_lat_lon.toGeographicLonLat(xlli, ylli) x2lon, y2lat = rot_lat_lon.toGeographicLonLat(xuri, yuri) x1, y1 = basemap(x1lon, y1lat) x2, y2 = basemap(x2lon, y2lat) ri = Rectangle((x1, y1), x2 - x1, y2 - y1, facecolor="none", edgecolor="r", linewidth=5) ax.add_patch(ri) xri_label, yri_label = rot_lat_lon.toGeographicLonLat( xlli + 2 * dx, yuri - 2 * dy) xri_label, yri_label = basemap(xri_label, yri_label) ax.annotate("{0}x{1}\nmarg. = {2}".format(nx - margin * 2, ny - margin * 2, margin + 20), xy=(xri_label, yri_label), va="top", ha="left", color="k", backgroundcolor="w") plt.show()