o
    Rŀg*                     @   s   d 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
 ddl	mZ dd	l	mZ d
ddddZee ed ZdZdZejZe D ]	\ZZeee qGdd Zdd Zdd ZG dd deZdd Zd$ddZG dd  d ZG d!d" d"Zd#S )%zLI/O function wrappers for the NeXML file format.

See: http://www.nexml.org
    StringIO)minidom)ElementTree)NeXML   )cdao_elements)cdao_namespaces)resolve_uriz)http://www.w3.org/2001/XMLSchema-instancez$http://www.w3.org/XML/1998/namespacezhttp://www.nexml.org/2009z!http://www.w3.org/2001/XMLSchema#)xsixmlnexxsdr   z0.9z-http://www.nexml.org/2009/nexml/xsd/nexml.xsdc                 C   s   t | tddS )z*Given a prefixed URI, return the full URI.T)
namespaces	xml_style)r
   
NAMESPACESs r   E/var/www/html/myenv/lib/python3.10/site-packages/Bio/Phylo/NeXMLIO.pyqUri+   s   r   c                 C   s   dt | tdd   S )zAOptionally converts a CDAO-prefixed URI into an OBO-prefixed URI.zobo:cdao:N)r   lenr   r   r   r   cdao_to_obo0   s   r   c                 C   s   |  dr| t| fS | fS )z2Check for matches in both CDAO and OBO namespaces.r   )
startswithr   r   r   r   r   matches5   s   
r   c                   @   s   e Zd ZdZdS )
NeXMLErrorz@Exception raised when NeXML object construction cannot continue.N)__name__
__module____qualname____doc__r   r   r   r   r   =   s    r   c                 K   s   t | jdi |S )znIterate over the trees in a NeXML file handle.

    :returns: generator of Bio.Phylo.NeXML.Tree objects.

    Nr   )Parserparse)handlekwargsr   r   r   r"   E   s   r"   Fc                 K   s   t | j|fd|i|S )zeWrite a trees in NeXML format to the given file handle.

    :returns: number of trees written.

    plain)Writerwrite)treesr#   r%   r$   r   r   r   r'   N   s   r'   c                   @   sB   e Zd ZdZdd Zedd Zdd Zdd	d
Zedd Z	dS )r!   z]Parse a NeXML tree given a file handle.

    Based on the parser in ``Bio.Nexus.Trees``.
    c                 C   s
   || _ dS )z,Initialize parameters for NeXML file parser.N)r#   )selfr#   r   r   r   __init__a   s   
zParser.__init__c                 C   s   t |}| |S )z'Convert file handle to StringIO object.r   )clstreetextr#   r   r   r   from_stringe   s   zParser.from_stringc                 C   sF   d|j v r|j d }nd}|tdv rt|j|d< dS |j||< dS )z%Add annotations for the NeXML parser.propertymetacdao:has_Support_Value
confidenceN)attribr   floattext)r)   	node_dict	meta_nodepropr   r   r   add_annotationk   s   
zParser.add_annotationFc                 #   s.   t j| jdd}|D ]\}}|jtdkri }i }d}g }	g }
|D ]}|jtdkr2|	| |jtdkr>|
| q$|	D ]@}|jd }i  }||< d|jv r_|jd r_|jd |d	< d
|jv rm|jd
 dkrm|}|D ]}|jtdkr| || | qoqAt  t |
D ]d}|jd |jd }} 	| 	| ||vrt ||< || 	| d|jv rt
|jd || d< d|jv r|jd tdv rt
|jd || d< |D ]}|jtdkr| || | qq|du rd} fdd|	D }t|}nd}tj| ||||dV  qdS )z7Parse the text stream this object was initialized with.)end)eventsznex:treeNznex:nodeznex:edgeidotunameroottrueznex:metasourcetargetlengthbranch_lengthr.   r0   contentr1   Fc                 3   s6    | ]}|j d   v r|j d  vr|j d  V  qdS )r;   N)r2   ).0nodesrcstarsr   r   	<genexpr>   s    zParser.parse.<locals>.<genexpr>T)r>   rooted)r   	iterparser#   tagr   appendr2   r8   setaddr3   r   nextr   Tree
_make_tree)r)   values_are_confidencerK   	nexml_doceventrF   r5   node_childrenr>   nodesedgeschildnode_id	this_nodeedgesrctarpossible_rootsr   rG   r   r"   w   sv   








