
:>"^                 @   s  d  Z  d d l m 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 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 m Z d d   Z d d   Z d d   Z e j d d  Z e j d d  Z d d d  Z d d   Z d d   Z Gd d   d e  Z Gd d    d  e  Z Gd! d"   d" e  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 "genbank" and "embl" file formats.

You are expected to use this module via the Bio.SeqIO functions.
Note that internally this module calls Bio.GenBank to do the actual
parsing of GenBank, EMBL and IMGT files.

See Also:
International Nucleotide Sequence Database Collaboration
http://www.insdc.org/

GenBank
http://www.ncbi.nlm.nih.gov/Genbank/

EMBL Nucleotide Sequence Database
http://www.ebi.ac.uk/embl/

DDBJ (DNA Data Bank of Japan)
http://www.ddbj.nig.ac.jp/

IMGT (use a variant of EMBL format with longer feature indents)
http://imgt.cines.fr/download/LIGM-DB/userman_doc.html
http://imgt.cines.fr/download/LIGM-DB/ftable_doc.html
http://www.ebi.ac.uk/imgt/hla/docs/manual.html

    )print_functionN)datetime)BiopythonWarning)
UnknownSeq)GenBankScannerEmblScanner_ImgtScanner)Alphabet)SequentialSequenceWriter)
SeqFeature)_is_int_or_long)
basestringc             C   s   t  d d  j |   S)a   Break up a Genbank file into SeqRecord objects.

    Every section from the LOCUS line to the terminating // becomes
    a single SeqRecord with associated annotation and features.

    Note that for genomes or chromosomes, there is typically only
    one record.

    This gets called internally by Bio.SeqIO for the GenBank file format:

    >>> from Bio import SeqIO
    >>> for record in SeqIO.parse("GenBank/cor6_6.gb", "gb"):
    ...     print(record.id)
    ...
    X55053.1
    X62281.1
    M81224.1
    AJ237582.1
    L31939.1
    AF297471.1

    Equivalently,

    >>> with open("GenBank/cor6_6.gb") as handle:
    ...     for record in GenBankIterator(handle):
    ...         print(record.id)
    ...
    X55053.1
    X62281.1
    M81224.1
    AJ237582.1
    L31939.1
    AF297471.1

    debugr   )r   parse_records)handle r   6/tmp/pip-build-ww9dw3qa/biopython/Bio/SeqIO/InsdcIO.pyGenBankIterator9   s    %r   c             C   s   t  d d  j |   S)ax  Break up an EMBL file into SeqRecord objects.

    Every section from the LOCUS line to the terminating // becomes
    a single SeqRecord with associated annotation and features.

    Note that for genomes or chromosomes, there is typically only
    one record.

    This gets called internally by Bio.SeqIO for the EMBL file format:

    >>> from Bio import SeqIO
    >>> for record in SeqIO.parse("EMBL/epo_prt_selection.embl", "embl"):
    ...     print(record.id)
    ...
    A00022.1
    A00028.1
    A00031.1
    A00034.1
    A00060.1
    A00071.1
    A00072.1
    A00078.1
    CQ797900.1

    Equivalently,

    >>> with open("EMBL/epo_prt_selection.embl") as handle:
    ...     for record in EmblIterator(handle):
    ...         print(record.id)
    ...
    A00022.1
    A00028.1
    A00031.1
    A00034.1
    A00060.1
    A00071.1
    A00072.1
    A00078.1
    CQ797900.1

    r   r   )r   r   )r   r   r   r   EmblIteratora   s    +r   c             C   s   t  d d  j |   S)a
  Break up an IMGT file into SeqRecord objects.

    Every section from the LOCUS line to the terminating // becomes
    a single SeqRecord with associated annotation and features.

    Note that for genomes or chromosomes, there is typically only
    one record.
    r   r   )r   r   )r   r   r   r   ImgtIterator   s    
