Example #1
0
def get_stem_rotation_matrix(stem, stem2, use_average_method=False):
    """
    :param stem: The first StemModel
    :param stem2: The second StemModel

    :retuirns: A RotationMatrix.
               Use stem1.vec()*rotMat to rotate stem1 onto stem2
               Use rotMat*stem2.vec() to rotate stem2 onto stem1
    """
    #twist1 = (stem.twists[0] + stem.twists[1]) / 2.

    if not use_average_method:
        twist1 = stem.twists[0]
        twist2 = stem2.twists[0]

    else:
        twist1 = ftug.virtual_res_3d_pos_core(stem.mids, stem.twists, 2, 4)[1]
        twist2 = ftug.virtual_res_3d_pos_core(stem2.mids, stem2.twists, 2,
                                              4)[1]

    return ftuv.get_double_alignment_matrix((stem.vec(), twist1),
                                            (stem2.vec(), twist2))
    # get normalvector to stem and twist.
    comp1 = np.cross(stem.vec(), twist1)

    # rotate around the first stem by t degrees
    rot_mat1 = ftuv.rotation_matrix(stem.vec(), t)
    rot_mat2 = ftuv.rotation_matrix(twist1, u - math.pi / 2)
    rot_mat3 = ftuv.rotation_matrix(comp1, v)

    rot_mat4 = np.dot(rot_mat3, np.dot(rot_mat2, rot_mat1))

    return rot_mat4
Example #2
0
    def add_stem_like_core(self, rna_plotter, coords, twists, stem_len, text, key,
                           color='green', width=2.4):
        (p, n) = coords
        width *= self.cylinder_width
        rna_plotter.add_segment(p, n, color, width, text, key=key)

        if self.show_twists:
            rna_plotter.add_cone(p, n, 'white', width, key)
            mult = 8.
            width = .3
            (twist1o, twist2o) = twists

            rna_plotter.add_segment(
                p, p + mult * twist1o, "cyan", width, '', key=key)
            rna_plotter.add_segment(
                n, n + mult * twist2o, "magenta", width, '', key=key)

            for i in range(stem_len):
                res = ftug.virtual_res_3d_pos_core((p, n), twists, i, stem_len)
                (pos, vec_c, vec_l, vec_r) = res
                rna_plotter.add_segment(
                    pos, pos + mult * vec_c, "orange", width, '', key=key)

                if self.add_letters:
                    rna_plotter.labels += [('L', list(pos + mult * vec_l))]
                    rna_plotter.labels += [('R', list(pos + mult * vec_r))]
