def get_seasonal_clim_obs_data(rconfig=None, vname="TT", bmp_info=None, season_to_months=None, obs_path=None): """ :param rconfig: :param vname: Corresponding model variable name i.e either TT or PR """ assert isinstance(rconfig, RunConfig) if season_to_months is None: season_to_months = DEFAULT_SEASON_TO_MONTHS if bmp_info is None: bmp_info = analysis.get_basemap_info_from_hdf( file_path=rconfig.data_path) obs_query_params = dict(start_year=rconfig.start_year, end_year=rconfig.end_year, lons_target=bmp_info.lons, lats_target=bmp_info.lats) # Calculate daily mean temperatures as T = (T(min) + T(max)) * 0.5 if vname == "TT": tmax_obs_manager = AnuSplinManager(variable="stmx", folder_path=obs_path) tmin_obs_manager = AnuSplinManager(variable="stmn", folder_path=obs_path) dates, vals_max = tmax_obs_manager.get_daily_clim_fields_interpolated_to( **obs_query_params) _, vals_min = tmin_obs_manager.get_daily_clim_fields_interpolated_to( **obs_query_params) daily_obs = (dates, (vals_min + vals_max) * 0.5) elif vname == "PR": pcp_obs_manager = AnuSplinManager(variable="pcp", folder_path=obs_path) daily_obs = pcp_obs_manager.get_daily_clim_fields_interpolated_to( **obs_query_params) # SWE elif vname == "I5": swe_manager = SweDataManager(var_name="SWE", path=obs_path) daily_obs = swe_manager.get_daily_clim_fields_interpolated_to( **obs_query_params) else: raise Exception("Unknown variable: {}".format(vname)) season_to_obs_data = OrderedDict() for season, months in season_to_months.items(): season_to_obs_data[season] = np.mean( [f for d, f in zip(*daily_obs) if d.month in months], axis=0) return season_to_obs_data
def compare_swe_diff_for_era40_driven(): b, lons2d, lats2d = draw_regions.get_basemap_and_coords(llcrnrlat=40.0, llcrnrlon=-145, urcrnrlon=-10) lons2d[lons2d > 180] -= 360 x, y = b(lons2d, lats2d) #period start_year = 1981 end_year = 1997 the_months = [12,1,2] levels = [10] + list(range(20, 120, 20)) + [150,200, 300,500,1000] cmap = mpl.cm.get_cmap(name="jet_r", lut = len(levels)) norm = colors.BoundaryNorm(levels, cmap.N) swe_obs_manager = SweDataManager(var_name="SWE") swe_obs = swe_obs_manager.get_mean(start_year, end_year, months=the_months) print("Calculated obs swe") swe_obs_interp = swe_obs_manager.interpolate_data_to(swe_obs, lons2d, lats2d) axes_list = [] levels_diff = np.arange(-100, 110, 10) #plot model res. (ERA40 driven 1) paths = ["data/CORDEX/na/era40_1", "data/CORDEX/na/era40_2"] prefixes = ["pmNorthAmerica_0.44deg_ERA40-Int_{0}_1958-1961".format("DJF"), "pmNorthAmerica_0.44deg_ERA40-Int2_{0}_1958-1961".format("DJF") ] pf_kinds = draw_regions.get_permafrost_mask(lons2d, lats2d) for i, the_path in enumerate(paths): base = os.path.basename(the_path) fig = plt.figure() ax = plt.gca() axes_list.append(ax) swe_model_era = CRCMDataManager.get_mean_2d_from_climatologies(path=the_path, var_name="I5", file_prefixes=prefixes) swe_model_era = maskoceans(lons2d, lats2d, swe_model_era) #plot model(ERA40 driven) - obs axes_list.append(ax) img = b.contourf(x, y, swe_model_era - swe_obs_interp, levels = levels_diff) draw_colorbar(fig, img, ax = ax, boundaries=levels_diff) ax.set_title("Model ({0} 1958-1961) - Obs.".format(base)) b.drawcoastlines(ax = ax, linewidth = 0.2) b.contour(x, y, pf_kinds, ax = ax, colors = "k") fig.savefig("swe_{0}.png".format(base))
def get_seasonal_clim_obs_data(rconfig=None, vname="TT", bmp_info=None, season_to_months=None, obs_path=None): """ :param rconfig: :param vname: Corresponding model variable name i.e either TT or PR """ assert isinstance(rconfig, RunConfig) if season_to_months is None: season_to_months = DEFAULT_SEASON_TO_MONTHS if bmp_info is None: bmp_info = analysis.get_basemap_info_from_hdf(file_path=rconfig.data_path) obs_query_params = dict( start_year=rconfig.start_year, end_year=rconfig.end_year, lons_target=bmp_info.lons, lats_target=bmp_info.lats ) # Calculate daily mean temperatures as T = (T(min) + T(max)) * 0.5 if vname == "TT": tmax_obs_manager = AnuSplinManager(variable="stmx", folder_path=obs_path) tmin_obs_manager = AnuSplinManager(variable="stmn", folder_path=obs_path) dates, vals_max = tmax_obs_manager.get_daily_clim_fields_interpolated_to(**obs_query_params) _, vals_min = tmin_obs_manager.get_daily_clim_fields_interpolated_to(**obs_query_params) daily_obs = (dates, (vals_min + vals_max) * 0.5) elif vname == "PR": pcp_obs_manager = AnuSplinManager(variable="pcp", folder_path=obs_path) daily_obs = pcp_obs_manager.get_daily_clim_fields_interpolated_to(**obs_query_params) # SWE elif vname == "I5": swe_manager = SweDataManager(var_name="SWE", path=obs_path) daily_obs = swe_manager.get_daily_clim_fields_interpolated_to(**obs_query_params) else: raise Exception("Unknown variable: {}".format(vname)) season_to_obs_data = OrderedDict() for season, months in season_to_months.items(): season_to_obs_data[season] = np.mean([f for d, f in zip(*daily_obs) if d.month in months], axis=0) return season_to_obs_data
def main(): # Monthly means from diagnostics model_data_path = Path("/RECH2/huziy/BC-MH/bc_mh_044deg/Diagnostics") swe_obs_manager = SweDataManager(var_name="SWE") swe_obs_manager.get_daily_clim_fields_interpolated_to() pass
def plot_swe_timeseries(ax, crcm5_manager, areas2d, model_data, mask=None): swe_obs_manager = SweDataManager(var_name="SWE") assert isinstance(crcm5_manager, Crcm5ModelDataManager) assert isinstance(ax, Axes) if mask is None: i_model0, j_model0 = model_data.metadata["ix"], model_data.metadata[ "jy"] mask = crcm5_manager.get_mask_for_cells_upstream(i_model0, j_model0) #print model_data.time[0], model_data.time[-1] #time window, inclusive start_date = model_data.time[0] end_date = model_data.time[-1] ts_swe_mod = crcm5_manager.get_monthly_means_over_points( mask, "I5", areas2d=areas2d, start_date=start_date, end_date=end_date) #cruManager = CRUDataManager(path="data/cru_data/CRUTS3.1/cru_ts_3_10.1901.2009.pre.dat.nc", var_name="pre") ts_swe_obs = swe_obs_manager.get_monthly_timeseries_using_mask( mask, crcm5_manager.lons2D, crcm5_manager.lats2D, areas2d, start_date=model_data.time[0], end_date=model_data.time[-1]) mod = np.array(ts_swe_mod.data) / 1000.0 #convert to m * m^2 sta = np.array(ts_swe_obs.data) / 1000.0 #convert to m * m^2 print(min(mod), max(mod)) print(min(sta), max(sta)) ax.annotate("r = {0:.2f}".format(float(np.corrcoef([mod, sta])[0, 1])), xy=(0.1, 0.8), xycoords="axes fraction", zorder=5) ax.plot(ts_swe_mod.time, (mod - sta), color="k", linewidth=2) ax.plot(ts_swe_mod.time, mod, color="b") ax.plot(ts_swe_mod.time, sta, color="r") ax.xaxis.set_major_formatter(DateFormatter("%y/%m")) ax.xaxis.set_major_locator(MonthLocator(bymonth=list(range(1, 13, 2)))) ax.set_title("CRCM5 versus Analysis (Ross Brown)") ax.set_ylabel("SWE, m^3, SWEmod - SWEobs")
def main(): start_year = 1979 end_year = 1988 img_folder = "nemo_vs_hostetler_GL_extended_domain" # create the image folder if necessary img_folder_p = Path(img_folder) if not img_folder_p.is_dir(): img_folder_p.mkdir() HL_LABEL = "CRCM5_HL" NEMO_LABEL = "CRCM5_NEMO" sim_label_to_path = OrderedDict( [(HL_LABEL, "/RECH2/huziy/coupling/GL_440x260_0.1deg_GL_with_Hostetler/Samples_selected"), (NEMO_LABEL, "/RECH2/huziy/coupling/coupled-GL-NEMO1h_30min/Samples")] ) obs_manager = SweDataManager() pass
def compare_vars(vname_model="TT", vname_obs="tmp", r_config=None, season_to_months=None, obs_path=None, nx_agg=5, ny_agg=5, bmp_info_agg=None, diff_axes_list=None, obs_axes_list=None, model_axes_list=None, bmp_info_model=None, mask_shape_file=None): """ if obs_axes_list is not None, plot observation data in those :param mask_shape_file: :param bmp_info_model: basemap info native to the model :param model_axes_list: Axes to plot model outputs :param vname_model: :param vname_obs: :param r_config: :param season_to_months: :param obs_path: :param nx_agg: :param ny_agg: :param bmp_info_agg: :param diff_axes_list: if it is None the plots for each variable is done in separate figures """ if vname_obs is None: vname_model_to_vname_obs = {"TT": "tmp", "PR": "pre"} vname_obs = vname_model_to_vname_obs[vname_model] seasonal_clim_fields_model = analysis.get_seasonal_climatology_for_runconfig(run_config=r_config, varname=vname_model, level=0, season_to_months=season_to_months) season_to_clim_fields_model_agg = OrderedDict() for season, field in seasonal_clim_fields_model.items(): print(field.shape) season_to_clim_fields_model_agg[season] = aggregate_array(field, nagg_x=nx_agg, nagg_y=ny_agg) if vname_model == "PR": season_to_clim_fields_model_agg[season] *= 1.0e3 * 24 * 3600 if vname_obs in ["SWE", ]: obs_manager = SweDataManager(path=obs_path, var_name=vname_obs) elif obs_path is None: obs_manager = CRUDataManager(var_name=vname_obs) else: obs_manager = CRUDataManager(var_name=vname_obs, path=obs_path) seasonal_clim_fields_obs = obs_manager.get_seasonal_means(season_name_to_months=season_to_months, start_year=r_config.start_year, end_year=r_config.end_year) seasonal_clim_fields_obs_interp = OrderedDict() # Derive the mask from a shapefile if provided if mask_shape_file is not None: the_mask = get_mask(bmp_info_agg.lons, bmp_info_agg.lats, shp_path=mask_shape_file) else: the_mask = np.zeros_like(bmp_info_agg.lons) for season, obs_field in seasonal_clim_fields_obs.items(): obs_field = obs_manager.interpolate_data_to(obs_field, lons2d=bmp_info_agg.lons, lats2d=bmp_info_agg.lats, nneighbours=1) obs_field = np.ma.masked_where(the_mask > 0.5, obs_field) seasonal_clim_fields_obs_interp[season] = obs_field # assert hasattr(seasonal_clim_fields_obs_interp[season], "mask") season_to_err = OrderedDict() print("-------------var: {} (PE with CRU)---------------------".format(vname_model)) for season in seasonal_clim_fields_obs_interp: seasonal_clim_fields_obs_interp[season] = np.ma.masked_where(np.isnan(seasonal_clim_fields_obs_interp[season]), seasonal_clim_fields_obs_interp[season]) season_to_err[season] = season_to_clim_fields_model_agg[season] - seasonal_clim_fields_obs_interp[season] if vname_model in ["I5"]: lons = bmp_info_agg.lons.copy() lons[lons > 180] -= 360 season_to_err[season] = maskoceans(lons, bmp_info_agg.lats, season_to_err[season]) good_vals = season_to_err[season] good_vals = good_vals[~good_vals.mask] print("{}: min={}; max={}; avg={}".format(season, good_vals.min(), good_vals.max(), good_vals.mean())) print("---------percetages --- CRU ---") print("{}: {} \%".format(season, good_vals.mean() / seasonal_clim_fields_obs_interp[season][~season_to_err[season].mask].mean() * 100)) cs = plot_seasonal_mean_biases(season_to_error_field=season_to_err, varname=vname_model, basemap_info=bmp_info_agg, axes_list=diff_axes_list) if obs_axes_list is not None and vname_model in ["I5"]: clevs = [0, 50, 60, 70, 80, 90, 100, 150, 200, 250, 300, 350, 400, 500] cs_obs = None xx, yy = bmp_info_agg.get_proj_xy() lons = bmp_info_agg.lons.copy() lons[lons > 180] -= 360 lons_model = None xx_model, yy_model = None, None cs_mod = None norm = BoundaryNorm(clevs, 256) for col, (season, obs_field) in enumerate(seasonal_clim_fields_obs_interp.items()): # Obsrved fields ax = obs_axes_list[col] if bmp_info_agg.should_draw_basin_boundaries: bmp_info_agg.basemap.readshapefile(BASIN_BOUNDARIES_SHP[:-4], "basin", ax=ax) to_plot = maskoceans(lons, bmp_info_agg.lats, obs_field) cs_obs = bmp_info_agg.basemap.contourf(xx, yy, to_plot, levels=clevs, ax=ax, norm=norm, extend="max") bmp_info_agg.basemap.drawcoastlines(ax=ax, linewidth=0.3) ax.set_title(season) # Model outputs if model_axes_list is not None: ax = model_axes_list[col] if bmp_info_agg.should_draw_basin_boundaries: bmp_info_agg.basemap.readshapefile(BASIN_BOUNDARIES_SHP[:-4], "basin", ax=ax) if lons_model is None: lons_model = bmp_info_model.lons.copy() lons_model[lons_model > 180] -= 360 xx_model, yy_model = bmp_info_model.basemap(lons_model, bmp_info_model.lats) model_field = seasonal_clim_fields_model[season] to_plot = maskoceans(lons_model, bmp_info_model.lats, model_field) cs_mod = bmp_info_agg.basemap.contourf(xx_model, yy_model, to_plot, levels=cs_obs.levels, ax=ax, norm=cs_obs.norm, cmap=cs_obs.cmap, extend="max") bmp_info_agg.basemap.drawcoastlines(ax=ax, linewidth=0.3) plt.colorbar(cs_obs, cax=obs_axes_list[-1]) return cs
def validate_daily_climatology(): """ """ #years are inclusive start_year = 1979 end_year = 1988 #sim_name_list = ["crcm5-r", "crcm5-hcd-r", "crcm5-hcd-rl"] sim_name_list = ["crcm5-hcd-rl", "crcm5-hcd-rl-intfl"] rpn_folder_paths = [ "/home/huziy/skynet3_rech1/from_guillimin/new_outputs/quebec_0.1_{0}_spinup".format(sim_name_list[0]), "/home/huziy/skynet3_rech1/from_guillimin/new_outputs/quebec_0.1_{0}_spinup2/Samples_all_in_one_folder".format( sim_name_list[1]) ] nc_db_folder = "/home/huziy/skynet3_rech1/crcm_data_ncdb" #select stations selected_ids = None selected_ids = ["092715", "080101", "074903", "050304", "080104", "081007", "061905", "041903", "040830", "093806", "090613", "081002", "093801", "080718"] selected_ids = ["074903", ] start_date = datetime(start_year, 1, 1) end_date = datetime(end_year, 12, 31) selected_ids = None stations = cehq_station.read_station_data(selected_ids=selected_ids, start_date=start_date, end_date=end_date ) stations_hydat = cehq_station.read_hydat_station_data(folder_path="/home/huziy/skynet3_rech1/HYDAT", start_date=start_date, end_date=end_date) stations.extend(stations_hydat) varname = "STFL" sim_name_to_manager = {} sim_name_to_station_to_model_point = {} day_stamps = Station.get_stamp_days(2001) sweManager = SweDataManager(var_name="SWE") cruTempManager = CRUDataManager(lazy=True) cruPreManager = CRUDataManager(var_name="pre", lazy=True, path="data/cru_data/CRUTS3.1/cru_ts_3_10.1901.2009.pre.dat.nc") #common lake fractions when comparing simulations on the same grid all_model_points = [] cell_manager = None for sim_name, rpn_folder in zip(sim_name_list, rpn_folder_paths): dmManager = Crcm5ModelDataManager(samples_folder_path=rpn_folder, file_name_prefix="dm", all_files_in_samples_folder=True, need_cell_manager=cell_manager is None) #here using the fact that all the simulations are on the same grid if cell_manager is None: cell_manager = dmManager.cell_manager else: dmManager.cell_manager = cell_manager #determine comon lake fractions, so it is not taken from the trivial case lf = 0, but note #this has only sense when all the simulations were performed on the same grid sim_name_to_manager[sim_name] = dmManager nc_sim_folder = os.path.join(nc_db_folder, sim_name) nc_path = os.path.join(nc_sim_folder, "{0}_all.nc4".format(varname)) #In general there are several model points corresponding to a given station st_to_mp = dmManager.get_model_points_for_stations(stations, sim_name=sim_name, nc_path=nc_path, nc_sim_folder=nc_sim_folder, set_data_to_model_points=True) print("got model points for stations") sim_name_to_station_to_model_point[sim_name] = st_to_mp #save model points to a list of all points for s, mps in st_to_mp.items(): assert isinstance(s, Station) for mp in mps: assert isinstance(mp, ModelPoint) #calculate upstream swe if needed if s.mean_swe_upstream_daily_clim is None: s.mean_swe_upstream_daily_clim = sweManager.get_mean_upstream_timeseries_daily(mp, dmManager, stamp_dates=day_stamps) #These are taken from CRU dataset, only monthly data are available s.mean_temp_upstream_monthly_clim = cruTempManager.get_mean_upstream_timeseries_monthly(mp, dmManager) s.mean_prec_upstream_monthly_clim = cruPreManager.get_mean_upstream_timeseries_monthly(mp, dmManager) print("Calculated observed upstream mean values...") all_model_points.extend(mps) print("imported input data successfully, plotting ...") #for tests #test(sim_name_to_station_to_model_point) #select only stations which have corresponding model points stations = list(sim_name_to_station_to_model_point[sim_name_list[0]].keys()) from matplotlib.backends.backend_pdf import PdfPages for s in stations: years = s.get_list_of_complete_years() if len(years) < 6: continue #skip stations with less than 6 continuous years of data pp = PdfPages("nc_diagnose_{0}.pdf".format(s.id)) #plot hydrographs fig = plt.figure() gs = gridspec.GridSpec(3, 3, left=0.05, hspace=0.3, wspace=0.2) ax_stfl = fig.add_subplot(gs[0, 0]) labels, handles = plot_hydrographs(ax_stfl, s, sim_name_to_station_to_model_point, day_stamps=day_stamps, sim_names=sim_name_list ) plt.setp(ax_stfl.get_xticklabels(), visible=False) #do not show ticklabels for upper rows fig.legend(handles, labels, "lower right") #plot swe 1d compare with obs ax_swe = fig.add_subplot(gs[1, 0], sharex=ax_stfl) plot_swe_1d_compare_with_obs(ax_swe, s, sim_name_to_station_to_model_point, day_stamps=day_stamps, sim_names=sim_name_list) #plot mean temp 1d compare with obs -- here plot biases directly...?? ax_temp = fig.add_subplot(gs[0, 2]) plot_temp_1d_compare_with_obs(ax_temp, s, sim_name_to_station_to_model_point, sim_names=sim_name_list) plt.setp(ax_temp.get_xticklabels(), visible=False) #do not show ticklabels for upper rows #plot mean precip 1d compare with obs -- here plot biases directly...?? ax = fig.add_subplot(gs[1, 2], sharex=ax_temp) plot_precip_1d_compare_with_obs(ax, s, sim_name_to_station_to_model_point, sim_names=sim_name_list) #plot mean Surface and subsurface runoff ax = fig.add_subplot(gs[0, 1], sharex=ax_stfl) plot_surf_runoff(ax, s, sim_name_to_station_to_model_point, sim_names=sim_name_list) plt.setp(ax.get_xticklabels(), visible=False) #do not show ticklabels for upper rows ax = fig.add_subplot(gs[1, 1], sharex=ax_stfl) plot_subsurf_runoff(ax, s, sim_name_to_station_to_model_point, sim_names=sim_name_list) plt.setp(ax.get_xticklabels(), visible=False) #do not show ticklabels for upper rows ax = fig.add_subplot(gs[2, 1], sharex=ax_stfl) plot_total_runoff(ax, s, sim_name_to_station_to_model_point, sim_names=sim_name_list) pp.savefig() #plot flow direction and basin boundaries fig = plt.figure() gs = gridspec.GridSpec(1, 2, right=0.99, bottom=0.001) ax = fig.add_subplot(gs[0, 1]) plot_flow_directions_and_basin_boundaries(ax, s, sim_name_to_station_to_model_point, sim_name_to_manager=sim_name_to_manager) pp.savefig() #plot 2d correlation between wind speed and measured streamflow at the station pp.close()
def draw_model_comparison(model_points=None, stations=None, sim_name_to_file_name=None, hdf_folder=None, start_year=None, end_year=None, cell_manager=None, stfl_name="STFA", drainage_area_reldiff_min=0.1, plot_upstream_area_averaged=True, sim_name_to_color=None): """ :param model_points: list of model point objects :param stations: list of stations corresponding to the list of model points :param cell_manager: is a CellManager instance which can be provided for better performance if necessary len(model_points) == len(stations) if stations is not None. if stations is None - then no measured streamflow will be plotted """ assert model_points is None or stations is None or len(stations) == len(model_points) label_list = list(sim_name_to_file_name.keys()) # Needed to keep the order the same for all subplots path0 = os.path.join(hdf_folder, list(sim_name_to_file_name.items())[0][1]) flow_directions = analysis.get_array_from_file(path=path0, var_name="flow_direction") lake_fraction = analysis.get_array_from_file(path=path0, var_name="lake_fraction") # mask lake fraction in the ocean lake_fraction = np.ma.masked_where((flow_directions <= 0) | (flow_directions > 128), lake_fraction) accumulation_area_km2 = analysis.get_array_from_file(path=path0, var_name=infovar.HDF_ACCUMULATION_AREA_NAME) area_m2 = analysis.get_array_from_file(path=path0, var_name=infovar.HDF_CELL_AREA_NAME_M2) # Try to read cell areas im meters if it is not Ok then try in km2 if area_m2 is not None: cell_area_km2 = area_m2 * 1.0e-6 else: cell_area_km2 = analysis.get_array_from_file(path=path0, var_name=infovar.HDF_CELL_AREA_NAME_KM2) print("cell area ranges from {} to {}".format(cell_area_km2.min(), cell_area_km2.max())) # print "plotting from {0}".format(path0) # plt.pcolormesh(lake_fraction.transpose()) # plt.colorbar() # plt.show() # exit() file_scores = open("scores_{0}_{1}-{2}.txt".format("_".join(label_list), start_year, end_year), "w") file_correlations = open("corr_{0}_{1}-{2}.txt".format("_".join(label_list), start_year, end_year), "w") file_annual_discharge = open("flow_{0}_{1}-{2}.txt".format("_".join(label_list), start_year, end_year), "w") text_files = [file_scores, file_correlations, file_annual_discharge] # write the following columns to the scores file header_format = "{0:10s}\t{1:10s}\t{2:10s}\t" + "\t".join(["{" + str(i + 3) + ":10s}" for i in range(len(sim_name_to_file_name))]) line_format = "{0:10s}\t{1:10.1f}\t{2:10.1f}\t" + "\t".join(["{" + str(i + 3) + ":10.1f}" for i in range(len(sim_name_to_file_name))]) header_ns = ("ID", "DAo", "DAm",) + tuple(["NS({0})".format(key) for key in sim_name_to_file_name]) file_scores.write(header_format.format(*header_ns) + "\n") header_qyear = ("ID", "DAo", "DAm",) + tuple(["Qyear({0})".format(key) for key in label_list]) + \ ("Qyear(obs)",) header_format_qyear = header_format + "\t{" + str(len(label_list) + 3) + ":10s}" file_annual_discharge.write(header_format_qyear.format(*header_qyear) + "\n") lons2d, lats2d, basemap = analysis.get_basemap_from_hdf(file_path=path0) # Create a cell manager if it is not provided if cell_manager is None: cell_manager = CellManager(flow_directions, accumulation_area_km2=accumulation_area_km2, lons2d=lons2d, lats2d=lats2d) if stations is not None: # Get the list of the corresponding model points station_to_modelpoint = cell_manager.get_model_points_for_stations( station_list=stations, lake_fraction=lake_fraction, drainaige_area_reldiff_limit=drainage_area_reldiff_min) station_list = list(station_to_modelpoint.keys()) station_list.sort(key=lambda st1: st1.latitude, reverse=True) mp_list = [station_to_modelpoint[st] for st in station_list] else: mp_list = model_points station_list = None # sort so that the northernmost stations appear uppermost mp_list.sort(key=lambda mpt: mpt.latitude, reverse=True) # set ids to the model points so they can be distinguished easier model_point.set_model_point_ids(mp_list) # ###Uncomment the lines below for the validation plot in paper 2 # brewer2mpl.get_map args: set name set type number of colors # bmap = brewer2mpl.get_map("Set1", "qualitative", 9) # Change the default colors # mpl.rcParams["axes.color_cycle"] = bmap.mpl_colors # For the streamflow only plot ncols = 3 nrows = max(len(mp_list) // ncols, 1) if ncols * nrows < len(mp_list): nrows += 1 figure_stfl = plt.figure(figsize=(4 * ncols, 3 * nrows)) gs_stfl = gridspec.GridSpec(nrows=nrows, ncols=ncols) # a flag which signifies if a legend should be added to the plot, it is needed so we ahve only one legend per plot legend_added = False ax_stfl = None all_years = [y for y in range(start_year, end_year + 1)] if station_list is not None: processed_stations = station_list else: processed_stations = [None] * len(mp_list) processed_model_points = mp_list plot_point_positions_with_upstream_areas(processed_stations, processed_model_points, basemap, cell_manager, lake_fraction_field=lake_fraction) if plot_upstream_area_averaged: # create obs data managers anusplin_tmin = AnuSplinManager(variable="stmn") anusplin_tmax = AnuSplinManager(variable="stmx") anusplin_pcp = AnuSplinManager(variable="pcp") daily_dates, obs_tmin_fields = anusplin_tmin.get_daily_clim_fields_interpolated_to( start_year=start_year, end_year=end_year, lons_target=lons2d, lats_target=lats2d) _, obs_tmax_fields = anusplin_tmax.get_daily_clim_fields_interpolated_to( start_year=start_year, end_year=end_year, lons_target=lons2d, lats_target=lats2d) _, obs_pcp_fields = anusplin_pcp.get_daily_clim_fields_interpolated_to( start_year=start_year, end_year=end_year, lons_target=lons2d, lats_target=lats2d) swe_path = "/skynet3_rech1/huziy/swe_ross_brown/swe.nc4" if not os.path.isfile(os.path.realpath(swe_path)): raise IOError("SWE-obs file {} does not exist".format(swe_path)) swe_manager = SweDataManager(path=swe_path, var_name="SWE") obs_swe_daily_clim = swe_manager.get_daily_climatology(start_year, end_year) interpolated_obs_swe_clim = swe_manager.interpolate_daily_climatology_to(obs_swe_daily_clim, lons2d_target=lons2d, lats2d_target=lats2d) values_obs = None for i, the_model_point in enumerate(mp_list): ax_stfl = figure_stfl.add_subplot(gs_stfl[i // ncols, i % ncols], sharex=ax_stfl) assert isinstance(the_model_point, ModelPoint) # Check the number of years accessible for the station if the list of stations is given the_station = None if station_list is None else station_list[i] if the_station is not None: assert isinstance(the_station, Station) year_list = the_station.get_list_of_complete_years() year_list = list(filter(lambda yi: start_year <= yi <= end_year, year_list)) if len(year_list) < 1: continue else: year_list = all_years fig = plt.figure(figsize=(12, 15)) gs = gridspec.GridSpec(4, 4, wspace=1) # plot station position ax = fig.add_subplot(gs[3, 0:2]) upstream_mask = _plot_station_position(ax, the_station, basemap, cell_manager, the_model_point) # plot streamflows ax = fig.add_subplot(gs[0:2, 0:2]) dates = None model_daily_temp_clim = {} model_daily_precip_clim = {} model_daily_clim_surf_runoff = {} model_daily_clim_subsurf_runoff = {} model_daily_clim_swe = {} # get model data for the list of years simlabel_to_vals = {} for label in label_list: fname = sim_name_to_file_name[label] if hdf_folder is None: fpath = fname else: fpath = os.path.join(hdf_folder, fname) if plot_upstream_area_averaged: # read temperature data and calculate daily climatologic fileds _, model_daily_temp_clim[label] = analysis.get_daily_climatology( path_to_hdf_file=fpath, var_name="TT", level=0, start_year=start_year, end_year=end_year) # read modelled precip and calculate daily climatologic fields _, model_daily_precip_clim[label] = analysis.get_daily_climatology( path_to_hdf_file=fpath, var_name="PR", level=0, start_year=start_year, end_year=end_year) # read modelled surface runoff and calculate daily climatologic fields _, model_daily_clim_surf_runoff[label] = analysis.get_daily_climatology( path_to_hdf_file=fpath, var_name="TRAF", level=0, start_year=start_year, end_year=end_year) # read modelled subsurface runoff and calculate daily climatologic fields _, model_daily_clim_subsurf_runoff[label] = analysis.get_daily_climatology( path_to_hdf_file=fpath, var_name="TDRA", level=0, start_year=start_year, end_year=end_year) # read modelled swe and calculate daily climatologic fields _, model_daily_clim_swe[label] = analysis.get_daily_climatology( path_to_hdf_file=fpath, var_name="I5", level=0, start_year=start_year, end_year=end_year) dates, values_model = analysis.get_daily_climatology_for_a_point(path=fpath, var_name=stfl_name, years_of_interest=year_list, i_index=the_model_point.ix, j_index=the_model_point.jy) ax.plot(dates, values_model, label=label, lw=2) if sim_name_to_color is None: ax_stfl.plot(dates, values_model, label=label, lw=2) else: ax_stfl.plot(dates, values_model, sim_name_to_color[label], label=label, lw=2) print(20 * "!!!") print("{} -> {}".format(label, sim_name_to_color[label])) print(20 * "!!!") simlabel_to_vals[label] = values_model if the_station is not None: assert isinstance(the_station, Station) dates, values_obs = the_station.get_daily_climatology_for_complete_years_with_pandas(stamp_dates=dates, years=year_list) # To keep the colors consistent for all the variables, the obs Should be plotted last ax.plot(dates, values_obs, label="Obs.", lw=2) # no ticklabels for streamflow plot plt.setp(ax.get_xticklabels(), visible=False) if sim_name_to_color is None: ax_stfl.plot(dates, values_obs, label="Obs.", lw=2) else: ax_stfl.plot(dates, values_obs, label="Obs.", lw=2, color=sim_name_to_color["Obs."]) # Print excesss from streamflow validation for label, values_model in simlabel_to_vals.items(): calclulate_spring_peak_err(dates, values_obs, values_model, st_id="{}: {}".format(label, the_station.id), da_mod=the_model_point.accumulation_area, da_obs=the_station.drainage_km2) ax.set_ylabel(r"Streamflow: ${\rm m^3/s}$") assert isinstance(ax, Axes) assert isinstance(fig, Figure) upstream_area_km2 = np.sum(cell_area_km2[upstream_mask == 1]) # Put some information about the point if the_station is not None: lf_upstream = lake_fraction[upstream_mask == 1] point_info = "{0}".format(the_station.id) write_annual_flows_to_txt(label_list, simlabel_to_vals, values_obs, file_annual_discharge, station_id=the_station.id, da_obs=the_station.drainage_km2, da_mod=the_model_point.accumulation_area) else: point_info = "{0}".format(the_model_point.point_id) ax.annotate(point_info, (0.8, 0.8), xycoords="axes fraction", bbox=dict(facecolor="white", alpha=0.5), va="top", ha="right") ax.legend(loc=(0.0, 1.05), borderaxespad=0, ncol=3) ax.xaxis.set_minor_formatter(FuncFormatter(lambda x, pos: num2date(x).strftime("%b")[0])) ax.xaxis.set_minor_locator(MonthLocator(bymonthday=15)) ax.xaxis.set_major_locator(MonthLocator()) ax.grid() streamflow_axes = ax # save streamflow axes for later use if not legend_added: ax_stfl.legend(loc="lower left", bbox_to_anchor=(0, 1.15), borderaxespad=0, ncol=3) ax_stfl.xaxis.set_minor_formatter(FuncFormatter(lambda x, pos: num2date(x).strftime("%b")[0])) ax_stfl.xaxis.set_minor_locator(MonthLocator(bymonthday=15)) ax_stfl.xaxis.set_major_locator(MonthLocator()) ax_stfl.set_ylabel(r"Streamflow ${\rm m^3/s}$") legend_added = True plt.setp(ax_stfl.get_xmajorticklabels(), visible=False) ax_stfl.yaxis.set_major_locator(MaxNLocator(nbins=5)) sfmt = ScalarFormatter(useMathText=True) sfmt.set_powerlimits((-2, 2)) ax_stfl.yaxis.set_major_formatter(sfmt) ax_stfl.grid() # annotate streamflow-only panel plot ax_stfl.annotate(point_info, (0.05, 0.95), xycoords="axes fraction", bbox=dict(facecolor="white"), va="top", ha="left") if plot_upstream_area_averaged: # plot temperature comparisons (tmod - daily with anusplin tmin and tmax) ax = fig.add_subplot(gs[3, 2:], sharex=streamflow_axes) _validate_temperature_with_anusplin(ax, the_model_point, cell_area_km2=cell_area_km2, upstream_mask=upstream_mask, daily_dates=daily_dates, obs_tmin_clim_fields=obs_tmin_fields, obs_tmax_clim_fields=obs_tmax_fields, model_data_dict=model_daily_temp_clim, simlabel_list=label_list) # plot temperature comparisons (tmod - daily with anusplin tmin and tmax) ax = fig.add_subplot(gs[2, 2:], sharex=streamflow_axes) _validate_precip_with_anusplin(ax, the_model_point, cell_area_km2=cell_area_km2, upstream_mask=upstream_mask, daily_dates=daily_dates, obs_precip_clim_fields=obs_pcp_fields, model_data_dict=model_daily_precip_clim, simlabel_list=label_list) # plot mean upstream surface runoff ax = fig.add_subplot(gs[0, 2:], sharex=streamflow_axes) _plot_upstream_surface_runoff(ax, the_model_point, cell_area_km2=cell_area_km2, upstream_mask=upstream_mask, daily_dates=daily_dates, model_data_dict=model_daily_clim_surf_runoff, simlabel_list=label_list) # plot mean upstream subsurface runoff ax = fig.add_subplot(gs[1, 2:], sharex=streamflow_axes, sharey=ax) _plot_upstream_subsurface_runoff(ax, the_model_point, cell_area_km2=cell_area_km2, upstream_mask=upstream_mask, daily_dates=daily_dates, model_data_dict=model_daily_clim_subsurf_runoff, simlabel_list=label_list) # plot mean upstream swe comparison ax = fig.add_subplot(gs[2, 0:2], sharex=streamflow_axes) print("Validating SWE for ", the_station.id, "--" * 20) _validate_swe_with_ross_brown(ax, the_model_point, cell_area_km2=cell_area_km2, upstream_mask=upstream_mask, daily_dates=daily_dates, model_data_dict=model_daily_clim_swe, obs_swe_clim_fields=interpolated_obs_swe_clim, simlabel_list=label_list) if the_station is not None: im_name = "comp_point_with_obs_{0}_{1}_{2}.png".format(the_station.id, the_station.source, "_".join(label_list)) im_folder_path = os.path.join(images_folder, the_station.source) else: im_name = "comp_point_with_obs_{0}_{1}.png".format(the_model_point.point_id, "_".join(label_list)) im_folder_path = os.path.join(images_folder, "outlets_point_comp") # create a folder for a given source of observed streamflow if it does not exist yet if not os.path.isdir(im_folder_path): os.mkdir(im_folder_path) im_path = os.path.join(im_folder_path, im_name) if plot_upstream_area_averaged: fig.savefig(im_path, dpi=cpp.FIG_SAVE_DPI, bbox_inches="tight", transparent=True) plt.close(fig) # return # temporary plot only one point assert isinstance(figure_stfl, Figure) figure_stfl.tight_layout() figure_stfl.savefig(os.path.join(images_folder, "comp_point_with_obs_{0}.png".format("_".join(label_list))), bbox_inches="tight", transparent=True, dpi=cpp.FIG_SAVE_DPI) plt.close(figure_stfl) # close information text files for f in text_files: f.close()
def do_4_seasons(start_year=1980, end_year=2010): # Creates one file per simulation containing biases for 4 seasons season_to_months = { "Winter": [12, 1, 2], "Spring": list(range(3, 6)), # "Summer": list(range(6, 9)), # "Fall": list(range(9, 11)) } season_to_plot_indices = { "Winter": (0, 0), "Spring": (0, 1), "Summer": (1, 0), "Fall": (1, 1) } simlabel_to_path = { # "CRCM5-R-CanESM2-current": "/skynet3_rech1/huziy/hdf_store/cc-canesm2-driven/quebec_0.1_crcm5-r-cc-canesm2-1980-2010.hdf5", # "CRCM5-R": "/skynet3_rech1/huziy/hdf_store/quebec_0.1_crcm5-r.hdf5", "CRCM5-NL": "/skynet3_rech1/huziy/hdf_store/quebec_0.1_crcm5-r.hdf5", "CRCM5-L1": "/skynet3_rech1/huziy/hdf_store/quebec_0.1_crcm5-hcd-r.hdf5", # "CRCM5-HCD-RL-INTFL-ECOCLIMAP": "/skynet3_rech1/huziy/hdf_store/quebec_0.1_crcm5-hcd-rl-intfl_spinup_ecoclimap.hdf", # "CRCM5-HCD-RL-INTFL-ECOCLIMAP-ERA075": "/skynet3_rech1/huziy/hdf_store/quebec_0.1_crcm5-hcd-rl-intfl_spinup_ecoclimap_era075.hdf" # "CRCM5-L-CanESM2": "/RESCUE/skynet3_rech1/huziy/hdf_store/cc-canesm2-driven/quebec_0.1_crcm5-hcd-rl-cc-canesm2-1980-2010.hdf5" } print("Period of interest: {0}-{1}".format(start_year, end_year)) lake_fraction = analysis.get_array_from_file( list(simlabel_to_path.items())[-1][1], var_name=infovar.HDF_LAKE_FRACTION_NAME) pcp_obs_manager = AnuSplinManager(variable="pcp") tmax_obs_manager = AnuSplinManager(variable="stmx") tmin_obs_manager = AnuSplinManager(variable="stmn") tmax_obs_manager = None tmin_obs_manager = None swe_obs_manager = SweDataManager(var_name="SWE") station_ids = ["104001", "093806", "093801", "081002", "081007", "080718"] for simlabel, path in simlabel_to_path.items(): # Validate precipitations validate_precip(model_file=path, obs_manager=pcp_obs_manager, season_to_months=season_to_months, simlabel=simlabel, season_to_plot_indices=season_to_plot_indices, start_year=start_year, end_year=end_year, station_ids_list=station_ids) # # # Validate daily maximum temperature validate_temperature(model_file=path, obs_manager=tmax_obs_manager, season_to_months=season_to_months, simlabel=simlabel, season_to_plot_indices=season_to_plot_indices, start_year=start_year, end_year=end_year, model_var_name="TT_max") validate_temperature(model_file=path, obs_manager=tmin_obs_manager, season_to_months=season_to_months, simlabel=simlabel, season_to_plot_indices=season_to_plot_indices, start_year=start_year, end_year=end_year, model_var_name="TT_min") # validate swe validate_swe(model_file=path, obs_manager=swe_obs_manager, season_to_months=season_to_months, simlabel=simlabel, season_to_plot_indices=season_to_plot_indices, start_year=start_year, end_year=end_year, lake_fraction=lake_fraction, station_ids_list=station_ids)
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 draw_model_comparison(model_points=None, stations=None, sim_name_to_file_name=None, hdf_folder=None, start_year=None, end_year=None, cell_manager=None, plot_upstream_averages=True): """ :param model_points: list of model point objects :param stations: list of stations corresponding to the list of model points :param cell_manager: is a CellManager instance which can be provided for better performance if necessary len(model_points) == len(stations) if stations is not None. if stations is None - then no measured streamflow will be plotted """ assert model_points is None or stations is None or len(stations) == len(model_points) path0 = os.path.join(hdf_folder, list(sim_name_to_file_name.items())[0][1]) flow_directions = analysis.get_array_from_file(path=path0, var_name="flow_direction") lake_fraction = analysis.get_array_from_file(path=path0, var_name="lake_fraction") accumulation_area_km2 = analysis.get_array_from_file(path=path0, var_name=infovar.HDF_ACCUMULATION_AREA_NAME) cell_area_km2 = analysis.get_array_from_file(path=path0, var_name=infovar.HDF_CELL_AREA_NAME_M2) # print "plotting from {0}".format(path0) # plt.pcolormesh(lake_fraction.transpose()) # plt.colorbar() # plt.show() # exit() file_scores = open( "scores_{0}_{1}-{2}.txt".format("_".join(list(sim_name_to_file_name.keys())), start_year, end_year), "w") # write the following columns to the scores file header_format = "{0:10s}\t{1:10s}\t{2:10s}\t" + "\t".join(["{" + str(i + 3) + ":10s}" for i in range(len(sim_name_to_file_name))]) line_format = "{0:10s}\t{1:10.1f}\t{1:10.1f}\t" + "\t".join(["{" + str(i + 3) + ":10.1f}" for i in range(len(sim_name_to_file_name))]) header = ("ID", "DAo", "DAm",) + tuple(["NS({0})".format(key) for key in sim_name_to_file_name]) file_scores.write(header_format.format(*header) + "\n") lons2d, lats2d, basemap = analysis.get_basemap_from_hdf(file_path=path0) # Create a cell manager if it is not provided if cell_manager is None: cell_manager = CellManager(flow_directions, accumulation_area_km2=accumulation_area_km2, lons2d=lons2d, lats2d=lats2d) if stations is not None: # Get the list of the corresponding model points station_to_modelpoint_list = cell_manager.get_lake_model_points_for_stations(station_list=stations, lake_fraction=lake_fraction, nneighbours=1) station_list = list(station_to_modelpoint_list.keys()) station_list.sort(key=lambda st1: st1.latitude, reverse=True) processed_stations = station_list else: mp_list = model_points station_list = None # sort so that the northernmost stations appear uppermost mp_list.sort(key=lambda mpt: mpt.latitude, reverse=True) # set ids to the model points so they can be distinguished easier model_point.set_model_point_ids(mp_list) processed_stations = mp_list station_to_modelpoint_list = {} # brewer2mpl.get_map args: set name set type number of colors bmap = brewer2mpl.get_map("Set1", "qualitative", 9) # Change the default colors mpl.rcParams["axes.color_cycle"] = bmap.mpl_colors # For the streamflow only plot ncols = 3 nrows = max(len(station_to_modelpoint_list) // ncols, 1) if ncols * nrows < len(station_to_modelpoint_list): nrows += 1 figure_panel = plt.figure() gs_panel = gridspec.GridSpec(nrows=nrows + 1, ncols=ncols) # a flag which signifies if a legend should be added to the plot, it is needed so we ahve only one legend per plot legend_added = False label_list = list(sim_name_to_file_name.keys()) # Needed to keep the order the same for all subplots all_years = [y for y in range(start_year, end_year + 1)] # processed_model_points = mp_list # plot_point_positions_with_upstream_areas(processed_stations, processed_model_points, basemap, cell_manager) if plot_upstream_averages: # create obs data managers anusplin_tmin = AnuSplinManager(variable="stmn") anusplin_tmax = AnuSplinManager(variable="stmx") anusplin_pcp = AnuSplinManager(variable="pcp") daily_dates, obs_tmin_fields = anusplin_tmin.get_daily_clim_fields_interpolated_to( start_year=start_year, end_year=end_year, lons_target=lons2d, lats_target=lats2d) _, obs_tmax_fields = anusplin_tmax.get_daily_clim_fields_interpolated_to( start_year=start_year, end_year=end_year, lons_target=lons2d, lats_target=lats2d) _, obs_pcp_fields = anusplin_pcp.get_daily_clim_fields_interpolated_to( start_year=start_year, end_year=end_year, lons_target=lons2d, lats_target=lats2d) swe_manager = SweDataManager(var_name="SWE") obs_swe_daily_clim = swe_manager.get_daily_climatology(start_year, end_year) interpolated_obs_swe_clim = swe_manager.interpolate_daily_climatology_to(obs_swe_daily_clim, lons2d_target=lons2d, lats2d_target=lats2d) # clear the folder with images (to avoid confusion of different versions) _remove_previous_images(processed_stations[0]) ax_panel = figure_panel.add_subplot(gs_panel[0, :]) plot_positions_of_station_list(ax_panel, station_list, [station_to_modelpoint_list[s][0] for s in station_list], basemap=basemap, cell_manager=cell_manager, fill_upstream_areas=False) ax_to_share = None for i, the_station in enumerate(station_list): # +1 due to the plot with station positions ax_panel = figure_panel.add_subplot(gs_panel[1 + i // ncols, i % ncols], sharex=ax_to_share) if ax_to_share is None: ax_to_share = ax_panel # Check the number of years accessible for the station if the list of stations is given if the_station is not None: assert isinstance(the_station, Station) year_list = the_station.get_list_of_complete_years() year_list = list(filter(lambda yi: start_year <= yi <= end_year, year_list)) if len(year_list) < 1: continue print("Working on station: {0}".format(the_station.id)) else: year_list = all_years fig = plt.figure() gs = gridspec.GridSpec(4, 4, wspace=1) # plot station position ax = fig.add_subplot(gs[3, 0:2]) upstream_mask = _plot_station_position(ax, the_station, basemap, cell_manager, station_to_modelpoint_list[the_station][0]) # plot streamflows ax = fig.add_subplot(gs[0:2, 0:2]) dates = None model_daily_temp_clim = {} model_daily_precip_clim = {} model_daily_clim_surf_runoff = {} model_daily_clim_subsurf_runoff = {} model_daily_clim_swe = {} model_daily_clim_evap = {} # get model data for the list of years for label in label_list: fname = sim_name_to_file_name[label] fpath = os.path.join(hdf_folder, fname) if plot_upstream_averages: # read temperature data and calculate daily climatologic fileds dates, model_daily_temp_clim[label] = analysis.get_daily_climatology( path_to_hdf_file=fpath, var_name="TT", level=1, start_year=start_year, end_year=end_year) # read modelled precip and calculate daily climatologic fields _, model_daily_precip_clim[label] = analysis.get_daily_climatology( path_to_hdf_file=fpath, var_name="PR", level=None, start_year=start_year, end_year=end_year) # read modelled surface runoff and calculate daily climatologic fields _, model_daily_clim_surf_runoff[label] = analysis.get_daily_climatology( path_to_hdf_file=fpath, var_name="TRAF", level=1, start_year=start_year, end_year=end_year) # read modelled subsurface runoff and calculate daily climatologic fields _, model_daily_clim_subsurf_runoff[label] = analysis.get_daily_climatology( path_to_hdf_file=fpath, var_name="TDRA", level=1, start_year=start_year, end_year=end_year) # read modelled swe and calculate daily climatologic fields _, model_daily_clim_swe[label] = analysis.get_daily_climatology( path_to_hdf_file=fpath, var_name="I5", level=None, start_year=start_year, end_year=end_year) values_model = None # lake level due to evap/precip values_model_evp = None lf_total = 0 for the_model_point in station_to_modelpoint_list[the_station]: if the_model_point.lake_fraction is None: mult = 1.0 else: mult = the_model_point.lake_fraction lf_total += mult # Calculate lake depth variation for this simulation, since I forgot to uncomment it in the model if label.lower() != "crcm5-hcd-r": assert isinstance(the_model_point, ModelPoint) _, temp = analysis.get_daily_climatology_for_a_point(path=fpath, var_name="CLDP", years_of_interest=year_list, i_index=the_model_point.ix, j_index=the_model_point.jy) if values_model is None: values_model = mult * np.asarray(temp) else: values_model = mult * np.asarray(temp) + values_model else: raise NotImplementedError("Cannot handle lake depth for {0}".format(label)) if label.lower() in ["crcm5-hcd-rl", "crcm5-l2"]: dates, temp = analysis.get_daily_climatology_for_a_point_cldp_due_to_precip_evap( path=fpath, i_index=the_model_point.ix, j_index=the_model_point.jy, year_list=year_list, point_label=the_station.id) if values_model_evp is None: values_model_evp = mult * np.asarray(temp) else: values_model_evp = mult * np.asarray(temp) + values_model_evp values_model /= float(lf_total) values_model = values_model - np.mean(values_model) print("lake level anomaly ranges for {0}:{1:.8g};{2:.8g}".format(label, values_model.min(), values_model.max())) ax.plot(dates, values_model, label=label, lw=2) ax_panel.plot(dates, values_model, label=label, lw=2) if values_model_evp is not None: # normalize cldp values_model_evp /= float(lf_total) # convert to m/s values_model_evp /= 1000.0 values_model_evp = values_model_evp - np.mean(values_model_evp) ax.plot(dates, values_model_evp, label=label + "(P-E)", lw=2) ax_panel.plot(dates, values_model_evp, label=label + "(P-E)", lw=2) if the_station is not None: print(type(dates[0])) dates, values_obs = the_station.get_daily_climatology_for_complete_years_with_pandas(stamp_dates=dates, years=year_list) # To keep the colors consistent for all the variables, the obs Should be plotted last ax.plot(dates, values_obs - np.mean(values_obs), label="Obs.", lw=2, color="k") ax_panel.plot(dates, values_obs - np.mean(values_obs), label="Obs.", lw=2, color="k") # calculate nash sutcliff coefficient and skip if too small ax.set_ylabel(r"Level variation: (${\rm m}$)") assert isinstance(ax, Axes) assert isinstance(fig, Figure) upstream_area_km2 = np.sum(cell_area_km2[upstream_mask == 1]) # Put some information about the point if the_station is not None: point_info = "{0}".format(the_station.id) else: point_info = "{0}".format(the_model_point.point_id) ax.annotate(point_info, (0.9, 0.9), xycoords="axes fraction", bbox=dict(facecolor="white")) ax_panel.annotate(point_info, (0.96, 0.96), xycoords="axes fraction", bbox=dict(facecolor="white"), va="top", ha="right") ax.legend(loc=(0.0, 1.05), borderaxespad=0, ncol=3) ax.xaxis.set_major_formatter(FuncFormatter(lambda val, pos: num2date(val).strftime("%b")[0])) # ax.xaxis.set_minor_locator(MonthLocator()) ax.xaxis.set_major_locator(MonthLocator()) ax.grid() streamflow_axes = ax # save streamflow axes for later use if not legend_added: ax_panel.legend(loc=(0.0, 1.1), borderaxespad=0.5, ncol=1) ax_panel.xaxis.set_minor_formatter(FuncFormatter(lambda val, pos: num2date(val).strftime("%b")[0])) ax_panel.xaxis.set_minor_locator(MonthLocator(bymonthday=15)) ax_panel.xaxis.set_major_locator(MonthLocator()) ax_panel.xaxis.set_major_formatter(FuncFormatter(lambda val, pos: "")) ax_panel.set_ylabel(r"Level variation (${\rm m}$)") legend_added = True ax_panel.yaxis.set_major_locator(MaxNLocator(nbins=5)) ax_panel.grid() if plot_upstream_averages: # plot temperature comparisons (tmod - daily with anusplin tmin and tmax) ax = fig.add_subplot(gs[3, 2:], sharex=streamflow_axes) success = _validate_temperature_with_anusplin(ax, the_model_point, cell_area_km2=cell_area_km2, upstream_mask=upstream_mask, daily_dates=daily_dates, obs_tmin_clim_fields=obs_tmin_fields, obs_tmax_clim_fields=obs_tmax_fields, model_data_dict=model_daily_temp_clim, simlabel_list=label_list) # plot temperature comparisons (tmod - daily with anusplin tmin and tmax) ax = fig.add_subplot(gs[2, 2:], sharex=streamflow_axes) _validate_precip_with_anusplin(ax, the_model_point, cell_area_km2=cell_area_km2, upstream_mask=upstream_mask, daily_dates=daily_dates, obs_precip_clim_fields=obs_pcp_fields, model_data_dict=model_daily_precip_clim, simlabel_list=label_list) # plot mean upstream surface runoff ax = fig.add_subplot(gs[0, 2:], sharex=streamflow_axes) _plot_upstream_surface_runoff(ax, the_model_point, cell_area_km2=cell_area_km2, upstream_mask=upstream_mask, daily_dates=daily_dates, model_data_dict=model_daily_clim_surf_runoff, simlabel_list=label_list) # plot mean upstream subsurface runoff ax = fig.add_subplot(gs[1, 2:], sharex=streamflow_axes, sharey=ax) _plot_upstream_subsurface_runoff(ax, the_model_point, cell_area_km2=cell_area_km2, upstream_mask=upstream_mask, daily_dates=daily_dates, model_data_dict=model_daily_clim_subsurf_runoff, simlabel_list=label_list) # plot mean upstream swe comparison ax = fig.add_subplot(gs[2, 0:2], sharex=streamflow_axes) _validate_swe_with_ross_brown(ax, the_model_point, cell_area_km2=cell_area_km2, upstream_mask=upstream_mask, daily_dates=daily_dates, model_data_dict=model_daily_clim_swe, obs_swe_clim_fields=interpolated_obs_swe_clim, simlabel_list=label_list) if the_station is not None: im_name = "comp_point_with_obs_{0}_{1}_{2}.pdf".format(the_station.id, the_station.source, "_".join(label_list)) im_folder_path = os.path.join(images_folder, the_station.source + "_levels") else: im_name = "comp_point_with_obs_{0}_{1}.pdf".format(the_model_point.point_id, "_".join(label_list)) im_folder_path = os.path.join(images_folder, "outlets_point_comp_levels") # create a folder for a given source of observed streamflow if it does not exist yet if not os.path.isdir(im_folder_path): os.mkdir(im_folder_path) im_path = os.path.join(im_folder_path, im_name) if plot_upstream_averages: fig.savefig(im_path, dpi=cpp.FIG_SAVE_DPI, bbox_inches="tight") plt.close(fig) assert isinstance(figure_panel, Figure) figure_panel.tight_layout() figure_panel.savefig( os.path.join(images_folder, "comp_lake-levels_at_point_with_obs_{0}.png".format("_".join(label_list))), bbox_inches="tight") plt.close(figure_panel) file_scores.close()
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(): b, lons2d, lats2d = draw_regions.get_basemap_and_coords(llcrnrlat=40.0, llcrnrlon=-145, urcrnrlon=-10) lons2d[lons2d > 180] -= 360 x, y = b(lons2d, lats2d) #period start_year = 1981 end_year = 1997 the_months = [12,1,2] levels = [10] + list(range(20, 120, 20)) + [150,200, 300,500,1000] cmap = mpl.cm.get_cmap(name="jet_r", lut = len(levels)) norm = colors.BoundaryNorm(levels, cmap.N) swe_obs_manager = SweDataManager(var_name="SWE") swe_obs = swe_obs_manager.get_mean(start_year, end_year, months=the_months) print("Calculated obs swe") swe_obs_interp = swe_obs_manager.interpolate_data_to(swe_obs, lons2d, lats2d, nneighbours=1) gs = gridspec.GridSpec(2,3) #plot_utils.apply_plot_params(width_pt=None, height_cm=20, width_cm=30, font_size=12) fig = plt.figure() coast_line_width = 0.25 axes_list = [] #plot obs on its own grid but in the model's projection ax = fig.add_subplot(gs[0,0]) axes_list.append(ax) x_obs, y_obs = b(swe_obs_manager.lons2d, swe_obs_manager.lats2d) swe_obs = maskoceans(swe_obs_manager.lons2d, swe_obs_manager.lats2d, swe_obs) img = b.contourf(x_obs, y_obs, swe_obs, levels = levels, norm = norm, cmap = cmap) draw_colorbar(fig, img, ax = ax) ax.set_title("Obs native grid") #plot obs interpolated ax = fig.add_subplot(gs[1,0]) axes_list.append(ax) swe_obs_interp = maskoceans(lons2d, lats2d, swe_obs_interp) img = b.contourf(x, y, swe_obs_interp, levels = levels, norm = norm, cmap = cmap) draw_colorbar(fig, img, ax = ax) ax.set_title("Obs interpolated \n to model grid") #plot model res. (ERA40 driven) ax = fig.add_subplot(gs[0,1]) axes_list.append(ax) prefixes = ["pmNorthAmerica_0.44deg_ERA40-Int_{0}_1958-1977".format(m) for m in ["Dec", "Jan", "Feb"]] swe_model_era = CRCMDataManager.get_mean_2d_from_climatologies(path="data/CORDEX/na/means_month/era40_driven", var_name="I5", file_prefixes=prefixes) swe_model_era = maskoceans(lons2d, lats2d, swe_model_era) img = b.contourf(x, y, swe_model_era, levels = levels, norm = norm, cmap = cmap) draw_colorbar(fig, img, ax = ax) ax.set_title("Model (ERA40 driven 1958-1977)") #plot model(ERA40 driven) - obs ax = fig.add_subplot(gs[0,2]) axes_list.append(ax) levels_diff = np.arange(-100, 110, 10) img = b.contourf(x, y, swe_model_era - swe_obs_interp, levels = levels_diff) draw_colorbar(fig, img, ax = ax, boundaries=levels_diff) ax.set_title("Model (ERA40 driven 1958-1977) - Obs.") #plot model res. (GCM driven, E2) ax = fig.add_subplot(gs[1,1]) axes_list.append(ax) path = "/skynet1_exec2/separovi/results/North_America/tests_E/all/means_season" prefix = "pmNorthAmerica_0.44deg_CanHistoE2_A1979-1997" suffixes = ["djf"] swe_model_gcm = CRCMDataManager.get_mean_2d_from_climatologies(path=path, file_prefixes=[prefix], file_suffixes=suffixes, var_name="I5") swe_model_gcm = maskoceans(lons2d, lats2d, swe_model_gcm) print("model: min = {0}; max = {1}".format(np.ma.min(swe_model_gcm), np.ma.max(swe_model_gcm))) img = b.contourf(x, y, swe_model_gcm, levels = levels, norm = norm, cmap = cmap) draw_colorbar(fig, img, ax = ax, boundaries=levels_diff) ax.set_title("Model (GCM driven, E2, 1979-1997)") #plot model(gcm driven) - obs ax = fig.add_subplot(gs[1,2]) axes_list.append(ax) levels_diff = np.arange(-100, 110, 10) img = b.contourf(x, y, np.ma.array(swe_model_gcm) - swe_obs_interp, levels = levels_diff) draw_colorbar(fig, img, ax = ax) ax.set_title("Model (GCM driven) - Obs.") ####Draw common elements pf_kinds = draw_regions.get_permafrost_mask(lons2d, lats2d) for the_ax in axes_list: b.drawcoastlines(ax = the_ax, linewidth = coast_line_width) b.contour(x, y, pf_kinds, ax = the_ax, colors = "k") gs.tight_layout(fig, h_pad = 0.9, w_pad = 18) fig.savefig("swe_validation.png")
def validate_using_monthly_diagnostics(): start_year = 1980 end_year = 1996 sim_data_folder = "/home/huziy/skynet1_rech3/cordex/CORDEX_DIAG/era40_driven_b1" sim_names = ["ERA40","MPI","CanESM"] simname_to_path = { "ERA40": "/home/huziy/skynet1_rech3/cordex/CORDEX_DIAG/era40_driven_b1", "MPI": "/home/huziy/skynet1_rech3/cordex/CORDEX_DIAG/NorthAmerica_0.44deg_MPI_B1", "CanESM": "/home/huziy/skynet1_rech3/cordex/CORDEX_DIAG/NorthAmerica_0.44deg_CanESM_B1" } coord_file = os.path.join(sim_data_folder, "pmNorthAmerica_0.44deg_ERA40-Int_B1_200812_moyenne") basemap, lons2d, lats2d = draw_regions.get_basemap_and_coords(resolution="c", file_path = coord_file, llcrnrlat=45.0, llcrnrlon=-145, urcrnrlon=-20, urcrnrlat=74, anchor="W" ) assert isinstance(basemap, Basemap) lons2d[lons2d > 180] -= 360 swe_obs_manager = SweDataManager(var_name="SWE") swe_obs = swe_obs_manager.get_mean(start_year, end_year, months=[12,1,2]) swe_obs = swe_obs_manager.interpolate_data_to(swe_obs, lons2d, lats2d, nneighbours=1) x, y = basemap(lons2d, lats2d) #x = (x[1:,1:] + x[:-1, :-1]) /2.0 permafrost_mask = draw_regions.get_permafrost_mask(lons2d, lats2d) mask_cond = (permafrost_mask <= 0) | (permafrost_mask >= 2) #plot_utils.apply_plot_params(width_pt=None, width_cm=35,height_cm=55, font_size=35) fig = plt.figure() assert isinstance(fig, Figure) cmap = my_colormaps.get_red_blue_colormap(ncolors=10) gs = gridspec.GridSpec(3,2, width_ratios=[1,0.1], hspace=0, wspace=0, left=0.05, bottom = 0.01, top=0.95) all_axes = [] all_img = [] i = 0 for name in sim_names: path = simname_to_path[name] dm = CRCMDataManager(data_folder=path) swe_mod = dm.get_mean_over_months_of_2d_var(start_year, end_year, months = [12,1,2], var_name="I5") delta = swe_mod - swe_obs ax = fig.add_subplot(gs[i,0]) assert isinstance(ax, Axes) delta = np.ma.masked_where(mask_cond, delta) img = basemap.pcolormesh(x, y, delta, cmap = cmap, vmin=-100, vmax = 100) if not i: ax.set_title("SWE, Mod - Obs, ({0} - {1}), DJF\n".format(start_year, end_year)) i += 1 #ax.set_ylabel(name) all_axes.append(ax) all_img.append(img) i = 0 axs_to_hide = [] #zones and coastlines for the_ax, the_img in zip(all_axes, all_img): #divider = make_axes_locatable(the_ax) #cax = divider.append_axes("bottom", "5%", pad="3%") assert isinstance(the_ax, Axes) basemap.drawcoastlines(ax = the_ax, linewidth=0.5) basemap.readshapefile("data/pf_4/permafrost8_wgs84/permaice", name="zone", ax=the_ax, linewidth=1.5, drawbounds=False) for nshape,seg in enumerate(basemap.zone): if basemap.zone_info[nshape]["EXTENT"] != "C": continue poly = mpl.patches.Polygon(seg,edgecolor = "k", facecolor="none", zorder = 10, lw = 1.5) the_ax.add_patch(poly) i += 1 cax = fig.add_subplot(gs[:,1]) assert isinstance(cax, Axes) cax.set_anchor("W") cax.set_aspect(30) formatter = FuncFormatter( lambda x, pos: "{0: <6}".format(str(x)) ) cb = fig.colorbar(all_img[0], ax = cax, cax = cax, extend = "both", format = formatter) cax.set_title("mm") print("aspect = ", cax.get_aspect()) #fig.tight_layout(h_pad=0) # for the_ax in axs_to_hide: # the_ax.set_visible(False) fig.savefig("swe_validation_era_mpi_canesm_djf.png") #swe_obs = swe_obs_manager.get_mean(start_year, end_year, months=the_months) pass
def compare_vars(vname_model="TT", vname_obs="tmp", r_config=None, season_to_months=None, obs_path=None, nx_agg_model=5, ny_agg_model=5, bmp_info_agg=None, diff_axes_list=None, obs_axes_list=None, model_axes_list=None, bmp_info_model=None, mask_shape_file=None, nx_agg_obs=1, ny_agg_obs=1): """ if obs_axes_list is not None, plot observation data in those :param mask_shape_file: :param bmp_info_model: basemap info native to the model :param model_axes_list: Axes to plot model outputs :param vname_model: :param vname_obs: :param r_config: :param season_to_months: :param obs_path: :param nx_agg_model: :param ny_agg_model: :param bmp_info_agg: :param diff_axes_list: if it is None the plots for each variable is done in separate figures """ if vname_obs is None: vname_model_to_vname_obs = {"TT": "tmp", "PR": "pre"} vname_obs = vname_model_to_vname_obs[vname_model] seasonal_clim_fields_model = analysis.get_seasonal_climatology_for_runconfig( run_config=r_config, varname=vname_model, level=0, season_to_months=season_to_months) season_to_clim_fields_model_agg = OrderedDict() for season, field in seasonal_clim_fields_model.items(): print(field.shape) season_to_clim_fields_model_agg[season] = aggregate_array( field, nagg_x=nx_agg_model, nagg_y=ny_agg_model) if vname_model == "PR": season_to_clim_fields_model_agg[season] *= 1.0e3 * 24 * 3600 if vname_obs in [ "SWE", ]: obs_manager = SweDataManager(path=obs_path, var_name=vname_obs) elif obs_path is None: obs_manager = CRUDataManager(var_name=vname_obs) else: obs_manager = CRUDataManager(var_name=vname_obs, path=obs_path) seasonal_clim_fields_obs = obs_manager.get_seasonal_means( season_name_to_months=season_to_months, start_year=r_config.start_year, end_year=r_config.end_year) seasonal_clim_fields_obs_interp = OrderedDict() # Derive the mask from a shapefile if provided if mask_shape_file is not None: the_mask = get_mask(bmp_info_agg.lons, bmp_info_agg.lats, shp_path=mask_shape_file) else: the_mask = np.zeros_like(bmp_info_agg.lons) for season, obs_field in seasonal_clim_fields_obs.items(): obs_field = obs_manager.interpolate_data_to(obs_field, lons2d=bmp_info_agg.lons, lats2d=bmp_info_agg.lats, nneighbours=nx_agg_obs * ny_agg_obs) obs_field = np.ma.masked_where(the_mask > 0.5, obs_field) seasonal_clim_fields_obs_interp[season] = obs_field # assert hasattr(seasonal_clim_fields_obs_interp[season], "mask") season_to_err = OrderedDict() print("-------------var: {} (PE with CRU)---------------------".format( vname_model)) for season in seasonal_clim_fields_obs_interp: seasonal_clim_fields_obs_interp[season] = np.ma.masked_where( np.isnan(seasonal_clim_fields_obs_interp[season]), seasonal_clim_fields_obs_interp[season]) season_to_err[season] = season_to_clim_fields_model_agg[ season] - seasonal_clim_fields_obs_interp[season] if vname_model in ["I5"]: lons = bmp_info_agg.lons.copy() lons[lons > 180] -= 360 season_to_err[season] = maskoceans(lons, bmp_info_agg.lats, season_to_err[season]) good_vals = season_to_err[season] good_vals = good_vals[~good_vals.mask] print("{}: min={}; max={}; avg={}".format(season, good_vals.min(), good_vals.max(), good_vals.mean())) print("---------percetages --- CRU ---") print("{}: {} \%".format( season, good_vals.mean() / seasonal_clim_fields_obs_interp[season] [~season_to_err[season].mask].mean() * 100)) cs = plot_seasonal_mean_biases(season_to_error_field=season_to_err, varname=vname_model, basemap_info=bmp_info_agg, axes_list=diff_axes_list) if obs_axes_list is not None and vname_model in ["I5"]: clevs = [0, 50, 60, 70, 80, 90, 100, 150, 200, 250, 300, 350, 400, 500] cs_obs = None xx, yy = bmp_info_agg.get_proj_xy() lons = bmp_info_agg.lons.copy() lons[lons > 180] -= 360 lons_model = None xx_model, yy_model = None, None cs_mod = None norm = BoundaryNorm(clevs, 256) for col, (season, obs_field) in enumerate( seasonal_clim_fields_obs_interp.items()): # Obsrved fields ax = obs_axes_list[col] if bmp_info_agg.should_draw_basin_boundaries: bmp_info_agg.basemap.readshapefile(BASIN_BOUNDARIES_SHP[:-4], "basin", ax=ax) to_plot = maskoceans(lons, bmp_info_agg.lats, obs_field) cs_obs = bmp_info_agg.basemap.contourf(xx, yy, to_plot, levels=clevs, ax=ax, norm=norm, extend="max") bmp_info_agg.basemap.drawcoastlines(ax=ax, linewidth=0.3) ax.set_title(season) # Model outputs if model_axes_list is not None: ax = model_axes_list[col] if bmp_info_agg.should_draw_basin_boundaries: bmp_info_agg.basemap.readshapefile( BASIN_BOUNDARIES_SHP[:-4], "basin", ax=ax) if lons_model is None: lons_model = bmp_info_model.lons.copy() lons_model[lons_model > 180] -= 360 xx_model, yy_model = bmp_info_model.basemap( lons_model, bmp_info_model.lats) model_field = seasonal_clim_fields_model[season] to_plot = maskoceans(lons_model, bmp_info_model.lats, model_field) cs_mod = bmp_info_agg.basemap.contourf(xx_model, yy_model, to_plot, levels=cs_obs.levels, ax=ax, norm=cs_obs.norm, cmap=cs_obs.cmap, extend="max") bmp_info_agg.basemap.drawcoastlines(ax=ax, linewidth=0.3) plt.colorbar(cs_obs, cax=obs_axes_list[-1]) return cs