B
    d                 @   s  d Z ddlZddlZddlZddlZddlZddlmZm	Z	 ddl
Z
ddlmZmZmZ ddlmZ ddlmZmZmZ ddlmZ ddlmZ dd	lmZmZmZmZ dd
lmZ ddlm Z  ddl!m"Z" ddl#Zddl$m%Z% ddl&mZ'm(Z(m)Z) e*dZ+e,edd e,edd iZ-ddddZ.dd Z/d1ddZ0dd Z1G dd de2Z3G d d! d!ed"Z4G d#d$ d$e4Z5G d%d& d&e4Z6G d'd( d(e4Z7e5j8e5e6j8e6e7j8e7iZ9d)d* Z:d+d, Z;G d-d. d.e2Z<G d/d0 d0e2Z=dS )2z>This module provides utilities for injecting signals into data    N)ABCMetaabstractmethod)waveformframelibutils)LimitedSizeDict)get_td_waveformfd_detget_td_det_waveform_from_fd_det)utils)ringdown_td_approximants)float64float32
TimeSeriesload_timeseries)Detector)tau0_from_mass1_mass2)resample_to_delta_t)LIGOLWContentHandler)r   ligolw	lsctablesZlalsimulationc              G   s
   t j|  S )N)simZSimAddInjectionREAL4TimeSeries)args r   `/work/yifan.wang/ringdown/master-ringdown-env/lib/python3.7/site-packages/pycbc/inject/inject.py<lambda>4       r   c              G   s
   t j|  S )N)r   ZSimAddInjectionREAL8TimeSeries)r   r   r   r   r   5   r   	longitudelatituder   )radecapproximantc             C   sv   yt | }W n tk
r$   |}Y nX |dkrJt|| _td|d  | _|dkrft| |dd|g nt| || dS )z$Sets data of a SimInspiral instance.tcg    eA   )Zspin1Zspin2r   N)sim_inspiral_mapKeyErrorintZgeocent_end_timeZgeocent_end_time_nssetattr)injfielddataZ	sim_fieldr   r   r   set_sim_data@   s    

r+   r#   c          	   C   s   t | }|| }|| }y|j}|j}|j}W n   |j}|j}|j}Y nX | j|7  _| j|7  _y t	||j
}	t	||j
}
W n tk
r   |}	|}
Y nX d}t|dr|j}td|| |j|	|
|||j||d}|S )zT Use the injection row to project the polarizations into the
    detector frame
    laldetector_projection_methodzInjecting at %s, method is %s)methodZreference_time)r   r"   r   r    time_geocentr   r   
start_timewfutilstaper_timeseriestaperAttributeErrorhasattrr-   logginginfoZproject_wavepolarization)detector_namer(   hphcdistance_scaledetectorr"   r   r    Z
hp_taperedZ
hc_taperedZprojection_methodsignalr   r   r   	projectorQ   s8    


r?   c             C   sH   t | } yt| }W n   td d}Y nX tt| }||fS )zConvert the old style xml approximant name to a name
    and phase_order. Alex: I hate this function. Please delete this when we
    use Collin's new tables.
    z>Warning: Could not read phase order from string, using default)strr   ZGetOrderFromStringprintZGetStringFromApproximantZGetApproximantFromString)Zapxordernamer   r   r   legacy_approximant_name{   s    
rE   c               @   sB   e Zd ZdZdd ZdddZddd	Zd
d ZedddZ	dS )_XMLInjectionSeta:  Manages sets of injections: reads injections from LIGOLW XML files
    and injects them into time series.

    Parameters
    ----------
    sim_file : string
        Path to a LIGOLW XML file containing a SimInspiralTable
        with injection definitions.

    Attributes
    ----------
    indoc
    table
    c             K   s,   t j|dtd| _tj| j| _|| _d S )NF)contenthandler)	ligolw_utilsload_filenamer   indocr   SimInspiralTable	get_tabletable
extra_args)selfsim_filekwdsr   r   r   __init__   s    z_XMLInjectionSet.__init__Nr#   c                s  |j ttfkr tdt|j  | }tjtj }	t|j	|	 }
t|j
|	 }t|j  }|j}|dk	rpd| }| j} r fdd|D }g }x|D ]}|dkr|jn|}|jd }t|j|j|}|jd|d   }||
k s||krq| j|||||d}t||jd	d
}t|j	|kr q||j }| }|||d || |dk	r|j}||| qW |jjdd |jdd< t| }t |_| j|7  _|dk	r||_|S )a  Add injections (as seen by a particular detector) to a time series.

        Parameters
        ----------
        strain : TimeSeries
            Time series to inject signals into, of type float32 or float64.
        detector_name : string
            Name of the detector used for projecting injections.
        f_lower : {None, float}, optional
            Low-frequency cutoff for injected signals. If None, use value
            provided by each injection.
        distance_scale: {1, float}, optional
            Factor to scale the distance of an injection with. The default is
            no scaling.
        simulation_ids: iterable, optional
            If given, only inject signals with the given simulation IDs.
        inj_filter_rejector: InjFilterRejector instance; optional, default=None
            If given send each injected waveform to the InjFilterRejector
            instance so that it can store a reduced representation of that
            injection if necessary.
        injection_sample_rate: float, optional
            The sample rate to generate the signal before injection

        Returns
        -------
        None

        Raises
        ------
        TypeError
            For invalid types of `strain`.
        z-Strain dtype must be float32 or float64, not Ng      ?c                s   g | ]}|j  kr|qS r   )simulation_id).0r(   )simulation_idsr   r   
<listcomp>   s    z*_XMLInjectionSet.apply.<locals>.<listcomp>   r#   )f_lowerr<   ldas)r.   )dtyper   r   	TypeErrorrA   r,   	REARTH_SIC_SIfloatr0   end_timeinjection_func_mapdelta_trM   rX   r/   r   mass1mass2make_strain_from_inj_objectr   astypeappendrS   generate_short_inj_from_injr*   copyr   rK   injection_params)rO   strainr9   rX   r<   rU   inj_filter_rejectorinjection_sample_rate	lalstrainearth_travel_timet0t1add_injectionra   
injectionsZinjection_parametersr(   f_lr_   
inj_lengthr0   r>   
signal_lalZsidinjectedr   )rU   r   apply   sR    $






z_XMLInjectionSet.applyc             C   sV   |dkr|j n|}t|j\}}t|f|||||jd| j\}	}
t|||	|
|dS )a;  Make a h(t) strain time-series from an injection object as read from
        a sim_inspiral table, for example.

        Parameters
        -----------
        inj : injection object
            The injection object to turn into a strain h(t).
        delta_t : float
            Sample rate to make injection at.
        detector_name : string
            Name of the detector used for projecting injections.
        f_lower : {None, float}, optional
            Low-frequency cutoff for injected signals. If None, use value
            provided by each injection.
        distance_scale: {1, float}, optional
            Factor to scale the distance of an injection with. The default is
            no scaling.

        Returns
        --------
        signal : float
            h(t) corresponding to the injection.
        N)r!   ra   phase_orderrX   distance)r<   )rX   rE   r   r   ry   rN   r?   )rO   r(   ra   r9   rX   r<   rs   rD   rx   r:   r;   r   r   r   rd      s    
z,_XMLInjectionSet.make_strain_from_inj_objectc             C   s   dd | j D S )z&Return the end times of all injectionsc             S   s   g | ]
}|j qS r   )r/   )rT   r(   r   r   r   rV   $  s    z._XMLInjectionSet.end_times.<locals>.<listcomp>)rM   )rO   r   r   r   	end_times"  s    z_XMLInjectionSet.end_timesc             C   s   t  }|t   ttj}|jd | |dkr>i }|dkrL|j}xt	|j
D ]z}t }x|jD ]}t||d qlW x$|D ]}	|| |	 }
t||	|
 qW x | D ]\}	}t||	| qW || qXW tj|| dd dS )aC  Writes the injection samples to the given xml.

        Parameters
        ----------
        filename : str
            The name of the file to write to.
        samples : io.FieldArray
            FieldArray of parameters.
        write_params : list, optional
            Only write the given parameter names. All given names must be keys
            in ``samples``. Default is to write all parameters in ``samples``.
        static_args : dict, optional
            Dictionary mapping static parameter names to values. These are
            written to the ``attrs``.
        r   Nauto)compress)r   ZDocumentZappendChildZLIGO_LWr   ZNewrK   Z
childNodes
fieldnamesrangesizeZSimInspiral	__slots__r'   r+   itemsrf   rH   Zwrite_filename)filenamesampleswrite_paramsstatic_argsZxmldocZsimtableiir   colr)   r*   valuer   r   r   write&  s&    
z_XMLInjectionSet.write)Nr#   NNN)Nr#   )NN)
__name__
__module____qualname____doc__rR   rw   rd   rz   staticmethodr   r   r   r   r   rF      s      
Y
%rF   c               @   sl   e Zd ZdZejjZdZdZ	dddZ
edddZedd	d
Zedd Zedd ZedddZdS )_HDFInjectionSetaF  Manages sets of injections: reads injections from hdf files
    and injects them into time series.

    Parameters
    ----------
    sim_file : string
        Path to an hdf file containing injections.
    \**kwds :
        The rest of the keyword arguments are passed to the waveform generation
        function when generating injections.

    Attributes
    ----------
    filehandler
    table
    static_args
    extra_args
    required_params : tuple
        Parameter names that must exist in the injection HDF file in order to
        create an injection of that type.
    Nr   c                s  t |d}|d kr|n||  || _t  } fdd|D }x.|D ]&}|| jjdkrJ|| d||< qJW t|dkrd}nt	|
 d j}y jd d| _W n tk
r   g | _Y nX || j x| jD ]z}	 j|	 }
t|
tjtt	fr,tj|td	}x(t|D ]}|
||< qW nt|
|}|jjdkrP|d}|||	< qW t| jt|  }|rtd
d|| jjf || _|| _ d S )Nrc                s   i | ]} | d  |qS )r   r   )rT   param)groupr   r   
<dictcomp>t  s    z-_HDFInjectionSet.__init__.<locals>.<dictcomp>SUr   r#   r   )rZ   z>required parameter(s) {} not found in the given injection filez, )!h5pyFileZfilehandlerlistkeysrZ   kindre   lentuplevaluesr   attrsr   r%   extend
isinstancenpZndarrayemptyobjectr~   repeatcharsetrequired_params
ValueErrorformatjoin_tableclassZfrom_kwargsrM   rN   )rO   rP   Z	hdf_grouprQ   fp
parametersZinjvalskZnuminjr   valZarrr   missingr   )r   r   rR   l  s@    


z_HDFInjectionSet.__init__r#   c             K   s   dS )z,Adds injections to a detector's time series.Nr   )rO   rj   r9   r<   rU   rk   kwargsr   r   r   rw     s    z_HDFInjectionSet.applyc             K   s   dS )zAMake a h(t) strain time-series from an injection object.
        Nr   )rO   r(   ra   r9   r<   r   r   r   r   rd     s    z,_HDFInjectionSet.make_strain_from_inj_objectc             C   s   dS )z&Return the end times of all injectionsNr   )rO   r   r   r   rz     s    z_HDFInjectionSet.end_timesc             C   s   dS )z,Return a list of the supported approximants.Nr   )rO   r   r   r   supported_approximants  s    z'_HDFInjectionSet.supported_approximantsc             K   s2  t |d}|dkri }ttt| |jd< | j|jd< x| D ]\}}||j|< qJW |dkrn|j	}xF| D ]:\}	}y||j|	< W qx t
k
r   t||j|	< Y qxX qxW xl|D ]d}
y||
 ||
< W q t
k
r } z.||
 jjdkr
||
 d||
< n|W dd}~X Y qX qW W dQ R X dS )a  Writes the injection samples to the given hdf file.

        Parameters
        ----------
        filename : str
            The name of the file to write to.
        samples : io.FieldArray
            FieldArray of parameters.
        write_params : list, optional
            Only write the given parameter names. All given names must be keys
            in ``samples``. Default is to write all parameters in ``samples``.
        static_args : dict, optional
            Dictionary mapping static parameter names to values. These are
            written to the ``attrs``.
        \**metadata :
            All other keyword arguments will be written to the file's attrs.
        wNr   injtyper   r   )r   r   r   maprA   r   r   r   r   r}   r[   rZ   r   re   )clsr   r   r   r   metadatar   keyr   argr)   er   r   r   r     s*    
z_HDFInjectionSet.write)N)r#   NN)r#   )NN)r   r   r   r   pycbcioZ
FieldArrayr   r   r   rR   r   rw   rd   rz   r   classmethodr   r   r   r   r   r   Q  s   
6 r   )	metaclassc               @   sH   e Zd ZdZejjZdZdZ	dddZ
ddd	Zd
d Zedd ZdS )CBCHDFInjectionSetzManages CBC injections.
    Zcbc)r"   Nr#   c             C   s  |j ttfkr tdt|j  | }| jd d tkrPt|j	}	t|j
}
n(tjtj }t|j	| }	t|j
| }
t|j  }|j}|dk	rd| }| j}|r|t| }g }xt|D ]\}}|dkr|jn|}|jd }t|j|j|}|jd|d   }||	k s||
krq| j|||||d}t||jd	d
}t|j	|
krLq||j }| }|||d || |dk	r||| qW |jjdd |jdd< t| }|t|t |_|dk	rt |dr|j!}|j"}t#||g}t#||g}||_!||_"|S )a  Add injections (as seen by a particular detector) to a time series.

        Parameters
        ----------
        strain : TimeSeries
            Time series to inject signals into, of type float32 or float64.
        detector_name : string
            Name of the detector used for projecting injections.
        f_lower : {None, float}, optional
            Low-frequency cutoff for injected signals. If None, use value
            provided by each injection.
        distance_scale: {1, float}, optional
            Factor to scale the distance of an injection with. The default is
            no scaling.
        simulation_ids: iterable, optional
            If given, only inject signals with the given simulation IDs.
        inj_filter_rejector: InjFilterRejector instance; optional, default=None
            If given send each injected waveform to the InjFilterRejector
            instance so that it can store a reduced representation of that
            injection if necessary.
        injection_sample_rate: float, optional
            The sample rate to generate the signal before injection

        Returns
        -------
        None

        Raises
        ------
        TypeError
            For invalid types of `strain`.
        z-Strain dtype must be float32 or float64, not r   r!   Ng      ?rW   r#   )rX   r<   rY   )r.   rv   )$rZ   r   r   r[   rA   r,   rM   r	   r^   r0   r_   r\   r]   r`   ra   r   	enumeraterX   r"   r   rb   rc   rd   r   re   rf   rg   r*   rh   r   arrayr&   r5   ri   Zinjection_idsZconcatenate)rO   rj   r9   rX   r<   rU   rk   rl   rm   ro   rp   rn   rq   ra   rr   Zinjected_idsr   r(   rs   r_   rt   r0   r>   ru   rv   Zprev_pZprev_idr   r   r   rw     sb    $





