seams CLI

The engine command is seams. The parser is Argum (the same parser as eonclient). Help, errors, ice-type counts, and --features are colorized through Argum’s environmentColorStatus.

seams --help
seams --version
seams --features
seams read FILE
seams chill FILE
seams chill-plus FILE
seams cages FILE
seams rdf FILE
seams cn FILE
seams hbonds FILE
seams pairs FILE
seams density-z FILE
seams domains FILE

A positional command and a positional file are required. Missing either, an unknown command, or a parse error exits 2.

Every command accepts --format text|json. Text is the human-readable format documented below. JSON emits one JSON object per output frame on stdout, with the fields schema (dseams.cli/v1), command, frame, status, and text. The text field contains the command’s text output without changing its contents. --strict-input returns 2 when a requested frame has no atoms; without it, empty input retains the legacy text output.

Commands

The command positional help string is read | chill | chill-plus | cages | fingerprint | ions | f4 | steinhardt | rdf | cn | hbonds | pairs | density-z | domains. chill_plus is an accepted alias of chill-plus (not listed in that help string).

command

action

stdout

read

print the loaded cloud

nop N frame F box Lx Ly Lz and, when box.size() >= 6, xy xz yz

chill

CHILL labels

nop N then name count for each ice type present

chill-plus

CHILL+ labels

same as chill

cages

ice score on six-membered rings

nop N graph KIND hexagonal IH cubic IC water W

cages --signature SPEC

closed polyhedra whose ring-size census matches SPEC; each vertex lies on at least three faces that close around it, V - E + F = 2, and rings that wind the periodic cell are left out

one line per signature, nop N graph KIND signature S cages C atoms A and, with --incomplete, incomplete K cups on the ring graph; with --guest-types, guests G occupied O multiple M free F

fingerprint

topology keys of the bonded graph

nop N graph KIND hops H method M key K classes C rings 3:a 4:b ... top key=count ...

fingerprint --emit-library LABEL

the frame’s distinct keys as library lines

# method M hops H colours C then key LABEL rows

fingerprint --library FILE[,FILE...]

atoms named by key libraries

nop N graph KIND hops H method M matched X label=count ... unmatched=U and, with several libraries, depth H1=n1 H2=n2

ions

ions classed by their first water shell against the seeded cages

nop N ice A ions I in-ice X front Y liquid Z shell S shell-ice F

f4

Rodger F4 on H-O…O-H pairs

nop N f4 MEAN n M

steinhardt

host \(q_3\), \(\bar q_3\), \(q_{12}\), \(\bar q_{12}\)

nop N q3 A q3bar B q12 C q12bar D

rdf

partial site-site \(g_{IJ}(r)\)

# r g count then # types I J rmax R bins N volume V then one r g count row per bin

cn

site-site coordination number

# site-site then # types I J cutoff R cn X nI N nJ M volume V

cn --ions --site

cage degree on ionCloud

cage ionCloud types 1 2 cutoff R degree D nCation N nAnion M

hbonds

geometric hydrogen-bond count

nop N hbonds E

pairs --site

mutual-nearest contact pairs

contact-pair count N nCation C nAnion A

density-z

type-resolved \(\rho\) along one axis

# z rho then one z rho row per bin

domains --site --subset

polar/apolar Stoddard component

subset polar n N largest L P P_inf

chill / chill-plus default to --graph cutoff: nneigh::neighListO, every pair closer than --cutoff. --graph mutual (alias knn) calls nneigh::kNearestNeighbourList with k = 4, mutual; there --cutoff is only the cell-size hint (cutoff + 1.5). Other graphs exit 2. Then chill::getCorrel / chill::getIceTypeNoPrint or chill::getCorrelPlus / chill::getIceTypePlusNoPrint. --water-types T,U is the neighbour mask (OW only); --type is the load filter and is not that mask. Ice names are the molSys::atom_state_type enumerators: cubic, hexagonal, water, interfacial, clathrate, interClathrate, reCubic, reHex, unclassified.

cages reports cage membership, not CHILL labels: hexagonal = HC (Ih), cubic = DDC (Ic), water = neither. The bond graph is --graph.

rdf and cn call rdf::partialRdf on LAMMPS type IDs from --types I,J (default I = J = --type). --cutoff is rmax. --bins is optional. The volume is nneigh::dumpVolume (det of dump H). cn integrates the site-site RDF to that cutoff (rdf::coordinationNumber). Help text and the cn header say site-site. There is no cage CN and no --ions.

