
    Ri                     h   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 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mZ ddlmZ d)dZd Zd*dZd Zd Zd Zd Zd Zd Zd+dZd Z d Z!d Z"d Z#d Z$d Z%d Z&d,d Z'd-d!Z(d" Z)d# Z*d$ Z+d% Z,d& Z-e.d'k(  rdd(l/m0Z0  e0        yy).z5Code for performing calculations on codon alignments.    N)Counter)defaultdict)heapify)heappop)heappush)permutations)erfc)floorlog)sqrt)	Alignment)
CodonTablec           	         |d}n!||dk7  rt        d      |dvrt        d      |t        j                  d   }g }g }| j                  \  	 j                  t              	 j                  t              | j                  \  }}t        ||      D ]Y  \  }	}
|	\  }}|
\  }}|j                  fdt        ||d      D               |j                  fd	t        ||d      D               [ h d
|D ]%  }t        fd|D              rt        d| d       |D ]%  }t        fd|D              rt        d| d       |dk(  rt        ||||      S |dk(  rt        ||||      S |dk(  rt        |||      S |dk(  rt        |||      S t        d| d      # t
        $ r Y Ww xY w# t
        $ r Y Ow xY w)ac  Calculate dN and dS of the given two sequences.

    Available methods:
        - NG86  - `Nei and Gojobori (1986)`_ (PMID 3444411).
        - LWL85 - `Li et al. (1985)`_ (PMID 3916709).
        - ML    - `Goldman and Yang (1994)`_ (PMID 7968486).
        - YN00  - `Yang and Nielsen (2000)`_ (PMID 10666704).

    .. _`Nei and Gojobori (1986)`: http://www.ncbi.nlm.nih.gov/pubmed/3444411
    .. _`Li et al. (1985)`: http://www.ncbi.nlm.nih.gov/pubmed/3916709
    .. _`Goldman and Yang (1994)`: http://mbe.oxfordjournals.org/content/11/5/725
    .. _`Yang and Nielsen (2000)`: https://doi.org/10.1093/oxfordjournals.molbev.a026236

    Arguments:
     - k  - transition/transversion rate ratio
     - cfreq - Current codon frequency vector can only be specified
       when you are using ML method. Possible ways of
       getting cfreq are: F1x4, F3x4 and F61.

    F3x4MLz8cfreq can only be specified when you are using ML method)F1x4r   F61z&cfreq must be 'F1x4', 'F3x4', or 'F61'   c              3   .   K   | ]  }||d z      yw   N ).0i	sequence1s     J/home/agent/.friday_env/lib/python3.12/site-packages/Bio/Align/analysis.py	<genexpr>z"calculate_dn_ds.<locals>.<genexpr>I        LyQU+L   r   c              3   .   K   | ]  }||d z      ywr   r   )r   r   	sequence2s     r   r   z"calculate_dn_ds.<locals>.<genexpr>J   r   r       ACGTc              3   &   K   | ]  }|v  
 y wNr   r   
nucleotidebasess     r   r   z"calculate_dn_ds.<locals>.<genexpr>M        @::&@   zUnrecognized character in z8 in the target sequence (Codons consist of A, T, C or G)c              3   &   K   | ]  }|v  
 y wr)   r   r*   s     r   r   z"calculate_dn_ds.<locals>.<genexpr>S   r-   r.   z7 in the query sequence (Codons consist of A, T, C or G)NG86LWL85YN00zUnknown method '')
ValueErrorr   generic_by_id	sequencesseqAttributeErrorstralignedzipextendrangeall_ml_ng86_lwl85_yn00)	alignmentmethodcodon_tablekcfreqcodons1codons2aligned1aligned2block1block2start1end1start2end2codon1codon2r,   r   r"   s                    @@@r   calculate_dn_dsrT      s/   * }		v~STT	-	-ABB ..q1GG$..IyMM	 IIMM	 II"**Hhh1 MLU645KLLLU645KLL	M
 !E @@@,VH 54 4   @@@,VH 54 4  ~7GUK88	6	Wgq+66	7	gw44	6	Wg{33+F81566I  
  s$   F* +F: *	F76F7:	GGc           	         t        | ||      \  }}t        |||      \  }}||z   dz  }||z   dz  }	ddg}
t        | |      D ]2  \  }}t        |
t        |||            D cg c]
  \  }}||z    }
}}4 |
d   |z  }|
d   |	z  }|dk  rt        dt	        dd|z  z
        z        }nd	}|dk  r!t        dt	        dd|z  z
        z        }||fS d	}||fS c c}}w )
z$NG86 method main function (PRIVATE).)rE   rF          @r   rE   r   g      ?      UUUUUU?)_count_site_NG86r;   _count_diff_NG86absr   )rH   rI   rF   rE   S_sites1N_sites1S_sites2N_sites2S_sitesN_sitesSNrR   rS   mnpspndSdNs                      r   r@   r@   i   s-   )'{aPHh)'{aPHh("c)G("c)G
QBgw/ 
 $VVM
1 E
 

 
AB	AB	EzCGbL 0112	EzCGbL 0112 r6M r6M#
s   $Cc                 B   d}d}d}d}d}| D ]  }g g d}	|j                  dd      }t        |      D ]  \  }
}|D ]  }||k(  r	||v r:||v r6t        |      }|||
<   dj                  |      }|	d	   j	                  |       G||v r:||v r6t        |      }|||
<   dj                  |      }|	d	   j	                  |       t        |      }|||
<   dj                  |      }|	d
   j	                  |         |j
                  |   }dx}}|	d	   D ]3  }||j                  v r||z  }|j
                  |   |k(  r||z  }/||z  }5 |	d
   D ]3  }||j                  v r|dz  }|j
                  |   |k(  r|dz  }/|dz  }5 ||z   dz  }|||z  z  }|||z  z  } ||fS )zCount synonymous and non-synonymous sites of a list of codons (PRIVATE).

    Arguments:
     - codons - A list of three letter codons.
     - k - transition/transversion rate ratio.

    r   r$   r&   r'   r%   r$   r'   r%   r&   )
