o
    Rŀg=                     @   s   d Z ddlZddlZddlZddlmZ dZdZdZdZ	e
dee d	ee	 d
ZG dd deZG dd dZG dd dejZdddZdS )a  Tree class to handle phylogenetic trees.

Provides a set of methods to read and write newick-format tree descriptions,
get information about trees (monphyly of taxon sets, congruence between trees,
common ancestors,...) and to manipulate trees (re-root trees, split terminal
nodes).
    N   )Nodes   z[&](|z|[(),])c                   @   s   e Zd ZdZdS )	TreeErrorz0Provision for the management of Tree exceptions.N)__name__
__module____qualname____doc__ r   r   C/var/www/html/myenv/lib/python3.10/site-packages/Bio/Nexus/Trees.pyr       s    r   c                   @   s   e Zd ZdZdddZdS )NodeDatazGStore tree-relevant data associated with nodes (e.g. branches or otus).N        c                 C   s   || _ || _|| _|| _dS )zInitialize the class.N)taxonbranchlengthsupportcomment)selfr   r   r   r   r   r   r   __init__'   s   
zNodeData.__init__)Nr   NN)r	   r
   r   r   r   r   r   r   r   r   $   s    r   c                   @   sl  e Zd ZdZddddeddfddZdd	 ZdOd
dZdd Zdd Z	dPddZ
dd ZdQddZdd Zdd ZdPddZdd Zdd  Zd!d" Zd#d$ ZdPd%d&ZdRd(d)ZdOd*d+Zd,d- Zd.d/ ZdRd0d1Zd2d3 Zd4d5 Zd6d7 ZdPd8d9Zd:d; Zd<d= ZdPd>d?Z 					'dSd@dAZ!dBdC Z"			'			'dTdDdEZ#dFdG Z$dHdI Z%dPdJdKZ&	dUdMdNZ'dS )VTreezmRepresent a tree using a chain of nodes with on predecessor (=ancestor) and multiple successors (=subclades).N      ?F c                 C   s   t j|  || _|| _|| _|| _|| _|| _t 	| }| 
|| _|rR| dddd}|d}| |\}	}
| |jg |
g|_| j|j|	d dS dS )zNtree(self,tree).
r   ;)	parent_idtreeN)r   Chainr   	dataclass_Tree__values_are_supportmax_supportweightrootednameNodeaddrootstripreplacerstrip_parse_add_nodedatadata_add_subtreeid)r   r   r#   r$   r%   r.   values_are_supportr"   r(   subtree_info	base_infor   r   r   r   ;   s    
zTree.__init__c                    s\  |  }|d|dkrtd| |ddkr|t}|d}|dkr7|dkr7|dg}}||gS |dkrS|dkrS|d|  ||d }}||gS |dkrq|dkrq|d|  ||d d }}||gS ||k r|d|  ||d d }}||gS |d|  ||d }}||gS |d} ||d d }|sdg}g }d}	d}
d	}t|d| }t	|D ]N\}}|s|dkr|	d7 }	q|dkr|	d8 }	q|tkrd
}q|dkr|	dkrt
dd |d|d  D }|||
|  |d }
q|tkrd	}q|||
|   fdd|D }||gS )zVParse (a,b,c...)[[[xx]:]yy] into subcomponents and travels down recursively (PRIVATE).r   )z'Parentheses do not match in (sub)tree: r   :Nr   FT,c                 s   s    | ]}t |V  qd S N)len).0blkr   r   r   	<genexpr>       zTree._parse.<locals>.<genexpr>c                       g | ]}  |qS r   )r,   )r:   subtreer   r   r   
<listcomp>       zTree._parse.<locals>.<listcomp>)r)   countr   findNODECOMMENT_START_get_valuesrfind_re_block_delimiterssplit	enumeratesumappendNODECOMMENT_END)r   r   nodecommentcolonbranchr   closingvalsubtreesplevelprev	incommentblocksidxr;   p	subcladesr   r@   r   r,   X   sh   


$
$




zTree._parsec                 C   s   |du rt d|D ]8}|  }| ||}t|d tr2t|}| || | |j	|d  q
|d |_
t|}| || q
dS )z=Add leaf or tree (in newick format) to a parent_id (PRIVATE).NzNeed node_id to connect to.r   )r   r    r-   
isinstancelistr   r&   r'   r/   r0   r   )r   r   r   stndsnleafr   r   r   r/      s   


