
    瞤dk!                         d dl mZ d dl mZ d dlmZ ddlmZ ddlmZ ddlm	Z	m
Z
 dd	lmZ d d
lmZ ddgZ G d de	          ZeZdS )    )absolute_import)print_function)stderr   )clustvalidation   )_translate_nodes)TreeNode
ArrayTable)numpy)rangeClusterNodeClusterTreec                   
   e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
 eee	          Z eee	          Z eee	          Z eee
	          Z ee	e	          Zd
d
ej        fdZd Zd Zd Zd Zd ZddZddZd Zd
S )r   a   Creates a new Cluster Tree object, which is a collection
    of ClusterNode instances connected in a hierarchical way, and
    representing a clustering result.

    a newick file or string can be passed as the first argument. An
    ArrayTable file or instance can be passed as a second argument.

    Examples:
      t1 = Tree() # creates an empty tree
      t2 = Tree( '(A:1,(B:1,(C:1,D:1):0.5):0.5);' )
      t3 = Tree( '/home/user/myNewickFile.txt' )
    c                      t          d          )Nz'This attribute can not be manually set.)
ValueErrorselfvalues     ;lib/python3.11/site-packages/ete3/clustering/clustertree.py_set_forbiddenzClusterNode._set_forbiddenA   s    BCCC    c                 F    | j         |                                  | j        S N)_silhouetteget_silhouette_intracluster_distr   s    r   
_get_intrazClusterNode._get_intraD   &    #!!!&&r   c                 F    | j         |                                  | j        S r   )r   r   _intercluster_distr   s    r   
_get_interzClusterNode._get_interI   r    r   c                 F    | j         |                                  | j         S r   )r   r   r   s    r   	_get_silhzClusterNode._get_silhN   s&    #!!!r   c                 F    | j         |                                  | j         S r   )_profile_calculate_avg_profiler   s    r   	_get_profzClusterNode._get_profS   s$    = '')))}r   c                 F    | j         |                                  | j         S r   )_std_profiler(   r   s    r   _get_stdzClusterNode._get_stdX   s&    $'')))  r   c                     || _         d S r   )r'   r   s     r   _set_profilezClusterNode._set_profile]   s    r   )fgetfsetNc                    t          j        | |           d | _        d | _        d | _        d | _        d | _        d | _        | j        	                    d           | j        	                    d           | j        	                    d           | j        	                    d           | j        	                    d           |r| 
                    |           |r|                     |           d S d S )Nintercluster_distintracluster_dist
silhouetteprofile	deviation)r
   __init___fdistr   r"   r   r'   r+   featuresaddlink_to_arraytableset_distance_function)r   newick
text_arrayfdists       r   r7   zClusterNode.__init__f   s    	$'''"&"&  	-...-...,''')$$$+&&&  	0##J/// 	.&&u-----	. 	.r   c                 J    dt          |                                           z  S )NzClusterTree node (%s))hex__hash__r   s    r   __repr__zClusterNode.__repr__   s    &DMMOO(<(<<<r   c                 l    |                                  D ]}||_        d|_        d|_        d|_        dS )at   Sets the distance function used to calculate cluster
        distances and silouette index.

        ARGUMENTS:

          fn: a pointer to python function acepting two arrays (numpy) as
          arguments.

        EXAMPLE:

          # A simple euclidean distance
          my_dist_fn = lambda x,y: abs(x-y)
          tree.set_distance_function(my_dist_fn)

          N)traverser8   r   r"   r   )r   fnns      r   r<   z!ClusterNode.set_distance_function   sF       	( 	(AAH AM#'A #'A  		( 	(r   c                    t          |          t          k    r|nt          |          g }fdt          t          j                            D             }t          |          _        t          |          _        | 	                                D ]}|_
        |                                r.|j        j        v r                     |j                  |_        K|                                r<t           j        gt          j                  z  |_        |                    |           t          |          dk    r&t)          dt          |          z  t*                     | _
        dS )a   Allows to link a given arraytable object to the tree
        structure under this node. Row names in the arraytable object
        are expected to match leaf names.

        Returns a list of nodes for with profiles could not been found
        in arraytable.

        c                 \    g | ](}j         |         D ]}t          j        |          |)S  )matrixr   isfinite).0riarrays      r   
