Tetrahedral descriptor
Definition
The degree of tetrahedrality of a particle \(i\) is the average deviation of the bond angles \(\{ \theta_{jik} \}\) between \(i\) and all the possible pairs of its nearest neighbors \((j,k)\) from the ideal angle in a tetrahedron, \(\theta_\mathrm{tetra} = 109.5^\circ\):
where \(N_\mathrm{ba}(i)\) is the total number of bond angles (i.e. the number of pairs) around particle \(i\) and \(N_b(i)\) is the number of its nearest neighbors. The resulting feature vector for particle \(i\) is given by
Note
Unlike most descriptors, this descriptor is scalar. Its feature vector \(X^\mathrm{T}(i)\) is thus composed of a single feature, and the inherited grid
attribute is therefore not relevant.
Setup
Instantiating this descriptor on a Trajectory
can be done as follows:
from partycls import Trajectory
from partycls.descriptors import TetrahedralDescriptor
traj = Trajectory("trajectory.xyz")
D = TetrahedralDescriptor(traj)
The constructor takes the following parameters:
- TetrahedralDescriptor.__init__(trajectory, accept_nans=True, verbose=False)[source]
- Parameters
trajectory (Trajectory) – Trajectory on which the structural descriptor will be computed.
accept_nans (bool, default: True) – If
False
, discard any row from the array of features that contains a NaN element. IfTrue
, keep NaN elements in the array of features.verbose (bool, default: False) – Show progress information and warnings about the computation of the descriptor when verbose is
True
, and remain silent when verbose isFalse
.
Requirements
The computation of this descriptor relies on:
Lists of nearest neighbors. These can either be read from the input trajectory file, computed in the
Trajectory
, or computed from inside the descriptor using a default method.
Demonstration
We consider an input trajectory file trajectory.xyz
in XYZ format that contains two particle types "A"
and "B"
. We compute the lists of nearest neighbors using the fixed-cutoffs method:
from partycls import Trajectory
# open the trajectory
traj = Trajectory("trajectory.xyz")
# compute the neighbors using pre-computed cuttofs
traj.nearest_neighbors_cuttofs = [1.45, 1.35, 1.35, 1.25]
traj.compute_nearest_neighbors(method='fixed')
nearest_neighbors = traj.get_property("nearest_neighbors")
# print the first three neighbors lists for the first trajectory frame
print("neighbors:\n",nearest_neighbors[0][0:3])
neighbors:
[list([16, 113, 171, 241, 258, 276, 322, 323, 332, 425, 767, 801, 901, 980])
list([14, 241, 337, 447, 448, 481, 496, 502, 536, 574, 706, 860, 951])
list([123, 230, 270, 354, 500, 578, 608, 636, 639, 640, 796, 799, 810, 826, 874, 913])]
We now instantiate a TetrahedralDescriptor
on this trajectory and restrict the analysis to type-B particles only:
from partycls.descriptors import TetrahedralDescriptor
# instantiation
D = TetrahedralDescriptor(traj)
# restrict the analysis to type-B particles
D.add_filter("species == 'B'", group=0)
# compute the descriptor's data matrix
X = D.compute()
# print the first three feature vectors
print("feature vectors:\n", X[0:3])
feature vectors:
[[0.48286880]
[0.48912898]
[0.47882811]]
feature vectors
shows the first three feature vectors \(X^\mathrm{T}(1)\), \(X^\mathrm{R}(2)\) and \(X^\mathrm{R}(3)\).