
:>"^>                 @   sH  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	 m
 Z
 yA d d l Z e j Z e d d# k s e d$ k r e d   Wn e k
 r e d   Yn Xd d d d d d i Z e j e	  d Z d d   Z d d   Z d d   Z d d d  Z Gd d    d  e  Z Gd! d"   d" e  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3.0.03.1.03.2.0z=Support for CDAO tree format requires RDFlib v3.2.1 or later.z-Support for CDAO tree format requires RDFlib.Zowlzhttp://www.w3.org/2002/07/owl#rdfz+http://www.w3.org/1999/02/22-rdf-syntax-ns#Zrdfsz%http://www.w3.org/2000/01/rdf-schema#   c             C   s   t  |  d t S)zResolve URI for librdf.
namespaces)r   RDF_NAMESPACES)x r   5/tmp/pip-build-ww9dw3qa/biopython/Bio/Phylo/CDAOIO.pyqUri9   s    r   c             C   s   |  j  d d  S)zFormat label for librdf._ )replace)r   r   r   r   format_label>   s    r   c             K   s   t  |   j |   S)zlIterate over the trees in a CDAO file handle.

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

    )Parserparse)handlekwargsr   r   r   r   G   s    r   Fc             K   s   t  |   j | d | | 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   P   s    r   c               @   s   e  Z d  Z d Z d d d  Z e d d    Z d d   Z d	 d
 d d d  Z d 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   s1   | |  _  d |  _ d |  _ i  |  _ d |  _ d S)zInitialize CDAO tree parser.NF)r   graph	node_infochildrenrooted)selfr   r   r   r   __init__`   s
    				zParser.__init__c             C   s   t  |  } |  |  S)z,Instantiate the class from the given string.)r   )clsZtreetextr   r   r   r   from_stringh   s    zParser.from_stringc             K   s   |  j  |   |  j   S)z7Parse the text stream this object was initialized with.)parse_handle_to_graphparse_graph)r%   r   r   r   r   r   n   s    zParser.parseFZturtlec       	      K   s   |  j  d k r t j   |  _  |  j  } x* t j   D] \ } } | j | |  q4 W| |  _ d | k rv | d } n( d t j j	 |  j
 j  j d d  } | j d |  j
 d | d |  |  j | d	 | S)
z,Parse self.handle into RDF model self.model.Nbase_urizfile://\/fileZpublicIDformatcontext)r!   rdflibZGraphr   itemsbindr$   ospathabspathr   namer   r   r*   )	r%   r$   Zparse_formatr0   r   r!   kvr+   r   r   r   r)   s   s    		(zParser.parse_handle_to_graphc             c   si   | d k r |  j  } |  j | d | x: |  j D]/ } |  j |  } t j d | d |  j  Vq2 Wd S)z4Iterate over RDF model yielding CDAO.Tree instances.Nr0   rootr$   )r!   get_node_info
tree_rootsparse_childrenr   ZTreer$   )r%   r!   r0   Z	root_nodeclader   r   r   r*      s    	zParser.parse_graphc             C   s   |  j  | } i  } d | k r- | d | d <d | k rS | d j d d  | d <d | k rm | d | d <t j |   } | S)z2Return a CDAO.Clade object for a given named node.branch_lengthlabelr   r   r7   
confidence)r"   r   r   ZClade)r%   noderesultr   r>   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 } x | D] \ } } } t |  t |  t |  } } } | |  j k r i  |  j | <|  j | } y | | | | <Wn t k
 rYn X| t d  k rY| t d  t d  f k rY|  j j	 |  | t d  k r |  j j	 |  q Wx|  j D]} i  |  j  | <|  j  | }	 |  j | }
 d |
 k r|  j |
 d } d | k r|  j | d } d | k rt
 | d  |	 d <d
 |
 k rG|  j |
 d
 } d | k rG| d |	 d <d |
 k r|
 d } | |  j k ryg  |  j | <|  j | j |  qWd S)zGCreate a dictionary containing information about all nodes in the tree.zcdao:has_Parentparentzcdao:belongs_to_Edge_as_Childedgezcdao:has_Annotation
annotationzcdao:has_Valuevaluezcdao:represents_TUtuz
rdfs:labelr@   zcdao:has_Support_ValuerA   zrdf:typezcdao:AncestralNodezcdao:TerminalNodezcdao:has_Rootr?   N)r"   Zobj_infor#   setZnodesr<   r   strKeyErroraddfloatappend)r%   r!   r0   Zassignmentssr9   othisrB   r"   objrF   rG   rI   rE   r   r   r   r;      sZ    			&
zParser.get_node_infoc                sQ     j  |  } |   j k 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  |  ] }   j  |   q Sr   )r=   ).0Z
child_node)r%   r   r   
<listcomp>   s   	 z)Parser.parse_children.<locals>.<listcomp>)rD   r#   clades)r%   rB   r>   r#   r   )r%   r   r=      s    "zParser.parse_children)__name__
__module____qualname____doc__r&   classmethodr(   r   r)   r*   rD   r;   r=   r   r   r   r   r   ]   s   Hr   c               @   s[   e  Z d  Z d Z e Z d d   Z d d d d d  Z d d	   Z d
 d d d  Z	 d
 S)r   z8Based on the writer in Bio.Nexus.Trees (str, to_string).c             C   s1   | |  _  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  | |  _  | |  _ | r2 | j d  r2 | d 7} |  j } | rR | j d |  x4 |  j j   D]# \ } } | j d | | f  qb W| j d |  j d  xe | D]] }	 |  j d 7_ d |  _ |	 j	 }
 |  j
 |
 d |	 } x | D] } |  j | |  q Wq Wd	 S)
z-Write this instance's trees to a file handle.r-   z@base <%s>
z@prefix %s: <%s> .
z<%s> a owl:Ontology .
Zcdaor   ztree%sr:   N)r$   record_complete_ancestryendswithr    r   prefixesr2   r_   tree_urir>   process_cladeadd_stmt_to_handle)r%   r   rd   ra   r$   r   r    r8   r9   treeZfirst_clade
statementsstmtr   r   r   r     s"    			
			zWriter.writec       
      C   s6  g  } xt  |  D]\ } } t | t j  r t |  } d } x] |  j j   D]L \ } }	 | j |	  rS | j |	 d | d  } | d k r d } d } qS W| s d | k r | j	 |  q| j	 d |  q t | t j
  r| j	 | j    q | j	 t |   q W| j d	 d
 j |   d S)zAdd URI prefix to handle.Fz%s:r   zrdf:typeaT:z<%s>z%s .
r   N)	enumerate
isinstancer1   URIRefrK   rc   r2   
startswithr   rO   LiteralZn3r   join)
r%   r   ri   Zstmt_stringsnpartZnode_urichangedprefixurir   r   r   rf   1  s$    
zWriter.add_stmt_to_handleNc          '   #   s  |  j  d 7_  d t |  j   j t    _ | rM | j | j g   _ n	 g    _ d d    d d     d  } g  } | d k	 r9|  j r  d	  n	  d
  } | |  d  | f |  d     j  f g 7} y | j } Wn t k
 rg  } Yn Xx* | D]" \ } }	 | j	 | | |	 f  qW  j
 r3|  j d 7_ d t |  j  j t  }
 |  |
   d   d  f    j   d   |
  f  |
   d  t j t   j
   f g 7} y   j } Wn t k
 rg  } Yn Xx( | D]  \ } }	  |
  | |	 f VqW  j   rEd n d } |    j   d   |  f    j   d  | f g 7} | d k	 rL|  j d 7_ 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 7} t   d  r  j d k	 rt j   j d d } |    j   d  | f g 7} |  j rOt   j  d  k rO|     f d! d"     j D 7}   j d k	 rd# t |  j  j t  } t j   j d t j d  } |  |   d   d$  f  |   d%   |  f  |   d&  | f g 7} y   j } Wn t k
 r g  } Yn Xx( | D]  \ } }	  |  | |	 f Vq(Wx | D] } | VqSWy   j } Wn t k
 rg  } Yn Xx+ | D]# \ } }	    j  | |	 f VqW  j   sx<   j D]1 } x( |  j | d'   d( d D] } | VqWqWd S))z9Recursively generate triples describing a tree of clades.r   znode%sc             S   s   t  j |   S)N)r1   rn   )rP   r   r   r   nUriU  s    z"Writer.process_clade.<locals>.nUric             S   s   t  j t |    S)N)r1   rn   r   )rP   r   r   r   pUriY  s    z"Writer.process_clade.<locals>.pUrir`   Fzcdao:RootedTreezcdao:UnrootedTreezrdf:typezcdao:has_Rootztu%szcdao:TUzcdao:represents_TUz
