def hofm_save_data(cfg, data_info, oce_hofm):
    """Save data for Hovmoeller diagrams."""

    ofiles = {}
    ofiles['ofilename'] = genfilename(**data_info, data_type='hofm')
    ofiles['ofilename_levels'] = genfilename(**data_info, data_type='levels')
    ofiles['ofilename_time'] = genfilename(**data_info, data_type='time')

    np.save(ofiles['ofilename'], oce_hofm)
    provenance_record = get_provenance_record(data_info, 'hofm', 'npy')
    with ProvenanceLogger(cfg) as provenance_logger:
        provenance_logger.log(ofiles['ofilename'] + '.npy', provenance_record)

    if isinstance(data_info['levels'], np.ma.core.MaskedArray):
        np.save(ofiles['ofilename_levels'],
                data_info['levels'][0:data_info['lev_limit']].filled())
    else:
        np.save(ofiles['ofilename_levels'],
                data_info['levels'][0:data_info['lev_limit']])
    provenance_record = get_provenance_record(data_info, 'lev', 'npy')
    with ProvenanceLogger(cfg) as provenance_logger:
        provenance_logger.log(ofiles['ofilename_levels'] + '.npy',
                              provenance_record)

    np.save(ofiles['ofilename_time'], data_info['time'])
    provenance_record = get_provenance_record(data_info, 'time', 'npy')
    with ProvenanceLogger(cfg) as provenance_logger:
        provenance_logger.log(ofiles['ofilename_time'] + '.npy',
                              provenance_record)
def tsplot_save_data(cfg, data_info, temp, salt, depth_model):
    """Save data for TS plots."""

    ofiles = {}
    data_info['variable'] = 'thetao'
    ofiles['ofilename_t'] = genfilename(**data_info, data_type='tsplot')
    np.save(ofiles['ofilename_t'], temp)
    provenance_record = get_provenance_record(data_info, 'tsplot', 'npy')
    with ProvenanceLogger(cfg) as provenance_logger:
        provenance_logger.log(ofiles['ofilename_t'] + '.npy',
                              provenance_record)

    data_info['variable'] = 'so'
    ofiles['ofilename_s'] = genfilename(**data_info, data_type='tsplot')
    np.save(ofiles['ofilename_s'], salt)
    provenance_record = get_provenance_record(data_info, 'tsplot', 'npy')
    with ProvenanceLogger(cfg) as provenance_logger:
        provenance_logger.log(ofiles['ofilename_s'] + '.npy',
                              provenance_record)

    data_info['variable'] = 'depth'
    ofiles['ofilename_depth'] = genfilename(**data_info, data_type='tsplot')
    np.save(ofiles['ofilename_depth'], depth_model)
    provenance_record = get_provenance_record(data_info, 'tsplot', 'npy')
    with ProvenanceLogger(cfg) as provenance_logger:
        provenance_logger.log(ofiles['ofilename_depth'] + '.npy',
                              provenance_record)
