B
    dL                 @   s   d dl Z d dlZd dlZd dlZd dlmZmZmZm	Z	 d dl
mZmZmZmZ d dlmZ d dlZdZdd Zddd	Zeed
d Zeedd Zdd ZdadadadddZdd ZdddZG dd deZG dd deZ dS )    N)zerosreal_same_precision_as
TimeSeriescomplex_same_precision_as)sigmasq_seriesmake_frequency_seriesmatched_filter_coreget_cutoff_indices)schemedzpycbc.vetoes.chisq_c             C   sL   | |d  }t d|| | }t j| || |dd}||7 }t ||S )a  Returns bins of equal power for use with the chisq functions

    Parameters
    ----------

    sigmasq_series: FrequencySeries
        A frequency series containing the cumulative power of a filter template
        preweighted by a psd.
    num_bins: int
        The number of chisq bins to calculate.
    kmin: int
        DOCUMENTME
    kmax: int
        DOCUMENTME

    Returns
    -------

    bins: List of ints
        A list of the edges of the chisq bins is returned.
       r   right)Zside)numpyZarangeZsearchsortedappend)r   num_binskminkmaxZsigmasqZedge_vecbins r   _/work/yifan.wang/ringdown/master-ringdown-env/lib/python3.7/site-packages/pycbc/vetoes/chisq.py$power_chisq_bins_from_sigmasq_series!   s
    r   c             C   s@   t | ||| }t||| jt| d d \}}t||||S )a  Returns bins of equal power for use with the chisq functions

    Parameters
    ----------

    htilde: FrequencySeries
        A frequency series containing the template waveform
    num_bins: int
        The number of chisq bins to calculate.
    psd: FrequencySeries
        A frequency series containing the psd. Its length must be commensurate
        with the template waveform.
    low_frequency_cutoff: {None, float}, optional
        The low frequency cutoff to apply
    high_frequency_cutoff: {None, float}, optional
        The high frequency cutoff to apply

    Returns
    -------

    bins: List of ints
        A list of the edges of the chisq bins is returned.
    r      )r   r   r	   delta_flenr   )htilder   psdlow_frequency_cutoffhigh_frequency_cutoffZ	sigma_vecr   r   r   r   r   power_chisq_bins>   s    
r   c             C   s   d}|d7 }t |d S )Nz<This function is a stub that should be overridden using the z+scheme. You shouldn't be seeing this error!)
ValueError)chisqqerr_msgr   r   r   chisq_accum_bin`   s    r"   c             C   s   d}|d7 }t |dS )z; Calculate the time shifted sum of the FrequencySeries
    z<This function is a stub that should be overridden using the z+scheme. You shouldn't be seeing this error!N)r   )Zv1Zshiftsr   r!   r   r   r   	shift_sumf   s    r#   c             C   s6   t |d }t| ||}|| | | j |d  S )aX  Calculate the chisq timeseries from precomputed values for only select points.

    This function calculates the chisq at each point by explicitly time shifting
    and summing each bin. No FFT is involved.

    Parameters
    ----------
    corr: FrequencySeries
        The product of the template and data in the frequency domain.
    snr: numpy.ndarray
        The unnormalized array of snr values at only the selected points in `indices`.
    snr_norm: float
        The normalization of the snr (EXPLAINME : refer to Findchirp paper?)
    bins: List of integers
        The edges of the equal power bins
    indices: Array
        The indices where we will calculate the chisq. These must be relative
        to the given `corr` series.

    Returns
    -------
    chisq: Array
        An array containing only the chisq at the selected points.
    r   g       @)r   r#   Zconjreal)corrsnrsnr_normr   indicesr   r   r   r   r   &power_chisq_at_points_from_precomputedo   s    r)   Fc             C   s  g }t dkstt t|krNtt|t|d}tt|t|d}|a |ant }t}|dk	rh||}tdksttt|k rtt|t|d}	|	antdt| }	|	  t|d }
xt	|
D ]}t
|| }t
||d  }| || |||< tj|| |||   |rD|t|| |
d  |j|jd |dk	r`t|	|| qt|	| qW |	|
 |  |d  }	|dkrt|	|j|jdd	}	|r|	|fS |	S dS )
