
:>"^Z0  ã               @   sú   d  Z  d d l m Z d d l m Z d d l m Z d d „  Z Gd d „  d e j ƒ Z Gd	 d
 „  d
 e j ƒ Z Gd d „  d e	 ƒ Z
 d d „  Z d d „  Z d d „  Z d d „  Z d d „  Z d d „  Z d d „  Z d d „  Z d d „  Z d S) z,Module for the support of MEME motif format.é    )Úprint_function)ÚSeq)Úmotifsc             C   s˜  t  ƒ  } t | |  ƒ t | |  ƒ t | |  ƒ t | |  ƒ t | |  ƒ x* |  D] } | j d ƒ rQ PqQ Wt d ƒ ‚ | j } d | j	 k } xt
 | ƒ \ } } } } t |  ƒ }	 t |  |	 | | | ƒ }
 t | |
 ƒ } | | _ | | _ | | _ |	 | _ | j | ƒ t | ƒ | k s&t ‚ t |  ƒ y t |  ƒ } Wn t k
 r`t d ƒ ‚ Yn X| j d ƒ rqP| j d ƒ s’ t d | ƒ ‚ q’ W| S)a¨  Parse the text output of the MEME program into a meme.Record object.

    Examples
    --------
    >>> from Bio.motifs import meme
    >>> with open("motifs/meme.out") as f:
    ...     record = meme.read(f)
    >>> for motif in record:
    ...     for instance in motif.instances:
    ...         print(instance.motif_name, instance.sequence_name, instance.strand, instance.pvalue)
    Motif 1 SEQ10; + 8.71e-07
    Motif 1 SEQ9; + 8.71e-07
    Motif 1 SEQ8; + 8.71e-07
    Motif 1 SEQ7; + 8.71e-07
    Motif 1 SEQ6; + 8.71e-07
    Motif 1 SEQ5; + 8.71e-07
    Motif 1 SEQ4; + 8.71e-07
    Motif 1 SEQ3; + 8.71e-07
    Motif 1 SEQ2; + 8.71e-07
    Motif 1 SEQ1; + 8.71e-07

    zMOTIF zUnexpected end of streamÚrevcompzNUnexpected end of stream: Expected to find new motif, or the summary of motifszSUMMARY OF MOTIFSÚMOTIFz$Line does not start with 'MOTIF':
%s)ÚRecordÚ__read_versionÚ__read_datafileÚ__read_alphabetÚ__read_sequencesÚ__read_commandÚ
startswithÚ
ValueErrorÚalphabetÚcommandÚ__read_motif_statisticsÚ__read_motif_nameÚ__read_motif_sequencesÚMotifÚlengthÚnum_occurrencesÚevalueÚnameÚappendÚlenÚAssertionErrorÚ__skip_unused_linesÚnextÚStopIteration)ÚhandleÚrecordÚliner   r   Úmotif_numberr   r   r   r   Ú	instancesÚmotif© r%   ú4/tmp/pip-build-ww9dw3qa/biopython/Bio/motifs/meme.pyÚread   sB    						
r'   c               @   s(   e  Z d  Z d Z d d d d „ Z d S)r   zäA subclass of Motif used in parsing MEME (and MAST) output.

    This subclass defines functions and data specific to MEME motifs.
    This includes the motif name, the evalue for a motif, and its number
    of occurrences.
    Nc             C   sG   t  j j |  | | ƒ d |  _ d |  _ d |  _ d |  _ d |  _ d S)zInitialize the class.g        r   N)r   r   Ú__init__r   r   r   ÚidZalt_id)Úselfr   r#   r%   r%   r&   r(   Q   s    				zMotif.__init__)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r(   r%   r%   r%   r&   r   I   s   r   c               @   s"   e  Z d  Z d Z d d „  Z d S)ÚInstancezGA class describing the instances of a MEME motif, and the data thereof.c             O   sP   t  j  j |  | | Ž d |  _ d |  _ d |  _ d |  _ d |  _ d |  _ d S)zInitialize the class.Ú r   g      ð?N)r   r(   Úsequence_nameÚstartÚpvalueÚstrandr   Ú
motif_name)r*   ÚargsÚkwdsr%   r%   r&   r(   ^   s    					zInstance.__init__N)r+   r,   r-   r.   r(   r%   r%   r%   r&   r/   [   s   r/   c               @   s.   e  Z d  Z d Z d d „  Z d d „  Z d S)r   aP  A class for holding the results of a MEME run.

    A meme.Record is an object that holds the results from running
    MEME. It implements no methods of its own.

    The meme.Record class inherits from list, so you can access individual
    motifs in the record by their index. Alternatively, you can find a motif
    by its name:

    >>> from Bio import motifs
    >>> with open("motifs/meme.out") as f:
    ...     record = motifs.parse(f, 'MEME')
    >>> motif = record[0]
    >>> print(motif.name)
    Motif 1
    >>> motif = record['Motif 1']
    >>> print(motif.name)
    Motif 1
    c             C   s1   d |  _  d |  _ d |  _ d |  _ g  |  _ d S)zInitialize.r0   N)ÚversionÚdatafiler   r   Ú	sequences)r*   r%   r%   r&   r(   ~   s
    				zRecord.__init__c             C   sJ   t  | t ƒ r6 x4 |  D] } | j | k r | Sq Wn t j |  | ƒ Sd S)zReturn the motif of index key.N)Ú
isinstanceÚstrr   ÚlistÚ__getitem__)r*   Úkeyr$   r%   r%   r&   r>   †   s
    zRecord.__getitem__N)r+   r,   r-   r.   r(   r>   r%   r%   r%   r&   r   i   s   r   c             C   sV   x* | D] } | j  d ƒ r Pq Wt d ƒ ‚ | j ƒ  } | j ƒ  } | d |  _ d  S)NzMEME versionzFImproper input file. File should contain a line starting MEME version.é   )r   r   ÚstripÚsplitr8   )r    r   r!   Úlsr%   r%   r&   r   “   s    r   c             C   sø   x* | D] } | j  d ƒ r Pq Wt d ƒ ‚ y t | ƒ } Wn t k
 r] t d ƒ ‚ Yn X| j  d ƒ s} t d | ƒ ‚ y t | ƒ } Wn t k
 r­ t d ƒ ‚ Yn X| j  d ƒ sÍ t d | ƒ ‚ | j ƒ  } | j d	 d
 ƒ } | |  _ d  S)NzTRAINING SETz‰Unexpected end of stream: 'TRAINING SET' not found. This can happen with minimal MEME files (MEME databases) which are not supported yet.zDUnexpected end of stream: Expected to find line starting with '****'z****z#Line does not start with '****':
%szHUnexpected end of stream: Expected to find line starting with 'DATAFILE'ZDATAFILEz'Line does not start with 'DATAFILE':
%sz
DATAFILE= r0   )r   r   r   r   rA   Úreplacer9   )r    r   r!   r%   r%   r&   r	   ž   s(    	r	   c             C   s«   y t  | ƒ } Wn t k
 r0 t d ƒ ‚ Yn X| j d ƒ sP t d | ƒ ‚ | j ƒ  } | j d d ƒ } | d k rƒ d } n | d k r˜ d } n d } | |  _ d  S)	NzHUnexpected end of stream: Expected to find line starting with 'ALPHABET'ZALPHABETz'Line does not start with 'ALPHABET':
%sz
ALPHABET= r0   ZACGTZACGUZACDEFGHIKLMNPQRSTVWY)r   r   r   r   rA   rD   r   )r    r   r!   Úalr%   r%   r&   r
   ·   s    		r
   c             C   s#  y t  | ƒ } Wn t k
 r0 t d ƒ ‚ Yn X| j d ƒ sP t d | ƒ ‚ y t  | ƒ } Wn t k
 r€ t d ƒ ‚ Yn X| j d ƒ s  t d | ƒ ‚ x| | D]h } | j d ƒ r½ P| j ƒ  } | j ƒ  } |  j j | d ƒ t | ƒ d	 k r§ |  j j | d
 ƒ q§ Wt d ƒ ‚ d  S)NzMUnexpected end of stream: Expected to find line starting with 'Sequence name'zSequence namez,Line does not start with 'Sequence name':
%szDUnexpected end of stream: Expected to find line starting with '----'z----z#Line does not start with '----':
%sz***r   é   é   zCUnexpected end of stream: Expected to find line starting with '***')	r   r   r   r   rA   rB   r:   r   r   )r    r   r!   rC   r%   r%   r&   r   É   s*    r   c             C   sX   x* | D] } | j  d ƒ r Pq Wt d ƒ ‚ | j ƒ  } | j d d ƒ } | |  _ d  S)Nzcommand:zGUnexpected end of stream: Expected to find line starting with 'command'z	command: r0   )r   r   rA   rD   r   )r    r   r!   r%   r%   r&   r   â   s    r   c             C   s\  |  j  ƒ  } | d d k s" t ‚ | d d  d … d k r\ t | d j  d ƒ d ƒ } n t | d ƒ } | d j d ƒ r’ | d	 d  … } n | d d  … } | d  d  d	 … } | d d  d	 … } | d d  d	 … } | d
 d d d g k sù t ‚ x  | D] } | d k s t ‚ q Wt | d ƒ } t | d ƒ }	 t | d	 ƒ }
 | | |	 |
 f S)Nr   r   r@   é   zMEME-ú-é   ZMEMErG   ÚwidthÚsitesZllrzE-valueú=)rB   r   Úintr   Úfloat)r!   Úwordsr"   Z
key_valuesÚkeysZequal_signsÚvaluesZ
equal_signr   r   r   r%   r%   r&   r   í   s$     r   c             C   s_   x' |  D] } d | k r Pq Wt  d ƒ ‚ | j ƒ  } | j ƒ  } d j | d d … ƒ } | S)Nzsorted by position p-valuez3Unexpected end of stream: Failed to find motif nameú r   r@   )r   rA   rB   Újoin)r   r!   rP   r   r%   r%   r&   r   
  s    r   c             C   sõ  y t  |  ƒ } Wn t k
 r0 t d ƒ ‚ Yn X| j d ƒ sP t d | ƒ ‚ y t  |  ƒ } Wn t k
 r€ t d ƒ ‚ Yn X| j d ƒ s  t d | ƒ ‚ y t  |  ƒ } Wn t k
 rÐ t d ƒ ‚ Yn X| j d ƒ sð t d | ƒ ‚ g  } xì |  D]Ø } | j d ƒ rP| j ƒ  } | j ƒ  } | rC| j d ƒ } n d } | d	 }	 t |	 ƒ | k skt ‚ t	 |	 | ƒ }
 | |
 _
 | d
 |
 _ t | d ƒ |
 _ t | d ƒ |
 _ | |
 _ | |
 _ | j |
 ƒ qý Wt d ƒ ‚ t j | | ƒ S)Nz8Unexpected end of stream: Failed to find motif sequencesz---z"Line does not start with '---':
%szMUnexpected end of stream: Expected to find line starting with 'Sequence name'zSequence namez,Line does not start with 'Sequence name':
%srJ   ú+é   r   r@   zUnexpected end of stream)r   r   r   r   rA   rB   Úpopr   r   r/   r5   r1   rN   r2   rO   r3   r4   r   r   r   Z	Instances)r   r5   r   r   r   r!   r#   rP   r4   ÚsequenceÚinstancer%   r%   r&   r     sN    
			r   c             C   sË  x* |  D] } | j  d ƒ r Pq Wt d ƒ ‚ x* |  D] } | j  d ƒ r4 Pq4 Wt d ƒ ‚ x* |  D] } | j  d ƒ ra Pqa Wt d ƒ ‚ x* |  D] } | j  d ƒ rŽ PqŽ Wt d ƒ ‚ x* |  D] } | j  d ƒ r» Pq» Wt d ƒ ‚ y t |  ƒ } Wn t k
 rt d	 ƒ ‚ Yn X| j ƒ  r.t d
 | ƒ ‚ y t |  ƒ } Wn t k
 r^t d ƒ ‚ Yn X| j  d ƒ s~t d | ƒ ‚ x' |  D] } | j ƒ  r…Pq…Wt d ƒ ‚ | j  d ƒ sÇt d | ƒ ‚ d  S)Nzlog-odds matrixzOUnexpected end of stream: Expected to find line starting with 'log-odds matrix'z---zCUnexpected end of stream: Expected to find line starting with '---'zletter-probability matrixzYUnexpected end of stream: Expected to find line starting with 'letter-probability matrix'ZTimezDUnexpected end of stream: Expected to find line starting with 'Time'z5Unexpected end of stream: Expected to find blank linez Expected blank line, but got:
%szCUnexpected end of stream: Expected to find line starting with '***'z***z"Line does not start with '***':
%s)r   r   r   r   rA   )r   r!   r%   r%   r&   r   B  sL    r   N)r.   Ú
__future__r   ZBior   r   r'   r   r/   r=   r   r   r	   r
   r   r   r   r   r   r   r%   r%   r%   r&   Ú<module>   s    ;*,