
    Ri3                         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	 ddlm
Z
  ej                  d	      Z ej                  d
      ZdZd Z G d de
      Z G d de	      Zy)aU  Bio.AlignIO support for "xmfa" output from Mauve/ProgressiveMauve.

You are expected to use this module via the Bio.AlignIO functions (or the
Bio.SeqIO functions if you want to work directly with the gapped sequences).

For example, consider a progressiveMauve alignment file containing the following::

    #FormatVersion Mauve1
    #Sequence1File	a.fa
    #Sequence1Entry	1
    #Sequence1Format	FastA
    #Sequence2File	b.fa
    #Sequence2Entry	2
    #Sequence2Format	FastA
    #Sequence3File	c.fa
    #Sequence3Entry	3
    #Sequence3Format	FastA
    #BackboneFile	three.xmfa.bbcols
    > 1:0-0 + a.fa
    --------------------------------------------------------------------------------
    --------------------------------------------------------------------------------
    --------------------------------------------------------------------------------
    > 2:5417-5968 + b.fa
    TTTAAACATCCCTCGGCCCGTCGCCCTTTTATAATAGCAGTACGTGAGAGGAGCGCCCTAAGCTTTGGGAAATTCAAGC-
    --------------------------------------------------------------------------------
    CTGGAACGTACTTGCTGGTTTCGCTACTATTTCAAACAAGTTAGAGGCCGTTACCTCGGGCGAACGTATAAACCATTCTG
    > 3:9476-10076 - c.fa
    TTTAAACACCTTTTTGGATG--GCCCAGTTCGTTCAGTTGTG-GGGAGGAGATCGCCCCAAACGTATGGTGAGTCGGGCG
    TTTCCTATAGCTATAGGACCAATCCACTTACCATACGCCCGGCGTCGCCCAGTCCGGTTCGGTACCCTCCATGACCCACG
    ---------------------------------------------------------AAATGAGGGCCCAGGGTATGCTT
    =
    > 2:5969-6015 + b.fa
    -----------------------
    GGGCGAACGTATAAACCATTCTG
    > 3:9429-9476 - c.fa
    TTCGGTACCCTCCATGACCCACG
    AAATGAGGGCCCAGGGTATGCTT

This is a multiple sequence alignment with multiple aligned sections, so you
would probably load this using the Bio.AlignIO.parse() function:

    >>> from Bio import AlignIO
    >>> align = AlignIO.parse("Mauve/simple_short.xmfa", "mauve")
    >>> alignments = list(align)
    >>> for aln in alignments:
    ...     print(aln)
    ...
    Alignment with 3 rows and 240 columns
    --------------------------------------------...--- a.fa
    TTTAAACATCCCTCGGCCCGTCGCCCTTTTATAATAGCAGTACG...CTG b.fa/5416-5968
    TTTAAACACCTTTTTGGATG--GCCCAGTTCGTTCAGTTGTG-G...CTT c.fa/9475-10076
    Alignment with 2 rows and 46 columns
    -----------------------GGGCGAACGTATAAACCATTCTG b.fa/5968-6015
    TTCGGTACCCTCCATGACCCACGAAATGAGGGCCCAGGGTATGCTT c.fa/9428-9476

