예제 #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
예제 #2
0
def map_points_and_weights(v,
                           above_threshold,
                           point_to_world_xform=Place(),
                           include_zeros=True):

    m, xyz_to_ijk_tf = v.matrix_and_transform(point_to_world_xform,
                                              subregion=None,
                                              step=None)

    if above_threshold and v.minimum_surface_level is None:
        above_threshold = False

    if above_threshold:
        # Keep only points where density is above lowest displayed threshold
        threshold = v.minimum_surface_level
        from chimerax.map import high_indices
        points_int = high_indices(m, threshold)
        from numpy import single as floatc
        points = points_int.astype(floatc)
        weights = m[points_int[:, 2], points_int[:, 1], points_int[:, 0]]
    else:
        from numpy import single as floatc, ravel, count_nonzero, nonzero, take
        from chimerax.map_data import grid_indices
        points = grid_indices(m.shape[::-1], floatc)  # i,j,k indices
        weights = ravel(m).astype(floatc)
        if not include_zeros:
            if count_nonzero(weights) < len(weights):
                nz = nonzero(weights)[0]
                points = take(points, nz, axis=0)
                weights = take(weights, nz, axis=0)

    xyz_to_ijk_tf.inverse().transform_points(points, in_place=True)

    return points, weights
예제 #3
0
  def _rotation_changed(self):

    v = self._map
    if v is None:
        return

    data = v.data

    if data.rotation == ((1,0,0),(0,1,0),(0,0,1)):
      axis, angle = (0,0,1), 0
    else:
      from chimerax.geometry import Place
      axis, angle = Place(axes = data.rotation).rotation_axis_and_angle()

    rax = self._rotation_axis.value
    from .volume_viewer import vector_value
    naxis = vector_value(rax, axis)
    if naxis is None:
      self._status('Invalid rotation axis.  Must be 3 numbers separated by spaces.')
      return
    if tuple(naxis) == (0,0,0):
      self._status('Rotation axis must be non-zero')
      return

    nangle = self._rotation_angle.value

    if tuple(naxis) != tuple(axis) or nangle != angle:
      from chimerax.geometry import rotation
      r = rotation(naxis, nangle)
      data.set_rotation(r.matrix[:,:3])
      # Have to change xyz origin for index origin to remain the same.
      self._origin_changed()
      self._redraw_regions(data)
      self._status('Set rotation axis %s, angle %.3g' % (rax, nangle))
예제 #4
0
def read_autopack_results(path):

    j = read_json(path)
    recipe_path = j['recipe']['setupfile']
    pieces = {}
    for comp_name, cres in j['compartments'].items():
        for interior_or_surface, comp_ingr in cres.items():
            for ingr_name, ingr_places in comp_ingr['ingredients'].items():
                for translation, rotation44 in ingr_places['results']:
                    t0,t1,t2 = translation
                    r00,r01,r02 = rotation44[0][:3]
                    r10,r11,r12 = rotation44[1][:3]
                    r20,r21,r22 = rotation44[2][:3]
                    tf = ((r00,r01,r02,t0),
                          (r10,r11,r12,t1),
                          (r20,r21,r22,t2))
                    from chimerax.geometry import Place
                    p = Place(tf)
                    ingr_id = (comp_name, interior_or_surface, ingr_name)
                    if ingr_id in pieces:
                        pieces[ingr_id].append(p)
                    else:
                        pieces[ingr_id] = [p]

    return recipe_path, pieces
예제 #5
0
    def helix_segment(self, base_index, count, spacing, rise):
        '''
        Lay out a single turn helix on x axis.
        Radius is calculated to fit the specified number of nucleotides.
        '''
        # Choose radius so one helix turn has desired length.
        # Helix arc length = s, radius = r, rise = h: s**2 = r**2 + (h/(2*pi))**2
        length = spacing * count
        from math import sqrt, pi
        radius = sqrt((length / (2 * pi))**2 - (rise / (2 * pi))**2)

        # Compute screw motion to advance along helix
        angle = 2 * pi / count
        angle_deg = angle * 180 / pi
        from chimerax.geometry import translation, rotation, vector_rotation, Place
        step = translation((rise / count, 0, 0)) * rotation(
            (1, 0, 0), angle_deg, center=(0, radius, 0))

        # Compute first nucleotide so P-P lies on helix.
        orient = vector_rotation((1, 0, 0), step * (0, 0, 0))

        # Place nucleotides on helix.
        place = {}
        p = Place()
        for i in range(count):
            place[base_index + i] = p * orient
            p = step * p

        return Segment(place, rise, pad=0)
