o
    Rŀg>                     @   s   d Z ddl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
 zddlZejZed d	v s6ed
v r:edW n eyG   eddw ddddZee	 dZdd Zdd Zdd ZdddZG dd dZG dd dZdS ) a  I/O function wrappers for the RDF/CDAO file format.

This is an RDF format that conforms to the Comparative Data Analysis Ontology (CDAO).
See: http://evolutionaryontology.org/cdao

This module requires the librdf Python bindings (http://www.librdf.org)

The CDAOIO.Parser, in addition to parsing text files, can also parse directly
from a triple store that implements the Redland storage interface; similarly,
the CDAOIO.Writer can store triples in a triple store instead of serializing
them to a file.
    NStringIO)MissingPythonDependencyError)CDAO   )cdao_namespaces)resolve_uri)12)z3.0.0z3.1.0z3.2.0z=Support for CDAO tree format requires RDFlib v3.2.1 or later.z-Support for CDAO tree format requires RDFlib.zhttp://www.w3.org/2002/07/owl#z+http://www.w3.org/1999/02/22-rdf-syntax-ns#z%http://www.w3.org/2000/01/rdf-schema#)owlrdfrdfs   c                 C   s   t | tdS )zResolve URI for librdf.)
namespaces)r   RDF_NAMESPACESx r   D/var/www/html/myenv/lib/python3.10/site-packages/Bio/Phylo/CDAOIO.pyqUri;      r   c                 C   s   |  ddS )zFormat label for librdf._ )replacer   r   r   r   format_label@   r   r   c                 K   s   t | jdi |S )zlIterate over the trees in a CDAO file handle.

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

    Nr   )Parserparse)handlekwargsr   r   r   r   I   s   r   Fc                 K   s   t | j|fd|i|S )zdWrite a trees in CDAO format to the given file handle.

    :returns: number of trees written.

    plain)Writerwrite)treesr   r   r   r   r   r   r!   R   s   r!   c                   @   s^   e Zd ZdZdddZedd Zdd Z	dddZdddZ	dd Z
dddZdd ZdS )r   z&Parse a CDAO tree given a file handle.Nc                 C   s"   || _ d| _d| _i | _d| _dS )zInitialize CDAO tree parser.NF)r   graph	node_infochildrenrooted)selfr   r   r   r   __init__b   s
   
zParser.__init__c                 C   s   t |}| |S )z,Instantiate the class from the given string.r   )clstreetextr   r   r   r   from_stringj   s   zParser.from_stringc                 K   s   | j di | |  S )z7Parse the text stream this object was initialized with.Nr   )parse_handle_to_graphparse_graph)r'   r   r   r   r   r   p   s   zParser.parseFturtlec           	      K   s   | j du r
t | _ | j }t D ]
\}}||| q|| _d|v r(|d }ndtj	| j
jdd }|j| j
||d | j||dS )z,Parse self.handle into RDF model self.model.Nbase_urizfile://\/)filepublicIDformatcontext)r#   rdflibGraphr   itemsbindr&   ospathabspathr   namer   r   r-   )	r'   r&   parse_formatr6   r   r#   kvr/   r   r   r   r,   u   s   


zParser.parse_handle_to_graphc                 c   sJ    |du r| j }| j||d | jD ]}| |}tj|| jdV  qdS )z4Iterate over RDF model yielding CDAO.Tree instances.Nr5   )rootr&   )r#   get_node_info
tree_rootsparse_childrenr   Treer&   )r'   r#   r6   	root_nodeclader   r   r   r-      s   

zParser.parse_graphc                 C   sf   | j | }i }d|v r|d |d< d|v r|d dd|d< d|v r)|d |d< tjdi |}|S )	z2Return a CDAO.Clade object for a given named node.branch_lengthlabelr   r   r>   
confidenceNr   )r$   r   r   Clade)r'   noderesultr   rH   r   r   r   	new_clade   s   
zParser.new_cladec                 C   s  i | _ i | _i | _t | _t | _tddtddtddtddtd	d
tddtddi}|D ]V\}}}t|t|t|}}}|| jvrNi | j|< | j| }z|||| < W n	 tyd   Y nw |tdkr{|tdtdfv r{| j	| |tdkr| j	| q1| jD ]b}i | j |< | j | }	| j| }
d|
v r| j|
d  }d|v r| j|d  }d|v rt
|d |	d< d
|
v r| j|
d
  }d|v r|d |	d< d|
v r|
d }|| jvrg | j|< | j| | qdS )zGCreate a dictionary containing information about all nodes in the tree.cdao:has_Parentparentcdao:belongs_to_Edge_as_Childedgecdao:has_Annotation
annotationcdao:has_Valuevaluecdao:represents_TUtu
rdfs:labelrJ   cdao:has_Support_ValuerK   rdf:typecdao:AncestralNodecdao:TerminalNodecdao:has_RootrI   N)r$   obj_infor%   setnodesrD   r   strKeyErroraddfloatappend)r'   r#   r6   assignmentssrA   othisrM   r$   objrS   rU   rY   rQ   r   r   r   rC      sd   









zParser.get_node_infoc                    s:     |}| jv r j| ng } fdd|D |_|S )zTraverse the tree to create a nested clade structure.

        Return a CDAO.Clade, and calls itself recursively for each child,
        traversing the entire tree and creating a nested structure of CDAO.Clade
        objects.
        c                    s   g | ]}  |qS r   )rE   ).0
child_noder'   r   r   
<listcomp>   s    z)Parser.parse_children.<locals>.<listcomp>)rO   r%   clades)r'   rM   rH   r%   r   ro   r   rE      s   
zParser.parse_childrenN)Fr.   N)NN)__name__
__module____qualname____doc__r(   classmethodr+   r   r,   r-   rO   rC   rE   r   r   r   r   r   _   s    




Hr   c                   @   s>   e Zd ZdZeZdd Z			dddZ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| _dS )z.Initialize parameters for writing a CDAO tree.r   N)r"   node_counteredge_counter
tu_countertree_counter)r'   r"   r   r   r   r(   	  s
   
zWriter.__init__ Fc                 K   s   || _ || _|r|ds|d7 }| j}|r|d| d | j D ]\}}|d| d| d q$|d| jd  d	 |D ]!}	|  jd
7  _d| _|	j	}
| j
|
|	d}|D ]}| || q[qCdS )z-Write this instance's trees to a file handle.r1   z@base <z>
z@prefix z: <z> .
<cdaoz> a owl:Ontology .
r   ztree%s)rB   N)r&   record_complete_ancestryendswithr"   r!   prefixesr9   r{   tree_urirH   process_cladeadd_stmt_to_handle)r'   r   r   r   r&   r   r"   r@   rA   treefirst_clade
statementsstmtr   r   r   r!     s&   	zWriter.writec           
      C   s   g }t |D ]\\}}t|tjrMt|}d}| j D ]\}}	||	r6||	| dd}|dkr4d}d}q|s=d|v rC|	| q|	d| d qt|tj
r[|	|  q|	t| q|d	| d
 dS )zAdd URI prefix to handle.F:r   r\   aTr}   >r   z .
N)	enumerate
isinstancer7   URIRefrc   r   r9   
startswithr   rg   Literaln3r!   join)
r'   r   r   stmt_stringsnpartnode_urichangedprefixurir   r   r   r   3  s&   
zWriter.add_stmt_to_handleNc                 #   sn   |  j d7  _ dt| j t  _|r|j|jg  _ng  _dd dd d}g }|durr| jr;d	nd
}||d|f|d jfg7 }z|j}W n tyb   g }Y nw |D ]\}}	|	|||	f qe j
r|  jd7  _dt| jt }
||
ddf jd|
f|
dtt j
fg7 }z j}W n ty   g }Y nw |D ]\}}	|
||	fV  q  rdnd}| jd|f jd|fg7 }|dur|  jd7  _dt| jt }||ddf|d|f|d|jf|d jf jd|f jd|jf|jd|fg7 }z j}W n
 tyb   Y nw |dur|tj|dd}| jd|fg7 }| jrt jdkr| fd d! jD 7 } jdurd"t| jt }tj jtdd}||dd#f|d$|f|d%|fg7 }z j}W n ty   g }Y nw |D ]\}}	|||	fV  q|E dH  z j}W n ty
   g }Y nw |D ]\}}	 j||	fV  q  s3 jD ]}| j| dd&E dH  q$dS dS )'z9Recursively generate triples describing a tree of clades.r   rM   c                 S   s
   t | S rr   )r7   r   ri   r   r   r   nUriW  s   
z"Writer.process_clade.<locals>.nUric                 S   s   t t| S rr   )r7   r   r   r   r   r   r   pUri[  s   z"Writer.process_clade.<locals>.pUrir|   Fzcdao:RootedTreezcdao:UnrootedTreer\   r_   rY   zcdao:TUrX   rZ   r^   r]   zcdao:belongs_to_TreeNrS   zcdao:DirectedEdgezcdao:has_Parent_Nodezcdao:has_Child_NoderR   rP   zcdao:belongs_to_Edge_as_Parentz(http://www.w3.org/2001/XMLSchema#decimal)datatyper[   r   c                    s$   g | ]} j d |fqS )zcdao:has_Ancestor)r   )rm   ancestorrH   r   r   r   r   rp     s    z(Writer.process_clade.<locals>.<listcomp>edge_annotationzcdao:EdgeLengthrT   rV   )rQ   rB   )rx   rc   zfillZEROESr   	ancestorsr&   
attributesAttributeErrorrg   r>   rz   r7   r   r   tu_attributesis_terminalry   rK   r   lenrI   r   edge_attributesrq   r   )r'   rH   rQ   rB   tree_idr   	tree_typetree_attributes	predicaterl   tu_urir   	node_typeedge_urirK   edge_ann_urirI   r   clade_attributesrO   r   r   r   r   N  s   










zWriter.process_clade)r|   FF)NF)
rs   rt   ru   rv   r   r   r(   r!   r   r   r   r   r   r   r      s    
!r    )F)rv   r;   ior   Bior   	Bio.Phylor   	_cdao_owlr   r   r7   __version__rdfverImportErrorr   updater   r   r   r   r!   r   r    r   r   r   r   <module>   sF   

	
	 &