
    {Ti>                     .   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
 	 ddlZej                  Zed   d	v sed
v r ed      	 ddddZej!                  e	       dZd Zd Zd ZddZ G d d      Z G d d      Zy# e$ r
  ed      dw xY w)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                 $    t        | t              S )zResolve URI for librdf.)
namespaces)r	   RDF_NAMESPACESxs    C/home/agent/.local/lib/python3.12/site-packages/Bio/Phylo/CDAOIO.pyqUrir   ;   s    q^44    c                 &    | j                  dd      S )zFormat label for librdf._ )replacer   s    r   format_labelr   @   s    99S#r   c                 8     t        |       j                  di |S )zlIterate over the trees in a CDAO file handle.

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

     )Parserparse)handlekwargss     r   r    r    I   s      6&>)&))r   c                 >     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"   s       r   r&   r&   R   s%     6%=v=U=f==r   c                   T    e Zd ZdZddZed        Zd Z	 ddZddZ	d Z
dd	Zd
 Zy)r   z&Parse a CDAO tree given a file handle.Nc                 J    || _         d| _        d| _        i | _        d| _        y)zInitialize CDAO tree parser.NF)r!   graph	node_infochildrenrooted)selfr!   s     r   __init__zParser.__init__b   s%    
r   c                 (    t        |      } | |      S )z,Instantiate the class from the given string.r   )clstreetextr!   s      r   from_stringzParser.from_stringj   s     (#6{r   c                 F     | j                   di | | j                         S )z7Parse the text stream this object was initialized with.r   )parse_handle_to_graphparse_graph)r.   r"   s     r   r    zParser.parsep   s$    """,V,!!r   c                    | j                   t        j                         | _         | j                   }t        j	                         D ]  \  }}|j                  ||        || _        d|v r|d   }nFdt        j                  j                  | j                  j                        j                  dd      z   }|j                  | j                  ||       | j                  ||      S )z,Parse self.handle into RDF model self.model.base_urizfile://\/)filepublicIDformatcontext)r*   rdflibGraphr   itemsbindr-   ospathabspathr!   namer   r    r6   )	r.   r-   parse_formatr?   r"   r*   kvr8   s	            r   r5   zParser.parse_handle_to_graphu   s     ::DJ

"((* 	DAqJJq!	 j)H !277??4;;3C3C#D#L#LTSV#WWHxMw77r   c              #      K   || j                   }| j                  ||       | j                  D ]6  }| j                  |      }t	        j
                  || j                         8 yw)z4Iterate over RDF model yielding CDAO.Tree instances.Nr>   )rootr-   )r*   get_node_info
tree_rootsparse_childrenr   Treer-   )r.   r*   r?   	root_nodeclades        r   r6   zParser.parse_graph   sa     =JJE 	5'2 	<I''	2E))t{{;;	<s   A(A*c                     | j                   |   }i }d|v r|d   |d<   d|v r|d   j                  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   rG   
confidencer   )r+   r   r   Clade)r.   noderesultr"   rR   s        r   	new_cladezParser.new_clade   s{    %f$&,_&=F?#f#G_44S#>F6N6!#),#7F< 

$V$r   c                    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 ]  \  }}}t        |      t        |      t        |      }}}|| j                  vri | j                  |<   | j                  |   }	 ||||   <   |t        d      k(  r3|t        d      t        d      fv r| j                  j                  |       |t        d      k(  s| j
                  j                  |        | j                  D ]  }i | j                   |<   | j                   |   }	| j                  |   }
d|
v r=| j                  |
d      }d|v r'| j                  |d      }d|v rt        |d         |	d<   d
|
v r| j                  |
d
      }d|v r|d   |	d<   d|
