Exemplo n.º 1
0
    def mergeProfiles( self, p0, p1, maxOverlap=3 ):
        """
        Merge profile p0 with profile p1, as long as they overlap in
        at most maxOverlap positions

        @param p0: profile
        @type  p0: [float]
        @param p1: profile
        @type  p1: [float]
        @param maxOverlap: maximal allowed overlap between profiles
        @type  maxOverlap: int
        
        @return: array
        @rtype: 
        """
        p0 = self.__list2array( p0 )
        p1 = self.__list2array( p1 )

        overlap = N.greater( N.greater(p0,0) + N.greater(p1,0), 1 )

        if N.sum( overlap ) <= maxOverlap:
            ## one of the two profiles will in most cases not belong to these
            ## positions. We can't decide which one is wrong, let's eliminate
            ## both values. Alternatively we could keep one, or the average, ..
            N.put( p1, N.nonzero( overlap ), 0 )
            N.put( p0, N.nonzero( overlap ), 0 )

            p0 = p0 + p1

        return p0
Exemplo n.º 2
0
    def mergeProfiles(self, p0, p1, maxOverlap=3):
        """
        Merge profile p0 with profile p1, as long as they overlap in
        at most maxOverlap positions

        @param p0: profile
        @type  p0: [float]
        @param p1: profile
        @type  p1: [float]
        @param maxOverlap: maximal allowed overlap between profiles
        @type  maxOverlap: int
        
        @return: array
        @rtype: 
        """
        p0 = self.__list2array(p0)
        p1 = self.__list2array(p1)

        overlap = N.greater(N.greater(p0, 0) + N.greater(p1, 0), 1)

        if N.sum(overlap) <= maxOverlap:
            ## one of the two profiles will in most cases not belong to these
            ## positions. We can't decide which one is wrong, let's eliminate
            ## both values. Alternatively we could keep one, or the average, ..
            N.put(p1, N.nonzero(overlap), 0)
            N.put(p0, N.nonzero(overlap), 0)

            p0 = p0 + p1

        return p0
Exemplo n.º 3
0
    def __resWindow(self,
                    res,
                    n_neighbores,
                    rchainMap=None,
                    left_allowed=None,
                    right_allowed=None):
        """
        Get indices of all atoms of a residue and some atoms of its
        neighboring residues (if they belong to the same chain).

        @param res: residue index
        @type  res: int
        @param n_neighbores: number of residues to include right and left
        @type  n_neighbores: int
        @param right_allowed: array 1 x N_atoms of 1|0, possible neighbore
                              atoms
        @type  right_allowed: array
        @param left_allowed: array 1 x N_atoms of 1|0, possible neighbore atoms
        @type  left_allowed: array 
        @param rchainMap: array 1 x N_residues of int, chain id of each res
        @type  rchainMap: array

        @return: atoms of res, atoms of neighbores
        @rtype: [ int ], [ int ]
        """
        ## some defaults.. time-consuming..
        if rchainMap is None:
            rchainMap = N.take(self.chainMap(), self.resIndex())

        if left_allowed is None: left_allowed = N.nonzero(self.ref.maskBB())
        if right_allowed is None: right_allowed = N.nonzero(self.ref.maskBB())

        ## atom indices of center residue
        result = self.ref.res2atomIndices([res]).tolist()

        ## get indices of neighbore residues that still belong to same chain
        l = self.ref.lenResidues()
        chain = rchainMap[res]

        outer_left = range(res - n_neighbores, res)
        outer_right = range(res + 1, res + n_neighbores + 1)

        outer_left = [i for i in outer_left if i > 0 and rchainMap[i] == chain]
        outer_right = [
            i for i in outer_right if i < l and rchainMap[i] == chain
        ]

        ## convert to atom indices, filter them against allowed neighbore atoms
        if outer_left:
            outer_left = self.ref.res2atomIndices(outer_left)
            outer_left = MU.intersection(left_allowed, outer_left)

        if outer_right:
            outer_right = self.ref.res2atomIndices(outer_right)
            outer_right = MU.intersection(right_allowed, outer_right)

        return result, outer_left + outer_right
Exemplo n.º 4
0
    def compress( self, rec_mask, lig_mask ):
        """
        Compress complex using a rec and lig mask.
        
        @param rec_mask: atom mask 
        @type  rec_mask: [1|0]
        @param lig_mask: atom mask 
        @type  lig_mask: [1|0]

        @return: compressed complex
        @rtype: Complex
        """
        return self.take( N.nonzero( rec_mask ), N.nonzero( lig_mask ) )
Exemplo n.º 5
0
    def __resWindow( self, res, n_neighbores, rchainMap=None,
                     left_allowed=None, right_allowed=None ):
        """
        Get indices of all atoms of a residue and some atoms of its
        neighboring residues (if they belong to the same chain).

        @param res: residue index
        @type  res: int
        @param n_neighbores: number of residues to include right and left
        @type  n_neighbores: int
        @param right_allowed: array 1 x N_atoms of 1|0, possible neighbore
                              atoms
        @type  right_allowed: array
        @param left_allowed: array 1 x N_atoms of 1|0, possible neighbore atoms
        @type  left_allowed: array 
        @param rchainMap: array 1 x N_residues of int, chain id of each res
        @type  rchainMap: array

        @return: atoms of res, atoms of neighbores
        @rtype: [ int ], [ int ]
        """
        ## some defaults.. time-consuming..
        if rchainMap is None:
            rchainMap = N.take( self.chainMap(), self.resIndex() )

        if left_allowed  is None: left_allowed = N.nonzero( self.ref.maskBB() )
        if right_allowed is None: right_allowed= N.nonzero( self.ref.maskBB() )

        ## atom indices of center residue
        result = self.ref.res2atomIndices( [ res ] ).tolist()

        ## get indices of neighbore residues that still belong to same chain
        l = self.ref.lenResidues()
        chain = rchainMap[res]

        outer_left = range( res-n_neighbores, res )
        outer_right= range( res+1, res+n_neighbores+1 )

        outer_left = [ i for i in outer_left  if i > 0 and rchainMap[i]==chain]
        outer_right= [ i for i in outer_right if i < l and rchainMap[i]==chain]

        ## convert to atom indices, filter them against allowed neighbore atoms
        if outer_left:
            outer_left = self.ref.res2atomIndices( outer_left )
            outer_left = MU.intersection( left_allowed,  outer_left )

        if outer_right:
            outer_right= self.ref.res2atomIndices( outer_right)
            outer_right= MU.intersection( right_allowed, outer_right)

        return result, outer_left + outer_right