예제 #6
0
def extrusion_transforms(path, tangents, yaxis=None):

    from chimerax.geometry import identity, vector_rotation, translation
    tflist = []
    if yaxis is None:
        # Make xy planes for coordinate frames at each path point not rotate
        # from one point to next.
        tf = identity()
        n0 = (0, 0, 1)
        for p1, n1 in zip(path, tangents):
            tf = vector_rotation(n0, n1) * tf
            tflist.append(translation(p1) * tf)
            n0 = n1
    else:
        # Make y-axis of coordinate frames at each point align with yaxis.
        from chimerax.geometry import normalize_vector, cross_product, Place
        for p, t in zip(path, tangents):
            za = t
            xa = normalize_vector(cross_product(yaxis, za))
            ya = cross_product(za, xa)
            tf = Place(
                ((xa[0], ya[0], za[0], p[0]), (xa[1], ya[1], za[1], p[1]),
                 (xa[2], ya[2], za[2], p[2])))
            tflist.append(tf)
    return tflist
예제 #7
0
def mmcif_assemblies(model):
    table_names = ('pdbx_struct_assembly', 'pdbx_struct_assembly_gen',
                   'pdbx_struct_oper_list')
    from chimerax import mmcif
    assem, assem_gen, oper = mmcif.get_mmcif_tables_from_metadata(
        model, table_names)
    if not assem or not assem_gen or not oper:
        return []

    name = assem.mapping('id', 'details')
    ids = list(name.keys())
    ids.sort()

    cops = assem_gen.fields(('assembly_id', 'oper_expression', 'asym_id_list'))
    chain_ops = {}
    for id, op_expr, cids in cops:
        chain_ops.setdefault(id, []).append((cids.split(','), op_expr))

    ops = {}
    mat = oper.fields(
        ('id', 'matrix[1][1]', 'matrix[1][2]', 'matrix[1][3]', 'vector[1]',
         'matrix[2][1]', 'matrix[2][2]', 'matrix[2][3]', 'vector[2]',
         'matrix[3][1]', 'matrix[3][2]', 'matrix[3][3]', 'vector[3]'))
    from chimerax.geometry import Place
    for id, m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34 in mat:
        ops[id] = Place(matrix=((m11, m12, m13, m14), (m21, m22, m23, m24),
                                (m31, m32, m33, m34)))

    alist = [Assembly(id, name[id], chain_ops[id], ops, True) for id in ids]
    return alist
예제 #8
0
def perspective_view_all(bounds,
                         position,
                         field_of_view,
                         window_size=None,
                         pad=0):
    '''
    Return the camera position that shows the specified bounds.
    Camera has perspective projection.
    '''
    from math import radians, sin, cos
    fov2 = radians(field_of_view) / 2
    s, c = sin(fov2), cos(fov2)
    face_normals = [
        position.transform_vector(v) for v in ((c / s, 0, 1), (-c / s, 0, 1))
    ]  # frustum side normals
    if window_size is not None:
        aspect = window_size[1] / window_size[0]
        from math import tan, atan
        fov2y = atan(aspect * tan(fov2))
        sy, cy = sin(fov2y), cos(fov2y)
        face_normals.extend([
            position.transform_vector(v)
            for v in ((0, cy / sy, 1), (0, -cy / sy, 1))
        ])  # frustum top/bottom normals
    center = bounds.center()
    bc = bounds.box_corners() - center
    from chimerax.geometry import inner_product, Place
    d = max(inner_product(n, c) for c in bc for n in face_normals)
    d *= 1 / max(0.01, 1 - pad)
    view_direction = -position.z_axis()
    camera_center = center - d * view_direction
    va_position = Place(axes=position.axes(), origin=camera_center)
    return va_position