transitiontransversionUr'    ro   rp   r   r   )replace	enumeratelistjoinappendforward_tablestop_codons)codonsrE   rF   S_siteN_sitepurine
pyrimidiner,   codonneighbor_codonr   r+   basecodon_chars
this_codonaathis_codon_N_sitethis_codon_S_siteneighbor
norm_consts                       r   r[   r[      s?    FFFJ E *1(*B?c3'&u- 	FMAz F%6)dfn"&u+K%)KN!#!5J"<077
C:-$*2D"&u+K%)KN!#!5J"<077
C"&u+K%)KN!#!5J">299*E#F	F( &&u-011-&|4 	'H;222!Q&!**84:!Q&!!Q&!	' '~6 	'H;222!Q&!**84:!Q&!!Q&!	' (*;;q@
#j00#j00U*1V F    c           
      .   ddg}| |k(  r|S t        t        | |            D cg c]  \  }\  }}||k7  r| }}}}dd}t        |      dk(  r,t        | || ||            D 	cg c]
  \  }}	||	z    }}}	|S t        |      dk(  rs|D ]l  }| d| ||   z   | |dz   d z   }
t        | || |
|d            D 	cg c]
  \  }}	||	z    }}}	t        | ||
||d            D 	cg c]
  \  }}	||	z    }}}	n |S t        |      d	k(  rt        t	        g d
d	            }g }|D ]  \  }}}| d| ||   z   | |dz   d z   }|d| ||   z   ||dz   d z   }|j                  ||f       t        | || ||d            D 	cg c]
  \  }}	||	z    }}}	t        | ||||d            D 	cg c]
  \  }}	||	z    }}}	t        | ||||d            D 	cg c]
  \  }}	||	z    }}}	 |S c c}}}w c c}	}w c c}	}w c c}	}w c c}	}w c c}	}w c c}	}w )zCount differences between two codons, three-letter string (PRIVATE).

    The function will take multiple pathways from codon1 to codon2
    into account.
    r   r   c           	          dx}}t        t        t        |j                  j                  | |g                  dk(  r	||z  }||fS ||z  }||fS )z4Compare two codon accounting for different pathways.r   r   )lensetmaprx   get)rR   rS   rE   weightsdnds         r   compare_codonz'_count_diff_NG86.<locals>.compare_codon   s^    KB3s;448866:JKLMQRRf 8O f8Or   rW      N      ?)rE   r   r   r   r   r   gUUUUUU?r   r   )rt   r;   r   ru   r   rw   )rR   rS   rE   rd   r   nucleotide1nucleotide2diff_posr   j
temp_codonpaths	tmp_codonindex1index2index3tmp1tmp2s                     r   r\   r\      s    QB	 2;3vv;N1O
 
--Kk) 
 
	 x=A  ff+NAq AB h I] ]a #BQZ&)3fQUWoE
 !$%"JKPS!1 E  !$%&KPS!1 E Z I3 ]ai34EI*/ &gv7&!:NNGV}vf~5VaZ\8JJ  $. !$M&$GT!1 E  !$M$k'R!1 E  !$M$GT!1 E !, II
  s)   G,'G3;G9&G? H+HHc                    t        |      }ddg}ddg}ddg}| |z   D ]G  }||   }|D ];  }	|	dk(  r|dxx   dz  cc<   |	dk(  r|dxx   dz  cc<   )|	dk(  s/|dxx   dz  cc<   = I t        |      dz  t        |      dz  t        |      dz  g}
dgdz  }t        | |      D ]8  \  }}||k(  rt        |t        |||            D cg c]
  \  }}||z    }}}: t        ||
d	z        D cg c]
  \  }}||z   }}}|d
d }|dd
 }t        ||      D cg c]7  \  }}dt	        ddd	|z  z
  |z
  z        z  dt	        ddd	|z  z
  z        z  z
  9 }}}|D cg c]  }dt	        ddd	|z  z
  z        z   }}d|
d	   |d   z  |
d	   |d	   |d	   z   z  z   z  |
d   d|
d	   z  z   z  }d|
d	   |d   z  |
d   |d   |d   z   z  z   z  d	|
d   z  d|
d   z  z   z  }||fS c c}}w c c}}w c c}}w c c}w )zlLWL85 method main function (PRIVATE).

    Nomenclature is according to Li et al. (1985), PMID 3916709.
    r   0r   24rV      )	fold_dictr   Nr   r         ?g      ?)_get_codon_foldsumr;   _diff_codonr   )rH   rI   rE   codon_fold_dictfold0fold2fold4r   fold_numfLPQrR   rS   r   r   PQr$   Bri   rj   s                         r   rA   rA     s   
 &k2OFEFEFE7" "5) 	ACxaAcaAcaA	 
Uc	3u:+SZ#-=>A
qBgw/ 
V BFFo VW
1 E
 

  AEN	+DAq!a%	+B	+
