o
    RŀgT~                     @   s<  d Z ddlmZ ddlmZ ddiZejZe D ]	\Z	Z
ee	e
 qdZG dd deZd	d
 Zdd ZedfddZdd Zdd Zed fddZdd ZefddZdd ZefddZd:ddZd d! Zd"d# Zd$d% Zd&d' Zd(d) Zd*d+ ZG d,d- d-Z d.d/ Z!d0d1 Z"d;d3d4Z#d5d6 Z$G d7d8 d8Z%d9S )<a  PhyloXML reader/parser, writer, and associated functions.

Instantiates tree elements from a parsed PhyloXML file, and constructs an XML
file from a ``Bio.Phylo.PhyloXML`` object.

About capitalization:
 - phyloXML means the file format specification
 - PhyloXML means the Biopython module ``Bio.Phylo.PhyloXML`` and its classes
 - Phyloxml means the top-level class used by ``PhyloXMLIO.read`` (but not
   ``Bio.Phylo.read``!), containing a list of Phylogenies (objects derived from
   ``BaseTree.Tree``)

    )ElementTree)PhyloXMLphyzhttp://www.phyloxml.orgunicodec                   @   s   e Zd ZdZdS )PhyloXMLErrorzException raised when PhyloXML object construction cannot continue.

    XML syntax errors will be found and raised by the underlying ElementTree
    module; this exception is for valid XML that breaks the phyloXML
    specification.
    N)__name__
__module____qualname____doc__ r   r   H/var/www/html/myenv/lib/python3.10/site-packages/Bio/Phylo/PhyloXMLIO.pyr   '   s    r   c                 C      t |  S )zParse a phyloXML file or stream and build a tree of Biopython objects.

    The children of the root node are phylogenies and possibly other arbitrary
    (non-phyloXML) objects.

    :returns: a single ``Bio.Phylo.PhyloXML.Phyloxml`` object.

    )Parserreadfiler   r   r   r   4      	r   c                 C   r   )a  Iterate over the phylogenetic trees in a phyloXML file.

    This ignores any additional data stored at the top level, but may be more
    memory-efficient than the ``read`` function.

    :returns: a generator of ``Bio.Phylo.PhyloXML.Phylogeny`` objects.

    )r   parser   r   r   r   r   @   r   r   Tc                    s~   dd  t | tjrn*t | tjjtjjfr |  } nt| dr1tji  fdd| D d} ntdt	| j
|||dS )	aR  Write a phyloXML file.

    :Parameters:
        obj
            an instance of ``Phyloxml``, ``Phylogeny`` or ``BaseTree.Tree``,
            or an iterable of either of the latter two. The object will be
            converted to a Phyloxml object before serialization.
        file
            either an open handle or a file name.

    c                 S   sj   t | tjr| S t | tjr|  S t | tjjrtj| S t | tjjr1tjtjj| dS td)N)rootz)iterable must contain Tree or Clade types)	
isinstancePX	PhylogenyCladeto_phylogenyBaseTreeTree	from_tree
ValueError)treer   r   r   
fix_singleY   s   zwrite.<locals>.fix_single__iter__c                 3   s    | ]} |V  qd S Nr   ).0tr   r   r   	<genexpr>j   s    zwrite.<locals>.<genexpr>)phylogenieszXFirst argument must be a Phyloxml, Phylogeny, Tree, or iterable of Trees or Phylogenies.)encodingindent)r   r   Phyloxmlr   r   r   to_phyloxmlhasattrr   Writerwrite)objr   r'   r(   r   r$   r   r-   L   s   
r-   c                 C   s&   | d dkr| |  dd d S | S )z;Extract the local tag from a namespaced tag name (PRIVATE).r   {}   N)indextagr   r   r   _localw   s   r5   c                 C   s2   z| dd  ddW S  ty   d| f Y S w )z;Split a tag into namespace and local tag strings (PRIVATE).r1   Nr0    )splitr   r3   r   r   r   _split_namespace~   s
   r8   c                 C   s   d| d|  S )z5Format an XML tag with the given namespace (PRIVATE).r/   r0   r   )r4   	namespacer   r   r   _ns   s   r:   c                 C   s"   |  t|}|dur||S dS )z|Find a child node by tag, and pass it through a constructor (PRIVATE).

    Returns None if no matching child is found.
    N)findr:   parentr4   	constructchildr   r   r   _get_child_as   s   r@   c                 C   s.   |  t|}|dur|jr||jS dS dS )z~Find a child node by tag; pass its text through a constructor (PRIVATE).

    Returns None if no matching child is found.
    N)r;   r:   textr<   r   r   r   _get_child_text   s   