Additional information is extracted from the XMFA file and available through
the annotation attribute of each record::

    >>> for record in alignments[0]:
    ...     print(record.id, len(record))
    ...     print("  start: %d, end: %d, strand: %d" %(
    ...         record.annotations['start'], record.annotations['end'],
    ...         record.annotations['strand']))
    ...
    a.fa 240
      start: 0, end: 0, strand: 1
    b.fa/5416-5968 240
      start: 5416, end: 5968, strand: 1
    c.fa/9475-10076 240
      start: 9475, end: 10076, strand: -1

    N)MultipleSeqAlignment)Seq)	SeqRecord   )AlignmentIterator)SequentialAlignmentWriterzG> (?P<id>\d+):(?P<start>\d+)-(?P<end>\d+) (?P<strand>[+-]) (?P<name>.*)z]> (?P<id>\d+):(?P<start>\d+)-(?P<end>\d+) (?P<strand>[+-]) (?P<name>[^#]*) # (?P<realname>.*)z<> {seq_name}:{start}-{end} {strand} {filename} # {ugly_hack}c                     | j                  d      \  }}}t        t        |j                  d            \  }}|dz  }||||fS )zDReturn (name, start, end) string tuple from an identifier (PRIVATE).:-r   )splitmapint)
identifieridlocstrandstartends         K/home/agent/.friday_env/lib/python3.12/site-packages/Bio/AlignIO/MauveIO.py_identifier_splitr   b   sH     &&s+OBVS#))C.)JE3	QJEuc6!!    c                   0     e Zd ZdZ fdZd ZddZ xZS )MauveWriterzMauve/XMFA alignment writer.c                 @    t        |   |i | d| _        d| _        y)zInitialize the class.FN)super__init___wrote_header_wrote_first)selfargskwargs	__class__s      r   r   zMauveWriter.__init__m   s%    $)&)"!r   c                    t        |      }|j                         | _        |dk(  rt        d      | j                  dk(  rt        d      | j                  sXd| _        | j
                  j                  d       t        d|dz         D ]$  }| j
                  j                  d| d| d	       & t        |      D ]  \  }}| j                  ||
        | j
                  j                  d       y)zUse this to write (another) single alignment to an open file.

        Note that sequences and their annotation are recorded
        together (rather than having a block of annotation followed
        by a block of aligned sequences).
        r   zMust have at least one sequencez Non-empty sequences are requiredTz#FormatVersion Mauve1
r   z	#SequencezEntry	
)
record_idxz=
N)
lenget_alignment_length_length_of_sequences
ValueErrorr   handlewriterange	enumerate_write_record)r   	alignmentcountiidxrecords         r   write_alignmentzMauveWriter.write_alignments   s     I$-$B$B$D!
 A:>??$$)?@@!!!%DKK78
 1eai( ?!!IaSs""=>? %Y/ 	7KCv#6	7% r   c                 
   | j                   t        |j                        k7  rt        d      |j                  }	 t        t        |j                              }d|j                  v rd|j                  v rd|j                  d    d|j                  d    }d|j                  d   dz    d|j                  d    }|t        |       d |k(  r|dt        |        }|t        |       d |k(  r|dt        |        }d|j                  v rd|j                  v rtd|j                  v rft        j                  ||j                  d   dz   |j                  d   |j                  d   dk(  rd	nd|j                  d
z   |j                        }d}n4t        j                  |ddd	|j                  d
z   |j                        }d}d|v sd|v r|s| j                  szd| _        t        j                  |ddd	|j                  d
z   |j                        }|j                  dd      j                  dd      }| j                  j                  |dz          yy|j                  dd      j                  dd      }| j                  j                  |dz          t        dt        |j                        d      D ]0  }| j                  j                  |j                  ||dz     d       2 y# t        $ r t        |dz         }Y w xY w)z/Write a single SeqRecord to the file (PRIVATE).z%Sequences must all be the same lengthr   r   r   /r   Nr   +z.fa)seq_namer   r   r   filename	ugly_hackFr   Tz:0-0 z:1-0 r$    z

