pyreactlab-core 0.1.4__tar.gz → 0.1.6__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.4 → pyreactlab_core-0.1.6}/PKG-INFO +1 -1
- {pyreactlab_core-0.1.4 → pyreactlab_core-0.1.6}/pyproject.toml +74 -74
- {pyreactlab_core-0.1.4 → pyreactlab_core-0.1.6}/pyreactlab_core/__init__.py +8 -2
- {pyreactlab_core-0.1.4 → pyreactlab_core-0.1.6}/pyreactlab_core/app.py +82 -6
- {pyreactlab_core-0.1.4 → pyreactlab_core-0.1.6}/pyreactlab_core/configs/info.py +1 -1
- {pyreactlab_core-0.1.4 → pyreactlab_core-0.1.6}/pyreactlab_core/core/chem_react.py +105 -2
- {pyreactlab_core-0.1.4 → pyreactlab_core-0.1.6}/pyreactlab_core/docs/chem_utils.py +92 -2
- {pyreactlab_core-0.1.4 → pyreactlab_core-0.1.6}/pyreactlab_core/models/reaction.py +25 -8
- pyreactlab_core-0.1.6/pyreactlab_core/utils/component_tools.py +38 -0
- {pyreactlab_core-0.1.4 → pyreactlab_core-0.1.6}/pyreactlab_core.egg-info/PKG-INFO +1 -1
- {pyreactlab_core-0.1.4 → pyreactlab_core-0.1.6}/pyreactlab_core.egg-info/SOURCES.txt +1 -0
- {pyreactlab_core-0.1.4 → pyreactlab_core-0.1.6}/LICENSE +0 -0
- {pyreactlab_core-0.1.4 → pyreactlab_core-0.1.6}/README.md +0 -0
- {pyreactlab_core-0.1.4 → pyreactlab_core-0.1.6}/pyreactlab_core/configs/__init__.py +0 -0
- {pyreactlab_core-0.1.4 → pyreactlab_core-0.1.6}/pyreactlab_core/configs/constants.py +0 -0
- {pyreactlab_core-0.1.4 → pyreactlab_core-0.1.6}/pyreactlab_core/core/__init__.py +0 -0
- {pyreactlab_core-0.1.4 → pyreactlab_core-0.1.6}/pyreactlab_core/docs/__init__.py +0 -0
- {pyreactlab_core-0.1.4 → pyreactlab_core-0.1.6}/pyreactlab_core/docs/chem_balance.py +0 -0
- {pyreactlab_core-0.1.4 → pyreactlab_core-0.1.6}/pyreactlab_core/models/__init__.py +0 -0
- {pyreactlab_core-0.1.4 → pyreactlab_core-0.1.6}/pyreactlab_core/utils/__init__.py +0 -0
- {pyreactlab_core-0.1.4 → pyreactlab_core-0.1.6}/pyreactlab_core/utils/tools.py +0 -0
- {pyreactlab_core-0.1.4 → pyreactlab_core-0.1.6}/pyreactlab_core.egg-info/dependency_links.txt +0 -0
- {pyreactlab_core-0.1.4 → pyreactlab_core-0.1.6}/pyreactlab_core.egg-info/requires.txt +0 -0
- {pyreactlab_core-0.1.4 → pyreactlab_core-0.1.6}/pyreactlab_core.egg-info/top_level.txt +0 -0
- {pyreactlab_core-0.1.4 → pyreactlab_core-0.1.6}/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.6
|
|
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
|
|
@@ -1,74 +1,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.
|
|
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
|
-
"scipy>=1.17.1",
|
|
33
|
-
"numpy>=2.4.3",
|
|
34
|
-
"pydantic>=2.12.5",
|
|
35
|
-
"pydantic-settings>=2.12.0",
|
|
36
|
-
"rich>=14.2.0",
|
|
37
|
-
"pythermodb-settings",
|
|
38
|
-
]
|
|
39
|
-
|
|
40
|
-
[project.urls]
|
|
41
|
-
Homepage = "https://github.com/sinagilassi/PyReactLab-Core"
|
|
42
|
-
Documentation = "https://pyreactlab-core.readthedocs.io/en/latest/"
|
|
43
|
-
Source = "https://github.com/sinagilassi/PyReactLab-Core"
|
|
44
|
-
Tracker = "https://github.com/sinagilassi/PyReactLab-Core/issues"
|
|
45
|
-
|
|
46
|
-
[tool.setuptools]
|
|
47
|
-
include-package-data = true
|
|
48
|
-
|
|
49
|
-
[tool.setuptools.packages.find]
|
|
50
|
-
where = ["."]
|
|
51
|
-
include = ["pyreactlab_core*"]
|
|
52
|
-
exclude = [
|
|
53
|
-
"tests",
|
|
54
|
-
"tests.*",
|
|
55
|
-
"examples",
|
|
56
|
-
"examples.*",
|
|
57
|
-
"notebooks",
|
|
58
|
-
"notebooks.*",
|
|
59
|
-
"statics",
|
|
60
|
-
"statics.*",
|
|
61
|
-
"private",
|
|
62
|
-
"private.*",
|
|
63
|
-
"app",
|
|
64
|
-
"app.*"
|
|
65
|
-
]
|
|
66
|
-
|
|
67
|
-
[tool.setuptools.package-data]
|
|
68
|
-
pyreactlab_core = [
|
|
69
|
-
"config/*.yml",
|
|
70
|
-
"data/*.csv",
|
|
71
|
-
"templates/*.html",
|
|
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.6"
|
|
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
|
+
"scipy>=1.17.1",
|
|
33
|
+
"numpy>=2.4.3",
|
|
34
|
+
"pydantic>=2.12.5",
|
|
35
|
+
"pydantic-settings>=2.12.0",
|
|
36
|
+
"rich>=14.2.0",
|
|
37
|
+
"pythermodb-settings",
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
[project.urls]
|
|
41
|
+
Homepage = "https://github.com/sinagilassi/PyReactLab-Core"
|
|
42
|
+
Documentation = "https://pyreactlab-core.readthedocs.io/en/latest/"
|
|
43
|
+
Source = "https://github.com/sinagilassi/PyReactLab-Core"
|
|
44
|
+
Tracker = "https://github.com/sinagilassi/PyReactLab-Core/issues"
|
|
45
|
+
|
|
46
|
+
[tool.setuptools]
|
|
47
|
+
include-package-data = true
|
|
48
|
+
|
|
49
|
+
[tool.setuptools.packages.find]
|
|
50
|
+
where = ["."]
|
|
51
|
+
include = ["pyreactlab_core*"]
|
|
52
|
+
exclude = [
|
|
53
|
+
"tests",
|
|
54
|
+
"tests.*",
|
|
55
|
+
"examples",
|
|
56
|
+
"examples.*",
|
|
57
|
+
"notebooks",
|
|
58
|
+
"notebooks.*",
|
|
59
|
+
"statics",
|
|
60
|
+
"statics.*",
|
|
61
|
+
"private",
|
|
62
|
+
"private.*",
|
|
63
|
+
"app",
|
|
64
|
+
"app.*"
|
|
65
|
+
]
|
|
66
|
+
|
|
67
|
+
[tool.setuptools.package-data]
|
|
68
|
+
pyreactlab_core = [
|
|
69
|
+
"config/*.yml",
|
|
70
|
+
"data/*.csv",
|
|
71
|
+
"templates/*.html",
|
|
72
|
+
"static/*",
|
|
73
|
+
"static/**/*"
|
|
74
|
+
]
|
|
@@ -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
|
|
@@ -2,13 +2,16 @@
|
|
|
2
2
|
import logging
|
|
3
3
|
import re
|
|
4
4
|
from typing import Dict, Any, List, Optional, Literal, TypedDict
|
|
5
|
-
from pythermodb_settings.models import Component
|
|
5
|
+
from pythermodb_settings.models import Component, ComponentKey
|
|
6
|
+
from pythermodb_settings.utils import set_component_id
|
|
7
|
+
# locals
|
|
6
8
|
from ..configs.constants import (
|
|
7
9
|
R_CONST_J__molK,
|
|
8
10
|
PRESSURE_REF_Pa,
|
|
9
11
|
TEMPERATURE_REF_K,
|
|
10
12
|
)
|
|
11
13
|
|
|
14
|
+
|
|
12
15
|
# NOTE: logger
|
|
13
16
|
logger = logging.getLogger(__name__)
|
|
14
17
|
|
|
@@ -69,10 +72,14 @@ class ChemReact:
|
|
|
69
72
|
# NOTE: component checker
|
|
70
73
|
_component_checker: bool = False
|
|
71
74
|
|
|
75
|
+
# NOTE: stoichiometry source
|
|
76
|
+
_stoichiometry_source: dict[str, Any] = {}
|
|
77
|
+
|
|
72
78
|
def __init__(
|
|
73
79
|
self,
|
|
74
80
|
reaction_mode_symbol: ReactionMode,
|
|
75
|
-
components: Optional[List[Component]]
|
|
81
|
+
components: Optional[List[Component]],
|
|
82
|
+
component_keys: Optional[List[ComponentKey]] = None
|
|
76
83
|
):
|
|
77
84
|
"""
|
|
78
85
|
Initialize the ChemReactUtils class.
|
|
@@ -83,6 +90,8 @@ class ChemReact:
|
|
|
83
90
|
The symbol used to separate reactants and products in a reaction equation.
|
|
84
91
|
components : Optional[List[Component]]
|
|
85
92
|
A list of Component objects involved in the reaction.
|
|
93
|
+
component_keys : List[ComponentKey], optional
|
|
94
|
+
The key used to identify components in the reaction.
|
|
86
95
|
|
|
87
96
|
Notes
|
|
88
97
|
-----
|
|
@@ -98,6 +107,12 @@ class ChemReact:
|
|
|
98
107
|
# NOTE: set components
|
|
99
108
|
self.components = components
|
|
100
109
|
|
|
110
|
+
# NOTE: set component key
|
|
111
|
+
if component_keys is not None:
|
|
112
|
+
self.component_keys = component_keys
|
|
113
|
+
else:
|
|
114
|
+
self.component_keys = []
|
|
115
|
+
|
|
101
116
|
# SECTION: Component id
|
|
102
117
|
# NOTE: component ids
|
|
103
118
|
if components is None:
|
|
@@ -115,6 +130,12 @@ class ChemReact:
|
|
|
115
130
|
raise ValueError("System inputs are not set.")
|
|
116
131
|
return self._system_inputs
|
|
117
132
|
|
|
133
|
+
@property
|
|
134
|
+
def stoichiometry_source(self) -> Dict[str, Any]:
|
|
135
|
+
"""Get the stoichiometry source."""
|
|
136
|
+
# res
|
|
137
|
+
return self._stoichiometry_source
|
|
138
|
+
|
|
118
139
|
def count_carbon(self, molecule: str, coefficient: float) -> float:
|
|
119
140
|
"""
|
|
120
141
|
Count the number of carbon atoms in a molecule.
|
|
@@ -396,6 +417,11 @@ class ChemReact:
|
|
|
396
417
|
products,
|
|
397
418
|
)
|
|
398
419
|
|
|
420
|
+
# SECTION: build stoichiometry source
|
|
421
|
+
stoichiometry_source = self.build_stoichiometry_source(
|
|
422
|
+
reaction_stoichiometry=reaction_stoichiometry
|
|
423
|
+
)
|
|
424
|
+
|
|
399
425
|
# res
|
|
400
426
|
res = {
|
|
401
427
|
'name': name,
|
|
@@ -411,6 +437,7 @@ class ChemReact:
|
|
|
411
437
|
'reaction_coefficients': reaction_coefficients,
|
|
412
438
|
'reaction_stoichiometry': reaction_stoichiometry,
|
|
413
439
|
'reaction_stoichiometry_matrix': reaction_stoichiometry_matrix,
|
|
440
|
+
'reaction_stoichiometry_source': stoichiometry_source,
|
|
414
441
|
'carbon_count': carbon_count,
|
|
415
442
|
'reaction_state': reaction_state,
|
|
416
443
|
'reaction_phase': reaction_phase,
|
|
@@ -1017,3 +1044,79 @@ class ChemReact:
|
|
|
1017
1044
|
return component_map
|
|
1018
1045
|
except Exception as e:
|
|
1019
1046
|
raise Exception(f"Error mapping components: {e}")
|
|
1047
|
+
|
|
1048
|
+
def reaction_stoichiometry_dict(
|
|
1049
|
+
self,
|
|
1050
|
+
reaction_stoichiometry: Dict[str, float],
|
|
1051
|
+
component_key: ComponentKey = "Name-Formula"
|
|
1052
|
+
) -> Dict[str, float]:
|
|
1053
|
+
'''
|
|
1054
|
+
Generate the reaction stoichiometry matrix.
|
|
1055
|
+
|
|
1056
|
+
Parameters
|
|
1057
|
+
----------
|
|
1058
|
+
reaction_stoichiometry: dict
|
|
1059
|
+
A dictionary containing the stoichiometry of the reaction, where keys are component IDs and values are their coefficients.
|
|
1060
|
+
|
|
1061
|
+
Returns
|
|
1062
|
+
-------
|
|
1063
|
+
dict
|
|
1064
|
+
A dictionary representing the reaction stoichiometry, where keys are component IDs and values are their coefficients.
|
|
1065
|
+
'''
|
|
1066
|
+
# >> check
|
|
1067
|
+
if self.components is None:
|
|
1068
|
+
return {}
|
|
1069
|
+
|
|
1070
|
+
# NOTE: component ids
|
|
1071
|
+
component_ids = list(reaction_stoichiometry.keys())
|
|
1072
|
+
|
|
1073
|
+
id_to_component = {}
|
|
1074
|
+
for comp in self.components:
|
|
1075
|
+
comp_id = set_component_id(comp, 'Formula-State') # type: ignore
|
|
1076
|
+
if comp_id in component_ids:
|
|
1077
|
+
# create component id
|
|
1078
|
+
comp_id_new = set_component_id(
|
|
1079
|
+
comp,
|
|
1080
|
+
component_key
|
|
1081
|
+
)
|
|
1082
|
+
id_to_component[comp_id_new] = reaction_stoichiometry[comp_id]
|
|
1083
|
+
else:
|
|
1084
|
+
logging.warning(
|
|
1085
|
+
f"Component '{comp_id}' not found in reaction stoichiometry.")
|
|
1086
|
+
|
|
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
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# import libs
|
|
2
2
|
from __future__ import annotations
|
|
3
|
-
|
|
3
|
+
import logging
|
|
4
4
|
from typing import Any, Dict, Optional, List
|
|
5
5
|
from pydantic import BaseModel, Field, computed_field, model_validator
|
|
6
|
-
from pythermodb_settings.models import Component
|
|
6
|
+
from pythermodb_settings.models import Component, ComponentKey
|
|
7
7
|
# local imports
|
|
8
8
|
from ..core.chem_react import (
|
|
9
9
|
ChemReact,
|
|
@@ -11,6 +11,9 @@ from ..core.chem_react import (
|
|
|
11
11
|
PhaseRule
|
|
12
12
|
)
|
|
13
13
|
|
|
14
|
+
# NOTE: set up logger
|
|
15
|
+
logger = logging.getLogger(__name__)
|
|
16
|
+
|
|
14
17
|
|
|
15
18
|
class Reaction(BaseModel):
|
|
16
19
|
"""
|
|
@@ -79,6 +82,14 @@ class Reaction(BaseModel):
|
|
|
79
82
|
default_factory=dict,
|
|
80
83
|
description="A dictionary containing the analysis results of the reaction."
|
|
81
84
|
)
|
|
85
|
+
component_keys: List[ComponentKey] = Field(
|
|
86
|
+
default_factory=lambda: [
|
|
87
|
+
"Formula-State",
|
|
88
|
+
"Name-State",
|
|
89
|
+
"Name-Formula",
|
|
90
|
+
],
|
|
91
|
+
description="The key used to identify components in the reaction analysis."
|
|
92
|
+
)
|
|
82
93
|
|
|
83
94
|
@model_validator(mode="after")
|
|
84
95
|
def _run_existing_analysis(self):
|
|
@@ -97,7 +108,8 @@ class Reaction(BaseModel):
|
|
|
97
108
|
# NOTE: analyze reaction
|
|
98
109
|
util = ChemReact(
|
|
99
110
|
reaction_mode_symbol=self.reaction_mode_symbol,
|
|
100
|
-
components=self.components
|
|
111
|
+
components=self.components,
|
|
112
|
+
component_keys=self.component_keys
|
|
101
113
|
)
|
|
102
114
|
|
|
103
115
|
# NOTE: perform analysis
|
|
@@ -141,8 +153,8 @@ class Reaction(BaseModel):
|
|
|
141
153
|
|
|
142
154
|
@computed_field
|
|
143
155
|
@property
|
|
144
|
-
def reaction_coefficients(self) ->
|
|
145
|
-
return self.analysis.get("reaction_coefficients",
|
|
156
|
+
def reaction_coefficients(self) -> float:
|
|
157
|
+
return self.analysis.get("reaction_coefficients", 0.0)
|
|
146
158
|
|
|
147
159
|
@computed_field
|
|
148
160
|
@property
|
|
@@ -156,8 +168,13 @@ class Reaction(BaseModel):
|
|
|
156
168
|
|
|
157
169
|
@computed_field
|
|
158
170
|
@property
|
|
159
|
-
def
|
|
160
|
-
return self.analysis.get("
|
|
171
|
+
def reaction_stoichiometry_source(self) -> Dict[str, Dict[str, float]]:
|
|
172
|
+
return self.analysis.get("reaction_stoichiometry_source", {})
|
|
173
|
+
|
|
174
|
+
@computed_field
|
|
175
|
+
@property
|
|
176
|
+
def carbon_count(self) -> Dict[str, float]:
|
|
177
|
+
return self.analysis.get("carbon_count", {})
|
|
161
178
|
|
|
162
179
|
@computed_field
|
|
163
180
|
@property
|
|
@@ -166,7 +183,7 @@ class Reaction(BaseModel):
|
|
|
166
183
|
|
|
167
184
|
@computed_field
|
|
168
185
|
@property
|
|
169
|
-
def reaction_phase(self) -> Optional[
|
|
186
|
+
def reaction_phase(self) -> Optional[str]:
|
|
170
187
|
return self.analysis.get("reaction_phase", None)
|
|
171
188
|
|
|
172
189
|
@computed_field
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# import libs
|
|
2
|
+
import logging
|
|
3
|
+
from typing import Dict, Any, List, Optional, Literal
|
|
4
|
+
from pythermodb_settings.models import Component, ComponentKey
|
|
5
|
+
from pythermodb_settings.utils import set_component_id
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def map_component_ids(
|
|
9
|
+
component_ids: list[str],
|
|
10
|
+
component: List[Component],
|
|
11
|
+
component_key: ComponentKey
|
|
12
|
+
):
|
|
13
|
+
"""
|
|
14
|
+
Map component IDs to their corresponding components.
|
|
15
|
+
|
|
16
|
+
Parameters
|
|
17
|
+
----------
|
|
18
|
+
component_ids : list[str]
|
|
19
|
+
A list of component IDs to be mapped.
|
|
20
|
+
component : List[Component]
|
|
21
|
+
A list of Component objects to be mapped against.
|
|
22
|
+
component_key : ComponentKey
|
|
23
|
+
The key used to identify components in the reaction.
|
|
24
|
+
|
|
25
|
+
Returns
|
|
26
|
+
-------
|
|
27
|
+
Dict[str, Component]
|
|
28
|
+
A dictionary mapping component IDs to their corresponding Component objects.
|
|
29
|
+
"""
|
|
30
|
+
id_to_component = {}
|
|
31
|
+
|
|
32
|
+
# iterate over components and map ids
|
|
33
|
+
for comp in component:
|
|
34
|
+
comp_id = set_component_id(comp, component_key)
|
|
35
|
+
if comp_id in component_ids:
|
|
36
|
+
id_to_component[comp_id] = comp
|
|
37
|
+
|
|
38
|
+
return id_to_component
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pyreactlab-core
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.6
|
|
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
|
|
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.4 → pyreactlab_core-0.1.6}/pyreactlab_core.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|