def test_angle_stat_deviation_from_around_circle(self): as1 = ftms.AngleStat(u=0.17, v=0.17, r1=1, u1=1.57, v1=0) # 0.17 rad ~ 10 degrees # 2.96 rad ~ 170 deg, 3.32 rad ~ 190 deg as2 = ftms.AngleStat(u=2.96, v=3.32, r1=2, u1=1.57, v1=0) self.assertTrue( np.allclose([as1.deviation_from(as2)], (1, 0.35, 0, 0), atol=0.05)) # 0.35 rad ~ 20 deg
def test_angle_stat_deviation_from(self): as1 = ftms.AngleStat(u=1.57, v=0., r1=1, u1=1.57, v1=0) as2 = ftms.AngleStat(u=1.57, v=0., r1=1, u1=1.57, v1=0) self.assertTrue(np.allclose([as1.deviation_from(as2)], (0, 0, 0, 0))) as2 = ftms.AngleStat(u=0, v=0., r1=1, u1=1.57, v1=0) self.assertTrue( np.allclose([as1.deviation_from(as2)], (0, 1.57, 0, 0), atol=0.01))
def test_angle_stat_difference(self): as1 = ftms.AngleStat(u=1.57, v=0., r1=1, u1=1.57, v1=0) as2 = ftms.AngleStat(u=1.57, v=0., r1=1, u1=1.57, v1=0) self.assertTrue(np.allclose([as1.diff(as2)], [0])) as2 = ftms.AngleStat(u=0, v=0., r1=1, u1=1.57, v1=0) self.assertTrue(np.allclose([as1.diff(as2)], [math.sqrt(2)], 0.01)) as2 = ftms.AngleStat(u=1.57, v=0., r1=1, u1=0, v1=0) fud.pv('as1.diff(as2)')
def test_angle_stat_get_angle(self): as1 = ftms.AngleStat(u=math.pi / 2, v=math.pi / 4, r1=4, u1=1.27, v1=1.5) self.assertAlmostEqual(as1.get_angle(), 3 * math.pi / 4) # If u=0 or 180 deg, the angle is always 90 deg as1 = ftms.AngleStat(u=0, v=1.23456, r1=3, u1=1.27, v1=1.5) self.assertAlmostEqual(as1.get_angle(), math.pi / 2) as1 = ftms.AngleStat(u=math.pi, v=0.987654, r1=3, u1=1.27, v1=1.5) self.assertAlmostEqual(as1.get_angle(), math.pi / 2)
def test_is_similar_to_zero_length(self): stat1 = ftms.AngleStat(u=math.radians(30), v=math.radians(40), t=math.radians(20), r1=0, u1=math.radians(15), v1=math.radians(15)) stat2 = ftms.AngleStat(u=math.radians(32), v=math.radians(40), t=math.radians(20), r1=0, u1=math.radians(22), v1=math.radians(65)) self.assertTrue(stat1.is_similar_to(stat2, 3)) self.assertFalse(stat1.is_similar_to(stat2, 1))
def test_is_similar_to_v(self): stat1 = ftms.AngleStat(u=math.radians(30), v=math.radians(40), t=math.radians(20), r1=15, u1=math.radians(15), v1=math.radians(15)) stat2 = ftms.AngleStat(u=math.radians(30), v=math.radians(45), t=math.radians(20), r1=15, u1=math.radians(15), v1=math.radians(15)) self.assertTrue(stat1.is_similar_to(stat1, 10**-5)) self.assertTrue(stat1.is_similar_to(stat2, 6)) self.assertFalse(stat1.is_similar_to(stat2, 4))
def get_bulge_angle_stats_core(self, define, connections): ''' Return the angle stats for a particular bulge. These stats describe the relative orientation of the two stems that it connects. @param define: The name of the bulge. @param connections: The two stems that are connected by it. @return: ftms.AngleStat object ''' (stem1, twist1, stem2, twist2, bulge) = ftug.get_stem_twist_and_bulge_vecs(self, define, connections) # Get the orientations for orienting these two stems (r, u, v, t) = ftug.get_stem_orientation_parameters(stem1, twist1, stem2, twist2) (r1, u1, v1) = ftug.get_stem_separation_parameters(stem1, twist1, bulge) dims =self.get_bulge_dimensions(define) ang_type = self.connection_type(define, connections) seqs = self.get_define_seq_str(define, adjacent=True) angle_stat = ftms.AngleStat(self.name, dims[0], dims[1], u, v, t, r1, u1, v1, ang_type, self.defines[define], seqs) return angle_stat
def sample(self): import scipy.stats as ss log.debug("DATA %s with shape %s", self.data, self.data.shape) r1 = ss.gaussian_kde(self.data[:, 3]).resample(1)[0][0] log.debug("r1 is %s", r1) rnd = np.random.rand(5) # 5 random values from 0 to 1 u = rnd[0] * np.pi v = rnd[1] * 2 * np.pi - np.pi t = rnd[2] * 2 * np.pi - np.pi u1 = rnd[3] * np.pi v1 = rnd[4] * 2 * np.pi - np.pi #sample = self.kde.resample(1).T log.debug("continuouse stat sample %s", (u, v, t, r1, u1, v1)) #u,v,t,r1,u1,v1 = sample[0] stat = ftmstats.AngleStat( stat_type="angle", pdb_name='cont-{:.1f}_{:.1f}_{:.1f}_{:.1f}_{:.1f}_{:.1f}'.format( u, v, t, r1, u1, v1), dim1=self.key[0], dim2=self.key[1], u=u, v=v, t=t, r1=r1, u1=u1, v1=v1, ang_type=self.key[2], define=[], seq="", vres={}) return stat
def setUp(self): self.sm = fbm.SpatialModel( ftmc.CoarseGrainRNA.from_bg_file('test/fess/data/4way.cg')) self.sm_zero_hairpin = fbm.SpatialModel( ftmc.CoarseGrainRNA.from_bg_file('test/fess/data/4GXY_A.cg')) self.sm_pseudoknot = fbm.SpatialModel( ftmc.CoarseGrainRNA.from_bg_file('test/fess/data/pseudoknot.cg')) self.example_angle_stat = ftms.AngleStat( "angle exampleStat 0 1000 1.69462078307 0.313515399557 0.165804917419 5.08692965666 1.04129866007 0.717061903121 3 CC" )
def parse_stats_file(file_handle): stats = { "stem": defaultdict(list), "angle": defaultdict(list), "loop": defaultdict(list), "3prime": defaultdict(list), "5prime": defaultdict(list) } for line in file_handle: line = line.strip() if "#" in line: line = line.split('#')[0] if not line: continue if line.startswith("stem"): stem_stat = ftmstats.StemStat(line) stats["stem"][stem_stat.bp_length].append(stem_stat) elif line.startswith("angle") or line.startswith( "open") or line.startswith("pseudo"): angle_stat = ftmstats.AngleStat() try: angle_stat.parse_line(line) except Exception as e: with log_to_exception(log, e): log.error( "Could not parse file due to error parsing line '{}'". format(line)) raise if len(angle_stat.define) > 0 and angle_stat.define[ 0] == 1: #An angle at the beginning of a structure #I guess this should never happen, if the stats do not stem from faulty bulge graphs. log.error( "Ignoring angle stat {} because it is at the beginning of a structure." " Does the stat come from a faulty BulgeGraph?".format( angle_stat.pdb_name)) continue angle_stat.ang_type = patch_angtype(angle_stat.ang_type) log.debug( "Reading angle_stat with dimensions %s and %s, and type %s. With define %s", angle_stat.dim1, angle_stat.dim2, angle_stat.ang_type, angle_stat.define) stats["angle"][(angle_stat.dim1, angle_stat.dim2, angle_stat.ang_type)].append(angle_stat) # Adding the reverse does not work as intended and produces a lot of structures # that do not fulfill the constraint energy. # stats["angle"][(angle_stat.dim1, angle_stat.dim2, -angle_stat.ang_type)].append(angle_stat) # Note that CoarseGrainRNA.get_stats extracts two angle stats per angle. else: key = line.split()[0] if key not in ["3prime", "5prime", "loop"]: raise ValueError( "Illegal line in stats file: '{}'".format(line)) stat = ftmstats.LoopStat(line) stats[key][stat.bp_length].append(stat) return stats
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 get_random_angle_stat(min_len=0., max_len=100.): ''' Create a random angle stats. This refers to the orienation of one helix with respect to another. @param min_len: The minimum separation between the two stems. @param max_len: The maximum separation between the two stems. @return: A random AngleStat ''' a = cbs.AngleStat('', 0, 0, rand.uniform(0, math.pi), rand.uniform(0, 2 * math.pi), rand.uniform(0, 2 * math.pi), rand.uniform(min_len, max_len), rand.uniform(0, math.pi), rand.uniform(0, 2 * math.pi)) return a
def get_bulge_angle_stats(self, bulge): ''' Return the angle stats for a particular bulge. These stats describe the relative orientation of the two stems that it connects. @param bulge: The name of the bulge. @param connections: The two stems that are connected by it. @return: The angle statistics in one direction and angle statistics in the other direction ''' if bulge == 'start': return (ftms.AngleStat(), cbs.AngleStat()) connections = self.connections(bulge) angle_stat1 = self.get_bulge_angle_stats_core(bulge, connections) angle_stat2 = self.get_bulge_angle_stats_core(bulge, list(reversed(connections))) return (angle_stat1, angle_stat2)
def test_read_stats_file(self): stats = fbstat.read_stats_file("test/fess/data/test1.stats") log.info(stats) self.assertEqual(len(stats["stem"]), 1) self.assertEqual(len(stats["angle"]), 3) self.assertEqual(len(stats["loop"]), 2) self.assertEqual(len(stats["3prime"]), 1) self.assertEqual(len(stats["5prime"]), 1) self.assertEqual(stats["stem"][5], [ ftmstats.StemStat( "stem test:s_0 5 10.388 2.43294047108 1 5 10 15 GCAUG UGCAU") ]) a_stat = ftmstats.AngleStat() a_stat.parse_line( "angle test:i_0 5 2 2.203691 2.099941 0.586450 17.134279 1.191397 1.274896 1" ) self.assertEqual(stats["angle"][(5, 2, 1)], [a_stat]) a_stat.parse_line( "angle test:m_0 4 1000 0.985166 -1.185545 -2.000463 13.701389 0.982669 0.267821 -4" ) self.assertEqual( stats["angle"][( 4, 1000, 6 )], # We patched ang_type to use 6 for all ml-segments. -6<=>-3, but -6<=>+4 [a_stat]) self.assertEqual(stats["loop"][6], [ ftmstats.LoopStat( "loop test:h_0 6 15.2401560955 0.269833051418 0.731484795668") ]) self.assertEqual(stats["3prime"][4], [ ftmstats.LoopStat( "3prime test:t_0 4 20.4034805163 1.47912394946 -0.0715301558972" ) ]) self.assertEqual(stats["5prime"][4], [ ftmstats.LoopStat( "5prime test:f_0 4 20.4034805163 1.47912394946 -0.0715301558972" ) ])
def test_angle_stat_deviation_from_zero_r(self): as1 = ftms.AngleStat(u=0.17, v=0.17, r1=0, u1=1.57, v1=0) as2 = ftms.AngleStat(u=0.17, v=0.17, r1=0, u1=2.7, v1=0.2) self.assertTrue(np.allclose([as1.deviation_from(as2)], (0, 0, 0, 0)))