Exemplo n.º 6
0
    def __cleanAtoms( self, m ):
        """
        Remove non protein atoms and H if needed.

        @param m: model to clean
        @type  m: PDBModel

        @return: cleaned model
        @rtype: PDBModel      
        """
        if self.protein:            
            m.keep( N.nonzero( m.maskProtein() ) )
        if self.heavy:
            m.keep( N.nonzero( m.maskHeavy() ) )
        return m
Exemplo n.º 7
0
    def __cleanAtoms(self, m):
        """
        Remove non protein atoms and H if needed.

        @param m: model to clean
        @type  m: PDBModel

        @return: cleaned model
        @rtype: PDBModel      
        """
        if self.protein:
            m.keep(N.nonzero(m.maskProtein()))
        if self.heavy:
            m.keep(N.nonzero(m.maskHeavy()))
        return m
Exemplo n.º 8
0
    def shuffledLists( self, n, lst, mask=None ):
        """
        shuffle order of a list n times, leaving masked(0) elements untouched

        @param n: number of times to shuffle the list
        @type  n: int
        @param lst: list to shuffle
        @type  lst: [any]
        @param mask: mask to be applied to lst
        @type  mask: [1|0]

        @return: list of shuffeled lists
        @rtype: [[any]]        
        """
        if not mask:
            mask = N.ones( len(lst)  )

        if type( lst ) == list:
            lst = N.array( lst )
        
        pos = N.nonzero( mask )

        rand_pos = N.array( [ self.__shuffleList( pos ) for i in range(n) ] )

        result = []
        for p in rand_pos:

            r = copy.copy( lst )
            N.put( r, p, N.take( lst, pos ) )
            result += [r]

        return result
Exemplo n.º 9
0
    def shuffledLists(self, n, lst, mask=None):
        """
        shuffle order of a list n times, leaving masked(0) elements untouched

        @param n: number of times to shuffle the list
        @type  n: int
        @param lst: list to shuffle
        @type  lst: [any]
        @param mask: mask to be applied to lst
        @type  mask: [1|0]

        @return: list of shuffeled lists
        @rtype: [[any]]        
        """
        if not mask:
            mask = N.ones(len(lst))

        if type(lst) == list:
            lst = N.array(lst)

        pos = N.nonzero(mask)

        rand_pos = N.array([self.__shuffleList(pos) for i in range(n)])

        result = []
        for p in rand_pos:

            r = copy.copy(lst)
            N.put(r, p, N.take(lst, pos))
            result += [r]

        return result
Exemplo n.º 10
0
    def getBuriedSurfaceTriangles(self,
                                  atomIndices=None,
                                  component=0,
                                  selnum=1,
                                  negate=0):
        """vfloat, vint, tri = getBuriedSurfaceTriangles(atomIndices=None, component=0, selnum=1, negate=0)

    Return the triangles of the specified SES component for which at least
    'selnum' vertices are either buried (if negate=0) or not burried
    (if negate=1). 0 < selnum < 4.
    
    vfloat and vint hold the data for all vertices of the surface.
    tri contains the subset of the triangles that are buried.
    """

        assert selnum in (1, 2, 3)

        vfloat, vint, tri = self.getTriangles(atomIndices, component=component)
        buriedFlag = vint[:, 2]
        if negate:
            buriedFlag = Numeric.logical_not(buriedFlag)
        #triBuried = Numeric.choose(tri[:,:3], buriedFlag)
        triBuried = Numeric.take(buriedFlag, tri[:, :3])
        sum = Numeric.sum(triBuried, 1)
        faceInd = Numeric.nonzero(Numeric.greater_equal(sum, selnum))
        faces = Numeric.take(tri, faceInd)
        return vfloat, vint, faces
Exemplo n.º 11
0
def nonRedundantSet(d, threshold, distanceMatrix = 1):
    """
    returns an array consisting of entries having
    a maximum similarity (or distance) of 'threshold'.
    distanceMatrix <> None means matrix elemens are similarities.

    Ref.: Hobohm et al. (1992). Prot. Sci. 1, 409-417

    gives somehow weired results.
    """
    import whrandom #@UnresolvedImport

    d = Numeric.array(d).astype(Float32)
    if not distanceMatrix: d = less(d, threshold)
    else: d = greater(d, threshold)

    s = shape(d)
    d = Numeric.concatenate((reshape(range(s[0]),(-1,1)),d),1)

    ok = 1

    while ok:
        nNeighbours = Numeric.sum(d)
        if len(nNeighbours) <= 1: break
        maxx = max(nNeighbours[1:])
        others = Numeric.nonzero(equal(nNeighbours[1:], maxx))+1
        candidate = whrandom.choice(others)
        ok = nNeighbours[candidate]
        if ok: d = deleteRowAndColumn(d, candidate-1, candidate)
    # end while
    
    return d[:,0]
Exemplo n.º 12
0
def nice_levels(z, n=8):
    """nice_levels(z, n = 8) finds approximately n "nice values"
    between min(z) and max(z) for axis labels. n defaults to eight.
    """
    zmax = max(ravel(z))
    zmin = min(ravel(z))
    finest = abs(zmax - zmin) / float(n)
    # blows up on zmin=zmax
    unit = 10.0 ** floor(log10(finest))
    finest = finest / unit
    if finest > 5.0:
        finest = 10.0
    elif finest > 2.0:
        finest = 5.0
    elif finest > 1.0:
        finest = 2.0
    unit = unit * finest
    cmin = unit * ceil(zmin / unit)
    if abs(cmin - zmin) < 0.01 * unit:
        cmin = cmin + unit
    cmax = unit * floor(zmax / unit)
    if abs(cmax - zmax) < 0.01 * unit:
        cmax = cmax - unit
    n = int(((cmax - cmin) / unit + 0.5) + 1)
    levs = span(cmin, cmax, n)
    list = nonzero(less(abs(levs), 0.1 * unit))
    if len(list) > 0:
        array_set(levs, list, 0.0)
    return levs
