pyKES 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.
Files changed (37) hide show
  1. pykes-0.1.6/PKG-INFO +57 -0
  2. pykes-0.1.6/README.md +26 -0
  3. pykes-0.1.6/pyproject.toml +51 -0
  4. pykes-0.1.6/src/pyKES/__init__.py +0 -0
  5. pykes-0.1.6/src/pyKES/database/__init__.py +0 -0
  6. pykes-0.1.6/src/pyKES/database/data_processing.py +218 -0
  7. pykes-0.1.6/src/pyKES/database/database_experiments.py +541 -0
  8. pykes-0.1.6/src/pyKES/fitting_ODE.py +613 -0
  9. pykes-0.1.6/src/pyKES/pathways/__init__.py +0 -0
  10. pykes-0.1.6/src/pyKES/pathways/pathways.py +509 -0
  11. pykes-0.1.6/src/pyKES/pathways/transform_pathways_data.py +680 -0
  12. pykes-0.1.6/src/pyKES/plotting/__init__.py +0 -0
  13. pykes-0.1.6/src/pyKES/plotting/lighten_colors.py +26 -0
  14. pykes-0.1.6/src/pyKES/plotting/plotting_pathways_transformed.py +283 -0
  15. pykes-0.1.6/src/pyKES/plotting/plotting_tools.py +560 -0
  16. pykes-0.1.6/src/pyKES/reaction_ODE.py +504 -0
  17. pykes-0.1.6/src/pyKES/reaction_model.py +321 -0
  18. pykes-0.1.6/src/pyKES/streamlit_app/components/__init__.py +38 -0
  19. pykes-0.1.6/src/pyKES/streamlit_app/components/analysis_results_component.py +1294 -0
  20. pykes-0.1.6/src/pyKES/streamlit_app/components/data_upload_component.py +310 -0
  21. pykes-0.1.6/src/pyKES/streamlit_app/components/home_component.py +91 -0
  22. pykes-0.1.6/src/pyKES/streamlit_app/components/results_table_component.py +539 -0
  23. pykes-0.1.6/src/pyKES/streamlit_app/components/time_series_component.py +303 -0
  24. pykes-0.1.6/src/pyKES/streamlit_app/config_interface.py +241 -0
  25. pykes-0.1.6/src/pyKES/utilities/__init__.py +0 -0
  26. pykes-0.1.6/src/pyKES/utilities/calculate_absorption.py +481 -0
  27. pykes-0.1.6/src/pyKES/utilities/find_nearest.py +40 -0
  28. pykes-0.1.6/src/pyKES/utilities/get_experiments.py +51 -0
  29. pykes-0.1.6/src/pyKES/utilities/harmonize_time_series.py +64 -0
  30. pykes-0.1.6/src/pyKES/utilities/make_json_serializable.py +19 -0
  31. pykes-0.1.6/src/pyKES/utilities/max_rate.py +1102 -0
  32. pykes-0.1.6/src/pyKES/utilities/offset_correction.py +22 -0
  33. pykes-0.1.6/src/pyKES/utilities/resolve_attributes.py +170 -0
  34. pykes-0.1.6/src/pyKES/utilities/time_series_resampling.py +35 -0
  35. pykes-0.1.6/src/pyKES/utilities/unit_handler/__init__.py +8 -0
  36. pykes-0.1.6/src/pyKES/utilities/unit_handler/config.py +244 -0
  37. pykes-0.1.6/src/pyKES/utilities/unit_handler/quantity.py +503 -0
