def test_line_segment_distance_parallel(self): a0 = np.array([0., 0., 1.]) a1 = np.array([0., 0., 10.]) b0 = np.array([0., 0., 11.]) b1 = np.array([0., 0., 20.]) self.assertAlmostEqual( ftuv.vec_distance(*ftuv.line_segment_distance(a0, a1, b0, b1)), 1.)
def test_line_segment_distance_point_to_line(self): a0 = np.array([0., 0., 1.]) a1 = np.array([0., 0., 10.]) b0 = np.array([0., -10., 12.]) b1 = np.array([0., 10., 12.]) self.assertAlmostEqual( ftuv.vec_distance(*ftuv.line_segment_distance(a0, a1, b0, b1)), 2.)
def test_line_segment_distance_windschief(self): a0 = np.array([0., 0., -10.]) a1 = np.array([0., 0., 10.]) b0 = np.array([5.2, -10., 5.]) b1 = np.array([5.2, 10., 5.]) self.assertAlmostEqual(ftuv.vec_distance( *ftuv.line_segment_distance(a0, a1, b0, b1)), 5.2)
def test_line_segment_distance_real_world(self): a0 = np.array([0., 0., 1.]) a1 = np.array([-2.76245752, -6.86976093, 7.54094508]) b0 = np.array([-27.57744115, 6.96488989, -22.47619655]) b1 = np.array([-16.93424799, -4.0631445, -16.19822301]) self.assertLess(ftuv.vec_distance( *ftuv.line_segment_distance(a0, a1, b0, b1)), 25)
def test_line_segment_distance_point_to_line(self): a0 = np.array([0., 0., 1.]) a1 = np.array([0., 0., 10.]) b0 = np.array([0., -10., 12.]) b1 = np.array([0., 10., 12.]) self.assertAlmostEqual(ftuv.vec_distance( *ftuv.line_segment_distance(a0, a1, b0, b1)), 2.)
def test_line_segment_distance_parallel(self): a0 = np.array([0., 0., 1.]) a1 = np.array([0., 0., 10.]) b0 = np.array([0., 0., 11.]) b1 = np.array([0., 0., 20.]) self.assertAlmostEqual(ftuv.vec_distance( *ftuv.line_segment_distance(a0, a1, b0, b1)), 1.)
def test_line_segment_distance_real_world(self): a0 = np.array([0., 0., 1.]) a1 = np.array([-2.76245752, -6.86976093, 7.54094508]) b0 = np.array([-27.57744115, 6.96488989, -22.47619655]) b1 = np.array([-16.93424799, -4.0631445, -16.19822301]) self.assertLess( ftuv.vec_distance(*ftuv.line_segment_distance(a0, a1, b0, b1)), 25)
def test_line_segment_distance_windschief(self): a0 = np.array([0., 0., -10.]) a1 = np.array([0., 0., 10.]) b0 = np.array([5.2, -10., 5.]) b1 = np.array([5.2, 10., 5.]) self.assertAlmostEqual( ftuv.vec_distance(*ftuv.line_segment_distance(a0, a1, b0, b1)), 5.2)
def output_all_distances(bg): for (key1, key2) in it.permutations(bg.defines.keys(), 2): if bg.has_connection(key1, key2): continue longrange = "N" if key2 in bg.longrange[key1]: longrange = "Y" #point1 = bg.get_point(key1) #point2 = bg.get_point(key2) try: (i1,i2) = cuv.line_segment_distance(bg.coords[key1][0], bg.coords[key1][1], bg.coords[key2][0], bg.coords[key2][1]) if abs(cuv.magnitude(i2 - i1)) < 0.000001: continue vec1 = bg.coords[key1][1] - bg.coords[key1][0] ''' basis = cuv.create_orthonormal_basis(vec1) coords2 = cuv.change_basis(i2 - i1, basis, cuv.standard_basis) (r, u, v) = cuv.spherical_cartesian_to_polar(coords2) ''' v = cuv.vec_angle(vec1, i2 - i1) except KeyError as ke: #print >>sys.stderr, 'Skipping %s or %s.' % (key1, key2) continue seq1 = 'x' seq2 = 'x' ''' receptor_angle = 0. if bg.get_type(key1) != 's' and bg.get_type(key1) != 'i' and bg.get_length(key1) > 1: seq1 = bg.get_seq(key1) if bg.get_type(key2) != 's' and bg.get_type(key2) != 'i'and bg.get_length(key2) > 1: seq2 = bg.get_seq(key2) if bg.get_type(key1) == 'l' and bg.get_type(key2) == 's': receptor_angle = cgg.receptor_angle(bg, key1, key2) ''' print "%s %s %d %s %s %d %f %s %s %s %f" % (key1, key1[0], bg.get_length(key1), key2, key2[0], bg.get_length(key2), cuv.magnitude(i2-i1), seq1, seq2, longrange, v)
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)
def output_long_range_distances(bg): for key1 in bg.longrange.keys(): for key2 in bg.longrange[key1]: if bg.has_connection(key1, key2): continue #point1 = bg.get_point(key1) #point2 = bg.get_point(key2) (i1,i2) = cuv.line_segment_distance(bg.coords[key1][0], bg.coords[key1][1], bg.coords[key2][0], bg.coords[key2][1]) vec1 = bg.coords[key1][1] - bg.coords[key2][0] basis = cuv.create_orthonormal_basis(vec1) coords2 = cuv.change_basis(i2 - i1, basis, cuv.standard_basis) (r, u, v) = cuv.spherical_polar_to_cartesian(coords2) seq1 = 'x' seq2 = 'x' ''' if key1[0] != 's' and key[0] != 'i': seq1 = bg.get_seq(key1) if key2[0] != 's' and key2[0] != 'i': seq2 = bg.get_seq(key2) ''' print "%s %s %d %s %s %d %f %s %s %s %f" % (key1, key1[0], bg.get_length(key1), key2, key2[0], bg.get_length(key2), cuv.magnitude(i2-i1), seq1, seq2, "Y", v)
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
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
def add_cg(self, cg, labels, color_modifier=1.0): """ :param labels: A dictionary with element names as keys and labels as values. """ rna_plotter = PyMolRNA(cg.name, color_modifier) for key in cg.coords.keys(): if self.only_elements is not None: if key not in self.only_elements: continue (p, n) = cg.coords[key] color = self.get_element_color(key) if key[0] == 's': try: text = labels[key] except KeyError: text = key self.add_stem_like(rna_plotter, cg, text, key, color=color) if self.show_bounding_boxes: self.draw_bounding_boxes(rna_plotter, cg, key) else: if key[0] == 'h': if self.add_loops: try: text = labels[key] except KeyError: text = key + " " + str(cg.get_length(key)) rna_plotter.add_segment(p, n, color, self.cylinder_width, text, key=key) elif key[0] == 'm': twists = cg.get_twists(key) try: text = labels[key] except KeyError: # check if the multiloop is longer than one. If it's not, then # it has an empty define and its length will be 0 if len(cg.defines[key]) == 0: text = key + " 0" else: text = key + " " + \ str(cg.defines[key][1] - cg.defines[key][0] + 1) rna_plotter.add_segment(p, n, color, self.cylinder_width, text, key=key) elif key[0] in 'ft': try: text = labels[key] except KeyError: text = key + " " + \ str(cg.defines[key][1] - cg.defines[key][0] + 1) if self.visualize_three_and_five_prime: rna_plotter.add_segment(p, n, color, self.cylinder_width, text, key=key) elif key[0] == "i": try: text = labels[key] except KeyError: text = key rna_plotter.add_segment( p, n, color, self.cylinder_width, text, key=key) if self.display_virtual_residues: for i in range(1, cg.seq_length + 1): pos = cg.get_virtual_residue(i, True) if cg.get_node_from_residue_num(i)[0] == "s": c = "cyan" else: c = "magenta" rna_plotter.add_sphere(pos, c, 1.) if self.add_longrange: for key1 in cg.longrange.keys(): for key2 in cg.longrange[key1]: if self.only_elements is not None: if key1 not in self.only_elements or key2 not in self.only_elements: continue try: p = cuv.line_segment_distance(cg.coords[key1][0], cg.coords[key1][1], cg.coords[key2][0], cg.coords[key2][1]) rna_plotter.add_dashed(p[0], p[1]) except: continue if self.encompassing_stems: self.add_encompassing_cylinders(rna_plotter, 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, key=key) rna_plotter.add_segment(i1, i2, 'cyan', 0.3, key=key) if self.virtual_atoms or self.sidechain_atoms: cg.add_all_virtual_residues() va = ftug.virtual_atoms(cg, sidechain=self.sidechain_atoms) 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') rna_plotter.add_sphere(va[r][a], color=cmap( i / float(len(va.keys()))), width=atom_width) else: d = cg.get_node_from_residue_num(r) if d[0] == 's': if a in ftup.nonsidechain_atoms: rna_plotter.add_sphere( va[r][a], self.stem_color, width=atom_width) else: rna_plotter.add_sphere( va[r][a], 'forest', width=atom_width) elif d[0] == 'i': rna_plotter.add_sphere( va[r][a], 'yellow', width=atom_width) elif d[0] == 'm': rna_plotter.add_sphere( va[r][a], self.multiloop_color, width=atom_width) elif d[0] == 'h': rna_plotter.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) rna_plotter.add_segment( origin, origin + 7. * basis[1], 'purple', 0.5, key=key) self.plotters.append(rna_plotter)
def add_cg(self, cg, labels, color_modifier=1.0): """ :param labels: A dictionary with element names as keys and labels as values. """ rna_plotter = PyMolRNA(cg.name, color_modifier) for key in cg.coords.keys(): if self.only_elements is not None: if key not in self.only_elements: continue (p, n) = cg.coords[key] color = self.get_element_color(key) if key[0] == 's': try: text = labels[key] except KeyError: text = key self.add_stem_like(rna_plotter, cg, text, key, color=color) if self.show_bounding_boxes: self.draw_bounding_boxes(rna_plotter, cg, key) else: if key[0] == 'h': if self.add_loops: try: text = labels[key] except KeyError: text = key + " " + str(cg.get_length(key)) rna_plotter.add_segment(p, n, color, self.cylinder_width, text, key=key) elif key[0] == 'm': twists = cg.get_twists(key) try: text = labels[key] except KeyError: # check if the multiloop is longer than one. If it's not, then # it has an empty define and its length will be 0 if len(cg.defines[key]) == 0: text = key + " 0" else: text = key + " " + \ str(cg.defines[key][1] - cg.defines[key][0] + 1) rna_plotter.add_segment(p, n, color, self.cylinder_width, text, key=key) elif key[0] in 'ft': try: text = labels[key] except KeyError: text = key + " " + \ str(cg.defines[key][1] - cg.defines[key][0] + 1) if self.visualize_three_and_five_prime: rna_plotter.add_segment(p, n, color, self.cylinder_width, text, key=key) elif key[0] == "i": try: text = labels[key] except KeyError: text = key rna_plotter.add_segment(p, n, color, self.cylinder_width, text, key=key) if self.display_virtual_residues: for i in range(1, cg.seq_length + 1): pos = cg.get_virtual_residue(i, True) if cg.get_node_from_residue_num(i)[0] == "s": c = "cyan" else: c = "magenta" rna_plotter.add_sphere(pos, c, 1.) if self.add_longrange: for key1 in cg.longrange.keys(): for key2 in cg.longrange[key1]: if self.only_elements is not None: if key1 not in self.only_elements or key2 not in self.only_elements: continue try: p = cuv.line_segment_distance(cg.coords[key1][0], cg.coords[key1][1], cg.coords[key2][0], cg.coords[key2][1]) rna_plotter.add_dashed(p[0], p[1]) except: continue if self.encompassing_stems: self.add_encompassing_cylinders(rna_plotter, 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, key=key) rna_plotter.add_segment(i1, i2, 'cyan', 0.3, key=key) if self.virtual_atoms or self.sidechain_atoms: cg.add_all_virtual_residues() va = ftug.virtual_atoms(cg, sidechain=self.sidechain_atoms) 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') rna_plotter.add_sphere(va[r][a], color=cmap( i / float(len(va.keys()))), width=atom_width) else: d = cg.get_node_from_residue_num(r) if d[0] == 's': if a in ftup.nonsidechain_atoms: rna_plotter.add_sphere(va[r][a], self.stem_color, width=atom_width) else: rna_plotter.add_sphere(va[r][a], 'forest', width=atom_width) elif d[0] == 'i': rna_plotter.add_sphere(va[r][a], 'yellow', width=atom_width) elif d[0] == 'm': rna_plotter.add_sphere(va[r][a], self.multiloop_color, width=atom_width) elif d[0] == 'h': rna_plotter.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) rna_plotter.add_segment(origin, origin + 7. * basis[1], 'purple', 0.5, key=key) self.plotters.append(rna_plotter)
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) '''
def describe_ml_segments(cg): data = defaultdict(list) loops = cg.find_mlonly_multiloops() for loop in it.chain(loops, [[i] for i in cg.iloop_iterator()]): print(loop) if loop[0][0] == "i": description = ["interior_loop"] else: description = cg.describe_multiloop(loop) try: j3_roles = cg._assign_loop_roles(loop) except ValueError: j3_roles = None if j3_roles: j3_familyFlat = cg._junction_family_westhof1(j3_roles) j3_family3D = cg._junction_family_3d(j3_roles) j3_familyPerp = cg._junction_family_is_perpenticular(j3_roles) j3_Delta = cg.get_length(j3_roles["J23"]) - cg.get_length( j3_roles["J31"]) else: j3_family3D = None j3_familyFlat = None j3_familyPerp = None j3_Delta = None loop_start = float("inf") for segment in loop: if cg.define_a(segment)[0] < loop_start: loop_start = cg.define_a(segment)[0] for segment in loop: if segment[0] not in "mi": continue data["loop_start_after"].append(loop_start) data["segment_start_after"].append(cg.define_a(segment)[0]) data["segment"].append(segment) data["junction_length"].append(len(loop)) data["segment_length"].append(cg.get_length(segment)) if segment[0] == "i": dims = list(sorted(cg.get_bulge_dimensions(segment))) else: dims = [-1, -1] data["iloop_length_1"].append(dims[0]) data["iloop_length_2"].append(dims[1]) data["loops_largest_segment_length"].append( max(cg.get_length(x) for x in loop)) data["loops_shortest_segment_length"].append( min(cg.get_length(x) for x in loop)) data["sum_of_loops_segment_lengths"].append( sum(cg.get_length(x) for x in loop)) data["loop_segment_lengths"].append(",".join( map(str, sorted(cg.get_length(x) for x in loop)))) data["angle_type"].append( abs(cg.get_angle_type(segment, allow_broken=True))) s1, s2 = cg.connections(segment) vec1 = cg.coords.get_direction(s1) if cg.get_sides(s1, segment) == (1, 0): vec1 = -vec1 else: assert cg.get_sides(s1, segment) == (0, 1) vec2 = cg.coords.get_direction(s2) if cg.get_sides(s2, segment) == (1, 0): vec2 = -vec2 else: assert cg.get_sides(s2, segment) == (0, 1) data["angle_between_stems"].append(ftuv.vec_angle(vec1, vec2)) data["offset1"].append( ftuv.point_line_distance( cg.coords[s1][cg.get_sides(s1, segment)[0]], cg.coords[s2][0], cg.coords.get_direction(s2))) data["offset2"].append( ftuv.point_line_distance( cg.coords[s2][cg.get_sides(s2, segment)[0]], cg.coords[s1][0], cg.coords.get_direction(s1))) closer1, far1 = cg.coords[s1][cg.get_sides( s1, segment)[0]], cg.coords[s1][cg.get_sides(s1, segment)[1]] closer2, far2 = cg.coords[s2][cg.get_sides( s2, segment)[0]], cg.coords[s2][cg.get_sides(s2, segment)[1]] data["offset"].append( ftuv.vec_distance(*ftuv.line_segment_distance( closer1, closer1 + (closer1 - far1) * 100000, closer2, closer2 + (closer2 - far2) * 100000))) data["junction_va_distance"].append( ftug.junction_virtual_atom_distance(cg, segment)) data["is_external_multiloop"].append("open" in description) data["is_pseudoknotted_multiloop"].append( "pseudoknot" in description) data["is_regular_multiloop"].append( "regular_multiloop" in description) data["is_interior_loop"].append("interior_loop" in description) if j3_roles is not None: elem_role, = [ x[0] for x in j3_roles.items() if x[1] == segment ] else: elem_role = "?" data["j3_role"].append(elem_role) data["j3_familyFlat"].append(j3_familyFlat) data["j3_family3D"].append(j3_family3D) data["j3_familyPerp"].append(j3_familyPerp) data["j3_Delta_j23_j31"].append(j3_Delta) dssr_stacking = False if "dssr_stacks" in cg.infos: if segment in cg.infos["dssr_stacks"]: dssr_stacking = True data["dssr_stacking"].append(dssr_stacking) kh_stem_angle = float("nan") if abs(cg.get_angle_type(segment, allow_broken=True)) == 5: next_ml = cg.get_next_ml_segment(segment) if isinstance(next_ml, str) and next_ml[0] == "m" and abs( cg.get_angle_type(next_ml, allow_broken=True)) == 5: stems1 = cg.edges[segment] stems2 = cg.edges[next_ml] try: s1, s2 = (stems1 | stems2) - (stems1 & stems2) except ValueError: pass else: vec1 = cg.coords.get_direction(s1) vec2 = cg.coords.get_direction(s2) angle = ftuv.vec_angle(vec1, vec2) if angle > math.pi / 2: angle = math.pi - angle kh_stem_angle = angle data["kh_stem_angle"].append(kh_stem_angle) if data: data["pk_number"] = number_by(data, "loop_start_after", "is_pseudoknotted_multiloop") data["loop_number"] = number_by(data, "loop_start_after", None) data["reguler_multiloop_number"] = number_by(data, "loop_start_after", "is_regular_multiloop") return data
def describe_ml_segments(cg): data = defaultdict(list) loops = cg.find_mlonly_multiloops() for loop in it.chain(loops, [[i] for i in cg.iloop_iterator()]): print(loop) if loop[0][0] == "i": description = ["interior_loop"] else: description = cg.describe_multiloop(loop) try: j3_roles = cg._assign_loop_roles(loop) except ValueError: j3_roles = None if j3_roles: j3_familyFlat = cg._junction_family_westhof1(j3_roles) j3_family3D = cg._junction_family_3d(j3_roles) j3_familyPerp = cg._junction_family_is_perpenticular(j3_roles) j3_Delta = cg.get_length( j3_roles["J23"]) - cg.get_length(j3_roles["J31"]) else: j3_family3D = None j3_familyFlat = None j3_familyPerp = None j3_Delta = None loop_start = float("inf") for segment in loop: if cg.define_a(segment)[0] < loop_start: loop_start = cg.define_a(segment)[0] for segment in loop: if segment[0] not in "mi": continue data["loop_start_after"].append(loop_start) data["segment_start_after"].append(cg.define_a(segment)[0]) data["segment"].append(segment) data["junction_length"].append(len(loop)) data["segment_length"].append(cg.get_length(segment)) if segment[0] == "i": dims = list(sorted(cg.get_bulge_dimensions(segment))) else: dims = [-1, -1] data["iloop_length_1"].append(dims[0]) data["iloop_length_2"].append(dims[1]) data["loops_largest_segment_length"].append( max(cg.get_length(x) for x in loop)) data["loops_shortest_segment_length"].append( min(cg.get_length(x) for x in loop)) data["sum_of_loops_segment_lengths"].append( sum(cg.get_length(x) for x in loop)) data["loop_segment_lengths"].append( ",".join(map(str, sorted(cg.get_length(x) for x in loop)))) data["angle_type"].append( abs(cg.get_angle_type(segment, allow_broken=True))) s1, s2 = cg.connections(segment) vec1 = cg.coords.get_direction(s1) if cg.get_sides(s1, segment) == (1, 0): vec1 = -vec1 else: assert cg.get_sides(s1, segment) == (0, 1) vec2 = cg.coords.get_direction(s2) if cg.get_sides(s2, segment) == (1, 0): vec2 = -vec2 else: assert cg.get_sides(s2, segment) == (0, 1) data["angle_between_stems"].append(ftuv.vec_angle(vec1, vec2)) data["offset1"].append(ftuv.point_line_distance(cg.coords[s1][cg.get_sides(s1, segment)[0]], cg.coords[s2][0], cg.coords.get_direction( s2) )) data["offset2"].append(ftuv.point_line_distance(cg.coords[s2][cg.get_sides(s2, segment)[0]], cg.coords[s1][0], cg.coords.get_direction( s1) )) closer1, far1 = cg.coords[s1][cg.get_sides( s1, segment)[0]], cg.coords[s1][cg.get_sides(s1, segment)[1]] closer2, far2 = cg.coords[s2][cg.get_sides( s2, segment)[0]], cg.coords[s2][cg.get_sides(s2, segment)[1]] data["offset"].append(ftuv.vec_distance(*ftuv.line_segment_distance(closer1, closer1 + (closer1 - far1) * 100000, closer2, closer2 + (closer2 - far2) * 100000))) data["junction_va_distance"].append( ftug.junction_virtual_atom_distance(cg, segment)) data["is_external_multiloop"].append("open" in description) data["is_pseudoknotted_multiloop"].append( "pseudoknot" in description) data["is_regular_multiloop"].append( "regular_multiloop" in description) data["is_interior_loop"].append("interior_loop" in description) if j3_roles is not None: elem_role, = [x[0] for x in j3_roles.items() if x[1] == segment] else: elem_role = "?" data["j3_role"].append(elem_role) data["j3_familyFlat"].append(j3_familyFlat) data["j3_family3D"].append(j3_family3D) data["j3_familyPerp"].append(j3_familyPerp) data["j3_Delta_j23_j31"].append(j3_Delta) dssr_stacking = False if "dssr_stacks" in cg.infos: if segment in cg.infos["dssr_stacks"]: dssr_stacking = True data["dssr_stacking"].append(dssr_stacking) kh_stem_angle = float("nan") if abs(cg.get_angle_type(segment, allow_broken=True)) == 5: next_ml = cg.get_next_ml_segment(segment) if isinstance(next_ml, str) and next_ml[0] == "m" and abs(cg.get_angle_type(next_ml, allow_broken=True)) == 5: stems1 = cg.edges[segment] stems2 = cg.edges[next_ml] try: s1, s2 = (stems1 | stems2) - (stems1 & stems2) except ValueError: pass else: vec1 = cg.coords.get_direction(s1) vec2 = cg.coords.get_direction(s2) angle = ftuv.vec_angle(vec1, vec2) if angle > math.pi / 2: angle = math.pi - angle kh_stem_angle = angle data["kh_stem_angle"].append(kh_stem_angle) if data: data["pk_number"] = number_by(data, "loop_start_after", "is_pseudoknotted_multiloop") data["loop_number"] = number_by(data, "loop_start_after", None) data["reguler_multiloop_number"] = number_by(data, "loop_start_after", "is_regular_multiloop") return data