Molecular Density Fitting Using 3D Gaussian Functions
This project implements a molecular density fitting approach that optimizes the correlation between an experimental density map and a synthetic density map originating from molecular dynamics using 3D Gaussian functions. The algorithm generates a force in the direction that increases the correlation between the simulated and effective maps. It also allows adjusting anisotropically the spread parameter (sigma) in each direction.
- Efficient simulation of density maps using 3D Gaussian functions.
- Optimization of molecular coordinates and sigma parameters to improve fit.
- Calculation of the correlation coefficient to measure fit quality.
- Use of numerical and analytical methods to compute derivatives.
- Implementation optimized with Numba for high performance.
OpenFit requires Python 3.10+, NumPy, SciPy and Numba.
# Core install
pip install openfit
# With OpenMM integration, density-map I/O, plotting, and the PDB workflow
pip install "openfit[all]"Available extras: openmm (molecular dynamics integration), io (density-map
I/O with mrcfile + trajectory I/O with mdtraj), pdb (the
MolScene-based PDB/CIF workflow), and
viz (matplotlib). all installs every extra.
Fit a structure into a density map in one call. With a structure-based (OpenSMOG) model:
from openfit import Fit
fit = Fit.from_smog("model.AA.gro", "model.AA.top", "model.AA.xml", "target.mrc")
fit.refine(steps=50_000) # bias an OpenMM MD run toward the density
print("correlation:", fit.cc)
fit.save("refined.pdb")Fit also offers from_amber(pdb, map) and from_system(topology, system, positions, map)
(bring your own OpenMM force field). See examples/4ake/ for a
complete, runnable flexible-fitting example (open→closed adenylate kinase).
Without any force field, use the DensityMap engine to rasterize particles,
score the map correlation, and optimize coordinates:
Each particle is an anisotropic 3D Gaussian set by its coordinates, per-axis
widths sigma, and a weight epsilon (often the atomic mass):
import numpy as np
from openfit import DensityMap
n = 100
coordinates = np.random.default_rng(0).uniform(0, 40, size=(n, 3))
sigma = np.full((n, 3), 2.0)
epsilon = np.ones(n) # per-particle weight (e.g. mass)
dm = DensityMap(experimental_map, voxel_size=[1, 1, 1]) # a 3D numpy array
dm.set_coordinates(coordinates, sigma=sigma, epsilon=epsilon)
print("cc:", dm.correlation())
grad = dm.gradient() # (n, 7): d(cc)/d(x, y, z, sx, sy, sz, epsilon)
dm.fit(n_iter=200) # gradient ascent on the coordinates (no MD)
dm.save_mrc("simulated.mrc")With the pdb extra (MolScene):
import molscene
from openfit import DensityMap
scene = molscene.Scene.from_pdb("structure.pdb")
dm = DensityMap.from_scene(scene) # coordinates + atomic-mass weights
dm.save_mrc("structure_density.mrc")OpenFit installs an openfit command:
# prebuilt SMOG structure-based model
openfit refine --smog model.AA.gro model.AA.top model.AA.xml target.mrc \
-o refined.pdb --steps 50000
# pick a force field from a single structure:
openfit refine --pdb model.pdb target.mrc -o refined.pdb # Amber14
openfit refine --charmm model.pdb target.mrc -o refined.pdb # CHARMM36
openfit refine --awsem model.pdb target.mrc -o refined.pdb # OpenAWSEM (coarse-grained)
openfit refine --smog-structure model.pdb target.mrc -o refined.pdb # generate SMOG model (needs SMOG 2)
# or drive it from a YAML config (needs the `cli` extra: pip install "openfit[cli]")
openfit run config.yamlThe config file mirrors the flags:
smog: [model.AA.gro, model.AA.top, model.AA.xml]
# or: pdb: model.pdb | charmm: model.pdb | awsem: model.pdb | smog_structure: model.pdb
map: target.mrc
output: refined.pdb
output_map: fitted.mrc # optional
steps: 50000
k: 6400
update_interval: 100See the examples/ directory and the
documentation for the full guide.
OpenFit adds a density-fitting potential to a standard force field,
where the cross-correlation (c.c.) between the experimental and simulated
densities over the voxels
The simulated density rasterizes each atom as an anisotropic 3D Gaussian; OpenFit computes it and the analytical gradient of the correlation with respect to the coordinates and Gaussian widths, and applies the corresponding force. The full derivation — the Gaussian integral over each voxel (via the error function) and the correlation derivatives — is in the user guide.
© 2024-2026, Carlos Bueno
Carlos Bueno was supported by the MolSSI Software Fellowship, under the mentorship of Jessica Nash. We thank AMD (Advanced Micro Devices, Inc.) for the donation of high-performance computing hardware and HPC resources. This project is also supported by the Center for Theoretical Biological Physics (NSF Grants PHY-2019745 and PHY-1522550), with additional support from the D.R. Bullard Welch Chair at Rice University (Grant No. C-0016 to PGW). Project based on the Computational Molecular Science Python Cookiecutter version 1.11.