Source code for firelight.config_parsing

from .visualizers.base import BaseVisualizer, ContainerVisualizer
from .utils.io_utils import yaml2dict
from pydoc import locate
import logging
import sys

# List of available visualizers (without container visualizers)
from .visualizers.visualizers import \
    IdentityVisualizer, \
    PcaVisualizer, \
    MaskedPcaVisualizer, \
    TsneVisualizer, \
    UmapVisualizer, \
    SegmentationVisualizer, \
    InputVisualizer, \
    TargetVisualizer, \
    PredictionVisualizer, \
    MSEVisualizer, \
    RGBVisualizer, \
    MaskVisualizer, \
    ThresholdVisualizer, \
    ImageVisualizer, \
    NormVisualizer, \
    DiagonalSplitVisualizer, \
    CrackedEdgeVisualizer, \
    UpsamplingVisualizer

# List of available container visualizers (visualizers acting on outputs of child visualizers)
from .visualizers.container_visualizers import \
    ImageGridVisualizer, \
    RowVisualizer, \
    ColumnVisualizer, \
    OverlayVisualizer, \
    RiffleVisualizer, \
    StackVisualizer


# set up logging
logging.basicConfig(format='[+][%(asctime)-15s][VISUALIZATION]'
                           ' %(message)s',
                    stream=sys.stdout,
                    level=logging.INFO)
parsing_logger = logging.getLogger(__name__)


[docs]def get_single_key_value_pair(d): """ Returns the key and value of a one element dictionary, checking that it actually has only one element Parameters ---------- d : dict Returns ------- tuple """ assert isinstance(d, dict), f'{d}' assert len(d) == 1, f'{d}' return list(d.keys())[0], list(d.values())[0]
[docs]def get_visualizer_class(name): """ Parses the class of a visualizer from a String. If the name is not found in globals(), tries to import it. Parameters ---------- name : str Name of a visualization class imported above, or dotted path to one (e.g. your custom visualizer in a different library). Returns ------- type or None """ if name in globals(): # visualizer is imported above return globals().get(name) else: # dotted path is given visualizer = locate(name) assert visualizer is not None, f'Could not find visualizer "{name}".' assert issubclass(visualizer, BaseVisualizer), f'"{visualizer}" is no visualizer'
[docs]def get_visualizer(config, indentation=0): """ Parses a yaml configuration file to construct a visualizer. Parameters ---------- config : str or dict or BaseVisualizer Either path to yaml configuration file or dictionary (as constructed by loading such a file). If already visualizer, it is just returned. indentation : int, optional How far logging messages arising here should be indented. Returns ------- BaseVisualizer """ if isinstance(config, BaseVisualizer): # nothing to do here return config # parse config to dict (does nothing if already dict) config = yaml2dict(config) # name (or dotted path) and kwargs of visualizer have to be specified as key and value of one element dictionary name, kwargs = get_single_key_value_pair(config) # get the visualizer class from its name visualizer = get_visualizer_class(name) parsing_logger.info(f'Parsing {" "*indentation}{visualizer.__name__}') if issubclass(visualizer, ContainerVisualizer): # container visualizer: parse sub-visualizers first child_visualizer_config = kwargs['visualizers'] assert isinstance(child_visualizer_config, (list, dict)), \ f'{child_visualizer_config}, {type(child_visualizer_config)}' if isinstance(child_visualizer_config, dict): # if dict, convert do list child_visualizer_config = [{key: value} for key, value in child_visualizer_config.items()] child_visualizers = [] for c in child_visualizer_config: v = get_visualizer(c, indentation + 1) assert isinstance(v, BaseVisualizer), f'Could not parse visualizer: {c}' child_visualizers.append(v) kwargs['visualizers'] = child_visualizers # TODO: add example with nested visualizers def parse_if_visualizer(config): if not (isinstance(config, dict) and len(config) == 1): return None # check if the key is the name of a visualizer try: get_visualizer_class(iter(config.items()).__next__()[0]) except AssertionError: return None # parse the visualizer return get_visualizer(config, indentation+1) # check if any input in 'input_mapping' should be parsed as visualizer input_mapping = kwargs.get('input_mapping', {}) for map_to, map_from in input_mapping.items(): nested_visualizer = parse_if_visualizer(map_from) if nested_visualizer is not None: input_mapping[map_to] = nested_visualizer # check if 'input' should be parsed as visualizer if kwargs.get('input') is not None: nested_visualizer = parse_if_visualizer(kwargs.get('input')) if nested_visualizer is not None: kwargs['input'] = nested_visualizer return visualizer(**kwargs)