Esempio n. 1
0
    def __init__(self, atom_group, box=None, bucket_size=10):
        """

        Parameters
        ----------
        atom_list : AtomGroup
          list of atoms
        box : array-like or ``None``, optional, default ``None``
          Simulation cell dimensions in the form of
          :attr:`MDAnalysis.trajectory.base.Timestep.dimensions` when
          periodic boundary conditions should be taken into account for
          the calculation of contacts.
        bucket_size : int
          Number of entries in leafs of the KDTree. If you suffer poor
          performance you can play around with this number. Increasing the
          `bucket_size` will speed up the construction of the KDTree but
          slow down the search.
        """
        self.atom_group = atom_group
        self._u = atom_group.universe
        self._box = box
        if box is None:
            self.kdtree = KDTree(dim=3, bucket_size=bucket_size)
        else:
            self.kdtree = PeriodicKDTree(box, bucket_size=bucket_size)
        self.kdtree.set_coords(atom_group.positions)
Esempio n. 2
0
def test_setcoords(b, cut, result):
    coords = np.array([[1, 1, 1], [2, 2, 2]], dtype=np.float32)
    if b is not None:
        b = np.array(b, dtype=np.float32)
    tree = PeriodicKDTree(box=b)
    print(b, tree.box, cut, result)
    with pytest.raises(RuntimeError, match=result):
        tree.set_coords(coords, cutoff=cut)
Esempio n. 3
0
def test_nopbc():
    cutoff = 0.3
    q = np.array([0.2, 0.3, 0.1])
    coords = f_dataset.copy()
    tree = PeriodicKDTree(box=None)
    tree.set_coords(coords)
    indices = tree.search(q, cutoff)
    assert_equal(indices, [0, 2])
Esempio n. 4
0
def test_setcoords(b, cut, result):
    coords = np.array([[1, 1, 1], [2, 2, 2]], dtype=np.float32)
    if b is not None:
        b = np.array(b, dtype=np.float32)
    tree = PeriodicKDTree(box=b)
    print(b, tree.box, cut, result)
    with pytest.raises(RuntimeError, match=result):
        tree.set_coords(coords, cutoff=cut)
Esempio n. 5
0
def test_nopbc():
    cutoff = 0.3
    q = np.array([0.2, 0.3, 0.1])
    coords = f_dataset.copy()
    tree = PeriodicKDTree(box=None)
    tree.set_coords(coords)
    indices = tree.search(q, cutoff)
    assert_equal(indices, [0, 2])
Esempio n. 6
0
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)
Esempio n. 7
0
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)
Esempio n. 8
0
def test_searchfail():
    coords = np.array([[1, 1, 1], [2, 2, 2]], dtype=np.float32)
    b = np.array([10, 10, 10, 90, 90, 90], dtype=np.float32)
    cutoff = 1.0
    search_radius = 2.0
    query = np.array([1, 1, 1], dtype=np.float32)
    tree = PeriodicKDTree(box=b)
    tree.set_coords(coords, cutoff=cutoff)
    match = 'Set cutoff greater or equal to the radius.'
    with pytest.raises(RuntimeError, match=match):
        tree.search(query, search_radius)
Esempio n. 9
0
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))
Esempio n. 10
0
    def _apply_KDTree(self, group):
        """KDTree based selection is about 7x faster than distmat
        for typical problems.
        """
        sel = self.sel.apply(group)
        # All atoms in group that aren't in sel
        sys = group[~np.in1d(group.indices, sel.indices)]

        box = self.validate_dimensions(group.dimensions)
        if box is None:
            kdtree = KDTree(dim=3, bucket_size=10)
            kdtree.set_coords(sys.positions)
            found_indices = []
            for atom in sel.positions:
                kdtree.search(atom, self.cutoff)
                found_indices.append(kdtree.get_indices())
            unique_idx = np.unique(np.concatenate(found_indices))

        else:
            kdtree = PeriodicKDTree(box, bucket_size=10)
            kdtree.set_coords(sys.positions)
            kdtree.search(sel.positions, self.cutoff)
            unique_idx = np.asarray(kdtree.get_indices())

        # These are the indices from SYS that were seen when
        # probing with SEL
        return sys[unique_idx.astype(np.int32)].unique
