Spatial¶
Textbook guide to the spatial distribution function (SDF) — the full 3-D generalization of \(g(r)\) in a body-fixed molecular frame.
1. Body-fixed density clouds¶
- Pick reference atoms on the central molecule and a template geometry.
- Kabsch-align those atoms each frame → body-fixed axes.
- Accumulate target-atom density \(\rho(\mathbf{x}_\mathrm{body})\) on a grid.
Normalized by bulk density,
\[
g_\mathrm{SDF}(\mathbf{x}) = \rho(\mathbf{x}_\mathrm{body})/\rho_\mathrm{bulk},
\]
so isotropic RDF shells become lobes (lone pairs, \(\pi\)-stacking, ion
approaches). An optional orientations block adds per-voxel mean orientation of
a head–tail vector on the target species.
2. Usage¶
import numpy as np
import molpy as mp
rng = np.random.default_rng(0)
xyz = rng.uniform(0.0, 20.0, size=(200, 3))
frame = mp.Frame()
frame["atoms"] = {"x": xyz[:, 0], "y": xyz[:, 1], "z": xyz[:, 2]}
frame.box = mp.Box.cubic(20.0)
import numpy as np
from molpy.compute import SpatialDistribution
sdf = SpatialDistribution(
reference=[0, 1, 2],
template=np.array([[0.0, 0.0, 0.0], [0.76, 0.59, 0.0], [-0.76, 0.59, 0.0]]),
target=[2],
n=(32, 32, 32),
extent=(8.0, 8.0, 8.0),
bulk_density=0.033,
)
result = sdf([frame])
result.density, result.g_sdf
3. Pitfalls¶
- Template atom order mismatch → garbage body frame.
- Sparse 3-D histograms need many frames.
- Extent too small clips the first shell.