Exemplo n.º 13
0
    def __checkProfileIntegrity(self,
                                profile,
                                upperLimit=1.0,
                                lowerLimit=-1.0):
        """
        In some cases SurfaceRacer generates incorrect curvature
        values for some atoms. This function sets values outside
        a given range to 0

        @param profile: profile name
        @type  profile: str
        @param upperLimit: upper limit for a valid value (default: 1.0)
        @type  upperLimit: float
        @param lowerLimit: lower limit for a valid value (default: -1.0)
        @type  lowerLimit: float

        @return: profile with inspected values
        @rtype: [float]
        """
        mask = N.greater(profile, upperLimit)
        mask += N.less(profile, lowerLimit)

        for i in N.nonzero(mask):
            print 'WARNING! Profile value %.2f set to O\n' % profile[i]
            profile[i] = 0

        return profile
Exemplo n.º 14
0
    def removeAtoms( self, what ):
        """
        Remove atoms from all frames of trajectory and from reference
        structure.

        @param what: Specify what atoms to remove::
                      - function( atom_dict ) -> 1 || 0    or (1..remove)
                      - list of int [4, 5, 6, 200, 201..], indices of atoms
                          to remove
                      - list of int [11111100001101011100..N_atoms], mask
                          (1..remove)
                      - int, remove atom with this index
        @type  what: any


        @return: N.array(1 x N_atoms_old) of 0||1, mask used to compress the
                 atoms and xyz arrays. This mask can be used to apply the
                 same change to another array of same dimension as the
                 old(!) xyz and atoms.
        @rtype: array
        """
        ## pass what on to PDBModel, collect resulting mask
        mask = N.logical_not( self.atomMask( what ) )

        self.keepAtoms( N.nonzero( mask ) )

        return mask
Exemplo n.º 15
0
    def __unmaskedMatrix( self, contacts, rec_mask, lig_mask ):
        """
        Map contacts between selected rec and lig atoms back to all atoms
        matrix.
        
        @param contacts: contact matrix, array sum_rec_mask x sum_lig_mask
        @type  contacts: array
        @param rec_mask: atom mask
        @type  rec_mask: [1|0]
        @param lig_mask: atom mask
        @type  lig_mask: [1|0]

        @return: atom contact matrix, array N_atoms_rec x N_atoms_lig
        @rtype: array
        """
        l_rec = len( self.rec_model )
        l_lig = len( self.lig_model )

        ## map contacts back to all atoms matrix
        r = N.zeros( l_rec * l_lig )
        rMask = N.ravel( N.outerproduct( rec_mask, lig_mask ) )

        ## (Optimization: nonzero is time consuming step)
        N.put( r, N.nonzero( rMask ), N.ravel( contacts ) )

        return N.resize( r, (l_rec, l_lig))
Exemplo n.º 16
0
    def addDensity( self, radius=6, minasa=None, profName='density' ):
        """
        Count the number of heavy atoms within the given radius.
        Values are only collected for atoms with |minasa| accessible surface
        area.

        @param minasa: relative exposed surface - 0 to 100%
        @type  minasa: float
        @param radius: in Angstrom
        @type  radius: float
        """
        mHeavy = self.m.maskHeavy()

        xyz = N.compress( mHeavy, self.m.getXyz(), 0 )

        if minasa and self.m.profile( 'relAS', 0 ) == 0:
            self.addASA()

        if minasa:
            mSurf = self.m.profile2mask( 'relAS', minasa )
        else:
            mSurf = N.ones( self.m.lenAtoms() )

        ## loop over all surface atoms
        surf_pos = N.nonzero( mSurf )
        contacts = []

        for i in surf_pos:
            dist = N.sum(( xyz - self.m.xyz[i])**2, 1)
            contacts += [ N.sum( N.less(dist, radius**2 )) -1]

        self.m.atoms.set( profName, contacts, mSurf, default=-1,
                          comment='atom density radius %3.1fA' % radius,
                          version= T.dateString() + ' ' + self.version() )
Exemplo n.º 17
0
    def removeAtoms(self, what):
        """
        Remove atoms from all frames of trajectory and from reference
        structure.

        @param what: Specify what atoms to remove::
                      - function( atom_dict ) -> 1 || 0    or (1..remove)
                      - list of int [4, 5, 6, 200, 201..], indices of atoms
                          to remove
                      - list of int [11111100001101011100..N_atoms], mask
                          (1..remove)
                      - int, remove atom with this index
        @type  what: any


        @return: N.array(1 x N_atoms_old) of 0||1, mask used to compress the
                 atoms and xyz arrays. This mask can be used to apply the
                 same change to another array of same dimension as the
                 old(!) xyz and atoms.
        @rtype: array
        """
        ## pass what on to PDBModel, collect resulting mask
        mask = N.logical_not(self.atomMask(what))

        self.keepAtoms(N.nonzero(mask))

        return mask
Exemplo n.º 18
0
def nonRedundantSet(d, threshold, distanceMatrix=1):
    """
    returns an array consisting of entries having
    a maximum similarity (or distance) of 'threshold'.
    distanceMatrix <> None means matrix elemens are similarities.

    Ref.: Hobohm et al. (1992). Prot. Sci. 1, 409-417

    gives somehow weired results.
    """
    import whrandom  #@UnresolvedImport

    d = Numeric.array(d).astype(Float32)
    if not distanceMatrix: d = less(d, threshold)
    else: d = greater(d, threshold)

    s = shape(d)
    d = Numeric.concatenate((reshape(range(s[0]), (-1, 1)), d), 1)

    ok = 1

    while ok:
        nNeighbours = Numeric.sum(d)
        if len(nNeighbours) <= 1: break
        maxx = max(nNeighbours[1:])
        others = Numeric.nonzero(equal(nNeighbours[1:], maxx)) + 1
        candidate = whrandom.choice(others)
        ok = nNeighbours[candidate]
        if ok: d = deleteRowAndColumn(d, candidate - 1, candidate)
    # end while

    return d[:, 0]
Exemplo n.º 19
0
    def __checkProfileIntegrity( self, profile, upperLimit=1.0,
                                 lowerLimit=-1.0):
        """
        In some cases SurfaceRacer generates incorrect curvature
        values for some atoms. This function sets values outside
        a given range to 0

        @param profile: profile name
        @type  profile: str
        @param upperLimit: upper limit for a valid value (default: 1.0)
        @type  upperLimit: float
        @param lowerLimit: lower limit for a valid value (default: -1.0)
        @type  lowerLimit: float

        @return: profile with inspected values
        @rtype: [float]
        """
        mask = N.greater( profile, upperLimit )
        mask += N.less( profile, lowerLimit )

        for i in  N.nonzero(mask):
            print 'WARNING! Profile value %.2f set to O\n'%profile[i]
            profile[i] = 0

        return profile