Example #3
0
    def add_stem_like_core(self, coords, twists, stem_len, key,
                           color='green', width=2.4):
        (p, n) = coords

        self.add_cone(p, n, 'white', width, key)
        self.add_segment(p, n, color, width, key, key=key)
        #self.add_sphere(p, 'light gray', width=2.0 ) 
        #self.add_sphere(n, 'dark gray', width=2.0 ) 

        if self.add_twists:
            mult = 8.
            width = .3
            #twist1o = bg.get_twists(key)[0]
            #twist2o = bg.get_twists(key)[1]
            (twist1o, twist2o) = twists

            self.add_segment(p, p + mult * twist1o, "cyan", width, '', key=key)
            self.add_segment(n, n + mult * twist2o, "magenta", width, '', key=key)
            '''

            twist_rot_mat_l = cuv.rotation_matrix(n - p, -(1.45 / 2.))
            twist_rot_mat_r = cuv.rotation_matrix(n - p, (1.45 / 2.))

            twist1 = np.dot(twist_rot_mat_l, twist1o)
            twist2 = np.dot(twist_rot_mat_l, twist2o)

            twist3 = np.dot(twist_rot_mat_r, twist1o)
            twist4 = np.dot(twist_rot_mat_r, twist2o)



            self.add_segment(p, p + mult * twist1, "white", width, '', key)
            self.add_segment(n, n + mult * twist2, "white", width, '', key)

            self.add_segment(p, p + mult * twist3, "red", width, '', key)
            self.add_segment(n, n + mult * twist4, "red", width, '', key)
            '''

        #stem_len = bg.stem_length(key)

            for i in range(stem_len):
                #(pos, vec) = ftug.virtual_res_3d_pos(bg, key, i)
                res = ftug.virtual_res_3d_pos_core((p, n), twists, i, stem_len)
                (pos, vec_c, vec_l, vec_r) = res
                self.add_segment(pos, pos + mult * vec_c, "orange", width, '', key=key)

                if self.add_letters:
                    self.labels += [('L', list(pos + mult * vec_l))]
                    self.labels += [('R', list(pos + mult * vec_r))]

                '''
                self.add_segment(pos, pos + mult * vec_l, "yellow", width, '', key)
                self.add_segment(pos, pos + mult * vec_r, "purple", width, '', key)
                '''

                if self.display_virtual_residues:
                    self.add_sphere(pos + mult * vec_l, "cyan", 1.)
                    self.add_sphere(pos + mult * vec_r, "magenta", 1.)

        '''
Example #4
0
    def add_stem_like_core(self, coords, twists, stem_len, key,
                           color='green', width=2.4):
        (p, n) = coords

        self.add_cone(p, n, 'white', width, key)
        self.add_segment(p, n, color, width, key, key=key)
        self.add_sphere(p, 'light gray', width=2.0 ) 
        self.add_sphere(n, 'dark gray', width=2.0 ) 

        if self.add_twists:
            mult = 8.
            width = .3
            #twist1o = bg.get_twists(key)[0]
            #twist2o = bg.get_twists(key)[1]
            (twist1o, twist2o) = twists

            self.add_segment(p, p + mult * twist1o, "cyan", width, '', key=key)
            self.add_segment(n, n + mult * twist2o, "magenta", width, '', key=key)
            '''

            twist_rot_mat_l = cuv.rotation_matrix(n - p, -(1.45 / 2.))
            twist_rot_mat_r = cuv.rotation_matrix(n - p, (1.45 / 2.))

            twist1 = np.dot(twist_rot_mat_l, twist1o)
            twist2 = np.dot(twist_rot_mat_l, twist2o)

            twist3 = np.dot(twist_rot_mat_r, twist1o)
            twist4 = np.dot(twist_rot_mat_r, twist2o)



            self.add_segment(p, p + mult * twist1, "white", width, '', key)
            self.add_segment(n, n + mult * twist2, "white", width, '', key)

            self.add_segment(p, p + mult * twist3, "red", width, '', key)
            self.add_segment(n, n + mult * twist4, "red", width, '', key)
            '''

        #stem_len = bg.stem_length(key)

            for i in range(stem_len):
                #(pos, vec) = ftug.virtual_res_3d_pos(bg, key, i)
                res = ftug.virtual_res_3d_pos_core((p, n), twists, i, stem_len)
                (pos, vec_c, vec_l, vec_r) = res
                self.add_segment(pos, pos + mult * vec_c, "orange", width, '', key=key)

                if self.add_letters:
                    self.labels += [('L', list(pos + mult * vec_l))]
                    self.labels += [('R', list(pos + mult * vec_r))]

                '''
                self.add_segment(pos, pos + mult * vec_l, "yellow", width, '', key)
                self.add_segment(pos, pos + mult * vec_r, "purple", width, '', key)
                '''

                if self.display_virtual_residues:
                    self.add_sphere(pos + mult * vec_l, "cyan", 1.)
                    self.add_sphere(pos + mult * vec_r, "magenta", 1.)

        '''
