def Func(arg_0, arg_1):
        """Deletes a single node from the tree.

        Removes all references to the node.

        Note that the 'parameters', 'results', 'derived_parameters', and 'config' groups
        hanging directly below root cannot be deleted. Also the root node itself cannot be
        deleted. (This would cause a tremendous wave of uncontrollable self destruction, which
        would finally lead to the Apocalypse!)

        """
        arg_2 = arg_1.v_full_name
        arg_3 = arg_0._root_instance

        if arg_2 == '':
            # You cannot delete root
            return

        if arg_1.v_is_leaf:
            if arg_2 in arg_3._parameters:
                del arg_3._parameters[arg_2]

            elif arg_2 in arg_3._config:
                del arg_3._config[arg_2]

            elif arg_2 in arg_3._derived_parameters:
                del arg_3._derived_parameters[arg_2]

            elif arg_2 in arg_3._results:
                del arg_3._results[arg_2]

            elif arg_2 in arg_3._other_leaves:
                del arg_3._other_leaves[arg_2]

            if arg_2 in arg_3._explored_parameters:

                if arg_3._stored:
                    # We always keep the explored parameters in case the trajectory was stored
                    arg_3._explored_parameters[arg_2] = None
                else:
                    del arg_3._explored_parameters[arg_2]
                if len(arg_3._explored_parameters) == 0:
                    arg_3.f_shrink()

            del arg_0._flat_leaf_storage_dict[arg_2]
        else:
            del arg_3._all_groups[arg_2]

            if arg_2 in arg_3._run_parent_groups:
                del arg_3._run_parent_groups[arg_2]

        # Delete all links to the node
        if arg_2 in arg_3._linked_by:
            arg_5 = arg_3._linked_by[arg_2]
            for arg_6 in list(arg_5.keys()):
                arg_7, arg_8 = arg_5[arg_6]
                for arg_9 in list(arg_8):
                    arg_7.f_remove_link(arg_9)

        if (arg_1.v_location, arg_1.v_name) in arg_0._root_instance._new_nodes:
            del arg_0._root_instance._new_nodes[(arg_1.v_location, arg_1.v_name)]

        # Finally remove all references in the dictionaries for fast search
        arg_0._remove_from_nodes_and_leaves(arg_1)

        # Remove circular references
        arg_1._vars = None
        arg_1._func = None


def Func(arg_0, arg_1, arg_2, arg_3=False):
        """Removes a given node from the tree.

        Starts from a given node and walks recursively down the tree to the location of the node
        we want to remove.

        We need to walk from a start node in case we want to check on the way back whether we got
        empty group nodes due to deletion.

        :param actual_node: Current node

        :param split_name: DEQUE of names to get the next nodes.

        :param recursive:

            To also delete all children of a group node

        :return: True if node was deleted, otherwise False

        """

        # If the names list is empty, we have reached the node we want to delete.

        if len(arg_2) == 0:
            if arg_1.v_is_group and arg_1.f_has_children():
                if arg_3:
                    for arg_4 in list(arg_1._children.keys()):
                        arg_1.f_remove_child(arg_4, arg_3=True)
                else:
                    raise TypeError('Cannot remove group `%s` it contains children. Please '
                                    'remove with `recursive=True`.' % arg_1.v_full_name)
            arg_0._delete_node(arg_1)
            return True

        # Otherwise get the next node by using the first name in the list
        arg_5 = arg_2.popleft()

        if arg_5 in arg_1._links:
            if len(arg_2)>0:
                raise RuntimeError('You cannot remove nodes while hopping over links!')
            arg_1.f_remove_link(arg_5)
        else:
            arg_4 = arg_1._children[arg_5]

            if arg_0.Func(arg_4, arg_2, arg_3=arg_3):

                del arg_1._children[arg_5]
                if arg_5 in arg_1._groups:
                    del arg_1._groups[arg_5]
                elif arg_5 in arg_1._leaves:
                    del arg_1._leaves[arg_5]
                else:
                    raise RuntimeError('You shall not pass!')
                del arg_4
                return False


def Func(arg_0, arg_1):
        """Maps a given shortcut to corresponding name

        * 'run_X' or 'r_X' to 'run_XXXXXXXXX'

        * 'crun' to the current run name in case of a
          single run instance if trajectory is used via `v_crun`

        * 'par' 'parameters'

        * 'dpar' to 'derived_parameters'

        * 'res' to 'results'

        * 'conf' to 'config'

        :return: True or False and the mapped name.

        """

        if isinstance(arg_1, int):
            return True, arg_0._root_instance.f_wildcard('$', arg_1)

        if arg_1.startswith('run_') or arg_1.startswith('r_'):
            arg_2 = arg_1.split('_')
            if len(arg_2) == 2:
                arg_3 = arg_2[1]
                if arg_3.isdigit():
                    return True, arg_0._root_instance.f_wildcard('$', int(arg_3))
                elif arg_3 == 'A':
                    return True, arg_0._root_instance.f_wildcard('$', -1)

        if arg_1.startswith('runtoset_') or arg_1.startswith('rts_'):
            arg_2 = arg_1.split('_')
            if len(arg_2) == 2:
                arg_3 = arg_2[1]
                if arg_3.isdigit():
                    return True, arg_0._root_instance.f_wildcard('$set', int(arg_3))
                elif arg_3 == 'A':
                    return True, arg_0._root_instance.f_wildcard('$set', -1)

        if arg_1 in SHORTCUT_SET:
            if arg_1 == 'par':
                return True, 'parameters'
            elif arg_1 == 'dpar':
                return True, 'derived_parameters'
            elif arg_1 == 'res':
                return True, 'results'
            elif arg_1 == 'conf':
                return True, 'config'
            else:
                raise RuntimeError('You shall not pass!')

        return False, arg_1


def Func(arg_0, arg_1, arg_2, arg_3):
        """Adds the correct sub branch prefix to a given name.

        Usually the prefix is the full name of the parent node. In case items are added
        directly to the trajectory the prefixes are chosen according to the matching subbranch.

        For example, this could be 'parameters' for parameters or 'results.run_00000004' for
        results added to the fifth single run.

        :param split_names:

            List of names of the new node (e.g. ``['mynewgroupA', 'mynewgroupB', 'myresult']``).

        :param start_node:

            Parent node under which the new node should be added.

        :param group_type_name:

            Type name of subbranch the item belongs to
            (e.g. 'PARAMETER_GROUP', 'RESULT_GROUP' etc).

        :return: The name with the added prefix.

        """
        arg_4 = arg_0._root_instance

        # If the start node of our insertion is root or one below root
        # we might need to add prefixes.
        # In case of derived parameters and results we also need to add prefixes containing the
        # subbranch and the current run in case of a single run.
        # For instance, a prefix could be 'results.runs.run_00000007'.
        arg_5 = []
        if arg_2.v_depth < 3 and not arg_3 == GROUP:
            if arg_2.v_depth == 0:

                if arg_3 == DERIVED_PARAMETER_GROUP:
                    if arg_1[0] == 'derived_parameters':
                        return arg_1
                    else:
                        arg_5 += ['derived_parameters']

                elif arg_3 == RESULT_GROUP:
                    if arg_1[0] == 'results':
                        return arg_1
                    else:
                        arg_5 += ['results']

                elif arg_3 == CONFIG_GROUP:
                    if arg_1[0] == 'config':
                        return arg_1
                    else:
                        arg_5 += ['config']

                elif arg_3 == PARAMETER_GROUP:
                    if arg_1[0] == 'parameters':
                        return arg_1[0]
                    else:
                        arg_5 += ['parameters']
                else:
                    raise RuntimeError('Why are you here?')

            # Check if we have to add a prefix containing the current run
            if arg_4._is_run and arg_4._auto_run_prepend:
                arg_6 = arg_4.f_wildcard('$', -1)
                arg_7 = arg_4.f_wildcard('$')
                if any(arg_8 in arg_4._run_information for arg_8 in arg_1):
                    pass
                elif any(arg_8 == arg_6 for arg_8 in arg_1):
                    pass
                elif (arg_3 == RESULT_GROUP or
                        arg_3 == DERIVED_PARAMETER_GROUP):

                    if arg_2.v_depth == 0:
                        arg_5 += ['runs', arg_7]

                    elif arg_2.v_depth == 1:

                        if len(arg_1) == 1 and arg_1[0] == 'runs':
                            return arg_1
                        else:
                            arg_5 += ['runs', arg_7]

                    elif arg_2.v_depth == 2 and arg_2.v_name == 'runs':
                        arg_5 += [arg_7]

        if arg_5:
            arg_1 = arg_5 + arg_1

        return arg_1


def Func(arg_0, arg_1, arg_2, arg_3):
        """Determines types for generic additions"""
        if arg_0.v_is_root:
            arg_4 = arg_1
        else:
            arg_4 = arg_0._branch

        if arg_4 in SUBTREE_MAPPING:
            arg_5 = SUBTREE_MAPPING[arg_4]
        else:
            arg_5 = (GROUP, LEAF)

        if arg_3:
            return arg_5[0], LINK
        if arg_2:
            return arg_5
        else:
            return arg_5[0], arg_5[0]


def Func(arg_0, arg_1, arg_2, arg_3):
        """Creates a link and checks if names are appropriate
        """

        arg_1._links[arg_2] = arg_3
        arg_1._children[arg_2] = arg_3

        arg_6 = arg_3.v_full_name
        if arg_6 not in arg_0._root_instance._linked_by:
            arg_0._root_instance._linked_by[arg_6] = {}
        arg_9 = arg_0._root_instance._linked_by[arg_6]
        if arg_1.v_full_name not in arg_9:
            arg_9[arg_1.v_full_name] = (arg_1, set())
        arg_9[arg_1.v_full_name][1].add(arg_2)

        if arg_2 not in arg_0._links_count:
            arg_0._links_count[arg_2] = 0
        arg_0._links_count[arg_2] = arg_0._links_count[arg_2] + 1

        arg_0._logger.debug('Added link `%s` under `%s` pointing '
                           'to `%s`.' % (arg_2, arg_1.v_full_name,
                                         arg_3.v_full_name))
        return arg_3


def Func(arg_0, arg_1, arg_2=None):
        """Checks if a list contains strings with invalid names.

        Returns a description of the name violations. If names are correct the empty
        string is returned.

        :param split_names: List of strings

        :param parent_node:

            The parental node from where to start (only applicable for node names)

        """

        arg_3 = ''

        if arg_2 is not None and arg_2.v_is_root and arg_1[0] == 'overview':
            arg_3 = '%s `overview` cannot be added directly under the root node ' \
                           'this is a reserved keyword,' % (arg_3)

        for arg_4 in arg_1:

            if len(arg_4) == 0:
                arg_3 = '%s `%s` contains no characters, please use at least 1,' % (
                    arg_3, arg_4)

            elif arg_4.startswith('_'):
                arg_3 = '%s `%s` starts with a leading underscore,' % (
                    arg_3, arg_4)

            elif re.match(CHECK_REGEXP, arg_4) is None:
                arg_3 = '%s `%s` contains non-admissible characters ' \
                               '(use only [A-Za-z0-9_-]),' % \
                               (arg_3, arg_4)

            elif '$' in arg_4:
                if arg_4 not in arg_0._root_instance._wildcard_keys:
                    arg_3 = '%s `%s` contains `$` but has no associated ' \
                                   'wildcard function,' % (arg_3, arg_4)

            elif arg_4 in arg_0._not_admissible_names:
                warnings.warn('`%s` is a method/attribute of the '
                              'trajectory/treenode/naminginterface, you may not be '
                              'able to access it via natural naming but only by using '
                              '`[]` square bracket notation. ' % arg_4,
                              category=SyntaxWarning)

            elif arg_4 in arg_0._python_keywords:
                warnings.warn('`%s` is a python keyword, you may not be '
                              'able to access it via natural naming but only by using '
                              '`[]` square bracket notation. ' % arg_4,
                              category=SyntaxWarning)

        arg_5 = arg_1[-1]
        if len(arg_5) >= pypetconstants.HDF5_STRCOL_MAX_NAME_LENGTH:
            arg_3 = '%s `%s` is too long the name can only have %d characters but it has ' \
                           '%d,' % \
                           (arg_3, arg_5, len(arg_5),
                            pypetconstants.HDF5_STRCOL_MAX_NAME_LENGTH)

        return arg_3


