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

Atomate2 OpenMM integration & broader classical MD framework #782

Merged
merged 265 commits into from
Sep 23, 2024

Conversation

orionarcher
Copy link
Contributor

@orionarcher orionarcher commented Mar 20, 2024

Developed by @xperrylinn and @orionarcher

Summary

This PR builds out support for OpenMM with a framework that could be extended to support other MD codes. Namely LAMMPS, Amber, and Gromacs. Rough visual example here

Core ideas:

  • Use the openff.interchange.Interchange object as a core engine-agnostic representation of an MD simulation.
  • Define a generic ClassicalMDTaskDocument and generic Interchange creation functions, then hand off responsibility for evolving the simulation to workflows for each MD engine. Currently only OpenMM support is implemented.
  • Support low-throughput workflows by making workflows that can easily output to local directories.
  • Use prev_task to pass meta-data between jobs. Since OpenMM is programmatic, the core information is not stored in the local directory.
  • No InputSets. Since OpenMM is programmatic, InputSets and InputGenerators don't make conceptual sense.

What's implemented:

  • Integration of Atomate2 and OpenFF for classical MD simulations
  • Support for energy minimization, NPT, NVT, and temperature change jobs
  • Implementation of annealing and production workflows
  • Serialization and deserialization of OpenFF objects (Molecule, Topology, Interchange, Quantity) with monty
  • Utility functions for generating OpenFF Interchange objects and creating molecule specifications

To do / open questions:

  • Need to add create conditional imports that fail nicely, where are some examples of this?

Future PR

  • Store trajectories in additional_stores, if available
  • The core openff.interchange.Interchange object can be larger than 16MB MongoDB doc limit. Need to implement a workaround by zipping the object and/or putting it on S3.
  • migrate schema dependencies to emmet
  • migrate utility dependencies to pymatgen

Related PRs:

  • PR to pymatgen would move most of atomate2.classical_md.utils upstream. PR #3729
  • PR to emmet would move atomate2.classical_md.schemas upstream. PR #975

Example usage

mol_specs_dicts = [
    {"smile": "CCO", "count": 10, "name": "ethanol"},
    {"smile": "O", "count": 200, "name": "water"},
]
inter_job = generate_interchange(mol_specs_dicts, mass_density=1)

production_maker = ProductionMaker(
    energy_maker=EnergyMinimizationMaker(),
    npt_maker=NPTMaker(steps=300000, pressure=1),
    anneal_maker=AnnealMaker.from_temps_and_steps(
        steps=1000000, anneal_temp=400, final_temp=300
    ),
    nvt_maker=NVTMaker(steps=5000000),
)

production_flow = production_maker.make(
    inter_job.output.interchange, 
    output_dir="my/directory/"
    prev_task=inter_job.output
)

wf = Flow([inter_job, production_flow])

run_locally(wf)

# will put outputs for the whole flow in "my/directory/"

Additional dependencies introduced

  • openmm
  • openff-toolkit
  • openff-interchange
  • packmol
  • openbabel

These are all necessary for the classical MD setup and execution workflow.

Checklist

Before a pull request can be merged, the following items must be checked:

  • Code is in the standard Python style.
    The easiest way to handle this is to run the following in the correct sequence on
    your local machine. Start with running ruff and ruff format on your new code. This will
    automatically reformat your code to PEP8 conventions and fix many linting issues.
  • Doc strings have been added in the Numpy docstring format.
    Run ruff on your code.
  • Type annotations are highly encouraged. Run mypy to
    type check your code.
  • Tests have been added for any new functionality or bug fixes.
  • All linting and tests pass.

Note that the CI system will run all the above checks. But it will be much more
efficient if you already fix most errors prior to submitting the PR. It is highly
recommended that you use the pre-commit hook provided in the repository. Simply run
pre-commit install and a check will be run prior to allowing commits.

…tion despite conflicting pydantic versioning between Interchange (using v1) and atomate2 (using v2)
@orionarcher
Copy link
Contributor Author

orionarcher commented Sep 11, 2024

@utf I believe I've addressed all comments and this is ready to merge.

EDIT: hold off actually, I forgot that I disabled the openmm tests because a new emmet release is needed. Pinging the MP team.

@orionarcher
Copy link
Contributor Author

orionarcher commented Sep 20, 2024

I've pinned the emmet pre-release to get tests passing. @utf are you good to merge this once the new emmet version is released and tested against? If so, maybe @janosh can merge once that happens so you don't need to circle back.

Copy link
Member

@janosh janosh left a comment

Choose a reason for hiding this comment

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

huge amount of work here! 👍