r   c             C   s   t  d d  j |  |  S)a   Break up a Genbank file into SeqRecord objects for each CDS feature.

    Every section from the LOCUS line to the terminating // can contain
    many CDS features.  These are returned as with the stated amino acid
    translation sequence (if given).
    r   r   )r   parse_cds_features)r   alphabetr   r   r   GenBankCdsFeatureIterator   s    r   c             C   s   t  d d  j |  |  S)zBreak up a EMBL file into SeqRecord objects for each CDS feature.

    Every section from the LOCUS line to the terminating // can contain
    many CDS features.  These are returned as with the stated amino acid
    translation sequence (if given).
    r   r   )r   r   )r   r   r   r   r   EmblCdsFeatureIterator   s    r   c                s7  t  |  t j  r! d |  j   St  |  t j  rV d |  j   |  j |  j   f St  |  t j  r d |  j   |  j |  j   f St  |  t j  r d |  j   St  |  t j  r d |  j   St  |  t j	  rd d j
   f d d	   |  j D  St  |  t j  r't d
   n t d   d S)zBuild a GenBank/EMBL position string (PRIVATE).

    Use offset=1 to add one to convert a start position from python counting.
    z%iz(%i.%i)z(%i^%i)z<%iz>%iz
one-of(%s),c             3   s   |  ] } t  |    Vq d  S)N)_insdc_feature_position_string).0p)offsetr   r   	<genexpr>   s    z1_insdc_feature_position_string.<locals>.<genexpr>z)Please report this as a bug in Biopython.z&Expected a SeqFeature position object.N)
isinstancer   ExactPositionpositionZWithinPosition	extensionZBetweenPositionZBeforePositionZAfterPositionZOneOfPositionjoinZposition_choicesZAbstractPositionNotImplementedError
ValueError)posr   r   )r   r   r      s(    

	r   c             C   s  |  j  r d |  j  } n d } |  j s/ t  t |  j t j  r t |  j t j  r |  j j |  j j k r |  j j | k r d | | f Sd | |  j j |  j j d f St |  j t j  rt |  j t j  r|  j j d |  j j k rd | |  j j f St |  j t j	  s6t |  j t j	  rt |  j t j	  rot |  j t j	  rot
 d   qt |  j t j	  rd | |  j t |  j  f Sd	 | t |  j d  |  j d f Sn% | t |  j d  d
 t |  j  Sd  S)Nz%s: z%s%i^1z%s%i^%i   z%s%izFeature with unknown locationz	%s<%i..%sz	%s%s..>%iz..r)   r)   )refZref_dbAssertionErrorr    startr   r!   endr"   ZUnknownPositionr&   nofuzzy_endr   nofuzzy_start)location
rec_lengthr*   r   r   r   6_insdc_location_string_ignoring_strand_and_subfeatures   s:    	!r2   c                s   y |  j  } |  j d
 k rU d |  j d j   f d d   | d d d  D  f Sd |  j d j   f d d   | D  f SWn< t k
 r t |     } |  j d k r d	 | S| SYn Xd S)aY  Build a GenBank/EMBL location from a (Compound) FeatureLocation (PRIVATE).

    There is a choice of how to show joins on the reverse complement strand,
    GenBank used "complement(join(1,10),(20,100))" while EMBL used to use
    "join(complement(20,100),complement(1,10))" instead (but appears to have
    now adopted the GenBank convention). Notice that the order of the entries
    is reversed! This function therefore uses the first form. In this situation
    we expect the CompoundFeatureLocation and its parts to all be marked as
    strand == -1, and to be in the order 19:100 then 0:10.
    r)   zcomplement(%s(%s))r   c             3   s   |  ] } t  |    Vq d  S)N)r2   )r   r   )r1   r   r   r   "  s   z)_insdc_location_string.<locals>.<genexpr>Nz%s(%s)c             3   s   |  ] } t  |    Vq d  S)N)_insdc_location_string)r   r   )r1   r   r   r   +  s    zcomplement(%s)r4   r4   )partsZstrandoperatorr$   AttributeErrorr2   )r0   r1   r5   locr   )r1   r   r3     s"    	(r3   c               @   s   e  Z d  Z d Z d Z d Z d e Z d Z d" Z d d d d  Z	 d d   Z
 d d   Z e d d d d   Z e d d    Z d  d!   Z d S)#_InsdcWriterz2Base class for GenBank and EMBL writers (PRIVATE).P       z     %s                	anticodoncitationcodon_startcompare	directionestimated_lengthmod_basenumberrpt_typerpt_unit_rangetag_peptidetransl_excepttransl_tableNc             C   s  | d  k r- |  j  j d |  j | f  d  St |  t k rQ | j d d  } | d  k r t |  sx | |  j k r d } n d } | r d |  j | | f } n d |  j | | f } t |  |  j	 k r |  j  j | d  d  Sx | j
   rt |  |  j	 k r%|  j  j | d  d  SxH t t t |  d	 |  j	  |  j d	 d  D] } | | d
 k rUPqUW| | d
 k r|  j	 } | |  j	 k st  |  j  j | d  |  d  |  j | | d   j
   } q Wd  S)Nz%s/%s
"z""FTz
%s/%s="%s"z%s/%s=%s
r)   r<   r4   )r   writeQUALIFIER_INDENT_STRtypestrreplacer   FTQUAL_NO_QUOTElen	MAX_WIDTHlstriprangeminQUALIFIER_INDENTr+   )selfkeyvaluequotelineindexr   r   r   _write_feature_qualifierO  s:    	0	z%_InsdcWriter._write_feature_qualifierc             C   s   |  j  |  j } t |  | k r& | S| d |  j d  } | d k rc t j d | t  | S| d | d  d |  j |  j | | d d   S)z@Split a feature location into lines (break at commas) (PRIVATE).Nr   r)   zCouldn't split location:
%srK   r4   )	rS   rW   rR   rfindwarningswarnr   rM   _wrap_location)rX   r0   lengthr]   r   r   r   rb   z  s    z_InsdcWriter._wrap_locationc       	      C   s   | j  s t |   t | j |  } | j  j d d  } |  j | d |  j  |  j |  d } |  j j	 |  xf | j
 j   D]U \ } } t | t t f  r x1 | D] } |  j | |  q Wq |  j | |  q Wd S)z=Write a single SeqFeature object to features table (PRIVATE).r<   _NrK   )rN   r+   r3   r0   rP   QUALIFIER_INDENT_TMPrW   rb   r   rL   Z
qualifiersitemsr    listtupler^   )	rX   featureZrecord_lengthr0   Zf_typer\   rY   valuesrZ   r   r   r   _write_feature  s    +z_InsdcWriter._write_feature.Fc             C   ss   y |  j  | } Wn t k
 r) | SYn Xt | t  re | sW t |  d k sW t  t | d  St |  Sd S)a  Get an annotation dictionary entry (as a string) (PRIVATE).

        Some entries are lists, in which case if just_first=True the first entry
        is returned.  If just_first=False (default) this verifies there is only
        one entry before returning it.
        r)   r   N)annotationsKeyErrorr    rg   rR   r+   rO   )recordrY   default
just_firstanswerr   r   r   _get_annotation_str  s    	z _InsdcWriter._get_annotation_strc             C   s"  |  j    }  t |   | k r% |  g S|  j   } d }  xQ | r t |   d t | d  | k r |  d | j d  7}  |  j    }  q: W|  g } xz | r| j d  }  xQ | r t |   d t | d  | k r |  d | j d  7}  |  j    }  q W| j |   q W| st  | S)zReturn a list of strings (PRIVATE).

        Any single words which are too long get returned as a whole line
        (e.g. URLs) without an exception or warning.
        r(   r)   r   r<   )striprR   splitpopappendr+   )textmax_lenwordsrr   r   r   r   _split_multi_line  s"    -		-z_InsdcWriter._split_multi_linec             C   s   | j  j d d  } t | t t f  r9 d j |  } |  j |  } g  } x | r t |  | k r | d | d  j d  } | d k r t	 d   | d | d  | | d d  } } n | d } } | j
 |  qQ W| S)z5Return a list of strings, splits on commas (PRIVATE).contigr(   Nr)   r   zCould not break up CONTIGr4   )rm   getr    rg   rh   r$   cleanrR   r_   r&   rw   )rX   ro   ry   r|   rr   r'   rx   r   r   r   _split_contig  s    	,z_InsdcWriter._split_contig)r=   r>   r?   r@   z	directionrB   rC   znumberrE   rF   rG   rH   rI   )__name__
