M-Chem database (.db) format

An M-Chem .db file is a standard SQLite 3 database that stores a parameterized molecular system: global force-field metadata, per-particle state, and bonded / non-bonded force terms. M-Chem reads these files as the primary input for MD simulations.

Conceptually, a .db is the output of force-field parameterization for one specific structure, rather than the type-based force field definition. It holds system-assigned atom types, enumerated bonded and non-bonded terms, coordinates, and simulation metadata for that instance. This is analogous to a GROMACS .tpr file, an OpenMM System object, or the AMBER prmtop + inpcrd pair combined: each encodes a ready-to-run parameterized system.

Overview

Every mchem database contains:

  1. A `meta` table — one row of system-wide force-field settings (AMOEBA polynomial coefficients, VdW combining rules, etc.).

  2. A `class` table — maps each term table name to the Python dataclass used to deserialize rows.

  3. One or more term tables — each row is one force term; column names match dataclass field names in mchem.terms.

  4. Optional `box` table (class Box) holds periodic cell lengths and angles from PDB CRYST1 when a box was present at conversion time.

Example file

tests/data/DHFR.db is a full AMOEBA-parameterized dihydrofolate reductase system produced from tests/data/DHFR.pdb. It illustrates a production-sized database:

Selected tables in DHFR.db

Table

Rows

Particle

23,558

AmoebaBond

16,569

Multipole

23,558

AmoebaTorsionTorsionGrid

625

box

1

Inspect it with any SQLite client:

sqlite3 tests/data/DHFR.db ".schema"
sqlite3 tests/data/DHFR.db "SELECT * FROM meta;"
sqlite3 tests/data/DHFR.db "SELECT tablename, clsname FROM class;"

Programmatic access:

from mchem.system import System

system = System("tests/data/DHFR.db")
print(system.meta["name"])           # DHFR
print(len(system["Particle"]))       # 23558
print(system["box"][0].a)          # 61.645 (Angstroms)

Required system tables

meta

Exactly one row. Columns are created dynamically from keys passed to mchem.system.System.addMeta() when the system is built (typically from force-field XML via mchem.forcefield.base.ForceField.createSystem()).

For DHFR.db, columns include:

meta columns in DHFR.db

Column

Meaning (typical)

name

System / topology name (e.g. DHFR)

bondCubic

AMOEBA bond cubic coefficient

bondQuartic

AMOEBA bond quartic coefficient

angleCubic

AMOEBA angle cubic coefficient

angleQuartic

AMOEBA angle quartic coefficient

anglePentic

AMOEBA angle quintic coefficient

angleSextic

AMOEBA angle sextic coefficient

opbendType

Out-of-plane bend type (e.g. ALLINGER)

opbendCubic

Out-of-plane bend cubic coefficient

opbendQuartic

Out-of-plane bend quartic coefficient

opbendPentic

Out-of-plane bend quintic coefficient

opbendSextic

Out-of-plane bend sextic coefficient

type

Non-bonded type label (e.g. BUFFERED-14-7)

radiusrule

VdW radius combining rule (e.g. CUBIC-MEAN)

radiustype

Radius definition (e.g. R-MIN)

radiussize

Radius size convention (e.g. DIAMETER)

epsilonrule

Epsilon combining rule (e.g. HHG)

vdw_13_scale

1-3 VdW scale factor

vdw_14_scale

1-4 VdW scale factor

vdw_15_scale

1-5 VdW scale factor

ubCubic

Urey-Bradley cubic coefficient

ubQuartic

Urey-Bradley quartic coefficient

Exact columns depend on which force generators ran for that system.

class

Maps SQLite table namePython class name (must exist in mchem.system’s internal registry or be registered explicitly).

Example from DHFR.db:

tablename              clsname
---------------------  ------------------------
Particle               Particle
AmoebaBond               AmoebaBond
box                      Box
...

The table name used in SQL may differ from clsname when terms are stored under a custom name (e.g. CMAPTable1 mapping to CMAPTable). Always use the name in class.tablename when querying.

Term tables

Each term table corresponds to one mchem.terms.base.TermList in memory. Column names equal dataclass field names; SQLite types are inferred from Python types:

Python type

SQLite type

int float str bool list

INTEGER FLOAT TEXT INTEGER TEXT (space- separated ints)

On load, list fields (e.g. IsotropicPolarization.grp) are split from space-separated text back into integers.

Particle indices

Bonded terms reference particles by integer indices p0, p1, … that match Particle.idx. Per-particle terms use idx.

Common term types (AMOEBA / DHFR.db)

Table / class

Role

Particle

Atom index, name, element, mass, residue, coordinates, velocities

AmoebaBond

Bond stretch (p0, p1, b0, kb, cubic, quartic)

AmoebaAngle

Valence angle

AmoebaAngleInPlane

In-plane valence angle (4 atoms)

AmoebaOutOfPlaneBend

Out-of-plane bend

PeriodicTorsion

Fourier dihedral (up to 6 terms)

AmoebaPiTorsion

Pi-system torsion (6 atoms)

AmoebaStretchBend

Stretch–bend coupling

AmoebaUreyBradley

Urey–Bradley 1–3 distance term

AmoebaTorsionTorsion

Torsion–torsion coupling (links to grid)

AmoebaTorsionTorsionGrid

2D grid points (angle1, angle2, f, gridIdx)

AmoebaVdw147

Buffered 14-7 VdW per particle

Multipole

Charge, dipole, quadrupole, axis frame

IsotropicPolarization

Polarizability, Thole, group list

Box (table box)

Cell lengths and angles (Å, degrees)

Field-level definitions live in mchem.terms.bonded and mchem.terms.nonbonded (also exposed in the API Reference).

Other term classes (HarmonicBond, CMAP, PairList, MBUCB terms, etc.) produce additional tables when present in a system; their schemas follow the same dataclass-column rule.

Sample rows (DHFR.db)

Periodic box (cubic 61.645 Å, 90° angles):

a=61.645  b=61.645  c=61.645  alpha=90  beta=90  gamma=90

First particle (MET N):

idx=0  name=N  element=N  mass=14.0067  resnum=1  resname=MET
xx=35.334  xy=19.608  xz=36.364  vx=vy=vz=0

First bond (particles 0–1):

p0=0  p1=1  b0=0.1015  kb=193258.96  cubic=-25.5  quartic=379.3125  paramIdx=69

Writing and reading

Create via CLI:

mchem-tools convert -i structure.pdb -o system.db -f amoebabio18.xml

Create / update in Python:

from mchem.forcefield import ForceField
from mchem.fileformats import load_pdb, read_pdb_box
from mchem.system import System, Box

top = load_pdb("structure.pdb")
system = ForceField("amoebabio18.xml").createSystem(top)
box = read_pdb_box("structure.pdb")
if box is not None:
    system.addTerm(Box(*box), "box")
system.save("system.db", overwrite=True)

Load:

system = System("system.db")
bonds = system["AmoebaBond"]

Custom term types: define a dataclass, call mchem.system.register_term_class() before System(path), and ensure the class table’s clsname matches the registered class name.

Implementation notes

  • On save, mchem uses a transaction, sets PRAGMA journal_mode=WAL and PRAGMA synchronous=OFF, then commits.

  • Term rows are sorted before insert by particle columns p0, p1, … (or idx when no p* fields exist) for stable, diff-friendly ordering.

  • Saving with overwrite=False (default) raises if the output file already exists.

  • The loader requires meta and class tables; unknown clsname values raise unless registered.

See also