2AA
12A 1I	Aq 
Cq1q5y1}-..'SAPQE	AR=S1SS	A 	 677'SAE	*+	+7A7	
adQqTkAaDAaD1Q4K00	1QqTA!H_	EB	
adQqTkAaDAaD1Q4K00	1Q1XAaD5H	IBr6M
 
,	 	8s   	G"/G(<G.G4c           	         i }| j                   }h d}|D ]  }d|v rd}t        |      }t        |      D ]  \  }}|t        |      z
  }	g }
|	D ]+  }|||<   	 |
j	                  |dj                  |                - |
j                  ||         dk(  r|dz  }nD|
j                  ||         dv r|dz  }n(|
j                  ||         d	k(  r|d
z  }nt        d      |||<    |||<    |S # t        $ r |
j	                  d       Y w xY w)zFClassify different position in a codon into different folds (PRIVATE).r#   rq   rr   stopr   r   )r   r   r   r   r   z3Unknown Error, cannot assign the position to a fold)	rx   ru   rt   r   rw   rv   KeyErrorcountRuntimeError)rE   
fold_tablerx   r,   r   foldcodon_base_lstr   r   other_basesr   
other_bases               r   r   r   @  sM   J--M E !%<e 0 	%GAt#d)+KB) &
$.q!&IImBGGN,CDE& xxe,-2-./69-./14"I  !%N1'	%( !
53!4    &IIf%&s   #C,,D		D		c                    dx}x}x}x}x}}||    }	d}
d}t        t        | |            D ]  \  }\  }}||k(  r||
v r?||
v r;|	|   dk(  r|dz  }%|	|   dk(  r|dz  }3|	|   dk(  r|dz  }At        d|	|   z        ||v r?||v r;|	|   dk(  r|dz  }h|	|   dk(  r|dz  }v|	|   dk(  r|dz  }t        d|	|   z        |	|   dk(  r|dz  }|	|   dk(  r|dz  }|	|   dk(  r|dz  }t        d|	|   z         ||||||fS )	zCount number of different substitution types between two codons (PRIVATE).

    returns tuple (P0, P2, P4, Q0, Q2, Q4)

    Nomenclature is according to Li et al. (1958), PMID 3916709.
    r   rl   rm   r   r   r   r   zUnexpected fold_num %d)rt   r;   r   )rR   rS   r   P0P2P4Q0Q2Q4r   r}   r~   rf   r   r   s                  r   r   r   b  s    #$#B##b#2#R HFJ)23vv3F)G K%%K+%F"{f'<{c!a!#a!#a"#;hqk#IJJJ&;*+D{c!a!#a!#a"#;hqk#IJJ {c!a!#a!#a"#;hqk#IJJ?K@ BB##r   c           	      	  4 ddl m} dddddddddddddddg}t        |      }t        t              }t        t              }| |z   D ]  }|d   |d   xx   dz  cc<   |d   |d   xx   dz  cc<   |d   |d   xx   dz  cc<   ||   }	t        |	      D ]1  \  }
}|dk(  r|||
   xx   dz  cc<   |dk(  s"|||
   xx   dz  cc<   3  t        |j                               }t        |j                               }t        ||      D ]  \  }
}||
   |z  ||
<   ||
   |z  ||
<    t        | ||      }t        ||      t        ||      f}||d   z  ||d   z  z   ||z   z  }t        d	      D ]K  }
t        ||
   j                               }||
   j                         D ci c]  \  }}|||z   c}}||
<   M t        t              }t        |j                  j                               |j                   z   D ]  }d
|vsd||<    | |z   D ]  }||xx   dz  cc<    t#        | ||||      \  }}}t#        || |||      \  }}}||z   dz  }||z   dz  }ddddddddddg}t        d      D ]#  }
dD ]  }||
   |   ||
   |   z   dz  ||
   |<    % ddg}t        | |      D ]2  \  } }!t        |t%        | |!|            D "#cg c]
  \  }"}#|"|#z    }}"}#4 |d   |z  }$|d   |z  }%t        |      ||z   z  }&t'        dd|%z  z
        t'        dd|$z  z
        z  }'dt'        dd|&z  z
        z  }(d4ddg})t        d      D ]r  }*t        |j                  j                               |j                   z   D cg c]  }d
|vr|
 }+}t)        |||'|+|      }, ||,|(z        }-g d}t+        t        | |            }.|.j                         D ];  \  \  }/}0}1t-        |/|0|-|+|      }2t        ||2      D "#cg c]  \  }"}#|"|#|1z  z    }}"}#= |d   |z  |d   |z  f|d   |z  |d	   |z  ff}g }3t        ||      D ]"  \  }}2|3j/                  t        ||2d             $ |3d   d	z  |z  ||z   z  |3d   d	z  |z  ||z   z  z   }(|3d   |3d   z  }'t1        4fdt        |3|)      D              r|3d   |3d   fc S |3})u yc c}}w c c}#}"w c c}w c c}#}"w )zsYN00 method main function (PRIVATE).

    Nomenclature is according to Yang and Nielsen (2000), PMID 10666704.
    r   expmr$   r&   r%   r'   r   r   r   r   rW   r   rq   )rF   rE   rn   rY   rX   h㈵>   r   r   r   r   T)tc              3   F   K   | ]  \  }}t        ||z
        k    y wr)   )r]   )r   r   r   	tolerances      r   r   z_yn00.<locals>.<genexpr>  s"     F$!Qs1q5zI%Fs   !N)scipy.linalgr   r   r   intrt   r   valuesr;   _get_TV_get_kappa_tr=   itemsru   rx   keysry   _count_site_YN00r\   r   _get_Qr   _count_diff_YN00rw   r>   )5rH   rI   rE   r   fcodonr   	fold0_cnt	fold4_cntr   r   r   r   f0_totalf4_totalr   TVk04kappatotrF   pir^   r_   bfreqSN1r`   ra   bfreqSN2rc   rb   bfreqSNr   rd   rR   rS   re   rf   rg   rh   pwr   dSdN_pretemprz   r   r   codon_npathr   r   r   tvdSdNr   s5                                                       @r   rB   rB     s   
 " aaa(aaa(aaa(F
 &k2OC IC I7" )q	%(q q	%(q q	%(q "5)h' 	)DAqCx%(#q(#c%(#q(#		)) 9##%&H9##%&HIy) /1 |h.	! |h.	!/ 
