scan3d (3D restrained grid scan)¶
scan3d relaxes every point of a grid over three coordinates of a layered enzyme structure with harmonic restraints and the ML/MM calculator, records the energy without the restraints, and draws the energy volume as isosurfaces in an HTML page. Each axis is a range: a distance (i,j,low,high) in Å, an angle (i,j,k,low,high), or a dihedral (i,j,k,l,low,high) in degrees.
What it is for¶
Reactions that involve three coordinates at once: see the energy landscape when, for example, a bond forms, another breaks, and a proton moves in the same step.
Redrawing a finished grid: plot an existing
surface.csvagain over another energy range (--csv).Judging the result:
surface.csvmarks every point as converged or not, andresult.jsongivesscientific_status.
The ML region uses UMA (Meta) by default; -b/--backend also selects ORB, MACE, AIMNet2, or DFT (dft). For a single path driven by one or more coordinates, use scan; for two coordinates, use scan2d.
Examples¶
Here complex.pdb contains the full system matching real.parm7, and ml_region.pdb selects its ML region without link hydrogens.
The atoms are those of the bundled enzyme example (examples/beza/1.R.pdb), whose PDB has an empty chain column. Each atom is therefore written with three fields, residue name, residue number, and atom name, in any order and separated by commas or spaces ("SAM,320,CS1").
1. From a YAML spec¶
Write the three ranges under pairs: and add --out-json to also get result.json. With the default step of 0.2 Å, this file gives a 9 × 9 × 7 grid (567 points).
# scan3d.yaml
pairs:
- ["SAM,320,CS1", "GPP,321,C7", 1.50, 3.00]
- ["GPP,321,H11", "GLU,186,OE2", 0.90, 2.50]
- ["SAM,320,SD", "SAM,320,CS1", 1.80, 3.00]
mlmm scan3d -i complex.pdb --parm7 real.parm7 --model-pdb ml_region.pdb -q 0 \
-s scan3d.yaml --out-json -o ./result_scan3d/
Open result_scan3d/scan3d_density.html in a browser for the isosurfaces; result.json gives scientific_status and the number of usable points (n_points_usable).
2. Inline literal¶
The same three ranges can be written on the command line as one literal.
mlmm scan3d -i complex.pdb --parm7 real.parm7 --model-pdb ml_region.pdb -q 0 \
-s '[("SAM,320,CS1","GPP,321,C7",1.50,3.00),("GPP,321,H11","GLU,186,OE2",0.90,2.50),("SAM,320,SD","SAM,320,CS1",1.80,3.00)]'
3. L-BFGS, dump, and pre-optimization¶
Optimize the input before the scan, relax each point with L-BFGS, keep the inner-loop trajectories, and measure the relative energies from the lowest usable point. --max-step-size 0.20, --opt-mode grad, and --baseline min are the defaults, written out here.
mlmm scan3d -i complex.pdb --parm7 real.parm7 --model-pdb ml_region.pdb -q 0 \
-s '[("SAM,320,CS1","GPP,321,C7",1.50,3.00),("GPP,321,H11","GLU,186,OE2",0.90,2.50),("SAM,320,SD","SAM,320,CS1",1.80,3.00)]' \
--max-step-size 0.20 --dump -o ./result_scan3d/ --opt-mode grad \
--preopt --baseline min
4. Re-plot an existing surface.csv¶
Redraw the isosurfaces of a finished grid over −10 to 40 kcal/mol; no energy is computed. A separate -o keeps the files of the original scan (see Notes).
mlmm scan3d --csv ./result_scan3d/surface.csv --zmin -10 --zmax 40 -o ./result_scan3d_replot/
How it works¶
Starting structure and grid: The ML-region charge comes from
-qor-l. With--preopt, the input is first optimized without restraints; if that does not converge, the input geometry is used. Each axis gets ceil(|high − low| / h) + 1 evenly spaced values, both ends included, where h is--max-step-size(Å) for a distance and--max-angle-step-sizeor--max-dihedral-step-size(degrees) for an angle or dihedral. The values are visited from the one closest to the starting structure.Three nested loops: For each d₁ value, the structure is relaxed with only the d₁ restraint; for each d₂ value, with the d₁ and d₂ restraints; the inner loop then scans d₃ with all three restraints. Each relaxation starts from the nearest structure that has already converged in the same loop; until one has, it starts from the structure the enclosing loop produced (the starting structure for d₁).
Relaxation at each point: A harmonic restraint E = ½ k (q − q_target)² holds each coordinate q at its target (k is
--restraint-k), and L-BFGS (--opt-mode grad, default) or RFO (rational function optimization,--opt-mode hess) relaxes the rest with the ML/MM calculator; the atoms of the Frozen-MM layer stay fixed. The energy is then computed without the restraints, and the structure is written undergrid/.Table and figure: After the last point, all points go into
surface.csv. The usable points are interpolated with radial basis functions (RBF) on a 50 × 50 × 50 grid, and eight semi-transparent isosurfaces with banded colors are drawn inscan3d_density.html. With--csv, only this step runs, on the given table.
Reading surface.csv¶
surface.csv has one row per grid point and one reference row.
Column |
Meaning |
|---|---|
|
Grid indices. Index 0 is the value closest to the starting structure, so the indices follow the visiting order, not ascending values |
|
Coordinate values measured after the relaxation. The |
|
Restraint targets of the point |
|
Energy without the restraints (Hartree) |
|
Whether the restrained relaxation converged |
|
|
|
Energy relative to the baseline (kcal/mol) |
|
Axis labels used in the figure |
Reference row:
i = j = k = -1andis_preopt = truehold the starting structure. The row stays in the table but is never a grid point, a baseline, or a plotted point.Usable points: a point is usable when its relaxation converged, its energy is finite, and its structure was written. Only usable points set the baseline and enter the figure.
Verdict: in
result.json(--out-json),scientific_statusissuccesswhen every grid point is usable,partialwhen only some are (exit status 0), andfailedwhen none is (exit status 1);n_points_attemptedandn_points_usablegive the counts.Next step: the isosurfaces are interpolated, so take a structure from a computed point near the saddle,
grid/point_*.pdb, and pass it totsopt; points in the reactant and product basins can be inputs forpath-search.Re-plotting a table (
--csv): the table needsd1_A,d2_A,d3_A, andenergy_hartreeorenergy_kcal. The reference row and rows withbias_converged = falseor a non-finite energy are left out.
Output files¶
After a run, --out-dir contains the following files.
result_scan3d/
├─ surface.csv # grid table with the reference row
├─ scan3d_density.html # 3D isosurfaces (open in a browser)
├─ grid/
│ ├─ point_i150_j090_k180.xyz # relaxed structure of each grid point
│ ├─ preopt_iDDD_jDDD_kDDD.xyz # starting structure (the reference row)
│ └─ inner_path_d1_000_d2_000_trj.xyz # inner-loop trajectory for each (d₁, d₂) pair (--dump)
└─ result.json # summary (--out-json); summary.json holds the same content
Start with scan3d_density.html and surface.csv; the structure of each point is under grid/. In result.json, grid_points[] maps each grid index to its values, targets, energy, convergence, and structure file.
File names: the number after
i,j, ork(the tagDDD) is the target × 100 (Å, or degrees for an angle), padded to at least three digits, not the grid index ofsurface.csv:d1 = 1.50 Å, d2 = 0.90 Å, d3 = 1.80 Ågivespoint_i150_j090_k180.xyz, and an angle of 120° gives12000. When two points round to the same tag, the later file name gets_grid_III_JJJ_KKKwith the zero-based indices; the numbers ininner_path_d1_000_d2_000are zero-based indices too.Other formats: each structure is also written as
.pdb(--no-convert-filesturns this off), with the layer of each atom in the B-factor column: 0 for the ML region, 10 for Movable-MM, and 20 for Frozen-MM. mmCIF input, and PDB input too large for the PDB columns, also get.ciffiles with the original identifiers.With
--csv: onlyscan3d_density.htmlis written, plusresult.json(withoutgrid_points) with--out-json.scientific_statusissuccesswhen the table has a usable point andfailedotherwise.
Main options¶
The options shared by every ML/MM calculation command are explained once in ML/MM options; the table below lists only the options specific to scan3d.
Option |
Type |
Default |
Description |
|---|---|---|---|
|
path |
|
Full-system structure ( |
|
integer |
|
Charge of the ML region. Required unless |
|
integer |
|
Spin multiplicity (2S+1) of the ML region |
|
text |
|
Total charge of the unknown ligand residues (e.g. |
|
text |
|
Three ranges as a YAML/JSON spec file or one inline literal: distance |
|
path |
|
Output directory |
|
float |
|
Largest grid spacing of a distance axis (Å) |
|
float |
|
Largest grid spacing of an angle axis (degrees) |
|
float |
|
Largest grid spacing of a dihedral axis (degrees) |
|
float |
|
Restraint strength k (eV/Ų for distances, eV/rad² for angles); alias |
|
|
|
Relaxation of each point: L-BFGS / RFO |
|
flag |
|
Optimize the input without restraints before the scan |
|
flag |
|
Write the inner-loop (d₃) trajectory for each (d₁, d₂) pair under |
|
|
|
Zero of |
|
float |
interpolated min / max |
Lower and upper ends of the energy range over which the eight isosurfaces are placed (kcal/mol) |
|
text |
|
Convergence preset of each relaxation ( |
|
path |
|
Read a finished |
|
flag |
|
Write a summary to |
See the generated CLI reference for every option.
Note: In YAML (
--config), thelbfgs(oropt.lbfgs) section applies with--opt-mode gradand therfo(oropt.rfo) section with--opt-mode hess. Trajectories are written only with--dump; YAMLopt.dumpis not used.
Notes¶
Three ranges in one literal:
-stakes exactly three ranges, in one inline literal or underpairs:in a YAML/JSON file. For staged scans, usescan.For a PDB with chains, the positional form
A:SAM:320:CS1picks one atom without ambiguity.Grid size: the number of relaxations is the product of the three axis lengths and grows quickly (567 for example 1). Start with a larger
--max-step-sizeor narrower ranges.--baseline first: zero is put at point(i, j, k) = (0, 0, 0)when it is usable; otherwise the run prints[baseline] 'first' requested but usable (i=0,j=0,k=0) is missing; using the usable minimum instead.and uses the lowest usable point.Frozen atoms: the atoms given by
--freeze-atomsor YAMLgeom.freeze_atoms, and the atoms of the Frozen-MM layer, stay fixed in every relaxation. A scanned coordinate whose atoms are all frozen is an error.Check the spec without computing:
--dry-runreads the input, the charge and spin, and-s, prints the plan, and exits without any optimization. With--csv, it checks only the options.Cycle limit:
--relax-max-cycles(default100000) limits each relaxation; an explicit value overrides YAMLopt.max_cycles, and without it the YAML value applies.Too few usable points: with fewer than four usable points, or with all of them in one plane, only the figure is skipped. The run prints
[plot] NOTE: Volume plot skipped: …, still writessurface.csv(andresult.jsonwith--out-json, listing no figure), and exits with status 0. With no usable point it prints[plot] No finite data for plotting.and exits with status 1.Re-plot warning: a table without the
bias_convergedorartifact_writtencolumn is still read, with[plot] WARNING: CSV lacks complete point provenance; …; thesurface.csvwritten byscan3dhas noartifact_writtencolumn, so re-plotting it prints this warning, andresult.jsonthen has non_points_usable.Re-plotting into the scan directory: with or without
--csv, a run without--out-jsonremovesresult.jsonandsummary.jsonfrom--out-dir, a run with it overwrites them, and every run removes the oldscan3d_density.htmlbefore drawing a new one. To keep the files of the original scan, give--csvanother-o, as in example 4.
See also¶
scan — staged scans of one or more coordinates from one structure
scan2d — energy map over two coordinates
opt — single-structure optimization before or after a scan
tsopt — optimize a structure near the saddle into a TS
path-search — MEP through structures taken from the grid
all — end-to-end workflow
Troubleshooting — diagnosing failed runs