This file is indexed.

/usr/share/pyshared/cogent/struct/asa.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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
"""Classes and functions for computing and manipulating accessible 
surface areas (ASA)."""

from cogent.app.stride import Stride
from cogent.parse.stride import stride_parser
from cogent.struct.selection import einput
from cogent.struct.annotation import xtradata
from cogent.maths.geometry import sphere_points, coords_to_symmetry, \
                                  coords_to_crystal
from _asa import asa_loop
from numpy import array, r_


__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 _run_asa(atoms, lattice_coords, spoints, probe=1.4, bucket_size=5, \
             MAXSYM=200000):
    """Runs an ASA calculation. This function takes a selection of atoms 
    (in the most common case all atoms in a structure) and lattice coordinates 
    (in the most common a 3x3 box of unit-cells).
    
    This function should be considered low-level and not part of the interface.
    
    Arguments:
    
        - atoms: Holder of atom entities.
        - lattice_coords: Numpy array of coordinates.
        - spoints: an array of coordinates on the unit sphere, defines the 
          accuracy of ASA calculation.
        - probe: size of the probe i.e. solvent molecule.
        - bucket_size: see: ``KDTree``.
        - MAXSYM (int): maximum number of symmetry generated atoms.
    """
    # get array of radii inflated by probe size of the selection of atoms.
    atom_radii = array(atoms.getData('radius', forgiving=False)) + probe
    # get array of coordinates
    atom_coords = array(atoms.getData('coords', forgiving=False))
    # calculate bounding box in a form of an array
    search_limit = 2 * (2.0 + probe)    # 2.0 is maximum atom radius
    atom_box = r_[atom_coords.min(axis=0) - search_limit, \
                  atom_coords.max(axis=0) + search_limit]
    # the lattice coordinates are atom coordinates after transformations in a 
    # 4D-array this array gets reshaped into an all_atoms x 3 array.
    shape = lattice_coords.shape
    lattice_coords = \
        lattice_coords.reshape((shape[0] * shape[1] * shape[2], shape[3]))
    # this calls the cython code which loops over all query atoms, surface 
    # points, and lattice atoms
    return asa_loop(atom_coords, lattice_coords, atom_radii, atom_radii, \
                    spoints, atom_box, probe, bucket_size, MAXSYM)

def _prepare_entities(entities):
    """Prepares input entities for ASA calculation, which includes masking water
    molecules and water chains.
    """
    # First we mask all water residues and chains with all residues masked 
    # (water chains).
    lattice_residues = einput(entities, 'R')
    lattice_residues.maskChildren('H_HOH', 'eq', 'name')
    lattice_chains = einput(entities, 'C')
    lattice_chains.maskChildren([], 'eq', 'values', method=True)
    # if no residues or chains are left - no atoms to work with, 
    # abort with warning.
    if not lattice_chains.values():
        # the following makes sure that masking changes by the above
        # tests are reverted.
        lattice_structures = einput(entities, 'S')
        lattice_structures.setUnmasked(force=True)
        raise ValueError('No unmasked atoms to build lattice.')
    # these are all atoms we can work with
    lattice_atoms = einput(entities, 'A')
    lattice_atoms.dispatch('setRadius')

def _postpare_entities(entities):
    """Restores entities after ASA calculation, which includes unmasking."""
    structures = einput(entities, 'S')
    structures.setUnmasked(force=True)


