From 7229dedae8bb628cce9ef50e3b46e2fd5d99c33b Mon Sep 17 00:00:00 2001 From: maaikedieuwertje <maaikedieuwertje@gmail.com> Date: Sat, 14 Apr 2018 11:15:25 +0200 Subject: [PATCH] only add information to node if valued and added new function add_instance_of() Former-commit-id: 3643709dcf62033308317c61ced58d29b55b0b68 --- kadmos/graph/graph_data.py | 6 +- kadmos/graph/graph_kadmos.py | 132 +++++++++++++++++++++++++++++------ 2 files changed, 114 insertions(+), 24 deletions(-) diff --git a/kadmos/graph/graph_data.py b/kadmos/graph/graph_data.py index 69c4e12b0..3d192006f 100644 --- a/kadmos/graph/graph_data.py +++ b/kadmos/graph/graph_data.py @@ -684,7 +684,7 @@ class DataGraph(KadmosGraph): :rtype: int """ assert 'instance' in self.nodes[node], 'node {} does not have the expected attribute "instance".'.format(node) - highest_instance = self.nodes[node]['instance'] + highest_instance = int(self.nodes[node]['instance']) instance_exists = True while instance_exists: # Check for one higher instance @@ -4307,8 +4307,8 @@ class MdaoDataGraph(DataGraph, MdaoMixin): cmdows_parameter_node.set('uID', graph_parameter_node) instance = int(self.nodes[graph_parameter_node].get('instance')) if instance > 1: - cmdows_parameter_node.add('relatedInstanceUID', graph_parameter_node.strip(self.INSTANCE_SUFFIX + - str(instance))) + cmdows_parameter_node.add('relatedInstanceUID', + self.get_first_node_instance(self.nodes[graph_parameter_node])) else: cmdows_parameter_node.add('relatedParameterUID', self.nodes[graph_parameter_node].get('related_to_schema_node')) diff --git a/kadmos/graph/graph_kadmos.py b/kadmos/graph/graph_kadmos.py index ca90887e7..2f0d0d467 100644 --- a/kadmos/graph/graph_kadmos.py +++ b/kadmos/graph/graph_kadmos.py @@ -1016,13 +1016,15 @@ class KadmosGraph(nx.DiGraph, EquationMixin, VistomsMixin): if instance > 1: instance = graph_design_competence_data.get('instance') - cmdows_design_competence.add('relatedInstanceUID', graph_design_competence.strip(self.INSTANCE_SUFFIX + - str(instance))) + cmdows_design_competence.add('relatedInstanceUID', + self.get_first_node_instance(self.nodes[cmdows_design_competence])) else: - cmdows_design_competence.add('ID', graph_design_competence_data.get('name')) - cmdows_design_competence.add('modeID', graph_design_competence_data.get('mode', 'main')) - cmdows_design_competence.add('version', graph_design_competence_data.get('version', '1.0')) + cmdows_design_competence.add('ID', graph_design_competence_data.get('name'), only_add_if_valued=True) + cmdows_design_competence.add('modeID', graph_design_competence_data.get('mode', 'main'), + only_add_if_valued=True) + cmdows_design_competence.add('version', graph_design_competence_data.get('version', '1.0'), + only_add_if_valued=True) # Create designCompetences/designCompetence/metadata with children # TODO: Preferably make sure that contacts are always saved to the database? @@ -1058,14 +1060,14 @@ class KadmosGraph(nx.DiGraph, EquationMixin, VistomsMixin): cmdows_parameter.add('instanceID', instance) if instance > 1: - cmdows_parameter.add('relatedInstanceUID', graph_parameter.strip(self.INSTANCE_SUFFIX + str(instance))) + cmdows_parameter.add('relatedInstanceUID', self.get_first_node_instance(self.nodes[graph_parameter])) else: cmdows_parameter.add('description', self.nodes[graph_parameter].get('description'), only_add_if_valued=True) - cmdows_parameter.add('note', self.nodes[graph_parameter].get('note')) - cmdows_parameter.add('unit', self.nodes[graph_parameter].get('unit')) - cmdows_parameter.add('dataType', self.nodes[graph_parameter].get('data_type')) + cmdows_parameter.add('note', self.nodes[graph_parameter].get('note'), only_add_if_valued=True) + cmdows_parameter.add('unit', self.nodes[graph_parameter].get('unit'), only_add_if_valued=True) + cmdows_parameter.add('dataType', self.nodes[graph_parameter].get('data_type'), only_add_if_valued=True) return cmdows_parameters @@ -1255,20 +1257,27 @@ class KadmosGraph(nx.DiGraph, EquationMixin, VistomsMixin): def _load_cmdows_parameters(self, cmdows): for variable in cmdows.findall('parameters/parameter'): + uid = variable.get('uID').replace("'", '"') + if variable.findtext('relatedInstanceUID'): related_variable = cmdows.xpath(get_uid_search_xpath(variable.findtext('relatedInstanceUID')))[0] else: related_variable = variable - self.add_node(variable.get('uID').replace("'", '"'), + self.add_node(uid, category='variable', shape='o', label=variable.findtext('label'), - instance=variable.findtext('instanceID'), - description=related_variable.findtext('description'), - note=related_variable.findtext('note'), - unit=related_variable.findtext('unit'), - data_type=related_variable.findtext('dataType')) + instance=variable.findtext('instanceID')) + + if related_variable.findtext('description') is not None: + self.nodes[uid]['description'] = related_variable.findtext('description') + if related_variable.findtext('note') is not None: + self.nodes[uid]['note'] = related_variable.findtext('note') + if related_variable.findtext('unit') is not None: + self.nodes[uid]['unit'] = related_variable.findtext('unit') + if related_variable.findtext('dataType') is not None: + self.nodes[uid]['data_type'] = related_variable.findtext('dataType') return @@ -1996,6 +2005,89 @@ class KadmosGraph(nx.DiGraph, EquationMixin, VistomsMixin): for key in attr_dict: self.adj[u][v][key] = attr_dict[key] + def add_instance_of(self, file_path, node): + """Method to duplicate a function with a higher instance + + :param file_path: path to CMDOWS file + :type file_path: basestring + :param node: node to get instance of + :type node: str + :return: new node + :rtype: str + """ + + assert int(self.nodes[node]['instance']) == 1, 'first instance of the function has to be supplied' + + inputs_list = [] + outputs_list = [] + cmdows = etree.parse(file_path, parser).getroot() + cmdows.clean() + ignore_modes=False + + uid = self.add_instance(node) + + kwargs = {'name': self.nodes[node]['name'], 'mode': self.nodes[node]['mode'], 'instance': uid[-1:], + 'version': self.nodes[node]['version'], 'label': self.nodes[node]['label'], + 'general_info': self.nodes[node]['general_info'], + 'performance_info': self.nodes[node]['performance_info'], + 'execution_info': self.nodes[node]['execution_info'], + 'projectSpecific': self.nodes[node]['projectSpecific']} + + new_node = self.copy_node_with_suffix(node, self.INSTANCE_SUFFIX + uid[-1:], '', **kwargs) + + function = cmdows.xpath(get_uid_search_xpath(node))[0] + + for inp in function.findall('inputs/input'): + self.add_edge(inp.findtext('parameterUID').replace("'", '"'), new_node, + valid_ranges=inp.finddict('validRanges', ordered=False, camel_case_conversion=True)) + + if not function.findall('inputs/input'): + # Determine assumed input file location (same folder as CMDOWS file) + input_file_path = os.path.join(os.path.split(os.path.normpath(function.base))[0], + function.findtext('ID') + '-input.xml').replace('file:' + os.path.sep, '') + + if os.path.isfile(input_file_path): + inputs_list.append(input_file_path) + else: + logger.warning('Could not find inputs for function: ' + function.get('uID')) + + for output in function.findall('outputs/output'): + self.add_edge(new_node, output.findtext('parameterUID').replace("'", '"')) + + if not function.findall('outputs/output'): + # Determine assumed output file location (same folder as CMDOWS file) + output_file_path = os.path.join(os.path.split(os.path.normpath(function.base))[0], + function.findtext('ID') + '-output.xml').replace('file:' + os.path.sep, '') + if os.path.isfile(output_file_path): + outputs_list.append(output_file_path) + else: + logger.warning('Could not find outputs for function: ' + function.get('uID')) + + # Add inputs and outputs based on XML + for input_el in inputs_list: + inputs = _read_io_xml_file(input_el, function.findtext('modeID'), ignore_modes=ignore_modes) + for input in inputs['leafNodes']: + if not self.has_node(input['xpath']): + self.add_node(input['xpath'], + category='variable', + shape='o', # TODO: Extend this XML attributes for description, note, unit, data_type + label=input['xpath'].split('/')[-1]) + self.add_edge(input['xpath'], new_node) + + for output_el in outputs_list: + outputs = _read_io_xml_file(output_el, function.findtext('modeID'), ignore_modes=ignore_modes) + for output in outputs['leafNodes']: + # Add new parameter if it does not exist yet + if not self.has_node(output['xpath']): + self.add_node(output['xpath'], + category='variable', + shape='o', + label=output['xpath'].split('/')[ + -1]) # TODO: Extend this to pick up XML attributes for description, note, unit, data_type + self.add_edge(new_node, output['xpath']) + + return new_node + def has_nodes(self, nodes): """Function that checks whether all nodes given in a list are present in the graph. @@ -3355,7 +3447,7 @@ class KadmosGraph(nx.DiGraph, EquationMixin, VistomsMixin): new_instance = highest_instance+1 else: new_instance = instance - if node_instance > 1: + if int(node_instance) > 1: original_node = node[:-len(self.INSTANCE_SUFFIX + str(node_instance))] else: original_node = node @@ -3401,7 +3493,7 @@ class KadmosGraph(nx.DiGraph, EquationMixin, VistomsMixin): :type label_extension: str :param kwargs: keyword arguments will be added as node attributes :type kwargs: dict, int - :return: new node name and enriched graph + :return: new node and enriched graph :rtype: str """ @@ -4948,8 +5040,7 @@ def check_database(file_name, source_folder=None, check_list=None, keep_running= if not function.findall('inputs/input'): # Determine assumed input file location (same folder as CMDOWS file) input_file_path = os.path.join(os.path.split(os.path.normpath(function.base))[0], - function.findtext('ID') + '-input.xml').replace('file:' + os.path.sep, - '') + function.findtext('ID') + '-input.xml').replace('file:' + os.path.sep, '') if os.path.isfile(input_file_path): inputs_list.append([input_file_path, function]) else: @@ -4958,8 +5049,7 @@ def check_database(file_name, source_folder=None, check_list=None, keep_running= if not function.findall('inputs/input'): # Determine assumed input file location (same folder as CMDOWS file) output_file_path = os.path.join(os.path.split(os.path.normpath(function.base))[0], - function.findtext('ID') + '-output.xml').replace('file:' + os.path.sep, - '') + function.findtext('ID') + '-output.xml').replace('file:' + os.path.sep, '') if os.path.isfile(input_file_path): outputs_list.append([output_file_path, function]) else: -- GitLab