def aw_core(model_filenames, diagworkdir, region, cmor_var):
    """Calculate Atlantic Water (AW) core depth the region.

    The AW core is defined as water temperature maximum
    between 200 and 1000 meters. Can be in future generalised
    to find the depth of specific water masses.

    The function relies on the data for the profiles, so
    this information should be available.

    Parameters
    ----------
    model_filenames: OrderedDict
        OrderedDict with model names as keys and input files as values.
    diagworkdir: str
        path to work directory.
    region: str
        one of the regions from `hofm_regions`,
        the data from the mean vertical profiles should be available.
    cmor_var: str
        name of the variable.

    Returns
    -------
    aw_core_parameters: dict
        For each model there is maximum temperature, depth level in the model,
        index of the depth level in the model.
    """
    logger.info("Calculate AW core statistics")
    aw_core_parameters = {}

    for mmodel in model_filenames:
        aw_core_parameters[mmodel] = {}
        logger.info("Plot profile %s data for %s, region %s", cmor_var, mmodel,
                    region)
        ifilename = genfilename(diagworkdir, cmor_var, mmodel, region, 'hofm',
                                '.npy')
        ifilename_levels = genfilename(diagworkdir, cmor_var, mmodel, region,
                                       'levels', '.npy')

        hofdata = np.load(ifilename, allow_pickle=True)
        lev = np.load(ifilename_levels, allow_pickle=True)

        profile = (hofdata)[:, :].mean(axis=1)
        maxvalue = np.max(profile[(lev >= 200) & (lev <= 1000)])
        maxvalue_index = np.where(profile == maxvalue)[0][0]
        maxvalue_depth = lev[maxvalue_index]

        if maxvalue > 100:
            maxvalue = maxvalue - 273.15

        aw_core_parameters[mmodel]['maxvalue'] = maxvalue
        aw_core_parameters[mmodel]['maxvalue_index'] = maxvalue_index
        aw_core_parameters[mmodel]['maxvalue_depth'] = maxvalue_depth

    return aw_core_parameters
예제 #4
0
def plot_aw_core_stat(aw_core_parameters, diagplotdir):
    """Generate plotsa t AW core depth.

    Depth of the AW core and temperature of the AW core.
    Use pandas plot functionality.

    Parameters
    ----------
    aw_core_parameters: dict
        Output of the `aw_core` function.
        It's a dictionary where for each model there is maximum temperature,
        depth level in the model, index of the depth level in the model.
    diagplotdir: str
        plot folder

    Returns
    -------
    None
    """
    logger.info("Plot AW core statistics")
    # Convert dictionary to pandas Dataframe
    dataframe = pd.DataFrame(aw_core_parameters).transpose()

    plt.figure()
    dataframe.maxvalue.plot(kind='barh')
    plt.xlabel(r'$^{\circ}$C')
    pltoutname = genfilename(diagplotdir,
                             variable='aw-core-temp',
                             region='EB',
                             data_type='awiCoreTemp')

    plt.tight_layout()
    plt.savefig(pltoutname, dpi=100)

    plt.figure()
    dataframe.maxvalue_depth.plot(kind='barh')
    plt.xlabel('m')
    pltoutname = genfilename(diagplotdir,
                             variable='aw-core-depth',
                             region='EB',
                             data_type='awiCoreTemp')

    plt.tight_layout()
    plt.savefig(pltoutname, dpi=100)
def transect_save_data(cfg, data_info, secfield, lon_s4new, lat_s4new):
    """Save data for transects."""

    ofiles = {}
    ofiles['ofilename'] = genfilename(**data_info, data_type='transect')
    ofiles['ofilename_depth'] = genfilename(
        data_info['basedir'], 'depth', data_info['mmodel'],
        data_info['region'], 'transect_' + data_info['variable'])
    ofiles['ofilename_dist'] = genfilename(data_info['basedir'], 'distance',
                                           data_info['mmodel'],
                                           data_info['region'],
                                           'transect_' + data_info['variable'])

    np.save(ofiles['ofilename'], secfield)
    print(ofiles['ofilename'])
    provenance_record = get_provenance_record(data_info, 'transect', 'npy')
    with ProvenanceLogger(cfg) as provenance_logger:
        provenance_logger.log(ofiles['ofilename'] + '.npy', provenance_record)
    # we have to fill masked arrays before saving

    if isinstance(data_info['levels'], np.ma.core.MaskedArray):
        np.save(ofiles['ofilename_depth'], data_info['levels'].filled())
    else:
        np.save(ofiles['ofilename_depth'], data_info['levels'])
    print(ofiles['ofilename_depth'])
    provenance_record = get_provenance_record(data_info, 'levels', 'npy')
    with ProvenanceLogger(cfg) as provenance_logger:
        provenance_logger.log(ofiles['ofilename_depth'] + '.npy',
                              provenance_record)

    np.save(ofiles['ofilename_dist'], point_distance(lon_s4new, lat_s4new))
    provenance_record = get_provenance_record(data_info, 'distance', 'npy')
    with ProvenanceLogger(cfg) as provenance_logger:
        provenance_logger.log(ofiles['ofilename_dist'] + '.npy',
                              provenance_record)
    print(ofiles['ofilename_dist'])