zTree._add_subtreec                 C   s   t |d d tr|d d tr|d d|_nt |d d tr5|d d |_|d dd |d< t|dkr~t|d dkr[|d d |_|d d durY|d d |_	|S t|d dkr~| j
sw|d d duru|d d |_	|S |d d |_|S )zKAdd data to the node parsed from the comments, taxon and support (PRIVATE).r   r6   r   N   )r[   str
startswithrE   popr   r   r9   r   r   r!   )r   r^   r]   r   r   r   r-      s$   $	zTree._add_nodedatac              	   C   s   |dkrdS d}t |v r8|t }|t}|dkr"tdt tf |||d  }|d| ||d d  }g }d}dd |dD D ]!}|rgz	|t| W qF tyf   |du sbJ d	|}Y qFw qF|rp|d
| |rw|| |S )zBExtract values (support/branchlength) from xx[:yyy], xx (PRIVATE).r   Nr6   z7Error in tree description: Found %s without matching %sr   c                 S   s   g | ]}|  qS r   )r)   )r:   tr   r   r   rA      s    z$Tree._get_values.<locals>.<listcomp>r5   zTwo string taxonomies?r   )	rE   rD   rM   r   rI   rL   float
ValueErrorinsert)r   textrN   nc_startnc_endvaluestaxonomypartr   r   r   rF      s<   


zTree._get_valuesc                 c   s<    |du r| j }| |jD ]}|V  | |E dH  qdS )z4Return all node_ids downwards from a node (PRIVATE).N)r(   nodesucc_walkr   ro   nr   r   r   rq      s   z
Tree._walkc                 C   s    || j vrtd| | j | S )zKReturn the instance of node_id.

        node = node(self,node_id)
        zUnknown node_id: %d)chainr   )r   node_idr   r   r   ro      s   

z	Tree.nodera   c                 C   sz   |du rt dg }| j| j}t|D ]&}t }|r1|  |_|jr-|jt| |j_||j_	|
| || q|S )zSpeciation: generates n (default two) descendants of a node.

        [new ids] = split(self,parent_id=None,n=2,branchlength=1.0):
        NzMissing node_id.)r   rt   r.   ranger   r&   r    r   rb   r   rL   r'   )r   r   rs   r   idsparent_datairo   r   r   r   rI      s   
z
Tree.splitc                 C   s,   | j  D ]\}}|jj|kr|  S qdS )zReturn the first matching taxon in self.data.taxon. Not restricted to terminal nodes.

        node_id = search_taxon(self,taxon)

        N)rt   itemsr.   r   )r   r   r0   ro   r   r   r   search_taxon  s
   zTree.search_taxonc                 C   s   |  |}|du rtd| ||  vrtd| | |}| | t| |jdkrp|| jkrN| | jjd | _d| | j_	| | |S | |jd }| |j
j	| |j
j	 }| | || |j
_	|S )a!  Prune a terminal taxon from the tree.

        id_of_previous_node = prune(self,taxon)
        If taxon is from a bifurcation, the connectiong node will be collapsed
        and its branchlength added to remaining terminal node. This might be no
        longer a meaningful value'
        NzTaxon not found: zNot a terminal taxon: r   r   r   )r{   r   get_terminalsunlinkkillr9   ro   rp   r(   r   r.   collapse)r   r   r0   rU   rp   new_blr   r   r   prune  s*   




	
z
Tree.prunec                 C   s~   |du r| j }|| jvrtd| | j| jg kr*| j| jr(| j| jjgS dS g }| j| jD ]
}|| | q2|S )zfReturn a list of all otus downwards from a node.

        nodes = get_taxa(self,node_id=None)
        NzUnknown node_id: %d.)r(   rt   r   rp   r.   r   extendget_taxa)r   ru   r\   rp   r   r   r   r   1  s   