'{	;B	2&Y(C
DCACF!22x(7JKE 1X ?&)""$%,21IOO,=>DAqQCZ>q	? 
S	Bk//4467+:Q:QQ eBuI 7" 
5	Q	#3";$ Hh $4";$ Hh ("a'G("a'GQQQ/qqqq1QRG1X K( 	KD (D 1HQK4E EJGAJt	KK QBgw/ 
 $VVM
1 E
 

 
AB	ABB7W$%AA"A"$4 55AQ]##AI1vHb	  k77<<>?%%&
% 
 
 2ua5QKc'7341<1B1B1D 	9-&[+!+{Av{SB,/BK8DAq!a%i-8B8	9 egor!uw/"Q%'/2a57?1SS "% 	5EArKKQd34	5GaK'!Ww%67$q'A+:Og;
 
 Gd1gF#dH2EFF7DG##7G ?,

 9s   %R?S>S7S
c                    d}d}ddg}d}t        | |      D ]]  \  }}t        ||      D ]I  \  }	}
|	|
k(  rn9|	|v r|
|v r|dxx   dz  cc<   n#|	|v r|
|v r|dxx   dz  cc<   n|dxx   dz  cc<   |dz  }K _ |d   |z  |d   |z  fS )zGet TV (PRIVATE).

    Arguments:
     - T - proportions of transitional differences
     - V - proportions of transversional differences

    rl   )r%   r'   r   r   )r;   )rH   rI   rE   r}   r~   r   sitesrR   rS   r   r   s              r   r   r      s     FJ
QBEgw/ 
(+FF(; 		$Kk)&;&+@1

*{j/H1
1
QJE		
 qEEM2a55=))r   c                    | d   | d   z   | d<   | d   | d   z   | d<   d| d   | d   z  | d   | d   z  z   z  d| d   | d   z  | d   z  | d   z  | d   | d   z  | d   z  | d   z  z   z  d|d   d| d   z  | d   z  z  z
  z  z   |d	   z
  d| d   | d   z  | d   z  | d   | d   z  | d   z  z   z  z  }d|d   d| d   z  | d   z  z  z
  }d
t        |      z  }d
t        |      z  }||z  dz
  }|du rCd| d   | d   z  | d   z  | d   | d   z  | d   z  z   |z  | d   | d   z  | d   | d   z  z   z  z   }|S d| d   z  | d   z  d|| d   z  z   z  d| d   z  | d   z  d|| d   z  z   z  z   d| d   z  | d   z  z   |z  }|S )zmCalculate kappa (PRIVATE).

    The following formula and variable names are according to PMID: 10666704
    r'   r%   Yr$   r&   Rr   r   r   g      F   r   )	r   r   r   r$   r   abkappaF84
kappaHKY85s	            r   r   r     sq   
 g3BsGg3BsG	RWr#wC2c7!223
sGbg3'"S'1g3"S')BsG34

 r!uBsGbg-..0	0 Q%	 
bg3"S')BsGbg,=3,GG	H		JA 	
BqEQC[2c7*++As1vAs1vA1uqyHEzsGbg3'"S'BsG*;bg*EE3"S')BsGbg,==? ?
  3K"S'!QBsG);%;<"S'kBsG#q8bg+='=>?"S'kBsG#$ 	
 r   c                    t        |       }|t        |      k(  sJ d}d}d}|j                  }	|j                  }
t        t	        | |            }dx}}ddddddddddg}|j                         D ]  \  }}|d   }dx}}t        d      D ]  }|D ]  }||   |k(  r|d| |z   ||dz   d z   }||
v r"||   }||   |v r
||v r||z  }n||   |v r	||v r||z  }|	|   |	|   k(  r||z  }|d   |xx   ||z  z  cc<   l||z  }|d   |xx   ||z  z  cc<     |||z  z  }|||z  z  } d|z  ||z   z  }||z  }||z  }|D ]/  }t        |j                               }|D ]  }||xx   |z  cc<    1 |||fS )a  Site counting method from Ina / Yang and Nielsen (PRIVATE).

    Method from `Ina (1995)`_ as modified by `Yang and Nielsen (2000)`_.
    This will return the total number of synonymous and nonsynonymous sites
    and base frequencies in each category. The function is equivalent to
    the ``CountSites()`` function in ``yn00.c`` of PAML.

    .. _`Ina (1995)`: https://doi.org/10.1007/BF00167113
    .. _`Yang and Nielsen (2000)`: https://doi.org/10.1093/oxfordjournals.molbev.a026236

    rl   rm   rn   r   r   Nr   )	r   rx   ry   r   r;   r   r=   r   r   )rH   rI   r   rF   rE   lengthr}   r~   r,   
