# Selection language¶

## Overview¶

Chemfiles implements a rich selection language that allows finding the atoms
matching a set of constraints in a `Frame`

. For
example, `atom: name == H and x > 15`

would select all atoms with a name equal
to “H” and x cartesian coordinate bigger than 15. Here, `name == H`

and ```
x >
15
```

are individual constraints, and they are combined with `and`

, meaning
both of them must be true for an atom to match to full selection.

Chemfiles atomic selection language differs from other atomic selection
languages (such as the ones in VMD, MDAnalysis, and many others) by the
fact that it is possible to formulate constraints not only on single atoms, but
also on pairs, triplets, and quadruplets of atoms. For example, ```
angles:
name(#2) O and mass(#3) < 1.5
```

will select all sets of three bonded atoms
forming an angle such that the name of the second atom is O and the mass of the
third atom is less than 1.5. Here, the first atom is left unconstrained. Where
evaluating simple selections yields a list of matching atomic indexes,
evaluating triplet selection will return a list of triplets of atomic indexes
(and correspondingly for pairs and quadruplets).

The number of atoms to select together is indicated in chemfiles by a context,
separated from the main selection by a colon. Seven contexts are available:
`atoms`

is the default context, matching single atoms. `two`

, `three`

, and
`four`

match arbitrary pairs, triplets and quadruplets of atoms respectively.
`bonds`

, `angles`

, and `dihedrals`

match pairs, triplets and quadruplets
of atoms bonded together to form the corresponding connectivity element.

### Expressing the constraints¶

Selections are built by assembling simple constraints with the Boolean operators
`and`

, `or`

and `not`

. They follow the usual interpretation of logic: ```
A
and B
```

will be true only if both A and B are true, `A or B`

will be true if
one of A or B is, and `not A`

will be true is A is false. You can use three
types of constraints in your selections: Boolean constraints, string constraints,
and numeric constraints.

String constraints check text values, such as the atomic `name`

or atomic
`type`

, comparing it to either a fixed string (`name(#1) == Fe`

) or another
string value (`type(#1) != type(#3)`

). When using a selection with more than
one atom, constraints are applied to different atoms using `#1`

, `#2`

,
`#3`

or `#4`

to refer to a specific atom: `angles: name(#3) Co`

will check
the name of the third atom of the angles, and so on.

Numeric constraints check numeric values such as the position of the atoms
(`x`

, `y`

, and `z`

), the atomic `mass`

, the `index`

of an atom in the
frame, *etc.* Numeric values can be combined with the usual mathematical
operations: `x^2 + y^2 + z^2 < 10^2`

will check for atoms inside the sphere
with a radius of 10 Å centered on the origin. The usual `+`

, `-`

, `*`

and
`/`

operators are supported, as well as `^`

for exponentiation and `%`

for
modulo (remainder of Euclidean division). These operations follow the standard
priority rules: `1 + 2 * 3`

is 7, not 9. Numeric values are then compared with
one of `==`

(equal), `!=`

(not equal), `<`

(less than),
`<=`

(less or equal), `>`

(more than), or `>=`

(more or equal).

Finally, Boolean constraints directly evaluate to either `true`

or `false`

for a given set of atoms. For example, `is_bonded(i, j)`

will check if atoms i
and j are bonded together. Here, `i`

and `j`

can either be one of the atoms
currently being matched (`#1 / #2 / #3 / #4`

) or another selection (called
sub-selection). In the latter case, all the atoms in the sub-selection are
checked to see if any of them verify the selection. This makes ```
is_bonded(#1,
name O)
```

select all atoms bonded to an oxygen; and ```
is_angle(type C, #1, name
O)
```

select all atoms in the middle of a C-X-O angle.

### Constraints on atomic properties¶

It is possible to use atomic `properties`

(unfortunately not frame or residue properties) in constraints, with the
`[<property>]`

syntax. `<property>`

should be replaced by the property name:
`[is_hetatm]`

, possibly using quotes around the property name if it contains
spaces: `["my own property"]`

. Depending on the context, a Boolean, string or
numeric property will be searched. If none can be found, or if the property type
does not match, a default value will be used instead.

## Selection language reference¶

Here is the list of currently implemented constraints. Additional ideas are welcome!

### Boolean constraints¶

`all`

: always matches any atom and returns`true`

;`none`

: never matches an atom and returns`false`

;`is_bonded(i, j)`

