def expand_crystal(structure, n=1, name='XTAL'): """Expands the contents of a structure to a crystal of a given size. Returns a `` StructureHolder`` entity instance. Arguments: - structure: ``Structure`` entity instance. - n: number number of unit-cell layers. - name: optional name. Requires a PDB file with correct CRYST1 field and space group information. """ sh = structure.header sn = structure.name fmx = sh['uc_fmx'] omx = sh['uc_omx'] # get initial coorinates atoms = einput(structure, 'A') coords = array([atoms.getData('coords')]) # fake 3D # expand the coordinates to crystal all_coords = coords_to_crystal(coords, fmx, omx, n) structures = StructureHolder(name) rng = range(-n, n + 1) # a range like -2, -1, 0, 1, 2 vectors = [(x, y, z) for x in rng for y in rng for z in rng] for i, (u, v, w) in enumerate(vectors): new_structure = copy(structure) new_atoms = einput(new_structure, 'A') new_coords = all_coords[i, 0] for (atom_id, new_coord) in izip(atoms.keys(), new_coords): new_atoms[atom_id].coords = new_coord new_structure.setName("%s_%s%s%s" % (sn, u, v, w)) structures.addChild(new_structure) return structures
def expand_symmetry(model, mode='uc', name='UC', **kwargs): """Applies the symmetry operations defined by the header of the PDB files to the given ``Model`` entity instance. Returns a ``ModelHolder`` entity. Arguments: - model: model entity to expand - mode: 'uc', 'bio' or 'raw' - name: optional name of the ``ModelHolder`` instance. Requires a PDB file with a correct CRYST1 field and space group information. """ structure = model.getParent('S') sh = structure.header fmx = sh['uc_fmx'] omx = sh['uc_omx'] mxs = sh['uc_mxs'] # get initial coordinates atoms = einput(model, 'A') coords = array(atoms.getData('coords')) # expand the coordinates to symmetry all_coords = coords_to_symmetry(coords, fmx, omx, mxs, mode) models = ModelHolder(name) for i in xrange(0, len(mxs)): # copy model new_model = copy(model) # with additional models which new_atoms = einput(new_model, 'A') # patch with coordinates new_coords = all_coords[i] for (atom_id, new_coord) in izip(atoms.keys(), new_coords): new_atoms[atom_id[1:]].coords = new_coord # give it an id: the models are numbered by the symmetry operations with # identity being the first model new_model.setName(i) models.addChild(new_model) return models