pyreactlab-core 0.1.5__tar.gz → 0.1.7__tar.gz
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.
- {pyreactlab_core-0.1.5 → pyreactlab_core-0.1.7}/PKG-INFO +3 -6
- {pyreactlab_core-0.1.5 → pyreactlab_core-0.1.7}/pyproject.toml +71 -74
- {pyreactlab_core-0.1.5 → pyreactlab_core-0.1.7}/pyreactlab_core/__init__.py +8 -2
- {pyreactlab_core-0.1.5 → pyreactlab_core-0.1.7}/pyreactlab_core/app.py +82 -6
- {pyreactlab_core-0.1.5 → pyreactlab_core-0.1.7}/pyreactlab_core/configs/info.py +1 -1
- {pyreactlab_core-0.1.5 → pyreactlab_core-0.1.7}/pyreactlab_core/core/chem_react.py +57 -8
- {pyreactlab_core-0.1.5 → pyreactlab_core-0.1.7}/pyreactlab_core/docs/chem_utils.py +92 -2
- {pyreactlab_core-0.1.5 → pyreactlab_core-0.1.7}/pyreactlab_core/models/reaction.py +14 -10
- {pyreactlab_core-0.1.5 → pyreactlab_core-0.1.7}/pyreactlab_core/utils/component_tools.py +2 -0
- {pyreactlab_core-0.1.5 → pyreactlab_core-0.1.7}/pyreactlab_core.egg-info/PKG-INFO +3 -6
- pyreactlab_core-0.1.7/pyreactlab_core.egg-info/requires.txt +3 -0
- pyreactlab_core-0.1.5/pyreactlab_core.egg-info/requires.txt +0 -6
- {pyreactlab_core-0.1.5 → pyreactlab_core-0.1.7}/LICENSE +0 -0
- {pyreactlab_core-0.1.5 → pyreactlab_core-0.1.7}/README.md +0 -0
- {pyreactlab_core-0.1.5 → pyreactlab_core-0.1.7}/pyreactlab_core/configs/__init__.py +0 -0
- {pyreactlab_core-0.1.5 → pyreactlab_core-0.1.7}/pyreactlab_core/configs/constants.py +0 -0
- {pyreactlab_core-0.1.5 → pyreactlab_core-0.1.7}/pyreactlab_core/core/__init__.py +0 -0
- {pyreactlab_core-0.1.5 → pyreactlab_core-0.1.7}/pyreactlab_core/docs/__init__.py +0 -0
- {pyreactlab_core-0.1.5 → pyreactlab_core-0.1.7}/pyreactlab_core/docs/chem_balance.py +0 -0
- {pyreactlab_core-0.1.5 → pyreactlab_core-0.1.7}/pyreactlab_core/models/__init__.py +0 -0
- {pyreactlab_core-0.1.5 → pyreactlab_core-0.1.7}/pyreactlab_core/utils/__init__.py +0 -0
- {pyreactlab_core-0.1.5 → pyreactlab_core-0.1.7}/pyreactlab_core/utils/tools.py +0 -0
- {pyreactlab_core-0.1.5 → pyreactlab_core-0.1.7}/pyreactlab_core.egg-info/SOURCES.txt +0 -0
- {pyreactlab_core-0.1.5 → pyreactlab_core-0.1.7}/pyreactlab_core.egg-info/dependency_links.txt +0 -0
- {pyreactlab_core-0.1.5 → pyreactlab_core-0.1.7}/pyreactlab_core.egg-info/top_level.txt +0 -0
- {pyreactlab_core-0.1.5 → pyreactlab_core-0.1.7}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pyreactlab-core
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.7
|
|
4
4
|
Summary: pyreactlab-core is the core foundation of the PyReactLab ecosystem, offering shared data structures and algorithms for chemical reaction representation, stoichiometry, and reaction analysis.
|
|
5
5
|
Author-email: Sina Gilassi <sina.gilassi@gmail.com>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -18,11 +18,8 @@ Classifier: Operating System :: Microsoft :: Windows
|
|
|
18
18
|
Requires-Python: >=3.11
|
|
19
19
|
Description-Content-Type: text/markdown
|
|
20
20
|
License-File: LICENSE
|
|
21
|
-
Requires-Dist:
|
|
22
|
-
Requires-Dist:
|
|
23
|
-
Requires-Dist: pydantic>=2.12.5
|
|
24
|
-
Requires-Dist: pydantic-settings>=2.12.0
|
|
25
|
-
Requires-Dist: rich>=14.2.0
|
|
21
|
+
Requires-Dist: numpy
|
|
22
|
+
Requires-Dist: pydantic
|
|
26
23
|
Requires-Dist: pythermodb-settings
|
|
27
24
|
Dynamic: license-file
|
|
28
25
|
|
|
@@ -1,74 +1,71 @@
|
|
|
1
|
-
[build-system]
|
|
2
|
-
requires = ["setuptools>=61.0", "wheel"]
|
|
3
|
-
build-backend = "setuptools.build_meta"
|
|
4
|
-
|
|
5
|
-
[project]
|
|
6
|
-
name = "pyreactlab-core"
|
|
7
|
-
version = "0.1.
|
|
8
|
-
description = "pyreactlab-core is the core foundation of the PyReactLab ecosystem, offering shared data structures and algorithms for chemical reaction representation, stoichiometry, and reaction analysis."
|
|
9
|
-
readme = "README.md"
|
|
10
|
-
requires-python = ">=3.11"
|
|
11
|
-
license = "Apache-2.0"
|
|
12
|
-
license-files = ["LICENSE"]
|
|
13
|
-
authors = [
|
|
14
|
-
{name = "Sina Gilassi", email = "sina.gilassi@gmail.com"}
|
|
15
|
-
]
|
|
16
|
-
keywords = [
|
|
17
|
-
"chemical-engineering",
|
|
18
|
-
"chemical-reactions",
|
|
19
|
-
"reaction-representation",
|
|
20
|
-
"reaction-stoichiometry",
|
|
21
|
-
"reaction-analysis",
|
|
22
|
-
]
|
|
23
|
-
classifiers = [
|
|
24
|
-
"Development Status :: 1 - Planning",
|
|
25
|
-
"Intended Audience :: Education",
|
|
26
|
-
"Programming Language :: Python :: 3.11",
|
|
27
|
-
"Operating System :: Unix",
|
|
28
|
-
"Operating System :: MacOS :: MacOS X",
|
|
29
|
-
"Operating System :: Microsoft :: Windows",
|
|
30
|
-
]
|
|
31
|
-
dependencies = [
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
[tool.setuptools]
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
[
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
"
|
|
54
|
-
"
|
|
55
|
-
"
|
|
56
|
-
"
|
|
57
|
-
"
|
|
58
|
-
"
|
|
59
|
-
"
|
|
60
|
-
"
|
|
61
|
-
"
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
"
|
|
70
|
-
"
|
|
71
|
-
|
|
72
|
-
"static/*",
|
|
73
|
-
"static/**/*"
|
|
74
|
-
]
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "pyreactlab-core"
|
|
7
|
+
version = "0.1.7"
|
|
8
|
+
description = "pyreactlab-core is the core foundation of the PyReactLab ecosystem, offering shared data structures and algorithms for chemical reaction representation, stoichiometry, and reaction analysis."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.11"
|
|
11
|
+
license = "Apache-2.0"
|
|
12
|
+
license-files = ["LICENSE"]
|
|
13
|
+
authors = [
|
|
14
|
+
{name = "Sina Gilassi", email = "sina.gilassi@gmail.com"}
|
|
15
|
+
]
|
|
16
|
+
keywords = [
|
|
17
|
+
"chemical-engineering",
|
|
18
|
+
"chemical-reactions",
|
|
19
|
+
"reaction-representation",
|
|
20
|
+
"reaction-stoichiometry",
|
|
21
|
+
"reaction-analysis",
|
|
22
|
+
]
|
|
23
|
+
classifiers = [
|
|
24
|
+
"Development Status :: 1 - Planning",
|
|
25
|
+
"Intended Audience :: Education",
|
|
26
|
+
"Programming Language :: Python :: 3.11",
|
|
27
|
+
"Operating System :: Unix",
|
|
28
|
+
"Operating System :: MacOS :: MacOS X",
|
|
29
|
+
"Operating System :: Microsoft :: Windows",
|
|
30
|
+
]
|
|
31
|
+
dependencies = [
|
|
32
|
+
"numpy",
|
|
33
|
+
"pydantic",
|
|
34
|
+
"pythermodb-settings",
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
[project.urls]
|
|
38
|
+
Homepage = "https://github.com/sinagilassi/PyReactLab-Core"
|
|
39
|
+
Documentation = "https://pyreactlab-core.readthedocs.io/en/latest/"
|
|
40
|
+
Source = "https://github.com/sinagilassi/PyReactLab-Core"
|
|
41
|
+
Tracker = "https://github.com/sinagilassi/PyReactLab-Core/issues"
|
|
42
|
+
|
|
43
|
+
[tool.setuptools]
|
|
44
|
+
include-package-data = true
|
|
45
|
+
|
|
46
|
+
[tool.setuptools.packages.find]
|
|
47
|
+
where = ["."]
|
|
48
|
+
include = ["pyreactlab_core*"]
|
|
49
|
+
exclude = [
|
|
50
|
+
"tests",
|
|
51
|
+
"tests.*",
|
|
52
|
+
"examples",
|
|
53
|
+
"examples.*",
|
|
54
|
+
"notebooks",
|
|
55
|
+
"notebooks.*",
|
|
56
|
+
"statics",
|
|
57
|
+
"statics.*",
|
|
58
|
+
"private",
|
|
59
|
+
"private.*",
|
|
60
|
+
"app",
|
|
61
|
+
"app.*"
|
|
62
|
+
]
|
|
63
|
+
|
|
64
|
+
[tool.setuptools.package-data]
|
|
65
|
+
pyreactlab_core = [
|
|
66
|
+
"config/*.yml",
|
|
67
|
+
"data/*.csv",
|
|
68
|
+
"templates/*.html",
|
|
69
|
+
"static/*",
|
|
70
|
+
"static/**/*"
|
|
71
|
+
]
|
|
@@ -8,7 +8,12 @@ from .configs.info import (
|
|
|
8
8
|
__license__,
|
|
9
9
|
)
|
|
10
10
|
|
|
11
|
-
from .app import
|
|
11
|
+
from .app import (
|
|
12
|
+
rxn,
|
|
13
|
+
rxn_stoichiometry_matrix,
|
|
14
|
+
rxns_stoichiometry,
|
|
15
|
+
build_rxns_stoichiometry
|
|
16
|
+
)
|
|
12
17
|
|
|
13
18
|
__all__ = [
|
|
14
19
|
# config
|
|
@@ -20,6 +25,7 @@ __all__ = [
|
|
|
20
25
|
"__license__",
|
|
21
26
|
# app
|
|
22
27
|
"rxn",
|
|
23
|
-
"
|
|
28
|
+
"rxn_stoichiometry_matrix",
|
|
24
29
|
"rxns_stoichiometry",
|
|
30
|
+
"build_rxns_stoichiometry",
|
|
25
31
|
]
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
# import libs
|
|
2
2
|
import logging
|
|
3
|
-
from typing import List, Optional, Dict
|
|
3
|
+
from typing import List, Optional, Dict, Tuple
|
|
4
|
+
from pythermodb_settings.models import Component, ComponentKey
|
|
4
5
|
# locals
|
|
5
6
|
from .models.reaction import Reaction
|
|
6
|
-
from .docs.chem_utils import build_stoichiometry_matrix
|
|
7
|
+
from .docs.chem_utils import build_stoichiometry_matrix, build_rxn_stoichiometry_source
|
|
7
8
|
|
|
8
9
|
# NOTE: configure logger
|
|
9
10
|
logger = logging.getLogger(__name__)
|
|
@@ -11,7 +12,7 @@ logger = logging.getLogger(__name__)
|
|
|
11
12
|
|
|
12
13
|
def rxn(
|
|
13
14
|
reaction_str: str,
|
|
14
|
-
name: Optional[str] = None
|
|
15
|
+
name: Optional[str] = None,
|
|
15
16
|
) -> Optional[Reaction]:
|
|
16
17
|
"""
|
|
17
18
|
Create and analyze a chemical reaction.
|
|
@@ -50,7 +51,7 @@ def rxn(
|
|
|
50
51
|
return None
|
|
51
52
|
|
|
52
53
|
|
|
53
|
-
def
|
|
54
|
+
def rxn_stoichiometry_matrix(
|
|
54
55
|
reaction: Reaction,
|
|
55
56
|
) -> Optional[List[float]]:
|
|
56
57
|
"""
|
|
@@ -85,6 +86,8 @@ def rxn_stoichiometry(
|
|
|
85
86
|
|
|
86
87
|
def rxns_stoichiometry(
|
|
87
88
|
reactions: List[Reaction],
|
|
89
|
+
components: Optional[List[Component]] = None,
|
|
90
|
+
component_key: ComponentKey = "Name-Formula"
|
|
88
91
|
) -> Optional[Dict]:
|
|
89
92
|
"""
|
|
90
93
|
Get the reaction stoichiometry matrices for a list of chemical reactions.
|
|
@@ -109,11 +112,16 @@ def rxns_stoichiometry(
|
|
|
109
112
|
return None
|
|
110
113
|
|
|
111
114
|
# SECTION: retrieve stoichiometry matrices
|
|
112
|
-
result = build_stoichiometry_matrix(
|
|
115
|
+
result = build_stoichiometry_matrix(
|
|
116
|
+
reactions=reactions,
|
|
117
|
+
components=components,
|
|
118
|
+
component_key=component_key
|
|
119
|
+
)
|
|
113
120
|
|
|
114
121
|
# NOTE: res
|
|
115
122
|
return {
|
|
116
|
-
"components": result["
|
|
123
|
+
"components": result["components"],
|
|
124
|
+
"component_list": result["component_list"],
|
|
117
125
|
"component_ids": result["component_dict"],
|
|
118
126
|
"stoichiometry_matrices_list": result["comp_coeff"],
|
|
119
127
|
"stoichiometry_matrices_dict": result["comp_list"],
|
|
@@ -121,3 +129,71 @@ def rxns_stoichiometry(
|
|
|
121
129
|
except Exception as e:
|
|
122
130
|
logger.error(f"Error retrieving reaction stoichiometry matrices: {e}")
|
|
123
131
|
return None
|
|
132
|
+
|
|
133
|
+
# SECTION: Build stoichiometry for reactions
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def build_rxns_stoichiometry(
|
|
137
|
+
reactions: List[Reaction],
|
|
138
|
+
components: List[Component],
|
|
139
|
+
component_key: ComponentKey
|
|
140
|
+
) -> Optional[
|
|
141
|
+
Dict[str, List[Dict[str, float]] | List[List[float]]]
|
|
142
|
+
]:
|
|
143
|
+
"""
|
|
144
|
+
Build the reaction stoichiometry matrices for a list of chemical reactions.
|
|
145
|
+
|
|
146
|
+
Parameters
|
|
147
|
+
----------
|
|
148
|
+
reactions : List[Reaction]
|
|
149
|
+
List of Reaction instances.
|
|
150
|
+
components : List[Component]
|
|
151
|
+
List of all components involved in the reactions.
|
|
152
|
+
component_key : ComponentKey
|
|
153
|
+
The key to use for mapping components (e.g., "Name-Formula").
|
|
154
|
+
|
|
155
|
+
Returns
|
|
156
|
+
-------
|
|
157
|
+
Optional[Dict[str, List[Dict[str, float]] | List[List[float]]]]
|
|
158
|
+
A dictionary containing the stoichiometry source and matrices if successful, None otherwise. The dictionary has the following structure:
|
|
159
|
+
- "source": List[Dict[str, float]] - A list of dictionaries representing the stoichiometry source for each reaction.
|
|
160
|
+
- "matrix": List[List[float]] - A list of stoichiometry matrices corresponding to each reaction.
|
|
161
|
+
"""
|
|
162
|
+
try:
|
|
163
|
+
# SECTION: validate inputs
|
|
164
|
+
if (
|
|
165
|
+
not isinstance(reactions, list) or
|
|
166
|
+
not all(isinstance(rxn, Reaction) for rxn in reactions)
|
|
167
|
+
):
|
|
168
|
+
logger.error("Invalid reactions list provided.")
|
|
169
|
+
return None
|
|
170
|
+
|
|
171
|
+
if (
|
|
172
|
+
not isinstance(components, list) or
|
|
173
|
+
not all(isinstance(comp, Component) for comp in components)
|
|
174
|
+
):
|
|
175
|
+
logger.error("Invalid components list provided.")
|
|
176
|
+
return None
|
|
177
|
+
|
|
178
|
+
# SECTION: build stoichiometry source
|
|
179
|
+
stoichiometry_source = build_rxn_stoichiometry_source(
|
|
180
|
+
reactions=reactions,
|
|
181
|
+
components=components,
|
|
182
|
+
component_key=component_key
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
# >> check
|
|
186
|
+
if not stoichiometry_source:
|
|
187
|
+
logger.error("Failed to build reaction stoichiometry source.")
|
|
188
|
+
return None
|
|
189
|
+
|
|
190
|
+
# result
|
|
191
|
+
res = {
|
|
192
|
+
"source": stoichiometry_source[0],
|
|
193
|
+
"matrix": stoichiometry_source[1]
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
return res
|
|
197
|
+
except Exception as e:
|
|
198
|
+
logger.error(f"Error building reaction stoichiometry: {e}")
|
|
199
|
+
return None
|
|
@@ -72,11 +72,14 @@ class ChemReact:
|
|
|
72
72
|
# NOTE: component checker
|
|
73
73
|
_component_checker: bool = False
|
|
74
74
|
|
|
75
|
+
# NOTE: stoichiometry source
|
|
76
|
+
_stoichiometry_source: dict[str, Any] = {}
|
|
77
|
+
|
|
75
78
|
def __init__(
|
|
76
79
|
self,
|
|
77
80
|
reaction_mode_symbol: ReactionMode,
|
|
78
81
|
components: Optional[List[Component]],
|
|
79
|
-
|
|
82
|
+
component_keys: Optional[List[ComponentKey]] = None
|
|
80
83
|
):
|
|
81
84
|
"""
|
|
82
85
|
Initialize the ChemReactUtils class.
|
|
@@ -87,7 +90,7 @@ class ChemReact:
|
|
|
87
90
|
The symbol used to separate reactants and products in a reaction equation.
|
|
88
91
|
components : Optional[List[Component]]
|
|
89
92
|
A list of Component objects involved in the reaction.
|
|
90
|
-
|
|
93
|
+
component_keys : List[ComponentKey], optional
|
|
91
94
|
The key used to identify components in the reaction.
|
|
92
95
|
|
|
93
96
|
Notes
|
|
@@ -105,7 +108,10 @@ class ChemReact:
|
|
|
105
108
|
self.components = components
|
|
106
109
|
|
|
107
110
|
# NOTE: set component key
|
|
108
|
-
|
|
111
|
+
if component_keys is not None:
|
|
112
|
+
self.component_keys = component_keys
|
|
113
|
+
else:
|
|
114
|
+
self.component_keys = []
|
|
109
115
|
|
|
110
116
|
# SECTION: Component id
|
|
111
117
|
# NOTE: component ids
|
|
@@ -124,6 +130,12 @@ class ChemReact:
|
|
|
124
130
|
raise ValueError("System inputs are not set.")
|
|
125
131
|
return self._system_inputs
|
|
126
132
|
|
|
133
|
+
@property
|
|
134
|
+
def stoichiometry_source(self) -> Dict[str, Any]:
|
|
135
|
+
"""Get the stoichiometry source."""
|
|
136
|
+
# res
|
|
137
|
+
return self._stoichiometry_source
|
|
138
|
+
|
|
127
139
|
def count_carbon(self, molecule: str, coefficient: float) -> float:
|
|
128
140
|
"""
|
|
129
141
|
Count the number of carbon atoms in a molecule.
|
|
@@ -405,9 +417,9 @@ class ChemReact:
|
|
|
405
417
|
products,
|
|
406
418
|
)
|
|
407
419
|
|
|
408
|
-
# SECTION:
|
|
409
|
-
|
|
410
|
-
reaction_stoichiometry
|
|
420
|
+
# SECTION: build stoichiometry source
|
|
421
|
+
stoichiometry_source = self.build_stoichiometry_source(
|
|
422
|
+
reaction_stoichiometry=reaction_stoichiometry
|
|
411
423
|
)
|
|
412
424
|
|
|
413
425
|
# res
|
|
@@ -425,7 +437,7 @@ class ChemReact:
|
|
|
425
437
|
'reaction_coefficients': reaction_coefficients,
|
|
426
438
|
'reaction_stoichiometry': reaction_stoichiometry,
|
|
427
439
|
'reaction_stoichiometry_matrix': reaction_stoichiometry_matrix,
|
|
428
|
-
'
|
|
440
|
+
'reaction_stoichiometry_source': stoichiometry_source,
|
|
429
441
|
'carbon_count': carbon_count,
|
|
430
442
|
'reaction_state': reaction_state,
|
|
431
443
|
'reaction_phase': reaction_phase,
|
|
@@ -1036,6 +1048,7 @@ class ChemReact:
|
|
|
1036
1048
|
def reaction_stoichiometry_dict(
|
|
1037
1049
|
self,
|
|
1038
1050
|
reaction_stoichiometry: Dict[str, float],
|
|
1051
|
+
component_key: ComponentKey = "Name-Formula"
|
|
1039
1052
|
) -> Dict[str, float]:
|
|
1040
1053
|
'''
|
|
1041
1054
|
Generate the reaction stoichiometry matrix.
|
|
@@ -1064,10 +1077,46 @@ class ChemReact:
|
|
|
1064
1077
|
# create component id
|
|
1065
1078
|
comp_id_new = set_component_id(
|
|
1066
1079
|
comp,
|
|
1067
|
-
|
|
1080
|
+
component_key
|
|
1081
|
+
)
|
|
1068
1082
|
id_to_component[comp_id_new] = reaction_stoichiometry[comp_id]
|
|
1069
1083
|
else:
|
|
1070
1084
|
logging.warning(
|
|
1071
1085
|
f"Component '{comp_id}' not found in reaction stoichiometry.")
|
|
1072
1086
|
|
|
1073
1087
|
return id_to_component
|
|
1088
|
+
|
|
1089
|
+
def build_stoichiometry_source(
|
|
1090
|
+
self,
|
|
1091
|
+
reaction_stoichiometry: Dict[str, float],
|
|
1092
|
+
) -> Dict[str, Any]:
|
|
1093
|
+
"""
|
|
1094
|
+
Build the stoichiometry source for the reaction according to the component keys.
|
|
1095
|
+
|
|
1096
|
+
Parameters
|
|
1097
|
+
----------
|
|
1098
|
+
reaction_stoichiometry : Dict[str, float]
|
|
1099
|
+
A dictionary containing the stoichiometry of the reaction, where keys are component IDs and values are their coefficients.
|
|
1100
|
+
"""
|
|
1101
|
+
# >> check
|
|
1102
|
+
if self.components is None:
|
|
1103
|
+
return {}
|
|
1104
|
+
|
|
1105
|
+
# NOTE: component ids
|
|
1106
|
+
component_ids = list(reaction_stoichiometry.keys())
|
|
1107
|
+
|
|
1108
|
+
# NOTE: build stoichiometry source
|
|
1109
|
+
stoichiometry_source = {}
|
|
1110
|
+
|
|
1111
|
+
for key in self.component_keys:
|
|
1112
|
+
id_to_component = self.reaction_stoichiometry_dict(
|
|
1113
|
+
reaction_stoichiometry,
|
|
1114
|
+
component_key=key
|
|
1115
|
+
)
|
|
1116
|
+
|
|
1117
|
+
# set
|
|
1118
|
+
stoichiometry_source[key] = id_to_component
|
|
1119
|
+
|
|
1120
|
+
# set stoichiometry source
|
|
1121
|
+
self._stoichiometry_source = stoichiometry_source
|
|
1122
|
+
return stoichiometry_source
|
|
@@ -1,14 +1,21 @@
|
|
|
1
1
|
# import libs
|
|
2
2
|
import logging
|
|
3
|
-
from typing import List, Optional
|
|
3
|
+
from typing import List, Optional, Tuple, Dict
|
|
4
|
+
from pythermodb_settings.models import Component, ComponentKey
|
|
5
|
+
from pythermodb_settings.utils import set_component_id
|
|
4
6
|
# locals
|
|
5
7
|
from ..models.reaction import Reaction
|
|
8
|
+
from ..utils.component_tools import map_component_ids
|
|
6
9
|
|
|
7
10
|
# NOTE: configure logger
|
|
8
11
|
logger = logging.getLogger(__name__)
|
|
9
12
|
|
|
10
13
|
|
|
11
|
-
def build_stoichiometry_matrix(
|
|
14
|
+
def build_stoichiometry_matrix(
|
|
15
|
+
reactions: List[Reaction],
|
|
16
|
+
components: Optional[List[Component]],
|
|
17
|
+
component_key: ComponentKey = "Name-Formula"
|
|
18
|
+
):
|
|
12
19
|
'''
|
|
13
20
|
Build stoichiometry matrix for reactions
|
|
14
21
|
|
|
@@ -16,6 +23,10 @@ def build_stoichiometry_matrix(reactions: List[Reaction]):
|
|
|
16
23
|
----------
|
|
17
24
|
reactions : List[Reaction]
|
|
18
25
|
List of Reaction instances
|
|
26
|
+
components : Optional[List[Component]]
|
|
27
|
+
List of Component instances
|
|
28
|
+
component_key : ComponentKey
|
|
29
|
+
The key used to identify components in the reaction.
|
|
19
30
|
|
|
20
31
|
Returns
|
|
21
32
|
-------
|
|
@@ -102,8 +113,18 @@ def build_stoichiometry_matrix(reactions: List[Reaction]):
|
|
|
102
113
|
[comp_list[j][item] for item in component_dict.keys()] for j in range(reaction_num)
|
|
103
114
|
]
|
|
104
115
|
|
|
116
|
+
# NOTE: map component ids to components
|
|
117
|
+
components_ext = {}
|
|
118
|
+
if components is not None:
|
|
119
|
+
components_ext = map_component_ids(
|
|
120
|
+
component_ids=component_list,
|
|
121
|
+
component=components,
|
|
122
|
+
component_key=component_key
|
|
123
|
+
)
|
|
124
|
+
|
|
105
125
|
# res
|
|
106
126
|
return {
|
|
127
|
+
"components": components_ext,
|
|
107
128
|
"component_list": component_list,
|
|
108
129
|
"component_dict": component_dict,
|
|
109
130
|
"component_state_list": component_state_list,
|
|
@@ -112,3 +133,72 @@ def build_stoichiometry_matrix(reactions: List[Reaction]):
|
|
|
112
133
|
}
|
|
113
134
|
except Exception as e:
|
|
114
135
|
raise Exception(f"Error defining component ID: {e}")
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
# SECTION: build stoichiometry matrix for reactions
|
|
139
|
+
def build_rxn_stoichiometry_source(
|
|
140
|
+
reactions: List[Reaction],
|
|
141
|
+
components: List[Component],
|
|
142
|
+
component_key: ComponentKey
|
|
143
|
+
) -> Optional[
|
|
144
|
+
Tuple[
|
|
145
|
+
List[Dict[str, float]],
|
|
146
|
+
List[List[float]]
|
|
147
|
+
]
|
|
148
|
+
]:
|
|
149
|
+
try:
|
|
150
|
+
# NOTE: stoichiometry source
|
|
151
|
+
stoichiometry_source = []
|
|
152
|
+
|
|
153
|
+
# iterate over reactions
|
|
154
|
+
for reaction in reactions:
|
|
155
|
+
# stoichiometry
|
|
156
|
+
stoichiometry_ = reaction.reaction_stoichiometry_source.get(
|
|
157
|
+
component_key, {})
|
|
158
|
+
# >> check
|
|
159
|
+
if not stoichiometry_:
|
|
160
|
+
logger.warning(
|
|
161
|
+
f"Stoichiometry source not found for reaction: {reaction.name}")
|
|
162
|
+
return None
|
|
163
|
+
|
|
164
|
+
# store
|
|
165
|
+
stoichiometry_source.append(stoichiometry_)
|
|
166
|
+
|
|
167
|
+
# NOTE: map component ids to components
|
|
168
|
+
components_source = [
|
|
169
|
+
set_component_id(
|
|
170
|
+
component=item,
|
|
171
|
+
component_key=component_key
|
|
172
|
+
) for item in components
|
|
173
|
+
]
|
|
174
|
+
|
|
175
|
+
# NOTE: stoichiometry
|
|
176
|
+
stoichiometry_result: List[Dict[str, float]] = []
|
|
177
|
+
|
|
178
|
+
# iterate over stoichiometry source
|
|
179
|
+
for i in range(len(reactions)):
|
|
180
|
+
sto_ = {}
|
|
181
|
+
for item in components_source:
|
|
182
|
+
# raw data
|
|
183
|
+
sto_[item] = 0.0
|
|
184
|
+
|
|
185
|
+
# update
|
|
186
|
+
stoichiometry_result.append(sto_)
|
|
187
|
+
|
|
188
|
+
# update stoichiometry result
|
|
189
|
+
for i, item in enumerate(stoichiometry_result):
|
|
190
|
+
for key, value in stoichiometry_source[i].items():
|
|
191
|
+
item[key] = value
|
|
192
|
+
|
|
193
|
+
# NOTE: create a matrix of stoichiometry
|
|
194
|
+
stoichiometry_result_matrix: List[List[float]] = []
|
|
195
|
+
for item in stoichiometry_result:
|
|
196
|
+
row = []
|
|
197
|
+
for key in components_source:
|
|
198
|
+
row.append(float(item[key]))
|
|
199
|
+
stoichiometry_result_matrix.append(row)
|
|
200
|
+
|
|
201
|
+
return stoichiometry_result, stoichiometry_result_matrix
|
|
202
|
+
except Exception as e:
|
|
203
|
+
logger.error(f"Error building reaction stoichiometry source: {e}")
|
|
204
|
+
return None
|
|
@@ -82,8 +82,12 @@ class Reaction(BaseModel):
|
|
|
82
82
|
default_factory=dict,
|
|
83
83
|
description="A dictionary containing the analysis results of the reaction."
|
|
84
84
|
)
|
|
85
|
-
|
|
86
|
-
|
|
85
|
+
component_keys: List[ComponentKey] = Field(
|
|
86
|
+
default_factory=lambda: [
|
|
87
|
+
"Formula-State",
|
|
88
|
+
"Name-State",
|
|
89
|
+
"Name-Formula",
|
|
90
|
+
],
|
|
87
91
|
description="The key used to identify components in the reaction analysis."
|
|
88
92
|
)
|
|
89
93
|
|
|
@@ -105,7 +109,7 @@ class Reaction(BaseModel):
|
|
|
105
109
|
util = ChemReact(
|
|
106
110
|
reaction_mode_symbol=self.reaction_mode_symbol,
|
|
107
111
|
components=self.components,
|
|
108
|
-
|
|
112
|
+
component_keys=self.component_keys
|
|
109
113
|
)
|
|
110
114
|
|
|
111
115
|
# NOTE: perform analysis
|
|
@@ -149,8 +153,8 @@ class Reaction(BaseModel):
|
|
|
149
153
|
|
|
150
154
|
@computed_field
|
|
151
155
|
@property
|
|
152
|
-
def reaction_coefficients(self) ->
|
|
153
|
-
return self.analysis.get("reaction_coefficients",
|
|
156
|
+
def reaction_coefficients(self) -> float:
|
|
157
|
+
return self.analysis.get("reaction_coefficients", 0.0)
|
|
154
158
|
|
|
155
159
|
@computed_field
|
|
156
160
|
@property
|
|
@@ -164,13 +168,13 @@ class Reaction(BaseModel):
|
|
|
164
168
|
|
|
165
169
|
@computed_field
|
|
166
170
|
@property
|
|
167
|
-
def
|
|
168
|
-
return self.analysis.get("
|
|
171
|
+
def reaction_stoichiometry_source(self) -> Dict[str, Dict[str, float]]:
|
|
172
|
+
return self.analysis.get("reaction_stoichiometry_source", {})
|
|
169
173
|
|
|
170
174
|
@computed_field
|
|
171
175
|
@property
|
|
172
|
-
def carbon_count(self) ->
|
|
173
|
-
return self.analysis.get("carbon_count",
|
|
176
|
+
def carbon_count(self) -> Dict[str, float]:
|
|
177
|
+
return self.analysis.get("carbon_count", {})
|
|
174
178
|
|
|
175
179
|
@computed_field
|
|
176
180
|
@property
|
|
@@ -179,7 +183,7 @@ class Reaction(BaseModel):
|
|
|
179
183
|
|
|
180
184
|
@computed_field
|
|
181
185
|
@property
|
|
182
|
-
def reaction_phase(self) -> Optional[
|
|
186
|
+
def reaction_phase(self) -> Optional[str]:
|
|
183
187
|
return self.analysis.get("reaction_phase", None)
|
|
184
188
|
|
|
185
189
|
@computed_field
|
|
@@ -28,6 +28,8 @@ def map_component_ids(
|
|
|
28
28
|
A dictionary mapping component IDs to their corresponding Component objects.
|
|
29
29
|
"""
|
|
30
30
|
id_to_component = {}
|
|
31
|
+
|
|
32
|
+
# iterate over components and map ids
|
|
31
33
|
for comp in component:
|
|
32
34
|
comp_id = set_component_id(comp, component_key)
|
|
33
35
|
if comp_id in component_ids:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pyreactlab-core
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.7
|
|
4
4
|
Summary: pyreactlab-core is the core foundation of the PyReactLab ecosystem, offering shared data structures and algorithms for chemical reaction representation, stoichiometry, and reaction analysis.
|
|
5
5
|
Author-email: Sina Gilassi <sina.gilassi@gmail.com>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -18,11 +18,8 @@ Classifier: Operating System :: Microsoft :: Windows
|
|
|
18
18
|
Requires-Python: >=3.11
|
|
19
19
|
Description-Content-Type: text/markdown
|
|
20
20
|
License-File: LICENSE
|
|
21
|
-
Requires-Dist:
|
|
22
|
-
Requires-Dist:
|
|
23
|
-
Requires-Dist: pydantic>=2.12.5
|
|
24
|
-
Requires-Dist: pydantic-settings>=2.12.0
|
|
25
|
-
Requires-Dist: rich>=14.2.0
|
|
21
|
+
Requires-Dist: numpy
|
|
22
|
+
Requires-Dist: pydantic
|
|
26
23
|
Requires-Dist: pythermodb-settings
|
|
27
24
|
Dynamic: license-file
|
|
28
25
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pyreactlab_core-0.1.5 → pyreactlab_core-0.1.7}/pyreactlab_core.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|