zTree.get_taxac                    s    fdd   D S )z$Return a list of all terminal nodes.c                    s    g | ]}  |jg kr|qS r   ro   rp   r:   ry   r@   r   r   rA   G       z&Tree.get_terminals.<locals>.<listcomp>)all_idsr@   r   r@   r   r|   E  s   zTree.get_terminalsc                 C   s   |  |jg kS )z'Return True if node is a terminal node.r   r   ro   r   r   r   is_terminalI  s   zTree.is_terminalc                 C   s   t | |jdkS )z(Return True if node is an internal node.r   )r9   ro   rp   r   r   r   r   is_internalM  s   zTree.is_internalc                    s,     |rd fdd |jD vS dS )z:Return True if all successors of a node are terminal ones.Fc                    r>   r   r   r:   rs   r@   r   r   rA   T  rB   z'Tree.is_preterminal.<locals>.<listcomp>)r   ro   rp   r   r   r@   r   is_preterminalQ  s   
zTree.is_preterminalc                    s*   |du r j }t fdd |D S )z?Count the number of terminal nodes that are attached to a node.Nc                    s   g | ]	}  |r|qS r   r   r   r@   r   r   rA   \  s    z(Tree.count_terminals.<locals>.<listcomp>)r(   r9   rq   r   r   r@   r   count_terminalsX  s   zTree.count_terminalsTc           	   
   C   s   	 |   D ]f}| |rq| |}g }|D ])}|r |dd}z
|ddd }W n ty5   d}Y nw ||vr?|| qt|dkrk|d d | |j	_
t| j |d}|D ]}| | q[g | |_ nqd	S q)
z|Collapse all subtrees which belong to the same genus.

        (i.e share the same first word in their taxon name.)
        T _r   r   Nonez <collapsed>ro   N)rq   r   r   r*   rI   
IndexErrorrL   r9   ro   r.   r   r\   r~   rp   )	r   space_equals_underscorers   taxagenerare   genus
nodes2killknr   r   r   collapse_genera^  s6   


	zTree.collapse_generac                 C   sd   |du r| j }|du rtdd}|dur0||ur0|| |jj7 }| |j}|dur0||us|S )zAdd up the branchlengths from root (default self.root) to node.

        sum = sum_branchlength(self,root=None,node=None)
        NzMissing node id.r   )r(   r   ro   r.   r   rU   )r   r(   ro   blenr   r   r   sum_branchlength}  s   zTree.sum_branchlengthc              
      s     |jg kr  |jjS zt fdd  |jD W S  tyW   t| t  |j   |jD ]}t| d |  q8t fdd  |jD   w )zWReturn subtree as a set of nested sets.

        sets = set_subtree(self,node)
        c                 3   s    | ]}  |V  qd S r8   set_subtreer   r@   r   r   r<     s    z#Tree.set_subtree.<locals>.<genexpr>r   c                    r>   r   r   r   r@   r   r   rA     rB   z$Tree.set_subtree.<locals>.<listcomp>)ro   rp   r.   r   	frozenset	Exceptionprintr   rr   r   r@   r   r     s    zTree.set_subtreec                 C   s   |  | j| |jkS )zXCompare tree and tree2 for identity.

        result = is_identical(self,tree2)
        )r   r(   )r   tree2r   r   r   is_identical  s   zTree.is_identicalc                    s0  t   t   }t  t    }|r>|s|r>|r,tdd| jf  |r:tdd|jf  td fdd  D }fdd D }g }|D ];\}	}
|D ]4\}}|	|s||	s|	|@ ||	 |	| }}}|r||s||s||	|
|||||f q`qZ|S )zyCompare branches with support>threshold for compatibility.

        result = is_compatible(self,tree2,threshold)
        z'Taxon/taxa %s is/are missing in tree %sr7   z6Can't compare trees with different taxon compositions.c                    s`   g | ],}  |jr.  |jr.  |jjr.  |jjkrt |  |jjfqS r   ro   rp   r.   r   setr   r   )r   	thresholdr   r   rA     s    

