B
    d0                 @   sf   d dl mZ d dl mZ d dlmZ d dlZd dlZdZdd	d
Z	G dd de
ZG dd deZdS )    )make_frequency_series)matched_filter_core)ArrayNzpycbc.vetoes.autochisq_   TFc	       !      C   sh  t | }	tt |}
t|	| }|dkr.|}||kr:|}t| | }| | j| }| | j| }| | }|| d }|dkrt|d|}n@|dkrt|||}n(t|d|}t|||}t||}|| }|j|j }||j|j 7 }d| }x8t	|D ]*\}}|| }|| }|| }| | j| | | j|  }|d dk rj||dk   |	7  < |d |	d kr|||	d k  |	8  < || j| || j|  }||j|  }|| | }|rd| }|| j | || j|  }||j|  }||| | 7 }|r(|
 |
|< n| |
|< q
W |} |dkrP| d } |r^| d } | |
|fS )	a   
    Compute correlation (two sided) between template and data
    and compares with autocorrelation of the template: C(t) = IFFT(A*A/S(f))

    Parameters
    ----------
    sn: Array[complex]
        normalized (!) array of complex snr for the template that produced the
        trigger(s) being tested
    corr_sn : Array[complex]
        normalized (!) array of complex snr for the template that you want to
        produce a correlation chisq test for. In the [common] case that sn and
        corr_sn are the same, you are computing auto-correlation chisq.
    hautocorr: Array[complex]
        time domain autocorrelation for the template
    indices: Array[int]
        compute correlation chisquare at the points specified in this array,
    num_points: [int, optional; default=None]
        Number of points used for autochisq on each side, if None all points
        are used.
    stride: [int, optional; default = 1]
        stride for points selection for autochisq
        total length <= 2*num_points*stride
    oneside: [str, optional; default=None]
        whether to use one or two sided autochisquare. If None (or not
        provided) twosided chi-squared will be used. If given, options are
        'left' or 'right', to do one-sided chi-squared on the left or right.
    twophase: Boolean, optional; default=True
        If True calculate the auto-chisq using both phases of the filter.
        If False only use the phase of the obtained trigger(s).
    maxvalued: Boolean, optional; default=False
        Return the largest auto-chisq at any of the points tested if True.
        If False, return the sum of auto-chisq at all points tested.

    Returns
    -------
    autochisq: [tuple]
        returns autochisq values and snr corresponding to the instances
        of time defined by indices
    Nr   leftr   rightg      ?   )lennpZzerosintabsrealimagZarangeappend	enumeratemaxsum)!snZcorr_snZ	hautocorrindicesstride
num_pointsonesidetwophase	maxvaluedZNsnrZachisqZnum_points_allZsnrabsZ
cphi_arrayZ
sphi_arrayZstart_pointZ	end_pointZachisq_idx_listZachisq_idx_list_pt1Zachisq_idx_list_pt2Zhauto_corr_vecZ
hauto_normZ
chisq_normipindZcurr_achisq_idx_listZcphiZsphiZsnr_indzZdzZcurr_achisq_listdof r   c/work/yifan.wang/ringdown/master-ringdown-env/lib/python3.7/site-packages/pycbc/vetoes/autochisq.pyautochisq_from_precomputed   sh    +

r!   c               @   s$   e Zd ZdZdddZd	ddZdS )
SingleDetAutoChisqzClass that handles precomputation and memory management for efficiently
    running the auto chisq in a single detector inspiral analysis.
    NFc       	      C   s   |dkrd| _ d| _d| _|| _|| _|| _|| _|dk	rF| jd | _|| _| jr^| jd | _|| _|| _	| j	r|dkrd}|d7 }|d	7 }t
