ImageMetaTag.ImageDict

This submodule contains the ImageMetaTag.ImageDict class, and functions for preparing instances of it.

The purpose of an ImageMetaTag.ImageDict is to sort the image metadata, supplied to ImageMetaTag.savefig() and usually stored in a database file, into a useful form that can quickly and easily be presented as a webpage by ImageMetaTag.webpage.write_full_page().

An easy example of creating a webpage, using an ImageDict is shown in simplest_image_dict.py

(C) Crown copyright Met Office. All rights reserved. Released under BSD 3-Clause License. See LICENSE for more details.

The ImageDict Class

class ImageMetaTag.ImageDict(input_dict, level_names=None, selector_widths=None, selector_animated=None, animation_direction=None)[source]

A class which holds a heirachical dictionary of dictionaries, and the associated methods for appending/removing dictionaries from it.

The expected use case for the dictionary is to represent a large set of images, which can be organised by their metadata tags.

When used in this way, the ImageDict module contains functions to produce web pages for browsing the images.

The input_dict should be a heirachical dictionary of dictionaries, containing the image metadata, in the required order. In order to convert a flat dictionary of metadata items, use ImageMetaTag.dict_heirachy_from_list()

Options:
  • level_names - a list of the tagnames, in full, giving a name/description of what the metadata item means. Ordered by level of the input dict.

  • selector_widths - a list of html strings giving the widths of each selector in the output webpage. CURRENTLY UNUSED!

  • selector_animated - integer giving the index of the selector on the output webpage is to be animated.

  • animation_dicrection - +1 indicates the animation moves forwards, -1 indicates it moves backwards.

Objects:
  • dict - the heirachical dictionary of dictionaries containing the image structure.

  • keys - a list of keys for each level of the dict, within a dictionary using the level number as the keys.

  • level_names - this stores the full names of the items in keys.

  • selector_animated - the level index which will be animated on the output webpage.

  • animation_direction - the direction of animation.

  • selector_widths - a list of desired widths on the output web page (CURRENTLY UNUSED).

append(new_dict, devmode=False, skip_key_relist=False)[source]

appends a new dictionary (with a single element in each layer!) into a current ImageDict.

The skip_key_relist option can be set to True to stop the regeneration of key lists to speed up multiple appends.

copy_except_dict_and_keys()[source]

returns a copy of an ImageDict except it will have null values for the dict and keys

dict_depth(uniform_depth=False)[source]

Uses dict_depths to get the depth of all branches of the plot_dict and, if required, checks they all equal the max.

dict_depths(in_dict, depth=0)[source]

Recursively finds the depth of a ImageDict, returns a list of lists

dict_index_array(devmode=False, maxdepth=None, verbose=False)[source]

Using the list of dictionary keys (at each level of a uniform_depth dictionary of dictionaries), this produces a list of the indices that can be used to reference the keys to get the result for each element.

Options:
  • maxdepth - the maximum desired depth to go to (ie. the number of levels)

dict_print(in_dict, indent=0, outstr='')[source]

recursively details a dictionary of dictionaries, with indentation, to a string

dict_prune(in_dict, dicts_pruned=False)[source]

Prunes the ImageDict of empty, unterminated, branches (which occur after parts have been removed). Returns True if a dict was pruned, False if not.

dict_remove(in_dict, rm_dict)[source]

removes a dictionary of dictionaries from another, larger, one. This can leave empty branches, at multiple levels of the dict, so needs cleaning up afterwards.

dict_union(in_dict, new_dict)[source]

produces the union of a dictionary of dictionaries

flatten_lists(in_list)[source]

Recursively flattens a list of lists:

key_at_depth(in_dict, depth)[source]

returns the keys of a dictionary, at a given depth

keys_by_depth(in_dict, depth=0, keys=None, subdirs=None)[source]

Returns:

  • a dictionary of sets, containing the keys at each level of the dictionary (keyed by the level number).

  • a set of the subdirectories for the target images

list_keys_by_depth(devmode=False)[source]

Lists the keys of the dictionary to create a list of keys, for each level of the dictionary, up to its depth.

It is usually much faster to create an ImageDict by appending images to it, with skip_key_relist=True but this leaves an ImageDict without a list of keys. In this case, list_keys_by_depth needs to be called once at the end of the process to complete the list of keys.

It works by converting the sets, from keys_by_depth to a list (where they can be ordered and indexed). This also produces the unique subdirectory locations of all images.

mergedicts(dict1, dict2)[source]

Alternative version of dict_union using generators which is much faster for large dicts but needs to be converted to a dict when it’s called: new_dict = dict(mergdicts(dict1,dict))

remove(rm_dict, skip_key_relist=False)[source]

