diff --git a/src/graph.py b/src/graph.py index 15177a5fd58d9a4542d9e729237bda059320186f..0f26b791d087ce7ba1b4ac286de3fa4fc7700042 100644 --- a/src/graph.py +++ b/src/graph.py @@ -16,6 +16,8 @@ class Graph(): self.link_dico = None #Dico to graph without operations self.dico_process_dependency_graph = {} + self.user_view_with_subworkflows = {} + self.new_nodes_user_view = [] self.dico_wo_branch_operation = {} #Dictionaries for metadata @@ -289,13 +291,14 @@ class Graph(): #============================ #GENERATE USER VIEW #============================ - def generate_user_view(self, relevant_processes = [], render_graphs = True): + + def get_user_view_graph(self, relevant_processes = []): #For now i'm only gonna work from the flattened dico self.initialise_flattened_dico(self.dico_process_dependency_graph) #self.initialise_flattened_dico(self.full_dico) dico = self.dico_flattened - user_view = relev_user_view_builder(dico, relevant_modules=relevant_processes) + user_view, self.new_nodes_user_view = relev_user_view_builder(dico, relevant_modules=relevant_processes) with open(self.get_output_dir()/ "graphs/user_view.json", 'w') as output_file : json.dump(user_view, output_file, indent=4) @@ -305,6 +308,11 @@ class Graph(): with open(self.get_output_dir()/ "graphs/user_view_with_subworkflows.json", 'w') as output_file : json.dump(user_view_with_subworkflows, output_file, indent=4) + return user_view, user_view_with_subworkflows + + def generate_user_view(self, relevant_processes = [], render_graphs = True): + user_view, user_view_with_subworkflows = self.get_user_view_graph(relevant_processes = relevant_processes) + self.user_view_with_subworkflows = user_view_with_subworkflows generate_graph(self.get_output_dir()/'graphs'/"user_view", user_view, label_edge=True, label_node=True, render_graphs = render_graphs) generate_graph(self.get_output_dir()/'graphs'/"user_view_with_subworkflows", user_view_with_subworkflows, label_edge=True, label_node=True, render_graphs = render_graphs) @@ -312,18 +320,43 @@ class Graph(): #GENERATE LEVEL GRAPHS #============================ def generate_level_graphs(self, render_graphs = True, label_edge=True, label_node=True): - #dico = self.dico_process_dependency_graph - dico = self.full_dico + dico = self.dico_process_dependency_graph + #dico = self.full_dico max_level = get_max_level(dico) for l in range(max_level+1): new_dico = get_graph_level_l(dico, l) #print(new_dico) generate_graph(self.get_output_dir()/'graphs'/f"level_{l}", new_dico, label_edge=label_edge, label_node=label_node, render_graphs = render_graphs) + #============================ + #GET NUMBER OF SUBWORKFLOWS + #============================ + def get_number_subworkflows_process_dependency_graph(self): + return get_number_of_subworkflows(self.dico_process_dependency_graph) + + def get_number_subworkflows_user_view(self): + return get_number_of_subworkflows(self.user_view_with_subworkflows ) - - + #============================ + #GET node_2_subworkflows + #============================ + def node_2_subworkflows_process_dependency_graph(self): + node_2_subworkflows = {} + fill_node_2_subworkflows(self.dico_process_dependency_graph, node_2_subworkflows) + return node_2_subworkflows + + #This methods returns the nodes to subworkflow dico but for the OG processes + def node_2_subworkflows_user_view(self): + node_2_subworkflows = {} + fill_node_2_subworkflows(self.user_view_with_subworkflows, node_2_subworkflows) + new_node_2_subworkflows = {} + for group in self.new_nodes_user_view: + for node in group: + for id in node_2_subworkflows: + if(node.replace('<', '').replace('>', '') in id): + new_node_2_subworkflows[node] = node_2_subworkflows[id] + return new_node_2_subworkflows #============================ #METADATA FROM GRAPH diff --git a/src/nextflow_file.py b/src/nextflow_file.py index 3566e4ebafe81a44e15416d3e7b25497523cfa96..4180fd0fa453f0df155457dc1209d1317749d2a1 100644 --- a/src/nextflow_file.py +++ b/src/nextflow_file.py @@ -720,6 +720,20 @@ class Nextflow_File(Nextflow_Building_Blocks): #def get_metadata_graph_wo_operations(self): # self.graph.get_metadata_graph_wo_operations() + def get_number_subworkflows_process_dependency_graph(self): + return self.graph.get_number_subworkflows_process_dependency_graph() + + def get_number_subworkflows_user_view(self): + return self.graph.get_number_subworkflows_user_view() + + def node_2_subworkflows_process_dependency_graph(self): + return self.graph.node_2_subworkflows_process_dependency_graph() + + def node_2_subworkflows_user_view(self): + return self.graph.node_2_subworkflows_user_view() + + + def add_main_DSL1_2_rocrate(self, dico, file_dico, file_name): main_key = f"{file_name}#main" file_dico["hasPart"].append(main_key) diff --git a/src/outils_graph.py b/src/outils_graph.py index 8ea7184ef6f5f09b72f4194573e2b9d84ff87bf6..0f5c1b1fd571f39de521a8f9b513f88595142373 100644 --- a/src/outils_graph.py +++ b/src/outils_graph.py @@ -638,7 +638,7 @@ def relev_user_view_builder(dico_param, relevant_modules): for out in outputs: dico["edges"].append({'A':out, 'B':'output'}) #TODO remove this -> it's to replicate the one in the algortihm demo - #dico["edges"].append({'A':get_id_from_name(dico, "M5")[0], 'B':'output'}) + #dico["edges"].append({'A':get_id_from_name(dico, f"M5{tag}0")[0], 'B':'output'}) for input in inputs: dico["edges"].append({'A':"input", 'B':input}) U = [] @@ -731,7 +731,6 @@ def relev_user_view_builder(dico_param, relevant_modules): new_nodes = list(U)+NRC - new_dico = {} new_dico["nodes"] = [] new_dico["edges"] = [] @@ -765,6 +764,8 @@ def relev_user_view_builder(dico_param, relevant_modules): "label": "" }) added_edges.append(edge_string) + + #The output nodes are the nodes which their outputs aren't connected to anything else outputs = get_output_nodes(new_dico) inputs = get_input_nodes(new_dico) new_dico["nodes"].append({"id": "input","name": "i","shape": "triangle", "fillcolor":"#ffffff"}) @@ -773,7 +774,7 @@ def relev_user_view_builder(dico_param, relevant_modules): new_dico["edges"].append({'A':out, 'B':'output', "label": ""}) for input in inputs: new_dico["edges"].append({'A':"input", 'B':input, "label": ""}) - return new_dico + return new_dico, new_nodes #This function fills the new_dico with the flattened_dico but #reintegrates the subworkflows (from the full workflow) @@ -807,16 +808,20 @@ def get_max_level(dico, val = 0): max_val = tmp return max_val +#Function that fills the dictionnary node_2_subworkflows +def fill_node_2_subworkflows(dico, node_2_subworkflows, back_log_subworklows = []): + for n in dico["nodes"]: + node_2_subworkflows[n['id']] = back_log_subworklows + for sub in dico["subworkflows"]: + fill_node_2_subworkflows(dico["subworkflows"][sub], node_2_subworkflows, back_log_subworklows+[sub]) + + def get_graph_level_l(dico, level): import time tag = str(time.time()) - def fill_node_2_subworkflows(dico, node_2_subworkflows, back_log_subworklows = []): - for n in dico["nodes"]: - node_2_subworkflows[n['id']] = back_log_subworklows - for sub in dico["subworkflows"]: - fill_node_2_subworkflows(dico["subworkflows"][sub], node_2_subworkflows, back_log_subworklows+[sub]) + node_2_subworkflows = {} fill_node_2_subworkflows(dico, node_2_subworkflows) #print(node_2_subworkflows) @@ -891,7 +896,13 @@ def get_graph_level_l(dico, level): return new_dico - +def get_number_of_subworkflows(dico, val= 0): + + for sub in dico["subworkflows"]: + if(dico["subworkflows"][sub]["nodes"]!=[]): + val += 1 + val=get_number_of_subworkflows(dico["subworkflows"][sub], val) + return val diff --git a/src/workflow.py b/src/workflow.py index 574f66f82048b96f11c18247a0b381ac10661b7e..1636137da0b24c697d9a66c258a5753f1f5b5e59 100644 --- a/src/workflow.py +++ b/src/workflow.py @@ -581,3 +581,16 @@ George Marchment, Bryan Brancotte, Marie Schmit, Frédéric Lemoine, Sarah Cohen return self.processes_2_tools else: return self.processes_2_tools + + + def get_number_subworkflows_process_dependency_graph(self): + return self.nextflow_file.get_number_subworkflows_process_dependency_graph() + + def get_number_subworkflows_user_view(self): + return self.nextflow_file.get_number_subworkflows_user_view() + + def node_2_subworkflows_process_dependency_graph(self): + return self.nextflow_file.node_2_subworkflows_process_dependency_graph() + + def node_2_subworkflows_user_view(self): + return self.nextflow_file.node_2_subworkflows_user_view() \ No newline at end of file