Skip to content

Sampler engine structure #280 - #287

Open
rozyczko wants to merge 15 commits into
developfrom
sampler-engine-structure-280
Open

Sampler engine structure #280#287
rozyczko wants to merge 15 commits into
developfrom
sampler-engine-structure-280

Conversation

@rozyczko

@rozyczko rozyczko commented Aug 7, 2026

Copy link
Copy Markdown
Member

Core refactoring and shared logic:

  • Introduced EngineBase (engine_base.py) as a new base class for all evaluation engines (minimizers and samplers), with centralized parameter handling, fit function wrapping, and evaluation logic.
  • Refactored MinimizerBase so it inherits from EngineBase. Cleaned up the constructor and removed duplicated parameter caching logic.

Bumps integration and utilities:

  • Extracted BUMPS-specific problem construction and parameter conversion functions into a new module bumps_utils/problem.py, including build_curve_problem, to_bumps_parameter, parameter_names, and parameter_snapshot. These are now imported and exposed in bumps_utils/__init__.py.
  • Added a new validation module (bumps_utils/validation.py) with functions for validating run settings and input arrays

API changes and deprecations:

  • mcmc_sample() now lives on Sampler class directly. The method now routes calls to Sampler(...).sample(...)
  • Updated the progress_callback signature in MinimizerBase.fit to clarify that its return value is ignored and to align with the new shared engine base.

@rozyczko rozyczko added [area] fitting Umbrella for fitting related work [scope] maintenance Code/tooling cleanup, no feature or bugfix (major.minor.PATCH) [priority] high Should be prioritized soon labels Aug 7, 2026
@rozyczko
rozyczko requested a review from damskii9992 September 2, 2026 12:53

@damskii9992 damskii9992 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am ALMOST done reviewing this behemoth of a PR. Still need to look at sampler_dream.py and the tests. but the day is almost over and I figured I should send off these comments now.

Comment thread src/easyscience/fitting/engine_base.py Outdated
Comment thread src/easyscience/fitting/minimizers/minimizer_base.py Outdated
Comment thread src/easyscience/fitting/sampler.py Outdated
Comment thread src/easyscience/fitting/sampler.py Outdated
Comment thread src/easyscience/fitting/sampler.py Outdated
Comment thread src/easyscience/fitting/minimizers/minimizer_bumps.py Outdated
Comment thread src/easyscience/fitting/minimizers/minimizer_bumps.py
Comment thread src/easyscience/fitting/minimizers/minimizer_bumps.py Outdated
Comment thread src/easyscience/fitting/minimizers/minimizer_bumps.py Outdated
Comment thread src/easyscience/fitting/minimizers/minimizer_bumps.py Outdated
@rozyczko
rozyczko requested a review from damskii9992 September 8, 2026 19:54
@damskii9992

Copy link
Copy Markdown
Contributor

You will need to change the tutorial in this PR too . . .

@damskii9992 damskii9992 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please also remove all the "Optional" typehints in the code and replace them with | None as is the new convention.

Comment on lines +166 to +170
if weights is None:
raise ValueError(
'weights must not be None for Bayesian sampling. Pass '
'measurement weights (e.g. ``1 / sigma``) matching x and y.'
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why allow None in the typehint signature then?

Comment thread src/easyscience/fitting/sampler.py Outdated
Comment on lines 379 to 380

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why allow None weights and None entries in weights if the Dream sampler doesn't allow them?


def __init__(
self,
fitter: 'Fitter',

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wasn't a big part of this re-factoring done to also ensure that you didn't need a Fitter to create a Sampler?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The refactor decoupled sampling from the minimizer, not from the Fitter. Fitter still has reshaping and fit-function wrapping.

One thing: __init__ requires hasattr(fitter, 'minimizer') but the minimizer is never used. I'll fix that.

Comment thread src/easyscience/fitting/engine_base.py Outdated
Comment on lines +8 to +33
def validate_run_settings(samples: int, burn: int, thin: int) -> None:
"""Validate the DREAM run settings.

Parameters
----------
samples : int
Number of raw samples to draw; must be a positive integer.
burn : int
Burn-in generations to discard; must be a non-negative integer.
thin : int
Thinning interval; must be a positive integer.

Raises
------
ValueError
If any value is out of range or not an integer.
"""
# bool is a subclass of int, so ``samples=True`` would otherwise pass as
# ``samples=1``; these checks are strict (``10.0`` is rejected), so
# booleans must be rejected too.
if not isinstance(samples, int) or isinstance(samples, bool) or samples <= 0:
raise ValueError('samples must be a positive integer.')
if not isinstance(burn, int) or isinstance(burn, bool) or burn < 0:
raise ValueError('burn must be a non-negative integer.')
if not isinstance(thin, int) or isinstance(thin, bool) or thin < 1:
raise ValueError('thin must be a positive integer.')

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why factor this into a separate module? It's only used by the DreamSampler, so shouldn't it live there?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, it is only used in 1 place, so why even factor it out at all? It's more readable to just have the code where it is used, if it is only used once . . .

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

moved to samples/validation.py, dropped from bumps_utils/init.py, exported from samplers/init.py

Comment on lines +173 to +174
validate_run_settings(samples, burn, thin)
validate_arrays(x, y, weights)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should our validations belong in the Sampler class or here? Right now you validate in both places . . .
I think validations should belong in Sampler as long as they aren't engine-specific. Which means the engines can assume that whatever is passed to them is valid.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is not actually duplicated. Sampler checks numeric/non-scalar/non-empty; validate_arrays checks shape match, finiteness, positive weights.
They are more complementary than dupes. And validate_arrays cannot move into Sampler regardless, since all three minimizers call it from Fitter.fit...

Comment thread src/easyscience/fitting/samplers/sampler_bumps.py
Comment thread src/easyscience/fitting/minimizers/minimizer_base.py Outdated
Comment thread src/easyscience/fitting/minimizers/minimizer_bumps.py Outdated
@rozyczko

rozyczko commented Sep 10, 2026

Copy link
Copy Markdown
Member Author

You will need to change the tutorial in this PR too . . .

No changes needed.
We removed Fitter.mcmc_sample, SamplingResults.to_legacy_dict, and the optional parameters and model list - things which are not used by any notebook.

I will need to change the tutorials for the ModelBase migration, true

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[area] fitting Umbrella for fitting related work [priority] high Should be prioritized soon [scope] maintenance Code/tooling cleanup, no feature or bugfix (major.minor.PATCH)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants