|
4 | 4 | import sys |
5 | 5 | import uuid |
6 | 6 | import zipfile |
7 | | -from datetime import datetime |
8 | 7 | from io import StringIO, BytesIO |
9 | 8 | from typing import Any |
10 | 9 |
|
@@ -195,8 +194,9 @@ def _action_debug(self): |
195 | 194 | print(df_rfu) |
196 | 195 |
|
197 | 196 | def _action_test(self): |
198 | | - pdbe_view = self.views["protein"] |
199 | | - pdbe_view.pdbe.test = not pdbe_view.pdbe.test |
| 197 | + src = self.sources['metadata'] |
| 198 | + d = src.get('user_settings') |
| 199 | + print(d) |
200 | 200 |
|
201 | 201 | @property |
202 | 202 | def _layout(self): |
@@ -265,7 +265,7 @@ def make_dict(self): |
265 | 265 |
|
266 | 266 | def config_download_callback(self) -> StringIO: |
267 | 267 | # Generate and set filename |
268 | | - timestamp = datetime.now().strftime("%Y%m%d%H%M") |
| 268 | + timestamp = self.parent.session_time.strftime("%Y%m%d%H%M") |
269 | 269 | self.widgets[ |
270 | 270 | "config_download" |
271 | 271 | ].filename = f"PyHDX_config_{timestamp}.yaml" |
@@ -400,15 +400,12 @@ def _action_load_datasets(self) -> None: |
400 | 400 | ) |
401 | 401 |
|
402 | 402 | def spec_download_callback(self) -> StringIO: |
403 | | - timestamp = datetime.now().strftime("%Y%m%d%H%M") |
| 403 | + timestamp = self.parent.session_time.strftime("%Y%m%d%H%M") |
404 | 404 | self.widgets[ |
405 | 405 | "download_spec_button" |
406 | 406 | ].filename = f"PyHDX_state_spec_{timestamp}.yaml" |
407 | 407 |
|
408 | | - s = yaml.dump(clean_types(self.state_spec), sort_keys=False) |
409 | | - output = "# " + pyhdx.VERSION_STRING + "\n" + s |
410 | | - sio = StringIO(output) |
411 | | - |
| 408 | + sio = self.parent.state_spec_callback() |
412 | 409 | return sio |
413 | 410 |
|
414 | 411 | @property |
@@ -1119,8 +1116,19 @@ def _action_fit(self): |
1119 | 1116 | self.param["do_fit"].constant = True |
1120 | 1117 | self.widgets["do_fit"].loading = True |
1121 | 1118 |
|
| 1119 | + user_dict = self.sources['metadata'].get('user_settings') |
| 1120 | + user_dict['d_uptake_fit'][self.fit_name] = self.get_user_settings() |
1122 | 1121 | async_execute(self._fit_d_uptake) |
1123 | 1122 |
|
| 1123 | + def get_user_settings(self) -> dict: |
| 1124 | + """ |
| 1125 | + Returns a dictionary with the current user settings. |
| 1126 | + """ |
| 1127 | + keys = ['bounds', 'r1'] |
| 1128 | + d = {k: getattr(self, k) for k in keys} |
| 1129 | + |
| 1130 | + return d |
| 1131 | + |
1124 | 1132 | async def _fit_d_uptake(self): |
1125 | 1133 |
|
1126 | 1134 | name = self.fit_name |
@@ -1276,7 +1284,9 @@ def _action_fit(self): |
1276 | 1284 | self.param["do_fit1"].constant = True |
1277 | 1285 | self.widgets["do_fit1"].loading = True |
1278 | 1286 |
|
1279 | | - num_samples = len(self.src.hdxm_objects) |
| 1287 | + user_dict = self.sources['metadata'].get('user_settings') |
| 1288 | + user_dict['initial_guess'][self.guess_name] = self.get_user_settings() |
| 1289 | + |
1280 | 1290 | if self.fitting_model.lower() in ["association", "dissociation"]: |
1281 | 1291 | loop = asyncio.get_running_loop() |
1282 | 1292 | loop.create_task(self._fit_rates(self.guess_name)) |
@@ -1322,6 +1332,21 @@ async def _fit_rates(self, name): |
1322 | 1332 | self.widgets["do_fit1"].loading = False |
1323 | 1333 | self.parent.logger.info(f"Finished initial guess fit {name}") |
1324 | 1334 |
|
| 1335 | + def get_user_settings(self) -> dict: |
| 1336 | + """ |
| 1337 | + Returns a dictionary with the current user settings. |
| 1338 | + """ |
| 1339 | + |
| 1340 | + d = {'fitting_model': self.fitting_model} |
| 1341 | + if self.fitting_model in ["association", "dissociation"]: |
| 1342 | + d['global_bounds'] = self.global_bounds |
| 1343 | + if self.global_bounds: |
| 1344 | + d["bounds"] = [self.lower_bound, self.upper_bound] |
| 1345 | + else: |
| 1346 | + d["bounds"] = self.bounds |
| 1347 | + |
| 1348 | + return d |
| 1349 | + |
1325 | 1350 |
|
1326 | 1351 | class FitControl(PyHDXControlPanel): |
1327 | 1352 | """ |
@@ -1481,6 +1506,9 @@ def _action_fit(self): |
1481 | 1506 | self._fit_names.append(self.fit_name) |
1482 | 1507 | self.parent.logger.info("Started PyTorch fit") |
1483 | 1508 |
|
| 1509 | + user_dict = self.sources['metadata'].get('user_settings') |
| 1510 | + user_dict['dG_fit'][self.fit_name] = self.get_user_settings() |
| 1511 | + |
1484 | 1512 | self._current_jobs += 1 |
1485 | 1513 | # if self._current_jobs >= self._max_jobs: |
1486 | 1514 | # self.widgets['do_fit'].constant = True |
@@ -1600,6 +1628,24 @@ def fit_kwargs(self): |
1600 | 1628 |
|
1601 | 1629 | return fit_kwargs |
1602 | 1630 |
|
| 1631 | + def get_user_settings(self) -> dict: |
| 1632 | + """ |
| 1633 | + Returns a dictionary with the current user settings. |
| 1634 | + """ |
| 1635 | + |
| 1636 | + d = { |
| 1637 | + 'initial_guess': self.initial_guess, |
| 1638 | + 'guess_mode': self.guess_mode |
| 1639 | + } |
| 1640 | + |
| 1641 | + if self.guess_mode == 'One-to-many': |
| 1642 | + d['guess_state'] = self.guess_state |
| 1643 | + d['fit_mode'] = self.fit_mode |
| 1644 | + |
| 1645 | + d.update(self.fit_kwargs) |
| 1646 | + |
| 1647 | + return d |
| 1648 | + |
1603 | 1649 |
|
1604 | 1650 | class DifferentialControl(PyHDXControlPanel): |
1605 | 1651 | _type = "diff" |
@@ -1660,6 +1706,9 @@ def _action_add_comparison(self): |
1660 | 1706 | ) |
1661 | 1707 | return |
1662 | 1708 |
|
| 1709 | + user_dict = self.sources['metadata'].get('user_settings') |
| 1710 | + user_dict['differential_HDX'][self.comparison_name] = self.get_user_settings() |
| 1711 | + |
1663 | 1712 | # RFU only app has no dGs, |
1664 | 1713 | if "ddG_fit_select" in self.transforms: |
1665 | 1714 | self.add_ddG_comparison() |
@@ -1790,6 +1839,14 @@ def add_dd_uptake_comparison(self): |
1790 | 1839 |
|
1791 | 1840 | self.src._add_table(dd_uptake, "dd_uptake") |
1792 | 1841 |
|
| 1842 | + def get_user_settings(self) -> dict: |
| 1843 | + """ |
| 1844 | + Returns a dictionary with the current user settings. |
| 1845 | + """ |
| 1846 | + |
| 1847 | + d = {'reference_state': self.reference_state} |
| 1848 | + |
| 1849 | + return d |
1793 | 1850 |
|
1794 | 1851 | class ColorTransformControl(PyHDXControlPanel): |
1795 | 1852 | """ |
@@ -2430,12 +2487,39 @@ def make_dict(self): |
2430 | 2487 | callback=self.color_export_callback, |
2431 | 2488 | ) |
2432 | 2489 |
|
| 2490 | + widgets["divider"] = pn.layout.Divider() |
| 2491 | + |
| 2492 | + widgets["download_state_spec"] = pn.widgets.FileDownload( |
| 2493 | + label="Download HDX spec", |
| 2494 | + callback=self.state_spec_callback, |
| 2495 | + ) |
| 2496 | + |
| 2497 | + widgets["download_config"] = pn.widgets.FileDownload( |
| 2498 | + label="Download config", |
| 2499 | + callback=self.config_callback, |
| 2500 | + ) |
| 2501 | + |
| 2502 | + widgets["download_user_settings"] = pn.widgets.FileDownload( |
| 2503 | + label="Download user settings", |
| 2504 | + callback=self.user_settings_callback, |
| 2505 | + ) |
| 2506 | + |
| 2507 | + widgets["download_log"] = pn.widgets.FileDownload( |
| 2508 | + label="Download log", |
| 2509 | + callback = self.log_callback, |
| 2510 | + ) |
| 2511 | + |
2433 | 2512 | widget_order = [ |
2434 | 2513 | "table", |
2435 | 2514 | "export_format", |
2436 | 2515 | "export_tables", |
2437 | 2516 | "export_pml", |
2438 | 2517 | "export_colors", |
| 2518 | + "divider", |
| 2519 | + "download_state_spec", |
| 2520 | + "download_config", |
| 2521 | + "download_user_settings", |
| 2522 | + "download_log", |
2439 | 2523 | ] |
2440 | 2524 | final_widgets = {w: widgets[w] for w in widget_order} |
2441 | 2525 |
|
@@ -2521,6 +2605,42 @@ def color_export_callback(self): |
2521 | 2605 | else: |
2522 | 2606 | return None |
2523 | 2607 |
|
| 2608 | + def state_spec_callback(self) -> StringIO: |
| 2609 | + timestamp = self.parent.session_time.strftime("%Y%m%d%H%M") |
| 2610 | + self.widgets[ |
| 2611 | + "download_state_spec" |
| 2612 | + ].filename = f"PyHDX_state_spec_{timestamp}.yaml" |
| 2613 | + |
| 2614 | + sio = self.parent.state_spec_callback() |
| 2615 | + return sio |
| 2616 | + |
| 2617 | + def config_callback(self) -> StringIO: |
| 2618 | + timestamp = self.parent.session_time.strftime("%Y%m%d%H%M") |
| 2619 | + self.widgets[ |
| 2620 | + "download_config" |
| 2621 | + ].filename = f"PyHDX_config_{timestamp}.yaml" |
| 2622 | + |
| 2623 | + sio = self.parent.config_callback() |
| 2624 | + return sio |
| 2625 | + |
| 2626 | + def user_settings_callback(self) -> StringIO: |
| 2627 | + timestamp = self.parent.session_time.strftime("%Y%m%d%H%M") |
| 2628 | + self.widgets[ |
| 2629 | + "download_user_settings" |
| 2630 | + ].filename = f"PyHDX_config_{timestamp}.yaml" |
| 2631 | + |
| 2632 | + sio = self.parent.user_settings_callback() |
| 2633 | + return sio |
| 2634 | + |
| 2635 | + def log_callback(self) -> StringIO: |
| 2636 | + timestamp = self.parent.session_time.strftime("%Y%m%d%H%M") |
| 2637 | + self.widgets[ |
| 2638 | + "download_log" |
| 2639 | + ].filename = f"PyHDX_log_{timestamp}.txt" |
| 2640 | + |
| 2641 | + sio = self.parent.log_callback() |
| 2642 | + return sio |
| 2643 | + |
2524 | 2644 |
|
2525 | 2645 | class FigureExportControl(PyHDXControlPanel): |
2526 | 2646 |
|
@@ -2805,30 +2925,30 @@ def make_dict(self): |
2805 | 2925 | return widgets |
2806 | 2926 |
|
2807 | 2927 | def export_session_callback(self): |
2808 | | - dt = datetime.today().strftime("%Y%m%d_%H%M") |
2809 | | - self.widgets["export_session"].filename = f"{dt}_PyHDX_session.zip" |
| 2928 | + self.widgets["export_session"].filename = f"{self.parent.session_time.strftime('%Y%m%d_%H%M')}_PyHDX_session.zip" |
2810 | 2929 | bio = BytesIO() |
2811 | 2930 | with zipfile.ZipFile(bio, "w") as session_zip: |
2812 | 2931 | # Write tables |
2813 | 2932 | for name, table in self.sources["main"].tables.items(): |
2814 | 2933 | sio = dataframe_to_stringio(table) |
2815 | 2934 | session_zip.writestr(name + ".csv", sio.getvalue()) |
2816 | 2935 |
|
2817 | | - # Write config file |
2818 | | - masked_conf = OmegaConf.masked_copy(cfg.conf, cfg.conf.keys() - {'server'}) |
2819 | | - s = OmegaConf.to_yaml(masked_conf) |
2820 | | - |
2821 | | - version_string = "# pyhdx configuration file " + __version__ + "\n\n" |
2822 | | - session_zip.writestr("PyHDX_config.yaml", version_string + s) |
2823 | | - |
2824 | | - # Write state spec file |
2825 | | - input_controllers = {"PeptideFileInputControl", "PeptideRFUFileInputControl"} |
2826 | | - input_ctrls = self.parent.control_panels.keys() & input_controllers |
2827 | | - if len(input_ctrls) == 1: |
2828 | | - input_ctrl = self.parent.control_panels[list(input_ctrls)[0]] |
2829 | | - sio = input_ctrl.spec_download_callback() |
| 2936 | + # Write HDX measurement state specifications |
| 2937 | + if sio := self.parent.state_spec_callback(): |
2830 | 2938 | session_zip.writestr("PyHDX_state_spec.yaml", sio.read()) |
2831 | 2939 |
|
| 2940 | + # Write config file |
| 2941 | + sio = self.parent.config_callback() |
| 2942 | + session_zip.writestr("PyHDX_config.yaml", sio.read()) |
| 2943 | + |
| 2944 | + # Write user settings |
| 2945 | + sio = self.parent.user_settings_callback() |
| 2946 | + session_zip.writestr("PyHDX_user_settings.yaml", sio.read()) |
| 2947 | + |
| 2948 | + # Write log file |
| 2949 | + sio = self.parent.log_callback() |
| 2950 | + session_zip.writestr("PyHDX_log.txt", sio.read()) |
| 2951 | + |
2832 | 2952 | bio.seek(0) |
2833 | 2953 | return bio |
2834 | 2954 |
|
|
0 commit comments