def main(cfg):
    """
    Load the config file and some metadata, then pass them the plot making
    tools.

    Parameters
    ----------
    cfg: dict
        the opened global config dictionairy, passed by ESMValTool.

    """
    #####
    for index, metadata_filename in enumerate(cfg['input_files']):
        logger.info(
            'metadata filename:\t%s',
            metadata_filename,
        )

        metadatas = diagtools.get_input_files(cfg, index=index)

        thresholds = diagtools.load_thresholds(cfg,
                                               next(iter(metadatas.values())))

        #######
        # Multi model contour plots
        if thresholds:
            multi_model_contours(
                cfg,
                metadatas,
            )

        for filename in sorted(metadatas):

            logger.info('-----------------')
            logger.info(
                'model filenames:\t%s',
                filename,
            )

            ######
            # Time series of individual model
            make_transects_plots(cfg, metadatas[filename], filename)

            ######
            # Contour maps of individual model
            if thresholds:
                make_transect_contours(cfg, metadatas[filename], filename)

    logger.info('Success')
def main(cfg):
    """
    Load the config file, and send it to the plot makers.

    Parameters
    ----------
    cfg: dict
        the opened global config dictionary, passed by ESMValTool.

    """
    cartopy.config['data_dir'] = cfg['auxiliary_data_dir']

    for index, metadata_filename in enumerate(cfg['input_files']):
        logger.info(
            'metadata filename:\t%s',
            metadata_filename,
        )

        metadatas = diagtools.get_input_files(cfg, index=index)
        thresholds = diagtools.load_thresholds(cfg, metadatas)

        if thresholds:
            #######
            # Multi model contour plots
            multi_model_contours(
                cfg,
                metadatas,
            )

        for filename in sorted(metadatas.keys()):

            logger.info('-----------------')
            logger.info(
                'model filenames:\t%s',
                filename,
            )

            ######
            # Contour maps of individual model
            if thresholds:
                make_map_contour(cfg, metadatas[filename], filename)

            ######
            # Maps of individual model
            make_map_plots(cfg, metadatas[filename], filename)

    logger.info('Success')
def multi_model_contours(
    cfg,
    metadatas,
):
    """
    Make a multi model comparison plot showing several transect contour plots.

    This tool loads several cubes from the files, checks that the units are
    sensible BGC units, checks for layers, adjusts the titles accordingly,
    determines the ultimate file name and format, then saves the image.

    Parameters
    ----------
    cfg: dict
        the opened global config dictionairy, passed by ESMValTool.
    metadatas: dict
        The metadatas dictionairy for a specific model.

    """
    ####
    # Load the data for each layer as a separate cube
    model_cubes = {}
    regions = {}
    thresholds = {}
    set_y_logscale = True

    for filename in sorted(metadatas):
        cube = iris.load_cube(filename)
        cube = diagtools.bgc_units(cube, metadatas[filename]['short_name'])
        cube = make_depth_safe(cube)
        cubes = make_cube_region_dict(cube)
        model_cubes[filename] = cubes
        for region in model_cubes[filename]:
            regions[region] = True

        # Determine y log scale.
        set_y_logscale = determine_set_y_logscale(cfg, metadatas[filename])

        # Load threshold/thresholds.
        tmp_thresholds = diagtools.load_thresholds(cfg, metadatas[filename])
        for threshold in tmp_thresholds:
            thresholds[threshold] = True

    # Load image format extention
    image_extention = diagtools.get_image_format(cfg)

    # Make a plot for each layer and each threshold
    for region, threshold in itertools.product(regions, thresholds):
        logger.info('plotting threshold: \t%s', threshold)
        title = ''
        plot_details = {}

        # Plot each file in the group
        for index, filename in enumerate(sorted(metadatas)):
            color = diagtools.get_colour_from_cmap(index, len(metadatas))
            linewidth = 1.
            linestyle = '-'
            # Determine line style for MultiModel statistics:
            if 'MultiModel' in metadatas[filename]['dataset']:
                linewidth = 2.
                linestyle = ':'
            # Determine line style for Observations
            if metadatas[filename]['project'] in diagtools.get_obs_projects():
                color = 'black'
                linewidth = 1.7
                linestyle = '-'

            qplt.contour(model_cubes[filename][region], [
                threshold,
            ],
                         colors=[
                             color,
                         ],
                         linewidths=linewidth,
                         linestyles=linestyle,
                         rasterized=True)

            plot_details[filename] = {
                'c': color,
                'ls': linestyle,
                'lw': linewidth,
                'label': metadatas[filename]['dataset']
            }

            if set_y_logscale:
                plt.axes().set_yscale('log')

            title = metadatas[filename]['long_name']
            units = str(model_cubes[filename][region].units)

            add_sea_floor(model_cubes[filename][region])

        # Add title, threshold, legend to plots
        title = ' '.join([
            title,
            str(threshold), units,
            determine_transect_str(model_cubes[filename][region], region)
        ])
        titlify(title)
        plt.legend(loc='best')

        # Saving files:
        if cfg['write_plots']:
            path = diagtools.get_image_path(
                cfg,
                metadatas[filename],
                prefix='MultipleModels',
                suffix='_'.join([
                    'contour_tramsect', region,
                    str(threshold) + image_extention
                ]),
                metadata_id_list=[
                    'field', 'short_name', 'preprocessor', 'diagnostic',
                    'start_year', 'end_year'
                ],
            )

        # Resize and add legend outside thew axes.
        plt.gcf().set_size_inches(9., 6.)
        diagtools.add_legend_outside_right(plot_details,
                                           plt.gca(),
                                           column_width=0.15)

        logger.info('Saving plots to %s', path)
        plt.savefig(path)
        plt.close()
