Source code for mfapy.mfapyio
#!/usr/bin/python
# -*- coding: utf-8 -*-
#-------------------------------------------------------------------------------
# Name: mfapyio.py
# Purpose: I/O funtions for mfapy
#
# Author: Fumio_Matsuda
#
# Created: 12/06/2018
# Copyright: (c) Fumio_Matsuda 2018
# Licence: MIT license
#-------------------------------------------------------------------------------
"""mfapyio.py:I/O funtions for mfapy
This module includes functions to read model description files.
Following functions are available::
load_metabolic_model_reactions
load_metabolic_model_metabolites
load_metabolic_model_reversibles
load_metabolic_model_fragments
load_metabolic_model
Example:
>>> reactions, reversible, metabolites, target_fragments = mfapy.mfapyio.load_metabolic_model("Explanation_1_13CMFA_toymodel_model.txt", format = "text")
Todo:
* Support other file formats
"""
import numpy as numpy
from . import mdv
from . import metabolicmodel
import re, csv
[docs]def load_metabolic_model_reactions(filename, format = "text", mode = "normal"):
"""Function to load metabolic reaction information from a text or CSV file with following format.
Examples::
//Reactions
v1 AcCoA + OAC --> Cit AcCoA + OAC --> Cit AB + CDEF --> FEDBAC (kegg:R00351) 0.0 300
v2 Cit --> AKG + CO2ex Cit --> AKG + CO2ex ABCDEF --> ABCDE + F (kegg:R00709) 0.0 300
v3 AKG --> Glu AKG --> Glu ABCDE --> ABCDE (kegg:R00243) 0.0 300
v4 AKG --> Suc + CO2ex AKG --> Suc + CO2ex ABCDE --> BCDE + A (kegg:R01197) 0.0 300
v5 Suc --> Fum Suc --> Fum ABCD --> ABCD (kegg:R02164) 0.0 300
v6 Fum --> OAC Fum --> OAC ABCD --> ABCD (kegg:R01082) 0.0 300
v7 OAC --> Fum OAC --> Fum ABCD --> ABCD (kegg:R01082) 0.0 300
v8 Asp --> OAC Asp --> OAC ABCD --> ABCD (kegg:R00355) 0.0 300
Args:
filename (str) : metabolic model file name
format (str) : "text" (defalut, tab deliminated) or "csv"
mode (str) : "normal" (defalut) or "debug" (to show loaded metabolic file data).
Returns:
dict : Dictionary describing metabolite reactions
Examples:
>>> reactions = load_metabolic_model_reaction('filename.txt')
>>> print reactions
{'r4': {'atommap': 'AB+CDEF-->FEDBAC', 'reaction': 'ACCOA+OAA-->ICI', 'use': 'use', 'lb': 0.1, 'flux_value': 0.0, 'reversible': 'no', 'flux_var': 1.0, 'type': 'free', 'order': 3, 'ub': 300.0},...}
"""
#
# Distionary for reaction data
#
reactions = {}
#
# Conter to keep reaction order
#
counter = 0
#
# Ititialize status
#
status = "start"
with open(filename, 'r') as f:
if format == "text":
reader = csv.reader(f, delimiter='\t')
elif format == "csv":
reader = csv.reader(f, dialect='excel')
else:
print("Unknown format!")
f.close()
return False
for i, row in enumerate(reader):
if len(row) == 0:
continue
if "#" == row[0][0]:
continue
row = [item for item in row if "#" not in item]
if len(row) < 1:
continue
if "//" in row[0]:
rid = row[0].replace(" ", "")
if rid == "//Reactions":
status = "Reactions"
continue
if rid == "//End":
break
status = "other"
# Remove '' from row
row = list(filter(lambda s:s != '', row))
if status == "Reactions":
if mode == "debug":
print(row)
if len(row) < 6:
print("This row was ignored due to small number of data. Please check column separation:", row)
continue
rid = row[0].replace(" ", "")
stoichiometry = row[1].replace(" ", "")
reaction = row[2].replace(" ", "")
atommap = row[3].replace(" ", "")
exid = row[4]
if rid == "":
print("This row was ignored due to no id:", row)
continue
if stoichiometry == "":
print("This row was ignored due to no stoichiometry data:", row)
continue
if reaction == "":
print("This row was ignored due to no reaction data:", row)
continue
if atommap == "":
print("This row was ignored due to no atommap data:", row)
continue
reactions[rid] = {
'stoichiometry': stoichiometry,
'reaction':reaction,
'atommap':atommap,
'externalids' :exid,
'order':int(counter)
}
if len(row) >= 6:
reactions[rid]['lb'] = float(row[5].replace(" ", ""))
reactions[rid]['ub'] = float(row[6].replace(" ", ""))
counter = counter + 1
return(reactions)
[docs]def load_metabolic_model_metabolites(filename, format = "text", mode = "normal"):
"""Function to load Metabolite information from a file with following format.
Examples::
//Metabolites
CO2ex 1 no no excreted (kegg:C00011) 0.0 300
AcCoA 2 no carbonsource no (kegg:C00024) 0.0 300
OAC 4 no no no (kegg:C00036) 0.0 300
Cit 6 no no no (kegg:C00158) 0.0 300
AKG 5 no no no (kegg:C00026) 0.0 300
Suc 4 symmetry no no (kegg:C00042) 0.0 300
Fum 4 symmetry no no (kegg:C00122) 0.0 300
Glu 5 no no no (kegg:C00025) 0.0 300
Asp 4 no carbonsource no (kegg:C00049) 0.0 300
Args:
filename (str) : metabolic model file
format (str) : "text" (defalut, tab deliminated) or "csv"
mode (str) : "normal" (defalut) or "debug" (to show loaded metabolic file data)
Returns:
dict: Dictionary including metabolite information
Examples:
>>> metabolites = load_metabolic_model_metabolites('filename.txt')
>>> print metabolites
{'GLUEX': {'excreted': 'no', 'carbonsource': 'carbonsource', 'C_number': 5, 'symmetry': 'no', 'order': 4}, ...}
"""
metabolites = {}
counter = 0
status = "start"
with open(filename, 'r') as f:
if format == "text":
reader = csv.reader(f, delimiter='\t')
elif format == "csv":
reader = csv.reader(f, dialect='excel')
else:
print("Unknown format!")
f.close()
return False
for i, row in enumerate(reader):
if len(row) == 0:
continue
if "#" == row[0][0]:
continue
row = [item for item in row if "#" not in item]
if len(row) < 1:
continue
if "//" in row[0]:
if row[0] == "//Metabolites":
status = "Metabolites"
continue
if row[0] == "//End":
break
status = "other"
# Remove '' from row
row = list(filter(lambda s:s != '', row))
#
if status == "Metabolites":
if mode == "debug":
print(row)
if len(row) < 5:
print("This row was ignored due to small number of data. Please check column separation:", row)
continue
name = row[0].replace(" ", "")
C_number = row[1]
symmetry = row[2].replace(" ", "")
carbonsource = row[3].replace(" ", "")
excreted = row[4].replace(" ", "")
if name == "":
print("This row was ignored due to no id:", row)
continue
if C_number == "":
print("This row was ignored due to no C_number:", row)
continue
if symmetry == "":
print("This row was ignored due to no symmetry:", row)
continue
if carbonsource == "":
print("This row was ignored due to no carbonsource:", row)
continue
if excreted == "":
print("This row was ignored due to no excreted:", row)
continue
metabolites[name] = {
'C_number' :int(C_number),
'symmetry':symmetry,
'carbonsource':carbonsource,
'excreted':excreted,
'order' :int(counter),
'externalids' :"no external id",
}
if len(row) >= 6:
metabolites[name]['externalids'] = row[5]
if len(row) >= 7:
metabolites[name]['lb'] = float(row[6].replace(" ", ""))
metabolites[name]['ub'] = float(row[7].replace(" ", ""))
counter = counter + 1
counter = counter + 1
return(metabolites)
[docs]def load_metabolic_model_reversibles(filename, format = "text", mode = "normal"):
"""Function to load definitions of reversible reactions from a metabolic model file with following format.
Examples::
//Reversible_reactions
FUM v6 v7 (kegg:R01082) 0.0 300
Args:
filename (str) : metabolic model file
format (str) : "text" (defalut, tab deliminated) or "csv"
mode (str) : "normal" (defalut) or "debug" (to show loaded metabolic file data)
Returns:
dict : Dictionary for defining reversible reactions
Examples:
>>> reversible = load_metabolic_model_reversibles('filename.txt')
>>> print reversible
{'MDH': {'flux_value': 0.0, 'reverse': 'r27', 'flux_var': 1.0, 'forward': 'r26', 'type': 'free', 'order': 6}, ...}
"""
dic = {}
counter = 0
status = "start"
with open(filename, 'r') as f:
if format == "text":
reader = csv.reader(f, delimiter='\t')
elif format == "csv":
reader = csv.reader(f, dialect='excel')
else:
print("Unknown format!")
f.close()
return False
for i, row in enumerate(reader):
if len(row) == 0:
continue
if "#" == row[0][0]:
continue
row = [item for item in row if "#" not in item]
if len(row) < 1:
continue
if "//" in row[0]:
if row[0] == "//Reversible_reactions":
status = "Reversible_reactions"
continue
if row[0] == "//End":
break
status = "other"
# Remove '' from row
row = list(filter(lambda s:s != '', row))
if status == "Reversible_reactions":
if mode == "debug":
print(row)
if len(row) < 3:
print("This row was ignored due to small number of data. Please check column separation:", row)
continue
name = row[0].replace(" ", "")
forward = row[1].replace(" ", "")
reverse = row[2].replace(" ", "")
if name == "":
print("This row was ignored due to no id:", row)
continue
if forward == "":
print("This row was ignored due to no forward ids:", row)
continue
if reverse == "":
print("This row was ignored due to no reverse ids:", row)
continue
dic[name] = {
'forward':forward,
'reverse':reverse,
'type': "free",
'order' :int(counter),
'externalids' :"no external id",
}
if len(row) >= 4:
dic[name]['externalids'] = row[3]
if len(row) >= 5:
dic[name]['lb'] = float(row[4].replace(" ", ""))
dic[name]['ub'] = float(row[5].replace(" ", ""))
counter = counter + 1
return(dic)
[docs]def load_metabolic_model_fragments(filename, format = "text", mode = "normal"):
"""Function to load mass fragment information from a metabolic model file with following format.
Examples::
//Target_fragments
Glue gcms Glu_1:2:3:4:5 use C5H10N2O3
Gluee gcms Glu_1:2:3+Glu_4:5 use C5H10N2O3
Args:
filename (str) : metabolic model file
format (str) : "text" (defalut, tab deliminated) or "csv"
mode (str) : "normal" (defalut) or "debug" (to show loaded metabolic file data)
Returns:
dict : Dictionary of target_fragments
Examples:
>>> target_fragments = load_metabolic_model_fragments('filename.txt')
>>> print target_fragments
{'Thr302': {'atommap': 'Thr_12', 'use': 'no', 'type': 'gcms', 'order': 35, 'number': 3}, ...}
"""
dic = {}
counter = 0
status = "start"
with open(filename, 'r') as f:
if format == "text":
reader = csv.reader(f, delimiter='\t')
elif format == "csv":
reader = csv.reader(f, dialect='excel')
else:
print("Unknown format!")
f.close()
return False
for i, row in enumerate(reader):
if len(row) == 0:
continue
if "#" == row[0][0]:
continue
row = [item for item in row if "#" not in item]
if len(row) < 1:
continue
if "//" in row[0]:
if row[0] == "//Target_fragments":
status = "Target_fragments"
continue
if row[0] == "//End":
break
status = "other"
row = list(filter(lambda s:s != '', row))
if status == "Target_fragments":
if mode == "debug":
print(row)
if len(row) < 4:
print("This row was ignored due to small number of data. Please check column separation:", row)
continue
formula = ""
name = row[0].replace(" ", "")
mtype = row[1].replace(" ", "")
atommap = row[2].replace(" ", "")
use = row[3].replace(" ", "")
if len(row) >= 5:
formula = row[4].replace(" ", "")
if name == "":
print("This row was ignored due to no id:", row)
continue
if mtype == "":
print("This row was ignored due to no detection method data:", row)
continue
if atommap == "":
print("This row was ignored due to no atommap data:", row)
continue
dic[name] = {
'type':mtype,
'atommap':atommap,
'use':use,
'order' :int(counter),
'formula':formula
}
counter = counter + 1
return(dic)
[docs]def load_metabolic_model(filename, format = "text",mode = "normal"):
"""Function to load metabolic model information from a text file
CAUTION: Now this function has no error checking.
Args:
filename (str) : metabolic model file
format (str) : "text" (defalut, tab deliminated) or "csv"
mode (str) : "normal" (defalut) or "debug" (to show loaded metabolic file data)
Returns:
* reactions (dict), Dictionary describing metabolite reactions
* reversible (dict), Dictionary for defining reversible reactions
* metabolites (dict), Dictionary including metabolite information
* target_fragments (dict), Dictionary of target_fragments
Examples:
>>> reactions, reversible, metabolites, target_fragments = load_metabolic_model("filename.txt')
# The obtaind data (dictionaries) are directly used for generation of new Metabolic Model object
>>> model = MetabolicModel(reactions, reversible, metabolites, target_fragments)
"""
reactions = load_metabolic_model_reactions(filename, format=format, mode = mode)
metabolites = load_metabolic_model_metabolites(filename, format=format, mode = mode)
reversible_reactions = load_metabolic_model_reversibles(filename, format=format , mode = mode)
target_fragments = load_metabolic_model_fragments(filename, format=format, mode = mode)
return(reactions, reversible_reactions, metabolites, target_fragments)