rdfs:labelzcdao:TerminalNodezcdao:AncestralNodezcdao:belongs_to_TreeNzedge%szcdao:DirectedEdgezcdao:has_Parent_Nodezcdao:has_Child_Nodezcdao:belongs_to_Edge_as_Childzcdao:has_Parentzcdao:belongs_to_Edge_as_ParentrA   datatypez(http://www.w3.org/2001/XMLSchema#decimalzcdao:has_Support_Valuer   c                s4   g  |  ]* }    j    d    |  f  q S)zcdao:has_Ancestor)rv   )rT   Zancestor)r>   rw   rx   r   r   rU     s   	z(Writer.process_clade.<locals>.<listcomp>zedge_annotation%szcdao:EdgeLengthzcdao:has_Annotationzcdao:has_ValuerE   r:   )r\   rK   zfillZEROESrv   Z	ancestorsr$   
attributesAttributeErrorrO   r7   r^   r1   rp   r   tu_attributesZis_terminalr]   hasattrrA   ra   lenr?   rn   edge_attributesrV   re   )r%   r>   rE   r:   Ztree_idrh   Z	tree_typeZtree_attributes	predicaterS   Ztu_urir~   	node_typeZedge_urirA   Zedge_ann_urir?   r   ri   Zclade_attributesrD   r   )r>   rw   rx   r   re   L  s    	!"	!		!"!!	$			"
		"zWriter.process_clade)
rW   rX   rY   rZ   r   rc   r&   r   rf   re   r   r   r   r   r     s   r   )r   r	   )r
   r   r   )rZ   r4   Z	Bio._py3kr   ZBior   Z	Bio.Phylor   Z	_cdao_owlr   r   r1   __version__ZrdfverImportErrorr   updater{   r   r   r   r   objectr   r   r   r   r   r   <module>   s0   			