Example #5
0
def _align_chain_to_stem(cg,
                         chains,
                         elem_name,
                         stem2,
                         use_average_method=True):
    """
    Rotate and tranlate chains to match the orientation of the coarse-grained stem.

    :param cg: The coarse-grained RNA where the fragment is originally from.
    :param chains: The PDB chains containing the original fragment.
    :param elem_name: The element name of the stem in cg.
    :param stem2: The target (cg-)stem. A StemModel object.
    """
    #The stem fragment we will rotate and translate
    stem1 = _define_to_stem_model(cg, chains, elem_name)
    '''
    (r, u, v, t) = ftug.get_stem_orientation_parameters(stem1.vec(),
                                                       (stem1.twists[0] + stem1.twists[1]) / 2.,
                                                       stem2.vec(),
                                                       (stem2.twists[0] + stem2.twists[1]) / 2.)
    '''
    if not use_average_method:
        (r, u,
         v, t) = ftug.get_stem_orientation_parameters(stem1.vec(),
                                                      stem1.twists[0],
                                                      stem2.vec(),
                                                      stem2.twists[0])
    else:
        tw1 = ftug.virtual_res_3d_pos_core(stem1.mids, stem1.twists, 2, 4)[1]
        tw2 = ftug.virtual_res_3d_pos_core(stem2.mids, stem2.twists, 2, 4)[1]
        (r, u,
         v, t) = ftug.get_stem_orientation_parameters(stem1.vec(), tw1,
                                                      stem2.vec(), tw2)
    rot_mat = get_stem_rotation_matrix(stem1, stem2, use_average_method)

    assert np.allclose(ftuv.normalize(stem2.vec()),
                       ftuv.normalize(np.dot(stem1.vec(), rot_mat)))
    rotate_chain(chains, rot_mat, (stem1.mids[0] + stem1.mids[1]) / 2.)
    translate_chain(chains, (stem2.mids[0] + stem2.mids[1]) / 2. -
                    (stem1.mids[0] + stem1.mids[1]) / 2.)

    assert _validate_pdb_to_stem(stem2, chains, cg, elem_name)
Example #6
0
    def verify_virtual_twist_angles(self, cg, s):
        sl = cg.stem_length(s)

        for i in range(0, sl):
            (pos, vec, vec_l, vec_r) = ftug.virtual_res_3d_pos_core(cg.coords[s],
                                                                    cg.twists[s],i,sl)

            if i > 1:
                self.assertGreater(ftuv.vec_angle(vec, prev_vec), 0.1)
                self.assertLess(ftuv.vec_angle(vec, prev_vec), 0.95)

            prev_vec = vec
Example #7
0
    def verify_virtual_twist_angles(self, cg, s):
        sl = cg.stem_length(s)

        for i in range(0, sl):
            (pos, vec, vec_l, vec_r) = ftug.virtual_res_3d_pos_core(cg.coords[s],
                                                                    cg.twists[s],i,sl)

            if i > 1:
                self.assertGreater(ftuv.vec_angle(vec, prev_vec), 0.53)
                self.assertLess(ftuv.vec_angle(vec, prev_vec), 0.73)

            prev_vec = vec
Example #8
0
    def add_stem_like_core(self,
                           rna_plotter,
                           coords,
                           twists,
                           stem_len,
                           text,
                           key,
                           color='green',
                           width=2.4):
        (p, n) = coords
        width *= self.cylinder_width
        rna_plotter.add_segment(p, n, color, width, text, key=key)

        if self.show_twists:
            rna_plotter.add_cone(p, n, 'white', width, key)
            mult = 8.
            width = .3
            (twist1o, twist2o) = twists

            rna_plotter.add_segment(p,
                                    p + mult * twist1o,
                                    "cyan",
                                    width,
                                    '',
                                    key=key)
            rna_plotter.add_segment(n,
                                    n + mult * twist2o,
                                    "magenta",
                                    width,
                                    '',
                                    key=key)

            for i in range(stem_len):
                res = ftug.virtual_res_3d_pos_core((p, n), twists, i, stem_len)
                (pos, vec_c, vec_l, vec_r) = res
                rna_plotter.add_segment(pos,
                                        pos + mult * vec_c,
                                        "orange",
                                        width,
                                        '',
                                        key=key)

                if self.add_letters:
                    rna_plotter.labels += [('L', list(pos + mult * vec_l))]
                    rna_plotter.labels += [('R', list(pos + mult * vec_r))]
