B
    bJ,                 @   s0  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
mZmZ dd	d
ddZee ed ZdZdZy
ejZW n: ek
r   eedsddlmZ eje_dd ZY nX xe D ]\ZZeee qW d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#)ZxsiZxmlnexZxsdr
   z0.9z-http://www.nexml.org/2009/nexml/xsd/nexml.xsd_namespace_mapc             C   s   | t j|< dS )zSet NameSpace map.N)r   r   )prefixuri r   0lib/python3.7/site-packages/Bio/Phylo/NeXMLIO.pyregister_namespace.   s    r   c             C   s   t | tddS )z*Given a prefixed URI, return the full URI.T)Z
namespacesZ	xml_style)r	   
NAMESPACES)sr   r   r   qUri7   s    r   c             C   s   dt | tdd   S )zAOptionally converts a CDAO-prefixed URI into an OBO-prefixed URI.zobo:%szcdao:N)r   len)r   r   r   r   cdao_to_obo<   s    r   c             C   s    |  dr| t| fS | fS dS )z2Check for matches in both CDAO and OBO namespaces.zcdao:N)
startswithr   )r   r   r   r   matchesA   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   I   s   r   c             K   s   t | jf |S )znIterate over the trees in a NeXML file handle.

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

    )Parserparse)handlekwargsr   r   r   r   S   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#   \   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__o   s    zParser.__init__c             C   s   t |}| |S )z'Convert file handle to StringIO object.)r   )clsZtreetextr   r   r   r   from_strings   s    zParser.from_stringc             C   sD   d|j kr|j d }nd}|tdkr6t|j|d< n
|j||< dS )z%Add annotations for the NeXML parser.propertymetazcdao:has_Support_Value
confidenceN)attribr   floattext)r%   	node_dictZ	meta_nodeZpropr   r   r   add_annotationy   s    
zParser.add_annotationFc             #   sR  t j| jdd}x:|D ]0\}}|jtdkri }i }d}g }	g }
x<|D ]4}|jtdkrf|	| |jtdkrJ|
| qJW x|	D ]}|jd }i  }||< d|jkr|jd r|jd |d	< d
|jkr|jd
 dkr|}x*|D ]"}|jtdkr| || | qW qW t  t x|
D ]}|jd |jd  }} 	| 	| ||krdt ||< || 	| d|jkrt
|jd || d< d|jkr|jd tdkrt
|jd || d< x.|D ]&}|jtdkr| || | qW q"W |dkr,d} fdd|	D }t|}nd}tj| ||||dV  qW dS )z7Parse the text stream this object was initialized with.)end)Zeventsznex:treeNznex:nodeznex:edgeidotunameroottrueznex:metasourcetargetlengthbranch_lengthr)   zcdao:has_Support_Valuecontentr+   Fc             3   s4   | ],}|j d   kr|j d  kr|j d  V  qdS )r2   N)r,   ).0node)srcstarsr   r   	<genexpr>   s   zParser.parse.<locals>.<genexpr>T)r5   rooted)r   Z	iterparser   tagr   appendr,   r0   setaddr-   r   nextr   ZTree
_make_tree)r%   Zvalues_are_confidencerA   Z	nexml_docZeventr=   r/   Znode_childrenr5   ZnodesZedgeschildnode_id	this_nodeedgesrcZtarZpossible_rootsr   )r>   r?   r   r      s`    













zParser.parsec                s<   | }t jf |}| kr8 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   )rG   )r<   rH   )childrenr'   r/   r   r   
<listcomp>   s    z%Parser._make_tree.<locals>.<listcomp>)r   ZCladeclades)r'   r=   r/   rM   rJ   clader   )rM   r'   r/   r   rG      s
    zParser._make_treeN)FF)
r   r   r   r   r&   classmethodr(   r0   r   rG   r   r   r   r   r   i   s   
Dr   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$   Znode_counterZedge_counterZtree_counter)r%   r$   r   r   r   r&      s    zWriter.__init__c             C   s0   d| }t | |t| |d  d|t| |f S )z'Create new labels for the NeXML writer.z
%s_counterr   z%s%s)setattrgetattr)r%   Zobj_typeZcounterr   r   r   	new_label   s    zWriter.new_labelTc             K   sd  || _ td}|dt |dt |dt x$t D ]\}}|d| | q>W tj	|dfddd	}tj	|d
fdddd}d}	t }
xN| j
D ]D}tj	|dfd| di}|j}|
| j|||jd |	d7 }	qW x |
D ]}tj	|dfd|i}qW t|d}t|}y||jddd W n( tk
r^   ||jdd Y nX |	S )z-Write this instance's trees to a file handle.z	nex:nexmlversionZxmlnszxsi:schemaLocationzxmlns:%sotusZtaxZRootTaxaBlock)r2   labelr$   ZTreesZTreesBlockFromXML)r2   rW   rV   r   treer2   )rA   r   r3   zutf-8z  )indentutf8)r   r   ZElementrD   VERSIONDEFAULT_NAMESPACESCHEMAr   items
SubElementr$   rT   rP   update_write_treerA   Ztostringr   ZparseStringr#   Ztoprettyxmlencode	TypeError)r%   r   r   r    Z	root_noder   r   rV   r$   counttusrX   Z	this_treeZfirst_cladeZtur3   Zrough_stringZreparsedr   r   r   r#      s<    

	
zWriter.writeNFc             C   s0  t  }| jrtndd }| d}||_||d}|o<|dk}	|	rJd|d< |jrf||j |j|d< tj|df|}
|dk	r| d	}||j|t|j	|d
d}y
|j
}W n tk
r   Y n$X |dk	r||ddd| d tj|d	f|}
| s(x&|jD ]}|| j|||d qW |`|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>1      z$Writer._write_tree.<locals>.<lambda>r=   )r2   rW   Nr6   r5   r3   rK   z	cdao:Edge)r2   r7   r8   r9   Ztypeofzcdao:has_Support_Valuez	xsd:floatz%1.2f)r)   Zdatatyper;   )parent)rD   r   rT   rI   r4   rE   r   r_   strr:   r+   AttributeErrorr`   Zis_terminalrO   ra   )r%   rP   rX   rh   rA   re   Zconvert_urirI   r,   r5   r=   Zedge_idr+   Z	new_clader   r   r   ra   *  sD    





zWriter._write_tree)T)NF)r   r   r   r   r&   rT   r#   ra   r   r   r   r   r"      s
   
9r"   N)F)#r   ior   Zxml.domr   Z	xml.etreer   Z	Bio.Phylor   Z	_cdao_owlr   r   r	   r   r`   r\   r[   r]   r   rj   hasattrZET_pyr   r^   r   r   r   r   r   	Exceptionr   r   r#   r   r"   r   r   r   r   <module>   s<   



	
w