Esempio n. 1
0
def test_ra(session):
    from chimerax.core.models import Model, Drawing
    m = Model('test', session)
    d = Drawing('ring')
    d.set_geometry(*ring_arrow_with_post(0.5, 0.05, 4, 6, 0.3, 0.1, 0.05, 1))
    m.add_drawing(d)
    session.models.add([m])
Esempio n. 2
0
def draw_asu(xmap):
    from chimerax.geometry import Place, Places
    from chimerax.core.models import Drawing, Model
    from chimerax.surface.shapes import sphere_geometry
    d = Drawing('asu corners')
    m = Model('asu box', session)
    #d.vertices, d.normals, d.triangles = sphere_geometry(80)
    d.set_geometry(*sphere_geometry(80))
    asu = xmap.grid_asu()
    grid = xmap.grid_sampling()
    cell = xmap.cell()
    minmax = [asu.min().coord_frac(grid).coord_orth(cell).xyz, asu.max().coord_frac(grid).coord_orth(cell).xyz]
    dp = []
    for i in range(2):
        for j in range(2):
            for k in range(2):
                dp.append(Place(origin=[minmax[i][0],minmax[j][1],minmax[k][2]]))
    d.positions = Places(dp)
    m.add_drawing(d)
    session.models.add([m])
    return d
Esempio n. 3
0
def draw_box(min_corner, max_corner, name='box'):
    from chimerax.geometry import Place, Places
    from chimerax.core.models import Drawing, Model
    from chimerax.surface.shapes import sphere_geometry
    d = Drawing('corners')
    m = Model(name, session)
    #d.vertices, d.normals, d.triangles = sphere_geometry(80)
    d.set_geometry(*sphere_geometry(80))
    minmax = [min_corner, max_corner]
    dp = []
    base_color = numpy.array([255,255,255,255])
    color_increment = numpy.array([0,-32,-32,0])
    colors = []
    for i in range(2):
        for j in range(2):
            for k in range(2):
                dp.append(Place(origin=[minmax[i][0],minmax[j][1],minmax[k][2]]))
                colors.append(base_color-color_increment*(i+j+k));
    d.positions = Places(dp)
    d.colors = colors
    m.add_drawing(d)
    session.models.add([m])
    return d