Exemplo n.º 20
0
def setChainID(m):
    """
    set chainID for Hex pdb files
    """
    if options['id']:
        id = T.toList(options['id'])
        cMap = m.chainMap()
        for chain in range(m.lenChains()):
            idx = N.nonzero(cMap == chain)
            for i in idx:
                m.atoms['chain_id'][i] = id[chain]
Exemplo n.º 21
0
    def compressFrames( self, mask ):
        """
        Compress trajectory with a frame mask. 

        @param mask: frame mask, 1 x N_frames
        @type  mask: [1|0]

        @return: copy of this Trajectory (fewer frames, semi-deep copy of ref)
        @rtype: Trajectory
        """
        return self.takeFrames( N.nonzero( mask ) )
Exemplo n.º 22
0
    def __compressPca( self, fMask ):
        """
        Compress PCA results using a frame mask.

        @param fMask: frame mask
        @type  fMask: [1|0]

        @return: list of pca values
        @rtype: [float]        
        """
        return self.__takePca( N.nonzero( fMask ) )
Exemplo n.º 23
0
 def compressMembers(self, mask):
     """
     Apply mask to member trajectories.
     
     @param mask: positions in trajectory list to keep or remove
     @type  mask: [1|0]
     
     @return: compressed EnsembleTraj 
     @rtype: EnsembleTraj
     """
     return self.takeMembers(N.nonzero(mask))
Exemplo n.º 24
0
    def compressFrames(self, mask):
        """
        Compress trajectory with a frame mask. 

        @param mask: frame mask, 1 x N_frames
        @type  mask: [1|0]

        @return: copy of this Trajectory (fewer frames, semi-deep copy of ref)
        @rtype: Trajectory
        """
        return self.takeFrames(N.nonzero(mask))
Exemplo n.º 25
0
    def __compressPca(self, fMask):
        """
        Compress PCA results using a frame mask.

        @param fMask: frame mask
        @type  fMask: [1|0]

        @return: list of pca values
        @rtype: [float]        
        """
        return self.__takePca(N.nonzero(fMask))
Exemplo n.º 26
0
def setChainID( m ):
    """
    set chainID for Hex pdb files
    """
    if options['id']:
        id = T.toList( options['id'] )
        cMap = m.chainMap()
        for chain in range( m.lenChains() ):
            idx = N.nonzero( cMap == chain )
            for i in idx:
                m.atoms['chain_id'][i] = id[chain]
Exemplo n.º 27
0
 def compressMembers( self, mask ):
     """
     Apply mask to member trajectories.
     
     @param mask: positions in trajectory list to keep or remove
     @type  mask: [1|0]
     
     @return: compressed EnsembleTraj 
     @rtype: EnsembleTraj
     """
     return self.takeMembers( N.nonzero( mask ) )
Exemplo n.º 28
0
    def filterFunct(self, f):
        """
        Get indices of items for which f( item ) == 1.

        @param f: f must take a single item as argument and return 1 or 0
        @type  f: function

        @return: array of int
        @rtype: array
        """
        mask = [f(c) for c in self]
        return N.nonzero(mask)
Exemplo n.º 29
0
    def compress(self, mask, deepcopy=0):
        """
        Extract certain items.

        @param mask: mask of positions; len( mask ) == len( self )
        @type  mask: [ 1|0 ]
        @param deepcopy: deepcopy items (default: 0)
        @type  deepcopy: 1|0

        @return: new instance (or sub-class) with specified items
        @rtype: instance
        """
        return self.take(N.nonzero(mask), deepcopy=deepcopy)
Exemplo n.º 30
0
    def memberFrames(self, threshold=0.):
        """
        Get indices of all frames belonging to each cluster. Each frame
        is guaranteed to belong, at least, to the cluster for which it has
        its maximum membership. If threshold > 0, it can additionally pop
        up in other clusters.

        @param threshold: minimal cluster membership or 0 to consider
                          only max membership (default: 0)
        @type  threshold: float

        @return: n_cluster, lst of lst of int, frame indices
        @rtype: [[int]]
        """
        ## best cluster for each frame
        msm = self.memberships()
        maxMemb = N.argmax(msm, 0)

        r = [N.nonzero(N.equal(maxMemb, i)) for i in range(0, self.n_clusters)]
        r = [x.tolist() for x in r]

        ## same thing but now taking all above threshold
        ## -> same frame can end up in several clusters
        if threshold > 0.:
            r2 = [N.nonzero(N.greater(l, threshold)) for l in msm]

            ## add only additional frames
            for i in range(0, len(r)):
                try:
                    frames = r[i].tolist()
                except:
                    frames = r[i]

                r[i] = frames + [fr for fr in r2[i] if fr not in r[i]]

        ## sort frames within each cluster by their membership
        r = [self.membershipSort(r[i], i) for i in range(0, len(r))]

        return r
Exemplo n.º 31
0
 def __inverseIndices(self, model, i_atoms):
     """
     @param model: model
     @type  model: PDBMode
     @param i_atoms: atom index
     @type  i_atoms: [int]
 
     @return: remaining atom indices of m that are NOT in i_atoms
     @rtype: [int]
     """
     mask = N.zeros(len(model), N.Int)
     N.put(mask, i_atoms, 1)
     return N.nonzero(N.logical_not(mask))
Exemplo n.º 32
0
 def __inverseIndices( self, model, i_atoms ):
     """
     @param model: model
     @type  model: PDBMode
     @param i_atoms: atom index
     @type  i_atoms: [int]
 
     @return: remaining atom indices of m that are NOT in i_atoms
     @rtype: [int]
     """
     mask = N.zeros( len( model ),N.Int )
     N.put( mask, i_atoms, 1 )
     return N.nonzero( N.logical_not( mask ) )
