<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 toytree quartet functions (in progress)
Step1:  get two random trees
Step2:  Plan for counting quartets (Illustrated below)
We will traverse the tree visiting every node in turn. At each node we will select the edge above it (towards the root) to be the focal 'split'. Each split can represent many possible quartets, where at least one tip can be sampled from each of the four edges leading from the split. In the example below, we are visiting node 12, and the focal split is shown in black. The four edges leaving this split are shown in red, pink, blue, and aqua. To get all quartets from this split we must sample all possible combinations of one sample from each colored set.
Step3:  Example to sample tips from each quartet edge
Step4:  Example to get all quartet sets from sampled tips
Step5:  Combine into a function
Step6:  Compare quartet sets
<ASSISTANT_TASK:>
Python Code:
import toytree
import itertools
import numpy as np
Explanation: toytree quartet functions (in progress)
End of explanation
t0 = toytree.rtree.unittree(10, seed=0)
t1 = toytree.rtree.unittree(10, seed=1)
toytree.mtree([t0, t1]).draw(ts='p', height=200);
Explanation: get two random trees
End of explanation
t0.draw(
    ts='p',
    node_colors="lightgrey",
    edge_widths=3,
    edge_colors=t0.get_edge_values_mapped(
        {11: 'red', 3: 'pink', 4: 'blue', 18: 'aqua', 12: 'black'},
    ),
);
Explanation: Plan for counting quartets (Illustrated below)
We will traverse the tree visiting every node in turn. At each node we will select the edge above it (towards the root) to be the focal 'split'. Each split can represent many possible quartets, where at least one tip can be sampled from each of the four edges leading from the split. In the example below, we are visiting node 12, and the focal split is shown in black. The four edges leaving this split are shown in red, pink, blue, and aqua. To get all quartets from this split we must sample all possible combinations of one sample from each colored set.
End of explanation
# focal node
nidx = 12
# get all tips as a set
fullset = set(i for i in t0.get_tip_labels())
# get tips from each child of a given node
down0 = set(t0.idx_dict[nidx].children[0].get_leaf_names())
down1 = set(t0.idx_dict[nidx].children[1].get_leaf_names())
up0 = set(t0.idx_dict[nidx].up.get_leaf_names()) - down0 - down1
up1 = fullset - down0 - down1 - up0
print(down0)
print(down1)
print(up0)
print(up1)
Explanation: Example to sample tips from each quartet edge
End of explanation
set(itertools.product(down0, down1, up0, up1))
Explanation: Example to get all quartet sets from sampled tips
End of explanation
def get_quartets(ttre):
    
    # store all quartets in this SET
    qset = set([])
    
    # get a SET with all tips in the tree
    fullset = set(ttre.get_tip_labels())
    
    # get a SET of the descendants from each internal node
    for node in ttre.idx_dict.values():   
        # skip leaf nodes
        if not node.is_leaf():
            
            children = set(node.get_leaf_names())
            prod = itertools.product(
                itertools.combinations(children, 2),
                itertools.combinations(fullset - children, 2),
            )
            quartets = set([tuple(itertools.chain(*i)) for i in prod])
            qset = qset.union(quartets)
    # order tups in sets
    sorted_set = set()
    for qs in qset:
        if np.argmin(qs) > 1:
            tup = tuple(sorted(qs[2:]) + sorted(qs[:2]))
            sorted_set.add(tup)
        else:
            tup = tuple(sorted(qs[:2]) + sorted(qs[2:]))
            sorted_set.add(tup)            
    
    return sorted_set
get_quartets(t1)
Explanation: Combine into a function
End of explanation
q0 = get_quartets(t0)
q1 = get_quartets(t1)
# quartets that are in one tree but not the other
q0.symmetric_difference(q1)
Explanation: Compare quartet sets
End of explanation
<END_TASK>