예제 #1
0
def interpolate_esmf(obs_file, mod_file, depth, cmor_var):
    """The 2d interpolation with ESMF.

    Parameters
    ----------
    obs_file: str
        path to file with observations/climatology,
        will be used to extract the grid to interpolate on to.
    mod_file: str
        path to the file with model data.
    depth: int
        depth to interpolate to. First the closest depth from the
        observations will be selected and then.
    """
    metadata_obs = load_meta(obs_file, fxpath=None)
    metadata_mod = load_meta(mod_file, fxpath=None)

    data_obs = metadata_obs['datafile'].variables[cmor_var][:]
    data_model = metadata_mod['datafile'].variables[cmor_var][:]

    # Select depth in climatology that is closest to the desired depth
    target_depth, level_depth = closest_depth(metadata_obs['lev'], depth)

    # climatology and model data on the level
    data_onlev_obs = data_obs[0, level_depth, :, :]
    data_onlev_mod = interpolate_vert(metadata_mod['lev'], target_depth,
                                      data_model[0, :, :, :])

    # prepear interpolation fields
    distfield = define_esmf_field(obs_file, data_onlev_obs, 'OBS')
    distfield.data[:] = 0.0

    sourcefield = define_esmf_field(mod_file, data_onlev_mod, 'Model')
    sourcefield.data[...] = data_onlev_mod.T

    lonc, latc, data_onlev_obs_cyc, data_interpolated_cyc = esmf_regriding(
        sourcefield, distfield, metadata_obs, data_onlev_obs)

    return lonc, latc, target_depth, data_onlev_obs_cyc, data_interpolated_cyc
