Skip to content

Commit

Permalink
Add settings history in web application (#301)
Browse files Browse the repository at this point in the history
* add history

* add dict source to rfu app

* add log download

* add differential hdx settings
  • Loading branch information
Jhsmit authored Sep 19, 2022
1 parent 4ef586a commit eb14500
Show file tree
Hide file tree
Showing 6 changed files with 296 additions and 41 deletions.
27 changes: 11 additions & 16 deletions dev/gui/dev_gui_secB.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@
from pyhdx.web.utils import load_state, fix_multiindex_dtypes
from pyhdx.config import cfg, reset_config

reset_config()

#def printfunc(args):
# 1/0

Expand Down Expand Up @@ -132,24 +130,21 @@ def init_dashboard():
input_control._action_load_datasets()

d_uptake_control = ctrl.control_panels["DUptakeFitControl"]
d_uptake_control.repeats = 3

d_uptake_control.repeats = 2

ctrl.sources['pdb'].add_from_string(pdb_string, '1qyn')

src = ctrl.sources['main']
df = csv_to_dataframe(web_data_dir / 'd_uptake.csv')
df.columns = fix_multiindex_dtypes(df.columns)
src.add_table('d_uptake', df)
src.updated = True

# todo needs to be done on _add_table / add_table
df = csv_to_dataframe(web_data_dir / 'dG.csv')
df.columns = fix_multiindex_dtypes(df.columns)
src.add_table('dG', df)

#src.param.trigger('updated')
src.updated = True
# df = csv_to_dataframe(web_data_dir / 'd_uptake.csv')
# df.columns = fix_multiindex_dtypes(df.columns)
# src.add_table('d_uptake', df)
# src.updated = True
#
# df = csv_to_dataframe(web_data_dir / 'dG.csv')
# df.columns = fix_multiindex_dtypes(df.columns)
# src.add_table('dG', df)

# src.updated = True


# guess_control = ctrl.control_panels['InitialGuessControl']
Expand Down
2 changes: 2 additions & 0 deletions pyhdx/web/apps/pyhdx_app.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ sources:
type: pyhdx
pdb:
type: pdb
metadata:
type: dict

transforms:
peptide_src:
Expand Down
2 changes: 2 additions & 0 deletions pyhdx/web/apps/rfu_app.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ sources:
type: pyhdx
pdb:
type: pdb
metadata:
type: dict

transforms:
peptide_src:
Expand Down
170 changes: 145 additions & 25 deletions pyhdx/web/controllers.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import sys
import uuid
import zipfile
from datetime import datetime
from io import StringIO, BytesIO
from typing import Any

Expand Down Expand Up @@ -195,8 +194,9 @@ def _action_debug(self):
print(df_rfu)

def _action_test(self):
pdbe_view = self.views["protein"]
pdbe_view.pdbe.test = not pdbe_view.pdbe.test
src = self.sources['metadata']
d = src.get('user_settings')
print(d)

@property
def _layout(self):
Expand Down Expand Up @@ -265,7 +265,7 @@ def make_dict(self):

def config_download_callback(self) -> StringIO:
# Generate and set filename
timestamp = datetime.now().strftime("%Y%m%d%H%M")
timestamp = self.parent.session_time.strftime("%Y%m%d%H%M")
self.widgets[
"config_download"
].filename = f"PyHDX_config_{timestamp}.yaml"
Expand Down Expand Up @@ -400,15 +400,12 @@ def _action_load_datasets(self) -> None:
)

def spec_download_callback(self) -> StringIO:
timestamp = datetime.now().strftime("%Y%m%d%H%M")
timestamp = self.parent.session_time.strftime("%Y%m%d%H%M")
self.widgets[
"download_spec_button"
].filename = f"PyHDX_state_spec_{timestamp}.yaml"

s = yaml.dump(clean_types(self.state_spec), sort_keys=False)
output = "# " + pyhdx.VERSION_STRING + "\n" + s
sio = StringIO(output)