zCBCHDFInjectionSet.applyc       
      C   sz   |dkr|j }n|}|d tkrHt|f|||d| j| }|| }n.t|f||d| j\}}	t||||	|d}|S )a  Make a h(t) strain time-series from an injection object.

        Parameters
        -----------
        inj : injection object
            The injection object to turn into a strain h(t). Can be any
            object which has waveform parameters as attributes, such as an
            element in a ``WaveformArray``.
        delta_t : float
            Sample rate to make injection at.
        detector_name : string
            Name of the detector used for projecting injections.
        f_lower : {None, float}, optional
            Low-frequency cutoff for injected signals. If None, use value
            provided by each injection.
        distance_scale: {1, float}, optional
            Factor to scale the distance of an injection with. The default is
            no scaling.

        Returns
        --------
        signal : float
            h(t) corresponding to the injection.
        Nr!   )ra   rX   Zifos)ra   rX   )r<   )rX   r	   r
   rN   r   r?   )
rO   r(   ra   r9   rX   r<   rs   rj   r:   r;   r   r   r   rd   W  s    
z.CBCHDFInjectionSet.make_strain_from_inj_objectc             C   s   | j jS )z&Return the end times of all injections)rM   r"   )rO   r   r   r   rz     s    zCBCHDFInjectionSet.end_timesc              C   sT   g } x4t j jt j jgD ] }x|D ]}| ||  q W qW | t j j tt| S )N)r   Ztd_wavZfd_wavr   r	   r   r   )Z
all_apprxsdr   r   r   r   r     s    
z)CBCHDFInjectionSet.supported_approximants)Nr#   NNN)Nr#   )r   r   r   r   r   r   ZWaveformArrayr   r   r   rw   rd   rz   r   r   r   r   r   r   r     s      
c
+r   c               @   s@   e Zd ZdZdZdZdddZddd	Zd
d Ze	dd Z
dS )RingdownHDFInjectionSetzeManages a ringdown injection: reads injection from hdf file
    and injects it into time series.
    Zringdown)r"   r#   Nc             C   s   |dk	rt d|jttfkr0tdt|j | }t|j }|j}	|dk	rXd| }	| j	}