예제 #6
0
def transect_plot(cfg, plot_params):
    """Plot transects.

    Parameters
    ----------
    model_filenames:OrderedDict
        OrderedDict with model names as keys and input files as values.
    cmor_var: str
        name of the variable
    region: str
        name of the region predefined in `transect_points` function.
    levels: tuple
       contours - (minimum, maximum, number of levels)
    ncols: int
        number of columns in the plot
    cmap: matplotlib colormap instance

    Returns
    -------
    None

    """
    figure, axis = create_plot(plot_params['model_filenames'],
                               ncols=plot_params['ncols'])

    # get transect positions and calculate distances between points
    lon_s4new, lat_s4new = transect_points(plot_params['region'], mult=2)
    dist = point_distance(lon_s4new, lat_s4new)

    # loop over models
    index = None
    for index, mmodel in enumerate(plot_params['model_filenames']):
        logger.info("Plot  %s data for %s, region %s", plot_params['variable'],
                    mmodel, plot_params['region'])
        # construct file names and get the data
        ifilename = genfilename(cfg['work_dir'], plot_params['variable'],
                                mmodel, plot_params['region'], 'transect',
                                '.npy')
        ifilename_depth = genfilename(cfg['work_dir'], 'depth', mmodel,
                                      plot_params['region'],
                                      'transect_' + plot_params['variable'],
                                      '.npy')
        ifilename_dist = genfilename(cfg['work_dir'], 'distance', mmodel,
                                     plot_params['region'],
                                     'transect_' + plot_params['variable'],
                                     '.npy')

        data = np.load(ifilename, allow_pickle=True)
        data = np.ma.masked_equal(data.T, 0)
        lev = np.load(ifilename_depth, allow_pickle=True)
        dist = np.load(ifilename_dist, allow_pickle=True)
        # get labeles and convert the data
        cb_label, data = label_and_conversion(plot_params['variable'], data)
        # index of the maximum depth
        lev_limit = lev[lev <= cfg['transects_depth']].shape[0] + 1

        image = axis[index].contourf(dist,
                                     lev[:lev_limit],
                                     data[:lev_limit, :],
                                     levels=plot_params['levels'],
                                     extend='both',
                                     cmap=plot_params['cmap'])
        # plot settings
        axis[index].set_ylabel('Depth, m', size=15, rotation='vertical')
        axis[index].set_xlabel('Along-track distance, km',
                               size=15,
                               rotation='horizontal')
        axis[index].set_title(mmodel, size=20)
        axis[index].set_ylim(cfg['transects_depth'], 0)
        # ax[ind].invert_yaxis()
        axis[index].tick_params(axis='both', labelsize=15)
        # color bar settings
        colorbar = figure.colorbar(image, ax=axis[index], pad=0.01)
        colorbar.set_label(cb_label, rotation='vertical', size=15)
        colorbar.ax.tick_params(labelsize=15)
    # fig.set_constrained_layout_pads(w_pad=2./30., h_pad=2./30.,
    #     hspace=10, wspace=10)
    for delind in range(index + 1, len(axis)):
        figure.delaxes(axis[delind])

    pltoutname = genfilename(cfg['plot_dir'],
                             plot_params['variable'],
                             region=plot_params['region'],
                             data_type='transect')

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

    provenance_record = get_provenance_record(plot_params, 'transect', 'png')
    with ProvenanceLogger(cfg) as provenance_logger:
        provenance_logger.log(pltoutname + '.png', provenance_record)