pykes-0.1.6/PKG-INFO ADDED
@@ -0,0 +1,57 @@
1
+ Metadata-Version: 2.4
2
+ Name: pyKES
3
+ Version: 0.1.6
4
+ Summary: Python package for kinetic modelling of chemical reaction networks.
5
+ Keywords: kinetics,photocatalysis,water-splitting,reaction-networks,ode
6
+ Author: Jacob Schneidewind
7
+ Author-email: Jacob Schneidewind <pyH2A.pypi@gmail.com>
8
+ License-Expression: MIT
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Intended Audience :: Science/Research
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.8
13
+ Classifier: Programming Language :: Python :: 3.9
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Topic :: Scientific/Engineering :: Chemistry
18
+ Requires-Dist: streamlit
19
+ Requires-Dist: pandas
20
+ Requires-Dist: numpy
21
+ Requires-Dist: plotly
22
+ Requires-Dist: matplotlib
23
+ Requires-Dist: scipy
24
+ Requires-Dist: h5py
25
+ Requires-Dist: openpyxl
26
+ Requires-Python: >=3.8
27
+ Project-URL: Homepage, https://github.com/jschneidewind/pyKES
28
+ Project-URL: Bug Tracker, https://github.com/jschneidewind/pyKES/issues
29
+ Project-URL: Source, https://github.com/jschneidewind/pyKES
30
+ Description-Content-Type: text/markdown
31
+
32
+ # pyKES
33
+
34
+ Working locally with pyKES:
35
+
36
+ In other repo running
37
+ pip install -e /Users/jacob/Documents/Water_Splitting/Projects/pyKES/pyKES
38
+
39
+ Adding .vscode/setting.json file with
40
+
41
+ {
42
+ "python.analysis.extraPaths": [
43
+ "/Users/jacob/Documents/Water_Splitting/Projects/pyKES/pyKES/src"
44
+ ],
45
+ "python.autoComplete.extraPaths": [
46
+ "/Users/jacob/Documents/Water_Splitting/Projects/pyKES/pyKES/src"
47
+ ]
48
+ }
49
+
50
+
51
+ ## Contributing
52
+
53
+ Contributions are welcome. Please open an issue or submit a pull request.
54
+
55
+ ## License
56
+
57
+ This project is licensed under the MIT License. See [LICENSE](LICENSE).
pykes-0.1.6/README.md ADDED
@@ -0,0 +1,26 @@
1
+ # pyKES
2
+
3
+ Working locally with pyKES:
4
+
5
+ In other repo running
6
+ pip install -e /Users/jacob/Documents/Water_Splitting/Projects/pyKES/pyKES
7
+
8
+ Adding .vscode/setting.json file with
9
+
10
+ {
11
+ "python.analysis.extraPaths": [
12
+ "/Users/jacob/Documents/Water_Splitting/Projects/pyKES/pyKES/src"
13
+ ],
14
+ "python.autoComplete.extraPaths": [
15
+ "/Users/jacob/Documents/Water_Splitting/Projects/pyKES/pyKES/src"
16
+ ]
17
+ }
18
+
19
+
20
+ ## Contributing
21
+
22
+ Contributions are welcome. Please open an issue or submit a pull request.
23
+
24
+ ## License
25
+
26
+ This project is licensed under the MIT License. See [LICENSE](LICENSE).
@@ -0,0 +1,51 @@
1
+ [build-system]
2
+ requires = ["uv_build>=0.11.13,<0.12"]
3
+ build-backend = "uv_build"
4
+
5
+ [project]
6
+ name = "pyKES"
7
+ version = "0.1.6"
8
+ description = "Python package for kinetic modelling of chemical reaction networks."
9
+ keywords = ["kinetics", "photocatalysis", "water-splitting", "reaction-networks", "ode"]
10
+ authors = [
11
+ {name = "Jacob Schneidewind", email = "pyH2A.pypi@gmail.com"},
12
+ ]
13
+ license = "MIT"
14
+ readme = "README.md"
15
+ requires-python = ">=3.8"
16
+ classifiers = [
17
+ "Development Status :: 3 - Alpha",
18
+ "Intended Audience :: Science/Research",
19
+ "Programming Language :: Python :: 3",
20
+ "Programming Language :: Python :: 3.8",
21
+ "Programming Language :: Python :: 3.9",
22
+ "Programming Language :: Python :: 3.10",
23
+ "Programming Language :: Python :: 3.11",
24
+ "Programming Language :: Python :: 3.12",
25
+ "Topic :: Scientific/Engineering :: Chemistry",
26
+ ]
27
+ dependencies = [
28
+ "streamlit",
29
+ "pandas",
30
+ "numpy",
31
+ "plotly",
32
+ "matplotlib",
33
+ "scipy",
34
+ "h5py",
35
+ "openpyxl",
36
+ ]
37
+
38
+ [project.urls]
39
+ "Homepage" = "https://github.com/jschneidewind/pyKES"
40
+ "Bug Tracker" = "https://github.com/jschneidewind/pyKES/issues"
41
+ "Source" = "https://github.com/jschneidewind/pyKES"
42
+
43
+ [tool.setuptools]
44
+ package-dir = {"" = "src"}
45
+
46
+ [tool.setuptools.packages.find]
47
+ where = ["src"]
48
+ include = ["pyKES*"]
49
+
50
+ [tool.uv.build-backend]
51
+ module-name = "pyKES"
File without changes
File without changes
@@ -0,0 +1,218 @@
1
+ import os
2
+ from concurrent.futures import ProcessPoolExecutor
3
+ import multiprocessing
4
+ from functools import partial
5
+ import traceback
6
+ from typing import Optional
7
+ from pathlib import Path
8
+
9
+ from pyKES.database.database_experiments import ExperimentalDataset, Experiment
10
+
11
+ def generate_list_of_files(keywords, directory):
12
+
13
+ files = [
14
+ os.path.join(directory, file)
15
+ for file in os.listdir(directory)
16
+ if any(keyword in file for keyword in keywords)
17
+ and not file.startswith('~$')
18
+ ]
19
+
20
+ return files
21
+
22
+ def read_in_single_experiment(file_name: str,
23
+ database: ExperimentalDataset,
24
+ metadata_retrival_function: callable,
25
+ raw_data_reading_function: callable,
26
+ processing_function: callable,
27
+ directory: Optional[Path] = None,
28
+ legacy_mode = True):
29
+ """
30
+ Legacy mode is for use with file-based processing and use in multi-processing mode.
31
+
32
+ Non-legacy mode is for use with overview_df-based processing in single-threaded mode,
33
+ where the file name is not necessarily the key to retrieve metadata and raw data.
34
+ In this case, the file name is used as an argument to the metadata retrieval function,
35
+ which then retrieves the necessary metadata and file paths for raw data reading and processing.
36
+
37
+
38
+ """
39
+
40
+ try:
41
+ if legacy_mode:
42
+ metadata_dict = metadata_retrival_function(file_name, database.overview_df)
43
+ raw_data_dict = raw_data_reading_function(file_name, metadata_dict)
44
+ processed_data_dict = processing_function(raw_data_dict, metadata_dict)
45
+
46
+ else:
47
+ metadata_dict = metadata_retrival_function(file_name, database.overview_df)
48
+ raw_data_dict = raw_data_reading_function(directory, metadata_dict)
49
+ processed_data_dict = processing_function(raw_data_dict, metadata_dict)
50
+
51
+ experiment = Experiment(
52
+ experiment_name = metadata_dict['experiment_name'],
53
+ raw_data_file = file_name,
54
+ color = metadata_dict.get('color', 'black'),
55
+ group = metadata_dict.get('group', 'default'),
56
+ metadata = metadata_dict,
57
+ raw_data = raw_data_dict,
58
+ processed_data = processed_data_dict
59
+ )
60
+
61
+ return {
62
+ 'success': True,
63
+ 'data': experiment
64
+ }
65
+
66
+ except Exception as e:
67
+ tb = traceback.format_exc()
68
+ print(f'{file_name} analysis failed, not added to dataset, error: {str(e)}')
69
+ print("Full traceback:")
70
+ print(tb)
71
+
72
+ return {
73
+ 'success': False,
74
+ 'file': file_name,
75
+ 'error': f"{str(e)}\n\nFull traceback:\n{tb}"
76
+ }
77
+
78
+
79
+ def read_in_experiments_single_threaded(database: ExperimentalDataset,
80
+ metadata_retrival_function: callable,
81
+ raw_data_reading_function: callable,
82
+ processing_function: callable,
83
+ overview_df_experiment_column: Optional[str] = 'Experiment',
84
+ directory: Optional[Path] = None):
85
+ """
86
+
87
+ """
88
+
89
+ if "Processed" not in database.overview_df.columns:
90
+ database.overview_df["Processed"] = False
91
+
92
+ # Returning only the experiments which have not been processed
93
+ # Do not contain "Processed" column or "Processed" is not True
94
+ # also returns experiments which are not in the database.experiments dict,
95
+
96
+ mask = (
97
+ database.overview_df["Processed"].ne('True')
98
+ | ~database.overview_df[overview_df_experiment_column].isin(database.experiments))
99
+
100
+ experiments = database.overview_df.loc[mask,
101
+ overview_df_experiment_column].astype(str).tolist()
102
+
103
+ results = []
104
+
105
+ for experiment_name in experiments:
106
+
107
+ result = read_in_single_experiment(
108
+ file_name = experiment_name,
109
+ database = database,
110
+ metadata_retrival_function = metadata_retrival_function,
111
+ raw_data_reading_function = raw_data_reading_function,
112
+ processing_function = processing_function,
113
+ directory = directory,
114
+ legacy_mode = False
115
+ )
116
+
117
+ results.append(result)
118
+
119
+ if result['success']:
120
+ # Add experiment to database
121
+ database.add_experiment(result['data'])
122
+
123
+ # Setting "Processed" to True in dataframe
124
+ database.overview_df.loc[
125
+ database.overview_df[overview_df_experiment_column].eq(result['data'].experiment_name),
126
+ "Processed",
127
+ ] = 'True'
128
+
129
+ else:
130
+ print(f"Failed to process {result['file']}: {result['error']}")
131
+
132
+ return results
133
+
134
+
135
+ def read_in_experiments_multiprocessing(database: ExperimentalDataset,
136
+ metadata_retrival_function: callable,
137
+ raw_data_reading_function: callable,
138
+ processing_function: callable,
139
+ keywords: Optional[list] = None,
140
+ directory: Optional[str] = None,
141
+ overview_df_based_processing: Optional[bool] = False,
142
+ overview_df_experiment_column: Optional[str] = 'Experiment'):
143
+ """
144
+
145
+ """
146
+
147
+ if overview_df_based_processing:
148
+ files = database.overview_df[overview_df_experiment_column].tolist()
149
+ else:
150
+ files = generate_list_of_files(keywords, directory)
151
+
152
+ read_in_single_experiment_partial = partial(read_in_single_experiment,
153
+ database = database,
154
+ metadata_retrival_function = metadata_retrival_function,
155
+ raw_data_reading_function = raw_data_reading_function,
156
+ processing_function = processing_function)
157
+
158
+ with ProcessPoolExecutor(max_workers=multiprocessing.cpu_count()) as executor:
159
+ results = list(executor.map(read_in_single_experiment_partial, files))
160
+
161
+ for result in results:
162
+ if result['success']:
163
+ database.add_experiment(result['data'])
164
+ else:
165
+ print(f"Failed to process {result['file']}: {result['error']}")
166
+
167
+ return results
168
+
169
+
170
+ def testing():
171
+
172
+ from tests.data.processing_functions_overview_df import (metadata_retrival_function,
173
+ raw_data_reading_function,
174
+ processing_function)
175
+ from tests.data.processing_parameters import PROCESSING_PARAMETERS, GROUP_MAPPING, PLOTTING_INSTRUCTIONS
176
+
177
+ import pandas as pd
178
+ import pprint as pp
179
+
180
+ overview_df = pd.read_excel(
181
+ '/Users/jacob/Documents/Water_Splitting/Projects/pyKES/pyKES/src/tests/data/251204_O2_H2_Experiment_Overview.xlsx',
182
+ sheet_name='Sheet1',
183
+ dtype={'active': str,
184
+ 'D2O': str,
185
+ 'Processed': str} # Force 'active' and 'D2O' columns to be read as strings
186
+ )
187
+
188
+ dataset = ExperimentalDataset(
189
+ overview_df = overview_df,
190
+ group_mapping = GROUP_MAPPING,
191
+ plotting_instruction = PLOTTING_INSTRUCTIONS,
192
+ processing_parameters = PROCESSING_PARAMETERS
193
+ )
194
+
195
+ read_in_experiments_single_threaded(
196
+ database = dataset,
197
+ metadata_retrival_function = metadata_retrival_function,
198
+ raw_data_reading_function = raw_data_reading_function,
199
+ processing_function = processing_function,
200
+ overview_df_experiment_column = 'Experiment',
201
+ directory = Path('/Users/jacob/Documents/Water_Splitting/Projects/pyKES/pyKES/src/tests/data/data_files')
202
+ )
203
+
204
+ pp.pprint(dataset.experiments['NB-316'])
205
+
206
+
207
+
208
+
209
+
210
+
211
+
212
+
213
+
214
+
215
+
216
+
217
+ if __name__ == '__main__':
218
+ testing()