B
    d             g   @   sb  d Z ddlZddlZddlmZmZmZmZmZ	 ddl
mZ ddlmZ ddlZed ddlmZ ddlZddlZddlZejd	 dd
lmZ ddl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lm&Z& ddlm'Z' ddlZddl(Z(ddl)m*Z* ddl+m,Z- ddl.Z.ddl/Z/yddl0Z1W n  e2k
r^   e3d  Y nX yddl4m5Z5 W n e2k
r   e3d Y nX ddl6m7Z7 y"e(8e(9 d :ddd Z;W n   dZ;Y nX e;dkse;dkrej<=ddd dd l>m?Z?m@Z@mAZAmBZB ddlCZCdd!lCmDZDmEZE dd"lFmGZG d#ZHd$eGjI ZJeGjKZLd%d& ZMd'd( ZNd)d* ZOd+d,d-d.d/d0d1d2d3d4d5d6d7d8d9d:d;gZPd<d= e*d>d?d@gdAD ZQdBdCdDdEgdFd= dGD  dHd= dGD  dId= dGD  eQ ZRdJd= dGD ZSdKd= dGD ZTeSeT ZUdLdMdNdOdPdQdRdSdTdUdVdWdXgZVdYdZd[d\d]d^d_d`dadbdcdddedfdgdhdidjdkdldmdndodpgZWdqdrdsdtgZXdudvdwdxdygZYeWeY eX ZZdzd{d|d}d~dddddddddddgZ[ddddddddddg
Z\dd= e]dD dd= dD  dd= e]dD  dd= e]dD  dd= e]dD  dd= e]dD  Z^dddgZ_dgZ`ddddddgZaddddddddgZbddddgZcddddgZddddddddddg	Zee\e^ e_ e` eb ec ed ee ea ZfddddgZgdddgZhdddgZiddddgZjdddgZkddgZldddgZmd5d+d0d1d2d3ddgZnddddddgZoddddgapdddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddfZqxeRD ]Zrdeqer< qW xdD ]Zseqd eqes< qW xeQD ]Ztdeqet< q"W x"e^e_ e` ea D ]Zudeqeu< qFW xebD ]Zudeqeu< q^W xecD ]Zudeqeu< qvW xedD ]Zudeqeu< qW xenD ]Zvdeqev< qW dd ZwddddgZxddddddgZydZzdZ{dd  Z|dd Z}G dd de~ZG dd de~ZG dd deZG d	d
 d
e~ZG dd de~ZG dd de~ZG dd de~ZG dd de~ZG dd de~ZG dd deZG dd deZG dd deZdd Zdd Zdd  Zd!d" Zd#d$ Zd%d& Zdd(d)Zdd*d+Zdd.d/Zd0d1 Zd2d3 Zd4d5 Zd6d7 Zdd8d9Zd:d; Zdd<d=Zd>d? Zd@dA ZdBdC ZdDdE ZdFdG ZdHdI ZdJdK ZdLdM ZdNdO ZdPdQ ZdRdS ZdTdU ZdVdW ZdXdY ZdZd[ Zd\d] Zdd^d_Zd`da ZddfdgZdhdi Zdjdk Zdldm Zdnd Zdodp Zdqdr Zdsdt Zdudv ZddwdxZG dydz dzejjZG d{d| d|ejjZG d}d~ d~ejjZG dd dejjZdddZdddZdddZdddZdddZdddZexddddddgdddfddZĐdd ZŐdd ZƐdd Zǐddddd-d-gddfddZȐdd ZexddddddgdfddZʐdd Zːdd Z̐dd Z͐dd ZG dd deσZАdd ZѐdddZҐdddZӐdd ZԐdd ZG dd de~Z֐dd ZאdddZؐdZG ddÄ dÃZڐdĐdń ZېdƐdǄ ZܐdȐdɄ Zdddddʐdːdgfd͐d΄ZސddАdфZߐdҐdӄ ZddԐdՄZd֐dׄ ZddڐdۄZddܐd݄Zdddddʐdːdgfdސd߄Zdd ZdS (  zw
This module contains classes and functions for post-processing the output
of the Bayesian parameter estimation codes.
    N)cosceilfloorsqrtpi)minidom)
itemgetterZagg   )read_samples*   )fmod)pyplotlines)stats)special)signal)newton)interpolate)	integrate)linspace)combinations)+LALInferenceHDF5PosteriorSamplesDatasetNamez)Cannot import lalsimulation SWIG bindings)bbh_average_fits_precessingzjCannot import lalinference.imrtgr.nrutils. Will suppress final parameter and peak luminosity calculations.)ScalarFormatter.Unknownzligo.caltech.eduzcluster.ldas.citZcustomT)zmathtext.fontsetzmathtext.fallback_to_cm)Element
SubElementtostring	XMLParser)LIGOTimeGPSTimeDelayFromEarthCenter)git_versionzBen Aylott <benjamin.aylott@ligo.org>, Ben Farr <bfarr@u.northwestern.edu>, Will M. Farr <will.farr@ligo.org>, John Veitch <john.veitch@ligo.org>, Vivien Raymond <vivien.raymond@ligo.org>z	git id %sc             C   s   | j d| j  S )Ng&.>)geocent_end_timegeocent_end_time_ns)siminspiral r&   f/work/yifan.wang/ringdown/master-ringdown-env/lib/python3.7/site-packages/lalinference/bayespputils.pyget_endf   s    r(   c             C   s4   | j |}| | | jtjj||d|d dS )zWorkaround for missing astropy.table.Table.replace_column method,
    which was added in Astropy 1.1.

    FIXME: remove this function when LALSuite depends on Astropy >= 1.1.)name)indexN)colnamesr*   Zremove_column
add_columnastropytableColumn)r.   oldnewr*   r&   r&   r'   replace_columni   s    
r2   c             C   s   y|   S    | jS dS )zWorkaround for missing astropy.table.Table.as_array method,
    which was added in Astropy 1.0.

    FIXME: remove this function when LALSuite depends on Astropy >= 1.0.N)as_array_data)r.   r&   r&   r'   r3   r   s    r3   loglZloglh1Zloglh2Zlogll1Zloglv1	deltaloglZdeltaloglh1Zdeltalogll1Zdeltaloglv1logwlogpriorlogpostZnullloglZchain_log_evidenceZchain_delta_log_evidenceZchain_log_noise_evidenceZchain_log_bayes_factorc             C   s   g | ]\}}|| d  qS )_relative_phaser&   ).0abr&   r&   r'   
<listcomp>   s    r>   h1l1v1   Zsnroptimal_snrmatched_filter_snrZ	coherencec             C   s   g | ]}d | qS )z%s_optimal_snrr&   )r;   ir&   r&   r'   r>      s    )r?   r@   rA   c             C   s   g | ]}d | qS )z%s_cplx_snr_ampr&   )r;   rE   r&   r&   r'   r>      s    c             C   s   g | ]}d | qS )z%s_cplx_snr_argr&   )r;   rE   r&   r&   r'   r>      s    c             C   s   g | ]}d | qS )z	calamp_%sr&   )r;   ifor&   r&   r'   r>      s    c             C   s   g | ]}d | qS )z	calpha_%sr&   )r;   rF   r&   r&   r'   r>      s    m1m2	chirpmassmchirpmcetaq	massratioasym_massratiomtotalmfmf_evol
mf_nonevola1a2phi1theta1phi2theta2costilt1costilt2costheta_jncosbetatilt1
tilt1_iscotilt2
tilt2_iscophi_jltheta_jnphi12
phi12_iscoafaf_evol
af_nonevolafzafz_evolafz_nonevolspin1spin2a1za2zchiZeffectivespinchi_effchi_totchi_p	m1_source	m2_sourcemtotal_source	mc_sourceredshift	mf_sourcemf_source_evolmf_source_nonevolm1_source_maxldistm2_source_maxldistmtotal_source_maxldistmc_source_maxldistredshift_maxldistmf_source_maxldistmf_source_maxldist_evolmf_source_maxldist_nonevolZppEalphaZ	ppEloweraZ	ppEupperAZppEbetaZ	ppElowerbZ	ppEupperBZalphaPPEZaPPEZbetaPPEZbPPEc             C   s   g | ]}d | qS )zdchi%ir&   )r;   rE   r&   r&   r'   r>      s       c             C   s   g | ]}d | qS )zdchi%ilr&   )r;   rE   r&   r&   r'   r>      s    )      c             C   s   g | ]}d |d  qS )zdxi%dr	   r&   )r;   rE   r&   r&   r'   r>      s    r   c             C   s   g | ]}d |d  qS )zdalpha%ir	   r&   )r;   rE   r&   r&   r'   r>      s    r   c             C   s   g | ]}d |d  qS )zdbeta%ir	   r&   )r;   rE   r&   r&   r'   r>      s       c             C   s   g | ]}d |d  qS )zdsigma%ir	   r&   )r;   rE   r&   r&   r'   r>      s       ZomegaBDZScalarCharge1ZScalarCharge2ZlambdaGlog10lambda_alambda_alog10lambda_eff
lambda_efflog10livampliv_amplambda1lambda2	lam_tilde
dlam_tildelambdatdlambdatlambdasblunilogp1gamma1gamma2gamma3sdgamma0sdgamma1sdgamma2sdgamma3e_rad
e_rad_evole_rad_nonevoll_peakl_peak_evoll_peak_nonevole_rad_maxldiste_rad_maxldist_evole_rad_maxldist_nonevoldistanceZdistMPCdistdistance_maxliotainclinationcosiotapsipolarisationpolarizationrarightascensiondeclinationdecphasephi0
phase_maxltime	time_meanl1_end_timeh1_end_timev1_end_timeZdeltaloglh2Zdeltaloglg1	calpha_l1	calpha_h1	calpha_v1	calamp_l1	calamp_h1	calamp_v1gq=
ףp??gffffff?gGz?g?g?gMbP?g{Gz?g{Gz?g-C6?g      ?g{Gz?g?)frK   rG   rH   mass1mass2rP   rw   rt   ru   rv   r   r|   r}   r~   rL   rM   rO   r   r   r   r   r   r   r   rx   r   rJ   rI   rl   rm   rn   ro   rT   rU   rV   rX   rW   rY   r   r   rp   rq   rr   rs   rZ   r[   Zthatasr\   betaomegar]   ZppealphaZppebetaZ	ppeloweraZ	ppelowerbZ	ppeupperaZ	ppeupperbr   r   r   rN   r   r   r^   r`   rb   rc   rd   flowr   r   r   r   r   r   r   logdistancer   r\   rQ   rR   ry   rz   r{   r   r   r   rf   rg   rh   ri   rj   rk   r   r   r   r   r   r   r   r   r   )r   r   r   
h1l1_delay
l1v1_delay
h1v1_delayg      @c             C   sH   t j|  j}|j}|j}t|j|j}|jd|j  }|t|||| S )Ng&.>)	lalcached_detector_by_prefixlocation	longitudelatituder    r#   r$   r!   )Z
ifo_prefixinjr   r   r   Zt_gpst0r&   r&   r'   det_end_time   s    r   ZsoliddashedZdashdotZdottedrr=   ygcma  
p,h1,h2,h3,h4,h5
{
font-family:"Trebuchet MS", Arial, Helvetica, sans-serif;
}

p
{
font-size:14px;
}

h1
{
font-size:20px;
}

h2
{
font-size:18px;
}

h3
{
font-size:16px;
}



table
{
font-family:"Trebuchet MS", Arial, Helvetica, sans-serif;
width:100%;
border-collapse:collapse;
}
td,th
{
font-size:12px;
border:1px solid #B5C1CF;
padding:3px 7px 2px 7px;
}
th
{
font-size:14px;
text-align:left;
padding-top:5px;
padding-bottom:4px;
background-color:#B3CEEF;
color:#ffffff;
}
#postable tr:hover
{
background: #DFF4FF;
}
#covtable tr:hover
{
background: #DFF4FF;
}
#statstable tr:hover
{
background: #DFF4FF;
}

img {
    max-width: 510px;
    max-height: 510px;
    width:100%;
    eight:100%;
}

.ppsection
{
border-bottom-style:double;
}

a  
//<![CDATA[
function toggle_visibility(tbid,lnkid)
{

  if(document.all){document.getElementById(tbid).style.display = document.getElementById(tbid).style.display == 'block' ? 'none' : 'block';}

  else{document.getElementById(tbid).style.display = document.getElementById(tbid).style.display == 'table' ? 'none' : 'table';}

  document.getElementById(lnkid).value = document.getElementById(lnkid).value == '[-] Collapse' ? '[+] Expand' : '[-] Collapse';

 }
 //]]>

c          k   C   s   ddd d d dd d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d ddddddddddd d d d d d d ddddddddddddddd d d d d d d d d d d d d d ddd d ddd d d d d d d d ddddddddj}y|| S    d S d S )Nuniformznp.coszx**2znp.sin)jrG   rH   rK   rL   rM   rP   rt   ru   rv   rw   rx   r|   r}   r~   r   r   rQ   rR   rS   ry   rz   r{   r   r   r   rf   rg   rh   ri   rj   rk   r   r   r   r   r   r   r   r   r   rl   rm   rT   rU   rn   ro   rW   rY   rV   rX   rq   rr   rs   r^   r`   r_   ra   rZ   r[   r   r   r   r   r   r   r   r   r   r   rc   r\   r   r]   rb   rd   re   r5   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   polar_eccentricitypolar_anglealphar&   )r)   distributionsr&   r&   r'   	get_prior+  s    r   c             C   s  ddg}ddg}dddg}dd	d
g}ddg}dddg}ddg}ddg}ddg}	ddddg}
dd t dD dd dD  dd t d D  d!d t d"D  d#d t d$D  d%d t d&D  }d'd(d)d*d+d,d-d.d/d0d1d2d3d4d5d6d7d8d9d:d;d<d=d>d?d@dAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd[d\d]d^d_d`dadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzd{d|d}d~d{d|ddddddddddddddddddddddddddddddddddddddddddddddddddddddddd}| |krd} n| |krd} n~| |krd} nn| |kr,d} n^| |kr<d} nN| |krLd} n>| |kr\d} n.| |krld} n| |	kr|d} n| |
krd} y||  }W n tk
r   | }Y nX |S )z)
    A lookup table for plot labels.
    r   rG   r   rH   rK   rJ   rI   rL   rN   sym_massratiorM   rO   r   inclr   r   r   r   r   r   r   phi_orbphir   r   c             S   s   g | ]}d | qS )zdchi%dr&   )r;   rE   r&   r&   r'   r>     s    zplot_label.<locals>.<listcomp>r   c             S   s   g | ]}d | qS )zdchil%dr&   )r;   rE   r&   r&   r'   r>     s    )r   r   c             S   s   g | ]}d |d  qS )zdxi%dr	   r&   )r;   rE   r&   r&   r'   r>     s    r   c             S   s   g | ]}d |d  qS )zdalpha%dr	   r&   )r;   rE   r&   r&   r'   r>     s    r   c             S   s   g | ]}d |d  qS )zdbeta%dr	   r&   )r;   rE   r&   r&   r'   r>     s    r   c             S   s   g | ]}d |d  qS )zdsigma%dr	   r&   )r;   rE   r&   r&   r'   r>     s    r   z$m_1\,(\mathrm{M}_\odot)$z$m_2\,(\mathrm{M}_\odot)$z!$\mathcal{M}\,(\mathrm{M}_\odot)$z$\eta$z$q$z&$M_\mathrm{total}\,(\mathrm{M}_\odot)$z+$m_{1}^\mathrm{source}\,(\mathrm{M}_\odot)$z+$m_{2}^\mathrm{source}\,(\mathrm{M}_\odot)$z6$M_\mathrm{total}^\mathrm{source}\,(\mathrm{M}_\odot)$z1$\mathcal{M}^\mathrm{source}\,(\mathrm{M}_\odot)$z$z$z6$m_{1}^\mathrm{source - maxLdist}\,(\mathrm{M}_\odot)$z6$m_{2}^\mathrm{source - maxLdist}\,(\mathrm{M}_\odot)$zA$M_\mathrm{total}^\mathrm{source - maxLdist}\,(\mathrm{M}_\odot)$z<$\mathcal{M}^\mathrm{source - maxLdist}\,(\mathrm{M}_\odot)$z$z^\mathrm{maxLdist}$z&$M_\mathrm{final}\,(\mathrm{M}_\odot)$z4$M_\mathrm{final}^\mathrm{evol}\,(\mathrm{M}_\odot)$z8$M_\mathrm{final}^\mathrm{non-evol}\,(\mathrm{M}_\odot)$z6$M_\mathrm{final}^\mathrm{source}\,(\mathrm{M}_\odot)$z<$M_\mathrm{final}^\mathrm{source, evol}\,(\mathrm{M}_\odot)$z@$M_\mathrm{final}^\mathrm{source, non-evol}\,(\mathrm{M}_\odot)$zA$M_\mathrm{final}^\mathrm{source - maxLdist}\,(\mathrm{M}_\odot)$zG$M_\mathrm{final}^\mathrm{source, evol - maxLdist}\,(\mathrm{M}_\odot)$zK$M_\mathrm{final}^\mathrm{source, non-evol - maxLdist}\,(\mathrm{M}_\odot)$z$a_\mathrm{final}$z $a_\mathrm{final}^\mathrm{evol}$z$$a_\mathrm{final}^\mathrm{non-evol}$z$a_{\mathrm{final}, z}$z%$a_{\mathrm{final}, z}^\mathrm{evol}$z)$a_{\mathrm{final}, z}^\mathrm{non-evol}$z$$E_\mathrm{rad}\,(\mathrm{M}_\odot)$z2$E_\mathrm{rad}^\mathrm{evol}\,(\mathrm{M}_\odot)$z6$E_\mathrm{rad}^\mathrm{non-evol}\,(\mathrm{M}_\odot)$z6$E_\mathrm{rad}^\mathrm{maxLdist}\,(\mathrm{M}_\odot)$z=$E_\mathrm{rad}^\mathrm{evol - maxLdist}\,(\mathrm{M}_\odot)$zA$E_\mathrm{rad}^\mathrm{non-evol - maxLdist}\,(\mathrm{M}_\odot)$z<$L_\mathrm{peak}\,(10^{56}\,\mathrm{ergs}\,\mathrm{s}^{-1})$zJ$L_\mathrm{peak}^\mathrm{evol}\,(10^{56}\,\mathrm{ergs}\,\mathrm{s}^{-1})$zN$L_\mathrm{peak}^\mathrm{non-evol}\,(10^{56}\,\mathrm{ergs}\,\mathrm{s}^{-1})$z$S_1$z$S_2$z$a_1$z$a_2$z$a_{1z}$z$a_{2z}$z$\theta_1\,(\mathrm{rad})$z$\theta_2\,(\mathrm{rad})$z$\phi_1\,(\mathrm{rad})$z$\phi_2\,(\mathrm{rad})$z$\chi_\mathrm{eff}$z$\chi_\mathrm{total}$z$\chi_\mathrm{P}$z$t_1\,(\mathrm{rad})$z$t_2\,(\mathrm{rad})$z#$t_1^\mathrm{ISCO}\,(\mathrm{rad})$z#$t_2^\mathrm{ISCO}\,(\mathrm{rad})$z$\mathrm{cos}(t_1)$z$\mathrm{cos}(t_2)$z$\iota\,(\mathrm{rad})$z$\mathrm{cos}(\iota)$z$t_\mathrm{c}\,(\mathrm{s})$z$<t>\,(\mathrm{s})$z$d_\mathrm{L}\,(\mathrm{Mpc})$z,$d_\mathrm{L}^\mathrm{maxL}\,(\mathrm{Mpc})$z$\alpha$z$\delta$z$\phi\,(\mathrm{rad})$z$$\phi^\mathrm{maxL}\,(\mathrm{rad})$z$\psi\,(\mathrm{rad})$z$$\theta_\mathrm{JN}\,(\mathrm{rad})$z"$\mathrm{cos}(\theta_\mathrm{JN})$z$\beta\,(\mathrm{rad})$z$\mathrm{cos}(\beta)$z"$\phi_\mathrm{JL}\,(\mathrm{rad})$z"$\phi_\mathrm{12}\,(\mathrm{rad})$z0$\phi_\mathrm{12}^\mathrm{ISCO}\,(\mathrm{rad})$z$\mathrm{log}(\mathcal{L})$z$t_\mathrm{H}$z$t_\mathrm{L}$z$t_\mathrm{V}$z$\Delta t_\mathrm{HL}$z$\Delta t_\mathrm{HV}$z$\Delta t_\mathrm{LV}$z$\tilde{\Lambda}$z$\delta \tilde{\Lambda}$z$\lambda_1$z$\lambda_2$z$\log(p_1)$z
$\Gamma_1$z
$\Gamma_2$z
$\Gamma_3$z$\gamma_{0}$z$\gamma_{1}$z$\gamma_{2}$z$\gamma_{3}$z$\delta A_{H1}$z$\delta A_{L1}$z$\delta \phi_{H1}$z$\delta \phi_{L1}$z$\epsilon_{polar}$z$\alpha_{polar}$z	$d\chi_0$z	$d\chi_1$z	$d\chi_2$z	$d\chi_3$z	$d\chi_4$z	$d\chi_5$z$d\chi_{5}^{(l)}$z	$d\chi_6$z$d\chi_{6}^{(l)}$z	$d\chi_7$z$d\xi_1$z$d\xi_2$z$d\xi_3$z$d\xi_4$z$d\xi_5$z$d\xi_6$z$d\alpha_1$z$d\alpha_2$z$d\alpha_3$z$d\alpha_4$z$d\alpha_5$z
$d\beta_1$z
$d\beta_2$z
$d\beta_3$z$d\sigma_1$z$d\sigma_2$z$d\sigma_3$z$d\sigma_4$z$\rho^{opt}$z$\rho^{opt}_{H1}$z$\rho^{opt}_{L1}$z$\rho^{opt}_{V1}$z$\rho^{MF}$z$\Lambda_S$z$BL_{uniform}$z'$\log\lambda_{\mathbb{A}} [\mathrm{m}]$z $\log\lambda_{eff} [\mathrm{m}]$z$\lambda_{eff} [\mathrm{m}]$z#$\lambda_{\mathbb{A}} [\mathrm{m}]$z'$\mathbb{A} [\mathrm{{eV}^{2-\alpha}}]$z+$\log \mathbb{A}[\mathrm{{eV}^{2-\alpha}}]$)rG   rH   rK   rL   rM   rP   rt   ru   rv   rw   rx   r|   r}   r~   r   r   rQ   rR   rS   ry   rz   r{   r   r   r   rf   rg   rh   ri   rj   rk   r   r   r   r   r   r   r   r   r   rl   rm   rT   rU   rn   ro   rW   rY   rV   rX   rq   rr   rs   r^   r`   r_   ra   rZ   r[   r   r   r   r   r   r   r   r   r   r   r   rc   r\   r   r]   rb   rd   re   r5   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   Zdchi0Zdchi1Zdchi2Zdchi3Zdchi4Zdchi5Zdchi5lZdchi6Zdchi6lZdchi7Zdxi1Zdxi2Zdxi3Zdxi4Zdxi5Zdxi6Zdalpha1Zdalpha2Zdalpha3Zdalpha4Zdalpha5Zdbeta1Zdbeta2Zdbeta3Zdsigma1Zdsigma2Zdsigma3Zdsigma4rC   Zh1_optimal_snrZl1_optimal_snrZv1_optimal_snrrD   r   r   r   r   r   r   r   r   )rangeKeyError)paramZm1_namesZm2_namesZmc_namesZ	eta_namesZq_namesZ
iota_namesZ
dist_namesZra_namesZ	dec_namesZphase_namesZgr_test_nameslabelslabelr&   r&   r'   
plot_label  sl   


h










r   c               @   s   e Zd ZdZd%ddZdd Zdd Zed	d
 Zedd Z	edd Z
edd Zedd Zedd Zedd Zdd Zdd Zedd Zdd Zedd  Zed!d" Zd#d$ ZdS )&PosteriorOneDPDFaC  
    A data structure representing one parameter in a chain of posterior samples.
    The Posterior class generates instances of this class for pivoting onto a given
    parameter (the Posterior class is per-Sampler oriented whereas this class represents
    the same one parameter in successive samples in the chain).
    Nc             C   s.   || _ t|| _|| _|| _|| _|| _dS )a  
        Create an instance of PosteriorOneDPDF based on a table of posterior_samples.

        @param name: A literal string name for the parameter.
        @param posterior_samples: A 1D array of the samples.
        @param injected_value: The injected or real value of the parameter.
        @param injFref: reference frequency for injection
        @param trigger_values: The trigger values of the parameter (dictionary w/ IFOs as keys).
        @param prior: The prior value corresponding to each sample.
        N)_PosteriorOneDPDF__namenparray$_PosteriorOneDPDF__posterior_samplesZ_PosteriorOneDPDF__injFref_PosteriorOneDPDF__injval_PosteriorOneDPDF__trigvalsZ_PosteriorOneDPDF__prior)selfr)   Zposterior_samplesinjected_valueinjFreftrigger_valuespriorr&   r&   r'   __init__n  s    zPosteriorOneDPDF.__init__c             C   s
   t | jS )zA
        Container method. Defined as number of samples.
        )lenr   )r   r&   r&   r'   __len__  s    zPosteriorOneDPDF.__len__c             C   s    t | j| j| | j| j| jdS )z^
        Container method . Returns posterior containing sample idx (allows slicing).
        )r   f_refr   )r   r   r   r   Z_PosteriorOneDPDF__f_refr   )r   idxr&   r&   r'   __getitem__  s    zPosteriorOneDPDF.__getitem__c             C   s   | j S )zC
        Return the string literal name of the parameter.

        )r   )r   r&   r&   r'   r)     s    zPosteriorOneDPDF.namec             C   s   t | jS )zT
        Return the arithmetic mean for the marginal PDF on the parameter.

        )r   meanr   )r   r&   r&   r'   r     s    zPosteriorOneDPDF.meanc             C   s   t | jS )zQ
        Return the median value for the marginal PDF on the parameter.

        )r   medianr   )r   r&   r&   r'   r     s    zPosteriorOneDPDF.medianc          	   C   s`   y"t t| j}t|s tW n8 tk
rZ   t| j}|t t| j|  }Y nX |S )zV
        Return the standard deviation of the marginal PDF on the parameter.

        )r   r   varr   isfiniteOverflowErrorr   )r   stdevr   r&   r&   r'   r    s    
zPosteriorOneDPDF.stdevc             C   s.   | j dkrdS tt| j| j  d S dS )a  
        Return the 'standard accuracy statistic' (stacc) of the marginal
        posterior of the parameter.

        stacc is a standard deviant incorporating information about the
        accuracy of the waveform recovery. Defined as the mean of the sum
        of the squared differences between the points in the PDF
        (x_i - sampled according to the posterior) and the true value
        ($x_{true}$).  So for a marginalized one-dimensional PDF:
        $stacc = \sqrt{rac{1}{N}\sum_{i=1}^N (x_i-x_{m true})2}$

        Ng       @)r   r   r   r   r   )r   r&   r&   r'   stacc  s    
zPosteriorOneDPDF.staccc             C   s   | j S )zq
        Return the injected value set at construction . If no value was set
        will return None .

        )r   )r   r&   r&   r'   injval  s    zPosteriorOneDPDF.injvalc             C   s   | j S )zp
        Return the trigger values set at construction. If no value was set
        will return None .

        )r   )r   r&   r&   r'   trigvals  s    zPosteriorOneDPDF.trigvalsc             C   s
   || _ dS )z{
        Set the injected/real value of the parameter.

        @param new_injval: The injected/real value to set.
        N)r   )r   
new_injvalr&   r&   r'   
set_injval  s    zPosteriorOneDPDF.set_injvalc             C   s
   || _ dS )z
        Set the trigger values of the parameter.

        @param new_trigvals: Dictionary containing trigger values with IFO keys.
        N)r   )r   new_trigvalsr&   r&   r'   set_trigvals  s    zPosteriorOneDPDF.set_trigvalsc             C   s   | j S )z:
        Return a 1D numpy.array of the samples.

        )r   )r   r&   r&   r'   samples  s    zPosteriorOneDPDF.samplesc             C   s   t | j|dd| _dS )z
        Remove samples from posterior, analagous to numpy.delete but opperates in place.

        @param samples: A list containing the indexes of the samples to be removed.
        r	   N)r   deleter   reshape)r   r
  r&   r&   r'   delete_samples_by_idx  s    z&PosteriorOneDPDF.delete_samples_by_idxc             C   sx   ddl m} ddlm} |dd |dd ytjt| j}W n.   t	dd}t
|| j |   Y nX |S )z\
        Return a SciPy gaussian_kde (representing a Gaussian KDE) of the samples.

        r   )seterrignore)underzexception.outw)numpyr  scipyr   kdegaussian_kder   	transposer   opensavetxtclose)r   	np_seterr	sp_seterrZreturn_valueZexfiler&   r&   r'   r    s    


zPosteriorOneDPDF.gaussian_kdec             C   s   dd }t j| jddd\}}ddlm} t| j}|dkrBtnH|d	krT|d
7 }n6d|krj|dd n |	dsd| }|d
7 }ntyt
|}W n   tY nX |||dS )a  Returns the KL divergence between the prior and the posterior.
        It measures the relative information content in nats. The prior is evaluated
        at run time. It defaults to None. If None is passed, it just returns the information content
        of the posterior."
        c                s   t  fdd D S )Nc                s$   g | ]}d t  t    qS )g      ?)r   maxmin)r;   _)xr&   r'   r>     s    z8PosteriorOneDPDF.KL.<locals>.uniform.<locals>.<listcomp>)r   r   )r   r&   )r   r'   r     s    z$PosteriorOneDPDF.KL.<locals>.uniform$   T)binsdensityr   )entropyNr   z(self.samples)r   zself.samplesznp.)Zqk)r   Z	histogramr
  Zscipy.statsr$  r   r)   
ValueErrorreplace
startswitheval)r   r   	posteriorZdxr$  r   Z
prior_distr&   r&   r'   KL  s&    




zPosteriorOneDPDF.KLc             C   s   g }t t | j}x|D ]}|dk r| t |}tt|d d|  }|dk rZd}|tt|d d|   }||kr|d }|t|| t|| f q|d qW |S )zv
        Evaluate probability intervals.

        @param intervals: A list of the probability intervals [0-1]
        g      ?g       @r	   r   )NN)	r   sortsqueezer
  sizeintr   appendfloat)r   Z	intervalsZ
list_of_ciZsamples_tempintervalNZ	lower_idxZ	upper_idxr&   r&   r'   prob_interval5  s    

 zPosteriorOneDPDF.prob_interval)NNNN)__name__