<listcomp>z2ClusterNode.link_to_arraytable.<locals>.<listcomp>   s[     J J Jq$)LOJ J u~a7H7HJ J J J Jr   r   z7[%d] leaf names could not be mapped to the matrix rows.)fileN)typer   r   lenrK   min_matrix_minmax_matrix_maxrE   
arraytableis_leafnamerowNamesget_row_vectorr'   r   nancolNamesappendprintr   )r   arraytblmissing_leavesmatrix_valuesrG   rP   s        @r   r;   zClusterNode.link_to_arraytable   st    >>Z''EEx((EJ J J JE#el*;*;$<$< J J J  .... 	) 	)A ALyy{{ )qv77"11!&99

 )#i[U^)<)<<
%%a((( ~q  ON##$*02 2 2 2  r   c              #   p   K   |                                  D ]}|                                d         V  dS )z\ Returns an iterator over all the profiles associated to
        the leaves under this node.r   N)iter_leavesget_profile)r   ls     r   iter_leaf_profileszClusterNode.iter_leaf_profiles   sI       !!## 	% 	%A--//!$$$$$	% 	%r   c                 >    d |                                  D             S )zW Returns the list of all the profiles associated to the
        leaves under this node.c                 B    g | ]}|                                 d          S )r   )rg   )rM   rh   s     r   rQ   z1ClusterNode.get_leaf_profiles.<locals>.<listcomp>   s%    ???q"???r   )rf   r   s    r   get_leaf_profileszClusterNode.get_leaf_profiles   s%     @?D,<,<,>,>????r   c                     || j         }t          j        ||           \  | _        | _        | _        | j        | j        | j        fS )a   Calculates the node's silhouette value by using a given
        distance function. By default, euclidean distance is used. It
        also calculates the deviation profile, mean profile, and
        inter/intra-cluster distances.

        It sets the following features into the analyzed node:
           - node.intracluster
           - node.intercluster
           - node.silhouete

        intracluster distances a(i) are calculated as the Centroid
        Diameter

        intercluster distances b(i) are calculated as the Centroid linkage distance

        ** Rousseeuw, P.J. (1987) Silhouettes: A graphical aid to the
        interpretation and validation of cluster analysis.
        J. Comput. Appl. Math., 20, 53-65.

        )r8   r   get_silhouette_widthr   r   r"   )r   r?   s     r   r   zClusterNode.get_silhouette   sO    * =KE 0== 	K$143J !8$:QQQr   c                 R    || j         }t          | g|R  }t          j        |g|R  S )zR Calculates the Dunn index for the given set of descendant
        nodes.
        )r8   r	   r   get_dunn_index)r   clustersr?   nodess       r   get_dunnzClusterNode.get_dunn   s>    
 =KE 1111-e<e<<<<r   c                 H    t          j        |           \  | _        | _        dS )zY This internal function updates the mean profile
        associated to an internal node. N)r   get_avg_profiler'   r+   r   s    r   r(   z"ClusterNode._calculate_avg_profile   s$    
 ,;+J4+P+P(t(((r   r   )__name__
__module____qualname____doc__r   r   r#   r%   r)   r,   r.   propertyr3   r2   r4   r5   r6   r   default_distr7   rC   r<   r;   ri   rl   r   rs   r(   rJ   r   r   r   r   3   s        D D D' ' '
' ' '
     
  
! ! !
   !j~FFF j~FFFy~>>>JhIL999Gh^<<<I $4&3. . . .8= = =( ( (,%  %  % N% % %@ @ @
R R R R<= = = =Q Q Q Q Qr   N)
__future__r   r   sysr    r   coretype.treer	   r
   r   r   	six.movesr   __all__r   r   rJ   r   r   <module>r      s   N ' & & & & & % % % % % %             , , , , , , # # # # # # # #            -
(GQ GQ GQ GQ GQ( GQ GQ GQZ r   