Esempio n. 11
0
class CollisionDetector(object):
    """Given a set of N particles this class allows to query if any new particle
    will overlap. If particles overlap this is called a collision

    Example
    -------
    >>> cd = CollisionDetector(coords, 3.81, [100, 100, 100])
    >>> cd.collision([50, 50, 50])

    """
    def __init__(self, coords, diameter, box):
        """
        Parameters
        ----------
        coords : array_like (N, 3)
            coordinates of N particles
        diameter : float
            diameter of particles
        box : array_like (3)
            box dimensions
        """
        fullbox = 90 * np.ones(6, dtype=np.float32)
        fullbox[:3] = box
        coords = np.asarray(coords, dtype=np.float32)
        max_cutoff = np.sum(np.sqrt(fullbox**2)) / 2
        self._kdt = PKDTree(fullbox)
        self._kdt.set_coords(coords, cutoff=max_cutoff)
        self._diameter = diameter

    def collision(self, pos):
        """check is there is a collision

        Parameters
        ----------
        pos : array_like (3)
             coordinates of new particles

        Returns
        -------
        collision : bool
             ``True`` if there is a collision,
        """
        pos = np.asarray(pos, dtype=np.float32)
        self._kdt.search(pos, self._diameter)
        indices = self._kdt.get_indices()
        return len(indices) != 0
Esempio n. 12
0
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)
Esempio n. 13
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)
Esempio n. 14
0
    def _apply_KDTree(self, group):
        box = group.dimensions if self.periodic else None
        if box is None:
            kdtree = KDTree(dim=3, bucket_size=10)
        else:
            kdtree = PeriodicKDTree(box, bucket_size=10)
        kdtree.set_coords(group.positions)
        kdtree.search(self.ref, self.cutoff)
        found_indices = kdtree.get_indices()

        return group[found_indices].unique
Esempio n. 15
0
 def _apply_KDTree(self, group):
     """Selection using KDTree and PeriodicKDTree for aperiodic and
     fully-periodic systems, respectively.
     """
     sel = self.sel.apply(group)
     box = self.validate_dimensions(group.dimensions)
     ref = sel.center_of_geometry(pbc=self.periodic)
     if box is None:
         kdtree = KDTree(dim=3, bucket_size=10)
     else:
         kdtree = PeriodicKDTree(box, bucket_size=10)
     kdtree.set_coords(group.positions)
     kdtree.search(ref, self.cutoff)
     found_indices = kdtree.get_indices()
     return group[found_indices].unique
Esempio n. 16
0
def test_searchfail():
    coords = np.array([[1, 1, 1], [2, 2, 2]], dtype=np.float32)
    b = np.array([10, 10, 10, 90, 90, 90], dtype=np.float32)
    cutoff = 1.0
    search_radius = 2.0
    query = np.array([1, 1, 1], dtype=np.float32)
    tree = PeriodicKDTree(box=b)
    tree.set_coords(coords, cutoff=cutoff)
    match = 'Set cutoff greater or equal to the radius.'
    with pytest.raises(RuntimeError, match=match):
        tree.search(query, search_radius)
Esempio n. 17
0
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))
Esempio n. 18
0
 def __init__(self, coords, diameter, box):
     """
     Parameters
     ----------
     coords : array_like (N, 3)
         coordinates of N particles
     diameter : float
         diameter of particles
     box : array_like (3)
         box dimensions
     """
     fullbox = 90 * np.ones(6, dtype=np.float32)
     fullbox[:3] = box
     coords = np.asarray(coords, dtype=np.float32)
     max_cutoff = np.sum(np.sqrt(fullbox**2)) / 2
     self._kdt = PKDTree(fullbox)
     self._kdt.set_coords(coords, cutoff=max_cutoff)
     self._diameter = diameter
