Classify ice on the mixed TIP4P example

You classify one in-tree frame two ways: CHILL+ (a four-neighbour staggered/eclipsed star per oxygen) and topological cages (HC/DDC membership). The result is a labelled oxygen set and a reason the two scores disagree.

Prerequisites

  • A seams-core checkout. Work from the repository root so input/traj/ is a child.

  • seams on PATH (pixi run build produces ./bbdir/seams; nix build produces ./result/bin/seams).

  • The in-tree dump input/traj/exampleTraj.lammpstrj (one frame, 750 atoms, 250 TIP4P waters; LAMMPS type 2 oxygen, type 1 hydrogen).

Python and Lua are not required. The Frame tutorial lives in pydseams. Lua is dseams.

Learning Objectives

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

  1. Read a LAMMPS dump with seams read and name the oxygen type.

  2. Run CHILL+ and read the four-neighbour star histogram.

  3. Run cages on the same oxygens and read HC / DDC membership.

  4. State why the two scores disagree on this mixed frame.

Step 1: Read the frame

seams read input/traj/exampleTraj.lammpstrj

Expected output starts nop 250 frame 1 box .... The CLI guesses oxygen (type 2, then type 1). Pass --type 2 on the classifiers so the type is explicit.

Step 2: CHILL+ from the CLI

CHILL+ looks at each oxygen’s bonded neighbours. The default list (--graph cutoff) bonds every pair closer than --cutoff. --graph mutual keeps the mutual four nearest neighbours (kNearestNeighbourList, k = 4); there --cutoff is the cell-size hint. Each of those four bonds is staggered or eclipsed from the pair correlation c_ij. The star of four labels is the ice type:

label

four-neighbour star

cubic

four staggered

hexagonal

three staggered and one eclipsed

clathrate

four eclipsed

interClathrate

three eclipsed

interfacial

ice-like, not one of the above

water

fewer than four bonds, or none of the above

seams chill-plus input/traj/exampleTraj.lammpstrj --cutoff 3.5 --type 2

Expected output:

nop 250 interClathrate 12 water 238
seams chill-plus input/traj/exampleTraj.lammpstrj --cutoff 3.5 --type 2 --graph mutual
nop 250 clathrate 1 interClathrate 7 water 242

label

atoms

clathrate

1

interClathrate

7

water

242

This dump is confined mixed TIP4P. One oxygen has four eclipsed bonds. Seven have three eclipsed bonds. The rest are water. Original CHILL (seams chill) labels every oxygen water. The four-neighbour stars do not close a cubic or hexagonal ice motif.

Step 3: Cages from the CLI

Cages ask a different question: does this oxygen belong to a complete hexagonal cage (HC, ice Ih, 12 waters) or a complete double-diamond cage (DDC, ice Ic, 14 waters)? The search walks primitive six-rings on a bonded graph. The default graph is --graph seeded: mutual four-nearest seeds, union completions.

seams cages input/traj/exampleTraj.lammpstrj --type 2

Expected output:

nop 250 graph seeded hexagonal 0 cubic 0 water 250

This mixed frame has no complete HC or DDC.

Step 4: Why the two scores differ

CHILL+ is a four-neighbour star. A molecule is cubic or hexagonal when its four bonds look like ice, even if those neighbours do not close a cage.

Cages are topological unit matching (TUM). A molecule is ice Ih only when it belongs to a hexagonal cage. It is ice Ic only when it belongs to a double-diamond cage. Otherwise it is water. Partial ice-like order is water on that score.

On this mixed frame the cutoff list labels 12 oxygens interfacial clathrate, and the mutual four-neighbour list labels one clathrate and seven interfacial clathrate. TUM finds no complete HC or DDC. A three-eclipsed star is not cage membership.

The longer argument is CHILL+ versus cages.

Step 5: A cubic crystal

The 4096-molecule cubic mW dump (input/traj/mW_cubic.lammpstrj, type 1) is the opposite case: every molecule is in a DDC, and CHILL+ reports cubic ice.

seams cages input/traj/mW_cubic.lammpstrj --type 1
seams chill-plus input/traj/mW_cubic.lammpstrj --type 1

On a perfect cubic lattice the four cage graphs (cutoff, knn, knn-union, seeded) coincide. The mixed TIP4P frame is the one that separates the two scores.

Step 6: Python, the same lists

Python is not built in this repository. Install the package the paper uses:

pip install pydseamslib
import pydseams as ds

frame = ds.read("input/traj/exampleTraj.lammpstrj")
print(frame.chill_plus())
print(frame.cages())

Frame.chill_plus defaults to the cutoff list, as seams chill-plus does; frame.chill_plus(graph="mutual") is the mutual list. On this dump the default prints:

IceCounts(interClathrate=12, water=238)
CageScore(n_ih=0, n_ic=0, n_water=250)

The cage score matches the CLI. The CHILL+ histogram does not, because the neighbour lists differ. import pydseamslib is the same package. The Frame walkthrough is pydseams. Lua is require(“dseams”).

Troubleshooting

  • nop 0 or an empty histogram: wrong --type. Mixed TIP4P in this tree is type 2. mW is type 1.

  • Unknown command, exit 2: the binary is seams, not yodaStruct. Commands are read, chill, chill-plus, and cages.

  • ModuleNotFoundError: pydseams: this repo does not install Python. pip install pydseamslib.

  • Lua require("dseams"): that module lives in yodaStruct.

Next steps

Summary

You read one mixed TIP4P frame, printed the CLI CHILL+ star (1 clathrate, 7 interfacial clathrate, 242 water), printed the seeded cage score (zero HC, zero DDC), and stated why those two answers differ.