Пример #1
0
    def setWeights(self, weights):
        """Set atomic weights."""

        if self._n_atoms == 0:
            raise AttributeError('first set reference coordinates')
        try:
            self._weights = checkWeights(weights, self._n_atoms, None)
        except ValueError:
            weights = checkWeights(weights, self.numSelected(), None)
            if not self._weights:
                self._weights = ones((self._n_atoms, 1), dtype=float)
            self._weights[self._indices, :] = weights
Пример #2
0
    def setWeights(self, weights):
        """Set atomic weights."""

        if self._n_atoms == 0:
            raise AttributeError('coordinates are not set')

        try:
            self._weights = checkWeights(weights, self._n_atoms, self._n_csets)
        except ValueError:
            weights = checkWeights(weights, self.numSelected(), self._n_csets)
            if not self._weights:
                self._weights = np.ones((self._n_csets, self._n_atoms, 1),
                                        dtype=float)
            self._weights[self._indices, :] = weights
Пример #3
0
def calcRMSD(reference, target=None, weights=None):
    """Returns root-mean-square deviation (RMSD) between reference and target
    coordinates.

    .. ipython:: python

       ens = loadEnsemble('p38_X-ray.ens.npz')
       ens.getRMSDs()
       calcRMSD(ens)
       calcRMSD(ens.getCoords(), ens.getCoordsets(), ens.getWeights())"""

    if isinstance(reference, np.ndarray):
        ref = reference
    else:
        try:
            ref = reference._getCoords()
        except AttributeError:
            raise TypeError('reference must be a numpy array or an object '
                            'with getCoords method')
        if target is None:
            try:
                target = reference._getCoordsets()
            except AttributeError:
                pass
        if weights is None:
            try:
                weights = reference._getWeights()
            except AttributeError:
                pass
    if ref.ndim != 2 or ref.shape[1] != 3:
        raise ValueError('reference must have shape (n_atoms, 3)')

    if isinstance(target, np.ndarray):
        tar = target
    else:
        try:
            tar = target._getCoords()
        except AttributeError:
            raise TypeError('target must be a numpy array or an object '
                            'with getCoords method')
    if tar.ndim not in (2, 3) or tar.shape[-1] != 3:
        raise ValueError('target must have shape ([n_confs,] n_atoms, 3)')

    if ref.shape != tar.shape[-2:]:
        raise ValueError('reference and target arrays must have the same '
                         'number of atoms')

    if weights is not None:
        n_atoms = len(ref)
        n_csets = 1 if tar.ndim == 2 else len(tar)
        weights = checkWeights(weights, n_atoms, n_csets)
    return getRMSD(ref, tar, weights)
Пример #4
0
def calcTransformation(mobile, target, weights=None):
    """Returns a :class:`Transformation` instance which, when applied to the
    atoms in *mobile*, minimizes the weighted RMSD between *mobile* and
    *target*.  *mobile* and *target* may be NumPy coordinate arrays, or
    :class:`.Atomic` instances, e.g. :class:`.AtomGroup`, :class:`.Chain`,
    or :class:`.Selection`."""

    if not isinstance(mobile, np.ndarray):
        try:
            mob = mobile._getCoords()
        except AttributeError:
            raise TypeError('mobile must be a numpy array or an object '
                            'with getCoords method')
    else:
        mob = mobile
    if not isinstance(target, np.ndarray):
        try:
            tar = target._getCoords()
        except AttributeError:
            raise TypeError('target must be a numpy array or an object '
                            'with getCoords method')
    else:
        tar = target

    if mob.shape != tar.shape:
        raise ValueError('reference and target coordinate arrays '
                         'must have same number of atoms')

    if mob.shape[1] != 3:
        raise ValueError('reference and target must be coordinate arrays')

    if weights is None:
        if isinstance(mobile, AtomMap):
            LOGGER.warn(
                'mobile is an AtomMap instance, consider assign weights=mobile.getFlags("mapped") '
                'if there are dummy atoms in mobile')

        if isinstance(target, AtomMap):
            LOGGER.warn(
                'target is an AtomMap instance, consider assign weights=target.getFlags("mapped") '
                'if there are dummy atoms in target')

    if weights is not None:
        weights = checkWeights(weights, mob.shape[0])

    return Transformation(*getTransformation(mob, tar, weights))
