def test_padmet_to_padmet_reversibility(): """ Test an issue encountered when a reaction is defined in a direction in one padmet. And in another the same reaction is defined as reversible. In old padmet this leads to the reaction having all of its reactants/products as reactants and also as products. """ # Read padmet file padmet_to_padmet('test_data/padmet', 'fabo.padmet') expected_padmet = PadmetSpec('fabo.padmet') reactants = [ rlt.id_out for rlt in expected_padmet.dicOfRelationIn['ENOYL-COA-HYDRAT-RXN'] if rlt.type in ['consumes'] ] products = [ rlt.id_out for rlt in expected_padmet.dicOfRelationIn['ENOYL-COA-HYDRAT-RXN'] if rlt.type in ['produces'] ] assert sorted(reactants) == [ 'TRANS-D2-ENOYL-COA', 'WATER' ] or sorted(products) == ['TRANS-D2-ENOYL-COA', 'WATER'] assert sorted(products) == [ 'L-3-HYDROXYACYL-COA' ] or sorted(reactants) == ['L-3-HYDROXYACYL-COA'] os.remove('fabo.padmet')
def test_padmet_to_padmet(): # Using inpu data, create 2 padmets and delete one reaction in each. fabo_1_padmetSpec = from_pgdb_to_padmet('test_data/pgdb', extract_gene=True) fabo_1_padmetSpec.delNode('ACYLCOASYN-RXN') fabo_1_padmetSpec.generateFile('fabo_1.padmet') _, _, all_rxns, _ = extract_data_padmet(fabo_1_padmetSpec) assert not set(FABO_RXNS).issubset(set(all_rxns)) fabo_2_padmetSpec = from_pgdb_to_padmet('test_data/pgdb', extract_gene=True) fabo_2_padmetSpec.delNode('ACYLCOADEHYDROG-RXN') fabo_2_padmetSpec.generateFile('fabo_2.padmet') _, _, all_rxns, _ = extract_data_padmet(fabo_2_padmetSpec) assert not set(FABO_RXNS).issubset(set(all_rxns)) # By merging them we should retrieve the two deleted reactions padmet_to_padmet('fabo_1.padmet,fabo_2.padmet', 'fabo.padmet') expected_padmet = PadmetSpec('fabo.padmet') _, _, all_rxns, _ = extract_data_padmet(expected_padmet) assert set(FABO_RXNS).issubset(set(all_rxns)) os.remove('fabo_1.padmet') os.remove('fabo_2.padmet') os.remove('fabo.padmet')
def main(): args = docopt.docopt(__doc__) if args["--padmetRef"]: padmetRef = PadmetRef(args["--padmetRef"]) else: padmetRef = None output = args["--output"] verbose = args["-v"] to_add = args["--to_add"] padmet_to_padmet.padmet_to_padmet(to_add, output, padmetRef, verbose)
def run_merge(run_id, nb_cpu_to_use, verbose, veryverbose=None): if verbose: print('--- Running merge step ---') merge_start_time = time.time() aucome_pool = Pool(nb_cpu_to_use) config_data = parse_config_file(run_id) padmet_from_annotation_path = config_data['padmet_from_annotation_path'] padmet_from_networks_path = config_data['padmet_from_networks_path'] sbml_from_networks_path = config_data['sbml_from_networks_path'] database_path = config_data['database_path'] structural_padmets_path = config_data['structural_padmets_path'] orthofinder_filtered_path = config_data['orthofinder_filtered_path'] orthofinder_padmet_path = config_data['orthofinder_padmet_path'] padmet_from_annotation_path = config_data['padmet_from_annotation_path'] networks_path = config_data['networks_path'] structural_padmets = [padmet for padmet in os.listdir(structural_padmets_path) if padmet.endswith('.padmet')] orthofinder_filtered_padmets = [padmet for padmet in os.listdir(orthofinder_filtered_path) if padmet.endswith('.padmet')] orthofinder_padmets = [padmet for padmet in os.listdir(orthofinder_padmet_path) if padmet.endswith('.padmet')] pathway_tools_padmets = [padmet for padmet in os.listdir(padmet_from_annotation_path) if padmet.endswith('.padmet')] if len(structural_padmets) > 0: padmets = [(padmet, structural_padmets_path + '/' + padmet) for padmet in structural_padmets] elif len(orthofinder_filtered_padmets) > 0: padmets = [(padmet, orthofinder_filtered_path + '/' + padmet) for padmet in orthofinder_filtered_padmets] elif len(orthofinder_padmets) > 0: padmets = [(padmet, orthofinder_padmet_path + '/' + padmet) for padmet in orthofinder_padmets] elif len(pathway_tools_padmets) > 0: padmets = [(padmet, padmet_from_annotation_path + '/' + padmet) for padmet in pathway_tools_padmets] else: sys.exit('No padmets have been created, run reconstruction or workflow.') study_draft_data = [] for study_name, padmet_path in padmets: tmp_study_data = {'padmet_path': padmet_path, 'study_padmet': study_name, 'padmet_from_networks_path': padmet_from_networks_path, 'sbml_from_networks_path': sbml_from_networks_path, 'database_path': database_path, 'verbose': verbose, 'veryverbose': veryverbose} study_draft_data.append(tmp_study_data) aucome_pool.map(create_output, study_draft_data) aucome_pool.close() aucome_pool.join() padmet_to_padmet.padmet_to_padmet(padmet_from_networks_path, networks_path + '/panmetabolism.padmet', verbose=veryverbose) sbmlGenerator.padmet_to_sbml(padmet=networks_path + '/panmetabolism.padmet', output=networks_path + '/panmetabolism.sbml', verbose=veryverbose) merge_end_time = (time.time() - merge_start_time) integer_part, decimal_part = str(merge_end_time).split('.') merge_time = ".".join([integer_part, decimal_part[:3]]) if verbose: print("--- merge step done in: %ss ---" %merge_time)
def test_padmet_to_padmet_cli(): # Using inpu data, create 2 padmets and delete one reaction in each. subprocess.call([ 'padmet', 'pgdb_to_padmet', '--pgdb', 'test_data/pgdb', '--output', 'test.padmet', '--extract-gene' ]) fabo_1_padmetSpec = PadmetSpec('test.padmet') fabo_1_padmetSpec.delNode('ACYLCOASYN-RXN') fabo_1_padmetSpec.generateFile('fabo_1.padmet') _, _, all_rxns, _ = extract_data_padmet(fabo_1_padmetSpec) os.remove('test.padmet') assert not set(FABO_RXNS).issubset(set(all_rxns)) subprocess.call([ 'padmet', 'pgdb_to_padmet', '--pgdb', 'test_data/pgdb', '--output', 'test.padmet', '--extract-gene' ]) fabo_2_padmetSpec = PadmetSpec('test.padmet') fabo_2_padmetSpec.delNode('ACYLCOADEHYDROG-RXN') fabo_2_padmetSpec.generateFile('fabo_2.padmet') _, _, all_rxns, _ = extract_data_padmet(fabo_2_padmetSpec) os.remove('test.padmet') assert not set(FABO_RXNS).issubset(set(all_rxns)) # By merging them we should retrieve the two deleted reactions padmet_to_padmet('fabo_1.padmet,fabo_2.padmet', 'fabo.padmet') subprocess.call([ 'padmet', 'padmet_to_padmet', '--to_add', 'fabo_1.padmet,fabo_2.padmet', '--output', 'fabo.padmet' ]) expected_padmet = PadmetSpec('fabo.padmet') _, _, all_rxns, _ = extract_data_padmet(expected_padmet) assert set(FABO_RXNS).issubset(set(all_rxns)) os.remove('fabo_1.padmet') os.remove('fabo_2.padmet') os.remove('fabo.padmet')
def analysis_on_group(group_name, groups, config_data, pvclust, nb_cpu_to_use, verbose): """Create reaction dendrogram and extract specific reactions using metabolic networks. Args: group_name (str): Name of the group from group_template.tsv. groups (list): All the species inside the group. config_data (dict): Dictionary with all configuration paths. pvclust (boolean): use also pvclust to create reaction dendrogram nb_cpu_to_use (int): number of CPU for multiprocessing verbose (bool): Verbose. """ database_path = config_data['database_path'] padmetRef = PadmetRef(database_path) padmet_from_networks_path = config_data['padmet_from_networks_path'] analysis_path = config_data['analysis_path'] all_padmet_path = [ os.path.join(padmet_from_networks_path, name + ".padmet") for name in groups ] group_analysis_path = analysis_path + '/' + group_name if not os.path.isdir(group_analysis_path): if len(groups) == 1: sys.exit('A group must contain more than one member.') for padmet_path in all_padmet_path: if not os.path.exists(padmet_path): org_name = os.path.splitext(os.path.basename(padmet_path))[0] sys.exit( "Padmet file of organism %s from group %s not found in %s" % (org_name, group_name, padmet_from_networks_path)) # Compare the padmet to create the reactions.tsv file needed to create the reaction dendrogram. compare_padmet.compare_padmet(padmet_path=",".join(all_padmet_path), output=group_analysis_path, padmetRef=padmetRef, verbose=verbose, number_cpu=nb_cpu_to_use) padmet_to_padmet.padmet_to_padmet( ",".join(all_padmet_path), group_analysis_path + '/' + group_name + '_panmetabolism.padmet') sbmlGenerator.padmet_to_sbml(padmet=group_analysis_path + '/' + group_name + '_panmetabolism.padmet', output=group_analysis_path + '/' + group_name + '_panmetabolism.sbml', verbose=verbose) dendrogram_reactions_distance.reaction_figure_creation( reaction_file=group_analysis_path + '/reactions.tsv', output_folder=group_analysis_path + '/dendrogram_output', padmetRef_file=database_path, pvclust=pvclust, verbose=verbose) else: print( group_analysis_path + ' already exists. Delete it if you want to relaunch the analysis.')
def visu_path_compounds(padmet_pathname, padmet_ref_pathname, pathway_ids, output_file, hide_currency_metabolites=None): """ Extract reactions from pathway and create a comppound/reaction graph. Parameters ---------- padmet_pathname: str pathname of the padmet file or a folder containing multiple padmet padmet_ref_pathname: str pathname of the padmetRef file pathway_ids: str name of the pathway (can be multiple pathways separated by a ',') output_file: str pathname of the output picture (extension can be .png or .svg) hide_currency_metabolites: bool hide currency metabolites """ if os.path.isfile(padmet_pathname): padmet = PadmetSpec(padmet_pathname) else: padmet = padmet_to_padmet.padmet_to_padmet(padmet_pathname) padmet_ref = PadmetRef(padmet_ref_pathname) pathway_ids = pathway_ids.split(',') pwy_all_reactions = [] if hide_currency_metabolites: compounds_to_hide = [ "PROTON", "WATER", "OXYGEN-MOLECULE", "NADP", "NADPH", "ATP", "PPI", "CARBON-DIOXIDE", "Pi", "ADP", "CO-A", "UDP", "NAD", "NADH", "AMP", "AMMONIA", "HYDROGEN-PEROXIDE", "Acceptor", "Donor-H2", "3-5-ADP", "GDP", "CARBON-MONOXIDE", "GTP", "FAD" ] else: compounds_to_hide = [] def get_reactions(pathway_id, padmet_ref, pwy_all_reactions): all_reactions = [ rlt.id_in for rlt in padmet_ref.dicOfRelationOut.get(pathway_id, None) if rlt.type == "is_in_pathway" ] for reaction_id in all_reactions: if reaction_id in padmet_ref.dicOfNode: node_reaction = padmet_ref.dicOfNode[reaction_id] if node_reaction.type == "pathway": pwy_all_reactions = get_reactions(node_reaction.id, padmet_ref, pwy_all_reactions) else: if reaction_id not in pwy_all_reactions: pwy_all_reactions.append(reaction_id) return pwy_all_reactions for pathway_id in pathway_ids: if pathway_id in padmet_ref.dicOfNode: tmp_pwy_all_reactions = [] tmp_pwy_all_reactions = get_reactions(pathway_id, padmet_ref, tmp_pwy_all_reactions) pwy_all_reactions.extend(tmp_pwy_all_reactions) else: print("Pathway " + pathway_id + " not in PadmetRef " + padmet_ref_pathname) reactions_in_network = [] for reaction_id in pwy_all_reactions: if reaction_id in padmet.dicOfNode: reactions_in_network.append(reaction_id) DG = nx.DiGraph() custom_node_color = OrderedDict() for reaction_id in pwy_all_reactions: # Reaction colors if reaction_id in reactions_in_network: custom_node_color[reaction_id] = "lightgreen" else: custom_node_color[reaction_id] = "red" # Reactants & products for each reaction reactants = [ rlt.id_out for rlt in padmet_ref.dicOfRelationIn.get(reaction_id, None) if rlt.type == "consumes" ] products = [ rlt.id_out for rlt in padmet_ref.dicOfRelationIn.get(reaction_id, None) if rlt.type == "produces" ] for reac in reactants: if reac not in compounds_to_hide: if reac not in custom_node_color: custom_node_color[reac] = "skyblue" DG.add_edge(reac, reaction_id) if 'REVERSIBLE' in padmet_ref.dicOfNode[reaction_id].misc[ 'DIRECTION']: DG.add_edge(reaction_id, reac) for prod in products: if prod not in compounds_to_hide: if prod not in custom_node_color: custom_node_color[prod] = "skyblue" DG.add_edge(reaction_id, prod) if 'REVERSIBLE' in padmet_ref.dicOfNode[reaction_id].misc[ 'DIRECTION']: DG.add_edge(prod, reaction_id) # https://networkx.github.io/documentation/latest/reference/generated/networkx.drawing.nx_pylab.draw_networkx.html # apt-get install graphviz graphviz-dev (python-pygraphviz) # pip install pygraphviz nx.draw_networkx( DG, pos=graphviz_layout(DG, prog='neato'), # Layout from graphviz node_size=1600, arrows=True, font_size=11, # font-size for labels node_shape='s', # shape of nodes alpha=0.6, # node & edge transparency width=1.5, # line width for edges nodelist=list(custom_node_color.keys()), node_color=[ custom_node_color[node] for node in list(custom_node_color.keys()) ]) plt.axis('off') plt.savefig(output_file, bbox_inches='tight') plt.clf()
def visu_path_pathways(padmet_pathname, padmet_ref_pathname, pathway_ids, output_file): """ Extract reactions from pathway and create a comppound/reaction graph. Parameters ---------- padmet_pathname: str pathname of the padmet file or a folder containing multiple padmet padmet_ref_pathname: str pathname of the padmetRef file pathway_ids: str name of the pathway (can be multiple pathways separated by a ',') output_file: str pathname of the output picture (extension can be .png or .svg) hide_compounds: bool hide common compounds (like water or proton) """ if os.path.isfile(padmet_pathname): padmet = PadmetSpec(padmet_pathname) else: padmet = padmet_to_padmet.padmet_to_padmet(padmet_pathname) padmet_ref = PadmetRef(padmet_ref_pathname) # Check if the padmets and padmetref contain the INPUT-COMPOUNDS and OUTPUT-COMPOUNDS in pathway node.misc needed for this analysis. padmetref_input_compounds_in_pwys = [ 1 for node_pathway in padmet_ref.dicOfNode if padmet_ref.dicOfNode[node_pathway].type == 'pathway' and 'INPUT-COMPOUNDS' in padmet_ref.dicOfNode[node_pathway].misc ] padmetref_output_compounds_in_pwys = [ 1 for node_pathway in padmet_ref.dicOfNode if padmet_ref.dicOfNode[node_pathway].type == 'pathway' and 'OUTPUT-COMPOUNDS' in padmet_ref.dicOfNode[node_pathway].misc ] if sum(padmetref_input_compounds_in_pwys) == 0 or sum( padmetref_output_compounds_in_pwys) == 0: sys.exit( "The padmetref " + padmet_ref_pathname + " does not contain INPUT-COMPOUNDS and OUTPUT-COMPOUNDS in the pathway node, can't produce the pathway visualization." ) padmet_input_compounds_in_pwys = [ 1 for node_pathway in padmet.dicOfNode if padmet.dicOfNode[node_pathway].type == 'pathway' and 'INPUT-COMPOUNDS' in padmet.dicOfNode[node_pathway].misc ] padmet_output_compounds_in_pwys = [ 1 for node_pathway in padmet.dicOfNode if padmet.dicOfNode[node_pathway].type == 'pathway' and 'OUTPUT-COMPOUNDS' in padmet.dicOfNode[node_pathway].misc ] if sum(padmet_input_compounds_in_pwys) == 0 or sum( padmet_output_compounds_in_pwys) == 0: sys.exit( "The padmet " + padmet_pathname + " does not contain INPUT-COMPOUNDS and OUTPUT-COMPOUNDS in the pathway node, can't produce the pathway visualization." ) # Extract pathway from superpathways. pathway_ids = pathway_ids.split(',') all_pathways = [] def get_pathways(pathway_id, padmet_ref, pwy_all_reactions): all_reactions_pathways = [ rlt.id_in for rlt in padmet_ref.dicOfRelationOut.get(pathway_id, None) if rlt.type == "is_in_pathway" ] for reaction_pathway_id in all_reactions_pathways: if reaction_pathway_id in padmet_ref.dicOfNode: node_reaction = padmet_ref.dicOfNode[reaction_pathway_id] if node_reaction.type == "pathway": pwy_all_reactions.append(reaction_pathway_id) pwy_all_reactions = get_pathways(node_reaction.id, padmet_ref, pwy_all_reactions) return pwy_all_reactions for pathway_id in pathway_ids: if pathway_id in padmet_ref.dicOfNode: tmp_pwy_all_pathways = [] tmp_pwy_all_pathways = get_pathways(pathway_id, padmet_ref, tmp_pwy_all_pathways) all_pathways.extend(tmp_pwy_all_pathways) else: print("Pathway " + pathway_id + " not in PadmetRef " + padmet_ref_pathname) # Find pathway in the padmet file. pathways_in_network = [] for pathway_id in all_pathways: if pathway_id in padmet.dicOfNode: pathways_in_network.append(pathway_id) # Create the graph. DG = nx.DiGraph() custom_node_color = OrderedDict() for pwy in all_pathways: node_pathway = padmet_ref.dicOfNode[pwy] if pwy in pathways_in_network: custom_node_color[pwy] = "lightgreen" else: custom_node_color[pwy] = "red" if 'INPUT-COMPOUNDS' in node_pathway.misc and 'OUTPUT-COMPOUNDS' in node_pathway.misc: for reactant in node_pathway.misc['INPUT-COMPOUNDS'][0].split(','): if reactant not in custom_node_color: custom_node_color[reactant] = "skyblue" DG.add_edge(reactant, pwy) for product in node_pathway.misc['OUTPUT-COMPOUNDS'][0].split(','): if product not in custom_node_color: custom_node_color[product] = "skyblue" DG.add_edge(pwy, product) # https://networkx.github.io/documentation/latest/reference/generated/networkx.drawing.nx_pylab.draw_networkx.html # apt-get install graphviz graphviz-dev (python-pygraphviz) # pip install pygraphviz nx.draw_networkx( DG, pos=graphviz_layout(DG, prog='neato'), # Layout from graphviz node_size=1600, arrows=True, font_size=11, # font-size for labels node_shape='s', # shape of nodes alpha=0.6, # node & edge transparency width=1.5, # line width for edges nodelist=list(custom_node_color.keys()), node_color=[ custom_node_color[node] for node in list(custom_node_color.keys()) ]) plt.axis('off') plt.savefig(output_file, bbox_inches='tight') plt.clf()