||| _d| _d| _nd
| _ dS )a  
        Initialize autochisq calculation instance

        Parameters
        -----------
        stride : int
            Number of sample points between points at which auto-chisq is
            calculated.
        num_points : int
            Number of sample points at which to calculate auto-chisq in each
            direction from the trigger
        onesided : optional, default=None, choices=['left','right']
            If None (default), calculate auto-chisq in both directions from the
            trigger. If left (backwards in time) or right (forwards in time)
            calculate auto-chisq only in that direction.
        twophase : optional, default=False
            If False calculate auto-chisq using only the phase of the trigger.
            If True, compare also against the orthogonal phase.
        reverse_template : optional, default=False
            If true, time-reverse the template before calculating auto-chisq.
            In this case this is more of a cross-correlation chisq than auto.
        take_maximum_value : optional, default=False
            If provided, instead of adding the auto-chisq value at each sample
            point tested, return only the maximum value.
        maximal_value_dof : int, required if using take_maximum_value
            If using take_maximum_value the expected value is not known. This
            value specifies what to store in the cont_chisq_dof output.
        r   TZ
cont_chisqZcont_chisq_dofNr	   z+Must provide the maximal_value_dof keyword z)argument if using the take_maximum_value zoption.F)doZcolumn_nameZtable_dof_namer   r   r   	one_sided	two_phasereverse_templatetake_maximum_value
ValueError_autocor_autocor_id)	selfr   r   Zonesidedr   r&   r'   Zmaximal_value_doferr_msgr   r   r    __init__   s2    zSingleDetAutoChisq.__init__c	             C   sr  | j rnt|dkrnt|}	t|t|f}
|
| jkrtd | jst|	|	|||d\}}}|d|d   }t	|dd| _
nHt|	 |	|||d\}}}|t||d  }||9 }t	|dd| _
|
| _td || }| jr |d	k	stt|	 |||||d
\}}}|| }n|}tg }t|}t||| j
|| j| j| j| j| jd	\}}}|| _|S d	S )a  
        Calculate the auto-chisq at the specified indices.

        Parameters
        -----------
        sn : Array[complex]
            SNR time series of the template for which auto-chisq is being
            computed. Provided unnormalized.
        indices : Array[int]
            List of points at which to calculate auto-chisq
        template : Pycbc template object
            The template for which we are calculating auto-chisq
        psd : Pycbc psd object
            The PSD of the data being analysed
        norm : float
            The normalization factor to apply to sn
        stilde : Pycbc data object, needed if using reverse-template
            The data being analysed. Only needed if using reverse-template,
            otherwise ignored
        low_frequency_cutoff : float
            The lower frequency to consider in matched-filters
        high_frequency_cutoff : float
            The upper frequency to consider in matched-filters
        r   zCalculating autocorrelation)psdlow_frequency_cutoffhigh_frequency_cutoffg      ?T)copyg      ?z...Calculating autochisquareN)r/   r0   Zh_norm)r   r   r   r   r   )r#   r
   r   idr*   logginginfor&   r   r   r)   ZconjfloatZsigmasqAssertionErrorr   arrayr!   r   r   r$   r%   r'   r   )r+   r   r   templater.   ZnormZstilder/   r0   ZhtildekeyZPt_ZP_normZnorm_facZasnZahnrmZcorrelation_snrZ	achi_listZ
index_listr   r   r   r    values   sN    







zSingleDetAutoChisq.values)NFFFN)NNN)__name__
__module____qualname____doc__r-   r;   r   r   r   r    r"      s     
9 r"   c                   s(   e Zd ZdZ fddZdd Z  ZS )SingleDetSkyMaxAutoChisqzGStub for precessing auto chisq if anyone ever wants to code it up.
    c                s   t t| j|| d S )N)superr@   r-   )r+   argskwds)	__class__r   r    r-     s    z!SingleDetSkyMaxAutoChisq.__init__c             O   s,   | j r$d}|d7 }|d7 }t|nd S d S )Nz6Precessing single detector sky-max auto chisq has not z2been written. If you want to use it, why not help z	write it?)r#   NotImplementedError)r+   rB   kwargsr,   r   r   r    r;     s    
zSingleDetSkyMaxAutoChisq.values)r<   r=   r>   r?   r-   r;   __classcell__r   r   )rD   r    r@     s   r@   )r   NNTF)Zpycbc.filterr   r   Zpycbc.typesr   numpyr   r3   ZBACKEND_PREFIXr!   objectr"   r@   r   r   r   r    <module>   s    
o 