codon_dictr   r   rb   rc   freqSN
codon_pairnpathr   SNposr   r   r   r   r   r   s                              r   r   r   >  s-    \FS\!!!FJ E**J""D#gw/0KGgaaa(aaa(F )..0 
E1	A8 	6C 6:%!&tt!3eC!GI6F!F!T)N+:+
0BaKF3Z6)dfnaKFe$
>(BBKA1IdOv~5OKA1IdOv~5O!6	6$ 	1u91u9-. Vw01JzGzG _
 	AaDJD	 GV##r   c                 F   g d}| |k(  r|S t        t        | |            D cg c]  \  }\  }}||k7  r| }	}}}d
d}
t        |	      dk(  r/t        | |
| ||	d   |            D cg c]
  \  }}||z    }}}|S t        |	      dk(  r+|	D cg c]  }| d| ||   z   | |dz   d z    }}g }|D ]X  }t        t	        |j
                  | ||g            }||d   |d   f   ||d   |d   f   f}|j                  |d   |d   z         Z |D cg c]  }d|z  t        |      z   }}t        |	      D ]}  \  }}| d| ||   z   | |dz   d z   }t        | |
| |||||   dz              D cg c]
  \  }}||z    }}}t        | |
| |||||   dz              D cg c]
  \  }}||z    }}} |S t        |	      dk(  rt        t        g d	d            }g }g }|D ]  \  }}}| d| ||   z   | |dz   d z   }|d| ||   z   ||dz   d z   }|j                  ||f       t        t	        |j
                  | |||g            }||d   |d   f   ||d   |d   f   ||d   |d   f   f}|j                  |d   |d   z  |d   z          |D cg c]  }d|z  t        |      z   }}t        |||      D ]  \  }}}t        | |
| |d   |d   ||dz              D cg c]
  \  }}||z    }}}t        | |
|d   |d   |d   ||dz              D cg c]
  \  }}||z    }}}t        | |
|d   ||d   ||dz              D cg c]
  \  }}||z    }}} |S c c}}}w c c}}w c c}w c c}w c c}}w c c}}w c c}w c c}}w c c}}w c c}}w )a&  Count differences between two codons (three-letter string; PRIVATE).

    The function will weighted multiple pathways from codon1 to codon2
    according to P matrix of codon substitution. The proportion
    of transition and transversion (TV) will also be calculated in
    the function.
    r   r   c                 t   d}d}|j                   }|j                  }| |v s||v r.| |   |v r||   |v rdd|dgS | |   |v r||   |v rdd|dgS ddd|gS ||    ||   k(  r.| |   |v r||   |v r|dddgS | |   |v r||   |v r|dddgS d|ddgS | |   |v r||   |v rdd|dgS | |   |v r||   |v rdd|dgS ddd|gS )Nrl   rm   r   )rx   ry   )	rR   rS   diffrE   r   r}   r~   dicr   s	            r   count_TVz"_count_diff_YN00.<locals>.count_TV  sP   F#J++C**D~4$<6)fTlf.Dq&!,,D\Z/F4LJ4Nq&!,,q!V,,VF+$<6)fTlf.D"Aq!,,D\Z/F4LJ4N"Aq!,,vq!,,$<6)fTlf.Dq&!,,D\Z/F4LJ4Nq&!,,q!V,,r   r   r   Nr   r   r   r   )	rt   r;   r   ru   r   indexrw   r   r   )rR   rS   r   rz   rE   r   r   r   r   r   r
  r   q
tmp_codons	path_probr   	codon_idxprobrf   r   r   r   r   r   r   r   rF   s                              r   r   r   x  s   
B 	 2;3vv;N1O
 
--Kk) 
 
	-8 x=A  HVVXa[+$VWAq AB H IA ]aLTUq&!*vay06!a%'?BUJUI# 4 V\\FE63J!KL	)A,	!45q1yQR|9S7TU  a47!234 :CCAQY/CIC!(+ 1r
VAY.A@ !$ "E1k)A,QRBR!1 E  !$ "E1k)A,QRBR!1 E p II ]ai34EIJ*/ 
>&gv7&!:NNGV}vf~5VaZ\8JJ!!4,/ V\\FD$3O!PQ	ilIaL01ilIaL01ilIaL01
   a47!2T!W!<=
> :CCAQY/CIC":y%@ q! !$HVU1Xqt[QRUVQVW!1 E  !$ q58QqT;qSTuU!1 E  !$HU1Xvqt[QRUVQVW!1 E ( IO
F
 V D0 Ds;   M)*M0M6M;0N "NN&NNNc                    ddl m} t        | |||      }t        t	        | |            }t        |j                  j                               |j                  z   D cg c]  }d|vr|
 }}||||fd}	 ||	g dddd	
      }
|
j                  \  }}}t        |||||      }dx}}t        |      D ]_  \  }}t        |      D ]L  \  }}||k7  s	 |j                  |   |j                  |   k(  r|||   |||f   z  z  }n|||   |||f   z  z  }N a ||z  }||z  }||||fd} ||ddgddd	
      }