z&Tree.is_compatible.<locals>.<listcomp>c                    s`   g | ],} |jr. |jr. |jjr. |jj krt| |jjfqS r   r   r   )r   r   r   r   rA     s    

)	r   r   r   joinr%   r   r   issubsetrL   )r   r   r   strictmissing2missing1t1t2conflictst1sup1st2sup2	intersectnotin1notin2r   )r   r   r   r   is_compatible  sV   

zTree.is_compatiblec                    sB   | j g| | j | }| j g| | j |   fdd|D d S )zqReturn the common ancestor that connects two nodes.

        node_id = common_ancestor(self,node1,node2)
        c                    s   g | ]}| v r|qS r   r   r   l2r   r   rA         z(Tree.common_ancestor.<locals>.<listcomp>r6   )r(   trace)r   node1node2l1r   r   r   common_ancestor  s   zTree.common_ancestorc                 C   s$   |  ||}| ||| || S )zrAdd and return the sum of the branchlengths between two nodes.

        dist = distance(self,node1,node2)
        )r   r   )r   r   r   car   r   r   distance  s   zTree.distancec                 C   s^   t |}| j}	 t | |}||kr|S | j| jD ]}t | ||r+|} nqdS q)zReturn node_id of common ancestor if taxon_list is monophyletic, -1 otherwise.

        result = is_monophyletic(self,taxon_list)
        Tr6   )r   r(   r   rt   rp   
issuperset)r   
taxon_list	taxon_setru   subclade_taxasubnoder   r   r   is_monophyletic  s   zTree.is_monophyleticc                 C   s   |du r| j }|| j kr7t| |jdkr7| | |jd o6| | |jd o6| | |jd S t| |jdkrW| | |jd oV| | |jd S t| |jdkrcdS dS )z?Return True if tree downstream of node is strictly bifurcating.N   r   r   ra   TF)r(   r9   ro   rp   is_bifurcatingr   r   r   r   r     s   zTree.is_bifurcatingc                 C   s6   | j D ]}| |jj| |j_d| |j_qdS )zMove values stored in data.branchlength to data.support, and set branchlength to 0.0.

        This is necessary when support has been stored as branchlength (e.g. paup), and has thus
        been read in as branchlength.
        r   N)rt   ro   r.   r   r   )r   rs   r   r   r   branchlength2support  s   
zTree.branchlength2supportc                 C   s6   |   D ]}| |jjr| |j j|  _qdS )zConvert absolute support (clade-count) to rel. frequencies.

        Some software (e.g. PHYLIP consense) just calculate how often clades appear, instead of
        calculating relative frequencies.
        Nrq   ro   r.   r   )r   nreprs   r   r   r   convert_absolute_support$  s
   zTree.convert_absolute_supportc                 C   s(   |  |D ]}| |jjr dS qdS )z9Return True if any of the nodes has data.support != None.TFr   rr   r   r   r   has_support.  s
   zTree.has_supportc                 C   s
  |s	|r	t |}n |s|rdd t|D }n|s|std|t |kr)td|   |  }t ||k rmt|}| j||d}|r]|D ]}	t||}
|
dk rUd}
|
| 	|	j
_qG|| || t ||k s7t| t||D ]\}}|| 	|j
_qwdS )a  Generate a random tree with ntax taxa and/or taxa from taxlabels.

        new_tree = randomize(self,ntax=None,taxon_list=None,branchlength=1.0,branchlength_sd=None,bifurcate=True)
        Trees are bifurcating by default. (Polytomies not yet supported).
        c                 S   s   g | ]
}d t |d  qS )r   r   )rb   r   r   r   r   rA   F  s    z"Tree.randomize.<locals>.<listcomp>z8Either number of taxa or list of taxa must be specified.z-Length of taxon list must correspond to ntax.)r   r   r   N)r9   rv   r   r   r|   randomchoicerI   gaussro   r.   r   r   removeshufflezipr   )r   ntaxr   r   branchlength_sd	bifurcate	terminalsnewsplitnew_terminalsntblro   r%   r   r   r   	randomize6  s4   




zTree.randomizec           	      C   s  dg}|   D ]m}| |}|js'|t|dt|jt|jddddf q|jj}|s/d}|jjd}|du r>d}d}n| j	|dd}|jj
}|du rQd}n|d}|jj}|du r_d}|t||t|jt|j||||f qtddd |D  td	| j  dS )
z#Quick and dirty lists of all nodes.)#r   rU   rp   brlenz
blen (sum)r   r   -z0.2fNr   r   c                 s   s    | ]}d | V  qdS )z$%3s %32s %15s %15s %8s %10s %8s %20sNr   )r:   liner   r   r   r<     r=   zTree.display.<locals>.<genexpr>z
Root:  )r   ro   r.   rL   rb   rU   rp   r   r   r   r   r   r   r   r(   )	r   tablery   rs   txblengthsum_blengthr   r   r   r   r   display`  sL   
"zTree.displayc           
         s  |s|rd}|_ |_ _|_d fdd	dfdd	dfdd	d	g}jr8|j n|d
 |d jdkrV|dttjdd j	r^|d 
