ChemicalSystem vs PLAMS Molecule

Use scm.base.ChemicalSystem for new code. It is the newer, preferred representation of chemical structures in AMS, it is the one that will be developed further, and it is backed by the compiled scm.base implementation instead of a pure Python molecule container.

PLAMS scm.plams.Molecule remains fully supported and is still useful in existing PLAMS workflows, but for new structure-building and structure-manipulation code, prefer ChemicalSystem.

Most examples use scm.base.ChemicalSystem; some older examples still use scm.plams.Molecule.

Quick Comparison

Topic

ChemicalSystem

PLAMS Molecule

Status for new code

Preferred AMS structure class for new scripting.

Legacy but still supported; best kept for existing PLAMS-heavy workflows.

Included with AMS

Yes, it is part of the amspython stack. No additional installation required.

Yes, it is part of the amspython stack. No additional installation required.

Installation in separate Python environments

Downloading or upgrading it in a separate Python environment requires valid SCM credentials, but once installed there is no runtime license check and it keeps working.

Standard free open-source Python package on PyPI.

Implementation

Backed by the compiled scm.base layer, so structure operations are typically much faster.

Implemented as a Python object model in PLAMS.

API growth

This is where new functionality is being added.

Not the main focus for future structure API development.

Atom indexing

Zero-based, like normal Python arrays: cs.atoms[0] is the first atom.

One-based for mol[i] access: mol[1] is the first atom.

Total charge

Explicit attribute: cs.charge.

Stored in the settings-like dictionary: mol.properties.charge.

Engine-specific atom data

Typed attribute groups such as atom.adf, atom.forcefield, atom.qe. Enable the attribute group first, for example cs.enable_atom_attributes("adf").

Stored as free-form data in atom.properties.suffix

End-of-line atom strings in AMS input

Typed (e.g. atom.mass), or through atom.qe.label = "H1".

Set through atom.properties.suffix

Selections and regions

Built in: selections, regions, species analysis, splitting, mapping, and comparison helpers are part of the class.

Usually handled by separate PLAMS helpers or by custom Python code.

Periodic systems

Native lattice support with many dedicated methods for periodic manipulations.

Supports mol.lattice, but the structure API is less rich.

Serialization

Round-trips naturally to AMS system blocks and KF files, preserving more AMS-specific information.

Can read and write many formats, but AMS-specific metadata is often represented more loosely.

Conversions

Built-in conversions to and from ASE and RDKit, plus conversion to and from PLAMS Molecule.

Strong ecosystem inside PLAMS and converters to ASE, RDKit, and ChemicalSystem.

Important Differences

  1. ChemicalSystem uses normal Python-style atom indexing.

    first_atom = cs.atoms[0]
    second_atom = cs.atoms[1]
    

    With PLAMS, the mol[i] shorthand is one-based:

    first_atom = mol[1]
    second_atom = mol[2]
    
  2. Total charge is a real attribute on ChemicalSystem.

    cs.charge = -1
    print(cs.charge)
    

    In PLAMS, the corresponding value lives in the molecule properties dictionary:

    mol.properties.charge = -1
    print(mol.properties.charge)
    
  3. Engine-specific atom annotations are typed in ChemicalSystem.

    For example, in PLAMS one often wrote:

    mol[1].properties.suffix = "adf.f=frag1"
    

    With ChemicalSystem, first enable the relevant attribute group and then use the typed attribute:

    cs.enable_atom_attributes("adf")
    cs.atoms[0].adf.f = "frag1"
    

    The same idea applies to other end-of-line AMS atom data such as force-field types.

  4. ChemicalSystem exposes more structure-manipulation functionality directly on the class.

    This includes dedicated support for regions, selections, splitting and combining systems, periodic cell manipulation, atom-species determination, geometry changes, structure comparisons, and conversion helpers.

Migration Examples

Charge

# PLAMS
mol.properties.charge = 1

# ChemicalSystem
cs.charge = 1

Atom annotations

# PLAMS
mol[1].properties.suffix = "forcefield.type=O_water"

# ChemicalSystem
cs.enable_atom_attributes("forcefield")
cs.atoms[0].forcefield.type = "O_water"

Index conversion

# PLAMS atom 5 corresponds to ChemicalSystem atom 4
plams_atom = mol[5]
chemsys_atom = cs.atoms[4]

Convert between both classes

from scm.utils.conversions import chemsys_to_plams_molecule, plams_molecule_to_chemsys

cs = plams_molecule_to_chemsys(mol)
mol = chemsys_to_plams_molecule(cs)

When PLAMS Molecule Still Makes Sense

PLAMS Molecule is still a reasonable choice when you are working inside an existing PLAMS workflow that already expects Molecule objects everywhere, or when you want to reuse older PLAMS examples with minimal changes.

For new scripts, especially if you are directly manipulating AMS systems or engine-specific atom data, ChemicalSystem is usually the better starting point.

Installation and Licensing

Both ChemicalSystem and PLAMS are included by default in the amspython distribution that ships with AMS. If you use amspython, there is normally nothing extra to install.

Installation is only needed if you want to use a separate Python environment.

See also