if self._func is None:<EOL><INDENT>self._func = NNTreeNodeFunc(self)<EOL><DEDENT>return self._func<EOL>

Alternative naming, you can use `node.func.name` instead of `node.f_func`


return self._stored<EOL>

Whether or not this tree node has been stored to disk before.


return self._comment<EOL>


comment = str(comment)<EOL>self._comment = comment<EOL>


return self._depth<EOL>

Depth of the node in the trajectory tree.


return self._is_leaf<EOL>

Whether node is a leaf or not (i.e. it is a group node)


return not self._is_leaf<EOL>

Whether node is a group or not (i.e. it is a leaf node)


return self._depth == <NUM_LIT:0><EOL>

Whether the group is root (True for the trajectory and a single run object)


return self._full_name<EOL>

The full name, relative to the root node.

        The full name of a trajectory or single run is the empty string since it is root.


return self._name<EOL>


return self._full_name[:-len(self._name) - <NUM_LIT:1>]<EOL>

Location relative to the root node.

        The location of a trajectory or single run is the empty string since it is root.


return self._run_branch<EOL>

If this node is hanging below a branch named `run_XXXXXXXXX`.

        The branch name is either the name of a single run
        (e.g. 'run_00000009') or 'trajectory'.


return self._branch<EOL>

The name of the branch/subtree, i.e. the first node below the root.

        The empty string in case of root itself.


self._full_name = full_name<EOL>if full_name:<EOL><INDENT>self._name = full_name.rsplit('<STR_LIT:.>', <NUM_LIT:1>)[-<NUM_LIT:1>]<EOL><DEDENT>


def _set_details(self, depth, branch, run_branch):

self._depth = depth<EOL>self._branch = branch<EOL>self._run_branch = run_branch<EOL>

Sets some details for internal handling.


return self.__class__.__name__<EOL>

Returns the class name of the parameter or result or group.

        Equivalent to `obj.__class__.__name__`


return False<EOL>

Whether or not fast access can be supported by the parameter or result.

        ABSTRACT: Needs to be implemented by subclass.


return self._is_parameter<EOL>

Whether the node is a parameter or not (i.e. a result)


return '<STR_LIT>'<EOL>

Returns a string summarizing the data handled by the parameter or result

        ABSTRACT: Needs to be implemented by subclass, otherwise the empty string is returned.


return self.v_full_name<EOL>

String representation of the parameter or result.

        If not specified in subclass this is simply the full name.


return {}<EOL>

Currently not used because I let the storage service infer how to store
        stuff from the data itself.

        If you write your own parameter or result you can implement this function
        to make specifications on how to store data,
        see also :func:`pypet.storageservice.HDF5StorageService.store`.

        :returns: {} (Empty dictionary)


return {}<EOL>

Currently not used because I let the storage service infer how to load
        stuff from the data itself.

        If you write your own parameter or result you can implement this function
        to make specifications on how to load data,
        see also :func:`pypet.storageservice.HDF5StorageService.store`.

        :returns: {} (Empty dictionary)


raise NotImplementedError('<STR_LIT>')<EOL>

Method called by the storage service for serialization.

        The method converts the parameter's or result's value(s) into  simple
        data structures that can be stored to disk.
        Returns a dictionary containing these simple structures.

        Understood basic structures are

        * python natives (int, long, str,bool,float,complex)

        * python lists and tuples

        * numpy natives arrays, and matrices of type
          np.int8-64, np.uint8-64, np.float32-64, np.complex, np.str

        * python dictionaries of the previous types (flat not nested!)

        * pandas data frames

        * object tables (see :class:`~pypet.parameter.ObjectTable`)

        :return: A dictionary containing basic data structures.

        ABSTRACT: Needs to be implemented by subclass


Method called by the storage service to reconstruct the original result.

        Data contained in the load_dict is equal to the data provided by the result or parameter
        when previously called with _store().

        :param load_dict:

            The dictionary containing basic data structures, see also
            :func:`~pypet.naturalnaming.NNLeafNode._store`.

        ABSTRACT: Needs to be implemented by subclass


Returns true if no data is handled by a result or parameter.

        ABSTRACT: Needs to be implemented by subclass


Removes all data from the result or parameter.

        If the result has already been stored to disk via a trajectory and a storage service,
        the data on disk is not affected by `f_empty`.

        Yet, this function is particularly useful if you have stored very large data to disk
        and you want to free some memory on RAM but still keep the skeleton of your result or
        parameter.

        Note that freeing RAM requires that all references to the data are deleted. If you
        reference the data somewhere else in your code, the data is not erased from RAM.

        ABSTRACT: Needs to be implemented by subclass


root = self._root_instance<EOL>if type_name == RESULT:<EOL><INDENT>return root._results<EOL><DEDENT>elif type_name == PARAMETER:<EOL><INDENT>return root._parameters<EOL><DEDENT>elif type_name == DERIVED_PARAMETER:<EOL><INDENT>return root._derived_parameters<EOL><DEDENT>elif type_name == CONFIG:<EOL><INDENT>return root._config<EOL><DEDENT>elif type_name == LEAF:<EOL><INDENT>return root._other_leaves<EOL><DEDENT>else:<EOL><INDENT>raise RuntimeError('<STR_LIT>')<EOL><DEDENT>

Maps a an instance type representation string (e.g. 'RESULT')
        to the corresponding dictionary in root.


def _fetch_from_string(self, store_load, name, args, kwargs):

if not isinstance(name, str):<EOL><INDENT>raise TypeError('<STR_LIT>')<EOL><DEDENT>node = self._root_instance.f_get(name)<EOL>return self._fetch_from_node(store_load, node, args, kwargs)<EOL>

Method used by f_store/load/remove_items to find a corresponding item in the tree.

        :param store_load:

            String constant specifying if we want to store, load or remove.
            The corresponding constants are defined at the top of this module.

        :param name: String name of item to store, load or remove.

        :param args: Additional arguments passed to the storage service

        :param kwargs: Additional keyword arguments passed to the storage service

        :return:

            A formatted request that can be handled by the storage service, aka
            a tuple: (msg, item_to_store_load_or_remove, args, kwargs)


def _fetch_from_node(self, store_load, node, args, kwargs):

msg = self._node_to_msg(store_load, node)<EOL>return msg, node, args, kwargs<EOL>

Method used by f_store/load/remove_items to find a corresponding item in the tree.

        :param store_load: String constant specifying if we want to store, load or remove
        :param node: A group, parameter or result instance.
        :param args: Additional arguments passed to the storage service
        :param kwargs: Additional keyword arguments passed to the storage service

        :return:

            A formatted request that can be handled by the storage service, aka
            a tuple: (msg, item_to_store_load_or_remove, args, kwargs)


def _fetch_from_tuple(self, store_load, store_tuple, args, kwargs):

node = store_tuple[<NUM_LIT:1>]<EOL>msg = store_tuple[<NUM_LIT:0>]<EOL>if len(store_tuple) > <NUM_LIT:2>:<EOL><INDENT>args = store_tuple[<NUM_LIT:2>]<EOL><DEDENT>if len(store_tuple) > <NUM_LIT:3>:<EOL><INDENT>kwargs = store_tuple[<NUM_LIT:3>]<EOL><DEDENT>if len(store_tuple) > <NUM_LIT:4>:<EOL><INDENT>raise ValueError('<STR_LIT>'<EOL>'<STR_LIT>' % str(store_tuple))<EOL><DEDENT>_ = self._fetch_from_node(store_load, node, args, kwargs)<EOL>return msg, node, args, kwargs<EOL>

Method used by f_store/load/remove_items to find a corresponding item in the tree.

        The input to the method should already be in the correct format, this method only
        checks for sanity.

        :param store_load: String constant specifying if we want to store, load or remove

        :param store_tuple:

            Tuple already in correct format (msg, item, args, kwargs). If args and kwargs
            are not given, they are taken from the supplied parameters

        :param args: Additional arguments passed to the storage service if len(store_tuple)<3

        :param kwargs:

            Additional keyword arguments passed to the storage service if
            ``len(store_tuple)<4``

        :return:

            A formatted request that can be handled by the storage service, aka
            a tuple: (msg, item_to_store_load_or_remove, args, kwargs)


if node.v_is_leaf:<EOL><INDENT>if store_load == STORE:<EOL><INDENT>return pypetconstants.LEAF<EOL><DEDENT>elif store_load == LOAD:<EOL><INDENT>return pypetconstants.LEAF<EOL><DEDENT>elif store_load == REMOVE:<EOL><INDENT>return pypetconstants.DELETE<EOL><DEDENT><DEDENT>else:<EOL><INDENT>if store_load == STORE:<EOL><INDENT>return pypetconstants.GROUP<EOL><DEDENT>elif store_load == LOAD:<EOL><INDENT>return pypetconstants.GROUP<EOL><DEDENT>elif store_load == REMOVE:<EOL><INDENT>return pypetconstants.DELETE<EOL><DEDENT><DEDENT>

Maps a given node and a store_load constant to the message that is understood by
        the storage service.


def _fetch_items(self, store_load, iterable, args, kwargs):

only_empties = kwargs.pop('<STR_LIT>', False)<EOL>non_empties = kwargs.pop('<STR_LIT>', False)<EOL>item_list = []<EOL>for iter_item in iterable:<EOL><INDENT>try:<EOL><INDENT>item_tuple = self._fetch_from_string(store_load, iter_item, args, kwargs)<EOL><DEDENT>except TypeError:<EOL><INDENT>try:<EOL><INDENT>item_tuple = self._fetch_from_node(store_load, iter_item, args, kwargs)<EOL><DEDENT>except AttributeError:<EOL><INDENT>item_tuple = self._fetch_from_tuple(store_load, iter_item, args, kwargs)<EOL><DEDENT><DEDENT>item = item_tuple[<NUM_LIT:1>]<EOL>msg = item_tuple[<NUM_LIT:0>]<EOL>if item.v_is_leaf:<EOL><INDENT>if only_empties and not item.f_is_empty():<EOL><INDENT>continue<EOL><DEDENT>if non_empties and item.f_is_empty():<EOL><INDENT>continue<EOL><DEDENT><DEDENT>item_list.append(item_tuple)<EOL><DEDENT>return item_list<EOL>

Method used by f_store/load/remove_items to find corresponding items in the tree.

        :param store_load:

            String constant specifying if we want to store, load or remove.
            The corresponding constants are defined at the top of this module.

        :param iterable:

            Iterable over items to look for in the tree. Can be strings specifying names,
            can be the item instances themselves or already correctly formatted tuples.

        :param args: Additional arguments passed to the storage service

        :param kwargs:

            Additional keyword arguments passed to the storage service.
            Two optional keyword arguments are popped and used by this method.

            only_empties:

                Can be in kwargs if only empty parameters and results should be considered.

            non_empties:

                Can be in kwargs if only non-empty parameters and results should be considered.

        :return:

            A list containing formatted tuples.
            These tuples can be handled by the storage service, they have
            the following format: (msg, item_to_store_load_or_remove, args, kwargs)


def _remove_subtree(self, start_node, name, predicate=None):