.github/workflows/testing.yml Show resolved Hide resolved
src/atomate2/openff/core.py Outdated Show resolved Hide resolved
src/atomate2/openff/utils.py Outdated Show resolved Hide resolved
src/atomate2/openff/utils.py Show resolved Hide resolved
src/atomate2/openff/utils.py Outdated Show resolved Hide resolved
src/atomate2/openmm/jobs/core.py Outdated Show resolved Hide resolved
src/atomate2/openmm/jobs/core.py Outdated Show resolved Hide resolved
src/atomate2/openmm/jobs/core.py Outdated Show resolved Hide resolved
src/atomate2/openmm/jobs/generate.py Outdated Show resolved Hide resolved
tests/openff_md/conftest.py Outdated Show resolved Hide resolved
@orionarcher
Copy link
Contributor Author

This is now pinned to the most recent version of emmet and ready to merge @utf.

Your previous suggestion to split out OpenMM and OpenFF was very good. They are now independent and the OpenMM workflows support MLFFs and can return structures to better interoperate with the rest of Atomate2.

- uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Set up micromamba
Copy link
Member

Choose a reason for hiding this comment

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

@utf i think it could help to have the micromamba-dependent MD CI be its own job or even its own test-md.yml workflow. that would enable only running the MD tests when any MD source files change and would also uncouple the remaining CI from any install/env issues micromamba might encounter

Copy link
Member

Choose a reason for hiding this comment

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

I'd be happy with that solution!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Using micromamba saves us from manually building enumlib so I favor keeping it in the main CI.

@utf
Copy link
Member

utf commented Sep 23, 2024

This really is fantastic. Thank you very much @orionarcher. @janosh, once you're happy I think we can merge.

@janosh janosh merged commit 3d6a3a3 into materialsproject:main Sep 23, 2024
6 checks passed
@rkingsbury
Copy link
Contributor

Amazing work, thanks for sticking with this @orionarcher !

@janosh janosh mentioned this pull request Nov 14, 2024
hrushikesh-s pushed a commit to hrushikesh-s/atomate2 that referenced this pull request Nov 16, 2024
…lsproject#782)

* Move remaining content from common.py to renamed base.py.

* Update core.py with skeleton code for openff_job and generate_interchange methods.

* Complete Calculation, CalculationInput, and CalculationOutput schemas for classical_md.openmm.tasks.py

* Implement BaseOpenMMMaker for classical_md.openmm workflow

* Update core jobs for classical_md.openmm to be compatible with new BaseOpenMMMaker

* Add MoleculeSpec to classical_md.schemas and modify OpenMMTaskDoc

* Implement attribute inheritance logic for base openmm maker and openmm jobs

* Add from/as_dict functions for openff topology, interchange, molecule, and quantity

* Fix serialization issues with conflicting pydantic versions between Interchange and atomate2

* Implement anneal and production workflows

* Update resolve_attr logic to set missing attributes

* Change ClassicalMDTaskDocument to OpenMMTaskDocument in base.py

* Store interchange intermediate as a JSON string to fix parsing issues

* Implement temperature change logic in TempChangeMaker

* Improve state reporter to append to state file

* Output taskdoc_json file to directory for easy building

* Enhance documentation for all components

* Implement micromamba for testing environment

* Change all docstrings to numpy format

* Add CodeCov for classical_md tests

* Rename "steps" argument to "n_steps" and "output_steps" to "steps" in CalculationOutput

* Add support for writing trajectory to HDF5 file

* Implement MDAReporter for trajectory output

* Add embed_traj argument to base_openmm_maker

* Add traj_blob keyword and switch interchange to type HexBytes

* Move classical_md schemas to emmet

* Implement OPLS force field support through ligpargen

* Create FauxInterchange object for OPLS compatibility

* Refactor OpenMMFlowMaker and BaseOpenMMMaker

* Add XMLMoleculeFF class for manipulating XML files representing OpenMM-compatible ForceFields

* Split utilities and jobs in jobs/opls.py into separate files

* Refactor utilities to isolate OpenFF dependency

* Add support for MACE-based interchanges

* Update OpenMM tutorial

* Support BaseOpenMMMaker returning structures

* Implement reading and writing of structure to/from OpenMMTaskDocument

---------

Co-authored-by: Alex Ganose <utf@users.noreply.github.com>
Co-authored-by: Orion Cohen <orioncohen@Orions-MBP.localdomain>
Co-authored-by: Janosh Riebesell <janosh.riebesell@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ecosystem Issues concerning the larger MP ecosystem enhancement Improvements to existing features feature A new feature being added schema pydantic/emmet schemas
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants