Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
# Changelog

## Release 0.1.5

- Split the Molecular Liquids benchmarks into four separately scored benchmarks:
`water_radial_distribution`, `water_density`, `solvent_radial_distribution`, and
`solvent_density`, all grouped under the `"Molecular Liquids"` category
- Add a `data_name` attribute (and `data_dir` property) to `Benchmark` so that
several benchmarks can share the same input data directory and HuggingFace archive.
- Add `Water density` and `Solvent density` UI pages showing the equilibrium-density
summary statistics and a per-frame density time series against the experimental
reference.
- Add the `nve_energy_conservation` benchmark, which runs short NVE (constant-energy)
MD simulations across a set of gas-phase and solvated systems and scores how well a
model conserves the total energy, quantified by the drift of the total energy over
the trajectory.

## Release 0.1.4

- Add an Apache-2.0 `LICENSE` file and declare the license in `pyproject.toml`.
Expand Down
2 changes: 2 additions & 0 deletions docs/source/api_reference/benchmark.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ Benchmark

.. automethod:: __init__

.. autoproperty:: data_dir

.. automethod:: run_model

.. automethod:: analyze
Expand Down
20 changes: 20 additions & 0 deletions docs/source/api_reference/general/nve_energy_conservation.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
.. _nve_energy_conservation_api:

NVE energy conservation
=======================

.. module:: mlipaudit.benchmarks.nve_energy_conservation.nve_energy_conservation

.. autoclass:: NVEEnergyConservationBenchmark

.. automethod:: __init__

.. automethod:: run_model

.. automethod:: analyze

.. autoclass:: NVEEnergyConservationResult

.. autoclass:: NVEStructureResult

.. autoclass:: NVEEnergyConservationModelOutput
8 changes: 6 additions & 2 deletions docs/source/api_reference/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Base classes and utilities
scoring
utils/trajectory_helpers
utils/inference_and_simulation
utils/molecular_liquids
ui

Benchmark implementations
Expand All @@ -32,11 +33,14 @@ Benchmark implementations
small_molecules/ring_planarity
small_molecules/reference_geometry_stability
small_molecules/bond_length_distribution
small_molecules/radial_distribution
small_molecules/solvent_radial_distribution
small_molecules/reactivity
small_molecules/nudged_elastic_band
molecular_liquids/water_radial_distribution
molecular_liquids/solvent_radial_distribution
molecular_liquids/water_density
molecular_liquids/solvent_density
biomolecules/folding_stability
biomolecules/sampling
general/stability
general/scaling
general/nve_energy_conservation
20 changes: 20 additions & 0 deletions docs/source/api_reference/molecular_liquids/solvent_density.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
.. _solvent_density_api:

Solvent Density
===============

.. module:: mlipaudit.benchmarks.solvent_density.solvent_density

.. autoclass:: SolventDensityBenchmark

.. automethod:: __init__

.. automethod:: run_model

.. automethod:: analyze

.. autoclass:: SolventDensityResult

.. autoclass:: SolventDensityStructureResult

.. autoclass:: SolventDensityModelOutput
18 changes: 18 additions & 0 deletions docs/source/api_reference/molecular_liquids/water_density.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
.. _water_density_api:

Water Density
=============

.. module:: mlipaudit.benchmarks.water_density.water_density

.. autoclass:: WaterDensityBenchmark

.. automethod:: __init__

.. automethod:: run_model

.. automethod:: analyze

.. autoclass:: WaterDensityResult

.. autoclass:: WaterDensityModelOutput
16 changes: 16 additions & 0 deletions docs/source/api_reference/utils/molecular_liquids.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
.. _molecular_liquids_helpers_api:

Molecular Liquids Helpers
=========================

.. module:: mlipaudit.utils.molecular_liquids

.. autofunction:: compute_densities

.. autofunction:: average_equilibrated_density

.. autofunction:: run_water_npt_simulation

.. autofunction:: run_solvent_npt_simulations

.. autofunction:: get_solvent_system_names
1 change: 1 addition & 0 deletions docs/source/benchmarks/general/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ applicable across molecular systems.

Stability <stability>
Scaling <scaling>
NVE energy conservation <nve_energy_conservation>
76 changes: 76 additions & 0 deletions docs/source/benchmarks/general/nve_energy_conservation.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
.. _nve_energy_conservation:

NVE energy conservation
=======================

Purpose
-------

To assess how well a machine-learned interatomic potential (**MLIP**) conserves the total
mechanical energy during microcanonical (**NVE**) molecular dynamics (**MD**). Energy
conservation is a fundamental physical requirement: under **NVE** dynamics, with no
thermostat exchanging energy with the environment, the total energy
:math:`E(t) = \mathrm{PE}(t) + \mathrm{KE}(t)` should stay constant. A systematic drift
indicates unphysical forces or an inconsistency between the model's energy and its
gradient.

Description
-----------

For each system in the dataset, the benchmark runs a short **NVE** (velocity-Verlet, no
thermostat) **MD** simulation with the **MLIP**, with velocities initialized from a
Maxwell-Boltzmann distribution at **300 K**, leveraging
`jax-md <https://github.com/google/jax-md>`_ as integrated via the
`mlip <https://github.com/instadeepai/mlip>`_ library. The potential and kinetic energies
are recorded at regular snapshots, and the total-energy drift relative to the first frame,
:math:`\Delta E(t) = E(t) - E(0)`, is fitted with a linear model.

The **energy-conservation metric** is the magnitude of the fitted drift over the whole
trajectory, normalized by the kinetic-energy fluctuation scale:

.. math::

r = \frac{\lvert \text{slope} \rvert \cdot T}{\sigma_{\mathrm{KE}}}

where :math:`T` is the trajectory duration and :math:`\sigma_{\mathrm{KE}}` is the
standard deviation of the kinetic energy along the trajectory. This dimensionless ratio is
mapped to a score in :math:`[0, 1]` via the standard soft threshold: a ratio at or below
**1.0** scores **1.0**, and larger ratios decay exponentially.

The threshold of **1.0** is set at the point where the systematic energy drift accumulated
over the whole trajectory reaches the same magnitude as the natural kinetic-energy
fluctuations: a ratio :math:`r \le 1` keeps the drift within the thermal noise floor, while
:math:`r > 1` means the drift dominates over those fluctuations. This is a deliberately
lenient threshold. Analogous energy-conservation tests for classical force fields typically
use a far tighter ratio, on the order of **0.01**; the more permissive value here reflects
a fundamental difference between the two. A classical force field is an analytic expression
whose potential-energy surface is smooth by construction, whereas an **MLIP** is a highly
parameterized model whose potential-energy surface is learned from finite training data.
While the model is trained to reproduce the training data, it is not guaranteed to be
smooth in between training points, as the interpolation between them can exhibit
high-frequency roughness. This roughness manifests as steep, sudden gradients, which the
MD integrator can struggle with. The resulting numerical error can accumulate and drive
larger integration drift compared to a classical force field. The threshold of **1.0** is
therefore chosen to be lenient enough to accommodate this behavior, while still being
strict enough to flag models that are clearly unphysical.

Dataset
-------

The dataset comprises four representative systems spanning vacuum, bulk liquid and solvated
regimes:

- Small molecule (HCNO) in vacuum
- Bulk water (500 molecules)
- Solvated peptide (Oxytocin)
- Solvated peptide with counter-ions (Neurotensin)

Systems whose elements the model cannot handle are skipped individually rather than
skipping the whole benchmark.

Interpretation
--------------

A score of **1.0** indicates excellent energy conservation, i.e. the total-energy drift is
small relative to the natural kinetic-energy fluctuations. A score approaching **0.0**
indicates a strongly drifting, non-conservative trajectory.
65 changes: 65 additions & 0 deletions docs/source/benchmarks/molecular_liquids/density.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
.. _density:

Density
=======

Purpose
-------