jj}fdd|D }	|dd|	 d |r|d S d|d S )z#Return a paup compatible tree line.Fc                    s  j rd}nbjr!|rdjd}nU| jrd| jd}nJd}nGjr,d| jd}n<|r6d| jd}n2| jdurL| jdurL| jdd| jd}n| jdurYd| jd}n| jdurf| jdd}nd	} sz
t| j| }W |S  ty~   Y |S w |S )
z.Create nicely formatted support/branchlengths.r   r5   z1.2fz:0.00z1.5fNz0.00000:z:0.00000z0.00:0.00000)	plainsupport_as_branchlengthsr"   r   branchlengths_onlyr   rb   rN   AttributeError)r.   terminalinfo_string)ignore_commentsr   r   r   make_info_string  s:   

z(Tree.to_string.<locals>.make_info_stringNc                    s^   |dv r+t  fdd| D }|dks|dkr|  |r'tt| d }|S g }|S | }|S )z<Sort node numbers according to the number of terminal nodes.)leftLEFTrightRIGHTc                 3   s     | ]} j |d |fV  qdS )r   N)r   r   r@   r   r   r<     s    
z:Tree.to_string.<locals>.ladderize_nodes.<locals>.<genexpr>r   r   r   )sortedreverser\   r   )nodes	ladderizesuccnode_terminals	succnodesr@   r   r   ladderize_nodes  s   z'Tree.to_string.<locals>.ladderize_nodesc                    sx    | js | jj | jdd S  | j d} fdd|D }dd| d | j S )	z1Convert a node tree to a newick tree recursively.T)r   r   c                       g | ]}| d qS r   r   r:   r_   r   	newickizer   r   rA     r   z5Tree.to_string.<locals>.newickize.<locals>.<listcomp>r   r7   r4   )ro   rp   r.   r   r   )ro   r   r   rS   )r   r   r   r   r   r   r     s   "z!Tree.to_string.<locals>.newickizer   a_tree=r   z[&Wr   r   z[&R]c                    r   r   r   r   r   r   r   rA     r   z"Tree.to_string.<locals>.<listcomp>r   r7   r4   r6   r   r   )Fr8   )r   r   r   r   r%   rL   r#   roundrf   r$   ro   r(   rp   r   )
r   r   r   r   plain_newickr   r   treeliner   rS   r   )r   r   r   r   r   r   r   	to_string  s0   %



zTree.to_stringc                 C   s   | j ddS )z/Short version of to_string(), gives plain tree.T)r   )r  r@   r   r   r   __str__  s   zTree.__str__c                    sN   fdd  j _tj jdkrfddjD }jj|d }jj|d }|d |d |d |d  g}|d d	u rW||d  nF|d d	u re||d  n8|d |d kru||d  n(|d dks|d dkr||d |d   ntd
t	|d t	|d f j| d	S d	S )z>Define a unrooted Tree structure, using data of a rooted Tree.c              	      sN   g } | jD ]}|| | |jj |jjg | | q|S r8   )ro   rp   rL   r.   r   r   r   )ro   branchesb_get_branchesr   r   r   r	    s   z"Tree.unroot.<locals>._get_branchesra   c                    s"   g | ]} j |d d v r|qS Nra   )r(   r:   r  r@   r   r   rA     s   " zTree.unroot.<locals>.<listcomp>r   r   r   Nz,Support mismatch in bifurcating root: %f, %f)
r(   unrootedr9   ro   rp   rd   indexrL   r   rf   )r   rootbranchesb1b2	newbranchr   r  r   unroot  s0   	zTree.unrootc           
         s   fdd |du rj S |}|dkrdS tj jdkr-|j jv s2|j kr5j S   tjD ] \}}||dd v r^|j|dd v r^j	|} nq>t
d||d krn|d }n|d } D ]}d|_g |_qvtjt d	}| |j_ j|j||d |d
 g j|j|ddg  |j|  |j| fdd D }	t|	dkrt