zParser.parsec                    s@   | }t jdi |}| v r fdd | D |_|S )zTraverse the tree creating a nested clade structure (PRIVATE).

        Return a NeXML.Clade, and calls itself recursively for each child,
        traversing the  entire tree and creating a nested structure of NeXML.Clade
        objects.
        c                    s   g | ]	} | qS r   )rS   )rE   rZ   childrenr+   r5   r   r   
<listcomp>   s    z%Parser._make_tree.<locals>.<listcomp>Nr   )r   Cladeclades)r+   rF   r5   rb   r\   clader   ra   r   rS      s   zParser._make_treeN)FF)
r   r   r   r    r*   classmethodr-   r8   r"   rS   r   r   r   r   r!   [   s    

Dr!   c                   @   s4   e Zd ZdZdd Zdd ZdddZdddZd	S )r&   z8Based on the writer in Bio.Nexus.Trees (str, to_string).c                 C   s   || _ d| _d| _d| _dS )z'Initialize parameters for NeXML writer.r   N)r(   node_counteredge_countertree_counter)r)   r(   r   r   r   r*      s   
zWriter.__init__c                 C   s2   | d}t | |t| |d  | t| | S )z'Create new labels for the NeXML writer._counterr   )setattrgetattr)r)   obj_typecounterr   r   r   	new_label   s   
zWriter.new_labelTc                 K   sf  || _ td}|dt |dt |dt t D ]\}}|d| | qtj	|dfi ddd	}tj	|d
fi dddd}d}	t }
| j
D ]$}tj	|dfi d| di}|j}|
| j|||jd |	d7 }	qO|
D ]}tj	|dfi d|i}qvt|d}t|}z||jddd W |	S  ty   ||jdd Y |	S w )z-Write this instance's trees to a file handle.z	nex:nexmlversionxmlnszxsi:schemaLocationzxmlns:otustaxRootTaxaBlockr;   labelr(   TreesTreesBlockFromXML)r;   rw   rs   r   treer;   )rK   r   r<   zutf-8z  )indentutf8)r   r   ElementrO   VERSIONDEFAULT_NAMESPACESCHEMAr   items
SubElementr(   rp   rf   update_write_treerK   tostringr   parseStringr'   toprettyxmlencode	TypeError)r)   r#   r   r$   	root_nodeprefixurirs   r(   counttusrz   	this_treefirst_cladetur<   rough_stringreparsedr   r   r   r'      sP   



	
zWriter.writeNFc                 C   s.  t  }| jrtndd }| d}||_||d}|o|du }	|	r%d|d< |jr3||j |j|d< tj|dfi |}
|dur~| d	}||j|t|j	|d
d}z|j
}W n	 tyb   Y nw |durt||dd|dd tj|d	fi |}
| s|jD ]}|| j|||d q|`|S )zRecursively process tree, adding nodes and edges to Tree object (PRIVATE).

        Returns a set of all OTUs encountered.
        c                 S   s   | S )Nr   r   r   r   r   <lambda>#  s    z$Writer._write_tree.<locals>.<lambda>rF   rv   Nr?   r>   r<   r]   z	cdao:Edge)r;   r@   rA   rB   typeofr0   z	xsd:floatz1.2f)r.   datatyperD   )parent)rO   r   rp   r[   r=   rP   r   r   strrC   r1   AttributeErrorr   is_terminalre   r   )r)   rf   rz   r   rK   r   convert_urir[   r2   r>   rF   edge_idr1   	new_clader   r   r   r     sL   





zWriter._write_tree)T)NF)r   r   r   r    r*   rp   r'   r   r   r   r   r   r&      s    
9r&   N)F)r    ior   xml.domr   	xml.etreer   	Bio.Phylor   	_cdao_owlr   r	   r
   r   r   r   r~   r   register_namespacer   r   r   r   r   r   	Exceptionr   r"   r'   r!   r&   r   r   r   r   <module>   s8   


	w