def Func(arg_0, arg_1, arg_2, arg_3, arg_4=None, arg_5=None,
                          arg_6=None, arg_7=None):
        """Generically creates a new group inferring from the `type_name`."""

        if arg_6 is None:
            arg_6 = []

        if arg_7 is None:
            arg_7 = {}

        arg_8 = arg_0._make_full_name(arg_1.v_full_name, arg_2)

        if arg_4 is None:
            if arg_5 is None:
                if arg_3 == RESULT_GROUP:
                    arg_5 = ResultGroup
                elif arg_3 == PARAMETER_GROUP:
                    arg_5 = ParameterGroup
                elif arg_3 == CONFIG_GROUP:
                    arg_5 = ConfigGroup
                elif arg_3 == DERIVED_PARAMETER_GROUP:
                    arg_5 = DerivedParameterGroup
                elif arg_3 == GROUP:
                    arg_5 = NNGroupNode
                else:
                    raise RuntimeError('You shall not pass!')
            arg_4 = arg_0._root_instance._construct_instance(arg_5, arg_8,
                                                               *arg_6, **arg_7)
        else:
            arg_4._rename(arg_8)
            # Check if someone tries to add a particular standard group to a branch where
            # it does not belong:
            if arg_3 == RESULT_GROUP:
                if type(arg_4) in (NNGroupNode,
                                   ParameterGroup,
                                   ConfigGroup,
                                   DerivedParameterGroup):
                    raise TypeError('You cannot add a `%s` type of group under results' %
                                    str(type(arg_4)))
            elif arg_3 == PARAMETER_GROUP:
                if type(arg_4) in (NNGroupNode,
                                   ResultGroup,
                                   ConfigGroup,
                                   DerivedParameterGroup):
                    raise TypeError('You cannot add a `%s` type of group under parameters' %
                                    str(type(arg_4)))
            elif arg_3 == CONFIG_GROUP:
                if type(arg_4) in (NNGroupNode,
                                   ParameterGroup,
                                   ResultGroup,
                                   DerivedParameterGroup):
                    raise TypeError('You cannot add a `%s` type of group under config' %
                                    str(type(arg_4)))
            elif arg_3 == DERIVED_PARAMETER_GROUP:
                if type(arg_4) in (NNGroupNode,
                                   ParameterGroup,
                                   ConfigGroup,
                                   ResultGroup):
                    raise TypeError('You cannot add a `%s` type of group under derived '
                                    'parameters' % str(type(arg_4)))
            elif arg_3 == GROUP:
                if type(arg_4) in (ResultGroup,
                                   ParameterGroup,
                                   ConfigGroup,
                                   DerivedParameterGroup):
                    raise TypeError('You cannot add a `%s` type of group under other data' %
                                    str(type(arg_4)))
            else:
                raise RuntimeError('You shall not pass!')

        arg_0._set_details_tree_node(arg_1, arg_2, arg_4)
        arg_4._nn_interface = arg_0
        arg_0._root_instance._all_groups[arg_4.v_full_name] = arg_4
        arg_0._add_to_nodes_and_leaves(arg_4)
        arg_1._children[arg_2] = arg_4
        arg_1._groups[arg_2] = arg_4

        return arg_4


def Func(arg_0, arg_1, arg_2, arg_3, arg_4, arg_5,
                                    arg_6, arg_7):
        """Generically creates a novel parameter or result instance inferring from the `type_name`.

        If the instance is already supplied it is NOT constructed new.

        :param parent_node:

            Parent trajectory node

        :param name:

            Name of the new result or parameter. Here the name no longer contains colons.

        :param type_name:

            Whether it is a parameter below parameters, config, derived parameters or whether
            it is a result.

        :param instance:

            The instance if it has been constructed somewhere else, otherwise None.

        :param constructor:

            A constructor used if instance needs to be constructed. If None the current standard
            constructor is chosen.

        :param args:

            Additional arguments passed to the constructor

        :param kwargs:

            Additional keyword arguments passed to the constructor

        :return: The new instance

        """
        arg_8 = arg_0._root_instance
        arg_9 = arg_0._make_full_name(arg_1.v_full_name, arg_2)
        if arg_4 is None:
            if arg_5 is None:
                if arg_3 == RESULT:
                    arg_5 = arg_8._standard_result
                elif arg_3 in [PARAMETER, CONFIG, DERIVED_PARAMETER]:
                    arg_5 = arg_8._standard_parameter
                else:
                    arg_5 = arg_8._standard_leaf
            arg_4 = arg_8._construct_instance(arg_5, arg_9, *arg_6, **arg_7)
        else:
            arg_4._rename(arg_9)

        arg_0._set_details_tree_node(arg_1, arg_2, arg_4)

        arg_10 = arg_0._map_type_to_dict(arg_3)
        arg_9 = arg_4._full_name

        if arg_9 in arg_10:
            raise AttributeError(arg_9 + ' is already part of trajectory,')

        if arg_3 != RESULT and arg_9 in arg_8._changed_default_parameters:
            arg_0._logger.info(
                'You have marked parameter %s for change before, so here you go!' %
                arg_9)

            arg_11, arg_12 = arg_8._changed_default_parameters.pop(arg_9)
            arg_4.f_set(*arg_11, **arg_12)

        arg_10[arg_9] = arg_4
        arg_0._add_to_nodes_and_leaves(arg_4)
        arg_1._children[arg_2] = arg_4
        arg_1._leaves[arg_2] = arg_4

        if arg_9 in arg_0._root_instance._explored_parameters:
            arg_4._explored = True  # Mark this parameter as explored.
            arg_0._root_instance._explored_parameters[arg_9] = arg_4

        arg_0._logger.debug('Added `%s` to trajectory.' % arg_9)

        return arg_4


def Func(arg_0, arg_1, arg_2, arg_3):
        """Renames a given `instance` based on `parent_node` and `name`.

        Adds meta information like depth as well.

        """
        arg_4 = arg_1._depth + 1
        if arg_1.v_is_root:
            arg_5 = arg_2  # We add below root
        else:
            arg_5 = arg_1._branch
        if arg_2 in arg_0._root_instance._run_information:
            arg_6 = arg_2
        else:
            arg_6 = arg_1._run_branch

        arg_3._set_details(arg_4, arg_5, arg_6)


def Func(arg_0, arg_1, arg_2=0):
        """Returns an iterator over a node's children.

        In case of using a trajectory as a run (setting 'v_crun') some sub branches
        that do not belong to the run are blinded out.

        """
        arg_3 = arg_2 + 1
        if arg_1:
            arg_4 = ((arg_3, x[0], x[1]) for x in arg_0._children.items())
        else:
            arg_5 = ((arg_3, x[0], x[1]) for x in arg_0._leaves.items())
            arg_6 = ((arg_3, y[0], y[1]) for y in arg_0._groups.items())
            arg_4 = itools.chain(arg_6, arg_5)
        return arg_4


def Func(arg_0, arg_1, arg_2, arg_3, arg_4, arg_5):
        """Fast search for a node in the tree.

        The tree is not traversed but the reference dictionaries are searched.

        :param node:

            Parent node to start from

        :param key:

            Name of node to find

        :param max_depth:

            Maximum depth.

        :param with_links:

            If we work with links than we can only be sure to found the node in case we
            have a single match. Otherwise the other match might have been linked as well.

        :param crun:

            If given only nodes belonging to this particular run are searched and the rest
            is blinded out.

        :return: The found node and its depth

        :raises:

            TooManyGroupsError:

                If search cannot performed fast enough, an alternative search method is needed.

            NotUniqueNodeError:

                If several nodes match the key criterion

        """

        if arg_2 in arg_0._links_count:
            return

        arg_6 = arg_1.v_full_name
        arg_7 = arg_1.v_depth
        arg_8 = arg_0._get_candidate_dict(arg_2, arg_5)

        # If there are to many potential candidates sequential search might be too slow
        if arg_4:
            arg_9 = 1
        else:
            arg_9 = FAST_UPPER_BOUND
        if len(arg_8) > arg_9:
            raise pex.TooManyGroupsError('Too many nodes')

        # Next check if the found candidates could be reached from the parent node
        arg_10 = None
        for arg_11 in arg_8:

            # Check if we have found a matching node
            if arg_11.startswith(arg_6):
                arg_12 = arg_8[arg_11]
                if arg_12.v_depth - arg_7 <= arg_3:
                    # In case of several solutions raise an error:
                    if arg_10 is not None:
                        raise pex.NotUniqueNodeError('Node `%s` has been found more than once, '
                                                     'full name of first occurrence is `%s` and of'
                                                     'second `%s`'
                                                     % (arg_2, arg_11, arg_10.v_full_name))
                    arg_10 = arg_12

        if arg_10 is not None:
            return arg_10, arg_10.v_depth


def Func(arg_0, arg_1, arg_2, arg_3=arg_4('inf'), arg_5=True, arg_6=None):
        """ Searches for an item in the tree below `node`

        :param node:

            The parent node below which the search is performed

        :param key:

            Name to search for. Can be the short name, the full name or parts of it

        :param max_depth:

            maximum search depth.

        :param with_links:

            If links should be considered

        :param crun:

            Used for very fast search if we know we operate in a single run branch

        :return: The found node and the depth it was found for

        """

        # If we find it directly there is no need for an exhaustive search
        if arg_2 in arg_1._children and (arg_5 or arg_2 not in arg_1._links):
            return arg_1._children[arg_2], 1

        # First the very fast search is tried that does not need tree traversal.
        try:
            arg_7 = arg_0._very_fastFunc(arg_1, arg_2, arg_3, arg_5, arg_6)
            if arg_7:
                return arg_7
        except pex.TooManyGroupsError:
            pass
        except pex.NotUniqueNodeError:
            pass

        # Slowly traverse the entire tree
        arg_8 = arg_0._iter_nodes(arg_1, recursive=True,
                                          arg_3=arg_3, inFunc=True,
                                          arg_5=arg_5)
        arg_9 = None
        arg_10 = arg_4('inf')
        for arg_11, arg_12, arg_13 in arg_8:

            if arg_11 > arg_10:
                # We can break here because we enter a deeper stage of the tree and we
                # cannot find matching node of the same depth as the one we found
                break

            if arg_2 == arg_12:
                # If result_node is not None means that we care about uniqueness and the search
                # has found more than a single solution.
                if arg_9 is not None:
                    raise pex.NotUniqueNodeError('Node `%s` has been found more than once within '
                                                 'the same depth %d. '
                                                 'Full name of first occurrence is `%s` and of '
                                                 'second `%s`'
                                                 % (arg_2, arg_13.v_depth, arg_9.v_full_name,
                                                    arg_13.v_full_name))

                arg_9 = arg_13
                arg_10 = arg_11

        return arg_9, arg_10