Exemplo n.º 33
0
    def memberFrames( self, threshold=0. ):
        """
        Get indices of all frames belonging to each cluster. Each frame
        is guaranteed to belong, at least, to the cluster for which it has
        its maximum membership. If threshold > 0, it can additionally pop
        up in other clusters.

        @param threshold: minimal cluster membership or 0 to consider
                          only max membership (default: 0)
        @type  threshold: float

        @return: n_cluster, lst of lst of int, frame indices
        @rtype: [[int]]
        """
        ## best cluster for each frame
        msm = self.memberships()
        maxMemb = N.argmax( msm, 0 )

        r = [N.nonzero( N.equal(maxMemb, i) ) for i in range(0, self.n_clusters)]
        r = [ x.tolist() for x in r ]

        ## same thing but now taking all above threshold
        ## -> same frame can end up in several clusters
        if threshold > 0.:
            r2 = [ N.nonzero( N.greater( l, threshold) ) for l in msm ]

            ## add only additional frames
            for i in range(0, len( r ) ):
                try:
                    frames = r[i].tolist()
                except:
                    frames = r[i]

                r[i] = frames + [ fr for fr in r2[i] if fr not in r[i] ]

        ## sort frames within each cluster by their membership
        r = [ self.membershipSort( r[i], i) for i in range(0, len(r) )]

        return r
Exemplo n.º 34
0
    def filterEqual(self, key, lst):
        """
        Get indices of items for which item[ key ] in lst.

        @param key: item attribute
        @type  key: any
        @param lst: [ any ], list of allowed values
        @type  lst: list

        @return: array of int
        @rtype: array
        """
        mask = [self.getValue(i, key) in lst for i in range(len(self))]
        return N.nonzero(mask)
Exemplo n.º 35
0
    def compressAtoms(self, aMask, returnClass=None):
        """
        Get copy of this trajectory with only atoms marked 1 in aMask.

        @param aMask: atom mask [10011100101111...],
                      lst 1 x N_atoms of 1(keep) or 0
        @type  aMask: [1|0]
        @param returnClass: default: None, same class as this object
        @type  returnClass: class

        @return: copy of Trajectory with fewer atoms
        @rtype: Trajectory
        """
        return self.takeAtoms(N.nonzero(aMask), returnClass)
Exemplo n.º 36
0
def random2DArray( matrix, ranNr=1, mask=None):
    """
    Create randomized 2D array containing ones and zeros.

    @param matrix: matrix to randomize
    @type  matrix: 2D array
    @param mask: mask OR None (default: None)
    @type  mask: list(1|0)
    @param ranNr: number of matricies to add up (default: 1)
    @type  ranNr: integer

    @return: 2D array or |ranNr| added contact matricies
    @rtype:2D array

    @raise MathUtilError: if mask does not fit matrix
    """
    ## get shape of matrix
    a,b = N.shape( matrix )

    ## get array from matrix that is to be randomized
    if mask is not None:
        if len(mask) == len( N.ravel(matrix) ):
            array = N.compress( mask, N.ravel(matrix) )

        if len(mask) != len( N.ravel(matrix) ):
            raise MathUtilError(
                'MatUtils.random2DArray - mask of incorrect length' +
                '\tMatrix length: %i Mask length: %i'\
                %(len( N.ravel(matrix) ), len(mask)))

    if not mask:
        array = N.ravel(matrix)

    ## number of ones and length of array
    nOnes = int( N.sum( array ) )
    lenArray = len( array )
    ranArray = N.zeros( lenArray )

    ## create random array
    for n in range(ranNr):
        ranArray += randomMask( nOnes, lenArray )

    ## blow up to size of original matix
    if mask is not None:
        r = N.zeros(a*b)
        N.put( r, N.nonzero(mask), ranArray)
        return N.reshape( r, (a,b) )

    if not mask:
        return  N.reshape( ranArray, (a,b) )
Exemplo n.º 37
0
    def compressAtoms( self, aMask, returnClass=None ):
        """
        Get copy of this trajectory with only atoms marked 1 in aMask.

        @param aMask: atom mask [10011100101111...],
                      lst 1 x N_atoms of 1(keep) or 0
        @type  aMask: [1|0]
        @param returnClass: default: None, same class as this object
        @type  returnClass: class

        @return: copy of Trajectory with fewer atoms
        @rtype: Trajectory
        """
        return self.takeAtoms( N.nonzero( aMask ), returnClass )
Exemplo n.º 38
0
def random2DArray(matrix, ranNr=1, mask=None):
    """
    Create randomized 2D array containing ones and zeros.

    @param matrix: matrix to randomize
    @type  matrix: 2D array
    @param mask: mask OR None (default: None)
    @type  mask: list(1|0)
    @param ranNr: number of matricies to add up (default: 1)
    @type  ranNr: integer

    @return: 2D array or |ranNr| added contact matricies
    @rtype:2D array

    @raise MathUtilError: if mask does not fit matrix
    """
    ## get shape of matrix
    a, b = N.shape(matrix)

    ## get array from matrix that is to be randomized
    if mask is not None:
        if len(mask) == len(N.ravel(matrix)):
            array = N.compress(mask, N.ravel(matrix))

        if len(mask) != len(N.ravel(matrix)):
            raise MathUtilError(
                'MatUtils.random2DArray - mask of incorrect length' +
                '\tMatrix length: %i Mask length: %i'\
                %(len( N.ravel(matrix) ), len(mask)))

    if not mask:
        array = N.ravel(matrix)

    ## number of ones and length of array
    nOnes = int(N.sum(array))
    lenArray = len(array)
    ranArray = N.zeros(lenArray)

    ## create random array
    for n in range(ranNr):
        ranArray += randomMask(nOnes, lenArray)

    ## blow up to size of original matix
    if mask is not None:
        r = N.zeros(a * b)
        N.put(r, N.nonzero(mask), ranArray)
        return N.reshape(r, (a, b))

    if not mask:
        return N.reshape(ranArray, (a, b))
Exemplo n.º 39
0
    def filterFunct( self, f ):
        """
        Get indices of Complexes where f( c ) == 1.

        Use::
           filterFunct( f )

        @param f: filterFunct
        @type  f: function

        @return: array of int
        @rtype: [int]
        """
        mask = [ f( c ) for c in self ]
        return N.nonzero( mask )
Exemplo n.º 40
0
def markOutliers( traj, z, page ):

    outliers = N.nonzero( traj.outliers( z=z, mask=traj.ref.maskCA() ) )

    for o in outliers:
        t = traj.takeMember( o )

        ## cross out outliers in plot
        prof = N.array( t.profiles['rmsCA_ref'] ).tolist()
        prof.extend( t.profiles['rmsCA_last'] )
        maxV = max( prof )
        
        line = biggles.Line( (0,0), (len(t),maxV) )

        page[ o / 2, o % 2 ].add( line )
