/usr/share/pyshared/cogent/struct/manipulation.py is in python-cogent 1.5.3-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 | """Contains functions to manipulate i.e. modify macromolecular entities."""
from numpy import array
from itertools import izip
from cogent.core.entity import HIERARCHY, copy, StructureHolder, ModelHolder
from cogent.maths.geometry import coords_to_symmetry, coords_to_crystal
from cogent.struct.selection import einput
__author__ = "Marcin Cieslik"
__copyright__ = "Copyright 2007-2012, The Cogent Project"
__credits__ = ["Marcin Cieslik"]
__license__ = "GPL"
__version__ = "1.5.3"
__maintainer__ = "Marcin Cieslik"
__email__ = "mpc4p@virginia.edu"
__status__ = "Development"
def clean_ical(entities, pretend=True, mask=True):
"""Removes or masks entities with ambiguous (i)nsertion (c)odes or
(a)lternate (l)ocations.
Arguments:
- entities: universal input see: ``cogent.struct.selection.einput``
- pretend: If ``True`` only reports icals and does not mask or remove
anything.
- mask (boolean): If pretend is ``False`` masks entities instead of
removing them.
This function does not check for occupancy. I retains the residue which is
first when sorted by id number, insertion code and finally name. Residues
without IC come first. Atoms within a retained residue are sorted according
to PDB rules and the first one is chosen. If The first entity has an IC or
alt_loc different from ' ' it will be changed to ' '.
"""
conflicts = []
changes = []
residues = einput(entities, 'R')
id_r = [[None, None, None]]
for r in residues.sortedvalues(): # sort by id, ic, name
id_a = [[None, None]]
if r.res_id == id_r[0][1]: # on collision choose first ...
conflicts.append(r.getFull_id())
if not pretend:
if mask:
r.setMasked(True)
else:
r.parent.delChild(r.id)
continue # an entity could be in other holders
# keep it there as-is
for a in r.sortedvalues(): # sort by id, alt_loc (' ', 'A' ...)
if a.at_id == id_a[0][0]: # on collision choose first
conflicts.append(a.getFull_id())
if not pretend:
if mask:
a.setMasked(True)
else:
r.delChild(a.id)
else:
if a.id[0][1] != ' ':
changes.append((a.getFull_id(), ((a.id[0][0], ' '),)))
if not pretend:
a.setAlt_loc(' ')
try:
a.parent.updateIds()
except AttributeError:
pass
id_a = a.id
if r.id[0][2] != ' ':
changes.append((r.getFull_id(), ((r.id[0][0], r.id[0][1], ' '),)))
if not pretend:
r.set_res_ic(' ')
try:
r.parent.updateIds()
except AttributeError:
pass
id_r = r.id
return (changes, conflicts)
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
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
|