Example #9
0
def get_relative_orientation(cg, l1, l2):
    '''
    Return how l1 is related to l2 in terms of three parameters. l2 should
    be the receptor of a potential A-Minor interaction, whereas l1 should
    be the donor.

        1. Distance between the closest points of the two elements
        2. The angle between l2 and the vector between the two
        3. The angle between the minor groove of l2 and the vector between
           l1 and l2
    '''
    (i1, i2) = ftuv.line_segment_distance(cg.coords[l1][0],
                                          cg.coords[l1][1],
                                          cg.coords[l2][0],
                                          cg.coords[l2][1])

    '''
    angle1 = ftuv.vec_angle(cg.coords[l2][1] - cg.coords[l2][0],
                           i2 - i1)
    '''
    angle1 = ftuv.vec_angle(cg.coords[l2][1] - cg.coords[l2][0],
                            cg.coords[l1][1] - cg.coords[l1][0])
    #fud.pv('angle1')

    tw = cg.get_twists(l2)

    if l2[0] != 's':
        angle2 = ftuv.vec_angle((tw[0] + tw[1]) / 2.,
                               i2 - i1)
    else:
        stem_len = cg.stem_length(l2)

        pos = ftuv.magnitude(i2 - cg.coords[l2][0]) / ftuv.magnitude(cg.coords[l2][1] - cg.coords[l2][0]) * stem_len
        vec = ftug.virtual_res_3d_pos_core(cg.coords[l2], cg.twists[l2], pos, stem_len)[1]
        angle2 = ftuv.vec_angle(vec,
                               i2 - i1)

    dist = ftug.element_distance(cg, l1, l2)

    return (dist, angle1, angle2)
Example #10
0
    def stem_atoms(self, coords, twists, stem_len, side=0):
        '''
        Add the locations of the virtual atoms as spheres.

        @param coords: The start and end coordinates of the stem.
        @param twists: The two twists of the stem.
        @param stem_len: The length of the stem.
        '''
        prev_p = [None, None]
        first_p = [None, None]
        last_o3 = [None, None]
        first_o3 = [None, None]

        colors = ['yellow', 'purple']

        for i in range(stem_len):
            vbasis = ftug.virtual_res_basis_core(coords, twists, i, stem_len)
            vpos = ftug.virtual_res_3d_pos_core(coords, twists, i, stem_len)

            # iterate once for each strand
            j = side
            # just use A for now
            for a in cua.avg_stem_vres_atom_coords[j]['A'].items():
                c = a[1]
                new_coords = np.dot(vbasis.transpose(), c) + vpos[0]
                #self.add_sphere(new_coords, colors[j], 0.3)

                if a[0] == 'P' and i == 0:
                    first_p[j] = new_coords
                if a[0] == 'P':
                    if prev_p[j] is not None:
                        self.add_segment(prev_p[j], new_coords,
                                         colors[j], 0.7)
                    prev_p[j] = new_coords
                if a[0] == 'O3*' and i == 0:
                    first_o3[j] = new_coords
                if a[0] == 'O3*':
                    last_o3[j] = new_coords
Example #11
0
def get_relative_orientation(cg, loop, stem):
    '''
    Return how loop is related to stem in terms of three parameters.

    The stem is the receptor of a potential A-Minor interaction, whereas the
    loop is the donor.

    The 3 parameters are:

        1.  Distance between the closest points of the two elements
        2.  The angle between the stem and the vector between the two
        3.  The angle between the minor groove of l2 and the projection of
            the vector between stem and loop onto the plane normal to the stem
            direction.
    '''
    point_on_stem, point_on_loop = ftuv.line_segment_distance(
        cg.coords[stem][0], cg.coords[stem][1], cg.coords[loop][0],
        cg.coords[loop][1])
    conn_vec = point_on_loop - point_on_stem
    dist = ftuv.magnitude(conn_vec)
    angle1 = ftuv.vec_angle(cg.coords.get_direction(stem), conn_vec)
    # The direction of the stem vector is irrelevant, so
    # choose the smaller of the two angles between two lines
    if angle1 > np.pi / 2:
        angle1 = np.pi - angle1
    tw = cg.get_twists(stem)
    if dist == 0:
        angle2 = float("nan")
    else:
        if stem[0] != 's':
            raise ValueError(
                "The receptor needs to be a stem, not {}".format(stem))
        else:
            stem_len = cg.stem_length(stem)
            # Where along the helix our A-residue points to the minor groove.
            # This can be between residues. We express it as floating point nucleotide coordinates.
            # So 0.0 means at the first basepair, while 1.5 means between the second and the third basepair.
            pos = ftuv.magnitude(
                point_on_stem - cg.coords[stem][0]) / ftuv.magnitude(
                    cg.coords.get_direction(stem)) * (stem_len - 1)
            # The vector pointing to the minor groove, even if we are not at a virtual residue (pos is a float value)
            virt_twist = ftug.virtual_res_3d_pos_core(cg.coords[stem],
                                                      cg.twists[stem], pos,
                                                      stem_len)[1]
            # The projection of the connection vector onto the plane normal to the stem
            conn_proj = ftuv.vector_rejection(conn_vec,
                                              cg.coords.get_direction(stem))
            try:
                # Note: here the directions of both vectors are well defined,
                # so angles >90 degrees make sense.
                angle2 = ftuv.vec_angle(virt_twist, conn_proj)
            except ValueError:
                if np.all(virt_twist == 0):
                    angle2 = float("nan")
                else:
                    raise
            # Furthermore, the direction of the second angle is meaningful.
            # We call use a positive angle, if the cross-product of the two vectors
            # has the same sign as the stem vector and a negative angle otherwise
            cr = np.cross(virt_twist, conn_proj)
            sign = ftuv.is_almost_parallel(cr, cg.coords.get_direction(stem))
            #assert sign != 0, "{} vs {} not (anti) parallel".format(
            #    cr, cg.coords.get_direction(stem))
            angle2 *= sign

    return dist, angle1, angle2