__module____qualname____doc__rS   rW   rM   re   rQ   r^   rb   rk   staticmethodrs   r{   r   r   r   r   r   r9   8  s2   
            +r9   c               @   s   e  Z d  Z d Z d Z d Z d Z d Z d Z d Z	 d Z
 d	 d
   Z d d   Z d d   Z e d d    Z e 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)"GenBankWriterzGenBank writer.   r;   z-START##z-END##z :: <   	   c             C   s   t  |  |  j k  s t  t  |  |  j |  j k rn | rZ t j d | | f t  n t j d | t  |  j j d | j	 |  j  | j
 d d  f  d S)zrWrite single line in each GenBank record (PRIVATE).

        Used in the 'header' of each GenBank record.
        z"Annotation %r too long for %r linezAnnotation %r too longz%s%s
rK   r<   N)rR   HEADER_WIDTHr+   rS   r`   ra   r   r   rL   ljustrP   )rX   tagrx   r   r   r   _write_single_line  s    	z GenBankWriter._write_single_linec             C   se   |  j  |  j } |  j | |  } |  j | | d  x( | d d  D] } |  j d |  qG Wd S)zuWrite multiple lines in each GenBank record (PRIVATE).

        Used in the 'header' of each GenBank record.
        r   r)   Nr(   )rS   r   r{   r   )rX   r   rx   ry   linesr\   r   r   r   _write_multi_line  s
    zGenBankWriter._write_multi_linec             C   sP   xI t  |  D]; \ } } | d k r8 |  j | |  q |  j d |  q Wd  S)Nr   r(   )	enumerater   )rX   r   Z	text_listirx   r   r   r   _write_multi_entries  s    z"GenBankWriter._write_multi_entriesc             C   s9  d } y |  j  d } Wn t k
 r/ | SYn Xt | t  r[ t |  d k r[ | d } t | t  r | j d  j   } d d d d	 d
 d d d d d d d g } t | t  s t |  d k r | SyK t t	 | d d    | j
 | d d   d t	 | d d    Wn t k
 r4| } Yn X| S)Nz01-JAN-1980dater)   r   z%d-%b-%YZJANZFEBZMARZAPRZMAYZJUNZJULZAUGZSEPZOCTZNOVZDEC               )rm   rn   r    rg   rR   r   strftimeupperr   intr]   r&   )ro   rp   r   monthsr   r   r   	_get_date  s8    	!
	"KzGenBankWriter._get_datec             C   s   y |  j  d } Wn t k
 r+ d } Yn X| d k r; nS d d d d d d d d	 d d d d i } y | | } Wn t k
 r d } Yn Xt |  d k s t  | S)Ndata_file_divisionUNKPRIRODMAMVRTINVPLNBCTVRLPHGSYNUNAESTPATSTSGSSHTGHTCENVCONFUNHUMMUSPROUNCXXXr   )r   r   r   r   r   r   r   r   r   r   r   zESTr   r   r   r   r   r   r   )rm   rn   rR   r+   )ro   divisionZembl_to_gbkr   r   r   _get_data_division=  sJ                      	z GenBankWriter._get_data_divisionc             C   sU   t  d  } |  j | d d d } | rI t  |  | k rI | j |  Sd | Sd S)z>Set the topology to 'circular', 'linear' if defined (PRIVATE).circulartopologyrp   r(   r<   N)rR   rs   r   )rX   ro   Zmax_topology_lenr   r   r   r   _get_topology  s
    zGenBankWriter._get_topologyc             C   s  | j  } | s | d k r% | j } | s8 | d k rP |  j | d d d } t |  d k r t |  d t t t |    d k r t j d	 t  t | j    d k r t	 |  } | j
 d
  r | j d  r | d d  } t d |   t |  d k r"t j d t  t j | j j  } t | t j  sXt d   nB t | t j  rsd } n' t | t j  rd } n t d   |  j | d d d } | rt |  d k r| j d d  j d d  } t |  d k rt j d | t  d } | dH k r&d } | r/n] t | t j  rJd } nB t | t j  red } n' t | t j  rd } n t d   |  j |  } |  j |  } t |  d k rt t t |    d  t |  d k r| d! t t |   }	 nk t t |   j d  }	 | |	 t |  d  }	 t |	  d k sXt |	   d! |	 k spt |	   t |  d" k st  t |  d# k st  d$ |	 | | j d  | | |  j |  f }
 t |
  d% k r}|
 j   } | d# dI k rt d& |
   | d' j   d k pWd | d' j   j   k pWd | d' j   j   k sjt d( |
   |  j  j! |
  nt |
  dJ k st t	 |
    |
 d* d+  j   | t t |   g k st |
   |
 d+ d,  dK k rt d& |
   |
 d, d/  dL k r't d4 |
   |
 d/ d5  j   d k pd |
 d/ d5  j   j   k pd |
 d/ d5  j   j   k st d( |
   |
 d5 d6  d! k rt d7 |
   |
 d6 d8  j   dM k rt d; |
   |
 d8 d<  d! k rt d= |
   |
 d> d?  d! k r5t d@ |
   |
 dA dB  dC k r[t dD |
   |
 dE dF  dC k rt dG |
   |  j  j! |
  d S)NzWrite the LOCUS line (PRIVATE).z<unknown name>z<unknown id>	accessionrq   T   r)      zoIncreasing length of locus line to allow long name. This will result in fields that are not in usual positions.zu''Nz'Invalid whitespace in %s for LOCUS linel   g] zThe sequence length is very long. The LOCUS line will be increased in length to compensate. This may cause unexpected behavior.zInvalid alphabetaabpz%Need a Nucleotide or Protein alphabetmolecule_typerp      zunassigned r(   zgenomic zMolecule type %r too longproteinPROTEINDNARNAz#Need a DNA, RNA or Protein alphabetr   r<   r   r   z!LOCUS       %s %s    %s %s %s %s
r:   z=LOCUS line does not contain size units at expected position:
r   zALOCUS line does not contain valid sequence type (DNA, RNA, ...):
O   r   (   ,    bp  aa /      ss-ds-ms-zCLOCUS line does not have valid strand type (Single stranded, ...):
6   7   z2LOCUS line does not contain space at position 55:
?   linearr   zALOCUS line does not contain valid entry (linear, circular, ...):
@   z2LOCUS line does not contain space at position 64:
C   D   z2LOCUS line does not contain space at position 68:
F   G   -z6LOCUS line does not contain - at position 71 in date:
J   K   z6LOCUS line does not contain - at position 75 in date:
)r   r   )r   r   r:   )r   r   )r   r   r   r   )r(   r   zcircular)"nameidrs   rR   rO   r`   ra   r   ru   repr
startswithendswithr&   r	   _get_base_alphabetseqr   r    	TypeErrorProteinAlphabetZNucleotideAlphabetrP   DNAAlphabetRNAAlphabetr   r   rjustr+   r   r   rt   r   r   rL   )rX   ro   Zlocustmpaunitsmol_typer   r   Zname_lengthr\   Z	splitliner   r   r   _write_the_first_line  s    		,					>