cn --ions --site SPEC builds site::ionCloud and prints the mean unlike degree of type-1 (cation) vertices from nneigh::neighList(cutoff, ions, 1, 2). The line contains cage. pairs --site SPEC prints the size of nneigh::mutualNearestUnlike(ions, 1, 2). That line contains contact-pair, not ionicity. Both need --site.

density-z calls site::densityZ. --type 0 (default) keeps every atom; --type I keeps that LAMMPS type. --axis is x, y, or z (default z). --bins defaults to the bound span over \(0.1\). Each slab volume is \(A_\perp \times dz\), with \(A_\perp\) from dump H (recovered lx, ly, lz, not bound spans). This is not an ice score.

chill, chill-plus, and cages call site::iceScoreAllowed. When --family is not waterIce they print site::refuseIceScore (the message names the family) and exit 2. They do not fall through to atom_state_type::water. Unflagged seams chill stays waterIce. If --family is absent and the frame has more than two LAMMPS types, one stderr line names --family and the command still exits 0.

An empty cloud (nop 0) still prints. chill / chill-plus print nop 0. cages prints nop 0 graph KIND hexagonal 0 cubic 0 water 0. rdf / cn still emit their headers. hbonds prints nop 0 hbonds 0. density-z prints # z rho and zero-density bins.

hbonds loads the heavy-atom cloud with --type and the hydrogen cloud with --htype, then builds a cutoff neighbour list. Without --donors it uses the water two-hydrogen-per-molecule set (hAtomMolList). --donors passes every hydrogen index to populateHbondsFromDonors. --hdist and --hangle are the acceptor-H distance and the acceptor-centered O-O-H angle cutoffs (angle between OO and OH); the C++ defaults stay the water values and are not an ionic-liquid criterion.

Options

Names and help text are the Argum Option / Positional definitions in src/seams_cli.cpp. Defaults are the C++ initializers (Argum does not write defaults into the help).

flag

default

Argum help

-h, --help

show this help message and exit

-v, --version

Print version information

--features

Print compile-time backends

-f, --frame N

1

First frame (1-based)

--last N

omitted (0)

Last frame (inclusive). Omit for a single --frame

-j, --jobs N

1

Parallel frame workers (OpenMP). 1 is serial

--rebuild

off

Recompute rings and cages on every frame. A one-worker frame range otherwise updates them from the previous frame; the output is the same

--format KIND

text

Output format: ~text (default) or json (JSONL)~

--strict-input

off

Fail when a requested frame produces no atoms

-t, --type I

0

Atom type (0 guesses oxygen then type 1; density-z: 0 is every atom)

--water-types T,U

unset

Neighbour graph on these LAMMPS types only (OW). Substrate and ions never enter the 4-NN list

--types I,J

I = J = --type

Pair types for site-site rdf/cn (default I=J=--type)

--family NAME

waterIce

Material family. Ice scores refuse every value except waterIce

--site SPEC

Type-to-kind map for ionCloud (1=cationHead,2=anion)

--ions

cn on ionCloud cage degree (needs --site)

-c, --cutoff ANGSTROM

3.5

Neighbour cutoff (rdf/cn rmax; hbonds heavy-atom nList)

--cage-edge SPEC

2.65,3.15

cages --signature: keep a face only when every edge lies in LO,HI, in the coordinate units of the file. ~none leaves the cage bound to the face census (SEAMS_CAGE_EDGE)

--bins N

rmax / 0.1 or L / 0.1

Histogram bins (rdf: rmax/0.1; density-z: bound span / 0.1)

--axis XYZ

z

Histogram axis for density-z (x, y, or z)

-k N

4

k for knn / seeded cages

--graph KIND

seeded

Bond graph for cages: cutoff, knn, knn-union or seeded

--complete

off

Seeded cages: fill the last vertex of six-rings whose other vertices carry a label (ring completion)

--signature SPEC

cages: ring-size census (4:6,6:8) or a named table entry (sodalite\vert{}alpha\vert{}512\vert{}51262\vert{}51264\vert{}51268\vert{}sh\vert{}hc\vert{}ddc); join several with + for one line each. Joined signatures share one ring network and one cage search

--incomplete

off

cages --signature: also report cups and incomplete cages on the ring graph

--guest-types T,U

cages --signature: LAMMPS types of guests (methane, THF, ions) placed in the found cages by their periodic centroids