Esempio n. 19
0
def test_ckd_searchpairs_nopbc(radius, result):
    coords = f_dataset.copy()
    tree = PeriodicKDTree()
    tree.set_coords(coords)
    indices = tree.search_pairs(radius)
    assert_equal(indices, result)
Esempio n. 20
0
def test_initialize_bm(box, rm):
    """
    Assert the construction of the recripocal box matrix.
    """
    assert_almost_equal(PeriodicKDTree(box)._rm, rm, decimal=7)
Esempio n. 21
0
def test_set_coords():
    match = 'coords must be a sequence of 3 dimensional coordinates'
    with pytest.raises(ValueError, match=match):
        xy = np.array([[2, 2], [5, 5], [1.1, 1.1]], dtype=np.float32)
        tree = PeriodicKDTree(boxes_1[0])
        tree.set_coords(xy)
Esempio n. 22
0
class AtomNeighborSearch(object):
    """This class can be used to find all atoms/residues/segments within the
    radius of a given query position.

    For the neighbor search, this class uses the BioPython KDTree and its
    wrapper PeriodicKDTree for non-periodic and periodic systems, respectively.
    """

    def __init__(self, atom_group, box=None, bucket_size=10):
        """

        Parameters
        ----------
        atom_list : AtomGroup
          list of atoms
        box : array-like or ``None``, optional, default ``None``
          Simulation cell dimensions in the form of
          :attr:`MDAnalysis.trajectory.base.Timestep.dimensions` when
          periodic boundary conditions should be taken into account for
          the calculation of contacts.
        bucket_size : int
          Number of entries in leafs of the KDTree. If you suffer poor
          performance you can play around with this number. Increasing the
          `bucket_size` will speed up the construction of the KDTree but
          slow down the search.
        """
        self.atom_group = atom_group
        self._u = atom_group.universe
        self._box = box
        if box is None:
            self.kdtree = KDTree(dim=3, bucket_size=bucket_size)
        else:
            self.kdtree = PeriodicKDTree(box, bucket_size=bucket_size)
        self.kdtree.set_coords(atom_group.positions)

    def search(self, atoms, radius, level='A'):
        """
        Return all atoms/residues/segments that are within *radius* of the
        atoms in *atoms*.

        Parameters
        ----------
        atoms : AtomGroup, MDAnalysis.core.groups.Atom
          list of atoms
        radius : float
          Radius for search in Angstrom.
        level : str
          char (A, R, S). Return atoms(A), residues(R) or segments(S) within
          *radius* of *atoms*.
        """
        if isinstance(atoms, Atom):
            positions = atoms.position.reshape(1, 3)
        else:
            positions = atoms.positions

        indices = []
        for pos in positions:
            self.kdtree.search(pos, radius)
            indices.append(self.kdtree.get_indices())
        unique_idx = np.unique([i for l in indices for i in l]).astype(np.int64)
        return self._index2level(unique_idx, level)

    def _index2level(self, indices, level):
        """Convert list of atom_indices in a AtomGroup to either the
        Atoms or segments/residues containing these atoms.

        Parameters
        ----------
        indices
           list of atom indices
        level : str
          char (A, R, S). Return atoms(A), residues(R) or segments(S) within
          *radius* of *atoms*.
        """
        n_atom_list = self.atom_group[indices]
        if level == 'A':
            if not n_atom_list:
                return []
            else:
                return n_atom_list
        elif level == 'R':
            return list({a.residue for a in n_atom_list})
        elif level == 'S':
            return list(set([a.segment for a in n_atom_list]))
        else:
            raise NotImplementedError('{0}: level not implemented'.format(level))
Esempio n. 23
0
def test_ckd_searchpairs_nopbc(radius, result):
    coords = f_dataset.copy()
    tree = PeriodicKDTree()
    tree.set_coords(coords)
    indices = tree.search_pairs(radius)
    assert_equal(indices, result)