removes a dictionary from within an ImageDict. The skip_key_relist option can be set to True to stop the regeneration of key lists.

TIP: Because the remove process needs to prune empty sections afterwards, it can be slow. When working with large dictionaries, and removing a large number of elements from it, is often faster to build up a dictionary of things you want to remove, and then do one remove at the end.

return_from_list(vals_at_depth)[source]

Returns the end values of ImageDict, when given a list of values for the keys at different depths. Returns None if the set of values is not contained in the ImageDict.

Assumes that the ImageDict has its keys up to date, so last time it was appended/removed it was with skip_key_relist=False or list_keys_by_depth() method has been called since.

return_key_inds(in_dict, out_array=None, this_set_of_inds=None, depth=None, level=None, verbose=False, devmode=False)[source]

Does the work for dict_index_array, by recursively adding indices to the keys to a current list, and branching where required, and adding compelted lists to the out_array

sort_keys(sort_methods, devmode=False)[source]

Sorts the keys of a plot dictionary, according to a particular sort method (or a list of sort methods that matches the number of keys).

Valid sort methods so far are mostly focused on meteorological terms, and include:

  • ‘sort’ - just an ordinary sort

  • ‘level’ or ‘numeric’ - starting with the surface and working upwards, then ‘special’ levels like cross sections etc.

  • ‘T+’ - in ascending order of the number after a ‘T+’ (or similar)

  • an input list - Specific elements in the input list are sorted as per their order in the list, while the rest are just sorted.

The methods activated by a string can be reversed as ‘reverse_sort’ or ‘reverse_sort’, or ‘reverse numeric’ or ‘reverse_numeric’.

Functions useful in preparing ImageDicts

ImageMetaTag.readmeta_from_image(img_file, img_format=None, keep_reserved_tags=False)[source]

Reads the metadata added by the ImageMetaTag savefig, from an image file, and returns a dictionary of tag_name: value pairs

By default tag names that cannot be written by ImageMetaTag savefig (e.g. dpi, chromaticity etc) cannot be read by readmeta_from_image.

keep_reserved_tags - keeps reserved tags from the image if True

ImageMetaTag.dict_heirachy_from_list(in_dict, payload, heirachy)[source]

Converts a flat dictionary of tagname: value pairs, into an ordered dictionary of dictionaries according to the input heirachy (which is a list of tagnames).

The output dictionary will only have one element per level, but can be used to create or append into an ImageMetaTag.ImageDict. The final level will be the ‘payload’ input, which is the object the dictionary, with all it’s levels, is describing. The payload would usually be the full/relative path of the image file, or list of image files.

Returns False if the input dict does not contain the required keys.

ImageMetaTag.dict_split(in_dict, n_split=None, size_split=None, extra_opts=None)[source]

Generator that breaks up a flat dictionary and yields a set of sub-dictionaries in n_split chunks, or size_split in size. It is split on it’s first level, not recursively.

It is very useful for splitting large dictionaries of image metadata to parallelise processing these into ImageDicts.

Inputs: in_dict - the dictionary to split

Options:
  • n_split - the number of dictionaries to break the in_dict up into.

  • size_split - the size of the required output dictionaries.

  • extra_opts - If supplied as an iterable, this routine will yield a tuple containing the output sub-dictionary and then each of the elements of extra_opts.

Note

One, and only one, of n_slpit, or size_split must be specified, as an integer.

ImageMetaTag.simple_dict_filter(simple_dict, tests, raise_key_mismatch=False)[source]

Tests the contents of a simple, un-heirachical dict (properties an image) against a set of tests.

An example set of tests:

tests = {'number of rolls': ['6 simulated rolls',
                             '216 simulated rolls',
                             '1296 simulated rolls'],
         'plot color': None,
         'image compression': None,
         'plot type': ['Histogram', ('All', ['Histogram', 'Line plots'])],
         'image trim': None}

Here, the ‘number of rolls’ is restricted to a simple list.

The plot type is filtered according to ‘Histogram’, and there is also a second element that contains both ‘Histogram and ‘Line plots’ which are to be presented together.

The other image characteristics are not filtered.

Options:
  • raise_key_mismatch - if True, then attempting to test a dictionary with a missing key will raise and exception. Default is to return all False.

Returns three logicals:
  • The first indicates whether the input dict passes the simple tests

  • The second indicates whether the input dict is part of the grouped elements of the test (the [‘Histogram’, ‘Line plots’] list).

  • The third indicates whether the input dict is the first element of a list grouped elements (is ‘Histogram’ in this [‘Histogram’, ‘Line plots’] list).

ImageMetaTag.check_for_required_keys(img_info, req_keys)[source]

Checks an img_info dictionary has a set of required keys, specifed as a list of strings

Returns True or False accordingly.