def make_transect_contours(
    cfg,
    metadata,
    filename,
):
    """
    Make a contour plot of the transect for an indivudual model.

    This tool loads the cube from the file, checks that the units are
    sensible BGC units, checks for layers, adjusts the titles accordingly,
    determines the ultimate file name and format, then saves the image.

    Parameters
    ----------
    cfg: dict
        the opened global config dictionairy, passed by ESMValTool.
    metadata: dict
        The metadata dictionairy for a specific model.
    filename: str
        The preprocessed model file.

    """
    # Load cube and set up units
    cube = iris.load_cube(filename)
    cube = diagtools.bgc_units(cube, metadata['short_name'])
    cube = make_depth_safe(cube)

    # Load threshold/thresholds.
    plot_details = {}
    colours = []
    thresholds = diagtools.load_thresholds(cfg, metadata)
    linewidths = [1 for thres in thresholds]
    linestyles = ['-' for thres in thresholds]

    cubes = make_cube_region_dict(cube)
    for region, cube in cubes.items():
        for itr, thres in enumerate(thresholds):
            colour = diagtools.get_colour_from_cmap(itr, len(thresholds))
            label = str(thres) + ' ' + str(cube.units)
            colours.append(colour)
            plot_details[thres] = {
                'c': colour,
                'lw': 1,
                'ls': '-',
                'label': label
            }

        qplt.contour(cube,
                     thresholds,
                     colors=colours,
                     linewidths=linewidths,
                     linestyles=linestyles,
                     rasterized=True)

        # Determine y log scale.
        if determine_set_y_logscale(cfg, metadata):
            plt.axes().set_yscale('log')

        add_sea_floor(cube)

        # Add legend
        diagtools.add_legend_outside_right(plot_details,
                                           plt.gca(),
                                           column_width=0.08,
                                           loc='below')

        # Add title to plot
        title = ' '.join([
            metadata['dataset'], metadata['long_name'],
            determine_transect_str(cube, region)
        ])
        titlify(title)

        # Load image format extention
        image_extention = diagtools.get_image_format(cfg)

        # Determine image filename:
        if metadata['dataset'].find('MultiModel') > -1:
            path = diagtools.folder(
                cfg['plot_dir']) + os.path.basename(filename)
            path.replace('.nc', region + '_transect_contour' + image_extention)
        else:
            path = diagtools.get_image_path(
                cfg,
                metadata,
                suffix=region + 'transect_contour' + image_extention,
            )

        # Saving files:
        if cfg['write_plots']:
            logger.info('Saving plots to %s', path)
            plt.savefig(path)

        plt.close()