|
j                  \  }}d}t        |||||      }dx}}t        |      D ]_  \  }}t        |      D ]L  \  }}||k7  s	 |j                  |   |j                  |   k(  r|||   |||f   z  z  }n|||   |||f   z  z  }N a |dz  }|dz  }||z  }||z  }||fS c c}w # t        $ r Y ,w xY w# t        $ r Y w xY w)z"ML method main function (PRIVATE).r   )minimizerW   rq   c           	      :    t        | d   | d   | d   ||||       S )z'Temporary function, params = [t, k, w].r   r   r   rz   rE   _likelihood_funcparamsr   	codon_cntrz   rE   s        r   funcz_ml.<locals>.func  s7     !1I1I1I#
 
 	
r   )r   皙?r   zL-BFGS-B)绽|=r   r  )r  
   r   )rD   boundstolc           	      4    t        | d   | d   d||||       S )z5Temporary function, params = [t, k]. w is fixed to 1.r   r   r   r  r  r  s        r   func_w1z_ml.<locals>.func_w12  s3     !1I1I#
 
 	
r   r   r  )r  r  r   r   )scipy.optimizer  _get_pir   r;   ru   rx   r   ry   xr   rt   r   )rH   rI   cmethodrE   r  r   r  r   rz   r  opt_resr   rF   r   r   SdNdr   rR   r   rS   r"  rhoSrhoNrj   ri   s                             r   r?   r?     s   '	'7	DBGW-.I +3388:;k>U>UUe 	F  6{
 6G iiGAq!r1a-AKBv& 	6"6* 	IAvAv#11&9&44V<= bj1QT722 bj1QT722	  !GB!GB 6{
 	
C)G 99DAqAr1a-AOD4v& 	6"6* 	IAvAv#11&9&44V<= 6
Qq!tW 44 6
Qq!tW 44	  	AIDAID	dB	dBr6MCZ   Z   s,   GA G"A G2"	G/.G/2	G>=G>c                    i }|dk(  rt        d | |z   D              }t        |j                               }|j                         D ci c]  \  }}|||z   }}}|j                  j                         |j                  z   D ]$  }	d|	vs||	d      ||	d      z  ||	d      z  ||	<   & |S |dk(  rdddddddddddddddg}| |z   D ];  }	|d   |	d   xx   dz  cc<   |d   |	d   xx   dz  cc<   |d   |	d   xx   dz  cc<   = t        d	      D ]K  }
t        ||
   j                               }||
   j                         D ci c]  \  }}|||z   c}}||
<   M t        |j                  j                               |j                  z   D ]-  }	d|	vs|d   |	d      |d   |	d      z  |d   |	d      z  ||	<   / |S |d
k(  r|j                  j                         |j                  z   D ]  }	d|	vsd||	<    | |z   D ]  }	||	xx   dz  cc<    t        |j                               }|j                         D ci c]  \  }}|||z   }}}|S c c}}w c c}}w c c}}w )zObtain codon frequency dict (pi) from two codon list (PRIVATE).

    This function is designed for ML method. Available counting methods
    (cfreq) are F1x4, F3x4 and F64.
    r   c              3   .   K   | ]  }|D ]  }|   y wr)   r   )r   r   r+   s      r   r   z_get_pi.<locals>.<genexpr>m  s'      
 
:DJ

s   rq   r   r   r   r   r   r   r   r  )	r   r   r   r   rx   r   ry   r=   ru   )rH   rI   r&  rE   r   r   r   r   rF   r   r   s              r   r$  r$  b  s    
B& 
$+g$5
 
 &--/")/8A!QW*88 ..3358O8OO 	SE%"58,veAh/??&qBRR5		S< I7 
F	 !!!,!!!,!!!,

 w& 	%E1IeAh1$1IeAh1$1IeAh1$	% q 	CAfQi&&()C06q	0AB1AGBF1I	C +3388:;k>U>UU 	E%1IeAh'&)E!H*==q	%PQ(@SS 5		 I 
E	 ..3358O8OO 	 E%5		  w& 	EuINI	"))+%'XXZ0TQaSj00I? 9" C 1s   	I	II#c                 :   | |k(  ry| |j                   v s||j                   v ry| |vs||vryd}d}t        t        | |            D 	
cg c]  \  }\  }	}
|	|
k7  r||	|
f }}	}}
t        |      dk\  ry|j                  |    |j                  |   k(  r=|d   d   |v r|d   d   |v r|||   z  S |d   d   |v r|d   d   |v r|||   z  S ||   S |d   d   |v r|d   d   |v r||z  ||   z  S |d   d   |v r|d   d   |v r||z  ||   z  S |||   z  S c c}
}	}w )aM  Q matrix for codon substitution (PRIVATE).

    Arguments:
     - codon1, codon2  : three letter codon string
     - pi              : expected codon frequency
     - k               : transition/transversion ratio
     - w               : nonsynonymous/synonymous rate ratio
     - codon_table     : Bio.Data.CodonTable object

    r   rl   rm   r   r   )ry   rt   r;   r   rx   )rR   rS   r   rF   r   rE   r}   r~   r   r   r   r  s               r   _qr/    s    (((Fk6M6M,MbfB.FJ .7s667J-K )A)[+% 
K%D 
 4yA~  (K,E,Ef,MM71:DGAJ&$8r&z>!!WQZ:%$q'!*
*Br&z>! f: 71:DGAJ&$8q52f:%%!WQZ:%$q'!*
*Bq52f:%% r&z>!9s   
Dc           
      t   t        |      }t        j                  ||f      }t        |      D ]4  \  }}t        |      D ]!  \  }	}