Exemplo n.º 41
0
    def centerPatch(self, patch_mask):
        """
        patch_mask - [ 1|0 ], mask of non-centered patch
        -> [ 1|0 ], mask of patch around geometric center of first patch
        """
        c = self.model.center(patch_mask)
        dist = self.__distances(c)

        n_atoms = len(N.nonzero(patch_mask))
        i_dist = N.argsort(dist)[:n_atoms]

        result = N.zeros(len(patch_mask))
        N.put(result, i_dist, 1)

        return result
Exemplo n.º 42
0
    def __center_model( self, model ):
        """
        translate PDBModel so that it's center is in 0,0,0

        @param model: model to center
        @type  model: PDBModel

        @return: PDBModel (clone of model)
        @rtype: PDBModel
        """
        r = model.clone()
        r.keep( N.nonzero( N.logical_not( r.maskH2O() ) ) )
        center = r.centerOfMass()
        r.setXyz( r.getXyz() - center )

        return r
Exemplo n.º 43
0
    def __center_model(self, model):
        """
        translate PDBModel so that it's center is in 0,0,0

        @param model: model to center
        @type  model: PDBModel

        @return: PDBModel (clone of model)
        @rtype: PDBModel
        """
        r = model.clone()
        r.keep(N.nonzero(N.logical_not(r.maskH2O())))
        center = r.centerOfMass()
        r.setXyz(r.getXyz() - center)

        return r
Exemplo n.º 44
0
    def draw(self):
        # XXX This method is not speed-optimized. I just wrote it to
        # get the job done. (Nonetheless, it seems faster than the C
        # version commented out above.)

        p = self.parameters # shorthand

        now_sec = VisionEgg.time_func()
        if self.start_times_sec is not None:
            # compute extinct dots and generate new positions
            replace_indices = Numeric.nonzero( Numeric.greater( now_sec - self.start_times_sec, p.dot_lifespan_sec) )
            Numeric.put( self.start_times_sec, replace_indices, now_sec )

            new_centers = np.random.standard_normal((3,len(replace_indices)))
            for i in range(3):
                Numeric.put( self.centers[i,:], replace_indices, new_centers[i,:] )
        else:
            # initialize dot extinction values to random (uniform) distribution
            self.start_times_sec = RandomArray.uniform( now_sec - p.dot_lifespan_sec, now_sec,
                                                        (self.constant_parameters.num_dots,))

        time_delta_sec = now_sec - self.last_time_sec
        self.last_time_sec = now_sec # reset for next loop
        self.centers = self.centers + np.array(p.signal_vec)[:,np.newaxis]*time_delta_sec

        xyz = self.centers*p.start_position_variance + np.array(p.start_position_mean)[:,np.newaxis]
        xs = xyz[0,:]
        ys = xyz[1,:]
        zs = xyz[2,:]

        if p.on:
            gl.glEnable( gl.GL_POINT_SMOOTH )
            # allow max_alpha value to control blending
            gl.glEnable( gl.GL_BLEND )
            gl.glBlendFunc( gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA )

            gl.glPointSize(p.dot_size)

            # Clear the modeview matrix
            gl.glMatrixMode(gl.GL_MODELVIEW)
            gl.glPushMatrix()

            gl.glDisable(gl.GL_TEXTURE_2D)

            draw_dots(xs,ys,zs,self.colors)
            gl.glDisable( gl.GL_POINT_SMOOTH ) # turn off
            gl.glPopMatrix()
Exemplo n.º 45
0
    def filterEqual( self, infoKey, lst ):
        """
        Get indices of Complexes where c.info[ infoKey ] in lst.

        Use::
           filterEqual( infoKey, lst )

        @param infoKey: key for info dict
        @type  infoKey: str
        @param lst: list of values to look for
        @type  lst: [any]

        @return: array of int
        @rtype: [int]
        """
        mask = [ c.info.get( infoKey ) in lst for c in self ]
        return N.nonzero( mask )
Exemplo n.º 46
0
def test_08BuriedSurfaceCalculations():
    print("______________________________")
    print("test_08BuriedSurfaceCalculations")
    print("______________________________")
    from mslib import MSMS, readxyzr, msms

    output1 = readxyzr('Data/1tpa_e.xyzr')
    coords_e = output1[0]
    names = output1[1]

    #coords_e, names = readxyzr('Data/1tpa_e.xyzr')
    output2 = readxyzr('Data/1tpa_i.xyzr')
    coords_i = output2[0]
    names = output2[1]
    #coords_i, names = readxyzr('Data/1tpa_i.xyzr')

    coords = coords_e[:, :3]
    rad = coords_e[:, 3]
    m = MSMS(coords=coords, radii=rad)
    m.compute()
    m.buriedVertices(coords_i)
    vfloat, vint, tri = m.getTriangles()
    indBuried = Numeric.nonzero(vint[:, 2])
    print(len(indBuried), " vertices buried")

    m.resetBuriedVertexArea()
    m.compute_numeric_area_vol(component=0, mode=msms.MS_SEMI_ANALYTICAL)
    print(m.sesr.fst.n_ses_volume)
    print(m.sesr.fst.n_ses_area)
    m.buriedSurfaceArea()

    print(m.sesr.fst.n_buried_ses_area)
    print(m.sesr.fst.n_buried_sas_area)

    vfloat, vint, tri = m.getBuriedSurfaceTriangles(selnum=1)
    print(
        "getBuriedSurfaceTriangles(selnum=1): len(vfloat): %d, len(vint): %d, len(tri): %d"
        % (len(vfloat), len(vint), len(tri)))
    vfloat, vint, tri = m.getBuriedSurfaceTriangles(selnum=2)
    print(
        "getBuriedSurfaceTriangles(selnum=2): len(vfloat): %d, len(vint): %d, len(tri): %d"
        % (len(vfloat), len(vint), len(tri)))
    vfloat, vint, tri = m.getBuriedSurfaceTriangles(selnum=3)
    print(
        "getBuriedSurfaceTriangles(selnum=3): len(vfloat): %d, len(vint): %d, len(tri): %d"
        % (len(vfloat), len(vint), len(tri)))