--guest-radius R

4.0

cages --signature: a guest belongs to the nearest cage centre within R

--hops N

2

fingerprint: bonds from the centre in each local key

--colour-types

off

fingerprint: colour vertices by LAMMPS type, so species never match across types

--library FILE

fingerprint: key library (from --emit-library) to name atoms by; several, comma separated, at different hop counts name each atom by the deepest that knows it

--emit-library LABEL

fingerprint: print the frame's distinct keys as library lines under LABEL instead of the summary

--ion-types I,J

ions: LAMMPS types read against the cage assignment

--ion-cutoff ANGSTROM

--cutoff

ions: first water shell radius

--htype I

1

Hydrogen atom type for hbonds

--hdist ANGSTROM

water C++ default

Acceptor-H distance cutoff for hbonds

--hangle DEG

water C++ default

O-O-H angle cutoff for hbonds (acceptor-centered)

--donors

off

Use every hydrogen as a donor candidate

--config FILE

SEAMS_CONFIG or ./seams.env

Dotenv of SEAMS_* / LINKCELL_* knobs. Env wins over the file

--print-config

Print the resolved runtime knobs and exit

--tpp N

0 (occupancy picker)

Threads per particle for the device k-NN (LINKCELL_TPP)

--block N

0 (occupancy picker)

CUDA block size (LINKCELL_BLOCK / SEAMS_BLOCK)

--resident FRAC

0.80

Fraction of free device memory for a resident batch (SEAMS_RESIDENT)

--cell ANGSTROM

3

Link-cell hint so NPT frames share a grid (SEAMS_CELL)

--help, --version, --features, and --print-config print and exit 0 before any file is opened.

--tpp, --block, --resident, and --cell apply to the device TUM ice score (seams cages) only. CHILL and \(q_{lm}\) stay on the host.

--cutoff is in Angstrom. -k also applies to knn-union (the same k feeds nneigh::kNearestNeighbourList). --graph is used by cages and fingerprint; a fingerprint wants one graph, so seeded (two graphs) falls back to cutoff there. --complete is used by cages and ions: it passes true as the fifth argument of seededCageAffiliation.

--type

value

single frame (load)

--last range (forEachLammpsFrame)

0

LAMMPS: type 2, then type 1 if that cloud is empty. chemfiles: keep every atom. XYZ: every atom is type 1

LAMMPS: every atom (sinp::readLammpsTrj). Classification uses cloud.pts[0].type

I > 0

LAMMPS readLammpsTrjO / chemfiles filter I

LAMMPS readLammpsTrjO with that type. The CLI does not pass a coordinate slice.

XYZ always stores type 1. Classification still uses --type after the read (type 0 then becomes 1).

A mixed-type dump that is not the water guess needs --type I. density-z treats 0 as every atom, not the oxygen guess. See Ionic-liquid dumps.

--water-types

--type is a load filter (one LAMMPS type, or the oxygen guess). It is not the neighbour mask. --water-types T,U loads the mixed dump (loadType = -1) and builds nneigh::kNearestNeighbourList / kNearestNeighbourPair on that type set. Ag, I, protein and ions stay in the cloud for guests and ions, but they never enter the four neighbours of OW. chill, chill-plus, cages and ions honour the flag. Ice and cage counts are the water types only.

seams chill-plus FILE --water-types 1
seams cages FILE --graph seeded --water-types 1
seams ions FILE --ion-types 3,4 --water-types 1

--types

Used by rdf and cn. The Argum form is I,J (one comma). A bad string exits 2 (bad --types (want I,J)). Omit the flag to set both sides to --type. These are LAMMPS type IDs on the original cloud (site-site). cn --ions is a different path (ionCloud cage degree).

--types

single-frame load

--last range

omitted

same as --type (one species)

same as --type

I,I (like)

keep type I

keep type I

I,J with I != J

every atom (readLammpsTrj / chemfiles unfiltered)

every atom (typeFilter 0)

cmdRdf / cmdCn then call rdf::partialRdf on those two integers. typeOf still resolves a zero to the first atom (or 1).

seams read and the box

seams read prints gen::formatDumpBox: the three bound spans, then xy xz yz when box.size() >= 6. There is no separate tilt flag. seams rdf uses the same dump H (gen::periodicDist and nneigh::dumpVolume). seams density-z uses recovered lx, ly, lz for \(A_\perp\), not bound spans. The in-plane sampler remains rdf2::sampleRDF_AA; see Sheared cells.

