Beispiel #1
0
def main(args):
    cg = ftmc.CoarseGrainRNA(args.rna)
    for stem in cg.stem_iterator():
        stem_vec = cg.coords.get_direction(stem)
        twist_vec = cg.twists[stem][0]
        try:
            ftuv.create_orthonormal_basis(stem_vec, twist_vec)
        except AssertionError:
            cg.twists[stem] = ftuv.vector_rejection(twist_vec, stem_vec), cg.twists[stem][1]
        twist_vec = cg.twists[stem][1]
        try:
            ftuv.create_orthonormal_basis(stem_vec, twist_vec)
        except AssertionError:
            cg.twists[stem] = cg.twists[stem][0], ftuv.vector_rejection(twist_vec, stem_vec)
    try:
        cg.add_all_virtual_residues()
    except:
        assert False
    print(cg.to_cg_string())
Beispiel #2
0
def main(args):
    cg = ftmc.CoarseGrainRNA.from_bg_file(args.rna)
    for stem in cg.stem_iterator():
        stem_vec = cg.coords.get_direction(stem)
        twist_vec = cg.twists[stem][0]
        try:
            ftuv.create_orthonormal_basis(stem_vec, twist_vec)
        except AssertionError:
            cg.twists[stem] = ftuv.vector_rejection(
                twist_vec, stem_vec), cg.twists[stem][1]
        twist_vec = cg.twists[stem][1]
        try:
            ftuv.create_orthonormal_basis(stem_vec, twist_vec)
        except AssertionError:
            cg.twists[stem] = cg.twists[stem][0], ftuv.vector_rejection(
                twist_vec, stem_vec)
    try:
        cg.add_all_virtual_residues()
    except:
        assert False
    print(cg.to_cg_string())
Beispiel #3
0
    def get_twists(self, node):
        ''' 
        Get the array of twists for this node. If the node is a stem,
        then the twists will simply those stored in the array. 
        If the node is an interior loop or a junction segment, 
        then the twists will be the ones that are adjacent to it. 
        If the node is a hairpin loop or a free end, then the same twist
        will be duplicated and returned twice.

        @param node: The name of the node
        '''                                                                                                           
        if node[0] == 's':
            return self.twists[node]                                                                                  

        connections = list(self.edges[node])
        (s1b, s1e) = self.get_sides(connections[0], node)

        if len(connections) == 1:
            vec = ftuv.normalize(ftuv.vector_rejection( 
                                  self.twists[connections[0]][s1b],
                                  self.coords[connections[0]][1] -  
                                  self.coords[connections[0]][0]))
            return (vec,vec)                                                  

        if len(connections) == 2: 
            # interior loop or junction segment                                                                  
            (s2b, s2e) = self.get_sides(connections[1], node) 
            bulge_vec = (self.coords[connections[0]][s1b] - 
                         self.coords[connections[1]][s2b])                                                            
            return (ftuv.normalize(ftuv.vector_rejection( 
                    self.twists[connections[0]][s1b], bulge_vec)),
                    ftuv.normalize(ftuv.vector_rejection(self.twists[connections[1]][s2b], bulge_vec)))  

        # uh oh, this shouldn't happen since every node                 
        # should have either one or two edges 
        return None                                                                                                   
