
:>"^%                 @   s  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
 d d l Z d d l Z y e j Z Wn e k
 r d d	   Z Yn Xe j d k  r d d l Z e j Z n6 e j d k  r d d l Z d d	   Z n d d	   Z y e j Wn e k
 r$d d   Z Yn Xd d	   Z y e j Z Wn' e k
 rgd d l Z e j Z Yn Xd d d  Z Gd d   d e  Z e d k rd d l m Z e d d  d S)a  Bio.SeqIO support for the UCSC nib file format.

Nib stands for nibble (4 bit) representation of nucleotide sequences.
The two nibbles in a byte each store one nucleotide, represented numerically
as follows:

    - ``0`` - T
    - ``1`` - C
    - ``2`` - A
    - ``3`` - G
    - ``4`` - N (unknown)

As the first bit in a nibble is set if the nucleotide is soft-masked, we
additionally have:

    - ``8`` - t
    - ``9`` - c
    - ``a`` - a
    - ``b`` - g
    - ``c`` - n (unknown)

A nib file contains only one sequence record.
You are expected to use this module via the Bio.SeqIO functions under
the format name "nib":

    >>> from Bio import SeqIO
    >>> record = SeqIO.read("Nib/test_even_bigendian.nib", "nib")
    >>> print("%i %s..." % (len(record), record.seq[:20]))
    50 nAGAAGagccgcNGgCActt...

For detailed information on the file format, please see the UCSC
description at https://genome.ucsc.edu/FAQ/FAQformat.html.
    )print_function)	as_handle)SequenceWriter)Seq)	SeqRecordNc             C   s   |  j  d  S)Nhex)decode)s r
   4/tmp/pip-build-ww9dw3qa/biopython/Bio/SeqIO/NibIO.py<lambda>7   s    r         c             C   s   t  j |   j d  S)Nascii)binasciihexlifyr   )br
   r
   r   r   B   s    c             C   s
   |  j    S)N)r   )r   r
   r
   r   r   E   s    c             C   sD   | d k r  t  j d |   d S| d k r@ t  j d |   d Sd S)zConvert byte array to integer.littlez<ir   bigz>iN)structunpack)r   	byteorderr
   r
   r   byte2intK   s    r   c             C   s   t  j |  |  S)N)int
from_bytes)r   r   r
   r
   r   r   U   s    c          
   c   s  | d k	 r t  d   t |  d  o}  |  j d  } | sK t  d   t |  } | d k rl d } n! | d k r d	 } n t  d
   |  j d  } t | |  } |  j   } t |  } | d d k r t |  | k r6t  d   nB | d d k r6t |  | d k r&t  d   | d |  } t |  j d  sWt  d   t d d  }	 | j	 |	  }
 t
 |
  } t |  } | VWd QRXd S)a  Iterate over a nib file and yield a SeqRecord.

        - handle - input file in the nib file format as defined by UCSC.
          This must be opened in binary mode!
        - alphabet - always ignored.

    Note that a nib file always contains only one sequence record.
    The sequence of the resulting SeqRecord object should match the sequence
    generated by Jim Kent's nibFrag utility run with the -masked option.

    This function is used internally via the Bio.SeqIO functions:

    >>> from Bio import SeqIO
    >>> record = SeqIO.read("Nib/test_even_bigendian.nib", "nib")
    >>> print("%s %i" % (record.seq, len(record)))
    nAGAAGagccgcNGgCActtGAnTAtCGTCgcCacCaGncGncTtGNtGG 50

    You can also call it directly:

    >>> with open("Nib/test_even_bigendian.nib", "rb") as handle:
    ...     for record in NibIterator(handle):
    ...         print("%s %i" % (record.seq, len(record)))
    ...
    nAGAAGagccgcNGgCActtGAnTAtCGTCgcCacCaGncGncTtGNtGG 50

    NzAlphabets are ignored.rb   zEmpty file.3a3de96br   6be93d3ar   z"unexpected signature in Nib header   r   zUnexpected file size   
0123489abcz&Unexpected sequence data found in file
TCAGNtcagn)
ValueErrorr   read	bytes2hexr   lensetissubset	maketrans	translater   r   )handleZalphabetword	signaturer   numberlengthdataindicestablenucleotidessequencerecordr
   r
   r   NibIteratora   s<    		r6   c               @   s.   e  Z d  Z d Z d d   Z d d   Z d S)	NibWriterzNib file writer.c             C   sc   | |  _  t j } | d k r' d } n% | d k r< d } n t d |   | j t |   d S)zvInitialize an Nib writer object.

        Arguments:
         - handle - Output handle, in binary write mode.
        r   r   r   r   zunexpected system byte order %sN)r+   sysr   RuntimeErrorwrite	hex2bytes)selfr+   r   r-   r
   r
   r   __init__   s    				zNibWriter.__init__c             C   s  d } x | D] } | d 7} q W| d k r9 t  d   | d k rQ t  d   |  j } | j } t |  } t |  } | j t j d |   t d d  } | d }	 |	 d	 }
 | |
 7} t	 |  j
 d
  s t  d   | j |  } | j t |   | S)z=Use this to write an entire file containing the given record.r   r    zMust have one sequencezMore than one sequence foundir"   r!   r   TZ
ACGTNacgtnz0Sequence should contain A,C,G,T,N,a,c,g,t,n only)r#   r+   seqstrr&   r:   r   packr)   r'   r(   r*   r;   )r<   recordscountr5   r+   r4   r3   r/   r2   paddingsuffixr1   r
   r
   r   
write_file   s*    		


zNibWriter.write_fileN)__name__
__module____qualname____doc__r=   rG   r
   r
   r
   r   r7      s   r7   __main__)run_doctestverbose)r   )r   r   ) rK   
__future__r   ZBio.Filer   ZBio.SeqIO.Interfacesr   ZBio.Seqr   ZBio.SeqRecordr   r   r8   bytesfromhexr;   AttributeErrorversion_infor   r   r%   r   r   r   rA   r)   stringr6   r7   rH   Z
Bio._utilsrM   r
   r
   r
   r   <module>(   sB   
?,