def Func(arg_0):
        """Alternative naming, you can use `node.Func.name` instead of `node.name`
        for easier tab completion."""
        if arg_0._Func is None:
            arg_0._Func = NNTreeNodeKids(arg_0)
        return arg_0._Func


def Func(arg_0, arg_1, arg_2):
        """Can be called from storage service to create a new group to bypass name checking"""
        return arg_0._nn_interface._add_generic(arg_0,
                                                type_name=GROUP,
                                                group_type_name=GROUP,
                                                arg_1=arg_1,
                                                arg_2=arg_2,
                                                add_prefix=False,
                                                check_naming=False)


def Func(arg_0):
        """Creates a dummy object containing the whole tree to make unfolding easier.

        This method is only useful for debugging purposes.
        If you use an IDE and want to unfold the trajectory tree, you always need to
        open the private attribute `_children`. Use to this function to create a new
        object that contains the tree structure in its attributes.

        Manipulating the returned object does not change the original tree!

        """

        class Bunch(object):
            """Dummy container class"""
            pass

        arg_1 = Bunch()

        if not arg_0.v_annotations.f_is_empty():
            arg_1.v_annotations = arg_0.v_annotations
        if not arg_0.v_comment == '':
            arg_1.v_comment = arg_0.v_comment

        for arg_4 in arg_0._leaves:
            arg_5 = arg_0._leaves[arg_4]
            setattr(arg_1, arg_4, arg_5)

        for arg_6 in arg_0._links:
            arg_7 = arg_0._links[arg_6]
            setattr(arg_1, arg_6, 'Link to `%s`' % arg_7.v_full_name)

        for arg_8 in arg_0._groups:
            arg_9 = arg_0._groups[arg_8]
            setattr(arg_1, arg_8, arg_9.Func())

        return arg_1


def Func(arg_0, arg_1):
        """ Removes a link from from the current group node with a given name.

        Does not delete the link from the hard drive. If you want to do this,
        checkout :func:`~pypet.trajectory.Trajectory.f_delete_links`

        """
        if arg_1 not in arg_0._links:
            raise ValueError('No link with name `%s` found under `%s`.' % (arg_1, arg_0._full_name))

        arg_0._nn_interface._remove_link(arg_0, arg_1)


def Func(arg_0, *arg_1, **arg_2):
        """Adds an empty generic leaf under the current node.

        You can add to a generic leaves anywhere you want. So you are free to build
        your trajectory tree with any structure. You do not necessarily have to follow the
        four subtrees `config`, `parameters`, `derived_parameters`, `results`.

        If you are operating within these subtrees this simply calls the corresponding adding
        function.

        Be aware that if you are within a single run and you add items not below a group
        `run_XXXXXXXX` that you have to manually
        save the items. Otherwise they will be lost after the single run is completed.

        """

        return arg_0._nn_interface._add_generic(arg_0, type_name=LEAF,
                                               group_type_name=GROUP,
                                               arg_1=arg_1, arg_2=arg_2,
                                               add_prefix=False)


def Func(arg_0, arg_1, arg_2=False, arg_3=None):
        """Removes a child of the group.

        Note that groups and leaves are only removed from the current trajectory in RAM.
        If the trajectory is stored to disk, this data is not affected. Thus, removing children
        can be only be used to free RAM memory!

        If you want to free memory on disk via your storage service,
        use :func:`~pypet.trajectory.Trajectory.f_delete_items` of your trajectory.

        :param name:

            Name of child, naming by grouping is NOT allowed ('groupA.groupB.childC'),
            child must be direct successor of current node.

        :param recursive:

            Must be true if child is a group that has children. Will remove
            the whole subtree in this case. Otherwise a Type Error is thrown.

        :param predicate:

            Predicate which can evaluate for each node to ``True`` in order to remove the node or
            ``False`` if the node should be kept. Leave ``None`` if you want to remove all nodes.

        :raises:

            TypeError if recursive is false but there are children below the node.

            ValueError if child does not exist.

        """
        if arg_1 not in arg_0._children:
            raise ValueError('Your group `%s` does not contain the child `%s`.' %
                             (arg_0.v_full_name, arg_1))
        else:
            arg_4 = arg_0._children[arg_1]
            if (arg_1 not in arg_0._links and
                    not arg_4.v_is_leaf and
                    arg_4.f_has_children() and
                    not arg_2):
                raise TypeError('Cannot remove child. It is a group with children. Use'
                                ' f_remove with ``recursive = True``')
            else:
                arg_0._nn_interface._remove_subtree(arg_0, arg_1, arg_3)


def Func(arg_0, arg_1, arg_2=True, arg_3=False, arg_4=None):
        """Checks if the node contains a specific parameter or result.

        It is checked if the item can be found via the
        :func:`~pypet.naturalnaming.NNGroupNode.f_get` method.

        :param item: Parameter/Result name or instance.

            If a parameter or result instance is supplied it is also checked if
            the provided item and the found item are exactly the same instance, i.e.
            `id(item)==id(found_item)`.

        :param with_links:

            If links are considered.

        :param shortcuts:

            Shortcuts is `False` the name you supply must
            be found in the tree WITHOUT hopping over nodes in between.
            If `shortcuts=False` and you supply a
            non colon separated (short) name, than the name must be found
            in the immediate children of your current node.
            Otherwise searching via shortcuts is allowed.

        :param max_depth:

            If shortcuts is `True` than the maximum search depth
            can be specified. `None` means no limit.

        :return: True or False

        """

        # Check if an instance or a name was supplied by the user
        try:
            arg_5 = arg_1.v_full_name
            arg_6 = arg_0.v_full_name

            if not arg_5.startswith(arg_6):
                return False

            if arg_6 != '':
                arg_5 = arg_5[len(arg_6) + 1:]
            else:
                arg_5 = arg_5

            arg_3 = False # if we search for a particular item we do not allow shortcuts

        except AttributeError:
            arg_5 = arg_1
            arg_1 = None

        if arg_5 == '':
            return False # To allow to search for nodes wit name = '', which are never part
            # of the trajectory

        try:
            arg_7 = arg_0.f_get(arg_5,
                                arg_3=arg_3, arg_4=arg_4, arg_2=arg_2)
        except AttributeError:
            return False

        if arg_1 is not None:
            return id(arg_1) == id(arg_7)
        else:
            return True


def Func(arg_0, arg_1, arg_2=None, arg_3=True, arg_4=True,
              arg_5=True, arg_6=None, arg_7=False):
        """ Similar to `f_get`, but returns the default value if `name` is not found in the
        trajectory.

        This function uses the `f_get` method and will return the default value
        in case `f_get` raises an AttributeError or a DataNotInStorageError.
        Other errors are not handled.

        In contrast to `f_get`, fast access is True by default.

        """
        try:
            return arg_0.f_get(arg_1, arg_3=arg_3,
                           arg_5=arg_5,
                           arg_6=arg_6,
                           arg_7=arg_7,
                           arg_4=arg_4)

        except (AttributeError, pex.DataNotInStorageError):
            return arg_2


def Func(arg_0, arg_1=True):
        """Returns a children dictionary.

        :param copy:

            Whether the group's original dictionary or a shallow copy is returned.
            If you want the real dictionary please do not modify it at all!

        :returns: Dictionary of nodes

        """
        if arg_1:
            return arg_0._children.copy()
        else:
            return arg_0._children


def Func(arg_0, arg_1=True):
        """Returns a dictionary of groups hanging immediately below this group.

        :param copy:

            Whether the group's original dictionary or a shallow copy is returned.
            If you want the real dictionary please do not modify it at all!

        :returns: Dictionary of nodes

        """
        if arg_1:
            return arg_0._groups.copy()
        else:
            return arg_0._groups


def Func(arg_0, arg_1, arg_2=False, arg_3=arg_4.STORE_DATA,
                      arg_6=None):
        """Stores a child or recursively a subtree to disk.

        :param name:

            Name of child to store. If grouped ('groupA.groupB.childC') the path along the way
            to last node in the chain is stored. Shortcuts are NOT allowed!

        :param recursive:

            Whether recursively all children's children should be stored too.

        :param store_data:

            For how to choose 'store_data' see :ref:`more-on-storing`.

        :param max_depth:

            In case `recursive` is `True`, you can specify the maximum depth to store
            data relative from current node. Leave `None` if you don't want to limit
            the depth.

        :raises: ValueError if the child does not exist.

        """
        if not arg_0.f_contains(arg_1, shortcuts=False):
            raise ValueError('Your group `%s` does not (directly) contain the child `%s`. '
                             'Please not that shortcuts are not allowed for `Func`.' %
                             (arg_0.v_full_name, arg_1))

        arg_7 = arg_0._nn_interface._root_instance
        arg_8 = arg_7.v_storage_service

        arg_8.store(arg_4.TREE, arg_0, arg_1,
                              trajectory_name=arg_7.v_name,
                              arg_2=arg_2,
                              arg_3=arg_3,
                              arg_6=arg_6)


def Func(arg_0, arg_1=True, arg_2=arg_3.LOAD_DATA,
               arg_5=None):
        """Loads a group from disk.

        :param recursive:

            Default is ``True``.
            Whether recursively all nodes below the current node should be loaded, too.
            Note that links are never evaluated recursively. Only the linked node
            will be loaded if it does not exist in the tree, yet. Any nodes or links
            of this linked node are not loaded.

        :param load_data:

            Flag how to load the data.
            For how to choose 'load_data' see :ref:`more-on-loading`.

        :param max_depth:

            In case `recursive` is `True`, you can specify the maximum depth to load
            load data relative from current node.

        :returns:

            The node itself.

        """

        arg_6 = arg_0._nn_interface._root_instance
        arg_7 = arg_6.v_storage_service

        arg_7.load(arg_3.GROUP, arg_0,
                             trajectory_name=arg_6.v_name,
                             arg_2=arg_2,
                             arg_1=arg_1,
                             arg_5=arg_5)
        return arg_0


def Func(arg_0, *arg_1, **arg_2):
        """ Adds a parameter under the current node.

        There are two ways to add a new parameter either by adding a parameter instance:

        >>> new_parameter = Parameter('group1.group2.myparam', data=42, comment='Example!')
        >>> traj.Func(new_parameter)

        Or by passing the values directly to the function, with the name being the first
        (non-keyword!) argument:

        >>> traj.Func('group1.group2.myparam', 42, comment='Example!')

        If you want to create a different parameter than the standard parameter, you can
        give the constructor as the first (non-keyword!) argument followed by the name
        (non-keyword!):

        >>> traj.Func(PickleParameter,'group1.group2.myparam', data=42, comment='Example!')

        The full name of the current node is added as a prefix to the given parameter name.
        If the current node is the trajectory the prefix `'parameters'` is added to the name.

        Note, all non-keyword and keyword parameters apart from the optional constructor
        are passed on as is to the constructor.

        Moreover, you always should specify a default data value of a parameter,
        even if you want to explore it later.

        """
        return arg_0._nn_interface._add_generic(arg_0, type_name=PARAMETER,
                                               group_type_name=PARAMETER_GROUP,
                                               arg_1=arg_1, arg_2=arg_2)