def _delete_from_children(node, child_name):<EOL><INDENT>del node._children[child_name]<EOL>if child_name in node._groups:<EOL><INDENT>del node._groups[child_name]<EOL><DEDENT>elif child_name in node._leaves:<EOL><INDENT>del node._leaves[child_name]<EOL><DEDENT>else:<EOL><INDENT>raise RuntimeError('<STR_LIT>')<EOL><DEDENT><DEDENT>def _remove_subtree_inner(node, predicate):<EOL><INDENT>if not predicate(node):<EOL><INDENT>return False<EOL><DEDENT>elif node.v_is_group:<EOL><INDENT>for name_ in itools.chain(list(node._leaves.keys()),<EOL>list(node._groups.keys())):<EOL><INDENT>child_ = node._children[name_]<EOL>child_deleted = _remove_subtree_inner(child_, predicate)<EOL>if child_deleted:<EOL><INDENT>_delete_from_children(node, name_)<EOL>del child_<EOL><DEDENT><DEDENT>for link_ in list(node._links.keys()):<EOL><INDENT>node.f_remove_link(link_)<EOL><DEDENT>if len(node._children) == <NUM_LIT:0>:<EOL><INDENT>self._delete_node(node)<EOL>return True<EOL><DEDENT>else:<EOL><INDENT>return False<EOL><DEDENT><DEDENT>else:<EOL><INDENT>self._delete_node(node)<EOL>return True<EOL><DEDENT><DEDENT>if name in start_node._links:<EOL><INDENT>start_node.f_remove_link(name)<EOL><DEDENT>else:<EOL><INDENT>child = start_node._children[name]<EOL>if predicate is None:<EOL><INDENT>predicate = lambda x: True<EOL><DEDENT>if _remove_subtree_inner(child, predicate):<EOL><INDENT>_delete_from_children(start_node, name)<EOL>del child<EOL>return True<EOL><DEDENT>else:<EOL><INDENT>return False<EOL><DEDENT><DEDENT>

Removes a subtree from the trajectory tree.

        Does not delete stuff from disk only from RAM.

        :param start_node: The parent node from where to start
        :param name: Name of child which will be deleted and recursively all nodes below the child
        :param predicate:

            Predicate that can be used to compute for individual nodes if they should be removed
            ``True`` or kept ``False``.


full_name = node.v_full_name<EOL>root = self._root_instance<EOL>if full_name == '<STR_LIT>':<EOL><INDENT>return<EOL><DEDENT>if node.v_is_leaf:<EOL><INDENT>if full_name in root._parameters:<EOL><INDENT>del root._parameters[full_name]<EOL><DEDENT>elif full_name in root._config:<EOL><INDENT>del root._config[full_name]<EOL><DEDENT>elif full_name in root._derived_parameters:<EOL><INDENT>del root._derived_parameters[full_name]<EOL><DEDENT>elif full_name in root._results:<EOL><INDENT>del root._results[full_name]<EOL><DEDENT>elif full_name in root._other_leaves:<EOL><INDENT>del root._other_leaves[full_name]<EOL><DEDENT>if full_name in root._explored_parameters:<EOL><INDENT>if root._stored:<EOL><INDENT>root._explored_parameters[full_name] = None<EOL><DEDENT>else:<EOL><INDENT>del root._explored_parameters[full_name]<EOL><DEDENT>if len(root._explored_parameters) == <NUM_LIT:0>:<EOL><INDENT>root.f_shrink()<EOL><DEDENT><DEDENT>del self._flat_leaf_storage_dict[full_name]<EOL><DEDENT>else:<EOL><INDENT>del root._all_groups[full_name]<EOL>if full_name in root._run_parent_groups:<EOL><INDENT>del root._run_parent_groups[full_name]<EOL><DEDENT><DEDENT>if full_name in root._linked_by:<EOL><INDENT>linking = root._linked_by[full_name]<EOL>for linking_name in list(linking.keys()):<EOL><INDENT>linking_group, link_set = linking[linking_name]<EOL>for link in list(link_set):<EOL><INDENT>linking_group.f_remove_link(link)<EOL><DEDENT><DEDENT><DEDENT>if (node.v_location, node.v_name) in self._root_instance._new_nodes:<EOL><INDENT>del self._root_instance._new_nodes[(node.v_location, node.v_name)]<EOL><DEDENT>self._remove_from_nodes_and_leaves(node)<EOL>node._vars = None<EOL>node._func = None<EOL>

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!)


def _remove_node_or_leaf(self, instance, recursive=False):

full_name = instance.v_full_name<EOL>split_name = deque(full_name.split('<STR_LIT:.>'))<EOL>self._remove_along_branch(self._root_instance, split_name, recursive)<EOL>

Removes a single node from the tree.

        Only from RAM not from hdf5 file!

        :param instance: The node to be deleted

        :param recursive: If group nodes with children should be deleted


def _remove_along_branch(self, actual_node, split_name, recursive=False):

<EOL>if len(split_name) == <NUM_LIT:0>:<EOL><INDENT>if actual_node.v_is_group and actual_node.f_has_children():<EOL><INDENT>if recursive:<EOL><INDENT>for child in list(actual_node._children.keys()):<EOL><INDENT>actual_node.f_remove_child(child, recursive=True)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>raise TypeError('<STR_LIT>'<EOL>'<STR_LIT>' % actual_node.v_full_name)<EOL><DEDENT><DEDENT>self._delete_node(actual_node)<EOL>return True<EOL><DEDENT>name = split_name.popleft()<EOL>if name in actual_node._links:<EOL><INDENT>if len(split_name)><NUM_LIT:0>:<EOL><INDENT>raise RuntimeError('<STR_LIT>')<EOL><DEDENT>actual_node.f_remove_link(name)<EOL><DEDENT>else:<EOL><INDENT>child = actual_node._children[name]<EOL>if self._remove_along_branch(child, split_name, recursive=recursive):<EOL><INDENT>del actual_node._children[name]<EOL>if name in actual_node._groups:<EOL><INDENT>del actual_node._groups[name]<EOL><DEDENT>elif name in actual_node._leaves:<EOL><INDENT>del actual_node._leaves[name]<EOL><DEDENT>else:<EOL><INDENT>raise RuntimeError('<STR_LIT>')<EOL><DEDENT>del child<EOL>return False<EOL><DEDENT><DEDENT>

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 isinstance(name, int):<EOL><INDENT>return True, self._root_instance.f_wildcard('<STR_LIT:$>', name)<EOL><DEDENT>if name.startswith('<STR_LIT>') or name.startswith('<STR_LIT>'):<EOL><INDENT>split_name = name.split('<STR_LIT:_>')<EOL>if len(split_name) == <NUM_LIT:2>:<EOL><INDENT>index = split_name[<NUM_LIT:1>]<EOL>if index.isdigit():<EOL><INDENT>return True, self._root_instance.f_wildcard('<STR_LIT:$>', int(index))<EOL><DEDENT>elif index == '<STR_LIT:A>':<EOL><INDENT>return True, self._root_instance.f_wildcard('<STR_LIT:$>', -<NUM_LIT:1>)<EOL><DEDENT><DEDENT><DEDENT>if name.startswith('<STR_LIT>') or name.startswith('<STR_LIT>'):<EOL><INDENT>split_name = name.split('<STR_LIT:_>')<EOL>if len(split_name) == <NUM_LIT:2>:<EOL><INDENT>index = split_name[<NUM_LIT:1>]<EOL>if index.isdigit():<EOL><INDENT>return True, self._root_instance.f_wildcard('<STR_LIT>', int(index))<EOL><DEDENT>elif index == '<STR_LIT:A>':<EOL><INDENT>return True, self._root_instance.f_wildcard('<STR_LIT>', -<NUM_LIT:1>)<EOL><DEDENT><DEDENT><DEDENT>if name in SHORTCUT_SET:<EOL><INDENT>if name == '<STR_LIT>':<EOL><INDENT>return True, '<STR_LIT>'<EOL><DEDENT>elif name == '<STR_LIT>':<EOL><INDENT>return True, '<STR_LIT>'<EOL><DEDENT>elif name == '<STR_LIT>':<EOL><INDENT>return True, '<STR_LIT>'<EOL><DEDENT>elif name == '<STR_LIT>':<EOL><INDENT>return True, '<STR_LIT>'<EOL><DEDENT>else:<EOL><INDENT>raise RuntimeError('<STR_LIT>')<EOL><DEDENT><DEDENT>return False, name<EOL>

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.


def _add_prefix(self, split_names, start_node, group_type_name):

root = self._root_instance<EOL>prepend = []<EOL>if start_node.v_depth < <NUM_LIT:3> and not group_type_name == GROUP:<EOL><INDENT>if start_node.v_depth == <NUM_LIT:0>:<EOL><INDENT>if group_type_name == DERIVED_PARAMETER_GROUP:<EOL><INDENT>if split_names[<NUM_LIT:0>] == '<STR_LIT>':<EOL><INDENT>return split_names<EOL><DEDENT>else:<EOL><INDENT>prepend += ['<STR_LIT>']<EOL><DEDENT><DEDENT>elif group_type_name == RESULT_GROUP:<EOL><INDENT>if split_names[<NUM_LIT:0>] == '<STR_LIT>':<EOL><INDENT>return split_names<EOL><DEDENT>else:<EOL><INDENT>prepend += ['<STR_LIT>']<EOL><DEDENT><DEDENT>elif group_type_name == CONFIG_GROUP:<EOL><INDENT>if split_names[<NUM_LIT:0>] == '<STR_LIT>':<EOL><INDENT>return split_names<EOL><DEDENT>else:<EOL><INDENT>prepend += ['<STR_LIT>']<EOL><DEDENT><DEDENT>elif group_type_name == PARAMETER_GROUP:<EOL><INDENT>if split_names[<NUM_LIT:0>] == '<STR_LIT>':<EOL><INDENT>return split_names[<NUM_LIT:0>]<EOL><DEDENT>else:<EOL><INDENT>prepend += ['<STR_LIT>']<EOL><DEDENT><DEDENT>else:<EOL><INDENT>raise RuntimeError('<STR_LIT>')<EOL><DEDENT><DEDENT>if root._is_run and root._auto_run_prepend:<EOL><INDENT>dummy = root.f_wildcard('<STR_LIT:$>', -<NUM_LIT:1>)<EOL>crun = root.f_wildcard('<STR_LIT:$>')<EOL>if any(name in root._run_information for name in split_names):<EOL><INDENT>pass<EOL><DEDENT>elif any(name == dummy for name in split_names):<EOL><INDENT>pass<EOL><DEDENT>elif (group_type_name == RESULT_GROUP or<EOL>group_type_name == DERIVED_PARAMETER_GROUP):<EOL><INDENT>if start_node.v_depth == <NUM_LIT:0>:<EOL><INDENT>prepend += ['<STR_LIT>', crun]<EOL><DEDENT>elif start_node.v_depth == <NUM_LIT:1>:<EOL><INDENT>if len(split_names) == <NUM_LIT:1> and split_names[<NUM_LIT:0>] == '<STR_LIT>':<EOL><INDENT>return split_names<EOL><DEDENT>else:<EOL><INDENT>prepend += ['<STR_LIT>', crun]<EOL><DEDENT><DEDENT>elif start_node.v_depth == <NUM_LIT:2> and start_node.v_name == '<STR_LIT>':<EOL><INDENT>prepend += [crun]<EOL><DEDENT><DEDENT><DEDENT><DEDENT>if prepend:<EOL><INDENT>split_names = prepend + split_names<EOL><DEDENT>return split_names<EOL>

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.