Example #12
0
def get_relative_orientation(cg, loop, stem):
    '''
    Return how loop is related to stem in terms of three parameters.

    The stem is the receptor of a potential A-Minor interaction, whereas the
    loop is the donor.

    The 3 parameters are:

        1.  Distance between the closest points of the two elements
        2.  The angle between the stem and the vector between the two
        3.  The angle between the minor groove of l2 and the projection of
            the vector between stem and loop onto the plane normal to the stem
            direction.
    '''
    point_on_stem, point_on_loop = ftuv.line_segment_distance(cg.coords[stem][0],
                                                              cg.coords[stem][1],
                                                              cg.coords[loop][0],
                                                              cg.coords[loop][1])
    conn_vec = point_on_loop - point_on_stem
    dist = ftuv.magnitude(conn_vec)
    angle1 = ftuv.vec_angle(cg.coords.get_direction(stem),
                            conn_vec)
    # The direction of the stem vector is irrelevant, so
    # choose the smaller of the two angles between two lines
    if angle1 > np.pi / 2:
        angle1 = np.pi - angle1
    tw = cg.get_twists(stem)
    if dist == 0:
        angle2 = float("nan")
    else:
        if stem[0] != 's':
            raise ValueError(
                "The receptor needs to be a stem, not {}".format(stem))
        else:
            stem_len = cg.stem_length(stem)
            # Where along the helix our A-residue points to the minor groove.
            # This can be between residues. We express it as floating point nucleotide coordinates.
            # So 0.0 means at the first basepair, while 1.5 means between the second and the third basepair.
            pos = ftuv.magnitude(point_on_stem - cg.coords[stem][0]) / ftuv.magnitude(
                cg.coords.get_direction(stem)) * (stem_len - 1)
            # The vector pointing to the minor groove, even if we are not at a virtual residue (pos is a float value)
            virt_twist = ftug.virtual_res_3d_pos_core(
                cg.coords[stem], cg.twists[stem], pos, stem_len)[1]
            # The projection of the connection vector onto the plane normal to the stem
            conn_proj = ftuv.vector_rejection(
                conn_vec, cg.coords.get_direction(stem))
            try:
                # Note: here the directions of both vectors are well defined,
                # so angles >90 degrees make sense.
                angle2 = ftuv.vec_angle(virt_twist, conn_proj)
            except ValueError:
                if np.all(virt_twist == 0):
                    angle2 = float("nan")
                else:
                    raise
            # Furthermore, the direction of the second angle is meaningful.
            # We call use a positive angle, if the cross-product of the two vectors
            # has the same sign as the stem vector and a negative angle otherwise
            cr = np.cross(virt_twist, conn_proj)
            sign = ftuv.is_almost_parallel(cr,  cg.coords.get_direction(stem))
            #assert sign != 0, "{} vs {} not (anti) parallel".format(
            #    cr, cg.coords.get_direction(stem))
            angle2 *= sign

    return dist, angle1, angle2