rB   c                        fdd|  t|D S )zFind child nodes by tag; pass each through a constructor (PRIVATE).

    Returns an empty list if no matching child is found.
    c                    s   g | ]} |qS r   r   r"   r?   r>   r   r   
<listcomp>   s    z$_get_children_as.<locals>.<listcomp>findallr:   r=   r4   r>   r   rE   r   _get_children_as      rJ   c                    rC   )zFind child nodes by tag; pass each node's text through a constructor (PRIVATE).

    Returns an empty list if no matching child is found.
    c                    s   g | ]
}|j r |j qS r   rA   rD   rE   r   r   rF      s    z&_get_children_text.<locals>.<listcomp>rG   rI   r   rE   r   _get_children_text   rK   rM   c                 C   s   d|d  }t | r?| jr| j s|d | _| D ]}t||d  |jr*|j s/|d |_q|jr8|j s=||_dS dS |rN| jrI| j sP|| _dS dS dS )zAdd line breaks and indentation to ElementTree in-place (PRIVATE).

    Sources:
     - http://effbot.org/zone/element-lib.htm#prettyprint
     - http://infix.se/2007/02/06/gentlemen-indent-your-xml

    
z  r1   N)lenrA   strip_indenttail)elemlevelier   r   r   rQ      s   



rQ   c                 C   s4   | dks| dkr
dS | dks| dkrdS t d|  )z$Convert string to boolean (PRIVATE).true1Tfalse0Fz*String could not be converted to boolean: )r   rL   r   r   r   	_str2bool   s
   r[   c                 C   s.   |   }|D ]}||v rt|| ||< q|S )zQReturn a new dictionary where string values are replaced with booleans (PRIVATE).)copyr[   )dctkeysoutkeyr   r   r   _dict_str2bool   s   ra   c                 C   ,   | durzt | W S  ty   Y dS w dS )z$Return text as an integer (PRIVATE).N)int	ExceptionrL   r   r   r   _int      
re   c                 C   rb   )z!Return text as a float (PRIVATE).N)floatrd   rL   r   r   r   _float   rf   rh   c                 C   s   | durd |  S dS )a  Replace all spans of whitespace with a single space character (PRIVATE).

    Also remove leading and trailing whitespace. See "Collapse Whitespace
    Policy" in the phyloXML spec glossary:
    http://phyloxml.org/documentation/version_100/phyloxml.xsd.html#Glossary
    N )joinr7   rL   r   r   r   _collapse_wspace   s   rk   c                 C   s"   dD ]}|| v r|  |d} q| S )zReplace tab, LF and CR characters with spaces, but don't collapse (PRIVATE).

    See "Replace Whitespace Policy" in the phyloXML spec glossary:
    http://phyloxml.org/documentation/version_100/phyloxml.xsd.html#Glossary
    )	rN   ri   )replace)rA   charr   r   r   _replace_wspace   s
   rp   c                   @   s  e Zd ZdZdd Zdd Zdd Zdd	 Zg d
ZdddddZ	e
ee	 g dZdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd  Zd!d" Zd#d$ Zd%d& Zd'd( Zd)d* Zd+d, Zd-d. Zd/d0 Zd1d2 Zd3d4 Zd5d6 Z d7d8 Z!d9d: Z"d;d< Z#d=d> Z$d?S )@r   a  Methods for parsing all phyloXML nodes from an XML stream.

    To minimize memory use, the tree of ElementTree parsing events is cleared
    after completing each phylogeny, clade, and top-level 'other' element.
    Elements below the clade level are kept in memory until parsing of the
    current clade is finished -- this shouldn't be a problem because clade is
    the only recursive element, and non-clade nodes below this level are of
    bounded size.
    c                 C   s.   t tj|dd}t|\}}|| _|| _dS )zInitialize the class.)startend)eventsN)iterr   	iterparsenextr   context)selfr   rw   eventr   r   r   r   __init__  s   