Exemplo n.º 47
0
    def random_contacts( self, contMat, n, maskRec=None, maskLig=None ):
        """
        Create randomized surface contact matrix with same number of
        contacts and same shape as given contact matrix.
        
        @param contMat: template contact matrix
        @type  contMat: matrix
        @param n: number of matrices to generate
        @type  n: int
        @param maskRec: surface masks (or something similar)
        @type  maskRec: [1|0]
        @param maskLig: surface masks (or something similar)
        @type  maskLig: [1|0]
        
        @return: list of [n] random contact matricies
        @rtype: [matrix]
        """
        a,b = N.shape( contMat )
        nContacts = N.sum( N.sum( contMat ))

        if not maskLig:
            r_size, l_size = N.shape( contMat )
            maskLig = N.ones( l_size )
            maskRec = N.ones( r_size )

        c_mask = N.ravel( N.outerproduct( maskRec, maskLig ) )
        c_pos = N.nonzero( c_mask )

        # get array with surface positions from complex
        cont = N.take( N.ravel(contMat), c_pos )
        length = len( cont )

        result = []

        for i in range( n ):
            # create random array
            ranCont = mathUtils.randomMask( nContacts,length )

            # blow up to size of original matrix
            r = N.zeros(a*b)
            N.put( r, c_pos, ranCont)

            result += [ N.reshape( r, (a,b) ) ]

        return result
Exemplo n.º 48
0
    def random_contacts(self, contMat, n, maskRec=None, maskLig=None):
        """
        Create randomized surface contact matrix with same number of
        contacts and same shape as given contact matrix.
        
        @param contMat: template contact matrix
        @type  contMat: matrix
        @param n: number of matrices to generate
        @type  n: int
        @param maskRec: surface masks (or something similar)
        @type  maskRec: [1|0]
        @param maskLig: surface masks (or something similar)
        @type  maskLig: [1|0]
        
        @return: list of [n] random contact matricies
        @rtype: [matrix]
        """
        a, b = N.shape(contMat)
        nContacts = N.sum(N.sum(contMat))

        if not maskLig:
            r_size, l_size = N.shape(contMat)
            maskLig = N.ones(l_size)
            maskRec = N.ones(r_size)

        c_mask = N.ravel(N.outerproduct(maskRec, maskLig))
        c_pos = N.nonzero(c_mask)

        # get array with surface positions from complex
        cont = N.take(N.ravel(contMat), c_pos)
        length = len(cont)

        result = []

        for i in range(n):
            # create random array
            ranCont = mathUtils.randomMask(nContacts, length)

            # blow up to size of original matrix
            r = N.zeros(a * b)
            N.put(r, c_pos, ranCont)

            result += [N.reshape(r, (a, b))]

        return result
Exemplo n.º 49
0
 def drawLines(self):
     # angle has to be provided in radians
     angle = self.angle
         
     self.circlePtsAngles = self.circlePtsAngles+angle
     self.circlePtsAngles = Numeric.remainder(self.circlePtsAngles,
                                              2*math.pi)
     xcoords = Numeric.cos(self.circlePtsAngles)
     xsin = Numeric.sin(self.circlePtsAngles)
     if self.orient=='horizontal':
         w = self.innerbox[2] - self.innerbox[0]
         r = w/2
         c = self.innerbox[0] + r
         y1 = self.innerbox[1]
         y2 = self.innerbox[3]
     else:
         w = self.innerbox[3] - self.innerbox[1]
         r = w/2
         c = self.innerbox[1] + r
         y1 = self.innerbox[0]
         y2 = self.innerbox[2]
         
     cl = self.canvas.create_line
     setCoords = self.canvas.coords
     setOpt = self.canvas.itemconfigure
     pi2 = math.pi/2.
     drawLines = 0
     co = Numeric.take(xcoords,
                       Numeric.nonzero(Numeric.greater_equal(xsin, 0.0)))
     co = Numeric.sort(co)
     co = [-1]+list(co)
     for i in range(len(co)):
         x = c - int(co[i]*r)
         if self.orient=='horizontal':
             setCoords(self.linesIds[i], x, y1, x, y2)
         else:
             setCoords(self.linesIds[i], y1, x, y2, x)
         shopt = self.shadowLinesOptions[i]
         x = x + shopt[0]
         if self.orient=='horizontal':
             setCoords(self.shLinesIds[i], x, y1, x, y2)
         else:
             setCoords(self.shLinesIds[i], y1, x, y2, x)
         setOpt(self.shLinesIds[i], fill = shopt[1], width=shopt[2])
Exemplo n.º 50
0
    def drawLines(self):
        # angle has to be provided in radians
        angle = self.angle

        self.circlePtsAngles = self.circlePtsAngles + angle
        self.circlePtsAngles = Numeric.remainder(self.circlePtsAngles,
                                                 2 * math.pi)
        xcoords = Numeric.cos(self.circlePtsAngles)
        xsin = Numeric.sin(self.circlePtsAngles)
        if self.orient == 'horizontal':
            w = self.innerbox[2] - self.innerbox[0]
            r = w / 2
            c = self.innerbox[0] + r
            y1 = self.innerbox[1]
            y2 = self.innerbox[3]
        else:
            w = self.innerbox[3] - self.innerbox[1]
            r = w / 2
            c = self.innerbox[1] + r
            y1 = self.innerbox[0]
            y2 = self.innerbox[2]

        cl = self.canvas.create_line
        setCoords = self.canvas.coords
        setOpt = self.canvas.itemconfigure
        pi2 = math.pi / 2.
        drawLines = 0
        co = Numeric.take(xcoords,
                          Numeric.nonzero(Numeric.greater_equal(xsin, 0.0)))
        co = Numeric.sort(co)
        co = [-1] + list(co)
        for i in range(len(co)):
            x = c - int(co[i] * r)
            if self.orient == 'horizontal':
                setCoords(self.linesIds[i], x, y1, x, y2)
            else:
                setCoords(self.linesIds[i], y1, x, y2, x)
            shopt = self.shadowLinesOptions[i]
            x = x + shopt[0]
            if self.orient == 'horizontal':
                setCoords(self.shLinesIds[i], x, y1, x, y2)
            else:
                setCoords(self.shLinesIds[i], y1, x, y2, x)
            setOpt(self.shLinesIds[i], fill=shopt[1], width=shopt[2])