예제 #9
0
def surfaces_from_nodes(nodes, color, place, instances, session):

    from collada.scene import GeometryNode, Node
    from chimerax.geometry import Place
    from chimerax.core.models import Surface
    splist = []
    for n in nodes:
        if isinstance(n, GeometryNode):
            materials = dict((m.symbol, m.target) for m in n.materials)
            g = n.geometry
            colors = g.sourceById
            if g.id in instances:
                add_geometry_instance(g.primitives, instances[g.id], place,
                                      color, materials)
            else:
                instances[g.id] = spieces = geometry_node_surfaces(
                    g.primitives, place, color, materials, colors, session)
                splist.extend(spieces)
        elif isinstance(n, Node):
            pl = place * Place(n.matrix[:3, :])
            spieces = surfaces_from_nodes(n.children, color, pl, instances,
                                          session)
            name = n.xmlnode.get('name')
            if len(spieces) > 1:
                m = Surface(name, session)
                m.add(spieces)
                splist.append(m)
            elif len(spieces) == 1:
                s = spieces[0]
                s.name = name
                splist.append(s)
    return splist
예제 #10
0
def read_collada_surfaces(session,
                          path,
                          name=None,
                          color=(200, 200, 200, 255),
                          **kw):
    '''Open a collada file.'''

    from collada import Collada
    c = Collada(path)
    if name is None:
        from os.path import basename
        name = basename(path)
    from chimerax.geometry import Place
    splist = surfaces_from_nodes(c.scene.nodes, color, Place(), {}, session)
    if len(splist) > 1:
        from chimerax.core.models import Model
        s = Model(name, session)
        s.add(splist)
    elif len(splist) == 1:
        s = splist[0]
        s.name = name
    else:
        from chimerax.core.errors import UserError
        raise UserError('Collada file has no TriangleSets: %s' % name)
    set_instance_positions_and_colors(s.all_drawings())

    ai = c.assetInfo
    if ai:
        s.collada_unit_name = ai.unitname
        s.collada_contributors = ai.contributors

    return [s], ('Opened collada file %s' % name)
예제 #11
0
def icosahedron_geometry(orientation='2n5'):

    a23, a25, a35 = icosahedron_angles()
    a = 2 * a25  # Angle spanned by edge from center

    # 5-fold symmetry axis along z
    from math import cos, sin, pi
    c5 = cos(2 * pi / 5)
    s5 = sin(2 * pi / 5)
    from chimerax.geometry import Place
    tf5 = Place(((c5, -s5, 0, 0), (s5, c5, 0, 0), (0, 0, 1, 0)))

    # 2-fold symmetry axis along x
    tf2 = Place(((1, 0, 0, 0), (0, -1, 0, 0), (0, 0, -1, 0)))

    p0 = (0, 0, 1)
    p50 = (0, sin(a), cos(a))
    p51 = tf5 * p50
    p52 = tf5 * p51
    p53 = tf5 * p52
    p54 = tf5 * p53
    vertices = [p0, p50, p51, p52, p53, p54]
    vertices.extend([tf2 * q for q in vertices])

    if orientation != '2n5':
        tf = coordinate_system_transform('2n5', orientation)
        vertices = [tf * p for p in vertices]

    #
    # Vertex numbering
    #
    #  Top   1          Bottom
    #      2   5        9   10
    #        0            6
    #      3   4        8   11
    #                     7
    # 20 triangles composing icosahedron.
    #
    triangles = ((0, 1, 2), (0, 2, 3), (0, 3, 4), (0, 4, 5), (0, 5, 1),
                 (6, 7, 8), (6, 8, 9), (6, 9, 10), (6, 10, 11), (6, 11, 7),
                 (1, 9, 2), (2, 9, 8), (2, 8, 3), (3, 8, 7), (3, 7, 4),
                 (4, 7, 11), (4, 11, 5), (5, 11, 10), (5, 10, 1), (1, 10, 9))

    from numpy import array, float32, uint32
    va = array(vertices, float32)
    ta = array(triangles, uint32)
    return va, ta
예제 #12
0
def singleton_segments(base_index, count, spacing, placement=None):
    '''Create one nucleotide Segments with the same orientation and width.'''
    if placement is None:
        from chimerax.geometry import Place
        placement = Place()
    return [
        Segment({base_index + i: placement}, width=spacing, pad=0)
        for i in range(count)
    ]
