def sample_b_to_rate(R): """ The b in this function name means branch. @param R: directed topology @return: a sampled map from vertex to expected rate """ b_to_rate = {} v_to_source = Ftree.R_to_v_to_source(R) for v in Ftree.R_to_preorder(R): p = v_to_source.get(v, None) if p is None: continue # sample a coefficient regardless of whether we use it # this is an obsolete method #log_coeff = (random.random() - 0.5) * epsrate #coeff = math.exp(log_coeff) curr_branch = frozenset([v, p]) gp = v_to_source.get(p, None) if gp is None: parent_rate = 1.0 else: prev_branch = frozenset([p, gp]) parent_rate = b_to_rate[prev_branch] b_to_rate[curr_branch] = random.expovariate(1/parent_rate) return b_to_rate
def sample_brownian_motion(R, B): """ Sample brownian motion on a tree. @param R: directed tree @param B: branch lengths @return: map from vertex to sample """ r = Ftree.R_to_root(R) v_to_sample = {r: 0} v_to_sinks = Ftree.R_to_v_to_sinks(R) for v in Ftree.R_to_preorder(R): for sink in v_to_sinks[v]: u_edge = frozenset((v, sink)) mu = v_to_sample[v] var = B[u_edge] v_to_sample[sink] = random.gauss(mu, math.sqrt(var)) return v_to_sample
def sample_jc_column(R, B): """ Sample a column of a Jukes-Cantor alignment. @param R: Ftree directed topology @param B: branch lengths in expected number of substitutions @return: a map from vertex to nucleotide """ acgt = 'ACGT' v_to_nt = {} v_to_source = Ftree.R_to_v_to_source(R) for v in Ftree.R_to_preorder(R): p = v_to_source.get(v, None) if p is None: v_to_nt[v] = random.choice(acgt) else: d = B[frozenset([v, p])] p_randomize = 1.0 - math.exp(-(4.0 / 3.0) * d) if random.random() < p_randomize: v_to_nt[v] = random.choice(acgt) else: v_to_nt[v] = v_to_nt[p] return v_to_nt