예제 #7
0
def transect_map(cfg,
                 region,
                 projection=ccrs.NorthPolarStereo(),
                 bbox=(-180, 180, 60, 90),
                 mult=2):
    """Plot the map with points of the transect overlayed.

    Parameters
    ----------
    region: str
        name of the region predefined in `transect_points` function.
    diagplotdir: str
        path to the plot directory
    projection: instance of cartopy ccrs
        cartopy progection
    bbox: list
        four values - [left, right, bottom, top]
    mult: int
        miltiplicator for the number of points.
        E.g. mult=2 increase the number of points 2 times.

    Returns
    -------
    None

    """
    logger.info("Create transect map for region %s", region)
    lon_s4new, lat_s4new = transect_points(region, mult=mult)
    dist = point_distance(lon_s4new, lat_s4new)
    figure, axis = plt.subplots(1,
                                1,
                                subplot_kw=dict(projection=projection),
                                constrained_layout=True)

    axis.set_extent(bbox, crs=ccrs.PlateCarree())
    image = axis.scatter(lon_s4new,
                         lat_s4new,
                         s=10,
                         c=dist,
                         transform=ccrs.PlateCarree(),
                         cmap=cm.Spectral,
                         edgecolors='none')
    axis.coastlines(resolution="50m")

    colorbar = figure.colorbar(image, ax=axis)
    colorbar.set_label('Along-track distance, km',
                       rotation='vertical',
                       size=15)
    pltoutname = genfilename(cfg['work_dir'],
                             'allvars',
                             region=region,
                             data_type='transect_map')

    plt.savefig(pltoutname, dpi=100)

    plot_params = {}
    plot_params['basedir'] = cfg['plot_dir']
    plot_params['ori_file'] = None
    plot_params['areacello'] = None
    plot_params['mmodel'] = None
    plot_params['region'] = region

    provenance_record = get_provenance_record(plot_params, 'transect_map',
                                              'png')
    with ProvenanceLogger(cfg) as provenance_logger:
        provenance_logger.log(pltoutname + '.png', provenance_record)
