B
    d0                 @   s   d dl Z d dlZddlmZ dd Zdd Zd!d	d
Zd"ddZd#ddZdd Z	dd Z
d$ddZd%ddZdd Zdd Zd&ddZd'dd ZdS )(    N   )	bin_utilsc             C   s<   | dd | dd  }|dd |dd  d }|| S )z
    Returns an array of elements of the integrand dP = p(mu) dmu
    for a density p(mu) defined at sample values mu ; samples need
    not be equally spaced.  Uses a simple trapezium rule.
    Number of dP elements is 1 - (number of mu samples).
    r   Ng       @ )mupdfZdmubin_meanr   r   W/work/yifan.wang/ringdown/master-ringdown-env/lib/python3.7/site-packages/pycbc/rate.pyintegral_element   s    r
   c             C   sB   t |dk rtdt | dk r(tdt| |}| |t| fS )z
    Takes a function pofmu defined at rate sample values mu and
    normalizes it to be a suitable pdf. Both mu and pofmu must be
    arrays or lists of the same length.
    r   z\Probabilities cannot be negative, don't ask me to normalize a function with negative values!zVRates cannot be negative, don't ask me to normalize a function over a negative domain!)min
ValueErrorr
   sum)r   Zpofmudpr   r   r	   normalize_pdf   s    
r   ?c             C   sl   d|  k rdk rDn n,t | |}t| |  |}| | }n$|dkr`t| |dk }ntd|S )z
    Returns the upper limit mu_high of confidence level alpha for a
    posterior distribution post on the given parameter mu.
    The posterior need not be normalized.
    r   r   z"Confidence level must be in (0,1].)r
   bisectbisect_leftcumsumr   numpymaxr   )mu_inpostalphar   Zhigh_idxmu_highr   r   r	   compute_upper_limit#   s    

r   c             C   sp   d|  k rdk rHn n0t | |}t| |  d| }| | }n$|dkrdt| |dk }ntd|S )z
    Returns the lower limit mu_low of confidence level alpha for a
    posterior distribution post on the given parameter mu.
    The posterior need not be normalized.
    r   r   z"Confidence level must be in (0,1].)r
   r   bisect_rightr   r   r   r   r   )r   r   r   r   Zlow_idxmu_lowr   r   r	   compute_lower_limit8   s    

r   c       	      C   s   d|  k rdk sn t dd}t| }t| }xRtdd| |D ]<}t| |d| }t| ||| }|| || k rJ|}|}qJW ||fS )z
    Returns the minimal-width confidence interval [mu_low, mu_high] of
    confidence level alpha for a posterior distribution post on the parameter mu.
    r   r   z"Confidence level must be in (0,1).g{Gz?)r   r   r   r   Zaranger   r   )	r   r   r   Z
alpha_stepr   r   Zaimlmhr   r   r	   confidence_interval_min_widthM   s    

r    c             C   s6   t | |}|dd |dd  d }|||k  S )z
    Integrates a pdf over mu taking only bins where
    the mean over the bin is above a given threshold
    This gives the coverage of the HPD interval for
    the given threshold.
    r   Nr   g       @)r
   r   )r   r   Zthreshr   r   r   r   r	   hpd_coverageg   s    
r!   c             C   sf   t | |}d}t|}xJtt| ||t| || |kr`|| d }t| |||krZ|}q|}qW |S )z
    For a PDF post over samples mu_in, find a density
    threshold such that the region having higher density
    has coverage of at least alpha, and less than alpha
    plus a given tolerance.
    g        g       @)r   r   absr!   )r   r   r   tolZ	norm_postZp_minusZp_plusZp_testr   r   r	   hpd_thresholdt   s    
r$   MbP?c       	      C   sz   |dkr*| |dk }t |}t |}nHd|  k r>dk rrn n0t| |||d}| ||k }t |}t |}||fS )a  
    Returns the minimum and maximum rate values of the HPD
    (Highest Posterior Density) credible interval for a posterior
    post defined at the sample values mu_in.  Samples need not be
    uniformly spaced and posterior need not be normalized.

    Will not return a correct credible interval if the posterior
    is multimodal and the correct interval is not contiguous;
    in this case will over-cover by including the whole range from
    minimum to maximum mu.
    r   r   )r#   )r   r   r   r$   )	r   r   r   Z	toleranceZnonzero_samplesr   r   ZpthreshZsamples_over_thresholdr   r   r	   hpd_credible_interval   s    


r&   Fc       
      C   s&  |rt | }|dd  |d d  }t t | dd  t | d d  d }t dt j |d  | | }t t dt j |d  | | d }n~| dd  | d d  }	| dd  | d d  d }t dt j |d  | |	 }t t dt j |d  | |	 d }||fS )Nr   r   g       @g      @g      @)r   logexpr   pisqrt)
