Esempio n. 1
0
    def buildAffinityMatrix(self, atoms, cutoff=4):
        """Build the affinity matrix for given *atoms*.

        Note that if you do not want to incorporate hydrogen and non-protein
        atoms in calculations, make the selection ``"noh and protein"``.
        
    
        :arg atoms: atoms for which the affinity matrix will be calculated
        :type atoms: :class:`~prody.atomic.Atomic`
        
        :arg cutoff: pairwise atomic contact cutoff distance, default is 4 Å
        :type cutoff: float

        """
        
        if not isinstance(atoms, prody.Atomic):
            raise TypeError('atoms must be an Atomic instance, '
                            '{0:s} is not valid'.format(type(atoms)))
        cutoff = float(cutoff)
        assert cutoff > 0, 'cutoff distance must be greater than 0'
        
        from KDTree import KDTree

        start = time.time()
        if not isinstance(atoms, prody.AtomGroup):
            atoms = atoms.getAtomGroup().copy(atoms)
        n_atoms = atoms.numAtoms()
        hv = prody.HierView(atoms)
        n_res = hv.numResidues()

        rids = np.zeros(n_atoms, int) # residue indices of atoms
        rlen = np.zeros(n_res) # residue lengths
        resmap = {} # used for symmetry purposes
        for i, res in enumerate(hv.iterResidues()):
            rids[ res.getIndices() ] = i
            rlen[ i ] = len(res)
            res = (res.getChid(), res.getNumber(), res.getIcode())
            resmap[i] = res
            resmap[res] = i
        self._resmap = resmap
        LOGGER.debug('Atoms were evalulated in {0:.2f}s.'
                     .format(time.time()-start))

        start = time.time()
        kdtree = KDTree(3)
        kdtree.set_coords(atoms.getCoords())
        kdtree.all_search(cutoff)
        LOGGER.debug('KDTree was built in {0:.2f}s.'
                     .format(time.time()-start))

        start = time.time()
        affinity = defaultdict(int)
        for i, j in kdtree.all_get_indices():
            i = rids[i] 
            j = rids[j]
            if i == j:
                affinity[(i,j)] += 0.5
            else:
                affinity[(i,j)] += 1
        
        length = len(affinity)
        i = np.zeros(length, int) 
        j = np.zeros(length, int)
        v = np.zeros(length, float)
        k = 0
        for key, value in affinity.iteritems():
            i[k] = key[0]
            j[k] = key[1]
            v[k] = value
            k += 1
        rlen = rlen ** -0.5
        # = Nij * (1/Ni^0.5) * (1/Nj^0.5)    
        v = v * rlen[i] * rlen[j]  
        affinity = sparse.coo_matrix((v, (i,j)), shape=(n_res, n_res))
        self._affinity = affinity + affinity.T 
        LOGGER.debug('Affinity matrix was built in {0:.2f}s.'
                     .format(time.time()-start))
        self._stationary = None
        self._n_nodes = n_res
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()
Esempio n. 3
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()