sio = self.parent.state_spec_callback()
return sio

@property
Expand Down Expand Up @@ -1119,8 +1116,19 @@ def _action_fit(self):
self.param["do_fit"].constant = True
self.widgets["do_fit"].loading = True

user_dict = self.sources['metadata'].get('user_settings')
user_dict['d_uptake_fit'][self.fit_name] = self.get_user_settings()
async_execute(self._fit_d_uptake)

def get_user_settings(self) -> dict:
"""
Returns a dictionary with the current user settings.
"""
keys = ['bounds', 'r1']
d = {k: getattr(self, k) for k in keys}

return d

async def _fit_d_uptake(self):

name = self.fit_name
Expand Down Expand Up @@ -1276,7 +1284,9 @@ def _action_fit(self):
self.param["do_fit1"].constant = True
self.widgets["do_fit1"].loading = True

num_samples = len(self.src.hdxm_objects)
user_dict = self.sources['metadata'].get('user_settings')
user_dict['initial_guess'][self.guess_name] = self.get_user_settings()

if self.fitting_model.lower() in ["association", "dissociation"]:
loop = asyncio.get_running_loop()
loop.create_task(self._fit_rates(self.guess_name))
Expand Down Expand Up @@ -1322,6 +1332,21 @@ async def _fit_rates(self, name):
self.widgets["do_fit1"].loading = False
self.parent.logger.info(f"Finished initial guess fit {name}")

def get_user_settings(self) -> dict:
"""
Returns a dictionary with the current user settings.
"""

d = {'fitting_model': self.fitting_model}
if self.fitting_model in ["association", "dissociation"]:
d['global_bounds'] = self.global_bounds
if self.global_bounds:
d["bounds"] = [self.lower_bound, self.upper_bound]
else:
d["bounds"] = self.bounds

return d


class FitControl(PyHDXControlPanel):
"""
Expand Down Expand Up @@ -1481,6 +1506,9 @@ def _action_fit(self):
self._fit_names.append(self.fit_name)
self.parent.logger.info("Started PyTorch fit")

user_dict = self.sources['metadata'].get('user_settings')
user_dict['dG_fit'][self.fit_name] = self.get_user_settings()

self._current_jobs += 1
# if self._current_jobs >= self._max_jobs:
# self.widgets['do_fit'].constant = True
Expand Down Expand Up @@ -1600,6 +1628,24 @@ def fit_kwargs(self):

return fit_kwargs

def get_user_settings(self) -> dict:
"""
Returns a dictionary with the current user settings.
"""

d = {
'initial_guess': self.initial_guess,
'guess_mode': self.guess_mode
}

if self.guess_mode == 'One-to-many':
d['guess_state'] = self.guess_state
d['fit_mode'] = self.fit_mode

d.update(self.fit_kwargs)

return d


class DifferentialControl(PyHDXControlPanel):
_type = "diff"
Expand Down Expand Up @@ -1660,6 +1706,9 @@ def _action_add_comparison(self):
)
return

user_dict = self.sources['metadata'].get('user_settings')
user_dict['differential_HDX'][self.comparison_name] = self.get_user_settings()

# RFU only app has no dGs,
if "ddG_fit_select" in self.transforms:
self.add_ddG_comparison()
Expand Down Expand Up @@ -1790,6 +1839,14 @@ def add_dd_uptake_comparison(self):

self.src._add_table(dd_uptake, "dd_uptake")

def get_user_settings(self) -> dict:
"""
Returns a dictionary with the current user settings.
"""

d = {'reference_state': self.reference_state}

return d

class ColorTransformControl(PyHDXControlPanel):
"""
Expand Down Expand Up @@ -2430,12 +2487,39 @@ def make_dict(self):
callback=self.color_export_callback,
)

widgets["divider"] = pn.layout.Divider()

widgets["download_state_spec"] = pn.widgets.FileDownload(
label="Download HDX spec",
callback=self.state_spec_callback,
)

