def test_cog(self): """ Test if reduced r & weights calculates centre of geometry accurately. """ r = Gyration._get_reduced_r(cluster, None) weights = Gyration._get_weights(cluster, None) assert np.abs(np.sum(r * weights)) < 1e-7
def test_com(self): """ Test if reduced r & weights calculates centre of mass accurately. """ weights = cluster.atoms.masses r = Gyration._get_reduced_r(cluster, weights) weights = Gyration._get_weights(cluster, weights) assert np.abs(np.sum(r * weights)) < 1e-7
def test_rg_mass(self): """ Check if, when all masses in the system are equal, mass and number weighted are being the same. """ gyration_values = Gyration().rgyr(perfect_cluster) gyration_mass_values = Gyration().rgyr(perfect_cluster, mass=True) for non_mass, mass in zip(gyration_values, gyration_mass_values): assert non_mass == approx(mass)
def test_sort_eig_reverse(self): """ Test if eigenvalue sorting has the correct sorting in reverse """ gyration_tensor = Gyration._gyration_tensor(cluster, None) eig_val, eig_vec = np.linalg.eig(gyration_tensor) eig_val, eig_vec = Gyration._sort_eig(eig_val, eig_vec, reverse=True) assert eig_val[2] <= eig_val[1] assert eig_val[1] <= eig_val[0]
def test_sort_eig_order(self): """ Test if eigenvalue sorting has the correct sorting """ gyration_tensor = Gyration._gyration_tensor(cluster, None) eig_val, eig_vec = np.linalg.eig(gyration_tensor) eig_val, eig_vec = Gyration._sort_eig(eig_val, eig_vec, reverse=False) assert eig_val[2] >= eig_val[1] assert eig_val[1] >= eig_val[0]
def test_sort_eig_transformation(self): """ Test if eigenvalue sorting results in the correct sorting via A*evec_i = eval_i*evec_i """ gyration_tensor = Gyration._gyration_tensor(cluster, None) eig_val, eig_vec = np.linalg.eig(gyration_tensor) eig_val, eig_vec = Gyration._sort_eig(eig_val, eig_vec, reverse=False) for i in range(3): t1 = np.matmul(gyration_tensor, eig_vec[:, i]) t2 = eig_val[i] * eig_vec[:, i] assert t1 == approx(t2)
def inertia_tensor(self, cluster, unwrap=False, test=True): """ Calculte the inertia tensor defined as: Ig_ab = 1/M sum_i m_i*(r^2 d_ab - r_a*r_b) with a,b = {x,y,z} and r = (x,y,z) a d_ab is the kronecker delta. Basically mass weightes distance of a particle from an axis. The matrix is diagonalised and the eigenvalues are the moment of inertia along the principal axis, where the smallest value accompanies the major axis (the most mass is close to this axis). The largest value accompanies the minor axis. Parameters: ----------- cluster: MDAnalysis.ResidueGroup cluster on which to perform analysis on. unwrap: bool, optional Wether or not to unwrap cluster around pbc. Default False. test: bool, optional Useful to compare some raw data with mdanalysis functions on the fly for when you're not sure if you fucke something up. Returns: -------- eigenvalue : tuple of float Starting with the lowest value corresponding to the major axis. """ return Gyration().inertia_tensor(cluster, unwrap, test)
def gyration(self, cluster, unwrap=False, mass=False, pca=False): """ Calculte the gyration tensor defined as: Rg_ab = 1/N sum_i a_i*b_i ; a,b = {x,y,z} The eigenvalues of these vector are helpful to determine the shape of clusters. See: J. Phys. Chem. B 2014, 118, 3864−3880, and: MOLECULAR SIMULATION 2020, VOL. 46, NO. 4, 308–322. Parameters: ----------- cluster: MDAnalysis.ResidueGroup cluster on which to perform analysis on. unwrap: bool, optional Wether or not to unwrap cluster around pbc. Default False. Returns: -------- eigenvalues : tuple of float eigenvalues (Rg_11^2, Rg_22^2, Rg_33^2) of the gyration tensor in nm, starting with the largest one corresponding to the major axis (different than for inertia per gyration definiton). """ return Gyration().gyration(cluster, unwrap, mass, pca)
def calc_f_factors(self, cluster, unwrap=False, test=False): """ Calculate eigenvalues of gryation tensor (see self.gyration()) and calculate f_32 and f_21 from their square roots: f_32 = (Rg_33 - Rg_22) / Rg_33 f_21 = (Rg_22 - Rg_11) / Rg_33 Rg_33 is the eigenvalue belonging to the principal axis -- largest value. J. Phys. Chem. B 2014, 118, 3864−3880, and: MOLECULAR SIMULATION 2020, VOL. 46, NO. 4, 308–322. Parameters: ----------- cluster: MDAnalysis.ResidueGroup cluster on which to perform analysis on. unwrap: bool, optional Wether or not to unwrap cluster around pbc. Default False. Returns: -------- f-factors : tuple of float f_32 and f_21, as defined above. """ return Gyration().calc_f_factors(cluster, unwrap, test)
def test_rg(self): """ The radius of gyration values x,y,z are the root-mean-square of the radii components orthogonal to each axis. THe rms radii of xyz are 5.25, 0.4, 0.4. Therefore the rg_i^2 must be 0.8, 5.65, 5.65. """ gyration_values = Gyration().rgyr(perfect_cluster) assert gyration_values[1] == approx(np.sqrt(0.4 + 0.4)) assert gyration_values[2] == approx(gyration_values[3]) assert gyration_values[2] == approx(np.sqrt(5.25 + 0.4))
def test_gyration(self): """ The gyration value is the root-mean-square distance of the radii components along the respecitve axis. The mrs radii of xyz are 5.25, 0.4, 0.4. """ gyration_values = Gyration().gyration(perfect_cluster) assert gyration_values[0] > gyration_values[1] assert gyration_values[1] == approx(gyration_values[2]) assert gyration_values[0] == approx(5.25) assert gyration_values[1] == approx(0.4)
def rgyr(self, cluster, mass=False, components=True, pca=True, unwrap=False, test=False): """ Calculate the radius of gyration with mass weightes or non mass weighted units (along prinicipal components) Rg = sqrt(sum_i mi(xi^2+yi^2+zi^2)/sum_i mi) if mass weighted Rg = sqrt(sum_i (xi^2+yi^2+zi^2)/sum_i i) if not mass weighted component rg defined like this: rg_x = sqrt(sum_i mi(yi^2+zi^2)/sum_i mi), Parameters ---------- cluster: MDAnalysis.ResidueGroup cluster on which to perform analysis on. mass : boolean, optional wether or not to mass weight radii, by default False components : boolean, optional wether or not to calculate rgyr components, by default False pca : booelan, optional wether or not to calculate rgyr components w.r.t. principal component vectors or not, by default True unwrap : boolean, optional wether or not to unwrap cluster around pbc, by default False test : boolean, optional wether or not to perform some sanity checks, by default False Returns: rg : float radius of gyration rg_i : floats, optional If components is True, the components along x, y, z direction and if pca is also true along the threeprincipal axis, starting with the principal axis with the largest eigenvalue. """ return Gyration().rgyr(cluster, mass, components, pca, unwrap, test)
def test_intertia_w_mda(self): """ Check if my inertia_tensor gives same results than MDA """ inertia_tensor = Gyration._inertia_tensor(cluster) assert inertia_tensor == approx(cluster.moment_of_inertia())