def runManyStepsAlternating(self, n_steps, **kwargs): LOGGER.timeit('_prody_runManySteps') n_start = self.numSteps while self.numSteps < n_start + n_steps: n_modes = self.n_modes self.runStep(structA=self.structA, structB=self.structB, reduceSelA=self.reduceSelA, reduceSelB=self.reduceSelB, alignSelA=self.alignSelA, alignSelB=self.alignSelB, n_modes=n_modes, **kwargs) LOGGER.debug( 'Total time so far is %.2f minutes' % ((time.time() - LOGGER._times['_prody_runManySteps']) / 60)) self.runStep(structA=self.structB, structB=self.structA, reduceSelA=self.reduceSelB, reduceSelB=self.reduceSelA, alignSelA=self.alignSelB, alignSelB=self.alignSelA, n_modes=n_modes, **kwargs) LOGGER.debug( 'Total time so far is %.2f minutes' % ((time.time() - LOGGER._times['_prody_runManySteps']) / 60)) converged = self.checkConvergence() if converged: self.structA.setCoords( self.coordsA ) # That way the original object is back to normal self.structB.setCoords( self.coordsB ) # That way the original object is back to normal LOGGER.debug( 'Process completed in %.2f hours' % ((time.time() - LOGGER._times['_prody_runManySteps']) / 3600)) break ensemble = Ensemble('combined trajectory') ensemble.setAtoms(self.structA) for coordset in self.ensembleA.getCoordsets(): ensemble.addCoordset(coordset) for coordset in reversed(self.ensembleB.getCoordsets()): ensemble.addCoordset(coordset) if self.outputPDB: writePDB(self.filename, ensemble) if self.outputDCD: writeDCD(self.filename, ensemble) return
def calcOneWayAdaptiveANM(a, b, n_steps, **kwargs): """Runs one-way adaptivate ANM. """ n_modes = kwargs.pop('n_modes', 20) coordsA, coordsB, title, atoms, weights, maskA, maskB, rmsd = checkInput( a, b, **kwargs) coordsA = coordsA.copy() LOGGER.timeit('_prody_calcAdaptiveANM') n = 0 resetFmin = True defvecs = [] rmsds = [rmsd] ensemble = Ensemble(title + '_aANM') ensemble.setAtoms(atoms) ensemble.setCoords(coordsB) ensemble.setWeights(weights) ensemble.addCoordset(coordsA.copy()) while n < n_steps: LOGGER.info('\nStarting cycle {0} with initial structure {1}'.format( n + 1, title)) n_modes = calcStep(coordsA, coordsB, n_modes, ensemble, defvecs, rmsds, mask=maskA, resetFmin=resetFmin, **kwargs) n += 1 resetFmin = False if n_modes == 0: LOGGER.report('One-way Adaptive ANM converged in %.2fs.', '_prody_calcAdaptiveANM') break return ensemble
def __getitem__(self, index): if self._closed: raise ValueError('I/O operation on closed file') if isinstance(index, int): return self.getFrame(index) elif isinstance(index, (slice, list, ndarray)): if isinstance(index, slice): ens = Ensemble('{0} ({1[0]}:{1[1]}:{1[2]})'.format( self._title, index.indices(len(self)))) else: ens = Ensemble('{0} slice'.format(self._title)) ens.setCoords(self.getCoords()) if self._weights is not None: ens.setWeights(self._weights.copy()) ens.addCoordset(self.getCoordsets(index)) ens.setAtoms(self._atoms) return ens else: raise IndexError('invalid index')
def __getitem__(self, index): if self._closed: raise ValueError('I/O operation on closed file') if isinstance(index, int): return self.getFrame(index) elif isinstance(index, (slice, list, np.ndarray)): if isinstance(index, slice): ens = Ensemble('{0:s} ({1[0]:d}:{1[1]:d}:{1[2]:d})'.format( self._title, index.indices(len(self)))) else: ens = Ensemble('{0:s} slice'.format(self._title)) ens.setCoords(self.getCoords()) if self._weights is not None: ens.setWeights(self._weights.copy()) ens.addCoordset(self.getCoordsets(index)) ens.setAtoms(self._atoms) return ens else: raise IndexError('invalid index')
def traverseMode(mode, atoms, n_steps=10, rmsd=1.5, **kwargs): """Generates a trajectory along a given *mode*, which can be used to animate fluctuations in an external program. :arg mode: mode along which a trajectory will be generated :type mode: :class:`.Mode` :arg atoms: atoms whose active coordinate set will be used as the initial conformation :type atoms: :class:`.Atomic` :arg n_steps: number of steps to take along each direction, for example, for ``n_steps=10``, 20 conformations will be generated along *mode* with structure *atoms* in between, default is 10. :type n_steps: int :arg rmsd: maximum RMSD that the conformations will have with respect to the initial conformation, default is 1.5 Å :type rmsd: float :arg pos: whether to include steps in the positive mode direction, default is **True** :type pos: bool :arg neg: whether to include steps in the negative mode direction, default is **True** :type neg: bool :arg reverse: whether to reverse the direction default is **False** :type reverse: bool :returns: :class:`.Ensemble` For given normal mode :math:`u_i`, its eigenvalue :math:`\\lambda_i`, number of steps :math:`n`, and maximum :math:`RMSD` conformations :math:`[R_{-n} R_{-n+1} ... R_{-1} R_0 R_1 ... R_n]` are generated. :math:`R_0` is the active coordinate set of *atoms*. :math:`R_k = R_0 + sk\\lambda_iu_i`, where :math:`s` is found using :math:`s = ((N (\\frac{RMSD}{n})^2) / \\lambda_i^{-1}) ^{0.5}`, where :math:`N` is the number of atoms.""" pos = kwargs.get('pos', True) neg = kwargs.get('neg', True) reverse = kwargs.get('reverse', False) if pos is False and neg is False: raise ValueError('pos and neg cannot both be False') if not isinstance(mode, VectorBase): raise TypeError('mode must be a Mode or Vector instance, ' 'not {0}'.format(type(mode))) if not mode.is3d(): raise ValueError('mode must be from a 3-dimensional model.') n_atoms = mode.numAtoms() initial = None if atoms is not None: if not isinstance(atoms, Atomic): raise TypeError('{0} is not correct type for atoms' .format(type(atoms))) if atoms.numAtoms() != n_atoms: raise ValueError('number of atoms do not match') initial = atoms.getCoords() name = str(mode) rmsd = float(rmsd) + 0.000004 LOGGER.info('Parameter: rmsd = {0:.2f} A'.format(rmsd)) n_steps = int(n_steps) LOGGER.info('Parameter: n_steps = {0}'.format(n_steps)) step = rmsd / n_steps LOGGER.info('Step size is {0:.2f} A RMSD'.format(step)) arr = mode.getArrayNx3() try: var = mode.getVariance() except AttributeError: var = 1. scale = ((n_atoms * step**2) / var) ** 0.5 LOGGER.info('Mode is scaled by {0}.'.format(scale)) array = arr * var**0.5 * scale / abs(mode) confs_add = [initial + array] for s in range(1, n_steps): confs_add.append(confs_add[-1] + array) confs_sub = [initial - array] for s in range(1, n_steps): confs_sub.append(confs_sub[-1] - array) confs_sub.reverse() ensemble = Ensemble('Conformations along {0}'.format(name)) ensemble.setAtoms(atoms) ensemble.setCoords(initial) conf_list = [initial] if pos: conf_list = conf_list + confs_add if neg: conf_list = confs_sub + conf_list conf_array = np.array(conf_list) if reverse: conf_array = conf_array[::-1] ensemble.addCoordset(conf_array) return ensemble
def traverseMode(mode, atoms, n_steps=10, rmsd=1.5): """Generates a trajectory along a given *mode*, which can be used to animate fluctuations in an external program. :arg mode: mode along which a trajectory will be generated :type mode: :class:`.Mode` :arg atoms: atoms whose active coordinate set will be used as the initial conformation :type atoms: :class:`.Atomic` :arg n_steps: number of steps to take along each direction, for example, for ``n_steps=10``, 20 conformations will be generated along the first mode, default is 10. :type n_steps: int :arg rmsd: maximum RMSD that the conformations will have with respect to the initial conformation, default is 1.5 Å :type rmsd: float :returns: :class:`.Ensemble` For given normal mode :math:`u_i`, its eigenvalue :math:`\\lambda_i`, number of steps :math:`n`, and maximum :math:`RMSD` conformations :math:`[R_{-n} R_{-n+1} ... R_{-1} R_0 R_1 ... R_n]` are generated. :math:`R_0` is the active coordinate set of *atoms*. :math:`R_k = R_0 + sk\\lambda_iu_i`, where :math:`s` is found using :math:`s = ((N (\\frac{RMSD}{n})^2) / \\lambda_i^{-1}) ^{0.5}`, where :math:`N` is the number of atoms.""" if not isinstance(mode, VectorBase): raise TypeError('mode must be a Mode or Vector instance, ' 'not {0}'.format(type(mode))) if not mode.is3d(): raise ValueError('mode must be from a 3-dimensional model.') n_atoms = mode.numAtoms() initial = None if atoms is not None: if not isinstance(atoms, Atomic): raise TypeError('{0} is not correct type for atoms' .format(type(atoms))) if atoms.numAtoms() != n_atoms: raise ValueError('number of atoms do not match') initial = atoms.getCoords() name = str(mode) rmsd = float(rmsd) + 0.000004 LOGGER.info('Parameter: rmsd = {0:.2f} A'.format(rmsd)) n_steps = int(n_steps) LOGGER.info('Parameter: n_steps = {0}'.format(n_steps)) step = rmsd / n_steps LOGGER.info('Step size is {0:.2f} A RMSD'.format(step)) arr = mode.getArrayNx3() var = mode.getVariance() scale = ((n_atoms * step**2) / var) ** 0.5 LOGGER.info('Mode is scaled by {0}.'.format(scale)) array = arr * var**0.5 * scale / abs(mode) confs_add = [initial + array] for s in range(1, n_steps): confs_add.append(confs_add[-1] + array) confs_sub = [initial - array] for s in range(1, n_steps): confs_sub.append(confs_sub[-1] - array) confs_sub.reverse() ensemble = Ensemble('Conformations along {0}'.format(name)) ensemble.setAtoms(atoms) ensemble.setCoords(initial) ensemble.addCoordset(np.array(confs_sub + [initial] + confs_add)) return ensemble