예제 #13
0
def _cube_map_face_views():
    from chimerax.geometry import Place
    views = [Place(matrix=m) for m in
             (((0,0,-1,0),(0,-1,0,0),(-1,0,0,0)),
              ((0,0,1,0),(0,-1,0,0),(1,0,0,0)),
              ((1,0,0,0),(0,0,-1,0),(0,1,0,0)),
              ((1,0,0,0),(0,0,1,0),(0,-1,0,0)),
              ((1,0,0,0),(0,-1,0,0),(0,0,-1,0)),
              ((-1,0,0,0),(0,-1,0,0),(0,0,1,0)))]
    return views
예제 #14
0
def principle_axes_box(varray, tarray):

    from chimerax import surface
    weights = surface.vertex_areas(varray, tarray)
    from chimerax.std_commands.measure_inertia import moments_of_inertia
    axes, d2e, center = moments_of_inertia([(varray, weights)])
    from chimerax.geometry import Place, point_bounds
    axes_points = Place(axes=axes).inverse().transform_points(varray)
    bounds = point_bounds(axes_points)
    return axes, bounds
예제 #15
0
def make_closest_placement_identity(tflist, center):

    d = tflist.array()[:, :, 3] - center
    d2 = (d * d).sum(axis=1)
    i = d2.argmin()
    tfinv = tflist[i].inverse()
    rtflist = [tf * tfinv for tf in tflist]
    from chimerax.geometry import Place, Places
    rtflist[i] = Place()
    return Places(rtflist)
예제 #16
0
def ellipsoid_geometry(center, axes, axis_lengths, num_triangles = 1000):

  from chimerax.surface import sphere_geometry
  varray, narray, tarray = sphere_geometry(num_triangles)
  narray = narray.copy()        # Is same as varray for sphere.
  from chimerax.geometry import Place, scale, normalize_vectors
  ptf = Place(axes = axes, origin = center) * scale(axis_lengths)
  ptf.transform_points(varray, in_place = True)
  ntf = Place(axes = axes) * scale([1/l for l in axis_lengths])
  ntf.transform_vectors(narray, in_place = True)
  normalize_vectors(narray)

  return varray, narray, tarray
예제 #17
0
def euler_rotation(euler_angles):
    from math import radians, cos, sin
    a, b, g = [radians(a) for a in euler_angles]
    R11, R12, R13 = cos(g) * cos(b) * cos(a) - sin(g) * sin(a), -sin(g) * cos(
        b) * cos(a) - cos(g) * sin(a), sin(b) * cos(a)
    R21, R22, R23 = cos(g) * cos(b) * sin(a) + sin(g) * cos(a), -sin(g) * cos(
        b) * sin(a) + cos(g) * cos(a), sin(b) * sin(a)
    R31, R32, R33 = -cos(g) * sin(b), sin(g) * sin(b), cos(b)
    from chimerax.geometry import Place
    rot = Place(axes=((R11, R21, R31), (R12, R22, R32), (R13, R23, R33)))
    return rot
