Esempio n. 1
0
class CoordinateNeighborSearch(object):
    """
    This class can be used for two related purposes:

    1. To find all indices of a coordinate list within radius
    of a given query position.

    2. To find all indices of a coordinate list that are within
    a fixed radius of each other.

    CoordinateNeighborSearch makes use of the KDTree C++ module, so it's fast.
    """

    def __init__(self, coordinates, bucket_size=10):  # , copy=True):
        """
        :Arguments:
         *coordinates*
            list of N coordinates (Nx3 numpy array)
         *bucket_size*
            bucket size of KD tree. You can play around with this to
            optimize speed if you feel like it.

        """
        # to Nx3 array of type float (required for the C++ code)
        ## (also force a copy by default and make sure that the array order is compatible
        ## with the C++ code)
        ##self.coords=numpy.array(coordinates,dtype=numpy.float32,copy=copy,order='C')
        self.coords = numpy.asarray(coordinates, dtype=numpy.float32, order='C')
        assert (self.coords.dtype == numpy.float32)
        assert (bucket_size > 1)
        assert (self.coords.shape[1] == 3)
        self.kdt = KDTree(3, bucket_size)
        self.kdt.set_coords(self.coords)

    def search(self, center, radius, distances=False):
        """Neighbor search.

        Return all indices in the coordinates list that have at least
        one atom within *radius* of *center*.

        :Arguments:
          * center
              numpy array
          * radius
              float
          * distances
              bool  ``True``: return (indices,distances); ``False``: return indices only
        """
        self.kdt.search(center, radius)
        if distances:
            return self.kdt.get_indices(), self.kdt.get_radii()
        else:
            return self.kdt.get_indices()

    def search_list(self, centers, radius):
        """Search neighbours near all centers.

        Returns all indices that are within *radius* of any center listed in
        *centers*, i.e. "find all A within R of B" where A are the
        coordinates used for setting up the CoordinateNeighborSearch and B
        are the centers.

        :Arguments:
          *centers*
            Mx3 numpy array of M centers
          *radius*
           float
        """
        self.kdt.list_search(centers, radius)
        return self.kdt.list_get_indices()

    def search_all(self, radius, distances=False):
        """All neighbor search.

        Return all index pairs corresponding to coordinates within the *radius*.

        :Arguments:
          *radius*
            float
          *distances*
            bool  ``True``:  return (indices,distances); ``False``: return indices only
            [``False``]
        """
        self.kdt.all_search(radius)
        if distances:
            return self.kdt.all_get_indices(), self.kdt.all_get_radii()
        else:
            return self.kdt.all_get_indices()

    def _distances(self):
        """Return all distances after search()."""
        return self.kdt.get_radii()

    def _distances_all(self):
        """Return all distances after search_all()."""
        return self.kdt.all_get_radii()
Esempio n. 2
0
class CoordinateNeighborSearch(object):
    """
    This class can be used for two related purposes:

    1. To find all indices of a coordinate list within radius
    of a given query position.

    2. To find all indices of a coordinate list that are within
    a fixed radius of each other.

    CoordinateNeighborSearch makes use of the KDTree C++ module, so it's fast.
    """
    def __init__(self, coordinates, bucket_size=10):  # , copy=True):
        """
        :Arguments:
         *coordinates*
            list of N coordinates (Nx3 numpy array)
         *bucket_size*
            bucket size of KD tree. You can play around with this to
            optimize speed if you feel like it.

        """
        # to Nx3 array of type float (required for the C++ code)
        ## (also force a copy by default and make sure that the array order is compatible
        ## with the C++ code)
        ##self.coords=numpy.array(coordinates,dtype=numpy.float32,copy=copy,order='C')
        self.coords = numpy.asarray(coordinates,
                                    dtype=numpy.float32,
                                    order='C')
        assert (self.coords.dtype == numpy.float32)
        assert (bucket_size > 1)
        assert (self.coords.shape[1] == 3)
        self.kdt = KDTree(3, bucket_size)
        self.kdt.set_coords(self.coords)

    def search(self, center, radius, distances=False):
        """Neighbor search.

        Return all indices in the coordinates list that have at least
        one atom within *radius* of *center*.

        :Arguments:
          * center
              numpy array
          * radius
              float
          * distances
              bool  ``True``: return (indices,distances); ``False``: return indices only
        """
        self.kdt.search(center, radius)
        if distances:
            return self.kdt.get_indices(), self.kdt.get_radii()
        else:
            return self.kdt.get_indices()

    def search_list(self, centers, radius):
        """Search neighbours near all centers.

        Returns all indices that are within *radius* of any center listed in
        *centers*, i.e. "find all A within R of B" where A are the
        coordinates used for setting up the CoordinateNeighborSearch and B
        are the centers.

        :Arguments:
          *centers*
            Mx3 numpy array of M centers
          *radius*
           float
        """
        self.kdt.list_search(centers, radius)
        return self.kdt.list_get_indices()

    def search_all(self, radius, distances=False):
        """All neighbor search.

        Return all index pairs corresponding to coordinates within the *radius*.

        :Arguments:
          *radius*
            float
          *distances*
            bool  ``True``:  return (indices,distances); ``False``: return indices only
            [``False``]
        """
        self.kdt.all_search(radius)
        if distances:
            return self.kdt.all_get_indices(), self.kdt.all_get_radii()
        else:
            return self.kdt.all_get_indices()

    def _distances(self):
        """Return all distances after search()."""
        return self.kdt.get_radii()

    def _distances_all(self):
        """Return all distances after search_all()."""
        return self.kdt.all_get_radii()