Tutorial: Classify ice#

Load a mixed ice-water LAMMPS dump, print CHILL+ counts, and compare them to cage membership on the same frame.

Prerequisites#

  • Python 3.12+

  • pydseams installed: pip install pydseams

  • The engine fixture dump, either:

    • from a PydSEAMSlib checkout: tests/data/exampleTraj.lammpstrj

    • from seams-core: input/traj/exampleTraj.lammpstrj (same file)

A wheel already links the C++ engine. The seams CLI lives in seams-core; Lua is dseams in yodaStruct. This tutorial does not run those front ends.

Learning Objectives#

By the end of this tutorial you will be able to:

  1. Load one configuration with ds.read

  2. Classify every analysed oxygen with Frame.chill_plus

  3. Score hexagonal-cage and double-diamond-cage membership with Frame.cages

  4. Read IceCounts and CageScore

  5. Point at the seams CLI and the Lua dseams module when you want those front ends

Step 1: Install pydseams#

pip install pydseams

pydseams is the Python package. import pydseamslib is a compatibility alias of pydseams. Requires Python 3.12+.

Step 2: Locate the fixture dump#

From a PydSEAMSlib checkout, at the repository root, the vendored copy is tests/data/exampleTraj.lammpstrj.

That file is the seams-core engine fixture input/traj/exampleTraj.lammpstrj. If you installed from PyPI only, copy the seams-core path and pass that filename to ds.read.

Step 3: Load the frame#

import pydseams as ds

frame = ds.read("tests/data/exampleTraj.lammpstrj")
print(frame.n_atoms)
print(frame.atom_type)

ds.read looks at the suffix and calls the matching constructor. .lammpstrj goes through Frame.from_file, which keeps LAMMPS type 2 (oxygen) when that type is present.

Expected output:

250
2

read keeps the 250 oxygen atoms. Classification does not write files.

Step 4: Classify with CHILL+#

print(frame.chill_plus())

Expected output:

IceCounts(interClathrate=12, water=238)

These counts are the engine fixture result for seams-core input/traj/exampleTraj.lammpstrj, vendored here as tests/data/exampleTraj.lammpstrj. CHILL+ labels each oxygen from its four neighbours: 12 interfacial clathrate (three eclipsed bonds) and 238 water.

IceCounts is a histogram. counts.cubic and counts["cubic"] are the same value. Missing labels read as 0.

Step 5: Score cages#

print(frame.cages())

Expected output:

CageScore(n_ih=0, n_ic=0, n_water=250)

cages() scores complete hexagonal cages (HC, ice Ih) and double-diamond cages (DDC, ice Ic). This mixed snapshot has no finished HC or DDC, so every oxygen stays water under the cage score. n_ih, n_ic, and n_water are atom counts, not cage counts.

Default cages() is the seeded (hysteresis) construction. Pass seeded=False for cutoff-graph affiliation on this frame’s six-rings.

CHILL+ and cages answer different questions on the same cloud. CHILL+ is a four-neighbour local label. Cages require a finished HC or DDC.

Step 6: The same engine elsewhere#

Frame calls the compiled module yoda. Same session:

from pydseams import yoda

print(yoda.__doc__)
print(type(frame.cloud))

Expected output includes d-SEAMS compiled surface (yoda) and <class 'pydseams.yoda.PointCloudDouble'>.

The seams CLI in seams-core and require("dseams") in yodaStruct run libyodaLib, the same engine yoda binds. Use those projects for the command-line and Lua workflows. Stay on Frame for Python.

Troubleshooting#

ModuleNotFoundError: No module named 'pydseams'#

Install into the active interpreter:

python -m pip install pydseams

FileNotFoundError on the dump#

From a checkout, run at the repository root or pass an absolute path to tests/data/exampleTraj.lammpstrj. From PyPI, copy seams-core input/traj/exampleTraj.lammpstrj.

Counts do not match the fixture#

The numbers above are the engine fixture result for that dump. A different trajectory, frame index, cutoff, or atom_type produces a different histogram. ds.read(path, frame=1) is 1-indexed.

You want the CLI or Lua#

Do not compile yoda from this tutorial. Install seams-core for seams, and yodaStruct for require("dseams").

Next Steps#

Summary#

You learned to:

  1. Install pydseams and load the engine fixture dump

  2. Call ds.read to get a Frame

  3. Print CHILL+ labels with frame.chill_plus()

  4. Print HC / DDC membership with frame.cages()

  5. Leave the seams CLI and Lua dseams module to their own repositories