B
    d.                 @   sp   d Z ddlZddlmZ ddlmZ ddlmZ ddlm	Z	 ddl
mZ ddlmZmZmZ G d	d
 d
eZdS )z3
This modules provides spin distributions of CBCs.
    N)conversions)Uniform)UniformAngle)UniformPowerLaw)	Arbitrary)get_param_bounds_from_configVARARGS_DELIMBoundedDistc                   sr   e Zd ZdZdZddddddd	d
gZd fdd	Zdd Zdd ZdddZ	dd Z
dddZedd Z  ZS )IndependentChiPChiEffa  A distribution such that :math:`\chi_{\mathrm{eff}}` and
    :math:`\chi_p` are uniform and independent of each other.

    To ensure constraints are applied correctly, this distribution produces all
    three components of both spins as well as the component masses.

    Parameters
    ----------
    mass1 : BoundedDist, Bounds, or tuple
        The distribution or bounds to use for mass1. Must be either a
        BoundedDist giving the distribution on mass1, or bounds (as
        either a Bounds instance or a tuple) giving the minimum and maximum
        values to use for mass1. If the latter, a Uniform distribution will
        be used.
    mass2 : BoundedDist, Bounds, or tuple
        The distribution or bounds to use for mass2. Syntax is the same as
        mass1.
    chi_eff : BoundedDist, Bounds, or tuple; optional
        The distribution or bounds to use for :math:`chi_eff`. Syntax is the
        same as mass1, except that None may also be passed. In that case,
        `(-1, 1)` will be used for the bounds. Default is None.
    chi_a : BoundedDist, Bounds, or tuple; optional
        The distribution or bounds to use for :math:`chi_a`. Syntax is the
        same as mass1, except that None may also be passed. In that case,
        `(-1, 1)` will be used for the bounds. Default is None.
    xi_bounds : Bounds or tuple, optional
        The bounds to use for :math:`\xi_1` and :math:`\xi_2`. Must be
        :math:`\in (0, 1)`. If None (the default), will be `(0, 1)`.
    nsamples : int, optional
        The number of samples to use for the internal kde. The larger the
        number of samples, the more accurate the pdf will be, but the longer
        it will take to evaluate. Default is 10000.
    seed : int, optional
        Seed value to use for the number generator for the kde. The current
        random state of numpy will be saved prior to setting the seed. After
        the samples are generated, the state will be set back to what it was.
        If None provided, will use 0.
    Zindependent_chip_chieffmass1mass2xi1xi2chi_effchi_aphi_aphi_sNc                s  t |tr|| _nt|d| _t |tr0|| _nt|d| _t |trN|| _n|d krZd}t|d| _t |trx|| _n|d krd}t|d| _|d krd}|d dks|d d	k s|d
 dks|d
 d	k rtdtd|d| _	td|d| _
tdd| _tdd| _| j| j| j	| j
| j| j| j| jd| _|d kr>d}tj }|d krVd}tj| | jt|d}	tj| tdd | j D }
tt| j|	d |	d |	d |	d |	d |	d |	d |	d |
d	 d S ) N)r   )r   )g      g      ?)r   )r   )r   g      ?r   g      ?g           zxi bounds must be in [0, 1)g      ?)dimr   )r   r   )r      )r   )r   )r   r   r   r   r   r   r   r   g     @)sizec             s   s"   | ]}|j  D ]
}|V  qqd S )N)boundsitems).0Zdistrb r   f/work/yifan.wang/ringdown/master-ringdown-env/lib/python3.7/site-packages/pycbc/distributions/spins.py	<genexpr>~   s    z1IndependentChiPChiEff.__init__.<locals>.<genexpr>r   r   r   r   r   r   r   r   )	r   r   r   r   r   r   r   r   r   )
isinstancer	   mass1_distrr   mass2_distrchieff_distr
chia_distr
ValueErrorr   	xi1_distr	xi2_distrr   
phia_distr
phis_distrdistributionsnumpyrandomZ	get_stateseedrvsintZ	set_statedictvaluessuperr
   __init__)selfr   r   r   r   	xi_boundsnsamplesr+   ZrstateZrvalsr   )	__class__r   r   r1   G   s^    