--graph

Used only by cages.

value

graph

seeded

mutual k-nearest seeds, union completions (ring::seededCageAffiliation; --complete sets the fifth argument)

cutoff

pairs inside --cutoff (nneigh::neighListO)

knn

mutual k-nearest (nneigh::BondGraph::KnnMutual)

knn-union

union k-nearest (nneigh::BondGraph::KnnUnion)

nneigh::bondGraphFromName also accepts knn-mutual and mutual as knn, and union as knn-union. seeded is handled in the CLI and is not a BondGraph enumerator. Any other name throws std::invalid_argument (unknown bond graph 'NAME' (use cutoff, knn, knn-union)) and cages exits 2.

Candidate cutoff for the knn graphs is --cutoff + 1.5.

--cage-edge

Used by cages --signature. Each face is kept when every minimum-image edge lies in the window. The default is 2.65,3.15. none (also off or false) leaves that test out, and the cage bound is the face census alone, which is the search from before the window existed. hc and ddc keep their geometric finders. The window applies to the ring-census search.

The numbers are in the coordinate units of the file. The LAMMPS dumps in this tree are angstroms, and the default covers the oxygen-oxygen contacts of the reference cells (about 2.74 to 2.81). Set the window to the heavy-atom contact range of the model. Widen it for a compressed cell or a guest that stretches a cage. A file in nanometres uses 0.265,0.315, or none when the contact range is unknown. Use a comma, a colon, or a slash. 2.65-3.15 is rejected.

seams cages FILE --graph cutoff --signature 512
seams cages FILE --graph cutoff --signature 512 --cage-edge none
seams cages FILE --graph cutoff --signature 512 --cage-edge 2.4,3.4

The same string is SEAMS_CAGE_EDGE. Python passes it as frame.cages_by_signature("512", edge="none"). Lua passes it as dseams.cages_by_signature(frame, "512", {edge = "none"}) with require("dseams"). The C entry is seams_frame_signature_edge; a null edge string is the default window.

Runtime knobs

Defaults live in the binary. An optional dotenv (SEAMS_CONFIG or ./seams.env) fills unset keys. The process environment wins the file; CLI flags win the environment. seams --print-config dumps the table.

variable

default

SEAMS_FRAME / SEAMS_LAST

1 / 0

SEAMS_JOBS

1

SEAMS_CARRY

1 (0 is --rebuild)

SEAMS_TYPE

0

SEAMS_CUTOFF

3.5

SEAMS_CAGE_EDGE

2.65,3.15 (none turns the window off)

SEAMS_K

4

SEAMS_GRAPH

seeded

SEAMS_FAMILY

waterIce

SEAMS_RESIDENT

0.80

SEAMS_CELL

3.0

SEAMS_TPP / LINKCELL_TPP

occupancy picker (0)

SEAMS_BLOCK / LINKCELL_BLOCK

occupancy picker (0)

SEAMS_OFFLOAD

false (Steinhardt Ylm and TUM cages; 0 forces host)

YODA_FENNEL_PATH / YODA_LUA_PATH

empty

Analysis choice (which command) is not this table.

File suffix

seams picks a reader from the path suffix (path.find_last_of('.')):

suffix

reader

compile-time gate

xyz

sinp::readXYZ

always

con

sinp::readCon

SEAMS_HAS_READCON

pdb, gro, dcd

sinp::readChemfiles

SEAMS_HAS_CHEMFILES

anything else

LAMMPS dump (readLammpsTrjO / readLammpsTrj)

always

A build without chemfiles or readcon-core treats .pdb / .gro / .dcd / .con as LAMMPS dumps. seams --features reports those gates.

Frame ranges

Omit --last, or set it equal to --frame, for one frame. That path calls load and works for every linked suffix.

A range (--last > --frame) dispatches by suffix. LAMMPS dumps use sinp::forEachLammpsFrame, with one handle per OpenMP worker and deterministic output order. XYZ is a single-frame input and emits frame 1 at most. Chemfiles and readcon inputs are read serially until the requested range or the first missing frame. --jobs 1 is serial; non-LAMMPS readers do not use OpenMP workers.

A serial range carries rings and cage affiliation from one frame to the next: primitive::RingUpdater and ring::AffiliationUpdater recompute only the atoms whose bounded ball changed. LAMMPS ranges with --jobs above 1, MPI ranks, single frames and --rebuild rebuild every frame. The output is the same either way; tests/cli_carry.py checks that.