dbinsefferrZlogbinsZlogdZdlogdZdrepsvolverrddr   r   r	   integrate_efficiency   s    
. ( *r1   c       
      C   s   t t|d }t t|d }xt|dd D ]\}}||d  }t || k| |k  }t ||k||k  }	||	 dkrd}	t|||	  ||< t || d||   ||	  ||< q6W ||fS )z
    Compute the efficiency as a function of distance for the given sets of found
    and missed injection distances.
    Note that injections that do not fit into any dbin get lost :(
    r   Nr   r   g      ?)r   zeroslen	enumerater   floatr*   )
f_distm_distr+   Z
efficiencyerrorjZdlowZdhighfoundmissedr   r   r	   compute_efficiency   s    r<   c       	      C   s   t | dkr4tt |d tt |d ddfS tdd | D }tdd |D }t|||\}}t|||\}}||||fS )Nr   r   c             S   s   g | ]
}|j qS r   )distance).0lr   r   r	   
<listcomp>   s    z*mean_efficiency_volume.<locals>.<listcomp>c             S   s   g | ]
}|j qS r   )r=   )r>   r?   r   r   r	   r@      s    )r3   r   r2   arrayr<   r1   )	r:   r;   r+   r6   r7   r,   r-   r.   r/   r   r   r	   mean_efficiency_volume   s    (rB   c                s  |dkrt  d t  d d gf}|| ||d   t  d t  d d gf}|| ||d   fdd| D }|S t  d t  d d gf| |d  |dkrfdd| D }n|d	krfd
d| D }nr|dkr<fdd| D }nR|dkr|dkrffdd| D }n(fdd| D }|fdd| D 7 }|S )z
    For a given set of injections (sim_inspiral rows), return the subset
    of injections that fall within the given mass range.
    Mass1_Mass2r   r   r   c                sv   g | ]n}|j   kr k r:n n|j  kr8k snn |j  krP k rn q|j   krjk rn q|qS r   )mass1mass2)r>   r?   )m1him1lom2him2lor   r	   r@      s    2z-filter_injections_by_mass.<locals>.<listcomp>Z
Chirp_Massc                s*   g | ]"}|j   kr k rn q|qS r   )Zmchirp)r>   r?   )mhighmlowr   r	   r@     s    Z
Total_Massc                s0   g | ](}|j |j   kr$ k rn q|qS r   )rD   rE   )r>   r?   )rJ   rK   r   r	   r@     s    ZComponent_Massc                s*   g | ]"}|j   kr k rn q|qS r   )rD   )r>   r?   )rJ   rK   r   r	   r@     s    ZBNS_BBH)r      c                sD   g | ]<}|j   kr k rn q|j  kr8 k rn q|qS r   )rD   rE   )r>   r?   )rJ   rK   r   r	   r@     s    c                sT   g | ]L} d  |j   kr& d k rn q d |j  krH d k rn q|qS )r   r   rL      )rD   rE   )r>   r?   )mbinsr   r	   r@     s    $c                sT   g | ]L} d  |j   kr& d k rn q d |j  krH d k rn q|qS )r   r   rL   rM   )rE   rD   )r>   r?   )rN   r   r	   r@     s    $)r   ZconcatenatelowerrA   upper)ZinjsrN   Zbin_numbin_typeZbin_num2Zm1binsZm2binsZnewinjsr   )rF   rG   rH   rI   rN   rJ   rK   r	   filter_injections_by_mass   s6    



rR   c             C   s  t |}t |}t |}t |}g }	g }
|dkrxt| d D ]\}}xt| d D ]\}}t| ||||}t|||||}t||||f< t||||f< t|||\}}}}|	| |
| ||||f< ||||f< qfW qLW |||||	|
fS xt| d D ]~\}}t| |||}t||||}t|||f< t|||f< t|||\}}}}|	| |
| |||f< |||f< qW |||||	|
fS )z
    Compute the average luminosity an experiment was sensitive to

    Assumes that luminosity is uniformly distributed in space.
    Input is the sets of found and missed injections.
    rC   r   r   )r   ZBinnedArrayr4   ZcentresrR   r3   rB   append)r:   r;   Z	mass_binsrQ   r+   ZvolArrayZ	vol2ArrayZ
foundArrayZmissedArrayZeffvmassZerrvmassr9   Zmc1kZmc2ZnewfoundZ	newmissedZmeaneffZefferrZmeanvolZvolerrZmcr   r   r	   compute_volume_vs_mass  sD    









rU   )r   )r   )r   )r   r%   )r   F)N)N)r   r    r   r
   r   r   r   r    r!   r$   r&   r1   r<   rB   rR   rU   r   r   r   r	   <module>   s   



 

.