def unit_cell_and_sym_axes(session, unit_cell):
    cell = unit_cell.cell
    from chimerax.core.models import Model
    from chimerax.geometry import Places, Place
    from collections import defaultdict
    import numpy
    from math import sqrt
    from fractions import Fraction
    from chimerax.clipper.clipper_python import (Coord_frac, Coord_orth,
                                                 RTop_frac, Vec3_double as
                                                 Vec3, Symop, Mat33_double as
                                                 Mat33)

    axis_defs = defaultdict(lambda: list())

    m = Model('Unit cell and symmetry', session)

    # box_origin_frac = unit_cell.origin.coord_frac(unit_cell.grid)-Coord_frac([1,1,1])
    # box_origin_xyz = box_origin_frac.coord_orth(cell).as_numpy()
    box_size = unit_cell.grid.dim * 3
    syms = unit_cell.symops

    #syms = Places(place_array = unit_cell.all_symops_in_box(box_origin_xyz, box_size).all_matrices_orth(unit_cell.cell, '3x4'))

    #syms = Places(place_array = unit_cell.symops.all_matrices_orth(unit_cell.cell, '3x4'))
    identity = Mat33.identity()

    # Need to check all operators covering a 3x3 unit cell block to ensure we
    # get them all. Generate all possible length-3 combinations of -1, 0 and 1
    u = v = w = numpy.linspace(-1, 1, 3)
    frac_offsets = numpy.array(numpy.meshgrid(u, v, w)).T.reshape(-1, 3)
    frac_offsets = [Vec3(f) for f in frac_offsets]

    rot44 = numpy.identity(4)

    for sym_index, s in enumerate(syms):
        if s.rot.equals(identity, 1e-6):
            # No rotation, therefore no symmetry axis
            continue

        rot = s.rot
        trn = s.trn

        ss = Symop(s)

        so = ss.rtop_orth(cell)
        pr = Place(axes=so.rot.as_numpy().T)
        if pr.is_identity(tolerance=1e-5):
            continue
        central_axis, angle = pr.rotation_axis_and_angle()
        central_axis /= numpy.linalg.norm(central_axis)
        angle = abs(round(angle))
        if angle == 0:
            # Pure translation
            continue
        if angle not in (60, 90, 120, 180):
            err_str = (
                'This transform has a rotation angle of {} degrees, '
                'which is not compatible with crystallographic symmetry. '
                'In real crystals, only rotations yielding 2, 3, 4 or 6-fold '
                'symmetry are possible.').format(angle)
            raise RuntimeError(err_str)
        fold_symmetry = 360 // angle

        ca_frac = Coord_orth(100 * central_axis).coord_frac(cell).unit()

        #screw_component = Coord_orth(so.screw_translation).coord_frac(cell)
        # screw_component_orth = numpy.dot(so.trn.as_numpy(), central_axis) * central_axis
        # screw_component = Coord_orth(screw_component_orth).coord_frac(cell).lattice_copy_zero()
        #screw_component = Coord_frac((Vec3.dot(ss.trn, ca_frac) * ca_frac)).lattice_copy_zero()
        #print('Symop: {}, symmetry: {}, fractional_translation: {}, central_axis_orth: {}, central_axis_frac: {}, screw_component_frac: {}'.format(
        #    sym_index, fold_symmetry, ss.trn.as_numpy(), central_axis, ca_frac, screw_component))

        # screw_mag = numpy.linalg.norm(screw_component.as_numpy())
        # print('Screw magnitude before normalisation: {}'.format(screw_mag))
        # # if screw_mag > 1/12:
        # #     print('Non-zero screw translation vector: {} along axis: {} for fractional transform number {}: {}'.format(screw_component, central_axis, sym_index, s))
        # screw_mag = numpy.linalg.norm([float(Fraction(s).limit_denominator(12)) for s in screw_component.as_numpy()])*sqrt(3) # LCM of possible fractional screw translations 1/(2,3,4 or 6)
        # print('Screw magnitude after normalisation: {}'.format(screw_mag))

        for offset in frac_offsets:
            this_trn = trn + offset

            tf = RTop_frac(rot, this_trn).rtop_orth(unit_cell.cell)
            trn_orth = tf.trn.as_numpy()
            screw_orth = numpy.dot(trn_orth, central_axis) * central_axis
            perp_orth = trn_orth - screw_orth

            # Remove any whole-unit-cell translation component
            screw_frac = Coord_orth(screw_orth).coord_frac(
                cell).lattice_copy_zero().as_numpy()
            normalised_screw_frac = [
                Fraction(s).limit_denominator(12) for s in screw_frac
            ]
            normalised_screw_frac_float = numpy.array(
                [float(s) for s in normalised_screw_frac])
            screw_mag = numpy.linalg.norm(normalised_screw_frac_float)

            rot44[:3, :3] = tf.rot.as_numpy()
            rot44[:3, 3] = perp_orth

            origin, slope = rotation_axis(rot44)

            origin = Coord_orth(origin).coord_frac(cell).as_numpy()
            slope = Coord_orth(slope * 100).coord_frac(cell).as_numpy()

            axis_defs[(fold_symmetry, screw_mag)].append([origin, slope])

    plane_points, plane_normals = unit_cell_planes(unit_cell,
                                                   fractional_coords=True,
                                                   pad=0.001)
    plane_points = numpy.array([pp[0] for pp in plane_points])

    for (fold_symmetry, screw_component), axes in axis_defs.items():
        uvw0, uvw1 = plane_intersections_in_unit_cell(axes, plane_points,
                                                      plane_normals)
        if uvw0 is None:
            continue
        from chimerax.clipper.clipper_python import Coord_frac
        axyz0 = numpy.array([
            Coord_frac(uvw).coord_orth(unit_cell.cell).as_numpy()
            for uvw in uvw0
        ])
        axyz1 = numpy.array([
            Coord_frac(uvw).coord_orth(unit_cell.cell).as_numpy()
            for uvw in uvw1
        ])
        d = sym_axis_drawing(fold_symmetry, screw_component, axyz0, axyz1)
        if d is not None:
            m.add_drawing(d)

    bd = unit_cell_box_drawing(unit_cell_corners(unit_cell))
    m.add_drawing(bd)

    return m