Esempio n. 1
0
def transformation_and_inverse(origin, step, axes):

    ox, oy, oz = origin
    d0, d1, d2 = step
    ax, ay, az = axes

    from chimerax.geometry import Place
    tf = Place(((d0 * ax[0], d1 * ay[0], d2 * az[0],
                 ox), (d0 * ax[1], d1 * ay[1], d2 * az[1], oy),
                (d0 * ax[2], d1 * ay[2], d2 * az[2], oz)))
    tf_inv = tf.inverse()

    return tf, tf_inv
Esempio n. 2
0
def ses_surface_geometry(xyz,
                         radii,
                         probe_radius=1.4,
                         grid_spacing=0.5,
                         sas=False):
    '''
    Calculate a solvent excluded molecular surface using a distance grid
    contouring method.  Vertex, normal and triangle arrays are returned.
    If sas is true then the solvent accessible surface is returned instead.
    '''

    # Compute bounding box for atoms
    xyz_min, xyz_max = xyz.min(axis=0), xyz.max(axis=0)
    pad = 2 * probe_radius + radii.max() + grid_spacing
    origin = [x - pad for x in xyz_min]

    # Create 3d grid for computing distance map
    from math import ceil
    s = grid_spacing
    shape = [
        int(ceil((xyz_max[a] - xyz_min[a] + 2 * pad) / s)) for a in (2, 1, 0)
    ]
    #    print('ses surface grid size', shape, 'spheres', len(xyz))
    from numpy import empty, float32, sqrt
    try:
        matrix = empty(shape, float32)
    except (MemoryError, ValueError):
        raise MemoryError(
            'Surface calculation out of memory trying to allocate a grid %d x %d x %d '
            % (shape[2], shape[1], shape[0]) +
            'to cover xyz bounds %.3g,%.3g,%.3g ' % tuple(xyz_min) +
            'to %.3g,%.3g,%.3g ' % tuple(xyz_max) +
            'with grid size %.3g' % grid_spacing)

    max_index_range = 2
    matrix[:, :, :] = max_index_range

    # Transform centers and radii to grid index coordinates
    from chimerax.geometry import Place
    xyz_to_ijk_tf = Place(
        ((1.0 / s, 0, 0, -origin[0] / s), (0, 1.0 / s, 0, -origin[1] / s),
         (0, 0, 1.0 / s, -origin[2] / s)))
    from numpy import float32
    ijk = xyz.astype(float32)
    xyz_to_ijk_tf.transform_points(ijk, in_place=True)
    ri = radii.astype(float32)
    ri += probe_radius
    ri /= s

    # Compute distance map from surface of spheres, positive outside.
    from chimerax.map import sphere_surface_distance
    sphere_surface_distance(ijk, ri, max_index_range, matrix)

    # Get the SAS surface as a contour surface of the distance map
    from chimerax.map import contour_surface
    level = 0
    sas_va, sas_ta, sas_na = contour_surface(matrix,
                                             level,
                                             cap_faces=False,
                                             calculate_normals=True)
    if sas:
        xyz_to_ijk_tf.inverse().transform_points(sas_va, in_place=True)
        return sas_va, sas_na, sas_ta

    # Compute SES surface distance map using SAS surface vertex
    # points as probe sphere centers.
    matrix[:, :, :] = max_index_range
    rp = empty((len(sas_va), ), float32)
    rp[:] = float(probe_radius) / s
    sphere_surface_distance(sas_va, rp, max_index_range, matrix)
    ses_va, ses_ta, ses_na = contour_surface(matrix,
                                             level,
                                             cap_faces=False,
                                             calculate_normals=True)

    # Transform surface from grid index coordinates to atom coordinates
    xyz_to_ijk_tf.inverse().transform_points(ses_va, in_place=True)

    # Delete connected components more than 1.5 probe radius from atom spheres.
    kvi = []
    kti = []
    from ._surface import connected_pieces
    vtilist = connected_pieces(ses_ta)
    for vi, ti in vtilist:
        v0 = ses_va[vi[0], :]
        d = xyz - v0
        d2 = (d * d).sum(axis=1)
        adist = (sqrt(d2) - radii).min()
        if adist < 1.5 * probe_radius:
            kvi.append(vi)
            kti.append(ti)
    from .split import reduce_geometry
    from numpy import concatenate
    keepv = concatenate(kvi) if kvi else []
    keept = concatenate(kti) if kti else []
    va, na, ta = reduce_geometry(ses_va, ses_na, ses_ta, keepv, keept)

    return va, na, ta
Esempio n. 3
0
for b in standard_bases.values():
    pts = [b["atoms"][n] for n in b["ring atom names"][0:2]]
    y_axis = pts[0] - pts[1]
    # insure that y_axis is perpendicular to z_axis
    # (should be zero already)
    y_axis[2] = 0.0
    normalize_vector(y_axis)
    x_axis = numpy.cross(y_axis, z_axis)
    xf = Place(matrix=((x_axis[0], y_axis[0], z_axis[0],
                        0.0), (x_axis[1], y_axis[1], z_axis[1], 0.0),
                       (x_axis[2], y_axis[2], z_axis[2], 0.0))
               # TODO: orthogonalize=True
               )
    # axis, angle = xf.getRotation()
    # print("axis = %s, angle = %s" % (axis, angle))
    b["correction factor"] = xf.inverse()
del b, pts, x_axis, y_axis, z_axis, xf

system_dimensions = {
    # predefined dimensions in local coordinate frame
    # note: (0, 0) corresponds to position of C1'
    'small': {
        ANCHOR: BASE,
        PURINE: ((0.0, -4.0), (2.1, 0.0)),
        PYRIMIDINE: ((0.0, -2.1), (2.1, 0.0)),
        PSEUDO_PYRIMIDINE: ((0.0, -2.1), (2.1, 0.0)),
    },
    'long': {
        ANCHOR: BASE,
        PURINE: ((0.0, -5.0), (2.1, 0.0)),
        PYRIMIDINE: ((0.0, -3.5), (2.1, 0.0)),