B
    d                 @   sV   d Z ddlZddlmZmZ dd Zdd Zdd	d
ZdddZdddZ	dd Z
dS )z8 Functions for removing frequency lines from real data.
    N)
TimeSerieszerosc             C   s4   t dd | D }t dd | D }|d|  S )a   Get the median value of a list of complex numbers.

    Parameters
    ----------
    complex_list: list
        List of complex numbers to calculate the median.

    Returns
    -------
    a + 1.j*b: complex number
        The median of the real and imaginary parts.
    c             S   s   g | ]
}|j qS  )real).0complex_numberr   r   _/work/yifan.wang/ringdown/master-ringdown-env/lib/python3.7/site-packages/pycbc/strain/lines.py
<listcomp>#   s   z"complex_median.<locals>.<listcomp>c             S   s   g | ]
}|j qS r   )imag)r   r   r   r   r   r	   %   s   y              ?)numpyZmedian)Zcomplex_listZmedian_realZmedian_imagr   r   r   complex_median   s
    



r   c          	   C   s   | j |j kst| j|jks tt|| j }g }xztt| j | D ]d}|| |d |  }}t| || }dt| j|| jt	
|j||   | }	||	 qFW t|}
|t	|
t	|
fS )a   Calculate the time-domain inner product averaged over bins.

    Parameters
    ----------
    data1: pycbc.types.TimeSeries
        First data set.
    data2: pycbc.types.TimeSeries
        Second data set, with same duration and sample rate as data1.
    bin_size: float
        Duration of the bins the data will be divided into to calculate
        the inner product.

    Returns
    -------
    inner_prod: list
        The (complex) inner product of data1 and data2 obtained in each bin.
    amp: float
        The absolute value of the median of the inner product.
    phi: float
        The angle of the median of the inner product.
          )durationAssertionErrorsample_rateintrangelensumdatar   r   	conjugateappendr   absZangle)Zdata1Zdata2bin_sizeseglenZ
inner_prodidxstartendZnormZbin_prodZinner_medianr   r   r   avg_inner_product)   s    0r   r   c             C   sV   t tt||j|jd}|jt| }dtj |  | | }|t	d|  |_
|S )a   Simple time-domain model for a frequency line.

    Parameters
    ----------
    freq: float
        Frequency of the line.
    data: pycbc.types.TimeSeries
        Reference data, to get delta_t, start_time, duration and sample_times.
    tref: float
        Reference time for the line model.
    amp: {1., float}, optional
        Amplitude of the frequency line.
    phi: {0. float}, optional
        Phase of the frequency line (radians).

    Returns
    -------
    freq_line: pycbc.types.TimeSeries
        A timeseries of the line model with frequency 'freq'. The returned
        data are complex to allow measuring the amplitude and phase of the
        corresponding frequency line in the strain data. For extraction, use
        only the real part of the data.
    )delta_tepochr   y              ?)r   r   r   r    
start_timeZsample_timesfloatr   piexpr   )freqr   trefampphiZ	freq_linetimesalphar   r   r   
line_modelO   s    
r,   c             C   s4   t | ||d}t|||d\}}}t | ||||dS )a]   Find the parameter of the line with frequency 'freq' in the data.

    Parameters
    ----------
    freq: float
        Frequency of the line to find in the data.
    data: pycbc.types.TimeSeries
        Data from which the line wants to be measured.
    tref: float
        Reference time for the frequency line.
    bin_size: {1, float}, optional
        Duration of the bins the data will be divided into for averaging.

    Returns
    -------
    line_model: pycbc.types.TimeSeries
        A timeseries containing the frequency line with the amplitude
        and phase measured from the data.
    )r'   )r   )r'   r(   r)   )r,   r   )r&   r   r'   r   Ztemplate_line_r(   r)   r   r   r   matching_linep   s    r.   c             C   sB   |dkrt |j}x*| D ]"}t||||jd}||jj8 }qW |S )a   Extract the calibration lines from strain data.

    Parameters
    ----------
    freqs: list
        List containing the frequencies of the calibration lines.
    data: pycbc.types.TimeSeries
        Strain data to extract the calibration lines from.
    tref: {None, float}, optional
        Reference time for the line. If None, will use data.start_time.

    Returns
    -------
    data: pycbc.types.TimeSeries
        The strain data with the calibration lines removed.
    N)r   )r#   r"   r.   r   r   r   )freqsr   r'   r&   Zmeasured_liner   r   r   calibration_lines   s    


r0   c          	   C   s  ||krt d||jkr"t dtdt|j| d d}||j }t|j}x0| D ]&}x|D ]}t|| t|d |  }	}
t|||	|
 ||d}t	t
|}ttt
||j|jd}|dkr|jt
|d d	  |t
|d d	 9  < nL||d
 krF|jd	t
|d   |d	t
|d  9  < n| j|9  _| j|j9  _|j|	|
  |jj8  < qhW qZW |S )a'   Extract time-varying (wandering) lines from strain data.

    Parameters
    ----------
    freqs: list
        List containing the frequencies of the wandering lines.
    data: pycbc.types.TimeSeries
        Strain data to extract the wandering lines from.
    chunk: float
        Duration of the chunks the data will be divided into to account
        for the time variation of the wandering lines. Should be smaller
        than data.duration, and allow for at least a few chunks.
    avg_bin: float
        Duration of the bins each chunk will be divided into for averaging
        the inner product when measuring the parameters of the line. Should
        be smaller than chunk.

    Returns
    -------
    data: pycbc.types.TimeSeries
        The strain data with the wandering lines removed.
    zNThe bin size for averaging the inner product must be less than the chunk size.z3The chunk size must be less than the data duration.r   g      ?r   )r   )r    r!   r   N)
ValueErrorr   r   Zaranger   r   r#   r"   r.   Zhanningr   r   Zonesr    r   r   )r/   r   chunkZavg_binZstepsr   r'   r&   stepr   r   Z
chunk_lineZhann_windowZ
apply_hannr   r   r   
clean_data   s4    





"r5   )r   r   )r   )N)__doc__r   Zpycbc.typesr   r   r   r   r,   r.   r0   r5   r   r   r   r   <module>   s   &
!