@staticmethod<EOL><INDENT>def _determine_types(start_node, first_name, add_leaf, add_link):<DEDENT>

if start_node.v_is_root:<EOL><INDENT>where = first_name<EOL><DEDENT>else:<EOL><INDENT>where = start_node._branch<EOL><DEDENT>if where in SUBTREE_MAPPING:<EOL><INDENT>type_tuple = SUBTREE_MAPPING[where]<EOL><DEDENT>else:<EOL><INDENT>type_tuple = (GROUP, LEAF)<EOL><DEDENT>if add_link:<EOL><INDENT>return type_tuple[<NUM_LIT:0>], LINK<EOL><DEDENT>if add_leaf:<EOL><INDENT>return type_tuple<EOL><DEDENT>else:<EOL><INDENT>return type_tuple[<NUM_LIT:0>], type_tuple[<NUM_LIT:0>]<EOL><DEDENT>


def _add_generic(self, start_node, type_name, group_type_name, args, kwargs,<EOL>add_prefix=True, check_naming=True):

args = list(args)<EOL>create_new = True<EOL>name = '<STR_LIT>'<EOL>instance = None<EOL>constructor = None<EOL>add_link = type_name == LINK<EOL>if add_link:<EOL><INDENT>name = args[<NUM_LIT:0>]<EOL>instance = args[<NUM_LIT:1>]<EOL>create_new = False<EOL><DEDENT>elif len(args) == <NUM_LIT:1> and len(kwargs) == <NUM_LIT:0>:<EOL><INDENT>item = args[<NUM_LIT:0>]<EOL>try:<EOL><INDENT>name = item.v_full_name<EOL>instance = item<EOL>create_new = False<EOL><DEDENT>except AttributeError:<EOL><INDENT>pass<EOL><DEDENT><DEDENT>if create_new:<EOL><INDENT>if len(args) > <NUM_LIT:0> and inspect.isclass(args[<NUM_LIT:0>]):<EOL><INDENT>constructor = args.pop(<NUM_LIT:0>)<EOL><DEDENT>if len(args) > <NUM_LIT:0> and isinstance(args[<NUM_LIT:0>], str):<EOL><INDENT>name = args.pop(<NUM_LIT:0>)<EOL><DEDENT>elif '<STR_LIT:name>' in kwargs:<EOL><INDENT>name = kwargs.pop('<STR_LIT:name>')<EOL><DEDENT>elif '<STR_LIT>' in kwargs:<EOL><INDENT>name = kwargs.pop('<STR_LIT>')<EOL><DEDENT>else:<EOL><INDENT>raise ValueError('<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>')<EOL><DEDENT><DEDENT>split_names = name.split('<STR_LIT:.>')<EOL>if check_naming:<EOL><INDENT>for idx, name in enumerate(split_names):<EOL><INDENT>translated_shortcut, name = self._translate_shortcut(name)<EOL>replaced, name = self._replace_wildcards(name)<EOL>if translated_shortcut or replaced:<EOL><INDENT>split_names[idx] = name<EOL><DEDENT><DEDENT>faulty_names = self._check_names(split_names, start_node)<EOL>if faulty_names:<EOL><INDENT>full_name = '<STR_LIT:.>'.join(split_names)<EOL>raise ValueError(<EOL>'<STR_LIT>'<EOL>'<STR_LIT>' % (full_name, faulty_names))<EOL><DEDENT>if add_link:<EOL><INDENT>if instance is None:<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>if instance.v_is_root:<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>if start_node.v_is_root and name in SUBTREE_MAPPING:<EOL><INDENT>raise ValueError('<STR_LIT>' % name)<EOL><DEDENT>if not self._root_instance.f_contains(instance, with_links=False, shortcuts=False):<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT><DEDENT><DEDENT>if add_prefix:<EOL><INDENT>split_names = self._add_prefix(split_names, start_node, group_type_name)<EOL><DEDENT>if group_type_name == GROUP:<EOL><INDENT>add_leaf = type_name != group_type_name and not add_link<EOL>group_type_name, type_name = self._determine_types(start_node, split_names[<NUM_LIT:0>],<EOL>add_leaf, add_link)<EOL><DEDENT>if self._root_instance._is_run and type_name in SENSITIVE_TYPES:<EOL><INDENT>raise TypeError('<STR_LIT>'<EOL>'<STR_LIT>')<EOL><DEDENT>return self._add_to_tree(start_node, split_names, type_name, group_type_name, instance,<EOL>constructor, args, kwargs)<EOL>

Adds a given item to the tree irrespective of the subtree.

        Infers the subtree from the arguments.

        :param start_node: The parental node the adding was initiated from

        :param type_name:

            The type of the new instance. Whether it is a parameter, parameter group, config,
            config group, etc. See the name of the corresponding constants at the top of this
            python module.

        :param group_type_name:

            Type of the subbranch. i.e. whether the item is added to the 'parameters',
            'results' etc. These subbranch types are named as the group names
            (e.g. 'PARAMETER_GROUP') in order to have less constants.
            For all constants used see beginning of this python module.

        :param args:

            Arguments specifying how the item is added.

            If len(args)==1 and the argument is the a given instance of a result or parameter,
            this one is added to the tree.

            Otherwise it is checked if the first argument is a class specifying how to
            construct a new item and the second argument is the name of the new class.

            If the first argument is not a class but a string, the string is assumed to be
            the name of the new instance.

            Additional args are later on used for the construction of the instance.

        :param kwargs:

            Additional keyword arguments that might be handed over to the instance constructor.

        :param add_prefix:

            If a prefix group, i.e. `results`, `config`, etc. should be added

        :param check_naming:

            If it should be checked for correct namings, can be set to ``False`` if data is loaded
            and we know that all names are correct.

        :return: The new added instance


def _replace_wildcards(self, name, run_idx=None):

if self._root_instance.f_is_wildcard(name):<EOL><INDENT>return True, self._root_instance.f_wildcard(name, run_idx)<EOL><DEDENT>else:<EOL><INDENT>return False, name<EOL><DEDENT>

Replaces the $ wildcards and returns True/False in case it was replaced


def _add_to_tree(self, start_node, split_names, type_name, group_type_name,<EOL>instance, constructor, args, kwargs):

<EOL>try:<EOL><INDENT>act_node = start_node<EOL>last_idx = len(split_names) - <NUM_LIT:1><EOL>add_link = type_name == LINK<EOL>link_added = False<EOL>for idx, name in enumerate(split_names):<EOL><INDENT>if name not in act_node._children:<EOL><INDENT>if idx == last_idx:<EOL><INDENT>if add_link:<EOL><INDENT>new_node = self._create_link(act_node, name, instance)<EOL>link_added = True<EOL><DEDENT>elif group_type_name != type_name:<EOL><INDENT>new_node = self._create_any_param_or_result(act_node,<EOL>name,<EOL>type_name,<EOL>instance,<EOL>constructor,<EOL>args, kwargs)<EOL>self._flat_leaf_storage_dict[new_node.v_full_name] = new_node<EOL><DEDENT>else:<EOL><INDENT>new_node = self._create_any_group(act_node, name,<EOL>group_type_name,<EOL>instance,<EOL>constructor,<EOL>args, kwargs)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>new_node = self._create_any_group(act_node, name,<EOL>group_type_name)<EOL><DEDENT>if name in self._root_instance._run_information:<EOL><INDENT>self._root_instance._run_parent_groups[act_node.v_full_name] = act_node<EOL><DEDENT>if self._root_instance._is_run:<EOL><INDENT>if link_added:<EOL><INDENT>self._root_instance._new_links[(act_node.v_full_name, name)] =(act_node, new_node)<EOL><DEDENT>else:<EOL><INDENT>self._root_instance._new_nodes[(act_node.v_full_name, name)] =(act_node, new_node)<EOL><DEDENT><DEDENT><DEDENT>else:<EOL><INDENT>if name in act_node._links:<EOL><INDENT>raise AttributeError('<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>' %<EOL>(name, act_node.v_full_name))<EOL><DEDENT>if idx == last_idx:<EOL><INDENT>if self._root_instance._no_clobber:<EOL><INDENT>self._logger.warning('<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>' % (name, act_node.v_full_name))<EOL><DEDENT>else:<EOL><INDENT>raise AttributeError('<STR_LIT>'<EOL>'<STR_LIT>' % (name, act_node.v_full_name))<EOL><DEDENT><DEDENT><DEDENT>act_node = act_node._children[name]<EOL><DEDENT>return act_node<EOL><DEDENT>except:<EOL><INDENT>self._logger.error('<STR_LIT>' %<EOL>(name, start_node.v_full_name))<EOL>raise<EOL><DEDENT>

Adds a new item to the tree.

        The item can be an already given instance or it is created new.

        :param start_node:

            Parental node the adding of the item was initiated from.

        :param split_names:

            List of names of the new item

        :param type_name:

            Type of item 'RESULT', 'RESULT_GROUP', 'PARAMETER', etc. See name of constants
            at beginning of the python module.

        :param group_type_name:

            Name of the subbranch the item is added to 'RESULT_GROUP', 'PARAMETER_GROUP' etc.
            See name of constants at beginning of this python module.

        :param instance:

            Here an already given instance can be passed. If instance should be created new
            pass None.

        :param constructor:

            If instance should be created new pass a constructor class. If None is passed
            the standard constructor for the instance is chosen.

        :param args:

            Additional arguments passed to instance construction

        :param kwargs:

            Additional keyword arguments passed to instance construction

        :return: The new added instance

        :raises: ValueError if naming of the new item is invalid


def _create_link(self, act_node, name, instance):

act_node._links[name] = instance<EOL>act_node._children[name] = instance<EOL>full_name = instance.v_full_name<EOL>if full_name not in self._root_instance._linked_by:<EOL><INDENT>self._root_instance._linked_by[full_name] = {}<EOL><DEDENT>linking = self._root_instance._linked_by[full_name]<EOL>if act_node.v_full_name not in linking:<EOL><INDENT>linking[act_node.v_full_name] = (act_node, set())<EOL><DEDENT>linking[act_node.v_full_name][<NUM_LIT:1>].add(name)<EOL>if name not in self._links_count:<EOL><INDENT>self._links_count[name] = <NUM_LIT:0><EOL><DEDENT>self._links_count[name] = self._links_count[name] + <NUM_LIT:1><EOL>self._logger.debug('<STR_LIT>'<EOL>'<STR_LIT>' % (name, act_node.v_full_name,<EOL>instance.v_full_name))<EOL>return instance<EOL>

Creates a link and checks if names are appropriate


def _check_names(self, split_names, parent_node=None):