예제 #18
0
def show_residue_fit(session, residues, map, range = 2, last_pos = None, motion_frames = 20):
    '''Set camera to show first residue in list and display map in zone around given residues.'''
    res = residues[0]
    ratoms = res.atoms
    anames = tuple(ratoms.names)
    try:
        i = [anames.index(aname) for aname in ('N', 'CA', 'C')]
    except ValueError:
        return None		# Missing backbone atom
    xyz = ratoms.filter(i).scene_coords

    # Align backbone to template backbone coords
    from chimerax.geometry import align_points, Place
    from numpy import array
    txyz = array([[ 12.83300018,   6.83900023,   6.73799992],
                  [ 12.80800056,   7.87400055,   5.70799971],
                  [ 11.91800022,   9.06700039,   5.9920001 ]])
    p, rms = align_points(txyz, xyz)

    # Set camera view relative to template.
    c = session.main_view.camera
    cp = c.position
    if last_pos is None:
        tc = Place(((-0.46696,0.38225,-0.79739,-3.9125),
                    (0.81905,-0.15294,-0.55296,-4.3407),
                    (-0.33332,-0.91132,-0.24166,-1.4889)))
        if c.name == 'orthographic':
            c.field_width = 12		# Set orthographic field of view, Angstroms
    else:
        # Maintain same relative camera position to backbone.
        tc = last_pos.inverse() * cp

    # Smooth interpolation
    np = p*tc
    if motion_frames > 1:
        def interpolate_camera(session, f, cp=cp, np=np, center=np.inverse()*xyz[1], frames=motion_frames):
            c = session.main_view.camera
            p = np if f+1 == frames else cp.interpolate(np, center, frac = (f+1)/frames)
            c.position = p
        from chimerax.core.commands import motion
        motion.CallForNFrames(interpolate_camera, motion_frames, session)
    else:
        c.position = np

    from numpy import concatenate
    zone_points = concatenate([r.atoms.scene_coords for r in residues])
    from chimerax.surface import zone
    for s in map.surfaces:
        zone.surface_zone(s, zone_points, range, auto_update = True)

    for r in residues:
        r.atoms.displays = True
    
    return p
예제 #19
0
 def _update_position(self, *_):
     v = self._session.main_view
     if v.center_of_rotation_method == 'front center':
         # Don't recompute front center rotation point, expensive, distracting.
         center = tuple(v._center_of_rotation)
     else:
         center = tuple(v.center_of_rotation)
     if center != self._center:
         self._center = center
         from chimerax.geometry import Place
         self.position = Place(origin=center)
예제 #20
0
def polygon_coordinate_frame(polygon):

    p = polygon
    c = p.center()
    za = p.normal()
    xa = p.vertices[0].coord - c
    from chimerax.geometry import normalize_vector, cross_product, Place
    ya = normalize_vector(cross_product(za, xa))
    xa = normalize_vector(cross_product(ya, za))
    tf = [(xa[a], ya[a], za[a], c[a]) for a in (0, 1, 2)]
    return Place(tf)
예제 #21
0
def parse_symmetry(session, group, center=None, axis=None, molecule=None):

    # Handle products of symmetry groups.
    groups = group.split('*')
    from chimerax.geometry import Places
    ops = Places()
    for g in groups:
        ops = ops * group_symmetries(session, g, molecule)

    # Apply center and axis transformation.
    if center is not None or axis is not None:
        from chimerax.geometry import Place, vector_rotation, translation
        tf = Place()
        if center is not None and tuple(center) != (0, 0, 0):
            tf = translation([-c for c in center])
        if axis is not None and tuple(axis) != (0, 0, 1):
            tf = vector_rotation(axis, (0, 0, 1)) * tf
        if not tf.is_identity():
            ops = ops.transform_coordinates(tf)
    return ops
예제 #22
0
def edge_coordinate_frame(edge):

    x0, x1 = edge_alignment_points(edge)
    p = edge.polygon
    c = p.center()
    c01 = 0.5 * (x0 + x1)
    from chimerax.geometry import cross_product, normalize_vector, Place
    xa = normalize_vector(x1 - x0)
    za = normalize_vector(cross_product(xa, c01 - c))
    ya = cross_product(za, xa)
    tf = Place(((xa[0], ya[0], za[0], c01[0]), (xa[1], ya[1], za[1], c01[1]),
                (xa[2], ya[2], za[2], c01[2])))
    return tf