Beispiel #4
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
Beispiel #5
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
Beispiel #6
0
    def coordinates_to_pymol(self, cg):
        loops = list(cg.hloop_iterator())

        for key in cg.coords.keys():
            if self.constraints is not None:
                if key not in self.constraints:
                    continue

            (p, n) = cg.coords[key]
            color = self.get_element_color(key)

            if key[0] == 's':
                self.add_stem_like(cg, key)
                self.draw_bounding_boxes(cg, key)
            else:
                if key[0] == 'h':
                    if self.add_loops:
                        if key in loops:
                            self.add_segment(p, n, color, 1.0,
                                             key + " " + str(cg.get_length(key)))
                elif key[0] == 'm':
                    twists = cg.get_twists(key)

                    # check if the multiloop is longer than one. If it's not, then
                    # it has an empty define and we its length will be 1
                    if len(cg.defines[key]) == 0:
                        self.add_segment(p, n, color, 1.0,
                                         key + " 1")
                    else:
                        self.add_segment(p, n, color, 1.0,
                                         key + " " +
                                         str(cg.defines[key][1] -
                                         cg.defines[key][0] + 1))

                    self.add_segment(p, p+ 7 * twists[0], 'light gray', 0.3)
                    self.add_segment(n, n+ 7 * twists[1], 'light gray', 0.3)

                    x = (p + n) / 2
                    t = ftuv.normalize((twists[0] + twists[1]) / 2.)
                    self.add_segment(x, x + 7 * t, 'middle gray', 0.3)
                elif key[0] == 'f':
                    if self.visualize_three_and_five_prime:
                        self.add_segment(p, n, color, 1.0,
                                         key + " " +
                                         str(cg.defines[key][1] -
                                         cg.defines[key][0] + 1) + "")

                elif key[0] == 't':
                    if self.visualize_three_and_five_prime:
                        self.add_segment(p, n, color, 1.0,
                                         key + " " +
                                         str(cg.defines[key][1] -
                                         cg.defines[key][0]) + "")
                else:
                    #self.add_stem_like(cg, key, "yellow", 1.0)
                    self.add_segment(p, n, color, 1.0, key)

        if self.add_longrange:
            for key1 in cg.longrange.keys():
                for key2 in cg.longrange[key1]:
                    try:

                        p = cuv.line_segment_distance(cg.coords[key1][0],
                                                      cg.coords[key1][1],
                                                      cg.coords[key2][0],
                                                      cg.coords[key2][1])
                        (point1, point2) = p

                        #point1 = cg.get_point(key1)
                        #point2 = cg.get_point(key2)

                        dash_length = 0.6
                        gap_length = dash_length * 2
                        direction = ftuv.normalize(point2 - point1)

                        num_dashes = ftuv.magnitude(point2 - point1) / (dash_length + gap_length)
                        fud.pv('num_dashes')

                        for i in range(int(num_dashes)):
                            self.add_segment(point1 + i * (dash_length + gap_length) * direction, 
                                             point1 + (i * (dash_length + gap_length) + dash_length) * direction, "purple",
                                             0.3, "")

                            '''
                            self.add_segment(point1, point2, "purple",
                                             0.3, key1 + " " + key2)
                            
                            '''
                    except:
                        continue

        if self.encompassing_stems:
            self.add_encompassing_cylinders(cg, 7.)

        if self.max_stem_distances > 0:
            for (s1, s2) in it.permutations(cg.stem_iterator(), r=2):
                (i1, i2) = cuv.line_segment_distance(cg.coords[s1][0],
                                                     cg.coords[s1][1],
                                                     cg.coords[s2][0],
                                                     cg.coords[s2][1])
                if cuv.magnitude(i2 - i1) < self.max_stem_distances:
                    #self.add_segment(i1, i2, 'cyan', 0.3, s1 + " " + s2)
                    self.add_segment(i1, i2, 'cyan', 0.3)

        if self.virtual_atoms:
            va = ftug.virtual_atoms(cg, sidechain=False)

            atom_width = 0.5
            for i,r in enumerate(sorted(va.keys())):
                for a in va[r].keys():
                    if self.rainbow:
                        import matplotlib
                        matplotlib.use('Agg')
                        import matplotlib.pyplot as plt
                        cmap = plt.get_cmap('gist_rainbow')
                        self.add_sphere(va[r][a], 
                                        color_rgb = cmap(i / float(len(va.keys()))), 
                                        width=atom_width)
                    else:
                        d = cg.get_node_from_residue_num(r)
                        if d[0] == 's':
                            self.add_sphere(va[r][a], 'green', width=atom_width)
                        elif d[0] == 'i':
                            self.add_sphere(va[r][a], 'yellow', width=atom_width)
                        elif d[0] == 'm':
                            self.add_sphere(va[r][a], 'red', width=atom_width)
                        elif d[0] == 'h':
                            self.add_sphere(va[r][a], 'blue', width=atom_width)

        if self.basis:
            for d in cg.defines.keys():
                origin, basis = ftug.element_coord_system(cg, d)

                self.add_segment(origin, origin + 7. * basis[1], 'purple', 2.)

        print >>sys.stderr, "energy_function:", self.energy_function
        # print the contributions of the energy function, if one is specified
        if self.energy_function is not None:
            print >>sys.stderr, "key"
            sum_energy = 0.

            e_func = self.energy_function
            e_func_iter = e_func.interaction_energy_iter(cg, background=False)
            int_energies = list(e_func_iter)
            max_energy = max(int_energies, key=lambda x: x[1])
            print >>sys.stderr, "max_energy:", max_energy

            for (interaction, energy) in int_energies:
                (p, n) = (cg.get_point(interaction[0]),
                          cg.get_point(interaction[1]))
                scaled_energy = - max_energy[1] + energy

                self.add_segment(p, n, 'purple', 3 * np.exp(scaled_energy))

                sum_energy += energy

        if self.stem_stem_orientations is not None:
            for (s1, s2) in it.permutations(cg.stem_iterator(), 2):
                '''
                if cg.are_adjacent_stems(s1, s2):
                    continue
                '''

                if s1 != 's65':
                    if s2 != 's65':
                        continue

                s1_vec = cg.coords[s1][1] - cg.coords[s1][0]
                s2_vec = cg.coords[s2][1] - cg.coords[s2][0]
                (i1, i2) = cuv.line_segment_distance(cg.coords[s1][0],
                                                     cg.coords[s1][1],
                                                     cg.coords[s2][0],
                                                     cg.coords[s2][1])
                i_vec = i2 - i1

                #i_rej will be orthogonal to s1_vec in the direction
                #of s2
                i_rej = cuv.vector_rejection(i_vec, s1_vec)

                #plane_vec will be orthogonal to s1_vec and to the direction
                # of s2
                plane_vec = np.cross(i_rej, s1_vec)

                # s2_proj is in the intersection plane
                s2_proj_in = cuv.vector_rejection(s2_vec, plane_vec)
                # s2 proj_out is out of the intersection plane
                #s2_proj_out = cuv.vector_rejection(s2_vec, i_rej)

                start_point = cg.coords[s1][0] + 5 * cg.twists[s1][0]
                ortho_offset = cuv.magnitude(i_rej)
                dist = cuv.magnitude(i_vec) + 0.0001

                lateral_offset = m.sqrt(dist ** 2 - ortho_offset ** 2)

                if lateral_offset > 10:
                    continue

                '''
                #self.add_segment(start_point,
                                  start_point + 10 * cuv.normalize(s2_vec),
                                  'white', 0.5)
                #self.add_segment(start_point,
                                  start_point + 5 * cuv.normalize(plane_vec),
                                  'magenta', 0.5)
                #self.add_segment(start_point,
                                  start_point + 5 * cuv.normalize(i_vec),
                                  'cyan', 0.5)
                #self.add_segment(i1, i1 + i_rej,  'cyan', 0.5)
                '''
                self.add_segment(start_point,
                                 start_point + 7 * cuv.normalize(s2_proj_in),
                                 'white', 1.5)
                '''