예제 #8
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)
예제 #9
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)
예제 #10
0
def plot_profile(cfg, plot_params):
    """Plot profiles.

    From previously calculated data for Hovmoeller diagrams.

    Parameters
    ----------
    model_filenames: OrderedDict
        OrderedDict with model names as keys and input files as values.
    cmor_var: str
        name of the CMOR variable
    region: str
        name of the region predefined in `hofm_regions` function.
    diagworkdir: str
        path to work directory.
    diagplotdir: str
        path to plotting directory.
    cmap: matplotlib.cmap object
        color map
    dpi: int
        dpi fro the output figure
    observations: str
        name of the dataset with observations

    Returns
    -------
    None
    """
    level_clim = Dataset(plot_params['model_filenames'][
        plot_params['observations']]).variables['lev'][:]
    plt.figure(figsize=(5, 6))
    axis = plt.subplot(111)

    color = iter(plot_params['cmap'](np.linspace(
        0, 1, len(plot_params['model_filenames']))))
    lev_limit_clim = level_clim[level_clim <= cfg['hofm_depth']].shape[0] + 1

    mean_profile = np.zeros((level_clim[:lev_limit_clim].shape[0],
                             len(plot_params['model_filenames']) - 1))
    mean_profile_counter = 0

    for mmodel in plot_params['model_filenames']:
        logger.info("Plot profile %s data for %s, region %s",
                    plot_params['variable'], mmodel, plot_params['region'])
        # construct input filenames
        ifilename = genfilename(cfg['work_dir'], plot_params['variable'],
                                mmodel, plot_params['region'], 'hofm', '.npy')
        ifilename_levels = genfilename(cfg['work_dir'],
                                       plot_params['variable'], mmodel,
                                       plot_params['region'], 'levels', '.npy')
        # load data
        hofdata = np.load(ifilename, allow_pickle=True)
        lev = np.load(ifilename_levels, allow_pickle=True)

        # convert data if needed and set labeles
        cb_label, hofdata = label_and_conversion(plot_params['variable'],
                                                 hofdata)

        # set index for maximum level (max_level+1)
        lev_limit = lev[lev <= cfg['hofm_depth']].shape[0] + 1

        # calculate mean profile
        profile = (hofdata)[:, :].mean(axis=1)

        if mmodel != plot_params['observations']:
            next_color = next(color)
        else:
            next_color = 'k'

        plt.plot(profile, lev[0:lev_limit], label=mmodel, c=next_color)

        # interpolate to standard levels and add to mean profile
        profile_interpolated = np.interp(level_clim[:lev_limit_clim],
                                         lev[0:lev_limit], profile)
        if mmodel != plot_params['observations']:

            print('include {} in to the mean'.format(mmodel))
            mean_profile[:, mean_profile_counter] = profile_interpolated
            mean_profile_counter += 1

    # Here we are ploting the mean profile separately
    mean_profile_mean = np.nanmean(mean_profile, axis=1)

    plt.plot(mean_profile_mean,
             level_clim[:lev_limit_clim],
             label='MODEL-MEAN',
             linestyle='--',
             color='k',
             lw=3)

    plt.xticks(size=12)
    plt.yticks(size=12)

    plt.xlabel(cb_label, size=12, rotation='horizontal')
    plt.ylabel('m', size=12, rotation='horizontal')

    plt.ylim(0, cfg['hofm_depth'])

    # we shift the legend and plot it
    box = axis.get_position()
    axis.set_position([box.x0, box.y0, box.width * 0.8, box.height])
    axis.legend(loc='center left', bbox_to_anchor=(1, 0.5), fontsize=10)

    plt.gca().invert_yaxis()

    plot_params['basedir'] = cfg['plot_dir']
    plot_params['ori_file'] = [ifilename]
    plot_params['areacello'] = None
    plot_params['mmodel'] = None

    pltoutname = genfilename(cfg['plot_dir'], plot_params['variable'],
                             'MULTIMODEL', plot_params['region'], 'profile')

    plt.savefig(pltoutname, dpi=plot_params['dpi'], bbox_inches='tight')
    provenance_record = get_provenance_record(plot_params, 'profile', 'png')
    with ProvenanceLogger(cfg) as provenance_logger:
        provenance_logger.log(pltoutname + '.png', provenance_record)
