Skip to content

Example Gallery

Short, runnable workflows that each take a molecular description to a simulation-ready object in a handful of lines. The examples span the capability spectrum — a single small molecule, a packed solvent box, virtual-site models, and polymer systems (the stress test for MolPy's editing machinery). Every example links to the in-depth guide that explains the steps behind it.

For a fully narrated, step-by-step walkthrough — including the full LAMMPS export — start with the Quickstart.

Small molecule — parse, type, export

Parse a SMILES string, add hydrogens and coordinates, and assign OPLS-AA types.

import molpy as mp

mol = mp.io.smiles.read_smiles("CCO").to_atomistic() # ethanol from SMILES (heavy atoms)
mol, _ = mp.conformer.Conformer(add_hydrogens=True, seed=42).generate(
 mol
) # add hydrogens + 3D coordinates
typifier = mp.ff.typifier.OplsAaTypifier() # embedded OPLS-AA table
typed = typifier.typify(mol) # assign force-field types
ff = typifier.forcefield() # the parameters it assigned

frame = typed.to_frame() # simulation-ready columnar arrays
# mp.io.write_lammps_data(...) + mp.io.write_lammps_forcefield(path, ff, frame)
# write system.data + system.ff (set frame.box and a per-atom mol_id first —
# see the Quickstart).

See also: Parsing Chemistry · Force Field Typification.

Solvent box — pack 500 waters

Build one molecule, then fill a cube with clash-free copies through molpack (pip install molcrafts-molpack).

# docs: skip — optional molcrafts-molpack; not a molpy runtime/doc dep
import molpy as mp
from molpack import GencanPack, Target

water = mp.Atomistic(name="water")
o = water.add_atom(atomic_number=8, x=0.000, y=0.000, z=0.000)
h1 = water.add_atom(atomic_number=1, x=0.957, y=0.000, z=0.000)
h2 = water.add_atom(atomic_number=1, x=-0.239, y=0.927, z=0.000)
water.add_bond(o, h1)
water.add_bond(o, h2)

target = (
 Target(water.to_frame(), count=500)
.with_name("water")
.with_restraint(mp.core.Cuboid([0.0, 0.0, 0.0], [30.0, 30.0, 30.0]))
)
packed = GencanPack().with_seed(42).run([target], max_loops=200).frame
# → one packed Frame (1500 atoms)

See also: Packing Systems.

Virtual sites — TIP4P water

Augment a water molecule with an off-atom M-site on the HOH bisector. The builder copies the input, places the site, and redistributes charge.

import molpy as mp
from molpy.builder import Tip4pBuilder

water = mp.Atomistic(name="water")
o = water.add_atom(atomic_number=8, x=0.000, y=0.000, z=0.000, charge=-0.834)
h1 = water.add_atom(atomic_number=1, x=0.957, y=0.000, z=0.000, charge=0.417)
h2 = water.add_atom(atomic_number=1, x=-0.239, y=0.927, z=0.000, charge=0.417)
water.add_bond(o, h1)
water.add_bond(o, h2)

# The M-site carries the oxygen's charge, so the input must already have one.
water4p = Tip4pBuilder(d_om=0.1546).apply(
 water
) # d_om: O–M distance in Å (TIP4P/2005); input unchanged

See also: Polarizable & Virtual-Site Models.

Polymer topologies — one monomer, six architectures

Guides and scripts share names under parallel trees. Every unit is a CGsmiles fragment whose bonding descriptors are its ports, every topology is a CGsmiles string, and mp.builder.Assembler with mp.builder.GrowthPlacer grows it into an mp.Atomistic.

Docs Examples
user-guide/topology/ examples/topology/
01_linear.md … 06_telechelic.md 01_linear.py … 06_telechelic.py
cd examples
python topology/01_linear.py

Minimal linear chain, ten EO units:

# run from examples/topology/ or put that dir on PYTHONPATH
import molpy as mp
from eo_kit import library

sites = mp.io.cgsmiles.read_cgsmiles("{[#EO]|10}").to_coarsegrain()
chain = mp.builder.Assembler(library(), mp.builder.GrowthPlacer()).assemble(sites, mp.Atomistic)

See also: Polymer Topologies · Assembly.

Carbon nanotubes — topology from chirality

Build open or axially periodic zigzag, armchair, and chiral tubes without a public planning object:

import molpy as mp
from molpy.builder import CarbonTubeBuilder

zigzag = mp.Atomistic.from_frame(CarbonTubeBuilder(8, 0, length=30.0).build())
armchair = mp.Atomistic.from_frame(
    CarbonTubeBuilder(6, 6, cells=4, periodic=True).build()
)
chiral = mp.Atomistic.from_frame(CarbonTubeBuilder(6, 3, cells=2).build())
chiral.generate_topology(gen_angle=True, gen_dihedral=True)

See also: Nanostructures.

Polydisperse melt — Schulz-Zimm distribution

Sample a reproducible chain population from a molecular-weight distribution.

import numpy as np
import molpy as mp
from molpy.builder import (
    PolydisperseChainGenerator,
    SchulzZimmPolydisperse,
    SystemPlanner,
    WeightedSequenceGenerator,
)

# Mn = 1500 Da, Mw = 3000 Da, total mass ≈ 500 kDa
planner = SystemPlanner(
 PolydisperseChainGenerator(
 WeightedSequenceGenerator({"EO": 1.0}),
 {"EO": 44.05},
 distribution=SchulzZimmPolydisperse(1500, 3000),
),
 target_total_mass=5e5,
)
plan = planner.plan_system(np.random.default_rng(42))
print(f"Planned {len(plan.chains)} chains") # reproducible chain population

# Each planned chain is a unit sequence; written as CGsmiles it is a site graph.
from eo_kit import library  # examples/topology/

first = plan.chains[0]
sites = mp.io.cgsmiles.read_cgsmiles("{" + "".join(f"[#{m}]" for m in first.monomers) + "}").to_coarsegrain()
chain = mp.builder.Assembler(library(), mp.builder.GrowthPlacer()).assemble(sites, mp.Atomistic)

See also: Polydisperse Systems · Packing Systems.

AmberTools pipeline — GAFF2 parameters

Build a GAFF2 PEO chain the way AMBER residues are made: antechamber types one oligomer whose head, chain and tail monomers are already bonded, prepgen cuts it into three residues (spreading the omitted atoms' charge over the atoms each keeps), and tleap sequence joins them. AmberPieces writes the oligomer and its cuts from three SMILES; the site graph is the sequence.

Requires AmberTools

This workflow shells out to antechamber, parmchk2, prepgen and tleap. Install AmberTools and activate its environment first.

# docs: skip — needs AmberTools
import molpy as mp

pieces = mp.builder.AmberPieces(head="COCC", repeat="OCC", tail="OCCOC")
oligomer, cuts = pieces.oligomer(seed=42)  # CH3O(CH2CH2O)3CH3 and its head/chain/tail cuts

sites = mp.io.cgsmiles.read_cgsmiles("{[#PEO]|10}").to_coarsegrain()  # head, 8 x chain, tail
built = mp.builder.AmberPolymerBuilder(
    {"PEO": oligomer}, {"PEO": cuts}, parameter_set="gaff2"
).assemble(sites)
peo = built.chain  # CH3-(OCH2CH2)10-OCH3: typed graph, 79 atoms
ff = built.forcefield  # units real, AMBER 1-4 scaling declared

ff merges with the force field of a small molecule typed natively (AtdTypifier, Am1BccModel, GaffTypifier), as the AmberTools guide does for TFSI.

See also: AmberTools Integration · Assembly.