zParser.__init__c           	      C   s   t dd | j D }d}| jD ]M\}}t|j\}}|dkr;|td kr,|d7 }q|dkr;| |}|j	
| |dkr_|td kr_|d8 }|dkr_| |||}|j
| | j  q|S )	z<Parse the phyloXML file and create a single Phyloxml object.c                 S   s   i | ]	\}}t ||qS r   )r5   )r"   r`   valr   r   r   
<dictcomp>  s    zParser.read.<locals>.<dictcomp>r   rq   r   r1   	phylogenyrr   )r   r)   r   itemsrw   r8   r4   
NAMESPACES_parse_phylogenyr&   appendotherclear)	rx   phyloxmlother_depthry   rS   r9   localtagr}   otrr   r   r   r     s&   

zParser.readc                 c   s<    t d}| jD ]\}}|dkr|j|kr| |V  qdS )z@Parse the phyloXML file incrementally and return each phylogeny.r}   rq   N)r:   rw   r4   r   )rx   phytagry   rS   r   r   r   r   1  s   zParser.parsec                 C   s6  t jdi t|jddg}ddddd}| jD ]\}}t|j\}}|dkr;|d	kr;|jd
ur4td| 	||_q|dkr|dkrJ|
   |S ||v r^t||| t| || q|dv rnt||t| || q|dv r|t||t|j q|td kr|j| ||| |
  qtd| q|S )a  Parse a single phylogeny within the phyloXML tree (PRIVATE).

        Recursively builds a phylogenetic tree with help from parse_clade, then
        clears the XML event history for the phylogeny element and returns
        control to the top-level parsing function.
        rooted
rerootableconfidences
propertiesclade_relationssequence_relations)
confidencepropertyclade_relationsequence_relationrq   cladeNz)Phylogeny object should only have 1 claderr   r}   )dateid)namedescriptionr   Misidentified tag: r   )r   r   ra   attribrw   r8   r4   r   r   _parse_clader   getattrr   setattrrk   rA   r   r   r   )rx   r=   r}   
list_typesry   rS   r9   r4   r   r   r   r   :  s@   
 
zParser._parse_phylogeny)colorrs   binary_charactersr   r   distributions
referencesr   )r   distribution	referencer   )branch_lengthr   node_idwidthc                 C   s  t jdi |j}|jdurt|j|_g }| jD ]\}}t|j\}}|dkr\|dkr6|j	| 
| q|dkrD|j	| | q|dkrR|j	| | q|| jv r\|	| |dkr|dkrk|   |S ||d krrq|  || jv rt|| j| 	t| || q|| jv rt||t| || q|dkr|jdurtd	t|j|_q|d
krt|j|_q|dkrt|j|_q|dkrt |j |jd|_q|t d kr|j!	| !||| |  qtd| q|S )z;Parse a Clade node and its children, recursively (PRIVATE).Nrq   r   taxonomysequencerr   r   z7Attribute branch_length was already set for this Clade.r   r   r   providerr   r   r   )"r   r   r   r   rg   rw   r8   r4   cladesr   r   
taxonomies_parse_taxonomy	sequences_parse_sequence_clade_tracked_tagsr   pop_clade_list_typesr   _clade_complex_typesr   r   rh   rA   r   rk   r   IdrP   getr   r   r   )rx   r=   r   	tag_stackry   rS   r9   r4   r   r   r   r   u  sh   