v s|
d   }|| j                  vrg | j                  |<   | j                  |   j                  |        y# t        $ r Y `w xY w)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:labelrU   cdao:has_Support_ValuerV   rdf:typecdao:AncestralNodecdao:TerminalNodecdao:has_RootrT   N)r+   obj_infor,   setnodesrN   r   strKeyErroraddfloatappend)r.   r*   r?   assignmentssrJ   othisrX   r+   objr_   ra   re   r]   s                  r   rM   zParser.get_node_info   s\   U
% "#X016&'!"G%&)*L
  	'GAq! !fc!fc!f!qA%#%a ==#D ()[^$ D$$23T:M5NOOJJNN1%D))##A&-	'0 JJ 	3D $&DNN4 t,I--%C} }}S[14'!%tL/A!BJ*,5::g;N5O	/2s{]]3t9-b=)+GIg&3 X.,.DMM&)f%,,T29	3  s   H66	IIc                     | j                  |      }|| j                  v r| j                  |   ng }|D cg c]  }| j                  |       c}|_        |S c c}w )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.
        )rZ   r,   rO   clades)r.   rX   rR   r,   
child_nodes        r   rO   zParser.parse_children   sU     t$*.$--*?4==&RJRSJ++J7S Ts   AN)FturtleN)NN)__name__
__module____qualname____doc__r/   classmethodr3   r    r5   r6   rZ   rM   rO   r   r   r   r   r   _   sD    0  
" <@8.< F3Pr   r   c                   6    e Zd ZdZeZd Z	 	 	 ddZd ZddZ	y)	r%   z8Based on the writer in Bio.Nexus.Trees (str, to_string).c                 J    || _         d| _        d| _        d| _        d| _        y)z.Initialize parameters for writing a CDAO tree.r   N)r'   node_counteredge_counter
tu_countertree_counter)r.   r'   s     r   r/   zWriter.__init__	  s(    
r   c                    || _         || _        |r|j                  d      s|dz  }| j                  }|r|j	                  d| d       | j
                  j                         D ]  \  }}|j	                  d| d| d        |j	                  d| j
                  d    d	       |D ]V  }	| xj                  d
z  c_        d| _        |	j                  }
| j                  |
|	      }|D ]  }| j                  ||        X y)z-Write this instance's trees to a file handle.r:   z@base <z>
z@prefix z: <z> .
<cdaoz> a owl:Ontology .
r   ztree%s)rL   N)r-   record_complete_ancestryendswithr'   r&   prefixesrB   r   tree_urirR   process_cladeadd_stmt_to_handle)r.   r!   r   r   r-   r"   r'   rI   rJ   treefirst_clade
statementsstmts                r   r&   zWriter.write  s    (@%H--c2OH

LL78*C01MM'') 	4DAqLL8A3c!E23	4 	qv.//CDE 	6D"$DM**K++Kd+CJ" 6''56	6r   c                 p   g }t        |      D ]  \  }}t        |t        j                        rt	        |      }d}| j
                  j                         D ]6  \  }}	|j                  |	      s|j                  |	| dd      }|dk(  rd}d}8 |sd|v r|j                  |       |j                  d| d       t        |t        j                        r |j                  |j                                |j                  t	        |              |j                  d	j                  |       d
       y)zAdd URI prefix to handle.F:r   rh   aTr   >r   z .