예제 #11
0
def tsplot_plot(cfg, plot_params):
    """Plot a TS diagram.

    Parameters
    ----------
    model_filenames: OrderedDict
        OrderedDict with model names as keys and input files as values.
    max_level: float
        maximum depth level the TS plot shoud go.
    region: str
        name of the region predefined in `hofm_regions` function.
    diagworkdir: str
        path to work directory.
    diagplotdir: str
        path to plotting directory.
    ncols: str
        number of columns in the resulting plot
        (raws will be calculated from total number of plots)
    cmap: matplotlib.cmap object
        color map
    observations: str
        name of the dataset with observations

    Returns
    -------
    None
    """
    # Setup a figure
    nplots = len(plot_params['model_filenames'])
    ncols = float(plot_params['ncols'])
    nrows = math.ceil(nplots / ncols)
    ncols = int(ncols)
    nrows = int(nrows)
    nplot = 1
    plt.figure(figsize=(8 * ncols, 2 * nrows * ncols))

    # loop over models
    for mmodel in plot_params['model_filenames']:
        logger.info("Plot  tsplot data for %s, region %s", mmodel,
                    plot_params['region'])
        # load mean data created by `tsplot_data`
        ifilename_t = genfilename(cfg['work_dir'], 'thetao', mmodel,
                                  plot_params['region'], 'tsplot', '.npy')
        ifilename_s = genfilename(cfg['work_dir'], 'so', mmodel,
                                  plot_params['region'], 'tsplot', '.npy')
        ifilename_depth = genfilename(cfg['work_dir'], 'depth', mmodel,
                                      plot_params['region'], 'tsplot', '.npy')

        temp = np.load(ifilename_t, allow_pickle=True)
        salt = np.load(ifilename_s, allow_pickle=True)
        depth = np.load(ifilename_depth, allow_pickle=True)
        # Still old fashioned way to setup a plot, works best for now.
        plt.subplot(nrows, ncols, nplot)
        # calculate background with density isolines
        si2, ti2, dens = dens_back(33, 36., -2, 6)

        # convert form Kelvin if needed
        if temp.min() > 100:
            temp = temp - 273.15

        # plot the background
        contour_plot = plt.contour(si2,
                                   ti2,
                                   dens,
                                   colors='k',
                                   levels=np.linspace(dens.min(), dens.max(),
                                                      15),
                                   alpha=0.3)
        # plot the scatter plot
        plt.scatter(salt[::],
                    temp[::],
                    c=depth,
                    s=3.0,
                    cmap=plot_params['cmap'],
                    edgecolors='none',
                    vmax=cfg['tsdiag_depth'])
        # adjust the plot
        plt.clabel(contour_plot, fontsize=12, inline=1, fmt='%1.1f')
        plt.xlim(33, 36.)
        plt.ylim(-2.1, 6)
        plt.xlabel('Salinity', size=20)
        plt.ylabel(r'Temperature, $^{\circ}$C', size=20)
        plt.xticks(size=15)
        plt.yticks(size=15)
        # setup the colorbar
        colorbar = plt.colorbar(pad=0.03)
        colorbar.ax.get_yaxis().labelpad = 15
        colorbar.set_label('depth, m', rotation=270, size=20)
        colorbar.ax.tick_params(labelsize=15)

        plt.title(mmodel, size=20)
        nplot = nplot + 1

    plt.tight_layout()
    # save the plot
    pltoutname = genfilename(cfg['plot_dir'],
                             'tsplot',
                             region=plot_params['region'],
                             data_type='tsplot')
    plt.savefig(pltoutname, dpi=100)
    plot_params['basedir'] = cfg['plot_dir']
    plot_params['ori_file'] = [ifilename_t]
    plot_params['areacello'] = None
    plot_params['mmodel'] = None

    provenance_record = get_provenance_record(plot_params, 'tsplot', 'png')
    with ProvenanceLogger(cfg) as provenance_logger:
        provenance_logger.log(pltoutname + '.png', provenance_record)