aI  Calculate the chisq timeseries from precomputed values.

    This function calculates the chisq at all times by performing an
    inverse FFT of each bin.

    Parameters
    ----------

    corr: FrequencySeries
        The produce of the template and data in the frequency domain.
    snr: TimeSeries
        The unnormalized snr time series.
    snr_norm:
        The snr normalization factor (true snr = snr * snr_norm) EXPLAINME - define 'true snr'?
    bins: List of integers
        The edges of the chisq bins.
    indices: {Array, None}, optional
        Index values into snr that indicate where to calculate
        chisq values. If none, calculate chisq for all possible indices.
    return_bins: {boolean, False}, optional
        Return a list of the SNRs for each chisq bin.

    Returns
    -------
    chisq: TimeSeries
    N)dtyper   r   g      ?)delta_tepochg       @F)r+   r,   copy)_q_lr   r   r   	_qtilde_lZtake_chisq_lr   clearrangeintpycbcZfftZifftr   r   r+   
start_timer"   Zsquared_norm)r%   r&   r'   r   r(   return_binsZbin_snrsr    Zqtilder   r   jZk_minZk_maxr   r   r   power_chisq_from_precomputed   sF    


r8   c             C   sB   ddl }t|jjj|jjr,t| ||||S t| ||||dS dS )a&  Calculate the chisq values for only selected points.

    This function looks at the number of points to be evaluated and selects
    the fastest method (FFT, or direct time shift and sum). In either case,
    only the selected points are returned.

    Parameters
    ----------
    corr: FrequencySeries
        The product of the template and data in the frequency domain.
    snr: Array
        The unnormalized snr
    snr_norm: float
        The snr normalization factor  --- EXPLAINME
    bins: List of integers
        The edges of the equal power bins
    indices: Array
        The indices where we will calculate the chisq. These must be relative
        to the given `snr` series.

    Returns
    -------
    chisq: Array
        An array containing only the chisq at the selected points.
    r   N)r(   )pycbc.scheme
isinstanceschemeZmgrstateZ	CPUSchemer)   r8   )r%   r&   snrvr'   r   r(   r4   r   r   r   fastest_power_chisq_at_points   s    

r>   c             C   sf   t | }t |}t|||||}	tt|d d |jd}
t||||||
d\}}}t||||	|dS )a  Calculate the chisq timeseries

    Parameters
    ----------
    template: FrequencySeries or TimeSeries
        A time or frequency series that contains the filter template.
    data: FrequencySeries or TimeSeries
        A time or frequency series that contains the data to filter. The length
        must be commensurate with the template.
        (EXPLAINME - does this mean 'the same as' or something else?)
    num_bins: int
        The number of frequency bins used for chisq. The number of statistical
        degrees of freedom ('dof') is 2*num_bins-2.
    psd: FrequencySeries
        The psd of the data.
    low_frequency_cutoff: {None, float}, optional
        The low frequency cutoff for the filter
    high_frequency_cutoff: {None, float}, optional
        The high frequency cutoff for the filter
    return_bins: {boolean, False}, optional
        Return a list of the individual chisq bins

    Returns
    -------
    chisq: TimeSeries
        TimeSeries containing the chisq values for all times.
    r   r   )r*   )Zcorr_out)r6   )r   r   r   r   r*   r   r8   )templatedatar   r   r   r   r6   r   Zstilder   ZcorraZ	total_snrr%   Ztnormr   r   r   power_chisq  s    
rA   c               @   s6   e Zd ZdZdddZedd Zdd	 Zd
d ZdS )SingleDetPowerChisqzClass that handles precomputation and memory management for efficiently
    running the power chisq in a single detector inspiral analysis.
    r   Nc             C   s:   |dks*|dks*d| _ d| _d| _|| _nd| _ || _d S )N0r   Tr   Z	chisq_dofF)doZcolumn_nameZtable_dof_namer   snr_threshold)selfr   rE   r   r   r   __init__6  s    zSingleDetPowerChisq.__init__c             C   s@   t td}|| j |tj |tjj t|dd i|S )N)maxmin__builtins__)rH   rI   update__dict__mathr4   Zpnutilseval)rowargZ	safe_dictr   r   r   parse_option@  s
    
z SingleDetPowerChisq.parse_optionc       	      C   s   ddl m} t|}t|ds$i |_t|ds:|dd|_||jksTt|j|jkrd|jt|j< t| || j	}t|dr|j
|jkrt|j|j }|j}t|j|j
 |||}nt||||j}||j|< |j| S )	Nr   )LimitedSizeDict_chisq_cached_key
