diff --git a/src/graph.py b/src/graph.py index 7252cb32fac66539d67797dc9c53c127f2a37663..925f15f5989aa30b5ceea892fbb689bcb56af0c4 100644 --- a/src/graph.py +++ b/src/graph.py @@ -292,11 +292,14 @@ class Graph(): def generate_user_view(self, relevant_processes = [], render_graphs = True): #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) + with open(self.get_output_dir()/ "graphs/user_view.json", 'w') as output_file : json.dump(user_view, output_file, indent=4) + generate_graph(self.get_output_dir()/'graphs'/"user_view", user_view, label_edge=True, label_node=True, render_graphs = render_graphs) diff --git a/src/outils_annotate.py b/src/outils_annotate.py new file mode 100644 index 0000000000000000000000000000000000000000..0f968a8e48a7254dc72ad44b6ba60c386eadab6d --- /dev/null +++ b/src/outils_annotate.py @@ -0,0 +1,201 @@ +import copy +import numpy as np +import re + +tools = [] +commands = [] + + + + +def get_propositions(process, tools = -1, commands = -1): + temp = [] + if(tools!=-1): + for tool in tools: + #for character in char_after_tool: + for match in re.finditer(r"(\s|\(|\/|\|)"+tool+r"(\s|\-|\\|\.)", process): + #if(f"{tool}{character}" in process): + temp.append(tool) + if(commands!=-1): + for commands in commands: + tool, command = commands.split() + command = command.replace('+', '\+') + for match in re.finditer(tool+r"\s+\-[^\s]+\s+"+command, process): + temp.append(commands) + for match in re.finditer(tool+r"\s+"+command, process): + temp.append(commands) + for match in re.finditer(tool+r"\s+\\\s+"+command, process): + temp.append(commands) + for match in re.finditer(tool+r"\s+\-[^\s]+\s+[^\s]+\s+"+command, process): + temp.append(commands) + for match in re.finditer(tool+r"\.\w+\s+"+command, process): + temp.append(commands) + for match in re.finditer(tool+r"\.jar\s+[^\s]+\s+"+command, process): + temp.append(commands) + + return list(set(temp)) + + +def get_propositions_from_user(): + propositions = [] + nb_prop = 1 + input_val = "a" + while(input_val!=""): + input_val = input(f"Proposition {nb_prop} : ") + if(input_val!=""): + propositions.append(input_val) + nb_prop+=1 + return propositions + +def print_colored_words(text, words): + temp_words = [] + for word in words: + temp_words+= word.split() + words = temp_words + + colors = ['\033[31m', '\033[32m', '\033[33m', '\033[34m', '\033[35m', '\033[36m'] # Colors: Red, Green, Yellow, Blue, Magenta, Cyan + color_index = 0 + + for i in range(len(words)): + word = words[i] + color = colors[color_index % len(colors)] + text = text.replace(word, f"{color}{word}\033[0m") + color_index += 1 + print(text) + +def get_tools_commands_from_user_for_process(p, exiting_tools, existing_commands): + tools_found, commands_found = [], [] + codes = [] + codes.append(p.get_code()) + codes+=p.get_external_scripts_code() + + for c in codes: + print_colored_words(c, get_propositions(p, commands=existing_commands)+get_propositions(p, tools=exiting_tools)) + print("\nTOOLS") + confirmation = 'a' + while(confirmation!=""): + propositions = get_propositions_from_user() + confirmation = input(f"Press 'ENTER' to validate this propostion of tools {propositions} (press any key otherwise) : ") + tools_found += propositions + print("\nCOMMANDS") + confirmation = 'a' + while(confirmation!=""): + propositions = get_propositions_from_user() + confirmation = input(f"Press 'ENTER' to validate this propostion of commands {propositions} (press any key otherwise) : ") + commands_found += propositions + + exiting_tools+= tools_found + existing_commands+= commands_found + return tools_found, commands_found, exiting_tools, existing_commands + + + + +index = 0 +for process_id in process_2_annotations_pre_verification: + p = process_2_annotations_pre_verification[process_id]["process"] + try: + tmp = process_2_annotation[process_id] + except: + current_tools = process_2_annotations_pre_verification[process_id]["tools"] + current_commands = process_2_annotations_pre_verification[process_id]["commands"] + + print(f"\n* Current progess : {index/len(process_2_annotations_pre_verification)*100:.2f}% ({len(process_2_annotations_pre_verification)-index} left)") + print("--------------------------------------------------") + print_colored_words(p, current_commands+current_tools+get_propositions(p, commands=commands)+get_propositions(p, tools=tools)) + + validate_annoation = False + while(not validate_annoation): + print() + print_colored_words(f" - Current tools: {current_tools}", current_commands+current_tools) + print_colored_words(f" - Current commands: {current_commands}", current_commands+current_tools) + print() + annotation = input("Validate current annotations (press enter/ anykey otherwise):") + if(annotation==""): + validate_annoation = True + else: + print("\nTOOLS") + confirmation = 'a' + while(confirmation!=""): + propositions = get_propositions_from_user() + confirmation = input(f"Press 'ENTER' to validate this propostion of tools {propositions} (press any key otherwise) : ") + current_tools = propositions + print("\nCOMMANDS") + confirmation = 'a' + while(confirmation!=""): + propositions = get_propositions_from_user() + confirmation = input(f"Press 'ENTER' to validate this propostion of commands {propositions} (press any key otherwise) : ") + current_commands = propositions + + tools+=current_tools + commands+=current_commands + tools = list(set(tools)) + commands = list(set(commands)) + + ext_tools, ext_commands = [], [] + for ext in process_2_annotations_pre_verification[process_id]["external_scripts"]: + envs = ["env python", "env Rscript"] + show_it = True + for env in envs: + if(env in ext): + show_it = False + + if(show_it): + print("\n--------------------------------------------------") + propositions = get_propositions(ext, tools=tools) + print_colored_words(ext, propositions) + + print("\nTOOLS") + print_colored_words(f"Propositions are : {propositions}", propositions) + val = input("Press 'ENTER' to validate (press any key otherwise) : ") + if(val==''): + ext_tools+=propositions + else: + confirmation = 'a' + while(confirmation!=""): + propositions = get_propositions_from_user() + confirmation = input(f"Press 'ENTER' to validate this propostion of tools {propositions} (press any key otherwise) : ") + ext_tools+=propositions + + propositions = get_propositions(ext, commands=commands) + print_colored_words(ext, propositions) + print("\nCOMMANDS") + print_colored_words(f"Propositions are : {propositions}", propositions) + val = input("Press 'ENTER' to validate (press any key otherwise) : ") + if(val==''): + ext_commands+=propositions + else: + confirmation = 'a' + while(confirmation!=""): + propositions = get_propositions_from_user() + confirmation = input(f"Press 'ENTER' to validate this propostion of commands {propositions} (press any key otherwise) : ") + current_commands = propositions + ext_commands+=propositions + + current_tools+=ext_tools + current_commands+=ext_commands + current_tools = list(set(current_tools)) + current_commands = list(set(current_commands)) + + tools+=current_tools + commands+=current_commands + tools = list(set(tools)) + commands = list(set(commands)) + + process_2_annotation[process_id] = {} + process_2_annotation[process_id]['process'] = process_2_annotations_pre_verification[process_id]['process'] + process_2_annotation[process_id]['has_external_scripts'] = process_2_annotations_pre_verification[process_id]['has_external_scripts'] + process_2_annotation[process_id]['external_scripts'] = process_2_annotations_pre_verification[process_id]['external_scripts'] + process_2_annotation[process_id]['R_modules'] = process_2_annotations_pre_verification[process_id]['R_modules'] + process_2_annotation[process_id]['python_modules'] = process_2_annotations_pre_verification[process_id]['python_modules'] + process_2_annotation[process_id]['perl_modules'] = process_2_annotations_pre_verification[process_id]['perl_modules'] + process_2_annotation[process_id]['tools'] = current_tools + process_2_annotation[process_id]['commands'] = current_commands + + with open("process_2_annotation.json", "w") as outfile: + json.dump(process_2_annotation, outfile, indent=4) + + + index+=1 + + diff --git a/src/outils_graph.py b/src/outils_graph.py index fc5d4c67f458e8842ee3abaf2e30779eb8873009..4f17a58cc4d36d3cf8a949a7430345dc79b55694 100644 --- a/src/outils_graph.py +++ b/src/outils_graph.py @@ -414,19 +414,24 @@ def get_neighbors(edges, A): Bs.append(e['B']) return Bs -def exist_path(A, B, edges): - N = get_nodes_from_edges(edges=edges) - visited = {} - for n in N: - visited[n] = False + +def exist_path_rec(A, B, edges, visited): visited[A] = True if(A==B): return True for neigh in get_neighbors(edges, A): - if(exist_path(neigh, B, edges)): - return True + if(not visited[neigh]): + if(exist_path_rec(neigh, B, edges, visited = visited)): + return True return False +def exist_path(A, B, edges): + N = get_nodes_from_edges(edges=edges) + visited = {} + for n in N: + visited[n] = False + return exist_path_rec(A, B, edges, visited) + def nr_path_succ(n, r, dico, R): rest_of_R = set(R)-set([r]) @@ -533,6 +538,7 @@ def relev_user_view_builder(dico, relevant_modules): R = [] for r in relevant_modules: R+=get_id_from_name(dico, r) + R = list(set(R)) outputs = get_output_nodes(dico) inputs = get_input_nodes(dico) #dico['nodes'].append({'id':"input", 'name':"input"}) diff --git a/src/workflow.py b/src/workflow.py index 77ccd87a1b807159df1b7ad9003095625aed40c9..96bc4bbd22c19f73f24c66547e9336bae1152eee 100644 --- a/src/workflow.py +++ b/src/workflow.py @@ -4,6 +4,7 @@ from .nextflow_file import Nextflow_File from .ro_crate import RO_Crate from . import constant from .outils_graph import flatten_dico, initia_link_dico_rec, get_number_cycles +from .outils_annotate import get_tools_commands_from_user_for_process from .bioflowinsighterror import BioFlowInsightError #Outside packages @@ -46,7 +47,8 @@ class Workflow: version = None, keywords = None, producer = None, publisher = None, processes_2_remove = None, processes_annotation = None, - personnal_acces_token = None): + personnal_acces_token = None, + processes_2_tools = None): if(not os.path.isfile(file)): nextflow_files = glob.glob(f'{file}/*.nf') @@ -83,6 +85,7 @@ class Workflow: self.producer = producer self.publisher = publisher self.personnal_acces_token = personnal_acces_token + self.processes_2_tools = processes_2_tools if(processes_2_remove==""): processes_2_remove = None self.processes_2_remove = processes_2_remove @@ -532,4 +535,21 @@ George Marchment, Bryan Brancotte, Marie Schmit, Frédéric Lemoine, Sarah Cohen temp = self.processes_2_remove.split(",") for t in temp: tab_processes_2_remove.append(t.strip()) - self.nextflow_file.generate_user_view(relevant_processes = relevant_processes, render_graphs = render_graphs, processes_2_remove = tab_processes_2_remove) \ No newline at end of file + self.nextflow_file.generate_user_view(relevant_processes = relevant_processes, render_graphs = render_graphs, processes_2_remove = tab_processes_2_remove) + + def build_processes_2_tools(self): + if(self.processes_2_tools==None): + exiting_tools, existing_commands = [], [] + processes = self.get_processes_used() + dico = {} + for p in processes: + tools_found, commands_found, exiting_tools, existing_commands = get_tools_commands_from_user_for_process(p, exiting_tools, existing_commands) + dico[p.get_code()] = {} + dico[p.get_code()]["tools"] = tools_found + dico[p.get_code()]["commands"] = commands_found + self.processes_2_tools = dico + with open(f"{self.get_output_dir()}/processes_2_tools.json", 'w') as output_file : + json.dump(self.processes_2_tools, output_file, indent=2) + return self.processes_2_tools + else: + return self.processes_2_tools