dd|	 t|	dkr|	d  j S )z5Define a tree's root with a reference group outgroup.c                    s   t jD ]\}}| |dd v r! |dd v r!j|} n	qtd|  f |   |d  j_|d  j_ fddjD }|D ]} |d kr[|d }n|d } | qNdS )	z<Attach subtree starting with node child to parent (PRIVATE).Nra   zFUnable to connect nodes for rooting: nodes %d and %d are not connectedr   c                    s    g | ]} |d d v r|qS r
  r   r  childr   r   rA   0  r   zETree.root_with_outgroup.<locals>._connect_subtree.<locals>.<listcomp>r   r   )	rJ   r  rd   r   linkro   r.   r   r   )parentr  ry   rP   child_branchesr  rp   _connect_subtreer   r  r   r  !  s(    
z1Tree.root_with_outgroup.<locals>._connect_subtreeNr6   ra   z%Unrooted and rooted Tree do not matchr   r   r.   r   r   c                    s*   g | ]}  |jd u r| jkr|qS r8   )ro   rU   r(   r   r@   r   r   rA   d  s    $z+Tree.root_with_outgroup.<locals>.<listcomp>z$Isolated nodes in tree description: r7   )r(   r   r9   ro   rp   r  rJ   r  rU   rd   r   r   r   r&   r   r'   r0   rL   r   r~   )
r   outgroupoutgroup_nodery   r  root_branchingroup_noders   r(   oldrootr   r  r   root_with_outgroup  sT   

(


zTree.root_with_outgroup      ?c           	         s   |r|rt d|s|st d|du r<z  jj}t fdd|D } |d }W n ty;   t ddw  | |rKt|||d}n|	 sS|
  ||   D ]}| |}|d	krv||jj |j_q\dS )
zMerge clade support (from consensus or list of bootstrap-trees) with phylogeny.

        tree=merge_bootstrap(phylo,bs_tree=<list_of_trees>)
        or
        tree=merge_bootstrap(phylo,consree=consensus_tree with clade support)
        zBSpecify either list of bootstrap trees or consensus tree, not bothz9Specify either list of bootstrap trees or consensus tree.Nc                 3   s"    | ]}t  ||fV  qd S r8   )r9   r   r   r@   r   r   r<     s     z*Tree.merge_with_support.<locals>.<genexpr>r   zError determining outgroup.)r   r  r6   )r   ro   r(   rp   minr   r   r   	consensusr   r   rq   r   r.   r   )	r   bstreesconstreer   r  r   smallestpnodecnoder   r@   r   merge_with_supportm  s4   	


zTree.merge_with_support)NNr8   )Nra   r   )T)NNr   NT)FFTFNT)NNr!  N)(r	   r
   r   r   r   r   r,   r/   r-   rF   rq   ro   rI   r{   r   r   r|   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r   r)  r   r   r   r   r   /   sp    

?
 
	
!



:	





*0
d
(Pr   r!  c                    sX  t | }|dkr
dS | d j}| d j}i }t| d  }| D ]?}|t| kr.td|j|d ||jD ]$}	t	||	}
t
|
}
|
|v rW||
  |j| 7  < q:|j| ||
< q:q fdd| D }|D ]}||= qmtdtd|d	 | D ]\}}tj| d
}||j_tt||j_ | qd  jj_|  jj_  }|j fddd t|dd D ]M\}}||d d D ]} |jj |jjr nqtd t  |jjdkr |jj  |j_nd |j_ || qd |d j_|t  kr*td S )zmCompute a majority rule consensus tree of all clades with relative frequency>=threshold from a list of trees.r   Nz.Trees for consensus must contain the same taxa)r  c                    s"   g | ]\}}t |d  k r|qS )r   )r  )r:   crY   )r   r   r   rA     s    zconsensus.<locals>.<listcomp>
consensus_z2.1f)r%   r.   r  c                    s   t  | jjS r8   )r9   ro   r.   r   )x)r#  r   r   <lambda>  s    zconsensus.<locals>.<lambda>)keyr6   r   zcorrupt tree structure?z&FATAL ERROR: consensus tree is corrupt)r9   r    r"   r   r   r   r   rq   r(   r   rb   r#   rz   r   rf   r   r&   r.   r   evalr   r'   ro   r   sortrJ   r   sysexitrd   r  )treesr   r  totalr    r"   cladesalltaxare   st_noder   	delcladesr*  sro   consensus_idsry   currentr  r   )r#  r   r   r#    sn   




r#  )r!  N)r   r   rer1  r   r   PRECISION_BRANCHLENGTHPRECISION_SUPPORTrE   rM   compileescaperH   r   r   r   r   r   r#  r   r   r   r   <module>   s,         k