Exemplo n.º 51
0
    def __setAll_1D( self, a ):
        """
        Replace content of this sparseArray with values from Numeric array
        or list of numbers -- only for 1-dimensional arrays.

        @param a: array OR list
        @type  a: array OR [ number ]
        """
        if type( a ) is list:
            a = N.array( a, self.__typecode )

        if self.shape != a.shape:
            raise SparseArrayError, 'dimensions not aligned'

        self.indices = N.nonzero( N.logical_not( N.equal(a, self.__default) ) )
        self.indices = self.indices.tolist()

        self.values = N.take( a, self.indices )
        self.values = self.values.tolist()
Exemplo n.º 52
0
    def __find_intervals(self, l):
        l = N.array(l)
        l = N.take(l, N.argsort(l))

        globals().update( locals() )

        break_points = N.nonzero(N.greater(l[1:] - l[:-1], 1))

        start = 0
        intervals = []

        for i in range(len(break_points)):
            index = break_points[i]
            intervals.append(tuple(N.take(l, range(start, index + 1))))
            start = index + 1

        intervals.append(tuple(l[start:]))

        return intervals
Exemplo n.º 53
0
def packBinaryMatrix( cm ):
    """
    Compress sparse array of 0 and ones to list of one-positions
    (space saving function, upack with L{unpackBinaryMatrix}).

    @param cm: X by Y array of int
    @type  cm: 2D array 

    @return: {'shape':(X,Y), 'nonzero':[int] }
    @rtype: dict
    """
    if cm == None or type( cm ) == dict:
        return cm

    result = {}
    result['shape'] = N.shape( cm )
    result['nonzero'] = N.nonzero( N.ravel( cm ) )
    result['nonzero'] = result['nonzero'].tolist()
    return result
Exemplo n.º 54
0
    def __setChainID( self, m, ids ):
        """
        set chaiID for Hex pdb files

        @param m: model
        @type  m: PDBModel
        @param ids: chain id, len(ids) == m.lenChains
        @type  ids: [str]

        @return: m is changed directly
        @rtype: PDBModel
        """
        if ids:
            ids = t.toList( ids )
            cMap = m.chainMap()

            for chain in range( m.lenChains() ):
                idx = N.nonzero( cMap == chain )
                for i in idx:
                    m.atoms['chain_id'][i] = ids[chain]
Exemplo n.º 55
0
    def getOutliers( self, traj, outlaws=[] ):
        """
        Identify member trajectories that haved moved much further than normal.

        @param traj: Trajectory to analyze
        @type  traj: Trajectory
        @param outlaws: members already marked for exclusion
        @type  outlaws: [int]

        @return: member indices of outlyer trajectories (plus outlaws)
        @rtype: [int]
        """
        if not self.zfilter:
            return outlaws

        outliers = N.nonzero( traj.outliers( z=self.zfilter,
                                             mask=traj.ref.maskCA(), step=10) )
        self.log.add('identified %i outliers with z-threshold %3.1f' %\
                     ( len(outliers), self.zfilter ) )

        return MU.union( outliers, outlaws )
Exemplo n.º 56
0
def test_08BuriedSurfaceCalculations():
    print("______________________________")
    print("test_08BuriedSurfaceCalculations")
    print("______________________________")
    from mslib import MSMS, readxyzr, msms

    output1 = readxyzr('Data/1tpa_e.xyzr')
    coords_e=output1[0]
    names = output1[1]

    #coords_e, names = readxyzr('Data/1tpa_e.xyzr')
    output2 = readxyzr('Data/1tpa_i.xyzr')
    coords_i=output2[0]
    names = output2[1]
    #coords_i, names = readxyzr('Data/1tpa_i.xyzr')

    coords = coords_e[:,:3]
    rad = coords_e[:,3]
    m = MSMS(coords=coords, radii = rad)
    m.compute()
    m.buriedVertices(coords_i)
    vfloat, vint, tri = m.getTriangles()
    indBuried = Numeric.nonzero(vint[:,2])
    print(len(indBuried)," vertices buried")

    m.resetBuriedVertexArea()
    m.compute_numeric_area_vol(component=0, mode=msms.MS_SEMI_ANALYTICAL)
    print(m.sesr.fst.n_ses_volume)
    print(m.sesr.fst.n_ses_area)
    m.buriedSurfaceArea()

    print(m.sesr.fst.n_buried_ses_area)
    print(m.sesr.fst.n_buried_sas_area)

    vfloat, vint, tri = m.getBuriedSurfaceTriangles(selnum=1)
    print("getBuriedSurfaceTriangles(selnum=1): len(vfloat): %d, len(vint): %d, len(tri): %d" % (len(vfloat), len(vint), len(tri)))
    vfloat, vint, tri = m.getBuriedSurfaceTriangles(selnum=2)
    print("getBuriedSurfaceTriangles(selnum=2): len(vfloat): %d, len(vint): %d, len(tri): %d" % (len(vfloat), len(vint), len(tri)))
    vfloat, vint, tri = m.getBuriedSurfaceTriangles(selnum=3)
    print("getBuriedSurfaceTriangles(selnum=3): len(vfloat): %d, len(vint): %d, len(tri): %d" % (len(vfloat), len(vint), len(tri)))
Exemplo n.º 57
0
 def filter(self, dlg):
     fptr = open(dlg)
     dlg_lines = fptr.readlines()
     fptr.close()
     #STEP 1:accumulate lines of various poses
     model_lines = []
     #keep all of them
     all_models = []
     in_model = False
     for ll in dlg_lines:
         if ll.find("DOCKED:")==0:
             #check for a new model
             if ll.find("DOCKED: MODEL")==0:
                 model_lines = []
             in_model = True
             model_lines.append(ll)
         if ll.find("_")==0 and in_model:
             all_models.append(model_lines)
             model_lines = []
             in_model = False
     #initialize this ligand 
     # loop over the models:
     for model_lines in all_models:
         self.setup_ligand(model_lines)
         bigR = self.bigRC[:self.lenK]
         bigM = self.bigC[:self.lenK]
         cutoff = bigR + self.keyRadii
         d = bigM - self.smallM
         dSQ = d*d
         dSQMAT = Numeric.sum(dSQ,2)
         cutoffSQMAT = cutoff*cutoff
         ansMat = Numeric.logical_and(Numeric.less(dSQMAT, cutoffSQMAT),Numeric.not_equal(dSQMAT, 0.))
         rowIndices = Numeric.nonzero(Numeric.sum(ansMat,1))
         num_contacts = 0
         for ind in rowIndices:
             for j in ansMat[ind]: 
                 if j: num_contacts+=1
         if num_contacts > 0:
             break 
     return num_contacts