N)	enumerate
isinstancer@   URIRefro   r   rB   
startswithr   rs   Literaln3r&   join)
r.   r!   r   stmt_stringsnpartnode_urichangedprefixuris
             r   r   zWriter.add_stmt_to_handle3  s      	/GAt$.t9#'==#6#6#8 'KFC**3/#+#3#3CF81q#I#z1'*H"&' cXo ''1 ''!H:Q8D&..1##DGGI. ##CI.'	/* 	./t45r   Nc              #     K   | xj                   dz  c_         dt        | j                         j                  t               |_        |r |j
                  |j                  gz   |_        ng |_        d }d } |d      }g }|durp| j                  r |d      n |d      }|| |d	      |f| |d
       ||j                        fgz  }	 |j                  }	|	D ]  \  }
}|j                  ||
|f        |j                  r| xj                  dz  c_        dt        | j                        j                  t               }| ||       |d	       |d      f ||j                         |d       ||      f ||       |d      t        j                  t        |j                              fgz  }	 |j                  }|D ]  \  }
} ||      |
|f  |j!                         rdnd}| ||j                         |d	       ||      f ||j                         |d      |fgz  }|| xj"                  dz  c_        dt        | j"                        j                  t               }| ||       |d	       |d      f ||       |d      |f ||       |d       ||j                        f ||       |d       ||j                        f ||j                         |d       ||      f ||j                         |d       ||j                        f ||j                         |d       ||      fgz  }	 |j$                  }|7t        j                  |d      }| ||j                         |d      |fgz  }	 | j&                  rTt)        |j
                        dkD  r<||j
                  D cg c]#  } ||j                         |d       ||      f% c}z  }|j*                  dt        | j"                        j                  t               }t        j                  |j*                  t        j,                  d            }| ||       |d	       |d       f ||       |d!       ||      f ||       |d"      |fgz  }	 |j.                  }|D ]  \  }
} ||      |
|f  |E d{    	 |j                  }|D ]  \  }
} ||j                        |
|f  |j!                         s.|j0                  D ]  }| j3                  ||d#      E d{      yy# t        $ r g }	Y ew xY w# t        $ r g }Y w xY w# t        $ r Y w xY wc c}w # t        $ r g }Y w xY w7 # t        $ r g }Y w xY w7 ew)$z9Recursively generate triples describing a tree of clades.r   rX   c                 ,    t        j                  |       S r|   )r@   r   ru   s    r   nUriz"Writer.process_clade.<locals>.nUriW  s    ==##r   c                 >    t        j                  t        |             S r|   )r@   r   r   r   s    r   pUriz"Writer.process_clade.<locals>.pUri[  s    ==a))r    Fzcdao:RootedTreezcdao:UnrootedTreerh   rk   re   zcdao:TUrd   rf   rj   ri   zcdao:belongs_to_TreeNr_   zcdao:DirectedEdgezcdao:has_Parent_Nodezcdao:has_Child_Noder^   r\   zcdao:belongs_to_Edge_as_Parentz(http://www.w3.org/2001/XMLSchema#decimal)datatyperg   r   zcdao:has_Ancestoredge_annotationzcdao:EdgeLengthr`   rb   )r]   rL   )r   ro   zfillZEROESr   	ancestorsr-   
attributesAttributeErrorrs   rG   r   r@   r   r   tu_attributesis_terminalr   rV   r   lenrT   r   edge_attributesrz   r   )r.   rR   r]   rL   r   r   tree_idr   	tree_typetree_attributes	predicaterx   tu_urir   	node_typeedge_urirV   ancestoredge_ann_urirT   r   clade_attributesrZ   s                          r   r   zWriter.process_cladeN  s    Q3t00177?@A	$..&**=EO EO	$	* r(
u ,0;;&'DAT<U  $z*I6$/eiiA J
%"&// #2 =	3!!7Is";<= ::OOq O#doo.44V<=>FftJ/iAeii$';"<d6lKL&NN<

#;< J# % 3 3 #0 5	3F|Y445 ,1+<+<+>'DX	%))_d:.Y@%))_d#9:GD
 	


 "c$"3"34::6BCDHhj!148K3LMh&<!=wGh&<!=tFJJ?OPh&;!<d599oNO89N
 eii$'8"94

;KL$9:N J$"--
 )!'"-W"J eii$/G*H*U# J ,,U__1E1I$)OO  %))_d+>&?hP 

 "".!0T5F5F1G1M1Mf1U0VW &''#]]+UV! ,'j)94@Q;RS(^T*?%@$|BTU,'.>)?O 
%"'"7"7 #2 7	3H~y#667 	"$// / 	4NIs		?Is33	4   ""\\ S	--iE-RRRS #_ " %"$%. " # "#L " * " %"$% 	  	"!	" Ss   CVT. CV3U  ?FVU A,V:(U""B1VU'  V<U8=VU: AV%V&V.T=9V<T==V UVUV	UVUV'U52V4U55V:VVVV)r   FF)NF)
r~   r   r   r   r   r   r/   r&   r   r   r   r   r   r%   r%     s,    BH !&6B66SSr   r%   )F)r   rD   ior   Bior   	Bio.Phylor   	_cdao_owlr   r	   r@   __version__rdfverImportErrorr   updater   r   r   r    r&   r   r%   r   r   r   <module>r      s    
  ,  & "
FayJ6-H#H*K
 	
 $I ,83
   o &	
5
*>^ ^J]S ]Sq  
&7s   #B B