def getColorByType(self, component=None): """colors <- getColorByType(component=None) Compute the surface area corresponding to the buried vertices. If component is None, this operation is performed on all components. Components are specified using 0-based integers, 0 being the external one it returns a list of (r,g,b) tuples for each component """ colors = ((1., 0., 1.), (1., 0.5, 0.), (0., 1., 0.), (1., 0., 0.), (0., 0., 1.)) col = [] if component is None: rs = self.rsr.fst i = 0 while rs: if rs.ses.this and rs.ses.nbtri > 0: dum, dum, tri = self.getTriangles(component=i) col.append(Numeric.take(colors, tri[:, 3] - 1)) i = i + 1 rs = rs.nxt else: comp = self._getSESComp(component).this dum, dum, tri = self.getTriangles(component=component) col = Numeric.take(colors, tri[:, 3] - 1) return col
def sortPoly(self, order=-1): if __debug__: if hasattr(DejaVu, 'functionName'): DejaVu.functionName() """None <- sortPoly(order=-1) Sorts the geometry polygons according to z values of polygon's geomtric centers. Order=-1 sorts by furthest z first, order=1 sorts by closest z first""" # FIXME will not work with instance matrices mat = self.GetMatrix() mat = Numeric.reshape(mat, (4,4)) vt = self.vertexSet.vertices*mat if vt is None: return triv = Numeric.take(vt, self.faceSet.faces.array) trig = Numeric.sum(triv,1)/3. trigz = trig[:,2] #triangle's center of gravity z value ind = Numeric.argsort(trigz) # sorted indices if len(self.faceSet.faces.array): faces = Numeric.take(self.faceSet.faces.array, ind[::order]) if self.shading==GL.GL_FLAT: # we also need to re-arrange the # face normals if self.normals is None: normals = None else: if len(self.normals)>1: normals = Numeric.take(self.normals, ind[::order]) else: normals = self.normals else: normals = None self.Set(faces=faces, fnormals=normals)
def rmsMatrixByMember( self, mirror=0, step=1 ): """ Get result matrix ordered first by member then by time. (requires EnsembleTraj) @param mirror: mirror matrix at diagonal (only for intra-traj. rms) (default: 0) @type mirror: 0|1 @param step: take only every step frame [1] @type step: int """ intra_traj = self.traj_2 is None m = self.getResult( mirror=intra_traj ) i1 = i2 = self.traj_1.argsortMember( step=step ) if self.traj_2 is not None: i2 = self.traj_2.argsortMember( step=step ) a = N.take( m, i1, 0 ) a = N.take( a, i2, 1 ) if intra_traj and not mirror: for i in range( N.shape(a)[0] ): for j in range( i, N.shape(a)[1] ): a[j,i] = 0. return a
def getColorByType(self, component=None): """colors <- getColorByType(component=None) Compute the surface area corresponding to the buried vertices. If component is None, this operation is performed on all components. Components are specified using 0-based integers, 0 being the external one it returns a list of (r,g,b) tuples for each component """ colors = ( (1.,0.,1.), (1., 0.5, 0.), (0.,1.,0.), (1., 0., 0.), (0., 0., 1.) ) col = [] if component is None: rs = self.rsr.fst i=0 while rs: if rs.ses.this and rs.ses.nbtri>0: dum, dum, tri = self.getTriangles(component=i) col.append( Numeric.take(colors, tri[:,3]-1) ) i = i + 1 rs=rs.nxt else: comp = self._getSESComp(component).this dum, dum, tri = self.getTriangles(component=component) col = Numeric.take(colors, tri[:,3]-1) return col
def takeFrames( self, indices ): """ Return a copy of the trajectory containing only the specified frames. @param indices: positions to take @type indices: [int] @return: copy of this Trajectory (fewer frames, semi-deep copy of ref) @rtype: Trajectory """ ## remove out-of-bound indices indices = N.compress( N.less( indices, len( self.frames) ), indices ) r = self.__class__() ## this step takes some time for large frames ! r.frames = N.take( self.frames, indices, 0 ) ## semi-deep copy of reference model r.setRef( self.ref.take( range( self.ref.lenAtoms() )) ) if self.frameNames != None: r.frameNames = N.take( self.frameNames, indices, 0 ) r.frameNames = map( ''.join, r.frameNames.tolist() ) r.pc = self.__takePca( indices ) r.profiles = self.profiles.take( indices ) r.resIndex = self.resIndex return r
def pca(data): transposed = 0 if shape(data)[0] < shape(data)[1]: transposed = 1 data = transpose(data) cov = dot(transpose(data), data) ## eigenvectors are row vectors val, vec = eigenvectors(cov) try: val = val.real except: pass try: vec = vec.real except: pass order = argsort(val) val = Numeric.take(val, order) vec = Numeric.take(vec, order) pc = Numeric.dot(data, transpose(vec)) if transposed: pc = Numeric.transpose(pc) return val, vec, pc
def take( self, rec_pos, lig_pos ): """ Get copy of this complex with given atoms of rec and lig. @param rec_pos: receptor indices to take @type rec_pos: [int] @param lig_pos: ligand indices to take @type lig_pos: [int] @return: new complex @rtype: Complex """ r = self.__class__() r.lig_model = self.lig_model.take( lig_pos ) r.rec_model = self.rec_model.take( rec_pos ) r.info = deepcopy( self.info ) if self.pw_dist: r.pw_dist = N.take( self.pw_dist, rec_pos, 1 ) r.pw_dist = N.take( r.pw_dist, lig_pos ) r.ligandMatrix = copy( self.ligandMatrix ) ## todo: take cached contacts as well return r
def takeFrames(self, indices): """ Return a copy of the trajectory containing only the specified frames. @param indices: positions to take @type indices: [int] @return: copy of this Trajectory (fewer frames, semi-deep copy of ref) @rtype: Trajectory """ ## remove out-of-bound indices indices = N.compress(N.less(indices, len(self.frames)), indices) r = self.__class__() ## this step takes some time for large frames ! r.frames = N.take(self.frames, indices, 0) ## semi-deep copy of reference model r.setRef(self.ref.take(range(self.ref.lenAtoms()))) if self.frameNames != None: r.frameNames = N.take(self.frameNames, indices, 0) r.frameNames = map(''.join, r.frameNames.tolist()) r.pc = self.__takePca(indices) r.profiles = self.profiles.take(indices) r.resIndex = self.resIndex return r
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
def deleteRowAndColumn(matrix, row, column): n = shape(matrix) rowIndices = range(row) + range(row+1,n[0]) columnIndices = range(column) + range(column+1,n[1]) pruned = Numeric.take(matrix, rowIndices) return Numeric.take(pruned, columnIndices, 1)
def deleteRowAndColumn(matrix, row, column): n = shape(matrix) rowIndices = range(row) + range(row + 1, n[0]) columnIndices = range(column) + range(column + 1, n[1]) pruned = Numeric.take(matrix, rowIndices) return Numeric.take(pruned, columnIndices, 1)
def __thinarray(self, a, step): """ @param a: input array @type a: N.array @param step: stepping in both dimensions @type step: int @return: smaller array @rtype: N.array """ r = N.take(a, range(0, len(a), step), axis=0) r = N.take(r, range(0, len(r[0]), step), axis=1) return r
def __translateChainIndices( self, atomIndices, newChainMap ): """ Translate current chain indices into what they would look like in a PDBModel containing only the given atoms in the given order. @param atomIndices: indices of atoms @type atomIndices: [int] @param newChainMap: chain map [0000011133333..] @type newChainMap: [int] @return: { int:int, .. } map current chain indices to new ones @rtype: {int:int} @raise ComplexTrajError: if (parts of) chains are inserted into each other """ ## todo: looks not very elegant oldChainMap = N.take( self.ref.chainMap(), atomIndices ) r = {} for i in range( len( oldChainMap ) ): old, new = oldChainMap[i], newChainMap[i] if old in r: if r[old] != new: raise ComplexTrajError( "Can't insert different chains into each other.") else: r[old] = new return r
def takeAtoms(self, indices, returnClass=None): """ Take atoms from frames:: takeAtoms( indices, type=None ) -> copy of Trajectory @param indices: list of atom indices @type indices: [int] @param returnClass: default: None, same class as this object @type returnClass: class OR None @return: copy of this Trajectory (with fewer atoms) @rtype: Trajectory """ returnClass = returnClass or self.__class__ r = returnClass() ## copy over everything, so that child classes can preserve own fields r.__dict__.update(self.__dict__) r.frames = r.ref = r.frameNames = r.profiles = None r.frames = N.take(self.frames, indices, 1) r.setRef(self.ref.take(indices)) r.frameNames = copy.copy(self.frameNames) r.resIndex = None r.profiles = self.profiles.clone() r.pc = self.pc ## this is not really clean return r
def group(self, a_indices, maxPerCenter): """ Group a bunch of integers (atom indices in PDBModel) so that each group has at most maxPerCenter items. @param a_indices: atom indices @type a_indices: [int] @param maxPerCenter: max entries per group @type maxPerCenter: int @return: list of lists of int @rtype: [[int],[int]..] """ ## how many groups are necessary? n_centers = len(a_indices) / maxPerCenter if len(a_indices) % maxPerCenter: n_centers += 1 ## how many items/atoms go into each group? nAtoms = N.ones(n_centers, N.Int) * int(len(a_indices) / n_centers) i = 0 while N.sum(nAtoms) != len(a_indices): nAtoms[i] += 1 i += 1 ## distribute atom indices into groups result = [] pos = 0 for n in nAtoms: result += [N.take(a_indices, N.arange(n) + pos)] pos += n return result
def getResFluct( self, atomFluctList=None ): """ Convert list of atomic fluctuations to list of residue fluctuation. @param atomFluctList: array 1 x N_atoms of float @type atomFluctList: [float] @return: array 1 x N_residues of float @rtype: [float] @raise TrajError: if result length <> N_residues: """ if atomFluctList == None: atomFluctList = self.getFluct_global() ## Give all atoms of each res. the same fluct. value ## (the highest fluctuation of any backbone atom) result = self.residusMaximus( atomFluctList, self.ref.maskBB() ) ## take first atoms only result = N.take( result, self.ref.resIndex() ) ## result = N.compress( self.ref.maskCA(), atomFluctList) ## check dimension if len( result ) <> self.ref.lenResidues(): raise TrajError( "getResFluct(): Length of result list (%i) <>" % len(result)+ " number of residues (%i)." % self.ref.lenResidues() ) return result
def tripples(self, lst, n): """ Group items of lst into n tripples with minimal overlap. """ all = [] l = len(lst) ## get all possible tripples for i in range(l): for j in range(i + 1, l): for k in range(j + 1, l): all += [(lst[i], lst[j], lst[k])] ## calculate pairwise "distance" between tripples pw = N.zeros((len(all), len(all)), N.Float32) for i in range(len(all)): for j in range(i, len(all)): pw[i, j] = pw[j, i] = len(MU.intersection(all[i], all[j]))**2 pos = 0 r = [] while len(r) < n: r += [pos] ## overlap of selected tripples with all others overlap = N.sum(N.array([pw[i] for i in r])) ## select one with lowest overlap to all tripples selected before pos = N.argmin(overlap) return N.take(all, r)
def group( self, a_indices, maxPerCenter ): """ Group a bunch of integers (atom indices in PDBModel) so that each group has at most maxPerCenter items. @param a_indices: atom indices @type a_indices: [int] @param maxPerCenter: max entries per group @type maxPerCenter: int @return: list of lists of int @rtype: [[int],[int]..] """ ## how many groups are necessary? n_centers = len( a_indices ) / maxPerCenter if len( a_indices ) % maxPerCenter: n_centers += 1 ## how many items/atoms go into each group? nAtoms = N.ones(n_centers, N.Int) * int(len( a_indices ) / n_centers) i=0 while N.sum(nAtoms) != len( a_indices ): nAtoms[i] += 1 i += 1 ## distribute atom indices into groups result = [] pos = 0 for n in nAtoms: result += [ N.take( a_indices, N.arange(n) + pos) ] pos += n return result
def Map(values, colorMap, mini=None, maxi=None): """Get colors corresponding to values in a colormap""" values = Numeric.array(values) if len(values.shape)==2 and values.shape[1]==1: values.shape = ( values.shape[0], ) elif len(values.shape) > 1: print 'ERROR: values array has bad shape' return None cmap = Numeric.array(colorMap) if len(cmap.shape) !=2 or cmap.shape[1] not in (3,4): print 'ERROR: colorMap array has bad shape' return None if mini is None: mini = min(values) else: values = Numeric.maximum(values, mini) if maxi is None: maxi = max(values) else: values = Numeric.minimum(values, maxi) valrange = maxi-mini if valrange < 0.0001: ind = Numeric.ones( values.shape ) else: colrange = cmap.shape[0]-1 ind = ((values-mini) * colrange) / valrange col = Numeric.take(colorMap, ind.astype(viewerConst.IPRECISION)) return col
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
def valuesOf(self, infoKey, default=None, indices=None, unique=0 ): """ Get all values of a certain info record of all or some Complexes. @param infoKey: key for info dict @type infoKey: str @param default: default value if infoKey is not found (None) @type default: any @param indices: list of int OR None(=all), indices of Complexes (None) @type indices: [int] OR None @param unique: report each value only once (set union), (default 0) @type unique: 1|0 @return: list of values @rtype: [any] """ l = self if indices != None: l = N.take( N.array(l,'O'), indices ) if not unique: return [ c.info.get(infoKey, default) for c in l ] r = [] for c in l: if c.info.get(infoKey, default) not in r: r += [ c.info.get( infoKey ) ] return r
def tripples( self, lst, n ): """ Group items of lst into n tripples with minimal overlap. """ all = [] l = len( lst ) ## get all possible tripples for i in range( l ): for j in range( i+1, l ): for k in range( j+1, l ): all += [ ( lst[i], lst[j], lst[k] ) ] ## calculate pairwise "distance" between tripples pw = N.zeros( (len(all), len(all)), N.Float32 ) for i in range( len( all ) ): for j in range( i, len(all) ): pw[i,j] = pw[j,i] = len( MU.intersection(all[i],all[j]) )**2 pos = 0 r = [] while len( r ) < n: r += [ pos ] ## overlap of selected tripples with all others overlap = N.sum( N.array( [ pw[ i ] for i in r ] ) ) ## select one with lowest overlap to all tripples selected before pos = N.argmin( overlap ) return N.take( all, r )
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
def get_coordinates(universe, E, indices=None, atom_names=('CA',), residue_index_list=None, atom_index_list=None): from numpy.oldnumeric import array, take if indices is None: indices = range(len(E)) chain = universe.get_polymer() if atom_index_list is None: atom_index_list, index_map = compile_index_list(chain, atom_names, residue_index_list) l = [] for i in indices: chain.set_torsions(E.torsion_angles[i], 1) X = array(take(universe.X, atom_index_list)) l.append(X) return array(l)
def get_coordinates(universe, E, indices=None, atom_names=('CA', ), residue_index_list=None, atom_index_list=None): from numpy.oldnumeric import array, take if indices is None: indices = list(range(len(E))) chain = universe.get_polymer() if atom_index_list is None: atom_index_list, index_map = compile_index_list( chain, atom_names, residue_index_list) l = [] for i in indices: chain.set_torsions(E.torsion_angles[i], 1) X = array(take(universe.X, atom_index_list)) l.append(X) return array(l)
def getResFluct(self, atomFluctList=None): """ Convert list of atomic fluctuations to list of residue fluctuation. @param atomFluctList: array 1 x N_atoms of float @type atomFluctList: [float] @return: array 1 x N_residues of float @rtype: [float] @raise TrajError: if result length <> N_residues: """ if atomFluctList == None: atomFluctList = self.getFluct_global() ## Give all atoms of each res. the same fluct. value ## (the highest fluctuation of any backbone atom) result = self.residusMaximus(atomFluctList, self.ref.maskBB()) ## take first atoms only result = N.take(result, self.ref.resIndex()) ## result = N.compress( self.ref.maskCA(), atomFluctList) ## check dimension if len(result) <> self.ref.lenResidues(): raise TrajError( "getResFluct(): Length of result list (%i) <>" % len(result) + " number of residues (%i)." % self.ref.lenResidues()) return result
def reduceToModel(self, xyz=None, reduce_profiles=1): """ Create a reduced PDBModel from coordinates. Atom profiles the source PDBModel are reduced by averaging over the grouped atoms. @param xyz: coordinte array (N_atoms x 3) or None (->use reference coordinates) @type xyz: array OR None @return: PDBModel with reduced atom set and profile 'mass' @rtype: PDBModel """ mass = self.m.atoms.get('mass') if xyz is None: xyz = self.m.getXyz() mProf = [N.sum(N.take(mass, group)) for group in self.groups] xyz = self.reduceXyz(xyz) result = PDBModel() for k in self.atoms.keys(): result.atoms.set(k, self.atoms.valuesOf(k)) ## result.setAtoms( self.atoms ) result.setXyz(xyz) result.atoms.set('mass', mProf) if reduce_profiles: self.reduceAtomProfiles(self.m, result) result.residues = self.m.residues return result
def reduceToModel( self, xyz=None, reduce_profiles=1 ): """ Create a reduced PDBModel from coordinates. Atom profiles the source PDBModel are reduced by averaging over the grouped atoms. @param xyz: coordinte array (N_atoms x 3) or None (->use reference coordinates) @type xyz: array OR None @return: PDBModel with reduced atom set and profile 'mass' @rtype: PDBModel """ mass = self.m.atoms.get('mass') if xyz is None: xyz = self.m.getXyz() mProf = [ N.sum( N.take( mass, group ) ) for group in self.groups ] xyz = self.reduceXyz( xyz ) result = PDBModel() for k in self.atoms.keys(): result.atoms.set( k, self.atoms.valuesOf(k) ) ## result.setAtoms( self.atoms ) result.setXyz( xyz ) result.atoms.set( 'mass', mProf ) if reduce_profiles: self.reduceAtomProfiles( self.m, result ) result.residues = self.m.residues return result
def takeAtoms( self, indices, returnClass=None ): """ Take atoms from frames:: takeAtoms( indices, type=None ) -> copy of Trajectory @param indices: list of atom indices @type indices: [int] @param returnClass: default: None, same class as this object @type returnClass: class OR None @return: copy of this Trajectory (with fewer atoms) @rtype: Trajectory """ returnClass = returnClass or self.__class__ r = returnClass() ## copy over everything, so that child classes can preserve own fields r.__dict__.update( self.__dict__ ) r.frames = r.ref = r.frameNames = r.profiles = None r.frames = N.take( self.frames, indices, 1 ) r.setRef( self.ref.take( indices ) ) r.frameNames = copy.copy( self.frameNames ) r.resIndex = None r.profiles = self.profiles.clone() r.pc = self.pc ## this is not really clean return r
def convertChainIdsNter( self, model, chains ): """ Convert normal chain ids to chain ids considering chain breaks. """ if len(chains) == 0: return chains i = N.take( model.chainIndex(), chains ) ## convert back to chain indices but this time including chain breaks return model.atom2chainIndices( i, breaks=1 )
def Map(self, values, mini='not passed', maxi='not passed'): """Get colors corresponding to values in a colormap. if mini or maxi are provided, self.mini and self.maxi are not used and stay inchanged. if mini or maxi are not provided or set to None, self.mini and self.maxi are used instead. if mini or maxi are set to None, self.mini and self.maxi are ignored """ #print "Map", mini, maxi, self.mini, self.maxi, values values = Numeric.array(values) if len(values.shape) == 2 and values.shape[1] == 1: values.shape = (values.shape[0], ) elif len(values.shape) > 1: raise ValueError('ERROR! values array has bad shape') ramp = Numeric.array(self.ramp) if len(ramp.shape) != 2 or ramp.shape[1] not in (3, 4): raise ValueError('ERROR! colormap array has bad shape') if mini == 'not passed': mini = self.mini if maxi == 'not passed': maxi = self.maxi if mini is None: mini = min(values) else: # All the values < mini will be set to mini values = Numeric.maximum(values, mini) if maxi is None: maxi = max(values) else: values = Numeric.minimum(values, maxi) # mini and maxi are now set if mini >= maxi: txt = 'mini:%f must be < maxi:%f' % (mini, maxi) warnings.warn(txt) valrange = maxi - mini if valrange < 0.0001: ind = Numeric.ones(values.shape) else: colrange = ramp.shape[0] ind = (values - mini) * (colrange / float(valrange)) ind = ind.astype(viewerConst.IPRECISION) ind = Numeric.minimum(ind, colrange - 1) col = Numeric.take(self.ramp, ind) self.lastMini = mini self.lastMaxi = maxi return col
def Map(self, values, mini='not passed', maxi='not passed'): """Get colors corresponding to values in a colormap. if mini or maxi are provided, self.mini and self.maxi are not used and stay inchanged. if mini or maxi are not provided or set to None, self.mini and self.maxi are used instead. if mini or maxi are set to None, self.mini and self.maxi are ignored """ #print "Map", mini, maxi, self.mini, self.maxi, values values = Numeric.array(values) if len(values.shape)==2 and values.shape[1]==1: values.shape = ( values.shape[0], ) elif len(values.shape) > 1: raise ValueError('ERROR! values array has bad shape') ramp = Numeric.array(self.ramp) if len(ramp.shape) !=2 or ramp.shape[1] not in (3,4): raise ValueError('ERROR! colormap array has bad shape') if mini == 'not passed': mini = self.mini if maxi == 'not passed': maxi = self.maxi if mini is None: mini = min(values) else: # All the values < mini will be set to mini values = Numeric.maximum(values, mini) if maxi is None: maxi = max(values) else: values = Numeric.minimum(values, maxi) # mini and maxi are now set if mini >= maxi: txt = 'mini:%f must be < maxi:%f'%(mini, maxi) warnings.warn( txt ) valrange = maxi - mini if valrange < 0.0001: ind = Numeric.ones( values.shape ) else: colrange = ramp.shape[0] ind = (values - mini) * (colrange/float(valrange)) ind = ind.astype(viewerConst.IPRECISION) ind = Numeric.minimum(ind, colrange - 1) col = Numeric.take(self.ramp, ind ) self.lastMini = mini self.lastMaxi = maxi return col
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
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
def pca(M): "Perform PCA on M, return eigenvectors and eigenvalues, sorted." T, N = shape(M) # if there are fewer rows T than columns N, use snapshot method if T < N: C = dot(M, t(M)) evals, evecsC = eigenvectors(C) # HACK: make sure evals are all positive evals = where(evals < 0, 0, evals) evecs = 1. / sqrt(evals) * dot(t(M), t(evecsC)) else: # calculate covariance matrix K = 1. / T * dot(t(M), M) evals, evecs = eigenvectors(K) # sort the eigenvalues and eigenvectors, descending order order = (argsort(evals)[::-1]) evecs = take(evecs, order, 1) evals = take(evals, order) return evals, t(evecs)
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
def convertChainIdsCter( self, model, chains ): """ Convert normal chain ids to chain ids considering chain breaks. """ if len(chains) == 0: return chains ## fetch last atom of given chains index = N.concatenate( (model.chainIndex(), [len(model)]) ) i = N.take( index, N.array( chains ) + 1 ) - 1 ## convert back to chain indices but this time including chain breaks return model.atom2chainIndices( i, breaks=1 )
def coef_maxCut(self, appxCoef): """returns the coefficients different from zero up to the abs. max. coefficient where the first coefficient is excluded from finding the max. accepts 2d matrix of coefficients where rows represent different curves """ assert len(appxCoef.shape) == 2 k = Numeric.shape(appxCoef)[1] maxInd = Numeric.argmax(Numeric.absolute(appxCoef[:,1:]),1) + 1 lowDiagOnes = Numeric.fromfunction(lambda i,j: i>=j, (k,k)) coefSelector = Numeric.take(lowDiagOnes, maxInd, 0) return appxCoef*coefSelector
def coef_maxCut(self, appxCoef): """returns the coefficients different from zero up to the abs. max. coefficient where the first coefficient is excluded from finding the max. accepts 2d matrix of coefficients where rows represent different curves """ assert len(appxCoef.shape) == 2 k = Numeric.shape(appxCoef)[1] maxInd = Numeric.argmax(Numeric.absolute(appxCoef[:, 1:]), 1) + 1 lowDiagOnes = Numeric.fromfunction(lambda i, j: i >= j, (k, k)) coefSelector = Numeric.take(lowDiagOnes, maxInd, 0) return appxCoef * coefSelector
def __shuffleList(self, lst): """ shuffle order of lst @param lst: list to shuffle @type lst: [any] @return: shuffeled list @rtype: [any] """ pos = RandomArray.permutation(len(lst)) return N.take(lst, pos)
def fit( self, traj, refModel=None, mask=None, conv=1e-6 ): """ Fit trajectory until convergence onto it's own average and then transform the average of all frames onto the reference. @param traj: trajectory in which to fit frames @type traj: Trajectory @param refModel: reference PDBModel @type refModel: PDBModel @param mask: atom mask for superposition (default: all) @type mask: [1|0] @param conv: convergence criteria (default: 1e-6) @type conv: float """ self.fit_e = self.fit_e or len( traj ) self.fit_s = self.fit_s or 0 traj.fit( ref=traj.ref, mask=mask ) m_avg = traj[self.fit_s : self.fit_e ].avgModel() ## fit on average until it's not getting better d = 1. dd= 1. while dd >= conv: traj.fit( ref=m_avg, mask=mask ) m_new_avg = traj[self.fit_s : self.fit_e].avgModel() oldD, d = d, m_avg.rms( m_new_avg, mask=mask ) if self.verbose: self.log.add( "rms difference: %f" % d ) dd = oldD - d m_avg = m_new_avg ## transform trajectory en block onto reference if refModel: if self.verbose: self.log.add('fitting trajectory en-block onto reference...') if refModel.atomNames() != traj.ref.atomNames(): if self.verbose: self.log.add('casting ref for fitting...') ref_i, i = refModel.compareAtoms( m_avg ) refModel = refModel.take( ref_i ) m_avg = m_avg.take( i ) if not mask is None: mask = N.take( mask, i ) r, t = m_avg.transformation( refModel, mask ) traj.transform( r, t )
def __shuffleList(self, lst ): """ shuffle order of lst @param lst: list to shuffle @type lst: [any] @return: shuffeled list @rtype: [any] """ pos = RandomArray.permutation( len( lst )) return N.take( lst, pos )
def fit(self, traj, refModel=None, mask=None, conv=1e-6): """ Fit trajectory until convergence onto it's own average and then transform the average of all frames onto the reference. @param traj: trajectory in which to fit frames @type traj: Trajectory @param refModel: reference PDBModel @type refModel: PDBModel @param mask: atom mask for superposition (default: all) @type mask: [1|0] @param conv: convergence criteria (default: 1e-6) @type conv: float """ self.fit_e = self.fit_e or len(traj) self.fit_s = self.fit_s or 0 traj.fit(ref=traj.ref, mask=mask) m_avg = traj[self.fit_s:self.fit_e].avgModel() ## fit on average until it's not getting better d = 1. dd = 1. while dd >= conv: traj.fit(ref=m_avg, mask=mask) m_new_avg = traj[self.fit_s:self.fit_e].avgModel() oldD, d = d, m_avg.rms(m_new_avg, mask=mask) if self.verbose: self.log.add("rms difference: %f" % d) dd = oldD - d m_avg = m_new_avg ## transform trajectory en block onto reference if refModel: if self.verbose: self.log.add('fitting trajectory en-block onto reference...') if refModel.atomNames() != traj.ref.atomNames(): if self.verbose: self.log.add('casting ref for fitting...') ref_i, i = refModel.compareAtoms(m_avg) refModel = refModel.take(ref_i) m_avg = m_avg.take(i) if not mask is None: mask = N.take(mask, i) r, t = m_avg.transformation(refModel, mask) traj.transform(r, t)
def reduceXyz(self, xyz, axis=0): """ Reduce the number of atoms in the given coordinate set. The set must have the same length and order as the reference model. It may have an additional (time) dimension as first axis. @param xyz: coordinates (N_atoms x 3) or (N_frames x N_atoms x 3) @type xyz: array @param axis: axis with atoms (default: 0) @type axis: int @return: coordinate array (N_less_atoms x 3) or (N_frames x N_less_atoms x 3) @rtype: array """ masses = self.m.atoms.get('mass') r_xyz = None for atom_indices in self.groups: x = N.take(xyz, atom_indices, axis) m = N.take(masses, atom_indices) center = N.sum(x * N.transpose([ m, ]), axis=axis) / N.sum(m) if axis == 0: center = center[N.NewAxis, :] if axis == 1: center = center[:, N.NewAxis, :] if r_xyz == None: r_xyz = center else: r_xyz = N.concatenate((r_xyz, center), axis) return r_xyz
def __init__(self, points, k, normalization=NORM_NORM_T0_1, force=False): """ calculate k polynomials of degree 0 to k-1 orthogonal on a set of distinct points map points to interval [-1,1] INPUT: points: array of dictinct points where polynomials are orthogonal k: number of polynomials of degree 0 to k-1 force=True creates basis even if orthogonality is not satisfied due to numerical error USES: x: array of points mapped to [-1,1] T_: matrix of values of polynomials calculated at x, shape (k,len(x)) TT_ = T_ * Numeric.transpose(T_) TTinv_ = inverse(TT_) sc_: scaling factors a, b: coefficients for calculating T (2k-4 different from 0, i.e. 6 for k=5) n: number of points = len(points) normalization = {0|1|2} """ self.k = k # number of basis polynomials of order 0 to k-1 self._force = force self.points = Numeric.asarray(points, Numeric.Float) self.pointsMin = min(points) self.pointsMax = max(points) # scaling x to [-1,1] results in smaller a and b, T is not affected; overflow is NOT a problem! self.xMin = -1 self.xMax = 1 self.x = self._map(self.points, self.pointsMin, self.pointsMax, self.xMin, self.xMax) # calculate basis polynomials self.n = len(points) # the number of approximation points t = Numeric.zeros((k,self.n),Numeric.Float) a = Numeric.zeros((k,1),Numeric.Float) b = Numeric.zeros((k,1),Numeric.Float) t[0,:] = Numeric.ones(self.n,Numeric.Float) if k > 1: t[1,:] = self.x - sum(self.x)/self.n for i in range(1,k-1): a[i+1] = Numeric.innerproduct(self.x, t[i,:] * t[i,:]) / Numeric.innerproduct(t[i,:],t[i,:]) b[i] = Numeric.innerproduct(t[i,:], t[i,:]) / Numeric.innerproduct(t[i-1,:],t[i-1,:]) t[i+1,:] = (self.x - a[i+1]) * t[i,:] - b[i] * t[i-1,:] self.a = a self.b = b # prepare for approximation self._T0 = t # orthonormal _TT0 = Numeric.matrixmultiply(self._T0, Numeric.transpose(self._T0)) self.sc1 = Numeric.sqrt(Numeric.reshape(Numeric.diagonal(_TT0),(self.k,1))) # scaling factors = sqrt sum squared self._T0 self._T1 = self._T0 / self.sc1 # orthonormal and T[0] == 1 self.sc2 = Numeric.sqrt(Numeric.reshape(Numeric.diagonal(_TT0),(self.k,1)) / self.n) # scaling factors = sqrt 1/n * sum squared self._T0 self._T2 = self._T0 / self.sc2 # T[:,-1] == 1 self.sc3 = Numeric.take(self._T0, (-1,), 1) # scaling factors = self._T0[:,-1] self._T3 = self._T0 / self.sc3 # set the variables according to the chosen normalization self.setNormalization(normalization)
def __takePca( self, indices ): """ extract PCA results for certain frames. @param indices: frame indecies @type indices: [int] @return: list of pca values @rtype: [float] """ result = copy.deepcopy( getattr(self, 'pc', None )) if result != None: result['p'] = N.take( result['p'], indices, 0 ) result['u'] = N.take( result['u'], indices, 0 ) if result['fMask'] != None: result['fMask'] = N.take( result['fMask'], indices, 0 ) return result
def __takePca(self, indices): """ extract PCA results for certain frames. @param indices: frame indecies @type indices: [int] @return: list of pca values @rtype: [float] """ result = copy.deepcopy(getattr(self, 'pc', None)) if result != None: result['p'] = N.take(result['p'], indices, 0) result['u'] = N.take(result['u'], indices, 0) if result['fMask'] != None: result['fMask'] = N.take(result['fMask'], indices, 0) return result
def calcProfiles(self, m): """ Calculate needed profiles. @param m: PDBModel to calculate data for @type m: PDBModel """ if self.verbose: print "Initiating PDBDope..." d = PDBDope(m) if not self.profileName in m.atoms.keys(): if self.profileName in ['MS', 'AS', 'curvature', 'relAS', 'relMS']: if self.verbose: print "Adding SurfaceRacer profile...", d.addSurfaceRacer() if self.profileName in ['relASA']: if self.verbose: print "Adding WhatIf ASA...", d.addASA() if self.profileName in ['density']: if self.verbose: print "Adding surface density...", d.addDensity() if not self.profileName in m.residues.keys(): if self.profileName in ['cons_abs', 'cons_max', 'cons_ent']: if self.verbose: print "Adding conservation data...", d.addConservation() if self.profileName in ['ASA_total', 'ASA_sc', 'ASA_bb']: if self.verbose: print "Adding WhatIf ASA...", d.addASA() if self.verbose: print 'Done.' ## convert atom profiles to average residue profile if self.profileName in m.atoms.keys(): prof = [] aProfile = m.profile(self.profileName) resIdx = m.resIndex().tolist() resIdx += [m.lenAtoms()] for i in range(len(resIdx) - 1): prof += [ N.average(N.take(aProfile, range(resIdx[i], resIdx[i + 1]))) ] else: prof = m.profile(self.profileName) return prof
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
def reduceXyz( self, xyz, axis=0 ): """ Reduce the number of atoms in the given coordinate set. The set must have the same length and order as the reference model. It may have an additional (time) dimension as first axis. @param xyz: coordinates (N_atoms x 3) or (N_frames x N_atoms x 3) @type xyz: array @param axis: axis with atoms (default: 0) @type axis: int @return: coordinate array (N_less_atoms x 3) or (N_frames x N_less_atoms x 3) @rtype: array """ masses = self.m.atoms.get('mass') r_xyz = None for atom_indices in self.groups: x = N.take( xyz, atom_indices, axis ) m = N.take( masses, atom_indices ) center = N.sum( x * N.transpose([m,]), axis=axis) / N.sum( m ) if axis == 0: center = center[N.NewAxis, :] if axis == 1: center = center[:, N.NewAxis, :] if r_xyz == None: r_xyz = center else: r_xyz = N.concatenate( (r_xyz, center), axis ) return r_xyz
def getMatrices(self): outMatrices=[] indicesComp = range(len(self.inMatrices)) if self.indices[0] == []: self.indices[0] = indicesComp fullList = [] else: fullList = Numeric.concatenate(self.indices) map( indicesComp.remove, fullList ) self.indices.insert(0,indicesComp) for i in range(len(self.indices)): outMatrices.append(Numeric.take(self.inMatrices, self.indices[i])) return outMatrices
def orderCenters(self, points, origin=None): """ Order random points by increasing distance to first or to origin. points - n x 3 array of float, random center coordinates origin - 3 array of float -> [ int ], indices into points ordered by increasing distance """ origin = origin if origin is None: origin = points[0] dist = self.__distances(origin, points) return N.take(points, N.argsort(dist))
def sortPoly(self, geom,vt, order=-1): """None <- sortPoly(order=-1) Sorts the geometry polygons according to z values of polygon's geomtric centers. Order=-1 sorts by furthest z first, order=1 sorts by closest z first""" # FIXME will not work with instance matrices #mat = geom.GetMatrix() #mat = Numeric.reshape(mat, (4,4)) #vt = geom.vertexSet.vertices*mat if vt is None: return triv = Numeric.take(vt, geom.faceSet.faces.array) trig = Numeric.sum(triv,1)/3. trigz = trig[:,2] #triangle's center of gravity z value ind = Numeric.argsort(trigz) # sorted indices if len(geom.faceSet.faces.array): faces = Numeric.take(geom.faceSet.faces.array, ind[::order]) n = geom.getFNormals() n = geom.faceSet.normals * geom.GetMatrix() normals = Numeric.take(n, ind[::order]) # #if geom.shading==GL.GL_FLAT: # we also need to re-arrange the # # face normals # if geom.normals is None: # normals = None # else: # if len(geom.normals)>1: #normals = Numeric.take(geom.normals, ind[::order]) # else: # normals = geom.normals # else: # normals = None #normals = None #geom.Set(faces=faces, fnormals=normals) return faces.copy(),normals.copy()
def memberIndices( self, member, step=1 ): """ List of frame indices for this member:: memberIndices( int_member, [int_step] ) @param member: member trajectory @type member: int @param step: return only every i'th frame (default: 1) @type step: int @return: indices for members @rtype: [int] """ r = range( member, self.lenFrames(), self.n_members ) if step != 1: r = N.take( r, range( 0, len( r ), step ) ).tolist() return r
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