An MPI build (-Dwith_mpi=enabled) started by mpiexec shares a LAMMPS dump’s frames among the ranks in serpentine rounds: of R ranks, rank r takes slot r of even rounds and slot R-1-r of odd ones, so a cost that steps, drifts or alternates along the run reaches every rank. Rank 0 prints every frame in order; ranks past the frame count idle. Other readers stay on rank 0, --per-atom needs a single rank, ranks that differ in arguments, directory or SEAMS_ settings are refused, and colour stays off unless the environment forces it. Each rank runs --jobs frame workers, OpenMP threads inside a frame, and linkcell’s rayon pool; on a launch of several ranks, OMP_NUM_THREADS and RAYON_NUM_THREADS default to 1 when unset. For hybrid runs set them per rank and bind each rank to its cores; with Open MPI:

mpiexec -n 2 --map-by slot:PE=4 -x OMP_NUM_THREADS=4 -x RAYON_NUM_THREADS=1 \
  seams --jobs 4 --frame 1 --last 100 cages dump.lammpstrj

On a host without a libfabric network, Open MPI’s ofi transport spends about a second probing at start-up; --mca btl ^ofi skips it. Ranks then matched --jobs on one 8-core node, beat it where frame cost steps or alternates along the run, and eight ranks on two 4-core core sets talking only over TCP took about half the time of threads on one. A run without a launcher, or with SEAMS_MPI=0, never initialises MPI.

--features

Heading Compile-time features: then one line per backend. Each line is NAME: enabled or NAME: disabled.

printed name

macro

OpenMP

SEAMS_HAS_OPENMP

MPI

SEAMS_HAS_MPI

Highway SIMD

SEAMS_HAS_HWY

vesin neighbours

SEAMS_HAS_VESIN

linkcell k-nearest

SEAMS_HAS_LINKCELL

chemfiles

SEAMS_HAS_CHEMFILES

readcon-core

SEAMS_HAS_READCON

IRA/SOFI

SEAMS_HAS_IRA

sphericart

SEAMS_HAS_SPHERICART

nauty

SEAMS_HAS_NAUTY

Colors

colorizerForFile(environmentColorStatus(), stdout). Argum’s environmentColorStatus (first match wins):

condition

result

NO_COLOR set and non-empty

off

FORCE_COLOR set and non-empty

on

CLICOLOR_FORCE set, non-empty, not 0 / false

on

CLICOLOR_FORCE is 0 or false

off

CLICOLOR is 0 or false

off

CLICOLOR set and non-empty

allowed (TTY decides)

COLORTERM set and non-empty

allowed

TERM=dumb

off

otherwise

TTY / TERM heuristics

Color roles on this binary:

role

used for

heading

d-SEAMS banner, nop, Compile-time features:

progName

seams in --version; clathrate, interClathrate

longOption

frame, graph; cubic, reCubic

shortOption

box; hexagonal, reHex

warning

usage line; interfacial; enabled

error

parse / missing-args / unknown-command; unclassified; disabled

uncolored

water

Exit status

code

when

0

success, including --help / --version / --features / --print-config

2

parse error, missing command or file, unknown command, unknown --graph, bad --types, --bins < 0, unknown --family, ice score refused by --family

Examples

seams read input/traj/exampleTraj.lammpstrj
seams chill-plus input/traj/exampleTraj.lammpstrj --cutoff 3.5 --type 2
seams cages input/traj/mW_cubic.lammpstrj --type 1 --graph seeded
seams cages dump.lammpstrj --graph cutoff
seams cages dump.lammpstrj --graph knn
seams cages dump.lammpstrj --graph knn-union
seams chill-plus dump.lammpstrj --frame 1 --last 50 --jobs 8
seams rdf dump.lammpstrj --types 1,2 --cutoff 10 --bins 100
seams cn dump.lammpstrj --types 1,2 --cutoff 4.5
seams cn dump.lammpstrj --ions --site '1=cationHead,2=anion' --cutoff 6.0
seams pairs dump.lammpstrj --site '1=cationHead,2=anion'
seams hbonds dump.lammpstrj --type 2 --htype 1
seams hbonds dump.lammpstrj --donors
seams chill dump.lammpstrj --family ionicLiquid

Lua and Python are not this binary. See yodaStruct (require("dseams")) and PydSEAMSlib (pydseams).