This benchmark assesses the ability of machine-learned interatomic potentials (**MLIP**) to
reproduce the **equilibrium density** of molecular liquids. Density is a fundamental
thermodynamic property: a model that predicts accurate local structure (see the
:ref:`radial_distribution` benchmark) may still get the density badly wrong if the simulation
box expands or collapses. Reproducing the correct density is therefore a complementary and
necessary check on the physical realism of a liquid-phase simulation.

Description
-----------

The benchmark runs the same **MD** simulation as the :ref:`radial_distribution` benchmark: an
**NPT** simulation using the **MLIP** model for **500,000 steps**, leveraging the
`jax-md <https://github.com/google/jax-md>`_ engine from the
`mlip <https://github.com/instadeepai/mlip>`_ library. Water is run at **295.15 K** and **1 atm**,
while all other solvents are run at **293.15 K** and **1 atm**. Because the :ref:`radial_distribution` and density
benchmarks of a system share their input systems and simulation output, the simulation is only
run once when both benchmarks are run together.

The density of each frame is computed from the (fluctuating) simulation cell volume:

.. math::

\rho = \frac{N_\text{mol} \, M}{N_A \, V}

where :math:`N_\text{mol}` is the number of molecules in the box, :math:`M` is the molecular
weight, :math:`N_A` is Avogadro's number and :math:`V` is the cell volume. The **equilibrium
density** is taken as the average density over the final four fifths of the trajectory (the
first fifth is discarded as equilibration).

Dataset
-------

The benchmark uses the same equilibrated input boxes as the :ref:`radial_distribution` benchmark
(a 500-molecule TIP3P water box, and methanol / acetonitrile / CCl4 boxes built with the GAFF
force field in OpenMM).