$	:

""

z#GenBankWriter._write_the_first_linec             C   s  d } x| j  d D]} t | t j  s/ q | d 7} t |  } | j r t | j  d k r t j | j	 j
  } t | t j  r d } n d } | d | | j d j d | j d j f 7} |  j d |  | j r |  j d | j  | j r|  j d	 | j  | j r,|  j d
 | j  | j rH|  j d | j  | j rd|  j d | j  | j r|  j d | j  | j r |  j d | j  q Wd  S)Nr   
referencesr)   Zresiduesbasesz  (%s %i to %i)Z	REFERENCEz	  AUTHORSz	  CONSRTMz  TITLEz	  JOURNALz	  MEDLINEz	   PUBMEDz  REMARK)rm   r    r   	ReferencerO   r0   rR   r	   r   r   r   r   r/   r.   r   authorsr   consrtmtitlejournalZ
medline_id	pubmed_idcomment)rX   ro   rD   r*   datar   r   r   r   r   _write_referencesT  s<    
								zGenBankWriter._write_referencesc             C   s  g  } d | j  k r.| j  d } d } x[ | j   D]M \ } } x> | j   D]0 \ } } t |  | k rx t |  n | } qN Wq5 Wx | j   D] \ } } | j d j | |  j   xP | j   D]B \ } } d | t |  }	 | j d j | |	 |  j |   q W| j d j | |  j   q Wd | j  k r| j  d } t | t	  ro| | j
 d  7} n4 t | t t f  r| t |  7} n t d   |  j d	 | d  x( | d
 d   D] }
 |  j d |
  qWd  S)Nstructured_commentr   z##{0}{1}r<   z{0}{1}{2}{3}r   rK   z'Could not understand comment annotationCOMMENTr)   r(   )rm   rf   rR   rw   formatSTRUCTURED_COMMENT_STARTSTRUCTURED_COMMENT_DELIMSTRUCTURED_COMMENT_ENDr    r   ru   rg   rh   r&   r   )rX   ro   r   r   paddingrY   r   subkeyZsubdataspacesr\   r   r   r   _write_comment  s2    , zGenBankWriter._write_commentc             C   se   |  j  |  j } |  j | |  } |  j d | d  x( | d d   D] } |  j d |  qG Wd  S)NZCONTIGr   r)   r(   )rS   r   r   r   )rX   ro   ry   r   rx   r   r   r   _write_contig  s
    zGenBankWriter._write_contigc             C   s  t  | j t  rE d | j k r1 |  j |  n |  j j d  d  S|  j |  j   } t	 |  } |  j j d  x t
 d | |  j  D] } |  j j t | d  j |  j   xL t
 | t | |  j |  d  D]( } |  j j d | | | d   q W|  j j d  q Wd  S)Nr|   zORIGIN