|rn|
t
| }
xvt|
jD ]h}|
| }| j||	||d}t||jdd}||j}| }|||d |jjdd |jdd< qzW dS )a7  Add injection (as seen by a particular detector) to a time series.

        Parameters
        ----------
        strain : TimeSeries
            Time series to inject signals into, of type float32 or float64.
        detector_name : string
            Name of the detector used for projecting injections.
        distance_scale: float, optional
            Factor to scale the distance of an injection with. The default (=1)
            is no scaling.
        simulation_ids: iterable, optional
            If given, only inject signals with the given simulation IDs.
        inj_filter_rejector: InjFilterRejector instance, optional
            Not implemented. If not ``None``, a ``NotImplementedError`` will
            be raised.
        injection_sample_rate: float, optional
            The sample rate to generate the signal before injection

        Returns
        -------
        None

        Raises
        ------
        NotImplementedError
            If an ``inj_filter_rejector`` is provided.
        TypeError
            For invalid types of `strain`.
        Nz6Ringdown injections do not support inj_filter_rejectorz-Strain dtype must be float32 or float64, not g      ?)r<   rY   )r.   )NotImplementedErrorrZ   r   r   r[   rA   r,   r`   ra   rM   r   r~   r   rd   r   re   r*   )rO   rj   r9   r<   rU   rk   rl   rm   rq   ra   rr   r   Z	injectionr>   ru   r   r   r   rw     s.    !
zRingdownHDFInjectionSet.applyc             C   s4   t |d  |fd|i| j\}}t|||||dS )a  Make a h(t) strain time-series from an injection object as read from
        an hdf file.

        Parameters
        -----------
        inj : injection object
            The injection object to turn into a strain h(t).
        delta_t : float
            Sample rate to make injection at.
        detector_name : string
            Name of the detector used for projecting injections.
        distance_scale: float, optional
            Factor to scale the distance of an injection with. The default (=1)
            is no scaling.

        Returns
        --------
        signal : float
            h(t) corresponding to the injection.
        r!   ra   )r<   )r   rN   r?   )rO   r(   ra   r9   r<   r:   r;   r   r   r   rd     s    
z3RingdownHDFInjectionSet.make_strain_from_inj_objectc             C   s   | j j}|d S )zReturn the approximate end times of all injections.

        Currently, this just assumes all ringdowns are 2 seconds long.
        rW   )rM   r"   )rO   Ztcsr   r   r   rz     s    z!RingdownHDFInjectionSet.end_timesc               C   s   t tj S )N)r   r   r   r   r   r   r   r   r     s    z.RingdownHDFInjectionSet.supported_approximants)r#   NNN)r#   )r   r   r   r   r   r   rw   rd   rz   r   r   r   r   r   r   r     s     
?

r   c               @   sh   e Zd ZdZdZdZdZdZdZdd Z	e
dd	 Zd
d Zdd Ze
dd ZdddZdddZdS )!IncoherentFromFileHDFInjectionSeta
  Manages injecting an arbitrary time series loaded from a file.

    The injections must have the following attributes set:

    * ``filename``: (str) the name of the file to load containing the time
      series. The file type and format can be a frame file or anything
      understood by :py:func:`pycbc.types.timeseries.load_timeseries`. If a
      frame file (ends in ``.gwf``) is specified, a ``channel`` attribute must
      also be set.

    * ``DETECTOR_gps_time``: (float) The GPS time at which the time series
      should be added to the ``DETECTOR`` data, where ``DETECTOR`` is the name
      of the instrument to inject into (e.g., ``h1_gps_time``). **The time
      series will only be injected into a detector if a GPS time is given for
      that detector.** Set to -inf, nan, or do not provide a GPS time for a
      particular detector if you do not want to inject into that detector.

    * ``ref_point``: (str or float) What to use as the reference time of the
      injected time series. The time series will be injected into the detector
      such that the ``ref_point`` in the time series occurs at the specifed
      ``DETECTOR_gps_time``. Options are: ``'start'``, ``'end'``, ``'center'``,
      ``'absmax'``, or a float giving the number of seconds into the time
      series.

    In addition, the following attributes may optionally be provided:

    * ``channel``: (str): If the filename points to a frame file, the channel
      to load in that file. Must be provided for frame files.

    * ``DETECTOR_phase_shift``: (float) Apply a phase shift to the time series
      before adding it to detector ``DETECTOR``.

    * ``DETECTOR_amp_scale``: (float) Scale the amplitude by the given amount
      before adding it to detector ``DETECTOR``.

    * ``slice_start``: (float) Slice the time series starting at
      ``ref_point + slice_start`` before injecting into the data. Measured in
      seconds.

    * ``slice_end``: (float) Slice the time series ending at
      ``ref_point + slice_end`` before injecting into the data. Measured in
      seconds.

    * ``left_taper_width``: (float) Taper the start of the time series (after
      slicing) using half a kaiser window over the given number of seconds.
      See `:py:func:waveform.utils.td_taper` for more details.

    * ``right_taper_width``: (float) Taper the end of the time series (after
      slicing) using half a kaiser window over the given number of seconds.
      See `:py:func:waveform.utils.td_taper` for more details.

    The signal will be resampled to the same sample rate as the data it is
    being injected into.

    In order to use with ``pycbc_create_injections``, set the ``approximant``
    name to ``'incoherent_from_file'``.
    incoherent_from_file)r   	ref_point
   Nc             C   s   t dd S )NzIIncoherentFromFile times cannot be determined without loading time series)r   )rO   r   r   r   rz   C  s    z+IncoherentFromFileHDFInjectionSet.end_timesc               C   s   dgS )Nr   r   r   r   r   r   r   G  s    z8IncoherentFromFileHDFInjectionSet.supported_approximantsc          
   C   s   | j dkrt| jd| _ y| j |j S  tk
r8   Y nX |jdry
|j}W n* tk
rz } ztdW dd}~X Y nX t	
|j|}n
t|j}|| j |j< |S )zLoads an injection time series.

        After the first time a time series is loaded it will be added to an
        internal buffer for faster in case another injection uses the same
        series.
        N)
size_limitz.gwfz&Must provide a channel for frame files)_bufferr   _buffersizer   r%   endswithchannelr4   r   r   Z
read_framer   )rO   r(   r   _errtsr   r   r   loadtsK  s    


z(IncoherentFromFileHDFInjectionSet.loadtsc          
   C   s$  y
|j }W n2 tk
r< } ztd| jW dd}~X Y nX | jdkrVt| jd| _y| j|j|f }W n t	k
r   |dkrd}nz|dkrt
| |j }n`|dkrt
| |j d }nB|d	kr|  |j }n(t|ttfrt| }ntd
||| j|j|f< Y nX ||_dS )zhSets t=0 of the given time series based on what the given
        injection's ``ref_point`` is.
        z*Must provide a ref_point for {} injectionsN)r   startg        endcenterg       @Zabsmaxz"Unrecognized ref_point {} provided)r   r4   r   r   r   	_rtbufferr   r   r   r%   r   ra   Zabs_arg_maxr   r^   r&   _epoch)rO   r(   r   r   r   Zreftimer   r   r   set_ref_timeh  s0    

z.IncoherentFromFileHDFInjectionSet.set_ref_timec             C   s   y
| j }W n tk
r$   |j}Y nX y
| j}W n tk
rJ   |j}Y nX ||| }y
| j}W n tk
r~   d}Y nX |rtj	||j|j| dd}y
| j
}W n tk
r   d}Y nX |rtj	||j| |jdd}|S )a  Slices and tapers a timeseries based on the injection settings.

        This assumes that ``set_ref_time`` has been applied to the timeseries
        first. A copy of the time series will be returned even if no slicing
        or tapering is done.
        r   left)Zsideright)Zslice_startr4   r0   Z	slice_endr_   Z
time_slicerh   Zleft_taper_widthr1   Ztd_taperZright_taper_width)r(   r   ZtstarttendZtwidthr   r   r   slice_and_taper  s0    





z1IncoherentFromFileHDFInjectionSet.slice_and_taperr#   c          	   C   s  |d k	rt d|d k	r"d| }n|j}| j}x|D ]}| |}	| ||	 y|d|  }
W n tk
r   tj	 }
Y nX t
|
rtj	 }
|
|	j }|
|	j }||jk o||jk}|r4| j|||||	d}	|	j|jkrt|	|jdd}	|j|	dd q4W d S )	Nz@IncoherentFromFile injections do not support inj_filter_rejectorg      ?z{}_gps_time)r<   r   rY   )r.   F)rh   )r   ra   rM   r   r   r   lowerr   r   infisnanr0   r_   rd   r   inject)rO   rj   r9   r<   rl   rk   ra   rr   r(   r   Zinjtimer0   r_   r   r   r   r   rw     s4    








z'IncoherentFromFileHDFInjectionSet.applyc       	      C   s   |d krt |j}| || | ||}| j|d|  7  _t||dd}y|d|  }W n tk
r   d}Y nX |r|	 }|t
d| 9 }| }y|d|  }W n tk
r   d}Y nX || }||9 }|S )	Nz{}_gps_timerY   )r.   z{}_phase_shiftr   y              ?z{}_amp_scaleg      ?)r   r   r   r   r   r   r   r   r   Zto_frequencyseriesr   expZto_timeseries)	rO   r(   ra   r9   r<   r   Zphase_shiftfsZ	amp_scaler   r   r   rd     s.    


z=IncoherentFromFileHDFInjectionSet.make_strain_from_inj_object)r#   NN)r#   N)r   r   r   r   r   r   r   r   r   rz   r   r   r   r   r   rw   rd   r   r   r   r   r     s   9 " 
(r   c             C   s   t | d0}y|jd }W n tk
r6   tj}Y nX W dQ R X yt| S  tk
r   yt| }W n t	k
r~   Y nX t| S X dS )a  Gets the HDFInjectionSet class to use with the given file.

    This looks for the ``injtype`` in the given file's top level ``attrs``. If
    that attribute isn't set, will default to :py:class:`CBCHDFInjectionSet`.

    Parameters
    ----------
    sim_file : str
        Name of the file. The file must already exist.

    Returns
    -------
    HDFInjectionSet :
        The type of HDFInjectionSet to use.
    r   r   N)
r   r   r   r%   r   r   hdfinjtypesrA   decoder4   )rP   r   Zftyper   r   r   get_hdf_injtype  s    r   c             C   s@   d}x t  D ]}| | kr|}qW |dkr<td| |S )zGets the HDFInjectionSet class to use with the given approximant.

    Parameters
    ----------
    approximant : str
        Name of the approximant.

    Returns
    -------
    HDFInjectionSet :
        The type of HDFInjectionSet to use.
    Nz.Injection file type unknown for approximant {})r   r   r   r   r   )r!   Zretclsr   r   r   r   hdf_injtype_from_approximant  s    r   c               @   s2   e Zd ZdZdd Zed	ddZedd ZdS )
InjectionSeta  Manages sets of injections and injects them into time series.

    Injections are read from either LIGOLW XML files or HDF files.

    Parameters
    ----------
    sim_file : string
        Path to an hdf file or a LIGOLW XML file that contains a
        SimInspiralTable.
    \**kwds :
        The rest of the keyword arguments are passed to the waveform generation
        function when generating injections.

    Attributes
    ----------
    table
    c             K   sx   t j|}|dr0t|f|| _| jj| _nt||f|| _| jj| _| jj	| _	| jj
| _
| jj| _| jj| _d S )N)z.xmlz.xml.gzz.xmlgz)ospathbasenamer   rF   Z_injhandlerrJ   r   rM   rN   rw   rd   rz   )rO   rP   rQ   extr   r   r   rR   G  s    




zInjectionSet.__init__Nc                s   t j| }|dr(t| ||| n|dkr|dk	rNd|krNt|d  qd|jkrt	|d }dd |D  t
 fdd D std d	  qtd
nt|   j| |||f| dS )a  Writes the injection samples to the given hdf file.

        Parameters
        ----------
        filename : str
            The name of the file to write to.
        samples : io.FieldArray
            FieldArray of parameters.
        write_params : list, optional
            Only write the given parameter names. All given names must be keys
            in ``samples``. Default is to write all parameters in ``samples``.
        static_args : dict, optional
            Dictionary mapping static parameter names to values. These are
            written to the ``attrs``.
        injtype : str, optional
            Specify which `HDFInjectionSet` class to use for writing. If not
            provided, will try to determine it by looking for an approximant in
            the ``static_args``, followed by the ``samples``.
        \**metadata :
            All other keyword arguments will be written to the file's attrs.
        )z.xmlz.xml.gzz.xmlgzNr!   c             S   s   g | ]}t |qS r   )r   )rT   ar   r   r   rV   |  s    z&InjectionSet.write.<locals>.<listcomp>c             3   s   | ]}| d  kV  qdS )r   Nr   )rT   c)injclsr   r   	<genexpr>}  s    z%InjectionSet.write.<locals>.<genexpr>z'injections must all be of the same typer   zCould not find an approximant in the static args or samples to determine the injection type. Please specify an injtype instead.)r   r   r   r   rF   r   r   r}   r   uniqueallr   r   )r   r   r   r   r   r   r   Zapprxsr   )r   r   r   V  s$    




zInjectionSet.writec             C   sH   | j dkrdS i }| jdk	r&| j|d< | jdk	r:| j|d< t| j f|S )z`Return an instance of InjectionSet configured as specified
        on the command line.
        NZf_refZf_final)Zinjection_fileZinjection_f_refZinjection_f_finalr   )optZkwar   r   r   from_cli  s    




zInjectionSet.from_cli)NNN)r   r   r   r   rR   r   r   r   r   r   r   r   r   4  s    3r   c               @   s"   e Zd ZdZdd ZdddZdS )	SGBurstInjectionSetaK  Manages sets of sine-Gaussian burst injections: reads injections
    from LIGOLW XML files and injects them into time series.

    Parameters
    ----------
    sim_file : string
        Path to a LIGOLW XML file containing a SimBurstTable
        with injection definitions.

    Attributes
    ----------
    indoc
    table
    c             K   s,   t j|dtd| _tj| j| _|| _d S )NF)rG   )	rH   rI   r   rJ   r   ZSimBurstTablerL   rM   rN   )rO   rP   rQ   r   r   r   rR     s    zSGBurstInjectionSet.__init__Nr#   c          
   C   s  |j ttfkr tdt|j  | }tjtj }t|j	| }t|j
| }t|j  }	x| jD ]}
|
j}d}d}d}|d|  }||k sd||krqdtt|
jt|
jt|
jt|t|t|j\}}t|jjdd |j|jd}t|jjdd |j|jd}| jt|7  _| jt|7  _t|j	|krDqdt||
j}||j  }|	||d qdW |jjdd |jdd< dS )a  Add injections (as seen by a particular detector) to a time series.

        Parameters
        ----------
        strain : TimeSeries
            Time series to inject signals into, of type float32 or float64.
        detector_name : string
            Name of the detector used for projecting injections.
        f_lower : {None, float}, optional
            Low-frequency cutoff for injected signals. If None, use value
            provided by each injection.
        distance_scale: {1, foat}, optional
            Factor to scale the distance of an injection with. The default is
            no scaling.

        Returns
        -------
        None

        Raises
        ------
        TypeError
            For invalid types of `strain`.
        z-Strain dtype must be float32 or float64, not g      $@g        rW   N)ra   epoch)rZ   r   r   r[   rA   r,   r\   r]   r^   r0   r_   r`   rM   r/   r   ZSimBurstSineGaussianqZ	frequencyZhrssra   r   r*   ZdeltaTr   r   r1   r2   r3   re   )rO   rj   r9   rX   r<   rm   rn   ro   rp   rq   r(   r_   rt   Zeccentricityr8   r0   r:   r;   ru   r   r   r   rw     s:    
zSGBurstInjectionSet.apply)Nr#   )r   r   r   r   rR   rw   r   r   r   r   r     s   r   )r#   )>r   r   numpyr   r,   rh   r6   abcr   r   r   r   r   r   r   Z	pycbc.optr   Zpycbc.waveformr   r	   r
   r   r1   r   Zpycbc.typesr   r   r   r   Zpycbc.detectorr   Zpycbc.conversionsr   Zpycbc.filterr   Zpycbc.ioZpycbc.io.ligolwr   Zligo.lwrH   r   r   Zimport_optionalr   rZ   r`   r$   r+   r?   rE   r   rF   r   r   r   r   r   r   r   r   r   r   r   r   r   r   <module>   sZ   

* H  'r q"g