Reference densities are the experimental values at the simulation conditions: water
:math:`0.9978\ \text{g/cm}^3` [#f1]_, CCl4 :math:`1.594\ \text{g/cm}^3` [#f2]_, methanol
:math:`0.792\ \text{g/cm}^3` [#f2]_ and acetonitrile :math:`0.787\ \text{g/cm}^3` [#f2]_.

Interpretation
--------------

Performance is quantified by the **density deviation**, the absolute difference between the
equilibrium density and the experimental reference. The deviation should be **as low as
possible**. The score is derived from the *relative* deviation (deviation divided by the
reference density) so that it is comparable across liquids of very different densities: a
relative deviation within roughly **2%** scores close to 1, decaying gently beyond that. (The
ideal per-solvent target is ultimately set by the isothermal compressibility of the liquid.) A
large deviation typically indicates that the box has expanded or collapsed during the
simulation, and the density time series can be inspected on the results page to diagnose this.

References
----------

.. [#f1] L. B. Skinner et al., J. Chem. Phys. 138, (2013). DOI: https://doi.org/10.1063/1.4790861
.. [#f2] PubChem Compounds Collection https://pubchem.ncbi.nlm.nih.gov/compound
3 changes: 2 additions & 1 deletion docs/source/benchmarks/molecular_liquids/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ Molecular Liquids
=================

Molecular Liquids benchmarks are focused on the properties and dynamics of molecular liquids,
including as initial benchmark its radial distribution function.
including their radial distribution function and equilibrium density.


.. toctree::
:maxdepth: 1

Radial distribution function <radial_distribution>
Density <density>
29 changes: 18 additions & 11 deletions docs/source/benchmarks/molecular_liquids/radial_distribution.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@ and emergent properties of liquid systems.
Description
-----------

The benchmark performs an **MD** simulation using the **MLIP** model in the **NVT** ensemble at
**300 K** for **500,000 steps**, leveraging the `jax-md <https://github.com/google/jax-md>`_ engine
from the `mlip <https://github.com/instadeepai/mlip>`_ library. The starting configuration is already
The benchmark performs an **MD** simulation using the **MLIP** model in the **NPT** ensemble for **500,000 steps**,
leveraging the `jax-md <https://github.com/google/jax-md>`_ engine from the
`mlip <https://github.com/instadeepai/mlip>`_ library. Water is run at **295.15 K** and **1 atm**,
while all other solvents are run at **293.15 K** and **1 atm**. The starting configuration is already
equilibrated. For every specific atom pair (e.g., **oxygen-oxygen** in water) the radial distribution
function (**RDF** or **g(r)**) is calculated from the simulation.
function (**RDF** or **g(r)**) is calculated from the simulation. The equilibrium
density of the same simulation is assessed separately in the :ref:`density` benchmark.

.. figure:: img/rdf.png
:figwidth: 35%
Expand All @@ -44,25 +46,30 @@ where:
- :math:`\delta` is the Dirac delta function,
- and the angle brackets denote an ensemble average.

For each system, the benchmark compares **MLIP**-predicted **RDF** against
experimental reference data. Performance is quantified using the following metrics:
For each system, the benchmark compares the **MLIP**-predicted **RDF** against
reference data. The metric depends on what reference data is available:

- **Mean Absolute Error (MAE)**
- **Root Mean Square Error (RMSE)**
- For **water**, a full experimental **RDF** curve is available, so we compute the
**Mean Absolute Error (MAE)** and **Root Mean Square Error (RMSE)** of the predicted
**RDF** against it, together with the deviation of the first-shell peak position.
- For the **other solvents**, only the reference first-solvation-shell peak positions
are known, so performance is quantified by the **deviation of the predicted first-peak
position** from the reference (no MAE/RMSE).

Dataset
-------
For the water radial distribution benchmark we set up a cubic box of 500 water molecules using OpenMM and the TIP3P water model.
For the :ref:`water radial distribution benchmark <water_radial_distribution_api>` we set up a cubic box of 500 water molecules using OpenMM and the TIP3P water model.
We equilibrated the box in the NPT ensemble at standard conditions and extracted the final snapshot as input for the benchmark.
For the solvent radial distribution benchmark, we initialized the solvent boxes (methanol, acetonitrile, CCl4) by stacking randomly rotated molecules
For the :ref:`solvent radial distribution benchmark <solvent_radial_distribution_api>`, we initialized the solvent boxes (methanol, acetonitrile, CCl4) by stacking randomly rotated molecules
to yield a cubic box with a target side-length of 28 Å at the experimental density. We equilibrated the box in the NPT ensemble using the GAFF force field and OpenMM.

We use the experimental water RDF profile of Skinner et al.\ [#f1]_ as reference data. For other solvents (methanol\ [#f2]_, acetonitrile\ [#f3]_, CCl4\ [#f4]_), we use the
location of the first solvation shell peaks as reference data.

Interpretation
--------------
The **MAE** and **RMSE** of the **RDF** should be **as low as possible**. These metrics
The relevant error — the **MAE**/**RMSE** of the **RDF** for water, or the first-peak
deviation for the other solvents — should be **as low as possible**. These metrics
are likely to vary significantly for different molecular liquids and temperature conditions.
**The error should be compared per liquid type and then examined in more detail for specific
molecular interactions** to identify areas where the **MLIP** struggles to reproduce the correct
Expand Down
6 changes: 3 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "mlipaudit"
version = "0.1.4"
version = "0.1.5"
description = "Library and CLI tool for benchmarking ML Interatomic Potentials"
readme = "README.md"
authors = [
Expand All @@ -27,7 +27,7 @@ requires-python = ">=3.11"
dependencies = [
"huggingface-hub>=0.33.4",
"mdtraj>=1.10.3",
"mlip>=0.2.0,<0.3.0",
"mlip>=0.2.2,<0.3.0",
"scikit-learn>=1.7.0",
"streamlit>=1.46.1",
"vl-convert-python>=1.8.0",
Expand All @@ -45,7 +45,7 @@ build-backend = "hatchling.build"

[project.optional-dependencies]
cuda = [
"mlip[cuda13]>=0.2.0,<0.3.0",
"mlip[cuda13]>=0.2.2,<0.3.0",
]

[dependency-groups]
Expand Down
Loading
Loading