def Func(arg_0, *arg_1, **arg_2):
        """Adds a result under the current node.

        There are two ways to add a new result either by adding a result instance:

        >>> new_result = Result('group1.group2.myresult', 1666, x=3, y=4, comment='Example!')
        >>> traj.Func(new_result)

        Or by passing the values directly to the function, with the name being the first
        (non-keyword!) argument:

        >>> traj.Func('group1.group2.myresult', 1666, x=3, y=3,comment='Example!')

        If you want to create a different result than the standard result, you can
        give the constructor as the first (non-keyword!) argument followed by the name
        (non-keyword!):

        >>> traj.Func(PickleResult,'group1.group2.myresult', 1666, x=3, y=3, comment='Example!')

        Additional arguments (here `1666`) or keyword arguments (here `x=3, y=3`) are passed
        onto the constructor of the result.

        Adds the full name of the current node as prefix to the name of the result.
        If current node is a single run (root) adds the prefix `'results.runs.run_08%d%'` to the
        full name where `'08%d'` is replaced by the index of the current run.

        """
        return arg_0._nn_interface._add_generic(arg_0, type_name=RESULT,
                                               group_type_name=RESULT_GROUP,
                                               arg_1=arg_1, arg_2=arg_2)


def Func(arg_0, *arg_1, **arg_2):
        """Adds a derived parameter under the current group.

        Similar to
        :func:`~pypet.naturalnaming.ParameterGroup.f_add_parameter`

        Naming prefixes are added as in
        :func:`~pypet.naturalnaming.DerivedParameterGroup.Func_group`

        """
        return arg_0._nn_interface._add_generic(arg_0, type_name=DERIVED_PARAMETER,
                                               group_type_name=DERIVED_PARAMETER_GROUP,
                                               arg_1=arg_1, arg_2=arg_2)


def Func(arg_0, *arg_1, **arg_2):
        """Adds an empty config group under the current node.

        Adds the full name of the current node as prefix to the name of the group.
        If current node is the trajectory (root), the prefix `'config'` is added to the full name.

        The `name` can also contain subgroups separated via colons, for example:
        `name=subgroup1.subgroup2.subgroup3`. These other parent groups will be automatically
        be created.

        """
        return arg_0._nn_interface._add_generic(arg_0, type_name=CONFIG_GROUP,
                                               group_type_name=CONFIG_GROUP,
                                               arg_1=arg_1, arg_2=arg_2)


def Func(arg_0, *arg_1, **arg_2):
        """Adds a config parameter under the current group.

        Similar to
        :func:`~pypet.naturalnaming.ParameterGroup.f_add_parameter`.

        If current group is the trajectory the prefix `'config'` is added to the name.

        """
        return arg_0._nn_interface._add_generic(arg_0, type_name=CONFIG,
                                               group_type_name=CONFIG_GROUP,
                                               arg_1=arg_1, arg_2=arg_2)


def Func(arg_0, arg_1):
    """The fitness function"""
    arg_0.f_add_result('$set.$.individual', list(arg_1))
    arg_2 = sum(arg_1)
    arg_0.f_add_result('$set.$.fitness', arg_2)
    arg_0.f_store()
    return (arg_2,)


def Func(arg_0, arg_1):
    """Adds commit information to the trajectory."""

    arg_2 = time.strftime('%Y_%m_%d_%Hh%Mm%Ss', time.localtime(arg_1.committed_date))

    arg_3 = str(arg_1.hexsha[0:7])
    arg_4 = 'commit_%s_' % arg_3
    arg_4 = 'git.' + arg_4 + arg_2

    if not arg_0.f_contains('config.'+arg_4, shortcuts=False):

        arg_4 += '.'
        # Add the hexsha
        arg_0.f_add_config(arg_4+'hexsha', arg_1.hexsha,
                          comment='SHA-1 hash of commit')

        # Add the description string
        arg_0.f_add_config(arg_4+'name_rev', arg_1.name_rev,
                          comment='String describing the commits hex sha based on '
                                  'the closest Reference')

        # Add unix epoch
        arg_0.f_add_config(arg_4+'committed_date',
                          arg_1.committed_date, comment='Date of commit as unix epoch seconds')

        # Add commit message
        arg_0.f_add_config(arg_4+'message', str(arg_1.message),
                          comment='The commit message')


def Func(arg_0, arg_1):
    """ Nests a given flat dictionary.

    Nested keys are created by splitting given keys around the `separator`.

    """
    arg_2 = {}
    for arg_3, arg_4 in arg_0.items():
        arg_5 = arg_3.split(arg_1)
        arg_6 = arg_2
        arg_7 = arg_5.pop()
        for arg_8 in arg_5:
            if not arg_8 in arg_6:
                arg_6[arg_8] = {}

            arg_6 = arg_6[arg_8]

        arg_6[arg_7] = arg_4
    return arg_2


def Func(arg_0, arg_1, arg_2=10, arg_3='print', arg_4=arg_5.INFO,
                 arg_7=True, arg_8=True, arg_9=20, arg_10=None, arg_11=False):
    """Plots a progress bar to the given `logger` for large for loops.

    To be used inside a for-loop at the end of the loop:

    .. code-block:: python

        for irun in range(42):
            my_costly_job() # Your expensive function
            Func(index=irun, total=42, reprint=True) # shows a growing Func

    There is no initialisation of the Func necessary before the for-loop.
    The Func will be reset automatically if used in another for-loop.

    :param index: Current index of for-loop
    :param total: Total size of for-loop
    :param percentage_step: Steps with which the bar should be plotted
    :param logger:

        Logger to write to - with level INFO. If string 'print' is given, the print statement is
        used. Use ``None`` if you don't want to print or log the Func statement.

    :param log_level: Log level with which to log.
    :param reprint:

        If no new line should be plotted but carriage return (works only for printing)

    :param time: If the remaining time should be estimated and displayed
    :param length: Length of the bar in `=` signs.
    :param fmt_string:

        A string which contains exactly one `%s` in order to incorporate the Func.
        If such a string is given, ``fmt_string % Func`` is printed/logged.

    :param reset:

        If the Func should be restarted. If Func is called with a lower
        index than the one before, the Func is automatically restarted.

    :return:

        The Func string or `None` if the string has not been updated.

    """
    return _Func(arg_0=arg_0, arg_1=arg_1, arg_2=arg_2,
                        arg_3=arg_3, arg_4=arg_4, arg_7=arg_7,
                        arg_8=arg_8, arg_9=arg_9, arg_10=arg_10, arg_11=arg_11)


def Func(arg_0):
    """Helper function to support both Python versions"""
    if inspect.isclass(arg_0):
        arg_0 = arg_0.__init__
    if not inspect.isfunction(arg_0):
        # Init function not existing
        return [], False
    arg_1 = inspect.signature(arg_0).parameters
    arg_2 = []
    arg_3 = False
    for arg_4 in arg_1.values():
        if (arg_4.kind == inspect.Parameter.POSITIONAL_OR_KEYWORD or
                    arg_4.kind == inspect.Parameter.KEYWORD_ONLY):
            arg_2.append(arg_4.name)
        elif arg_4.kind == inspect.Parameter.VAR_KEYWORD:
            arg_3 = True
    return arg_2, arg_3


def Func(arg_0, arg_1):
    """Takes a function and keyword arguments and returns the ones that can be passed."""
    arg_2, arg_3 = _get_argspec(arg_0)
    if arg_3:
        return arg_1.copy()
    else:
        arg_4 = dict((k, arg_1[k]) for k in arg_2 if k in arg_1)
        return arg_4


def Func(arg_0):
    """Formats timestamp to human readable format"""
    arg_1 = '%Y_%m_%d_%Hh%Mm%Ss'
    arg_2 = datetime.datetime.fromtimestamp(arg_0).strftime(arg_1)
    return arg_2


def Func(arg_0=None):
    """Returns local tcp address for a given `port`, automatic port if `None`"""
    #address = 'tcp://' + socket.gethostbyname(socket.getfqdn())
    arg_1 = socket.getfqdn()
    try:
        arg_2 = socket.getaddrinfo(arg_1, None)
    except Exception:
        arg_2 = socket.getaddrinfo('127.0.0.1', None)
    arg_3, arg_4, arg_5, arg_6, arg_7 = arg_2[0]
    arg_8 = convert_ipv6(arg_7[0])
    arg_9 =  'tcp://' + arg_8
    if arg_0 is None:
        arg_0 = ()
    if not isinstance(arg_0, int):
        # determine port automatically
        arg_10 = zmq.Context()
        try:
            arg_11 = arg_10.socket(zmq.REP)
            arg_11.ipv6 = is_ipv6(arg_9)
            arg_0 = arg_11.bind_to_random_port(arg_9, *arg_0)
        except Exception:
            print('Could not connect to {} using {}'.format(arg_9, arg_2))
            arg_13 = logging.getLogger('pypet')
            arg_13.exception('Could not connect to {}'.format(arg_9))
            raise
        arg_11.close()
        arg_10.term()
    return arg_9 + ':' + str(arg_0)


def Func(arg_0, arg_1, arg_2, arg_3, arg_4):
        """Resets to the progressbar to start a new one"""
        arg_0._start_time = datetime.datetime.now()
        arg_0._start_index = arg_1
        arg_0._current_index = arg_1
        arg_0._percentage_step = arg_3
        arg_0._total = float(arg_2)
        arg_0._total_minus_one = arg_2 - 1
        arg_0._length = arg_4
        arg_0._norm_factor = arg_2 * arg_3 / 100.0
        arg_0._current_interval = int((arg_1 + 1.0) / arg_0._norm_factor)


def Func(arg_0, arg_1):
        """Removes `key` from annotations"""
        arg_1 = arg_0._translate_key(arg_1)
        try:
            del arg_0._dict[arg_1]
        except KeyError:
            raise AttributeError('Your annotations do not contain %s' % arg_1)


def Func(arg_0, arg_1, arg_2=None, arg_3=True):
    """Turns a given shared data item into a an ordinary one.

    :param result: Result container with shared data
    :param key: The name of the shared data
    :param trajectory:

        The trajectory, only needed if shared data has
        no access to the trajectory, yet.

    :param reload: If data should be reloaded after conversion

    :return: The result

    """
    arg_4 = arg_0.f_get(arg_1)
    if arg_2 is not None:
        arg_4.traj = arg_2
    arg_4._request_data('make_ordinary')
    arg_0.f_remove(arg_1)
    if arg_3:
        arg_2.f_load_item(arg_0, load_data=pypetconstants.OVERWRITE_DATA)
    return arg_0