예제 #23
0
def scene_and_node_models(scenes, nodes, file_name, session):

    smodels = []
    for si, s in enumerate(scenes):
        if 'name' in s:
            sname = s['name']
        elif len(scenes) == 1:
            sname = file_name
        else:
            sname = '%s scene %d' % (file_name, si + 1)
        sm = gltfModel(sname, session)
        smodels.append(sm)
        if 'nodes' not in s:
            raise glTFError('glTF scene %d has no nodes' % si)
        sm.gltf_nodes = s['nodes']

    # Make model for each node
    nmodels = []
    for ni, node in enumerate(nodes):
        if 'name' in node:
            nname = node['name']
        else:
            nname = '%d' % (ni + 1)
        nm = gltfModel(nname, session)
        if 'mesh' in node:
            nm.gltf_mesh = node['mesh']
        if 'children' in node:
            nm.gltf_child_nodes = node['children']
        if 'matrix' in node:
            m = node['matrix']
            from chimerax.geometry import Place
            nm.position = Place(
                ((m[0], m[4], m[8], m[12]), (m[1], m[5], m[9], m[13]),
                 (m[2], m[6], m[10], m[14])))
        if 'scale' in node or 'translation' in node or 'rotation' in node:
            session.logger.warning(
                'glTF node %d has unsupported rotation, scale or translation, ignoring it'
                % ni)
        nmodels.append(nm)

    # Add node models to scenes.
    for sm in smodels:
        sm.add([nmodels[ni] for ni in sm.gltf_nodes])

    # Add child nodes to parent nodes.
    for nm in nmodels:
        if hasattr(nm, 'gltf_child_nodes'):
            nm.add([nmodels[ni] for ni in nm.gltf_child_nodes])

    return smodels, nmodels
예제 #24
0
def map_overlap_and_correlation(map1,
                                map2,
                                above_threshold,
                                xform=None,
                                include_zeros=False):

    p, w1 = map_points_and_weights(map1,
                                   above_threshold,
                                   include_zeros=include_zeros)
    if xform is None:
        from chimerax.geometry import Place
        xform = Place()
    w2 = map2.interpolated_values(p, xform, subregion=None, step=None)
    return overlap_and_correlation(w1, w2)
예제 #25
0
def _show_surface(session, varray, tarray, color, mesh,
                  center, rotation, qrotation, coordinate_system,
                  slab, model_id, shape_name, edge_mask = None, sharp_slab = False):
        
    if center is not None or rotation is not None or qrotation is not None:
        from chimerax.geometry import Place, translation
        tf = Place()
        if rotation is not None:
            tf = rotation * tf
        if qrotation is not None:
            tf = qrotation * tf
        if center is not None:
            from chimerax.core.commands import Center
            if isinstance(center, Center):
                center = center.scene_coordinates()
            tf = translation(center) * tf
        varray = tf.transform_points(varray)
        
    from chimerax.surface import calculate_vertex_normals
    narray = calculate_vertex_normals(varray, tarray)
    
    if slab is not None:
        from chimerax.mask.depthmask import slab_surface
        varray, narray, tarray = slab_surface(varray, tarray, narray, slab,
                                              sharp_edges = sharp_slab)

    s = _surface_model(session, model_id, shape_name, coordinate_system)
    s.set_geometry(varray, narray, tarray)
    if color is not None:
        s.color = color
    if mesh:
        s.display_style = s.Mesh
    if edge_mask is not None:
        s.edge_mask = edge_mask    # Hide spokes of hexagons.
    _add_surface(s)

    return s
예제 #26
0
    def __init__(self, drawing, *, window_size=(256, 256), trigger_set=None):

        self.triggers = trigger_set
        self.drawing = drawing
        self.window_size = window_size  # pixels
        self._render = None
        self._opengl_initialized = False

        # Lights and material properties
        from .opengl import Lighting, Material, Silhouette
        self._lighting = Lighting()
        self._material = Material()
        self._silhouette = Silhouette()

        # Red, green, blue, opacity, 0-1 range.
        self._background_rgba = (0, 0, 0, 0)
        self._highlight_color = (0, 1, 0, 1)
        self._highlight_width = 1  # pixels

        # Create camera
        from .camera import MonoCamera
        self._camera = MonoCamera()
        from chimerax.geometry import Place
        self._view_matrix = Place()  # Temporary used during rendering

        # Clip planes
        from .clipping import ClipPlanes
        self.clip_planes = ClipPlanes()
        self._near_far_pad = 0.01  # Extra near-far clip plane spacing.
        self._min_near_fraction = 0.001  # Minimum near distance, fraction of depth

        # Graphics overlays, used for example for crossfade
        self._overlays = []

        # Center of rotation
        from numpy import array, float32
        self._center_of_rotation = array((0, 0, 0), float32)
        self._update_center_of_rotation = False
        self._center_of_rotation_method = 'front center'

        # Redrawing
        self.frame_number = 1
        self.redraw_needed = True
        self._time_graphics = False
        self.update_lighting = True

        self._drawing_manager = dm = _RedrawNeeded()
        if trigger_set:
            self.drawing.set_redraw_callback(dm)
