pyreactlab-core 0.1.9__tar.gz → 0.2.0__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.9 → pyreactlab_core-0.2.0}/PKG-INFO +1 -1
- {pyreactlab_core-0.1.9 → pyreactlab_core-0.2.0}/pyproject.toml +1 -1
- {pyreactlab_core-0.1.9 → pyreactlab_core-0.2.0}/pyreactlab_core/__init__.py +11 -1
- pyreactlab_core-0.2.0/pyreactlab_core/configs/constants.py +95 -0
- {pyreactlab_core-0.1.9 → pyreactlab_core-0.2.0}/pyreactlab_core/configs/info.py +1 -1
- {pyreactlab_core-0.1.9 → pyreactlab_core-0.2.0}/pyreactlab_core/core/chem_react.py +5 -4
- {pyreactlab_core-0.1.9 → pyreactlab_core-0.2.0}/pyreactlab_core/core/chem_react_utils.py +32 -0
- {pyreactlab_core-0.1.9 → pyreactlab_core-0.2.0}/pyreactlab_core/models/reaction.py +24 -15
- pyreactlab_core-0.2.0/pyreactlab_core/utils/reaction_tools.py +153 -0
- {pyreactlab_core-0.1.9 → pyreactlab_core-0.2.0}/pyreactlab_core.egg-info/PKG-INFO +1 -1
- {pyreactlab_core-0.1.9 → pyreactlab_core-0.2.0}/pyreactlab_core.egg-info/SOURCES.txt +1 -0
- pyreactlab_core-0.1.9/pyreactlab_core/configs/constants.py +0 -40
- {pyreactlab_core-0.1.9 → pyreactlab_core-0.2.0}/LICENSE +0 -0
- {pyreactlab_core-0.1.9 → pyreactlab_core-0.2.0}/README.md +0 -0
- {pyreactlab_core-0.1.9 → pyreactlab_core-0.2.0}/pyreactlab_core/app.py +0 -0
- {pyreactlab_core-0.1.9 → pyreactlab_core-0.2.0}/pyreactlab_core/configs/__init__.py +0 -0
- {pyreactlab_core-0.1.9 → pyreactlab_core-0.2.0}/pyreactlab_core/core/__init__.py +0 -0
- {pyreactlab_core-0.1.9 → pyreactlab_core-0.2.0}/pyreactlab_core/core/reaction_component_mapper.py +0 -0
- {pyreactlab_core-0.1.9 → pyreactlab_core-0.2.0}/pyreactlab_core/core/reaction_network_analysis.py +0 -0
- {pyreactlab_core-0.1.9 → pyreactlab_core-0.2.0}/pyreactlab_core/docs/__init__.py +0 -0
- {pyreactlab_core-0.1.9 → pyreactlab_core-0.2.0}/pyreactlab_core/docs/chem_balance.py +0 -0
- {pyreactlab_core-0.1.9 → pyreactlab_core-0.2.0}/pyreactlab_core/docs/chem_utils.py +0 -0
- {pyreactlab_core-0.1.9 → pyreactlab_core-0.2.0}/pyreactlab_core/models/__init__.py +0 -0
- {pyreactlab_core-0.1.9 → pyreactlab_core-0.2.0}/pyreactlab_core/utils/__init__.py +0 -0
- {pyreactlab_core-0.1.9 → pyreactlab_core-0.2.0}/pyreactlab_core/utils/component_tools.py +0 -0
- {pyreactlab_core-0.1.9 → pyreactlab_core-0.2.0}/pyreactlab_core/utils/tools.py +0 -0
- {pyreactlab_core-0.1.9 → pyreactlab_core-0.2.0}/pyreactlab_core.egg-info/dependency_links.txt +0 -0
- {pyreactlab_core-0.1.9 → pyreactlab_core-0.2.0}/pyreactlab_core.egg-info/requires.txt +0 -0
- {pyreactlab_core-0.1.9 → pyreactlab_core-0.2.0}/pyreactlab_core.egg-info/top_level.txt +0 -0
- {pyreactlab_core-0.1.9 → pyreactlab_core-0.2.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pyreactlab-core
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
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
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "pyreactlab-core"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.2.0"
|
|
8
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
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.11"
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# config
|
|
1
|
+
# NOTE: config
|
|
2
2
|
from .configs.info import (
|
|
3
3
|
__version__,
|
|
4
4
|
__author__,
|
|
@@ -8,6 +8,13 @@ from .configs.info import (
|
|
|
8
8
|
__license__,
|
|
9
9
|
)
|
|
10
10
|
|
|
11
|
+
# NOTE: configs
|
|
12
|
+
from .configs.constants import (
|
|
13
|
+
REACTION_SYMBOLIC_MODES,
|
|
14
|
+
ReactionMode
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
# NOTE: app
|
|
11
18
|
from .app import (
|
|
12
19
|
rxn,
|
|
13
20
|
rxn_stoichiometry_matrix,
|
|
@@ -23,6 +30,9 @@ __all__ = [
|
|
|
23
30
|
"__description__",
|
|
24
31
|
"__email__",
|
|
25
32
|
"__license__",
|
|
33
|
+
# configs
|
|
34
|
+
"REACTION_SYMBOLIC_MODES",
|
|
35
|
+
"ReactionMode",
|
|
26
36
|
# app
|
|
27
37
|
"rxn",
|
|
28
38
|
"rxn_stoichiometry_matrix",
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# import libs
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
from typing import Literal
|
|
4
|
+
|
|
5
|
+
# SECTION: PyThermoDBLink/PyThermoDB
|
|
6
|
+
import math
|
|
7
|
+
DATASOURCE = "datasource"
|
|
8
|
+
EQUATIONSOURCE = "equationsource"
|
|
9
|
+
|
|
10
|
+
# NOTE: universal gas constant [J/mol.K]
|
|
11
|
+
R_CONST_J__molK = 8.314472
|
|
12
|
+
|
|
13
|
+
# NOTE: pi
|
|
14
|
+
PI_CONST = math.pi
|
|
15
|
+
|
|
16
|
+
# NOTE: STP condition
|
|
17
|
+
# pressure [Pa]
|
|
18
|
+
PRESSURE_STP_Pa = 101325
|
|
19
|
+
# temperature [K]
|
|
20
|
+
TEMPERATURE_STP_K = 273.15
|
|
21
|
+
# reference pressure [Pa]
|
|
22
|
+
PRESSURE_REF_Pa = 101325
|
|
23
|
+
# reference temperature [K]
|
|
24
|
+
TEMPERATURE_REF_K = 298.15
|
|
25
|
+
|
|
26
|
+
# SECTION: Periodic Table Elements
|
|
27
|
+
PERIODIC_TABLE_ELEMENTS = [
|
|
28
|
+
"H", "He", "Li", "Be", "B", "C", "N", "O", "F", "Ne",
|
|
29
|
+
"Na", "Mg", "Al", "Si", "P", "S", "Cl", "Ar",
|
|
30
|
+
"K", "Ca", "Sc", "Ti", "V", "Cr", "Mn", "Fe", "Co", "Ni",
|
|
31
|
+
"Cu", "Zn", "Ga", "Ge", "As", "Se", "Br", "Kr",
|
|
32
|
+
"Rb", "Sr", "Y", "Zr", "Nb", "Mo", "Tc", "Ru", "Rh", "Pd",
|
|
33
|
+
"Ag", "Cd", "In", "Sn", "Sb", "Te", "I", "Xe",
|
|
34
|
+
"Cs", "Ba", "La", "Ce", "Pr", "Nd", "Pm", "Sm", "Eu", "Gd",
|
|
35
|
+
"Tb", "Dy", "Ho", "Er", "Tm", "Yb", "Lu",
|
|
36
|
+
"Hf", "Ta", "W", "Re", "Os", "Ir", "Pt",
|
|
37
|
+
"Au", "Hg", "Tl", "Pb", "Bi", "Po", "At", "Rn",
|
|
38
|
+
"Fr", "Ra", "Ac", "Th", "Pa", "U", "Np", "Pu",
|
|
39
|
+
"Am", "Cm", "Bk", "Cf", "Es", "Fm", "Md", "No", "Lr",
|
|
40
|
+
"Rf", "Db", "Sg", "Bh", "Hs", "Mt", "Ds", "Rg", "Cn",
|
|
41
|
+
"Nh", "Fl", "Mc", "Lv", "Ts", "Og",
|
|
42
|
+
]
|
|
43
|
+
|
|
44
|
+
# SECTION: Reaction
|
|
45
|
+
REACTION_SYMBOLIC_MODES = {
|
|
46
|
+
# irreversible
|
|
47
|
+
"->": ("irreversible", "forward"),
|
|
48
|
+
"=>": ("irreversible", "forward"),
|
|
49
|
+
"→": ("irreversible", "forward"),
|
|
50
|
+
"⇒": ("irreversible", "forward"),
|
|
51
|
+
|
|
52
|
+
# backward irreversible
|
|
53
|
+
# ! not recommended for use in reaction expressions
|
|
54
|
+
"<-": ("irreversible", "backward"),
|
|
55
|
+
"←": ("irreversible", "backward"),
|
|
56
|
+
|
|
57
|
+
# reversible
|
|
58
|
+
"<=>": ("reversible", "forward"),
|
|
59
|
+
"<->": ("reversible", "forward"),
|
|
60
|
+
"⇌": ("reversible", "forward"),
|
|
61
|
+
"↔": ("reversible", "forward"),
|
|
62
|
+
|
|
63
|
+
# thermodynamic equilibrium
|
|
64
|
+
"=": ("equilibrium", "forward"),
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
# NOTE: irreversible reaction mode symbols
|
|
68
|
+
IRREVERSIBLE_REACTION_MODE_SYMBOLS = [
|
|
69
|
+
"->", "=>", "→", "⇒",
|
|
70
|
+
"<-", "←"
|
|
71
|
+
]
|
|
72
|
+
|
|
73
|
+
# NOTE: reversible reaction mode symbols
|
|
74
|
+
REVERSIBLE_REACTION_MODE_SYMBOLS = [
|
|
75
|
+
"<=>", "<->", "⇌", "↔"
|
|
76
|
+
]
|
|
77
|
+
|
|
78
|
+
# NOTE: equilibrium reaction mode symbols
|
|
79
|
+
EQUILIBRIUM_REACTION_MODE_SYMBOLS = [
|
|
80
|
+
"="
|
|
81
|
+
]
|
|
82
|
+
|
|
83
|
+
# NOTE: all reaction mode symbols
|
|
84
|
+
ALL_REACTION_MODE_SYMBOLS = (
|
|
85
|
+
IRREVERSIBLE_REACTION_MODE_SYMBOLS +
|
|
86
|
+
REVERSIBLE_REACTION_MODE_SYMBOLS +
|
|
87
|
+
EQUILIBRIUM_REACTION_MODE_SYMBOLS
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
# NOTE: Reaction Mode
|
|
91
|
+
ReactionMode = Literal["<=>", "=>", "="]
|
|
92
|
+
# NOTE: Reaction Type
|
|
93
|
+
ReactionType = Literal["irreversible", "reversible", "equilibrium"]
|
|
94
|
+
# NOTE: Reaction Direction
|
|
95
|
+
ReactionDirection = Literal["forward", "backward"]
|
|
@@ -8,6 +8,7 @@ from ..configs.constants import (
|
|
|
8
8
|
R_CONST_J__molK,
|
|
9
9
|
PRESSURE_REF_Pa,
|
|
10
10
|
TEMPERATURE_REF_K,
|
|
11
|
+
ReactionMode,
|
|
11
12
|
)
|
|
12
13
|
from .chem_react_utils import ChemReactUtils
|
|
13
14
|
from .reaction_component_mapper import ReactionComponentMapper
|
|
@@ -17,9 +18,6 @@ from .reaction_network_analysis import ReactionNetworkAnalysis
|
|
|
17
18
|
# NOTE: logger
|
|
18
19
|
logger = logging.getLogger(__name__)
|
|
19
20
|
|
|
20
|
-
# NOTE: Reaction Mode
|
|
21
|
-
ReactionMode = Literal["<=>", "=>", "="]
|
|
22
|
-
|
|
23
21
|
# NOTE: Phase Rule
|
|
24
22
|
PhaseRule = Literal["gas", "liquid", "aqueous", "solid"]
|
|
25
23
|
|
|
@@ -116,6 +114,8 @@ class ChemReact(
|
|
|
116
114
|
|
|
117
115
|
# NOTE: set reaction mode symbol used by this reaction parser
|
|
118
116
|
self.reaction_mode_symbol = reaction_mode_symbol
|
|
117
|
+
# >> reaction type
|
|
118
|
+
self.reaction_type = self.get_reaction_type(reaction_mode_symbol)
|
|
119
119
|
|
|
120
120
|
# NOTE: initialize component mapping settings
|
|
121
121
|
ReactionComponentMapper.__init__(
|
|
@@ -393,6 +393,8 @@ class ChemReact(
|
|
|
393
393
|
res = {
|
|
394
394
|
'name': name,
|
|
395
395
|
'reaction': reaction,
|
|
396
|
+
'reaction_mode_symbol': self.reaction_mode_symbol,
|
|
397
|
+
'reaction_type': self.reaction_type,
|
|
396
398
|
"component_ids": component_ids,
|
|
397
399
|
"all_components": all_components,
|
|
398
400
|
"symbolic_reaction": symbolic_reaction,
|
|
@@ -417,4 +419,3 @@ class ChemReact(
|
|
|
417
419
|
return res
|
|
418
420
|
except Exception as e:
|
|
419
421
|
raise Exception(f"Error analyzing reaction: {e}")
|
|
420
|
-
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# import libs
|
|
2
2
|
import re
|
|
3
3
|
from typing import Dict, List, Optional
|
|
4
|
+
# locals
|
|
5
|
+
from ..configs.constants import REACTION_SYMBOLIC_MODES
|
|
4
6
|
|
|
5
7
|
|
|
6
8
|
# SECTION: ChemReactUtils class
|
|
@@ -147,3 +149,33 @@ class ChemReactUtils:
|
|
|
147
149
|
return state_count
|
|
148
150
|
except Exception as e:
|
|
149
151
|
raise Exception(f"Error determining reaction phase: {e}")
|
|
152
|
+
|
|
153
|
+
# ! reaction types
|
|
154
|
+
|
|
155
|
+
def get_reaction_type(self, reaction_mode_symbol: str) -> str:
|
|
156
|
+
"""
|
|
157
|
+
Determine the type of reaction based on the reaction mode symbol.
|
|
158
|
+
|
|
159
|
+
Reaction Mode Symbols:
|
|
160
|
+
- `Reversible`: "<=>"
|
|
161
|
+
- `Irreversible`: "=>"
|
|
162
|
+
- `Equilibrium`: "="
|
|
163
|
+
"""
|
|
164
|
+
try:
|
|
165
|
+
# SECTION: validate reaction mode symbol
|
|
166
|
+
if reaction_mode_symbol not in ("<=>", "=>", "="):
|
|
167
|
+
raise ValueError(
|
|
168
|
+
f"Invalid reaction mode symbol: {reaction_mode_symbol}")
|
|
169
|
+
|
|
170
|
+
# SECTION: determine reaction type
|
|
171
|
+
if reaction_mode_symbol == "<=>":
|
|
172
|
+
return "reversible"
|
|
173
|
+
elif reaction_mode_symbol == "=>":
|
|
174
|
+
return "irreversible"
|
|
175
|
+
elif reaction_mode_symbol == "=":
|
|
176
|
+
return "equilibrium"
|
|
177
|
+
else:
|
|
178
|
+
raise ValueError(
|
|
179
|
+
f"Unknown reaction mode symbol: {reaction_mode_symbol}")
|
|
180
|
+
except Exception as e:
|
|
181
|
+
raise Exception(f"Error determining reaction type: {e}")
|
|
@@ -5,11 +5,9 @@ from typing import Any, Dict, Optional, List
|
|
|
5
5
|
from pydantic import BaseModel, Field, computed_field, model_validator
|
|
6
6
|
from pythermodb_settings.models import Component, ComponentKey
|
|
7
7
|
# local imports
|
|
8
|
-
from ..
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
PhaseRule
|
|
12
|
-
)
|
|
8
|
+
from ..configs.constants import ReactionMode
|
|
9
|
+
from ..core.chem_react import ChemReact
|
|
10
|
+
from ..utils.reaction_tools import get_reaction_mode_symbol, normalize_reaction_expression
|
|
13
11
|
|
|
14
12
|
# NOTE: set up logger
|
|
15
13
|
logger = logging.getLogger(__name__)
|
|
@@ -29,6 +27,8 @@ class Reaction(BaseModel):
|
|
|
29
27
|
The symbol used to separate reactants and products in a reaction equation.
|
|
30
28
|
analysis : Dict[str, Any]
|
|
31
29
|
A dictionary containing the analysis results of the reaction.
|
|
30
|
+
component_keys : List[ComponentKey]
|
|
31
|
+
The key used to identify components in the reaction analysis, with a default value of ["Formula-State", "Name-State", "Name-Formula"].
|
|
32
32
|
|
|
33
33
|
Properties
|
|
34
34
|
----------
|
|
@@ -93,17 +93,16 @@ class Reaction(BaseModel):
|
|
|
93
93
|
|
|
94
94
|
@model_validator(mode="after")
|
|
95
95
|
def _run_existing_analysis(self):
|
|
96
|
-
# NOTE:
|
|
97
|
-
if
|
|
98
|
-
self.reaction_mode_symbol =
|
|
99
|
-
elif "=>" in self.reaction:
|
|
100
|
-
self.reaction_mode_symbol = "=>"
|
|
101
|
-
elif "=" in self.reaction:
|
|
102
|
-
self.reaction_mode_symbol = "="
|
|
96
|
+
# NOTE: validate reaction mode symbol
|
|
97
|
+
if self.reaction_mode_symbol is None:
|
|
98
|
+
self.reaction_mode_symbol = get_reaction_mode_symbol(self.reaction)
|
|
103
99
|
else:
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
100
|
+
# validate provided reaction mode symbol
|
|
101
|
+
if self.reaction_mode_symbol not in ["<=>", "=>", "="]:
|
|
102
|
+
raise ValueError(
|
|
103
|
+
f"Invalid reaction mode symbol: {self.reaction_mode_symbol}. "
|
|
104
|
+
f"Must be one of ['<=>', '=>', '=']."
|
|
105
|
+
)
|
|
107
106
|
|
|
108
107
|
# NOTE: analyze reaction
|
|
109
108
|
util = ChemReact(
|
|
@@ -112,6 +111,9 @@ class Reaction(BaseModel):
|
|
|
112
111
|
component_keys=self.component_keys
|
|
113
112
|
)
|
|
114
113
|
|
|
114
|
+
# NOTE: normalize reaction string
|
|
115
|
+
self.reaction = normalize_reaction_expression(self.reaction)
|
|
116
|
+
|
|
115
117
|
# NOTE: perform analysis
|
|
116
118
|
self.analysis = util.analyze_reaction(
|
|
117
119
|
reaction_pack={
|
|
@@ -119,6 +121,8 @@ class Reaction(BaseModel):
|
|
|
119
121
|
"reaction": self.reaction
|
|
120
122
|
},
|
|
121
123
|
)
|
|
124
|
+
|
|
125
|
+
# ! return self to allow for method chaining or further processing if needed
|
|
122
126
|
return self
|
|
123
127
|
|
|
124
128
|
@computed_field
|
|
@@ -126,6 +130,11 @@ class Reaction(BaseModel):
|
|
|
126
130
|
def symbolic_reaction(self) -> str:
|
|
127
131
|
return self.analysis.get("symbolic_reaction", "")
|
|
128
132
|
|
|
133
|
+
@computed_field
|
|
134
|
+
@property
|
|
135
|
+
def reaction_type(self) -> str:
|
|
136
|
+
return self.analysis.get("reaction_type", "")
|
|
137
|
+
|
|
129
138
|
@computed_field
|
|
130
139
|
@property
|
|
131
140
|
def symbolic_unbalanced_reaction(self) -> str:
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
# import libs
|
|
2
|
+
import logging
|
|
3
|
+
from typing import Any, Dict, List, Optional, cast, NamedTuple
|
|
4
|
+
# locals
|
|
5
|
+
from ..configs.constants import (
|
|
6
|
+
IRREVERSIBLE_REACTION_MODE_SYMBOLS,
|
|
7
|
+
REVERSIBLE_REACTION_MODE_SYMBOLS,
|
|
8
|
+
EQUILIBRIUM_REACTION_MODE_SYMBOLS,
|
|
9
|
+
ReactionMode,
|
|
10
|
+
ReactionDirection,
|
|
11
|
+
ReactionType,
|
|
12
|
+
REACTION_SYMBOLIC_MODES,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
# NOTE: logger
|
|
16
|
+
logger = logging.getLogger(__name__)
|
|
17
|
+
|
|
18
|
+
# ! reaction mode
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class ReactionSymbolInfo(NamedTuple):
|
|
22
|
+
reaction: str
|
|
23
|
+
symbol: str
|
|
24
|
+
type: ReactionType
|
|
25
|
+
mode: ReactionMode
|
|
26
|
+
direction: ReactionDirection
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def check_reaction(
|
|
30
|
+
reaction: str,
|
|
31
|
+
) -> ReactionSymbolInfo:
|
|
32
|
+
"""
|
|
33
|
+
Determine the reaction mode symbol, type, and direction from a given reaction string.
|
|
34
|
+
|
|
35
|
+
Parameters
|
|
36
|
+
----------
|
|
37
|
+
reaction : str
|
|
38
|
+
The chemical reaction equation as a string.
|
|
39
|
+
|
|
40
|
+
Returns
|
|
41
|
+
-------
|
|
42
|
+
ReactionSymbolInfo
|
|
43
|
+
A named tuple containing the reaction mode symbol, type, and direction.
|
|
44
|
+
"""
|
|
45
|
+
try:
|
|
46
|
+
# SECTION: check for reaction mode symbols in the reaction string
|
|
47
|
+
rxn_direction = None
|
|
48
|
+
rxn_mode = None
|
|
49
|
+
rxn_symbol = None
|
|
50
|
+
|
|
51
|
+
# Longest symbols first to avoid "=" matching "<=>"
|
|
52
|
+
symbols = sorted(
|
|
53
|
+
REACTION_SYMBOLIC_MODES,
|
|
54
|
+
key=len,
|
|
55
|
+
reverse=True,
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
for symbol in symbols:
|
|
59
|
+
if symbol in reaction:
|
|
60
|
+
mode, direction = REACTION_SYMBOLIC_MODES[symbol]
|
|
61
|
+
rxn_mode = mode
|
|
62
|
+
rxn_direction = direction
|
|
63
|
+
rxn_symbol = symbol
|
|
64
|
+
# replace the symbol with :::
|
|
65
|
+
reaction = reaction.replace(symbol, ":::")
|
|
66
|
+
# break after finding the first valid symbol
|
|
67
|
+
break
|
|
68
|
+
|
|
69
|
+
# NOTE: if a valid reaction mode symbol is found, return it
|
|
70
|
+
if (
|
|
71
|
+
rxn_symbol is not None and
|
|
72
|
+
rxn_symbol is not None and
|
|
73
|
+
rxn_direction is not None
|
|
74
|
+
):
|
|
75
|
+
if rxn_mode == "irreversible":
|
|
76
|
+
return ReactionSymbolInfo(
|
|
77
|
+
reaction=reaction.replace(":::", '=>'),
|
|
78
|
+
symbol=rxn_symbol,
|
|
79
|
+
type=cast(ReactionType, "irreversible"),
|
|
80
|
+
mode=cast(ReactionMode, "=>"),
|
|
81
|
+
direction=cast(ReactionDirection, "forward")
|
|
82
|
+
)
|
|
83
|
+
elif rxn_mode == "reversible":
|
|
84
|
+
return ReactionSymbolInfo(
|
|
85
|
+
reaction=reaction.replace(":::", '<=>'),
|
|
86
|
+
symbol=rxn_symbol,
|
|
87
|
+
type=cast(ReactionType, "reversible"),
|
|
88
|
+
mode=cast(ReactionMode, "<=>"),
|
|
89
|
+
direction=cast(ReactionDirection, "forward")
|
|
90
|
+
)
|
|
91
|
+
elif rxn_mode == "equilibrium":
|
|
92
|
+
return ReactionSymbolInfo(
|
|
93
|
+
reaction=reaction.replace(":::", '='),
|
|
94
|
+
symbol=rxn_symbol,
|
|
95
|
+
type=cast(ReactionType, "equilibrium"),
|
|
96
|
+
mode=cast(ReactionMode, "="),
|
|
97
|
+
direction=cast(ReactionDirection, "forward")
|
|
98
|
+
)
|
|
99
|
+
else:
|
|
100
|
+
raise ValueError(f"Unknown reaction type: {rxn_mode}")
|
|
101
|
+
|
|
102
|
+
# NOTE: no valid reaction mode found
|
|
103
|
+
raise
|
|
104
|
+
except Exception as e:
|
|
105
|
+
raise Exception(f"Error determining reaction mode: {e}")
|
|
106
|
+
|
|
107
|
+
# ! get reaction mode symbol
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def get_reaction_mode_symbol(reaction: str) -> ReactionMode:
|
|
111
|
+
"""
|
|
112
|
+
Determine the reaction mode symbol from a given reaction string.
|
|
113
|
+
|
|
114
|
+
Parameters
|
|
115
|
+
----------
|
|
116
|
+
reaction : str
|
|
117
|
+
The chemical reaction equation as a string.
|
|
118
|
+
|
|
119
|
+
Returns
|
|
120
|
+
-------
|
|
121
|
+
ReactionMode
|
|
122
|
+
The reaction mode symbol.
|
|
123
|
+
"""
|
|
124
|
+
try:
|
|
125
|
+
# SECTION: check for reaction mode symbols in the reaction string
|
|
126
|
+
rxn_symbol_info = check_reaction(reaction)
|
|
127
|
+
return rxn_symbol_info.mode
|
|
128
|
+
except Exception as e:
|
|
129
|
+
raise Exception(f"Error determining reaction mode symbol: {e}")
|
|
130
|
+
|
|
131
|
+
# ! get reaction expression
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def normalize_reaction_expression(reaction: str) -> str:
|
|
135
|
+
"""
|
|
136
|
+
Normalize the reaction expression by removing the reaction mode symbol and updating the symbol to a standard form including "<=>", "=>", or "=".
|
|
137
|
+
|
|
138
|
+
Parameters
|
|
139
|
+
----------
|
|
140
|
+
reaction : str
|
|
141
|
+
The chemical reaction equation as a string.
|
|
142
|
+
|
|
143
|
+
Returns
|
|
144
|
+
-------
|
|
145
|
+
str
|
|
146
|
+
The reaction expression without the mode symbol.
|
|
147
|
+
"""
|
|
148
|
+
try:
|
|
149
|
+
# SECTION: check for reaction mode symbols in the reaction string
|
|
150
|
+
rxn_symbol_info = check_reaction(reaction)
|
|
151
|
+
return rxn_symbol_info.reaction
|
|
152
|
+
except Exception as e:
|
|
153
|
+
raise Exception(f"Error determining reaction expression: {e}")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pyreactlab-core
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
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,40 +0,0 @@
|
|
|
1
|
-
# import libs
|
|
2
|
-
|
|
3
|
-
# SECTION: PyThermoDBLink/PyThermoDB
|
|
4
|
-
import math
|
|
5
|
-
DATASOURCE = "datasource"
|
|
6
|
-
EQUATIONSOURCE = "equationsource"
|
|
7
|
-
|
|
8
|
-
# NOTE: universal gas constant [J/mol.K]
|
|
9
|
-
R_CONST_J__molK = 8.314472
|
|
10
|
-
|
|
11
|
-
# NOTE: pi
|
|
12
|
-
PI_CONST = math.pi
|
|
13
|
-
|
|
14
|
-
# NOTE: STP condition
|
|
15
|
-
# pressure [Pa]
|
|
16
|
-
PRESSURE_STP_Pa = 101325
|
|
17
|
-
# temperature [K]
|
|
18
|
-
TEMPERATURE_STP_K = 273.15
|
|
19
|
-
# reference pressure [Pa]
|
|
20
|
-
PRESSURE_REF_Pa = 101325
|
|
21
|
-
# reference temperature [K]
|
|
22
|
-
TEMPERATURE_REF_K = 298.15
|
|
23
|
-
|
|
24
|
-
# SECTION: Periodic Table Elements
|
|
25
|
-
PERIODIC_TABLE_ELEMENTS = [
|
|
26
|
-
"H", "He", "Li", "Be", "B", "C", "N", "O", "F", "Ne",
|
|
27
|
-
"Na", "Mg", "Al", "Si", "P", "S", "Cl", "Ar",
|
|
28
|
-
"K", "Ca", "Sc", "Ti", "V", "Cr", "Mn", "Fe", "Co", "Ni",
|
|
29
|
-
"Cu", "Zn", "Ga", "Ge", "As", "Se", "Br", "Kr",
|
|
30
|
-
"Rb", "Sr", "Y", "Zr", "Nb", "Mo", "Tc", "Ru", "Rh", "Pd",
|
|
31
|
-
"Ag", "Cd", "In", "Sn", "Sb", "Te", "I", "Xe",
|
|
32
|
-
"Cs", "Ba", "La", "Ce", "Pr", "Nd", "Pm", "Sm", "Eu", "Gd",
|
|
33
|
-
"Tb", "Dy", "Ho", "Er", "Tm", "Yb", "Lu",
|
|
34
|
-
"Hf", "Ta", "W", "Re", "Os", "Ir", "Pt",
|
|
35
|
-
"Au", "Hg", "Tl", "Pb", "Bi", "Po", "At", "Rn",
|
|
36
|
-
"Fr", "Ra", "Ac", "Th", "Pa", "U", "Np", "Pu",
|
|
37
|
-
"Am", "Cm", "Bk", "Cf", "Es", "Fm", "Md", "No", "Lr",
|
|
38
|
-
"Rf", "Db", "Sg", "Bh", "Hs", "Mt", "Ds", "Rg", "Cn",
|
|
39
|
-
"Nh", "Fl", "Mc", "Lv", "Ts", "Og",
|
|
40
|
-
]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pyreactlab_core-0.1.9 → pyreactlab_core-0.2.0}/pyreactlab_core/core/reaction_component_mapper.py
RENAMED
|
File without changes
|
{pyreactlab_core-0.1.9 → pyreactlab_core-0.2.0}/pyreactlab_core/core/reaction_network_analysis.py
RENAMED
|
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.9 → pyreactlab_core-0.2.0}/pyreactlab_core.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|