예제 #12
0
def hofm_plot(cfg, plot_params):
    """Plot Hovmoeller diagram from data at diagworkdir.

    Parameters
    ----------
    model_filenames: OrderedDict
        OrderedDict with model names as keys and input files as values.
    cmor_var: str
        name of the CMOR variable
    max_level: float
        maximum depth level the Hovmoeller diagrams should go to.
    region: str
        name of the region predefined in `hofm_regions` function.
    diagworkdir: str
        path to work directory.
    diagplotdir: str
        path to plotting directory.
    levels: list
        levels for the contour plot.
    ncols: str
        number of columns in the resulting plot
        (raws will be calculated from total number of plots)
    cmap: matplotlib.cmap object
        color map
    observations: str
        name of the dataset with observations

    Returns
    -------
    None
    """

    # create a basis for the muli panel figure
    figure, axis = create_plot(plot_params['model_filenames'],
                               ncols=plot_params['ncols'])

    # plot data on the figure, axis by axis
    index = None
    for index, mmodel in enumerate(plot_params['model_filenames']):
        logger.info("Plot  %s data for %s, region %s", plot_params['variable'],
                    mmodel, plot_params['region'])
        # generate input filenames that
        # the data prepared by `hofm_data` function

        ifilename = genfilename(cfg['work_dir'], plot_params['variable'],
                                mmodel, plot_params['region'], 'hofm', '.npy')
        ifilename_levels = genfilename(cfg['work_dir'],
                                       plot_params['variable'], mmodel,
                                       plot_params['region'], 'levels', '.npy')
        ifilename_time = genfilename(cfg['work_dir'], plot_params['variable'],
                                     mmodel, plot_params['region'], 'time',
                                     '.npy')
        # load the data
        hofdata = np.load(ifilename, allow_pickle=True)
        lev = np.load(ifilename_levels, allow_pickle=True)
        time = np.load(ifilename_time, allow_pickle=True)

        # convert data if needed and get labeles for colorbars
        cb_label, hofdata = label_and_conversion(plot_params['variable'],
                                                 hofdata)

        # find index of the model level closes to the `max_level`
        # and add 1, to make a plot look better
        lev_limit = lev[lev <= cfg['hofm_depth']].shape[0] + 1

        # get the length of the time series
        series_lenght = time.shape[0]

        # create 2d arrays with coordinates of time and depths
        months, depth = np.meshgrid(range(series_lenght), lev[0:lev_limit])

        # plot an image for the model on the axis (ax[ind])
        image = axis[index].contourf(months,
                                     depth,
                                     hofdata,
                                     cmap=plot_params['cmap'],
                                     levels=plot_params['levels'],
                                     extend='both')
        # Generate tick marks with years that looks ok
        year_indexes, year_value = year_ticks(series_lenght, time)

        # set properties of the axis
        axis[index].set_xticks(year_indexes)
        axis[index].set_xticklabels(year_value, size=15)
        axis[index].set_title(mmodel, size=20)
        axis[index].set_ylabel('m', size=15, rotation='horizontal')
        axis[index].invert_yaxis()
        axis[index].tick_params(axis='y', labelsize=15)

        # Add a colorbar
        colorbar = figure.colorbar(image, ax=axis[index], pad=0.01)
        colorbar.set_label(cb_label, rotation='vertical', size=15)
        colorbar.ax.tick_params(labelsize=15)

    # delete unused axis
    for delind in range(index + 1, len(axis)):
        figure.delaxes(axis[delind])
    # tighten the layout
    plt.tight_layout()
    # generate the path to the output file
    plot_params['basedir'] = cfg['plot_dir']
    plot_params['ori_file'] = [ifilename]
    plot_params['areacello'] = None
    plot_params['mmodel'] = None

    pltoutname = genfilename(**plot_params, data_type='hofm')

    plt.savefig(pltoutname, dpi=100)
    provenance_record = get_provenance_record(plot_params, 'hofm', 'png')
    with ProvenanceLogger(cfg) as provenance_logger:
        provenance_logger.log(pltoutname + '.png', provenance_record)
