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
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
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)
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))
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')
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)