__module____qualname____doc__r   r   r   propertyr)   r   r   r  r  r  r  r  r	  r
  r  r  r*  r3  r&   r&   r&   r'   r   g  s$   
	
		"r   c               @   s  e Zd ZdZdlddZdd Zd	d
 Zdd Zdd Ze	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#d$ Zd%d& Zd'd( Zd)d* Ze	d+d, Ze	d-d. Ze	d/d0 Ze	d1d2 Ze	d3d4 Ze	d5d6 Ze	d7d8 Zd9d: Zd;d< Z d=d> Z!d?d@ Z"dmdBdCZ#dDdE Z$dndGdHZ%dIdJ Z&dKdL Z'dMdN Z(dOdP Z)dQdR Z*e	dSdT Z+e	dUdV Z,dWdX Z-dYdZ Z.d[d\ Z/dod^d_Z0d`da Z1dbdc Z2ddde Z3dfdg Z4dhdi Z5dpdjdkZ6dS )q	Posteriorz;
    Data structure for a table of posterior samples .
    NOrbitalLd   c          &      sl  |\}}	i  _ | _| _| _dddddg _dddd	d
dg _dd |D }dd dd dd dd dd dd dd dd dd  j jdd dd dd dd dd dd dd dd d d d!d  j j j jd"d d#d d$d d%d d&d  fd'dd(d d)d d*d d+d d,d d-d d.% _x, j	 j|d/
 D ]\}
}| j|
< qDW xPtt|	|	jd0 |D ]4\}}t| | | j |d1 j |< qvW d2|krdd3|krdd4|krdd5|krdyntd6 t j d2 j j d3 j\}}td4| d4 d4d7 j d4< td5| d5 d5d7 j d5< W n tk
rb   td8 Y nX d9}xX jD ]N}||krpy j | j _W n& tk
r   td:|  wpY nX d;}qpW |std<d= _xp jD ]f}||kry j | j _W n& tk
r$   td:|  wY nX d>|krd?d  jD  _qW |d=k	rX| _|d=k	rh| _d=S )@a  
        Constructor.

        @param commonResultsFormatData: A 2D array containing the posterior
            samples and related data. The samples chains form the columns.
        @param SimInspiralTableEntry: A SimInspiralTable row containing the injected values.
        @param SnglInspiralList: A list of SnglInspiral objects containing the triggers.
        @param inj_spin_frame: spin frame
        @param injFref: reference frequency
        @param name: optional name
        @param description: optional description

        r6   r)  r5   logL
likelihoodlogplogPr   r8   PriorlogPriorc             S   s   g | ]}|  qS r&   )lower)r;   rE   r&   r&   r'   r>   l  s    z&Posterior.__init__.<locals>.<listcomp>c             S   s   | j S )N)rJ   )r   r&   r&   r'   <lambda>p      z$Posterior.__init__.<locals>.<lambda>c             S   s   | j S )N)rJ   )r   r&   r&   r'   rC  q  rD  c             S   s   | j S )N)rJ   )r   r&   r&   r'   rC  r  rD  c             S   s   | j S )N)r   )r   r&   r&   r'   rC  s  rD  c             S   s   | j S )N)r   )r   r&   r&   r'   rC  t  rD  c             S   s   | j S )N)r   )r   r&   r&   r'   rC  u  rD  c             S   s   | j S )N)r   )r   r&   r&   r'   rC  v  rD  c             S   s   t | jt | j S )N)r0  r   r   )r   r&   r&   r'   rC  w  rD  c             S   s   | j S )N)rL   )r   r&   r&   r'   rC  x  rD  c             S   s   | j S )N)rL   )r   r&   r&   r'   rC  {  rD  c             S   s   | j S )N)rL   )r   r&   r&   r'   rC  |  rD  c             S   s   t t| S )N)r0  r(   )r   r&   r&   r'   rC  }  rD  c             S   s   t t| S )N)r0  r(   )r   r&   r&   r'   rC  ~  rD  c             S   s   t t| S )N)r0  r(   )r   r&   r&   r'   rC    rD  c             S   s   | j S )N)r   )r   r&   r&   r'   rC    rD  c             S   s   | j S )N)	coa_phase)r   r&   r&   r'   rC    rD  c             S   s   | j S )N)rE  )r   r&   r&   r'   rC    rD  c             S   s   | j S )N)r   )r   r&   r&   r'   rC    rD  c             S   s   | j S )N)r   )r   r&   r&   r'   rC    rD  c             S   s   | j S )N)r   )r   r&   r&   r'   rC    rD  c             S   s   | j S )N)r   )r   r&   r&   r'   rC    rD  c             S   s   | j S )N)r   )r   r&   r&   r'   rC    rD  c             S   s   | j S )N)r   )r   r&   r&   r'   rC    rD  c             S   s   t | jt jS )N)r   modr   r   )r   r&   r&   r'   rC    rD  c                s    j S )N)_injFref)r   )r   r&   r'   rC    rD  c             S   s   | j S )N)r   )r   r&   r&   r'   rC    rD  c             S   s   | j S )N)r   )r   r&   r&   r'   rC    rD  c             S   s   t td| S )NH)det_endr   )r   r&   r&   r'   rC    rD  c             S   s   t td| S )NL)rI  r   )r   r&   r&   r'   rC    rD  c             S   s   t td| S )NV)rI  r   )r   r&   r&   r'   rC    rD  c             S   s   | j S )N)	amp_order)r   r&   r&   r'   rC    rD  )%rJ   rI   rK   r   rG   r   rH   rP   rL   rM   rO   rN   r   r   r   end_timer   r   r   r   r   r   r   longr   r   r   latr   r   r   r   r   r   r   r   lal_amporder)framer	   )r   r   r   rJ   rL   rG   rH   z'Inferring m1 and m2 from mchirp and eta)r   r   z-Unable to deduce m1 and m2 from input columnsFzNo '%s' column in input table!Tz%No likelihood/posterior values found!Nlogc             S   s   g | ]}t |qS r&   )r   rR  )r;   rE   r&   r&   r'   r>     s    )
_posteriorrG  
_injection	_triggers_loglaliases_logpaliases_inj_q_inj_longitude_injXMLFuncMap
_inj_spinsitemszipr   hsplitshaper   rB  
_getinjpar_gettrigparprintmc2msr
  r   _logLRuntimeError_logP_Posterior__name_Posterior__description)r   commonResultsFormatDataZSimInspiralTableEntryZinj_spin_framer   ZSnglInspiralListr)   descriptioncommon_output_table_headercommon_output_table_rawkeyvalone_d_posterior_samples
param_namerG   rH   	logLFound	loglalias	logpaliasr&   )r   r'   r   U  s    
"0"&







zPosterior.__init__c       +         s6  | j }| djkrd}ndjkr*d}nd}djkr>d}nd}djkrRd}ndjkrbd}nd}d	jkrd
jkrddd d |jkr|jkrd	jksdjkrd
jksdjkrڈdt||f |jkrB|jkrBd	jks
djkrBd
jks"djkrBdt||f dt| djkrxdjkrxdjkrxddd d djkrddd d djkrddd d djkr҈ddd d djkrddd d djkrd d!d d d"jkr,d#d$d d" d%d&d'g}xt|d(D ]x\}}|d) }|d) }	|jkrB|	jkrBt| j	|	 j	 tj
 d*tj
 tj
 }
t|| d+ |
 qBW yd,jksd-jkr|d.jksd/jkr|d0jkr|d1d2lmm d1d3lm d4d5d6d7d8d9d:}d,jkr>d,}nd-}d/jkrTd/}nd.}i }d;d<d=g}x|D ]}d>}|rt||}tj| jttfd?d| j	| j	d0 j	||< t| d@ || |dA}| qlW x|D ]~}xv|D ]n}||krq|| ||  }|rFtt||t|| }nd>}t| |  dB ||}| qW qW W n& tk
r   tdC tdD Y nX dEdFdGdHg}t|tjs&dI|ddJdd dg}djkr|dd#dg7 }y|t| W n tk
r$   tdK Y nX djkrdEjkrRdLdMd dN nPdLdOd d d>}|d>k	rx|j}dL  | !d ddPd dL djkrdFjkrΈdQdRd dS nPdQdTd d d>}|d>k	r|j"}dQ  | !d ddUd dQ djkr`dLjkr`djkr`dQjkr`dVdWd dX djkrdjkrdEjkrdjkrdjkrdFjkrdYdZd d[ djkrdjkrdEjkrdjkrdjkrdFjkrd\t#dddEdddFg d]jkr8d^t$d] n6d_jkrTd^t$d_ nd`jkrndat$d` djkrd^jkrdbt%dd^g djkrd^jkrdct%dd^g djkrd^jkrddt%dd^g djkrd^jkrdet%dd^g djkr@dajkr@dft%ddag djkrjdajkrjdgt%ddag djkrdajkrdht%ddag djkrdajkrdit%ddag djjkrd^jkrdkdld d^dmdjd_g djjk	r"d^jk	r"dndod d^dmdjd_g dpjk	rPd^jk	rPdqt&d^dmdjd_g dpjk	r~d^jk	r~drt'd^dmdpd_g dsdtg}dudvdg}dujk	sdvjk	ry|t(| W n tk
	r   tdw Y nX dJd dd#ddHg}dGdxdEdFdydddddIdzg}yPdI j	d1 d1 d{k
rRx2d|D ]*}|jk
r$dGdxdEdFdydddd|g
}
q$W W n   td} Y nX t|tj
rt|tj
s|t)| d~jkrd> }}|rt*|j+|j+ |j,|j,  |j|j  }t*|j-|j- |j.|j.  |j"|j"  }y*t/d~ j	}td||dA}| W n tk
rV   td Y nX y*t/d j	} td| |dA}!|! W n tk
r   td Y nX t0t1jt2d1kr2dddgddg ddgd}"d}#t3fdddD rd}"nt3fdddD rd}#td{gdE|" }$dF|" }%dy|" }&d|# }'d|# }(d|# })djkrdjkrdjkr"djkr"|$jkr|%jkr|&jkrtd |#dkrtd ntd td dd y,d|# fdddddd|$|%|&g W n< t4k
rD }* ztdd|# t5|*f  W d>d>}*~*X Y nX y,d|# fdddddd|$|%g W n< t4k
r }* ztdd|# t5|*f  W d>d>}*~*X Y nX y(|' fdddddd|$|%g W n8 t4k
r }* ztd|'t5|*f  W d>d>}*~*X Y nX y,d|# fdddddd|$|%g W n< t4k
rz }* ztdd|# t5|*f  W d>d>}*~*X Y nX qdLjkrdQjkrtd td td dd y$dfdddddLdQg W n4 t4k
r }* ztdt5|*  W d>d>}*~*X Y nX yddd d W n4 t4k
r^ }* ztdt5|*  W d>d>}*~*X Y nX y$d fdddddLdQg W n4 t4k
r }* ztdt5|*  W d>d>}*~*X Y nX y$dfdddddLdQg W n4 t4k
r }* ztdt5|*  W d>d>}*~*X Y nX ntd nptd td td dd y dfddddg W n4 t4k
r }* ztdt5|*  W d>d>}*~*X Y nX yddd d W n4 t4k
r }* ztdt5|*  W d>d>}*~*X Y nX y d fddddg W n4 t4k
r: }* ztdt5|*  W d>d>}*~*X Y nX y dfddddg W n4 t4k
r }* ztdt5|*  W d>d>}*~*X Y nX |'jkrd^jkry|(t%|'d^g W n4 t4k
r }* ztdt5|*  W d>d>}*~*X Y nX |'jkrZdajkrZy|)t%|'dag W n4 t4k
rX }* ztdt5|*  W d>d>}*~*X Y nX ddjkr|(jkryd|# dd dd|(g W n4 t4k
r }* ztdt5|*  W d>d>}*~*X Y nX dhjkr2|)jkr2yd|# dd dh|)g W n4 t4k
r0 }* ztdt5|*  W d>d>}*~*X Y nX d>S )zt
        Add some useful derived parameters (such as tilt angles, time delays, etc) in the Posterior object
        rK   rI   rJ   rO   rM   r   rN   rL   r   r   )rG   rH   c             S   s   | |fS )Nr&   )r   r   r&   r&   r'   rC    rD  z,Posterior.extend_posterior.<locals>.<lambda>)r   r   rG   rH   rP   c             S   s   | | S )Nr&   )rG   rH   r&   r&   r'   rC    rD  Za_spin1rT   c             S   s   | S )Nr&   )r<   r&   r&   r'   rC    rD  Za_spin2rU   c             S   s   | S )Nr&   )r<   r&   r&   r'   rC    rD  	phi_spin1rV   c             S   s   | S )Nr&   )r<   r&   r&   r'   rC    rD  	phi_spin2rX   c             S   s   | S )Nr&   )r<   r&   r&   r'   rC    rD  theta_spin1rW   c             S   s   | S )Nr&   )r<   r&   r&   r'   rC    rD  theta_spin2rY   c             S   s   | S )Nr&   )r<   r&   r&   r'   rC    rD  r?   r@   rA   rB   Z_cplx_snr_argg       @r:   r   r   r   r   r   r   )r    r!   )r   ZLHO_4kZLHO_2kZLLO_4kZGEO_600ZVIRGOZTAMA_300)H1ZH2L1ZG1V1ZT1rx  ry  rz  Nc          
      s0   |d | d |d  t |d  gS )Nr   )r0  )r   r   r   )r    r!   r   r   r&   r'   rC  %  rD  Z	_end_time)r   Z_delayz_Warning: Could not import lal python bindings, check you ./configured with --enable-swig-pythonz)This means I cannot calculate time delaysr^   r`   rc   r   r   r   zHWarning: Cannot find spin parameters.  Skipping spin angle calculations.rn   c             S   s   | t | S )N)r   r   )r<   tiltr&   r&   r'   rC  C  rD  )rT   r^   c             S   s   | S )Nr&   )r   r&   r&   r'   rC  E  rD  c             S   s
   t | S )N)r   abs)r   r&   r&   r'   rC  K  rD  ro   c             S   s   | t | S )N)r   r   )r<   r{  r&   r&   r'   rC  O  rD  )rU   r`   c             S   s   | S )Nr&   )r   r&   r&   r'   rC  Q  rD  c             S   s
   t | S )N)r   r|  )r   r&   r&   r'   rC  W  rD  rq   c             S   s   | | ||  | |  S )Nr&   )rG   rn   rH   ro   r&   r&   r'   rC  [  rD  )rG   rn   rH   ro   rr   c             S   s   | | ||  | |  S )Nr&   )rG   rT   rH   rU   r&   r&   r'   rC  _  rD  )rG   rT   rH   rU   rs   r   rx   r   r   r   rt   ru   rv   rw   r|   r}   r~   r   r   r   c             S   s   t t| |d| |S )N
   )r   log10r   )znonGR_alphawlr   r&   r&   r'   rC    rD  r  r   c             S   s   t t| |d| |S )Nr}  )r   r~  amplitudeMeasure)r  r  r  r   r&   r&   r'   rC    rD  r   r   r   r   r   r   r   zDWarning: Cannot find tidal parameters.  Skipping tidal calculations.rb   rd   r   g        )r   f_lowerzBNo f_ref for SimInspiralTransformPrecessingNewInitialConditions().rl   z(Warning: problem accessing spin1 values.rm   zWarning: no spin2 values found.ZHBR2016ZUIB2016ZHL2016 Z_evolc                s   g | ]}| j kqS r&   )names)r;   r   )posr&   r'   r>     s    z.Posterior.extend_posterior.<locals>.<listcomp>)r_   ra   re   Z_iscoc                s   g | ]}| j kqS r&   )r  )r;   r   )r  r&   r'   r>     s    )r^   r`   rd   Z_nonevolrQ   ry   r   zhUsing averages of fit formulae for final mass, final spin, and peak luminosity (on masses and 3D spins).zLApplying these to *_isco evolved spin samples and outputting *_evol samples.zJApplying these to unevolved spin samples and outputting *_nonevol samples.zFinal mass fits:z; Final spin fits:z; Peak luminosity fits:rf   c          
      s   t | ||||||d 	S )Nrf   )r   )rG   rH   chi1chi2r^   r`   rd   )FinalSpinFitsr&   r'   rC    rD  z)Could not calculate %s. The error was: %sri   c          
      s   t | |||||d 	S )Nri   )r   )rG   rH   r  r  r^   r`   )r  zero_vecr&   r'   rC    rD  c          
      s   t | |||||d 	S )NMf)r   )rG   rH   r  r  r^   r`   )FinalMassFitsr  r&   r'   rC    rD  r   c          
      s   t | |||||d 	S )NLpeak)r   )rG   rH   r  r  r^   r`   )	LpeakFitsr  r&   r'   rC    rD  ziUsing averages for final mass, final spin, and peak luminosity (on masses and projected spin components).zWOutputting *_evol samples because spin evolution is trivial in this nonprecessing case.rj   c                sH   t | |t|t|dtj dt|  dtj dt|  d 	S )Ng      ?g      ?ri   )r   r|  r   r   sign)rG   rH   r  r  )r  r  r&   r'   rC    rD  z/Could not calculate afz_evol. The error was: %srg   c             S   s   t | S )N)r|  )r<   r&   r&   r'   rC    rD  z.Could not calculate af_evol. The error was: %srR   c                sH   t | |t|t|dtj dt|  dtj dt|  d 	S )Ng      ?g      ?r  )r   r|  r   r   r  )rG   rH   r  r  )r  r  r&   r'   rC    rD  z.Could not calculate mf_evol. The error was: %sr   c                sH   t | |t|t|dtj dt|  dtj dt|  d 	S )Ng      ?g      ?r  )r   r|  r   r   r  )rG   rH   r  r  )r  r  r&   r'   rC  	  rD  z2Could not calculate l_peak_evol. The error was: %szCould not calculate final parameters or Lpeak. Found samples for a1 and a2 but not for tilt angles and phi12 or spin components (a1z and a2z).zjUsing averages of fit formulae for final mass, final spin, and peak luminosity (on masses and zero spins).zUOutputting *_evol samples because spin evolution is trivial in this nonspinning case.c          
      s   t | |d 	S )Nri   )r   )rG   rH   )r  r  r&   r'   rC    rD  c             S   s   t | S )N)r|  )r<   r&   r&   r'   rC    rD  c          
      s   t | |d 	S )Nr  )r   )rG   rH   )r  r  r&   r'   rC    rD  c          
      s   t | |d 	S )Nr  )r   )rG   rH   )r  r  r&   r'   rC     rD  z>Could not calculate final source frame mass. The error was: %szVCould not calculate final source frame mass using maxldist redshift. The error was: %sr   c             S   s   | | S )Nr&   )mtot_smf_sr&   r&   r'   rC  4  rD  z6Could not calculate radiated energy. The error was: %sr   c             S   s   | | S )Nr&   )r  r  r&   r&   r'   rC  :  rD  zVCould not calculate radiated energy using maxldist redshift results. The error was: %s)6rT  r  append_mappingrc  q2msq2etar   r   rF  r
  r   r/  r   r   r    r!   r  r   r   r   r   listmaprB  r0  ImportErrorrb  setissubsetspin_anglesr   spin1zr  popspin2zchi_precessingcalculate_redshiftsource_massr   r  symm_tidal_paramsphysical2radiationFramer   spin1xspin1yspin2xspin2yr|  r   Zintersect1dtidalParamsall	Exceptionstr)+r   	injectionZmchirp_nameZq_nameZeta_nameZmy_ifosZifo1Zifo2p1p2deltaZdetMapZra_nameZdec_nameZ	ifo_timesrF   Zinj_timeZloc_end_timeZ
delay_timeZ	inj_delayZ
time_delayZnew_spin_params
old_paramsZinj_azZnew_tidal_paramsZold_tidal_paramsZold_spin_paramsr)   Zinj_a1Zinj_a2Za1_sampsZa1_posZa2_sampsZa2_posZspin_angle_suffixZevol_suffixZ
tilt1_nameZ
tilt2_nameZ
phi12_nameZmf_nameZmf_source_nameZmf_source_maxldist_nameer&   )	r  r  r    r  r!   r   r   r  r  r'   extend_posterior  s:   




$      
.


:


  



0HH

",((
$