faulty_names = '<STR_LIT>'<EOL>if parent_node is not None and parent_node.v_is_root and split_names[<NUM_LIT:0>] == '<STR_LIT>':<EOL><INDENT>faulty_names = '<STR_LIT>''<STR_LIT>' % (faulty_names)<EOL><DEDENT>for split_name in split_names:<EOL><INDENT>if len(split_name) == <NUM_LIT:0>:<EOL><INDENT>faulty_names = '<STR_LIT>' % (<EOL>faulty_names, split_name)<EOL><DEDENT>elif split_name.startswith('<STR_LIT:_>'):<EOL><INDENT>faulty_names = '<STR_LIT>' % (<EOL>faulty_names, split_name)<EOL><DEDENT>elif re.match(CHECK_REGEXP, split_name) is None:<EOL><INDENT>faulty_names = '<STR_LIT>''<STR_LIT>' %(faulty_names, split_name)<EOL><DEDENT>elif '<STR_LIT:$>' in split_name:<EOL><INDENT>if split_name not in self._root_instance._wildcard_keys:<EOL><INDENT>faulty_names = '<STR_LIT>''<STR_LIT>' % (faulty_names, split_name)<EOL><DEDENT><DEDENT>elif split_name in self._not_admissible_names:<EOL><INDENT>warnings.warn('<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>' % split_name,<EOL>category=SyntaxWarning)<EOL><DEDENT>elif split_name in self._python_keywords:<EOL><INDENT>warnings.warn('<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>' % split_name,<EOL>category=SyntaxWarning)<EOL><DEDENT><DEDENT>name = split_names[-<NUM_LIT:1>]<EOL>if len(name) >= pypetconstants.HDF5_STRCOL_MAX_NAME_LENGTH:<EOL><INDENT>faulty_names = '<STR_LIT>''<STR_LIT>' %(faulty_names, name, len(name),<EOL>pypetconstants.HDF5_STRCOL_MAX_NAME_LENGTH)<EOL><DEDENT>return faulty_names<EOL>

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)


def _create_any_group(self, parent_node, name, type_name, instance=None, constructor=None,<EOL>args=None, kwargs=None):

if args is None:<EOL><INDENT>args = []<EOL><DEDENT>if kwargs is None:<EOL><INDENT>kwargs = {}<EOL><DEDENT>full_name = self._make_full_name(parent_node.v_full_name, name)<EOL>if instance is None:<EOL><INDENT>if constructor is None:<EOL><INDENT>if type_name == RESULT_GROUP:<EOL><INDENT>constructor = ResultGroup<EOL><DEDENT>elif type_name == PARAMETER_GROUP:<EOL><INDENT>constructor = ParameterGroup<EOL><DEDENT>elif type_name == CONFIG_GROUP:<EOL><INDENT>constructor = ConfigGroup<EOL><DEDENT>elif type_name == DERIVED_PARAMETER_GROUP:<EOL><INDENT>constructor = DerivedParameterGroup<EOL><DEDENT>elif type_name == GROUP:<EOL><INDENT>constructor = NNGroupNode<EOL><DEDENT>else:<EOL><INDENT>raise RuntimeError('<STR_LIT>')<EOL><DEDENT><DEDENT>instance = self._root_instance._construct_instance(constructor, full_name,<EOL>*args, **kwargs)<EOL><DEDENT>else:<EOL><INDENT>instance._rename(full_name)<EOL>if type_name == RESULT_GROUP:<EOL><INDENT>if type(instance) in (NNGroupNode,<EOL>ParameterGroup,<EOL>ConfigGroup,<EOL>DerivedParameterGroup):<EOL><INDENT>raise TypeError('<STR_LIT>' %<EOL>str(type(instance)))<EOL><DEDENT><DEDENT>elif type_name == PARAMETER_GROUP:<EOL><INDENT>if type(instance) in (NNGroupNode,<EOL>ResultGroup,<EOL>ConfigGroup,<EOL>DerivedParameterGroup):<EOL><INDENT>raise TypeError('<STR_LIT>' %<EOL>str(type(instance)))<EOL><DEDENT><DEDENT>elif type_name == CONFIG_GROUP:<EOL><INDENT>if type(instance) in (NNGroupNode,<EOL>ParameterGroup,<EOL>ResultGroup,<EOL>DerivedParameterGroup):<EOL><INDENT>raise TypeError('<STR_LIT>' %<EOL>str(type(instance)))<EOL><DEDENT><DEDENT>elif type_name == DERIVED_PARAMETER_GROUP:<EOL><INDENT>if type(instance) in (NNGroupNode,<EOL>ParameterGroup,<EOL>ConfigGroup,<EOL>ResultGroup):<EOL><INDENT>raise TypeError('<STR_LIT>'<EOL>'<STR_LIT>' % str(type(instance)))<EOL><DEDENT><DEDENT>elif type_name == GROUP:<EOL><INDENT>if type(instance) in (ResultGroup,<EOL>ParameterGroup,<EOL>ConfigGroup,<EOL>DerivedParameterGroup):<EOL><INDENT>raise TypeError('<STR_LIT>' %<EOL>str(type(instance)))<EOL><DEDENT><DEDENT>else:<EOL><INDENT>raise RuntimeError('<STR_LIT>')<EOL><DEDENT><DEDENT>self._set_details_tree_node(parent_node, name, instance)<EOL>instance._nn_interface = self<EOL>self._root_instance._all_groups[instance.v_full_name] = instance<EOL>self._add_to_nodes_and_leaves(instance)<EOL>parent_node._children[name] = instance<EOL>parent_node._groups[name] = instance<EOL>return instance<EOL>

Generically creates a new group inferring from the `type_name`.


def _create_any_param_or_result(self, parent_node, name, type_name, instance, constructor,<EOL>args, kwargs):

root = self._root_instance<EOL>full_name = self._make_full_name(parent_node.v_full_name, name)<EOL>if instance is None:<EOL><INDENT>if constructor is None:<EOL><INDENT>if type_name == RESULT:<EOL><INDENT>constructor = root._standard_result<EOL><DEDENT>elif type_name in [PARAMETER, CONFIG, DERIVED_PARAMETER]:<EOL><INDENT>constructor = root._standard_parameter<EOL><DEDENT>else:<EOL><INDENT>constructor = root._standard_leaf<EOL><DEDENT><DEDENT>instance = root._construct_instance(constructor, full_name, *args, **kwargs)<EOL><DEDENT>else:<EOL><INDENT>instance._rename(full_name)<EOL><DEDENT>self._set_details_tree_node(parent_node, name, instance)<EOL>where_dict = self._map_type_to_dict(type_name)<EOL>full_name = instance._full_name<EOL>if full_name in where_dict:<EOL><INDENT>raise AttributeError(full_name + '<STR_LIT>')<EOL><DEDENT>if type_name != RESULT and full_name in root._changed_default_parameters:<EOL><INDENT>self._logger.info(<EOL>'<STR_LIT>' %<EOL>full_name)<EOL>change_args, change_kwargs = root._changed_default_parameters.pop(full_name)<EOL>instance.f_set(*change_args, **change_kwargs)<EOL><DEDENT>where_dict[full_name] = instance<EOL>self._add_to_nodes_and_leaves(instance)<EOL>parent_node._children[name] = instance<EOL>parent_node._leaves[name] = instance<EOL>if full_name in self._root_instance._explored_parameters:<EOL><INDENT>instance._explored = True  <EOL>self._root_instance._explored_parameters[full_name] = instance<EOL><DEDENT>self._logger.debug('<STR_LIT>' % full_name)<EOL>return instance<EOL>

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


def _set_details_tree_node(self, parent_node, name, instance):

depth = parent_node._depth + <NUM_LIT:1><EOL>if parent_node.v_is_root:<EOL><INDENT>branch = name  <EOL><DEDENT>else:<EOL><INDENT>branch = parent_node._branch<EOL><DEDENT>if name in self._root_instance._run_information:<EOL><INDENT>run_branch = name<EOL><DEDENT>else:<EOL><INDENT>run_branch = parent_node._run_branch<EOL><DEDENT>instance._set_details(depth, branch, run_branch)<EOL>

Renames a given `instance` based on `parent_node` and `name`.

        Adds meta information like depth as well.


if fast_access and data.f_supports_fast_access():<EOL><INDENT>return data.f_get()<EOL><DEDENT>else:<EOL><INDENT>return data<EOL><DEDENT>

Method that checks if fast access is possible and applies it if desired


def _iter_nodes(self, node, recursive=False, max_depth=float('<STR_LIT>'),<EOL>with_links=True, in_search=False, predicate=None):

def _run_predicate(x, run_name_set):<EOL><INDENT>branch = x.v_run_branch<EOL>return branch == '<STR_LIT>' or branch in run_name_set<EOL><DEDENT>if max_depth is None:<EOL><INDENT>max_depth = float('<STR_LIT>')<EOL><DEDENT>if predicate is None:<EOL><INDENT>predicate = lambda x: True<EOL><DEDENT>elif isinstance(predicate, (tuple, list)):<EOL><INDENT>run_list = predicate<EOL>run_name_set = set()<EOL>for item in run_list:<EOL><INDENT>if item == -<NUM_LIT:1>:<EOL><INDENT>run_name_set.add(self._root_instance.f_wildcard('<STR_LIT:$>', -<NUM_LIT:1>))<EOL><DEDENT>elif isinstance(item, int):<EOL><INDENT>run_name_set.add(self._root_instance.f_idx_to_run(item))<EOL><DEDENT>else:<EOL><INDENT>run_name_set.add(item)<EOL><DEDENT><DEDENT>predicate = lambda x: _run_predicate(x, run_name_set)<EOL><DEDENT>if recursive:<EOL><INDENT>return NaturalNamingInterface._recursive_traversal_bfs(node,<EOL>self._root_instance._linked_by,<EOL>max_depth, with_links,<EOL>in_search, predicate)<EOL><DEDENT>else:<EOL><INDENT>iterator = (x for x in self._make_child_iterator(node, with_links) if<EOL>predicate(x[<NUM_LIT:2>]))<EOL>if in_search:<EOL><INDENT>return iterator <EOL><DEDENT>else:<EOL><INDENT>return (x[<NUM_LIT:2>] for x in iterator)<EOL><DEDENT><DEDENT>

Returns an iterator over nodes hanging below a given start node.

        :param node:

            Start node

        :param recursive:

            Whether recursively also iterate over the children of the start node's children

        :param max_depth:

            Maximum depth to search for

        :param in_search:

            if it is used during get search and if detailed info should be returned

        :param with_links:

            If links should be considered

        :param predicate:

            A predicate to filter nodes

        :return: Iterator


def _to_dict(self, node, fast_access=True, short_names=False, nested=False,<EOL>copy=True, with_links=True):

if (fast_access or short_names or nested) and not copy:<EOL><INDENT>raise ValueError('<STR_LIT>'<EOL>'<STR_LIT>')<EOL><DEDENT>if nested and short_names:<EOL><INDENT>raise ValueError('<STR_LIT>'<EOL>'<STR_LIT>')<EOL><DEDENT>if node.v_is_root:<EOL><INDENT>temp_dict = self._flat_leaf_storage_dict<EOL>if not fast_access and not short_names:<EOL><INDENT>if copy:<EOL><INDENT>return temp_dict.copy()<EOL><DEDENT>else:<EOL><INDENT>return temp_dict<EOL><DEDENT><DEDENT>else:<EOL><INDENT>iterator = temp_dict.values()<EOL><DEDENT><DEDENT>else:<EOL><INDENT>iterator = node.f_iter_leaves(with_links=with_links)<EOL><DEDENT>result_dict = {}<EOL>for val in iterator:<EOL><INDENT>if short_names:<EOL><INDENT>new_key = val.v_name<EOL><DEDENT>else:<EOL><INDENT>new_key = val.v_full_name<EOL><DEDENT>if new_key in result_dict:<EOL><INDENT>raise ValueError('<STR_LIT>'<EOL>'<STR_LIT>' % new_key)<EOL><DEDENT>new_val = self._apply_fast_access(val, fast_access)<EOL>result_dict[new_key] = new_val<EOL><DEDENT>if nested:<EOL><INDENT>if node.v_is_root:<EOL><INDENT>nest_dict = result_dict<EOL><DEDENT>else:<EOL><INDENT>strip = len(node.v_full_name) + <NUM_LIT:1><EOL>nest_dict = {key[strip:]: val for key, val in result_dict.items()}<EOL><DEDENT>result_dict = nest_dictionary(nest_dict, '<STR_LIT:.>')<EOL><DEDENT>return result_dict<EOL>