r   r)   
   z %srK   )r    r   r   rm   r  r   rL   _get_seq_stringlowerrR   rU   LETTERS_PER_LINErO   r   SEQUENCE_INDENTrV   )rX   ro   r   seq_lenline_numberrz   r   r   r   _write_sequence  s    &#&zGenBankWriter._write_sequencec             C   s  |  j  } |  j |  | j } | j d  d k rp | | j d  d d  j   rp | j j d d  d } |  j | d | d d } | } | j j | d  r y- d | t	 | j j d d  d  f } Wn t
 k
 r Yn X|  j | d	 d d } | j } | d
 k rd } | d 7} |  j d |  |  j d |  | d k ro|  j d d | | f  n |  j d d |  g  } x< | j D]1 }	 d |	 k r|	 j d d  }	 | j |	  qW|  j d |  ~ y3 d j | j d  }
 |
 j d  s|
 d 7}
 Wn t k
 r(d }
 Yn X|  j d |
  d | j k r| j d } t | t  rt |  d k st |   | d } |  j d |  |  j d |  j | d   |  j | d  } t |  |  j |  j k r| d |  j |  j d  d } |  j d |  y3 d j | j d  } | j d  sJ| d 7} Wn t k
 red } Yn X|  j d |  d  | j k r|  j |  d! | j k sd" | j k r|  j |  | j d#  t |  } x! | j D] } |  j  | |  qW|  j! |  | j d$  d S)%z)Write a single record to the output file.rl   r)   Nr   r   rq   Tz%s.%igiz<unknown description>r(   Z
DEFINITIONZ	ACCESSIONVERSIONz	%s  GI:%sz%sz: :ZDBLINKz; keywordsZKEYWORDSsegmentZSEGMENTZSOURCEsourceorganismr   z...z
  ORGANISMtaxonomyr   r   r   z)FEATURES             Location/Qualifiers
z//
)"r   r   r   countr]   isdigitru   rs   r   r   r&   descriptionr   r   dbxrefsrP   rw   r   r$   rm   r   rn   r    rg   rR   r+   rS   r   r   r  rL   featuresrk   r  )rX   ro   r   rp   r   Zacc_with_versionr  descrZdbxrefs_with_spacexr  r  orgr  r1   ri   r   r   r   write_record  s    		8'	

