Exemplo n.º 1
0
    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
Exemplo n.º 2
0
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
Exemplo n.º 3
0
    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')
Exemplo n.º 4
0
    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')
Exemplo n.º 5
0
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
Exemplo n.º 6
0
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