Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Devel #42

Open
wants to merge 41 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
c470f31
Improved legend display name in case no name was present and made sur…
ckoerber Nov 11, 2021
9777b96
Added an additional attribute to prevent showing the texed latex expr…
ckoerber Nov 11, 2021
d2fcd81
Ignored a few more warnings regarding formatting and docstrings
ckoerber Nov 11, 2021
22f997d
Slightly refacored app such that the callback methods for the prior a…
ckoerber Nov 11, 2021
8e90e2a
Made sure typing hints are correct and standardized inputs
ckoerber Nov 11, 2021
be36b8e
Updated toml for mypy
ckoerber Nov 11, 2021
48182c0
First draft of making the entire content a class
ckoerber Nov 11, 2021
74abb33
Made sure to not nest body
ckoerber Nov 11, 2021
0a791f8
made body class an gui argument
ckoerber Nov 11, 2021
5b20525
Starting to improve doc for new design
ckoerber Nov 12, 2021
dbaecda
Updated api doc
ckoerber Nov 12, 2021
20094ad
Also pass meta to get content
ckoerber Nov 12, 2021
97bb6ce
Added updatetable grid points to sidebar
ckoerber Nov 12, 2021
a11e5da
Removed un-needed start_app
ckoerber Nov 12, 2021
fa4f773
Prepared customization doc
ckoerber Nov 12, 2021
e497f6d
Documented sidebar
ckoerber Nov 12, 2021
56ec0d1
Added first customization doc
ckoerber Nov 12, 2021
d428adf
Updated docs
ckoerber Nov 12, 2021
d1cd635
Changed version number as this introduces significant changes
ckoerber Nov 12, 2021
bc6d4cf
Merge pull request #41 from ckoerber/html-class-design
ckoerber Nov 12, 2021
ff01595
Improved legend display name in case no name was present and made sur…
ckoerber Nov 11, 2021
44fbcc3
Added an additional attribute to prevent showing the texed latex expr…
ckoerber Nov 11, 2021
957d1db
Ignored a few more warnings regarding formatting and docstrings
ckoerber Nov 11, 2021
709d9d5
Slightly refacored app such that the callback methods for the prior a…
ckoerber Nov 11, 2021
0241ada
Made sure typing hints are correct and standardized inputs
ckoerber Nov 11, 2021
0ece9f1
Updated toml for mypy
ckoerber Nov 11, 2021
6336838
First draft of making the entire content a class
ckoerber Nov 11, 2021
47565fc
Made sure to not nest body
ckoerber Nov 11, 2021
32d9f23
made body class an gui argument
ckoerber Nov 11, 2021
097fc8b
Starting to improve doc for new design
ckoerber Nov 12, 2021
2704f3f
Updated api doc
ckoerber Nov 12, 2021
733460b
Also pass meta to get content
ckoerber Nov 12, 2021
45ade6c
Added updatetable grid points to sidebar
ckoerber Nov 12, 2021
6a3cb09
Removed un-needed start_app
ckoerber Nov 12, 2021
52f67ad
Prepared customization doc
ckoerber Nov 12, 2021
e8e697a
Documented sidebar
ckoerber Nov 12, 2021
844d328
Added first customization doc
ckoerber Nov 12, 2021
9f6a4f4
Updated docs
ckoerber Nov 12, 2021
fe01c8b
Changed version number as this introduces significant changes
ckoerber Nov 12, 2021
a353cbf
Merge branch 'devel' of https://github.com/ckoerber/lsqfit-gui into d…
ckoerber Nov 12, 2021
0ff456b
Black max line length and eliminated unused attributes
ckoerber Nov 15, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ __pycache__
*.log
tmp
build
.coverage
22 changes: 22 additions & 0 deletions doc/source/api/lsqfitgui.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,25 @@ API: lsqfitgui

.. autoclass:: FitGUI
:members:



``BodyTemplate``
------------------

.. autoclass:: BodyTemplate
:members:


``DefaultBodyTemplate``
-----------------------

.. autoclass:: DefaultBodyTemplate
:members:


``DEFAULT_PLOTS``
-----------------------

.. autodata:: lsqfitgui.frontend.content.DEFAULT_PLOTS
:no-value:
31 changes: 31 additions & 0 deletions doc/source/customization.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Customization

The content of the dashboard created by `lsqfitgui` is generated by the {class}`lsqfitgui.DefaultBodyTemplate` class.
To update this content, you have to
1. create a new class which inherits from the default template (or from the base {class}`lsqfitgui.BodyTemplate` class if you want to start from scratch),
2. overload the {func}`lsqfitgui.DefaultBodyTemplate.get_content` method, and
3. pass it to the GUI on instantiation.

For example, the following code appends additional text to the dashboard