P   )r(   r&   seqr)   namestrr   annotationsID_LINE_FMTformatr   r   replacer*   r+   r,   )	r   r3   r%   r8   suffix0suffix1id_linelacking_annotationsr1   s	            r   r.   zMauveWriter._write_record   s   $$FJJ7DEE;;	+3v{{+,H f(((Uf6H6H-H&,,W56a8J8J58Q7RSG&,,W59:!F<N<Nu<U;VWGW(G3#Os7|m4W(G3#Os7|m4 v)))+++F...!((!((1A5&&u-%11(;q@cu, )) ) G #(!((!u, )) ) G #' w'W"4>Q$$$(! &,,%#[[50$ii -  "//$4<<T3G!!'F"23 %( oodC088sCGKKgn-1c&**or2 A!!VZZAF%;$<B"?@A  	+:>*H	+s   K' 'LL)r   )__name__
__module____qualname____doc__r   r4   r.   __classcell__)r"   s   @r   r   r   j   s    &"!BHAr   r   c                   ,    e Zd ZU dZg Zee   ed<   d Zy)MauveIteratorzMauve xmfa alignment iterator._idsc           	      H   | j                   }|j                         }|st        |rQ|j                         j	                  d      r2|j                         }|r |j                         j	                  d      r2i }i }d}d}	 |sn<|j                         }|j	                  d      rn|j	                  d      rt
        j                  |      }|s#t        j                  |      }|st        d|      |j                  d      }i }	dD ]C  }
	 |j                  |
      }|
d	k(  rt        |      }|d
kD  r|dz  }|
dk(  rt        |      }||	|
<   E |	||<   || j                  vr| j                  j                  |       |j                  |d       |}n|rJ |t        d      ||xx   |z  cc<   |j                         }@t        |      t        | j                        k  sJ | j                  | _        || _        | j                  r|rt%        t'        t        t)        |j+                                           }g }| j                  D ]5  }||vs"t        ||         d
k(  st        ||         d
k(  rd|z  }n||   }|t        |      k7  rt        d      ||vrS||   d	   d
k7  s||   d   d
k7  rG dj,                  di ||   }d||   v r	||   d   }n||   d   }|j/                  |      d
k(  r||z  }nd||   v r	||   d   }n||   d   }t1        t3        |      ||      }||   d	   |j4                  d	<   ||   d   |j4                  d<   ||   d   dk(  rdnd|j4                  d<   |j                  |       8 t7        |      S t        # t        $ r Y w xY w)z)Parse the next alignment from the handle.#FN=>zMalformed header line: %sr   )r   r   r   r   r?   realnamer   r   r   r    z#Saw sequence before definition liner   z8Sequences have different lengths, or repeated identifierz/{start}-{end}rU   r?   )r   r?   r   r7    )r*   readlineStopIterationstrip
startswithXMFA_HEADER_REGEX_BIOPYTHONmatchXMFA_HEADER_REGEXr)   groupr   
IndexErrorrP   append
setdefaultr&   ids	sequencesmaxr   listvaluesrC   r0   r   r   rA   r   )r   r*   lineseqsseq_regionspassed_end_alignment	latest_idm	parsed_idparsed_datakeyvaluealignment_lengthrecordsr   r>   suffixcorrected_idr3   s                      r   __next__zMauveIterator.__next__   s     tzz|..s3??$D tzz|..s3 $	::<Ds# %/55d;)//5A()DdKKGGDM	 O C !'>$'JE$qy %
%<$'JE+0C(  *5I&DII-II$$Y/	2.%	///$$%JKKY4'??$D] ` 4yC		N***9999"3sD,?#@AGii ''T>Sb]a%73tBx=A;M 00Cr(C#s3x/$R  [(r?7+q0KOE4Ja4O4-44G{2GF![_4'22z'B'22v'>#))&1Q6$.![_4'22z'B'22v'>"3s82F.9"og.F""7+,7OE,B""5)$R2c9Ar ""8, v&O''P (00I &  s   A N	N! N!N)	rI   rJ   rK   rL   rP   rg   r@   __annotations__rw   rX   r   r   rO   rO      s    (D$s)s r   rO   )rL   re	Bio.Alignr   Bio.Seqr   Bio.SeqRecordr   
Interfacesr   r   compiler_   r]   rB   r   r   rO   rX   r   r   <module>r      sx   GR 
 *  # ) 1BJJN  )bjjd  M"rA+ rAjx % x r   