def calculate_burial(kd, position, directions, radius=5, step_size=1., max_dist=500): ''' Calculate how far we need to travel from this position until we arrive at a region with no atoms within the search radius. (we assume we have got out of the protein) :param kd: A Bio.KDTree containing all the other atoms in this molecule :param position: The position to start at :param directions: The directions to travel in :param radius: The radius within which to check for neighbors :param step_size: How far to step at each point in the simulation :param max_dist: The maximal distance to travel from the center ''' distances = [] for direction in directions: # we assume that each direction is a unit vector step_vector = step_size * direction new_pos = np.array(position) while ftuv.magnitude((new_pos - position)) < max_dist: kd.search(new_pos, float(radius)) # kd.all_search(10) neighbors = kd.get_indices() distance = ftuv.magnitude(new_pos - position) if len(neighbors) == 0: distances += [ftuv.magnitude(new_pos - position)] break new_pos += step_vector return min(distances)
def main(): # Moving segment moving=make_random_chain(20) # Fixed segment # Last three residues of the moving segment # after applying a random rotation/translation fixed=rotate_last_three(moving) angles1 = [vec_angle(moving[i-1] - moving[i-2], moving[i] - moving[i-1]) for i in range(2, len(moving))] distances1 = [magnitude(moving[i] - moving[i-1]) for i in range(1, len(moving))] #print "moving:", moving if len(sys.argv) < 2: moving = ccd(moving, fixed, 10, True) else: moving = ccd(moving, fixed, iterations = int(sys.argv[1]), print_d = False) #print "moving:", moving angles2 = [vec_angle(moving[i-1] - moving[i-2], moving[i] - moving[i-1]) for i in range(2, len(moving))] distances2 = [magnitude(moving[i] - moving[i-1]) for i in range(1, len(moving))] assert(allclose(distances1, distances2)) assert(allclose(angles1, angles2))
def main(): # Moving segment moving = make_random_chain(20) # Fixed segment # Last three residues of the moving segment # after applying a random rotation/translation fixed = rotate_last_three(moving) angles1 = [ vec_angle(moving[i - 1] - moving[i - 2], moving[i] - moving[i - 1]) for i in range(2, len(moving)) ] distances1 = [ magnitude(moving[i] - moving[i - 1]) for i in range(1, len(moving)) ] #print "moving:", moving if len(sys.argv) < 2: moving = ccd(moving, fixed, 10, True) else: moving = ccd(moving, fixed, iterations=int(sys.argv[1]), print_d=False) #print "moving:", moving angles2 = [ vec_angle(moving[i - 1] - moving[i - 2], moving[i] - moving[i - 1]) for i in range(2, len(moving)) ] distances2 = [ magnitude(moving[i] - moving[i - 1]) for i in range(1, len(moving)) ] assert (allclose(distances1, distances2)) assert (allclose(angles1, angles2))
def test_ProjectionMatchEnergy_eval_energy_correct_projection(self): ENERGY_TOLERANCE=0.2 VECTOR_A_TOLERANCE=0.05 e=self.energy1a.eval_energy(self.sm1) self.assertLessEqual(e, ENERGY_TOLERANCE) targetdir=np.array([0.362,0.023, -0.826]) targetdir=targetdir/ftuv.magnitude(targetdir) if self.energy1a.projDir[2]>0: targetdir=-1*targetdir nptest.assert_allclose(self.energy1a.projDir, targetdir,atol=VECTOR_A_TOLERANCE) e=self.energy1b.eval_energy(self.sm1) self.assertLessEqual(e, ENERGY_TOLERANCE) targetdir= np.array([-0.193,-0.319,0.074]) targetdir=targetdir/ftuv.magnitude(targetdir) if self.energy1b.projDir[1]>0: targetdir=-1*targetdir nptest.assert_allclose(self.energy1b.projDir, targetdir, atol=VECTOR_A_TOLERANCE) e=self.energy2a.eval_energy(self.sm2) self.assertLessEqual(e, ENERGY_TOLERANCE) targetdir=np.array([-0.223,0.048,-0.579]) targetdir=targetdir/ftuv.magnitude(targetdir) if self.energy2a.projDir[2]>0: targetdir=-1*targetdir nptest.assert_allclose(self.energy2a.projDir, targetdir,atol=VECTOR_A_TOLERANCE) e=self.energy2b.eval_energy(self.sm2) self.assertLessEqual(e, ENERGY_TOLERANCE) targetdir=np.array([-0.464,-0.345,-0.192]) targetdir=targetdir/ftuv.magnitude(targetdir) if self.energy2b.projDir[2]>0: targetdir=-1*targetdir nptest.assert_allclose(self.energy2b.projDir, targetdir, atol=VECTOR_A_TOLERANCE)
def test_virtual_residue_atoms(self): cg = ftmc.from_pdb('test/forgi/threedee/data/1y26.pdb') ftug.add_virtual_residues(cg, 's0') ftug.add_virtual_residues(cg, 's1') bases_to_test = [] bases_to_test.append(ftug.virtual_residue_atoms(cg, 's0', 1, 0)) bases_to_test.append(ftug.virtual_residue_atoms(cg, 's0', 2, 1)) bases_to_test.append(ftug.virtual_residue_atoms(cg, 's1', 0, 0)) #Assert that any two atoms of the same base within reasonable distance to each other #(https://en.wikipedia.org/wiki/Bond_length says than a CH-bond is >= 1.06A) for va in bases_to_test: for k1, v1 in va.items(): for k2, v2 in va.items(): dist = ftuv.magnitude(v1 - v2) self.assertLess(dist, 30, msg="Nucleotide too big: " "Distance between {} and {} is {}".format( k1, k2, dist)) if k1 != k2: dist = ftuv.magnitude(v1 - v2) self.assertGreater( dist, 0.8, msg="Nucleotide too small: " "Distance between {} and {} is {}".format( k1, k2, dist))
def get_loop_stat(self, d): ''' Return the statistics for this loop. These stats describe the relative orientation of the loop to the stem to which it is attached. @param d: The name of the loop ''' loop_stat = ftms.LoopStat() loop_stat.pdb_name = self.name loop_stat.bp_length = self.get_length(d) loop_stat.phys_length = ftuv.magnitude(self.coords[d][1] - self.coords[d][0]) stem1 = list(self.edges[d])[0] (s1b, s1e) = self.get_sides(stem1, d) stem1_vec = self.coords[stem1][s1b] - self.coords[stem1][s1e] twist1_vec = self.twists[stem1][s1b] bulge_vec = self.coords[d][1] - self.coords[d][0] + 0.1 * (stem1_vec / ftuv.magnitude(stem1_vec)) (r,u,v) = ftug.get_stem_separation_parameters(stem1_vec, twist1_vec, bulge_vec) (loop_stat.r, loop_stat.u, loop_stat.v) = (r,u,v) return loop_stat
def test_new_traverse_and_build(self): self.sm.load_sampled_elems() self.sm.new_traverse_and_build() for k in self.cg_copy.defines.keys(): log.info("k: %s file: %s, built %s", k, ftuv.magnitude(self.cg_copy.coords.get_direction(k)), ftuv.magnitude(self.sm.bg.coords.get_direction(k))) self.assertAlmostEqual(ftmsim.cg_rmsd(self.sm.bg, self.cg_copy), 0, places=6)
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 test_virtual_atoms_same_strand_nuc_distance(self): """ Distance between virtual atoms of nucleotides on same strand in stem""" for i in range(1,9): for j in range (i+1,10): dist=ftuv.magnitude(self.va1[i]["C1'"]-self.va1[j]["C1'"]) self.assertLess(dist, 2.2+4.5*(j-i))#, msg="Distance between nucleotide {} and {} " # "is too big: {}".format(i, j, dist)) self.assertGreater(dist, 2*(j-i))#, msg="Distance between nucleotide {} and {} " # "is too small: {}".format(i, j, dist)) for i in range(63,71): for j in range (i+1,72): dist=ftuv.magnitude(self.va1[i]["C1'"]-self.va1[j]["C1'"]) self.assertLess(dist, 2.2+4.5*(j-i))#, msg="Distance between nucleotide {} and {} " # "is too big: {}".format(i, j, dist)) self.assertGreater(dist, 2*(j-i))#, msg="Distance between nucleotide {} and {} "
def add_encompassing_cylinders(self, rna_plotter, cg, radius=7.): cylinders_to_stems = ftug.get_encompassing_cylinders(cg, radius) for stems in cylinders_to_stems.values(): print("stems:", stems) points = [] for s in stems: points += [cg.coords[s][0], cg.coords[s][1]] # create the linear regression data = np.array(points) datamean = data.mean(axis=0) uu, dd, vv = np.linalg.svd(data - datamean) furthest = max([ftuv.magnitude(d) for d in (data - datamean)]) start_point = -furthest * vv[0] + datamean end_point = furthest * vv[0] + datamean rna_plotter.add_segment(start_point, end_point, 'white', width=4, text='', key='')
def add_encompassing_cylinders(self, cg, radius=7.): cylinders_to_stems = ftug.get_encompassing_cylinders(cg, radius) for stems in cylinders_to_stems.values(): print "stems:", stems points = [] for s in stems: points += [cg.coords[s][0], cg.coords[s][1]] # create the linear regression data = np.array(points) datamean = data.mean(axis=0) uu, dd, vv = np.linalg.svd(data - datamean) furthest = max([ftuv.magnitude(d) for d in (data - datamean) ]) start_point = -furthest * vv[0] + datamean end_point = furthest * vv[0] + datamean self.add_segment(start_point, end_point, 'white', width=4, text='') print >>sys.stderr, "YOOOOOOOOOOOOOOOOOOOOOOO"
def consensus(coords, structs): #structure 1 as reference: directions =[] for i in range(len(coords)): directions.append(structs[i].coords_to_directions()) directions = np.array(directions) new_directions = [] for i in range(len(directions[0])): av_dir = np.zeros(3) av_len = 0 for j in range(len(coords)): av_dir+=directions[j,i] av_len+=ftuv.magnitude(directions[j,i]) av_dir=ftuv.normalize(av_dir) av_len/=len(coords) new_directions.append(av_dir*av_len) flexibilities = [] for i in range(len(directions[0])): flex = np.zeros(3) for j in range(len(coords)): flex+=(new_directions[i]-directions[j,i])**2 flex/=len(coords) flexibilities.append(flex) sorted_defines = sorted(structs[0].defines.keys()) for i,d in enumerate(sorted_defines): print(d, new_directions[i], "+-", flexibilities[i]) consensus = copy.copy(structs[0]) consensus.coords_from_directions(new_directions) consensus.to_cg_file("consensus.coord") print("File consensus.coord written") return consensus
def test_create_orthonormal_basis(self): basis1 = ftuv.create_orthonormal_basis(np.array([0.0, 0.0, 2.0])) self.assertTrue( ftuv.is_almost_parallel(basis1[0], np.array([0., 0., 2.]))) basis2 = ftuv.create_orthonormal_basis(np.array([0.0, 0.0, 2.0]), np.array([0.0, 3.6, 0.])) self.assertTrue( ftuv.is_almost_parallel(basis2[0], np.array([0., 0., 2.]))) self.assertTrue( ftuv.is_almost_parallel(basis2[1], np.array([0., 3.6, 0]))) basis3 = ftuv.create_orthonormal_basis(np.array([0.0, 0.0, 2.0]), np.array([0.0, 3.6, 0.]), np.array([1., 0, 0])) self.assertTrue( ftuv.is_almost_parallel(basis3[0], np.array([0., 0., 2.]))) self.assertTrue( ftuv.is_almost_parallel(basis3[1], np.array([0., 3.6, 0]))) self.assertTrue( ftuv.is_almost_parallel(basis3[2], np.array([1., 0, 0]))) for basis in [basis1, basis2, basis3]: self.assertAlmostEqual(np.dot(basis[0], basis[1]), 0) self.assertAlmostEqual(np.dot(basis[0], basis[2]), 0) self.assertAlmostEqual(np.dot(basis[2], basis[1]), 0) for b in basis: self.assertAlmostEqual(ftuv.magnitude(b), 1)
def test_create_orthonormal_basis(self): #Note: If the input vectors are not orthogonal, the result are 3 vectors that might not form a basis. basis1 = ftuv.create_orthonormal_basis(np.array([0.0, 0.0, 2.0])) self.assertTrue( ftuv.is_almost_parallel(basis1[0], np.array([0., 0., 2.]))) basis2 = ftuv.create_orthonormal_basis(np.array([0.0, 0.0, 2.0]), np.array([0.0, 3.6, 0.])) self.assertTrue( ftuv.is_almost_parallel(basis2[0], np.array([0., 0., 2.]))) self.assertTrue( ftuv.is_almost_parallel(basis2[1], np.array([0., 3.6, 0]))) basis3 = ftuv.create_orthonormal_basis(np.array([0.0, 0.0, 2.0]), np.array([0.0, 3.6, 0.]), np.array([1., 0, 0])) self.assertTrue( ftuv.is_almost_parallel(basis3[0], np.array([0., 0., 2.]))) self.assertTrue( ftuv.is_almost_parallel(basis3[1], np.array([0., 3.6, 0]))) self.assertTrue( ftuv.is_almost_parallel(basis3[2], np.array([1., 0, 0]))) for basis in [basis1, basis2, basis3]: self.assertAlmostEqual(np.dot(basis[0], basis[1]), 0) self.assertAlmostEqual(np.dot(basis[0], basis[2]), 0) self.assertAlmostEqual(np.dot(basis[2], basis[1]), 0) for b in basis: self.assertAlmostEqual(ftuv.magnitude(b), 1)
def get_initial_measurement_distance(chain_stems, chain_loop, handles): ''' Calculate the rmsd between the measurement vectors after aligning the starts. @param chain_stems: The PDB coordinates of the chain with the stem. @param chain_loop: The PDB coordinates of the sampled loop. @param iterations: The number of iterations to use for the CCD loop closure. ''' align_starts(chain_stems, chain_loop, handles) c1_target = [] c1_sampled = [] for i in range(2): target = np.array(get_measurement_vectors(chain_stems, handles[0], handles[1])) sampled = np.array(get_measurement_vectors(chain_loop, handles[2], handles[3])) ''' for a in backbone_atoms: c1_target += [cuv.magnitude( chain_stems[handles[0] - i][a] - chain_stems[handles[1] + i][a])] c1_sampled += [cuv.magnitude( chain_loop[handles[2] - i][a] - chain_loop[handles[3] + i][a])] c1_target = np.array(c1_target) c1_sampled = np.array(c1_sampled) ''' #return cbc.calc_rmsd(np.array(c1_target), np.array(c1_sampled)) #return math.sqrt(sum([c ** 2 for c in c1_sampled - c1_target])) distances = [cuv.magnitude((sampled - target)[i]) for i in range(len(sampled))] rmsd = cuv.vector_set_rmsd(sampled, target) #dist = math.sqrt(sum([cuv.magnitude((sampled - target)[i]) ** 2 for i in range(len(sampled))])) return rmsd
def test_virtual_atoms_same_strand_nuc_distance(self): """ Distance between nucleotides on same strand in stem""" for i in range(1,9): for j in range (i+1,10): dist=ftuv.magnitude(self.va1[i]["C1'"]-self.va1[j]["C1'"]) self.assertLess(dist, 2+4.5*(j-i), msg="Distance between nucleotide {} and {} " "is too big: {}".format(i, j, dist)) self.assertGreater(dist, 2*(j-i), msg="Distance between nucleotide {} and {} " "is too small: {}".format(i, j, dist)) for i in range(63,71): for j in range (i+1,72): dist=ftuv.magnitude(self.va1[i]["C1'"]-self.va1[j]["C1'"]) self.assertLess(dist, 2+4.5*(j-i), msg="Distance between nucleotide {} and {} " "is too big: {}".format(i, j, dist)) self.assertGreater(dist, 2*(j-i), msg="Distance between nucleotide {} and {} " "is too small: {}".format(i, j, dist))
def consensus(coords, structs): #structure 1 as reference: directions = [] for i in range(len(coords)): directions.append(structs[i].coords_to_directions()) directions = np.array(directions) new_directions = [] for i in range(len(directions[0])): av_dir = np.zeros(3) av_len = 0 for j in range(len(coords)): av_dir += directions[j, i] av_len += ftuv.magnitude(directions[j, i]) av_dir = ftuv.normalize(av_dir) av_len /= len(coords) new_directions.append(av_dir * av_len) flexibilities = [] for i in range(len(directions[0])): flex = np.zeros(3) for j in range(len(coords)): flex += (new_directions[i] - directions[j, i])**2 flex /= len(coords) flexibilities.append(flex) sorted_defines = sorted(structs[0].defines.keys()) for i, d in enumerate(sorted_defines): print(d, new_directions[i], "+-", flexibilities[i]) consensus = copy.copy(structs[0]) consensus.coords_from_directions(new_directions) consensus.to_cg_file("consensus.coord") print("File consensus.coord written") return consensus
def test_virtual_atoms_distance_neighboring_atoms_in_nucleotide(self): # C2' is next to C3' for i in range(1, 9): dist = ftuv.magnitude(self.va1[i]["C3'"] - self.va1[i]["C2'"]) self.assertLess(dist, 3, msg="Distance between C3' and C2' for nucleotide {} " "is too big: {}".format(i, dist)) self.assertGreater(dist, 1, msg="Distance between C3' and C2' for nucleotide {} " "is too small: {}".format(i, dist))
def test_virtual_atoms_distance_neighboring_atoms_in_nucleotide(self): # C2' is next to C3' for i in range(1,9): dist=ftuv.magnitude(self.va1[i]["C3'"]-self.va1[i]["C2'"]) self.assertLess(dist, 3, msg="Distance between C3' and C2' for nucleotide {} " "is too big: {}".format(i, dist)) self.assertGreater(dist, 1, msg="Distance between C3' and C2' for nucleotide {} " "is too small: {}".format(i, dist))
def align_rnas(rnas): crds0 = rnas[0].get_ordered_virtual_residue_poss() centroid0 = ftuv.get_vector_centroid(crds0) print(centroid0) rnas[0].rotate_translate(centroid0, ftuv.identity_matrix) crds0 -= centroid0 assert ftuv.magnitude( ftuv.get_vector_centroid(crds0)) < 10**-5, ftuv.magnitude( ftuv.get_vector_centroid(crds0)) assert ftuv.magnitude( ftuv.get_vector_centroid(rnas[0].get_ordered_virtual_residue_poss()) ) < 10**-5, ftuv.get_vector_centroid( rnas[0].get_ordered_virtual_residue_poss()) for rna in rnas[1:]: crds1 = rna.get_ordered_virtual_residue_poss() centroid1 = ftuv.get_vector_centroid(crds1) crds1 -= centroid1 rot_mat = ftms.optimal_superposition(crds0, crds1) rna.rotate_translate(centroid1, rot_mat) assert ftuv.magnitude( ftuv.get_vector_centroid(crds1)) < 10**-5, ftuv.magnitude( ftuv.get_vector_centroid(crds1)) assert ftuv.magnitude( ftuv.get_vector_centroid(rna.get_ordered_virtual_residue_poss()) ) < 10**-5, ftuv.magnitude( ftuv.get_vector_centroid(rna.get_ordered_virtual_residue_poss()))
def test_get_random_vector(self): for _ in range(REPEAT_TESTS_CONTAINING_RANDOM): vec=ftuv.get_random_vector() self.assertLessEqual(ftuv.magnitude(vec[0]),1.) vec1=ftuv.get_random_vector() vec2=ftuv.get_random_vector() self.assertTrue(all( vec1[j]!=vec2[j] for j in [0,1,2]), msg="Repeated calls should generate different results." "This tests depends on random values. if it fails, try running it again.")
def test_virtual_atoms_basepairdistance_in_stem(self): """ distance between two atoms that pair in stem """ for i in range(1,10): for j in range (71,62): mindist=min(ftuv.magnitude(a1-a2) for a1 in self.va2[i].values() for a2 in self.va2[j].values()) self.assertLess(dist, 20, msg="Distance between nucleotide {} and {} is too big: " "the minimal distance is {}".format(i, j, mindist)) self.assertGreater(dist, 1.1, msg="Distance between nucleotide {} and {} is too small: " "the minimal distance is {}".format(i, j, mindist))
def pymol_text_string(self): counter = 0 s = '' pa_s = 'cmd.set("label_size", 20)\n' uids = [] for (p, n, color, width, text, key) in self.segments: if len(text) == 0: continue # generate a unique identifier for every object so that other # scripts can add others that don't clash uid = str(uuid.uuid4()).replace('-', 'x') uids += [uid] s += "cgox_%s = []" % (uid) + '\n' if np.all(n==p): pos = n axes = [ [2,0,0], [0,2,0], [0,0,2] ] else: comp1 = cuv.normalize(n - p) ncl = cuv.get_non_colinear_unit_vector(comp1) comp2 = cuv.normalize(np.cross(ncl, comp1)) comp3 = cuv.normalize(np.cross(ncl, comp2)) pos = (p + n) / 2.0 + 3 * comp2 axes = [list(comp1 * 2), list(comp2 * 2), list(comp3 * 2)] text = "%s: %.1f" % (text, cuv.magnitude(n - p)) s += "cyl_text(cgox_%s, plain, %s, " % (uid, str(list(pos))) s += "\"%s\", 0.20, axes=%s)" % (text, str(axes)) + '\n' pa_s += "pa_%s = cmd.pseudoatom(pos=%s," % (uid, str(list(pos))) pa_s += "b=1.0, label=\"%s\")\n" % (text) counter += 1 ''' for (text, pos) in self.labels: uid = str(uuid.uuid4()).replace('-', 'x') uids += [uid] pa_s += "pa_%s = cmd.pseudoatom(pos=%s," % (uid, str(list(pos))) pa_s += "b=1.0, label=\"%s\")\n" % (text) ''' s += "cmd.set(\"cgo_line_radius\",0.03)" + '\n' for i in range(counter): s += "cmd.load_cgo(cgox_%s, " % (uids[i]) s += "\'cgox%s\')" % (uids[i]) + '\n' s += "cmd.zoom(\"all\", 2.0)" + '\n' return pa_s
def _coplanar_point_indices(*points): """ Thanks to https://stackoverflow.com/a/18968498""" from numpy.linalg import svd points = np.array(points).T assert points.shape[0] <= points.shape[1], "There are only {} points in {} dimensions.".format( points.shape[1], points.shape[0]) ctr = points.mean(axis=1) x = points - ctr[:, np.newaxis] M = np.dot(x, x.T) # Could also use np.cov(x) here. normal = svd(M)[0][:, -1] out = [] for i, p in enumerate(points.T): w = p - ctr oop_distance = ftuv.magnitude( np.dot(w, normal)) / ftuv.magnitude(normal) if oop_distance <= OOP_CUTOFF: out.append(i) return out, ctr, normal
def test_add_loop_for_hairpin(self): cg=ftmc.CoarseGrainRNA() cg.from_dotbracket("(((...)))") sm=fbm.SpatialModel(cg) sm.elem_defs={} sm.elem_defs["s0"]=self.example_stem_stat sm.elem_defs["h0"]=self.example_hairpin_stat sm.stems['s0'] = sm.add_stem('s0', sm.elem_defs['s0'], fbm.StemModel(), ftms.AngleStat(), (0,1)) sm.add_loop("h0","s0") self.assertAlmostEqual(ftuv.magnitude(sm.bulges["h0"].mids[1] - sm.bulges["h0"].mids[0]), self.example_hairpin_stat.phys_length)
def test_virtual_atoms_intranucleotide_distances_stem_withsidechain(self): """ distance between two atoms of same nucleotide IN STEM """ for i in it.chain(range(1,10)+range(63,72)): for k1, a1 in self.va2[i].items(): for k2, a2 in self.va2[i].items(): if k1==k2: continue dist=ftuv.magnitude(a1-a2) self.assertLess(dist, 30, msg="Nucleotide {} too big: Distance between " "{} and {} is {}".format(i, k1, k2, dist) ) self.assertGreater(dist, 0.8, msg="Nucleotide {} too small: Distance between " "{} and {} is {}".format(i, k1, k2, dist) )
def test_get_random_vector(self): for _ in range(REPEAT_TESTS_CONTAINING_RANDOM): vec = ftuv.get_random_vector() self.assertLessEqual(ftuv.magnitude(vec[0]), 1.) vec1 = ftuv.get_random_vector() vec2 = ftuv.get_random_vector() self.assertTrue( all(vec1[j] != vec2[j] for j in [0, 1, 2]), msg="Repeated calls should generate different results." "This tests depends on random values. if it fails, try running it again." )
def pymol_text_string(self): counter = 0 s = '' pa_s = 'cmd.set("label_size", 20)\n' uids = [] for (p, n, color, width, text) in self.segments: if len(text) == 0: continue # generate a unique identifier for every object so that other # scripts can add others that don't clash uid = str(uuid.uuid4()).replace('-', 'x') uids += [uid] s += "cgox_%s = []" % (uid) + '\n' comp1 = cuv.normalize(n - p) ncl = cuv.get_non_colinear_unit_vector(comp1) comp2 = cuv.normalize(np.cross(ncl, comp1)) comp3 = cuv.normalize(np.cross(ncl, comp2)) pos = (p + n) / 2.0 + 3 * comp2 #pos = p + (n - p) / 4.0 + 3 * comp2 axes = [list(comp1 * 2), list(comp2 * 2), list(comp3 * 2)] text = "%s: %.1f" % (text, cuv.magnitude(n - p)) #text = "%s" % (text) s += "cyl_text(cgox_%s, plain, %s, " % (uid, str(list(pos))) s += "\"%s\", 0.20, axes=%s)" % (text, str(axes)) + '\n' pa_s += "pa_%s = cmd.pseudoatom(pos=%s," % (uid, str(list(pos))) pa_s += "b=1.0, label=\"%s\")\n" % (text) counter += 1 ''' for (text, pos) in self.labels: uid = str(uuid.uuid4()).replace('-', 'x') uids += [uid] pa_s += "pa_%s = cmd.pseudoatom(pos=%s," % (uid, str(list(pos))) pa_s += "b=1.0, label=\"%s\")\n" % (text) ''' s += "cmd.set(\"cgo_line_radius\",0.03)" + '\n' for i in range(counter): s += "cmd.load_cgo(cgox_%s, " % (uids[i]) s += "\'cgox%s\')" % (uids[i]) + '\n' s += "cmd.zoom(\"all\", 2.0)" + '\n' return pa_s
def cylinderToThree(line, name): start, end = line length = ftuv.magnitude(end - start) look_at = end center = (start + end) / 2 return { "center": center.tolist(), "look_at": look_at.tolist(), "length": length, "type": name[0], "name": name }
def add_cone(self, p, n, color='white', width=2.4, text=''): if self.override_color is not None: color = self.override_color cone_extension = 2. cyl_vec = cuv.normalize(n-p) cyl_len = cuv.magnitude(n-p) new_width = width * (cyl_len + cone_extension) / cyl_len self.new_cones += [(np.array(p) - cone_extension * cyl_vec, np.array(n), color, width, text)] self.new_cones += [(np.array(n) + cone_extension * cyl_vec, np.array(p), color, width, text)]
def test_add_loop_for_hairpin(self): cg = ftmc.CoarseGrainRNA.from_dotbracket("(((...)))") sm = fbm.SpatialModel(cg) sm.elem_defs = {} sm.elem_defs["s0"] = self.example_stem_stat sm.elem_defs["h0"] = self.example_hairpin_stat sm.stems['s0'] = sm.add_stem('s0', sm.elem_defs['s0'], fbm.StemModel(), ftms.AngleStat(), (0, 1)) sm.add_loop("h0", "s0") self.assertAlmostEqual( ftuv.magnitude(sm.bulges["h0"].mids[1] - sm.bulges["h0"].mids[0]), self.example_hairpin_stat.phys_length)
def add_cone(self, p, n, color='white', width=2.4, text=''): cone_extension = 2. cyl_vec = cuv.normalize(n - p) cyl_len = cuv.magnitude(n - p) new_width = width * (cyl_len + cone_extension) / cyl_len self.cones += [(np.array(p) - cone_extension * cyl_vec, np.array(n), color, width, text)] self.cones += [(np.array(n) + cone_extension * cyl_vec, np.array(p), color, width, text)]
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 test_ProjectionMatchEnergy_eval_energy_correct_projection(self): ENERGY_TOLERANCE = 0.2 VECTOR_A_TOLERANCE = 0.05 e = self.energy1a.eval_energy(self.sm1) self.assertLessEqual(e, ENERGY_TOLERANCE) targetdir = np.array([0.362, 0.023, -0.826]) targetdir = targetdir / ftuv.magnitude(targetdir) if self.energy1a.projDir[2] > 0: targetdir = -1 * targetdir nptest.assert_allclose(self.energy1a.projDir, targetdir, atol=VECTOR_A_TOLERANCE) e = self.energy1b.eval_energy(self.sm1) self.assertLessEqual(e, ENERGY_TOLERANCE) targetdir = np.array([-0.193, -0.319, 0.074]) targetdir = targetdir / ftuv.magnitude(targetdir) if self.energy1b.projDir[1] > 0: targetdir = -1 * targetdir nptest.assert_allclose(self.energy1b.projDir, targetdir, atol=VECTOR_A_TOLERANCE) e = self.energy2a.eval_energy(self.sm2) self.assertLessEqual(e, ENERGY_TOLERANCE) targetdir = np.array([-0.223, 0.048, -0.579]) targetdir = targetdir / ftuv.magnitude(targetdir) if self.energy2a.projDir[2] > 0: targetdir = -1 * targetdir nptest.assert_allclose(self.energy2a.projDir, targetdir, atol=VECTOR_A_TOLERANCE) e = self.energy2b.eval_energy(self.sm2) self.assertLessEqual(e, ENERGY_TOLERANCE) targetdir = np.array([-0.464, -0.345, -0.192]) targetdir = targetdir / ftuv.magnitude(targetdir) if self.energy2b.projDir[2] > 0: targetdir = -1 * targetdir nptest.assert_allclose(self.energy2b.projDir, targetdir, atol=VECTOR_A_TOLERANCE)
def test_virtual_residue_atoms(self): cg, = ftmc.CoarseGrainRNA.from_pdb('test/forgi/threedee/data/1y26.pdb') ftug.add_virtual_residues(cg, 's0') ftug.add_virtual_residues(cg, 's1') bases_to_test = [] bases_to_test.append(ftug.virtual_residue_atoms(cg, 's0', 1, 0)) bases_to_test.append(ftug.virtual_residue_atoms(cg, 's0', 2, 1)) bases_to_test.append(ftug.virtual_residue_atoms(cg, 's1', 0, 0)) # Assert that any two atoms of the same base within reasonable distance to each other #(https://en.wikipedia.org/wiki/Bond_length says than a CH-bond is >= 1.06A) for va in bases_to_test: for k1, v1 in va.items(): for k2, v2 in va.items(): dist = ftuv.magnitude(v1 - v2) self.assertLess(dist, 30, msg="Nucleotide too big: " "Distance between {} and {} is {}".format(k1, k2, dist)) if k1 != k2: dist = ftuv.magnitude(v1 - v2) self.assertGreater(dist, 0.8, msg="Nucleotide too small: " "Distance between {} and {} is {}".format(k1, k2, dist))
def calculate_burial(kd, position, directions, radius=5, step_size=1., max_dist=500): ''' Calculate how far we need to travel from this position until we arrive at a region with no atoms within the search radius. (we assume we have got out of the protein) :param kd: A Bio.KDTree containing all the other atoms in this molecule :param position: The position to start at :param directions: The directions to travel in :param radius: The radius within which to check for neighbors :param step_size: How far to step at each point in the simulation :param max_dist: The maximal distance to travel from the center ''' distances = [] for direction in directions: # we assume that each direction is a unit vector step_vector = step_size * direction new_pos = np.array(position) while ftuv.magnitude((new_pos - position)) < max_dist: kd.search(new_pos, float(radius)) #kd.all_search(10) neighbors = kd.get_indices() distance = ftuv.magnitude(new_pos - position) if len(neighbors) == 0: distances += [ftuv.magnitude(new_pos - position)] break new_pos += step_vector return min(distances)
def noncovalent_distances(chain, cutoff=0.3): ''' Print out the distances between all non-covalently bonded atoms which are closer than cutoff to each other. :param chain: The Bio.PDB chain. :param cutoff: The maximum distance ''' all_atoms = bpdb.Selection.unfold_entities(chain, 'A') ns = bpdb.NeighborSearch(all_atoms) contacts = ns.search_all(cutoff) return [ftuv.magnitude(c[1] - c[0]) for c in contacts if not is_covalent(c)]
def add_dashed(self, point1, point2, width=0.3): ''' Add a dashed line from point1 to point2. ''' dash_length = 0.6 gap_length = dash_length * 2 direction = ftuv.normalize(point2 - point1) num_dashes = ftuv.magnitude(point2 - point1) / (dash_length + gap_length) 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", width, "", key=key)
def test_create_orthonormal_basis(self): #Note: If the input vectors are not orthogonal, the result are 3 vectors that might not form a basis. basis1=ftuv.create_orthonormal_basis(np.array([0.0,0.0,2.0])) self.assertTrue( ftuv.is_almost_colinear(basis1[0], np.array([0.,0.,2.])) ) basis2=ftuv.create_orthonormal_basis(np.array([0.0,0.0,2.0]), np.array([0.0, 3.6, 0.])) self.assertTrue( ftuv.is_almost_colinear(basis2[0], np.array([0.,0.,2.])) ) self.assertTrue( ftuv.is_almost_colinear(basis2[1], np.array([0.,3.6,0])) ) basis3=ftuv.create_orthonormal_basis(np.array([0.0,0.0,2.0]), np.array([0.0, 3.6, 0.]), np.array([1,0,0])) self.assertTrue( ftuv.is_almost_colinear(basis3[0], np.array([0.,0.,2.])) ) self.assertTrue( ftuv.is_almost_colinear(basis3[1], np.array([0.,3.6,0])) ) self.assertTrue( ftuv.is_almost_colinear(basis3[2], np.array([1.,0,0])) ) for basis in [basis1, basis2, basis3]: self.assertAlmostEqual(np.dot(basis[0],basis[1]),0) self.assertAlmostEqual(np.dot(basis[0],basis[2]),0) self.assertAlmostEqual(np.dot(basis[2],basis[1]),0) for b in basis: self.assertAlmostEqual(ftuv.magnitude(b),1)
def get_loop_flexibility(cg, loop): """ Unused. We tried to see if the length of the loop vs # bases had an effect on ointeraction probability. """ assert loop[0] == "i" d = cg.define_a(loop) nt1, nt2 = d[1] - d[0], d[3] - d[2] max_nts = max(nt1, nt2) loop_length = ftuv.magnitude(cg.coords.get_direction(loop)) # As number of nucleotide-links (or phosphate groups) per Angstrom # 9.2 is the sum of average bond lengths for bonds in the nucleotide linkage. # Bond lengths taken from: DOI: 10.1021/ja9528846 # A value of 1 means, all bonds are stretched. # Ideal helices have a value of: 4.41 # A value below 1 should be rare. # Higher values mean higher flexibility. return (max_nts) / loop_length * 9.2
def get_stem_stats(self, stem): ''' Calculate the statistics for a stem and return them. These statistics will describe the length of the stem as well as how much it twists. @param stem: The name of the stem. @return: A StemStat structure containing the above information. ''' ss = ftms.StemStat() ss.pdb_name = self.name #ss.bp_length = abs(self.defines[stem][0] - self.defines[stem][1]) ss.bp_length = self.stem_length(stem) ss.phys_length = ftuv.magnitude(self.coords[stem][0] - self.coords[stem][1]) ss.twist_angle = ftug.get_twist_angle(self.coords[stem], self.twists[stem]) ss.define = self.defines[stem] return ss
def _find_annot_pos_on_circle(nt, coords, cg): for i in range(5): for sign in [-1,1]: a = np.pi/4*i*sign if cg.get_elem(nt)[0]=="s": bp = cg.pairing_partner(nt) anchor = coords[bp-1] else: anchor =np.mean([ coords[nt-2], coords[nt]], axis=0) vec = coords[nt-1]-anchor vec=vec/ftuv.magnitude(vec) rotated_vec = np.array([vec[0]*math.cos(a)-vec[1]*math.sin(a), vec[0]*math.sin(a)+vec[1]*math.cos(a)]) annot_pos = coords[nt-1]+rotated_vec*18 if _clashfree_annot_pos(annot_pos, coords): log.debug("Annot pos on c is %s",annot_pos) return annot_pos return None
def align_rnas(rnas): crds0 = rnas[0].get_ordered_virtual_residue_poss() centroid0 = ftuv.get_vector_centroid(crds0) print(centroid0) rnas[0].rotate_translate(centroid0, ftuv.identity_matrix) crds0-=centroid0 assert ftuv.magnitude(ftuv.get_vector_centroid(crds0))<10**-5, ftuv.magnitude(ftuv.get_vector_centroid(crds0)) assert ftuv.magnitude(ftuv.get_vector_centroid(rnas[0].get_ordered_virtual_residue_poss()))<10**-5, ftuv.get_vector_centroid(rnas[0].get_ordered_virtual_residue_poss()) for rna in rnas[1:]: crds1 = rna.get_ordered_virtual_residue_poss() centroid1 = ftuv.get_vector_centroid(crds1) crds1-=centroid1 rot_mat = ftms.optimal_superposition(crds0, crds1) rna.rotate_translate(centroid1, rot_mat) assert ftuv.magnitude(ftuv.get_vector_centroid(crds1))<10**-5, ftuv.magnitude(ftuv.get_vector_centroid(crds1)) assert ftuv.magnitude(ftuv.get_vector_centroid(rna.get_ordered_virtual_residue_poss()))<10**-5, ftuv.magnitude(ftuv.get_vector_centroid(rna.get_ordered_virtual_residue_poss()))
def deviation_from(self, stat2): """ How much does the other stat differ from this stat? :param stat2: Another AngleStat :returns: A 4-tuple: The positional deviation in Angstrom, and 3 absolute angular deviations in radians. The angular deviations are u, v and t """ ret = [] pos1 = ftuv.spherical_polar_to_cartesian(self.position_params()) pos2 = ftuv.spherical_polar_to_cartesian(stat2.position_params()) ret.append(ftuv.magnitude(pos1 - pos2)) log.debug("Position difference is %f", ret[-1]) for attr in ["u", "v", "t"]: raw_diff = getattr(self, attr) - getattr(stat2, attr) # Map the difference to a value between 0 and pi raw_diff_on_circle = abs( (raw_diff + math.pi / 2) % (math.pi) - math.pi / 2) log.debug("Angular difference for %s is %f, mapped to %f", attr, raw_diff, raw_diff_on_circle) ret.append(raw_diff_on_circle) return tuple(ret)
def deviation_from(self, stat2): """ How much does the other stat differ from this stat? :param stat2: Another AngleStat :returns: A 4-tuple: The positional deviation in Angstrom, and 3 absolute angular deviations in radians. The angular deviations are u, v and t """ ret = [] pos1 = ftuv.spherical_polar_to_cartesian(self.position_params()) pos2 = ftuv.spherical_polar_to_cartesian(stat2.position_params()) ret.append(ftuv.magnitude(pos1 - pos2)) log.debug("Position difference is %f", ret[-1]) for attr in ["u", "v", "t"]: raw_diff = getattr(self, attr) - getattr(stat2, attr) #Map the difference to a value between 0 and pi raw_diff_on_circle = abs((raw_diff + math.pi / 2) % (math.pi) - math.pi / 2) log.debug("Angular difference for %s is %f, mapped to %f", attr, raw_diff, raw_diff_on_circle) ret.append(raw_diff_on_circle) return tuple(ret)
def test_create_orthonormal_basis(self): basis1 = ftuv.create_orthonormal_basis(np.array([0.0, 0.0, 2.0])) self.assertTrue(ftuv.is_almost_parallel( basis1[0], np.array([0., 0., 2.]))) basis2 = ftuv.create_orthonormal_basis( np.array([0.0, 0.0, 2.0]), np.array([0.0, 3.6, 0.])) self.assertTrue(ftuv.is_almost_parallel( basis2[0], np.array([0., 0., 2.]))) self.assertTrue(ftuv.is_almost_parallel( basis2[1], np.array([0., 3.6, 0]))) basis3 = ftuv.create_orthonormal_basis( np.array([0.0, 0.0, 2.0]), np.array([0.0, 3.6, 0.]), np.array([1., 0, 0])) self.assertTrue(ftuv.is_almost_parallel( basis3[0], np.array([0., 0., 2.]))) self.assertTrue(ftuv.is_almost_parallel( basis3[1], np.array([0., 3.6, 0]))) self.assertTrue(ftuv.is_almost_parallel( basis3[2], np.array([1., 0, 0]))) for basis in [basis1, basis2, basis3]: self.assertAlmostEqual(np.dot(basis[0], basis[1]), 0) self.assertAlmostEqual(np.dot(basis[0], basis[2]), 0) self.assertAlmostEqual(np.dot(basis[2], basis[1]), 0) for b in basis: self.assertAlmostEqual(ftuv.magnitude(b), 1)
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 cylinderToThree(line, name): start, end=line length=ftuv.magnitude(end-start) look_at=end center=(start+end)/2 return {"center":center.tolist(), "look_at":look_at.tolist(), "length":length, "type":name[0], "name":name}
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 main(): usage = """ ./helix_orienation_divergences.py Analyze how much the helix-helix orientations diverge between two data sets. """ num_args=0 parser = OptionParser() parser.add_option('-r', '--resolution', dest='resolution', default=10, help="The resolution of the resulting plot", type='int') parser.add_option('-a', '--angle', dest='angle', default=0, help="The angle of the camera", type='float') parser.add_option('-f', '--fig-name', dest='fig_name', default='', help="The name of the file to save the figure to. If it is not specified, the figure will not be saved", type='str') parser.add_option('-i', '--interior_loops', dest='interior_loops', default=False, help='Cluster only the interior loops', action='store_true') parser.add_option('-m', '--multi_loops', dest='multi_loops', default=False, help='Cluster only the interior loops', action='store_true') #parser.add_option('-u', '--useless', dest='uselesss', default=False, action='store_true', help='Another useless option') (options, args) = parser.parse_args() if len(args) < num_args: parser.print_help() sys.exit(1) column_names = ['type', 'pdb', 's1', 's2', 'u', 'v', 't', 'r', 'u1', 'v1', 'atype', 'something1', 'something2', 'sth3', 'sth4'] real_stats = ftms.ConformationStats('fess/stats/real.stats').angle_stats sampled_stats = ftms.ConformationStats('fess/stats/temp.stats').angle_stats # count how many statistics we have for each statistic type stat_counts = c.defaultdict(int) for sc in real_stats.keys(): stat_counts[sc] += len(real_stats[sc]) histograms = dict() for b in stat_counts.keys(): if b[2] != 2.: # only look at type 2 angles continue if options.interior_loops: if b[0] == 1000 or b[1] == 1000: continue if options.multi_loops: if b[0] != 1000 and b[1] != 1000: continue (selected_sizes, count) = get_nearest_dimension_sizes(b, stat_counts, 1) if count < 3: continue fud.pv('b, selected_sizes') combined_real = [] # get the statistics that correspond to the selected sampled sizes for ss in selected_sizes: #ss_r = get_certain_angle_stats(real_stats, ss) ss_r = real_stats[ss] combined_real += list(ss_r[['u','v']].as_matrix()) num_points = len(combined_real) combined_real = np.array(combined_real) #histograms[b] = (np.histogram2d(combined_real[:,0], combined_real[:,1], range=[[0, m.pi], [-m.pi, m.pi]])[0] + 0.5) / float(num_points) histograms[b] = combined_real dists = [] named_dists = dict() pp_dists = dict() for k1, k2 in it.combinations(histograms.keys(), 2): per_point_distances = [] for p1 in histograms[k1]: point_distances = [] for p2 in histograms[k2]: point_distances += [ftuv.magnitude(p1 - p2)] per_point_distances += [min(point_distances)] for p2 in histograms[k2]: point_distances = [] for p1 in histograms[k1]: point_distances += [ftuv.magnitude(p1-p2)] per_point_distances += [min(point_distances)] dists += [max(per_point_distances)] named_dists[(k1,k2)] = max(per_point_distances) pp_dists[(k1,k2)] = per_point_distances ''' kl = histograms[k1] * (histograms[k1] / histograms[k2]) kl = sum(map(sum, kl)) dists += [kl] ''' fud.pv('dists') Z = sch.complete(dists) fud.pv('Z') sch.dendrogram(Z, labels = histograms.keys(), leaf_rotation=90) plt.subplots_adjust(bottom=0.25) plt.show() k1 = (6,7,2) k2 = (5,6,2) rs = get_certain_angle_stats(real_stats, k1) ss = get_certain_angle_stats(real_stats, k2) fud.pv('named_dists[(k1,k2)]') fud.pv('pp_dists[(k1,k2)]') real_us = rs[['u', 'v']].as_matrix() sampled_us = ss[['u','v']].as_matrix() U_r = real_us[:,0] V_r = real_us[:,1] U_s = sampled_us[:,0] V_s = sampled_us[:,1] total_r = len(U_r) total_s = len(U_s) hr = np.histogram2d(U_r, V_r) hs = np.histogram2d(U_s, V_s) pseudo_r = (hr[0] + 1) / total_r pseudo_s = (hs[0] + 1) / total_r kl = pseudo_r * (pseudo_r / pseudo_s) fud.pv('kl') fud.pv('sum(map(sum, kl))') X_r = np.sin(U_r) * np.cos(V_r) Y_r = np.sin(U_r) * np.sin(V_r) Z_r = np.cos(U_r) r = 1. X_s = r * np.sin(U_s) * np.cos(V_s) Y_s = r * np.sin(U_s) * np.sin(V_s) Z_s = r * np.cos(U_s) fud.pv('real_us') real_us_orig = np.copy(real_us) sampled_us_orig = np.copy(sampled_us) print len(real_us), len(sampled_us) fig = plt.figure(figsize=(10,10)) ax = Axes3D(fig) a = Arrow3D([-1.3,1.3],[0,0],[0,0], mutation_scale=20, lw=5, arrowstyle="-|>", color="g") ax.add_artist(a) ax.plot(X_r, Y_r, Z_r, 'bo', alpha=0.3) ax.plot(X_s, Y_s, Z_s, 'ro', alpha=0.3) u, v = np.mgrid[0:2*np.pi:20j, 0:np.pi:10j] x=np.cos(u)*np.sin(v) y=np.sin(u)*np.sin(v) z=np.cos(v) ax.plot_wireframe(x, y, z, color="y") #surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, facecolors=colors, # linewidth=0, antialiased=False) ax._axis3don=False ax.set_zlim3d(-1, 1) ax.w_zaxis.set_major_locator(LinearLocator(6)) ax.view_init(0, options.angle) ''' plt.subplots_adjust(left=0.4, right=0.9, top=0.9, bottom=0.1) for i in xrange(0, 360, 40): savefig("fig%d.png", (i)) ''' ''' sm = cm.ScalarMappable(cmap=cm.jet) sm.set_array(W) fig.colorbar(sm) ''' if options.fig_name != "": plt.savefig(options.fig_name, bbox_inches='tight') else: plt.show()