Smoothed bond-angle descriptor
Important
See Bond-angle descriptor first.
Definition
This is a smooth version of the Bond-angle descriptor in which the bond angles \(\theta_{jik}\) are multiplied by a weighting function \(f(r_{ij}, r_{ik})\) that depends on the radial distances \(r_{ij}\) and \(r_{ik}\) between \((i,j)\) and \((i,k)\) respectively, where \(j\) and \(k\) can be any particle in the system (i.e. not necessarily a nearest neighbors of \(i\)).
Essentially, we define the smoothed number of bond angles around particle \(i\) as
where the superscript \(S\) indicates the smooth nature of the descriptor, and \(f(r_{ij}, r_{ik})\) is the following smoothing function:
where:
\(r_{\alpha\beta}^c\) and \(r_{\alpha\beta'}^c\) are the first minima of the corresponding partial radial distribution functions for the pairs \((i,j)\) and \((i,k)\).
\(\gamma\) is an integer.
\(R_\mathrm{max}^c = \xi \times \max(\{ r_{\alpha\beta}^c \})\) is the largest nearest neighbor cutoff rescaled by \(\xi > 1\).
\(H\) is the Heavide step function, which ensures for efficiency reasons, that the descriptor only has contributions from particles within a distance \(R_\mathrm{max}^c\).
We then consider \(N_i^S(\theta_n)\) for a set of angles \(\{ \theta_n \}\) that go from \(\theta_0 = 0^\circ\) to \(\theta_{n_\mathrm{max}}=180^\circ\) by steps of \(\Delta \theta\). 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 SmoothedBondAngleDescriptor
traj = Trajectory("trajectory.xyz")
D = SmoothedBondAngleDescriptor(traj)
The constructor takes the following parameters:
- SmoothedBondAngleDescriptor.__init__(trajectory, dtheta=3.0, cutoff_enlargement=1.3, exponent=8, accept_nans=True, verbose=False)[source]
- Parameters
trajectory (Trajectory) – Trajectory on which the structural descriptor will be computed.
dtheta (float) – Bin width \(\Delta \theta\) in degrees.
cutoff_enlargement (float, default: 1.3) – Scaling factor \(\xi\) for the largest nearest neighbors cutoff \(\max(\{ r_\mathrm{\alpha\beta}^c \})\) to consider neighbors \(j\) a distance \(R_\mathrm{max}^c = \xi \times \max(\{r_{\alpha\beta}^c\})\) away from the central particle \(i\).
exponent (int, default: 8) – Exponent \(\gamma\) in the smoothing function \(f(r_{ij},r_{ik})\).
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:
Nearest neighbors cutoffs. These can either be set in the
Trajectoryprior to the computation of the descriptor, 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 can either compute or set the nearest neighbors cutoffs \(\{ r_{\alpha\beta}^c \}\) for the smoothing directly in Trajectory:
from partycls import Trajectory
# open the trajectory
traj = Trajectory("trajectory.xyz")
# compute the nearest neighbors cutoffs
traj.compute_nearest_neighbors_cutoffs(dr=0.1)
print("computed cuttofs\n", traj.nearest_neighbors_cutoffs)
# set the nearest neighbors cuttofs
traj.nearest_neighbors_cutoffs = [1.45, 1.35, 1.35, 1.25]
print("manually set cuttofs\n", traj.nearest_neighbors_cutoffs)
computed cutoffs:
[1.4500000000000004, 1.3500000000000003, 1.3500000000000003, 1.2500000000000002]
manually set cutoffs:
[1.45, 1.35, 1.35, 1.25]
Note
If not computed in Trajectory or manually set, the cutoffs \(\{ r_{\alpha\beta}^c \}\) will be computed from inside the descriptor.
We now instantiate a SmoothedBondAngleDescriptor on this trajectory and restrict the analysis to type-B particles only. We set \(\Delta \theta = 18^\circ\), \(\xi=1.3\) and \(\gamma=8\):
from partycls.descriptors import SmoothedBondAngleDescriptor
# instantiation
D = SmoothedBondAngleDescriptor(traj,
dtheta=18.0,
cutoff_enlargement=1.3,
exponent=8)
# print the grid of angles (in degrees)
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])
grid:
[ 9. 27. 45. 63. 81. 99. 117. 135. 153. 171.]
feature vectors:
[[ 0. 0.24735055 5.1652519 29.43498845 10.5325834 14.99235213
19.81940987 10.74915154 5.74995792 3.83545611]
[ 0. 0.16020613 4.79852719 35.17585892 9.27868908 14.30365693
20.88630866 12.92153832 2.269351 7.38748952]
[ 0. 0.08214317 11.23967682 32.2093987 4.0642088 24.10157113
19.94955473 7.72183504 12.2267004 3.29940419]]
gridshows the grid of angles \(\{ \theta_n \}\) in degrees, where \(\Delta \theta = 18^\circ\).feature vectorsshows the first three feature vectors \(X^\mathrm{SBA}(1)\), \(X^\mathrm{SBA}(2)\) and \(X^\mathrm{SBA}(3)\) corresponding to the grid.