Пример #5
0
    def addCoordset(self, coords, weights=None, label=None, **kwargs):
        """Add coordinate set(s) to the ensemble.  *coords* must be a Numpy
        array with suitable shape and dimensionality, or an object with
        :meth:`getCoordsets`. *weights* is an optional argument.
        If provided, its length must match number of atoms.  Weights of
        missing (not resolved) atoms must be ``0`` and weights of those
        that are resolved can be anything greater than ``0``.  If not
        provided, weights of all atoms for this coordinate set will be
        set equal to ``1``. *label*, which may be a PDB identifier or a
        list of identifiers, is used to label conformations."""

        degeneracy = kwargs.pop('degeneracy', False)

        atoms = coords
        n_atoms = self._n_atoms
        n_select = self.numSelected()
        n_confs = self.numCoordsets()

        try:
            if degeneracy:
                if self._coords is not None:
                    if isinstance(coords, Ensemble):
                        coords = coords._getCoords(selected=False)
                    elif hasattr(coords, '_getCoords'):
                        coords = coords._getCoords()
                else:
                    if isinstance(coords, Ensemble):
                        coords = coords.getCoords(selected=False)
                    elif hasattr(coords, 'getCoords'):
                        coords = coords.getCoords()
            else:
                if self._coords is not None:
                    if isinstance(coords, Ensemble):
                        coords = coords._getCoordsets(selected=False)
                    elif hasattr(coords, '_getCoordsets'):
                        coords = coords._getCoordsets()
                else:
                    if isinstance(coords, Ensemble):
                        coords = coords.getCoordsets(selected=False)
                    elif hasattr(coords, 'getCoordsets'):
                        coords = coords.getCoordsets()

        except AttributeError:
            label = label or 'Unknown'

        else:
            if coords is None:
                raise ValueError('coordinates are not set')
            elif label is None and isinstance(atoms, Atomic):
                if not isinstance(atoms, AtomGroup):
                    ag = atoms.getAtomGroup()
                else:
                    ag = atoms
                label = ag.getTitle()
                if coords.shape[0] < ag.numCoordsets():
                    label += '_m' + str(atoms.getACSIndex())
            else:
                label = label or 'Unknown'

        # check coordinates
        try:
            checkCoords(coords, csets=True, natoms=n_atoms)
        except:
            try:
                checkCoords(coords, csets=True, natoms=n_select)
            except TypeError:
                raise TypeError('coords must be a numpy array or an object '
                                'with `getCoords` method')

        if coords.ndim == 2:
            n_nodes, _ = coords.shape
            coords = coords.reshape((1, n_nodes, 3))
            n_csets = 1
        else:
            n_csets, n_nodes, _ = coords.shape
            if degeneracy:
                coords = coords[:1]

        n_repeats = 1 if degeneracy else n_csets

        if not n_atoms:
            self._n_atoms = n_nodes

        if n_nodes == n_select and self.isSelected():
            full_coords = np.repeat(self._coords[np.newaxis, :, :],
                                    n_csets,
                                    axis=0)
            full_coords[:, self._indices, :] = coords
            coords = full_coords

        # check weights
        if weights is None:
            weights = np.ones((n_csets, n_atoms, 1), dtype=float)
        else:
            weights = checkWeights(weights, n_atoms, n_csets)

        if degeneracy:
            weights = weights[:1]

        # assign new values
        # update labels
        if n_csets > 1 and not degeneracy:
            if isinstance(label, str):
                labels = [
                    '{0}_m{1}'.format(label, i + 1) for i in range(n_csets)
                ]
            else:
                if len(label) != n_csets:
                    raise ValueError('length of label and number of '
                                     'coordinate sets must be the same')
                labels = label
        else:
            labels = [label] if np.isscalar(label) else label

        self._labels.extend(labels)

        # update coordinates
        if self._confs is None and self._weights is None:
            self._confs = coords
            self._weights = weights
            self._n_csets = n_repeats

        elif self._confs is not None and self._weights is not None:
            self._confs = np.concatenate((self._confs, coords), axis=0)
            self._weights = np.concatenate((self._weights, weights), axis=0)
            self._n_csets += n_repeats
        else:
            raise RuntimeError('_confs and _weights must be set or None at '
                               'the same time')
Пример #6
0
    def setWeights(self, weights):
        """Set atomic weights."""

        if self._n_atoms == 0:
            raise AttributeError('coordinates must be set first')
        self._weights = checkWeights(weights, self._n_atoms, None)