def multi_model_contours(
    cfg,
    metadata,
):
    """
    Make a contour map showing several models.

    Parameters
    ----------
    cfg: dict
        the opened global config dictionary, passed by ESMValTool.
    metadata: dict
        the metadata dictionary.

    """
    ####
    # Load the data for each layer as a separate cube
    model_cubes = {}
    layers = {}
    for filename in sorted(metadata):
        cube = iris.load_cube(filename)
        cube = diagtools.bgc_units(cube, metadata[filename]['short_name'])

        cubes = diagtools.make_cube_layer_dict(cube)
        model_cubes[filename] = cubes
        for layer in cubes:
            layers[layer] = True

    # Load image format extention
    image_extention = diagtools.get_image_format(cfg)

    # Load threshold/thresholds.
    thresholds = diagtools.load_thresholds(cfg, metadata)

    # Make a plot for each layer and each threshold
    for layer, threshold in itertools.product(layers, thresholds):

        title = ''
        z_units = ''
        plot_details = {}
        cmap = plt.cm.get_cmap('jet')
        land_drawn = False

        # Plot each file in the group
        for index, filename in enumerate(sorted(metadata)):

            if len(metadata) > 1:
                color = cmap(index / (len(metadata) - 1.))
            else:
                color = 'blue'
            linewidth = 1.
            linestyle = '-'

            # Determine line style for Observations
            if metadata[filename]['project'] in diagtools.get_obs_projects():
                color = 'black'
                linewidth = 1.7
                linestyle = '-'

            # Determine line style for MultiModel statistics:
            if 'MultiModel' in metadata[filename]['dataset']:
                color = 'black'
                linestyle = ':'
                linewidth = 1.4

            cube = model_cubes[filename][layer]
            qplt.contour(cube, [
                threshold,
            ],
                         colors=[
                             color,
                         ],
                         linewidths=linewidth,
                         linestyles=linestyle,
                         rasterized=True)
            plot_details[filename] = {
                'c': color,
                'ls': linestyle,
                'lw': linewidth,
                'label': metadata[filename]['dataset']
            }

            if not land_drawn:
                try:
                    plt.gca().coastlines()
                except AttributeError:
                    logger.warning('Not able to add coastlines')
                plt.gca().add_feature(cartopy.feature.LAND,
                                      zorder=10,
                                      facecolor=[0.8, 0.8, 0.8])
                land_drawn = True

            title = metadata[filename]['long_name']
            if layer != '':
                z_units = model_cubes[filename][layer].coords('depth')[0].units
            units = str(model_cubes[filename][layer].units)

        # Add title, threshold, legend to plots
        title = ' '.join([title, str(threshold), units])
        if layer:
            title = ' '.join([title, '(', str(layer), str(z_units), ')'])
        plt.title(title)
        plt.legend(loc='best')

        # Saving files:
        if cfg['write_plots']:
            path = diagtools.get_image_path(
                cfg,
                metadata[filename],
                prefix='MultipleModels_',
                suffix='_'.join([
                    '_contour_map_',
                    str(threshold),
                    str(layer) + image_extention
                ]),
                metadata_id_list=[
                    'field', 'short_name', 'preprocessor', 'diagnostic',
                    'start_year', 'end_year'
                ],
            )

        # Resize and add legend outside thew axes.
        plt.gcf().set_size_inches(9., 6.)
        diagtools.add_legend_outside_right(plot_details,
                                           plt.gca(),
                                           column_width=0.15)

        logger.info('Saving plots to %s', path)
        plt.savefig(path)
        plt.close()
def make_map_contour(
    cfg,
    metadata,
    filename,
):
    """
    Make a simple contour map plot for an individual model.

    Parameters
    ----------
    cfg: dict
        the opened global config dictionary, passed by ESMValTool.
    metadata: dict
        the metadata dictionary
    filename: str
        the preprocessed model file.

    """
    # Load cube and set up units
    cube = iris.load_cube(filename)
    cube = diagtools.bgc_units(cube, metadata['short_name'])

    # Is this data is a multi-model dataset?
    multi_model = metadata['dataset'].find('MultiModel') > -1

    # Make a dict of cubes for each layer.
    cubes = diagtools.make_cube_layer_dict(cube)

    # Load image format extention and threshold.thresholds.
    image_extention = diagtools.get_image_format(cfg)

    # Load threshold/thresholds.
    plot_details = {}
    colours = []
    thresholds = diagtools.load_thresholds(cfg, metadata)

    for itr, thres in enumerate(thresholds):
        if len(thresholds) > 1:
            colour = plt.cm.jet(float(itr) / float(len(thresholds) - 1.))
        else:
            colour = plt.cm.jet(0)
        label = str(thres) + ' ' + str(cube.units)
        colours.append(colour)
        plot_details[thres] = {'c': colour, 'lw': 1, 'ls': '-', 'label': label}

    linewidths = [1 for thres in thresholds]
    linestyles = ['-' for thres in thresholds]
    # Making plots for each layer
    for layer_index, (layer, cube_layer) in enumerate(cubes.items()):
        layer = str(layer)
        qplt.contour(cube_layer,
                     thresholds,
                     colors=colours,
                     linewidths=linewidths,
                     linestyles=linestyles,
                     rasterized=True)

        try:
            plt.gca().coastlines()
        except AttributeError:
            logger.warning('Not able to add coastlines')
        try:
            plt.gca().add_feature(cartopy.feature.LAND,
                                  zorder=10,
                                  facecolor=[0.8, 0.8, 0.8])
        except AttributeError:
            logger.warning('Not able to add coastlines')
        # Add legend
        diagtools.add_legend_outside_right(plot_details,
                                           plt.gca(),
                                           column_width=0.02,
                                           loc='below')

        # Add title to plot
        title = ' '.join([metadata['dataset'], metadata['long_name']])
        depth_units = str(cube_layer.coords('depth')[0].units)
        if layer:
            title = '{} ({} {})'.format(title, layer, depth_units)
        plt.title(title)

        # Determine image filename:
        if multi_model:
            path = os.path.join(diagtools.folder(cfg['plot_dir']),
                                os.path.basename(filename))
            path = path.replace('.nc', '_contour_map_' + str(layer_index))
            path = path + image_extention
        else:
            path = diagtools.get_image_path(
                cfg,
                metadata,
                suffix='_contour_map_' + str(layer_index) + image_extention,
            )

        # Saving files:
        if cfg['write_plots']:
            logger.info('Saving plots to %s', path)
            plt.savefig(path)

        plt.close()