zIndependentChiPChiEff.__init__c             C   s   t |d |d |d |d |d |d |d |d \	}}}}}}}}	}
t |||}t |||	||}t |||}t |||	||}t ||||}t ||||}|d	 |d	  |d	  d
k |d	 |d	  |d	  d
k @ }|S )a/  Applies physical constraints to the given parameter values.

        Parameters
        ----------
        values : {arr or dict}
            A dictionary or structured array giving the values.

        Returns
        -------
        bool
            Whether or not the values satisfy physical
        r   r   r   r   r   r   r   r   g       @g      ?)r   ZensurearrayZspin1x_from_xi1_phi_a_phi_sZ'spin2x_from_mass1_mass2_xi2_phi_a_phi_sZspin1y_from_xi1_phi_a_phi_sZ'spin2y_from_mass1_mass2_xi2_phi_a_phi_sZ%spin1z_from_mass1_mass2_chi_eff_chi_aZ%spin2z_from_mass1_mass2_chi_eff_chi_a)r2   r/   r   r   r   r   r   r   r   r   _Zs1xZs2xZs1yZs2yZs1zZs2ztestr   r   r   _constraints   s"    "

z"IndependentChiPChiEff._constraintsc                s.   t  fdd| j D }|s$dS |  S )zpDetermines whether the given values are in each parameter's bounds
        and satisfy the constraints.
        c                s   g | ]} |kqS r   r   )r   dist)paramsr   r   
<listcomp>   s    z6IndependentChiPChiEff.__contains__.<locals>.<listcomp>F)allr(   r/   r8   )r2   r:   isinr   )r:   r   __contains__   s    z"IndependentChiPChiEff.__contains__r   c             K   s
  y|d }W n& t k
r2   | jj|dd }Y nX y|d }W n& t k
rf   | jj|dd }Y nX y|d }W n& t k
r   | jj|dd }Y nX y|d }W n& t k
r   | jj|dd }Y nX y|d }W n( t k
r   | jj|dd }Y nX y|d }W n( t k
r:   | jj|dd }Y nX y|d }	W n( t k
rp   | jj|dd }	Y nX y|d	 }
W n( t k
r   | j	j|dd	 }
Y nX d
d | j
D }tj||d}||d< ||d< ||d< ||d< ||d< ||d< |	|d< |
|d	< |S )zCDraws random samples without applying physical constrains.
        r   )r   r   r   r   r   r   r   r   c             S   s   g | ]}|t fqS r   )float)r   pr   r   r   r;      s    z/IndependentChiPChiEff._draw.<locals>.<listcomp>)dtype)KeyErrorr   r,   r    r&   r'   r!   r"   r$   r%   r:   r)   zeros)r2   r   kwargsr   r   r   r   r   r   r   r   rA   arrr   r   r   _draw   sV    zIndependentChiPChiEff._drawc             K   s   |S )Nr   )r2   rD   r   r   r   apply_boundary_conditions   s    z/IndependentChiPChiEff.apply_boundary_conditionsc       
      K   s   t |}dd | jD }tj||d}|}d}xR|r| jf d|i|}| |}| }	|| ||||	 < ||	7 }|| }q0W |S )z9Returns random values for all of the parameters.
        c             S   s   g | ]}|t fqS r   )r?   )r   r@   r   r   r   r;      s    z-IndependentChiPChiEff.rvs.<locals>.<listcomp>)rA   r   r   )r-   r:   r)   rC   rF   r8   sum)
r2   r   rD   rA   rE   	remainingZkeepidxZdrawsmaskZaddptsr   r   r   r,      s    
zIndependentChiPChiEff.rvsc             C   s   |}| t}t|t| jks(tdt|||d}t|||d}t|||d}t|||d}t|||d}	|d||gdrt|	d||gd}
nd	}
| |||||	|
d
S )a  Returns a distribution based on a configuration file. The parameters
        for the distribution are retrieved from the section titled
        "[`section`-`variable_args`]" in the config file.

        Parameters
        ----------
        cp : pycbc.workflow.WorkflowConfigParser
            A parsed configuration file that contains the distribution
            options.
        section : str
            Name of the section in the configuration file.
        variable_args : str
            The names of the parameters for this distribution, separated by
            `prior.VARARGS_DELIM`. These must appear in the "tag" part
            of the section header.

        Returns
        -------
        IndependentChiPChiEff
            A distribution instance.
        zTNot all parameters used by this distribution included in tag portion of section namer   r   r   r   r3   -r4   N)r   r   r   r   r3   r4   )
splitr   set_paramsr#   r   
has_optionjoinr-   get)clscpsectionZvariable_argstagr   r   r   r   r3   r4   r   r   r   from_config   s    

z!IndependentChiPChiEff.from_config)NNNNNNN)r   )r   )__name__
__module____qualname____doc__namerN   r1   r8   r>   rF   rG   r,   classmethodrV   __classcell__r   r   )r5   r   r
      s   & > 

3
r
   )rZ   r)   Zpycbcr   Zpycbc.distributions.uniformr   Zpycbc.distributions.angularr   Zpycbc.distributions.power_lawr   Zpycbc.distributions.arbitraryr   Zpycbc.distributions.boundedr   r   r	   r
   r   r   r   r   <module>   s   