"zGenBankWriter.write_recordN)r   r   r   r   r   rW   r   r  r   r
  r  r   r   r   r   r   r   r   r   r   r  r  r  r  r   r   r   r   r     s(   	#V
,&r   c               @   s   e  Z d  Z d Z d Z d Z d d e d Z d Z d Z d	 Z	 d
 Z
 e	 e
 Z d	 Z d d   Z d d   Z d d   Z d d   Z d d   Z e d d    Z d d   Z d d   Z d d   Z d d   Z d S) 
EmblWriterzEMBL writer.   r;   FTr<   r   zFT   %s                z,FH   Key             Location/Qualifiers
FH
r  r   c             C   sG   |  j  |  j } |  j | |  } x | D] } |  j d |  q) Wd  S)NZCO)rS   r   r   r   )rX   ro   ry   r   rx   r   r   r   r  T  s    zEmblWriter._write_contigc             C   s  |  j  } t | j t  rK d | j k r: |  j |  n | j d  d  S|  j |  j   } t	 |  } t
 j | j j  } t | t
 j  r?| j d  | j d  } | j d  | j d  } | j d  | j d  } | j d	  | j d
  }	 | | | | |	 }
 | j d | | | | |	 |
 f  n | j d  x t d | |  j  D] } | j d  xQ t |  j  D]@ } |  j | |  j | } | j d | | | |  j   qW| j t | d |  j  j |  j   | j d  qcW| |  j r| |  j } | j d  xZ t |  j  D]I } |  j | |  j | } | j d | | | |  j  j d   q<W| j t |  j |  j   | j d  d  S)Nr|   zSQ   
