ChemicalSystem vs PLAMS Molecule
********************************

ChemicalSystem PLAMS Technical

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".


Conversion ChemicalSystem ↔ PLAMS Molecule
==========================================

   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)


Quick Comparison
================

+--------------------------+----------------------------------------+----------------------------------------+
| Topic                    | "ChemicalSystem"                       | "PLAMS Molecule"                       |
|==========================|========================================|========================================|
| Status for new code      | Preferred AMS structure class for new  | Legacy but still supported; best kept  |
|                          | scripting.                             | for existing PLAMS-heavy workflows.    |
+--------------------------+----------------------------------------+----------------------------------------+
| Included with AMS        | Yes, it is part of the "amspython"     | Yes, it is part of the "amspython"     |
|                          | stack. No additional installation      | stack. No additional installation      |
|                          | required.                              | required.                              |
+--------------------------+----------------------------------------+----------------------------------------+
| Installation in separate | Downloading or upgrading it in a       | Standard free open-source Python       |
| Python environments      | separate Python environment requires   | package on PyPI.                       |
|                          | valid SCM credentials, but once        |                                        |
|                          | installed there is no runtime license  |                                        |
|                          | check and it keeps working.            |                                        |
+--------------------------+----------------------------------------+----------------------------------------+
| Implementation           | Backed by the compiled "scm.base"      | Implemented as a Python object model   |
|                          | layer, so structure operations are     | in PLAMS.                              |
|                          | typically much faster.                 |                                        |
+--------------------------+----------------------------------------+----------------------------------------+
| API growth               | This is where new functionality is     | Not the main focus for future          |
|                          | being added.                           | structure API development.             |
+--------------------------+----------------------------------------+----------------------------------------+
| Atom indexing            | Zero-based, like normal Python arrays: | One-based for "mol[i]" access:         |
|                          | "cs.atoms[0]" is the first atom.       | "mol[1]" is the first atom.            |
+--------------------------+----------------------------------------+----------------------------------------+
| Total charge             | Explicit attribute: "cs.charge".       | Stored in the settings-like            |
|                          |                                        | dictionary: "mol.properties.charge".   |
+--------------------------+----------------------------------------+----------------------------------------+
| Engine-specific atom     | Typed attribute groups such as         | Stored as free-form data in            |
| data                     | "atom.adf", "atom.forcefield",         | "atom.properties.suffix"               |
|                          | "atom.qe". Enable the attribute group  |                                        |
|                          | first, for example                     |                                        |
|                          | "cs.enable_atom_attributes("adf")".    |                                        |
+--------------------------+----------------------------------------+----------------------------------------+
| End-of-line atom strings | Typed (e.g. "atom.mass"), or through   | Set through "atom.properties.suffix"   |
| in AMS input             | "atom.qe.label = "H1"".                |                                        |
+--------------------------+----------------------------------------+----------------------------------------+
| Selections and regions   | Built in: selections, regions, species | Usually handled by separate PLAMS      |
|                          | analysis, splitting, mapping, and      | helpers or by custom Python code.      |
|                          | comparison helpers are part of the     |                                        |
|                          | class.                                 |                                        |
+--------------------------+----------------------------------------+----------------------------------------+
| Periodic systems         | Native lattice support with many       | Supports "mol.lattice", but the        |
|                          | dedicated methods for periodic         | structure API is less rich.            |
|                          | manipulations.                         |                                        |
+--------------------------+----------------------------------------+----------------------------------------+
| Serialization            | Round-trips naturally to AMS system    | Can read and write many formats, but   |
|                          | blocks and KF files, preserving more   | AMS-specific metadata is often         |
|                          | AMS-specific information.              | represented more loosely.              |
+--------------------------+----------------------------------------+----------------------------------------+
| Conversions              | Built-in conversions to and from ASE   | Strong ecosystem inside PLAMS and      |
|                          | and RDKit, plus conversion to and from | converters to ASE, RDKit, and          |
|                          | PLAMS Molecule.                        | "ChemicalSystem".                      |
+--------------------------+----------------------------------------+----------------------------------------+


Important Differences and Migration Examples
============================================

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 Molecule, 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 Molecule one often wrote:

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

   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"
      cs.atoms[0].mass = 1.234

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

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.


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
========


Related examples
----------------

* Molecule Tools for Inspection and Manipulation

* Complete guide to storing and converting PLAMS Molecules between
  Python libraries and file formats

* ChemicalSystem: Getting Started With AMS System Blocks


Related tutorials
-----------------

* Python scripting with PLAMS tutorial

* Building molecules tutorial


Related documentation
---------------------

* Chemical System overview

* Amsterdam Modeling PySuite installation

* ChemicalSystem atoms, bonds, and elements

* ChemicalSystem conversion to and from Python libraries

* PLAMS molecule API

* PLAMS AMS interface and system-block notes
