B
    dY-                 @   sl   d Z ddlZddlmZ ddlmZ dd fdd	Zd
d Zdd ZdddZ	dd Z
dddZdd ZdS )zC This module contains utilities for calculating search sensitivity
    N)chirp_distance   )	bin_utilsc             C   s   | j fS )N)distance)sim r   ^/work/yifan.wang/ringdown/master-ringdown-env/lib/python3.7/site-packages/pycbc/sensitivity.py<lambda>
       r	   c                s   t |  fdd| D   fdd|D     t jt |  d}t|jd|j   j	j }t jt ||d}||fS )z
    Calculate search efficiency in the given ndbins.

    The first dimension of ndbins must be bins over injected distance.
    sim_to_bins_function must map an object to a tuple indexing the ndbins.
    c                s   g | ]}  |qS r   )Zincnumerator).0r   )binssim_to_bins_functionr   r   
<listcomp>   s    z5compute_search_efficiency_in_bins.<locals>.<listcomp>c                s   g | ]}  |qS r   )Zincdenominator)r   r   )r   r   r   r   r      s    )arrayr   )
r   ZBinnedRatiosZ
regularizeBinnedArrayNDBinsrationumpysqrtr   denominator)foundtotalndbinsr   effZerr_arrerrr   )r   r   r   !compute_search_efficiency_in_bins   s    	
r   c       
      C   s   t | |||\}}|d  |d   }|d  }tt|dd }tt|dd }	t|j	j
d tj |d  |||_	tdtj |d  |j	j
 | d jdd|	_	||	fS )	a/  
    Calculate search sensitive volume by integrating efficiency in distance bins

    No cosmological corrections are applied: flat space is assumed.
    The first dimension of ndbins must be bins over injected distance.
    sim_to_bins_function must maps an object to a tuple indexing the ndbins.
    r   r   Ng      @      )Zaxis)r   upperlowerZcentresr   r   r   r   Ztrapzr   Tpir   sum)
r   r   r   r   r   r   Zdxrvolerrorsr   r   r   compute_search_volume_in_bins$   s    &.r'   c             C   sn   | d d t j d }| | d d t j d | }t | |k| | d}||d d t j d  }|||fS )z Return the distance and standard deviation upper and lower bounds

    Parameters
    ----------
    vol: float
    vol_err: float

    Returns
    -------
    dist: float
    ehigh: float
    elow: float

    g      @g      @gUUUUUU?r   )r   r"   where)r%   vol_errdistZehighdeltaZelowr   r   r   volume_to_distance_with_errors@   s
    r,   c	             C   sN  ddddd| }	ddddd| }
|d	krtd
}t ||f}| }|dk	r`||| d  }qt|  | }n6|dkr|dk	r|}qt|  | }ntd| dt j |d  }|dkr| |	 }||	 }n8|d	kr| |	 ||
  }||	 ||
  }ntd| t ||f}t |d| f}t|}|dkrJt|}n|d	krht||| d  }|| }|dkrt|}n|d	kr|dkr|dk	r|t || d  }ntt | t |}t || }t|dtt || |   }nt|| |
 }t|d | || d  }|| }||| d  }||fS )a  
    Compute sensitive volume and standard error via direct Monte Carlo integral

    Injections should be made over a range of distances such that sensitive
    volume due to signals closer than D_min is negligible, and efficiency at
    distances above D_max is negligible
    TODO : Replace this function by Collin's formula given in Usman et al. ?
    OR get that coded as a new function?

    Parameters
    -----------
    found_d: numpy.ndarray
        The distances of found injections
    missed_d: numpy.ndarray
        The distances of missed injections
    found_mchirp: numpy.ndarray
        Chirp mass of found injections
    missed_mchirp: numpy.ndarray
        Chirp mass of missed injections
    distribution_param: string
        Parameter D of the injections used to generate a distribution over
        distance, may be 'distance', 'chirp_distance'.
    distribution: string
        form of the distribution over the parameter, may be
        'log' (uniform in log D)
        'uniform' (uniform in D)
        'distancesquared' (uniform in D**2)
        'volume' (uniform in D**3)
    limits_param: string
        Parameter Dlim specifying limits inside which injections were made
        may be 'distance', 'chirp distance'
    min_param: float
        minimum value of Dlim at which injections were made; only used for
        log distribution, then if None the minimum actually injected value
        will be used
    max_param: float
        maximum value of Dlim out to which injections were made; if None
        the maximum actually injected value will be used

    Returns
    --------
    volume: float
        Volume estimate
    volume_error: float
        The standard error in the volume
    g      @g       @g      ?g        )loguniformZdistancesquaredvolumeg?g?g      @r   g0f?Nr   z %s is not a recognized parametergUUUUUU?z)%s is not a recognized distance parameterr   r-   g      ?)	r   concatenatemaxNotImplementedErrorr"   r#   lenminr-   )found_dmissed_dfound_mchirpmissed_mchirpdistribution_paramdistributionlimits_param	min_param	max_paramZd_powerZmchirp_powerZmchirp_standard_bnsZ
all_mchirpZ
max_mchirpZmax_distanceZmontecarlo_vtotZfound_weightsZmissed_weightsZall_weightsZmc_weight_samplesZmc_sumZmc_normZmc_prefactorZNinjZmin_distanceZlograngeZmc_sample_variancer%   r)   r   r   r   volume_montecarloV   sx    2










r>   c	          
   C   sD   |dkst |dkst t| |}	t||}
t|	|
||d|d||	S )Nr   r   )AssertionErrorr   r>   )r5   r6   r7   r8   r9   r:   r;   r<   r=   Zfound_dchirpZmissed_dchirpr   r   r   chirp_volume_montecarlo   s    

r@      c             C   sf   dd }t | |g}ttt|t||tdddg}t| |||\}}|jd |jd fS )a|   Compute the sensitive volume using a distance binned efficiency estimate

    Parameters
    -----------
    f_dist: numpy.ndarray
        The distances of found injections
    m_dist: numpy.ndarray
        The distances of missed injections

    Returns
    --------
    volume: float
        Volume estimate
    volume_error: float
        The standard error in the volume
    c             S   s   | dfS )Nr   r   )r   r   r   r   sims_to_bin  s    z(volume_binned_pylal.<locals>.sims_to_bing        r   r   )	r   r0   r   r   Z
LinearBinsr4   r1   r'   r   )f_distm_distr   rB   r   r   r%   Zverrr   r   r   volume_binned_pylal   s    rE   c       
      C   s   |    |   t| |g}| }|| }d}d}d}xtt|D ]}|t|d kr^P ||d  ||  d }|| }	|| t| k r|dtj || d  |	 7 }|dtj || d  |	 d 7 }|}qHW |d }||fS )aq   Compute the sensitive volume using sum over spherical shells.

    Parameters
    -----------
    f_dist: numpy.ndarray
        The distances of found injections
    m_dist: numpy.ndarray
        The distances of missed injections

    Returns
    --------
    volume: float
        Volume estimate
    volume_error: float
        The standard error in the volume
    r   r   r   r   g       @g      ?)sortr   r0   Zargsortranger3   r"   )
rC   rD   Z	distancesZdist_sortinglowr%   r)   ihighZ	bin_widthr   r   r   volume_shell  s&    "rK   )NN)rA   )__doc__r   Zpycbc.conversionsr    r   r   r'   r,   r>   r@   rE   rK   r   r   r   r   <module>   s   
 
