equilibrator-pathway 0.7.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,38 @@
1
+ """Init file for the equilibrator_pathway module."""
2
+ # The MIT License (MIT)
3
+ #
4
+ # Copyright (c) 2013 Weizmann Institute of Science
5
+ # Copyright (c) 2018-2020 Institute for Molecular Systems Biology,
6
+ # ETH Zurich
7
+ # Copyright (c) 2018-2020 Novo Nordisk Foundation Center for Biosustainability,
8
+ # Technical University of Denmark
9
+ #
10
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ # of this software and associated documentation files (the "Software"), to deal
12
+ # in the Software without restriction, including without limitation the rights
13
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ # copies of the Software, and to permit persons to whom the Software is
15
+ # furnished to do so, subject to the following conditions:
16
+ #
17
+ # The above copyright notice and this permission notice shall be included in
18
+ # all copies or substantial portions of the Software.
19
+ #
20
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26
+ # THE SOFTWARE.
27
+
28
+ from equilibrator_api import Q_
29
+ from equilibrator_api.model import Bounds, StoichiometricModel, open_sbtabdoc
30
+
31
+ default_conc_lb = Q_("1e-6 M")
32
+ default_conc_ub = Q_("1e-2 M")
33
+
34
+ from equilibrator_pathway.cost_function import EnzymeCostFunction
35
+ from equilibrator_pathway.ecm_model import EnzymeCostModel
36
+ from equilibrator_pathway.pathway import Pathway
37
+ from equilibrator_pathway.simulator import EnzymeCostSimulator
38
+ from equilibrator_pathway.thermo_models import ThermodynamicModel
@@ -0,0 +1,230 @@
1
+ """A general class for holding solutions to pathway analyses."""
2
+
3
+ # The MIT License (MIT)
4
+ #
5
+ # Copyright (c) 2013 Weizmann Institute of Science
6
+ # Copyright (c) 2018-2020 Institute for Molecular Systems Biology,
7
+ # ETH Zurich
8
+ # Copyright (c) 2018-2020 Novo Nordisk Foundation Center for Biosustainability,
9
+ # Technical University of Denmark
10
+ #
11
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
12
+ # of this software and associated documentation files (the "Software"), to deal
13
+ # in the Software without restriction, including without limitation the rights
14
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15
+ # copies of the Software, and to permit persons to whom the Software is
16
+ # furnished to do so, subject to the following conditions:
17
+ #
18
+ # The above copyright notice and this permission notice shall be included in
19
+ # all copies or substantial portions of the Software.
20
+ #
21
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27
+ # THE SOFTWARE.
28
+ from typing import Iterable, Optional
29
+
30
+ import numpy as np
31
+ import pandas as pd
32
+ from equilibrator_api import R, default_T, standard_concentration
33
+ from sbtab import SBtab
34
+
35
+ from .pathway import Pathway
36
+
37
+
38
+ class PathwayAnalysisSolution(object):
39
+ """A general class for pathway analysis results."""
40
+
41
+ def __init__(
42
+ self,
43
+ pathway: Pathway,
44
+ score: float,
45
+ ln_conc: np.ndarray,
46
+ y: Optional[np.array] = None,
47
+ ) -> None:
48
+ """Create a PathwayAnalysisSolution object.
49
+
50
+ Parameters
51
+ ----------
52
+ thermo_model : ThermodynamicModel
53
+ ln_conc : array
54
+ log concentrations at MDF optimum
55
+ """
56
+ self.score = score
57
+ self.ln_conc = ln_conc
58
+ self.ln_conc_mu = pathway.ln_conc_mu
59
+ self.ln_conc_sigma = pathway.ln_conc_sigma
60
+ self.dg_confidence = pathway.dg_confidence
61
+ self.ln_conc_confidence = pathway.ln_conc_confidence
62
+ self.y = y
63
+
64
+ standard_dg_primes = pathway.standard_dg_primes.squeeze()
65
+
66
+ physiological_dg_primes = standard_dg_primes.copy()
67
+ for i, rxn in enumerate(pathway.reactions):
68
+ physiological_dg_primes[i] += (
69
+ rxn.physiological_dg_correction() * R * default_T
70
+ )
71
+
72
+ optimized_dg_primes = standard_dg_primes.copy()
73
+ _dg_adj = (pathway.S.T @ self.ln_conc).values.squeeze()
74
+ optimized_dg_primes += _dg_adj * R * default_T
75
+
76
+ # add the calculated error values (due to the ΔG'0 uncertainty)
77
+ if y is not None and pathway.dg_sigma is not None:
78
+ dg_adjustment = pathway.dg_sigma @ y.squeeze()
79
+ else:
80
+ dg_adjustment = np.zeros(standard_dg_primes.shape)
81
+
82
+ # adjust ΔGs to flux directions
83
+ standard_dg_primes = pathway.I_dir @ standard_dg_primes
84
+ physiological_dg_primes = pathway.I_dir @ physiological_dg_primes
85
+ optimized_dg_primes = pathway.I_dir @ optimized_dg_primes
86
+ dg_adjustment = pathway.I_dir @ dg_adjustment
87
+
88
+ # all dG values are in units of RT, so we convert them to kJ/mol
89
+ reaction_data = zip(
90
+ pathway.reaction_ids,
91
+ pathway.reaction_formulas,
92
+ pathway.fluxes,
93
+ standard_dg_primes,
94
+ standard_dg_primes + dg_adjustment,
95
+ physiological_dg_primes + dg_adjustment,
96
+ optimized_dg_primes + dg_adjustment,
97
+ )
98
+ self._reaction_df = pd.DataFrame(
99
+ data=list(reaction_data),
100
+ columns=[
101
+ "reaction_id",
102
+ "reaction_formula",
103
+ "flux",
104
+ "original_standard_dg_prime",
105
+ "standard_dg_prime",
106
+ "physiological_dg_prime",
107
+ "optimized_dg_prime",
108
+ ],
109
+ )
110
+
111
+ lbs, ubs = pathway.bounds
112
+ compound_data = zip(
113
+ pathway.compound_ids,
114
+ np.exp(self.ln_conc).flatten(order="C") * standard_concentration.m_as("M"),
115
+ map(lambda x: x.m_as("M"), lbs),
116
+ map(lambda x: x.m_as("M"), ubs),
117
+ )
118
+ self._compound_df = pd.DataFrame(
119
+ data=list(compound_data),
120
+ columns=[
121
+ "compound_id",
122
+ "concentration_in_molar",
123
+ "lower_bound_in_molar",
124
+ "upper_bound_in_molar",
125
+ ],
126
+ )
127
+
128
+ @property
129
+ def reaction_df(self) -> pd.DataFrame:
130
+ """Get a DataFrame with all the reaction data.
131
+
132
+ The columns are:
133
+ reaction_id
134
+ reaction_formula
135
+ flux
136
+ original_standard_dg_prime
137
+ standard_dg_prime
138
+ physiological_dg_prime
139
+ optimized_dg_prime
140
+
141
+ """
142
+ return self._reaction_df
143
+
144
+ @property
145
+ def compound_df(self) -> pd.DataFrame:
146
+ """Get a DataFrame with all the compound data.
147
+
148
+ The columns are:
149
+ compound_id
150
+ concentration_in_molar
151
+ lower_bound_in_molar
152
+ upper_bound_in_molar
153
+
154
+ """
155
+ return self._compound_df
156
+
157
+ @property
158
+ def reaction_ids(self) -> Iterable[str]:
159
+ """Return the reaction IDs."""
160
+ return self._reaction_df.reaction_id.__iter__()
161
+
162
+ @property
163
+ def compound_ids(self) -> Iterable[str]:
164
+ """Return the compound IDs."""
165
+ return self._compound_df.compound_id.__iter__()
166
+
167
+ def to_sbtab(self) -> SBtab.SBtabDocument:
168
+ """Generate a report (in SBtab format)."""
169
+ sbtabdoc = SBtab.SBtabDocument("report")
170
+
171
+ # add a table with the optimized metabolite concentrations, together
172
+ # with the allowed concentration range (the lower/upper bounds used as
173
+ # constraints in the optimization).
174
+ met_data = []
175
+ for row in self.compound_df.itertuples():
176
+ met_data.append(
177
+ (
178
+ "concentration",
179
+ row.compound_id,
180
+ f"{row.concentration_in_molar:.3e}",
181
+ f"{row.lower_bound_in_molar:.3e}",
182
+ f"{row.upper_bound_in_molar:.3e}",
183
+ )
184
+ )
185
+ met_df = pd.DataFrame(
186
+ columns=["!QuantityType", "!Compound", "!Value", "!Min", "!Max"],
187
+ data=met_data,
188
+ )
189
+ met_sbtab = SBtab.SBtabTable.from_data_frame(
190
+ met_df,
191
+ table_id="Predicted concentrations",
192
+ table_type="Quantity",
193
+ unit="M",
194
+ )
195
+ sbtabdoc.add_sbtab(met_sbtab)
196
+
197
+ # add a table with the reaction Gibbs energies. Alongside the optimized
198
+ # ΔG' (!Value) we also report the standard ΔG'° (at 1 M) and the
199
+ # physiological ΔG'm (at 1 mM), so the full thermodynamic profile is
200
+ # available without re-running the analysis.
201
+ rxn_data = []
202
+ for row in self.reaction_df.itertuples():
203
+ rxn_data.append(
204
+ (
205
+ "reaction gibbs energy",
206
+ row.reaction_id,
207
+ f"{row.optimized_dg_prime.m_as('kJ/mol'):.3e}",
208
+ f"{row.standard_dg_prime.m_as('kJ/mol'):.3e}",
209
+ f"{row.physiological_dg_prime.m_as('kJ/mol'):.3e}",
210
+ )
211
+ )
212
+ rxn_df = pd.DataFrame(
213
+ columns=[
214
+ "!QuantityType",
215
+ "!Reaction",
216
+ "!Value",
217
+ "!StandardGibbsEnergy",
218
+ "!PhysiologicalGibbsEnergy",
219
+ ],
220
+ data=rxn_data,
221
+ )
222
+ rxn_sbtab = SBtab.SBtabTable.from_data_frame(
223
+ rxn_df,
224
+ table_id="Predicted Gibbs energies",
225
+ table_type="Quantity",
226
+ unit="kJ/mol",
227
+ )
228
+ sbtabdoc.add_sbtab(rxn_sbtab)
229
+
230
+ return sbtabdoc