Molecule
Molecule class for representing molecular structures and computed properties.
Molecule
pydantic-model
Bases: BaseModel
Molecular structure with optional computed properties.
Can be created from SMILES, XYZ, or directly from atoms. Wraps stjames.Molecule internally but provides a cleaner interface.
Initialize from stjames.Molecule or keyword arguments.
Show JSON schema:
Config:
arbitrary_types_allowed:True
vibrational_modes
property
Vibrational modes from frequency calculation.
thermal_energy_correction
property
Thermal correction to energy (Hartree).
thermal_enthalpy_correction
property
Thermal correction to enthalpy (Hartree).
thermal_free_energy_correction
property
Thermal correction to Gibbs free energy (Hartree).
gradient
property
Nuclear gradient (Hartree/Bohr).
xrd_peaks
property
XRD reflections as (h, k, l, intensity) tuples.
band_structure
property
Electronic band structure and DOS (periodic systems only).
density_of_states
property
Total DOS as (energy in Hartree, k-weighted count) pairs (Fermi level = 0).
elastic_tensor
property
elastic_tensor: tuple[tuple[float, float, float, float, float, float], tuple[float, float, float, float, float, float], tuple[float, float, float, float, float, float], tuple[float, float, float, float, float, float], tuple[float, float, float, float, float, float], tuple[float, float, float, float, float, float]] | None
Elastic stiffness matrix in GPa (Voigt order: xx yy zz yz xz xy).
from_smiles
classmethod
Create molecule from SMILES string.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
smiles
|
str
|
SMILES string |
required |
Returns:
| Type | Description |
|---|---|
Self
|
molecule instance |
from_xyz
classmethod
Create Molecule from XYZ string.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
xyz_string
|
str
|
XYZ format string |
required |
charge
|
int | None
|
charge |
None
|
multiplicity
|
int | None
|
spin multiplicity |
None
|
Returns:
| Type | Description |
|---|---|
Self
|
molecule |
from_xyz_file
classmethod
Create molecule from XYZ file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str | Path
|
path to XYZ file |
required |
charge
|
int | None
|
charge |
None
|
multiplicity
|
int | None
|
spin multiplicity |
None
|
Returns:
| Type | Description |
|---|---|
Self
|
molecule |
molecules_from_sdf
classmethod
Read all records from an SDF file as a list of molecules.
Each record becomes one Molecule, in file order, with atom ordering preserved across records -- so a multi-conformer SDF reads as a consistent ensemble.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str | Path
|
path to the SDF file |
required |
Returns:
| Type | Description |
|---|---|
list[Self]
|
one Molecule per record |
from_stjames
classmethod
Create from stjames.Molecule.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
stj
|
Molecule
|
stjames.Molecule |
required |
Returns:
| Type | Description |
|---|---|
Self
|
molecule |
from_atoms
classmethod
from_atoms(atoms: list[Atom], charge: int = 0, multiplicity: int = 1, cell: PeriodicCell | None = None) -> Self
Create molecule from a list of atoms.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
atoms
|
list[Atom]
|
list of Atom objects |
required |
charge
|
int
|
molecular charge (default 0) |
0
|
multiplicity
|
int
|
spin multiplicity (default 1) |
1
|
cell
|
PeriodicCell | None
|
PeriodicCell for periodic boundary conditions |
None
|
Returns:
| Type | Description |
|---|---|
Self
|
molecule instance |
distance
Calculate distance between two atoms.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
i
|
int
|
first atom index (1-based) |
required |
j
|
int
|
second atom index (1-based) |
required |
Returns:
| Type | Description |
|---|---|
float
|
distance in Angstroms |
angle
Calculate angle between three atoms (i-j-k).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
i
|
int
|
first atom index (1-based) |
required |
j
|
int
|
central atom index (1-based) |
required |
k
|
int
|
third atom index (1-based) |
required |
degrees
|
bool
|
return angle in degrees (default) or radians |
True
|
Returns:
| Type | Description |
|---|---|
float
|
angle in degrees or radians |
dihedral
Calculate dihedral angle between four atoms (i-j-k-l).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
i
|
int
|
first atom index (1-based) |
required |
j
|
int
|
second atom index (1-based) |
required |
k
|
int
|
third atom index (1-based) |
required |
l
|
int
|
fourth atom index (1-based) |
required |
degrees
|
bool
|
return angle in degrees (default) or radians |
True
|
Returns:
| Type | Description |
|---|---|
float
|
dihedral angle in degrees (0-360) or radians |
perturb
Return a copy with random Gaussian noise added to each atom position.
Useful for breaking symmetry before resubmitting an optimization (e.g. when a calculation is stuck in a saddle point or converges to an unwanted geometry).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
stddev
|
float
|
standard deviation of the Gaussian displacement (Angstroms) |
0.005
|
Returns:
| Type | Description |
|---|---|
Molecule
|
new Molecule with perturbed coordinates |
displace_along_mode
Return a copy with atom positions displaced along a vibrational normal mode.
Requires a prior frequency calculation. For a transition state, the imaginary mode has a negative frequency and points toward the reactant or product.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mode
|
VibrationalMode
|
vibrational mode to displace along, from |
required |
displacement
|
float
|
displacement distance along the normalized mode (Angstroms) |
required |
Returns:
| Type | Description |
|---|---|
Molecule
|
new Molecule with displaced coordinates |
Raises:
| Type | Description |
|---|---|
ValueError
|
mode has no displacements or zero-norm displacements |
load_named_ligands
Load named ligands from a multi-molecule file.
Molecule names are read from the title field of each record. Use this when ligand identity needs to be preserved - for example, building a ligand dict for an RBFE workflow where names are used as keys throughout submission and results. Every record must therefore have a unique name; duplicates raise rather than silently collapsing into one ligand.
Supported formats (all carry per-molecule name fields):
- SDF / MOL (.sdf, .mol) - name from the title line
- MOL2 (.mol2) - name from the @<TRIPOS>MOLECULE block
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
Path | str
|
path to an SDF, MOL, or MOL2 file |
required |
Returns:
| Type | Description |
|---|---|
dict[str, Molecule]
|
dict mapping ligand name to Molecule, in file order |
Raises:
| Type | Description |
|---|---|
ValueError
|
no valid molecules are found, the format is unsupported, or two records share a name |
smiles_to_stjames
Convert a SMILES string to a stjames.Molecule object.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
smiles
|
str
|
string representing the SMILES notation of the molecule |
required |
Returns:
| Type | Description |
|---|---|
Molecule
|
|
Atom
pydantic-model
Bases: Base
A single atom.
:param atomic_number: atomic number :param position: Cartesian coordinates, in Å :param mass: mass, in Daltons; if None, most common isotopologue will be used
Show JSON schema:
{
"description": "A single atom.\n\n:param atomic_number: atomic number\n:param position: Cartesian coordinates, in \u00c5\n:param mass: mass, in Daltons; if None, most common isotopologue will be used",
"properties": {
"atomic_number": {
"minimum": 0,
"title": "Atomic Number",
"type": "integer"
},
"position": {
"maxItems": 3,
"minItems": 3,
"prefixItems": [
{
"type": "number"
},
{
"type": "number"
},
{
"type": "number"
}
],
"title": "Position",
"type": "array"
},
"mass": {
"anyOf": [
{
"type": "number"
},
{
"type": "null"
}
],
"default": null,
"title": "Mass"
}
},
"required": [
"atomic_number",
"position"
],
"title": "Atom",
"type": "object"
}
Fields:
-
atomic_number(NonNegativeInt) -
position(Vector3D) -
mass(float | None)
atomic_symbol
property
Atom(atomic_number=2, position=[0, 1, 2]).atomic_symbol 'He'
VibrationalMode
pydantic-model
Bases: Base
Vibrational mode from frequency analysis.
:param frequency: vibrational frequency, in cm⁻¹ :param reduced_mass: reduced mass, in amu :param force_constant: force constant, in mDyne/Å :param displacements: atomic displacement vectors, in Å :param ir_intensity: infrared intensity, in km/mol :param symmetry_label: irreducible representation of mode, interpreted per Molecule.symmetry point group (e.g. "A1", "B2g", "E'")
Show JSON schema:
{
"description": "Vibrational mode from frequency analysis.\n\n:param frequency: vibrational frequency, in cm\u207b\u00b9\n:param reduced_mass: reduced mass, in amu\n:param force_constant: force constant, in mDyne/\u00c5\n:param displacements: atomic displacement vectors, in \u00c5\n:param ir_intensity: infrared intensity, in km/mol\n:param symmetry_label: irreducible representation of mode, interpreted per Molecule.symmetry point group (e.g. \"A1\", \"B2g\", \"E'\")",
"properties": {
"frequency": {
"title": "Frequency",
"type": "number"
},
"reduced_mass": {
"title": "Reduced Mass",
"type": "number"
},
"force_constant": {
"title": "Force Constant",
"type": "number"
},
"displacements": {
"items": {
"maxItems": 3,
"minItems": 3,
"prefixItems": [
{
"type": "number"
},
{
"type": "number"
},
{
"type": "number"
}
],
"type": "array"
},
"title": "Displacements",
"type": "array"
},
"ir_intensity": {
"anyOf": [
{
"type": "number"
},
{
"type": "null"
}
],
"default": null,
"title": "Ir Intensity"
},
"symmetry_label": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Symmetry Label"
}
},
"required": [
"frequency",
"reduced_mass",
"force_constant",
"displacements"
],
"title": "VibrationalMode",
"type": "object"
}
Fields:
-
frequency(float) -
reduced_mass(float) -
force_constant(float) -
displacements(Vector3DPerAtom) -
ir_intensity(float | None) -
symmetry_label(str | None)
PeriodicCell
pydantic-model
Bases: Base
Unit cell for periodic systems.
:param lattice_vectors: 3x3 matrix of lattice vectors, in Å :param is_periodic: periodicity in each dimension
Show JSON schema:
{
"description": "Unit cell for periodic systems.\n\n:param lattice_vectors: 3x3 matrix of lattice vectors, in \u00c5\n:param is_periodic: periodicity in each dimension",
"properties": {
"lattice_vectors": {
"maxItems": 3,
"minItems": 3,
"prefixItems": [
{
"maxItems": 3,
"minItems": 3,
"prefixItems": [
{
"type": "number"
},
{
"type": "number"
},
{
"type": "number"
}
],
"type": "array"
},
{
"maxItems": 3,
"minItems": 3,
"prefixItems": [
{
"type": "number"
},
{
"type": "number"
},
{
"type": "number"
}
],
"type": "array"
},
{
"maxItems": 3,
"minItems": 3,
"prefixItems": [
{
"type": "number"
},
{
"type": "number"
},
{
"type": "number"
}
],
"type": "array"
}
],
"title": "Lattice Vectors",
"type": "array"
},
"is_periodic": {
"default": [
true,
true,
true
],
"maxItems": 3,
"minItems": 3,
"prefixItems": [
{
"type": "boolean"
},
{
"type": "boolean"
},
{
"type": "boolean"
}
],
"title": "Is Periodic",
"type": "array"
}
},
"required": [
"lattice_vectors"
],
"title": "PeriodicCell",
"type": "object"
}
Fields:
-
lattice_vectors(Matrix3x3) -
is_periodic(Bool3)
Validators:
-
check_tensor_3D→lattice_vectors -
check_pbc→is_periodic
from_string
classmethod
Create a PeriodicCell from a string representation.
PeriodicCell.from_string("[(1, -2, 3.0), [4e1, +5, 6], (7.1, 8, 9)]") PeriodicCell(lattice_vectors=((1.0, -2.0, 3.0), (40.0, 5.0, 6.0), (7.1, 8.0, 9.0)), is_periodic=(True, True, True)) PeriodicCell.from_string("[(a, -2, 3.0), [4e1, +5, 6], (7.1, 8, 9)]") Traceback (most recent call last): ... ValueError: Could not parse cell from string: [(a, -2, 3.0), [4e1, +5, 6], (7.1, 8, 9)] PeriodicCell.from_string("[(1, -2, 3.0), [4e1, +5, 6], (7.1, 8, 9, 10)]") Traceback (most recent call last): ... ValueError: Cell must be a 3x3 matrix: got [(1, -2, 3.0), [4e1, +5, 6], (7.1, 8, 9, 10)] PeriodicCell.from_string("[('a', -2, 3.0), [4e1, +5, 6], (7.1, 8, 9)]") Traceback (most recent call last): ValueError: Cell must be a 3x3 matrix of numbers: got [('a', -2, 3.0), [4e1, +5, 6], (7.1, 8, 9)]
Data models for periodic system properties.
BandStructure
pydantic-model
Bases: BaseModel
Electronic band structure for a periodic system.
Eigenvalues are shifted so the Fermi level is at 0.
:param kpoint_distances: cumulative distances along the k-path, in units of 2π/Å; length = n_kpoints :param eigenvalues: eigenvalues in Hartree (Fermi level = 0); shape (n_bands, n_kpoints) :param high_symmetry_points: high-symmetry k-point labels and their cumulative path distances in 2π/Å (e.g. [("Γ", 0.0), ("X", 1.23)]) :param total_density_of_states: density of states from a separate uniform k-mesh; list of (energy in Hartree, k-weighted count) pairs (Fermi level = 0) :param band_gap: band gap in Hartree :param valence_band_maximum: valence band maximum in Hartree (Fermi level = 0) :param conduction_band_minimum: conduction band minimum in Hartree (Fermi level = 0)
Show JSON schema:
{
"description": "Electronic band structure for a periodic system.\n\nEigenvalues are shifted so the Fermi level is at 0.\n\n:param kpoint_distances: cumulative distances along the k-path, in units of 2\u03c0/\u00c5; length = n_kpoints\n:param eigenvalues: eigenvalues in Hartree (Fermi level = 0); shape (n_bands, n_kpoints)\n:param high_symmetry_points: high-symmetry k-point labels and their cumulative path distances in 2\u03c0/\u00c5 (e.g. [(\"\u0393\", 0.0), (\"X\", 1.23)])\n:param total_density_of_states: density of states from a separate uniform k-mesh; list of (energy in Hartree, k-weighted count) pairs (Fermi level = 0)\n:param band_gap: band gap in Hartree\n:param valence_band_maximum: valence band maximum in Hartree (Fermi level = 0)\n:param conduction_band_minimum: conduction band minimum in Hartree (Fermi level = 0)",
"properties": {
"kpoint_distances": {
"items": {
"type": "number"
},
"title": "Kpoint Distances",
"type": "array"
},
"eigenvalues": {
"items": {
"items": {
"type": "number"
},
"type": "array"
},
"title": "Eigenvalues",
"type": "array"
},
"high_symmetry_points": {
"items": {
"maxItems": 2,
"minItems": 2,
"prefixItems": [
{
"type": "string"
},
{
"type": "number"
}
],
"type": "array"
},
"title": "High Symmetry Points",
"type": "array"
},
"total_density_of_states": {
"items": {
"maxItems": 2,
"minItems": 2,
"prefixItems": [
{
"type": "number"
},
{
"type": "number"
}
],
"type": "array"
},
"title": "Total Density Of States",
"type": "array"
},
"band_gap": {
"title": "Band Gap",
"type": "number"
},
"valence_band_maximum": {
"title": "Valence Band Maximum",
"type": "number"
},
"conduction_band_minimum": {
"title": "Conduction Band Minimum",
"type": "number"
}
},
"required": [
"kpoint_distances",
"eigenvalues",
"high_symmetry_points",
"total_density_of_states",
"band_gap",
"valence_band_maximum",
"conduction_band_minimum"
],
"title": "BandStructure",
"type": "object"
}
Fields:
-
kpoint_distances(list[float]) -
eigenvalues(list[list[float]]) -
high_symmetry_points(list[tuple[str, float]]) -
total_density_of_states(list[tuple[float, float]]) -
band_gap(float) -
valence_band_maximum(float) -
conduction_band_minimum(float)