예제 #27
0
def view_initial(session, models=None):
    '''
    Set models to initial positions.

    Parameters
    ----------
    models : Models
      Set model positions to no rotation, no shift.
    '''

    if models is None:
        models = session.models.list()
    from chimerax.geometry import Place
    for m in models:
        m.position = Place()
예제 #28
0
def edge_join_transform(link, rlink, vertex_degree):

    f0 = edge_coordinate_frame(rlink)
    f1 = edge_coordinate_frame(link)
    from chimerax.geometry import Place
    r = Place(((-1, 0, 0, 0), (0, -1, 0, 0),
               (0, 0, 1, 0)))  # Rotate 180 degrees about z.

    if vertex_degree is None:
        ea = 0
    else:
        a = 180 - 360.0 / link.polygon.n
        ra = 180 - 360.0 / rlink.polygon.n
        ea = vertex_degree * (a + ra) - 720
    if ea != 0:
        from math import sin, cos, pi
        a = -pi / 6 if ea < 0 else pi / 6
        rx = Place(
            ((1, 0, 0, 0), (0, cos(a), sin(a), 0), (0, -sin(a), cos(a), 0)))
        r = rx * r

    tf = f0 * r * f1.inverse()

    return tf
예제 #29
0
def pdb_mtrix_matrices(pdb_headers, add_identity=True, given=False):

    h = pdb_headers
    have_matrix = ('MTRIX1' in h and 'MTRIX2' in h and 'MTRIX3' in h)
    if not have_matrix:
        if add_identity:
            from chimerax.geometry import identity
            return [identity()]
        else:
            return []

    row1_list = h['MTRIX1']
    row2_list = h['MTRIX2']
    row3_list = h['MTRIX3']
    if len(row1_list) != len(row2_list) or len(row2_list) != len(row3_list):
        if add_identity:
            from chimerax.geometry import identity
            return [identity()]
        else:
            return []

    row_triples = zip(row1_list, row2_list, row3_list)

    mlist = []
    from chimerax.geometry import Place
    for row_triple in row_triples:
        matrix = []
        for line in row_triple:
            try:
                mrow = [
                    float(f) for f in (line[10:20], line[20:30], line[30:40],
                                       line[45:55])
                ]
            except ValueError:
                break
            mgiven = (len(line) >= 60 and line[59] == '1')
            if (mgiven and given) or (not mgiven and not given):
                matrix.append(mrow)
        if len(matrix) == 3:
            mlist.append(Place(matrix))

    if add_identity:
        if len([m for m in mlist if m.is_identity()]) == 0:
            # Often there is no MTRIX identity entry
            from chimerax.geometry import identity
            mlist.append(identity())

    return Places(mlist)
예제 #30
0
def set_map_state(s, volume, notify = True):

  v = volume

  v.rendering_options = rendering_options_from_state(s['rendering_options'])

  if not 'display' in s:
     # Fix old session files
    s['display'] = s['displayed'] if 'displayed' in s else True
    
  for attr in basic_map_attributes:
    if attr in s:
      setattr(v, attr, s[attr])

  for old_attr, new_attr in renamed_attributes:
    if old_attr in s:
      setattr(v, new_attr, s[old_attr])

  if 'representation' in s:
    # Handle old session files that had representation attribute.
    style = s['representation']
    if style == 'solid':
      style = 'image'
    v.set_display_style(style)
      
  from chimerax.geometry import Place
  v.position = Place(s['place'])

  v.new_region(*s['region'], adjust_step = False)

  if 'region_list' in s:
    region_list_from_state(s['region_list'], v.region_list)

  if s['version'] == 1:
    for lev, color in zip(s['surface_levels'], s['surface_colors']):
      v.add_surface(lev, rgba = color)
      
#  dsize = [a*b for a,b in zip(v.data.step, v.data.size)]
#  v.transparency_depth /= min(dsize)

  if notify:
    v.call_change_callbacks(('display style changed',
                             'region changed',
                             'thresholds changed',
                             'displayed',
                             'colors changed',
                             'rendering options changed',
                             'coordinates changed'))