Returns a dictionary with pairings of (full) names as keys and instances as values.

        :param fast_access:

            If true parameter or result values are returned instead of the
            instances.

        :param short_names:

            If true keys are not full names but only the names.
            Raises a ValueError if the names are not unique.

        :param nested:

            If true returns a nested dictionary.

        :param with_links:

            If links should be considered

        :return: dictionary

        :raises: ValueError


@staticmethod<EOL><INDENT>def _make_child_iterator(node, with_links, current_depth=<NUM_LIT:0>):<DEDENT>

cdp1 = current_depth + <NUM_LIT:1><EOL>if with_links:<EOL><INDENT>iterator = ((cdp1, x[<NUM_LIT:0>], x[<NUM_LIT:1>]) for x in node._children.items())<EOL><DEDENT>else:<EOL><INDENT>leaves = ((cdp1, x[<NUM_LIT:0>], x[<NUM_LIT:1>]) for x in node._leaves.items())<EOL>groups = ((cdp1, y[<NUM_LIT:0>], y[<NUM_LIT:1>]) for y in node._groups.items())<EOL>iterator = itools.chain(groups, leaves)<EOL><DEDENT>return iterator<EOL>

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.


if predicate is None:<EOL><INDENT>predicate = lambda x: True<EOL><DEDENT>iterator_queue = IteratorChain([(<NUM_LIT:0>, node.v_name, node)])<EOL>start = True<EOL>visited_linked_nodes = set([])<EOL>while True:<EOL><INDENT>try:<EOL><INDENT>depth, name, item = next(iterator_queue)<EOL>full_name = item._full_name<EOL>if start or predicate(item):<EOL><INDENT>if full_name in visited_linked_nodes:<EOL><INDENT>if in_search:<EOL><INDENT>yield depth, name, item<EOL><DEDENT><DEDENT>elif depth <= max_depth:<EOL><INDENT>if start:<EOL><INDENT>start = False<EOL><DEDENT>else:<EOL><INDENT>if in_search:<EOL><INDENT>yield depth, name, item<EOL><DEDENT>else:<EOL><INDENT>yield item<EOL><DEDENT><DEDENT>if full_name in linked_by:<EOL><INDENT>visited_linked_nodes.add(full_name)<EOL><DEDENT>if not item._is_leaf and depth < max_depth:<EOL><INDENT>child_iterator = NaturalNamingInterface._make_child_iterator(item,<EOL>with_links,<EOL>current_depth=depth)<EOL>iterator_queue.add(child_iterator)<EOL><DEDENT><DEDENT><DEDENT><DEDENT>except StopIteration:<EOL><INDENT>break<EOL><DEDENT><DEDENT>

Iterator function traversing the tree below `node` in breadth first search manner.

        If `run_name` is given only sub branches of this run are considered and the rest is
        blinded out.


def _very_fast_search(self, node, key, max_depth, with_links, crun):

if key in self._links_count:<EOL><INDENT>return<EOL><DEDENT>parent_full_name = node.v_full_name<EOL>starting_depth = node.v_depth<EOL>candidate_dict = self._get_candidate_dict(key, crun)<EOL>if with_links:<EOL><INDENT>upper_bound = <NUM_LIT:1><EOL><DEDENT>else:<EOL><INDENT>upper_bound = FAST_UPPER_BOUND<EOL><DEDENT>if len(candidate_dict) > upper_bound:<EOL><INDENT>raise pex.TooManyGroupsError('<STR_LIT>')<EOL><DEDENT>result_node = None<EOL>for goal_name in candidate_dict:<EOL><INDENT>if goal_name.startswith(parent_full_name):<EOL><INDENT>candidate = candidate_dict[goal_name]<EOL>if candidate.v_depth - starting_depth <= max_depth:<EOL><INDENT>if result_node is not None:<EOL><INDENT>raise pex.NotUniqueNodeError('<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>'<EOL>% (key, goal_name, result_node.v_full_name))<EOL><DEDENT>result_node = candidate<EOL><DEDENT><DEDENT><DEDENT>if result_node is not None:<EOL><INDENT>return result_node, result_node.v_depth<EOL><DEDENT>

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


def _search(self, node, key, max_depth=float('<STR_LIT>'), with_links=True, crun=None):

<EOL>if key in node._children and (with_links or key not in node._links):<EOL><INDENT>return node._children[key], <NUM_LIT:1><EOL><DEDENT>try:<EOL><INDENT>result = self._very_fast_search(node, key, max_depth, with_links, crun)<EOL>if result:<EOL><INDENT>return result<EOL><DEDENT><DEDENT>except pex.TooManyGroupsError:<EOL><INDENT>pass<EOL><DEDENT>except pex.NotUniqueNodeError:<EOL><INDENT>pass<EOL><DEDENT>nodes_iterator = self._iter_nodes(node, recursive=True,<EOL>max_depth=max_depth, in_search=True,<EOL>with_links=with_links)<EOL>result_node = None<EOL>result_depth = float('<STR_LIT>')<EOL>for depth, name, child in nodes_iterator:<EOL><INDENT>if depth > result_depth:<EOL><INDENT>break<EOL><DEDENT>if key == name:<EOL><INDENT>if result_node is not None:<EOL><INDENT>raise pex.NotUniqueNodeError('<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>'<EOL>% (key, child.v_depth, result_node.v_full_name,<EOL>child.v_full_name))<EOL><DEDENT>result_node = child<EOL>result_depth = depth<EOL><DEDENT><DEDENT>return result_node, result_depth<EOL>

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


def _backwards_search(self, start_node, split_name, max_depth=float('<STR_LIT>'), shortcuts=True):

result_list = [] <EOL>full_name_set = set() <EOL>colon_name = '<STR_LIT:.>'.join(split_name)<EOL>key = split_name[-<NUM_LIT:1>]<EOL>candidate_dict = self._get_candidate_dict(key, None, use_upper_bound=False)<EOL>parent_full_name = start_node.v_full_name<EOL>split_length = len(split_name)<EOL>for candidate_name in candidate_dict:<EOL><INDENT>candidate = candidate_dict[candidate_name]<EOL>if key != candidate.v_name or candidate.v_full_name in full_name_set:<EOL><INDENT>continue<EOL><DEDENT>if candidate_name.startswith(parent_full_name):<EOL><INDENT>if parent_full_name != '<STR_LIT>':<EOL><INDENT>reduced_candidate_name = candidate_name[len(parent_full_name) + <NUM_LIT:1>:]<EOL><DEDENT>else:<EOL><INDENT>reduced_candidate_name = candidate_name<EOL><DEDENT>candidate_split_name = reduced_candidate_name.split('<STR_LIT:.>')<EOL>if len(candidate_split_name) > max_depth:<EOL><INDENT>break<EOL><DEDENT>if len(split_name) == <NUM_LIT:1> or reduced_candidate_name.endswith(colon_name):<EOL><INDENT>result_list.append(candidate)<EOL>full_name_set.add(candidate.v_full_name)<EOL><DEDENT>elif shortcuts:<EOL><INDENT>candidate_set = set(candidate_split_name)<EOL>climbing = True<EOL>for name in split_name:<EOL><INDENT>if name not in candidate_set:<EOL><INDENT>climbing = False<EOL>break<EOL><DEDENT><DEDENT>if climbing:<EOL><INDENT>count = <NUM_LIT:0><EOL>candidate_length = len(candidate_split_name)<EOL>for idx in range(candidate_length):<EOL><INDENT>if idx + split_length - count > candidate_length:<EOL><INDENT>break<EOL><DEDENT>if split_name[count] == candidate_split_name[idx]:<EOL><INDENT>count += <NUM_LIT:1><EOL>if count == len(split_name):<EOL><INDENT>result_list.append(candidate)<EOL>full_name_set.add(candidate.v_full_name)<EOL>break<EOL><DEDENT><DEDENT><DEDENT><DEDENT><DEDENT><DEDENT><DEDENT>return result_list<EOL>

Performs a backwards search from the terminal node back to the start node

        :param start_node:

            The node from where search starts, or here better way where backwards search should
            end.

        :param split_name:

            List of names

        :param max_depth:

            Maximum search depth where to look for

        :param shortcuts:

            If shortcuts are allowed


def _get_all(self, node, name, max_depth, shortcuts):

if max_depth is None:<EOL><INDENT>max_depth = float('<STR_LIT>')<EOL><DEDENT>if isinstance(name, list):<EOL><INDENT>split_name = name<EOL><DEDENT>elif isinstance(name, tuple):<EOL><INDENT>split_name = list(name)<EOL><DEDENT>elif isinstance(name, int):<EOL><INDENT>split_name = [name]<EOL><DEDENT>else:<EOL><INDENT>split_name = name.split('<STR_LIT:.>')<EOL><DEDENT>for idx, key in enumerate(split_name):<EOL><INDENT>_, key = self._translate_shortcut(key)<EOL>_, key = self._replace_wildcards(key)<EOL>split_name[idx] = key<EOL><DEDENT>return self._backwards_search(node, split_name, max_depth, shortcuts)<EOL>

Searches for all occurrences of `name` under `node`.

        :param node:

            Start node

        :param name:

            Name what to look for can be longer and separated by colons, i.e.
            `mygroupA.mygroupB.myparam`.

        :param max_depth:

            Maximum depth to search for relative to start node.

        :param shortcuts:

            If shortcuts are allowed

        :return:

            List of nodes that match the name, empty list if nothing was found.


def _get(self, node, name, fast_access,<EOL>shortcuts, max_depth, auto_load, with_links):