def _prepare_asa(entities, symmetry_mode=None, crystal_mode=None, points=960, \
                **kwargs):
    """Prepares the atomic solvent-accessible surface area (ASA) calculation.
    
    Arguments:
    
        - entities: input entities for ASA calculation (most commondly a 
          structure entity).
        - symmetry_mode (str): One of 'uc', 'bio' or 'table'. This defines the 
          transformations of applied to the coordinates of the input entities. 
          It is one of 'bio', 'uc' or 'table'. Where 'bio' and 'uc' are 
          transformations to create the biological molecule or unit-cell from 
          the PDB header. The 'table' uses transformation matrices derived from 
          space-group information only using crystallographic tables(requires 
          ``cctbx``).
        - crystal_mode (int): Defines the number of unit-cells to expand the 
          initial unit-cell into. The number of unit-cells in each direction 
          i.e. 1 is makes a total of 27 unit cells: (-1, 0, 1) == 3, 3^3 == 27
        - points: number of points on atom spheres higher is slower but more 
          accurate.    

    Additional keyworded arguments are passed to the ``_run_asa`` function.
    """
    # generate uniform points on the unit-sphere
    spoints = sphere_points(points)
    # prepare entities for asa calculation
    # free-floating area mode
    result = {}
    atoms = einput(entities, 'A')
    if not symmetry_mode and not crystal_mode:

        coords = array(atoms.getData('coords', forgiving=False))
        coords = array([[coords]]) # fake 3D and 4D
        idx_to_id = dict(enumerate(atoms.getData('getFull_id', \
                                                forgiving=False, method=True)))
        asas = _run_asa(atoms, coords, spoints, **kwargs)
        for idx in xrange(asas.shape[0]):
            result[idx_to_id[idx]] = asas[idx]
    # crystal-contact area mode    
    elif symmetry_mode in ('table', 'uc'):
        structure = einput(entities, 'S').values()[0]
        sh = structure.header
        coords = array(atoms.getData('coords', forgiving=False))
        idx_to_id = dict(enumerate(atoms.getData('getFull_id', \
                                                forgiving=False, method=True)))
        # expand to unit-cell, real 3D
        coords = coords_to_symmetry(coords, \
                                            sh[symmetry_mode + '_fmx'], \
                                            sh[symmetry_mode + '_omx'], \
                                            sh[symmetry_mode + '_mxs'], \
                                            symmetry_mode)
        # expand to crystal, real 4D
        if crystal_mode:
            coords = coords_to_crystal(coords, \
                                               sh[symmetry_mode + '_fmx'], \
                                               sh[symmetry_mode + '_omx'], \
                                               crystal_mode) # real 4D
        else:
            coords = array([coords]) # fake 4D
        asas = _run_asa(atoms, coords, spoints, **kwargs)
        for idx in xrange(asas.shape[0]):
            result[idx_to_id[idx]] = asas[idx]

     # biological area mode
    elif symmetry_mode == 'bio':
        structure = einput(entities, 'S').values()[0]
        chains = einput(entities, 'C')
        sh = structure.header
        start = 0
        for chain_ids, mx_num in sh['bio_cmx']:
            sel = chains.selectChildren(chain_ids, 'contains', 'id').values()
            atoms = einput(sel, 'A')
            coords = array(atoms.getData('coords', forgiving=False))
            idx_to_id = dict(enumerate(atoms.getData('getFull_id', \
                                              forgiving=False, method=True)))
            stop = start + mx_num
            coords = coords_to_symmetry(coords, \
                                               sh['uc_fmx'], \
                                               sh['uc_omx'], \
                                               sh['bio_mxs'][start:stop], \
                                               symmetry_mode)
            coords = array([coords])
            start = stop
            asas = _run_asa(atoms, coords, spoints, **kwargs)
            for idx in xrange(asas.shape[0]):
                result[idx_to_id[idx]] = asas[idx]
    return result


def asa_xtra(entities, mode='internal', xtra_key=None, **asa_kwargs):
    """Calculates accessible surface areas (ASA) and puts the results into the
    xtra dictionaries of entities.
    
    Arguments:
    
        - entities: an entity or sequence of entities
        - mode(str): 'internal' for calculations using the built-in cython code 
          or 'stride' if the stride binary should be called to do the job.
        - xtra_key(str): Key in the xtra dictionary to hold the result for each
          entity
    
    Additional keyworded arguments are passed to the ``_prepare_asa`` and 
    ``_run_asa`` functions.
    """
    xtra_key = xtra_key or 'ASA'
    structures = einput(entities, 'S')
    if len(structures.values()) > 1:
        raise ValueError('Entities from multiple structures are not supported.')
    if mode == 'internal':
        _prepare_entities(entities) # mask waters
        result = _prepare_asa(entities, **asa_kwargs) # calculate ASA
        _postpare_entities(entities) # unmask waters
        result = dict([(id, {xtra_key:v}) for id, v in result.iteritems()])
        xtradata(result, structures)
    elif mode == 'stride':
        models = einput(entities, 'M')
        stride_app = Stride()
        result = stride_app(entities)['StdOut'].readlines()
        result = stride_parser(result)
        xtradata(result, structures.values()[0][(0,)])
    else:
        raise ValueError('Not a valid mode: "%s"' % mode)
    return result