musica 0.11.1.4__cp312-cp312-macosx_11_0_arm64.whl → 0.12.0__cp312-cp312-macosx_11_0_arm64.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.
Potentially problematic release.
This version of musica might be problematic. Click here for more details.
- musica/_musica.cpython-312-darwin.so +0 -0
- musica/_version.py +1 -1
- musica/constants.py +3 -0
- musica/mechanism_configuration/__init__.py +1 -0
- musica/mechanism_configuration/aqueous_equilibrium.py +101 -0
- musica/mechanism_configuration/arrhenius.py +121 -0
- musica/mechanism_configuration/branched.py +116 -0
- musica/mechanism_configuration/condensed_phase_arrhenius.py +116 -0
- musica/mechanism_configuration/condensed_phase_photolysis.py +91 -0
- musica/mechanism_configuration/emission.py +67 -0
- musica/mechanism_configuration/first_order_loss.py +67 -0
- musica/mechanism_configuration/henrys_law.py +85 -0
- musica/mechanism_configuration/mechanism_configuration.py +161 -0
- musica/mechanism_configuration/phase.py +43 -0
- musica/mechanism_configuration/photolysis.py +83 -0
- musica/mechanism_configuration/reactions.py +61 -0
- musica/mechanism_configuration/simpol_phase_transfer.py +88 -0
- musica/mechanism_configuration/species.py +72 -0
- musica/mechanism_configuration/surface.py +89 -0
- musica/mechanism_configuration/troe.py +137 -0
- musica/mechanism_configuration/tunneling.py +103 -0
- musica/mechanism_configuration/user_defined.py +83 -0
- musica/mechanism_configuration/utils.py +10 -0
- musica/mechanism_configuration/wet_deposition.py +49 -0
- musica/mechanism_configuration.cpp +0 -1
- musica/test/examples/v1/full_configuration/full_configuration.json +30 -15
- musica/test/examples/v1/full_configuration/full_configuration.yaml +16 -1
- musica/test/test_analytical.py +1 -1
- musica/test/test_parser.py +3 -639
- musica/test/test_serializer.py +69 -0
- musica/test/test_util_full_mechanism.py +668 -0
- musica/types.py +1 -4
- {musica-0.11.1.4.dist-info → musica-0.12.0.dist-info}/METADATA +61 -46
- musica-0.12.0.dist-info/RECORD +57 -0
- musica-0.12.0.dist-info/licenses/AUTHORS.md +59 -0
- musica/mechanism_configuration.py +0 -1291
- musica-0.11.1.4.dist-info/RECORD +0 -33
- {musica-0.11.1.4.dist-info → musica-0.12.0.dist-info}/WHEEL +0 -0
- {musica-0.11.1.4.dist-info → musica-0.12.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
from typing import Optional, Any, Dict, List, Union, Tuple
|
|
2
|
+
from musica import _FirstOrderLoss, _ReactionComponent
|
|
3
|
+
from .phase import Phase
|
|
4
|
+
from .species import Species
|
|
5
|
+
from .reactions import ReactionComponentSerializer
|
|
6
|
+
from .utils import _add_other_properties, _remove_empty_keys
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class FirstOrderLoss(_FirstOrderLoss):
|
|
10
|
+
"""
|
|
11
|
+
A class representing a first-order loss reaction rate constant.
|
|
12
|
+
|
|
13
|
+
Attributes:
|
|
14
|
+
name (str): The name of the first-order loss reaction rate constant.
|
|
15
|
+
scaling_factor (float): The scaling factor for the first-order loss rate constant.
|
|
16
|
+
reactants (List[Union[Species, Tuple[float, Species]]]): A list of reactants involved in the reaction.
|
|
17
|
+
gas_phase (Phase): The gas phase in which the reaction occurs.
|
|
18
|
+
other_properties (Dict[str, Any]): A dictionary of other properties of the first-order loss reaction rate constant.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
def __init__(
|
|
22
|
+
self,
|
|
23
|
+
name: Optional[str] = None,
|
|
24
|
+
scaling_factor: Optional[float] = None,
|
|
25
|
+
reactants: Optional[List[Union[Species, Tuple[float, Species]]]] = None,
|
|
26
|
+
gas_phase: Optional[Phase] = None,
|
|
27
|
+
other_properties: Optional[Dict[str, Any]] = None,
|
|
28
|
+
):
|
|
29
|
+
"""
|
|
30
|
+
Initializes the FirstOrderLoss object with the given parameters.
|
|
31
|
+
|
|
32
|
+
Args:
|
|
33
|
+
name (str): The name of the first-order loss reaction rate constant.
|
|
34
|
+
scaling_factor (float): The scaling factor for the first-order loss rate constant.
|
|
35
|
+
reactants (List[Union[Species, Tuple[float, Species]]]): A list of reactants involved in the reaction.
|
|
36
|
+
gas_phase (Phase): The gas phase in which the reaction occurs.
|
|
37
|
+
other_properties (Dict[str, Any]): A dictionary of other properties of the first-order loss reaction rate constant.
|
|
38
|
+
"""
|
|
39
|
+
super().__init__()
|
|
40
|
+
self.name = name if name is not None else self.name
|
|
41
|
+
self.scaling_factor = scaling_factor if scaling_factor is not None else self.scaling_factor
|
|
42
|
+
self.reactants = (
|
|
43
|
+
[
|
|
44
|
+
(
|
|
45
|
+
_ReactionComponent(r.name)
|
|
46
|
+
if isinstance(r, Species)
|
|
47
|
+
else _ReactionComponent(r[1].name, r[0])
|
|
48
|
+
)
|
|
49
|
+
for r in reactants
|
|
50
|
+
]
|
|
51
|
+
if reactants is not None
|
|
52
|
+
else self.reactants
|
|
53
|
+
)
|
|
54
|
+
self.gas_phase = gas_phase.name if gas_phase is not None else self.gas_phase
|
|
55
|
+
self.other_properties = other_properties if other_properties is not None else self.other_properties
|
|
56
|
+
|
|
57
|
+
@staticmethod
|
|
58
|
+
def serialize(instance) -> Dict:
|
|
59
|
+
serialize_dict = {
|
|
60
|
+
"type": "FIRST_ORDER_LOSS",
|
|
61
|
+
"name": instance.name,
|
|
62
|
+
"scaling factor": instance.scaling_factor,
|
|
63
|
+
"reactants": ReactionComponentSerializer.serialize_list_reaction_components(instance.reactants),
|
|
64
|
+
"gas phase": instance.gas_phase,
|
|
65
|
+
}
|
|
66
|
+
_add_other_properties(serialize_dict, instance.other_properties)
|
|
67
|
+
return _remove_empty_keys(serialize_dict)
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
from typing import Optional, Any, Dict, Union, Tuple
|
|
2
|
+
from musica import _HenrysLaw, _ReactionComponent
|
|
3
|
+
from .phase import Phase
|
|
4
|
+
from .species import Species
|
|
5
|
+
from .utils import _add_other_properties, _remove_empty_keys
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class HenrysLaw(_HenrysLaw):
|
|
9
|
+
"""
|
|
10
|
+
A class representing a Henry's law reaction rate constant.
|
|
11
|
+
|
|
12
|
+
Attributes:
|
|
13
|
+
name (str): The name of the Henry's law reaction rate constant.
|
|
14
|
+
gas_phase (Phase): The gas phase in which the reaction occurs.
|
|
15
|
+
gas_phase_species (Union[Species, Tuple[float, Species]]): The gas phase species involved in the reaction.
|
|
16
|
+
aerosol_phase (Phase): The aerosol phase in which the reaction occurs.
|
|
17
|
+
aerosol_phase_water (Species): The water species in the aerosol phase.
|
|
18
|
+
aerosol_phase_species (Union[Species, Tuple[float, Species]]): The aerosol phase species involved in the reaction.
|
|
19
|
+
other_properties (Dict[str, Any]): A dictionary of other properties of the Henry's law reaction rate constant.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
def __init__(
|
|
23
|
+
self,
|
|
24
|
+
name: Optional[str] = None,
|
|
25
|
+
gas_phase: Optional[Phase] = None,
|
|
26
|
+
gas_phase_species: Optional[Union[Species, Tuple[float, Species]]] = None,
|
|
27
|
+
aerosol_phase: Optional[Phase] = None,
|
|
28
|
+
aerosol_phase_water: Optional[Species] = None,
|
|
29
|
+
aerosol_phase_species: Optional[Union[Species, Tuple[float, Species]]] = None,
|
|
30
|
+
other_properties: Optional[Dict[str, Any]] = None,
|
|
31
|
+
):
|
|
32
|
+
"""
|
|
33
|
+
Initializes the HenrysLaw object with the given parameters.
|
|
34
|
+
|
|
35
|
+
Args:
|
|
36
|
+
name (str): The name of the Henry's law reaction rate constant.
|
|
37
|
+
gas_phase (Phase): The gas phase in which the reaction occurs.
|
|
38
|
+
gas_phase_species (Union[Species, Tuple[float, Species]]): The gas phase species involved in the reaction.
|
|
39
|
+
aerosol_phase (Phase): The aerosol phase in which the reaction occurs.
|
|
40
|
+
aerosol_phase_water (Species): The water species in the aerosol phase.
|
|
41
|
+
aerosol_phase_species (Union[Species, Tuple[float, Species]]): The aerosol phase species involved in the reaction.
|
|
42
|
+
other_properties (Dict[str, Any]): A dictionary of other properties of the Henry's law reaction rate constant.
|
|
43
|
+
"""
|
|
44
|
+
super().__init__()
|
|
45
|
+
self.name = name if name is not None else self.name
|
|
46
|
+
self.gas_phase = gas_phase.name if gas_phase is not None else self.gas_phase
|
|
47
|
+
self.gas_phase_species = (
|
|
48
|
+
(
|
|
49
|
+
_ReactionComponent(gas_phase_species.name)
|
|
50
|
+
if isinstance(gas_phase_species, Species)
|
|
51
|
+
else _ReactionComponent(gas_phase_species[1].name, gas_phase_species[0])
|
|
52
|
+
)
|
|
53
|
+
if gas_phase_species is not None
|
|
54
|
+
else self.gas_phase_species
|
|
55
|
+
)
|
|
56
|
+
self.aerosol_phase = aerosol_phase.name if aerosol_phase is not None else self.aerosol_phase
|
|
57
|
+
self.aerosol_phase_water = (
|
|
58
|
+
aerosol_phase_water.name if aerosol_phase_water is not None else self.aerosol_phase_water
|
|
59
|
+
)
|
|
60
|
+
self.aerosol_phase_species = (
|
|
61
|
+
(
|
|
62
|
+
_ReactionComponent(aerosol_phase_species.name)
|
|
63
|
+
if isinstance(aerosol_phase_species, Species)
|
|
64
|
+
else _ReactionComponent(
|
|
65
|
+
aerosol_phase_species[1].name, aerosol_phase_species[0]
|
|
66
|
+
)
|
|
67
|
+
)
|
|
68
|
+
if aerosol_phase_species is not None
|
|
69
|
+
else self.aerosol_phase_species
|
|
70
|
+
)
|
|
71
|
+
self.other_properties = other_properties if other_properties is not None else self.other_properties
|
|
72
|
+
|
|
73
|
+
@staticmethod
|
|
74
|
+
def serialize(instance) -> Dict:
|
|
75
|
+
serialize_dict = {
|
|
76
|
+
"type": "HL_PHASE_TRANSFER",
|
|
77
|
+
"name": instance.name,
|
|
78
|
+
"gas phase": instance.gas_phase,
|
|
79
|
+
"gas-phase species": instance.gas_phase_species.species_name,
|
|
80
|
+
"aerosol phase": instance.aerosol_phase,
|
|
81
|
+
"aerosol-phase water": instance.aerosol_phase_water,
|
|
82
|
+
"aerosol-phase species": instance.aerosol_phase_species.species_name,
|
|
83
|
+
}
|
|
84
|
+
_add_other_properties(serialize_dict, instance.other_properties)
|
|
85
|
+
return _remove_empty_keys(serialize_dict)
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
# Copyright (C) 2025 University Corporation for Atmospheric Research
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
#
|
|
4
|
+
# This file is part of the musica Python package.
|
|
5
|
+
# For more information, see the LICENSE file in the top-level directory of this distribution.
|
|
6
|
+
import os
|
|
7
|
+
import json
|
|
8
|
+
import yaml
|
|
9
|
+
from typing import Optional, Any, Dict, List
|
|
10
|
+
from musica import _Mechanism, _Version, _Parser
|
|
11
|
+
from .species import Species
|
|
12
|
+
from .phase import Phase
|
|
13
|
+
from .arrhenius import Arrhenius, _Arrhenius
|
|
14
|
+
from .condensed_phase_arrhenius import CondensedPhaseArrhenius, _CondensedPhaseArrhenius
|
|
15
|
+
from .troe import Troe, _Troe
|
|
16
|
+
from .branched import Branched, _Branched
|
|
17
|
+
from .tunneling import Tunneling, _Tunneling
|
|
18
|
+
from .surface import Surface, _Surface
|
|
19
|
+
from .photolysis import Photolysis, _Photolysis
|
|
20
|
+
from .condensed_phase_photolysis import CondensedPhasePhotolysis, _CondensedPhasePhotolysis
|
|
21
|
+
from .emission import Emission, _Emission
|
|
22
|
+
from .first_order_loss import FirstOrderLoss, _FirstOrderLoss
|
|
23
|
+
from .aqueous_equilibrium import AqueousEquilibrium, _AqueousEquilibrium
|
|
24
|
+
from .wet_deposition import WetDeposition, _WetDeposition
|
|
25
|
+
from .henrys_law import HenrysLaw, _HenrysLaw
|
|
26
|
+
from .simpol_phase_transfer import SimpolPhaseTransfer, _SimpolPhaseTransfer
|
|
27
|
+
from .user_defined import UserDefined, _UserDefined
|
|
28
|
+
from .reactions import Reactions, ReactionType
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class Version(_Version):
|
|
32
|
+
"""
|
|
33
|
+
A class representing the version of the mechanism.
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class Mechanism(_Mechanism):
|
|
38
|
+
"""
|
|
39
|
+
A class representing a chemical mechanism.
|
|
40
|
+
|
|
41
|
+
Attributes:
|
|
42
|
+
name (str): The name of the mechanism.
|
|
43
|
+
reactions (List[Reaction]): A list of reactions in the mechanism.
|
|
44
|
+
species (List[Species]): A list of species in the mechanism.
|
|
45
|
+
phases (List[Phase]): A list of phases in the mechanism.
|
|
46
|
+
version (Version): The version of the mechanism.
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
def __init__(
|
|
50
|
+
self,
|
|
51
|
+
name: Optional[str] = None,
|
|
52
|
+
reactions: Optional[List[Any]] = None,
|
|
53
|
+
species: Optional[List[Species]] = None,
|
|
54
|
+
phases: Optional[List[Phase]] = None,
|
|
55
|
+
version: Optional[Version] = None,
|
|
56
|
+
):
|
|
57
|
+
"""
|
|
58
|
+
Initializes the Mechanism object with the given parameters.
|
|
59
|
+
|
|
60
|
+
Args:
|
|
61
|
+
name (str): The name of the mechanism.
|
|
62
|
+
reactions (List[]): A list of reactions in the mechanism.
|
|
63
|
+
species (List[Species]): A list of species in the mechanism.
|
|
64
|
+
phases (List[Phase]): A list of phases in the mechanism.
|
|
65
|
+
version (Version): The version of the mechanism.
|
|
66
|
+
"""
|
|
67
|
+
super().__init__()
|
|
68
|
+
self.name = name
|
|
69
|
+
self.species = species if species is not None else []
|
|
70
|
+
self.phases = phases if phases is not None else []
|
|
71
|
+
self.reactions = Reactions(reactions=reactions if reactions is not None else [])
|
|
72
|
+
self.version = version if version is not None else Version()
|
|
73
|
+
|
|
74
|
+
def to_dict(self) -> Dict:
|
|
75
|
+
species_list = []
|
|
76
|
+
for species in self.species:
|
|
77
|
+
species_list.append(Species.serialize(species))
|
|
78
|
+
|
|
79
|
+
phases_list = []
|
|
80
|
+
for phase in self.phases:
|
|
81
|
+
phases_list.append(Phase.serialize(phase))
|
|
82
|
+
|
|
83
|
+
reactions_list = []
|
|
84
|
+
for reaction in self.reactions:
|
|
85
|
+
if isinstance(reaction, (_Arrhenius, Arrhenius)):
|
|
86
|
+
reactions_list.append(Arrhenius.serialize(reaction))
|
|
87
|
+
elif isinstance(reaction, (_Branched, Branched)):
|
|
88
|
+
reactions_list.append(Branched.serialize(reaction))
|
|
89
|
+
elif isinstance(reaction, (_CondensedPhaseArrhenius, CondensedPhaseArrhenius)):
|
|
90
|
+
reactions_list.append(CondensedPhaseArrhenius.serialize(reaction))
|
|
91
|
+
elif isinstance(reaction, (_CondensedPhasePhotolysis, CondensedPhasePhotolysis)):
|
|
92
|
+
reactions_list.append(CondensedPhasePhotolysis.serialize(reaction))
|
|
93
|
+
elif isinstance(reaction, (_Emission, Emission)):
|
|
94
|
+
reactions_list.append(Emission.serialize(reaction))
|
|
95
|
+
elif isinstance(reaction, (_FirstOrderLoss, FirstOrderLoss)):
|
|
96
|
+
reactions_list.append(FirstOrderLoss.serialize(reaction))
|
|
97
|
+
elif isinstance(reaction, (_SimpolPhaseTransfer, SimpolPhaseTransfer)):
|
|
98
|
+
reactions_list.append(SimpolPhaseTransfer.serialize(reaction))
|
|
99
|
+
elif isinstance(reaction, (_AqueousEquilibrium, AqueousEquilibrium)):
|
|
100
|
+
reactions_list.append(AqueousEquilibrium.serialize(reaction))
|
|
101
|
+
elif isinstance(reaction, (_WetDeposition, WetDeposition)):
|
|
102
|
+
reactions_list.append(WetDeposition.serialize(reaction))
|
|
103
|
+
elif isinstance(reaction, (_HenrysLaw, HenrysLaw)):
|
|
104
|
+
reactions_list.append(HenrysLaw.serialize(reaction))
|
|
105
|
+
elif isinstance(reaction, (_Photolysis, Photolysis)):
|
|
106
|
+
reactions_list.append(Photolysis.serialize(reaction))
|
|
107
|
+
elif isinstance(reaction, (_Surface, Surface)):
|
|
108
|
+
reactions_list.append(Surface.serialize(reaction))
|
|
109
|
+
elif isinstance(reaction, (_Troe, Troe)):
|
|
110
|
+
reactions_list.append(Troe.serialize(reaction))
|
|
111
|
+
elif isinstance(reaction, (_Tunneling, Tunneling)):
|
|
112
|
+
reactions_list.append(Tunneling.serialize(reaction))
|
|
113
|
+
elif isinstance(reaction, (_UserDefined, UserDefined)):
|
|
114
|
+
reactions_list.append(UserDefined.serialize(reaction))
|
|
115
|
+
else:
|
|
116
|
+
raise TypeError(f'Reaction type {type(reaction)} is not supported for export.')
|
|
117
|
+
|
|
118
|
+
return {
|
|
119
|
+
"name": self.name,
|
|
120
|
+
"reactions": reactions_list,
|
|
121
|
+
"species": species_list,
|
|
122
|
+
"phases": phases_list,
|
|
123
|
+
"version": self.version.to_string(),
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
def export(self, file_path: str) -> None:
|
|
127
|
+
MechanismSerializer.serialize(self, file_path)
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
class Parser(_Parser):
|
|
131
|
+
"""
|
|
132
|
+
A class for parsing a chemical mechanism.
|
|
133
|
+
"""
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
class MechanismSerializer():
|
|
137
|
+
"""
|
|
138
|
+
A class for exporting a chemical mechanism.
|
|
139
|
+
"""
|
|
140
|
+
|
|
141
|
+
@staticmethod
|
|
142
|
+
def serialize(mechanism: Mechanism, file_path: str = "./mechanism.json") -> None:
|
|
143
|
+
if not isinstance(mechanism, Mechanism):
|
|
144
|
+
raise TypeError(f"Object {mechanism} is not of type Mechanism.")
|
|
145
|
+
|
|
146
|
+
directory, file = os.path.split(file_path)
|
|
147
|
+
if directory:
|
|
148
|
+
os.makedirs(directory, exist_ok=True)
|
|
149
|
+
dictionary = mechanism.to_dict()
|
|
150
|
+
|
|
151
|
+
_, file_ext = os.path.splitext(file)
|
|
152
|
+
file_ext = file_ext.lower()
|
|
153
|
+
if file_ext in ['.yaml', '.yml']:
|
|
154
|
+
with open(file_path, 'w') as file:
|
|
155
|
+
yaml.dump(dictionary, file)
|
|
156
|
+
elif '.json' == file_ext:
|
|
157
|
+
json_str = json.dumps(dictionary, indent=4)
|
|
158
|
+
with open(file_path, 'w') as file:
|
|
159
|
+
file.write(json_str)
|
|
160
|
+
else:
|
|
161
|
+
raise Exception('Allowable write formats are .json, .yaml, and .yml')
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
from typing import Optional, Any, Dict, List
|
|
2
|
+
from musica import _Phase
|
|
3
|
+
from .species import Species
|
|
4
|
+
from .utils import _add_other_properties, _remove_empty_keys
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Phase(_Phase):
|
|
8
|
+
"""
|
|
9
|
+
A class representing a phase in a chemical mechanism.
|
|
10
|
+
|
|
11
|
+
Attributes:
|
|
12
|
+
name (str): The name of the phase.
|
|
13
|
+
species (List[Species]): A list of species in the phase.
|
|
14
|
+
other_properties (Dict[str, Any]): A dictionary of other properties of the phase.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
def __init__(
|
|
18
|
+
self,
|
|
19
|
+
name: Optional[str] = None,
|
|
20
|
+
species: Optional[List[Species]] = None,
|
|
21
|
+
other_properties: Optional[Dict[str, Any]] = None,
|
|
22
|
+
):
|
|
23
|
+
"""
|
|
24
|
+
Initializes the Phase object with the given parameters.
|
|
25
|
+
|
|
26
|
+
Args:
|
|
27
|
+
name (str): The name of the phase.
|
|
28
|
+
species (List[Species]): A list of species in the phase.
|
|
29
|
+
other_properties (Dict[str, Any]): A dictionary of other properties of the phase.
|
|
30
|
+
"""
|
|
31
|
+
super().__init__()
|
|
32
|
+
self.name = name if name is not None else self.name
|
|
33
|
+
self.species = [s.name for s in species] if species is not None else self.species
|
|
34
|
+
self.other_properties = other_properties if other_properties is not None else self.other_properties
|
|
35
|
+
|
|
36
|
+
@staticmethod
|
|
37
|
+
def serialize(instance):
|
|
38
|
+
serialize_dict = {
|
|
39
|
+
"name": instance.name,
|
|
40
|
+
"species": instance.species,
|
|
41
|
+
}
|
|
42
|
+
_add_other_properties(serialize_dict, instance.other_properties)
|
|
43
|
+
return _remove_empty_keys(serialize_dict)
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
from typing import Optional, Any, Dict, List, Union, Tuple
|
|
2
|
+
from musica import _Photolysis, _ReactionComponent
|
|
3
|
+
from .phase import Phase
|
|
4
|
+
from .species import Species
|
|
5
|
+
from .reactions import ReactionComponentSerializer
|
|
6
|
+
from .utils import _add_other_properties, _remove_empty_keys
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class Photolysis(_Photolysis):
|
|
10
|
+
"""
|
|
11
|
+
A class representing a photolysis reaction rate constant.
|
|
12
|
+
|
|
13
|
+
Attributes:
|
|
14
|
+
name (str): The name of the photolysis reaction rate constant.
|
|
15
|
+
scaling_factor (float): The scaling factor for the photolysis rate constant.
|
|
16
|
+
reactants (List[Union[Species, Tuple[float, Species]]]): A list of reactants involved in the reaction.
|
|
17
|
+
products (List[Union[Species, Tuple[float, Species]]]): A list of products formed in the reaction.
|
|
18
|
+
gas_phase (Phase): The gas phase in which the reaction occurs.
|
|
19
|
+
other_properties (Dict[str, Any]): A dictionary of other properties of the photolysis reaction rate constant.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
def __init__(
|
|
23
|
+
self,
|
|
24
|
+
name: Optional[str] = None,
|
|
25
|
+
scaling_factor: Optional[float] = None,
|
|
26
|
+
reactants: Optional[List[Union[Species, Tuple[float, Species]]]] = None,
|
|
27
|
+
products: Optional[List[Union[Species, Tuple[float, Species]]]] = None,
|
|
28
|
+
gas_phase: Optional[Phase] = None,
|
|
29
|
+
other_properties: Optional[Dict[str, Any]] = None,
|
|
30
|
+
):
|
|
31
|
+
"""
|
|
32
|
+
Initializes the Photolysis object with the given parameters.
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
name (str): The name of the photolysis reaction rate constant.
|
|
36
|
+
scaling_factor (float): The scaling factor for the photolysis rate constant.
|
|
37
|
+
reactants (List[Union[Species, Tuple[float, Species]]]): A list of reactants involved in the reaction.
|
|
38
|
+
products (List[Union[Species, Tuple[float, Species]]]): A list of products formed in the reaction.
|
|
39
|
+
gas_phase (Phase): The gas phase in which the reaction occurs.
|
|
40
|
+
other_properties (Dict[str, Any]): A dictionary of other properties of the photolysis reaction rate constant.
|
|
41
|
+
"""
|
|
42
|
+
super().__init__()
|
|
43
|
+
self.name = name if name is not None else self.name
|
|
44
|
+
self.scaling_factor = scaling_factor if scaling_factor is not None else self.scaling_factor
|
|
45
|
+
self.reactants = (
|
|
46
|
+
[
|
|
47
|
+
(
|
|
48
|
+
_ReactionComponent(r.name)
|
|
49
|
+
if isinstance(r, Species)
|
|
50
|
+
else _ReactionComponent(r[1].name, r[0])
|
|
51
|
+
)
|
|
52
|
+
for r in reactants
|
|
53
|
+
]
|
|
54
|
+
if reactants is not None
|
|
55
|
+
else self.reactants
|
|
56
|
+
)
|
|
57
|
+
self.products = (
|
|
58
|
+
[
|
|
59
|
+
(
|
|
60
|
+
_ReactionComponent(p.name)
|
|
61
|
+
if isinstance(p, Species)
|
|
62
|
+
else _ReactionComponent(p[1].name, p[0])
|
|
63
|
+
)
|
|
64
|
+
for p in products
|
|
65
|
+
]
|
|
66
|
+
if products is not None
|
|
67
|
+
else self.products
|
|
68
|
+
)
|
|
69
|
+
self.gas_phase = gas_phase.name if gas_phase is not None else self.gas_phase
|
|
70
|
+
self.other_properties = other_properties if other_properties is not None else self.other_properties
|
|
71
|
+
|
|
72
|
+
@staticmethod
|
|
73
|
+
def serialize(instance) -> Dict:
|
|
74
|
+
serialize_dict = {
|
|
75
|
+
"type": "PHOTOLYSIS",
|
|
76
|
+
"name": instance.name,
|
|
77
|
+
"scaling factor": instance.scaling_factor,
|
|
78
|
+
"reactants": ReactionComponentSerializer.serialize_list_reaction_components(instance.reactants),
|
|
79
|
+
"products": ReactionComponentSerializer.serialize_list_reaction_components(instance.products),
|
|
80
|
+
"gas phase": instance.gas_phase,
|
|
81
|
+
}
|
|
82
|
+
_add_other_properties(serialize_dict, instance.other_properties)
|
|
83
|
+
return _remove_empty_keys(serialize_dict)
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
from typing import Optional, Any, Dict, List, Union
|
|
2
|
+
from musica import _ReactionType, _Reactions, _ReactionsIterator
|
|
3
|
+
from .species import Species, _Species
|
|
4
|
+
from .utils import _remove_empty_keys
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class ReactionType(_ReactionType):
|
|
8
|
+
"""
|
|
9
|
+
A enum class representing a reaction type in a chemical mechanism.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class Reactions(_Reactions):
|
|
14
|
+
"""
|
|
15
|
+
A class representing a collection of reactions in a chemical mechanism.
|
|
16
|
+
|
|
17
|
+
Attributes:
|
|
18
|
+
reactions (List[Any]): A list of reactions in the mechanism.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
def __init__(
|
|
22
|
+
self,
|
|
23
|
+
reactions: Optional[List[Any]] = None,
|
|
24
|
+
):
|
|
25
|
+
"""
|
|
26
|
+
Initializes the Reactions object with the given parameters.
|
|
27
|
+
|
|
28
|
+
Args:
|
|
29
|
+
reactions (List[]): A list of reactions in the mechanism.
|
|
30
|
+
"""
|
|
31
|
+
super().__init__(reactions)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class ReactionsIterator(_ReactionsIterator):
|
|
35
|
+
"""
|
|
36
|
+
An iterator for the Reactions class.
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class ReactionComponentSerializer():
|
|
41
|
+
"""
|
|
42
|
+
A class for serializing reaction components.
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
@staticmethod
|
|
46
|
+
def serialize_reaction_component(rc) -> Union[Dict, str]:
|
|
47
|
+
if isinstance(rc, Species) or isinstance(rc, _Species):
|
|
48
|
+
return rc.name
|
|
49
|
+
|
|
50
|
+
return _remove_empty_keys({
|
|
51
|
+
"species name": rc.species_name,
|
|
52
|
+
"coefficient": rc.coefficient,
|
|
53
|
+
"other_properties": rc.other_properties,
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
@staticmethod
|
|
57
|
+
def serialize_list_reaction_components(reaction_component_list) -> List[Union[Dict, str]]:
|
|
58
|
+
ret = []
|
|
59
|
+
for rc in reaction_component_list:
|
|
60
|
+
ret.append(ReactionComponentSerializer.serialize_reaction_component(rc))
|
|
61
|
+
return ret
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
from typing import Optional, Any, Dict, List, Union, Tuple
|
|
2
|
+
from musica import _SimpolPhaseTransfer, _ReactionComponent
|
|
3
|
+
from .phase import Phase
|
|
4
|
+
from .species import Species
|
|
5
|
+
from .utils import _add_other_properties, _remove_empty_keys
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class SimpolPhaseTransfer(_SimpolPhaseTransfer):
|
|
9
|
+
"""
|
|
10
|
+
A class representing a simplified phase transfer reaction rate constant.
|
|
11
|
+
|
|
12
|
+
Attributes:
|
|
13
|
+
name (str): The name of the simplified phase transfer reaction rate constant.
|
|
14
|
+
gas_phase (Phase): The gas phase in which the reaction occurs.
|
|
15
|
+
gas_phase_species (Union[Species, Tuple[float, Species]]): The gas phase species involved in the reaction.
|
|
16
|
+
aerosol_phase (Phase): The aerosol phase in which the reaction occurs.
|
|
17
|
+
aerosol_phase_species (Union[Species, Tuple[float, Species]]): The aerosol phase species involved in the reaction.
|
|
18
|
+
B (List[float]): The B parameters [unitless].
|
|
19
|
+
unknown_properties (Dict[str, Any]): A dictionary of other properties of the simplified phase transfer reaction rate constant.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
def __init__(
|
|
23
|
+
self,
|
|
24
|
+
name: Optional[str] = None,
|
|
25
|
+
gas_phase: Optional[Phase] = None,
|
|
26
|
+
gas_phase_species: Optional[Union[Species, Tuple[float, Species]]] = None,
|
|
27
|
+
aerosol_phase: Optional[Phase] = None,
|
|
28
|
+
aerosol_phase_species: Optional[Union[Species, Tuple[float, Species]]] = None,
|
|
29
|
+
B: Optional[List[float]] = None,
|
|
30
|
+
other_properties: Optional[Dict[str, Any]] = None,
|
|
31
|
+
):
|
|
32
|
+
"""
|
|
33
|
+
Initializes the SimpolPhaseTransfer object with the given parameters.
|
|
34
|
+
|
|
35
|
+
Args:
|
|
36
|
+
name (str): The name of the simplified phase transfer reaction rate constant.
|
|
37
|
+
gas_phase (Phase): The gas phase in which the reaction occurs.
|
|
38
|
+
gas_phase_species (Union[Species, Tuple[float, Species]]): The gas phase species involved in the reaction.
|
|
39
|
+
aerosol_phase (Phase): The aerosol phase in which the reaction occurs.
|
|
40
|
+
aerosol_phase_species (Union[Species, Tuple[float, Species]]): The aerosol phase species involved in the reaction.
|
|
41
|
+
B (List[float]): The B parameters [unitless].
|
|
42
|
+
other_properties (Dict[str, Any]): A dictionary of other properties of the simplified phase transfer reaction rate constant.
|
|
43
|
+
"""
|
|
44
|
+
super().__init__()
|
|
45
|
+
self.name = name if name is not None else self.name
|
|
46
|
+
self.gas_phase = gas_phase.name if gas_phase is not None else self.gas_phase
|
|
47
|
+
self.gas_phase_species = (
|
|
48
|
+
(
|
|
49
|
+
_ReactionComponent(gas_phase_species.name)
|
|
50
|
+
if isinstance(gas_phase_species, Species)
|
|
51
|
+
else _ReactionComponent(gas_phase_species[1].name, gas_phase_species[0])
|
|
52
|
+
)
|
|
53
|
+
if gas_phase_species is not None
|
|
54
|
+
else self.gas_phase_species
|
|
55
|
+
)
|
|
56
|
+
self.aerosol_phase = aerosol_phase.name if aerosol_phase is not None else self.aerosol_phase
|
|
57
|
+
self.aerosol_phase_species = (
|
|
58
|
+
(
|
|
59
|
+
_ReactionComponent(aerosol_phase_species.name)
|
|
60
|
+
if isinstance(aerosol_phase_species, Species)
|
|
61
|
+
else _ReactionComponent(
|
|
62
|
+
aerosol_phase_species[1].name, aerosol_phase_species[0]
|
|
63
|
+
)
|
|
64
|
+
)
|
|
65
|
+
if aerosol_phase_species is not None
|
|
66
|
+
else self.aerosol_phase_species
|
|
67
|
+
)
|
|
68
|
+
if B is not None:
|
|
69
|
+
if len(B) != 4:
|
|
70
|
+
raise ValueError("B must be a list of 4 elements.")
|
|
71
|
+
self.B = B
|
|
72
|
+
else:
|
|
73
|
+
self.B = [0, 0, 0, 0]
|
|
74
|
+
self.other_properties = other_properties if other_properties is not None else self.other_properties
|
|
75
|
+
|
|
76
|
+
@staticmethod
|
|
77
|
+
def serialize(instance) -> Dict:
|
|
78
|
+
serialize_dict = {
|
|
79
|
+
"type": "SIMPOL_PHASE_TRANSFER",
|
|
80
|
+
"name": instance.name,
|
|
81
|
+
"gas phase": instance.gas_phase,
|
|
82
|
+
"gas-phase species": instance.gas_phase_species.species_name,
|
|
83
|
+
"aerosol phase": instance.aerosol_phase,
|
|
84
|
+
"aerosol-phase species": instance.aerosol_phase_species.species_name,
|
|
85
|
+
"B": instance.B,
|
|
86
|
+
}
|
|
87
|
+
_add_other_properties(serialize_dict, instance.other_properties)
|
|
88
|
+
return _remove_empty_keys(serialize_dict)
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
from typing import Optional, Any, Dict
|
|
2
|
+
from musica import _Species
|
|
3
|
+
from .utils import _add_other_properties, _remove_empty_keys
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Species(_Species):
|
|
7
|
+
"""
|
|
8
|
+
A class representing a species in a chemical mechanism.
|
|
9
|
+
|
|
10
|
+
Attributes:
|
|
11
|
+
name (str): The name of the species.
|
|
12
|
+
HLC_298K_mol_m3_Pa (float): Henry's Law Constant at 298K [mol m-3 Pa-1]
|
|
13
|
+
HLC_exponential_factor_K: Henry's Law Constant exponential factor [K]
|
|
14
|
+
diffusion_coefficient_m2_s (float): Diffusion coefficient [m2 s-1]
|
|
15
|
+
N_star (float): A parameter used to calculate the mass accomodation factor (Ervens et al., 2003)
|
|
16
|
+
molecular_weight_kg_mol (float): Molecular weight [kg mol-1]
|
|
17
|
+
density_kg_m3 (float): Density [kg m-3]
|
|
18
|
+
tracer_type (str): The type of tracer ("AEROSOL", "THIRD_BODY", "CONSTANT").
|
|
19
|
+
other_properties (Dict[str, Any]): A dictionary of other properties of the species.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
def __init__(
|
|
23
|
+
self,
|
|
24
|
+
name: Optional[str] = None,
|
|
25
|
+
HLC_298K_mol_m3_Pa: Optional[float] = None,
|
|
26
|
+
HLC_exponential_factor_K: Optional[float] = None,
|
|
27
|
+
diffusion_coefficient_m2_s: Optional[float] = None,
|
|
28
|
+
N_star: Optional[float] = None,
|
|
29
|
+
molecular_weight_kg_mol: Optional[float] = None,
|
|
30
|
+
density_kg_m3: Optional[float] = None,
|
|
31
|
+
tracer_type: Optional[str] = None,
|
|
32
|
+
other_properties: Optional[Dict[str, Any]] = None,
|
|
33
|
+
):
|
|
34
|
+
"""
|
|
35
|
+
Initializes the Species object with the given parameters.
|
|
36
|
+
|
|
37
|
+
Args:
|
|
38
|
+
name (str): The name of the species.
|
|
39
|
+
HLC_298K_mol_m3_Pa (float): Henry's Law Constant at 298K [mol m-3 Pa-1]
|
|
40
|
+
HLC_exponential_factor_K: Henry's Law Constant exponential factor [K]
|
|
41
|
+
diffusion_coefficient_m2_s (float): Diffusion coefficient [m2 s-1]
|
|
42
|
+
N_star (float): A parameter used to calculate the mass accomodation factor (Ervens et al., 2003)
|
|
43
|
+
molecular_weight_kg_mol (float): Molecular weight [kg mol-1]
|
|
44
|
+
density_kg_m3 (float): Density [kg m-3]
|
|
45
|
+
tracer_type (str): The type of tracer ("AEROSOL", "THIRD_BODY", "CONSTANT").
|
|
46
|
+
other_properties (Dict[str, Any]): A dictionary of other properties of the species.
|
|
47
|
+
"""
|
|
48
|
+
super().__init__()
|
|
49
|
+
self.name = name if name is not None else self.name
|
|
50
|
+
self.HLC_298K_mol_m3_Pa = HLC_298K_mol_m3_Pa if HLC_298K_mol_m3_Pa is not None else self.HLC_298K_mol_m3_Pa
|
|
51
|
+
self.HLC_exponential_factor_K = HLC_exponential_factor_K if HLC_exponential_factor_K is not None else self.HLC_exponential_factor_K
|
|
52
|
+
self.diffusion_coefficient_m2_s = diffusion_coefficient_m2_s if diffusion_coefficient_m2_s is not None else self.diffusion_coefficient_m2_s
|
|
53
|
+
self.N_star = N_star if N_star is not None else self.N_star
|
|
54
|
+
self.molecular_weight_kg_mol = molecular_weight_kg_mol if molecular_weight_kg_mol is not None else self.molecular_weight_kg_mol
|
|
55
|
+
self.density_kg_m3 = density_kg_m3 if density_kg_m3 is not None else self.density_kg_m3
|
|
56
|
+
self.tracer_type = tracer_type if tracer_type is not None else self.tracer_type
|
|
57
|
+
self.other_properties = other_properties if other_properties is not None else self.other_properties
|
|
58
|
+
|
|
59
|
+
@staticmethod
|
|
60
|
+
def serialize(instance) -> Dict:
|
|
61
|
+
serialize_dict = {
|
|
62
|
+
"name": instance.name,
|
|
63
|
+
"HLC(298K) [mol m-3 Pa-1]": instance.HLC_298K_mol_m3_Pa,
|
|
64
|
+
"HLC exponential factor [K]": instance.HLC_exponential_factor_K,
|
|
65
|
+
"diffusion coefficient [m2 s-1]": instance.diffusion_coefficient_m2_s,
|
|
66
|
+
"N star": instance.N_star,
|
|
67
|
+
"molecular weight [kg mol-1]": instance.molecular_weight_kg_mol,
|
|
68
|
+
"density [kg m-3]": instance.density_kg_m3,
|
|
69
|
+
"tracer type": instance.tracer_type,
|
|
70
|
+
}
|
|
71
|
+
_add_other_properties(serialize_dict, instance.other_properties)
|
|
72
|
+
return _remove_empty_keys(serialize_dict)
|