```python
from dash import html
from lsqfit import nonlinear_fit
from lsqfitgui import FitGUI, DefaultBodyTemplate

class MyBodyTemplate(DefaultBodyTemplate):

def get_content(self, fit: nonlinear_fit, meta: Optional[Dict]=None) -> List[html.Base]:
"""Add additional content to the default content."""
content = super().get_content(fit, meta=meta)
content.append(html.P("Hello world!"))
return content

fit = nonlinear_fit(...)

fit_gui = FitGUI(fit, template_cls=MyBodyTemplate)
fit_gui.run_server()
```

The `fit` object represents the current fit (after updating the prior or meta information) and the `meta` values (if applicable).
The content is a list of [`dash.html` components](https://dash.plotly.com/dash-html-components), which can be regular text content or figures.
1 change: 1 addition & 0 deletions doc/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ lsqfitgui documentation

quickstart
examples
customization
api/lsqfitgui


Expand Down
45 changes: 27 additions & 18 deletions example/entrypoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,34 +5,43 @@

from dash import html

from lsqfitgui import run_server


def get_additional_content(fit):
"""Generate aditional dash html elements based on a fit object."""
return html.Div(
[
html.H2("Comparison against initial synthetic data values"),
html.P("Synthetic"),
html.Pre(str(A0)),
html.P("Posterior"),
html.Pre(str(fit.p)),
]
)
from lsqfitgui import FitGUI, DefaultBodyTemplate


class MyBodyTemplate(DefaultBodyTemplate):
# Bootstrap columns: https://getbootstrap.com/docs/5.0/layout/grid/#grid-options
sidebar_div_class = "col-xs-12 col-sm-6 col-md-6 col-xl-5 col-xxl-4"
content_div_class = "col-xs-12 col-sm-6 col-md-6 col-xl-7 col-xxl-8"

def get_content(self, fit, meta=None):
"""Add additional content to the default content."""
content = super().get_content(fit, meta=meta)
content.append(
html.Div(
[
html.H2("Comparison against initial synthetic data values"),
html.P("Synthetic"),
html.Pre(str(A0)),
html.P("Posterior"),
html.Pre(str(fit.p)),
]
)
)
return content


def main():
"""Start the GUI for the fit."""
run_server(
name="Poly fit",
fit_gui = FitGUI(
fit_setup_function=generate_fit,
fit_setup_kwargs={"n_poly": 4},
meta_config=[
{"name": "n_poly", "type": "number", "min": 1, "max": 10, "step": 1}
],
use_default_content=True,
get_additional_content=get_additional_content,
template_cls=MyBodyTemplate,
)
fit_gui.name = "Poly fit"
fit_gui.run_server()


if __name__ == "__main__":
Expand Down
16 changes: 15 additions & 1 deletion lsqfitgui/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,20 @@
""" # noqa: E501
from lsqfitgui.lsqfitgui import FitGUI, run_server # noqa
from lsqfitgui.plot.uncertainty import wrap_plot_gvar, plot_gvar # noqa
from lsqfitgui.frontend.body import ( # noqa
BodyTemplate,
DefaultBodyTemplate,
DEFAULT_PLOTS,
)
from lsqfitgui.version import __version__ # noqa

__all__ = ["FitGUI", "run_server", "wrap_plot_gvar", "plot_gvar", "__version__"]
__all__ = [
"FitGUI",
"run_server",
"wrap_plot_gvar",
"plot_gvar",
"BodyTemplate",
"DefaultBodyTemplate",
"DEFAULT_PLOTS",
"__version__",
]
2 changes: 1 addition & 1 deletion lsqfitgui/_version.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.1.0
0.2.0
5 changes: 5 additions & 0 deletions lsqfitgui/backend/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
"""Access to backend functions."""

from lsqfitgui.backend.sidebar import process_priors, process_meta # noqa

__all__ = ["process_priors", "process_meta"]
25 changes: 23 additions & 2 deletions lsqfitgui/backend/sidebar.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
"""Functions for parsing sidebar form values into python objects."""
from typing import Dict, List, Any, Optional

import re
import gvar as gv
from lsqfit import nonlinear_fit
Expand Down Expand Up @@ -33,6 +35,25 @@ def process_priors(prior_flat, initial_fit):
return fit


def process_meta(meta_array, meta_config):
def process_meta(
meta_array: Optional[List[Any]], meta_config: Optional[List[Dict[str, Any]]]
) -> Dict[str, Any]:
"""Parse meta form input into dictionary shape using meta config name values."""
return {config["name"]: val for config, val in zip(meta_config, meta_array)}
# for python 3.10+ this will be zip(*, strict=False)
if not meta_array and not meta_config:
return {}
elif meta_array and not meta_config:
raise TypeError(
"Improperly configured. Received meta config values but no meta config."
)
elif meta_config and not meta_array:
raise TypeError("Improperly configured. Received meta configs but no values.")
else:
assert isinstance(meta_config, list)
assert isinstance(meta_array, list)
if len(meta_config) != len(meta_array):
raise ValueError(
"Improperly configured."
" Meta config options does not have the same number of values recieved."
)
return {config["name"]: val for config, val in zip(meta_config, meta_array)}
Loading