Commit 5bce6385 authored by Elad Noor's avatar Elad Noor

Merge branch 'transport' into 'develop'

Transport

See merge request !14
parents 67c20f8d c21b9e16
Pipeline #112650309 passed with stages
in 5 minutes and 15 seconds
......@@ -30,10 +30,9 @@ keywords =
zip_safe = True
install_requires =
optlang>=1.4.3
sbtab>=0.9.72
matplotlib>=3.0.0
equilibrator-cache==0.2.6
component-contribution==0.2.6
equilibrator-cache==0.2.7b1
component-contribution==0.2.7b2
python_requires = >=3.6
tests_require =
tox
......
......@@ -50,8 +50,5 @@ from equilibrator_api.utils import (
parse_reaction_formula,
search_reaction,
)
from equilibrator_api.bounds import Bounds
from equilibrator_api.component_contribution import ComponentContribution
from equilibrator_api.pathway import Pathway
from equilibrator_api.thermo_models import PathwayThermoModel
from equilibrator_api.phased_reaction import PhasedReaction as Reaction
This diff is collapsed.
......@@ -304,10 +304,12 @@ class ComponentContribution(object):
def multicompartmental_standard_dg_prime(
self,
reaction: PhasedReaction,
nH: int,
charge: int,
delta_p_h: ureg.Measurement,
delta_phi: ureg.Measurement,
reaction_other: PhasedReaction,
transported_protons: float,
transported_charge: float,
p_h_other: Q_,
ionic_strength_other: Q_,
delta_chi: Q_,
) -> ureg.Measurement:
"""Calculate the transformed energies of a multi-compartmental reaction.
......@@ -323,11 +325,33 @@ class ComponentContribution(object):
:return: the transport reaction Gibbs free energy change
"""
assert delta_phi.check(
"[length]**2 * [mass] / [time]**2"
), "delta_phi has the wrong units"
residual_reaction, stored_dg_prime = reaction.separate_stored_dg_prime(
p_h=self.p_h,
ionic_strength=self.ionic_strength,
temperature=self.temperature,
)
(
residual_reaction_other,
stored_dg_prime_other,
) = reaction_other.separate_stored_dg_prime(
p_h=p_h_other,
ionic_strength=ionic_strength_other,
temperature=self.temperature,
)
dg = self.standard_dg_prime(reaction)
dg -= nH * self.RT * np.log(10.0) * delta_p_h
dg -= FARADAY * charge * delta_phi
return dg
(
standard_dg
) = ComponentContribution.predictor.multicompartmental_standard_dg_prime( # noqa: E501
residual_reaction,
residual_reaction_other,
transported_protons,
transported_charge,
self.p_h,
p_h_other,
self.ionic_strength,
ionic_strength_other,
delta_chi,
self.temperature,
)
return standard_dg + stored_dg_prime + stored_dg_prime_other
This diff is collapsed.
This diff is collapsed.
!!SBtab TableID='Reaction' TableType='Reaction' Document='Pathway Model' SBtabVersion='1.0'
!ID !ReactionFormula
glucokinase glucose + atp <=> g6p + adp
pgi g6p <=> f6p
pfk atp + f6p <=> adp + fbp
ald fbp <=> dhap + gap
tim dhap <=> gap
gapdh pi + nad + gap <=> nadh + bpg
pgk adp + bpg <=> atp + 3pg
pgm 3pg <=> 2pg
eno 2pg <=> pep + h2o
pdh adp + pep <=> pyr + atp
pyruvate_decarboxylase pyr <=> acetaldehyde + co2
adh acetaldehyde + nadh <=> ethanol + nad
!!SBtab TableID='RelativeFlux' TableType='Quantity' Document='Pathway Model' SBtabVersion='1.0'
!QuantityType !Reaction !Value
flux glucokinase 1
flux pgi 1
flux pfk 1
flux ald 1
flux tim 1
flux gapdh 2
flux pgk 2
flux pgm 2
flux eno 2
flux pdh 2
flux pyruvate_decarboxylase 2
flux adh 2
!!SBtab TableID='Parameter' TableType='Quantity' Document='Pathway Model' SBtabVersion='1.0' pH='7.00' 'IonicStrength='100 mM'
!QuantityType !Reaction !Value !ID
equilibrium constant glucokinase 1061.24772470112 kEQ_R0
!!SBtab TableID='ConcentrationConstraint' TableType='Quantity' Document='Pathway Model' SBtabVersion='1.0'
!QuantityType !Compound !Compound:Identifiers !Concentration:Min !Concentration:Max
concentration co2 bigg.metabolite:co2 10 uM 10 uM
concentration f6p bigg.metabolite:f6p 1 uM 10 mM
concentration nadh bigg.metabolite:nadh 0.1 mM 0.1 mM
concentration dhap bigg.metabolite:dhap 1 uM 10 mM
concentration 2pg bigg.metabolite:2pg 1 uM 10 mM
concentration pi bigg.metabolite:pi 10 mM 10 mM
concentration adp bigg.metabolite:adp 0.5 mM 0.5 mM
concentration 3pg bigg.metabolite:3pg 1 uM 10 mM
concentration glucose bigg.metabolite:glc__D 1 uM 10 mM
concentration nad bigg.metabolite:nad 1 mM 1 mM
concentration atp bigg.metabolite:atp 5 mM 5 mM
concentration pep bigg.metabolite:pep 1 uM 10 mM
concentration gap bigg.metabolite:g3p 1 uM 10 mM
concentration acetaldehyde bigg.metabolite:acald 1 uM 10 mM
concentration ethanol bigg.metabolite:etoh 1 uM 10 mM
concentration h2o bigg.metabolite:h2o 1 M 1 M
concentration pyr bigg.metabolite:pyr 1 uM 10 mM
concentration g6p bigg.metabolite:g6p 1 uM 10 mM
concentration fbp bigg.metabolite:fdp 1 uM 10 mM
concentration bpg bigg.metabolite:13dpg 1 uM 10 mM
"""unit test for component-contribution predictions."""
# The MIT License (MIT)
#
# Copyright (c) 2013 The Weizmann Institute of Science.
# Copyright (c) 2018-2020 Novo Nordisk Foundation Center for Biosustainability,
# Technical University of Denmark.
# Copyright (c) 2018-2020 Institute for Molecular Systems Biology,
# ETH Zurich, Switzerland.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
import pytest
from equilibrator_api import (
Q_,
ComponentContribution,
Reaction,
parse_reaction_formula,
)
from helpers import approx_unit
@pytest.fixture(scope="module")
def comp_contribution() -> ComponentContribution:
"""Create a ComponentContribution object."""
return ComponentContribution(p_h=Q_("7"), ionic_strength=Q_("0.0 M"))
@pytest.fixture(scope="module")
def cytoplasmic_half_reaction() -> Reaction:
"""Create the cytoplasmic half of a reaction."""
# formula = "bigg.metabolite:2oxoadp = bigg.metabolite:akg"
formula = "bigg.metabolite:thf ="
return parse_reaction_formula(formula)
@pytest.fixture(scope="module")
def mitochondrial_half_reaction() -> Reaction:
"""Create the mitochondrial half of a reaction."""
formula = "= bigg.metabolite:thf"
return parse_reaction_formula(formula)
@pytest.mark.parametrize(
"p_h, ionic_strength, delta_chi, " "exp_delta_g_zero_prime, exp_sigma",
[
list(
map(Q_, ["8.00", "0.0 M", "-155 mV", "-29.56 kJ/mol", "0.0 kJ/mol"])
)
],
)
def test_multicompartment_reaction(
p_h,
ionic_strength,
delta_chi,
exp_delta_g_zero_prime,
exp_sigma,
cytoplasmic_half_reaction,
mitochondrial_half_reaction,
comp_contribution,
):
"""Test the multicompartment reaction estimation function."""
transported_protons = 21
transported_charge = -2
standard_dg_prime = comp_contribution.multicompartmental_standard_dg_prime(
cytoplasmic_half_reaction,
mitochondrial_half_reaction,
transported_protons,
transported_charge,
p_h,
ionic_strength,
delta_chi,
)
approx_unit(standard_dg_prime.value, exp_delta_g_zero_prime, abs=0.1)
approx_unit(standard_dg_prime.error * 1.96, exp_sigma, abs=0.1)
"""UNit test for pathway analysis."""
# The MIT License (MIT)
#
# Copyright (c) 2013 Weizmann Institute of Science
# Copyright (c) 2018 Institute for Molecular Systems Biology,
# ETH Zurich
# Copyright (c) 2018 Novo Nordisk Foundation Center for Biosustainability,
# Technical University of Denmark
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
import inspect
import os
import warnings
import pytest
from sbtab import SBtab
from equilibrator_api import Q_, Bounds, Pathway, Reaction, ccache
from helpers import approx_unit
warnings.simplefilter("error", UserWarning)
@pytest.fixture(scope="module")
def toy_pathway() -> Pathway:
"""Create a Pathway object."""
test_dir = os.path.dirname(
os.path.abspath(inspect.getfile(inspect.currentframe()))
)
sbtab = SBtab.read_csv(os.path.join(test_dir, "pathway.tsv"), "pathway")
return Pathway.from_sbtab(sbtab)
def test_shadow_prices(toy_pathway: Pathway):
"""Test the shadow prices of the MDF analysis."""
warnings.simplefilter("ignore", ResourceWarning)
net_rxn = toy_pathway.net_reaction
reference_net_rxn = Reaction.parse_formula(
ccache.get_compound,
"2 kegg:C00008 + 2 kegg:C00009 + kegg:C00031 = "
"2 kegg:C00002 + 2 kegg:C00001 + 2 kegg:C00469 + 2 kegg:C00011",
)
assert net_rxn == reference_net_rxn
mdf_data = toy_pathway.calc_mdf(stdev_factor=1.0)
shadow_prices = mdf_data.reaction_df.set_index("reaction_id").shadow_price
assert shadow_prices["glucokinase"] == pytest.approx(0.0, abs=1e-2)
assert shadow_prices["ald"] == pytest.approx(0.25, abs=1e-2)
assert shadow_prices["tim"] == pytest.approx(0.25, abs=1e-2)
assert shadow_prices["gapdh"] == pytest.approx(0.50, abs=1e-2)
compound_prices = mdf_data.compound_df.set_index("compound").shadow_price
assert compound_prices["h2o"] == pytest.approx(0.0, abs=1e-2)
assert compound_prices["nad"] == pytest.approx(0.5, abs=1e-2)
assert compound_prices["nadh"] == pytest.approx(-0.5, abs=1e-2)
# test that the plotting functions run without crashing
try:
mdf_data.reaction_plot
mdf_data.compound_plot
except Exception:
pytest.fail("MDF plot function raises exception")
@pytest.mark.parametrize(
"p_h, ionic_strength, stdev_factor, expected_mdf",
[
(Q_("6"), Q_("0.25M"), 1.0, Q_("-2.08 kJ/mol")),
(Q_("7"), Q_("0.1M"), 1.0, Q_("1.88 kJ/mol")),
(Q_("8"), Q_("0.1M"), 1.0, Q_("4.77 kJ/mol")),
(Q_("7"), Q_("0.25M"), 0.0, Q_("2.04 kJ/mol")),
(Q_("7"), Q_("0.25M"), 1.0, Q_("2.75 kJ/mol")),
(Q_("7"), Q_("0.25M"), 2.0, Q_("3.46 kJ/mol")),
],
)
def test_mdf(p_h, ionic_strength, stdev_factor, expected_mdf, toy_pathway):
"""Test the MDF analysis result in different conditions."""
toy_pathway.set_aqueous_params(p_h=p_h, ionic_strength=ionic_strength)
mdf_data = toy_pathway.calc_mdf(stdev_factor=stdev_factor)
approx_unit(mdf_data.mdf, expected_mdf, abs=0.1)
def test_default_bounds():
"""Test the default bounds file."""
bounds = Bounds.GetDefaultBounds()
bound_df = bounds.to_data_frame()
assert bound_df.shape == (112, 3)
# this test sums up all the compound IDs, which is a quick and dirty way
# to make sure none of them changed.
assert bound_df["compound"].apply(lambda x: x.id).sum() == 867024
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment