B
    d_I                 @   sj   d Z ddlmZmZ ddlZddlmZ ddlm	Z	 G dd dedZ
G d	d
 d
e
ZG dd deZdS )z2 Classes and functions for adjusting strain data.
    )ABCMetaabstractmethodN)UnivariateSpline)FrequencySeriesc               @   s>   e Zd ZdZdZdd Zedd Zddd	Ze	d
d Z
dS )Recalibratez& Base class for modifying calibration Nc             C   s   || _ t | _d S )N)ifo_namedictparams)selfr    r   e/work/yifan.wang/ringdown/master-ringdown-env/lib/python3.7/site-packages/pycbc/strain/recalibrate.py__init__   s    zRecalibrate.__init__c             C   s   dS )a:  Apply calibration model

        This method should be overwritten by subclasses

        Parameters
        ----------
        strain : FrequencySeries
            The strain to be recalibrated.

        Return
        ------
        strain_adjusted : FrequencySeries
            The recalibrated strain.
        Nr   )r
   strainr   r   r   apply_calibration#   s    zRecalibrate.apply_calibrationrecalib_c                s,   j  fdd D  |}|S )a[  Map an input dictionary of sampling parameters to the
        adjust_strain function by filtering the dictionary for the
        calibration parameters, then calling adjust_strain.

        Parameters
        ----------
        strain : FrequencySeries
            The strain to be recalibrated.
        prefix: str
            Prefix for calibration parameter names
        params : dict
            Dictionary of sampling parameters which includes
            calibration parameters.
        Return
        ------
        strain_adjusted : FrequencySeries
            The recalibrated strain.
        c                s4   i | ],}|krj |kr | |td  qS )N)r   len).0key)r	   prefixr
   r   r   
<dictcomp>I   s   z-Recalibrate.map_to_adjust.<locals>.<dictcomp>)r	   updater   )r
   r   r   r	   strain_adjustedr   )r	   r   r
   r   map_to_adjust5   s    

zRecalibrate.map_to_adjustc                sT   t ||  fdd D fddD d  d< | f S )a7  Read a config file to get calibration options and transfer
        functions which will be used to intialize the model.

        Parameters
        ----------
        cp : WorkflowConfigParser
            An open config file.
        ifo : string
            The detector (H1, L1) for which the calibration model will
            be loaded.
        section : string
            The section name in the config file from which to retrieve
            the calibration options.
        Return
        ------
        instance
            An instance of the class.
        c                s2   i | ]*}  |kr | |td  d qS )   N)lowerr   )r   r   )
all_paramsifor   r   r   f   s   z+Recalibrate.from_config.<locals>.<dictcomp>c                s   i | ]} | |qS r   r   )r   r   )r	   r   r   r   h   s    modelr   )r   itemspopr   )clscpr   sectionr   )r   r   r	   r   from_configQ   s    
zRecalibrate.from_config)r   )__name__
__module____qualname____doc__namer   r   r   r   classmethodr#   r   r   r   r   r      s   
r   )	metaclassc               @   s$   e Zd ZdZdZdd Zdd ZdS )CubicSplinea  Cubic spline recalibration

    see https://dcc.ligo.org/LIGO-T1400682/public

    This assumes the spline points follow
    np.logspace(np.log(minimum_frequency), np.log(maximum_frequency),
    n_points)

    Parameters
    ----------
    minimum_frequency: float
    minimum frequency of spline points
    maximum_frequency: float
    maximum frequency of spline points
    n_points: int
    number of spline points
    Zcubic_splinec             C   s\   t j| |d t|}t|}t|}|dk r6td|| _tt|t||| _	d S )N)r      z2Use at least 4 spline points for calibration model)
r   r   floatint
ValueErrorn_pointsnpZlogspacelog10spline_points)r
   Zminimum_frequencyZmaximum_frequencyr0   r   r   r   r   r      s    zCubicSpline.__init__c       	         s    fddt  jD }t j|}||j } fddt  jD }t j|}||j }|d|  dd|   dd|   }|S )a?  Apply calibration model

        This applies cubic spline calibration to the strain.

        Parameters
        ----------
        strain : FrequencySeries
            The strain to be recalibrated.

        Return
        ------
        strain_adjusted : FrequencySeries
            The recalibrated strain.
        c                s    g | ]} j d  j| qS )zamplitude_{}_{})r	   formatr   )r   ii)r
   r   r   
<listcomp>   s   z1CubicSpline.apply_calibration.<locals>.<listcomp>c                s    g | ]} j d  j| qS )zphase_{}_{})r	   r4   r   )r   r5   )r
   r   r   r6      s   g      ?g       @y              ?)ranger0   r   r3   sample_frequenciesnumpy)	r
   r   Zamplitude_parametersZamplitude_splineZdelta_amplitudeZphase_parametersZphase_splineZdelta_phaser   r   )r
   r   r      s    

$zCubicSpline.apply_calibrationN)r$   r%   r&   r'   r(   r   r   r   r   r   r   r+   o   s   r+   c               @   sh   e Zd ZdZdZdddZdddZdd
dZdddZdddZ	e
dddZe
dd Zdd ZdS )PhysicalModela   Class for adjusting time-varying calibration parameters of given
    strain data.

    Parameters
    ----------
    strain : FrequencySeries
        The strain to be adjusted.
    freq : array
        The frequencies corresponding to the values of c0, d0, a0 in Hertz.
    fc0 : float
        Coupled-cavity (CC) pole at time t0, when c0=c(t0) and a0=a(t0) are
        measured.
    c0 : array
        Initial sensing function at t0 for the frequencies.
    d0 : array
        Digital filter for the frequencies.
    a_tst0 : array
        Initial actuation function for the test mass at t0 for the
        frequencies.
    a_pu0 : array
        Initial actuation function for the penultimate mass at t0 for the
        frequencies.
    fs0 : float
        Initial spring frequency at t0 for the signal recycling cavity.
    qinv0 : float
        Initial inverse quality factor at t0 for the signal recycling
        cavity.
    Zphysical_modelNc	       
      C   s   t || _|| _|| _|| _|| _t|| _t|| _	t|| _
| jd | jd d| j | j	 | j
  | j	d   }	| j| j | j| j  | _d| j | j | _| jdd| j | j   |	 | _d S )N   y              ?g      ?r   )r1   realfreqc0d0a_tst0a_pu0r-   fc0fs0qinv0Zg0r0c_res)
r
   r=   rB   r>   r?   r@   rA   rC   rD   Zinit_detuningr   r   r   r      s    


,zPhysicalModel.__init__      ?c             C   sN   | j d | j d d| j  | |  |d   }| j| dd| j  |   | S )aM   Calculate the sensing function c(f,t) given the new parameters
        kappa_c(t), kappa_a(t), f_c(t), fs, and qinv.

        Parameters
        ----------
        fc : float
            Coupled-cavity (CC) pole at time t.
        kappa_c : float
            Scalar correction factor for sensing function at time t.
        fs : float
            Spring frequency for signal recycling cavity.
        qinv : float
            Inverse quality factor for signal recycling cavity.

        Returns
        -------
        c : numpy.array
            The new sensing function c(f,t).
        r;   y              ?r   )r=   rF   )r
   fsqinvfckappa_cZdetuning_termr   r   r   update_c   s    &zPhysicalModel.update_c        c	             C   sH   | j ||||d}	| j|d|   }
| j|d|   }|	| j |
|  S )aa   Calculate the open loop gain g(f,t) given the new parameters
        kappa_c(t), kappa_a(t), f_c(t), fs, and qinv.

        Parameters
        ----------
        fc : float
            Coupled-cavity (CC) pole at time t.
        kappa_c : float
            Scalar correction factor for sensing function c at time t.
        kappa_tst_re : float
            Real part of scalar correction factor for actuation function
            a_tst0 at time t.
        kappa_pu_re : float
            Real part of scalar correction factor for actuation function
            a_pu0 at time t.
        kappa_tst_im : float
            Imaginary part of scalar correction factor for actuation function
            a_tst0 at time t.
        kappa_pu_im : float
            Imaginary part of scalar correction factor for actuation function
            a_pu0 at time t.
        fs : float
            Spring frequency for signal recycling cavity.
        qinv : float
            Inverse quality factor for signal recycling cavity.

        Returns
        -------
        g : numpy.array
            The new open loop gain g(f,t).
        )rH   rI   rJ   rK   y              ?)rL   r@   rA   r?   )r
   rH   rI   rJ   kappa_tst_rekappa_tst_imkappa_pu_rekappa_pu_imrK   cZa_tstZa_pur   r   r   update_g  s    "zPhysicalModel.update_gc	          
   C   s8   | j ||||d}	| j||||||||d}
d|
 |	 S )ag   Calculate the response function R(f,t) given the new parameters
        kappa_c(t), kappa_a(t), f_c(t), fs, and qinv.

        Parameters
        ----------
        fc : float
            Coupled-cavity (CC) pole at time t.
        kappa_c : float
            Scalar correction factor for sensing function c at time t.
        kappa_tst_re : float
            Real part of scalar correction factor for actuation function
            a_tst0 at time t.
        kappa_pu_re : float
            Real part of scalar correction factor for actuation function
            a_pu0 at time t.
        kappa_tst_im : float
            Imaginary part of scalar correction factor for actuation function
            a_tst0 at time t.
        kappa_pu_im : float
            Imaginary part of scalar correction factor for actuation function
            a_pu0 at time t.
        fs : float
            Spring frequency for signal recycling cavity.
        qinv : float
            Inverse quality factor for signal recycling cavity.

        Returns
        -------
        r : numpy.array
            The new response function r(f,t).
        )rH   rI   rJ   rK   )rH   rI   rJ   rK   rN   rO   rP   rQ   g      ?)rL   rS   )r
   rH   rI   rJ   rK   rN   rO   rP   rQ   rR   gr   r   r   update_r(  s    "
zPhysicalModel.update_rc
          
   C   s   |r| j | n| j }
|r"| j| n| j}|r6| j| n| j}| j|||
|||||	d}|| j }t|}tt|}d}t	| j
||dd}t	| j
||dd}|j }||td||  }t| | |jd}|S )a  Adjust the FrequencySeries strain by changing the time-dependent
        calibration parameters kappa_c(t), kappa_a(t), f_c(t), fs, and qinv.

        Parameters
        ----------
        strain : FrequencySeries
            The strain data to be adjusted.
        delta_fc : float
            Change in coupled-cavity (CC) pole at time t.
        kappa_c : float
            Scalar correction factor for sensing function c0 at time t.
        kappa_tst_re : float
            Real part of scalar correction factor for actuation function
            A_{tst0} at time t.
        kappa_tst_im : float
            Imaginary part of scalar correction factor for actuation function
            A_tst0 at time t.
        kappa_pu_re : float
            Real part of scalar correction factor for actuation function
            A_{pu0} at time t.
        kappa_pu_im : float
            Imaginary part of scalar correction factor for actuation function
            A_{pu0} at time t.
        fs : float
            Spring frequency for signal recycling cavity.
        qinv : float
            Inverse quality factor for signal recycling cavity.

        Returns
        -------
        strain_adjusted : FrequencySeries
            The adjusted strain.
        )rH   rI   rJ   rK   rN   rO   rP   rQ   r   r   )ksy              ?)delta_f)rB   rC   rD   rU   rE   r1   absunwrapZangler   r=   r8   r9   expr   rX   )r
   r   delta_fs
delta_qinvdelta_fcrK   rN   rO   rP   rQ   rJ   rH   rI   Z
r_adjustedrV   Zk_ampZk_phaseorderZ	k_amp_offZk_phase_offZ	freq_evenZk_even_sampler   r   r   r   adjust_strainQ  s*    $



zPhysicalModel.adjust_strain c             C   sT   t j||d}|dddf }|dddf d|dddf   }t ||g S )a,  Convert the contents of a file with the columns
        [freq, real(h), imag(h)] to a numpy.array with columns
        [freq, real(h)+j*imag(h)].

        Parameters
        ----------
        path : string
        delimiter : {" ", string}

        Return
        ------
        numpy.array
        )	delimiterNr   r   y              ?r;   )r1   ZloadtxtarrayZ	transpose)r    pathrb   datar=   hr   r   r   tf_from_file  s    $zPhysicalModel.tf_from_filec          
      sP  g }ddddg}x8 fdd|D D ]"}| ||d}|| | q$W |d ddd	f }|d	 ddd	f }	|d
 ddd	f }
|d ddd	f }|d dddf }d dg}|||r| ||d}|	| |ddd	f 7 }	| |d dgd}| |d dgd}| |d dgd}| |||
|||	||dS )aD  Read a config file to get calibration options and transfer
        functions which will be used to intialize the model.

        Parameters
        ----------
        cp : WorkflowConfigParser
            An open config file.
        ifo : string
            The detector (H1, L1) for which the calibration model will
            be loaded.
        section : string
            The section name in the config file from which to retrieve
            the calibration options.

        Return
        ------
        instance
            An instance of the Recalibrate class.
        za-tstza-purR   dc                s   g | ]}d   d|gqS )-ztransfer-function)join)r   r(   )r   r   r   r6     s   z-PhysicalModel.from_config.<locals>.<listcomp>Nr   r   r;      ri   ztransfer-function-a-uimrB   rC   rD   )r=   rB   r>   r?   r@   rA   rC   rD   )Zget_opt_tagappendrg   rj   
has_option)r    r!   r   r"   ZtfsZtf_namestagZtf_pathr@   rA   r>   r?   r=   Zuim_tagrB   rC   rD   r   )r   r   r#     s(    zPhysicalModel.from_configc       
      K   s   ddddddddg}d	d
 |D }ddddddddg}g }x8t ||D ]*\}}||krf|||  qF|| qFW | j||d |d |d |d |d |d |d |d d	}	|	S )a  Map an input dictionary of sampling parameters to the
        adjust_strain function by filtering the dictionary for the
        calibration parameters, then calling adjust_strain.

        Parameters
        ----------
        strain : FrequencySeries
            The strain to be recalibrated.
        params : dict
            Dictionary of sampling parameters which includes
            calibration parameters.

        Return
        ------
        strain_adjusted : FrequencySeries
            The recalibrated strain.
        r\   r^   r]   rK   rN   rO   rP   rQ   c             S   s   g | ]}d  d|gqS ) Zcalib_)rj   )r   r(   r   r   r   r6     s    z/PhysicalModel.map_to_adjust.<locals>.<listcomp>g        g      ?r   r   r;   rk   r,            )r\   r^   r]   rK   rN   rO   rP   rQ   )ziprl   r`   )
r
   r   r	   	arg_namesZ
arg_labelsdefault_valuesZ
calib_argsargvalr   r   r   r   r     s$    zPhysicalModel.map_to_adjust)NNNNNNNN)NNNrG   )NNNrG   rM   rG   rM   rG   )NNNrG   rG   rM   rG   rM   )NNNrG   rG   rM   rG   rM   )ra   )r$   r%   r&   r'   r(   r   rL   rS   rU   r`   r)   rg   r#   r   r   r   r   r   r:      s$    

  
%  
'  
A1r:   )r'   abcr   r   r9   r1   Zscipy.interpolater   Zpycbc.typesr   r   r+   objectr:   r   r   r   r   <module>   s   TC