예제 #2
0
def plot2d_bias(cfg, plot_params):
    """Plot 2d maps of the bias relative to climatology.

    Parameters
    ----------
    model_filenames:OrderedDict
        OrderedDict with model names as keys and input files as values.
    cmor_var: str
        name of the variable
    depth: int
        we will plot the data on the model level
        that is closest to the `depth`.
    diagworkdir: str
        path to the working directory
    diagplotdir: str
        path to the plot directory
    levels: tuple
        values to be used for vmin and vmax in the form of (vmin, vmax)
    dpi: int
        the dpi values to save the figure
    observations: str
        name of the observations
    projection: instance of cartopy projection (ccrs)
    bbox: list
        bounding box. It will be the input for cartopy `set_extent`.
    ncols: int
        number of columns.

    Retuns
    ------
    None
    """
    # setupa a base figure
    figure, axis = create_plot(plot_params['model_filenames'],
                               ncols=plot_params['ncols'],
                               projection=plot_params['projection'])
    # get the filename of observations
    ifilename_obs = genfilename(cfg['work_dir'],
                                plot_params['variable'],
                                plot_params['observations'],
                                data_type='timmean',
                                extension='.nc')
    # get the metadata for observations (we just need a size)
    metadata = load_meta(
        datapath=plot_params['model_filenames'][plot_params['observations']],
        fxpath=None)
    lon2d = metadata['lon2d']

    # Create an empty array to store the mean.
    # One point larger along long to acount for cyclic point
    model_mean = np.zeros((lon2d.shape[0], lon2d.shape[1] + 1))
    print("MODEL MEAN SHAPE {}".format(model_mean.shape))

    # delete observations from the model list
    model_filenames = plot_params['model_filenames'].copy()
    del model_filenames[plot_params['observations']]
    # loop over models
    index = None
    for index, mmodel in enumerate(model_filenames):
        logger.info("Plot plot2d_bias %s for %s", plot_params['variable'],
                    mmodel)
        # get the filename with the mean generated by the `timemean`
        ifilename = genfilename(cfg['work_dir'],
                                plot_params['variable'],
                                mmodel,
                                data_type='timmean',
                                extension='.nc')
        # do the interpolation to the observation grid
        # the output is
        lonc, latc, target_depth, data_obs, interpolated = interpolate_esmf(
            ifilename_obs, ifilename, plot_params['depth'],
            plot_params['variable'])
        # get the label and convert data if needed
        cb_label, data_obs = label_and_conversion(plot_params['variable'],
                                                  data_obs)
        cb_label, interpolated = label_and_conversion(plot_params['variable'],
                                                      interpolated)
        # add to the mean model
        model_mean = model_mean + interpolated
        # set the map extent
        left, right, down, upper = plot_params['bbox']
        axis[index].set_extent([left, right, down, upper],
                               crs=ccrs.PlateCarree())
        # Only pcolormesh is working for now with cartopy,
        # contourf is failing to plot curvilinear meshes,
        # let along the unstructures ones.
        image = axis[index].contourf(
            lonc,
            latc,
            interpolated - data_obs,
            levels=plot_params['levels'],
            extend='both',
            # vmin=contours[0],
            # vmax=contours[-1],
            transform=ccrs.PlateCarree(),
            cmap=plot_params['cmap'],
        )
        # fill continents
        axis[index].add_feature(
            cfeature.GSHHSFeature(levels=[1],
                                  scale="low",
                                  facecolor="lightgray"))

        axis[index].set_title("{}, {} m".format(mmodel, int(target_depth)),
                              size=18)
        axis[index].set_rasterization_zorder(-1)
    # calculate the model mean and plot it
    if index:
        index = index
    else:
        index = 0
    model_mean = model_mean / len(model_filenames)
    axis[index + 1].set_extent([left, right, down, upper],
                               crs=ccrs.PlateCarree())
    image = axis[index + 1].contourf(
        lonc,
        latc,
        model_mean - data_obs,
        levels=plot_params['levels'],
        extend='both',
        # vmin=contours[0],
        # vmax=contours[-1],
        transform=ccrs.PlateCarree(),
        cmap=cmo.balance,
    )

    axis[index + 1].add_feature(
        cfeature.GSHHSFeature(levels=[1], scale="low", facecolor="lightgray"))

    axis[index + 1].set_title("Model mean bias, {} m".format(
        int(target_depth)),
                              size=18)
    axis[index + 1].set_rasterization_zorder(-1)
    # delete the axis that are not needed
    for delind in range(index + 2, len(axis)):
        figure.delaxes(axis[delind])
    # set common colorbar
    colorbar = figure.colorbar(image,
                               orientation='horizontal',
                               ax=axis,
                               pad=0.01,
                               shrink=0.9)
    colorbar.set_label(cb_label, rotation='horizontal', size=18)
    colorbar.ax.tick_params(labelsize=18)
    # save the picture
    pltoutname = genfilename(cfg['plot_dir'],
                             plot_params['variable'],
                             "MULTIMODEL",
                             data_type='plot2d_bias_{}_level'.format(
                                 str(int(target_depth))))

    plot_params['basedir'] = cfg['plot_dir']
    plot_params['ori_file'] = [ifilename]
    plot_params['areacello'] = None
    plot_params['mmodel'] = None
    plot_params['region'] = "Global"
    plt.savefig(pltoutname, dpi=plot_params['dpi'])

    provenance_record = get_provenance_record(plot_params, 'plot2d_bias',
                                              'png')
    with ProvenanceLogger(cfg) as provenance_logger:
        provenance_logger.log(pltoutname + '.png', provenance_record)
