def checkConvergence(self, **kwargs): converged = False rmsd_diff_cutoff = kwargs.get('rmsd_diff_cutoff', self.rmsd_diff_cutoff) target_rmsd = kwargs.get('target_rmsd', self.target_rmsd) if self.rmsds[-2] - self.rmsds[-1] < rmsd_diff_cutoff: LOGGER.warn( 'The RMSD decrease fell below {0}'.format(rmsd_diff_cutoff)) converged = True if self.rmsds[-1] < target_rmsd: LOGGER.warn( 'The RMSD fell below target RMSD {0}'.format(target_rmsd)) converged = True all_dists = np.array([ calcDistance(self.structA, self.structA[i]) for i in range(self.structA.numAtoms()) ]) min_dists = np.array([ np.min([np.min(all_dists[i, :i]), np.min(all_dists[i, i + 1:])]) for i in range(1, self.structA.numAtoms() - 1) ]) if max(min_dists) > self.cutoff: LOGGER.warn( 'A bead has become disconnected. Adaptive ANM cannot proceed without unrealistic deformations' ) converged = True return converged
def testCoordArgumentSwitching(self): dist = 12. neighbors1 = findNeighbors(UCA_XYZ, dist, UCA_XYZ[1]) neighbors2 = findNeighbors(UCA_XYZ[1], dist, UCA_XYZ) n_neighbors = (calcDistance(UCA_XYZ, UCA_XYZ[1]) <= dist).sum() assert_equal(len(neighbors1), n_neighbors) neighbors1.sort() neighbors2.sort() assert_array_equal(array(neighbors1)[:, -1], array(neighbors2)[:, -1])
def testAtomicArgumentSwitching(self): dist = 12.0 neighbors1 = [(a.getIndex(), d) for a, b, d in iterNeighbors(UCA, dist, UCA[1])] neighbors2 = [(b.getIndex(), d) for a, b, d in iterNeighbors(UCA[1], dist, UCA)] n_neighbors = (calcDistance(UCA, UCA[1]) <= dist).sum() assert_equal(len(neighbors1), n_neighbors) neighbors1.sort() neighbors2.sort() self.assertEqual(neighbors1, neighbors2)
def testCoordArgumentSwitching(self): dist = 12.0 neighbors1 = findNeighbors(UCA_XYZ, dist, UCA_XYZ[1]) neighbors2 = findNeighbors(UCA_XYZ[1], dist, UCA_XYZ) n_neighbors = (calcDistance(UCA_XYZ, UCA_XYZ[1]) <= dist).sum() assert_equal(len(neighbors1), n_neighbors) neighbors1.sort() neighbors2.sort() assert_array_equal(array(neighbors1)[:, -1], array(neighbors2)[:, -1])
def testAtomicArgumentSwitching(self): dist = 12. neighbors1 = [(a.getIndex(), d) for a, b, d in iterNeighbors(UCA, dist, UCA[1])] neighbors2 = [(b.getIndex(), d) for a, b, d in iterNeighbors(UCA[1], dist, UCA)] n_neighbors = (calcDistance(UCA, UCA[1]) <= dist).sum() assert_equal(len(neighbors1), n_neighbors) neighbors1.sort() neighbors2.sort() self.assertEqual(neighbors1, neighbors2)
def checkDisconnection(coords, cutoff): """Check disconnection of ANM, i.e. a node in *coords* gets disconnected from another by > *cutoff*. This is one of the stopping criteria for adaptive ANM. """ all_dists = np.array([calcDistance(coords, entry) for entry in coords]) min_dists = np.array([ np.min([np.min(all_dists[i, :i]), np.min(all_dists[i, i + 1:])]) for i in range(1, coords.shape[0] - 1) ]) if max(min_dists) > cutoff: LOGGER.warn( 'A bead has become disconnected. ' 'Adaptive ANM cannot proceed without unrealistic deformations') return True return False
def countUnpairedBreaks(chone, chtwo, resnum=True): """This function is under development. Return number of unpaired breaks in aligned chains *chone* and *chtwo*, which are expected to be :class:`.AtomMap` instances obtained from one of :func:`.matchChains` or :func:`.mapOntoChain` functions. Pairwise global or local alignment of chains with missing residues may be problematic, as in the following illustrations for example. This function helps identifying some of these problems. Breaks in a chain are determined using Cα-Cα distances between consecutive residues, i.e. Cα to Cα distance larger than 4 Å corresponds to a break or gap of 1 or more residues. This function counts such breaks in *chone* or *chtwo* that is not paired with a break in the other. The following example illustrates a problem that may occur when aligning two structures of the same protein chain where one of the chains have a few missing residues:: Correct alignment: A.L.R.S - - V.W.Y.K.L -> no unpaired breaks Target chain : A.L.R.S.V.T.V.W.Y.K.L Wrong alignment : A.L.R.S_V - - W.Y.K.L | --> 1 unpaired break, counted Key: - (dash) is a gap in the alignment . (dot) is a peptide bond _ (underscore) is a break In this case, one unpaired break is an indicator of the problem in the alignment. The following example illustrates a case where an unpaired break is due to an insertion in the homologous chain:: Target chain : 1A.2L.3R.4S.5V.6T.7V Homologous chain : 1A.2L.3K.4S.6V_9S.10L | --> 1 unpaired break, not counted In this case, residue numbers are used to determine whether the unpaired break is due to an insertion/deletion in the chain or misalignment.""" try: if chone.numAtoms() != chtwo.numAtoms(): raise ValueError('number of atoms do not match') except AttributeError: raise TypeError('one and two must be Atomic instances') mapped = chone.getFlags('mapped') * chtwo.getFlags('mapped') if mapped.sum() == 0: raise ValueError('chains do not have common mapped atoms') chone = chone[mapped] chtwo = chtwo[mapped] rnone = chone.getResnums() rntwo = chtwo.getResnums() brone = calcDistance(chone[1:], chone[:-1]) > 4. brtwo = calcDistance(chtwo[1:], chtwo[:-1]) > 4. brone[(rnone[1:] - rnone[:-1]) > 1] = False brtwo[(rntwo[1:] - rntwo[:-1]) > 1] = False brone = set(brone.nonzero()[0]) brtwo = set(brtwo.nonzero()[0]) return len(brone.union(brtwo)) - len(brone.intersection(brtwo))
def filterRankedPairs(pdb, indices, msa_indices, rank_row, rank_col, zscore_sort, \ num_of_pairs=20, seqDistance=5, resi_range=None, \ pdbDistance=8, chain1='A', chain2='A'): ''' indices and msa_indices are lists output from alignSequenceToMSA rank_row, rank_col and zscore_sort are the outputs from calcRankorder :arg num_of_pairs: The number of pairs to be output, if no value is given then all pairs are output. Default is 20 :type num_of_pairs: int :arg seqDistance: Remove pairs that are closer than this in the reference sequence Default is 5 :type seqDistance: int :arg pdbDistance: Remove pairs with Calpha atoms further apart than this in the PDB Default is 8 :type pdbDistance: int :arg chain1: The chain used for the residue specified by rank_row when measuring distances :type chain1: str :arg chain2: The chain used for the residue specified by rank_col when measuring distances :type chain2: str ''' if isscalar(indices): raise TypeError('Please provide a valid indices list') if isscalar(msa_indices): raise TypeError( 'Please provide valid msa_indices, which should be a list') if isscalar(rank_row): raise TypeError('Please provide ranked row from calcRankorder') if isscalar(rank_col): raise ValueError('Please provide ranked col from calcRankorder') if isscalar(zscore_sort): raise ValueError('Please provide sorted Z scores from calcRankorder') if num_of_pairs is None: num_of_pairs = len(rank_row) pairList = [] i = -1 j = 0 while j < num_of_pairs: i += 1 row_idx = indices[where(msa_indices == rank_row[i])[0][0]] col_idx = indices[where(msa_indices == rank_col[i])[0][0]] if not isinstance(row_idx, Integral) or not isinstance( col_idx, Integral): continue if row_idx - col_idx < seqDistance: continue distance = calcDistance(pdb.select('chain %s and resid %s' % (chain1, \ row_idx)).copy(), \ pdb.select('chain %s and resid %s' % (chain2, \ row_idx)).copy()) if distance > pdbDistance: continue if resi_range is not None: if not row_idx in resi_range and not col_idx in resi_range: continue pairList.append('%3d:\t%3d\t%3d\t%5.1f\t%5.1f\n' % (i, row_idx, col_idx, zscore_sort[i], distance)) j += 1 return pairList
def testPBC(self): assert_equal(PBC_DIST, calcDistance(PBC_ONE, PBC_TWO, unitcell=PBC_UC)) assert_equal(PBC_DIST, calcDistance(PBC_TWO, PBC_ONE, unitcell=PBC_UC))
def testPBCSymmetry(self): dist1 = calcDistance(SYM_ONE, SYM_TWO, unitcell=SYM_UC) dist2 = calcDistance(SYM_TWO, SYM_ONE, unitcell=SYM_UC) assert_equal(dist1, dist2)
def filterRankedPairs(pdb, indices, msa_indices, rank_row, rank_col, zscore_sort, \ num_of_pairs=20, seqDistance=5, resi_range=None, \ pdbDistance=8, chain1='A', chain2='A'): ''' indices and msa_indices are lists output from alignSequenceToPDB rank_row, rank_col and zscore_sort are the outputs from calcRankorder :arg num_of_pairs: The number of pairs to be output, if no value is given then all pairs are output. Default is 20 :type num_of_pairs: int :arg seqDistance: Remove pairs that are closer than this in the reference sequence Default is 5 :type seqDistance: int :arg pdbDistance: Remove pairs with Calpha atoms further apart than this in the PDB Default is 8 :type pdbDistance: int :arg chain1: The chain used for the residue specified by rank_row when measuring distances :type chain1: str :arg chain2: The chain used for the residue specified by rank_col when measuring distances :type chain2: str ''' if isscalar(indices): raise TypeError('Please provide a valid indices list') if isscalar(msa_indices): raise TypeError('Please provide valid msa_indices, which should be a list') if isscalar(rank_row): raise TypeError('Please provide ranked row from calcRankorder') if isscalar(rank_col): raise ValueError('Please provide ranked col from calcRankorder') if isscalar(zscore_sort): raise ValueError('Please provide sorted Z scores from calcRankorder') if num_of_pairs is None: num_of_pairs = len(rank_row) pairList = [] i = -1 j = 0 while j < num_of_pairs: i += 1 row_idx = indices[where(msa_indices == rank_row[i])[0][0]] col_idx = indices[where(msa_indices == rank_col[i])[0][0]] if not isinstance(row_idx, Integral) or not isinstance(col_idx, Integral): continue if row_idx - col_idx < seqDistance: continue distance = calcDistance(pdb.select('chain %s and resid %s' % (chain1, \ row_idx)).copy(), \ pdb.select('chain %s and resid %s' % (chain2, \ row_idx)).copy()) if distance > pdbDistance: continue if resi_range is not None: if not row_idx in resi_range and not col_idx in resi_range: continue pairList.append('%3d:\t%3d\t%3d\t%5.1f\t%5.1f\n'%(i, row_idx, col_idx, zscore_sort[i], distance)) j += 1 return pairList