def getTransformation(self): """Returns the :class:`~.Transformation` used to superpose this conformation onto reference coordinates. The transformation can be used to superpose original PDB file onto the reference PDB file.""" if self._ensemble._trans is not None: return Transformation(self._ensemble._trans[self._index])
def buildBiomolecules(header, atoms, biomol=None): """Returns *atoms* after applying biomolecular transformations from *header* dictionary. Biomolecular transformations are applied to all coordinate sets in the molecule. Some PDB files contain transformations for more than 1 biomolecules. A specific set of transformations can be choosen using *biomol* argument. Transformation sets are identified by numbers, e.g. ``"1"``, ``"2"``, ... If multiple biomolecular transformations are provided in the *header* dictionary, biomolecules will be returned as :class:`.AtomGroup` instances in a :func:`list`. If the resulting biomolecule has more than 26 chains, the molecular assembly will be split into multiple :class:`.AtomGroup` instances each containing at most 26 chains. These :class:`.AtomGroup` instances will be returned in a tuple. Note that atoms in biomolecules are ordered according to chain identifiers. """ if not isinstance(header, dict): raise TypeError('header must be a dictionary') if not isinstance(atoms, Atomic): raise TypeError('atoms must be an Atomic instance') biomt = header.get('biomoltrans') if not isinstance(biomt, dict) or len(biomt) == 0: raise ValueError("header doesn't contain biomolecular transformations") if not isinstance(atoms, AtomGroup): atoms = atoms.copy() biomols = [] if biomol is None: keys = list(biomt) else: biomol = str(biomol) if biomol in biomt: keys = [biomol] else: LOGGER.warn('Transformations for biomolecule {0} was not ' 'found in the header dictionary.'.format(biomol)) return None keys.sort() for i in keys: segnm = list('ABCDEFGHIJKLMNOPQRSTUVWXYZ' * 20) ags = [] mt = biomt[i] # mt is a list, first item is list of chain identifiers # following items are lines corresponding to transformation # mt must have 3n + 1 lines if (len(mt)) % 4 != 0: LOGGER.warn('Biomolecular transformations {0} were not ' 'applied'.format(i)) continue for times in range(int((len(mt)) / 4)): rotation = np.zeros((3, 3)) translation = np.zeros(3) line0 = np.fromstring(mt[times * 4 + 1], sep=' ') rotation[0, :] = line0[:3] translation[0] = line0[3] line1 = np.fromstring(mt[times * 4 + 2], sep=' ') rotation[1, :] = line1[:3] translation[1] = line1[3] line2 = np.fromstring(mt[times * 4 + 3], sep=' ') rotation[2, :] = line2[:3] translation[2] = line2[3] t = Transformation(rotation, translation) newag = atoms.select('chain ' + ' '.join(mt[0])).copy() if newag is None: continue newag.all.setSegnames(segnm.pop(0)) for acsi in range(newag.numCoordsets()): newag.setACSIndex(acsi) newag = t.apply(newag) newag.setACSIndex(0) ags.append(newag) if ags: newag = ags.pop(0) while ags: newag += ags.pop(0) newag.setTitle('{0} biomolecule {1}'.format(atoms.getTitle(), i)) biomols.append(newag) if biomols: if len(biomols) == 1: return biomols[0] else: return biomols else: return None
def buildBiomolecules(header, atoms, biomol=None): """Returns *atoms* after applying biomolecular transformations from *header* dictionary. Biomolecular transformations are applied to all coordinate sets in the molecule. Some PDB files contain transformations for more than 1 biomolecules. A specific set of transformations can be choosen using *biomol* argument. Transformation sets are identified by numbers, e.g. ``"1"``, ``"2"``, ... If multiple biomolecular transformations are provided in the *header* dictionary, biomolecules will be returned as :class:`.AtomGroup` instances in a :func:`list`. If the resulting biomolecule has more than 26 chains, the molecular assembly will be split into multiple :class:`.AtomGroup` instances each containing at most 26 chains. These :class:`.AtomGroup` instances will be returned in a tuple. Note that atoms in biomolecules are ordered according to chain identifiers. """ if not isinstance(header, dict): raise TypeError('header must be a dictionary') if not isinstance(atoms, Atomic): raise TypeError('atoms must be an Atomic instance') biomt = header.get('biomoltrans') if not isinstance(biomt, dict) or len(biomt) == 0: LOGGER.warn("no biomolecular transformations found so original structure was used") return atoms if not isinstance(atoms, AtomGroup): atoms = atoms.copy() biomols = [] if biomol is None: keys = list(biomt) else: biomol = str(biomol) if biomol in biomt: keys = [biomol] else: LOGGER.warn('Transformations for biomolecule {0} was not ' 'found in the header dictionary.'.format(biomol)) return None keys.sort() for i in keys: segnm = list('ABCDEFGHIJKLMNOPQRSTUVWXYZ'*20) ags = [] mt = biomt[i] # mt is a list, first item is list of chain identifiers # following items are lines corresponding to transformation # mt must have 3n + 1 lines if (len(mt)) % 4 != 0: LOGGER.warn('Biomolecular transformations {0} were not ' 'applied'.format(i)) continue for times in range(int((len(mt)) / 4)): rotation = np.zeros((3, 3)) translation = np.zeros(3) line0 = np.fromstring(mt[times*4+1], sep=' ') rotation[0, :] = line0[:3] translation[0] = line0[3] line1 = np.fromstring(mt[times*4+2], sep=' ') rotation[1, :] = line1[:3] translation[1] = line1[3] line2 = np.fromstring(mt[times*4+3], sep=' ') rotation[2, :] = line2[:3] translation[2] = line2[3] t = Transformation(rotation, translation) newag = atoms.select('chain ' + ' '.join(mt[0])).copy() if newag is None: continue newag.all.setSegnames(segnm.pop(0)) for acsi in range(newag.numCoordsets()): newag.setACSIndex(acsi) newag = t.apply(newag) newag.setACSIndex(0) ags.append(newag) if ags: newag = ags.pop(0) while ags: newag += ags.pop(0) newag.setTitle('{0} biomolecule {1}' .format(atoms.getTitle(), i)) biomols.append(newag) if biomols: if len(biomols) == 1: return biomols[0] else: return biomols else: return None
def buildBiomolecules(header, atoms, biomol=None): """Return *atoms* after applying biomolecular transformations from *header* dictionary. Biomolecular transformations are applied to all coordinate sets in the molecule. Some PDB files contain transformations for more than 1 biomolecules. A specific set of transformations can be choosen using *biomol* argument. Transformation sets are identified by numbers, e.g. ``"1"``, ``"2"``, ... If multiple biomolecular transformations are provided in the *header* dictionary, biomolecules will be returned as :class:`~.AtomGroup` instances in a :func:`list`. If the resulting biomolecule has more than 26 chains, the molecular assembly will be split into multiple :class:`~.AtomGroup` instances each containing at most 26 chains. These :class:`~.AtomGroup` instances will be returned in a tuple. Note that atoms in biomolecules are ordered according to chain identifiers. """ if not isinstance(header, dict): raise TypeError('header must be a dictionary') if not isinstance(atoms, Atomic): raise TypeError('atoms must be an Atomic instance') biomt = header.get('biomoltrans') if not isinstance(biomt, dict) or len(biomt) == 0: raise ValueError("header doesn't contain biomolecular transformations") if not isinstance(atoms, AtomGroup): atoms = atoms.copy() biomols = [] if biomol is None: keys = biomt.keys() else: biomol = str(biomol) if biomol in biomt: keys = [biomol] else: LOGGER.warning('Transformations for biomolecule {0:s} was not ' 'found in the header dictionary.'.format(biomol)) return None c_max = 26 keys.sort() for i in keys: chids = list('ABCDEFGHIJKLMNOPQRSTUVWXYZ'*20) ags = [] mt = biomt[i] # mt is a list, first item is list of chain identifiers # following items are lines corresponding to transformation # mt must have 3n + 1 lines if (len(mt) - 1) % 3 != 0: LOGGER.warning('Biomolecular transformations {0:s} were not ' 'applied'.format(i)) continue chids_used = [] for times in range((len(mt) - 1)/ 3): rotation = np.zeros((3,3)) translation = np.zeros(3) line = np.fromstring(mt[times*3+1], sep=' ') rotation[0,:] = line[:3] translation[0] = line[3] line = np.fromstring(mt[times*3+2], sep=' ') rotation[1,:] = line[:3] translation[1] = line[3] line = np.fromstring(mt[times*3+3], sep=' ') rotation[2,:] = line[:3] translation[2] = line[3] t = Transformation(rotation, translation) for chid in mt[0]: chids_used.append(chid) newag = atoms.select('chain ' + chid).copy() if newag is None: continue for acsi in range(newag.numCoordsets()): newag.setACSIndex(acsi) newag = t.apply(newag) newag.setACSIndex(0) ags.append(newag) if ags: # Handles the case when there is more atom groups than the number # of chain identifiers if len(chids_used) != len(set(chids_used)): for newag in ags: newag.select('all').setChids(chids.pop(0)) if len(ags) <= c_max: ags_ = [ags] else: ags_ = [] for j in range(len(ags)/c_max + 1): ags_.append(ags[j*c_max: (j+1)*c_max]) parts = [] for k, ags in enumerate(ags_): if not ags: continue newag = ags.pop(0) while ags: newag += ags.pop(0) if len(ags_) > 1: newag.setTitle('{0:s} biomolecule {1:s} part {2:d}' .format(atoms.getTitle(), i, k+1)) else: newag.setTitle('{0:s} biomolecule {1:s}' .format(atoms.getTitle(), i)) parts.append(newag) if len(parts) == 1: biomols.append(newag) else: biomols.append(tuple(parts)) if biomols: if len(biomols) == 1: return biomols[0] else: return biomols else: return None