feat(optimizers): Add scipy-based FF optimizer#56
Merged
ericchansen merged 2 commits intomasterfrom Mar 18, 2026
Merged
Conversation
Introduce q2mm.optimizers package with ObjectiveFunction, ReferenceData, and ScipyOptimizer wrapping scipy.optimize.minimize and least_squares. - ObjectiveFunction: weighted sum-of-squares over energy, frequency, and geometry reference data with multi-molecule support - ScipyOptimizer: L-BFGS-B, Nelder-Mead, Powell, trust-constr, and Levenberg-Marquardt with auto-bounds from ForceField.get_bounds() - Tuned finite-difference step size (eps=1e-3) for FF parameter magnitudes where scipy defaults produce sub-precision changes - 18 integration tests covering all methods and data types Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Fix critical: DetectedAngle.angle → .value (AttributeError crash) - Fix geometry refs: use engine.minimize() so bond/angle observables respond to FF parameter changes instead of being constant - Fix silent failure: raise IndexError for out-of-range data_idx - Fix API trap: make data_idx required for frequency/bond/angle refs - Fix method options: per-method tolerance mapping (Powell ftol/xtol, Nelder-Mead fatol/xatol, trust-constr gtol) - Fix history: residuals() now tracks n_eval and history for least_squares convergence analysis - Improve bounds: configurable via overrides dict, wider defaults for angles (30-180°) and vdW epsilon (0.001-2.0) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Add
q2mm.optimizers-- a scipy-based force field optimization framework built on the clean model layer and OpenMM backend.What changed
New:
q2mm/optimizers/packageobjective.py--ObjectiveFunctionclassForceField, MM engine, molecules, andReferenceDatascipy_opt.py--ScipyOptimizerclassscipy.optimize.minimizeandscipy.optimize.least_squaresForceField.get_bounds()for bounded methodseps=1e-3) -- scipy's default ~1e-8 produces sub-precision energy changes for FF parameter magnitudesOptimizationResultwith success flag, scores, history, and human-readable summaryModified:
q2mm/models/forcefield.pyget_bounds()method returning(min, max)tuples matching the param vector layoutTesting
Design notes
The key insight for scipy integration with MM force fields: scipy's default finite-difference step for gradient estimation (~1e-8) is far too small for FF parameters with magnitudes of ~0.5-10. A step of 1e-3 reliably produces meaningful energy differences through the OpenMM evaluation pipeline. This is set via the
epsparameter and passed asoptions['eps']for minimize ordiff_stepfor least_squares.