Skip to content
Snippets Groups Projects
Commit 32357914 authored by George Marchment's avatar George Marchment
Browse files

Added warning when channels are defined/used multiple times in different...

Added warning when channels are defined/used multiple times in different blocks -> sometimes breaks the rewrite
parent dc3e33c0
No related branches found
No related tags found
No related merge requests found
Pipeline #14648 failed with stage
in 2 minutes and 11 seconds
# creating a custom warning
class BioFlowInsightWarning(UserWarning):
pass
...@@ -246,4 +246,8 @@ class Main(Nextflow_Building_Blocks): ...@@ -246,4 +246,8 @@ class Main(Nextflow_Building_Blocks):
most_influential_conditions[condition]+=1 most_influential_conditions[condition]+=1
return most_influential_conditions return most_influential_conditions
else: else:
raise Exception("This shouldn't happen") raise Exception("This shouldn't happen")
\ No newline at end of file
def check_that_a_channel_is_not_defined_used_and_redefined_used_in_another_block(self):
return self.root.check_that_a_channel_is_not_defined_used_and_redefined_used_in_another_block()
\ No newline at end of file
...@@ -5,13 +5,10 @@ import json ...@@ -5,13 +5,10 @@ import json
import glob import glob
from datetime import date from datetime import date
#TODO -> check this or either change the warnings to nothing
import warnings
from pathlib import Path from pathlib import Path
from . import constant from . import constant
warnings.filterwarnings("ignore")
from .nextflow_building_blocks import Nextflow_Building_Blocks from .nextflow_building_blocks import Nextflow_Building_Blocks
from .outils import * from .outils import *
from .bioflowinsighterror import BioFlowInsightError from .bioflowinsighterror import BioFlowInsightError
......
...@@ -128,6 +128,7 @@ class Operation(Executor): ...@@ -128,6 +128,7 @@ class Operation(Executor):
else: else:
origin = self.origin.root origin = self.origin.root
#V1
#First check that the channel is not defined at the same level #First check that the channel is not defined at the same level
channels = origin.get_channels_from_name_same_level(name) channels = origin.get_channels_from_name_same_level(name)
#Then check that the channel is defined in the below level #Then check that the channel is defined in the below level
...@@ -138,6 +139,11 @@ class Operation(Executor): ...@@ -138,6 +139,11 @@ class Operation(Executor):
channels = origin.get_channels_from_name_above_level(name) channels = origin.get_channels_from_name_above_level(name)
if(channels==[]): if(channels==[]):
channels = origin.get_channels_from_name_other_blocks_on_same_level(name) channels = origin.get_channels_from_name_other_blocks_on_same_level(name)
#V2
channels = origin.get_channels_from_name_same_level(name)+origin.get_channels_from_name_inside_level(name)+origin.get_channels_from_name_above_level(name)+origin.get_channels_from_name_other_blocks_on_same_level(name)
channels = list(set(channels))
#If it still doesn't exist -> we create it #If it still doesn't exist -> we create it
if(channels==[]): if(channels==[]):
channel = Channel(name=name, origin=origin) channel = Channel(name=name, origin=origin)
...@@ -243,7 +249,8 @@ class Operation(Executor): ...@@ -243,7 +249,8 @@ class Operation(Executor):
origin = self.origin.root origin = self.origin.root
else: else:
origin = self.origin origin = self.origin
#V1
channels = origin.get_channels_from_name_same_level(name) channels = origin.get_channels_from_name_same_level(name)
if(channels==[]): if(channels==[]):
channels = origin.get_channels_from_name_inside_level(name) channels = origin.get_channels_from_name_inside_level(name)
...@@ -251,6 +258,10 @@ class Operation(Executor): ...@@ -251,6 +258,10 @@ class Operation(Executor):
channels = origin.get_channels_from_name_above_level(name) channels = origin.get_channels_from_name_above_level(name)
#if(channels==[]): #if(channels==[]):
# channels = origin.get_channels_from_name_other_blocks_on_same_level(name) # channels = origin.get_channels_from_name_other_blocks_on_same_level(name)
#V2
#channels = origin.get_channels_from_name_same_level(name)+origin.get_channels_from_name_inside_level(name)+origin.get_channels_from_name_above_level(name)
if(channels==[]): if(channels==[]):
channel = Channel(name=name, origin=self.origin) channel = Channel(name=name, origin=self.origin)
origin.add_channel(channel) origin.add_channel(channel)
...@@ -590,7 +601,7 @@ class Operation(Executor): ...@@ -590,7 +601,7 @@ class Operation(Executor):
if(to_add): if(to_add):
self.add_origin(c.get_name()) self.add_origin(c.get_name())
#TODO update this -> it's an operation itselfs #TODO update this -> it's an operation itselfs
warnings.warn(f"I don't know what i'm looking at '{name}' in '{self.get_code()}'\n") #warnings.warn(f"I don't know what i'm looking at '{name}' in '{self.get_code()}'\n")
...@@ -876,7 +887,7 @@ class Operation(Executor): ...@@ -876,7 +887,7 @@ class Operation(Executor):
self.gives = list(set(self.gives)) self.gives = list(set(self.gives))
#TODO -> this was originally uncommented, check it doesn't add any other bugs #TODO -> this was originally uncommented, check it doesn't add any other bugs
#self.origins = [] #self.origins = []
warnings.warn(f"TO CHECK !! From this : '{self.get_code()}'. I extracted to give (for a call) '{self.gives}' (in file '{self.get_file_address()}')\n") #warnings.warn(f"TO CHECK !! From this : '{self.get_code()}'. I extracted to give (for a call) '{self.gives}' (in file '{self.get_file_address()}')\n")
#TODO #TODO
#We check that the operation is an actuel operation and not just a string for example #We check that the operation is an actuel operation and not just a string for example
#if(len(self.get_origins())==0 and len(self.get_gives())==0): #if(len(self.get_origins())==0 and len(self.get_gives())==0):
......
...@@ -345,6 +345,40 @@ class Root(Nextflow_Building_Blocks): ...@@ -345,6 +345,40 @@ class Root(Nextflow_Building_Blocks):
element = sorted_position_2_thing_2_analyse[key] element = sorted_position_2_thing_2_analyse[key]
element.initialise() element.initialise()
#Example with 132
def check_that_a_channel_is_not_defined_used_and_redefined_used_in_another_block(self):
channels_defined_at_root_level = []
for exe in self.get_executors_same_level():
if(exe.get_type()=="Operation"):
channels_defined_at_root_level+=exe.get_gives()
channels_defined_used_in_calls_at_root = []
for call in self.get_calls_same_level():
params = call.get_parameters()
for p in params:
if(p.get_type()=="Operation"):
channels_defined_used_in_calls_at_root += p.origins
if(channels_defined_used_in_calls_at_root!=[]):
for block in self.blocks:
temp_return = block.check_that_a_channel_is_not_defined_used_and_redefined_used_in_another_block()
if(temp_return!=None):
return temp_return
channels_defined_inside_block = []
for exe in block.get_executors_same_level()+block.get_inside_executors():
if(exe.get_type()=="Operation"):
channels_defined_inside_block+=exe.get_gives()
calls_inside_block = block.get_calls_same_level()+block.get_calls_inside_level()
for call in calls_inside_block:
params = call.get_parameters()
for p in params:
if(p.get_type()=="Operation"):
for o in p.origins:
if(o in channels_defined_inside_block):
for ch in channels_defined_used_in_calls_at_root:
if(o.get_code()==ch.get_code()):
return o.get_code()
return None
def get_process_from_name(self, name): def get_process_from_name(self, name):
for m in self.modules_defined: for m in self.modules_defined:
......
...@@ -349,11 +349,17 @@ class Subworkflow(Main): ...@@ -349,11 +349,17 @@ class Subworkflow(Main):
for i in range(len(code)): for i in range(len(code)):
code[i] = code[i].strip() code[i] = code[i].strip()
if(code[i]!=""): if(code[i]!=""):
#V1
channels = self.root.get_channels_from_name_same_level(code[i]) channels = self.root.get_channels_from_name_same_level(code[i])
if(channels==[]): if(channels==[]):
channels = self.root.get_channels_from_name_inside_level(code[i]) channels = self.root.get_channels_from_name_inside_level(code[i])
if(channels==[]): if(channels==[]):
channels = self.root.get_channels_from_name_other_blocks_on_same_level(code[i]) channels = self.root.get_channels_from_name_other_blocks_on_same_level(code[i])
#V2
#channels = self.root.get_channels_from_name_same_level(code[i])+self.root.get_channels_from_name_inside_level(code[i])+self.root.get_channels_from_name_other_blocks_on_same_level(code[i])
if(channels!=[]): if(channels!=[]):
ope = Operation(code=f"e: {code[i]}", origin=self) ope = Operation(code=f"e: {code[i]}", origin=self)
ope.set_as_artificial() ope.set_as_artificial()
......
...@@ -8,6 +8,8 @@ from .outils_graph import get_flatten_dico, initia_link_dico_rec, get_number_cyc ...@@ -8,6 +8,8 @@ from .outils_graph import get_flatten_dico, initia_link_dico_rec, get_number_cyc
from .outils_annotate import get_tools_commands_from_user_for_process from .outils_annotate import get_tools_commands_from_user_for_process
from .bioflowinsighterror import BioFlowInsightError from .bioflowinsighterror import BioFlowInsightError
from .graph import Graph from .graph import Graph
import warnings
from .bioflowinsightwarning import BioFlowInsightWarning
#Outside packages #Outside packages
import os import os
...@@ -597,6 +599,7 @@ George Marchment, Bryan Brancotte, Marie Schmit, Frédéric Lemoine, Sarah Cohen ...@@ -597,6 +599,7 @@ George Marchment, Bryan Brancotte, Marie Schmit, Frédéric Lemoine, Sarah Cohen
min_condition_score = score min_condition_score = score
return min_relevant_processes return min_relevant_processes
#TODO -> add excpetion Channel exists in multiple forms -> check with 132
def get_relevant_following_best_general_score(self, def get_relevant_following_best_general_score(self,
reduction_alpha = 0.2, reduction_alpha = 0.2,
reduction_beta = 0.8, reduction_beta = 0.8,
...@@ -841,7 +844,10 @@ George Marchment, Bryan Brancotte, Marie Schmit, Frédéric Lemoine, Sarah Cohen ...@@ -841,7 +844,10 @@ George Marchment, Bryan Brancotte, Marie Schmit, Frédéric Lemoine, Sarah Cohen
generate_graph(self.get_output_dir()/ "debug" /"spec_graph", self.graph.full_dico, render_graphs = True) generate_graph(self.get_output_dir()/ "debug" /"spec_graph", self.graph.full_dico, render_graphs = True)
#generate_graph(self.get_output_dir()/ "debug" /"process_dependency_graph_OG", temp_process_dependency_graph, render_graphs = True) #generate_graph(self.get_output_dir()/ "debug" /"process_dependency_graph_OG", temp_process_dependency_graph, render_graphs = True)
generate_graph(self.get_output_dir()/ "debug" /"process_dependency_graph", self.graph.get_process_dependency_graph() , render_graphs = True) generate_graph(self.get_output_dir()/ "debug" /"process_dependency_graph", self.graph.get_process_dependency_graph() , render_graphs = True)
raise Exception("Something went wrong: The flat dependency graph is not the same!") if(self.channel_that_is_defined_used_and_redefined_used_in_another_block!=""):
raise BioFlowInsightError(f"Given that the channel '{self.channel_that_is_defined_used_and_redefined_used_in_another_block}' is defined and used in multiple conditional blocks. The rewrite could not be done with the proprosed relavant processes. Either correct the defintion of the workflow or give another set of relevant processes.", type="Channel exists in multiple forms")
else:
raise Exception("Something went wrong: The flat dependency graph is not the same!")
def check_relevant_processes_in_workflow(self, relevant_processes): def check_relevant_processes_in_workflow(self, relevant_processes):
...@@ -1036,12 +1042,31 @@ George Marchment, Bryan Brancotte, Marie Schmit, Frédéric Lemoine, Sarah Cohen ...@@ -1036,12 +1042,31 @@ George Marchment, Bryan Brancotte, Marie Schmit, Frédéric Lemoine, Sarah Cohen
seen.append(sub.get_code()) seen.append(sub.get_code())
#This methods raises a warning when there is a channel is defined in a bloc
#And used as a parameter in a call in the same bloc
#And that the channel is defined somewhere else in the code
def check_that_a_channel_is_not_defined_used_and_redefined_used_in_another_block(self):
self.channel_that_is_defined_used_and_redefined_used_in_another_block = False
for main in [self.get_workflow_main()]+self.get_subworkflows_called():
problematic_channel = main.check_that_a_channel_is_not_defined_used_and_redefined_used_in_another_block()
if(problematic_channel!=None):
self.channel_that_is_defined_used_and_redefined_used_in_another_block = problematic_channel
warnings.warn(f'The channel "{problematic_channel}" is defined and used in multiple seperate conditional blocks, depending on the relevant processes given, the rewrite may not be done.', BioFlowInsightWarning)
#This function checks that the rewrite can be done correctly -> checks for the elements "illegal" in the code
def check_something_illegal_for_rewrite(self):
self.check_that_a_channel_is_not_defined_used_and_redefined_used_in_another_block()
#Method which rewrites the workflow follwong the user view #Method which rewrites the workflow follwong the user view
#Conert workflow to user_view only makes sense when the option duplicate is activated -> otherwise is doesn't make sense + it makes the analysis way more complicated #Conert workflow to user_view only makes sense when the option duplicate is activated -> otherwise is doesn't make sense + it makes the analysis way more complicated
def convert_workflow_2_user_view(self, relevant_processes = [], render_graphs = True): def convert_workflow_2_user_view(self, relevant_processes = [], render_graphs = True):
self.iniatilise_tab_processes_2_remove() self.iniatilise_tab_processes_2_remove()
self.graph.initialise(processes_2_remove = self.processes_2_remove) self.graph.initialise(processes_2_remove = self.processes_2_remove)
self.check_something_illegal_for_rewrite()
def get_object(address): def get_object(address):
address = int(re.findall(r"\dx\w+", address)[0], base=16) address = int(re.findall(r"\dx\w+", address)[0], base=16)
return ctypes.cast(address, ctypes.py_object).value return ctypes.cast(address, ctypes.py_object).value
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment