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 = N0.shape( matrix ) ## get array from matrix that is to be randomized if mask is not None: if len(mask) == len( N0.ravel(matrix) ): array = N0.compress( mask, N0.ravel(matrix) ) if len(mask) != len( N0.ravel(matrix) ): raise MathUtilError( 'MatUtils.random2DArray - mask of incorrect length' + '\tMatrix length: %i Mask length: %i'\ %(len( N0.ravel(matrix) ), len(mask))) if not mask: array = N0.ravel(matrix) ## number of ones and length of array nOnes = int( N0.sum( array ) ) lenArray = len( array ) ranArray = N0.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 = N0.zeros(a*b) N0.put( r, N0.nonzero(mask), ranArray) return N0.reshape( r, (a,b) ) if not mask: return N0.reshape( ranArray, (a,b) )
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 = N0.shape(matrix) ## get array from matrix that is to be randomized if mask is not None: if len(mask) == len(N0.ravel(matrix)): array = N0.compress(mask, N0.ravel(matrix)) if len(mask) != len(N0.ravel(matrix)): raise MathUtilError( 'MatUtils.random2DArray - mask of incorrect length' + '\tMatrix length: %i Mask length: %i'\ %(len( N0.ravel(matrix) ), len(mask))) if not mask: array = N0.ravel(matrix) ## number of ones and length of array nOnes = int(N0.sum(array)) lenArray = len(array) ranArray = N0.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 = N0.zeros(a * b) N0.put(r, N0.nonzero(mask), ranArray) return N0.reshape(r, (a, b)) if not mask: return N0.reshape(ranArray, (a, b))
def loadResContacts(self): """ Uncompress residue contact matrix if necessary. @return: dict with contact matrix and parameters OR None @rtype: dict OR None """ ## Backwards compatibility if self.contacts is not None and type(self.contacts) == str: self.contacts = t.load(self.contacts) EHandler.warning("loading old-style pickled contacts.") return self.contacts ## New, uncompression from list of indices into raveled array if self.contacts is not None and \ len( N0.shape( self.contacts['result'])) == 1: try: lenRec, lenLig = self.contacts['shape'] except: EHandler.warning("uncompressing contacts without shape") lenRec = self.rec().lenResidues() lenLig = self.lig().lenResidues() m = N0.zeros(lenRec * lenLig) N0.put(m, self.contacts['result'], 1) self.contacts['result'] = N0.reshape(m, (lenRec, lenLig)) return self.contacts
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 __atom2residueMatrix(self, m): """ Reduce binary matrix of n x k atoms to binary matrix of i x j residues. @param m: atom contact matrix, array n x k with 1(contact) or 0(no contact) @type m: array @return: residue contact matrix, 2-D numpy array(residues_receptor x residues_ligand) @rtype: array """ recInd = N0.concatenate( (self.rec().resIndex(), [self.rec().lenAtoms()])) ligInd = N0.concatenate( (self.lig_model.resIndex(), [self.lig_model.lenAtoms()])) residueMatrix = N0.zeros((len(recInd) - 1, len(ligInd) - 1), N0.Int) for r in range(len(recInd) - 1): for l in range(len(ligInd) - 1): res2res = m[int(recInd[r]):int(recInd[r + 1]), int(ligInd[l]):int(ligInd[l + 1])] if N0.any(res2res): residueMatrix[r, l] = 1 return residueMatrix
def randomMask( nOnes, length ): """ Create random array of given lenght and number of ones. :param nOnes: number of ones :type nOnes: int :param length: lenght of array :type length: int :return: array with ones and zeros :rtype: array( 1|0 ) """ r = N0.zeros( length ) pos = [] ## add random ones for i in range( nOnes ): pos += [ int( random.random() * length ) ] N0.put( r, pos, 1 ) ## if two ones ended up on the same position while nOnes != N0.sum(r): pos = int( random.random() * length ) N0.put( r, pos, 1 ) return r
def unpackBinaryMatrix(pcm, raveled=0): """ Uncompress array of 0 and 1 that was compressed with :class:`packBinaryMatrix`. :param pcm: {'shape':(X,Y,..), 'nonzero':[int]} :type pcm: dict :param raveled: return raveled (default: 0) :type raveled: 1|0 :return: N0.array(X by Y by ..) of int :rtype: 2D array """ if type(pcm) != dict: return pcm s = pcm['shape'] m = N0.zeros(N0.cumproduct(s)[-1], N0.Int) pass ## m.savespace( 1 ) N0.put(m, pcm['nonzero'], 1) if raveled: return m return N0.reshape(m, s)
def randomMask(nOnes, length): """ Create random array of given lenght and number of ones. :param nOnes: number of ones :type nOnes: int :param length: lenght of array :type length: int :return: array with ones and zeros :rtype: array( 1|0 ) """ r = N0.zeros(length) pos = [] ## add random ones for i in range(nOnes): pos += [int(random.random() * length)] N0.put(r, pos, 1) ## if two ones ended up on the same position while nOnes != N0.sum(r): pos = int(random.random() * length) N0.put(r, pos, 1) return r
def __atom2residueMatrix( self, m ): """ Reduce binary matrix of n x k atoms to binary matrix of i x j residues. @param m: atom contact matrix, array n x k with 1(contact) or 0(no contact) @type m: array @return: residue contact matrix, 2-D numpy array(residues_receptor x residues_ligand) @rtype: array """ recInd = N0.concatenate((self.rec().resIndex(), [ self.rec().lenAtoms()] )) ligInd = N0.concatenate((self.lig_model.resIndex(), [ self.lig_model.lenAtoms() ] )) residueMatrix = N0.zeros(( len(recInd)-1, len(ligInd)-1 ), N0.Int) for r in range( len(recInd)-1 ): for l in range( len(ligInd)-1 ): res2res = m[ int(recInd[r]):int(recInd[r+1]), int(ligInd[l]):int(ligInd[l+1]) ] if N0.any( res2res ): residueMatrix[r, l] = 1 return residueMatrix
def unpackBinaryMatrix( pcm, raveled=0 ): """ Uncompress array of 0 and 1 that was compressed with :class:`packBinaryMatrix`. :param pcm: {'shape':(X,Y,..), 'nonzero':[int]} :type pcm: dict :param raveled: return raveled (default: 0) :type raveled: 1|0 :return: N0.array(X by Y by ..) of int :rtype: 2D array """ if type( pcm ) != dict: return pcm s = pcm['shape'] m = N0.zeros( N0.cumproduct( s )[-1], N0.Int) pass ## m.savespace( 1 ) N0.put( m, pcm['nonzero'], 1 ) if raveled: return m return N0.reshape( m, s )
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 loadResContacts( self ): """ Uncompress residue contact matrix if necessary. @return: dict with contact matrix and parameters OR None @rtype: dict OR None """ ## Backwards compatibility if self.contacts is not None and type( self.contacts ) == str: self.contacts = t.load( self.contacts ) EHandler.warning("loading old-style pickled contacts.") return self.contacts ## New, uncompression from list of indices into raveled array if self.contacts is not None and \ len( N0.shape( self.contacts['result'])) == 1: try: lenRec, lenLig = self.contacts['shape'] except: EHandler.warning("uncompressing contacts without shape") lenRec = self.rec().lenResidues() lenLig = self.lig().lenResidues() m = N0.zeros( lenRec * lenLig ) N0.put( m, self.contacts['result'], 1 ) self.contacts['result'] = N0.reshape( m, (lenRec, lenLig) ) return self.contacts
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 = N0.zeros( (len(all), len(all)), N0.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 = N0.sum( N0.array( [ pw[ i ] for i in r ] ) ) ## select one with lowest overlap to all tripples selected before pos = N0.argmin( overlap ) return N0.take( all, r )
def pairwiseRmsd( self, aMask=None, noFit=0 ): """ Calculate rmsd between each 2 coordinate frames. :param aMask: atom mask :type aMask: [1|0] :return: frames x frames array of float :rtype: array """ frames = self.frames if aMask is not None: frames = N0.compress( aMask, frames, 1 ) result = N0.zeros( (len( frames ), len( frames )), N0.Float32 ) for i in range(0, len( frames ) ): for j in range( i+1, len( frames ) ): if noFit: d = N0.sqrt(N0.sum(N0.power(frames[i]-frames[j], 2), 1)) result[i,j] = result[j,i] = N0.sqrt( N0.average(d**2) ) else: rt, rmsdLst = rmsFit.match( frames[i], frames[j], 1 ) result[i,j] = result[j,i] = rmsdLst[0][1] 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 = N0.zeros((len(all), len(all)), N0.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 = N0.sum(N0.array([pw[i] for i in r])) ## select one with lowest overlap to all tripples selected before pos = N0.argmin(overlap) return N0.take(all, r)
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 test_MatrixPlot( self ): """MatrixPlot test""" n = 30 z = N0.zeros((n,n), N0.Float) for i in range(N0.shape(z)[0]): for j in range(N0.shape(z)[1]): z[i,j] = N0.exp(-0.01*((i-n/2)**2+(j-n/2)**2)) self.p = MatrixPlot(z, palette='sausage', legend=1) if self.local or self.VERBOSITY > 2: self.p.show() self.assertTrue( self.p is not None )
def area(curve, start=0.0, stop=1.0): """ Numerically add up the area under the given curve. The curve is a 2-D array or list of tupples. The x-axis is the first column of this array (curve[:,0]). (originally taken from biskit.Statistics.ROCalyzer) :param curve: a list of x,y coordinates :type curve: [ (y,x), ] or N0.array :param start: lower boundary (in x) (default: 0.0) :type start: float :param stop: upper boundary (in x) (default: 1.0) :type stop: float :return: the area underneath the curve between start and stop. :rtype: float """ ## convert and swap axes curve = N0.array(curve) c = N0.zeros(N0.shape(curve), curve.dtype) c[:, 0] = curve[:, 1] c[:, 1] = curve[:, 0] assert len(N0.shape(c)) == 2 ## apply boundaries ## here we have a problem with flat curves mask = N0.greater_equal(c[:, 1], start) mask *= N0.less_equal(c[:, 1], stop) c = N0.compress(mask, c, axis=0) ## fill to boundaries -- not absolutely accurate: we actually should ## interpolate to the neighboring points instead c = N0.concatenate((N0.array([ [c[0, 0], start], ]), c, N0.array([ [c[-1, 0], stop], ]))) x = c[:, 1] y = c[:, 0] dx = x[1:] - x[:-1] # distance on x between points dy = y[1:] - y[:-1] # distance on y between points areas1 = y[:-1] * dx # the rectangles between all points areas2 = dx * dy / 2.0 # the triangles between all points return N0.sum(areas1) + N0.sum(areas2)
def area(curve, start=0.0, stop=1.0 ): """ Numerically add up the area under the given curve. The curve is a 2-D array or list of tupples. The x-axis is the first column of this array (curve[:,0]). (originally taken from biskit.Statistics.ROCalyzer) :param curve: a list of x,y coordinates :type curve: [ (y,x), ] or N0.array :param start: lower boundary (in x) (default: 0.0) :type start: float :param stop: upper boundary (in x) (default: 1.0) :type stop: float :return: the area underneath the curve between start and stop. :rtype: float """ ## convert and swap axes curve = N0.array( curve ) c = N0.zeros( N0.shape(curve), curve.dtype ) c[:,0] = curve[:,1] c[:,1] = curve[:,0] assert len( N0.shape( c ) ) == 2 ## apply boundaries ## here we have a problem with flat curves mask = N0.greater_equal( c[:,1], start ) mask *= N0.less_equal( c[:,1], stop ) c = N0.compress( mask, c, axis=0 ) ## fill to boundaries -- not absolutely accurate: we actually should ## interpolate to the neighboring points instead c = N0.concatenate((N0.array([[c[0,0], start],]), c, N0.array([[c[-1,0],stop ],])) ) x = c[:,1] y = c[:,0] dx = x[1:] - x[:-1] # distance on x between points dy = y[1:] - y[:-1] # distance on y between points areas1 = y[:-1] * dx # the rectangles between all points areas2 = dx * dy / 2.0 # the triangles between all points return N0.sum(areas1) + N0.sum(areas2)
def memberMask( self, member ): """ Get mask for all frames belonging to a given ensemble member. :param member: member index starting with 0 :type member: int :return: member mask, N0.array( N_frames x 1) of 1||0 :rtype: [1|0] """ result = N0.zeros( self.lenFrames() ) if isinstance( member, (int, N0.integer)): N0.put( result, self.memberIndices( member ), 1 ) if type( member ) == list: for m in member: N0.put( result, self.memberIndices( m ), 1 ) return result
def eulerRotation(alpha, beta, gamma): """ Builds a rotation matrix from successive rotations: 1. rotation about y-axis by angle alpha 2. rotation about x-axis by angle beta 3. rotation about z-axis by angle gamma Written by Michael Habeck. :param alpha: euler angle S{alpha} :type alpha: float :param beta: euler angle S{beta} :type beta: float :param gamma: euler angle S{gamma} :type gamma: float :return: 3 x 3 array of float :rtype: array """ cos_alpha = N0.cos(alpha) sin_alpha = N0.sin(alpha) cos_beta = N0.cos(beta) sin_beta = N0.sin(beta) cos_gamma = N0.cos(gamma) sin_gamma = N0.sin(gamma) R = N0.zeros((3, 3), N0.Float32) R[0][0] = cos_gamma * cos_alpha - sin_gamma * cos_beta * sin_alpha R[0][1] = cos_gamma * sin_alpha + sin_gamma * cos_beta * cos_alpha R[0][2] = sin_gamma * sin_beta R[1][0] = -sin_gamma * cos_alpha - cos_gamma * cos_beta * sin_alpha R[1][1] = -sin_gamma * sin_alpha + cos_gamma * cos_beta * cos_alpha R[1][2] = cos_gamma * sin_beta R[2][0] = sin_beta * sin_alpha R[2][1] = -sin_beta * cos_alpha R[2][2] = cos_beta return R
def rotateAxis(theta, vector): """ Calculate a left multiplying rotation matrix that rotates theta rad around vector. Taken from: http://osdir.com/ml/python.bio.devel/2008-09/msg00084.html Example: >>> m=rotateAxis(pi, N0.array([1,0,0])) :type theta: float :param theta: the rotation angle :type vector: :class:`Vector` :param vector: the rotation axis :return: The rotation matrix, a 3x3 Numeric array. """ vector = vector / N0.linalg.norm(vector) x,y,z=vector c=N0.cos(theta) s=N0.sin(theta) t=1-c rot=N0.zeros((3,3), "d") # 1st row rot[0,0]=t*x*x+c rot[0,1]=t*x*y-s*z rot[0,2]=t*x*z+s*y # 2nd row rot[1,0]=t*x*y+s*z rot[1,1]=t*y*y+c rot[1,2]=t*y*z-s*x # 3rd row rot[2,0]=t*x*z-s*y rot[2,1]=t*y*z+s*x rot[2,2]=t*z*z+c return rot
def rotateAxis(theta, vector): """ Calculate a left multiplying rotation matrix that rotates theta rad around vector. Taken from: http://osdir.com/ml/python.bio.devel/2008-09/msg00084.html Example: >>> m=rotateAxis(pi, N0.array([1,0,0])) :type theta: float :param theta: the rotation angle :type vector: :class:`Vector` :param vector: the rotation axis :return: The rotation matrix, a 3x3 Numeric array. """ vector = vector / N0.linalg.norm(vector) x, y, z = vector c = N0.cos(theta) s = N0.sin(theta) t = 1 - c rot = N0.zeros((3, 3), "d") # 1st row rot[0, 0] = t * x * x + c rot[0, 1] = t * x * y - s * z rot[0, 2] = t * x * z + s * y # 2nd row rot[1, 0] = t * x * y + s * z rot[1, 1] = t * y * y + c rot[1, 2] = t * y * z - s * x # 3rd row rot[2, 0] = t * x * z - s * y rot[2, 1] = t * y * z + s * x rot[2, 2] = t * z * z + c return rot
def outliers(a, z=5, it=5): """ Iterative detection of outliers in a set of numeric values. Requirement: len(a) > 0; outlier detection is only performed if len(a)>2 :param a: array or list of values :type a: [ float ] :param z: z-score threshold for iterative refinement of median and SD :type z: float :param it: maximum number of iterations :type it: int :return: outlier mask, median and standard deviation of last iteration :rtype: N0.array( int ), float, float """ assert (len(a) > 0) mask = N0.ones(len(a)) out = N0.zeros(len(a)) if len(a) < 3: return out, N0.median(a), N0.std(a) for i in range(it): b = N0.compress(N0.logical_not(out), a) me = N0.median(b) sd = N0.std(b) bz = N0.absolute( (N0.array(a) - me) / sd) # pseudo z-score of each value o = bz > z ## print 'iteration %i: <%5.2f> +- %5.2f -- %i outliers' % (i,me,sd,N0.sum(o)) ## stop if converged or reached bottom if (N0.sum(o) == N0.sum(out)) or (N0.sum(o) > len(a) - 3): return o, me, sd out = o return out, me, sd
def outliers( a, z=5, it=5 ): """ Iterative detection of outliers in a set of numeric values. Requirement: len(a) > 0; outlier detection is only performed if len(a)>2 :param a: array or list of values :type a: [ float ] :param z: z-score threshold for iterative refinement of median and SD :type z: float :param it: maximum number of iterations :type it: int :return: outlier mask, median and standard deviation of last iteration :rtype: N0.array( int ), float, float """ assert( len(a) > 0 ) mask = N0.ones( len(a) ) out = N0.zeros( len(a) ) if len(a) < 3: return out, N0.median(a), N0.std(a) for i in range( it ): b = N0.compress( N0.logical_not(out), a ) me = N0.median( b ) sd = N0.std( b ) bz = N0.absolute((N0.array( a ) - me) / sd) # pseudo z-score of each value o = bz > z ## print 'iteration %i: <%5.2f> +- %5.2f -- %i outliers' % (i,me,sd,N0.sum(o)) ## stop if converged or reached bottom if (N0.sum(o) == N0.sum(out)) or (N0.sum(o) > len(a) - 3): return o, me, sd out = o return out, me, sd
def eulerRotation(alpha, beta, gamma): """ Builds a rotation matrix from successive rotations: 1. rotation about y-axis by angle alpha 2. rotation about x-axis by angle beta 3. rotation about z-axis by angle gamma Written by Michael Habeck. :param alpha: euler angle S{alpha} :type alpha: float :param beta: euler angle S{beta} :type beta: float :param gamma: euler angle S{gamma} :type gamma: float :return: 3 x 3 array of float :rtype: array """ cos_alpha = N0.cos(alpha); sin_alpha = N0.sin(alpha) cos_beta = N0.cos(beta); sin_beta = N0.sin(beta) cos_gamma = N0.cos(gamma); sin_gamma = N0.sin(gamma) R = N0.zeros((3,3), N0.Float32) R[0][0] = cos_gamma * cos_alpha - sin_gamma * cos_beta * sin_alpha R[0][1] = cos_gamma * sin_alpha + sin_gamma * cos_beta * cos_alpha R[0][2] = sin_gamma * sin_beta R[1][0] = -sin_gamma * cos_alpha - cos_gamma * cos_beta * sin_alpha R[1][1] = -sin_gamma * sin_alpha + cos_gamma * cos_beta * cos_alpha R[1][2] = cos_gamma * sin_beta R[2][0] = sin_beta * sin_alpha R[2][1] = -sin_beta * cos_alpha R[2][2] = cos_beta return R
def getFluct_local( self, mask=None, border_res=1, left_atoms=['C'], right_atoms=['N'], verbose=1 ): """ Get mean displacement of each atom from it's average position after fitting of each residue to the reference backbone coordinates of itself and selected atoms of neighboring residues to the right and left. :param mask: N_atoms x 1 array of 0||1, atoms for which fluctuation should be calculated :type mask: array :param border_res: number of neighboring residues to use for fitting :type border_res: int :param left_atoms: atoms (names) to use from these neighbore residues :type left_atoms: [str] :param right_atoms: atoms (names) to use from these neighbore residues :type right_atoms: [str] :return: Numpy array ( N_unmasked x 1 ) of float :rtype: array """ if mask is None: mask = N0.ones( len( self.frames[0] ), N0.Int32 ) if verbose: T.errWrite( "rmsd fitting per residue..." ) residues = N0.nonzero( self.ref.atom2resMask( mask ) ) ## backbone atoms used for fit fit_atoms_right = N0.nonzero( self.ref.mask( right_atoms ) ) fit_atoms_left = N0.nonzero( self.ref.mask( left_atoms ) ) ## chain index of each residue rchainMap = N0.take( self.ref.chainMap(), self.ref.resIndex() ) result = [] for res in residues: i_res, i_border = self.__resWindow(res, border_res, rchainMap, fit_atoms_left, fit_atoms_right) try: if not len( i_res ): raise PDBError('empty residue') t_res = self.takeAtoms( i_res + i_border ) i_center = range( len( i_res ) ) mask_BB = t_res.ref.maskBB() * t_res.ref.maskHeavy() ## fit with border atoms .. t_res.fit( ref=t_res.ref, mask=mask_BB, verbose=0 ) ## .. but calculate only with center residue atoms frames = N0.take( t_res.frames, i_center, 1 ) avg = N0.average( frames ) rmsd = N0.average(N0.sqrt(N0.sum(N0.power(frames - avg, 2), 2) )) result.extend( rmsd ) if verbose: T.errWrite('#') except ZeroDivisionError: result.extend( N0.zeros( len(i_res), N0.Float32 ) ) T.errWrite('?' + str( res )) if verbose: T.errWriteln( "done" ) return result