Radial descriptor
Definition
Let \(\mathbf{r}_i\) be the position of particle \(i\) and define \(r_{ij} = |\mathbf{r}_j - \mathbf{r}_i|\) as the distance between particle \(i\) and its neighbors \(j\).
We define \(n_i(r_m)\) as the number of neighbors \(j\) of particle \(i\) for which \(r_{ij}\) is between \(r_m = r_\mathrm{min} + m \times \Delta r\) and \(r_{m+1} = r_\mathrm{min} + (m+1) \times \Delta r\) [1]. Here, \(\Delta r\) has the interpration of a bin width in a histogram.
We then consider \(n_i(r_m)\) for a set of distances \(\{ d_n \}\) separated by \(\Delta r\), \(\{ d_n \} = \{ r_0, r_1, \dots, r_{n_\mathrm{max}} \}\). The resulting feature vector for particle \(i\) is given by
Setup
Instantiating this descriptor on a Trajectory
can be done as follows:
from partycls import Trajectory
from partycls.descriptors import RadialDescriptor
traj = Trajectory("trajectory.xyz")
D = RadialDescriptor(traj)
The constructor takes the following parameters:
- RadialDescriptor.__init__(trajectory, dr=0.1, n_shells=3, bounds=None, accept_nans=True, verbose=False)[source]
- Parameters
trajectory (Trajectory) – Trajectory on which the structural descriptor will be computed.
dr (float) – Bin width \(\Delta r\).
n_shells (int, default: 3) – Number of coordination shells (based on the \(g(r)\) of group=0). This sets the upper bound \(r_\mathrm{max}\) for the distance grid \(\{d_n\}\) up to which correlations are computed.
bounds (tuple, default: None) – Lower and upper bounds \((r_\mathrm{min},r_\mathrm{max})\) to describe the radial correlations. If set, this has the priority over
n_shells
.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
.
Demonstration
We consider an input trajectory file trajectory.xyz
in XYZ format that contains two particle types "A"
and "B"
:
from partycls import Trajectory
# open the trajectory
traj = Trajectory("trajectory.xyz")
We now instantiate a RadialDescriptor
on this trajectory and restrict the analysis to type-B particles only. We set \(\Delta r = 0.1\) and \((r_\mathrm{min},r_\mathrm{max}) = (1, 1.5)\) to set the grid of distances \(\{d_n\}\):
from partycls.descriptors import RadialDescriptor
# instantiation
D = RadialDescriptor(traj, dr=0.1, bounds=(1.0, 1.5))
# print the grid of angles
print("grid:\n", D.grid)
# 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])
Output:
grid:
[1.05 1.15 1.25 1.35 1.45]
feature vectors:
[[2 2 1 1 3]
[5 1 0 1 2]
[4 2 1 0 1]]
grid
shows the grid of distances \(\{ d_n \}\), where \(\Delta r = 0.1\).feature vectors
shows the first three feature vectors \(X^\mathrm{R}(1)\), \(X^\mathrm{R}(2)\) and \(X^\mathrm{R}(3)\) corresponding to the grid.
References
- 1
Joris Paret, Robert L. Jack, and Daniele Coslovich. Assessing the structural heterogeneity of supercooled liquids through community inference. J. Chem. Phys., 152(14):144502, 2020. doi:10.1063/5.0004732.