def Func(arg_0, arg_1, arg_2, arg_3=None):
    """Turns an ordinary data item into a shared one.

    Removes the old result from the trajectory and replaces it.
    Empties the given result.

    :param result: The result containing ordinary data
    :param key: Name of ordinary data item
    :param trajectory: Trajectory container
    :param new_class:

        Class of new shared data item.
        Leave `None` for automatic detection.

    :return: The `result`

    """
    arg_4 = arg_0.f_get(arg_1)
    if arg_3 is None:
        if isinstance(arg_4, ObjectTable):
            arg_3 = SharedTable
        elif isinstance(arg_4, pd.DataFrame):
            arg_3 = SharedPandasFrame
        elif isinstance(arg_4, (tuple, list)):
            arg_3 = SharedArray
        elif isinstance(arg_4, (np.ndarray, np.matrix)):
            arg_3 = SharedCArray
        else:
            raise RuntimeError('Your data `%s` is not understood.' % arg_1)
    arg_5 = arg_3(arg_0.f_translate_key(arg_1), arg_0, arg_2=arg_2)
    arg_0[arg_1] = arg_5
    arg_5._request_data('make_shared')
    return arg_0


def Func(arg_0, **arg_1):
        """Creates shared data on disk with a StorageService on disk.

        Needs to be called before shared data can be used later on.

        Actual arguments of ``kwargs`` depend on the type of data to be
        created. For instance, creating an array one can use the keyword
        ``obj`` to pass a numpy array (``obj=np.zeros((10,20,30))``).
        Whereas for a PyTables table may need a description dictionary
        (``description={'column_1': pt.StringCol(2, pos=0),'column_2': pt.FloatCol( pos=1)}``)
        Refer to the PyTables documentation on how to create tables.

        """
        if 'flag' not in arg_1:
            arg_1['flag'] = arg_0.FLAG
        if 'data' in arg_1:
            arg_1['obj'] = arg_1.pop('data')
        if 'trajectory' in arg_1:
            arg_0.traj = arg_1.pop('trajectory')
        if 'traj' in arg_1:
            arg_0.traj = arg_1.pop('traj')
        if 'name' in arg_1:
            arg_0.name = arg_1.pop['name']
        if 'parent' in arg_1:
            arg_0.parent = arg_1.pop('parent')
            if arg_0.name is not None:
                arg_0.parent[arg_0.name] = arg_0
        return arg_0._request_data('Func', arg_1=arg_1)


def Func(arg_0, arg_1, arg_2=None, arg_3=None):
        """Interface with the underlying storage.

        Passes request to the StorageService that performs the appropriate action.
        For example, given a shared table ``t``.
        ``t.remove_row(4)`` is parsed into ``request='remove_row', args=(4,)`` and
        passed onto the storage service. In case of the HDF5StorageService,
        this is again translated back into ``hdf5_table_node.remove_row(4)``.

        """
        return arg_0._storage_service.store(pypetconstants.ACCESS_DATA,
                                           arg_0.parent.v_full_name,
                                           arg_0.name,
                                           arg_1, arg_2, arg_3,
                                           trajectory_name=arg_0.traj.v_name)


def Func(arg_0):
        """Returns the actula node of the underlying data.

        In case one uses HDF5 this will be the HDF5 leaf node.

        """
        if not arg_0._storage_service.is_open:
            warnings.warn('You requesting the data item but your store is not open, '
                          'the item itself will be closed, too!',
                          category=RuntimeWarning)
        return arg_0._request_data('__thenode__')


def Func(arg_0, arg_1):
        """Checks if outer data structure is supported."""
        arg_2 = super(SharedResult, arg_0).Func(arg_1)
        arg_2 = arg_2 or type(arg_1) in SharedResult.SUPPORTED_DATA
        return arg_2


def Func(arg_0, arg_1=None, **arg_2):
        """Calls the corresponding function of the shared data item"""
        if arg_1 is None:
            arg_3 = arg_0.f_get()
        else:
            arg_3 = arg_0.f_get(arg_1)
        return arg_3.Func(**arg_2)


def Func(arg_0, arg_1, arg_2, arg_3):
        """Hanldes locking of locks

        If a lock is already locked sends a WAIT command,
        else LOCKs it and sends GO.

        Complains if a given client re-locks a lock without releasing it before.

        """
        if arg_1 in arg_0.Funcs:
            arg_4, arg_5 = arg_0.Funcs[arg_1]
            if arg_4 == arg_2:
                arg_6 = (arg_0.LOCK_ERROR + arg_0.DELIMITER +
                            'Re-request of lock `%s` (old request id `%s`) by `%s` '
                            '(request id `%s`)' % (arg_1, arg_2, arg_5, arg_3))
                arg_0._logger.warning(arg_6)
                return arg_6
            else:
                return arg_0.WAIT
        else:
            arg_0.Funcs[arg_1] = (arg_2, arg_3)
            return arg_0.GO


def Func(arg_0):
        """Notifies the Server to shutdown"""
        arg_0.start(test_connection=False)
        arg_0._logger.debug('Sending shutdown signal')
        arg_0._req_rep(ZMQServer.DONE)


def Func(arg_0):
        """Closes socket and terminates context

        NO-OP if already closed.

        """
        if arg_0._context is not None:
            if arg_0._socket is not None:
                arg_0._close_socket(confused=False)
            arg_0._context.term()
            arg_0._context = None
            arg_0._poll = None


def Func(arg_0, arg_1=True):
        """Starts connection to server if not existent.

        NO-OP if connection is already established.
        Makes ping-pong test as well if desired.

        """
        if arg_0._context is None:
            arg_0._logger.debug('Starting Client')
            arg_0._context = zmq.Context()
            arg_0._poll = zmq.Poller()
            arg_0._Func_socket()
            if arg_1:
                arg_0.test_ping()


def Func(arg_0, arg_1):
        """Returns response and number of retries"""
        arg_2 = arg_0.RETRIES
        while arg_2:
            arg_0._logger.log(1, 'Sending REQ `%s`', arg_1)
            arg_0._send_request(arg_1)
            arg_3 = dict(arg_0._poll.poll(arg_0.TIMEOUT))
            if arg_3.get(arg_0._socket) == zmq.POLLIN:
                arg_4 = arg_0._receive_response()
                arg_0._logger.log(1, 'Received REP `%s`', arg_4)
                return arg_4, arg_0.RETRIES - arg_2
            else:
                arg_0._logger.debug('No response from server (%d retries left)' %
                                   arg_2)
                arg_0._close_socket(confused=True)
                arg_2 -= 1
                if arg_2 == 0:
                    raise RuntimeError('Server seems to be offline!')
                time.sleep(arg_0.SLEEP)
                arg_0._start_socket()


def Func(arg_0):
        """Acquires lock and returns `True`

        Blocks until lock is available.

        """
        arg_0.start(test_connection=False)
        while True:
            arg_1, arg_2 = arg_0._req_rep_retry(LockerServer.LOCK)
            arg_3 = arg_1.split(LockerServer.DELIMITER)
            if arg_3[0] == LockerServer.GO:
                return True
            elif arg_3[0] == LockerServer.LOCK_ERROR and arg_2 > 0:
                # Message was sent but Server response was lost and we tried again
                arg_0._logger.error(arg_1 + '; Probably due to retry')
                return True
            elif arg_3[0] == LockerServer.WAIT:
                time.sleep(arg_0.SLEEP)
            else:
                raise RuntimeError('Response `%s` not understood' % arg_3)


def Func(arg_0):
        """ Handles Funcing requests from the client.

        There are 4 types of requests:

        1- Check space in the queue
        2- Tests the socket
        3- If there is a space, it sends data
        4- after data is sent, puts it to queue for storing

        """
        arg_1 = 0
        arg_0._start()
        while True:
            arg_2 = arg_0._socket.recv_pyobj()

            if isinstance(arg_2, tuple):
                arg_3, arg_4 = arg_2
            else:
                arg_3 = arg_2
                arg_4 = None

            if arg_3 == arg_0.SPACE:
                if arg_0.queue.qsize() + arg_1 < arg_0.queue_maxsize:
                    arg_0._socket.send_string(arg_0.SPACE_AVAILABLE)
                    arg_1 += 1
                else:
                    arg_0._socket.send_string(arg_0.SPACE_NOT_AVAILABLE)

            elif arg_3 == arg_0.PING:
                arg_0._socket.send_string(arg_0.PONG)

            elif arg_3 == arg_0.DATA:
                arg_0._socket.send_string(arg_0.STORING)
                arg_0.queue.put(arg_4)
                arg_1 -= 1

            elif arg_3 == arg_0.DONE:
                arg_0._socket.send_string(ZMQServer.CLOSED)
                arg_0.queue.put(('DONE', [], {}))
                arg_0._close()
                break

            else:
                raise RuntimeError('I did not understand your request %s' % arg_3)


def Func(arg_0, arg_1, arg_2, arg_3):
        """Handles data and returns `True` or `False` if everything is done."""
        arg_4 = False
        try:
            if arg_1 == 'DONE':
                arg_4 = True
            elif arg_1 == 'STORE':
                if 'msg' in arg_3:
                    arg_5 = arg_3.pop('msg')
                else:
                    arg_5 = arg_2[0]
                    arg_2 = arg_2[1:]
                if 'stuff_to_store' in arg_3:
                    arg_6 = arg_3.pop('stuff_to_store')
                else:
                    arg_6 = arg_2[0]
                    arg_2 = arg_2[1:]
                arg_7 = arg_3['trajectory_name']
                if arg_0._trajectory_name != arg_7:
                    if arg_0._storage_service.is_open:
                        arg_0._close_file()
                    arg_0._trajectory_name = arg_7
                    arg_0._open_file()
                arg_0._storage_service.store(arg_5, arg_6, *arg_2, **arg_3)
                arg_0._storage_service.store(pypetconstants.FLUSH, None)
                arg_0._check_and_collect_garbage()
            else:
                raise RuntimeError('You queued something that was not '
                                   'intended to be queued. I did not understand message '
                                   '`%s`.' % arg_1)
        except Exception:
            arg_0._logger.exception('ERROR occurred during storing!')
            time.sleep(0.01)
            pass  # We don't want to kill the queue process in case of an error

        return arg_4


def Func(arg_0):
        """Starts listening to the queue."""
        try:
            while True:
                arg_1, arg_2, arg_3 = arg_0._receive_data()
                arg_4 = arg_0._handle_data(arg_1, arg_2, arg_3)
                if arg_4:
                    break
        finally:
            if arg_0._storage_service.is_open:
                arg_0._close_file()
            arg_0._trajectory_name = ''


def Func(arg_0):
        """Gets data from pipe"""
        while True:
            while len(arg_0._buffer) < arg_0.max_size and arg_0.conn.poll():
                arg_1 = arg_0._read_chunks()
                if arg_1 is not None:
                    arg_0._buffer.append(arg_1)
            if len(arg_0._buffer) > 0:
                return arg_0._buffer.popleft()


def Func(arg_0, arg_1, arg_2, *arg_3, **arg_4):
        """Simply keeps a reference to the Funcd data """
        arg_5 = arg_4['trajectory_name']
        if arg_5 not in arg_0.references:
            arg_0.references[arg_5] = []
        arg_0.references[arg_5].append((arg_1, cp.copy(arg_2), arg_3, arg_4))


def Func(arg_0, arg_1):
        """Stores references to disk and may collect garbage."""
        for arg_2 in arg_1:
            arg_0._storage_service.store(pypetconstants.LIST, arg_1[arg_2], arg_2=arg_2)
        arg_0._check_and_collect_garbage()


