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 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 not None: weights = checkWeights(weights, mob.shape[0]) return Transformation(*getTransformation(mob, tar, weights))
def setWeights(self, weights): """Set atomic weights.""" n_atoms = self.numAtoms() n_modesets = self.numModeSets() if n_atoms > 0 and n_modesets > 0: self._weights = checkWeights(weights, n_atoms, n_modesets) else: raise RuntimeError('modesets must be set before weights can be assigned')
def addModeSet(self, modeset, weights=None, label=None): """Adds a modeset or modesets to the mode ensemble.""" if isinstance(modeset, (NMA, ModeSet, Mode)): modesets = [modeset] else: modesets = modeset if label is not None: if np.isscalar(label): labels = [label] else: labels = label if len(labels) != len(modesets): raise ValueError('labels should have the same length as modesets') if not self._labels and labels: self._labels = ['']*len(self._modesets) self._labels.extend(labels) if not labels and self._labels: labels = ['']*len(modesets) self._labels.extend(labels) for i in range(len(modesets)): modeset = modesets[i] if isinstance(modeset, NMA): modeset = modeset[:] elif isinstance(modeset, Mode): modeset = ModeSet(modeset.getModel(), [modeset.getIndex()]) if not isinstance(modeset, ModeSet): raise TypeError('modesets should be a list of Mode or ModeSet instances') if self._modesets: if modeset.numAtoms() != self.numAtoms(): raise ValueError('to be added, modesets should contain exactly %d atoms'%self.numAtoms()) if modeset.numModes() < self.numModes(): raise ValueError('to be added, modesets should contain at least %d modes'%self.numModes()) if modeset.numModes() > self.numModes(): modeset = modeset[:self.numModes()] self._modesets.append(modeset) else: self._modesets = [modeset] if weights is None: weights = np.ones((len(modesets), self.numAtoms(), 1)) if self._weights is not None: self._weights = np.concatenate((self._weights, weights), axis=0) else: self._weights = weights else: weights = checkWeights(weights, self.numAtoms(), len(modesets)) if self._weights is None: self._weights = np.ones((self.numModeSets()-len(modesets), self.numAtoms(), 1)) self._weights = np.concatenate((self._weights, weights), axis=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)
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) adddata = kwargs.pop('data', None) 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 n_atoms = self._n_atoms 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] # check sequences seqs = None sequence = kwargs.pop('sequence', None) if hasattr(atoms, 'getSequence'): if sequence is not None: LOGGER.warn( 'sequence is supplied though coords has getSequence') sequence = atoms.getSequence() seqs = [sequence for _ in range(n_repeats)] else: if sequence is None: try: sequence = self._atoms.getSequence() except AttributeError: if self._msa: sequence = ''.join('X' for _ in range(n_atoms)) # sequence and seqs remains to be None if MSA has not been created if isinstance(sequence, Sequence): seqs = [str(sequence)] elif isinstance(sequence, MSA): seqs = [str(seq) for seq in sequence] elif np.isscalar(sequence): seqs = [sequence for _ in range(n_repeats)] if seqs: if len(seqs) != n_repeats: raise ValueError( 'the number of sequences should be either one or ' 'that of coordsets') # 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 sequences if seqs: msa = MSA(seqs, title=self.getTitle(), labels=labels) if self._msa is None: if n_confs > 0: def_seqs = np.chararray((n_confs, n_atoms)) def_seqs[:] = 'X' old_labels = [self._labels[i] for i in range(n_confs)] self._msa = MSA(def_seqs, title=self.getTitle(), labels=old_labels) self._msa.extend(msa) else: self._msa = msa else: self._msa.extend(msa) # update coordinates if self._confs is None and self._weights is None: self._confs = coords self._weights = weights 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) else: raise RuntimeError('_confs and _weights must be set or None at ' 'the same time') # appending new data if self._data is not None and adddata is not None: if self._data is None: self._data = {} if adddata is None: adddata = {} all_keys = set(list(self._data.keys()) + list(adddata.keys())) for key in all_keys: if key in self._data: data = self._data[key] if key not in adddata: shape = [n_repeats] for s in data.shape[1:]: shape.append(s) newdata = np.zeros(shape, dtype=data.dtype) else: newdata = np.asarray(adddata[key]) if newdata.shape[0] != n_repeats: raise ValueError( 'the length of data["%s"] does not match that of coords' % key) else: newdata = np.asarray(adddata[key]) shape = [self._n_csets] for s in newdata.shape[1:]: shape.append(s) data = np.zeros(shape, dtype=newdata.dtype) self._data[key] = np.concatenate((data, newdata), axis=0) # update the number of coordinate sets self._n_csets += n_repeats
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)
def addCoordset(self, coords, weights=None, label=None, degeneracy=False): """Add coordinate set(s) to the ensemble. *coords* must be a Numpy array with suitable shape and dimensionality, or an object with :meth:`getCoordsets` method. *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.""" atoms = coords try: 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): ag = atoms if not isinstance(atoms, AtomGroup): ag = atoms.getAtomGroup() label = ag.getTitle() if coords.shape[0] < ag.numCoordsets(): label += 'm' + str(atoms.getACSIndex()) else: label = label or str(coords) try: checkCoords(coords, csets=True, natoms=self._n_atoms) except TypeError: raise TypeError('coords must be a Numpy array or must have ' '`getCoords` attribute') if coords.ndim == 2: coords = coords.reshape((1, self._n_atoms, 3)) n_csets, n_atoms, _ = coords.shape if not self._n_atoms: self._n_atoms = n_atoms if weights is None: weights = np.ones((n_csets, n_atoms, 1), dtype=float) else: weights = checkWeights(weights, n_atoms, n_csets) if n_csets > 1: if degeneracy == False: if isinstance(label, str): self._labels.extend('{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') self._labels.extend(label) else: self._labels.append(label) coords = np.reshape( coords[0], (1, coords[0].shape[0], coords[0].shape[1])) weights = np.reshape( weights[0], (1, weights[0].shape[0], weights[0].shape[1])) else: self._labels.append(label) if self._confs is None and self._weights is None: self._confs = coords self._weights = weights if degeneracy == False: self._n_csets = n_csets else: self._n_csets = 1 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) if degeneracy == False: self._n_csets += n_csets else: self._n_csets += 1 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('first set reference coordinates') self._weights = checkWeights(weights, self._n_atoms, None)
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] # check sequences seqs = None sequence = kwargs.pop('sequence', None) if hasattr(atoms, 'getSequence'): if sequence is not None: LOGGER.warn('sequence is supplied though coords has getSequence') sequence = atoms.getSequence() seqs = [sequence for _ in range(n_repeats)] else: if sequence is None: try: sequence = self.getAtoms().getSequence() except AttributeError: if self._msa: sequence = ''.join('X' for _ in range(n_atoms)) # sequence and seqs remains to be None if MSA has not been created if isinstance(sequence, Sequence): seqs = [str(sequence)] elif isinstance(sequence, MSA): seqs = [str(seq) for seq in sequence] elif np.isscalar(sequence): seqs = [sequence for _ in range(n_repeats)] if seqs: if len(seqs) != n_repeats: raise ValueError('the number of sequences should be either one or ' 'that of coordsets') # 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 sequences if seqs: msa = MSA(seqs, title=self.getTitle(), labels=labels) if self._msa is None: if n_confs > 0: def_seqs = np.chararray((n_confs, n_atoms)) def_seqs[:] = 'X' old_labels = [self._labels[i] for i in range(n_confs)] self._msa = MSA(def_seqs, title=self.getTitle(), labels=old_labels) self._msa.extend(msa) else: self._msa = msa else: self._msa.extend(msa) # 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')