def tsplot_data(cfg, mmodel, region, observations='PHC'):
    """Extract data for TS plots from one specific model.

    Parameters
    ----------

    mmodel: str
        model name
    max_level: int
        maximum level (depth) of TS data to be used
    region: str
        region as defined in `hofm_regions`
    observations: str
        name of the observations

    Returns
    -------
    None
    """
    logger.info("Extract  TS data for %s, region %s", mmodel, region)

    # generate input names for T and S. The files are generated by the
    # `timmean` function.
    ifilename_t = genfilename(cfg['work_dir'],
                              'thetao',
                              mmodel,
                              data_type='timmean',
                              extension='.nc')
    ifilename_s = genfilename(cfg['work_dir'],
                              'so',
                              mmodel,
                              data_type='timmean',
                              extension='.nc')
    # get the metadata for T and S

    metadata_t = load_meta(datapath=ifilename_t, fxpath=None)
    metadata_s = load_meta(datapath=ifilename_s, fxpath=None)

    # find index of the max_level
    lev_limit = metadata_t['lev'][
        metadata_t['lev'] <= cfg['tsdiag_depth']].shape[0] + 1
    # find indexes of data that are in the region
    indexes = hofm_regions(region, metadata_t['lon2d'], metadata_t['lat2d'])

    temp = np.array([])
    salt = np.array([])
    depth_model = np.array([])
    # loop over depths
    for ind, depth in enumerate(metadata_t['lev'][0:lev_limit]):
        level_pp, level_pp_s = tsplot_extract_data(mmodel, observations,
                                                   metadata_t, metadata_s, ind)
        # select individual points for T, S and depth
        temp = np.hstack((temp, level_pp[indexes[0], indexes[1]].compressed()))
        salt = np.hstack((salt, level_pp_s[indexes[0],
                                           indexes[1]].compressed()))
        depth_temp = np.zeros_like(level_pp[indexes[0],
                                            indexes[1]].compressed())
        depth_temp[:] = depth
        depth_model = np.hstack((depth_model, depth_temp))

    # Saves the data to individual files
    data_info = {}
    data_info['basedir'] = cfg['work_dir']
    data_info['mmodel'] = mmodel
    data_info['region'] = region
    data_info['levels'] = metadata_t['lev']
    data_info['ori_file'] = [ifilename_t, ifilename_s]
    data_info['areacello'] = None
    tsplot_save_data(cfg, data_info, temp, salt, depth_model)

    metadata_t['datafile'].close()
    metadata_s['datafile'].close()
def transect_data(cfg, mmodel, cmor_var, region, mult=2):
    """Extract data for transects (defined in regions.transect_points).

    Parameters
    ----------
    mmodel: str
        model name that will be processed.
    cmor_var: str
        name of the CMOR variable
    region: str
        name of the region predefined in `transect_points` function.
    diagworkdir: str
        path to work directory.
    mult: integer
        multiplicator for the number of points in the transect.
        Can be used to increase transect resolution.
    observations: str
        name of the observation dataset.
    """
    logger.info("Extract  %s transect data for %s, region %s", cmor_var,
                mmodel, region)
    # get the path to preprocessed file
    ifilename = genfilename(cfg['work_dir'],
                            cmor_var,
                            mmodel,
                            data_type='timmean',
                            extension='.nc')
    # open with netCDF4
    datafile = Dataset(ifilename)
    # open with ESMF
    grid = ESMF.Grid(filename=ifilename, filetype=ESMF.FileFormat.GRIDSPEC)

    # get depth of the levels
    lev = datafile.variables['lev'][:]

    # indexesi, indexesj = hofm_regions(region, lon2d, lat2d)
    lon_s4new, lat_s4new = transect_points(region, mult=mult)

    # masking true
    # domask = True

    # create instans of the location stream (set of points)
    locstream = ESMF.LocStream(lon_s4new.shape[0],
                               name="Atlantic Inflow Section",
                               coord_sys=ESMF.CoordSys.SPH_DEG)

    # appoint the section locations
    locstream["ESMF:Lon"] = lon_s4new
    locstream["ESMF:Lat"] = lat_s4new
    # if domask:
    locstream["ESMF:Mask"] = np.array(np.ones(lon_s4new.shape[0]),
                                      dtype=np.int32)
    # initialise array for the section
    secfield = np.zeros(
        (lon_s4new.shape[0], datafile.variables[cmor_var].shape[1]))

    # loop over depth levels
    for level in range(0, datafile.variables[cmor_var].shape[1]):
        secfield[:, level] = transect_level(datafile, cmor_var, level, grid,
                                            locstream).data
    data_info = {}
    data_info['basedir'] = cfg['work_dir']
    data_info['variable'] = cmor_var
    data_info['mmodel'] = mmodel
    data_info['region'] = region
    data_info['levels'] = lev
    data_info['ori_file'] = ifilename
    data_info['areacello'] = None

    transect_save_data(cfg, data_info, secfield, lon_s4new, lat_s4new)

    datafile.close()