if auto_load and not with_links:<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>if isinstance(name, list):<EOL><INDENT>split_name = name<EOL><DEDENT>elif isinstance(name, tuple):<EOL><INDENT>split_name = list(name)<EOL><DEDENT>elif isinstance(name, int):<EOL><INDENT>split_name = [name]<EOL><DEDENT>else:<EOL><INDENT>split_name = name.split('<STR_LIT:.>')<EOL><DEDENT>if node.v_is_root:<EOL><INDENT>if len(split_name) == <NUM_LIT:1> and split_name[<NUM_LIT:0>] == '<STR_LIT>':<EOL><INDENT>return node<EOL><DEDENT>key = split_name[<NUM_LIT:0>]<EOL>_, key = self._translate_shortcut(key)<EOL>if key in SUBTREE_MAPPING and key not in node._children:<EOL><INDENT>node.f_add_group(key)<EOL><DEDENT><DEDENT>if max_depth is None:<EOL><INDENT>max_depth = float('<STR_LIT>')<EOL><DEDENT>if len(split_name) > max_depth and shortcuts:<EOL><INDENT>raise ValueError(<EOL>'<STR_LIT>' %<EOL>(str(name), max_depth))<EOL><DEDENT>try_auto_load_directly1 = False<EOL>try_auto_load_directly2 = False<EOL>wildcard_positions = []<EOL>root = self._root_instance<EOL>for idx, key in enumerate(split_name):<EOL><INDENT>translated_shortcut, key = self._translate_shortcut(key)<EOL>if translated_shortcut:<EOL><INDENT>split_name[idx] = key<EOL><DEDENT>if key[<NUM_LIT:0>] == '<STR_LIT:_>':<EOL><INDENT>raise AttributeError('<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>' % key)<EOL><DEDENT>is_wildcard = self._root_instance.f_is_wildcard(key)<EOL>if (not is_wildcard and key not in self._nodes_and_leaves and<EOL>key not in self._links_count):<EOL><INDENT>try_auto_load_directly1 = True<EOL>try_auto_load_directly2 = True<EOL><DEDENT>if is_wildcard:<EOL><INDENT>wildcard_positions.append((idx, key))<EOL>if root.f_wildcard(key) not in self._nodes_and_leaves:<EOL><INDENT>try_auto_load_directly1 = True<EOL><DEDENT>if root.f_wildcard(key, -<NUM_LIT:1>) not in self._nodes_and_leaves:<EOL><INDENT>try_auto_load_directly2 = True<EOL><DEDENT><DEDENT><DEDENT>run_idx = root.v_idx<EOL>wildcard_exception = None <EOL>if try_auto_load_directly1 and try_auto_load_directly2 and not auto_load:<EOL><INDENT>for wildcard_pos, wildcard in wildcard_positions:<EOL><INDENT>split_name[wildcard_pos] = root.f_wildcard(wildcard, run_idx)<EOL><DEDENT>raise AttributeError('<STR_LIT>' %<EOL>str('<STR_LIT:.>'.join(split_name)))<EOL><DEDENT>if run_idx > -<NUM_LIT:1>:<EOL><INDENT>with self._disable_logging:<EOL><INDENT>try:<EOL><INDENT>for wildcard_pos, wildcard in wildcard_positions:<EOL><INDENT>split_name[wildcard_pos] = root.f_wildcard(wildcard, run_idx)<EOL><DEDENT>result = self._perform_get(node, split_name, fast_access,<EOL>shortcuts, max_depth, auto_load, with_links,<EOL>try_auto_load_directly1)<EOL>return result<EOL><DEDENT>except (pex.DataNotInStorageError, AttributeError) as exc:<EOL><INDENT>wildcard_exception = exc<EOL><DEDENT><DEDENT><DEDENT>if wildcard_positions:<EOL><INDENT>for wildcard_pos, wildcard in wildcard_positions:<EOL><INDENT>split_name[wildcard_pos] = root.f_wildcard(wildcard, -<NUM_LIT:1>)<EOL><DEDENT><DEDENT>try:<EOL><INDENT>return self._perform_get(node, split_name, fast_access,<EOL>shortcuts, max_depth, auto_load, with_links,<EOL>try_auto_load_directly2)<EOL><DEDENT>except (pex.DataNotInStorageError, AttributeError):<EOL><INDENT>if wildcard_exception is not None:<EOL><INDENT>raise wildcard_exception<EOL><DEDENT>else:<EOL><INDENT>raise<EOL><DEDENT><DEDENT>

Searches for an item (parameter/result/group node) with the given `name`.

        :param node: The node below which the search is performed

        :param name: Name of the item (full name or parts of the full name)

        :param fast_access: If the result is a parameter, whether fast access should be applied.

        :param max_depth:

            Maximum search depth relative to start node.

        :param auto_load:

            If data should be automatically loaded

        :param with_links

            If links should be considered

        :return:

            The found instance (result/parameter/group node) or if fast access is True and you
            found a parameter or result that supports fast access, the contained value is returned.

        :raises:

            AttributeError if no node with the given name can be found.
            Raises errors that are raised by the storage service if `auto_load=True` and
            item cannot be found.


def _perform_get(self, node, split_name, fast_access,<EOL>shortcuts, max_depth, auto_load, with_links,<EOL>try_auto_load_directly):

result = None<EOL>name = '<STR_LIT:.>'.join(split_name)<EOL>if len(split_name) > max_depth:<EOL><INDENT>raise AttributeError('<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>' %<EOL>(name, node.v_full_name))<EOL><DEDENT>if shortcuts and not try_auto_load_directly:<EOL><INDENT>first = split_name[<NUM_LIT:0>]<EOL>if len(split_name) == <NUM_LIT:1> and first in node._children and (with_links or<EOL>first not in node._links):<EOL><INDENT>result = node._children[first]<EOL><DEDENT>else:<EOL><INDENT>result = self._check_flat_dicts(node, split_name)<EOL>if result is None:<EOL><INDENT>result = node<EOL>crun = None<EOL>for key in split_name:<EOL><INDENT>if key in self._root_instance._run_information:<EOL><INDENT>crun = key<EOL><DEDENT>result, depth = self._search(result, key, max_depth, with_links, crun)<EOL>max_depth -= depth<EOL>if result is None:<EOL><INDENT>break<EOL><DEDENT><DEDENT><DEDENT><DEDENT><DEDENT>elif not try_auto_load_directly:<EOL><INDENT>result = node<EOL>for name in split_name:<EOL><INDENT>if name in result._children and (with_links or not name in result._links):<EOL><INDENT>result = result._children[name]<EOL><DEDENT>else:<EOL><INDENT>raise AttributeError(<EOL>'<STR_LIT>'<EOL>'<STR_LIT>' % (name, result.v_full_name))<EOL><DEDENT><DEDENT><DEDENT>if result is None and auto_load:<EOL><INDENT>try:<EOL><INDENT>result = node.f_load_child('<STR_LIT:.>'.join(split_name),<EOL>load_data=pypetconstants.LOAD_DATA)<EOL>if (self._root_instance.v_idx != -<NUM_LIT:1> and<EOL>result.v_is_leaf and<EOL>result.v_is_parameter and<EOL>result.v_explored):<EOL><INDENT>result._set_parameter_access(self._root_instance.v_idx)<EOL><DEDENT><DEDENT>except:<EOL><INDENT>self._logger.error('<STR_LIT>' %<EOL>(name, node.v_full_name))<EOL>raise<EOL><DEDENT><DEDENT>if result is None:<EOL><INDENT>raise AttributeError('<STR_LIT>' %<EOL>(name, node.v_full_name))<EOL><DEDENT>if result.v_is_leaf:<EOL><INDENT>if auto_load and result.f_is_empty():<EOL><INDENT>try:<EOL><INDENT>self._root_instance.f_load_item(result)<EOL>if (self._root_instance.v_idx != -<NUM_LIT:1> and<EOL>result.v_is_parameter and<EOL>result.v_explored):<EOL><INDENT>result._set_parameter_access(self._root_instance.v_idx)<EOL><DEDENT><DEDENT>except:<EOL><INDENT>self._logger.error('<STR_LIT>'<EOL>'<STR_LIT>' %<EOL>(name, node.v_full_name))<EOL>raise<EOL><DEDENT><DEDENT>return self._apply_fast_access(result, fast_access)<EOL><DEDENT>else:<EOL><INDENT>return result<EOL><DEDENT>

Searches for an item (parameter/result/group node) with the given `name`.

        :param node: The node below which the search is performed

        :param split_name: Name split into list according to '.'

        :param fast_access: If the result is a parameter, whether fast access should be applied.

        :param max_depth:

            Maximum search depth relative to start node.

        :param auto_load:

            If data should be automatically loaded

        :param with_links:

            If links should be considered.

        :param try_auto_load_directly:

            If one should skip search and directly try auto_loading

        :return:

            The found instance (result/parameter/group node) or if fast access is True and you
            found a parameter or result that supports fast access, the contained value is returned.

        :raises:

            AttributeError if no node with the given name can be found
            Raises errors that are raiesd by the storage service if `auto_load=True`


if self._kids is None:<EOL><INDENT>self._kids = NNTreeNodeKids(self)<EOL><DEDENT>return self._kids<EOL>

Alternative naming, you can use `node.kids.name` instead of `node.name`
        for easier tab completion.


root_copy = self.v_root.__copy__()<EOL>return root_copy.f_get(self.v_full_name,<EOL>auto_load=False,<EOL>shortcuts=False,<EOL>with_links=False)<EOL>

Shallow copy includes copy of full tree but not leave nodes


def _add_group_from_storage(self, args, kwargs):

return self._nn_interface._add_generic(self,<EOL>type_name=GROUP,<EOL>group_type_name=GROUP,<EOL>args=args,<EOL>kwargs=kwargs,<EOL>add_prefix=False,<EOL>check_naming=False)<EOL>

Can be called from storage service to create a new group to bypass name checking


def _add_leaf_from_storage(self, args, kwargs):

return self._nn_interface._add_generic(self,<EOL>type_name=LEAF,<EOL>group_type_name=GROUP,<EOL>args=args, kwargs=kwargs,<EOL>add_prefix=False,<EOL>check_naming=False)<EOL>

Can be called from storage service to create a new leaf to bypass name checking


if (self._nn_interface is not None and<EOL>self._nn_interface._root_instance is not None<EOL>and self.v_root.v_auto_load):<EOL><INDENT>try:<EOL><INDENT>if self.v_is_root:<EOL><INDENT>self.f_load(recursive=True, max_depth=<NUM_LIT:1>,<EOL>load_data=pypetconstants.LOAD_SKELETON,<EOL>with_meta_data=False,<EOL>with_run_information=False)<EOL><DEDENT>else:<EOL><INDENT>self.f_load(recursive=True, max_depth=<NUM_LIT:1>, load_data=pypetconstants.LOAD_SKELETON)<EOL><DEDENT><DEDENT>except Exception as exc:<EOL><INDENT>pass<EOL><DEDENT><DEDENT>return list(self._children.keys())<EOL>


result = super(NNGroupNode, self).__dir__()<EOL>if not is_debug():<EOL><INDENT>result.extend(self.f_dir_data())<EOL><DEDENT>return result<EOL>


return self.f_iter_nodes(recursive=self.v_root.v_iter_recursive)<EOL>

Equivalent to call :func:`~pypet.naturalnaming.NNGroupNode.f_iter_nodes`

        Whether to iterate recursively is determined by `v_iter_recursive`.


return self._debug()<EOL>

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):<EOL><INDENT>"""<STR_LIT>"""<EOL>pass<EOL><DEDENT>debug_tree = Bunch()<EOL>if not self.v_annotations.f_is_empty():<EOL><INDENT>debug_tree.v_annotations = self.v_annotations<EOL><DEDENT>if not self.v_comment == '<STR_LIT>':<EOL><INDENT>debug_tree.v_comment = self.v_comment<EOL><DEDENT>for leaf_name in self._leaves:<EOL><INDENT>leaf = self._leaves[leaf_name]<EOL>setattr(debug_tree, leaf_name, leaf)<EOL><DEDENT>for link_name in self._links:<EOL><INDENT>linked_node = self._links[link_name]<EOL>setattr(debug_tree, link_name, '<STR_LIT>' % linked_node.v_full_name)<EOL><DEDENT>for group_name in self._groups:<EOL><INDENT>group = self._groups[group_name]<EOL>setattr(debug_tree, group_name, group._debug())<EOL><DEDENT>return debug_tree<EOL>