예제 #3
0
def plot2d_original_grid(cfg, plot_params):
    """Plot 2d maps on original grid using cartopy.

    Parameters
    ----------
    model_filenames:OrderedDict
        OrderedDict with model names as keys and input files as values.
    cmor_var: str
        name of the variable
    depth: int
        we will plot the data on the model
        level that is closest to the `depth`.
        Ignored if explicit_depths is provided.
    levels: tuple
        values to be used for vmin and vmax in the form of (vmin, vmax)
    diagworkdir: str
        path to the working directory
    diagplotdir: str
        path to the plot directory
    cmap:  matplotlib colormap
        colormap
    dpi: int
        the dpi values to save the figure
    explicit_depths: dict
        Output of the `aw_core` function.
        It's a dictionary where for each model there is a maximum temperature,
        depth level in the model, index of the depth level in the model.
        If provided the `depth` parameter is excluded.
    projection: instance of cartopy projection (ccrs)
    bbox: list
        bounding box. It will be the input for cartopy `set_extent`.
    ncols: int
        number of columns.

    Retuns
    ------
    None
    """
    figure, axis = create_plot(plot_params['model_filenames'],
                               ncols=plot_params['ncols'],
                               projection=plot_params['projection'])
    index = None
    for index, mmodel in enumerate(plot_params['model_filenames']):
        logger.info("Plot plot2d_original_grid %s for %s",
                    plot_params['variable'], mmodel)

        ifilename = genfilename(cfg['work_dir'],
                                plot_params['variable'],
                                mmodel,
                                data_type='timmean',
                                extension='.nc')

        metadata = load_meta(ifilename, fxpath=None)
        datafile = metadata['datafile']
        lon2d = metadata['lon2d']
        lat2d = metadata['lat2d']
        lev = metadata['lev']

        if not plot_params['explicit_depths']:
            depth_target, level_target = closest_depth(lev,
                                                       plot_params['depth'])
        else:
            level_target = plot_params['explicit_depths'][mmodel][
                'maxvalue_index']
            depth_target = lev[level_target]

        if datafile.variables[plot_params['variable']].ndim < 4:
            data = datafile.variables[plot_params['variable']][
                level_target, :, :]
        else:
            data = datafile.variables[plot_params['variable']][
                0, level_target, :, :]

        cb_label, data = label_and_conversion(plot_params['variable'], data)

        left, right, down, upper = plot_params['bbox']

        axis[index].set_extent([left, right, down, upper],
                               crs=ccrs.PlateCarree())
        # Only pcolormesh is working for now with cartopy,
        # contourf is failing to plot curvilinear meshes,
        # let along the unstructures ones.
        image = axis[index].pcolormesh(
            lon2d,
            lat2d,
            data,
            vmin=plot_params['levels'][0],
            vmax=plot_params['levels'][-1],
            transform=ccrs.PlateCarree(),
            cmap=plot_params['cmap'],
        )

        axis[index].add_feature(
            cfeature.GSHHSFeature(levels=[1],
                                  scale="low",
                                  facecolor="lightgray"))
        axis[index].set_title("{}, {} m".format(mmodel,
                                                np.round(depth_target, 1)),
                              size=18)
        axis[index].set_rasterization_zorder(-1)

    # delete unused axis
    for delind in range(index + 1, len(axis)):
        figure.delaxes(axis[delind])

    # set common colorbar
    colorbar = figure.colorbar(image,
                               orientation='horizontal',
                               ax=axis,
                               pad=0.01,
                               shrink=0.9)
    colorbar.set_label(cb_label, rotation='horizontal', size=18)
    colorbar.ax.tick_params(labelsize=18)

    if not plot_params['explicit_depths']:
        plot_type = 'plot2d_{}_depth'.format(str(plot_params['depth']))
    else:
        plot_type = "plot2d_different_levels"

    # save the figure
    pltoutname = genfilename(cfg['plot_dir'],
                             plot_params['variable'],
                             "MULTIMODEL",
                             data_type=plot_type)

    plot_params['basedir'] = cfg['plot_dir']
    plot_params['ori_file'] = [ifilename]
    plot_params['areacello'] = None
    plot_params['mmodel'] = None
    plot_params['region'] = "Global"
    plt.savefig(pltoutname, dpi=plot_params['dpi'])

    provenance_record = get_provenance_record(plot_params, 'plot2d', 'png')
    with ProvenanceLogger(cfg) as provenance_logger:
        provenance_logger.log(pltoutname + '.png', provenance_record)