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 = N0.greater(N0.greater(p0, 0) + N0.greater(p1, 0), 1) if N0.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, .. N0.put(p1, N0.nonzero(overlap), 0) N0.put(p0, N0.nonzero(overlap), 0) p0 = p0 + p1 return p0
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 = N0.greater( N0.greater(p0,0) + N0.greater(p1,0), 1 ) if N0.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, .. N0.put( p1, N0.nonzero( overlap ), 0 ) N0.put( p0, N0.nonzero( overlap ), 0 ) p0 = p0 + p1 return p0
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(N0.nonzero(rec_mask), N0.nonzero(lig_mask))
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 = N0.take( self.chainMap(), self.resIndex() ) if left_allowed is None: left_allowed = N0.nonzero( self.ref.maskBB() ) if right_allowed is None: right_allowed= N0.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
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 = N0.ones( len(lst) ) if type( lst ) == list: lst = N0.array( lst ) pos = N0.nonzero( mask ) rand_pos = N0.array( [ self.__shuffleList( pos ) for i in range(n) ] ) result = [] for p in rand_pos: r = copy.copy( lst ) N0.put( r, p, N0.take( lst, pos ) ) result += [r] return result
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 = N0.zeros(l_rec * l_lig) rMask = N0.ravel(N0.outerproduct(rec_mask, lig_mask)) ## (Optimization: nonzero is time consuming step) N0.put(r, N0.nonzero(rMask), N0.ravel(contacts)) return N0.resize(r, (l_rec, l_lig))
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: N0.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 = N0.logical_not( self.atomMask( what ) ) self.keepAtoms( N0.nonzero( mask ) ) return mask
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 = N0.greater( profile, upperLimit ) mask += N0.less( profile, lowerLimit ) for i in N0.nonzero(mask): print 'WARNING! Profile value %.2f set to O\n'%profile[i] profile[i] = 0 return profile
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 = N0.argmax(msm, 0) r = [ N0.nonzero(N0.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 = [N0.nonzero(N0.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
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 = N0.nonzero( cMap == chain ) for i in idx: m.atoms['chain_id'][i] = id[chain]
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( N0.nonzero( mask ) )
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( N0.nonzero( fMask ) )
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(N0.nonzero(mask))
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 = N0.nonzero(cMap == chain) for i in idx: m.atoms['chain_id'][i] = id[chain]
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 N0.nonzero(mask)
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 = N0.zeros(len(model), N0.Int) N0.put(mask, i_atoms, 1) return N0.nonzero(N0.logical_not(mask))
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(N0.nonzero(mask), deepcopy=deepcopy)
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( N0.nonzero( aMask ), returnClass )
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 N0.nonzero(mask)
def markOutliers( traj, z, page ): outliers = N0.nonzero( traj.outliers( z=z, mask=traj.ref.maskCA() ) ) for o in outliers: t = traj.takeMember( o ) ## cross out outliers in plot prof = N0.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 )
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( N0.nonzero( patch_mask ) ) i_dist = N0.argsort( dist )[:n_atoms] result = N0.zeros( len( patch_mask ) ) N0.put( result, i_dist, 1 ) return result
def markOutliers(traj, z, page): outliers = N0.nonzero(traj.outliers(z=z, mask=traj.ref.maskCA())) for o in outliers: t = traj.takeMember(o) ## cross out outliers in plot prof = N0.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)
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(N0.nonzero(patch_mask)) i_dist = N0.argsort(dist)[:n_atoms] result = N0.zeros(len(patch_mask)) N0.put(result, i_dist, 1) return result
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 N0.nonzero( mask )
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( N0.nonzero( N0.logical_not( r.maskH2O() ) ) ) center = r.centerOfMass() r.setXyz( r.getXyz() - center ) return r
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 N0.nonzero( mask )
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 = N0.shape( contMat ) nContacts = N0.sum( N0.sum( contMat )) if not maskLig: r_size, l_size = N0.shape( contMat ) maskLig = N0.ones( l_size ) maskRec = N0.ones( r_size ) c_mask = N0.ravel( N0.outerproduct( maskRec, maskLig ) ) c_pos = N0.nonzero( c_mask ) # get array with surface positions from complex cont = N0.take( N0.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 = N0.zeros(a*b) N0.put( r, c_pos, ranCont) result += [ N0.reshape( r, (a,b) ) ] return result
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 = N0.array(a, self.__typecode) if self.shape != a.shape: raise SparseArrayError, 'dimensions not aligned' self.indices = N0.nonzero(N0.logical_not(N0.equal(a, self.__default))) self.indices = self.indices.tolist() self.values = N0.take(a, self.indices) self.values = self.values.tolist()
def __find_intervals(self, l): l = N0.array(l) l = N0.take(l, N0.argsort(l)) globals().update(locals()) break_points = N0.nonzero(N0.greater(l[1:] - l[:-1], 1)) start = 0 intervals = [] for i in range(len(break_points)): index = break_points[i] intervals.append(tuple(N0.take(l, range(start, index + 1)))) start = index + 1 intervals.append(tuple(l[start:])) return intervals
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 = N0.array( a, self.__typecode ) if self.shape != a.shape: raise SparseArrayError, 'dimensions not aligned' self.indices = N0.nonzero( N0.logical_not( N0.equal(a, self.__default) ) ) self.indices = self.indices.tolist() self.values = N0.take( a, self.indices ) self.values = self.values.tolist()
def test( model, center2center, nAtoms=10, exclude=None ): from Biskit import Pymoler, PDBModel g = PatchGeneratorFromOrbit( model, center2center ) overlap = int( round( nAtoms / 4.0 ) ) r = g.randomPatches( nAtoms, 500, max_overlap=overlap, exclude=exclude ) profile = N0.sum( N0.array(r) ) pm = Pymoler() pm.addPdb( model, 'all' ) ms = [ model.take( N0.nonzero(mask) ) for mask in r ] pm.addMovie( ms ) return pm
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 = N0.nonzero(cMap == chain) for i in idx: m.atoms['chain_id'][i] = ids[chain]
def filterRange(self, key, vLow, vHigh): """ Get indices of items where vLow <= item[ key ] <= vHigh. @param key: item attribute @type key: any @param vLow: lower bound @type vLow: any @param vHigh: upper bound @type vHigh: any @return: array of int @rtype: array """ vLst = self.valuesOf(key) maskL = N0.greater_equal(vLst, vLow) maskH = N0.less_equal(vLst, vHigh) return N0.nonzero(maskL * maskH)
def test(model, center2center, nAtoms=10, exclude=None): from Biskit import Pymoler, PDBModel g = PatchGeneratorFromOrbit(model, center2center) overlap = int(round(nAtoms / 4.0)) r = g.randomPatches(nAtoms, 500, max_overlap=overlap, exclude=exclude) profile = N0.sum(N0.array(r)) pm = Pymoler() pm.addPdb(model, 'all') ms = [model.take(N0.nonzero(mask)) for mask in r] pm.addMovie(ms) return pm
def xyzOfNearestCovalentNeighbour(i, model): """ Closest atom in the same residue as atom with index i @param model: PDBModel @type model: PDBModel @param i: atom index @type i: int @return: coordinates of the nearest atom @rtype: [float, float, float] """ resModel = model.filter(residue_number=model.atoms['residue_number'][i]) dist = N0.sqrt(N0.sum((resModel.xyz - model.xyz[i])**2, 1)) ## set distance to self to something high dist[N0.argmin(dist)] = 100. pos_shortest = N0.nonzero(dist == min(dist))[0] return resModel.xyz[pos_shortest]
def xyzOfNearestCovalentNeighbour( i, model ): """ Closest atom in the same residue as atom with index i @param model: PDBModel @type model: PDBModel @param i: atom index @type i: int @return: coordinates of the nearest atom @rtype: [float, float, float] """ resModel = model.filter( residue_number=model.atoms['residue_number'][i] ) dist = N0.sqrt( N0.sum( (resModel.xyz - model.xyz[i])**2 , 1) ) ## set distance to self to something high dist[ N0.argmin(dist) ] = 100. pos_shortest = N0.nonzero( dist == min(dist) )[0] return resModel.xyz[ pos_shortest ]
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 = N0.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)
ref = PDBModel( T.absfile( ref ) ) if 'prot' in o: ref = ref.compress( ref.maskProtein() ) result_xyz = [] result_frameNames = [] result_ref = None T.flushPrint("Loading and appending trajectories...") for i in range( len( inLst ) ): t = loadTraj( inLst[i], i, start, end, step ) if 'prot' in o: t.keepAtoms( N0.nonzero(t.ref.maskProtein()) ) result_ref = result_ref or ref or t.ref if t.ref.equals( result_ref ) != [1,1]: raise Exception( 'Incompatible reference structure.' ) for xyz in t.frames: result_xyz.append( xyz.astype('f') ) for fname in t.frameNames: result_frameNames.append( fname ) T.flushPrint('#') print " Done"
def filter_zero_contacts( cl ): """ """ s = [ len( c['c_ratom_10']['nonzero'] ) for c in cl ] return cl.take( N0.nonzero( s ) )
surf_lig = lig.profile2mask( 'MS', 0.0001, 101 ) ## kick out non-surface rec = rec.compress( surf_rec ) lig = lig.compress( surf_lig ) com = Complex( rec, lig ) ## get interface patch cont = com.atomContacts( cutoff=6.0 ) rec_if = N0.sum( cont, 1 ) lig_if = N0.sum( cont, 0 ) ## center distance c2c = N0.sqrt( N0.sum( (rec.center() - lig.center())**2, 0 ) ) print "Center2Center: ", c2c ## get patches and put them into Pymoler for display print "Patching" excl = N0.compress( N0.ones( len( rec_if ) ), rec_if ) pm = test( rec, c2c, nAtoms=len(N0.nonzero(rec_if)), exclude=rec_if ) pm.addPdb( rec.compress( rec_if ), 'rec_interface' ) pm.addPdb( lig.compress( lig_if ), 'lig_interface' ) pm.addPdb( com.model(), 'complex') ## show everything ## the patches are as movie in 'model' pm.show()