"zParser._parse_cladec                 C   s   t jd	i |j}| jD ]d\}}t|j\}}|dkrp|dkr&|   |S |dv r6t||t| || q|dkrD|j	
| | q|dkrOt|j|_q|dv r[t|||j q|td krp|j
| ||| |  q|S )
z%Parse a molecular sequence (PRIVATE).rr   r   )	accessionmol_sequridomain_architecture
annotationr   )symbollocationr   Nr   )r   Sequencer   rw   r8   r4   r   r   r   annotationsr   r   rk   rA   r   r   r   )rx   r=   r   ry   rS   r9   r4   r   r   r   r     s*   zParser._parse_sequencec                 C   s   t jd	i |j}| jD ]e\}}t|j\}}|dkrq|dkr&|   |S |dv r6t||t| || q|dkrD|j	
t|j q|dkrP|j
|j q|dv r\t|||j q|td krq|j
| ||| |  q|S )
z2Parse taxonomic information for a clade (PRIVATE).rr   r   )r   r   common_namesynonym)codescientific_name	authorityrankr   Nr   )r   Taxonomyr   rw   r8   r4   r   r   r   common_namesr   rk   rA   synonymsr   r   )rx   r=   r   ry   rS   r9   r4   r   r   r   r     s*   zParser._parse_taxonomyc                    s4   t j|||j|jr|j pd fdd|D dS )z/Create an Other object, a non-phyloXML element.Nc                    s$   g | ]} j |gt|jR  qS r   )r   r8   r4   rD   rx   r   r   rF     s    z Parser.other.<locals>.<listcomp>)valuechildren)r   Otherr   rA   rP   )rx   rS   r9   r   r   r   r   r     s   
zParser.otherc                 C   s   t |j |dS )zCreate accession object.source)r   	AccessionrA   rP   r   rx   rS   r   r   r   r        zParser.accessionc              	   C   sD   t jdtt|dt|d| jt|d| jt|d| jd|j	S )zCreate annotation object.descr   r   r   )r   r   r   r   Nr   )
r   
Annotationrk   rB   r@   r   rJ   r   r   r   r   r   r   r   r     s   zParser.annotationc                 C   sr   dd }t j|dt|dt|dt|dt|dt|d|t|d	|t|d
|t|d|d	S )z Create binary characters object.c                 S   s
   t | dS )z$Get binary characters from subnodes.bc)rM   rS   r   r   r   	bc_getter  s   
z+Parser.binary_characters.<locals>.bc_gettertypegained_count
lost_countpresent_countabsent_countgainedlostpresentabsent)	r   r   r   r   r   r   r   r   r   )r   BinaryCharactersr   re   r@   )rx   rS   r   r   r   r   r     s   



zParser.binary_charactersc              	   C   s6   t j|d|d|d|dt|d| jdS )z!Create clade relationship object.r   id_ref_0id_ref_1distancer   r   r   )r   CladeRelationr   r@   r   r   r   r   r   r     s   zParser.clade_relationc                    s&    fdddD \}}}t |||S )zCreate branch color object.c                 3   s    | ]	}t  |tV  qd S r!   )rB   rc   )r"   r   r   r   r   r%     s    
zParser.color.<locals>.<genexpr>redgreenblue)r   BranchColor)rx   rS   r   r   r   r   r   r   r     s   
zParser.colorc                 C   s   t t|j|dS )zCreate confidence object.r   )r   
Confidencerh   rA   r   r   r   r   r   r     r   zParser.confidencec              	   C   s<   t j|dtt|dt|dtt|dtt|dtdS )zCreate date object.unitr   r   minimummaximum)r   r   r   r   r   )r   Dater   rk   rB   rg   r   r   r   r   r      s   


zParser.datec                 C   s.   t jtt|dt|d| jt|d| jdS )z&Create geographic distribution object.r   pointpolygon)r   pointspolygons)r   Distributionrk   rB   rJ   r   r   r   r   r   r   r   *  s
   zParser.distributionc                 C   sB   t j|j t|dd t|dt|d|ddS )zCreate protein domain object.fromr1   tor   r   )r   r   )r   ProteinDomainrA   rP   rc   r   rh   r   r   r   r   domain2  s   zParser.domainc                 C   s"   t jt|dt|d| jdS )z"Create domain architecture object.lengthr   )r   domains)r   DomainArchitecturerc   r   rJ   r   r   r   r   r   r   <  s   zParser.domain_architecturec              	   C   s<   t jt|dt|dtt|dtt|dtt|d| jdS )zCreate events object.r   duplicationsspeciationslossesr   r   r   r   r   r   )r   EventsrB   rc   r@   r   r   r   r   r   rs   C  s   


