
    Ri                         d Z ddlZddl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
  G d d	e	      Z G d
 de
      Zedk(  rddlmZ  ed       yy)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.
    N)Seq)	SeqRecord   )SequenceIterator)SequenceWriterc                   ,     e Zd ZdZdZ fdZd Z xZS )NibIteratorzParser for nib files.bc                     t         |   |d       | j                  j                  d      }|st	        d      |j                         }|dk(  rd| _        y
|dk(  rd| _        y
t	        d	      )a  Iterate over a nib file and yield a SeqRecord.

            - source - a file-like object or a path to a file in the nib file
              format as defined by UCSC; the file must be opened in binary mode.

        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

        Nib)fmt   zEmpty file.3a3de96blittle6be93d3abigz"unexpected signature in nib headerN)super__init__streamread
ValueErrorhex	byteorder)selfsourceword	signature	__class__s       G/home/agent/.friday_env/lib/python3.12/site-packages/Bio/SeqIO/NibIO.pyr   zNibIterator.__init__:   sn    4 	U+{{"]++HHJ	
"%DN*$"DNABB    c                 6   | j                   }| j                  }|j                  d      }|st        t        j                  ||      }|j                         }t        j                  |      }|dz  dk(  rt        |      |k7  r4t        d      |dz  dk(  r!t        |      |dz   k7  rt        d      |d| }t        |      j                  d      st        d      t        j                  dd	      }|j                  |      }t        |      }	t!        |	      }
|
S )
z)Iterate over the records in the nib file.r      r   zUnexpected file sizer   N
   0123489abcz&Unexpected sequence data found in file
   TCAGNtcagn)r   r   r   StopIterationint
from_bytesbinasciihexlifylenr   setissubsetbytes	maketrans	translater   r   )r   r   r   numberlengthdataindicestablenucleotidessequencerecords              r   __next__zNibIterator.__next__`   s   NN	Q	2{{}""4(A:?7|v% !788aZ1_7|vz) !788gv&G7|$$]3EFF}=''.{#8$r    )__name__
__module____qualname____doc__modesr   r8   __classcell__)r   s   @r   r	   r	   5   s    E$CLr    r	   c                   &    e Zd ZdZdZd Zd Zd Zy)	NibWriterzNib file writer.r
   c                     | j                   }t        j                  }|dk(  rd}n|dk(  rd}nt        d|       |j	                  t
        j                  |             y)zWrite the file header.r   r   r   r   zunexpected system byte order N)handlesysr   RuntimeErrorwriter-   fromhex)r   rB   r   r   s       r   write_headerzNibWriter.write_header   sV    MM	 "I%"I!>ykJKKU]]9-.r    c                    | j                   }|j                  }t        |      }t        |      }|j	                  t        j                  d|             t        j                  dd      }|dz  }|dz  }||z  }t        |      j                  d      st        d      |j                  |      }	|j	                  t        j                  |	             y)	z)Write a single record to the output file.ir$   r#   r"      Ts
   ACGTNacgtnz0Sequence should contain A,C,G,T,N,a,c,g,t,n onlyN)rB   seqr-   r*   rE   structpackr.   r+   r,   r   r/   r(   	unhexlify)
r   r7   rB   r6   r5   r1   r4   paddingsuffixr3   s
             r   write_recordzNibWriter.write_record   s    ::HoXV[[f-.}=1*4v;((7OPP''.X''01r    c                     | j                          d}|D ](  }|dk(  rt        d      | j                  |       |dz  }* |dk7  rt        d      |S )zWrite records to the output file, and return the number of records.

        records - A list or iterator returning SeqRecord objects
        r   r   zMore than one sequence foundzMust have one sequence)rG   r   rQ   )r   recordscountr7   s       r   write_recordszNibWriter.write_records   sh    
 	 	Fz !?@@f%QJE		
 A:566r    N)r9   r:   r;   r<   r=   rG   rQ   rU    r    r   r@   r@   z   s    E
/2 r    r@   __main__)run_doctest)verbose)r<   r(   rL   rC   Bio.Seqr   Bio.SeqRecordr   
Interfacesr   r   r	   r@   r9   
Bio._utilsrX   rV   r    r   <module>r^      sY    D   
  # ( &B" BJ/ /d z& r    