if self.v_is_root:<EOL><INDENT>raise TypeError('<STR_LIT>')<EOL><DEDENT>elif self.v_location == '<STR_LIT>':<EOL><INDENT>return self.v_root<EOL><DEDENT>else:<EOL><INDENT>return self.v_root.f_get(self.v_location, fast_access=False, shortcuts=False)<EOL><DEDENT>

Returns the parent of the node.

        Raises a TypeError if current node is root.


return self._nn_interface._add_generic(self, type_name=GROUP,<EOL>group_type_name=GROUP,<EOL>args=args, kwargs=kwargs, add_prefix=False)<EOL>

Adds an empty generic group under the current node.

        You can add to a generic group anywhere you want. So you are free to build
        your parameter 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.


def f_add_link(self, name_or_item, full_name_or_item=None):

if isinstance(name_or_item, str):<EOL><INDENT>name = name_or_item<EOL>if isinstance(full_name_or_item, str):<EOL><INDENT>instance = self.v_root.f_get(full_name_or_item)<EOL><DEDENT>else:<EOL><INDENT>instance =  full_name_or_item<EOL><DEDENT><DEDENT>else:<EOL><INDENT>instance = name_or_item<EOL>name = instance.v_name<EOL><DEDENT>return self._nn_interface._add_generic(self, type_name=LINK,<EOL>group_type_name=GROUP, args=(name, instance),<EOL>kwargs={},<EOL>add_prefix=False)<EOL>

Adds a link to an existing node.

        Can be called as ``node.f_add_link(other_node)`` this will add a link the `other_node`
        with the link name as the name of the node.

        Or can be called as ``node.f_add_link(name, other_node)`` to add a link to the
        `other_node` and the given `name` of the link.

        In contrast to addition of groups and leaves,  colon separated names
        are **not** allowed, i.e. ``node.f_add_link('mygroup.mylink', other_node)``
        does not work.


if name not in self._links:<EOL><INDENT>raise ValueError('<STR_LIT>' % (name, self._full_name))<EOL><DEDENT>self._nn_interface._remove_link(self, name)<EOL>

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`


return self._nn_interface._add_generic(self, type_name=LEAF,<EOL>group_type_name=GROUP,<EOL>args=args, kwargs=kwargs,<EOL>add_prefix=False)<EOL>

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 len(self._links)<EOL>

Returns the number of links of the group


return len(self._links) != <NUM_LIT:0><EOL>


return len(self._children)<EOL>

Returns the number of children of the group


return len(self._children) != <NUM_LIT:0><EOL>


return len(self._leaves)<EOL>

Returns the number of immediate leaves of the group


return len(self._leaves) != <NUM_LIT:0><EOL>


return len(self._groups)<EOL>

Returns the number of immediate groups of the group


return len(self._groups) != <NUM_LIT:0><EOL>


return self.f_contains(item,<EOL>shortcuts=self.v_root.v_shortcuts,<EOL>max_depth=self.v_root.v_max_depth,<EOL>with_links=self.v_root.v_with_links)<EOL>

Equivalent to calling :func:`~pypet.naturalnaming.NNGroupNode.f_contains`.

        Whether to allow shortcuts is taken from `v_shortcuts`.
        Whether to stop at a given depth is taken from `v_max_depth`.


def f_remove(self, recursive=True, predicate=None):

parent = self.f_get_parent()<EOL>parent.f_remove_child(self.v_name, recursive=recursive, predicate=predicate)<EOL>

Recursively removes the group and all it's children.

        :param recursive:

            If removal should be applied recursively. If not, node can only be removed
            if it has no children.

        :param predicate:

            In case of recursive removal, you can selectively remove nodes in the tree.
            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.


def f_remove_child(self, name, recursive=False, predicate=None):

if name not in self._children:<EOL><INDENT>raise ValueError('<STR_LIT>' %<EOL>(self.v_full_name, name))<EOL><DEDENT>else:<EOL><INDENT>child = self._children[name]<EOL>if (name not in self._links and<EOL>not child.v_is_leaf and<EOL>child.f_has_children() and<EOL>not recursive):<EOL><INDENT>raise TypeError('<STR_LIT>'<EOL>'<STR_LIT>')<EOL><DEDENT>else:<EOL><INDENT>self._nn_interface._remove_subtree(self, name, predicate)<EOL><DEDENT><DEDENT>

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.


@kwargs_api_change('<STR_LIT>')<EOL><INDENT>def f_contains(self, item, with_links=True, shortcuts=False, max_depth=None):<DEDENT>

<EOL>try:<EOL><INDENT>search_string = item.v_full_name<EOL>parent_full_name = self.v_full_name<EOL>if not search_string.startswith(parent_full_name):<EOL><INDENT>return False<EOL><DEDENT>if parent_full_name != '<STR_LIT>':<EOL><INDENT>search_string = search_string[len(parent_full_name) + <NUM_LIT:1>:]<EOL><DEDENT>else:<EOL><INDENT>search_string = search_string<EOL><DEDENT>shortcuts = False <EOL><DEDENT>except AttributeError:<EOL><INDENT>search_string = item<EOL>item = None<EOL><DEDENT>if search_string == '<STR_LIT>':<EOL><INDENT>return False <EOL><DEDENT>try:<EOL><INDENT>result = self.f_get(search_string,<EOL>shortcuts=shortcuts, max_depth=max_depth, with_links=with_links)<EOL><DEDENT>except AttributeError:<EOL><INDENT>return False<EOL><DEDENT>if item is not None:<EOL><INDENT>return id(item) == id(result)<EOL><DEDENT>else:<EOL><INDENT>return True<EOL><DEDENT>

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


Equivalent to calling `__getattr__`.

        Per default the item is returned and fast access is applied.


return self._nn_interface._root_instance<EOL>

Link to the root of the tree, i.e. the trajectory


def f_iter_nodes(self, recursive=True, with_links=True, max_depth=None, predicate=None):

return self._nn_interface._iter_nodes(self, recursive=recursive, with_links=with_links,<EOL>max_depth=max_depth,<EOL>predicate=predicate)<EOL>

Iterates recursively (default) over nodes hanging below this group.

        :param recursive: Whether to iterate the whole sub tree or only immediate children.

        :param with_links: If links should be considered

        :param max_depth: Maximum depth in search tree relative to start node (inclusive)

        :param predicate:

            A predicate function that is applied for each node and only returns the node
            if it evaluates to ``True``. If ``False``
            and you iterate recursively also the children are spared.

            Leave to `None` if you don't want to filter and simply iterate over all nodes.

            For example, to iterate only over groups you could use:

            >>> traj.f_iter_nodes(recursive=True, predicate=lambda x: x.v_is_group)

            To blind out all runs except for a particular set, you can simply pass a tuple
            of run indices with -1 referring to the ``run_ALL`` node.

            For instance

            >>> traj.f_iter_nodes(recursive=True, predicate=(0,3,-1))

            Will blind out all nodes hanging below a group named ``run_XXXXXXXXX``
            (including the group) except ``run_00000000``, ``run_00000003``, and ``run_ALL``.

        :return: Iterator over nodes


for node in self.f_iter_nodes(with_links=with_links):<EOL><INDENT>if node.v_is_leaf:<EOL><INDENT>yield node<EOL><DEDENT><DEDENT>

Iterates (recursively) over all leaves hanging below the current group.

        :param with_links:

            If links should be ignored, leaves hanging below linked nodes are not listed.

        :returns:

            Iterator over all leaf nodes


def f_get_all(self, name, max_depth=None, shortcuts=True):

return self._nn_interface._get_all(self, name, max_depth=max_depth, shortcuts=shortcuts)<EOL>

Searches for all occurrences of `name` under `node`.

        Links are NOT considered since nodes are searched bottom up in the tree.

        :param node:

            Start node

        :param name:

            Name of what to look for, can be separated by colons, i.e.
            ``'mygroupA.mygroupB.myparam'``.

        :param max_depth:

            Maximum search depth relative to start node.
            `None` for no limit.

        :param shortcuts:

            If shortcuts are allowed, otherwise the stated name defines a
            consecutive name.For instance. ``'mygroupA.mygroupB.myparam'`` would
            also find ``mygroupA.mygroupX.mygroupB.mygroupY.myparam`` if shortcuts
            are allowed, otherwise not.

        :return:

            List of nodes that match the name, empty list if nothing was found.


@kwargs_api_change('<STR_LIT>')<EOL><INDENT>def f_get_default(self, name, default=None, fast_access=True, with_links=True,<EOL>shortcuts=True, max_depth=None, auto_load=False):<DEDENT>

try:<EOL><INDENT>return self.f_get(name, fast_access=fast_access,<EOL>shortcuts=shortcuts,<EOL>max_depth=max_depth,<EOL>auto_load=auto_load,<EOL>with_links=with_links)<EOL><DEDENT>except (AttributeError, pex.DataNotInStorageError):<EOL><INDENT>return default<EOL><DEDENT>

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.


@kwargs_api_change('<STR_LIT>')<EOL><INDENT>def f_get(self, name, fast_access=False, with_links=True,<EOL>shortcuts=True, max_depth=None, auto_load=False):<DEDENT>

return self._nn_interface._get(self, name, fast_access=fast_access,<EOL>shortcuts=shortcuts,<EOL>max_depth=max_depth,<EOL>auto_load=auto_load,<EOL>with_links=with_links)<EOL>

Searches and returns an item (parameter/result/group node) with the given `name`.

        :param name: Name of the item (full name or parts of the full name)

        :param fast_access: Whether fast access should be applied.

        :param with_links:

            If links are considered. Cannot be set to ``False`` if ``auto_load`` is ``True``.

        :param shortcuts:

            If shortcuts are allowed and the trajectory can *hop* over nodes in the
            path.

        :param max_depth:

            Maximum depth relative to starting node (inclusive).
            `None` means no depth limit.

        :param auto_load:

            If data should be loaded from the storage service if it cannot be found in the
            current trajectory tree. Auto-loading will load group and leaf nodes currently
            not in memory and it will load data into empty leaves. Be aware that auto-loading
            does not work with shortcuts.

        :return:

            The found instance (result/parameter/group node) or if fast access is True and you
            found a parameter or result that supports fast access, the contained value is returned.

        :raises:

            AttributeError: If no node with the given name can be found

            NotUniqueNodeError

                In case of forward search if more than one candidate node is found within a
                particular depth of the tree. In case of backwards search if more than
                one candidate is found regardless of the depth.

            DataNotInStorageError:

                In case auto-loading fails

            Any exception raised by the StorageService in case auto-loading is enabled


if copy:<EOL><INDENT>return self._children.copy()<EOL><DEDENT>else:<EOL><INDENT>return self._children<EOL><DEDENT>

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 copy:<EOL><INDENT>return self._groups.copy()<EOL><DEDENT>else:<EOL><INDENT>return self._groups<EOL><DEDENT>

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 copy:<EOL><INDENT>return self._leaves.copy()<EOL><DEDENT>else:<EOL><INDENT>return self._leaves<EOL><DEDENT>

Returns a dictionary of all leaves 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 copy:<EOL><INDENT>return self._links.copy()<EOL><DEDENT>else:<EOL><INDENT>return self._links<EOL><DEDENT>

Returns a link 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


def f_to_dict(self, fast_access=False, short_names=False, nested=False, with_links=True):

return self._nn_interface._to_dict(self, fast_access=fast_access, short_names=short_names,<EOL>nested=nested, with_links=with_links)<EOL>

Returns a dictionary with pairings of (full) names as keys and instances as values.

        This will iteratively traverse the tree and add all nodes below this group to
        the dictionary.

        :param fast_access:

            If True parameter or result values are returned instead of the instances.

        :param short_names:

            If true keys are not full names but only the names. Raises a ValueError
            if the names are not unique.

        :param nested:

            If dictionary should be nested

        :param with_links:

            If links should be considered

        :return: dictionary

        :raises: ValueError


def f_store_child(self, name, recursive=False, store_data=pypetconstants.STORE_DATA,<EOL>max_depth=None):

if not self.f_contains(name, shortcuts=False):<EOL><INDENT>raise ValueError('<STR_LIT>'<EOL>'<STR_LIT>' %<EOL>(self.v_full_name, name))<EOL><DEDENT>traj = self._nn_interface._root_instance<EOL>storage_service = traj.v_storage_service<EOL>storage_service.store(pypetconstants.TREE, self, name,<EOL>trajectory_name=traj.v_name,<EOL>recursive=recursive,<EOL>store_data=store_data,<EOL>max_depth=max_depth)<EOL>

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.


def f_store(self, recursive=True, store_data=pypetconstants.STORE_DATA,<EOL>max_depth=None):

traj = self._nn_interface._root_instance<EOL>storage_service = traj.v_storage_service<EOL>storage_service.store(pypetconstants.GROUP, self,<EOL>trajectory_name=traj.v_name,<EOL>recursive=recursive,<EOL>store_data=store_data,<EOL>max_depth=max_depth)<EOL>

Stores a group node to disk

        :param recursive:

            Whether recursively all children should be stored too. Default is ``True``.

        :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.


def f_load_child(self, name, recursive=False, load_data=pypetconstants.LOAD_DATA,<EOL>max_depth=None):

traj = self._nn_interface._root_instance<EOL>storage_service = traj.v_storage_service<EOL>storage_service.load(pypetconstants.TREE, self, name,<EOL>trajectory_name=traj.v_name,<EOL>load_data=load_data,<EOL>recursive=recursive,<EOL>max_depth=max_depth)<EOL>return self.f_get(name, shortcuts=False)<EOL>

Loads a child or recursively a subtree from disk.

        :param name:

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

        :param recursive:

            Whether recursively all nodes below the last child 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. Leave `None` if you don't want to limit
            the depth.

        :returns:

            The loaded child, in case of grouping ('groupA.groupB.childC') the last
            node (here 'childC') is returned.


def f_load(self, recursive=True, load_data=pypetconstants.LOAD_DATA,<EOL>max_depth=None):

traj = self._nn_interface._root_instance<EOL>storage_service = traj.v_storage_service<EOL>storage_service.load(pypetconstants.GROUP, self,<EOL>trajectory_name=traj.v_name,<EOL>load_data=load_data,<EOL>recursive=recursive,<EOL>max_depth=max_depth)<EOL>return self<EOL>

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.


def f_add_parameter_group(self, *args, **kwargs):

return self._nn_interface._add_generic(self, type_name=PARAMETER_GROUP,<EOL>group_type_name=PARAMETER_GROUP,<EOL>args=args, kwargs=kwargs)<EOL>

Adds an empty parameter group under the current node.

        Can be called with ``f_add_parameter_group('MyName', 'this is an informative comment')``
        or ``f_add_parameter_group(name='MyName', comment='This is an informative comment')``
        or with a given new group instance:
        ``f_add_parameter_group(ParameterGroup('MyName', comment='This is a comment'))``.

        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 `'parameters'`
        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
        created.


def f_add_parameter(self, *args, **kwargs):

return self._nn_interface._add_generic(self, type_name=PARAMETER,<EOL>group_type_name=PARAMETER_GROUP,<EOL>args=args, kwargs=kwargs)<EOL>

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.f_add_parameter(new_parameter)

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

        >>> traj.f_add_parameter('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.f_add_parameter(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.


def f_add_result_group(self, *args, **kwargs):

return self._nn_interface._add_generic(self, type_name=RESULT_GROUP,<EOL>group_type_name=RESULT_GROUP,<EOL>args=args, kwargs=kwargs)<EOL>

Adds an empty result 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 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.

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


def f_add_result(self, *args, **kwargs):

return self._nn_interface._add_generic(self, type_name=RESULT,<EOL>group_type_name=RESULT_GROUP,<EOL>args=args, kwargs=kwargs)<EOL>

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.f_add_result(new_result)

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

        >>> traj.f_add_result('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.f_add_result(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.


def f_add_derived_parameter_group(self, *args, **kwargs):

return self._nn_interface._add_generic(self, type_name=DERIVED_PARAMETER_GROUP,<EOL>group_type_name=DERIVED_PARAMETER_GROUP,<EOL>args=args, kwargs=kwargs)<EOL>

Adds an empty derived parameter 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 a single run (root) adds the prefix `'derived_parameters.runs.run_08%d%'`
        to the full name where `'08%d'` is replaced by the index of the current run.

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


def f_add_derived_parameter(self, *args, **kwargs):

return self._nn_interface._add_generic(self, type_name=DERIVED_PARAMETER,<EOL>group_type_name=DERIVED_PARAMETER_GROUP,<EOL>args=args, kwargs=kwargs)<EOL>

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.f_add_derived_parameter_group`