zParser.eventsc                 C   s&   | dp	| d}t|j |S )zCreate identifier object.r   r   )r   r   r   rA   rP   )rx   rS   r   r   r   r   r   M  s   z	Parser.idc                 C   s.   | d}|durt|}tj|j |dS )z!Create molecular sequence object.
is_alignedNr   )r   r[   r   MolSeqrA   rP   )rx   rS   r   r   r   r   r   R  s   
zParser.mol_seqc                 C   s8   t j|dt|dtt|dtt|dt|ddS )z,Create point object, coordinates of a point.geodetic_datumlatlongaltalt_unit)r  r  )r   Pointr   rB   rg   r   r   r   r   r   Y  s   


zParser.pointc                 C   s   t jt|d| jdS )z&Create polygon object, list of points.r   )r   )r   PolygonrJ   r   r   r   r   r   r   c  s   zParser.polygonc              	   C   s:   t j|j |d|d|d|d|ddS )z*Create properties from external resources.ref
applies_todatatyper   id_ref)r   r  )r   PropertyrA   rP   r   r   r   r   r   r   g  s   zParser.propertyc                 C   s   t j|dt|ddS )z#Create literature reference object.doir   )r  r   )r   	Referencer   rB   r   r   r   r   r   r  s   zParser.referencec              	   C   s:   t j|d|d|dt|dt|d| jdS )zHCreate sequence relationship object, relationship between two sequences.r   r   r   r   r   r   )r   SequenceRelationr   rh   r@   r   r   r   r   r   r   v  s   zParser.sequence_relationc                 C   s&   t j|j t|d|ddS )z(Create uri object, expected to be a url.r   r   r   r   )r   UrirA   rP   rk   r   r   r   r   r   r     s
   z
Parser.uriN)%r   r   r	   r
   rz   r   r   r   r   r   setunionr^   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rs   r   r   r   r   r   r   r   r   r   r   r   r   r     sN    
	.

9






r   c                 C   s4   t | trt|  S t | trt|  S t| S )zEConvert a Python primitive to a phyloXML-compatible string (PRIVATE).)r   rg   strupperboollower)r   r   r   r   
_serialize  s
   

r  c                 C   s0   i }|D ]}t | |}|durt|||< q|S )zNCreate a dictionary from an object's specified, non-None attributes (PRIVATE).N)r   r  )r.   attrsr_   r`   r{   r   r   r   _clean_attrib  s   
r  Fc                    s$    fdd}d d|_ |S )z2Handle to serialize nodes with subnodes (PRIVATE).c                    s   t t| }D ]2}t|tr't||dur&|t| |t|| q|\}}t||D ]}|t| || q0qrFt|j|_	|S )z$Wrap nodes and subnodes as elements.N)
r   Elementr  r   r  r   r   r  r   rA   )rx   r.   rS   subnmethodpluralitemattribshas_textsubnodesr4   r   r   wrapped  s   
z _handle_complex.<locals>.wrappedzSerialize a z and its subnodes, in order.r
   )r4   r#  r%  r$  r&  r   r"  r   _handle_complex  s   r(  c                    s    fdd}d  d|_ |S )z+Handle to serialize simple nodes (PRIVATE).c                    s   t  }t||_|S )zWrap node as element.)r   r  r  rA   rx   r.   rS   r3   r   r   r&    s   

z_handle_simple.<locals>.wrappedzSerialize a simple z node.r'  )r4   r&  r   r3   r   _handle_simple  s   r*  c                   @   s:  e Zd ZdZdd ZedfddZdd Zd	d
 Ze	dddZ
