diff --git a/docs/source/conf.py b/docs/source/conf.py index 8d0f983d..ae794d25 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -8,9 +8,19 @@ # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. -import sys +import sys, mock +import os from pathlib import Path +devdir='' +try: + if os.environ['DEVDIR']: + devdir = os.environ['DEVDIR'] +except KeyError: + print 'Unable to obtain $DEVDIR from the environment.' + exit(-1) + +sys.path.insert(0, os.path.abspath('.')) sys.path.insert(0, str(Path(__file__).parent / '../../')) sys.path.insert(0, str(Path(__file__).parent / '../../rostok')) @@ -30,6 +40,7 @@ extensions = ['sphinx.ext.autodoc', 'sphinx.ext.napoleon','sphinx.ext.githubpages'] +autodoc_member_order = 'groupwise' napoleon_google_docstring = False napoleon_use_param = False diff --git a/docs/source/modules/block_builder.rst b/docs/source/modules/block_builder.rst index cc3add9f..13d0b2d9 100644 --- a/docs/source/modules/block_builder.rst +++ b/docs/source/modules/block_builder.rst @@ -3,14 +3,14 @@ Block builder ============= Block blueprints -============ +================ .. automodule:: rostok.block_builder_api.block_blueprints :members: :undoc-members: Block parameters -======= +================ .. automodule:: rostok.block_builder_api.block_parameters :members: diff --git a/docs/source/modules/criterion.rst b/docs/source/modules/criterion.rst index d7d1b6aa..517212f8 100644 --- a/docs/source/modules/criterion.rst +++ b/docs/source/modules/criterion.rst @@ -11,5 +11,5 @@ Criterion calculation Flag stop simulation ==================== -.. automodule:: rostok.criterion.simulation_flag +.. automodule:: rostok.criterion.simulation_flags :members: \ No newline at end of file diff --git a/docs/source/modules/graph_generators.rst b/docs/source/modules/graph_generators.rst index 8c13b32a..3796c911 100644 --- a/docs/source/modules/graph_generators.rst +++ b/docs/source/modules/graph_generators.rst @@ -18,7 +18,7 @@ MCTS MCTS Manager -================== +============ .. automodule:: rostok.graph_generators.mcts_manager :members: diff --git a/docs/source/modules/graph_grammar.rst b/docs/source/modules/graph_grammar.rst index 89028963..569d24c4 100644 --- a/docs/source/modules/graph_grammar.rst +++ b/docs/source/modules/graph_grammar.rst @@ -9,7 +9,7 @@ Node :members: Graph-grammar explorer -============== +====================== .. automodule:: rostok.graph_grammar.graphgrammar_explorer :members: diff --git a/docs/source/modules/simulation_chrono.rst b/docs/source/modules/simulation_chrono.rst index ca030242..fca91d08 100644 --- a/docs/source/modules/simulation_chrono.rst +++ b/docs/source/modules/simulation_chrono.rst @@ -1,21 +1,21 @@ -================== +=========================== Simulation in ProjectChrono -================== +=========================== Simulation scenario -=============== +================== .. automodule:: rostok.simulation_chrono.simulation_scenario :members: Simulation -================== +========== .. automodule:: rostok.simulation_chrono.simulation :members: Simulation utils -================== +================ .. automodule:: rostok.simulation_chrono.simulation_utils :members: \ No newline at end of file diff --git a/docs/source/modules/utils.rst b/docs/source/modules/utils.rst index 10743c5b..b3233228 100644 --- a/docs/source/modules/utils.rst +++ b/docs/source/modules/utils.rst @@ -3,7 +3,7 @@ Utils ===== Pickle save -================= +=========== .. automodule:: rostok.utils.pickle_save :members: diff --git a/docs/source/modules/virtual_experiment.rst b/docs/source/modules/virtual_experiment.rst index 1147ca17..638368dd 100644 --- a/docs/source/modules/virtual_experiment.rst +++ b/docs/source/modules/virtual_experiment.rst @@ -3,13 +3,13 @@ Virtual experiment ================== Robot -=============== +===== .. automodule:: rostok.virtual_experiment.robot_new :members: -Auxilarity sensors -================== +Sensors +======= .. automodule:: rostok.virtual_experiment.sensors :members: \ No newline at end of file diff --git a/rostok/block_builder_api/block_blueprints.py b/rostok/block_builder_api/block_blueprints.py index 404428c6..c7b411f2 100644 --- a/rostok/block_builder_api/block_blueprints.py +++ b/rostok/block_builder_api/block_blueprints.py @@ -89,7 +89,7 @@ def __init__(self, *args: object) -> None: super().__init__('Need implementation for method in child class') -class BlockCreatorInterface(): +class BlockCreatorInterface: """ To use it, you need to implement functions for creating from blueprints. Raises: diff --git a/rostok/graph_grammar/node_vocabulary.py b/rostok/graph_grammar/node_vocabulary.py index fbd4897e..419f8ea7 100644 --- a/rostok/graph_grammar/node_vocabulary.py +++ b/rostok/graph_grammar/node_vocabulary.py @@ -1,17 +1,15 @@ -""" Module contains NodeVocabulary class.""" - from typing import Optional from rostok.block_builder_api.block_blueprints import ALL_BLUEPRINT from rostok.graph_grammar.node import ROOT, Node -class NodeVocabulary(): +class NodeVocabulary: """The class contains dictionary of nodes and methods to manipulate with it. This is a class to manage a dictionary of nodes. The keys are labels of the nodes and the values are Node objects. User can create or add nodes to vocabulary, get individual nodes or list of nodes. - + Attributes: node_dict (List[Node]): dictionary of all nodes. terminal_node_dict (List[Node]): dictionary of only terminal nodes. @@ -26,15 +24,17 @@ def __init__(self): def add_node(self, node: Node): """Add an already created node to the vocabulary. - + Args: node (Node): node to be added to vocabulary. - + Raises: Exception: Attempt to add a Node with a label that is already in dictionary! """ if node.label in self.node_dict: - raise Exception('Attempt to add a Node with a label that is already in dictionary!') + raise Exception( + "Attempt to add a Node with a label that is already in dictionary!" + ) self.node_dict[node.label] = node if node.is_terminal: @@ -42,25 +42,29 @@ def add_node(self, node: Node): else: self.nonterminal_node_dict[node.label] = node - def create_node(self, - label: str, - is_terminal: bool = False, - block_blueprint: Optional[ALL_BLUEPRINT] = None): + def create_node( + self, + label: str, + is_terminal: bool = False, + block_blueprint: Optional[ALL_BLUEPRINT] = None, + ): """Create a node and add it to the vocabulary. - + Args: label (str): the label of the new node. is_terminal (bool, optional): defines if the new node is a terminal node. Default is False. block_blueprint (BlockBlueprint, optional): the object that contains physical properties of the node. Default is None. - + Raises: Exception: Attempt to add a Node with a label that is already in dictionary! """ if label in self.node_dict: - raise Exception('Attempt to create a Node with a label that is already in dictionary!') + raise Exception( + "Attempt to create a Node with a label that is already in dictionary!" + ) node = Node(label, is_terminal, block_blueprint) self.node_dict[label] = node @@ -71,13 +75,13 @@ def create_node(self, def get_node(self, label: str) -> Node: """Return a node corresponding to the label. - + Args: label(str): the label of the node that should be returned. - + Returns: A requested node as a Node class object. - + Raises Exception: Node with given label not found! """ @@ -90,10 +94,10 @@ def get_node(self, label: str) -> Node: def check_node(self, label: str) -> bool: """Check if the label is in the vocabulary. - + Args: label(str): the label of the node that should be checked. - + Returns: bool: True is the label is in dictionary, False otherwise. """ @@ -110,10 +114,10 @@ def __str__(self): def get_list_of_nodes(self, nodes: list[str]) -> list[Node]: """Returns list of Node objects corresponding to list of labels. - + Args: nodes (list[str]): list of labels to construct a list of Node objects. - + Returns: list of Node objects corresponding to the list of passed labels. """ @@ -123,14 +127,14 @@ def get_list_of_nodes(self, nodes: list[str]) -> list[Node]: return result -if __name__ == '__main__': +if __name__ == "__main__": node_vocab = NodeVocabulary() node_vocab.add_node(ROOT) - node_vocab.create_node('A') - node_vocab.create_node('B') - node_vocab.create_node('C') - node_vocab.create_node('D') - node_vocab.create_node('A1', is_terminal=True) - node_vocab.create_node('B1', is_terminal=True) - node_vocab.create_node('C1', is_terminal=True) - print(node_vocab) \ No newline at end of file + node_vocab.create_node("A") + node_vocab.create_node("B") + node_vocab.create_node("C") + node_vocab.create_node("D") + node_vocab.create_node("A1", is_terminal=True) + node_vocab.create_node("B1", is_terminal=True) + node_vocab.create_node("C1", is_terminal=True) + print(node_vocab) diff --git a/rostok/graph_grammar/rule_vocabulary.py b/rostok/graph_grammar/rule_vocabulary.py index b6a7a0cb..5f0242a6 100644 --- a/rostok/graph_grammar/rule_vocabulary.py +++ b/rostok/graph_grammar/rule_vocabulary.py @@ -1,5 +1,3 @@ -"""Module contains RuleVocabulary class.""" - import matplotlib.pyplot as plt import networkx as nx import numpy as np @@ -8,7 +6,7 @@ from rostok.graph_grammar.node_vocabulary import NodeVocabulary -class RuleVocabulary(): +class RuleVocabulary: """The class that contains the rules for building the :py:class:`rostok.graph_grammar.node.GraphGrammar` object. All rules for mechanism generation should be created with an instance of :py:class:`rostok.graph_grammar.rule_vocabulary.RuleVocabulary`. This class provides utility methods for the rules. @@ -43,14 +41,16 @@ def __init__(self, node_vocab: NodeVocabulary = NodeVocabulary()): self.terminal_dict: dict[str, list[str]] = {} self._completed = False - def create_rule(self, - name: str, - current_nodes: list[str], - new_nodes: list[str], - current_in_edges: int, - current_out_edges: int, - new_edges: list[tuple[int, int]] = [], - current_links: list[tuple[int, int]] = []): + def create_rule( + self, + name: str, + current_nodes: list[str], + new_nodes: list[str], + current_in_edges: int, + current_out_edges: int, + new_edges: list[tuple[int, int]] = [], + current_links: list[tuple[int, int]] = [], + ): """Create a rule and add it to the dictionary. The method checks the created rule. There is no method to add already created rule to the vocabulary. @@ -73,28 +73,34 @@ def create_rule(self, """ if name in self.rule_dict: - raise Exception('This name is already in the rule vocabulary!') + raise Exception("This name is already in the rule vocabulary!") # Currently the GraphGrammar class can only apply rules that replace one node with the # new system of nodes. # But in future we may apply replacement of the linked set of nodes if len(current_nodes) != 1: - raise Exception(f'Prohibited length of the current_nodes: {len(current_nodes)}!') + raise Exception( + f"Prohibited length of the current_nodes: {len(current_nodes)}!" + ) # Check that all nodes are in vocabulary for node in current_nodes: if not self.node_vocab.check_node(node): - raise Exception(f'Label {node} not in node vocabulary!') + raise Exception(f"Label {node} not in node vocabulary!") for node in new_nodes: if not self.node_vocab.check_node(node): - raise Exception(f'Label {node} not in node vocabulary!') + raise Exception(f"Label {node} not in node vocabulary!") # if the rule deletes a node dont check its in and out connections if len(new_nodes) != 0: - #Currently current_ins_links and current_out_links should be just numbers - if current_in_edges > len(new_nodes) - 1 or current_out_edges > len( - new_nodes) - 1 or current_in_edges < 0 or current_out_edges < 0: + # Currently current_ins_links and current_out_links should be just numbers + if ( + current_in_edges > len(new_nodes) - 1 + or current_out_edges > len(new_nodes) - 1 + or current_in_edges < 0 + or current_out_edges < 0 + ): raise Exception("Invalid linking of the in or out edges!") i = 0 @@ -105,9 +111,14 @@ def create_rule(self, i += 1 for edge in new_edges: - if edge[0] > len(new_nodes) - 1 or edge[1] > len( - new_nodes) - 1 or edge[0] < 0 or edge[1] < 0 or edge[0] == edge[1]: - raise Exception(f'Invalid edge {edge}') + if ( + edge[0] > len(new_nodes) - 1 + or edge[1] > len(new_nodes) - 1 + or edge[0] < 0 + or edge[1] < 0 + or edge[0] == edge[1] + ): + raise Exception(f"Invalid edge {edge}") new_graph.add_edge(*edge) # graph_insert set the terminal status for the rule @@ -131,13 +142,21 @@ def create_rule(self, def __str__(self): """Print the rules from the dictionary of rules.""" - result = '' + result = "" for rule_tule in self.rule_dict.items(): rule_graph = rule_tule[1].graph_insert rule_node = rule_tule[1].replaced_node - result = result + rule_tule[0] + ": " + rule_node.label + " ==> " + str([ - node[1]['Node'].label for node in rule_graph.nodes.items() - ]) + ' ' + str([edge for edge in rule_graph.edges]) + '\n' + result = ( + result + + rule_tule[0] + + ": " + + rule_node.label + + " ==> " + + str([node[1]["Node"].label for node in rule_graph.nodes.items()]) + + " " + + str([edge for edge in rule_graph.edges]) + + "\n" + ) return result @@ -153,9 +172,13 @@ def check_rules(self): print(f"Nodes {diff} are not used as end nodes in the nonterminal rules!") # Check if all nodes in the end graphs of nonterminal rules have a terminal rule - diff = self.rules_nonterminal_node_set.difference(set(self.terminal_dict.keys())) + diff = self.rules_nonterminal_node_set.difference( + set(self.terminal_dict.keys()) + ) if len(diff) > 0: - print(f"Nodes {diff} don't have terminal rules! The set of rules is not completed!") + print( + f"Nodes {diff} don't have terminal rules! The set of rules is not completed!" + ) else: self._completed = True @@ -181,8 +204,8 @@ def get_list_of_applicable_rules(self, grammar: GraphGrammar): rule_name = rule_tuple[0] label_to_replace = rule.replaced_node.label for node in grammar.nodes.items(): - #find a node that can be replaced using the rule - if label_to_replace == node[1]['Node'].label: + # find a node that can be replaced using the rule + if label_to_replace == node[1]["Node"].label: list_of_applicable_rules.append(rule_name) return list(set(list_of_applicable_rules)) @@ -203,8 +226,8 @@ def get_list_of_applicable_nonterminal_rules(self, grammar: GraphGrammar): rule_name = rule_tuple[0] label_to_replace = rule.replaced_node.label for node in grammar.nodes.items(): - #find a node that can be replaced using the rule - if label_to_replace == node[1]['Node'].label: + # find a node that can be replaced using the rule + if label_to_replace == node[1]["Node"].label: list_of_applicable_rules.append(rule_name) return list(set(list_of_applicable_rules)) @@ -225,8 +248,8 @@ def get_list_of_applicable_terminal_rules(self, grammar: GraphGrammar): rule_name = rule_tuple[0] label_to_replace = rule.replaced_node.label for node in grammar.nodes.items(): - #find a node that can be replaced using the rule - if label_to_replace == node[1]['Node'].label: + # find a node that can be replaced using the rule + if label_to_replace == node[1]["Node"].label: list_of_applicable_rules.append(rule_name) return list(set(list_of_applicable_rules)) @@ -258,7 +281,7 @@ def make_graph_terminal(self, grammar: GraphGrammar): rule_list = [] for node in grammar.nodes.items(): if not node[1]["Node"].is_terminal: - rules = self.terminal_rules_for_node(node[1]['Node'].label) + rules = self.terminal_rules_for_node(node[1]["Node"].label) rule = self.terminal_rule_dict[rules[np.random.choice(len(rules))]] rule_list.append(rule) for rule in rule_list: @@ -281,11 +304,13 @@ def rule_vis(self, name: str): node.add_node(1, Node=rule.replaced_node) ax1 = plt.subplot(121) ax1.set_title("Replaced node") - nx.draw_networkx(node, - with_labels=True, - pos=nx.shell_layout(node, dim=2), - node_size=800, - labels={n: node.nodes[n]["Node"].label for n in node}) + nx.draw_networkx( + node, + with_labels=True, + pos=nx.shell_layout(node, dim=2), + node_size=800, + labels={n: node.nodes[n]["Node"].label for n in node}, + ) ax1.axis("off") ax2 = plt.subplot(122) @@ -295,32 +320,34 @@ def rule_vis(self, name: str): # node_size=500, # labels={n: graph.nodes[n]["Node"].label for n in graph}) - nx.draw_networkx(graph, - with_labels=True, - pos=nx.planar_layout(graph, dim=2, scale=5), - node_size=800, - labels={n: graph.nodes[n]["Node"].label for n in graph}) + nx.draw_networkx( + graph, + with_labels=True, + pos=nx.planar_layout(graph, dim=2, scale=5), + node_size=800, + labels={n: graph.nodes[n]["Node"].label for n in graph}, + ) ax2.axis("off") plt.show() -if __name__ == '__main__': +if __name__ == "__main__": node_vocab = NodeVocabulary() node_vocab.add_node(ROOT) - node_vocab.create_node('A') - node_vocab.create_node('B') - node_vocab.create_node('C') - node_vocab.create_node('D') - - node_vocab.create_node('A1', is_terminal=True) - node_vocab.create_node('B1', is_terminal=True) - node_vocab.create_node('C1', is_terminal=True) + node_vocab.create_node("A") + node_vocab.create_node("B") + node_vocab.create_node("C") + node_vocab.create_node("D") + + node_vocab.create_node("A1", is_terminal=True) + node_vocab.create_node("B1", is_terminal=True) + node_vocab.create_node("C1", is_terminal=True) rule_vocab = RuleVocabulary(node_vocab) - rule_vocab.create_rule("First_Rule", ['A'], ['B', 'C'], 0, 1, [(0, 1)]) - rule_vocab.create_rule("AT", ['A'], ['A1'], 0, 0) - rule_vocab.create_rule("BT", ['B'], ['B1'], 0, 0) - rule_vocab.create_rule("CT", ['C'], ['C1'], 0, 0) + rule_vocab.create_rule("First_Rule", ["A"], ["B", "C"], 0, 1, [(0, 1)]) + rule_vocab.create_rule("AT", ["A"], ["A1"], 0, 0) + rule_vocab.create_rule("BT", ["B"], ["B1"], 0, 0) + rule_vocab.create_rule("CT", ["C"], ["C1"], 0, 0) rule_vocab.create_rule("ROOT", ["ROOT"], ["A"], 0, 0) rule_vocab.create_rule("CD", ["C"], [], 0, 0) print(rule_vocab)