From 26416fc4336c308b10bd64c53672ac4ff0e3d601 Mon Sep 17 00:00:00 2001 From: Andrew Freiburger Date: Sat, 2 Jul 2022 21:04:33 -0400 Subject: [PATCH 1/5] initial commit --- modelseedpy/fbapkg/fullthermopkg.py | 1 + 1 file changed, 1 insertion(+) diff --git a/modelseedpy/fbapkg/fullthermopkg.py b/modelseedpy/fbapkg/fullthermopkg.py index 7197f698..c6d88212 100644 --- a/modelseedpy/fbapkg/fullthermopkg.py +++ b/modelseedpy/fbapkg/fullthermopkg.py @@ -3,6 +3,7 @@ from __future__ import absolute_import import logging +logger = logging.getLogger(__name__) from scipy.constants import physical_constants, calorie, kilo, R from numpy import log as ln from modelseedpy.fbapkg.basefbapkg import BaseFBAPkg From 802f757651c183f92404e5e4eb3c600dc031ddb1 Mon Sep 17 00:00:00 2001 From: Andrew Freiburger Date: Sat, 2 Jul 2022 21:08:58 -0400 Subject: [PATCH 2/5] initial ocmmit --- modelseedpy/fbapkg/fullthermopkg.py | 113 +++++++++++++++------------- 1 file changed, 60 insertions(+), 53 deletions(-) diff --git a/modelseedpy/fbapkg/fullthermopkg.py b/modelseedpy/fbapkg/fullthermopkg.py index c6d88212..024e6e7e 100644 --- a/modelseedpy/fbapkg/fullthermopkg.py +++ b/modelseedpy/fbapkg/fullthermopkg.py @@ -3,82 +3,91 @@ from __future__ import absolute_import import logging -logger = logging.getLogger(__name__) from scipy.constants import physical_constants, calorie, kilo, R from numpy import log as ln from modelseedpy.fbapkg.basefbapkg import BaseFBAPkg from modelseedpy.core.fbahelper import FBAHelper #Base class for FBA packages -class FullThermoPkg(BaseFBAPkg): +class FullThermoPkg(BaseFBAPkg): @staticmethod - def default_concentration(): + def default_concentrations(): return { - "cpd00067_c0":[0.0000001,0.0000001],#M H+ - equivalent to pHint = 7 - "cpd00007_c0":[1E-07,8.2E-06],#M O2 instracellular - "cpd00011_c0":[1E-08,0.0014],#M CO2 instracellular - "cpd00067_e0":[3.16228E-07,3.16228E-07],#M H+ - equivalent to pHext = 6.5 - "cpd00009_e0":[0.056,0.056],#Extracellular phosphate - overridden by media when media concentration is given - "cpd00048_e0":[0.0030,0.0030],#Extracellular sulfate - overridden by media when media concentration is given - "cpd00013_e0":[0.019,0.019],#Extracellular ammonia - overridden by media when media concentration is given - "cpd00971_e0":[0.16,0.16],#Extracellular sodium - overridden by media when media concentration is given - "cpd00205_e0":[0.022,0.022],#Extracellular potassium - overridden by media when media concentration is given - "cpd10515_e0":[0.062,0.062],#Extracellular Fe2+ - overridden by media when media concentration is given - "cpd00011_e0":[0.00010,0.00010],#Extracellular CO2 - overridden by media when media concentration is given - "cpd00007_e0":[8.2E-06,8.2E-06],#Extracellular O2 - overridden by media when media concentration is given - "cpd00027_e0":[0.020,0.020]#Extracellular glucose - overridden by media when media concentration is given + "cpd00067_c0":[0.0000001,0.0000001], #M H+ - equivalent to pHint = 7 + "cpd00007_c0":[1E-07,8.2E-06], #M O2 instracellular + "cpd00011_c0":[1E-08,0.0014], #M CO2 instracellular + "cpd00067_e0":[3.16228E-07,3.16228E-07], #M H+ - equivalent to pHext = 6.5 + "cpd00009_e0":[0.056,0.056], #Extracellular phosphate - overridden by media when media concentration is given + "cpd00048_e0":[0.0030,0.0030], #Extracellular sulfate - overridden by media when media concentration is given + "cpd00013_e0":[0.019,0.019], #Extracellular ammonia - overridden by media when media concentration is given + "cpd00971_e0":[0.16,0.16], #Extracellular sodium - overridden by media when media concentration is given + "cpd00205_e0":[0.022,0.022], #Extracellular potassium - overridden by media when media concentration is given + "cpd10515_e0":[0.062,0.062], #Extracellular Fe2+ - overridden by media when media concentration is given + "cpd00011_e0":[0.00010,0.00010], #Extracellular CO2 - overridden by media when media concentration is given + "cpd00007_e0":[8.2E-06,8.2E-06], #Extracellular O2 - overridden by media when media concentration is given + "cpd00027_e0":[0.020,0.020] #Extracellular glucose - overridden by media when media concentration is given } @staticmethod def default_deltaG_error(): return { - "cpd00067":0#KJ/mol - H delta G is based on pH and so has no error + "cpd00067":0 #KJ/mol - H delta G is based on pH and so has no error } @staticmethod - def default_compartment_potential(): + def default_compartment_potentials(): return { - "e0":0,#Extracellular MUST be the zero reference for compartment electrochemical potential (so community modeling works) - "c0":-160#mV = 0.33 (pHint - pHext) - 143.33 where pHint = 7 and pHext = 6.5 + "e0":0, #Extracellular MUST be the zero reference for compartment electrochemical potential (so community modeling works) + "c0":-160 #mV = 0.33 (pHint - pHext) - 143.33 where pHint = 7 and pHext = 6.5 } def __init__(self,model): BaseFBAPkg.__init__(self,model,"full thermo",{"logconc":"metabolite","dgerr":"metabolite"},{"potc":"metabolite"}) self.pkgmgr.addpkgs(["SimpleThermoPkg"]) - def build_package(self,parameters, verbose = True): - self.validate_parameters(parameters,["modelseed_path"],{ - "default_max_conc":0.02,#M - "default_min_conc":0.000001,#M - "default_max_error":5,#KJ/mol + def build_package(self, + parameters: dict, # simulation parameters + verbose: bool = True + ): + # define hard-coded defaults + self.parameters["deltaG_error"] = FullThermoPkg.default_deltaG_error() + self.parameters["compartment_potential"] = FullThermoPkg.default_compartment_potentials() + self.parameters["concentrations"] = FullThermoPkg.default_concentrations() + + # amalgamate default and specified paramters + self.validate_parameters(parameters, # specified parameters + ["modelseed_db_path"] # required parameter for uploading the ModelSEED Database + ,{ # default parameters + "default_max_conc":0.02, #M + "default_min_conc":0.000001, #M + "default_max_error":5, #KJ/mol "custom_concentrations":{}, "custom_deltaG_error":{}, - "compartment_potential":{}, - "temperature":298,#K + "custom_compartment_potential":{}, + "temperature":298, #K "filter":None, "infeasible_model": False, 'dgbin':False }) - self.parameters["modelseed_api"] = FBAHelper.get_modelseed_db_api(self.parameters["modelseed_path"]) + self.parameters["modelseed_api"] = FBAHelper.get_modelseed_db_api(self.parameters["modelseed_db_path"]) + for cpd in self.parameters["custom_concentrations"]: + self.parameters["concentrations"][cpd] = self.parameters["custom_concentrations"][cpd] + for cpd in self.parameters["custom_deltaG_error"]: + self.parameters["deltaG_error"][cpd] = self.parameters["custom_deltaG_error"][cpd] + for cmp in self.parameters["custom_compartment_potential"]: + self.parameters["compartment_potential"][cmp] = self.parameters["custom_compartment_potential"][cmp] + + # implements an accommodating variable to encourage feasibility simple_thermo_parameters = { "filter":self.parameters["filter"], - "min_potential":-100000,#KJ/mol - "max_potential":100000,#KJ/mol + "min_potential":-100000, #KJ/mol + "max_potential":100000, #KJ/mol 'dgbin':self.parameters['dgbin'] } if self.parameters['infeasible_model']: simple_thermo_parameters['dgbin'] = True self.pkgmgr.getpkg("SimpleThermoPkg").build_package(simple_thermo_parameters) - self.parameters["combined_custom_concentrations"] = FullThermoPkg.default_concentration() - for cpd in self.parameters["custom_concentrations"]: - self.parameters["combined_custom_concentrations"][cpd] = self.parameters["custom_concentrations"][cpd] - self.parameters["combined_custom_deltaG_error"] = FullThermoPkg.default_deltaG_error() - for cpd in self.parameters["custom_deltaG_error"]: - self.parameters["combined_custom_deltaG_error"][cpd] = self.parameters["custom_deltaG_error"][cpd] - self.parameters["combined_custom_comp_pot"] = FullThermoPkg.default_compartment_potential() - for cmp in self.parameters["compartment_potential"]: - self.parameters["combined_custom_comp_pot"][cmp] = self.parameters["compartment_potential"][cmp] msid_hash = {} for metabolite in self.model.metabolites: msid = FBAHelper.modelseed_id_from_cobra_metabolite(metabolite) @@ -86,29 +95,27 @@ def build_package(self,parameters, verbose = True): if msid not in msid_hash: msid_hash[msid] = {} msid_hash[msid][metabolite.id] = metabolite - #Build concentration variable - self.build_variable(metabolite,"logconc") - #Build error variable - self.build_variable(metabolite,"dgerr") - #Build the potential constraint - self.build_constraint(metabolite, verbose) + + self._build_variable(metabolite,"logconc") #Build concentration variable + self._build_variable(metabolite,"dgerr") #Build error variable + self._build_constraint(metabolite, verbose) #Build the potential constraint - def build_variable(self,object,type): + def _build_variable(self,object,type): msid = FBAHelper.modelseed_id_from_cobra_metabolite(object) - if type == "logconc" and msid != "cpd00001":#Do not make a concentration variable for water + if type == "logconc" and msid != "cpd00001": #Do not make a concentration variable for water lb = ln(self.parameters["default_min_conc"]) ub = ln(self.parameters["default_max_conc"]) - if object.id in self.parameters["combined_custom_concentrations"]: - lb = ln(self.parameters["combined_custom_concentrations"][object.id][0]) - ub = ln(self.parameters["combined_custom_concentrations"][object.id][1]) + if object.id in self.parameters["concentrations"]: + lb = ln(self.parameters["concentrations"][object.id][0]) + ub = ln(self.parameters["concentrations"][object.id][1]) return BaseFBAPkg.build_variable(self,"logconc",lb,ub,"continuous",object) elif type == "dgerr": ub = self.parameters["default_max_error"] - if object.id in self.parameters["combined_custom_deltaG_error"]: - ub = self.parameters["combined_custom_deltaG_error"][object.id] + if object.id in self.parameters["deltaG_error"]: + ub = self.parameters["deltaG_error"][object.id] return BaseFBAPkg.build_variable(self,"dgerr",-1*ub,ub,"continuous",object) - def build_constraint(self,object, verbose): + def _build_constraint(self,object, verbose): #potential(i) (KJ/mol) = deltaG(i) (KJ/mol) + R * T(K) * lnconc(i) + charge(i) * compartment_potential if object.id not in self.pkgmgr.getpkg("SimpleThermoPkg").variables["potential"]: return None From 73f428e9e900fa9c9044058676a3d23f8eb99ba1 Mon Sep 17 00:00:00 2001 From: Andrew Freiburger Date: Sat, 2 Jul 2022 21:17:51 -0400 Subject: [PATCH 3/5] polished edits --- modelseedpy/fbapkg/fullthermopkg.py | 62 ++++++++++++++--------------- 1 file changed, 30 insertions(+), 32 deletions(-) diff --git a/modelseedpy/fbapkg/fullthermopkg.py b/modelseedpy/fbapkg/fullthermopkg.py index 024e6e7e..458284a0 100644 --- a/modelseedpy/fbapkg/fullthermopkg.py +++ b/modelseedpy/fbapkg/fullthermopkg.py @@ -9,9 +9,9 @@ from modelseedpy.core.fbahelper import FBAHelper #Base class for FBA packages -class FullThermoPkg(BaseFBAPkg): +class FullThermoPkg(BaseFBAPkg): @staticmethod - def default_concentrations(): + def default_concentration(): return { "cpd00067_c0":[0.0000001,0.0000001], #M H+ - equivalent to pHint = 7 "cpd00007_c0":[1E-07,8.2E-06], #M O2 instracellular @@ -35,7 +35,7 @@ def default_deltaG_error(): } @staticmethod - def default_compartment_potentials(): + def default_compartment_potential(): return { "e0":0, #Extracellular MUST be the zero reference for compartment electrochemical potential (so community modeling works) "c0":-160 #mV = 0.33 (pHint - pHext) - 143.33 where pHint = 7 and pHext = 6.5 @@ -49,11 +49,6 @@ def build_package(self, parameters: dict, # simulation parameters verbose: bool = True ): - # define hard-coded defaults - self.parameters["deltaG_error"] = FullThermoPkg.default_deltaG_error() - self.parameters["compartment_potential"] = FullThermoPkg.default_compartment_potentials() - self.parameters["concentrations"] = FullThermoPkg.default_concentrations() - # amalgamate default and specified paramters self.validate_parameters(parameters, # specified parameters ["modelseed_db_path"] # required parameter for uploading the ModelSEED Database @@ -70,10 +65,13 @@ def build_package(self, 'dgbin':False }) self.parameters["modelseed_api"] = FBAHelper.get_modelseed_db_api(self.parameters["modelseed_db_path"]) + self.parameters["concentrations"] = FullThermoPkg.default_concentrations() for cpd in self.parameters["custom_concentrations"]: self.parameters["concentrations"][cpd] = self.parameters["custom_concentrations"][cpd] + self.parameters["deltaG_error"] = FullThermoPkg.default_deltaG_error() for cpd in self.parameters["custom_deltaG_error"]: self.parameters["deltaG_error"][cpd] = self.parameters["custom_deltaG_error"][cpd] + self.parameters["compartment_potential"] = FullThermoPkg.default_compartment_potentials() for cmp in self.parameters["custom_compartment_potential"]: self.parameters["compartment_potential"][cmp] = self.parameters["custom_compartment_potential"][cmp] @@ -100,48 +98,48 @@ def build_package(self, self._build_variable(metabolite,"dgerr") #Build error variable self._build_constraint(metabolite, verbose) #Build the potential constraint - def _build_variable(self,object,type): - msid = FBAHelper.modelseed_id_from_cobra_metabolite(object) - if type == "logconc" and msid != "cpd00001": #Do not make a concentration variable for water + def build_variable(self,cobra_obj,obj_type): + msid = FBAHelper.modelseed_id_from_cobra_metabolite(cobra_obj) + if obj_type == "logconc" and msid != "cpd00001": #Do not make a concentration variable for water lb = ln(self.parameters["default_min_conc"]) ub = ln(self.parameters["default_max_conc"]) - if object.id in self.parameters["concentrations"]: - lb = ln(self.parameters["concentrations"][object.id][0]) - ub = ln(self.parameters["concentrations"][object.id][1]) - return BaseFBAPkg.build_variable(self,"logconc",lb,ub,"continuous",object) - elif type == "dgerr": + if cobra_obj.id in self.parameters["concentrations"]: + lb = ln(self.parameters["concentrations"][cobra_obj.id][0]) + ub = ln(self.parameters["concentrations"][cobra_obj.id][1]) + return BaseFBAPkg.build_variable(self,"logconc",lb,ub,"continuous",cobra_obj) + elif obj_type == "dgerr": ub = self.parameters["default_max_error"] - if object.id in self.parameters["deltaG_error"]: - ub = self.parameters["deltaG_error"][object.id] - return BaseFBAPkg.build_variable(self,"dgerr",-1*ub,ub,"continuous",object) + if cobra_obj.id in self.parameters["deltaG_error"]: + ub = self.parameters["deltaG_error"][cobra_obj.id] + return BaseFBAPkg.build_variable(self,"dgerr",-1*ub,ub,"continuous",cobra_obj) - def _build_constraint(self,object, verbose): + def build_constraint(self, cobra_obj, verbose): #potential(i) (KJ/mol) = deltaG(i) (KJ/mol) + R * T(K) * lnconc(i) + charge(i) * compartment_potential - if object.id not in self.pkgmgr.getpkg("SimpleThermoPkg").variables["potential"]: + if cobra_obj.id not in self.pkgmgr.getpkg("SimpleThermoPkg").variables["potential"]: return None - msid = FBAHelper.modelseed_id_from_cobra_metabolite(object) + msid = FBAHelper.modelseed_id_from_cobra_metabolite(cobra_obj) if msid == None: if verbose: - print(object.id+" has no modelseed ID!") + print(cobra_obj.id+" has no modelseed ID!") return None mscpd = self.parameters["modelseed_api"].get_seed_compound(msid) if mscpd is None: if verbose: - print(object.id+" has modelseed ID "+msid+" but cannot be found in ModelSEED DB!") + print(cobra_obj.id+" has modelseed ID "+msid+" but cannot be found in ModelSEED DB!") return None if mscpd.deltag == 10000000: if verbose: - print(object.id+" has modelseed ID "+msid+" but does not have a valid deltaG!") + print(cobra_obj.id+" has modelseed ID "+msid+" but does not have a valid deltaG!") return None Faraday = physical_constants['Faraday constant'][0]#C/mol compartment_potential = 0 - if object.compartment in self.parameters["combined_custom_comp_pot"]: - compartment_potential = self.parameters["combined_custom_comp_pot"][object.compartment] - constant = mscpd.deltag/calorie + object.charge*Faraday*compartment_potential/kilo/kilo + if cobra_obj.compartment in self.parameters["combined_custom_comp_pot"]: + compartment_potential = self.parameters["combined_custom_comp_pot"][cobra_obj.compartment] + constant = mscpd.deltag/calorie + cobra_obj.charge*Faraday*compartment_potential/kilo/kilo coef = { - self.pkgmgr.getpkg("SimpleThermoPkg").variables["potential"][object.id]:1, - self.variables["dgerr"][object.id]:-1 + self.pkgmgr.getpkg("SimpleThermoPkg").variables["potential"][cobra_obj.id]:1, + self.variables["dgerr"][cobra_obj.id]:-1 } if msid != "cpd00001":#Water concentration should not contribute to potential - coef[self.variables["logconc"][object.id]] = -1*R/kilo*self.parameters["temperature"] - return BaseFBAPkg.build_constraint(self,"potc",constant,constant,coef,object) \ No newline at end of file + coef[self.variables["logconc"][cobra_obj.id]] = -1*R/kilo*self.parameters["temperature"] + return BaseFBAPkg.build_constraint(self,"potc",constant,constant,coef,cobra_obj) \ No newline at end of file From e63e842b7f6f3ebe3809dd07de21747308520e41 Mon Sep 17 00:00:00 2001 From: Andrew Freiburger Date: Sat, 2 Jul 2022 21:19:29 -0400 Subject: [PATCH 4/5] polished edits --- modelseedpy/fbapkg/fullthermopkg.py | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/modelseedpy/fbapkg/fullthermopkg.py b/modelseedpy/fbapkg/fullthermopkg.py index 458284a0..cf1fd46e 100644 --- a/modelseedpy/fbapkg/fullthermopkg.py +++ b/modelseedpy/fbapkg/fullthermopkg.py @@ -64,17 +64,7 @@ def build_package(self, "infeasible_model": False, 'dgbin':False }) - self.parameters["modelseed_api"] = FBAHelper.get_modelseed_db_api(self.parameters["modelseed_db_path"]) - self.parameters["concentrations"] = FullThermoPkg.default_concentrations() - for cpd in self.parameters["custom_concentrations"]: - self.parameters["concentrations"][cpd] = self.parameters["custom_concentrations"][cpd] - self.parameters["deltaG_error"] = FullThermoPkg.default_deltaG_error() - for cpd in self.parameters["custom_deltaG_error"]: - self.parameters["deltaG_error"][cpd] = self.parameters["custom_deltaG_error"][cpd] - self.parameters["compartment_potential"] = FullThermoPkg.default_compartment_potentials() - for cmp in self.parameters["custom_compartment_potential"]: - self.parameters["compartment_potential"][cmp] = self.parameters["custom_compartment_potential"][cmp] - + self.parameters["modelseed_api"] = FBAHelper.get_modelseed_db_api(self.parameters["modelseed_db_path"]) # implements an accommodating variable to encourage feasibility simple_thermo_parameters = { "filter":self.parameters["filter"], @@ -82,10 +72,21 @@ def build_package(self, "max_potential":100000, #KJ/mol 'dgbin':self.parameters['dgbin'] } + if self.parameters['infeasible_model']: simple_thermo_parameters['dgbin'] = True self.pkgmgr.getpkg("SimpleThermoPkg").build_package(simple_thermo_parameters) - + + self.parameters["concentrations"] = FullThermoPkg.default_concentrations() + for cpd in self.parameters["custom_concentrations"]: + self.parameters["concentrations"][cpd] = self.parameters["custom_concentrations"][cpd] + self.parameters["deltaG_error"] = FullThermoPkg.default_deltaG_error() + for cpd in self.parameters["custom_deltaG_error"]: + self.parameters["deltaG_error"][cpd] = self.parameters["custom_deltaG_error"][cpd] + self.parameters["compartment_potential"] = FullThermoPkg.default_compartment_potentials() + for cmp in self.parameters["custom_compartment_potential"]: + self.parameters["compartment_potential"][cmp] = self.parameters["custom_compartment_potential"][cmp] + msid_hash = {} for metabolite in self.model.metabolites: msid = FBAHelper.modelseed_id_from_cobra_metabolite(metabolite) From c5fc2de13a524192abfa9ac65d4a2fa692845dba Mon Sep 17 00:00:00 2001 From: Andrew Freiburger Date: Sat, 2 Jul 2022 21:21:45 -0400 Subject: [PATCH 5/5] polished edits --- modelseedpy/fbapkg/fullthermopkg.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modelseedpy/fbapkg/fullthermopkg.py b/modelseedpy/fbapkg/fullthermopkg.py index cf1fd46e..ad7618ef 100644 --- a/modelseedpy/fbapkg/fullthermopkg.py +++ b/modelseedpy/fbapkg/fullthermopkg.py @@ -76,14 +76,14 @@ def build_package(self, if self.parameters['infeasible_model']: simple_thermo_parameters['dgbin'] = True self.pkgmgr.getpkg("SimpleThermoPkg").build_package(simple_thermo_parameters) - - self.parameters["concentrations"] = FullThermoPkg.default_concentrations() + + self.parameters["concentrations"] = FullThermoPkg.default_concentration() for cpd in self.parameters["custom_concentrations"]: self.parameters["concentrations"][cpd] = self.parameters["custom_concentrations"][cpd] self.parameters["deltaG_error"] = FullThermoPkg.default_deltaG_error() for cpd in self.parameters["custom_deltaG_error"]: self.parameters["deltaG_error"][cpd] = self.parameters["custom_deltaG_error"][cpd] - self.parameters["compartment_potential"] = FullThermoPkg.default_compartment_potentials() + self.parameters["compartment_potential"] = FullThermoPkg.default_compartment_potential() for cmp in self.parameters["custom_compartment_potential"]: self.parameters["compartment_potential"][cmp] = self.parameters["custom_compartment_potential"][cmp]