: check if atoms i and j are bonded together. If i and j refers to the same atom, this returns false;`is_angle(i, j, k)`

: check if atoms i, j and k are bonded together to form an angle,*i.e.*that i is bonded to j and j is bonded to k. If any of i, j or k refer to the same atom, this returns false;`is_dihedral(i, j, k, m)`

: check if atoms i, j, k and m are bonded together to form a dihedral angle,*i.e.*that i is bonded to j, j is bonded to k, and k is bonded to m. If any of i, j, k or m refer to the same atom, this returns false;`is_improper(i, j, k, m)`

: check if atoms i, j, k and m are bonded together to form a dihedral angle,*i.e.*that all of i, k, and m are bonded to j. If any of i, j, k or m refer to the same atom, this returns false;`[<property>]`

: check if atoms have a Boolean property named ‘property’ set, and that this property is true. This will return false if the property is not set;

### String properties¶

`type`

: gives the atomic type;`name`

: gives the atomic name. Some formats store both an atomic name (H3) and an atom type (H), this is why you can use two different selectors depending on the actual data;`resname`

: gives the residue name. If an atom is not in a residue, this return the empty string;`[<property>]`

: gives the value of the string property named ‘property’ for the atom. This will return an empty string (“”) if the property is not set;

### Numeric properties¶

Most of the numeric properties only apply to a single atom:

`index`

: gives the atomic index in the frame;`mass`

: gives the atomic mass;`x`

,`y`

and`z`

: gives the atomic position in cartesian coordinates;`vx`

,`vy`

and`vz`

: gives the atomic velocity in cartesian coordinates;`resid`

: gives the atomic residue index. If an atom is not in a residue, this return -1;`[<property>]`

: gives the value of the numeric property named ‘property’ for the atom. This will return 0 if the property is not set;

But some properties apply to multiple atoms, and as such are only usable when selecting multiple atoms:

`distance(i, j)`

: gives the distance in Ångströms between atoms i and j, accounting for periodic boundary conditions.`angle(i, j, k)`

: gives the angle between atoms i, j and k in radians, accounting for periodic boundary conditions. The atoms do not need to be bonded together.`dihedral(i, j, k, m)`

: gives the dihedral angle between atoms i, j, k and m in radians, accounting for periodic boundary conditions. The atoms do not need to be bonded together.`out_of_plane(i, j, k, m)`

: gives the distance in Ångströms between the plane formed by the three atoms i, k, and m; and the atom j, accounting for periodic boundary conditions.

Note

The `angle`

and `dihedral`

selectors are different from the `is_angle`

and `is_dihedral`

selectors. The firsts returns a number that can then be
used in mathematical expressions, while the second returns directly `true`

or `false`

.

One can also use mathematical function to transform a number to another value.
Currently supported functions are: `deg2rad`

and `rad2deg`

functions for
transforming radians to degrees and respectively; `sin`

, `cos`

, `tan`

for
the trigonometric functions; `asin`

and `acos`

inverse trigonometric
functions and `sqrt`

. Adding new functions is easy, open an issue about the
one you need on the chemfiles repository.

Note

Numeric selection operate on double precision floating point number, and as
such are subject to the same limitations. In particular, while ```
1 + 2 ==
3
```

will match all atoms, since this relation is always true, ```
0.1 + 0.2 ==
0.3
```

will not, since `0.1 + 0.2 == 0.30000000000000004`

when using
floating point arithmetic.

### Elisions¶

This selection language is very explicit but it can be too verbose in some cases. The following rules allow to omit some parts of the selection when the meaning is clear:

First, in the

`atoms`

context, the`#1`

variable is optional, and`atoms: name(#1) == H`

is equivalent to`atoms: name == H`

.Then, if no context is given, the

`atoms`

context is used. This make`atoms: name == H`

equivalent to`name == H`

.Then if no comparison operator is given,

`==`

is used by default. This means that we can write`name H`

instead of`name == H`

.Then, multiple values are interpreted as multiple choices. A selection like

`name H O C`

is expanded into`name H or name O or name C`

.

At the end, using all these elisions rules, ```
atom: name(#1) == H or name(#1) ==
O
```

is equivalent to `name H O`

. A more complex example can be ```
bonds:
name(#1) O C and index(#2) 23 55 69
```

, which is equivalent to ```
bonds:
(name(#1) == O or name(#1) == C) and (index(#2) == 23 or index(#2) == 55 or
index(#2) == 69)
```