widgets["download_config"] = pn.widgets.FileDownload(
label="Download config",
callback=self.config_callback,
)

widgets["download_user_settings"] = pn.widgets.FileDownload(
label="Download user settings",
callback=self.user_settings_callback,
)

widgets["download_log"] = pn.widgets.FileDownload(
label="Download log",
callback = self.log_callback,
)

widget_order = [
"table",
"export_format",
"export_tables",
"export_pml",
"export_colors",
"divider",
"download_state_spec",
"download_config",
"download_user_settings",
"download_log",
]
final_widgets = {w: widgets[w] for w in widget_order}

Expand Down Expand Up @@ -2521,6 +2605,42 @@ def color_export_callback(self):
else:
return None

def state_spec_callback(self) -> StringIO:
timestamp = self.parent.session_time.strftime("%Y%m%d%H%M")
self.widgets[
"download_state_spec"
].filename = f"PyHDX_state_spec_{timestamp}.yaml"

sio = self.parent.state_spec_callback()
return sio

def config_callback(self) -> StringIO:
timestamp = self.parent.session_time.strftime("%Y%m%d%H%M")
self.widgets[
"download_config"
].filename = f"PyHDX_config_{timestamp}.yaml"

sio = self.parent.config_callback()
return sio

def user_settings_callback(self) -> StringIO:
timestamp = self.parent.session_time.strftime("%Y%m%d%H%M")
self.widgets[
"download_user_settings"
].filename = f"PyHDX_config_{timestamp}.yaml"

sio = self.parent.user_settings_callback()
return sio

def log_callback(self) -> StringIO:
timestamp = self.parent.session_time.strftime("%Y%m%d%H%M")
self.widgets[
"download_log"
].filename = f"PyHDX_log_{timestamp}.txt"

sio = self.parent.log_callback()
return sio


class FigureExportControl(PyHDXControlPanel):

Expand Down Expand Up @@ -2805,30 +2925,30 @@ def make_dict(self):
return widgets

def export_session_callback(self):
dt = datetime.today().strftime("%Y%m%d_%H%M")
self.widgets["export_session"].filename = f"{dt}_PyHDX_session.zip"
self.widgets["export_session"].filename = f"{self.parent.session_time.strftime('%Y%m%d_%H%M')}_PyHDX_session.zip"
bio = BytesIO()
with zipfile.ZipFile(bio, "w") as session_zip:
# Write tables
for name, table in self.sources["main"].tables.items():
sio = dataframe_to_stringio(table)
session_zip.writestr(name + ".csv", sio.getvalue())

# Write config file
masked_conf = OmegaConf.masked_copy(cfg.conf, cfg.conf.keys() - {'server'})
s = OmegaConf.to_yaml(masked_conf)

version_string = "# pyhdx configuration file " + __version__ + "\n\n"
session_zip.writestr("PyHDX_config.yaml", version_string + s)

# Write state spec file
input_controllers = {"PeptideFileInputControl", "PeptideRFUFileInputControl"}
input_ctrls = self.parent.control_panels.keys() & input_controllers
if len(input_ctrls) == 1:
input_ctrl = self.parent.control_panels[list(input_ctrls)[0]]
sio = input_ctrl.spec_download_callback()
# Write HDX measurement state specifications
if sio := self.parent.state_spec_callback():
session_zip.writestr("PyHDX_state_spec.yaml", sio.read())

# Write config file
sio = self.parent.config_callback()
session_zip.writestr("PyHDX_config.yaml", sio.read())

# Write user settings
sio = self.parent.user_settings_callback()
session_zip.writestr("PyHDX_user_settings.yaml", sio.read())

# Write log file
sio = self.parent.log_callback()
session_zip.writestr("PyHDX_log.txt", sio.read())

bio.seek(0)
return bio

Expand Down
Loading

0 comments on commit eb14500

Please sign in to comment.