def Func(arg_0):
    """Decorator wrapping the environment to use a config file"""
    @functools.wraps(arg_0)
    def new_func(arg_1, *arg_2, **arg_3):
        arg_4 = ConfigInterpreter(arg_3)
        # Pass the config data to the kwargs
        arg_5 = arg_4.interpret()
        arg_0(arg_1, *arg_2, **arg_5)
        # Add parameters and config data from the `.ini` file
        arg_4.add_parameters(arg_1.traj)
    return new_func


def Func(arg_0, arg_1):
        """Collects all settings within a section"""
        arg_2 = {}
        try:
            if arg_0.parser.has_section(arg_1):
                arg_3 = arg_0.parser.options(arg_1)
                for arg_4 in arg_3:
                    arg_5 = arg_0.parser.get(arg_1, arg_4)
                    arg_6 = ast.literal_eval(arg_5)
                    arg_2[arg_4] = arg_6
            return arg_2
        except:
            raise


def Func(arg_0):
        """Copies parsed arguments into the kwargs passed to the environment"""
        if arg_0.config_file:
            arg_1 = arg_0._collect_config()
            for arg_2 in arg_1:
                # Already specified kwargs take precedence over the ini file
                if arg_2 not in arg_0.kwargs:
                    arg_0.kwargs[arg_2] = arg_1[arg_2]
            if not use_simple_logging(arg_0.kwargs) and 'log_config' not in arg_0.kwargs:
                arg_0.kwargs['log_config'] = arg_0.config_file
        return arg_0.kwargs


def Func(arg_0, arg_1):
        """Adds parameters and config from the `.ini` file to the trajectory"""
        if arg_0.config_file:
            arg_2 = arg_0._collect_section('parameters')
            for arg_3 in arg_2:
                arg_4 = arg_2[arg_3]
                if not isinstance(arg_4, tuple):
                    arg_4 = (arg_4,)
                arg_1.f_add_parameter(arg_3, *arg_4)
            arg_5 = arg_0._collect_section('config')
            for arg_3 in arg_5:
                arg_4 = arg_5[arg_3]
                if not isinstance(arg_4, tuple):
                    arg_4 = (arg_4,)
                arg_1.f_add_config(arg_3, *arg_4)


