def test_distarray(self): from MDAnalysis.lib.distances import distance_array from MDAnalysis.lib.distances import transform_StoR, transform_RtoS R_mol1 = transform_StoR(self.S_mol1, self.box, backend=self.backend) R_mol2 = transform_StoR(self.S_mol2, self.box, backend=self.backend) # Try with box dists = distance_array(R_mol1, R_mol2, box=self.box, backend=self.backend) # Manually calculate distance_array manual = np.zeros((len(R_mol1), len(R_mol2))) for i, Ri in enumerate(R_mol1): for j, Rj in enumerate(R_mol2): Rij = Rj - Ri Rij -= round(Rij[2] / self.box[2][2]) * self.box[2] Rij -= round(Rij[1] / self.box[1][1]) * self.box[1] Rij -= round(Rij[0] / self.box[0][0]) * self.box[0] Rij = np.linalg.norm(Rij) # find norm of Rij vector manual[i][j] = Rij assert_almost_equal(dists, manual, self.prec, err_msg="distance_array failed with box") # Now check using boxV dists = distance_array(R_mol1, R_mol2, box=self.boxV, backend=self.backend) assert_almost_equal(dists, manual, self.prec, err_msg="distance_array failed with boxV")
def test_distarray(self): from MDAnalysis.lib.distances import distance_array from MDAnalysis.lib.distances import transform_StoR, transform_RtoS R_mol1 = transform_StoR(self.S_mol1, self.box) R_mol2 = transform_StoR(self.S_mol2, self.box) # Try with box dists = distance_array(R_mol1, R_mol2, box=self.box) # Manually calculate distance_array manual = np.zeros((len(R_mol1), len(R_mol2))) for i, Ri in enumerate(R_mol1): for j, Rj in enumerate(R_mol2): Rij = Rj - Ri Rij -= round(Rij[2] / self.box[2][2]) * self.box[2] Rij -= round(Rij[1] / self.box[1][1]) * self.box[1] Rij -= round(Rij[0] / self.box[0][0]) * self.box[0] Rij = np.linalg.norm(Rij) # find norm of Rij vector manual[i][j] = Rij assert_almost_equal(dists, manual, self.prec, err_msg="distance_array failed with box") # Now check using boxV dists = distance_array(R_mol1, R_mol2, box=self.boxV) assert_almost_equal(dists, manual, self.prec, err_msg="distance_array failed with boxV")
def test_search(b, qns): """ Test finding neighbors for a given query vector and type of box. Parameters ---------- b : list MDAnalysis dimensions like list qns : tuple a query point and a list of expected neighbors. """ b = np.array(b, dtype=np.float32) q = transform_StoR(np.array(qns[0], dtype=np.float32), b) # Setting up the periodic tree tree = PeriodicKDTree(b) coords = transform_StoR(f_dataset, b) tree.set_coords(coords) # Input real space coordinates # Carry out the search and retrieve results tree.search(q, radius) indices = tree.get_indices() if indices: found_neighbors = np.sort(coords[indices], axis=0) else: found_neighbors = list() if qns[1]: expected_neighbors = transform_StoR(np.array(qns[1],dtype=np.float32), b) expected_neighbors = np.sort(expected_neighbors, axis=0) else: expected_neighbors = list() assert_equal(found_neighbors, expected_neighbors)
def test_search(b, q, result): b = np.array(b, dtype=np.float32) q = transform_StoR(np.array(q, dtype=np.float32), b) cutoff = 3.0 coords = transform_StoR(f_dataset, b) tree = PeriodicKDTree(box=b) tree.set_coords(coords, cutoff=cutoff) indices = tree.search(q, cutoff) assert_equal(indices, result)
def test_selfdist(self): from MDAnalysis.lib.distances import self_distance_array from MDAnalysis.lib.distances import transform_RtoS, transform_StoR R_coords = transform_StoR(self.S_mol1, self.box, backend=self.backend) # Transform functions are tested elsewhere so taken as working here dists = self_distance_array(R_coords, box=self.box, backend=self.backend) # Manually calculate self_distance_array manual = np.zeros(len(dists), dtype=np.float64) distpos = 0 for i, Ri in enumerate(R_coords): for Rj in R_coords[i + 1:]: Rij = Rj - Ri Rij -= round(Rij[2] / self.box[2][2]) * self.box[2] Rij -= round(Rij[1] / self.box[1][1]) * self.box[1] Rij -= round(Rij[0] / self.box[0][0]) * self.box[0] Rij = np.linalg.norm(Rij) # find norm of Rij vector manual[distpos] = Rij # and done, phew distpos += 1 assert_almost_equal(dists, manual, self.prec, err_msg="self_distance_array failed with input 1") # Do it again for input 2 (has wider separation in points) # Also use boxV here in self_dist calculation R_coords = transform_StoR(self.S_mol2, self.box, backend=self.backend) # Transform functions are tested elsewhere so taken as working here dists = self_distance_array(R_coords, box=self.boxV, backend=self.backend) # Manually calculate self_distance_array manual = np.zeros(len(dists), dtype=np.float64) distpos = 0 for i, Ri in enumerate(R_coords): for Rj in R_coords[i + 1:]: Rij = Rj - Ri Rij -= round(Rij[2] / self.box[2][2]) * self.box[2] Rij -= round(Rij[1] / self.box[1][1]) * self.box[1] Rij -= round(Rij[0] / self.box[0][0]) * self.box[0] Rij = np.linalg.norm(Rij) # find norm of Rij vector manual[distpos] = Rij # and done, phew distpos += 1 assert_almost_equal(dists, manual, self.prec, err_msg="self_distance_array failed with input 2")
def test_augment(b, q, res): radius = 1.5 q = transform_StoR(np.array(q, dtype=np.float32), b) if q.shape == (3, ): q = q.reshape((1, 3)) q = apply_PBC(q, b) aug, mapping = augment_coordinates(q, b, radius) if aug.size > 0: aug = np.sort(aug, axis=0) else: aug = list() if len(res) > 0: cs = transform_StoR(np.array(res, dtype=np.float32), b) cs = np.sort(cs, axis=0) else: cs = list() assert_almost_equal(aug, cs, decimal=5)
def test_undoaugment(b, qres): radius = 1.5 q = transform_StoR(np.array(qres[0], dtype=np.float32), b) if q.shape == (3, ): q = q.reshape((1, 3)) q = apply_PBC(q, b) aug, mapping = augment_coordinates(q, b, radius) for idx, val in enumerate(aug): imageid = np.asarray([len(q) + idx], dtype=np.int64) assert_equal(mapping[idx], undo_augment(imageid, mapping, len(q))[0])
def test_undoaugment(b, qres): radius = 1.5 q = transform_StoR(np.array(qres[0], dtype=np.float32), b) if q.shape == (3, ): q = q.reshape((1, 3)) q = apply_PBC(q, b) aug, mapping = augment_coordinates(q, b, radius) for idx, val in enumerate(aug): imageid = np.asarray([len(q) + idx], dtype=np.intp) assert_equal(mapping[idx], undo_augment(imageid, mapping, len(q))[0])
def test_find_images(b, qcs): """ Test the generation of images for a given query vector and type of box. Parameters ---------- b : list MDAnalysis dimensions like list qns : tuple a query point and a list of expected neighbors. """ b = np.array(b, dtype=np.float32) q = transform_StoR(np.array(qcs[0], dtype=np.float32), b) tree = PeriodicKDTree(b) coords = transform_StoR(f_dataset, b) tree.set_coords(coords) # Input real space coordinates cs = np.sort(transform_StoR(np.array(qcs[1], dtype=np.float32), b), axis=0) q_wrapped = apply_PBC(q.reshape((1, 3)), b) found_images = np.sort(tree.find_images(q_wrapped, radius), axis=0) assert_almost_equal(found_images, cs, decimal=6)
def test_searchpairs(b, radius, result): b = np.array(b, dtype=np.float32) cutoff = 2.0 coords = transform_StoR(f_dataset, b) tree = PeriodicKDTree(box=b) tree.set_coords(coords, cutoff=cutoff) if cutoff < radius: with pytest.raises(RuntimeError, match=result): indices = tree.search_pairs(radius) else: indices = tree.search_pairs(radius) assert_equal(len(indices), len(result))
def test_transforms(self): from MDAnalysis.lib.distances import transform_StoR, transform_RtoS # To check the cython coordinate transform, the same operation is done in numpy # Is a matrix multiplication of Coords x Box = NewCoords, so can use np.dot # Test transformation R_mol1 = transform_StoR(self.S_mol1, self.box) R_np1 = np.dot(self.S_mol1, self.box) # Test transformation when given box in different form R_mol2 = transform_StoR(self.S_mol2, self.boxV) R_np2 = np.dot(self.S_mol2, self.box) assert_almost_equal(R_mol1, R_np1, self.prec, err_msg="StoR transform failed with box") assert_almost_equal(R_mol2, R_np2, self.prec, err_msg="StoR transform failed with boxV") # Round trip test S_test1 = transform_RtoS(R_mol1, self.boxV) # boxV here althought initial transform with box S_test2 = transform_RtoS(R_mol2, self.box) # and vice versa, should still work assert_almost_equal(S_test1, self.S_mol1, self.prec, err_msg="Round trip failed in transform") assert_almost_equal(S_test2, self.S_mol2, self.prec, err_msg="Round trip failed in transform")
def test_transforms(self): from MDAnalysis.lib.distances import transform_StoR, transform_RtoS # To check the cython coordinate transform, the same operation is done in numpy # Is a matrix multiplication of Coords x Box = NewCoords, so can use np.dot # Test transformation R_mol1 = transform_StoR(self.S_mol1, self.box) R_np1 = np.dot(self.S_mol1, self.box) # Test transformation when given box in different form R_mol2 = transform_StoR(self.S_mol2, self.boxV) R_np2 = np.dot(self.S_mol2, self.box) assert_almost_equal(R_mol1, R_np1, self.prec, err_msg="StoR transform failed with box") assert_almost_equal(R_mol2, R_np2, self.prec, err_msg="StoR transform failed with boxV") # Round trip test S_test1 = transform_RtoS( R_mol1, self.boxV) # boxV here althought initial transform with box S_test2 = transform_RtoS(R_mol2, self.box) # and vice versa, should still work assert_almost_equal(S_test1, self.S_mol1, self.prec, err_msg="Round trip failed in transform") assert_almost_equal(S_test2, self.S_mol2, self.prec, err_msg="Round trip failed in transform")
def fractional_to_real(xyz, dims): """Convert fractional positions to real positions Parameters ---------- xyz : np.ndarray fractional positions dims : dict dict of box information Returns ------- xyz : np.ndarray real space representation of fractional positions """ box = np.array([ dims['a'], dims['b'], dims['c'], dims['alpha'], dims['beta'], dims['gamma'] ], dtype=np.float32) xyz = distances.transform_StoR(xyz, box) return distances.apply_PBC(xyz, box)