def f_add_config_group(self, *args, **kwargs):

return self._nn_interface._add_generic(self, type_name=CONFIG_GROUP,<EOL>group_type_name=CONFIG_GROUP,<EOL>args=args, kwargs=kwargs)<EOL>

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.


def f_add_config(self, *args, **kwargs):

return self._nn_interface._add_generic(self, type_name=CONFIG,<EOL>group_type_name=CONFIG_GROUP,<EOL>args=args, kwargs=kwargs)<EOL>

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.


pass<EOL>

Adds parameters to `traj`.

        Function called from the :class:`~pypet.brian2.network.NetworkManager` to
        define and add parameters to the trajectory container.


def pre_build(self, traj, brian_list, network_dict):

pass<EOL>

Builds network objects before the actual experimental runs.

        Function called from the :class:`~pypet.brian2.network.NetworkManager` if
        components can be built before the actual experimental runs or in
        case the network is pre-run.

        Parameters are the same as for the :func:`~pypet.brian2.network.NetworkComponent.build`
        method.


def build(self, traj, brian_list, network_dict):

pass<EOL>

Builds network objects at the beginning of each individual experimental run.

        Function called from the :class:`~pypet.brian2.network.NetworkManager`
        at the beginning of every experimental run,

        :param traj:

            Trajectory container

        :param brian_list:

            Add BRIAN2 network objects like NeuronGroups or Synapses to this list.
            These objects will be automatically added at the instantiation of the network
            in case the network was not pre-run
            via `Network(*brian_list)`.

        :param network_dict:

            Add any item to this dictionary that should be shared or accessed by all
            your components and which are not part of the trajectory container.
            It is recommended to also put all items from the `brian_list` into
            the dictionary for completeness.

        For convenience I recommend documenting the implementation of `build` and
        `pre-build` and so on in the subclass like the following. Use statements like `Adds`
        for items that are added to the list and the dict and statements like `Expects`
        for what is needed to be part of the `network_dict` in order to build the
        current component.

            brian_list:

                Adds:

                4 Connections, between all types of neurons (e->e, e->i, i->e, i->i)

            network_dict:

                Expects:

                'neurons_i': Inhibitory neuron group

                'neurons_e': Excitatory neuron group

                Adds:

                'connections':  List of 4 Connections,
                                between all types of neurons (e->e, e->i, i->e, i->i)


def add_to_network(self, traj, network, current_subrun, subrun_list, network_dict):

pass<EOL>

Can add network objects before a specific `subrun`.

        Called by a :class:`~pypet.brian2.network.NetworkRunner` before a the
        given `subrun`.

        Potentially one wants to add some BRIAN2 objects later to the network than
        at the very beginning of an experimental run. For example, a monitor might
        be added at the second subrun after an initial phase that is not supposed
        to be recorded.

        :param traj: Trajectoy container

        :param network:

            BRIAN2 network where elements could be added via `add(...)`.

        :param current_subrun:

            :class:`~pypet.brian2.parameter.Brian2Parameter` specifying the very next
            subrun to be simulated.

        :param subrun_list:

            List of :class:`~pypet.brian2.parameter.Brian2Parameter` objects that are to
            be run after the current subrun.

        :param network_dict:

            Dictionary of items shared by all components.


def remove_from_network(self, traj, network, current_subrun, subrun_list, network_dict):

pass<EOL>

Can remove network objects before a specific `subrun`.

        Called by a :class:`~pypet.brian2.network.NetworkRunner` after a
        given `subrun` and shortly after analysis (see
        :class:`~pypet.brian2.network.NetworkAnalyser`).

        :param traj: Trajectoy container

        :param network:

            BRIAN2 network where elements could be removed via `remove(...)`.

        :param current_subrun:

            :class:`~pypet.brian2.parameter.Brian2Parameter` specifying the current subrun
            that was executed shortly before.

        :param subrun_list:

            List of :class:`~pypet.brian2.parameter.Brian2Parameter` objects that are to
            be run after the current subrun.

        :param network_dict:

            Dictionary of items shared by all components.


def analyse(self, traj, network, current_subrun, subrun_list, network_dict):

pass<EOL>

Can perform statistical analysis on a given network.

        Called by a :class:`~pypet.brian2.network.NetworkRunner` directly after a
        given `subrun`.

        :param traj: Trajectoy container

        :param network: BRIAN2 network

        :param current_subrun:

            :class:`~pypet.brian2.parameter.Brian2Parameter` specifying the current subrun
            that was executed shortly before.

        :param subrun_list:

            List of :class:`~pypet.brian2.parameter.Brian2Parameter` objects that are to
            be run after the current subrun. Can be deleted or added to change the actual course
            of the experiment.

        :param network_dict:

            Dictionary of items shared by all components.


def execute_network_pre_run(self, traj, network, network_dict, component_list, analyser_list):

self._execute_network_run(traj, network, network_dict, component_list, analyser_list,<EOL>pre_run=True)<EOL>

Runs a network before the actual experiment.

        Called by a :class:`~pypet.brian2.network.NetworkManager`.
        Similar to :func:`~pypet.brian2.network.NetworkRunner.run_network`.

        Subruns and their durations are extracted from the trajectory. All
        :class:`~pypet.brian2.parameter.Brian2Parameter` instances found under
        `traj.parameters.simulation.pre_durations` (default, you can change the
        name of the group where to search for durations at runner initialisation).
        The order is determined from
        the `v_annotations.order` attributes. There must be at least one subrun in the trajectory,
        otherwise an AttributeError is thrown. If two subruns equal in their order
        property a RuntimeError is thrown.

        :param traj: Trajectory container

        :param network: BRIAN2 network

        :param network_dict: Dictionary of items shared among all components

        :param component_list: List of :class:`~pypet.brian2.network.NetworkComponent` objects

        :param analyser_list: List of :class:`~pypet.brian2.network.NetworkAnalyser` objects