,*,*(&,.$""$"$$ "" " """"zPosterior.extend_posteriorc       
      C   s   g }g }x,| j  D ]\}}|| ||j qW t|}|ddddf }|jd }t||}x&t|D ]}	t	
|||	ddf< qtW t||f| j| jS )zc
        Returns a new Posterior object that contains a bootstrap
        sample of self.

        Nr   )rS  r\  r/  r
  r   hstackr_  Zvsplitr   randomchoicer9  rT  rU  )
r   r  r
  r)   ZoneDposZsamplesBlockZbootstrapSamplesZNsamprowsrE   r&   r&   r'   	bootstrap>  s    


zPosterior.bootstrapc             C   s    x| D ]\}}| | qW dS )z|
        Remove samples from all OneDPosteriors.

        @param samples: The indexes of the samples to be removed.
        N)r  )r   r
  r)   r  r&   r&   r'   r  V  s    zPosterior.delete_samples_by_idxc       	      C   s   t d}i }xX|D ]P}t | | jd}t |dkd }t|dkrt|||< t ||}qW t| }t|}|dk	rtd||f  x$|	 D ]}td|| |f  qW | 
| dS )z
        Remove samples containing NaN in request params.

        @param param_list: The parameters to be checked for NaNs.
        r&   r	   Tr   z5WARNING: removing %i of %i total samples due to NaNs:z	%i NaNs in %s.N)r   r   isnanr
  anywherer   r/  rb  keysr  )	r   Z
param_listZnan_idxsZnan_dictr   Znan_bool_arrayZidxsZtotal_sampsZ	nan_sampsr&   r&   r'   delete_NaN_entries`  s     


zPosterior.delete_NaN_entriesc             C   s   dt | jt | j  S )zReturns the Deviance Information Criterion estimated from the
        posterior samples.  The DIC is defined as -2*(<log(L)> -
        Var(log(L))); smaller values are "better."

        g       )r   r   rd  r   )r   r&   r&   r'   DICw  s    zPosterior.DICc             C   s   | j S )z.
        Return the injected values.

        )rT  )r   r&   r&   r'   r    s    zPosterior.injectionc             C   s   | j S )z.
        Return the trigger values .

        )rU  )r   r&   r&   r'   triggers  s    zPosterior.triggersc             C   sF   d}|d }x(|dd  D ]}||k r.||7 }|}qW ||d 7 }|S )Nr   r	   r  r&   )r   r
  totallastr   r&   r&   r'   _total_incl_restarts  s    zPosterior._total_incl_restartsc       	      C   s   |   \}}| }d|kr$td|d}d|kr|d}t|dd|f }d}x8|D ]0}||dd|f |k|f }t|| |}q`W t|S t| |dd|f S dS )zD
        Returns the number of cycles in the longest chain

        cyclez0Cannot compute number of cycles in longest chainchainNr   )	r
  splitre  r*   r   uniquer  r  r.  )	r   sampsheaderZ	cycle_colZ	chain_colZchain_indexesZ	max_cycleindZchain_cycle_sampsr&   r&   r'   longest_chain_cycles  s    


zPosterior.longest_chain_cyclesc             C   sD   |dk	r@|| _ x0| D ](\}}| |}|dk	r| | | qW dS )z
        Set the injected values of the parameters.

        @param injection: A SimInspiralTable row object containing the injected parameters.
        N)rT  r`  r  )r   r  r)   oneposr  r&   r&   r'   set_injection  s    
zPosterior.set_injectionc             C   sD   |dk	r@|| _ x0| D ](\}}| |}|dk	r| | | qW dS )zu
        Set the trigger values of the parameters.

        @param triggers: A list of SnglInspiral objects.
        N)rU  ra  r	  )r   r  r)   r  r  r&   r&   r'   set_triggers  s    
zPosterior.set_triggersc          	   C   sj   | j dk	rfxZ| j D ]L\}}|  |  kry| j| | j S  tk
r`   | j| S X qW dS )zK
        Map parameter names to parameters in a SimInspiralTable .
        N)rT  rZ  r\  rB  strip	TypeError)r   	paramnamerm  valuer&   r&   r'   r`    s    
zPosterior._getinjparc          	      s   d}j dk	rxzj D ]l\ }|     kryt fddj D }W q tk
rr   j  S  tk
r   dS X qW |S )zF
        Map parameter names to parameters in a SnglInspiral.
        Nc                s    g | ]}|j j  |fqS r&   )rF   rZ  )r;   trig)rm  r   r&   r'   r>     s    z)Posterior._gettrigpar.<locals>.<listcomp>)rU  rZ  r\  rB  r  dictr  AttributeError)r   r  valsr  r&   )rm  r   r'   ra    s    


zPosterior._gettrigparc             C   s   | j |  S )za
        Container method . Returns posterior chain,one_d_pos, with name one_d_pos.name.
        )rS  rB  )r   rm  r&   r&   r'   r     s    zPosterior.__getitem__c             C   s
   t | jS )zA
        Container method. Defined as number of samples.
        )r   rd  )r   r&   r&   r'   r     s    zPosterior.__len__c             C   s   |   S )zq
        Container method. Returns iterator from self.forward for use in
        for (...) in (...) etc.
        )forward)r   r&   r&   r'   __iter__  s    zPosterior.__iter__c             c   sF   d}x<|| j k r@t| j | }| j| }|d7 }||fV  qW dS )zu
        Generate a forward iterator (in sense of list of names) over Posterior
        with name,one_d_pos.
        r   r	   N)dimr  rS  r  )r   current_itemr)   r  r&   r&   r'   r    s    
zPosterior.forwardc             c   sP   d}| j \}}x<|t| k rJt||ddf }t|||V  |d7 }qW dS )z
        Generate a forward iterator over the list of samples corresponding to
        the data stored within the Posterior instance. These are returned as
        ParameterSamples instances.
        r   Nr	   )r
  r   r   r,  PosteriorSample)r   r  Z	pos_arrayr  sample_arrayr&   r&   r'   bySample  s    
zPosterior.bySamplec             C   s   t | j S )z.
        Return number of parameters.
        )r   rS  r  )r   r&   r&   r'   r    s    zPosterior.dimc             C   s$   g }x| D ]\}}| | q
W |S )z1
        Return list of parameter names.
        )r/  )r   Z	nameslistrm  r  r&   r&   r'   r     s    zPosterior.namesc             C   s$   i }x| D ]\}}|j ||< q
W |S )z5
        Return dict {paramName:paramMean} .
        )r   )r   Z	meansdictr)   r  r&   r&   r'   means*  s    zPosterior.meansc             C   s$   i }x| D ]\}}|j ||< q
W |S )z7
        Return dict {paramName:paramMedian} .
        )r   )r   Zmediansdictr)   r  r&   r&   r'   medians4  s    zPosterior.mediansc             C   s$   i }x| D ]\}}|j ||< q
W |S )zB
        Return dict {paramName:paramStandardDeviation} .
        )r  )r   Zstdsdictr)   r  r&   r&   r'   stdevs>  s    zPosterior.stdevsc             C   s   | j S )zZ
        Return qualified string containing the 'name' of the Posterior instance.
        )rg  )r   r&   r&   r'   r)   H  s    zPosterior.namec             C   s   | j S )z_
        Return qualified string containing a 'description' of the Posterior instance.
        )rh  )r   r&   r&   r'   rj  O  s    zPosterior.descriptionc             C   s   || j |j< dS )zV
        Container method. Add a new OneDParameter to the Posterior instance.
        N)rS  r)   )r   Zone_d_posteriorr&   r&   r'   r/  V  s    zPosterior.appendc             C   s   | j |S )zY
        Container method.  Remove PosteriorOneDPDF from the Posterior instance.
        )rS  r  )r   rp  r&   r&   r'   r  ]  s    zPosterior.popc                s  ddl t|tr| }|j}|j}|r:||}nd}|rji }x&| D ] ||  | < qPW nd}||j}	t||	||d}
|
jj	dkrt
d|j  n
|
 n؇fdd|D }dd |D }dd |D }|d	d |D  }	t|trd|kr|| }nd}d|kr^i }x:|d  D ]$  fd
d|D }|| | < q4W nd}t||	||d}
|
 n
d|kr|| }ndd |D }d|krdd tt|D }xl|d  D ]D  fdd|D }|| }x"t|D ]\}}|||  < qW qW ndd tt|D }|	s:dS dd t||	||D }x6|D ].}|jj	dkrzt
d|j  n
| qXW dS )zB
        Append posteriors pos1,pos2,...=func(post_names)
        r   N)r   r   z+WARNING: No posterior calculated for %s ...c                s   g | ]}  | qS r&   )deepcopy)r;   	post_name)copyr   r&   r'   r>     s    z,Posterior.append_mapping.<locals>.<listcomp>c             S   s   g | ]
}|j qS r&   )r  )r;   postr&   r&   r'   r>     s    c             S   s   g | ]
}|j qS r&   )r  )r;   r  r&   r&   r'   r>     s    c             S   s   g | ]
}|j qS r&   )r
  )r;   r  r&   r&   r'   r>     s    c                s   g | ]}|  qS r&   r&   )r;   r   )IFOr&   r'   r>     s    c             S   s   g | ]}d qS )Nr&   )r;   r)   r&   r&   r'   r>     s    c             S   s   g | ]}i qS r&   r&   )r;   r   r&   r&   r'   r>     s    c                s   g | ]}|  qS r&   r&   )r;   r   )r  r&   r'   r>     s    c             S   s   g | ]}d qS )Nr&   )r;   r   r&   r&   r'   r>     s    r&   c             S   s$   g | ]\}}}}t ||||d qS ))r   r   )r   )r;   Znew_param_namesampr   	new_trigsr&   r&   r'   r>     s    )r  
isinstancer  r  r  r  r  r
  r   ndimrb  r)   r/  r   r   	enumerater]  )r   Znew_param_namesfuncZ
post_namesZold_postZold_injZ	old_trigsZnew_injr  r  Znew_postr  Z	old_postsZold_injsr   ZoldvalsZinjsZnewvalsr   ZnewvalZ	new_postsr&   )r  r  r   r'   r  c  sj    








 
zPosterior.append_mappingc             C   s*   d}x|D ]}|||  }q
W |t | S )zc
        Returns the average value of the 'post_name' column of the
        given samples.
        g        )r   )r   r
  r  apr  r&   r&   r'   _average_posterior  s    
zPosterior._average_posteriorr   c             C   s<   d}x*|D ]"}|t || | ||  7 }q
W |t| S )z
        Returns the average value of the posterior assuming that the
        'logl_name' column contains log(L) and the 'prior_name' column
        contains the prior (un-logged).
        g        )r   expr   )r   r
  Z	logl_nameZ
prior_nameZlog_biasr  r  r&   r&   r'   _average_posterior_like_prior  s    
"z'Posterior._average_posterior_like_priorc             C   s   t | jS )zy
        Returns a sensible bias factor for the evidence so that
        integrals are representable as doubles.
        )r   r   rd  )r   r&   r&   r'   _bias_factor  s    zPosterior._bias_factor@   c                s2  ddddddddd	d
ddddddddddg}  \} fdd|D fdd|D }t|}dkrdkr   t| fdd| S dkrdkrވ   t| fdd| S dkrt|fdd|S d kr&t|fd!d|S td"d#S )$zg
        Returns the log of the direct-integration evidence for the
        posterior samples.
        rl   rm   rT   rV   rW   rU   rX   rY   r   r   r   r   r   r   r   r   rK   rJ   rI   rM   c                s   g | ]}| kr|qS r&   r&   )r;   r)   )r  r&   r'   r>     s    z)Posterior.di_evidence.<locals>.<listcomp>c                s   g | ]}t | qS r&   )r  )r;   row)coord_namesr  r&   r'   r>     s    r   r5   c                s    | dd S )Nr5   r   )r  )r  )bfr   r&   r'   rC    rD  z'Posterior.di_evidence.<locals>.<lambda>r=  c                s    | dd S )Nr=  r   )r  )r  )r  r   r&   r'   rC    rD  r  c                s     | dS )Nr  )r  )r  )r   r&   r'   rC    rD  r)  c                s     | dS )Nr)  )r  )r  )r   r&   r'   rC    rD  zcould not find 'post', 'posterior', 'logl' and 'prior', or 'likelihood' and 'prior' columns in output to compute direct integration evidenceN)r
  r  KDTreer  r   rR  r   re  )r   boxingallowed_coord_namesr
  coordinatized_samplestreer&   )r  r  r  r   r'   di_evidence  s&      

zPosterior.di_evidencec                s  ddddddddd	d
ddddddddddg}|   \} td|jd  }|dks^tfdd|D  t| jdddf }||| d ddf }t fdd|D }tj	|dd}tj
|dd}d}xD|D ]<}	t|	| tj||	| }
|dkr|
}qt||
}qW g }g }xft|| jD ]V\}}t|  }t|| tj||| }
|
|kr8|| || q8W t|d| krtd|  t|}t|}t }tj|d   ||d    t|d  d  ttj| }yXd!}t	|dd|f }t|dd|f }|| d"krXtd# || }W n tk
r|   |}Y nX t	|}|| }t|tt	d"t|  | S )$aN  Returns an approximation to the log(evidence) obtained by
        fitting an ellipse around the highest-posterior samples and
        performing the harmonic mean approximation within the ellipse.
        Because the ellipse should be well-sampled, this provides a
        better approximation to the evidence than the full-domain HM.rl   rm   rT   rV   rW   rU   rX   rY   r   r   r   r   r   r   r   r   rK   rJ   rI   rM   g?r   r	   c                s   g | ]}| kr|qS r&   r&   )r;   r)   )r  r&   r'   r>     s    z;Posterior.elliptical_subregion_evidence.<locals>.<listcomp>Nc                s   g | ]}t |  qS r&   )r  coord)r;   sample)r  r  r&   r'   r>     s    )axis)Zrowvarr   zLWARNING: ellpise evidence region encloses significantly more samples than %dg       @r   g      ?zCWARNING: prior variation greater than 100\% over elliptical volume.)r
  r  r.  r_  
IndexErrorr   argsortrd  r   r   covdotlinalgZsolver  r]  r  r  r/  r   rb  r   r   gammar   Zdetr*   Zstdr   rR  r  )r   r  r
  nZindexesZ
my_samplesmur  Zd0ZmysampledZellipse_loglZellipse_samplesr  r5   r  r  Zellipse_volumeZprior_indexZpmuZpstdZapprox_prior_integralZll_biasr&   )r  r  r'   elliptical_subregion_evidence  s\    





>


z'Posterior.elliptical_subregion_evidencec             C   s0   |   }|tdtdt| j|    S )zi
        Returns the log of the harmonic mean evidence for the set of
        posterior samples.
        r	   )r  r   rR  r   r  rd  )r   r  r&   r&   r'   harmonic_mean_evidence'  s    z Posterior.harmonic_mean_evidencec             C   sH   | j }d}|d }x,tt|D ]}|| |kr || }|}q W ||fS )z
        Find the sample with maximum likelihood probability. Returns value
        of likelihood and index of sample .
        r   )rd  r   r   )r   	logl_valsmax_imax_loglrE   r&   r&   r'   _posMaxL/  s    zPosterior._posMaxLc             C   sv   | j }| jdk	r| j}ndS d}|d |d  }x<tt|D ],}|| ||  |kr>|| ||  }|}q>W ||fS )z
        Find the sample with maximum a posteriori probability. Returns value
        of posterior and index of sample .
        Nr   )rd  rf  r   r   )r   r  Z	logp_valsr  max_posrE   r&   r&   r'   _posMap=  s    
zPosterior._posMapc             C   s.   d| }x|D ]}|d| 7 }qW |d7 }|S )z^
        Print a html table row representation of

        name:item1,item2,item3,...
        z<tr><td>%s</td>z<td>%s</td>z</tr>r&   )r   r)   entriesZrow_strentryr&   r&   r'   _print_table_rowP  s
    
zPosterior._print_table_rowc             C   s@   i }|   \}}x&| jD ]}| j| j| d ||< qW ||fS )zl
        Return the maximum likelihood probability and the corresponding
        set of parameters.
        r   )r	  r  rS  r
  )r   ZmaxLvalsr  r  rp  r&   r&   r'   maxL]  s
    zPosterior.maxLc             C   s@   i }|   \}}x&| jD ]}| j| j| d ||< qW ||fS )zn
        Return the maximum a posteriori probability and the corresponding
        set of parameters.
        r   )r  r  rS  r
  )r   ZmaxPvalsr
  r  rp  r&   r&   r'   maxPj  s
    zPosterior.maxPc             C   sR   d}g }x2| D ]*\}}t |j}||d 7 }|| qW t|}t ||fS )zj
        Return an (M,N) numpy.array of posterior samples; M = len(self);
        N = dim(self) .
        r  	)r   r   r
  r/  tuplecolumn_stack)r   header_stringposterior_tablerp  Zone_poscolumnr&   r&   r'   r
  x  s    zPosterior.samplesc             C   s$   |   \}}tj||dd|d dS )zL
        Dump the posterior table to a file in the 'common format'.
        r  r  )comments	delimiterr  N)r
  r   r  )r   fnamer  r  r&   r&   r'   write_to_file  s    zPosterior.write_to_filec                s   ddl m} |dd d| jkrt| d j}| jd | j||  \} fdd|D }t|}dd |D }d	d |D }t|}	t	|}
|
|	 }t
|}||	|  }y||
 }W n   td
|  tj}Y nX |S tddS )a  
        Returns an approximation to the Gelman-Rubin statistic (see
        Gelman, A. and Rubin, D. B., Statistical Science, Vol 7,
        No. 4, pp. 457--511 (1992)) for the parameter given, accurate
        as the number of samples in each chain goes to infinity.  The
        posterior samples must have a column named 'chain' so that the
        different chains can be separated.
        r   )r  raise)r  r  c                s(   g | ] }d d  f |kf qS )Nr&   )r;   r  )chain_indexdataparam_indexr&   r'   r>     s    z*Posterior.gelman_rubin.<locals>.<listcomp>c             S   s   g | ]}t |qS r&   )r   r   )r;   r  r&   r&   r'   r>     s    c             S   s   g | ]}t |qS r&   )r   r   )r;   r  r&   r&   r'   r>     s    zSError when computer Gelman-Rubin R statistic for %s.  This may be a fixed parameterzCcould not find necessary column header "chain" in posterior samplesN)r  r  r  r   r  r
  r*   concatenater   r   r   rb  nanre  )r   Zpnamer  chainsr  	chainDataZallDataZ
chainMeansZ	chainVarsZBoverNWZ	sigmaHat2r   ZVHatRr&   )r  r  r  r'   gelman_rubin  s.    	




zPosterior.gelman_rubinTc             C   s   d}x&t j|dd|d d kr*|d9 }qW | d j }| d j }|}tjd | }t j|||dd	}t|}	|	jd
 t 	|k rt
|	tt 	||	jd
  f}	t jj|	|tj d d}
|
t|
t j|dd  }
|rt j|
dd}
|
S )zReturns a healpix map in the pixel ordering that represents the
        posterior density (per square degree) on the sky.  The pixels
        will be chosen to have at least the given resolution (in
        degrees).

        rB   T)arcming      N@g       @r   r   F)nestr   g     f@)sigma)degrees)Zr2n)hpZnside2resolr
  r,  r   r   ang2pixZbincountr_  Z
nside2npixr  zerosZsphtfuncZ	smoothingsumnside2pixareaZreorder)r   Zresolr'  nsideZrasZdecsZphisZthetasZindscountshpmapr&   r&   r'   healpix_map  s     	
$zPosterior.healpix_mapc          
   C   s  d}dddddddg}g }| j d	k	rPd
d | j D }x|D ]}||d  q:W x|D ]}|d| 7 }qVW |d7 }x| D ]\}}|  \}}	|j|	 d }
|  \}}|j| d }t|j}t|j}tt	|j
}t|j}t|j}|j}||
|||||g}| j d	k	rXxF|D ]>}y|t||  W n  tk
rP   |d	 Y nX qW || ||7 }qxW |d7 }t }|| | }|}t|d}t|}|jdd}|tdd d	 S )z
        Define a string representation of the Posterior class ; returns
        a html formatted table of various properties of posteriors.
        z+<table border="1" id="statstable"><tr><th/>maPr  r  r   r   r  zinjection valueNc             S   s   g | ]
}|j qS r&   )rF   )r;   r  r&   r&   r'   r>     s    z%Posterior.__str__.<locals>.<listcomp>z trigger valuesz<th>%s</th>z</tr>r   z</table>zutf-8z  )indentz<?xml version="1.0" ?>r	   )rU  r/  r	  r
  r  r  r   r  r   r,  r   r  r  r  r  r  r   feedr  r   r   parseStringtoprettyxmlr   )r   
return_valZcolumn_namesIFOsr  Zcolumn_namer)   Zoned_posr  r  r  Zmax_postZmax_jr3  r   r  r   r  r  r  r  parserEstrelemrough_stringreparsedr&   r&   r'   __str__  sL    










zPosterior.__str__c             C   s   t |j|j\}}|S )a  
        Return the mapping of (mchirp,eta)->m1; m1>m2 i.e. return the greater of the mass
        components (m1) calculated from the chirp mass and the symmetric mass ratio.

        @param inj: a custom type with the attributes 'mchirp' and 'eta'.
        )rc  rJ   rL   )r   r   r   r   r&   r&   r'   _inj_m1  s    zPosterior._inj_m1c             C   s   t |j|j\}}|S )a  
        Return the mapping of (mchirp,eta)->m2; m1>m2 i.e. return the lesser of the mass
        components (m2) calculated from the chirp mass and the symmetric mass ratio.

        @param inj: a custom type with the attributes 'mchirp' and 'eta'.
        )rc  rJ   rL   )r   r   r   r   r&   r&   r'   _inj_m2  s    zPosterior._inj_m2c             C   s   t |j|j\}}|| S )z
        Return the mapping of (mchirp,eta)->q; m1>m2 i.e. return the mass ratio q=m2/m1.

        @param inj: a custom type with the attributes 'mchirp' and 'eta'.
        )rc  rJ   rL   )r   r   r   r   r&   r&   r'   rX  %  s    zPosterior._inj_qc             C   sp   |j dt ks|j dk rfdt t|j dt  tt|j dt    }tdt|j t|f  |S |j S dS )z
        Return the mapping of longitude found in inj to the interval [0,2*pi).

        @param inj: a custom type with the attribute 'longitude'.
        rB   g        zWarning: Injected longitude/ra (%s) is not within [0,2\pi)! Angles are assumed to be in radians so this will be mapped to [0,2\pi). Mapped value is: %s.N)r   pi_constantr0  r   rb  r  )r   r   maplongr&   r&   r'   rY  .  s
    0zPosterior._inj_longitudec       (      C   s   ddl m} i }| j}|s"i }nt|}|j}|j}|j}	|j}
|j	}|j
}|j}|j|j }}|j|j }}t|||	\}}}t|
||\}}}|||||||d}|j|j  kr|j  kr|j	  krdkrn n|j|d< |j
|d< t||||}t|||	f}t|
||f}tdddg}t||}t||}|| tdd|  ||   }||d	 9 }||d	 9 }|| | }t||} | |d
< ||d< |dkstd |S ||j|j|j|j|j|j	|j
||||j\}!}"}#}$}%}&}'|!|d< |%|d< |#|d< |$|d< |"|d< |S )Nr   )$SimInspiralTransformPrecessingWvf2PE)rT   rW   rV   rU   rY   rX   r   g        rn   ro   g      ?g      @rB   r   Zspinchir:  z_I cannot calculate the injected values of the spin angles unless frame is OrbitalL. Skipping...rc   rd   r^   r`   rb   )lalsimulationrD  rG  lalsimZ!SimInspiralGetFrameAxisFromStringr  r  r  r  r  r  r   r   r   rJ   rL   cart2sphorbital_momentumr   r  r   	array_dotr   array_ang_seprb  rE  )(r   r   rQ  rD  Zspinsr   r  s1xs1ys1zs2xs2ys2zr   rG   rH   rK   rL   rT   rW   rV   rU   rY   rX   rJ  S1S2ZzhatZaligned_comp_spin1Zaligned_comp_spin2rp   Jr   rc   rb   r^   r`   rd   r  r  r&   r&   r'   r[  ;  s^    
4





:zPosterior._inj_spins)Nr:  r;  NNN)r   )r  )T)r:  )7r4  r5  r6  r7  r   r  r  r  r  r8  r  r  r  r  r  r  r  r`  ra  r   r   r  r  r  r  r  r  r  r  r)   rj  r/  r  r  r  r  r  r  r  r  r	  r  r  r  r  r
  r  r%  r2  r?  r@  rA  rX  rY  r[  r&   r&   r&   r'   r9  Q  sj   
v  u

		




I


D#
#8

	r9  c               @   s"   e Zd ZdZdddZdd ZdS )BurstPosteriorz;
    Data structure for a table of posterior samples .
    Nc                sb  |\}}i  _ | _| _| _dddddg _dddd	d
dg _dd |D }dd dd dd dd dd dd dd dd dd dd dd dd dd dd  j j j jdd dd dd d d d!d  fd"dd#d d$d d%d d&d d'd d(d d) _xPtt	
||jd* |D ]4\}	}
t|
 |	 |
 j |
d+ j |
< q"W d,}xX jD ]N}||krfy j | j _W n& tk
r   td-|  wfY nX d.}qfW |std/d0 _xp jD ]f}||kry j | j _W n& tk
r   td-|  wY nX d1|krd2d  jD  _qW |d0k	rN| _|d0k	r^| _d0S )3a%  
        Constructor.

        @param commonResultsFormatData: A 2D array containing the posterior
            samples and related data. The samples chains form the columns.
        @param SimBurstTableEntry: A glue.ligolw.lscstables.SimBurst row containing the injected values.
        @param SnglBurstList: A list of SnglBurst objects containing the triggers.
        @param injFref: reference frequency in injection
        @param name: optional name for this Posterior
        @param description: optional description for this Posterior
        r)  r5   r<  r=  r6   r>  r?  r   r8   r@  rA  c             S   s   g | ]}|  qS r&   )rB  )r;   rE   r&   r&   r'   r>     s    z+BurstPosterior.__init__.<locals>.<listcomp>c             S   s   | j S )N)	frequency)r   r&   r&   r'   rC    rD  z)BurstPosterior.__init__.<locals>.<lambda>c             S   s   | j S )N)rU  )r   r&   r&   r'   rC    rD  c             S   s   | j S )N)rU  )r   r&   r&   r'   rC    rD  c             S   s   | j S )N)rM   )r   r&   r&   r'   rC    rD  c             S   s   | j S )N)hrss)r   r&   r&   r'   rC    rD  c             S   s
   t | jS )N)rR  rV  )r   r&   r&   r'   rC    rD  c             S   s   | j S )N)pol_ellipse_angle)r   r&   r&   r'   rC    rD  c             S   s   | j S )N)rW  )r   r&   r&   r'   rC    rD  c             S   s   | j S )N)pol_ellipse_e)r   r&   r&   r'   rC    rD  c             S   s   | j S )N)rW  )r   r&   r&   r'   rC    rD  c             S   s   | j S )N)rX  )r   r&   r&   r'   rC    rD  c             S   s   | j S )N)rX  )r   r&   r&   r'   rC    rD  c             S   s   t t| S )N)r0  r(   )r   r&   r&   r'   rC    rD  c             S   s   t t| S )N)r0  r(   )r   r&   r&   r'   rC    rD  c             S   s   | j S )N)r   )r   r&   r&   r'   rC    rD  c             S   s   | j S )N)r   )r   r&   r&   r'   rC    rD  c             S   s   | j S )N)r   )r   r&   r&   r'   rC    rD  c             S   s   | j S )N)r   )r   r&   r&   r'   rC    rD  c             S   s   t | jt jS )N)r   rF  r   r   )r   r&   r&   r'   rC    rD  c                s    j S )N)rG  )r   )r   r&   r'   rC    rD  c             S   s   | j S )N)r   )r   r&   r&   r'   rC    rD  c             S   s   | j S )N)r   )r   r&   r&   r'   rC    rD  c             S   s   | j S )N)duration)r   r&   r&   r'   rC    rD  c             S   s
   t d| S )NrH  )get_end_time)r   r&   r&   r'   rC    rD  c             S   s
   t d| S )NrJ  )rZ  )r   r&   r&   r'   rC    rD  c             S   s
   t d| S )NrK  )rZ  )r   r&   r&   r'   rC    rD  )f0rU  Zcentre_frequencyqualityrV  loghrssr   rW  rX  r   r   Zeccentricityr   rM  r   r   rN  r   r   r   rO  r   r   r   r   r   rY  r   r   r   r	   )r   r   r   FzNo '%s' column in input table!Tz%No likelihood/posterior values found!NrR  c             S   s   g | ]}t |qS r&   )r   rR  )r;   rE   r&   r&   r'   r>     s    )rS  rG  rT  rU  rV  rW  rY  rZ  r]  r   r^  r_  r   rB  r`  ra  r
  rd  r   rb  re  rf  Z_BurstPosterior__nameZ_BurstPosterior__description)r   ri  ZSimBurstTableEntryr   ZSnglBurstListr)   rj  rk  rl  ro  rp  rq  rr  rs  r&   )r   r'   r     s    
"0







zBurstPosterior.__init__c             C   sp   |j dt ks|j dk rfdt t|j dt  tt|j dt    }tdt|j t|f  |S |j S dS )z
        Return the mapping of longitude found in inj to the interval [0,2*pi).

        @param inj: a custom type with the attribute 'longitude'.
        rB   g        zWarning: Injected longitude/ra (%s) is not within [0,2\pi)! Angles are assumed to be in radians so this will be mapped to [0,2\pi). Mapped value is: %s.N)r   rB  r0  r   rb  r  )r   r   rC  r&   r&   r'   rY    s
    0zBurstPosterior._inj_longitude)NNNNN)r4  r5  r6  r7  r   rY  r&   r&   r&   r'   rT    s   
_rT  c               @   s|   e Zd ZdZ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d Zdd Zdd ZdddZdddZdS ) r  z
    A kD-tree.
    c                s  t |dkrtdnjt |dkrN|dd | _| jd  }||f| _n4| |r|d g| _| jd  }||f| _n|dd | _|  | _| j\}}|  | _| jt	| jfddd}t |}d|t
|d	    |t
|d	 d        fd
d| jD } fdd| jD }t |dkrn fdd| jD } fdd| jD }t|| _t|| _dS )z
        Construct a kD-tree from a sequence of objects.  Each object
        should return its coordinates using obj.coord().
        r   zZcannot construct kD-tree out of zero objects---you may have a repeated sample in your listr	   Nc                s   |     S )N)r  )obj)longest_dimr&   r'   rC  	  rD  z!KDTree.__init__.<locals>.<lambda>)rm  g      ?rB   c                s    g | ]}|    k r|qS r&   )r  )r;   r^  )boundr_  r&   r'   r>   	  s    z#KDTree.__init__.<locals>.<listcomp>c                s    g | ]}|    kr|qS r&   )r  )r;   r^  )r`  r_  r&   r'   r>   	  s    c                s    g | ]}|    kr|qS r&   )r  )r;   r^  )r`  r_  r&   r'   r>   	  s    c                s    g | ]}|    kr|qS r&   )r  )r;   r^  )r`  r_  r&   r'   r>   	  s    )r   re  _objectsr  _bounds_same_coords_bounds_of_objects_longest_dimension
_split_dimsortedr.  r  _left_right)r   objectsr  lowhighsorted_objectsr2  r&   )r`  r_  r'   r     s2    



8
zKDTree.__init__c             C   sR   t |dkrdS dd |D }|d }x&|dd D ]}t||ks4dS q4W dS )z^
        True if and only if all the given objects have the same
        coordinates.
        r	   Tc             S   s   g | ]}|  qS r&   )r  )r;   r^  r&   r&   r'   r>   $	  s    z'KDTree._same_coords.<locals>.<listcomp>r   NF)r   r   r  )r   rj  coordsc0cir&   r&   r'   rc  	  s    zKDTree._same_coordsc             C   s\   | j d  }| j d  }x6| j dd D ]$}t|| }t|| }q,W ||fS )z>
        Bounds of the objects contained in the tree.
        r   r	   N)ra  r  r   minimummaximum)r   rk  rl  r^  r&   r&   r'   rd  +	  s    zKDTree._bounds_of_objectsc             C   s   | j \}}|| }t|S )z7
        Longest dimension of the tree bounds.
        )rb  r   argmax)r   rk  rl  widthsr&   r&   r'   re  6	  s    
zKDTree._longest_dimensionc             C   s   | j dd S )z2
        Returns the objects in the tree.
        N)ra  )r   r&   r&   r'   rj  >	  s    zKDTree.objectsc             C   s
   | j  S )zF
        Iterator over all the objects contained in the tree.
        )ra  r  )r   r&   r&   r'   r  D	  s    zKDTree.__iter__c             C   s   | j S )z(
        Returns the left tree.
        )rh  )r   r&   r&   r'   leftJ	  s    zKDTree.leftc             C   s   | j S )z)
        Returns the right tree.
        )ri  )r   r&   r&   r'   rightP	  s    zKDTree.rightc             C   s   | j S )z]
        Returns the dimension along which this level of the kD-tree
        splits.
        )rf  )r   r&   r&   r'   	split_dimV	  s    zKDTree.split_dimc             C   s   | j S )z
        Returns the coordinates of the lower-left and upper-right
        corners of the bounding box for this tree: low_left, up_right
        )rb  )r   r&   r&   r'   bounds]	  s    zKDTree.boundsc             C   s6   d}| j \}}x"t||D ]\}}|||  }qW |S )zE
        Returns the volume of the bounding box of the tree.
        g      ?)rb  r]  )r   vrk  rl  lhr&   r&   r'   volumed	  s
    
zKDTree.volumer  c                s$    fdd}dd }| j |||dS )z
        Returns the integral of f(objects) over the tree.  The
        optional boxing parameter determines how deep to descend into
        the tree before computing f.
        c                s   |    | j S )N)r|  ra  )r  )fr&   r'   r   y	  s    zKDTree.integrate.<locals>.xc             S   s   | | S )Nr&   )r<   r=   r&   r&   r'   r   |	  s    zKDTree.integrate.<locals>.y)r  )operate)r   r}  r  r   r   r&   )r}  r'   r   n	  s    zKDTree.integratec             C   s<   t | j|kr|| S || j|||| j|||S dS )zJ
        Operates on tree nodes exceeding boxing parameter depth.
        N)r   ra  rh  r~  ri  )r   r}  r   r  r&   r&   r'   r~  	  s    zKDTree.operateN)r  )r  )r4  r5  r6  r7  r   rc  rd  re  rj  r  ru  rv  rw  rx  r|  r   r~  r&   r&   r&   r'   r    s   #

r  c               @   s   e Zd ZdZd 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d Zd!ddZd"ddZd#ddZd$ddZdS )%KDTreeVolumea  
    A kD-tree suitable for splitting parameter spaces and counting hypervolumes.
    Is modified from the KDTree class so that bounding boxes are stored. This means that
    there are no longer gaps in the hypervolume once the samples have been split into groups.
    r   c                s  || _ || _d| _t|dkr*tdnt|dkrH|dd | _n| |rzt|| _|d g| _| jd  }n|dd | _| j t| jfddd}t|}d|t	|d	    |t	|d	 d      | _
| j
  fd
d| jD } fdd| jD }t|dkrR fdd| jD } fdd| jD }g }	g }
x,| jD ]"}|	t| |
t| qbW  |	d <  |
d < t| jd  d k rƈd }nd}t||	|d| _t|dkrt||
|d| _nd| _dS )a.  
        Construct a kD-tree from a sequence of objects.  Each object
        should return its coordinates using obj.coord().
        the obj should also store the bounds of the hypervolume its found in.
        for non-leaf objects we need the name of the dimension split and value at split.
        r	   r   zZcannot construct kD-tree out of zero objects---you may have a repeated sample in your listNc                s   |     S )N)r  )r^  )rw  r&   r'   rC  	  rD  z'KDTreeVolume.__init__.<locals>.<lambda>)rm  g      ?rB   c                s    g | ]}|    k r|qS r&   )r  )r;   r^  )r`  rw  r&   r'   r>   	  s    z)KDTreeVolume.__init__.<locals>.<listcomp>c                s    g | ]}|    kr|qS r&   )r  )r;   r^  )r`  rw  r&   r'   r>   	  s    c                s    g | ]}|    kr|qS r&   )r  )r;   r^  )r`  rw  r&   r'   r>   	  s    c                s    g | ]}|    kr|qS r&   )r  )r;   r^  )r`  rw  r&   r'   r>   	  s    )dims)
_dimensionrb  _weightr   re  ra  rc  r  rg  r.  _split_valuer/  r  r  rh  ri  )r   rj  Zboundingboxr  r  rm  r2  rk  rl  ZleftBoundingboxZrightBoundingboxrE   Z	child_dimr&   )r`  rw  r'   r   	  sH    

:
zKDTreeVolume.__init__c             C   sR   t |dkrdS dd |D }|d }x&|dd D ]}t||ks4dS q4W dS )z^
        True if and only if all the given objects have the same
        coordinates.
        r	   Tc             S   s   g | ]}|  qS r&   )r  )r;   r^  r&   r&   r'   r>   	  s    z-KDTreeVolume._same_coords.<locals>.<listcomp>r   NF)r   r   r  )r   rj  rn  ro  rp  r&   r&   r'   rc  	  s    zKDTreeVolume._same_coordsc             C   s   | j dd S )z2
        Returns the objects in the tree.
        N)ra  )r   r&   r&   r'   rj  	  s    zKDTreeVolume.objectsc             C   s
   | j  S )zF
        Iterator over all the objects contained in the tree.
        )ra  r  )r   r&   r&   r'   r  	  s    zKDTreeVolume.__iter__c             C   s   | j S )z(
        Returns the left tree.
        )rh  )r   r&   r&   r'   ru  	  s    zKDTreeVolume.leftc             C   s   | j S )z)
        Returns the right tree.
        )ri  )r   r&   r&   r'   rv  	  s    zKDTreeVolume.rightc             C   s   | j S )z]
        Returns the dimension along which this level of the kD-tree
        splits.
        )rf  )r   r&   r&   r'   rw  	  s    zKDTreeVolume.split_dimc             C   s   | j S )z
        Returns the coordinates of the lower-left and upper-right
        corners of the bounding box for this tree: low_left, up_right
        )rb  )r   r&   r&   r'   rx  	  s    zKDTreeVolume.boundsc             C   s6   d}| j \}}x"t||D ]\}}|||  }qW |S )zE
        Returns the volume of the bounding box of the tree.
        g      ?)rb  r]  )r   ry  rk  rl  rz  r{  r&   r&   r'   r|  	  s
    
zKDTreeVolume.volumer  c                s$    fdd}dd }| j |||dS )z
        Returns the integral of f(objects) over the tree.  The
        optional boxing parameter determines how deep to descend into
        the tree before computing f.
        c                s   |    | j S )N)r|  ra  )r  )r}  r&   r'   r   
  s    z!KDTreeVolume.integrate.<locals>.xc             S   s   | | S )Nr&   )r<   r=   r&   r&   r'   r   
  s    z!KDTreeVolume.integrate.<locals>.y)r  )r~  )r   r}  r  r   r   r&   )r}  r'   r   
  s    zKDTreeVolume.integratec             C   s<   t | j|kr|| S || j|||| j|||S dS )zJ
        Operates on tree nodes exceeding boxing parameter depth.
        N)r   ra  rh  r~  ri  )r   r}  r   r  r&   r&   r'   r~  
  s    zKDTreeVolume.operatec             C   sR   t | j|kr"| jt | j| jfS || j | jk r@| j||S | j||S dS )z
        takes a set of coordinates and searches down through the tree untill it gets
        to a box with less than 'boxing' objects in it and returns the box bounds,
        number of objects in the box, and the weighting.
        N)	r   ra  rb  r  r  r  rh  searchri  )r   coordinatesr  r&   r&   r'   r  
  s
    zKDTreeVolume.searchFc             C   s   |}t | j|kr^t|  ddd}|rD|t | jt|   n|t | j|   |S |rt| j| jj|dd| j	j|ddd}|t | jt|   n6t| j| j|| j	|d}|t | j|   |
| j| j |S dS )zN
        copies tree structure, but with KDSkeleton as the new nodes.
        N)
left_childright_childT)isArea)r   ra  
KDSkeletonrx  setImportanceskyArear|  rh  fillNewTreeri  setSplitr  r  )r   r  r  ZboxNZnewNoder&   r&   r'   r  )
  s    ( zKDTreeVolume.fillNewTreeN)r   )r  )r  )r  )r  F)r4  r5  r6  r7  r   rc  rj  r  ru  rv  rw  rx  r|  r   r~  r  r  r&   r&   r&   r'   r  	  s   
5


	
r  c               @   sB   e Zd ZdZdddZdd Zdd Zd	d
 Zdd Zdd Z	dS )r  z4
    object to store the structure of a kd tree
    Nc             C   s4   || _ || _|| _d| _d | _d | _d | _d | _d S )Nr   )rb  rh  ri  _samples_splitValue	_splitDim_importance_volume)r   Zbounding_boxr  r  r&   r&   r'   r   D
  s    zKDSkeleton.__init__c             C   s   |  j d7  _ d S )Nr	   )r  )r   r&   r&   r'   	addSampleO
  s    zKDSkeleton.addSamplec             C   s   | j S )N)rb  )r   r&   r&   r'   rx  R
  s    zKDSkeleton.boundsc             C   sF   | j dkr| j| j| jfS || j | jk r6| j |S | j|S dS )z
        takes a set of coordinates and searches down through the tree untill it gets
        to a box with less than 'boxing' objects in it and returns the box bounds,
        number of objects in the box, and the weighting.
        N)rh  rb  r  r  r  r  r  ri  )r   r  r&   r&   r'   r  U
  s
    
zKDSkeleton.searchc             C   s   || | _ || _d S )N)r  r  )r   ZsampleNumberr|  r&   r&   r'   r  b
  s    
zKDSkeleton.setImportancec             C   s   || _ || _d S )N)r  r  )r   	dimensionr  r&   r&   r'   r  f
  s    zKDSkeleton.setSplit)NN)
r4  r5  r6  r7  r   r  rx  r  r  r  r&   r&   r&   r'   r  ?
  s   
r  c               @   s(   e Zd ZdZdd Zdd Zdd ZdS )	r  zT
    A single parameter sample object, suitable for inclusion in a
    kD-tree.
    c                sj   |dd  _ | _t|t jksLtdt j tdt| td| _ fdd|D  _dS )z
        Given the sample array, headers for the values, and the names
        of the desired coordinates, construct a parameter sample
        object.
        NzHeader length = zSample length = z)parameter and sample lengths do not agreec                s   g | ]} j |qS r&   )_headersr*   )r;   r)   )r   r&   r'   r>   ~
  s    z,PosteriorSample.__init__.<locals>.<listcomp>)r  r  r   rb  re  Z_coord_names_coord_indexes)r   r  headersr  r&   )r   r'   r   q
  s    zPosteriorSample.__init__c             C   s8   |  }|| jkr(| j|}| j| S td| dS )zA
        Return the element with the corresponding name.
        z%key not found in posterior sample: %sN)rB  r  r*   r  r   )r   rm  r   r&   r&   r'   r   
  s
    

zPosteriorSample.__getitem__c             C   s   | j | j S )zB
        Return the coordinates for the parameter sample.
        )r  r  )r   r&   r&   r'   r  
  s    zPosteriorSample.coordN)r4  r5  r6  r7  r   r   r  r&   r&   r&   r'   r  k
  s   r  c               @   s4   e Zd ZdZdd Zdd Zdd Zedd	 Zd
S )AnalyticLikelihoodz,
    Return analytic likelihood values.
    c          	      s  t |tr|g}t |tr |g}dd |D }t|}|t|krJtdt|d  }dd |dD | _dd  g | _x>t	|D ]0}|| }|| }t| }d	d |dD }	t
|	t
| jkrtd
tt|	t| t	t|	}
tt|
 fdd|
D }tj|dd|d}yFx@|D ]8}tt|	|fdd|	D }| jt| q4W W q tk
r   tt|	|fdd|	D }| jt| Y qX qW t| j| _dS )zG
        Prepare analytic likelihood for the given parameters.
        c             S   s   g | ]}t j|d dqS ),)r  )r   loadtxt)r;   ZcsvFiler&   r&   r'   r>   
  s    z/AnalyticLikelihood.__init__.<locals>.<listcomp>z8Must give a mean vector list for every covariance matrixr   c             S   s   g | ]}|  qS r&   )r  )r;   r   r&   r&   r'   r>   
  s    r  c             S   s   t | ddt S )Nr   z%.32f)r(  r&  rB  )r   r&   r&   r'   rC  
  rD  z-AnalyticLikelihood.__init__.<locals>.<lambda>c             S   s   g | ]}|  qS r&   )r  )r;   r   r&   r&   r'   r>   
  s    z2Parameters do not agree between mean vector files.c                s   g | ]} qS r&   r&   )r;   rE   )	converterr&   r'   r>   
  s    r	   )r  Zskiprows
convertersc                s&   g | ]}|t j | | d fqS ))locscale)r   norm)r;   r   )r  sigmasr&   r'   r>   
  s    c                s&   g | ]}|t j | | d fqS ))r  r  )r   r  )r;   r   )r  r  r&   r'   r>   
  s    N)r  r  r   re  r  readliner  _params_modesr   r  r  r]  r   r   Zdiagonalr  r/  r  
_num_modes)r   Zcovariance_matrix_filesZmean_vector_filesZcovarianceMatricesZnum_matricesZ
param_linerE   ZCMZvecFileparamsZcolNumsr  ZmeanVectorsvecmoder&   )r  r  r  r'   r   
  sB    


zAnalyticLikelihood.__init__c                s    d} j kr fdd}|S )z4
        Return PDF function for parameter.
        Nc                s$   dj  t fddjD  S )Ng      ?c                s   g | ]}|   qS r&   )pdf)r;   r  )r   r   r&   r'   r>   
  s    z<AnalyticLikelihood.pdf.<locals>.<lambda>.<locals>.<listcomp>)r  r-  r  )r   )r   r   )r   r'   rC  
  rD  z(AnalyticLikelihood.pdf.<locals>.<lambda>)r  )r   r   r  r&   )r   r   r'   r  
  s    
zAnalyticLikelihood.pdfc                s    d} j kr fdd}|S )z4
        Return PDF function for parameter.
        Nc                s$   dj  t fddjD  S )Ng      ?c                s   g | ]}|   qS r&   )cdf)r;   r  )r   r   r&   r'   r>   
  s    z<AnalyticLikelihood.cdf.<locals>.<lambda>.<locals>.<listcomp>)r  r-  r  )r   )r   r   )r   r'   rC  
  rD  z(AnalyticLikelihood.cdf.<locals>.<lambda>)r  )r   r   r  r&   )r   r   r'   r  
  s    
zAnalyticLikelihood.cdfc             C   s   | j S )z[
        Return list of parameter names described by analytic likelihood function.
        )r  )r   r&   r&   r'   r  
  s    zAnalyticLikelihood.namesN)	r4  r5  r6  r7  r   r  r  r8  r  r&   r&   r&   r'   r  
  s
   -		r  c               @   s   e Zd ZdZd#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d Zdd Zdd Zdd Zd$ddZd%ddZd&dd Zd!d" ZdS )'	htmlChunkzG
    A base class for representing web content using ElementTree .
    Nc             C   sD   t || _|r0x | D ]\}}|| jj|< qW |r@|| j d S )N)r   _htmlr\  attribr/  )r   tagr  parentZ
attribnameZattribvaluer&   r&   r'   r   
  s    
zhtmlChunk.__init__c             C   s$   | j }t|}t|}|jddS )zE
        Return a pretty-printed XML string of the htmlPage.
        z  )r4  )r  r   r   r6  r7  )r   r<  r=  r>  r&   r&   r'   r7  
  s    
zhtmlChunk.toprettyxmlc             C   s   |   S )N)r7  )r   r&   r&   r'   r?  
  s    zhtmlChunk.__str__c             C   s(   t  }|| | }| j| d S )N)r   r5  r  r  r/  )r   stringr:  r;  r&   r&   r'   write
  s    
zhtmlChunk.writec             C   s   t d}||_| j| |S )Np)r   textr  r/  )r   ZpstringEpr&   r&   r'   r    s    zhtmlChunk.pc             C   s   t d}||_| j| |S )Nr?   )r   r  r  r/  )r   h1stringr  r&   r&   r'   r?     s    zhtmlChunk.h1c             C   s   t d}||_| j| |S )Nh5)r   r  r  r/  )r   r  r  r&   r&   r'   r    s    zhtmlChunk.h5c             C   s   t d}||_| j| |S )Nh2)r   r  r  r/  )r   Zh2stringr  r&   r&   r'   r    s    zhtmlChunk.h2c             C   s   t d}||_| j| |S )Nh3)r   r  r  r/  )r   r  r  r&   r&   r'   r    s    zhtmlChunk.h3c             C   s   t d}| j| |S )Nbr)r   r  r/  )r   ZEbrr&   r&   r'   r  #  s    zhtmlChunk.brc             C   s   t d}| j| |S )Nhr)r   r  r/  )r   ZEhrr&   r&   r'   r  (  s    zhtmlChunk.hrc             C   s(   t d}||jd< ||_| j| |S )Nr<   href)r   r  r  r  r/  )r   urlZlinktextZEar&   r&   r'   r<   -  s
    
zhtmlChunk.ac             C   s.   i }|d k	rd|i}t d|}| j| |S )Nidr.   )r   r  r/  )r   ZidtableargsZEtabr&   r&   r'   tab4  s    
zhtmlChunk.tabc             C   s(   t d}|dk	r||jd< || |S )z_
        Insert row in table tab.
        If given, label used as id for the table tag
        trNr  )r   r  r/  )r   r  r   ZEtrr&   r&   r'   
insert_row=  s
    

zhtmlChunk.insert_rowc             C   s   t d}t|tkr||_n$t|}t|}|jdd}||_|dk	rR||jd< |dk	rv|	d| d|  |
  || |S )zQ
        Insert cell td into row row.
        Sets id to label, if given
        tdz  )r4  Nr  z#%sz%s)r   typer  r  r   r   r6  r7  r  r<   r  r/  )r   r  r  r   legendZEtdr&   r&   r'   	insert_tdJ  s    


zhtmlChunk.insert_tdc             C   s   | j | d S )N)r  r/  )r   elementr&   r&   r'   r/  a  s    zhtmlChunk.append)NN)N)N)NN)r4  r5  r6  r7  r   r7  r?  r  r  r?   r  r  r  r  r  r<   r  r  r  r/  r&   r&   r&   r'   r  
  s"   
		
	

r  c               @   sV   e Zd ZdZdddZdd Zddd	ZdddZdd Ze	dd Z
e	dd ZdS )htmlPagezX
    A concrete class for generating an XHTML(1) document. Inherits from htmlChunk.
    NFc             C   s   t j| dddid d| _t| jd| _t| jd}t| jd| _d | _d | _|d k	rvt	||_
t| jd	| _|| j_
|d k	rt| jd
| _d| jjd< t	|| j_
|d k	rt| jd| _d| jjd< t	|| j_
d S )Nhtmlxmlnszhttp://www.w3.org/1999/xhtml)r  zy<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">headtitlebodyr?   scriptztext/javascriptr  styleztext/css)r  r   doctype_strr   r  _head_bodyZ_cssZ_jscriptr  r  _titler  )r   r  css
javascriptZtocZEtitler&   r&   r'   r   j  s&    
zhtmlPage.__init__c             C   s   | j d |   S )N
)r  r7  )r   r&   r&   r'   r?    s    zhtmlPage.__str__c             C   s>   t |}| j|j |d k	r:|d| d|  |  |S )Nz#%sz%s)htmlSectionr  r/  r  r<   r  )r   section_namer  
newSectionr&   r&   r'   add_section  s    zhtmlPage.add_sectionTc             C   sD   t |||d}| j|j |dk	r@|d| d|  |  |S )z\
        Create a section embedded into a table that can be collapsed with a button
        )table_idstart_closedNz#%sz%s)htmlCollapseSectionr  r/  r  r<   r  )r   r  r  innertable_idr  r  r&   r&   r'   add_collapse_section  s    zhtmlPage.add_collapse_sectionc             C   s   t ||dd}||j |S )zg
        Create a section which is not appended to the body of html, but to the parent Element
        T)htmlElementblank)r  r/  r  )r   r  r  r  r&   r&   r'   add_section_to_element  s    zhtmlPage.add_section_to_elementc               C   s   t jS )N)r   r  r&   r&   r&   r'   r    s    zhtmlPage.bodyc               C   s   t jS )N)r   r  r&   r&   r&   r'   r    s    zhtmlPage.head)NNNF)N)NNT)r4  r5  r6  r7  r   r?  r  r  r  r8  r  r  r&   r&   r&   r'   r  f  s   


	r  c               @   s   e Zd ZdZdddZdS )r  zX
    Represents a block of html fitting within a htmlPage. Inherits from htmlChunk.
    NFc             C   sD   |st j| dd|d|d nt j| dd|d|d | | d S )Ndiv	ppsection)classr  )r  r  z"color:#000000")r  r  )r  r   r  )r   r  r  r  r&   r&   r'   r     s    zhtmlSection.__init__)NF)r4  r5  r6  r7  r   r&   r&   r&   r'   r    s   r  c               @   s"   e Zd ZdZdddZdd ZdS )	r  zX
    Represents a block of html fitting within a htmlPage. Inherits from htmlChunk.
    NTc             C   s<   t j| dd|d|d |d kr,tdd}|| _|| _d S )Nr  r  )r  r  )r  r  r	   i )r  r   r  randintr  _start_closed)r   r  r  r  r  r&   r&   r'   r     s
    zhtmlCollapseSection.__init__c             C   s   t dd}| jr:d| jjd || j|f }|dd}n&d| jjd || j|f }|dd}||7 }|d	7 }t| | d S )
Nr	   i a  <table border="0" align="center" cellpadding="5" cellspacing="0"><tr bgcolor="#4682B4" height="50"><td width="5%%"><font size="4" face="tahoma" color="white"><a href="#"> Top</a></font></td><td width="45%%"><font size="4" face="tahoma" color="white"><strong>%s</strong></font></td><td bgcolor="#4682B4" align="center" width="50%%"><input id="lnk%s" type="button" value="[+] Expand" onclick="toggle_visibility('%s','lnk%s');"></input></td></tr><tr><td colspan="7">r  ztable ztable style="display: none" a  <table border="0" align="center" cellpadding="5" cellspacing="0"><tr bgcolor="#4682B4" height="50"><td width="5%%"><font size="4" face="tahoma" color="white"><a href="#"> Top</a></font></td><td width="45%%"><font size="4" face="tahoma" color="white"><strong>%s</strong></font></td><td bgcolor="#4682B4" align="center" width="50%%"><input id="lnk%s" type="button" value="[-] Collapse" onclick="toggle_visibility('%s','lnk%s');"></input></td></tr><tr><td colspan="7">ztable style="display: table" z</td></tr></table>)	r  r  r  r  r  r  r&  r  r  )r   r  kstr&   r&   r'   r    s    zhtmlCollapseSection.write)NNT)r4  r5  r6  r7  r   r  r&   r&   r&   r'   r    s   
r  c       	      C   s   t | ddd }g }d}d}x^|D ]V}|t| | t| 7 }|||df ||df ||f ||kr&|}td|  q&W ||fS )a  
    Returns (injectionconf, toppoints), where injectionconf is the
    confidence level of the injection, contained in the injBin and
    toppoints is a list of (pointx, pointy, ptindex, frac), with
    pointx and pointy the (x,y) coordinates of the corresponding
    element of the points array, ptindex the index of the point in the
    array, and frac the cumulative fraction of points with larger
    posterior probability.

    The hist argument should be a one-dimensional array that contains
    counts of sample points in each bin.

    The points argument should be a 2-D array storing the sky location
    associated with each bin; the first index runs from 0 to NBins -
    1, while the second index runs from 0 to 1.

    The injBin argument gives the bin index in which the injection is
    found.

    The NSamples argument is used to normalize the histogram counts
    into fractional probability.
    Nr  g        r   r	   z&Injection found at confidence level %g)r   r  r0  r/  rb  )	histZpointsZinjBinZNSamplesZhistIndices	toppointsfracZinjConfrE   r&   r&   r'   _calculate_confidence_levels  s    
"r  c             C   s   t | |||\}}d}|  i }	t|}x\|D ]T}
t|dddf |
d }|t|krjt|d }||d df }|| |	|
< q2W d}|r|rttt|dddf |kd }||d  }|||	|fS )z{
    An interal function representing the common, dimensionally-independent part of the
    greedy binning algorithms.
    r   Nr   r	   rB   )	r  r+  r   r   Zsearchsortedr   r  nonzeroasarray)
greedyHistgreedyPointsZinjection_bin_indexZbin_sizeZNsamplesconfidence_levelsinjectionconfidencer  ZnBinsresesZprintclZacclinjection_arearE   r&   r&   r'   _greedy_bin  s     

(r  c             C   sJ   t td | d d  t td | d d    | d d | d d   S )Ng       @r   r	   )r   rB  )rx  r&   r&   r'   r    s    r  c             C   s2   t t| | }t|  | d | | |d  fS )N)r.  r   r  shuffle)r\  fractionr-  r&   r&   r'   random_split  s    
r  c             C   sB   | j d kr|   n*|| j | jk r2t| j | nt| j| d S )N)rh  r  r  r  ri  )r  r  r&   r&   r'   r  "  s
    

r  c                s   |   G dd dt}dd }|  \} dddg  fdd	|D }t|}| }d
}|j|||d | }	|	  d}
d}d}i }xL|	D ]D\}}}|
|7 }
||7 }|
|| kr|||
< |d7 }|t|krP qW |S )Nc               @   s$   e Zd Zdd Zdd Zdd ZdS )z(kdtree_bin_sky_volume.<locals>.Harvesterc             S   s   t |  d| _d S )Ng        )r  r   unrho)r   r&   r&   r'   r   5  s    
z1kdtree_bin_sky_volume.<locals>.Harvester.__init__c             S   sF   t t| t |  }| || | g |  j|7  _d S )N)r0  r   rj  r|  r/  rx  r  )r   r  number_densityr&   r&   r'   __call__9  s    z1kdtree_bin_sky_volume.<locals>.Harvester.__call__c             S   s<   x*t t| D ]}| | d  | j  < qW t| tddS )Nr   )rm  )r   r   r  rg  r   )r   rE   r&   r&   r'   close_ranks>  s    z4kdtree_bin_sky_volume.<locals>.Harvester.close_ranksN)r4  r5  r6  r   r  r  r&   r&   r&   r'   	Harvester3  s   r  c             S   s   d S )Nr&   )r<   r=   r&   r&   r'   r{  E  s    z kdtree_bin_sky_volume.<locals>.hr   r   r   c                s   g | ]}t | qS r&   )r  )r;   r  )r  r  r&   r'   r>   K  s    z)kdtree_bin_sky_volume.<locals>.<listcomp>r}  )r  g        r   r	   )	r+  r  r
  r  r  r~  r  reverser   )r)  r  r  r{  r
  r  r  r<   samples_per_binr=   acc_rhoacc_volcl_idxconfidence_intervalsrhovolrx  r&   )r  r  r'   kdtree_bin_sky_volume/  s4    
r  r}  c       !         s  |   ddlmm G fdddt}dd }td}|  \} dd	g d
 d gd d gg} fdd|D }t||}	| }
|	j	|
||d t
|	 }|
 }|  d
}x,|D ]$}||d 7 }t|t| |d< qW d
}d
}d}| d jdk	r| d	 jdk	r|	j| d j| d	 jg|d\}}}|||g}d |d d  d |d d    |d d |d d   }t|t| }||
j }nd}d}d}d}i }xd|D ]\\}}}}||7 }||| krtt| t| |||| < |d7 }|t
|krP qW d
}x|D ]\}}}}||7 }q>W tdt|  d}d} |dk	rd
}xV|D ]N\}}}}||7 }||kr|}|} || ||  tdt|  P qW |||fS )a  
    takes samples and applies a KDTree to them to return confidence levels
    returns confidence_intervals - dictionary of user_provided_CL:calculated_area
            b - ordered list of KD leaves
            injInfo - if injection values provided then returns
                      [Bounds_of_inj_kd_leaf ,number_samples_in_box, weight_of_box,injection_CL ,injection_CL_area]
    Not quite sure that the repeated samples case is fixed, posibility of infinite loop.
    r   )r   r   c                   s.   e Zd ZdZdd Z fddZdd ZdS )	z&kdtree_bin_sky_area.<locals>.Harvesterzl
        when called by kdtree.operate will be used to calculate the density of each bin (sky area)
        c             S   s   t |  d| _d S )Ng        )r  r   r  )r   r&   r&   r'   r   t  s    
z/kdtree_bin_sky_area.<locals>.Harvester.__init__c                s    d |  d d   d |  d d    |  d d |  d d   }tt| t| }| |t| ||  g |  j|7  _d S )Ng       @r   r	   )rx  r0  r   rj  r/  r  )r   r  Zarear  )r   r   r&   r'   r  x  s    Zz/kdtree_bin_sky_area.<locals>.Harvester.__call__c             S   s<   x*t t| D ]}| | d  | j  < qW t| tddS )Nr   )rm  )r   r   r  rg  r   )r   rE   r&   r&   r'   r    s    z2kdtree_bin_sky_area.<locals>.Harvester.close_ranksN)r4  r5  r6  r7  r   r  r  r&   )r   r   r&   r'   r  p  s   r  c             S   s   d S )Nr&   )r<   r=   r&   r&   r'   r{    s    zkdtree_bin_sky_area.<locals>.hcommonr   r   g        g       @c                s   g | ]}t | qS r&   )r  )r;   r  )r  r  r&   r'   r>     s    z'kdtree_bin_sky_area.<locals>.<listcomp>)r  r	   Nztotal area: zinj )r+  mathr   r   r  PEOutputParserr
  r  r  r~  r   rj  r  r  r0  r  r  r  rb  r  r/  )!r)  r  r  r  r{  peparserr
  Zinitial_dimensionsr  r  r<   totalSamplesr=   samplecounterr  r  r   r  injBoundinjNum	injWeightinjInfoinj_areainj_number_densityinj_rhor  r  confidence_levelr  rx  sample_numberinj_confidenceinj_confidence_arear&   )r  r   r  r   r'   kdtree_bin_sky_areae  sz    	

 $
J



r  c       )         s  |   t| G dd dt}dd }td} \}  fdd|D }	|dkr|	d	  }
|	d	  }x4|	d
d D ]$}t|
| }
t	|| }qW |
|g}t
|	|}| }|j|||d | }|  t| }d}x,|D ]$}||d
 7 }t|t| |d
< qW d}d}d	}fdd}| r|jfdd D |d\}}}|||g}d}|d	 }
|d
 }x$t|
|D ]\}}|||  }qW t|t| }||j }t||||j| nd}d} d}d}i }!xT|D ]L\}"}#}$}%||$7 }|#|| kr||#f|!|| < |d
7 }|t|krP qW d}x|D ]\}"}#}$}%||$7 }qNW d}&d}'|dk	rtd d}xF|D ]>\}"}(}$}%||$7 }|"|kr|(}&|}'||& ||' P qW |!|||fS )a2  
    takes samples and applies a KDTree to them to return confidence levels
    returns confidence_intervals - dictionary of user_provided_CL:calculated_volume
            b - ordered list of KD leaves
            initial_boundingbox - list of lists [upperleft_coords,lowerright_coords]
            injInfo - if injection values provided then returns
                      [Bounds_of_inj_kd_leaf ,number_samples_in_box, weight_of_box,injection_CL ,injection_CL_volume]
    Not quite sure that the repeated samples case is fixed, posibility of infinite loop.
    c               @   s(   e Zd ZdZdd Zdd Zdd ZdS )	zkdtree_bin.<locals>.Harvesterza
        when called by kdtree.operate will be used to calculate the density of each bin
        c             S   s   t |  d| _d S )Ng        )r  r   r  )r   r&   r&   r'   r     s    
z&kdtree_bin.<locals>.Harvester.__init__c             S   sP   t t| t |  }| |t| | | g |  j|7  _d S )N)r0  r   rj  r|  r/  rx  r  )r   r  r  r&   r&   r'   r    s    "z&kdtree_bin.<locals>.Harvester.__call__c             S   s<   x*t t| D ]}| | d  | j  < qW t| tddS )Nr   )rm  )r   r   r  rg  r   )r   rE   r&   r&   r'   r    s    z)kdtree_bin.<locals>.Harvester.close_ranksN)r4  r5  r6  r7  r   r  r  r&   r&   r&   r'   r    s   r  c             S   s   d S )Nr&   )r<   r=   r&   r&   r'   r{    s    zkdtree_bin.<locals>.hr  c                s   g | ]}t | qS r&   )r  )r;   r  )r  r  r&   r'   r>     s    zkdtree_bin.<locals>.<listcomp>Nr   r	   )r  g        c                s$   x| D ]} | j d krdS qW dS )NFT)r  )listoParamsr   )r)  r&   r'   	checkNone  s    
zkdtree_bin.<locals>.checkNonec                s   g | ]} | j qS r&   )r  )r;   r   )r)  r&   r'   r>     s    g      ?zcalculating cl)r+  rb  r  r  r
  r  r  r   rq  rr  r  r~  r  r  r   rj  r0  r  r]  r  r/  ))r)  r  r  initial_boundingboxr  r  r{  r	  r
  r  rk  rl  r^  r  r<   r=   r
  r  r  r  r   r  r  r  r  r  r  Z
inj_volumeZaCoordZbCoordr  r  r  r  r  r  r  rx  r  r  r  r&   )r  r  r)  r'   
kdtree_bin  s    



"





r  F      ?c	       0         sn  |    \}	t|	}
|dkr4t|	|\}}n(|	dt|
|  }|	t|
| d }t|}  fdd|D }|dkrdt d gdt td gg}|dkr|d  }|d  }x4|d	d D ]$}t	|| }t
|| }qW ||g}t||}|j||d
}g }x D ]}|| q(W x:|D ]2}g }x|D ]}|||  qVW t|| qHW fddg }|| g }x|D ]}|||  qW t|dd d}|  d}x<tt|D ],}||| d 7 }|| t||  qW d}d} d}!t|}"i }#i }$d}%x|D ]}&| |&d 7 } |%d	7 }%|!|&d 7 }!||"k r:| || kr:|!t| | f|#|| < |!|&d | ||   |&d   |$|| < |d	7 }q:W |dk	r||\}'}(})|'|(|)g}*nd}*d}+d},|*dk	rdd}-d}.xZ|D ]R}&|-|&d 7 }-|.|&d 7 }.|&d	 |)krt|.| }+|-},|*|+ |*|, P qW ||$|*fS )aa  
    input: posterior class instance, list of confidence levels, optional choice of inital parameter space, samples per box in kdtree
    note initial_boundingbox is [[lowerbound of each param][upper bound of each param]], if not specified will just take limits of samples
    fraction is proportion of samples used for making the tree structure.
    returns: confidence_intervals, sorted list of kd objects, initial_boundingbox, injInfo
    where injInfo is [bounding box injection is found within, samples in said box, weighting of box (in case of repeated samples),inj_confidence, inj_confidence_area]
    FNc                s   g | ]}t | qS r&   )r  )r;   r  )r  r  r&   r'   r>   `  s    z#kdtree_bin2Step.<locals>.<listcomp>Tr   g       @rB   r	   )r  r  c                sD   | j d kr(||  | j| j| jg n | j |  | j| d S )N)rh  r/  rx  r  r  r  ri  )r  Zlisting)	getValuesr&   r'   r  x  s    
z"kdtree_bin2Step.<locals>.getValuesc             S   s   | d S )Nr	   r&   )Z
importancer&   r&   r'   rC    rD  z!kdtree_bin2Step.<locals>.<lambda>)rm  r   g        c                s$   x| D ]} | j d krdS qW dS )NFT)r  )r  r   )r)  r&   r'   r    s    
z"kdtree_bin2Step.<locals>.checkNone)r+  r
  r   r  r.  r  rB  r  r   rq  rr  r  r  r/  r*   r  rg  r  r   r0  r  )0r)  r  r  r  r  	injCoordsZ	alternater  Z	skyCoordsr
  ZnumberSamplesZsamplesStructureZsamplesFillZsamplesFillLenr  rk  rl  r^  r  Z	tree2fillcolumnsr)   r  Z
tempSampler  Z
listLeavesZ	clSamplesclZsortedLeavesListZrunningTotalSamplesrE   levelZcountSamplesr|  Zlenclr  ZinterpConfAreasZcountLeavesleafr  r  ZinjImportancer  r  r  r   Zacc_clr  r&   )r  r  r  r)  r'   kdtree_bin2StepL  s    







(





r#  c              C   s  |  \}}| |  j}| |  j}|| }|| }| |  j}	| |  j}
t|d }t|d }t|d }t|d }tt|| | d }tt|| | d }tj	|| dd}t	|| df}|}|}x^t
|D ]R}|}x@t
|D ]4}|||||  df< |||||  df< ||7 }qW ||7 }qW d}|	dk	r|
dk	rtt|	| | }tt|
| | }t|||  }nB|	dkr|
dk	rtd|  n |	dk	r|
dkrtd|  xt||D ]\}}|d }|d }tt|| | }tt|| | }y||||    d7  < W n6   td|||||||  ||||||f Y nX qW t|||t|| tt||\}}}}||||fS )	aZ  
    Determine the 2-parameter Bayesian Confidence Intervals using a greedy
    binning algorithm.

    @param posterior: an instance of the Posterior class.

    @param greedy2Params: a dict - {param1Name:param1binSize,param2Name:param2binSize} .

    @param confidence_levels: A list of floats of the required confidence intervals [(0-1)].
    r   r	   i8)dtyperB   Nz!Injection value not found for %s!z;Problem binning samples: %i,%i,%i,%i,%i,%f,%f,%f,%f,%f,%f .)r  rB  r
  r  r  r  r.  r   r   r,  r   r   rb  r]  re  r  r0  r   ) r)  greedy2Paramsr  	par1_name	par2_nameZpar1posZpar2pospar1_binpar2_binpar1_injvaluepar2_injvaluepar1pos_minpar2pos_minpar1pos_maxpar2pos_maxpar1pos_Nbinspar2pos_Nbinsr  r  Z
par1_pointZ
par2_pointrE   jinjbinZpar1_binNumberZpar2_binNumberZ	par1_sampZ	par2_sampr  Zinjection_clr  r  r&   r&   r'   greedy_bin_two_param  sd    6

r5  c             C   sB   t |t |  }t |t |  }t |}t |||gS )zh
    Utility function to convert longitude,latitude on a unit sphere to
    cartesian co-ordinates.
    )r   r   sinr   )rN  rO  r   r   r  r&   r&   r'   pol2cart  s    
r7  c             C   sH   | t | t | }| t | t | }| t | }|||fS )zL
    Utiltiy function to convert r,theta,phi to cartesian co-ordinates.
    )r   r6  r   )r   thetar   r   r   r  r&   r&   r'   sph2cart&  s    r9  c             C   sV   t | |  ||  ||  }t || }t dt t ||  dt }|||fS )zF
    Utility function to convert cartesian coords to r,theta,phi.
    rB   )r   r   arccosr   rB  arctan2)r   r   r  r   r8  r   r&   r&   r'   rG  0  s     rG  c          
   C   s   t jddd}tj| |dt| dd|jdd t jd	d
|d |dk	rttjd |d  }tj	||d ddddd t 
tj|d |S )a  Plots a sky map from a healpix map, optionally including an
    injected position. This is a temporary map to display before
    ligo.skymap utility is used to generated a smoother one.

    :param hpmap: An array representing a healpix map (in nested
      ordering if ``nest = True``).

    :param outdir: The output directory.

    :param inj: If not ``None``, then ``[ra, dec]`` of the injection
      associated with the posterior map.

    :param nest: Flag indicating the pixel ordering in healpix.

    F)r   r   )Zframeonfigsizer   ZGreysEzHistogrammed skymap)r'  r  r  cmapr  figr  Tr   )colorfigureNg       @r	   *whiteblackr}  )ZmarkerfacecolorZmarkeredgecolor
markersizez
skymap.png)pltrA  r*  Zmollviewr   r  numbergridr   Zprojplotsavefigospathjoin)r1  outdirr   r'  r?  r8  r&   r&   r'   plot_sky_map<  s    "rN  c             C   s   | t |  } t | ddd } t | }tt| jd }|dt j d  }g }x(|D ] }t ||k }|	||  q^W t 
|S )zReturns the area (in square degrees) for each confidence level with
    a greedy binning algorithm for the given healpix map.

    Nr  r   g     f@rB   )r   r-  r+  cumsumr*  r.  
npix2nsider_  r   r/  r   )r1  clsZ	cum_hpmapZpixareaZareasr   Znpixr&   r&   r'   skymap_confidence_areasY  s    

rR  c             C   s\   t | jd }| t|  } t j|tjd |d  |d |d}| | }t| | |k S )zBReturns the greedy p-value estimate for the given injection.

    r   g       @r	   )r'  )r*  rP  r_  r   r-  r+  r   )r1  r   r'  r/  ZinjpixZinjvaluer&   r&   r'   skymap_inj_pvaluen  s
    $rS  c             C   sn   t d| }d| d|  }d| }| t d| d t |d }| t d| d t |d }||fS )z
    Utility function for converting mchirp,eta to component masses. The
    masses are defined so that m1>m2. The rvalue is a tuple (m1,m2).
    g      ?g      ?r	   g?g333333?)r   r   power)rK   rL   rootr  ZinvfractionrH   rG   r&   r&   r'   rc  }  s      rc  c             C   s<   | t d| d }|t |d }|t |d }||fS )z
    Utility function for converting mchirp,q to component masses. The
    masses are defined so that m1>m2. The rvalue is a tuple (m1,m2).
    r	   g?g333333g?)r   rT  )rK   rM   factorrG   rH   r&   r&   r'   r    s    r  c             C   s"   | d|  d|    }t |ddS )zJ
    Utility function for converting q to eta. The
    rvalue is eta.
    r	   r   g      ?)r   Zclip)rM   rL   r&   r&   r'   r    s    r  c             C   s   t | |\}}|| }|S )zQ
    Utility function for converting mchirp,eta to new mass ratio q (m2/m1).
    )rc  )rK   rL   rG   rH   rM   r&   r&   r'   mc2q  s    rW  c             C   s   t |t |  }t |t |  }t |}t |t | }t |t | }t |}	t|| ||  ||	  }
|
S )zo
    Find the angular separation of (long1,lat1) and (long2,lat2), which are
        specified in radians.
    )r   r   r6  r  acos)Zlong1Zlat1Zlong2Zlat2x1y1Zz1Zx2y2Zz2sepr&   r&   r'   ang_dist  s    

r]  c             C   s4   | j dkr| |  }n| | jdddd}|S )zI
    Calculate dot products between vectors in rows of numpy arrays.
    r	   )r  r  )r  r-  r  )vec1vec2productr&   r&   r'   rI    s    
rI  c             C   s8   t t| | }t t||}t t| |||  S )z>
    Find angles between vectors in rows of numpy arrays.
    )r   r   rI  r:  )r^  r_  Zvec1_magZvec2_magr&   r&   r'   rJ    s    rJ  c             C   sJ   | j dkr| d }n| dddf dd}tt| | }t|| S )z@
    Find polar angles of vectors in rows of a numpy array.
    r	   rB   Nr  )r  r  r   r   rI  r:  )r  r  r  r&   r&   r'   array_polar_ang  s
    

ra  c                s  t |  t | t t yft| }t dd  jD }|t  fddt|D 7 }|t fddt|D 7 }W n t	k
r   t 
   g}|t d   7 }|t dd  d gd dd	  gd  d	 dgg 7 }Y nX |S )
zU
    Compute general rotation matrices for a given angles and direction vectors.
    c             S   s   g | ]}t |||gqS r&   )r   diag)r;   rE   r&   r&   r'   r>     s    z#rotation_matrix.<locals>.<listcomp>c                s,   g | ]$}t | | d  |   qS )g      ?)r   outer)r;   rE   )cosa	directionr&   r'   r>     s    c          
      sl   g | ]d}t d  |df   |df g |df d  |df  g |df   |df d gg|  qS )g        rB   r	   r   )r   r   )r;   rE   )re  sinar&   r'   r>     s   g      ?g        rB   r	   r   )r   r   r6  r   rI  r   r   flatr   r  rb  rc  )anglere  ZnSampsr$  r&   )rd  re  rf  r'   rotation_matrix  s     

"$ri  c                sF   j dkr t t t }n"t fddttD }|S )z;
    Rotate vectors using the given rotation matrices.
    r	   c                s    g | ]}t  | | qS r&   )r   r  )r;   rE   )r$  r  r&   r'   r>     s    z!rotate_vector.<locals>.<listcomp>)r  r   r  rE   r   r   r   )r$  r  ZnewVecr&   )r$  r  r'   rotate_vector  s    
"rj  c             C   sH   |t |  |t |   }|t |  |t |   }t |||gS )N)r   r   r6  r  )rh  vxvyvztmp1tmp2r&   r&   r'   ROTATEZ  s    rp  c             C   sJ   |t |  |t |   }| t |  |t |   }t |||gS )N)r   r   r6  r  )rh  rk  rl  rm  rn  ro  r&   r&   r'   ROTATEY  s    rq  c       	      C   sH   || || ||   }t | |||}t||d\}}}t|||fS )a+  
    Calculate orbital angular momentum vector.
    Note: The units of Lmag are different than what used in lalsimulation.
    Mc must be called in units of Msun here.

    Note that if one wants to build J=L+S1+S2 with L returned by this function, S1 and S2
    must not get the Msun^2 factor.
    g        )orbital_momentum_magr9  r   r  )	frefrG   rH   r   rL   LmagZLxZLyZLzr&   r&   r'   rH    s    	rH  c             C   sV   t || t tj |  d}|| d | | }d|d d|d    }|| }|S )NgUUUUUU?rB   r	   g      ?g      @)r   rT  rB  r   ZMTSUN_SI)rs  rG   rH   rL   Zv0ZPNFirstZPNSecondrt  r&   r&   r'   rr  !  s
    rr  c             C   s*   t | d | ||\}}}t|||fS )z/
    Calculate BH angular momentum vector.
    rB   )r9  r   r  )r   r<   r8  r   ZSxZSyZSzr&   r&   r'   component_momentum)  s    ru  c       	      C   s   | | }| | }t |dkr&tdd| d|  }t|}ddd|  d| |  | |dd|  d| |   |   }d	|dd
| d  d| | d   | dd| d  d| | d  d| | | d  |   }||fS )zu
    Calculate best tidal parameters [Eqs. (5) and (6) in Wade et al. PRD 89, 103012 (2014)]
    Requires q <= 1
    r	   z+q > 1, while this function requires q <= 1.g      ?g;;?g      @g      ?@g      "@g      &@g      ?g     @g     @g     x@g     @g    @
@g     h@)r   r  r%  r  )	r   r   rM   ZlambdapZlambdamZdmbymrL   r   r   r&   r&   r'   r  2  s    @dr  c
             C   s   d|||	fk}
t ||\}}t| |||}t||||}|
sLt||||	}nd}|| | }t||}|
svt||}nd}t|}t||}||||fS )z)
    Calculate physical spin angles.
    Ng        )rc  rH  ru  rJ  ra  )rs  rK   rL   r   rT   rW   rV   rU   rY   rX   Z
singleSpinrG   rH   rJ  rQ  rR  rS  r^   r`   rc   r   r&   r&   r'   r  F  s    

r  c             C   s|   | | }dd| d  }ddd|   }|t | |  |  }	|t | | | }
t ||
 ||	 }|||  |   }|S )a  
    Calculate the magnitude of the effective precessing spin
    following convention from Phys. Rev. D 91, 024043   --   arXiv:1408.1810
    note: the paper uses naming convention where m1 < m2
    (and similar for associated spin parameters) and q > 1
    g       @g      @)r   r6  rr  )rG   rT   r^   rH   rU   r`   Zq_invA1A2ZS1_perpZS2_perpZSprs   r&   r&   r'   r  \  s    r  |?5^?V-?x&1?      c                s   dd  t ||||ddt| trLtt tjdd| fdg}n&t fdd| ddd	f D }|	|j
d	 d
S )a  
    Calculate the redshift from the luminosity distance measurement using the
    Cosmology Calculator provided in LAL.
    By default assuming cosmological parameters from arXiv:1502.01589 - 'Planck 2015 results. XIII. Cosmological parameters'
    Using parameters from table 4, column 'TT+lowP+lensing+ext'
    This corresponds to Omega_M = 0.3065, Omega_Lambda = 0.6935, H_0 = 67.90 km s^-1 Mpc^-1
    Returns an array of redshifts
    c             S   s   |t ||  S )N)r   ZLuminosityDistance)r  dlr   r&   r&   r'   find_z_rootu  s    z'calculate_redshift.<locals>.find_z_rootg        g       @)r  c                s(   g | ] }t  tjd d|fdqS )g        g       @)r  )r   r   r  r   )r;   r  )r}  r   r&   r'   r>   |  s    z&calculate_redshift.<locals>.<listcomp>Nr   r	   )r   CreateCosmologicalParametersr  r0  r   r   r   r  r   r  r_  )r   r{  omolZw0r  r&   )r}  r   r'   r  l  s    	
&&r  c             C   s   | d|  S )zl
    Calculate source mass parameter for mass m as:
    m_source = m / (1.0 + z)
    For a parameter m.
    g      ?r&   )Zmassrx   r&   r&   r'   r    s    r  c             C   sJ   t dddddd}|j}|j}d|  |d  t|d|  d  |  S )	z
    Calculate D_alpha integral; multiplicative factor put later
    D_alpha = integral{ ((1+z')^(alpha-2))/sqrt(Omega_m*(1+z')^3 +Omega_lambda) dz'} # eq.15 of arxiv 1110.2720
    g|?5^?gV-?gx&1?g      g        g      ?g       @g      @)r   r~  r  r  r   r   )rx   r  r   Zomega_mZomega_lr&   r&   r'   integrand_distance  s    r  c             C   s\   t dddddd}|jt j }tjtd| |dd }|d|  d|  9 }|| }|t j S )	z
    D_alpha = ((1+z)^(1-alpha))/H_0 * D_alpha # from eq.15 of arxiv 1110.2720
    D_alpha calculated from integrand in above function
    g|?5^?gV-?gx&1?g      g        r   )r  g      ?)r   r~  r{  ZH0FAC_SIr   quadr  C_SI)rx   r  r   ZH0r   r&   r&   r'   DistanceMeasure  s    r  c             C   sJ   t t}|| |}|tj d }|||d|  d|    dd|    S )z
    Converting from the effective wavelength-like parameter to lambda_A:
    lambda_A = lambda_{eff}*(D_alpha/D_L)^(1/(2-alpha))*(1/(1+z)^((1-alpha)/(2-alpha)))
    g    .Ag      ?g       @)r   	vectorizer  r   PC_SI)rx   r  r   r   ZDfuncZD_alphar|  r&   r&   r'   r     s    

c             C   s2   d}t t}|| |||tj }|| |d  S )z
    Converting to Lorentz violating parameter "A" in dispersion  relation from lambda_A:
    A = (lambda_A/h)^(alpha-2) # eqn. 13 of arxiv 1110.2720
    gy}FV<g       @)r   r  r   r   r  )rx   r  r   r   ZhPlanckZampFuncZlambdaAr&   r&   r'   r    s    
r  c       $         s  yddl }W n$ tk
r0   td td dS X ddlm} |j |tj }|tj }| |||||||||	|
g}t||dkrVy&x t	|D ]\}}|
 ||< qW W n   Y nX yt fddt| D }|dddf d	d}|dddf d	d}|ddd
f d	d}|dddf d	d}|dddf d	d}|dddf d	d}|dddf d	d}t|||\}}}t|||\}}}t|| dt|| d }t|	|||}t|| | || | || | g} t|| | || | || | g}!||  |! }"t|"|}#||||||#fS    dS nTt||dkry$xt	|D ]\}}|||< qtW W n   Y nX yt | |||||||||	|
}|d }|d }|d
 }|d }|d }|d }|d }t|||\}}}t|||\}}}t|| dt|| d }t|	|||}|| t|||g } || t|||g }!||  |! }"t|"|}#||||||#fS    dS dS )z
    Wrapper function for SimInspiralTransformPrecessingNewInitialConditions().
    Vectorizes function for use in append_mapping() methods of the posterior class.
    r   Nz]bayespputils.py: Cannot import lalsimulation SWIG bindings to calculate physical to radiationz\frame angles, did you remember to use --enable-swig-python when ./configuring lalsimulation?)r_  r	   c                s>   g | ]6\}}}}}}}}}	}
} |||||||||	|
|qS r&   r&   )r;   Zt_jnZp_jlt1t2Zp12rT   rU   m1_SIm2_SIr}  Zphir)transformFuncr&   r'   r>     s    z+physical2radiationFrame.<locals>.<listcomp>r  rB   r   r   r   r   g333333?gɿ)rE  r  rb  r  r_  2SimInspiralTransformPrecessingNewInitialConditionsr   MSUN_SIr   r  flattenr   r   r]  r  rG  rT  rH  r  rJ  )$rc   rb   r^   r`   rd   rT   rU   rG   rH   rs  ZphirefrF  r_  r  r  Zinsr  r   resultsr   r  r  r  r  r  r  rW   rV   rY   rX   rK   rJ  rQ  rR  rS  r   r&   )r  r'   r    s~    

 ((
" 
r  c             C   s   ddl m} tjdd |dd |j}y
|j}W n" tjjjk
rT   td Y n6X tt	|t
|d}||}tj||dd d S )	Nr   )r  r  )r  z Singular matrix in KDE. Skippinge   green)r@  )r  r  r   r
  r  r  ZLinAlgErrorrb  r   r  r  evaluaterF  plot)r?  Zonedposr  	pos_sampsZgkder  kdepdfr&   r&   r'   plot_one_param_pdf_kde  s    


r  c             C   s   t |t d S )N)rF  r  r  )r?  r  r&   r&   r'   plot_one_param_pdf_line_hist  s    r  c       (         s  dt jd< t| d  }t| d }| | j}| | j}| | j}	t	j
ddd}
t	|
dddd	g}|
| td
d dd  _td
d}dd |_ d
 |d
 d}|ddkrtt|}|| }|dk	r|| }|dt|  }n|}t	j||d
dd\}}}tt fdd| }|dkrBd}n$|dkrRd}n|dkrbd}nd}t jj|d}t	 \}}|dks|dkrt||d}t  |d ks|d!krt||d}t  |j   |j! | |"|d |d  |j#| |rt$|
| |  |d" |d  }|rt	 \}}t%&||d#t'| }t	j(|||| d$d#d%d& |rd'}dd(l)m*} ||d|ddf + }t,j-|| |d)d*\}}t	.d+||f  d}|dk	rt|t| }t|d,|  } t|d,|  }!| |k r,|!|kr,t	j/|d$d-dd. t||k rt||kr||d  | }"tt|"}#|"t0|# }$t1|d|#d"  |$||#   | }|	dk	r$xd/d0 |	 D D ]n}%|	|% }&t||&k rt||&kr|%d1krd$}'n$|%d2krd3}'n|%d4kr
d5}'nd6}'t	j/|&|'d-d7 qW t	2  t	3t4| t	5d8 | dks`| dkrxt	 \}}t	|| ||
fS )9a  
    Plots a 1D histogram and (gaussian) kernel density estimate of the
    distribution of posterior samples for a given parameter.

    @param posterior: an instance of the Posterior class.

    @param plot1DParams: a dict; {paramName:Nbins}

    @param analyticPDF: an analytic probability distribution function describing the distribution.

    @param analyticCDF: an analytic cumulative distribution function describing the distribution.

    @param plotkde: Use KDE to smooth plot (default: False)
    Fztext.usetexr   )r   g      @   )r<  dpig333333?g333333?gRQ?T)useMathTextc             S   s   d|  S )Nz%.6gr&   )r  r&   r&   r'   rC  @  rD  z$plot_one_param_pdf.<locals>.<lambda>c             S   s   d|  S )Nz%.6gr&   )r  r&   r&   r'   rC  B  rD  g        r   r  Nz + %iZgrey)r#  Z	facecolorc                s   t  | S )N)r   format_data)r  )majorFormatterXr&   r'   rC  O  rD  r   r   r   r   r   )nbinsr   r   )r  r  r   r   r	   rB   r   r   )r@  	linewidth	linestylei  )permutationasymp)r  z%s: ks p-value %.3fg?z-.)r@  r  r  c             S   s   g | ]}|qS r&   r&   )r;   r  r&   r&   r'   r>     s    z&plot_one_param_pdf.<locals>.<listcomp>rx  ry  r   rz  r   r   )r@  r  zProbability Density)6
matplotlibrcParamsr  r  rB  valuesr
  r  r  rF  rA  Axesadd_axesr   r  set_scientificfindr   r  r.  r  r  r  
get_xtickstickerMaxNLocatorxlim	RALocatorRAFormatter
DecLocatorDecFormatterxaxisset_major_formatteryaxisZview_limitsset_major_locatorr  r   r   r   r  Znumpy.randomr  r  r   Zkstestr  axvliner0  r-  rH  xlabelr   ylabel)(r)  Zplot1DParamsZanalyticPDFZanalyticCDFplotkder   Zhistbinsr  injparr  myfigaxesmajorFormatterYoffsetax1_namer  r"  ZpatchesNcharsNtickslocatorXxminxmaxZhistbinSizer   Z	max_sampsr  r  Dr  rbinsZdelta_sampsminrangemaxrangeZbins_to_injZinjbinhZinjbin_fracr  Ztrigvalr@  r&   )r  r'   plot_one_param_pdf!  s    













 
$

 
 
 

r  c               @   s"   e Zd ZdZdde fddZdS )r  z2
    RA tick locations with some intelligence
    g        g       @c             C   s   t d }|| d| kr"d| }nR|| d| kr<d| }n8|| dt  d krV|}n|| |krl|d }n|d }tjjj| |d d S )Ng      (@g      @g      @g       @g      @)base)rB  r  r  MultipleLocatorr   )r   r  r  hourr  r&   r&   r'   r     s    


zRALocator.__init__N)r4  r5  r6  r7  rB  r   r&   r&   r&   r'   r    s   r  c               @   s(   e Zd ZdZe d ed fddZdS )r  z3
    Dec tick locations with some intelligence
    g       @c             C   sp   t d }|| d| kr"d| }n8|| d| kr<d| }n|| d| krVd| }n|}tjjj| |d d S )Ng     f@<   g      >@   r}  r   )r  )rB  r  r  r  r   )r   r  r  degr  r&   r&   r'   r     s    


zDecLocator.__init__N)r4  r5  r6  r7  rB  r   r&   r&   r&   r'   r    s   r  c               @   s   e Zd ZdddZdS )r  autoc             C   s   t jj| t d S )N)r  r  FuncFormatterr   getRAString)r   accuracyr&   r&   r'   r     s    zRAFormatter.__init__N)r  )r4  r5  r6  r   r&   r&   r&   r'   r    s   r  c               @   s   e Zd ZdddZdS )r  r  c             C   s   t jj| t d S )N)r  r  r  r   getDecString)r   r  r&   r&   r'   r     s    zDecFormatter.__init__N)r  )r4  r5  r6  r   r&   r&   r&   r'   r    s   r  r  c                s   t | }t| }|dkrNd t|| td k r4d t|| td k rRd n| t | dt krjdt }t| d	k rzd	}t||t| } t fd
d| }tdd |}t|tt	t|fS )z
    Format locs, ticks to RA angle with given accuracy
    accuracy can be 'hour', 'min', 'sec', 'all'
    returns (locs, ticks)
    'all' does no rounding, just formats the tick strings
    'auto' will use smallest appropriate units
    r  r  g      (@r  g     @secrB   g       @g        c                s   t |  dS )N)r  )roundRadAngle)r<   )accr&   r'   rC    rD  zformatRATicks.<locals>.<lambda>c             S   s   | dko| dt  kS )Nr   g       @)rB  )r<   r&   r&   r'   rC    rD  )
r  r  r|  rB  r   r   r  filterr  r  )locsr  newmaxnewmin	roundlocsnewlocsr&   )r  r'   formatRATicks  s"      r  c                s   t | }t| }|dkrNd t|| td k r4d t|| td k rRd n| |dt krfdt }|dt k rzdt }t||t| } t fd	d
| }tdd
 |}t|tt	t|fS )z
    Format locs to Dec angle with given accuracy
    accuracy can be 'deg', 'arcmin', 'arcsec', 'all'
    'all' does no rounding, just formats the tick strings
    r  r  g     v@r&  g     @arcsecg      ?g      c                s   t |  dS )N)r  )r  )r<   )r  r&   r'   rC    rD  z formatDecTicks.<locals>.<lambda>c             S   s   | t  d ko| t d kS )Ng       @)rB  )r<   r&   r&   r'   rC    rD  )
r  r  r|  rB  r   r   r  r  r  r  )r  r  r  r  r  r  r&   )r  r'   formatDecTicks  s"      r  r  c             C   sp   |dkrt S |dkrd}|dkr$d}|dkr0d}|dkr<d	}|d
krHd}|dkrTd}|dt  }t| | | S )z
    round given angle in radians to integer hours, degrees, mins or secs
    accuracy can be 'hour'. 'deg', 'min', 'sec', 'all', all does nothing
    'arcmin', 'arcsec'
    r  r     r  ih  r  i  r  iQ r&  i`T  r  i g       @)r  rB  round)Zradsr  Zmultr&   r&   r'   r    s            r  c             C   s   | d d t  }t|d\}}t|d\}}|}|dkrH|d }|d }|dkr`|d }|d }|dkrvtd| S |dkrtd	||f S |d
krtd|||f S tt|ddkrt| d
dS tt|ddkrt| ddS t| ddS d S )Ng      (@i  r  g     M@r	   r  z%ihr  z%ih%imr  z%ih%im%2.0fsg      N@g      ?)r  )rB  divmodsixur|  r   r  )radiansr  secshoursremminsr&   r&   r'   r    s*         r  c       
      C   s   t jd rd}d}d}ntd}td}td}| dk rJ|  } d	}nd
}t| td \}}t|td \}}|d t }	|dks|dkr|	dkr|d
 }|dkr|dkr|d
 }|dkrd||  | S |dkrd|| |||f S |dkrd|| ||||	|f S t||  ddS d S )Nztext.usetexz$^\circ$'z''   '   i3   r   r  r	   g     f@g     @g    #Ar&  r     z%iz%i%s%i%sr  z%i%s%i%s%2.0f%s)r  )r  r  r  unichrr  rB  r  )
r  r  ZdegsymbZminsymbZsecsymbr  r  r  r  r  r&   r&   r'   r  +  s2    



    
 r  c                s   yddl }W n> tk
rJ   yddl}W n tk
rD   td dS X Y nX tt fdd|}dd |D }t fdd|D } jr fd	d|D }|j ||||d
dd}n|j |||d
dd}|S )z
    Make a corner plot using the triangle module
    (See http://github.com/dfm/corner.py)
    @param posterior: The Posterior object
    @param levels: a list of confidence levels
    @param parnames: list of parameters to include
    r   Nz<Cannot load corner module. Try running
	$ pip install cornerc                s
   |  j kS )N)r  )r   )r)  r&   r'   rC  ]  rD  zplot_corner.<locals>.<lambda>c             S   s   g | ]}t |qS r&   )r   )r;   Zparnamer&   r&   r'   r>   ^  s    zplot_corner.<locals>.<listcomp>c                s   g | ]} | j qS r&   )r
  )r;   r  )r)  r&   r'   r>   _  s    c                s   g | ]} | j qS r&   )r  )r;   r  )r)  r&   r'   r>   a  s    Fr  )r   Ztruths	quantilesplot_datapointsr"  )r   r  r  r"  )	cornerr  trianglerb  r  r  r   r  r  )r)  levelsZparnamesr  r   r  Zinjvalsr  r&   )r)  r'   plot_cornerM  s     r  )r   r      g?gQ?g      ?rv  2   c       T   
      s  ddl m} |}| \}}|| }|| }|}tjdd |dd tjd||d}t  ||}g }t|t|k rt	dg }x| 
 D ]\}}td|  || || j}|| j}|| j}|| j}|| j}|| j}t|| j}t|| j}d	}|d
dkr8tt|}|| }|rX|| }|dt|  } n|} |d
dkrtt|}|| }|r|| }|dt|  }!n|}!tt||f}"ytj|"}#|#|"}$W n
   dS |
}%|
}&tj|dd}'tj|dd}(tdt|' })tdt|' }*|'|* }+|'|) },|(|* }-|(|) }.d|,|+  }/d|.|-  }0|/|,|/ d  },|/|+|/ d  }+|0|.|0 d  }.|0|-|0 d  }-t|,|+|%}1t|.|-|&}2t|1|2\}3}4t|3 |4 f}5|#|5}6|6|%|&}6t|$ddd }7g }8|j d }9g }:x>|D ]6};t|9|; d }<|<|9kr@|9d }<|:|7|<  qW tj!|3|4|6|:|| g|d}=||= |dk	r|dk	rtj"|g|gddddd |dk	r|dk	rt#dd | D }>t#dd | D }?|>$|?}@xd|@D ]\}A|Adkrd}Bn$|Adkrd}Bn|Adkr(d }Bnd!}Btj"||A g||A g|Bd"ddd# qW qW t%t&| t't&| t(  t|t|krt	d$g }Cg }Dx|D ]}E|C|E qW t|dkr2xjt)|dt| |D ]P\}F}G|Dt*j+t,d	d%gt,d	d%g|Fd&d' |Cd(t-t|Gd)   qW d*d |D }H|H.|D |dk	rytj/t0|Ht0|Cd+d,d-}IW n$   tj/t0|Ht0|Cd+d.}IY nX x|I1 D ]}J|J2d/ qW t3d0d1 d2d3  _4t3d0d1}Kd4d3 |K_4 5d0 |K5d0 |j67  |j87|K t9t: fd5d3|; }L|Ld6kr4d7}Mn$|Ld8krDd9}Mn|Ld9krTd8}Mnd:}Mt<j=j>|Md d;}N|d<ks~|d=krt? \}O}Pt@|O|Pd>}NtA  |d?ks|d@krt? \}Q}RtB|Q|Rd>}NtC  |j67  |d<ks|d=krtD \}O}Pt@|O|P}S|j8E|S tA }K|d?ks*|d@krTtD \}Q}RtB|Q|Rd>}StC }K|j8E|S |j87|K |j6E|N tFt|| |G d=ks|G d<krt? \},}+|,d	k rd	},|+dAtH krdAtH }+t?|+|, |S )Ba  
    Plots a 2D kernel density estimate of the 2-parameter marginal posterior.

    @param posteriors_by_name: dictionary of Posterior objects, indexed by name

    @param plot2DkdeParams: a dict {param1Name:Nparam1Bins,param2Name:Nparam2Bins}

    @param levels: list of credible levels

    @param colors_by_name: dict of colors, indexed by name

    @param line_styles: list of line styles for the credible levels

    @param figsize: figsize to pass to matplotlib

    @param dpi: dpi to pass to matplotlib

    @param figposition: figposition to pass to matplotlib

    @param legend: position of legend

    @param hatches_by_name: dict of hatch styles indexed by name

    @param Npixels: Number of pixels in each axis of the 2D grid
    r   )r  r  )r  r	   )r<  r  zTError: Need as many or more line styles to choose from as confidence levels to plot!z	Plotting g        r   r  z + %iN)r  g{Gz?gGz?g      ?gffffff?)colors
linestyleszb*F   )scalexscaleyrE  c             S   s   g | ]}|qS r&   r&   )r;   r  r&   r&   r'   r>     s    z4plot_two_param_kde_greedy_levels.<locals>.<listcomp>c             S   s   g | ]}|qS r&   r&   )r;   r  r&   r&   r'   r>     s    rx  r   ry  r   rz  r   r   o)r@  markerr  r  zyError number of contour objects does not equal number of names! Use only *one* contour from each set to associate a name.g      ?r  )lsr@  z%s%%r;  c             S   s   g | ]}|j d  qS )r   )collections)r;   csr&   r&   r'   r>   	  s    rv  g?)r  
framealpha)r  smallT)r  c             S   s   d|  S )Nz%.4gr&   )r  r&   r&   r'   rC    rD  z2plot_two_param_kde_greedy_levels.<locals>.<lambda>c             S   s   d|  S )Nz%.4gr&   )r  r&   r&   r'   rC    rD  c                s   t  | S )N)r   r  )r  )r  r&   r'   rC    rD  r   r   r   r   r   )r  r   r   )r  r  r   r   g       @)Ir  r  r  r   rF  rA  clfr  r   re  r\  rb  r/  r  r  r
  r,  r  r   r  r.  r  r  r   r  r  r+  r   meshgridZ	row_stackr  r  r_  contourr  r  intersectionr  r   r  rH  r]  	mpl_linesLine2Dr   r  extend	figlegendr  	get_textsset_fontsizer   r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  ylimr  fix_axis_namesrB  rB  )Tposteriors_by_nameplot2DkdeParamsr  colors_by_nameline_stylesr<  r  figpositionr  hatches_by_nameZNpixelsr  r  r(  r'  ZxbinZybinr?  r  	name_listCSlstr)   r)  r+  r,  par_trigvalues1par_trigvalues2xdatydatr<   r=   r  r  ax2_namer  r  ZdenNxNyZxsortedZysortedZiminimaxr  r  ymaxyminZxmidZymidxaxyaxr   r   grid_coordsr  densortr  Nptszvaluesr!  ilevelCSpar1IFOspar2IFOsr9  r  r@  full_name_listdummy_lines	plot_namels_r   fig_actor_lsttwodcontour_legendr  r  r  r  r  raminramaxdecmindecmaxlocatorYr&   )r  r'    plot_two_param_kde_greedy_levelsh  sH   















 
 
 ,
 , 












  r6  c       !   	   C   s  ddl m} | \}}|| }|| }| | j}| | j}| | j}	| | j}
| | j}| | j}tjdd |dd tjdddd}|	t
|d	d	d
dg t  tt|t||}tt|t||}t||\}}tt||f}tj|}tj|dd|dddd}||j}|||}g }xNtD ]F}tt| d }|tkrHtd }tt|  ttt t!t qHW |" |"  }tj#||d |d |d |d f|dd t$  |	dk	r |
dk	r tj%|	g|
gdddd |dk	r|dk	rt&dd | D }t&dd | D }|'|}xd|D ]\}|dkrdd}n$|dkrtd}n|dkrd}nd}tj%|| g|| g|dddd  qPW t(t)| t*t)| t+  |, d!ks|, d"krt- \}} t-| | |S )#z
    Plots a 2D kernel density estimate of the 2-parameter marginal posterior.

    @param posterior: an instance of the Posterior class.

    @param plot2DkdeParams: a dict {param1Name:Nparam1Bins,param2Name:Nparam2Bins}
    r   )r  r  )r  r	   )r   r      )r<  r  g?g      ?gffffff?r  )r  g      ?rB  )extentaspectoriginNboF)r  r  c             S   s   g | ]}|qS r&   r&   )r;   r  r&   r&   r'   r>     s    z&plot_two_param_kde.<locals>.<listcomp>c             S   s   g | ]}|qS r&   r&   )r;   r  r&   r&   r'   r>     s    rx  r   ry  r   rz  r   r   r  )r@  r  r  r  r   r   ).r  r  r  r
  r  r  r   rF  rA  r  r  r  r   r  r  r  r  r  r   r  r  r/  r  Tr  r.  r%  r&  r$  ppr  ZXSZYSZZSZptpimshowcolorbarr  r  r  r  r   r  rH  rB  r  )!r)  r  r  r'  r(  r  r  r  r  Zpar_injvalue1Zpar_injvalue2r  r  r  r!  r"  r   r   r  r  r#  r  r  r!  r'  Zaspr)  r*  r9  r  r@  r  r  r&   r&   r'   plot_two_param_kdeH  sn    	






 


*


 
 
 (r@  c                s$   ddl }| fdd|  }|S )zV
    Filter injections to find the injection with end time given by time +/- 0.1s
    r   Nc                s   t tt|   dk S )Ng?)r|  r0  r(   )r<   )r   r&   r'   rC    rD  z!get_inj_by_time.<locals>.<lambda>)	itertoolsifilternext)Z
injectionsr   rA  r  r&   )r   r'   get_inj_by_time  s    rD  c             C   sn  |  \}}|| }|| }| |  j}| |  j}t| | j}	t| | j}
|	 }|
 }|	 }|
 }tt	|| | d }tt	|| | d }tj
|	|
||fdd\}}}t|}| }|  d}g }t|}t|d }xd|D ]\}xJt|t| |k rP|| }|d8 }|| }|}||7 }d||< qW || qW ||||fS )a  
    Returns a 2D histogram and edges for the two parameters passed in greedy2Params, plus the actual discrete confidence levels
    imposed by the finite number of samples.
       H,xedges,yedges,Hlasts = histogram2D(posterior,greedy2Params,confidence_levels)
    @param posterior: Posterior instance
    @param greedy2Params: a dict ;{param1Name:param1binSize,param2Name:param2binSize}
    @param confidence_levels: a list of the required confidence levels to plot on the contour map.
    r	   T)r"  r#  r   )r  rB  r  r   r,  r
  r  r  r.  r   histogram2dr  ravelr+  r  r   r0  r-  r/  )r)  r&  r  r'  r(  r)  r*  r+  r,  r<   r=   r-  r.  r/  r0  r1  r2  rH  xedgesyedgestempHsumHlastsidxesr3  r   r  rn  Hlastr&   r&   r'   histogram2D  s>    



rN  )   r   x   g333333?c	          
   C   sV  t jd||d}	t   |	| g }
g }| \}}x|  D ]\}}|| t|||dg \}}}}|d |d |d |d g}t j|dd |dd ||d|| gdd	}t j	|dd |dd ||d|| gd
}|
| q@W t 
d||f  t t| t t| t|t|
kr8tdg }g }x|D ]}|| t|dkrxX|dg D ]J}|tjtddgtddgdd |dtt|d   qnW dd |
D }|| qFW |dk	rFyt jt|t|ddd}W n$   t jt|t|dd}Y nX x| D ]}|d q2W tt || |	S )aZ  
    @param posteriors_by_name A dictionary of posterior objects indexed by name
    @param greedy2Params: a dict ;{param1Name:param1binSize,param2Name:param2binSize}
    @param confidence_levels: a list of the required confidence levels to plot on the contour map.
    @param colors_by_name: dict of colors, indexed by name
    @param figsize: figsize to pass to matplotlib
    @param dpi: dpi to pass to matplotlib
    @param figposition: figposition to pass to matplotlib
    @param legend: Legend position to pass to matplotlib
    @param hatches_by_name: dict of hatch styles, indexed by name
    r	   )r<  r  g?r   r  Nr  g333333?)r	  r  r   )r	  r  z*%s-%s confidence contours (greedy binning)zyError number of contour objects does not equal number of names! Use only *one* contour from each set to associate a name.g        g      ?r  )r@  z%s%%r;  c             S   s   g | ]}|j d  qS )r   )r  )r;   r   r&   r&   r'   r>   
  s    z7plot_two_param_greedy_bins_contourf.<locals>.<listcomp>rv  g?)r  r  )r  r  )rF  rA  r  r  r  r\  r/  rN  Zcontourfr  r  r  r   r  r   re  r  r  r   r   r  r.  r	  r
  r  r  r  r  )r  r&  r  r  r<  r  r  r  r  r?  r  r  r'  r(  r)   r)  rH  rG  rH  rK  r8  ZCS2r(  r+  r,  r-  r   r/  r0  r  r&   r&   r'   #plot_two_param_greedy_bins_contourf  sJ    

.,

* 
rQ  c             C   s  dS |  \}}|dk rd}|dt kr0dt }| || |  dksT|  dkrx|  \}}t|\}}	| ||	 |  dks|  dkr|  \}}t|\}}	| ||	 |  dks|  dkr|  \}
}|
dk rd}
|dt k rdt }| ||
 |  dks$|  dkrL|  \}}t|\}}	| j||	dd	 |  dksh|  dkr|  \}}t|\}}	| j||	dd	 | S )
z
    Fixes names of axes
    Nr   r   g        g       @r   r   -   )Zrotation)rB  r  rB  Zyticksr  r  r  Zxticks)rF  r'  r(  r   r  r  r  Zticksr  Znewticksr  r  r&   r&   r'   r    s@         r  c	       F   	      s  t jd||d}	t   |	|}
t|t|k r:tdg }g }x|  D ]\}}|| | \}}|| }|| }||	  j
}||	  j
}||	  j}||	  j}t|| j}t|| j}| }| }| }| }tt|| | d }tt|| | d }|ddkrjtt|}|| }|rX|| }|dt|  } n|} |ddkrtt|}|| }|r|| }|dt|  }!n|}!tdd d	d
  _tdd}"dd
 |"_ d |"d |
j  |
j|" tj||||fdd\}#}$}%|$d |%d |$d |$d g}&t|#}'|' }'|  d}(g })t|'}*t|*d }+xd|D ]\},xJt |(t!|# |,k r|*|+ }-|+d8 }+|'|- }.|.}/|(|.7 }(d|'|-< qW |)|/ qW t j"|%dd |$dd |#|)|| g|d}0t #  |dk	rB|dk	rBt j$|g|gddddd |dk	r|dk	rt%dd | D }1t%dd | D }2|1&|2}3t'dkrd}4n$t'dkrd}4nt'dkrd}4nd}4t j$|t' g|t' g|4dddd ||0 tt( fd d
|
) }5|5d!krd"}6n$|5d#kr&d$}6n|5d$kr6d#}6nd%}6t*j+j,|6d d&}7|d'ks`|d(kr~t - \}8}9t.|8|9d)}7t/  |d*ks|d+krt - \}:};t0|:|;d)}7t1  |
j  |d'ks|d(krt 2 \}8}9t.|8|9}<|
j3|< t/ }"|d*ks|d+kr6t 2 \}:};t0|:|;d)}<t1 }"|
j3|< |
j|" |
j3|7 qNW t 4t5|! t 6t5|  t|t|krtd,g }=g }>x|D ]}?|=|? qW t|dkr$xjt7|dt| |D ]P\}@},|>t8j9t:d-d.gt:d-d.g|@d/d0 |=d1t;t|,d2   qW d3d |D }A|A<|> |dk	ryt j=t>|At>|=d4d5d6}BW n$   t j=t>|At>|=d4d7}BY nX x|B? D ]}C|C@d8 qW |	 d(ks|	 d'kr t - \}D}E|Dd-k rd-}D|Ed9tA krd9tA }Et -|E|D |	S ):a(  
    Plots the confidence level contours as determined by the 2-parameter
    greedy binning algorithm.

    @param posteriors_by_name: A dict containing Posterior instances referenced by some id.

    @param greedy2Params: a dict ;{param1Name:param1binSize,param2Name:param2binSize}

    @param confidence_levels: a list of the required confidence levels to plot on the contour map.

    @param colors_by_name: A dict of colors cross-referenced to the above Posterior ids.

    @param legend: Argument for legend placement or None for no legend ('right', 'upper left', 'center' etc)

    @param line_styles: list of line styles for credible regions

    @param figsize: figsize to pass to matplotlib

    @param dpi: dpi to pass to matplotlib

    @param figposition: figposition to pass to matplotlib

    r	   )r<  r  zTError: Need as many or more line styles to choose from as confidence levels to plot!r   r  z + %iT)r  c             S   s   d|  S )Nz%.4gr&   )r  r&   r&   r'   rC    rD  z4plot_two_param_greedy_bins_contour.<locals>.<lambda>c             S   s   d|  S )Nz%.4gr&   )r  r&   r&   r'   rC    rD  )r"  r#  r   N)r  r  zb*Fr  )r  r  rE  c             S   s   g | ]}|qS r&   r&   )r;   r  r&   r&   r'   r>     s    z6plot_two_param_greedy_bins_contour.<locals>.<listcomp>c             S   s   g | ]}|qS r&   r&   )r;   r  r&   r&   r'   r>     s    rx  r   ry  r   rz  r   r   rB  )r@  r  r  r  c                s   t  | S )N)r   r  )r  )r  r&   r'   rC    rD  r   r   r   r   r   )r  r   r   )r  r  r   r   zyError number of contour objects does not equal number of names! Use only *one* contour from each set to associate a name.g        g      ?r  )r  r@  z%s%%r;  c             S   s   g | ]}|j d  qS )r   )r  )r;   r   r&   r&   r'   r>     s    rv  g?)r  r  )r  r  g       @)BrF  rA  r  r  r   re  r\  r/  r  rB  r  r  r   r,  r
  r  r  r.  r   r  r   r   r  r  r  r  r  rE  r  rF  r+  r  r0  r-  r  rH  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r   r  r]  r  r  r   r  r	  r
  r  r  r  rB  )Fr  r&  r  r  r  r<  r  r  r  r?  r  r  r  r)   r)  r'  r(  r)  r*  r+  r,  par1_trigvaluespar2_trigvaluesr<   r=   r-  r.  r/  r0  r1  r2  r  r  r  r  rH  rG  rH  r8  rI  rJ  rK  rL  r3  r   r  rn  rM  r(  r)  r*  r9  r@  r  r  r  r1  r2  r3  r4  r5  r+  r,  r-  r.  r/  r0  r  r  r  r&   )r  r'   "plot_two_param_greedy_bins_contour:  s   










,

 
 
 "





 , 


  
rU  c       2         st  ddl m} tjdd |dd | \}}|| }|| }t| | j}t| | j}	| |  j}
| |  j}| }|	 }|	 }|		 }t
t|| | d }t
t|| | d }|ddkrtt|}|| }|
r|
| }
|dt
|  }n|}|ddkrTtt|	}|	| }	|rB|| }|dt
|  }n|}| |  j}| |  j}t }t|d	d	d
dg}|| tt| tt| d}tdd dd  _tdd}dd |_ d |d |j  |j| tj||	|dd\}}}t|}| }d}t|} t |}!t!|!d }"xV|| k r|!|" }#|"d8 }"||# }$|t
|$7 }d||#< dt"|t"|   |j#|#< q^W |d |d |d |d g}%tj$t%||d|%ddd t& '  t(  t	t) fdd|* }&|&dkr*d}'n$|&dkr:d}'n|&dkrJd}'nd}'t+j,j-|'d d}(t. \})}*t/ \}+},|dks|d krt0|)|*d!}(t1  |d"ks|d#krt2|)|*d!}(t3  |dks|d krt0|+|,d!}-|j4|- t1 }|d"ks
|d#kr(t2|+|,d!}-|j4|- t3 }|j  |j| |j4|( |
d$k	rx|d$k	rxtj5|g|
gd%ddd& |d$k	r|d$k	rt6d'd( | D }.t6d)d( | D }/|.7|/}0t8d*krd+}1n$t8d,krd-}1nt8d.krd/}1nd0}1tj5|t8 g|t8 g|1d1ddd2 | d ks4| dkrpt. \})}*|)d3k rNd3})|*d4t9 krdd4t9 }*t.|*|) |S )5aX  
    Histograms of the ranked pixels produced by the 2-parameter greedy
    binning algorithm colured by their confidence level.

    @param posterior: an instance of the Posterior class.

    @param greedy2Params: a dict ;{param1Name:param1binSize,param2Name:param2binSize}

    @param confidence_levels: list of confidence levels to show
    r   )r  r  )r  r	   r   r  z + %ig333333?g?g433333?)r  r  T)r  c             S   s   d|  S )Nz%.4gr&   )r  r&   r&   r'   rC  c  rD  z1plot_two_param_greedy_bins_hist.<locals>.<lambda>c             S   s   d|  S )Nz%.4gr&   )r  r&   r&   r'   rC  e  rD  F)r#  r  ZnearestZgray_r)r  r9  r8  interpolationr>  c                s   t  | S )N)r   r  )r  )r  r&   r'   rC    rD  r   r   r   r   r   )r  r   r   )r  r  r   r   Nr;  )r  r  c             S   s   g | ]}|qS r&   r&   )r;   r  r&   r&   r'   r>     s    z3plot_two_param_greedy_bins_hist.<locals>.<listcomp>c             S   s   g | ]}|qS r&   r&   )r;   r  r&   r&   r'   r>     s    rx  r   ry  r   rz  r   r   r  )r@  r  r  r  g        g       @):r  r  r   r  r,  r
  rB  r  r  r  r.  r   r  r   r  rF  rA  r  r  r  r   r  r   r  r  r  r  r  rE  r  r  r-  r  r   r0  rg  r>  ZflipudZgcaZautoscale_viewr?  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  rB  )2r)  r&  r  r  r'  r(  r)  r*  r<   r=   r+  r,  r-  r.  r/  r0  r1  r2  r  r  r  rS  rT  r  r  r"  r  rH  rG  rH  rI  rJ  ZHsum_actualrL  r3  r  rn  r8  r  r  r  r  r  r   r  r5  r)  r*  r9  r@  r&   )r  r'   plot_two_param_greedy_bins_hist  s    










 




 
 
 "
  
rW  c          	   C   s  t | d }t | d }| |  j}t|d }t|d }|}tt|| | d }	t	
|	df}
t	j
|	dd}x0t|	D ]$}||
|df< ||
|df< ||7 }qW xf|D ]^}|d }tt|| | }y||  d7  < W q tk
r   td||	|f  Y qX qW d}| | j}|r@t|| | }|}t||
|t|tt||\}}}}g }|  x|D ]}t	|dddf |k }t|d dkr|t	||df t	||df f n&|||d df ||d df f qxW |||||fS )	a;  
    Determine the 1-parameter Bayesian Confidence Interval using a greedy
    binning algorithm.

    @param posterior: an instance of the posterior class.

    @param greedy1Param: a dict; {paramName:paramBinSize}.

    @param confidence_levels: A list of floats of the required confidence intervals [(0-1)].
    r   r	   rB   r$  )r%  z6IndexError: bin number: %i total bins: %i parsamp: %f Nr  )r  r  r  rB  r
  r  r  r.  r   r   r,  r   r   r  rb  r  r  r0  r   r+  r  r/  )r)  Zgreedy1Paramr  	paramNamepar_bin	par_samps
parpos_min
parpos_max	par_pointparpos_Nbinsr  r  rE   par_samppar_binNumberr4  par_injvaluer  r  r  r  cl_intervalsr   r  r&   r&   r'   greedy_bin_one_param  sF    

&
,,rc  c             C   s  i }i }t | d }t | d }| | j}| | j}t|}	t|}
|	}tt|
|	 | d }t	j
|dd}x||D ]t}tt||	 | }y||  d7  < W q| tk
r   td|||t|d df t|d df | f  Y q|X q|W d}|rt||	 | }|}d}t|}d}x|t|k r|| }d}d}xtt|D ]}d}d}|}xr|t|k rt||| }t|t| }|dkr|}|}|}n||kr|}|}|}|d7 }|d7 }qdW |dk	r|dkr|t||kr|| | }||d< d| |d< ||kr&P d}qRW |dkrHtd	|  nh|| |d
< || |d< || | |d< |}x:|d t|k r||d  |k r|d7 }|d7 }qvW |d7 }q&W ||fS )a-  
    Calculates the smallest contigious 1-parameter confidence interval for a
    set of given confidence levels.

    @param posterior: an instance of the Posterior class.

    @param contInt1Params: a dict {paramName:paramBinSize}.

    @param confidence_levels: Required confidence intervals.

    r   r	   r$  )r%  zBIndexError: bin number: %i total bins: %i parsamp: %f bin: %f - %fNr1  
confidencez*Cant determine intervals at %f confidence!ru  rv  width)r  r  r  r  r
  r  r  r.  r   r   r,  r   r  rb  r  r   r   r-  r0  )r)  ZcontInt1Paramsr  Z
oneDContCLZoneDContInjrX  rY  ra  rZ  r[  r\  r]  r^  r  r_  r`  r4  r3  Zlen_par_sampsZinjintervalr  Zmax_leftZ	max_rightrE   Zmax_fracru  rv  ZNpointsr  r  r&   r&   r'   contigious_interval_one_param  s    


$




rf  c             C   s   t | |||\}}||fS )N)Z_burnin)r  Z	spin_flag	deltaLogPZ
outputfiler  bayesfactorr&   r&   r'   burnin  s    ri  c                   s   e Zd Z fddZ  ZS )ACLErrorc                s   t t| j|  d S )N)superrj  r   )r   r  )	__class__r&   r'   r     s    zACLError.__init__)r4  r5  r6  r   __classcell__r&   r&   )rl  r'   rj    s   rj  c             C   s\   | t |  }t |ddd }t jtj||dd}| jd }|d| }||d  S )zReturns an estimate of the autocorrelation function of a given
    series.  Returns only the positive-lag portion of the ACF,
    normalized so that the zero-th element is 1.Nr  full)r  r   )r   r   ZconjZfftZ	ifftshiftr   Zfftconvolver_  )seriesr   r   acfr2  r&   r&   r'   autocorrelation  s    
rq  c             C   s   |dkrt | }|dd  d9  < t|jd | }t|}td|jd d t| }t|d| |d| k }|jd dkr||d  S tddS )a  Attempts to find a self-consistent estimate of the
    autocorrelation length of a given series.

    If C(tau) is the autocorrelation function (normalized so C(0) = 1,
    for example from the autocorrelation procedure in this module),
    then the autocorrelation length is the smallest s such that

    1 + 2*C(1) + 2*C(2) + ... + 2*C(M*s) < s

    In words: the autocorrelation length is the shortest length so
    that the sum of the autocorrelation function is smaller than that
    length over a window of M times that length.

    The maximum window length is restricted to be len(series)/K as a
    safety precaution against relying on data near the extreme of the
    lags in the ACF, where there is a lot of noise.  Note that this
    implies that the series must be at least M*K*s samples long in
    order to get a reliable estimate of the ACL.

    If no such s can be found, raises ACLError; in this case it is
    likely that the series is too short relative to its true
    autocorrelation length to obtain a consistent ACL estimate.Nr	   g       @r   z8autocorrelation length too short for consistent estimate)	rq  r.  r_  r   rO  aranger0  Zflatnonzerorj  )ro  rp  MKr  ZcacfsZ	estimatesr&   r&   r'   autocorrelation_length_estimate  s    
rv  c             C   sx   t | }t| t|d d }y t| t|d d |d}W n tk
rX   |}Y nX t|| }||9 }|||fS )z
    Compute the effective sample size, calculating the ACL using only
    the second half of the samples to avoid ACL overestimation due to
    chains equilibrating after adaptation.
    rB   N)rp  )r   rq  r.  rv  rj  r   )r
  Nskipr2  rp  aclZ
Neffectiver&   r&   r'   effectiveSampleSize  s     
ry  c       
         s   d }ddl m} ddl m} ddl m} |j| ||jd}|j|}|j	|}|j
|}	|t|krtd|tttf n2|d|   fdd	|D fd
d	|	D }|S )Nr   )ligolw)	lsctables)utils)contenthandlerzAError: You asked for trigger %d, but %s contains only %d triggerscoinc_event_idc                s   g | ]}|j  kr|jqS r&   )r~  event_id)r;   r  )coincEventIDr&   r'   r>     s    z readCoincXML.<locals>.<listcomp>c                s   g | ]}|j  kr|qS r&   )r  )r;   r  )eventIDsr&   r'   r>     s    )ligo.lwrz  r{  r|  load_filenameuse_inLIGOLWContentHandlerZ
CoincTable	get_tableZCoincMapTableZSnglInspiralTabler   re  Z	coincfileZtiggersZgetColumnByName)
Zxml_fileZtrignumr  rz  r{  r|  ZcoincXMLZcoincZcoincMapZ	snglInspsr&   )r  r  r'   readCoincXML  s    r  c          '      s  |dkrt d dddg}xVtdD ]H}xBtjD ]8}|| d t|  || d t|  q4W q(W d	d
ddddddddddddddddddddddd d!d"d#d$d%d&d'd(d)d*d+d,dd-g't t	 |  fd.d/j
D }t d0t|   |  fd1d/j
D }td d2 }tfd3d/|D }|ddd2f }	t|	}
|ddd4f }t|}|| }t d5|| || f  d4}|dk	rt|kr|tt| 9 }t|}n8|
}|d4krt|krttt| }ntj}|S )6z
    Given a list of files, threshold value, and a desired
    number of outputs posterior samples, return the skip number to
    achieve the desired number of posterior samples.
    NzMax ACL(s):
spcal_nptsspcal_activeconstantcal_active   Z_spcal_freq_Z_spcal_logfreq_r9   r  r  	timestampsnrh1snrl1snrv1margtimemargtimephitime_maxtime_minr   	time_maxl	sky_framepsdscaleflag	logdeltafr   r   rP  lal_pnorderlal_approximanttideospinosignalmodelflagtemperaturenifonlocaltempsntemps
randomseed
sampleratesegmentlengthsegmentstartr   r   azimuthcosalphar   c                s,   g | ]$ t  fd d  D r qS )c             3   s   | ]}|  d  kV  qdS )r   Nr&   )r;   r   )r  r
  r&   r'   	<genexpr>  s    z.find_ndownsample.<locals>.<listcomp>.<genexpr>)r  )r;   )r
  )r  r'   r>     s    z$find_ndownsample.<locals>.<listcomp>zFixed parameters: c                s   g | ]}|   kr|qS r&   )rB  )r;   r  )	nonParamsr&   r'   r>     s    r   c                s&   g | ]}t t | d d qS )NrB   )r   r   ry  )r;   r   )r
  r&   r'   r>     s    r	   z%i (%s).)rb  r   rr  r   r   r/  rB  r  	logParams	snrParamsr+   r	  diffr   r  rs  r   r   r.  r   r   )r
  nDownsamplesplineParamsrE   r  ZfixedParamsr  strider  nEffsZ
nEffectiveACLs	maxACLindmaxACLnskipnEffr&   )r  r
  r'   find_ndownsample  s>    

"^




r  c               @   s   e Zd ZdZdd Zdd Zd-dd	Zd.d
dZdd Zdd Z	dd Z
dd Zdd Zdd Zd/ddZd0ddZdd Zdd  Zd!d" Zd#d$ Zd1d%d&Zd2d'd(Zd3d)d*Zddgfd+d,ZdS )4r  z
    A parser for the output of Bayesian parameter estimation codes.

    TODO: Will be abstract class when LDG moves over to Python >2.6,
    inherited by each method .
    c             C   s   |dkr| j | _n|dkr$| j| _nx|dkr6| j| _nf|dkrH| j| _nT|dkrZ| j| _nB|dkrl| j| _n0|dkr~| j| _n|dkr| j| _nt	d	| d S )
NZmcmc_burninnsr  fmZinf_mcmcxmlZhdf5Zhdf5sz!Invalid value for "inputtype": %r)
_mcmc_burnin_to_pos_parser
_ns_to_pos_common_to_pos_followupmcmc_to_pos_infmcmc_to_pos_xml_to_pos_hdf5_to_pos_hdf5s_to_posr%  )r   Z	inputtyper&   r&   r'   r   /  s"    







zPEOutputParser.__init__c             K   s   | j |f|S )z
        Parse files.
        )r  )r   fileskwargsr&   r&   r'   parseC  s    zPEOutputParser.parseNFc          	   K   s  |dk	rv|dk	rt d t|dkrRt|dkrRt d tt|d|d  }nt|t|krjtdt d| ntt|}tj }|dk	r| }t d	| | ||||}	|dkr@t d
 t|	dkrt|	d rt d | |||d}	nFxDt	t|	D ]4}
t|	|
 r&t d nt d|	d d|d qW |dkrNd}t
j|d}d}t|d}t|d}z| ||||||	| W d|  |  X | t|dS )z9
        Parser for lalinference_mcmcmpi output.
        Nz=Warning: using deltaLogP criteria in addition to fixed burninr	   z\Only one fixedBurnin criteria given for more than one output.  Applying this to all outputs.r.  r   zHInconsistent number of fixed burnin criteria and output files specified.zFixed burning criteria: z+Eliminating any samples before log(Post) = zHDownsampling to take only uncorrelated posterior samples from each file.z^WARNING: All samples in chain are correlated.  Downsampling to 10000 samples for inspection!!!i'  z/%s eliminated since all samples are correlated.zDownsampling by a factor of z to achieve approximately z posterior samplesr  zlalinfmcmc_headers.datzposterior_samples.datr  r   )rb  r   r   onesre  r,  inf_find_ndownsampler  r   rJ  rK  rL  r  !_infmcmc_output_posterior_samplesr  r  )r   r  rM  rg  fixedBurninsr  oldMassConventionr  logPThresholdnskipsrE   ZrunfileNameZpostNamerunfileoutfiler&   r&   r'   r  I  sF    






zPEOutputParser._infmcmc_to_posc          	      sX  d}d}	d}
|dkr$t t|d}xt|tdt|d ||D ]\}}}}t|d}ztd||jf   |\}}|	dt
| d	  || td
||jf  d}d|krd} |}|r fdd|D }|	s<x |D ]}|	| |	d qW |r|	d |	d |	d |	d |}	|d}|d}d}x|D ]}| }| }t|| }t|| }||kr||krd}|rZ|| dkrx,|	D ]$}|	|||  |	d qW |r|	| |	d |	t
| |	d |d }qZW |r.|
d7 }
W d|  X qDW td|
t|f  dS )z
        Concatenate all the samples from the given files into outfile.
        For each file, only those samples past the point where the
        log(post) > logPThreshold are concatenated after eliminating
        fixedBurnin.
        r   FNr.  r	   r   zWriting header of %s to %szChain z:
zProcessing file %s to %sr   Tc                s   g | ]}  |qS r&   )_swaplabel12)r;   r   )r   r&   r'   r>     s    zDPEOutputParser._infmcmc_output_posterior_samples.<locals>.<listcomp> r  r  r  r9   r  z%i of %i chains accepted.)r   r  r   r]  r   r  rb  r)   _clear_infmcmc_headerr  r  
writelines_find_infmcmc_f_refr*   lstripr  r.  r0  r  )r   r  r  r  r  r  r  r  ZnReadZoutputHeaderZacceptedChainsZ
infilenamerE   r  fixedBurnininfilerunInfor  Z
write_frefr   r   	iterindex	logpindexoutputlineZ
lineParamsiterr?  r&   )r   r'   r  v  sl    .















 z0PEOutputParser._infmcmc_output_posterior_samplesc             C   sH   |d dkr|dd d S |d dkr8|dd d S |d d  S d S )Nr  1r   2r&   )r   r   r&   r&   r'   r    s
    zPEOutputParser._swaplabel12c       
   	   C   s   t j }xp|D ]h}t|d}zN| |\}}|d}x0|D ](}|  }t|| }	|	|kr<|	}q<W W d|  X qW t	d| |S )zR
        Given a list of files, reads them, finding the maximum log(post)
        r   r9   NzFound max log(post) = )
r   r  r  r  r*   r  r  r0  r  rb  )
r   r  ZmaxLogPinpnamer  r  r  r  r  r?  r&   r&   r'   _find_max_logP  s    




zPEOutputParser._find_max_logPc       $   %      s  t |}g }g }|dkr td xt||D ]\}}	t|d}
z| |
\} dd  D   d} d}d}d}d	}g }d
}x|
D ]|}|  }t|| }t	|| }||	krd	}n|rd}d
}g }||krd	}|d
krd}|r|r|s|d7 }|
| qW |
| |dkrydddg}xPtdD ]B}x:dD ]2}|
|d t|  |
|d t|  qHW q>W ddddddddddddddddd d!d"d#d$d%d&d'd(d)d*d+d,d-d.d/d0d1d2d3g$t t | } fd4d|D t|t	ttjd
d5tjd
d5 d6kd
 }| fd7dtt  D }d|f d
|f  }tfd8d|D }|ddd
f }|
t| |dddf }t|} ||  }!||  } td9||!  |  |f  W n"   |
d td:|  Y nX W d|
  X q.W t|}"t|}|dk	rR||kr|"tt|| 9 }"nVxTt|D ]H}|| }#|| }|#dkr||#krtt||# |"|< nd|"|< q\W |"S );z
        Given a list of files, threshold value, and a desired
        number of outputs posterior samples, return the skip number to
        achieve the desired number of posterior samples.
        NzMax ACL(s):r   c             S   s   g | ]}|  qS r&   )rB  )r;   r)   r&   r&   r'   r>     s    z4PEOutputParser._find_ndownsample.<locals>.<listcomp>r9   r  FTr   r	   r  r  r  r   )r?   r@   Z_spcal_freqZ_spcal_logfreqr  r  r  r  r  r  r  r  r   r  r  r  r  r   r   rP  r  r  r  r  r  r  r  r  r  r  r  r  r  r   r   r  r  c                s   g | ]}| kr  |qS r&   )r*   )r;   r)   )r  r&   r'   r>     s    )r  g        c                s   g | ]}| kr|qS r&   r&   )r;   rE   )nonParamsIdxsr&   r'   r>     s    c                s.   g | ]&}t t d d |f d d qS )NrB   )r   r   ry  )r;   rE   )r  r&   r'   r>     s    z%i (%s) for chain %s.z,Error computing effective sample size of %s!)r   rb  r]  r  r  r*   r  r  r.  r0  r/  r   rr  r  r  r  r   astyper  ZaminZamaxr	  r   r  rs  r  r  r-  r   r   )$r   r  ZlogPthresholdr  r  ZnfilesZntotsZnEffectivesr  r  r  r  r  r  ZdeltaLburnedInZfixedBurnedInZadaptingr   Zntotr  r  r?  r  rE   r  r  Z	fixedIdxsZ	paramIdxsr  r  r  r  r  r  r  r  r&   )r  r  r  r'   r    s     







"X*







z PEOutputParser._find_ndownsamplec       	   	   C   s  d}t |}x`|D ]X}|   }y,|d}|    }|d }P W q tk
rh   wY qX qW |st |}xv|D ]n}|   }yB|d dkry|dd }|| }W n tk
r   Y nX P W q tk
r   wY qX qW |s| |}|S )z
        Searches through header to determine reference frequency of waveforms.
        If no fRef given, calls _find_infmcmc_f_lower to get the lower frequency
        bound, which is the default reference frequency for LALInference.
        Nr   r  r   commandz--frefr	   )	r  r  rB  r  r*   rC  r%  r  _find_infmcmc_f_lower)	r   r  fRefZrunInfoIterr  r  Z
fRefColNuminfoZfRefIndr&   r&   r'   r  4  s8    



z"PEOutputParser._find_infmcmc_f_refc          	   C   sn   t |}x`|D ]X}|   }y,|d}|    }|| }P W q tk
rd   wY qX qW |S )zz
        Searches through header to determine starting frequency of waveforms.
        Assumes same for all IFOs.
        Zf_low)r  r  rB  r  r*   rC  r%  )r   r  r  r  Z
flowColNumZIFOinfor  r&   r&   r'   r  ]  s    

z$PEOutputParser._find_infmcmc_f_lowerc          	   C   sl   g }xV|D ]F}| | |   }y|d P W q
 tk
rN   w
Y q
X q
W td|dd |fS )z}
        Reads lalinference_mcmcmpi file given, returning the run info and
        common output header information.
        r  z9couldn't find line with 'cycle' in LALInferenceMCMC inputNr  )r/  r  rB  r  r*   r%  re  )r   r  r  r  r  r&   r&   r'   r  n  s    


z$PEOutputParser._clear_infmcmc_headerc             C   s2   t |dk	r.tt||d\}}| tddS dS )z0
        Parser for SPINspiral output .
        Nzposterior_samples.datr   )NotImplementedErrorri  r  r  r  )r   r  spinrg  r  rh  r&   r&   r'   r    s    z"PEOutputParser._mcmc_burnin_to_posposterior_samples.datc          	      s  yddl m}m} W n tk
r2   td  Y nX  dkrDtdt|}| dd }t	j
|rtd|  t	|t	jrt|d	}	|	 d
 }
W dQ R X qtd| nd}
|
 }dx(tt|D ]}||  dkr|qW dkr
td|
  ttttj|}|dkrP|| fdd|D fdd|D d}n,|| fdd|D |fdd|D d}t|dH}||
 x6|D ].}x|D ]}|d|  qW |d
 qW W dQ R X t|d	}| |}W dQ R X |S )a	  
        Parser for nested sampling output.
        files : list of input NS files
        Nlive : Number of live points
        Npost : Desired number of posterior samples
        posfilename : Posterior output file name (default: 'posterior_samples.dat')
        r   )draw_N_posterior_manydraw_posterior_manyz=Need lalinference.nest2pos to convert nested sampling output!NzGNeed to specify number of live points in positional arguments of parse!z.gzz_params.txtzLooking for r   r  zCannot open parameters file %s!zNmchirp 	 eta 	 time 	 phi0 	 dist 	 RA 	             dec 	 psi 	 iota 	 logl 
r  r5   z7Error! Could not find logL column in parameter list: %sc                s   g | ]} qS r&   r&   )r;   r}  )Nliver&   r'   r>     s    z-PEOutputParser._ns_to_pos.<locals>.<listcomp>c                s   g | ]} qS r&   r&   )r;   r}  )logLcolr&   r'   r>     s    )ZlogLcolsc                s   g | ]} qS r&   r&   )r;   r}  )r  r&   r'   r>     s    c                s   g | ]} qS r&   r&   )r;   r}  )r  r&   r'   r>     s    r  z%10.12e	)Zlalinference.nest2posr  r  r  rb  re  r  rC  r  rJ  rK  isfileaccessR_OKr  r  r  r   r   rB  r  r  r   r  r  r  )r   r  r  ZNpostZposfilenamer  r  itZparsfilenameZparsfileZoutparsZparsvecrE   Zinarraysr  Zposfiler  r8  r&   )r  r  r'   r    sJ    

,,


zPEOutputParser._ns_to_posc             C   s   | j t|d dddS )z1
        Parser for followupMCMC output.
        r   r   r  )r  )r  r  )r   r  r&   r&   r'   r    s    z#PEOutputParser._followupmcmc_to_posc             C   s   |  t|d dS )z.
        Parser for MultiNest output.
        r   r   )r  r  )r   r  r&   r&   r'   _multinest_to_pos  s    z PEOutputParser._multinest_to_posc                s   ddl m  d}y
 j}W n  tk
r:    fdd}Y nX |d|   }|| |d| }x$|D ]}|dd	krl| |S qlW xD|D ]<}|dd
krdd |d| D d }| t|S qW t	d| dS )z.
        Parser for VOTable XML Using
        r   )ElementTreez$http://www.ivoa.net/xml/VOTable/v1.1c                s   |  j |< d S )N)_namespace_map)prefixuri)ETr&   r'   register_namespace  s    z6PEOutputParser._xml_to_pos.<locals>.register_namespacevotz.//{%s}TABLEutypez%lalinference:results:posteriorsamplesz"lalinference:results:nestedsamplesc             S   s   g | ]}| d dkr|qS )r  zlalinference:results)get)r;   noder&   r&   r'   r>     s    z.PEOutputParser._xml_to_pos.<locals>.<listcomp>z{%s}RESOURCEzBCannot find "Posterior Samples" TABLE element in XML input file %sN)
	xml.etreer  r  r  r  findallr  _VOTTABLE2posvo_nest2posre  )r   r  r  r  r  Ztablesr.   
nsresourcer&   )r  r'   r    s$    




zPEOutputParser._xml_to_posc       
   	      s  ddl m  dy
 jW n$ tk
r>    fddY nX g }x&|d D ]}||jd  qTW t|dkrtd|d	 }|d 	d
 }g }x*|D ]"}|t
ttdd | qW t
|}xtdt|D ]}	||	  	ddkr||	  tkrtdd||	  dd |D kr||	  tkrtd||	   t
|dd|	f |dd|	f< tjdd||	 tjd||	< ||	  	ddkr.tdd||	  dd |D kr.td||	   t
|dd|	f |dd|	f< tjdd||	 tjd||	< ||	  	ddkrtdd||	  dd |D krtd||	   t
|dd|	f |dd|	f< tjdd||	 tjd||	< ||	 dd||	< ||	 dd||	< qW tdt|  ||fS )zS
        Parser for a VOT TABLE element with FIELDs and TABLEDATA elements
        r   )r  z$http://www.ivoa.net/xml/VOTable/v1.1c                s   |  j |< d d S )Nr  )r  )r  r  )r  r  r  r&   r'   r    s    
z8PEOutputParser._VOTTABLE2pos.<locals>.register_namespacez./{%s}FIELDr)   z9Unable to find FIELD nodes for table headers in XML tablez
./{%s}DATAz./{%s}TABLEDATAc             S   s
   t | jS )N)r0  r  )r<   r&   r&   r'   rC    rD  z.PEOutputParser._VOTTABLE2pos.<locals>.<lambda>rR  r  r  c             S   s   g | ]}|  qS r&   )rB  )r;   r{  r&   r&   r'   r>     s    z0PEOutputParser._VOTTABLE2pos.<locals>.<listcomp>zexponentiating %sN)flagsr6  c             S   s   g | ]}|  qS r&   )rB  )r;   r{  r&   r&   r'   r>     s    z
asining %sr   c             S   s   g | ]}|  qS r&   )rB  )r;   r{  r&   r&   r'   r>     s    z
acosing %s()zRead columns %s)r  r  r  r  r  r/  r  r   re  r  r   r   r  r  r   rB  r  resub lorentzInvarianceViolationParamsrb  r  
IGNORECASEarcsinr:  r&  r  )
r   r.   r  fieldr  Z	tabledatallinesr  flinesrE   r&   )r  r  r  r'   r    sD    

"
b">">"zPEOutputParser._VOTTABLE2posc          	   K   s  ddl m} |d kr"tt|}t|dkr2d}g }	xjtt||D ]X\}
\}}| j|f|||||d|}|t	j
j|
tt| dd |	| qFW |d k	rtj }x0|	D ](}t|dkrt|t|d | g}qW td	| xlt|	D ]`\}
}|d k	rHtt||d |k }t|dkr>|d nt|}nd}||d  |	|
< qW ||	}|d k	rt||}|d d | }|jt|td
t|jfS )Nr   )vstackr	   T)r  rg  r  multiple_chains	tablenamer  )r)   r9   z*Eliminating any samples before log(L) = {}r  )astropy.tabler  r   r,  r   r  r]  _hdf5_to_tabler,   r-   r.   r/   r  r/  r  r  rb  formatrr  r  r+   r3   viewr0  r  r  )r   infilesr  rg  r  r  r  r  r  r!  rE   r  r  r  r  Zabove_threshold
burnin_idxr
  r  r&   r&   r'   r  "  s6    $

 

zPEOutputParser._hdf5s_to_posc             K   s  |st |td}nt ||d}|j}	x|	D ]}
|
 }|ddkr|tkrtdd|dd |	D kr|tkrt	d|
  tjdd|
tj
d}t||
 ||< ||
= |}
|d	dkrtd	d|d
d |	D krt	d|
  tjd	d|
tj
d}t||
 ||< ||
= |}
|ddkrtdd|dd |	D krt	d|
  tjdd|
tj
d}t||
 ||< ||
= |}
|
|
ddkr||
|
dd |
|
ddkr||
|
dd t||
||
 t q,W |j}	t	dt|	  d|	kr|dk	r2|dk	r&t	d t	d| nd}tt||d |k }t|dkrf|d nt|}||d }tj }t|dkr|dk	rt|d | }t	d| tt||d |k d }||d }t|dkrt||}|dkr<t	d t|r|st	d t|d}|dd| }nFt|rdt	d| |dd }nt	d|d|d |dd| }|S ) z
        Parse a HDF5 file and return an array of posterior samples ad list of
        parameter names. Equivalent to '_common_to_pos' and work in progress.
        )r  rR  r  r  c             S   s   g | ]}|  qS r&   )rB  )r;   r  r&   r&   r'   r>   W  s    z1PEOutputParser._hdf5_to_table.<locals>.<listcomp>zexponentiating %s)r  r6  c             S   s   g | ]}|  qS r&   )rB  )r;   r  r&   r&   r'   r>   ]  s    z
asining %sr   c             S   s   g | ]}|  qS r&   )rB  )r;   r  r&   r&   r'   r>   c  s    z
acosing %sr  r  zRead columns %sr  Nz=Warning: using deltaLogP criteria in addition to fixed burninzFixed burning criteria: r   r9   z+Eliminating any samples before log(post) = zHDownsampling to take only uncorrelated posterior samples from each file.z^WARNING: All samples in chain are correlated.  Downsampling to 10000 samples for inspection!!!i'  z*WARNING: All samples in {} are correlated.zDownsampling by a factor of z to achieve approximately z posterior samples)r
   posterior_grp_namer+   rB  r  r  r  r  r  rb  r  r   r  r	  r:  r&  Zrename_columnr2   r  r0  r  rr  r   r  r  r  r  r  )r   r  rg  r  r  r  r  r  r
  r  r   Z	param_low	new_paramZburned_in_cyclesr  r  r  r&   r&   r'   r  J  sx    :..






zPEOutputParser._hdf5_to_tablec             K   s>   | j |f||||d|}|jt|tdt|jfS )N)r  rg  r  r  r  )r  r+   r3   r  r0  r  r   r  )r   r  r  rg  r  r  r  r
  r&   r&   r'   r    s    zPEOutputParser._hdf5_to_posc             C   s  |\}}|dkr|   }nt|d}|   }|  |dd}|dd}||}|d d|d< t|}g }	t	d}
xt
|D ]\}}||}|d dkr|d= d	}t|d
k rtd|  d}n,t||krtjd|t||f  d}xXt
|D ]L\}}|dd}|
|dkrHtd|||f  d}n|dkrd}qW |r|	ttt| qW t|	}| stdx
tdt|D ]}||  ddkr\||  tkr\tdd||  dd |D kr\||  tkr\td||   t|dd|f |dd|f< tjdd|| tjd||< ||  ddkrtdd||  dd |D krtd||   t |dd|f |dd|f< tjdd|| tjd||< ||  ddkrttdd||  dd |D krttd||   t!|dd|f |dd|f< tjdd|| tjd||< || dd||< || dd||< qW tdt"|  ||fS )z
        Parse a file in the 'common format' and return an array of posterior
        samples and list of parameter names. Will apply inverse functions to
        columns with names containing sin,cos,log.
        Nr   #r  "r  r  z.^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?$|^inf$Tr	   z%Ignoring empty line in input file: %sFzHWARNING: Malformed row %i, read %i elements but there is meant to be %i
zLWarning! Ignoring non-numeric data after the header: %s. Row = %i,Element=%izERROR: no lines read in!r   rR  c             S   s   g | ]}|  qS r&   )rB  )r;   r{  r&   r&   r'   r>     s    z1PEOutputParser._common_to_pos.<locals>.<listcomp>zexponentiating %s)r  r6  c             S   s   g | ]}|  qS r&   )rB  )r;   r{  r&   r&   r'   r>     s    z
asining %sr   c             S   s   g | ]}|  qS r&   )rB  )r;   r{  r&   r&   r'   r>     s    z
acosing %sr  r  zRead columns %s)#r  r  r  r  r&  r  rstripr   r  compiler  rb  sysstderrr  r  r/  r  r  r0  r   r   r  re  r   rB  r  r  r  r  r  r  r	  r:  r  )r   r  r  Z
headerfiler  Z	formatstrZhfr  Znparamsr  r   line_numberr  slineproceedZelemnr  ru  r  rE   r&   r&   r'   r    sj    







b">">"zPEOutputParser._common_to_pos)NNNNF)NF)FN)NNr  )NNNN)NNNFN)NNNN)r4  r5  r6  r7  r   r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r&   r&   r&   r'   r  (  s*   
-
F\)
	
E,
(
Q
r  c       	      C   s   i }|  d}d}x|D ]}d|krN|dddd}i ||< || }q|i k	rd|krdd}q|rd}|d  d	 }g ||< || }qy.|d  }|g k	r||d   W q   Y qX qW |S )
Nr  Fz[1]r  r  r  r  Tr	   )r  r&  r  r/  )	foresultr   Z
chain_liner  rm  outZout2newliner&   r&   r'   parse_converge_output_section  s2    



r%  c                s  ddl m  ddl}ddlm}m} d}y
 j}W n  tk
rR    fdd}Y nX |d|  jd	| d
ddd}d}dd | 	d| D }	|	d }
|dkrdd | 	d| D d }dd |	d| D d }t
dd |	d| D d d}td|  |dkr tdd}xD|
	d| D ]2}|ddkrL|}|d }||| q4W x(|
	d| D ]}||| qzW |dkrtd  d| } d| }|| || |
d ||f }|d!|d"t|  }g }x:|D ]2}t|| j}|||  |d!t|  }q
W t|fd#d|D }x:t||D ],\}}||t krf||| qfW |S )$z
    Parse a VO Table RESOURCE containing nested sampling output and
    return a VOTable TABLE element with posterior samples in it.
    This can be added to an existing tree by the user.
    Nlive will be read from the nsresource, unless specified
    r   )r  N)rR  r  z$http://www.ivoa.net/xml/VOTable/v1.1c                s   |  j |< d S )N)r  )r  r  )r  r&   r'   r    s    z'vo_nest2pos.<locals>.register_namespacer  z	{%s}TABLEzPosterior Samplesz%lalinference:results:posteriorsamples)r)   r  )r  c             S   s   g | ]}| d dkr|qS )r  z"lalinference:results:nestedsamples)r  )r;   resourcer&   r&   r'   r>     s    zvo_nest2pos.<locals>.<listcomp>z./{%s}TABLEc             S   s   g | ]}| d dkr|qS )r  zlalinference:state)r  )r;   r&  r&   r&   r'   r>   "  s    z./{%s}RESOURCEc             S   s   g | ]}| d dkr|qS )r  z"lalinference:state:algorithmparams)r  )r;   r.   r&   r&   r'   r>   #  s    c             S   s   g | ]}| d dkr|qS )r)   r  )r  )r;   r   r&   r&   r'   r>   $  s    z./{%s}PARAMr  zFound Nlive %iz>Cannot find number of live points in XML table, please specifyz./{%s}FIELDr)   r<  r	   zUnable to find logL columnz{%s}DATAz{%s}TABLEDATAz./{%s}DATA/{%s}TABLEDATAg      ?g      c                s   g | ]}|  qS r&   r&   )r;   r  )mwr&   r'   r>   >  s    )r  r  r  r  rR  r  r  r  r   r  r.  r  rb  re  r/  r  r  r0  r  r  r]  r  )r  r  r  rR  r  r  r  ZpostablerE   ZnstablesZnstableZrunstateResourceZalgTabler  Z	fieldnodeZ	paramnodeZposdataNodeZpostabledataNodeZnstabledatar7   weightsr  r<  weightr&   )r  r'  r'   r   
  s^    


&




r   z$http://www.ivoa.net/xml/VOTable/v1.1c               @   s4   e Zd Zdd Zdd Zdd Zdd Zd	d
 ZdS )VOT2HTMLc             C   s   t d| _d| _d S )NzVOTable informationr   )r  r  	skiptable)r   r&   r&   r'   r   G  s    
zVOT2HTML.__init__c             C   sf  |dt  kr|d dks$|d dkr,d| _nd| _td| _| j|d  y| j|d  W n tk
rt   Y nX td	d
di| jd| _td	d
di| jd| _td| jd| _	|dt  krtdd|d i| j	d| _
|dt  krtd| jd| _|dt  krtd| jd| _|dt  krbtd| jd}td|d}||d  td|d}||d  d S )Nz	{%s}TABLEr  z"lalinference:results:nestedsamplesz%lalinference:results:posteriorsamplesr	   r   r  r)   r.   r  Z
statstable)r  r  r  )r  z	{%s}FIELDthz{%s}TRz{%s}TDr  z	{%s}PARAMr  )r  r+  r  
tableouterr  r  r   Zfixedparamsr.   Z	tabheaderr
  Ztabrowr  )r   r  r  ZpnodeZnamenodeZvalnoder&   r&   r'   startK  s4    
zVOT2HTML.startc             C   sZ   |dt  kr"| js"| j| jj |dt  kr<| j| j |dt  krV| j	| j d S )Nz	{%s}TABLEz	{%s}FIELDz{%s}TD)
r  r+  r  r/  r-  r  r
  r  r  r  )r   r  r&   r&   r'   endh  s    zVOT2HTML.endc             C   s
   || _ d S )N)r  )r   r  r&   r&   r'   r  q  s    zVOT2HTML.datac             C   s
   | j  S )N)r  r7  )r   r&   r&   r'   r  t  s    zVOT2HTML.closeN)r4  r5  r6  r   r.  r/  r  r  r&   r&   r&   r'   r*  F  s
   	r*  c             C   s   | d | d  S )zCReturns (high - low), the width of the given confidence
    bounds.r	   r   r&   )cl_boundr&   r&   r'   	_cl_widthw  s    r1  c             C   s   t || d k|| d k@ S )zEReturns the number of samples within the given confidence
    bounds.r   r	   )r   r-  )r0  r
  r&   r&   r'   	_cl_count}  s    r2  c                s  dd |D }t | ttjdd |D dd}ttj fddt||D dd}t|}|| }|| }tj||d}|jd }d|  d	 }	t|}
t	|
|	kd d }t	|
d|	 kd d }|| || f}t
d
d |D }t
dd |D }t|t|f}t|t|f}|d |d k rJd}t|t| }|| }|t| }tt||t|| t| }|||fS )a  Returns a tuple (relative_change, fractional_uncertainty,
    percentile_uncertainty) giving the uncertainty in confidence
    intervals from multiple posteriors.

    The uncertainty in the confidence intervals is the difference in
    length between the widest interval, formed from the smallest to
    largest values among all the cl_bounds, and the narrowest
    interval, formed from the largest-small and smallest-large values
    among all the cl_bounds.  Note that neither the smallest nor the
    largest confidence intervals necessarily correspond to one of the
    cl_bounds.

    The relative change relates the confidence interval uncertainty to
    the expected value of the parameter, the fractional uncertainty
    relates this length to the length of the confidence level from the
    combined posteriors, and the percentile uncertainty gives the
    change in percentile over the combined posterior between the
    smallest and largest confidence intervals.

    @param cl The confidence level (between 0 and 1).

    @param cl_bounds A list of (low, high) pairs giving the confidence
    interval associated with each posterior.

    @param posteriors A list of PosteriorOneDPDF objects giving the
    posteriors.c             S   s   g | ]}|j jd  qS )r   )r
  r_  )r;   r  r&   r&   r'   r>     s    z3confidence_interval_uncertainty.<locals>.<listcomp>c             S   s   g | ]
}|j qS r&   )r
  )r;   r  r&   r&   r'   r>     s    r   )r  c                s&   g | ]\}}|j d  d |   qS )g        g      ?)r
  )r;   r2  r  )	Nsamplersr&   r'   r>     s    )r(  g      ?g       @c             S   s   g | ]\}}|qS r&   r&   )r;   rz  r{  r&   r&   r'   r>     s    c             S   s   g | ]\}}|qS r&   r&   )r;   rz  r{  r&   r&   r'   r>     s    r	   )g        g        )r   r   r,  r  r]  r  Zaverager_  rO  r  r   r  r  r1  r0  r2  )r   Z	cl_boundsZ
posteriorsZNsZall_samplesr(  ZisortZ
param_meanr2  r   ZwttotalZilowZihighZall_cl_boundZ
low_boundsZhigh_boundsZlargest_cl_boundZsmallest_cl_boundZci_uncertaintyZrelative_changeZfrac_uncertaintyZquant_uncertaintyr&   )r3  r'   confidence_interval_uncertainty  s2    (


 r4  rx  ry  rz  c       p         s  ddl m}m} ddlm}m} ddlm}	m}
 ddlm	}m
}m}m}m}m} ddlm}m} ddlm} ddlm} dd	lm} dd l}dd
lm}m}m} ddl m} dd l}dd l}ddlm} |d kr| }|d krd}dddddd}dddddd}d} d}!| |! }"d|  d|"  }#d}$|t|"d}%|t|"d|$ |  |" }&||&j|&j j! }'d}(|d|(dd|  |t|"|d|(d|#|t|"d d d})d}*| d }+|+},t"d d! |D }-t"d"d! |D }.d }/d }0d#}1|d k	rd}2yB|j#||$|j%d$}3|j&'|3}4|dkr,|4| }4n|4d }4W n4   t() d }5t*|5 t*d%||f  d}2Y nX |2s|4j+d&|4j,   | }6|4j-}7|4j.}8|4j/}9|7| }:|8| };|4j0}<|4j1})|4j2}=|4j3}>|4j4}?|4j5}@|4j6}A|4j7}B|9| d' }C|4j8}Dt*d( d}Ed}Ft9|4j:}G|;|G}Ht|4j<}I|=|G}Jt>? }K|@|K|I |A|K|J |4jB}L|4jC}M|4jD}N|
|Hrd)}/||:|;|=|>|?|@|A|B|C|D|<ddd|#|)|+|*|K|H\}OnP|	|Hrd*}/||:|;|=|>|?|@|A|B|C|D|<ddd|)|*|K|H\}Ont*d+|H  d S x|D ]}P|t>jE|P jF|L|M|N| \}Q}R|/d*krxx|j j!D ]f}S|Sj j!k rn|Qj j |S  |R|Oj j |S   j j |S< ndj j |S< j j |S  |&j j |S 9  < q2W |Gfd,d-|j j!D |-|P d* d.< |G fd/d-|j j!D |-|P d* d0< x"|j j!D ]}Tdj j |T< qW ||% x*|j j!D ]}Tj j |T  |'  < q8W |Gfd1d-|tj j!D |-|P d) d.< |Gfd2d-|tj j!D |-|P d) d0< n|/d)krx\|j j!D ]J}S|Sj j!k r|Qj j |S  |R|Oj j |S   j j |S< ndj j |S< qW |Gfd3d-|tj j!D |-|P d) d.< |Gfd4d-|tj j!D |-|P d) d0< qW | d k	r`| H \}U}Vd5| jIkr| d5 jJ|V d  nd6| jIkr| d6 jJ|V d  n`d7| jIkr0d8| jIkr0| d7 jJ|V d d9| d8 jJ|V d | d7 jJ|V d     nt*d: d S d}2yFt| d; jJ|V d }Wt| d< jJ|V d }It| d= jJ|V d }JW n   d}2Y nX |2dkr`| }6| d> jJ|V d }X| d? jJ|V d }YtK|Y|X\}7}8d@| jIkr| d@ jJ|V d }9nBdA| jIkr| dA jJ|V d }9n"dB| jIkr>tL| dA jJ|V d }9|7| }:|8| };dC| jIkrn| dC jJ|V d }<nTdD| jIkr| dD jJ|V d }<n4dE| jIkr| dE jJ|V d }<t*dF nt*dG d}<y2x,dHD ]$}Z|Z| jIkr| |Z jJ|V d })qW W n   Y nX y\xdID ]}Z|Z| jIk	r
|Z}[	q
W |M| |[ jJ}\tN|\dk	rTt*dJ t*|\ n|\d }*W n tOk
	r|   t*dK Y nX y| dL jJ|V d }]| dM jJ|V d }^| dN jJ|V d }_|]||^ ||_ }=|]||^ ||_ }>|]||^ }?| dO jJ|V d }]| dP jJ|V d }^| dQ jJ|V d }_|]||^ ||_ }@|]||^ ||_ }A|]||^ }B| dR jJ|V d }DW nv   y|P| dS jJ|V d | dT jJ|V d | dU jJ|V d | dV jJ|V d | dW jJ|V d | dL jJ|V d | dO jJ|V d |:|;|*|<\}D}=}>}?}@}A}BW n   dX| jIkr,| dX jJ|V d }?n$dL| jIkrL| dL jJ|V d }?nd}?dY| jIkrp| dY jJ|V d }Bn$dO| jIkr| dO jJ|V d }Bnd}Bd }= }> }@}AdR| jIkr| dR jJ|V d }Dn| dS jJ|V d }DY nX Y nX |9| d' }Ct| d; jJ|V d }Wt| d< jJ|V d }It| d= jJ|V d }Jt>? }K|@|K|I |A|K|J dZ| jIkr~t| dZ jJ|V d }`|Q|K|` d[| jIkrt| d[ jJ|V d }a|R|K|a d\| jIkr|S|K| d\ jJ|V d  d]| jIkr|T|K| d] jJ|V d  |
|Wr:d)}0||:|;|=|>|?|@|A|B|C|D|<ddd|#|)|+|*|K|W\}OnP|	|Wrzd*}0||:|;|=|>|?|@|A|B|C|D|<ddd|)|*|K|W\}Ont*d^|W  d S | d_ jJ|V d }L| d` jJ|V d }M| da jJ|V d }Ni }bx|D ]}P|t>jE|P jF|L|M|N| \}Q}R|0d*krxx|j j!D ]f}S|Sj j!k rH|Qj j |S  |R|Oj j |S   j j |S< ndj j |S< j j |S  |&j j |S 9  < qW |Gfdbd-|j j!D |.|P d* d.< |G fdcd-|j j!D |.|P d* d0< x"|j j!D ]}Tdj j |T< qW ||% x*|j j!D ]}Tj j |T  |'  < qW |Gfddd-|tj j!D |.|P d) d.< |Gfded-|tj j!D |.|P d) d0< n|0d)krx\|j j!D ]J}S|Sj j!k r|Qj j |S  |R|Oj j |S   j j |S< ndj j |S< qW |Gfdfd-|tj j!D |.|P d) d.< |Gfdgd-|tj j!D |.|P d) d0< qW tUjVddhdi}ctN|}ddj}ed)}f|0d k	r|/d k	r|0d*kr|/d*krd*}fn2|0d k	r|0d*krd*}fn|/d k	r|/d*krd*}ftUjW|d|edkdkdl\}g}htUjX|gdmdndo xtY||d|D ]\}C}ix||eD ]}j|h|C }ktZ|k|j[krX|k|j }kn|h|j }k|.|i d* d. d k	s|.|i d) d. d k	r|jdkr8|fd*kr|kj\|.|i d* d0 |.|i d* d. ||i d9dp|i dq n`|.|i d) d. }l|.|i d) d0 }m|]|m|)k|m|,k}n|l}o|kj^|m|n |o|n j_dr||i d9dp|i ds n|.|i d) d. }l|.|i d) d0 }m|]|m|)k|m|,k}n|l}o|kj`|m|n ta|o|n dt||i d9dudv |kbtc|m|n td|m|n g |kjedwdxdy |-|i d* d. d k	s|-|i d) d. d k	r$|jdkr|fd*kr8|kj\|-|i d* d0 |-|i d* d. ||i d9dz|i dq n`|-|i d) d. }l|-|i d) d0 }m|]|m|)k|m|,k}n|l}o|kj\|m|n |o|n j_dr||i d9dz|i ds n|-|i d) d. }l|-|i d) d0 }m|]|m|)k|m|,k}n|l}o|kj`|m|n ta|o|n dt||i d9dudv |kbtc|m|n td|m|n g |kjedwdxdy |Cdkrr|jdkrb|fd*krR|kjfd{|1d| n|kjfd}|1d| n|kjfd~|1d| nP|C|dd kr|jdkr|fd*kr|kjgd|1d| n|kjgd|1d| n|kjgd|1d| |kjhdd |kedw q0W qW |gji|jjk|ddd |-|.fS )Nr   )r{  rz  )SimInspiralChooseTDWaveformSimInspiralChooseFDWaveform)$SimInspiralImplementedTDApproximants$SimInspiralImplementedFDApproximants)CreateREAL8TimeSeriesCreateForwardREAL8FFTPlanCreateTukeyREAL8WindowCreateCOMPLEX16FrequencySeriesDimensionlessUnitREAL8TimeFreqFFT)ComputeDetAMResponseGreenwichMeanSiderealTime)r    )r  )r  )r   r6  r   )r|  )rr  r   r   r   r=   r   )rx  ry  rz  I1J1r  g      @g      N@r	   g      ?g?g       @i strainTg        strainFr  r;  c             s   s(   | ] }|d d dd d ddfV  qd S )N)r   strain)r<  Fr&   )r;   rE   r&   r&   r'   r    s    z plot_waveform.<locals>.<genexpr>c             s   s(   | ] }|d d dd d ddfV  qd S )N)r   rE  )r<  rF  r&   )r;   rE   r&   r&   r'   r    s       )r}  zBCannot read event %s from table %s. Won't plot injected waveform 
g&.>g    .AzWARNING: Defaulting to inj_fref =100Hz to plot the injected WF. This is hardcoded since xml table does not carry this information
rF  r<  zW
The approximant %s doesn't seem to be recognized by lalsimulation!
 Skipping WF plots
c                s   g | ]} j j | qS r&   )r  )r;   r  )rC  r&   r'   r>   O  s    z!plot_waveform.<locals>.<listcomp>rE  c                s$   g | ]} j jd  |   qS )r	   )r  length)r;   r  )	REAL8timedeltaTplusr&   r'   r>   P  s    r   c                s   g | ]} j j | qS r&   )r  )r;   r  )rD  r&   r'   r>   Y  s    c                s   g | ]} j | j  qS r&   )r[  deltaF)r;   r  )rD  r&   r'   r>   Z  s    c                s   g | ]} j j | qS r&   )r  )r;   r  )rD  r&   r'   r>   b  s    c                s   g | ]} j | j  qS r&   )r[  rL  )r;   r  )rD  r&   r'   r>   c  s    r   r  r  r  g      ?zWERROR: could not find any time parameter in the posterior file. Not plotting the WF...
LAL_APPROXIMANTZLAL_AMPORDERZLAL_PNORDERrM   rK   r   r   r   r   r   r   z;INFO: phi_orb not estimated, using maximum likelihood valuezgWARNING: phi_orb not found in posterior files. Defaulting to 0.0 which is probably *not* what you want
)r   r  )rs  r   Zf_Refr  zqERROR: Expected f_ref to be constant for all samples.  Can't tell which value was injected! Defaulting to 100 Hz
zGWARNING: Could not read fref from posterior file! Defaulting to 100 Hz
rT   rv  rt  rU   rw  ru  r   rc   Zphi_JLr^   r`   rd   rn   ro   ZtideOspinOr   r   zVThe approximant %s doesn't seem to be recognized by lalsimulation!
 Skipping WF plots
r   r   r   c                s   g | ]} j j | qS r&   )r  )r;   r  )rC  r&   r'   r>     s    c                s$   g | ]} j jd  |   qS )r	   )r  rH  )r;   r  )rI  rJ  rK  r&   r'   r>     s    c                s   g | ]} j j | qS r&   )r  )r;   r  )rD  r&   r'   r>     s    c                s   g | ]} j | j  qS r&   )r[  rL  )r;   r  )rD  r&   r'   r>     s    c                s   g | ]} j j | qS r&   )r  )r;   r  )rD  r&   r'   r>     s    c                s   g | ]} j | j  qS r&   )r[  rL  )r;   r  )rD  r&   r'   r>     s    )      )r<  rB   F)nrowsncolssharexshareyrO  rP  )figwidth	figheightz%s maP)r   r   z.-)r@  r   r   z--r   )r@  r   r  Tboth)whichz%s injz$h(t)$)fontsizez$\Re[h(f)]$z$|h(f)|$ztime [s]zfrequency [Hz]best)r  zWF_DetFrame.pngtight)bbox_inches)lr  r{  rz  Zlalsimulation.lalsimulationr5  r6  r7  r8  lal.lalr9  r:  r;  r<  r=  r>  r?  r@  r    r  r  rE  r  r   r6  r   r|  rJ  r  rr  getcwdr.  Zsumofsquaresr  rH  r  r  r  r  ZSimInspiralTabler  r  exc_inforb  r#   r$   r   r   r   rE  r  r  r  r  r  r  r  r   r  waveformZGetApproximantFromStringrL  ZGetOrderFromStringr   Z
CreateDictZ/SimInspiralWaveformParamsInsertPNAmplitudeOrderZ+SimInspiralWaveformParamsInsertPNPhaseOrderr   r   r   r   responser   r  r  r
  r  r  r  r   r%  r  Z+SimInspiralWaveformParamsInsertPNTidalOrderZ*SimInspiralWaveformParamsInsertPNSpinOrderZ+SimInspiralWaveformParamsInsertTidalLambda1Z+SimInspiralWaveformParamsInsertTidalLambda2rF  rA  subplotssetpr]  r  ndarrayr  logical_andZsemilogxrealloglogr|  set_xlimr  r  rH  	set_title
set_xlabelr  rI  rK  rL  )pr  r%   eventrK  ifosr{  rz  r5  r6  r7  r8  r9  r:  r;  r<  r=  r>  r?  r@  r    ZLAL_MSUN_SIZ	LAL_PC_SIrF  r   r6  r   r|  rJ  r   rr  
colors_inj
colors_recsrateseglenrH  rL  padtimeToFreqFFTPlanwindowZWinNormsegStartf_minr   f_max	plot_fmaxinj_strainsrec_strains
inj_domain
rec_domain	font_sizeskipxmldoctblr  GPStimeZM1ZM2r  rG   rH   ZphiRefrK  rL  rM  rN  rO  rP  r   r   r   r   wfinjapproximantZ
amplitudeOZphaseOZ	waveFlagsr   r   r   crossrF   fpfcr  r3  r  rX  approximantrM   rK   r)   r  ZFrefr<   Zther   ZtidalOrN  fsr  r  colsglobal_domainAr  rE   r   axr  r}  maskysr&   )rI  rJ  rK  rD  rC  r'   plot_waveform  s    









 
*",202
*06
<








 
*",202
*06




,

6*&,

6*&




r        >@c          	   C   s  t jddd}t ddd}ddddd	d
}|d kr<t }g }x0| D ](}tj|sdtd|  qF|| qFW |g kr~d S |} i }x| D ]}t	
|}	|	d d df }
|	d d df }	|d}||d | }|
|| < g }g }xDt|
|	D ]6\}}||kr|dkrt	|r|| || qW t j|||| |ddd qW t t|t|g t jddd t jddd t jdd t jdd y$t   |jtj|ddd W n    |tj|d Y nX |  |S )N)rP  rP  i  )r<  r  r	   r   r   r   r  r   )rx  ry  rz  rA  rB  z4PSD file %s has not been found and won't be plotted
r   z-PSD.datrB   g        g      ?r   )r   r   r  zFrequency [Hz]rG  )rY  ZPSDrZ  )r  rW  )rX  zPSD.pngr[  )r\  )rF  rA  ZsubplotrJ  r^  rK  r  rb  r/  r   r  r  rB  r]  r   rg  r  r  r  r  r  r  rH  tight_layoutrI  rL  r  )Z	psd_filesoutpathru  Zmyfig2r  r  tmpr}  Zfreqsr  freqr   rF   frdar  r&   r&   r'   plot_psdq  sP    




r  c             C   s   t j|ddt| t|  S )Nr   )r  )r   r+  r.  r   )r   r   r&   r&   r'   rC    rD  rC  c             C   s,   |rt d| d | S t d| d | S dS )zReturn location of lower or upper confidence levels
    Args:
        x: List of samples.
        cl: Confidence level to return the bound of.
        lower: If ``True``, return the lower bound, otherwise return the upper bound.
    g      ?rB   N)
cred_level)r   r   rB  r&   r&   r'   cred_interval  s    r  c             C   s:   dd|   dd|    }dt j t t |t | S )zdReturns the angle in degrees corresponding to the spline
    calibration parameters delta_psi.

    g       @y              ?g     f@)r   r   r;  imagrf  )Z	delta_psiZrotr&   r&   r'   spline_angle_xform  s    r  r;  r  c          
   C   s  t | }t | | |}t |jd |f}	|dkrB|}
n||}
t j|
dd}|t|
|dd }t|
|dd| }t	j
t | |||gd|dd	dd
 xt|D ]v\}}yt| |t |}W n4 tk
r   tj| |ddd}|t |}Y nX |dkr||	|< q|||	|< qW t	j|t j|	dd||d\}| }t	j|t|	|t|	|dd|ddd t	| d	 | d  dS )a  Plot calibration posterior estimates for a spline model in log space.
    Args:
        logf: The (log) location of spline control points.
        ys: List of posterior draws of function at control points ``logf``
        nx: Number of points to evaluate spline at for plotting.
        level: Credible level to fill in.
        color: Color to plot with.
        label: Label for plot.
        xform: Function to transform the spline into plotted values.
    r   N)r  T)rB  Fr   r   g      ?)Zyerrfmtr@  Zlwr   Zcapsizer   rB   )r  ext)r@  r   g?)r@  r   r  r  )r   r  r   r  r  r,  r_  r   r  rF  Zerrorbarr  r   ZsplinerR  r  ZInterpolatedUnivariateSpliner  	get_colorZfill_betweenr  )Zlogfr  nfr!  r@  r   xformr}  r  r  Zzsr  Zlower_clZupper_clrE   r  rI  Z	calSpliner  r&   r&   r'   plot_spline_pos  s.    
$

&r  c                s  t jddddd\}\}}d}|d kr.t }j}tdd |D }xL|D ]B  d	krdd
}	n  dkrrd}	n dkrd}	nd}	t fdd|D }
tfdd|
D }t 	| t fdd|D }t
|dkr&dtfdd|D  }t|||	|d  t|d d t 	| t fdd|D }t
|dkrPtfdd|D }t|||	|d  t|d td qPW |jd| d |jd| d yt jddd| idd  W n"   t jddd| id! Y nX |d" |d" |jd#|d$ |jd%|d$ |jd&|d$ tj|d'}y|  |j|d(d) W n   || Y nX t | d S )*NrB   r	   )rP  rP  i  )r<  r      c             S   s"   g | ]}d |kr| dd qS )Z
spcal_freqr  r   )r  )r;   r   r&   r&   r'   r>     s    z(plot_calibration_pos.<locals>.<listcomp>r?   r   r@   r   rA   r   r   c                s   g | ]}d   |kr|qS )z{0}_spcal_freq)r  )r;   r   )rF   r&   r'   r>     s    c                s   g | ]} | j qS r&   )r   )r;   r   )r  r&   r'   r>     s    c                s   g | ]}d   |kr|qS )z{0}_spcal_amp)r  )r;   r   )rF   r&   r'   r>     s    r   r;  c                s   g | ]} | j qS r&   )r
  )r;   r   )r  r&   r'   r>     s    z{0} (mean, {1}%))r@  r!  r   c                s   g | ]}d   |kr|qS )z{0}_spcal_phase)r  )r;   r   )rF   r&   r'   r>      s    c                s   g | ]} | j qS r&   )r
  )r;   r   )r  r&   r'   r>     s    )r@  r!  r   r  g      ?)Z	labelsizezupper rightr-  g?)r  propr  )r  r  rR  zFrequency (Hz))rY  zAmplitude (%)zPhase (deg)zcalibration.pngr[  )r\  )rF  rb  rJ  r^  r  r   r  r+  rR  Zscar   r  r  r  upperr.  r  Ztick_paramsr  Z
set_xscalerj  Z
set_ylabelrK  rL  r  rI  r  )r  r!  r  r?  Zax1Zax2r|  r  rl  r@  Zfreq_paramsZlogfreqsZ
amp_paramsampZphase_paramsr   Zoutpr&   )rF   r  r'   plot_calibration_pos  sX       
&
,

r  c       l         s  ddl m}m} ddl m}m} ddlm}	m}
m}m	}m
}m}m} ddlm} dd l}ddlm}m}m} ddlm}m}m} ddlm dd	lm} dd l}dd l}dd
lm}m}m}m}m} ddl m!} |d kr|" }|d krd}dddddd} dddddd}!ddlm# ddlm$ G fdddj%}"&|" d}#d}$|#|$ }%d|#  d|%   }&d}'|
t'|%d}(|t'|%d})|t'|%d|' |# |% }*d}+|d|+d|&|t'|%d d |	d |+dd|# |t'|%|d|+d|&|t'|%d d |	d |+dd|# |t'|%d },d!}-d"}.|#d }/d#}0d$}1d%}2d&}3t(d'd( |D }4t(d)d( |D }5d }6d }7d*}8|d k		rd}9y:|j)||"d+}:j*+|:};|dkr|;| };n|;d };W n    t,d,||f  d}9Y nX |9	s|;j-d-|;j.  }<||<}=|<},|t/|,d|$d  _0|t/|,d|$d  _0|;j1}>|;j2}?|;j3}@|;j4}A|;j5}B|;j6}Cd }Dt7|;j8}E|9|E}F|;j:}G|;j;}H|;j<}I||Frd.}6||& |>|?|@|-|/|A|B|C|D|F\}J}Kn@||Frd/}6| |>|?|@|-|/|A|B|C|D|F\}J}Knt,d0|F  d S x|D ]}L|tj=|L j>|G|H|I||<\}M}N|6d/kr|?|<t@j0   }Ot'|<|t@|Jj0 |t@j0   }P|<|t@|Jj0 |t@j0   |P }Qx ||PD ]}RdjAjA|R< qW xD||JjAjBD ]2}R|M|JjAjA|R  |N|KjAjA|R   jAjA|R|P < qW x<|jAjB|P|JjAjB  D ]}RdjAjA|R|P |JjAjB < qW x4|jAjBD ]"}RjAjA|R  |*jAjA|R 9  < q@W |Cd1tD|E fd2d3|jAjBD |Efd4d3|jAjBD  |Efd5d3|jAjBD |4|L d/ d6< |E fd7d3|jAjBD |4|L d/ d8< x"|jAjBD ]}SdjAjA|S< qW ||( d|j |Q   }TxT|jAjBD ]D}R||T|& |R }U||T|& |R  }VjAjA|R  |Ud9|V  9  < q\W |Efd:d3|t'jAjBD |4|L d. d6< |Efd;d3|t'jAjBD |4|L d. d8< n6|6d.kr>x\|jAjBD ]J}R|R|JjAjBk r^|M|JjAjA|R  |N|KjAjA|R   jAjA|R< ndjAjA|R< q"W d|j |<t@j0  }TxT|jAjBD ]D}R||T|& |R }U||T|& |R  }VjAjA|R  |Ud9|V  9  < qW |Efd<d3|t'jAjBD |4|L d. d6< |Efd=d3|t'jAjBD |4|L d. d8< |>d k	r|>|jFk	r|?d k	r|?|jFk	r|>|? }W|>d>|W  |1kr|>d>|W  }1|>d>|W  |0k r|>d>|W  }0|?d| |>  }X|<d>|X  |2k r|<d>|X  }2|<d>|X  |3kr|<d>|X  }3|@d k	r|@|jFk	rd|d | |@ }Wdd>|W  |0k 	rBdd>|W  }0d}1|@|d }X|<d>|X  |2k 	rp|<d>|X  }2|<d>|X  |3kr|<d>|X  }3qW | d k	r6| G \}Y}Zd?| jHk	r| d? jI|Z d }<nd@| jHk	r| d@ jI|Z d }<ndA| jHk
r
| dA jI|Z d }<n`dB| jHk
r^dC| jHk
r^| dB jI|Z d dD| dC jI|Z d | dB jI|Z d    }<nt,dE d S d}9yt'| dF jI|Z d }[W n   d}9Y nX |9dkr6||<}=|,d k
r|<},|t/|,d|$d  _0|t/|,d|$d  _0dG| jHkr
| dG jI|Z d }@n|jF}@dH| jHkr0| dH jI|Z d }?n|jF}?dI| jHkrV| dI jI|Z d }>n|jF}>y| dJ jI|Z d }AW n"   tJ| dK jI|Z d }AY nX |K|?r|K|@s|dL| |@ }?d }\dM| jHkr| dM jI|Z d }\|\}B| dN jI|Z d }Cn0dO| jHkr(| dO jI|Z d }B| dN jI|Z d }Cd }D||[r^d.}7||& |>|?|@|-|/|A|B|C|D|[\}J}Kn@||[rd/}7| |>|?|@|-|/|A|B|C|D|[\}J}Knt,dP|[  d S | dQ jI|Z d }G| dR jI|Z d }H| dS jI|Z d }Ii }]xZ|D ]P}L|tj=|L j>|G|H|I||<\}M}N|7d/kr|?|<t@j0   }Ot'|<|t@|Jj0 |t@j0   }P|<|t@|Jj0 |t@j0   |P }Qx ||PD ]}RdjAjA|R< qW xD||JjAjBD ]2}R|M|JjAjA|R  |N|KjAjA|R   jAjA|R|P < qW x<|jAjB|P|JjAjB  D ]}RdjAjA|R|P |JjAjB < qW x4|jAjBD ]"}RjAjA|R  |*jAjA|R 9  < q.W |EfdTd3|jAjBD |5|L d/ d6< |E fdUd3|jAjBD |5|L d/ d8< x"|jAjBD ]}SdjAjA|S< qW ||( d|j |Q   }TxT|jAjBD ]D}R||T|& |R }U||T|& |R  }VjAjA|R  |Ud9|V  9  < qW |EfdVd3|t'jAjBD |5|L d. d6< |EfdWd3|t'jAjBD |5|L d. d8< n6|7d.krx\|jAjBD ]J}R|R|JjAjBk r |M|JjAjA|R  |N|KjAjA|R   jAjA|R< ndjAjA|R< qW d|j |<t@j0  }TxT|jAjBD ]D}R||T|& |R }U||T|& |R  }VjAjA|R  |Ud9|V  9  < q8W |EfdXd3|t'jAjBD |5|L d. d6< |EfdYd3|t'jAjBD |5|L d. d8< |>d k	r|>|jFk	r|?d k	r|?|jFk	r|>|? }W|>d>|W  |1kr2|>d>|W  }1|>d>|W  |0k rP|>d>|W  }0|?d| |>  }X|<d>|X  |2k r~|<d>|X  }2|<d>|X  |3kr|<d>|X  }3|@d k	r|@|jFk	rd|d | |@ }Wdd>|W  |0k rdd>|W  }0d}1|@|d }X|<d>|X  |2k r|<d>|X  }2|<d>|X  |3kr|<d>|X  }3qW |jLddZd[}^tM|}_dL}`d.}a|7d k	r|6d k	r|7d/kr|6d/krd/}an2|7d k	r|7d/krd/}an|6d k	r|6d/krd/}a|jN|_|`d\d\d]\}b}c|jO|bd^d_d` xtD||_|D ]\}d}ex||`D ]}f|c|d }gtP|g|jQkr.|g|f }gn|c|f }g|5|e d/ d6 d k	sb|5|e d. d6 d k	r|fdkr,|ad/kr|gjR|5|e d/ d8 |5|e d/ d6 |!|e da|e dbdc |gS|2|3g np|5|e d. d6 }h|5|e d. d8 }i|T|i|1k|i|0k}j|h}k|gjR|i|j ||k|j dd|!|e da|e dbde |gS|1|0g nx|5|e d. d6 }h|5|e d. d8 }i|T|i|1k|i|0k}j|h}k|gjU|i|j ||k|j df|!|e dbdg |gjVdhdidj |gS|1|0g |4|e d/ d6 d k	s|4|e d. d6 d k	r|fdkr|ad/kr(|gjR|4|e d/ d8 |4|e d/ d6 | |e dk|e dLdc |gS|2|3g np|4|e d. d6 }h|4|e d. d8 }i|T|i|1k|i|0k}j|h}k|gjR|i|j ||k|j dd| |e dk|e dLde |gS|1|0g nx|4|e d. d6 }h|4|e d. d8 }i|T|i|1k|i|0k}j|h}k|gjU|i|j ||k|j df| |e dLdg |gjVdhdidj |gS|1|0g |ddkr`|fdkrP|ad/kr@|gjWdl|8dm n|gjWdn|8dm n|gjWdo|8dm nP|d|_d kr|fdkr|ad/kr|gjXdp|8dm n|gjXdq|8dm n|gjXdq|8dm |gjYdrds |gVdh qW qW |bjZ|j[\|dtdudv |4|5fS )wNr   )SimBurstChooseFDWaveformSimBurstChooseTDWaveform)!SimBurstImplementedFDApproximants!SimBurstImplementedTDApproximants)r9  r:  r;  r<  r=  r>  CreateReverseREAL8FFTPlan)r    )r?  r@  r    )r   r6  r   )r{  )r|  )rr  rf  absolutefabsr   )r   r   r   r   r=   r   )rx  ry  rz  rA  rB  r  )rz  )r.   c                   s4   e Zd Z fddZ fddZ fddZdS )zEplot_burst_waveform.<locals>.LIGOLWContentHandlerExtractSimBurstTablec                s(    j | | jj| _d| _d| _d S )NFr  )r  r   SimBurstTableZ	tableNametabnameintabletableElementName)r   Zdocument)rz  r{  r&   r'   r   6  s    
zNplot_burst_waveform.<locals>.LIGOLWContentHandlerExtractSimBurstTable.__init__c                sX   | dr>j|d | jkr>|| _ j| || d| _n| jrT j| || d S )NNameT)Zhas_keyTableZ	TableNamer  r  r  startElementr  )r   r)   attrs)rz  r.   r&   r'   r  ;  s     zRplot_burst_waveform.<locals>.LIGOLWContentHandlerExtractSimBurstTable.startElementc                s.   | j r j| | | j r*|| jkr*d| _ d S )NF)r  r  
endElementr  )r   r)   )rz  r&   r'   r  C  s      zPplot_burst_waveform.<locals>.LIGOLWContentHandlerExtractSimBurstTable.endElementN)r4  r5  r6  r   r  r  r&   )rz  r{  r.   r&   r'   (LIGOLWContentHandlerExtractSimBurstTable5  s   r  g      @g      $@r	   g      ?g?g       @g   G&ArD  g        rC  r  r;  i   g{Gz?g   vH7Bg   vH7c             s   s(   | ] }|d d dd d ddfV  qd S )N)r   rE  )r<  rF  r&   )r;   rE   r&   r&   r'   r  e  s    z&plot_burst_waveform.<locals>.<genexpr>c             s   s(   | ] }|d d dd d ddfV  qd S )N)r   rE  )r<  rF  r&   )r;   rE   r&   r&   r'   r  f  s    rG  )r}  zBCannot read event %s from table %s. Won't plot injected waveform 
g&.>rF  r<  zV
The approximant %s doesn't seem to be recognized by lalinference!
 Skipping WF plots
zfile.outc                s   g | ]}j |   qS r&   )epoch)r;   r3  )rJ  
strainTinjr&   r'   r>     s    z'plot_burst_waveform.<locals>.<listcomp>c                s   g | ]} j j | qS r&   )r  )r;   r3  )r  r&   r'   r>     s    c                s   g | ]} j j | qS r&   )r  )r;   r3  )r  r&   r'   r>     s    rE  c                s   g | ]}j |   qS r&   )r  )r;   r3  )rJ  r  r&   r'   r>     s    r   y              ?c                s   g | ]} j j | qS r&   )r  )r;   r  )
strainFinjr&   r'   r>     s    c                s   g | ]} j | j  qS r&   )r[  rL  )r;   r  )r  r&   r'   r>     s    c                s   g | ]} j j | qS r&   )r  )r;   r  )r  r&   r'   r>     s    c                s   g | ]} j | j  qS r&   )r[  rL  )r;   r  )r  r&   r'   r>     s    g      @r   r  r   r  r  g      ?zWERROR: could not find any time parameter in the posterior file. Not plotting the WF...
rM  rY  r\  rU  rV  r]  rB   r   r   Zpolar_ellipse_anglezUThe approximant %s doesn't seem to be recognized by lalinference!
 Skipping WF plots
r   r   r   c                s   g | ]} j j | qS r&   )r  )r;   r3  )
strainTrecr&   r'   r>   F  s    c                s   g | ]}j |   qS r&   )r  )r;   r3  )rJ  r  r&   r'   r>   G  s    c                s   g | ]} j j | qS r&   )r  )r;   r  )
strainFrecr&   r'   r>   R  s    c                s   g | ]} j | j  qS r&   )r[  rL  )r;   r  )r  r&   r'   r>   S  s    c                s   g | ]} j j | qS r&   )r  )r;   r  )r  r&   r'   r>   `  s    c                s   g | ]} j | j  qS r&   )r[  rL  )r;   r  )r  r&   r'   r>   a  s    )r}  rO  )r<  F)rQ  rR  rS  rT  r}  rO  )rU  rV  z%s maPr   )r   r  -)r@  r   r  z--)r@  r  TrW  )rX  z%s injz$h(t)$)rY  z$\Re[h(f)]$z$|h(f)|$ztime [s]zfrequency [Hz]rZ  )r  zWF_DetFrame.pngr[  )r\  )]Zlalinference.lalinferencer  r  r  r  r]  r9  r:  r;  r<  r=  r>  r  r    lalinferencer   r?  r@  r  r   r6  r   r  r{  r|  rJ  r  rr  rf  r  r  r   r  r   r^  rz  r.   r  r  r.  r  r  r  r  rb  Ztime_geocent_gpsZtime_geocent_gps_nsr  r  rU  rM   rY  rV  rW  rX  r  r`  ZGetBurstApproximantFromStringr   r   r   r   ra  r   r0  r  rH  r  r]  r   r   r  r  r
  r  r  rA  r   rb  rc  r  rd  r  rh  re  rg  rH  ri  rj  r  rI  rK  rL  )lr  Zsimburstrk  rK  rl  r  r  r  r  r9  r:  r;  r<  r=  r>  r  r    Zlalinfr?  r@  r   r6  r   r|  rJ  r   rr  rf  r  r  r   rF  rm  rn  r  ro  rp  rH  rL  rq  rr  ZfreqToTimeFFTPlanrs  rt  ZGlobREAL8timeru  r   rv  rw  Z	plot_fminZ	plot_tminZ	plot_tmaxrx  ry  rz  r{  r|  r}  r~  r  rI  r  r[  rM   ZdurrV  Zpolar_e_angleZpolar_e_eccZBurstExtraParamsr  r  r   r   r   rK  r  rF   r  r  Z
tCinstrainZ
tSinstrainr  r  r3  Ztwopitr  ZimZsigmaFZsigmaTr  rX  r  r   r  r  r  r  r  r  r  r   rE   r   r  r  r}  r  r  r&   )rJ  rz  r{  r  r  r  r  r.   r'   plot_burst_waveform  s   $







$
" 
((2 "L,."04
*"00
<



$
" 
((2 ",."04
*"00




,

4*$,

4*$




r  c       A         s  ddl m}m t}i }|g kr$|S t|jt| t|jkrD|S d|  }| jd| ||d}|srd| }nd| }d}d|jkr<| \}|j	d	|j	d ||d j} fd
d|D }g }g }x|D ]T}t
|dkr"||d |d   ||d |d   q|d |d qW nRd	|jkr|d	 j}t
|dkr|d |d  }|d |d  }nd}d}d}xB|D ]8}| }y||   W n tk
r   wY nX y|| }W n& tk
r   td|  wY nX ||i}d }d }|
rL|dkr4td d}t|||\} }!}"}}#nj|dkrbtd d}|| jd krxd }$n|| jg}$t||g||$d\}%}"}&|&d k	r|&d }!|&d }td|  |"||< d  }'}(|r||}'||}(|di})yt||)|'|(dd\}*}+W n   td|  wY nX |d },tj||,}-|+|- |	rj|+tj||d  t|+ |*rtd||*f  tjddd}.|| j}/d|jkrtj|/dd d!d"|.d# t
|/}0n| \}|j	||j	d ||d j} fd$d|D }1d%d |1D }2td&d |1D }0x0t|2|1D ]"\}3tj|3d'dd!d"|.d( qBW td)||  || j}4|4d k	rt |/d*t|/t |/   }5t|/d*t|/t |/   }6|5|4k r|6|4krtj!|4d+d,dd- |.tj||,"dd. |	r,|.tj||,"dd/ t|. d}7|sbtjddd}8d|jkrH|/d d df yt#|\}9}:};tj|;dd'dd!d"|8d(}<|d krtd0 n>d	|jkr|<d $ }=tj%|:| d,|=d1 td2|:|9f  |8tj||,"dd3 |	r&|8tj||,"dd4 t|8 W n   d}7Y nX nyg }>d"}?xt|2|1||D ]r\}3}}t#|\}9}:};|>|: |?|97 }?tj|;dd'dd!d"|8d(}<|d k	rd|<d $ }=tj%|:| d,|=d1 qdW |d krtd0 ntd5t|>|?f  |8tj||,"dd3 |	rD|8tj||,"dd4 t|8 W n   d}7Y nX |s|7sd6|,"dd3 d7 }@nd8}@|d9|, d: |,"dd. d7 |@ d; 7 }n |d9|, d: |,"dd. d< 7 }qW |d=7 }|&| |S )>Nr   )r  r+  Zonedmargtable_z1D marginal posterior PDFs (%s))r  r  zs<table id="%s"><tr><th>Histogram and Kernel Density Estimate</th><th>Samples used</th><th>Autocorrelation</th></tr>z[<table id="%s"><tr><th>Histogram and Kernel Density Estimate</th><th>Samples used</th></tr>r  r  c                s,   g | ]$}d d  f |kf qS )Nr&   )r;   r  )r  r  	par_indexr+  r&   r'   r>     s    z!make_1d_table.<locals>.<listcomp>r	   r  z-Bin size is not set for %s, skipping binning.z*Using greedy 1-d binning credible regions
z&Using 2-step KDE 1-d credible regions
)r  r   r   zGenerating 1D plot for %s.r  F)r  zFailed to produce plot for %s.z.pngz.pdfz%r of injected value of %s (bins) = %f)r   g      @r7  )r<  r  zk.r   g      ?g        )rE  r   r  rA  c                s(   g | ] }d d  f |kf qS )Nr&   )r;   r  )r  r  r  r&   r'   r>   R  s    c             S   s   g | ]}t t|qS r&   )r   r   )r;   cdr&   r&   r'   r>   S  s    c             S   s   g | ]}t |qS r&   )r   )r;   r  r&   r&   r'   r>   T  s    r   )r  rE  r   r  rA  zGelman-Rubin R = %gg?r   z-.)r@  r  r  z
_samps.pngz
_samps.pdfzAutocorrelation Function)r  r@  zACL = %i   N = %iz_acf.pngz_acf.pdfzACL = %i  N = %iz/<td width="30%"><img width="100%" src="1Dsamps/z"/></td>z<td>ACF generation failed!</td>z1<tr><td width="30%"><img width="100%" src="1Dpdf/z7"/></td><td width="30%"><img width="100%" src="1Dsamps/z</tr>z"/></td></tr>z</table>)'r  r  r+  confidenceLevelsr  r  rB  r  r
  r*   r   r/  r   rb  rc  r  r#  r  r  r  rJ  rK  rL  rI  rF  r  rA  r  r  r]  r  r%  r  Zaxhliner&  ry  r  r  r  )Ar  r  r   r  ZparsZnoacfZ	GreedyResZ	onepdfdirZsampsdirZsavepdfsZgreedyZanalyticLikelihoodr  r  r  r#  ZtabidZ
html_ompdfZhtml_ompdf_writerw  r  r!  ZchainCyclesZchainNcyclesZchainNskipsZcyclesZNcyclesZprintedZpar_namerY  Z	binParamsr  r  r  r  rb  r  r  Zinjstatsr  r  ZoneDPDFParamsr  ZplotFigZfignameZoneDplotPathr  r  maxLenr"  ZchainDataRangesrngr  r  r  ZacfailZacffigZNeffrx  rp  r   Z
last_colorZaclsZNsampsZacfhtmlr&   )r  r  r  r+  r'   make_1d_table  s@   











 




 

 



 *&
r  )r}  )Nr}  )Nr}  NFr  F)NT)T)NNN)rx  ry  rz  r{  )NNF)r  )r  )r  )r  )r  )N)Nr   rB   )r	   )N)Nr  )r   T)r;  r   r  NN)r   N)r7  rJ  r  r  r   r   r   r   r   rB  Zxml.domr   operatorr   r  Zuseior
   Zhealpyr*  r  r-   r  r   r  seedr   r   rF  r   r  r  r   r   r   Zscipy.optimizer   r   r   r   socketrA  r   r  r   r  r  r  rE  rF  r  rb  Zimrtgr.nrutilsr   Zmatplotlib.tickerr   gethostbyaddrgethostnamer  Zhostname_shortr  updateZxml.etree.cElementTreer   r   r   r   r   r    r!   r  r"   
__author__r  __version__date__date__r(   r2   r3   r  ZrelativePhaseParamsr  ZcalAmpParamsZcalPhaseParamsZ	calParamsZ
massParamsZspinParamsPrecZspinParamsAliZspinParamsEffZ
spinParamsZ
cosmoParamZ	ppEParamsr   ZtigerParamsZbransDickeParamsZmassiveGravitonParamsr  r  ZfourPiecePolyParamsZspectralParamsZenergyParamsZstrongFieldParamsZ
distParamsZ	incParamsZ	polParamsZ	skyParamsZphaseParamsZ
timeParamsZendTimeParamsZstatsParamsZcalibParamsr  ZgreedyBinSizesru  Zderived_timeZderived_phaser   Zloglnamer   Z__default_line_stylesZ__default_color_lstZ__default_css_stringZ__default_javascript_stringr   r   objectr   r9  rT  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r#  r5  r7  r9  rG  rN  rR  rS  rc  r  r  rW  r]  rI  rJ  ra  ri  rj  rp  rq  rH  rr  ru  r  r  r  r  r  r  r  r   r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r6  r@  rD  rN  rQ  r  rU  rW  rc  rf  ri  r  rj  rq  rv  ry  r  r  r  r%  r   r  r*  r1  r2  r4  r  r  r  r  r  r  r  r  r  r&   r&   r&   r'   <module>#   s  
"


	&:4$h
$










	L
u H k          ?p  4,*Q B&"6j}r\



		

W "4 ah+.3$. ` :Ar/0     H:1J$   '/	*<$   >