Ar   CcGgTtz7SQ   Sequence %i BP; %i A; %i C; %i G; %i T; %i other;
r   z    z %sr)   rK   r   )r   r    r   r   rm   r  rL   r  r	  rR   r	   r   r   r   r  rU   r
  BLOCKS_PER_LINELETTERS_PER_BLOCKrO   r   POSITION_PADDINGr   )rX   ro   r   r   r  r   Za_countZc_countZg_countZt_countotherr  blockr]   r   r   r   r  Z  sJ    	&)zEmblWriter._write_sequencec             C   sg   t  |  d k s t  | d | } t  |  |  j k rO t j d | t  |  j j | d  d  S)Nr   z   zLine %r too longrK   )rR   r+   rS   r`   ra   r   r   rL   )rX   r   rx   r\   r   r   r   r     s
    zEmblWriter._write_single_linec             C   sG   |  j  |  j } |  j | |  } x | D] } |  j | |  q) Wd  S)N)rS   r   r{   r   )rX   r   rx   ry   r   r\   r   r   r   r     s    zEmblWriter._write_multi_linec       
   
   C   sZ  d | j  k r| | j  j d d  d j   r| d | j  j d d  d } |  j | d | j  j d d  d d d } n$ d } |  j | d | j  d d } d	 | k r t d
 t t |     d | k r t d t t |     |  j | d d d } t j | j	 j
  } t | t j  s>t d   no t | t j  r_d } d } nN t | t j  rd } d } n- t | t j  rd } d } n t d   | j j d d  r| j d } | d k rd } |  j |  } |  j }	 |  j d d | | | | | t |  | f  |	 j d  |  j d | d	  |	 j d  d S)z$Write the ID and AC lines (PRIVATE).rl   r)   zSV r   r   rq   Tr(   ;z,Cannot have semi-colon in EMBL accession, %sr<   z(Cannot have spaces in EMBL accession, %sr   rp   zInvalid alphabetr   ZBPr   r   ZAAz#Need a DNA, RNA or Protein alphabetr   Nr   ZIDz%s; %s; %s; %s; ; %s; %i %s.zXX
ZAC)zprotein)r   rsplitr  rs   r&   r   rO   r	   r   r   r   r    r   r   r   r   rm   r}   r   r   r   rR   rL   )
rX   ro   versionr   r   r   r   r   r   r   r   r   r   _write_the_first_lines  sP    .+					#z!EmblWriter._write_the_first_linesc             C   s   y |  j  d } Wn t k
 r+ d } Yn X| d k r; n; d d d d i } y | | } Wn t k
 ru d } Yn Xt |  d k s t  | S)Nr   r   r   r   r   r   r   r   r   r   r   r   r   r   TGNr   r   r   r   r   )zPHGzENVzFUNzHUMzINVzMAMzVRTzMUSzPLNzPROzRODzSYNr3  zUNCzVRLzXXX)rm   rn   rR   r+   )ro   r   Zgbk_to_emblr   r   r   r     s:                   	zEmblWriter._get_data_divisionc             C   s<   x% | j  d D] } |  j d |  q W|  j j d  d  S)Nr  ZKWzXX
)rm   r   r   rL   )rX   ro   keywordr   r   r   _write_keywords&  s    zEmblWriter._write_keywordsc             C   sQ  d } xD| j  d D]5} t | t j  s/ q | d 7} |  j d d |  | j r t | j  d k r |  j d d | j d j d | j d j f  | j	 r |  j d d	 | j	  | j
 r |  j d
 d | j
  | j r |  j d | j d  | j r|  j d d | j  | j r9|  j d | j  |  j j d  q Wd  S)Nr   r   r)   ZRNz[%i]ZRPz%i-%iZRXzPUBMED; %s.ZRGz%sZRAr/  ZRTz"%s";ZRLzXX
)rm   r    r   r   r   r0   rR   r/   r.   r   r   r   r   r   r   r   rL   )rX   ro   rD   r*   r   r   r   r   /  s,    
&					zEmblWriter._write_referencesc             C   s   | j  d } t | t  r. | j d  } n* t | t t f  rL | } n t d   | sb d  Sx | D] } |  j d |  qi W|  j j	 d  d  S)Nr   rK   z'Could not understand comment annotationCCzXX
)
rm   r    r   ru   rg   rh   r&   r   r   rL   )rX   ro   r   r   r\   r   r   r   r  P  s    	zEmblWriter._write_commentc             C   s  |  j  } |  j |  x t | j  D]r } | j d  rg |  j d | d d  d  | j d  P| j d  r& |  j d | d  | j d  Pq& W| j } | d k r d	 } |  j d
 |  | j d  d | j	 k r |  j
 |  |  j d |  j | d   y d j | j	 d  d	 } Wn t k
 rDd	 } Yn X|  j d |  | j d  d | j	 k r~|  j |  d | j	 k r|  j |  | j |  j  t |  } x! | j D] } |  j | |  qW| j d  |  j |  | j d  d S)z)Write a single record to the output file.zBioProject:ZPRr   Nr/  zXX
zProject:z<unknown description>rl   ZDEr  ZOSr  z; r  ZOCr   r   z//
)r   r2  sortedr  r   r   rL   r  r   rm   r5  rs   r$   rn   r   r  FEATURE_HEADERrR   r  rk   r  )rX   ro   r   Zxrefr  r  r1   ri   r   r   r   r  e  sH    		zEmblWriter.write_recordN)r   r   r   r   r   rW   rM   re   r8  r+  r*  r
  r,  r  r  r   r   r2  r   r   r5  r   r  r  r   r   r   r   r   E  s(   
<H;	!r   c               @   s@   e  Z d  Z d Z d Z d Z d d e d Z d Z d Z d	 S)

ImgtWriterz"IMGT writer (EMBL format variant).r!     r"  r<   r   zFT   %s                    z0FH   Key                 Location/Qualifiers
FH
N)	r   r   r   r   r   rW   rM   re   r8  r   r   r   r   r9    s   r9  __main__)run_doctestverbose)$r   
__future__r   r`   r   ZBior   ZBio.Seqr   ZBio.GenBank.Scannerr   r   r   r	   ZBio.SeqIO.Interfacesr
   r   Z	Bio._py3kr   r   r   r   r   Zgeneric_proteinr   r   r   r2   r3   r9   r   r   r9  r   Z
Bio._utilsr<  r   r   r   r   <module>   s:   (.>)  _ i
