Exemplo n.º 1
0
def lattitude_longtitude_circles(n=10):
    cvertices, cedges = unit_circle()

    vertices = []
    edges = []

    # Make lattitude circles
    from math import pi, sin, cos
    for i in range(n):
        a = pi * (i + 1) / (n + 1)
        v, e = cvertices.copy(), cedges.copy()
        v *= sin(a)
        v[:, 2] += cos(a)
        e += len(vertices) * len(v)
        vertices.append(v)
        edges.append(e)

    # Make longitude circles
    from chimerax.geometry import vector_rotation
    for i in range(n):
        a = pi * i / n
        v, e = cvertices.copy(), cedges.copy()
        normal = (cos(a), sin(a), 0)
        vector_rotation((0, 0, 1), normal).transform_points(v, in_place=True)
        e += len(vertices) * len(v)
        vertices.append(v)
        edges.append(e)

    from numpy import concatenate
    return concatenate(vertices), concatenate(edges)
Exemplo n.º 2
0
def _line_orientation(from_point, to_point, axis, height):
    if from_point is None and to_point is None and axis is None:
        return None

    c,h,r = None, height, None

    from chimerax.core.commands import Axis, Center
    if isinstance(axis, Axis):
        axis = axis.scene_coordinates()
    if isinstance(from_point, Center):
        from_point = from_point.scene_coordinates()
    if isinstance(to_point, Center):
        to_point = to_point.scene_coordinates()
        
    from chimerax.geometry import vector_rotation, norm
    if axis is not None:
        r = vector_rotation((0,0,1), axis)
    else:
        from numpy import array, float32
        axis = array((0,0,1), float32)
        
    if from_point is not None and to_point is not None:
        c = 0.5 * (from_point + to_point)
        v = to_point - from_point
        r = vector_rotation((0,0,1), v)
        h = norm(v)
    elif from_point is not None and to_point is None:
        c = from_point + 0.5*height*axis
    elif from_point is None and to_point is not None:
        c = to_point - 0.5*height*axis
        
    return h, c, r
Exemplo n.º 3
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
Exemplo n.º 4
0
    def sphere_geometry(self, points, sphere_radius, disc_radius, num_disc_points):
        'Place a disc tangent to a unit sphere centered at each point'

        # Disc geometry
        from math import sin, cos, pi
        from numpy import array, float32, int32, concatenate
        r = disc_radius
        n = num_disc_points
        cp = [(r*cos(a*2*pi/n), r*sin(a*2*pi/n), sphere_radius) for a in range(n)]
        dv = array([(0,0,sphere_radius)] + cp, float32)
        dn = array([(0,0,1)]*(n+1), float32)
        dt = array([(0,1+i,1+(i+1)%n) for i in range(n)], int32)

        # Discs for each sphere point
        vs = []
        ns = []
        ts = []
        from chimerax.geometry import vector_rotation, normalize_vector
        for i in range(len(points)):
            p = points[i]
            rv = vector_rotation((0,0,1), p)
            vs.append(rv * dv)
            ns.append(rv * dn)
            ts.append(dt + i*(n+1))
        va, na, ta = concatenate(vs), concatenate(ns), concatenate(ts)
        return va, na, ta
Exemplo n.º 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)
Exemplo n.º 6
0
 def _update_geometry(self):
     from chimerax.shape.shape import cylinder_geometry
     varray, tarray = cylinder_geometry(
         self.radius, self.thickness, max(2, int(self.thickness / 3 + 0.5)),
         max(40, int(20.0 * self.radius + 0.5)), True)
     from chimerax.geometry import translation, vector_rotation
     varray = (translation(self.plane.origin) * vector_rotation(
         (0, 0, 1), self.plane.normal)).transform_points(varray)
     from chimerax.surface import calculate_vertex_normals
     narray = calculate_vertex_normals(varray, tarray)
     self.set_geometry(varray, narray, tarray)
Exemplo n.º 7
0
 def update_pointer(self, msg):
     if 'name' in msg:
         if 'id' in msg:  # If id not in msg leave name as "my pointer".
             self.name = '%s pointer' % msg['name']
     if 'color' in msg:
         self.color = msg['color']
     if 'mouse' in msg:
         xyz, axis = msg['mouse']
         from chimerax.geometry import vector_rotation, translation
         p = translation(xyz) * vector_rotation((0, 0, 1), axis)
         self.position = p
Exemplo n.º 8
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
Exemplo n.º 9
0
    def layout(self, params, circuit_segments):

        p = params
        from chimerax.geometry import translation, rotation, Place, vector_rotation, norm
        from math import pi, cos, sin

        # Compute helix axis direction.
        # The helix rotation axis is does not make a 90 degree angle with
        # the P-P basepair line.  It makes an angle of approximately 110 degrees.
        pa = p.pair_tilt * pi / 180
        from numpy import array
        axis = array((cos(pa), sin(pa), 0))

        # Compute screw motion that advances basepair along helix.
        # Initial basepair P-P is spans (0,0,0) to (pair_width,0,0).
        rtf = rotation(axis,
                       p.stem_twist,
                       center=(0.5 * p.pair_width, 0, -p.pair_off_axis))
        ttf = translation(p.pair_spacing * axis)
        stf = ttf * rtf

        # Specify initial orientations of basepair nucleotides
        # so P-atoms are on helix and paired P atom is in the
        # oriented xy plane.
        p0, p1 = (0, 0, 0), (p.pair_width, 0, 0)
        tf1 = self.stem_residue_orientation(p0, stf * p0, p1)
        p2 = stf.inverse() * p1
        tf2 = self.stem_residue_orientation(p1, p2, p0)

        # Keep track of basepair P-P orientation used to
        # orient the loop at the end of the stem.
        ctf = Place()

        # Layout nucleotides for both strands of double helix.
        coords = {}
        for i in range(self.length):
            coords[self.base5p + i] = tf1
            coords[self.base3p - i] = tf2
            tf1 = stf * tf1
            tf2 = stf * tf2
            ctf = stf * ctf

        # The next segment after the stem should put its first
        # P-atom at a position on the helix so that the last
        # nucleotide of the stem has the right orientation to
        # make a base pair.  To achieve this the initial basepair
        # P-P does not lie on the x-axis.  Instead we tilt the
        # entire helix so the paired P is advanced up the helix
        # by one position.
        width = norm(p2)
        ttf = vector_rotation(p2, p1)
        for b, tf in coords.items():
            coords[b] = ttf * coords[b]

        # Added circuit at end of stem.
        ccoords = self.circuit.layout(p, gap=width)

        # Position the end circuit using the P-P orientation at
        # the end of the stem and taking account of the tilt of
        # the entire helix.
        ctf = ttf * ctf * ttf.inverse()
        for b, tf in ccoords.items():
            coords[b] = ctf * tf

        # Use segment width for the tilted helix.
        seg = [Segment(coords, width, 0)]

        return seg