_bin_cache   )Z
size_limitTsigmasq_vec)Z	pycbc.optrR   idhasattrrS   rT   paramsr3   rQ   r   approximantrV   f_lowerr   end_idxr   r   )	rF   r?   r   rR   keyr   r   r   r   r   r   r   cached_chisq_binsH  s*    




z%SingleDetPowerChisq.cached_chisq_binsc             C   s   | j rt|}| jrft|| | jk}| }td|  || }	|| }
tjt|tj	d}d}n|}	|}
|dkr| 
||}t|d d d }t||
|||	}| jr|dkr|||< n|}|t|t|fS dS dS )	a   Calculate the chisq at points given by indices.

        Returns
        -------
        chisq: Array
            Chisq values, one for each sample index, or zero for points below
            the specified SNR threshold

        chisq_dof: Array
            Number of statistical degrees of freedom for the chisq test
            in the given template, equal to 2 * num_bins - 2
        z#%s above chisq activation threshold)r*   ir   r   r   )NNN)rD   r   rE   abssumlogginginfor   r   float32r^   r)   repeat)rF   r%   r=   r'   r   r(   r?   	num_aboveaboveabove_indices
above_snrvZ	chisq_outdofr   Z_chisqr   r   r   valuesf  s.    
zSingleDetPowerChisq.values)r   N)	__name__
__module____qualname____doc__rG   staticmethodrQ   r^   rj   r   r   r   r   rB   2  s
   

rB   c                   s0   e Zd ZdZ fddZdd Zdd Z  ZS )SingleDetSkyMaxPowerChisqzClass that handles precomputation and memory management for efficiently
    running the power chisq in a single detector inspiral analysis when
    maximizing analytically over sky location.
    c                s"   t t| jf | d | _d | _d S )N)superrp   rG   template_memcorr_mem)rF   kwds)	__class__r   r   rG     s    z"SingleDetSkyMaxPowerChisq.__init__c             C   sj   t | || j}t|drV|j|jkrVt |j|j }|j}t	|j|j |||}nt
||||j}|S )z: Obtain the chisq bins for this template and PSD.
        rV   )r3   rQ   r   rX   rZ   rV   r[   r   r\   r   r   )rF   r?   r   r   r   r   r   r   r   r   calculate_chisq_bins  s    
z.SingleDetSkyMaxPowerChisq.calculate_chisq_binsc       "      C   sn  | j rft|}| jrlt|| jk}| }td|  || }|| }|| }tjt|tj	d}d}n|}|}|dkr2g }d}d}| j
dkst| j
t|kstt|t|d| _
| jdkst| jt|kstt|t|d| _|j}|j}t| j
j|j t| jj|j | j
j|_| jj|_xt|D ]\}}t|g}t|| g}|| }|||| }|}|j|_|j|_|| d }|d| |	 7 }||d	  }||
 | }|||| }|}| ||} t| d d d }t||| || |}!||!d  q<W t|}||_||_| jrN|dkrR|||< n|}|t|t|fS d
S dS )a'   Calculate the chisq at points given by indices.

        Returns
        -------
        chisq: Array
            Chisq values, one for each sample index

        chisq_dof: Array
            Number of statistical degrees of freedom for the chisq test
            in the given template
        z#%s above chisq activation threshold)r*   ir   g        Nr   r   g      ?)NN)rD   r   rE   r_   r`   ra   rb   r   r   rc   rr   r   rs   r@   Zcopyto_data	enumeratearrayZmultiply_and_addr[   rY   rv   r)   r   rd   )"rF   Z	corr_plusZ
corr_crossr=   r   r(   Ztemplate_plusZtemplate_crossZu_valsZhplus_cross_corrZhpnormZhcnormre   rf   rg   rh   Zrchisqri   r   Zcurr_tmplt_mult_facZcurr_corr_mult_facZ
tmplt_dataZ	corr_dataZlidxindexZabove_local_indicesZabove_local_snrZlocal_u_valr?   Znorm_facZhp_facr%   r   Z
curr_chisqr   r   r   rj     s|    









z SingleDetSkyMaxPowerChisq.values)rk   rl   rm   rn   rG   rv   rj   __classcell__r   r   )ru   r   rp     s   rp   )NN)NF)NNF)!r   ra   rM   Z	pycbc.fftr4   Zpycbc.typesr   r   r   r   Zpycbc.filterr   r   r   r	   r9   r
   Zpycbc.pnutilsZBACKEND_PREFIXr   r   r"   r#   r)   r.   r/   r0   r8   r>   rA   objectrB   rp   r   r   r   r   <module>   s*     
!	
R&  
)a