Пример #1
0
def sim_discrete(tree, Q, anc=None, charname=None, rseed=None):
    """
    Simulate discrete character on a tree given transition rate matrix.

    Args:
        tree (Node): Root node of tree.
        Q (np.array): Instantaneous rate matrix
        anc (int): Root state. Optional. If None, root state is chosen
          from stationary distrubution of Q matrix
        rseed (int): Random seed to be passed to np.random. Optional
    Returns:
        Node: Copy of tree with each node containing its simulated
          state and the character history of its subtending branch.
    """
    assert tree.isroot, "Given node must be root"
    nchar = Q.shape[0]
    simtree = tree.copy()

    ####################################
    # Start with ancestral state of root
    ####################################
    if anc is None:
        # Randomly pick ancestral state from stationary distribution
        anc = rv_discrete(values=(list(range(nchar)), mk.qsd(Q))).rvs()
    simtree.sim_char = {}
    simtree.sim_char["sim_state"] = anc
    simtree.sim_char["sim_hist"] = []
    ###############################################################
    # Go through the tree in preorder sequence and simulate history
    ###############################################################
    if rseed:
        np.random.seed(rseed)
    for node in simtree.descendants():
        prevstate = node.parent.sim_char["sim_state"]
        node.sim_char = {}
        node.sim_char["sim_state"] = prevstate
        node.sim_char["sim_hist"] = []
        if node.length == 0:
            pass
        else:
            dt = 0
            while 1:
                dt += np.random.exponential(1.0 / -Q[prevstate, prevstate])
                if dt > node.length:
                    break
                vals = np.concatenate(
                    (Q[prevstate][:prevstate], Q[prevstate][prevstate + 1:]))
                newstate = rv_discrete(
                    values=(list(range(nchar))[:prevstate] +
                            list(range(nchar))[prevstate + 1:],
                            vals / sum(vals))).rvs()
                node.sim_char["sim_hist"].append((newstate, dt))
                node.sim_char["sim_state"] = newstate
                prevstate = newstate
    return simtree
Пример #2
0
    def test_qsd_ERQ3_returnsflatpi(self):
        Q = np.array([[-.2, .2], [.1, -.1]], dtype=np.double)

        calculatedPi = mk.qsd(Q)

        expectedPi = np.array([1.0 / 3.0, 2.0 / 3.0])

        try:
            np.testing.assert_allclose(expectedPi, calculatedPi)
        except AssertionError:
            self.fail("expectedPi != calculatedPi")
Пример #3
0
    def test_qsd_ARDQ3_matchesphytools(self):
        Q = np.array([[-.3, .1, .2], [.05, -.3, .25], [.05, .1, -.15]],
                     dtype=np.double)

        calculatedPi = mk.qsd(Q)

        expectedPi = np.array([0.1428571, 0.2500000, 0.6071429])

        try:
            np.testing.assert_allclose(expectedPi, calculatedPi, atol=1e-5)
        except AssertionError:
            self.fail("expectedPi != calculatedPi")
Пример #4
0
    def test_qsd_ARDQ4_matchesphytools(self):
        Q = np.array([[-.6, .1, .2, .3], [.05, -.4, .25, .1],
                      [.05, .1, -.15, 0], [.1, .1, .1, -.3]],
                     dtype=np.double)

        calculatedPi = mk.qsd(Q)

        expectedPi = np.array([0.08888889, 0.200000, 0.555555555, 0.155555556])

        try:
            np.testing.assert_allclose(expectedPi, calculatedPi, atol=1e-5)
        except AssertionError:
            self.fail("expectedPi != calculatedPi")
Пример #5
0
    def test_qsd_ARDQ2_matchesphytools(self):
        Q = np.array([[-.3, .1, .2], [.05, -.3, .25], [.05, .1, -.15]],
                     dtype=np.double)

        calculatedPi = mk.qsd(Q)

        expectedPi = np.array([0.1428571, 0.2500000, 0.6071429])

        try:  # Results will vary slightly from phytools (order of 1e-3)
            # Possibly due to differences in optimization implementation?
            np.testing.assert_allclose(expectedPi, calculatedPi, atol=1e-3)
        except AssertionError:
            self.fail("expectedPi != calculatedPi")