# -*- coding: utf-8 -*-
from __future__ import absolute_import
import os
import itertools
import sys
from pickle import dump
import networkx as nx
from metquest import fetch_reactions
def _create_graph_with_internal_reaction(organismsdata):
"""
This function creates a NetworkX DiGraph object which consists of
reactions and metabolites happening inside the organisms in a community.
This makes use of the reaction information i.e., irreversible and
reversible, which is obtained from another script fetch_reactions.
Parameters
----------
organismsdata : dict
Dictionary containing the reaction information about organisms
Returns
-------
G : NetworkX DiGraph Object
Bipartite graph consisting of internal reactions in organisms
"""
G = nx.DiGraph()
for modelname in organismsdata:
G.add_nodes_from(organismsdata[modelname]
['irreversible_rxn_no'], bipartite=1)
G.add_nodes_from(organismsdata[modelname]
['reversible_rxn_no'], bipartite=1)
G.add_nodes_from(organismsdata[modelname]
['reversible_back_rxn_no'], bipartite=1)
irrev_lhs_nodes = list(set(
[item for sublist in organismsdata[modelname]['irreversible_lhs_nodes']
for item in sublist]))
irrev_rhs_nodes = list(set(
[item for sublist in organismsdata[modelname]['irreversible_rhs_nodes']
for item in sublist]))
rev_lhs_nodes = list(set(
[item for sublist in organismsdata[modelname]['reversible_lhs_nodes']
for item in sublist]))
rev_rhs_nodes = list(set(
[item for sublist in organismsdata[modelname]['reversible_rhs_nodes']
for item in sublist]))
G.add_nodes_from(irrev_lhs_nodes, bipartite=0)
G.add_nodes_from(irrev_rhs_nodes, bipartite=0)
G.add_nodes_from(rev_lhs_nodes, bipartite=0)
G.add_nodes_from(rev_rhs_nodes, bipartite=0)
for irrevidx in range(len(organismsdata[modelname]['irreversible_rxn_no'])):
for lhsmetidx in range(len(organismsdata[modelname]['irreversible_lhs_nodes'][irrevidx])):
G.add_edges_from([(organismsdata[modelname]['irreversible_lhs_nodes'][irrevidx]
[lhsmetidx],
organismsdata[modelname]['irreversible_rxn_no'][irrevidx])])
for rhsmetidx in range(len(organismsdata[modelname]['irreversible_rhs_nodes'][irrevidx])):
G.add_edges_from([(organismsdata[modelname]['irreversible_rxn_no'][irrevidx],
organismsdata[modelname]['irreversible_rhs_nodes'][irrevidx][rhsmetidx])])
for revidx in range(len(organismsdata[modelname]['reversible_rxn_no'])):
for lhsmetidxrev in range(len(organismsdata[modelname]['reversible_lhs_nodes'][revidx])):
G.add_edges_from([(organismsdata[modelname]['reversible_lhs_nodes'][revidx]
[lhsmetidxrev],
organismsdata[modelname]['reversible_rxn_no'][revidx])])
G.add_edges_from([(organismsdata[modelname]['reversible_back_rxn_no'][revidx],
organismsdata[modelname]['reversible_lhs_nodes'][revidx][lhsmetidxrev])])
for rhsmetidxrev in range(len(organismsdata[modelname]['reversible_rhs_nodes'][revidx])):
G.add_edges_from([(organismsdata[modelname]['reversible_rxn_no'][revidx],
organismsdata[modelname]['reversible_rhs_nodes'][revidx][rhsmetidxrev])])
G.add_edges_from([(organismsdata[modelname]['reversible_rhs_nodes'][revidx]
[rhsmetidxrev],
organismsdata[modelname]['reversible_back_rxn_no'][revidx])])
return G
def _create_graph_with_exchange_reactions(G, orgs, namemap):
"""
This function first identifies the common exchange metabolites
and the non-common exchange metabolites and adds them to the
DiGraph object generated above.
Parameters
----------
G : NetworkX DiGraph Object
Bipartite graph of reaction network from organisms
orgs : dict
Dictionary consisting of irreversible, reversible and exchange
reactions pertaining to the organisms. If more than one organism
is used, this dictionary consists of information about all the
organisms.
namemap : dict
Dictionary mapping the adhoc reaction names to reaction names in
the model
Returns
-------
G : NetworkX DiGraph Object
Bipartite graph consisting of internal and exchange reactions in organisms
namemap : dict
Dictionary mapping the adhoc exchange reaction names to reaction names in
the model
"""
metabolite_exchanged = []
for orgnames in orgs:
exc_met = orgs[orgnames]['exchange_metab_nodes']
metabolite_exchanged.append(exc_met)
# Common exchange metabolites in different organisms
common_exchange_metabolite = list(
set.intersection(*list(map(set, metabolite_exchanged))))
common_exchange_metabolite.sort()
# Adding the common exchange metabolites to the graph
for orgnames in orgs:
renamed_exc_met = [orgnames + ' ' +
comexcmet for comexcmet in common_exchange_metabolite]
number_exc_met = list(range(0, len(common_exchange_metabolite)))
mod_exc_rxn_number = ['Org_%s ER' %
orgnames + str(num + 1) for num in number_exc_met]
mod_exc_rev_rxn_number = ['Org_%s ERR' %
orgnames + str(num + 1) for num in number_exc_met]
G.add_nodes_from(mod_exc_rxn_number, bipartite=1)
G.add_nodes_from(mod_exc_rev_rxn_number, bipartite=1)
G.add_nodes_from(common_exchange_metabolite, bipartite=0)
G.add_nodes_from(renamed_exc_met, bipartite=0)
for k in range(len(renamed_exc_met)):
namemap[mod_exc_rxn_number[k]] = common_exchange_metabolite[k]
namemap[mod_exc_rev_rxn_number[k]] = common_exchange_metabolite[k]
G.add_edges_from([(renamed_exc_met[k], mod_exc_rxn_number[k])])
G.add_edges_from(
[(mod_exc_rxn_number[k], common_exchange_metabolite[k])])
G.add_edges_from(
[(common_exchange_metabolite[k], mod_exc_rev_rxn_number[k])])
G.add_edges_from([(mod_exc_rev_rxn_number[k], renamed_exc_met[k])])
# Adding the non common exchange metabolites to the graph
for orgnames in orgs:
metitems = orgs[orgnames]['exchange_metab_nodes']
non_common_exc_met = list(
set(metitems) - set(common_exchange_metabolite))
non_common_exc_met.sort()
renamed_non_common_exc_met = [
orgnames + ' ' + s for s in non_common_exc_met]
number_non_common_exc_met = list(range(0, len(non_common_exc_met)))
mod_non_common_exc_rxn_number = [
'Org_%s NCER' % orgnames + str(num + 1) for num in number_non_common_exc_met]
mod_non_common_exc_rev_rxn_number = [
'Org_%s NCERR' % orgnames + str(num + 1) for num in number_non_common_exc_met]
G.add_nodes_from(mod_non_common_exc_rxn_number, bipartite=1)
G.add_nodes_from(mod_non_common_exc_rev_rxn_number, bipartite=1)
G.add_nodes_from(non_common_exc_met, bipartite=0)
G.add_nodes_from(renamed_non_common_exc_met, bipartite=0)
for k in range(len(renamed_non_common_exc_met)):
namemap[mod_non_common_exc_rxn_number[k]] = non_common_exc_met[k]
namemap[mod_non_common_exc_rev_rxn_number[k]
] = non_common_exc_met[k]
G.add_edges_from(
[(renamed_non_common_exc_met[k], mod_non_common_exc_rxn_number[k])])
G.add_edges_from(
[(mod_non_common_exc_rxn_number[k], non_common_exc_met[k])])
G.add_edges_from(
[(non_common_exc_met[k], mod_non_common_exc_rev_rxn_number[k])])
G.add_edges_from(
[(mod_non_common_exc_rev_rxn_number[k], renamed_non_common_exc_met[k])])
return G, namemap
[docs]def create_graph(path_name_with_models, no_of_orgs):
"""
This function creates bipartite graph of the organisms based on the
path provided and the number of organsisms. For instance, if a folder
has 3 model files, and the number of organisms is 2, 3 (3C2) different
bipartite graphs are created. The graph objects and the dictionary
are saved as gpickle and pickle files respectively.
Parameters
----------
path_name_with_models : str
Absolute path name of the folder containing the models.
no_of_orgs : int
Number of organisms to be used for creating the DiGraph.
Returns
-------
H : NetworkX DiGraph Object
Bipartite graph consisting of internal and exchange reactions in organisms
full_name_map : dict
Dictionary mapping the adhoc reaction names to reaction names in
the model
"""
organisms_reaction_data, partial_name_map = \
fetch_reactions.segregate_reactions_from_models(path_name_with_models)
if organisms_reaction_data:
organisms_names = list(organisms_reaction_data.keys())
all_possible_combis = list(itertools.combinations(
list(range(len(organisms_names))), int(no_of_orgs)))
if all_possible_combis:
for ncom in range(len(all_possible_combis)):
file_name = ''
current_combination = {}
for numincom in range(len(all_possible_combis[ncom])):
current_combination[organisms_names[all_possible_combis[ncom][numincom]]] = \
organisms_reaction_data[organisms_names[all_possible_combis[ncom][numincom]]]
file_name = file_name + \
organisms_names[all_possible_combis[ncom]
[numincom]] + '_'
H = _create_graph_with_internal_reaction(current_combination)
H, full_name_map = _create_graph_with_exchange_reactions(
H, current_combination, partial_name_map)
print('Number of edges in graph', len(H.edges()))
print('Number of nodes in graph', len(H.nodes()))
if os.access(path_name_with_models, os.W_OK):
with open(file_name + 'namemap' + '.pickle', 'wb') as filetodump:
dump(full_name_map, filetodump)
nx.write_gpickle(H, file_name + '.gpickle')
print('Graph and namemap saved for file(s) in', path_name_with_models)
sys.path.append(path_name_with_models)
else:
print(
'Number of organisms for creating a consortium graph is more than the models given')
print('Program will now exit')
sys.exit()
else:
print("Cannot create graph")
sys.exit()
return H, full_name_map