e	dddZe	dddddZe	dddZdd Ze	dddZe	dddZe	dd dddZe	d!d"d#Ze	d$dd%Zd&d' Ze	d(d)d*Ze	d+dd,Ze	d-d.dddZe	d/d0dddZe	d1d.dddZe	d2d3d4Ze	d5dd6Ze	d7d8dddZe	d9d:d;Ze	d<d=d>Ze	d?ddZe	d@ddAZ e	dBdCdddZ!e"dDZ#e"dEZ$e"dFZ%e"dGZ&e"dHZ'e"dIZ(e"dJZ)e"dKZ*e"dLZ+e"dMZ,e"dNZ-e"dOZ.e"dPZ/e"dQZ0e"dRZ1e"dSZ2e"dTZ3e"dUZ4e"dVZ5e"dWZ6e"dXZ7e"dYZ8e"dZZ9e"d[Z:e"d\Z;e"d]Z<d^S )_r,   z1Methods for serializing a PhyloXML object to XML.c                 C   s*   t |tjs
J dt| || _dS )z,Build an ElementTree from a PhyloXML object.zNot a Phyloxml objectN)r   r   r)   r   r   _tree)rx   r   r   r   r   rz     s   zWriter.__init__Tc                 C   s.   |r	t | j  | j|| t| j S )zWrite PhyloXML to a file.)rQ   r+  getrootr-   rO   )rx   r   r'   r(   r   r   r   r-     s   zWriter.writec                 C   sJ   t d|j}|jD ]
}|| | q
|jD ]
}|| | q|S )z"Convert phyloxml to Etree element.r   )r   r  
attributesr&   r   r}   r   )rx   r.   rS   r   r   r   r   r   r     s   

zWriter.phyloxmlc                 C   s@   t t|j|j|j}|j|_|jD ]
}|	| 
| q|S )zConvert other to Etree element.)r   r  r:   r4   r9   r-  r   rA   r   r   r   )rx   r.   rS   r?   r   r   r   r     s
   
zWriter.otherr}   )r   r   branch_length_unitr   )
r   r   r   r   r   r   r   )r   r   )r   r   r   r   r   r   r   )	id_source)r   r   r/  r   r   r   )r   r   )r   r   rs   r   )r   r   r   )r   r   r0  )r   r   r1  r   )r   r   )r$  r   )r
  r   evidencer   )r   r   r0  r   c                 C   sT   t dt|d}dD ]}t |}t||D ]
}|| | q|| q|S )z4Serialize a binary_characters node and its subnodes.r   )r   r   r   r   r   )r   r   r   r   )r   r  r  r   r   r   )rx   r.   rS   r  subelemtokenr   r   r   r     s   
zWriter.binary_charactersr   )r   r   r   r   )r   r   r   r   )r   r   )r   )r   r   r   r   r   )r   r   r   )r   r   c                 C   sf   t dt|jd t|jd}|jdur|dt|j |jdur+|d|j t|j	|_
|S )zSerialize a domain node.r   r1   )r   r   Nr   r   )r   r  r  rq   rr   r   r  r  r   r   rA   r)  r   r   r   r   6  s   

zWriter.domainr   )r   ))r   r   rs   r   r   )r   r   r  r   r   )r  r  )r  r  r  r   )r6  r   )r
  r   r  r  r  r   )r  )r   r   )r   r  r2  )	r   r   r   r   r   r   )r   r   r   r1  r   r   )	r   r   r   r   )r   r   )r   r   r   r   r1  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   N)=r   r   r	   r
   rz   DEFAULT_ENCODINGr-   r   r   r(  r}   r   r   r   r   r   r   r   r   r   r   r   rs   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   r   r   r   r   r   r   r   r   r   r   r,     s    		r,   N)r   )F)&r
   	xml.etreer   	Bio.Phylor   r   r   register_namespacer~   prefixr   r7  rd   r   r   r   r-   r5   r8   r:   r@   r  rB   rJ   rM   rQ   r[   ra   re   rh   rk   rp   r   r  r  r(  r*  r,   r   r   r   r   <module>   sF   +


				   
	