def Func(arg_0):
    """ Converts a rule given as an integer into a binary list representation.

    It reads from left to right (contrary to the Wikipedia article given below),
    i.e. the 2**0 is found on the left hand side and 2**7 on the right.

    For example:

        ``Func(30)`` returns [0, 1, 1, 1, 1, 0, 0, 0]

    The resulting binary list can be interpreted as
    the following transition table:

         neighborhood  new cell state
                000     0
                001     1
                010     1
                011     1
                100     1
                101     0
                110     0
                111     0

    For more information about this rule
    see: http://en.wikipedia.org/wiki/Rule_30

    """
    arg_1 = [(arg_0 // pow(2,i)) % 2 for i in range(8)]
    return np.array(arg_1)


def Func(arg_0, arg_1, arg_2=42):
    """ Creates an initial state for the automaton.

    :param name:

        Either ``'single'`` for a single live cell in the middle of the cell ring,
        or ``'random'`` for uniformly distributed random pattern of zeros and ones.

    :param ncells: Number of cells in the automaton

    :param seed: Random number seed for the ``#random'`` condition

    :return: Numpy array of zeros and ones (or just a one lonely one surrounded by zeros)

    :raises: ValueError if the ``name`` is unknown

    """
    if arg_0 == 'single':
        arg_3 = np.zeros(arg_1)
        arg_3[arg_4(arg_1/2)] = 1.0
        return arg_3
    elif arg_0 == 'random':
        np.random.seed(arg_2)
        arg_5 = np.random.randint(2, size=arg_1)
        return arg_5
    else:
        raise ValueError('I cannot handel your initial state `%s`.' % arg_0)


def Func(arg_0, arg_1, arg_2):
    """ Plots an automaton ``pattern`` and stores the image under a given ``filename``.

    For axes labels the ``rule_number`` is also required.

    """
    plt.figure()
    plt.imshow(arg_0)
    plt.xlabel('Cell No.')
    plt.ylabel('Time Step')
    plt.title('CA with Rule %s' % str(arg_1))
    plt.savefig(arg_2)
    #plt.show()
    plt.close()


def Func(arg_0, arg_1, arg_2):
    """ Simulates a 1 dimensional cellular automaton.

    :param initial_state:

        The initial state of *dead* and *alive* cells as a 1D numpy array.
        It's length determines the size of the simulation.

    :param rule_number:

        The update rule as an integer from 0 to 255.

    :param steps:

        Number of cell iterations

    :return:

        A 2D numpy array (steps x len(initial_state)) containing zeros and ones representing
        the automaton development over time.

    """

    arg_3 = len(arg_0)
    # Create an array for the full pattern
    arg_4 = np.zeros((arg_2, arg_3))

    # Pass initial state:
    arg_4[0,:] = arg_0

    # Get the binary rule list
    arg_5 = convert_rule(arg_1)

    # Conversion list to get the position in the binary rule list
    arg_6 = np.array([1, 2, 4])

    # Iterate over all steps to compute the CA
    arg_7 = range(arg_3)
    for arg_8 in range(arg_2-1):
        arg_9 = arg_4[arg_8, :]
        arg_10 = arg_4[arg_8+1, :]
        for arg_11 in arg_7:
            # Get the neighbourhood
            arg_12 = range(arg_11 - 1, arg_11 + 2)
            arg_13 = np.take(arg_9, arg_12, mode='wrap')
            # Convert neighborhood to decimal
            arg_14 = int(np.sum(arg_13 * arg_6))
            # Get next state from rule book
            arg_15 = arg_5[arg_14]
            # Update next state of cell
            arg_10[arg_11] = arg_15

    return arg_4


def Func():
    """ Main simulation function """
    arg_0 = [10, 30, 90, 110, 184]  # rules we want to explore:
    arg_1 = 250  # cell iterations
    arg_2 = 400  # number of cells
    arg_3 = 100042  # RNG seed
    arg_4 = ['single', 'random']  # Initial states we want to explore

    # create a folder for the plots and the data
    arg_5 = os.path.join(os.getcwd(), 'experiments', 'ca_patterns_original')
    if not os.path.isdir(arg_5):
        os.makedirs(arg_5)
    arg_6 = os.path.join(arg_5, 'all_patterns.p')

    print('Computing all patterns')
    arg_7 = []  # list containing the simulation results
    for arg_8, arg_9 in enumerate(arg_0):
        # iterate over all rules
        for arg_10 in arg_4:
            # iterate over the initial states

            # make the initial state
            arg_11 = make_initial_state(arg_10, arg_2, arg_3=arg_3)
            # simulate the automaton
            arg_12 = cellular_automaton_1D(arg_11, arg_9, arg_1)
            # keep the resulting pattern
            arg_7.append((arg_9, arg_10, arg_12))

        # Print a progressbar, because I am always impatient
        #  (ok that's already from pypet, but it's really handy!)
        progressbar(arg_8, len(arg_0), reprint=True)

    # Store all patterns to disk
    with open(arg_6, 'wb') as file:
        pickle.dump(arg_7, file=file)

    # Finally print all patterns
    print('Plotting all patterns')
    for arg_8, arg_13 in enumerate(arg_7):
        arg_9, arg_10, arg_12 = arg_13
        # Plot the pattern
        arg_6 = os.path.join(arg_5, 'rule_%s_%s.png' % (str(arg_9), arg_10))
        plot_pattern(arg_12, arg_9, arg_6)
        progressbar(arg_8, len(arg_7), reprint=True)


def Func(arg_0):
    """
    Convert a numeric timestamp to a timezone-aware datetime.

    A client may override this function to change the default behavior,
    such as to use local time or timezone-naïve times.
    """
    return datetime.datetime.utcfromtimestamp(arg_0).replace(tzinfo=pytz.utc)


def Func(arg_0, arg_1, arg_2):
        """
        Construct a DelayedCommand to come due at `at`, where `at` may be
        a datetime or timestamp.
        """
        arg_1 = arg_0._from_timestamp(arg_1)
        arg_3 = arg_0.from_datetime(arg_1)
        arg_3.delay = arg_1 - now()
        arg_3.target = arg_2
        return arg_3


def Func(arg_0, arg_1, arg_2):
        """
        Schedule a command to run at a specific time each day.
        """
        arg_3 = datetime.timedelta(days=1)
        # convert when to the next datetime matching this time
        arg_4 = datetime.datetime.combine(datetime.date.today(), arg_1)
        if arg_4 < now():
            arg_4 += arg_3
        return arg_0.at_time(arg_0._localize(arg_4), arg_3, arg_2)


def Func(arg_0):
        """Signals the process timer.

        If more time than the display time has passed a message is emitted.

        """
        if not arg_0.active:
            return

        arg_0._updates += 1
        arg_1 = time.time()
        arg_2 = arg_1 - arg_0._last_time
        if arg_2 > arg_0._display_time:
            arg_3 = arg_1 - arg_0._start_time
            arg_4 = int(arg_3) % 60
            arg_5 = int(arg_3) / 60
            if arg_5 == 0:
                arg_6 = '%ds' % arg_4
            else:
                arg_6 = '%dm%02ds' % (arg_5, arg_4)
            arg_7 = arg_0._updates / arg_3
            arg_8 = 'Processed %d nodes in %s (%.2f nodes/s).' % \
                      (arg_0._updates, arg_6, arg_7)
            arg_0._logger.info(arg_8)
            arg_0._last_time = arg_1


def Func(arg_0):
        """Direct link to the overview group"""
        if arg_0.Func_ is None:
            arg_0.Func_ = arg_0._all_create_or_get_groups('overview')[0]
        return arg_0.Func_


def Func(arg_0, arg_1, *arg_2, **arg_3):
        """Loads several items from an iterable

        Iterables are supposed to be of a format like `[(msg, item, args, kwarg),...]`
        If `args` and `kwargs` are not part of a tuple, they are taken from the
        current `args` and `kwargs` provided to this function.

        """
        for arg_4 in arg_1:
            arg_5 = arg_4[0]
            arg_6 = arg_4[1]
            if len(arg_4) > 2:
                arg_2 = arg_4[2]
            if len(arg_4) > 3:
                arg_3 = arg_4[3]
            if len(arg_4) > 4:
                raise RuntimeError('You shall not pass!')

            arg_0.load(arg_5, arg_6, *arg_2, **arg_3)


def Func(arg_0, arg_1):
        """Reads out the properties for storing new data into the hdf5file

        :param traj:

            The trajectory

        """

        for arg_2 in HDF5StorageService.ATTR_LIST:
            try:
                arg_3 = arg_1.f_get('config.hdf5.' + arg_2).f_get()
                setattr(arg_0, arg_2, arg_3)
            except AttributeError:
                arg_0._logger.debug('Could not find `%s` in traj config, '
                                     'using (default) value `%s`.' %
                                     (arg_2, str(getattr(arg_0, arg_2))))

        for arg_2, arg_4 in HDF5StorageService.NAME_TABLE_MAPPING.items():
            try:
                if arg_4 in ('parameters', 'config'):
                    arg_4 += '_overview'
                arg_3 = arg_1.f_get('config.hdf5.overview.' + arg_4).f_get()
                setattr(arg_0, arg_2, arg_3)
            except AttributeError:
                arg_0._logger.debug('Could not find `%s` in traj config, '
                                     'using (default) value `%s`.' %
                                     (arg_4, str(getattr(arg_0, arg_2))))

        for arg_2, arg_5 in HDF5StorageService.PR_ATTR_NAME_MAPPING.items():
            try:
                arg_3 = arg_1.f_get('config.hdf5.' + arg_5).f_get()
                setattr(arg_0, arg_2, arg_3)
            except AttributeError:
                arg_0._logger.debug('Could not find `%s` in traj config, '
                                     'using (default) value `%s`.' %
                                     (arg_5, str(getattr(arg_0, arg_2))))

        if ((not arg_0._overview_results_summary or
                    not arg_0._overview_derived_parameters_summary) and
                    arg_0._purge_duplicate_comments):
            raise RuntimeError('You chose to purge duplicate comments but disabled a summary '
                                   'table. You can only use the purging if you enable '
                                   'the summary tables.')

        arg_0._filters = None


def Func(arg_0, arg_1):
        """Routine to close an hdf5 file

        The file is closed only when `closing=True`. `closing=True` means that
        the file was opened in the current highest recursion level. This prevents re-opening
        and closing of the file if `store` or `load` are called recursively.

        """
        if (not arg_0._keep_open and
                arg_1 and
                    arg_0.is_open):

            arg_2 = arg_0._hdf5file.fileno()
            arg_0._hdf5file.flush()
            try:
                os.fsync(arg_2)
                try:
                    arg_0._hdf5store.flush(fsync=True)
                except TypeError:
                    arg_2 = arg_0._hdf5store._handle.fileno()
                    arg_0._hdf5store.flush()
                    os.fsync(arg_2)
            except OSError as exc:
                # This seems to be the only way to avoid an OSError under Windows
                arg_3 = ('Encountered OSError while flushing file.'
                                   'If you are using Windows, don`t worry! '
                                   'I will ignore the error and try to close the file. '
                                   'Original error: %s' % repr(exc))
                arg_0._logger.debug(arg_3)

            arg_0._hdf5store.close()
            if arg_0._hdf5file.isopen:
                arg_0._logger.error('Could not close HDF5 file!')
            arg_0._hdf5file = None
            arg_0._hdf5store = None
            arg_0._trajectory_group = None
            arg_0._trajectory_name = None
            arg_0._trajectory_index = None
            arg_0._overview_group_ = None
            arg_0._logger.debug('Closing HDF5 file')
            return True
        else:
            return False


def Func(arg_0, arg_1):
        """Extracts file information from kwargs.

        Note that `kwargs` is not passed as `**kwargs` in order to also
        `pop` the elements on the level of the function calling `Func`.

        """
        if 'filename' in arg_1:
            arg_0._filename = arg_1.pop('filename')

        if 'file_title' in arg_1:
            arg_0._file_title = arg_1.pop('file_title')

        if 'trajectory_name' in arg_1:
            arg_0._trajectory_name = arg_1.pop('trajectory_name')

        if 'trajectory_index' in arg_1:
            arg_0._trajectory_index = arg_1.pop('trajectory_index')


def Func(arg_0, arg_1, arg_2, arg_3):
        """Prepares a trajectory for merging.

        This function will already store extended parameters.

        :param traj: Target of merge
        :param changed_parameters: List of extended parameters (i.e. their names).

        """

        if not arg_1._stored:
            arg_1.f_store()

        # Update meta information
        arg_4 = getattr(arg_0._overview_group, 'info')
        arg_5 = arg_0._all_extract_insert_dict(arg_1, arg_4.colnames)
        arg_0._all_add_or_modify_row(arg_1.v_name, arg_5, arg_4, index=0,
                                    flags=(HDF5StorageService.MODIFY_ROW,))

        # Store extended parameters
        for arg_6 in arg_2:
            arg_7 = arg_1.f_get(arg_6)

            try:
                arg_0._all_delete_parameter_or_result_or_group(arg_7)
            except pt.NoSuchNodeError:
                pass  # We are fine and the node did not exist in the first place

        # Increase the run table by the number of new runs
        arg_8 = getattr(arg_0._overview_group, 'runs')
        arg_9 = arg_8.nrows
        arg_0._trj_fill_run_table(arg_1, arg_9, len(arg_1))

        # Extract parameter summary and if necessary create new explored parameter tables
        # in the result groups
        for arg_10 in range(arg_3, len(arg_1)):
            arg_11 = arg_1.f_idx_to_run(arg_10)
            arg_12 = arg_1.f_get_run_information(arg_11)
            arg_12['name'] = arg_11

            arg_1._set_explored_parameters_to_idx(arg_10)

            arg_13 = arg_0._srn_summarize_explored_parameters(list(
                                                            arg_1._explored_parameters.values()))

            arg_12['parameter_summary'] = arg_13

            arg_0._all_add_or_modify_row(arg_11, arg_12, arg_8, index=arg_10,
                                        flags=(HDF5StorageService.MODIFY_ROW,))

        arg_1.f_restore_default()


def Func(arg_0, arg_1, arg_2, arg_3, arg_4, arg_5):
        """Loads meta information about the trajectory

        Checks if the version number does not differ from current pypet version
        Loads, comment, timestamp, name, version from disk in case trajectory is not loaded
        as new. Updates the run information as well.

        """

        arg_6 = arg_0._overview_group.info
        arg_7 = arg_6[0]

        try:
            arg_8 = arg_7['version'].decode('utf-8')
        except (IndexError, ValueError) as ke:
            arg_0._logger.error('Could not check version due to: %s' % str(ke))
            arg_8 = '`COULD NOT BE LOADED`'

        try:
            arg_9 = arg_7['python'].decode('utf-8')
        except (IndexError, ValueError) as ke:
            arg_0._logger.error('Could not check version due to: %s' % str(ke))
            arg_9 = '`COULD NOT BE LOADED`'

        arg_0._trj_check_version(arg_8, arg_9, arg_5)

        # Load the skeleton information
        arg_0._grp_load_group(arg_1, arg_2=arg_2,
                             with_links=False, recursive=False, _traj=arg_1,
                             _as_new=arg_3, _hdf5_group=arg_0._trajectory_group)

        if arg_3:
            arg_10 = int(arg_7['length'])
            for arg_11 in range(arg_10):
                arg_1._add_run_info(arg_11)
        else:
            arg_1._comment =  arg_7['comment'].decode('utf-8')
            arg_1._timestamp = float(arg_7['timestamp'])
            arg_1._trajectory_timestamp = arg_1._timestamp
            arg_1._time = arg_7['time'].decode('utf-8')
            arg_1._trajectory_time = arg_1._time
            arg_1._name = arg_7['name'].decode('utf-8')
            arg_1._trajectory_name = arg_1._name
            arg_1._version = arg_8
            arg_1._python = arg_9

            arg_21 = arg_0._overview_group.runs

            if arg_4:
                for arg_22 in arg_21.iterrows():
                    arg_23 = arg_22['name'].decode('utf-8')
                    arg_24 = int(arg_22['idx'])
                    arg_25 = float(arg_22['timestamp'])
                    arg_26 = arg_22['time'].decode('utf-8')
                    arg_27 = int(arg_22['completed'])
                    arg_28 = arg_22['parameter_summary'].decode('utf-8')
                    arg_29 = arg_22['short_environment_hexsha'].decode('utf-8')

                    # To allow backwards compatibility we need this try catch block
                    try:
                        arg_30 = arg_22['runtime'].decode('utf-8')
                        arg_31 = float(arg_22['finish_timestamp'])
                    except (IndexError, ValueError) as ke:
                        arg_30 = ''
                        arg_31 = 0.0
                        arg_0._logger.debug('Could not load runtime, ' + repr(ke))

                    arg_32 = {'idx': arg_24,
                                 'timestamp': arg_25,
                                 'finish_timestamp': arg_31,
                                 'runtime': arg_30,
                                 'time': arg_26,
                                 'completed': arg_27,
                                 'name': arg_23,
                                 'parameter_summary': arg_28,
                                 'short_environment_hexsha': arg_29}

                    arg_1._add_run_info(**arg_32)
            else:
                arg_1._length = arg_21.nrows

        # Load explorations
        arg_0._trj_load_exploration(arg_1)
        # Load the hdf5 config data:
        arg_0._srvc_load_hdf5_settings()


def Func(arg_0, arg_1, arg_2, arg_3):
        """Checks for version mismatch

        Raises a VersionMismatchError if version of loaded trajectory and current pypet version
        do not match. In case of `force=True` error is not raised only a warning is emitted.

        """
        arg_4 = pypetconstants.python_version_string

        if (arg_1 != VERSION or arg_4 != arg_2) and not arg_3:
            raise pex.VersionMismatchError('Current pypet version is %s used under python %s '
                                           '  but your trajectory'
                                           ' was created with version %s and python %s.'
                                           ' Use >>force=True<< to perform your load regardless'
                                           ' of version mismatch.' %
                                           (VERSION, arg_4, arg_1, arg_2))
        elif arg_1 != VERSION or arg_4 != arg_2:
            arg_0._logger.warning('Current pypet version is %s with python %s but your trajectory'
                                 ' was created with version %s under python %s.'
                                 ' Yet, you enforced the load, so I will'
                                 ' handle the trajectory despite the'
                                 ' version mismatch.' %
                                 (VERSION, arg_4, arg_1, arg_2))


def Func(arg_0, arg_1, arg_2, arg_3):
        """Fills the `run` overview table with information.

        Will also update new information.

        """

        def _make_row(arg_4):
            arg_5 = (arg_4['idx'],
                   arg_4['name'],
                   arg_4['time'],
                   arg_4['timestamp'],
                   arg_4['finish_timestamp'],
                   arg_4['runtime'],
                   arg_4['parameter_summary'],
                   arg_4['short_environment_hexsha'],
                   arg_4['completed'])
            return arg_5

        arg_6 = getattr(arg_0._overview_group, 'runs')

        arg_7 = []
        arg_8 = arg_1._updated_run_information
        for arg_9 in range(arg_2, arg_3):
            arg_4 = arg_1._run_information[arg_1._single_run_ids[arg_9]]
            arg_7.append(_make_row(arg_4))
            arg_8.discard(arg_9)

        if arg_7:
            arg_6.append(arg_7)
            arg_6.flush()

        # Store all runs that are updated and that have not been stored yet
        arg_7 = []
        arg_10 = []
        for arg_9 in arg_8:
            arg_4 = arg_1.f_get_run_information(arg_9, copy=False)
            arg_7.append(_make_row(arg_4))
            arg_10.append(arg_9)

        if arg_7:
            arg_6.modify_coordinates(arg_10, arg_7)

        arg_1._updated_run_information = set()


def Func(arg_0, arg_1):
        """Recalls names of all explored parameters"""
        if hasattr(arg_0._overview_group, 'explorations'):
            arg_2 = arg_0._overview_group._f_get_child( 'explorations')
            for arg_3 in arg_2.iterrows():
                arg_4 = arg_3['explorations'].decode('utf-8')
                if arg_4 not in arg_1._explored_parameters:
                    arg_1._explored_parameters[arg_4] = None
        else:
            # This is for backwards compatibility
            for arg_6 in ('parameters', 'derived_parameters'):
                if hasattr(arg_0._trajectory_group, arg_6):
                    arg_7 = arg_0._trajectory_group._f_get_child(arg_6)
                    for arg_8 in arg_7._f_walk_groups():
                        if arg_0._all_get_from_attrs(arg_8, HDF5StorageService.LENGTH):
                            arg_9 = arg_8._v_pathname
                            arg_10 = '.'.join(arg_9.split('/')[2:])
                            arg_1._explored_parameters[arg_10] = None


def Func(arg_0, arg_1, arg_2=None):
        """Creates the overview tables in overview group"""
        for arg_3 in arg_1:
            # Prepare the tables desciptions, depending on which overview table we create
            # we need different columns
            arg_4 = {}
            arg_5 = 0

            # Every overview table has a name and location column
            arg_4['location'] = pt.StringCol(
                pypetconstants.HDF5_STRCOL_MAX_LOCATION_LENGTH,
                pos=0)
            arg_4['name'] = pt.StringCol(pypetconstants.HDF5_STRCOL_MAX_NAME_LENGTH,
                                                        pos=1)

            arg_4['comment'] = pt.StringCol(
                    pypetconstants.HDF5_STRCOL_MAX_COMMENT_LENGTH)

            arg_4['value'] = pt.StringCol(
                    pypetconstants.HDF5_STRCOL_MAX_VALUE_LENGTH, pos=2)

            if arg_3 == 'config_overview':
                if arg_2 is not None:
                    arg_5 = len(arg_2._config)

            if arg_3 == 'parameters_overview':
                if arg_2 is not None:
                    arg_5 = len(arg_2._parameters)

            if arg_3 == 'explored_parameters_overview':
                arg_4['range'] = pt.StringCol(
                    pypetconstants.HDF5_STRCOL_MAX_RANGE_LENGTH)
                arg_4['length'] = pt.IntCol()
                if arg_2 is not None:
                    arg_5 = len(arg_2._explored_parameters)

            if arg_3.endswith('summary'):
                arg_4['hexdigest'] = pt.StringCol(64, pos=10)

            # Check if the user provided an estimate of the amount of results per run
            # This can help to speed up storing
            if arg_3 == 'derived_parameters_overview':

                arg_5 = arg_0._derived_parameters_per_run

                if arg_2 is not None:
                    arg_5 *= len(arg_2)
                    arg_5 += len(arg_2._derived_parameters)

            if arg_3 == 'results_overview':
                arg_5 = arg_0._results_per_run

                if arg_2 is not None:
                    arg_5 *= len(arg_2)
                    arg_5 += len(arg_2._results)

            if arg_5 > 0:
                arg_6 = arg_0._all_get_or_create_table(where=arg_0._overview_group,
                                                           tablename=arg_3,
                                                           description=arg_4,
                                                           arg_5=arg_5)
            else:
                arg_6 = arg_0._all_get_or_create_table(where=arg_0._overview_group,
                                                           tablename=arg_3,
                                                           description=arg_4)

            arg_6.flush()


def Func(arg_0, arg_1, arg_2=False, arg_3=arg_4.STORE_DATA,
                              arg_6=None):
        """ Stores a trajectory to an hdf5 file

        Stores all groups, parameters and results

        """
        if not arg_2:
            arg_0._logger.info('Start storing Trajectory `%s`.' % arg_0._trajectory_name)
        else:
            arg_0._logger.info('Initialising storage or updating meta data of Trajectory `%s`.' %
                              arg_0._trajectory_name)
            arg_3 = arg_4.STORE_NOTHING

        # In case we accidentally chose a trajectory name that already exist
        # We do not want to mess up the stored trajectory but raise an Error
        if not arg_1._stored and arg_0._trajectory_group is not None:
            raise RuntimeError('You want to store a completely new trajectory with name'
                               ' `%s` but this trajectory is already found in file `%s`.'
                               'Did you try to accidentally overwrite existing data? If '
                               'you DO want to override existing data, use `overwrite_file=True`.'
                               'Note that this deletes the whole HDF5 file not just the particular '
                               'trajectroy therein! ' %
                               (arg_1.v_name, arg_0._filename))

        # Extract HDF5 settings from the trajectory
        arg_0._srvc_check_hdf_properties(arg_1)

        # Store the trajectory for the first time if necessary:
        if arg_0._trajectory_group is None:
            arg_0._trajectory_group = arg_0._hdf5file.create_group(where='/',
                                                           name=arg_0._trajectory_name,
                                                           title=arg_0._trajectory_name,
                                                           filters=arg_0._all_get_filters())
        # Store meta information
        arg_0._trj_store_meta_data(arg_1)

        # # Store recursively the config subtree
        # self._tree_store_recursively(pypetconstants.LEAF,traj.config,self._trajectory_group)

        if arg_3 in (arg_4.STORE_DATA_SKIPPING,
                          arg_4.STORE_DATA,
                          arg_4.OVERWRITE_DATA):

            arg_8 = 0
            arg_9 = 10
            arg_10 = set(['parameters', 'config', 'derived_parameters', 'results'])

            for arg_11 in arg_1._children:

                if arg_11 in arg_10:
                    arg_0._logger.info('Storing branch `%s`.' % arg_11)
                else:
                    if arg_8 < arg_9:
                        arg_0._logger.info('Storing branch/node `%s`.' % arg_11)
                    elif arg_8 == arg_9:
                        arg_0._logger.info('To many branches or nodes at root for display. '
                                          'I will not inform you about storing anymore. '
                                          'Branches are stored silently in the background. '
                                          'Do not worry, I will not freeze! Pinky promise!!!')
                    arg_8 += 1

                # Store recursively the elements
                arg_0._tree_store_sub_branch(arg_1, arg_11, arg_3=arg_3,
                                            with_links=True,
                                            recursive=True, arg_6=arg_6,
                                            hdf5_group=arg_0._trajectory_group)

            arg_0._logger.info('Finished storing Trajectory `%s`.' % arg_0._trajectory_name)
        else:
            arg_0._logger.info('Finished init or meta data update for `%s`.' %
                              arg_0._trajectory_name)
        arg_1._stored = True


def Func(arg_0, arg_1, arg_2, arg_3, arg_4, arg_5,
                          arg_6, arg_7,
                          arg_8):
        """Stores a node to hdf5 and if desired stores recursively everything below it.

        :param parent_traj_node: The parental node
        :param name: Name of node to be stored
        :param store_data: How to store data
        :param with_links: If links should be stored
        :param recursive: Whether to store recursively the subtree
        :param max_depth: Maximum recursion depth in tree
        :param current_depth: Current depth
        :param parent_hdf5_group: Parent hdf5 group

        """
        if arg_6 is None:
            arg_6 = float('inf')

        arg_9 = [(arg_1, arg_2, arg_7, arg_8)]

        while arg_9:
            arg_1, arg_2, arg_7, arg_8 = arg_9.pop()

            # Check if we create a link
            if arg_2 in arg_1._links:
                if arg_4:
                    arg_0._tree_store_link(arg_1, arg_2, arg_8)
                continue

            arg_10 = arg_1._children[arg_2]

            # If the node does not exist in the hdf5 file create it
            if not hasattr(arg_8, arg_2):
                arg_11 = True
                arg_12 = arg_0._hdf5file.create_group(where=arg_8,
                                                       arg_2=arg_2, filters=arg_0._all_get_filters())
            else:
                arg_11 = False
                arg_12 = getattr(arg_8, arg_2)

            if arg_10.v_is_leaf:
                arg_0._prm_store_parameter_or_result(arg_10, arg_3=arg_3,
                                                     _hdf5_group=arg_12,
                                                    _newly_created=arg_11)

            else:
                arg_0._grp_store_group(arg_10, arg_3=arg_3, arg_4=arg_4,
                                      arg_5=False, arg_6=arg_6,
                                      _hdf5_group=arg_12,
                                      _newly_created=arg_11)

                if arg_5 and arg_7 < arg_6:
                    for arg_13 in arg_10._children.keys():
                        arg_9.append((arg_10, arg_13, arg_7 + 1, arg_12))


def Func(arg_0, arg_1, arg_2, arg_3,
                                               arg_4=None):
        """Stores a single row into an overview table

        :param instance: A parameter or result instance

        :param table: Table where row will be inserted

        :param flags:

            Flags how to insert into the table. Potential Flags are
            `ADD_ROW`, `REMOVE_ROW`, `MODIFY_ROW`

        :param additional_info:

            Dictionary containing information that cannot be extracted from
            `instance`, but needs to be inserted, too.

        """
        # assert isinstance(table, pt.Table)

        arg_5 = arg_1.v_location
        arg_6 = arg_1.v_name
        arg_7 = arg_1.v_full_name

        if (arg_3 == (HDF5StorageService.ADD_ROW,) and arg_2.nrows < 2
                and 'location' in arg_2.colnames):
            # We add the modify row option here because you cannot delete the very first
            # row of the table, so there is the rare condition, that the row might already
            # exist.
            # We also need to check if 'location' is in the columns in order to avoid
            # confusion with the smaller explored parameter overviews
            arg_3 = (HDF5StorageService.ADD_ROW, HDF5StorageService.MODIFY_ROW)

        if arg_3 == (HDF5StorageService.ADD_ROW,):
            # If we are sure we only want to add a row we do not need to search!
            arg_8 = None
            arg_9 = None
        else:
            # Condition to search for an entry
            arg_8 = {'namecol': arg_2.cols.name, 'locationcol': arg_2.cols.location,
                        'name': arg_6, 'location': arg_5}

            arg_9 = """(namecol == name) & (locationcol == location)"""

        if HDF5StorageService.REMOVE_ROW in arg_3:
            # If we want to remove a row, we don't need to extract information
            arg_10 = {}
        else:
            # Extract information to insert from the instance and the additional info dict
            arg_11 = set(arg_2.colnames)
            arg_10 = arg_0._all_extract_insert_dict(arg_1, arg_11, arg_4)

        # Write the table entry
        arg_0._all_add_or_modify_row(arg_7, arg_10, arg_2, arg_9=arg_9,
                                    arg_8=arg_8, arg_3=arg_3)


def Func(arg_0, arg_1, arg_2, arg_3, arg_4=None):
        """Creates a new table, or if the table already exists, returns it."""
        arg_5 = arg_0._hdf5file.get_node(arg_1)

        if not arg_2 in arg_5:
            if not arg_4 is None:
                arg_6 = arg_0._hdf5file.create_table(arg_1=arg_5, name=arg_2,
                                              arg_3=arg_3, title=arg_2,
                                              arg_4=arg_4,
                                              filters=arg_0._all_get_filters())
            else:
                arg_6 = arg_0._hdf5file.create_table(arg_1=arg_5, name=arg_2,
                                              arg_3=arg_3, title=arg_2,
                                              filters=arg_0._all_get_filters())
        else:
            arg_6 = arg_5._f_get_child(arg_2)

        return arg_6


def Func(arg_0, arg_1):
        """Returns an HDF5 node by the path specified in `name`"""
        arg_2 = arg_1.replace('.', '/')
        arg_3 = '/%s/%s' % (arg_0._trajectory_name, arg_2)
        return arg_0._hdf5file.get_node(arg_3=arg_3)