diff --git a/doc/conf.py b/doc/conf.py index 35d87e79..165f1c0d 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -36,13 +36,6 @@ print("\n".join(sys.path)) print("== end path ==") -# Register the refl1d model loader -import bumps.cli - -from refl1d.bumps_interface import fitplugin - -bumps.cli.install_plugin(fitplugin) - # -- General configuration ----------------------------------------------------- # Add any Sphinx extension module names here, as strings. They can be extensions diff --git a/pyproject.toml b/pyproject.toml index 465fe346..b747bdfe 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -52,6 +52,30 @@ documentation = "https://refl1d.github.io" homepage = "https://refl1d.github.io" repository = "https://github.com/reflectometry/refl1d" +[project.entry-points."bumps.serialization.migration"] +refl1d = "refl1d.bumps_interface.migrations:full_migration" + +[project.entry-points."bumps.model.load"] +refl1d = "refl1d.bumps_interface.fitplugin:load_model" + +[project.entry-points."bumps.model.new"] +refl1d = "refl1d.bumps_interface.fitplugin:new_model" + +[project.entry-points."bumps.serialize.save_json"] +refl1d = "refl1d.bumps_interface.fitplugin:save_json" + +[project.entry-points."bumps.wx_gui.data_view"] +refl1d = "refl1d.wx_gui.data_view:DataView" + +[project.entry-points."bumps.wx_gui.model_view"] +refl1d = "refl1d.wx_gui.model_view:ModelView" + +[project.entry-points."bumps.calc_errors"] +refl1d = "refl1d.uncertainty:calc_errors" + +[project.entry-points."bumps.show_errors.matplotlib"] +refl1d = "refl1d.uncertainty:show_errors" + [build-system] requires = ["setuptools", "versioningit"] build-backend = "setuptools.build_meta" diff --git a/refl1d/bumps_interface/fitplugin.py b/refl1d/bumps_interface/fitplugin.py index ef8634d6..ce0ae6ba 100644 --- a/refl1d/bumps_interface/fitplugin.py +++ b/refl1d/bumps_interface/fitplugin.py @@ -11,29 +11,14 @@ from typing import cast import numpy as np -from .migrations import migrate from bumps.fitproblem import FitProblem from ..experiment import Experiment from ..sample.materialdb import air, silicon from ..probe.data_loaders import ncnrdata as NCNR -from ..uncertainty import calc_errors, show_errors # List of modules that contain dataclasses for the saved json file format -# These are names used by the driver -def data_view(): - from refl1d.wx_gui.data_view import DataView - - return DataView - - -def model_view(): - from refl1d.wx_gui.model_view import ModelView - - return ModelView - - def load_model(filename: str): # TODO: bumps plugin api needs to allow options for loader options = None @@ -66,6 +51,22 @@ def new_model(): return problem -def migrate_serialized(model_dict): - _, migrated = migrate(model_dict) - return migrated +def errplot(problem: FitProblem[Experiment], points: np.ndarray, ax=None, **kwargs): + """ + Show the model confidence intervals. + + *problem* is the FitProblem containing the model and data. + *points* is a set of points in the parameter space, typically + sampled from the MCMC state or generated by a sampling method. + *ax* is an optional matplotlib Axes object to plot on. + """ + from ..uncertainty import calc_errors, show_errors + + errs = calc_errors(problem, points) + + if errs is not None: + if ax is None: + import matplotlib.pyplot as plt + + ax = plt.gca() + show_errors(problem, errs, ax=ax, **kwargs) diff --git a/refl1d/bumps_interface/migrations.py b/refl1d/bumps_interface/migrations.py index 0d7c3b24..cbebaa52 100644 --- a/refl1d/bumps_interface/migrations.py +++ b/refl1d/bumps_interface/migrations.py @@ -30,6 +30,17 @@ def migrate( return current_version, serialized +def full_migration(serialized: dict) -> dict: + """ + Migrate a serialized object to the current schema version. + This is a convenience function that migrates from the earliest version to the current version. + """ + current_version, migrated = migrate(serialized) + if current_version != CURRENT_SCHEMA_VERSION: + raise ValueError(f"Migration did not reach the current schema version: {CURRENT_SCHEMA_VERSION}") + return migrated + + def _migrate_0_to_1(serialized: dict): MAPPINGS = { "refl1d.abeles": "refl1d.probe.abeles", diff --git a/refl1d/main.py b/refl1d/main.py index 43156db3..3658ccae 100644 --- a/refl1d/main.py +++ b/refl1d/main.py @@ -14,24 +14,13 @@ from . import __version__ -def setup_bumps(): - """ - Install the refl1d plugin into bumps, but don't run main. - """ - import bumps.cli - - bumps.cli.set_mplconfig(appdatadir="Refl1D-" + __version__) - from .bumps_interface import fitplugin - - bumps.cli.install_plugin(fitplugin) - - def cli(): """ Install the Refl1D plugin into bumps and run the command line interface. """ - setup_bumps() + import bumps.plugin + bumps.plugin.ACTIVE_PLUGIN_NAME = "refl1d" # TODO: Add subcommand support to bumps. if len(sys.argv) > 2 and sys.argv[1] == "align": from .uncertainty import run_errors @@ -48,9 +37,10 @@ def gui(): """ Install the Refl1D plugin into bumps and run the graphical user interface. """ - setup_bumps() + import bumps.plugin import bumps.gui.gui_app + bumps.plugin.ACTIVE_PLUGIN_NAME = "refl1d" bumps.gui.gui_app.main() diff --git a/refl1d/webview/server/cli.py b/refl1d/webview/server/cli.py index 2e8ca824..edb080f1 100644 --- a/refl1d/webview/server/cli.py +++ b/refl1d/webview/server/cli.py @@ -9,20 +9,9 @@ from . import api # uses side-effects to register refl1d functions from refl1d import __version__ -# Register the refl1d model loader -# from refl1d.bumps_interface import fitplugin -# from .profile_plot import plot_sld_profile_plotly CLIENT_PATH = Path(__file__).parent.parent / "client" -# from dataclasses import dataclass -# from bumps.webview.server.cli import BumpsOptions, SERIALIZERS -# @dataclass -# class Refl1DOptions(BumpsOptions): -# serializer: SERIALIZERS = "dataclass" -# headless: bool = True -# bumps_cli.OPTIONS_CLASS = Refl1DOptions - def main(): cli.plugin_main(name="refl1d", client=CLIENT_PATH, version=__version__)