||	k7  st	        ||
| |||      |||	f<   # 6 d}t        |      D ]/  \  }}t        ||ddf          |||f<   	 || |   |||f    z  z  }1 ||z  }|S # t        $ r Y Dw xY w)z*Q matrix for codon substitution (PRIVATE).rW   r   N)r   npzerosrt   r/  r   r   )r   rF   r   rz   rE   	codon_numr   i1rR   i2rS   nucl_substitutionsr   r   s                 r   r   r     s    FI
)Y'(A' R
F#F+ 	RJBRxvvr1a[Q"b&		RR f% 5qAw<-!Q$	"U)!Q$x"88 	AH  		s   B++	B76B7c           
      "   ddl m} t        |||||      } ||| z        }	d}
t        |      D ]^  \  }}t        |      D ]K  \  }}||f|v s|	||f   ||   z  dk  r|
|||f   dz  z  }
+|
|||f   t	        ||   |	||f   z        z  z  }
M ` |
S )z,Likelihood function for ML method (PRIVATE).r   r   )r   r   r   rt   r   )r   rF   r   r   r  rz   rE   r   r   r   
likelihoodr   rR   r   rS   s                  r   r  r    s    !r1a-AQUAJv& 	6"6* 	IAv9,QT7RZ'1,)VV,<"="AAJ)VV,<"=6
Qq!tW,A # J	 r   c                 z   ddl m} |t        j                  d   }| j                  }| j
                  }|D cg c]  }|j                   }}t        |      }g }	g }
t        |      D ]  }|	j                  g        |
j                  g        t        |      D ]\  }||   ||   g}|||fddf   }t        ||      }t        |||      \  }}|	|   j                  |       |
|   j                  |       ^ |	|   j                  d       |
|   j                  d         |||	      } |||
      }||fS c c}w )zCalculate dN and dS pairwise for the multiple alignment, and return as matrices.

    Argument:
     - method       - Available methods include NG86, LWL85, YN00 and ML.
     - codon_table  - Codon table to use for forward translation.

    r   )DistanceMatrixNr   )rD   rE   g        )matrix)Bio.Phylo.TreeConstructionr:  r   r5   r6   coordinatesidr   r=   rw   r   rT   )rC   rD   rE   r:  r6   r=  recordnamessize	dn_matrix	ds_matrixr   r   pairwise_sequencespairwise_coordinatespairwise_alignmentdndsdn_dmds_dms                       r   calculate_dn_ds_matrixrK    s^    : ..q1##I''K%./6VYY/E/u:DII4[ !q 	$A"+A,	!!=#.1vqy#9 !*+=?S!T$"6{FB aL#aL#	$ 	!C !C ! 53E53E%<) 0s   D8c                    |t         j                  d   }t        |      \  }}t        |      }g }| j                  D ]+  }	 |j
                  }t        |      }|j                  |       - d\  }}	}
}t        j                  }| j                  j                         D ]  }t        ||z
        }t        d|d      D ]  }|D ci c]  }|g  }}t        |||      D ](  \  }}}|||z   ||z   dz    }||   j                  |       * d}t               }|j!                         D ].  }t        |      }t#        |      dkD  rd}|j%                  |       0 t#        |      dk(  rt'        ||      }t'        ||      |z
  }|du r|	|z  }	||z  }||z  }|
|z  }
 |} t)        ||	|
|g      S # t        $ r Y iw xY wc c}w )a4  McDonald-Kreitman test for neutrality.

    Implement the McDonald-Kreitman test for neutrality (PMID: 1904993)
    This method counts changes rather than sites
    (http://mkt.uab.es/mkt/help_mkt.asp).

    Arguments:
     - alignment    - Alignment of gene nucleotide sequences to compare.
     - species      - List of the species ID for each sequence in the alignment.
       Typically, the species ID is the species name as a string, or an integer.
     - codon_table  - Codon table to use for forward translation.

    Return the p-value of test result.
    r   rW   r   r   r   TF)r   r5   _get_codon2codon_matrixr   r6   r7   r8   r9   rw   sysmaxsizer=  	transposeminr=   r;   r   r   update_count_replacement_G_test)rC   speciesrE   r&   nonsyn_Gunique_speciesr6   sequencesyn_fix
nonsyn_fixsyn_polynonsyn_polystartsendsstepr   keyrz   startr   fixed
all_codonsvaluenonsynsyns                            r   mktestrg    s     ..q1)kBKAx\NI'' #	||H x="# 2<.GZ;[[F%%//1 4&=!q$" 	 A)78#c2g8F8(+GY(G *$Xu UQY];s""5)* EJ )E
u:>!E!!%(	)
 :!#'
H=F$Z3f<C}f$
3 v%C/	 0 56 GZ;?@@C  		 9s   F+
F;+	F87F8c                    d}t        | j                  j                               | j                  z   D cg c]  }d|vr|
 }}| j                  j	                         }| j                  D ]  }d||<   	 t        |      }i }i }i }	i }
t        |      D ]i  \  }}i |	|<   i |
|<   t        d      D ]L  }|D ]E  }|d| |z   ||dz   d z   }||   ||   k7  rd|
|   |<   d|	|   |<   0||k7  s6d|
|   |<   d|	|   |<   G N k |D ]O  }i ||<   i ||<   |D ]>  }||k(  rd||   |<   d||   |<   t        |
||      ||   |<   t        |	||      ||   |<   @ Q ||fS c c}w )	zGet codon codon substitution matrix (PRIVATE).

    Elements in the matrix are number of synonymous and nonsynonymous
    substitutions required for the substitution.
    rn   rq   r   r   r   r   Nr  )	ru   rx   r   ry   copyr   rt   r=   	_dijkstra)rE   r,   r   rz   r   r   numr&   rV  graphgraph_nonsynr   r   r   r   rR   rS   s                    r   rM  rM  L  s     !E +3388:;k>U>UUe 	F  **//1J'' "!
4" f+C
AHELf% 45e Uq 		4A 4!!AJ-a!eg>	e$
9(==56L'	2./E%L+	)9<U+I623eY/4		44  	E&	 	EF+, ($%&	&!+4\66+R ($-eVV$D&	&!	E	E h;Ms   Ec                    i }i }| j                         D ]  }d||<   d||<    d||<   t        | j                               }t        |      dkD  rd}d}|D ]  }|||   }|}||   |k  s||   }|} |j                  |       | |   j	                         D ]$  \  }	}
||	   ||   |
z   kD  s||   |
z   ||	<   |||	<   & ||k(  rnt        |      dkD  rg }|}d}||k(  s3|j                  |      dk(  r|j                  d|       ||   }nn||k(  s3|j                  d|       t        t        |      dz
        D ]  }|| ||      ||dz         z  } |S )a  Dijkstra's algorithm Python implementation (PRIVATE).

    Algorithm adapted from
    http://thomas.pelletier.im/2010/02/dijkstras-algorithm-python-implementation/.
    However, an obvious bug in::

        if D[child_node] >(<) D[node] + child_value:

    is fixed.
    This function will return the distance between start and end.

    Arguments:
     - graph: Dictionary of dictionary (keys are vertices).
     - start: Start vertex.
     - end: End vertex.

    Output:
       List of vertices from the beginning to the end.

    d   rr   r   Nr   )r   ru   r   remover   r   insertr=   )rl  ra  endDr   nodeunseen_nodesshortest	temp_node
child_nodechild_valuepathdistancer   s                 r   rj  rj  |  s   * 	A
A

 $$ AeH

%L
l
a
% 	!IY< 9(Y< 	! 	D!',T{'8'8': 	%#J}qw44 !$+ 5* $*		%
 3;) l
a
, DDHu}::dq KK4 T7D u} 	KK53t9q=! 0E$q'N4A;//0Or   c                    t        |       dk(  ryt        |       dk(  r"t        |       } t        || d      | d            S | D ci c]   }|| D ci c]  }||k7  s	|||   |    c}" }}}t        |      S c c}w c c}}w )z9Count replacement needed for a given codon_set (PRIVATE).r   )r   r   r   r   )r   ru   r
   _prim)rz   r&   rR   rS   subgraphs        r   rS  rS    s    
6{a	V	fQvay\&),-- !
 VX6vQWGWVQvYv..XX
 
 X Y
s   
A=
A8A8%A=8A=c                    g }g }| j                         D ]S  }|j                  |       | |   D ]8  }||| |   |   f|vs||| |   |   f|vs|j                  ||| |   |   f       : U t        t              }|D ]4  \  }}}||   j                  |||f       ||   j                  |||f       6 g }	t	        |d         }
||d      dd }t        |       |rYt        |      \  }}}||
vrC|
j                  |       |	j                  |||f       ||   D ]  }|d   |
vst        ||        |rYd}|	D ]  }|t        |d         z  } |S )zPrim's algorithm to find minimum spanning tree (PRIVATE).

    Code is adapted from
    http://programmingpraxis.com/2010/04/09/minimum-spanning-tree-prims-algorithm/
    r   Nr   )
r   rw   r   ru   r   r   r   addr   r
   )r&   nodesedgesr   r   connn1n2cmstusedusable_edgescoster   r   s                   r   r}  r}    s    EEVVX .Q1 	.A1ad1ge+AqtAwu0LaAaDG_-	..
 tD %	BRB$RB$% CuQx=Da>!$LL
|,b"T>HHRLJJB~&"X .Q4t#\1-.  F %!+Mr   c                 4   d}t        |       }| d   | d   z   }| d   | d   z   }t        | dd       }t        | dd       }||z  |z  ||z  |z  ||z  |z  ||z  |z  g}t        | |      D ]  \  }}	||t        ||	z        z  z  } t        t	        |            S )zG test for 2x2 contingency table (PRIVATE).

    Arguments:
     - site_counts - [syn_fix, nonsyn_fix, syn_poly, nonsyn_poly]

    >>> print("%0.6f" % _G_test([17, 7, 42, 2]))
    0.004924
    r   r   r   r   N)r   r;   r   r	   r   )
site_countsr&   r   tot_syntot_nontot_fixtot_polyexpobsexs
             r   rT  rT    s     	
A
k
C!n{1~-G!n{1~-G+bq/"G;qr?#H'C'C7S 7S 	C {C( !R	S3sRx=  ! Q=r   __main__)run_doctest)r0   Nr   Nr   )F)r0   N)NN)1__doc__rN  collectionsr   r   heapqr   r   r   	itertoolsr   mathr	   r
   r   r   numpyr1  	Bio.Alignr   Bio.Datar   rT   r@   r[   r\   rA   r   r   rB   r   r   r   r   r?   r$  r/  r   r  rK  rg  rM  rj  rS  r}  rT  __name__
Bio._utilsr  r   r   r   <module>r     s    < 
  #    "       F7\88vNl'TD+$fhV*6 F7$tx@gT.b0"f&&"J8Av-`AH F< z&M r   