B
    dc             	   @   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m	Z	m
Z
 ddlmZmZ ddlmZ ddlmZmZ ddlmZmZ dd	lmZmZ dd
lmZmZ ddlmZ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"Zddl#m$Z$m%Z% ddl&Zddl'ZddlZddl(m)Z) dd Z*dIddZ+dJddZ,dKd d!Z-dLd"d#Z.dMd%d&Z/dNd'd(Z0g Z1e12d)d*d+d,d-d.g d/d0d1d2d3gZ3d4d5 Z4d6d7 Z5d8d9 Z6G d:d; d;e7Z8ej9d<d=dOd>d?Z:dPd@dAZ;dBdC Z<dDZ=dEZ>dFZ?G dGdH dHej@jAZBdS )QzQ
This modules contains functions reading, generating, and segmenting strain data
    N)
TimeSerieszeros)ArrayFrequencySeries)MultiDetOptionAppendActionMultiDetOptionAction)MultiDetOptionActionSpecial)DictOptionActionMultiDetDictOptionAction)required_optsrequired_opts_multi_ifo)ensure_one_optensure_one_opt_multi_ifo)copy_opts_for_single_ifocomplex_same_precision_as)InjectionSetSGBurstInjectionSet)resample_to_delta_tlowpasshighpassmake_frequency_series)
filter_zpk)spa_distance)FFTIFFT)	kaiserordc             C   s   d|   > S )zReturn the smallest integer power of 2 larger than the argument.

    Parameters
    ----------
    n : int
        A positive integer.

    Returns
    -------
    m : int
        Smallest integer power of 2 larger than n.
       )
bit_length)n r   `/work/yifan.wang/ringdown/master-ringdown-env/lib/python3.7/site-packages/pycbc/strain/strain.pynext_power_of_2*   s    r!         @       @median      >@      I@      @Fc
                s  |rt  d| dd n   t| j }
t|
t|
 } d|
  tjj	| j
d9  <  t |
 d  tjj	|ddd  j
d9  < |	r d tt }t|d	 t d	  }|t  } j|t j  }tjjtjj| j
d jd
|d} dd |||< tjj |
t |
  t| j t| j |d
d}tj|d|j }tjj|t| j |dd}t||j }tj|d|< |rt||j }tj||d< | }|r|| }n jd | }||| d 9 }| }|	r ||| d t||| }|	r@|d | }d|d|
< d|d|
 d d< t||kd }tj|t || t| j } fdd|| D }|S )a	  Automatic identification of loud transients for gating purposes.

    This function first estimates the PSD of the input time series using the
    FindChirp Welch method. Then it whitens the time series using that
    estimate. Finally, it computes the magnitude of the whitened series,
    thresholds it and applies the FindChirp clustering over time to the
    surviving samples.

    Parameters
    ----------
    strain : TimeSeries
        Input strain time series to detect glitches over.
    psd_duration : {float, 4}
        Duration of the segments for PSD estimation in seconds.
    psd_stride : {float, 2}
        Separation between PSD estimation segments in seconds.
    psd_avg_method : {string, 'median'}
        Method for averaging PSD estimation segments.
    low_freq_cutoff : {float, 30}
        Minimum frequency to include in the whitened strain.
    threshold : {float, 50}
        Minimum magnitude of whitened strain for considering a transient to
        be present.
    cluster_window : {float, 5}
        Length of time window to cluster surviving samples over, in seconds.
    corrupt_time : {float, 4}
        Amount of time to be discarded at the beginning and end of the input
        time series.
    high_frequency_cutoff : {float, None}
        Maximum frequency to include in the whitened strain. If given, the
        input series is downsampled accordingly. If omitted, the Nyquist
        frequency is used.
    output_intermediates : {bool, False}
        Save intermediate time series for debugging.
    g      ?ldas)methodr   )dtypeNzstrain_conditioned.wav   F)delta_tcopyepoch)seg_len
seg_strideZ
avg_methodZrequire_exact_data_fitg      ?Zhann)low_frequency_cutoffZtrunc_methodg       @g      zstrain_whitened.wavzstrain_whitened_mag.npyr   c                s   g | ]}| j   j qS r   )r-   
start_time).0idx)strainr   r    
<listcomp>   s   z(detect_loud_glitches.<locals>.<listcomp>)!r   r.   intsample_ratenumpyarangefloatpycbctypesr   r*   lenZsave_to_wavr!   r3   r   r   r-   psdwelchinterpolatedurationinverse_spectrum_truncationdelta_finfto_frequencyseriesto_timeseriesabssavewhereeventsZfindchirp_cluster_over_windowarray)r6   psd_duration
psd_strideZpsd_avg_methodlow_freq_cutoff	thresholdcluster_windowcorrupt_timeZhigh_freq_cutoffZoutput_intermediatesZcorrupt_lengthwZstrain_pad_lengthZ	pad_startZpad_endZ	pad_epochZ
strain_padr@   ZkminkmaxZstrain_tildeZnormmagindicesZcluster_idxtimesr   )r6   r    detect_loud_glitches9   sn    (

" 



rY   r   singlec       )   	      s  i }t  } js& js& js& jr jr2 j} jr> j}td t dr` j	r` j	}nd} jrt
jj j j j j  j j |dnb js jrt
jj| j j j  j j |dn, jrt
j j j j j  j j nx js jrttd  j j }|d j 7 }d j }	 j}
 j} j}t j|	 d d } jrtd	 t
jj j||	|
d
d}n. jdkrtd t
jj j||	|
f|} jdkrtd tt
j || d|  j j dnBtd ddl!m"} || j j  j j  j#||
d|	 d$|std}|d7 }|d7 }|d7 }|d7 }t%| js j&s j'rt%d j(r j)r j*rtd t+ j,dtd t-. j(}t-. j)}t/ j*}t01t-j2||| j3r&td  j3}|  j,rFtd t+ j,d jrltd t4d j dd |dk	rtd! |j5 j6d"d  j7 j8|d#} j'rtd$ t9 j'}|j5 j6d"d  j7d% |d&krtd' | 1t
jj:n6|d(kr.td) | 1t
jj2nt%d*;| j<dk	rtd+ t-= j<}t>|j?dkrt|g}x*|D ]"\}}}j@|| jAd,|d-qzW fd.d/|D |d0<  jBdk	r|g |d1< xtC jDD ]}tE jB jF j, j jG d2} fd3d/|D }|d1  |7  < x*|D ]"\}}}j@|| jAd,|d-q"W t>|dkrttd4d5Hd6d/ |D  nP qW  j,rtd t+ j,d jIrtd7 tJ jIdt d8r jKrL }ddlM}|N jO}x&|D ]}t
jj jKtP|jQjRd9} | | 1jS} t
jjT jO|d:}!|!1|jS}!tU jVj }"t
jW|!|jX}!|!Y }#tZt-[|"d jSd;}$|#d|"  |$|"d 9  < |#t>|#|" d  |$d|" 9  < |#L }!t\t>|!t>|d }%|d|%  |!d|% | L d|%  8  < qW |Y  jrdtd< tU jj }&tUt>j j  }'|&|'  j]rtd=  j]}(jQd>|(fg}|^jRd>|(f t_| |dk	r|_`|_aS )?a  Parses the CLI options related to strain data reading and conditioning.

    Parameters
    ----------
    opt : object
        Result of parsing the CLI with OptionParser, or any object with the
        required attributes  (gps-start-time, gps-end-time, strain-high-pass,
        pad-data, sample-rate, (frame-cache or frame-files), channel-name,
        fake-strain, fake-strain-seed, fake-strain-from-file, gating_file).
    dyn_range_fac : {float, 1}, optional
        A large constant to reduce the dynamic range of the strain.
    precision : string
        Precision of the returned strain ('single' or 'double').
    inj_filter_rejector : InjFilterRejector instance; optional, default=None
        If given send the InjFilterRejector instance to the inject module so
        that it can store a reduced representation of injections if
        necessary.

    Returns
    -------
    strain : TimeSeries
        The time series containing the conditioned strain data.
    zReading Framesframe_sieveN)r3   end_timesievezGenerating Fake Strainr,   g      ?r   zReading ASD from fileT)Zis_asd_file	zeroNoisezMaking PSD for strainzMaking zero-noise time series)r-   r/   zMaking colored noiser   )colored_noise)seedr9   r2   Zfilter_durationz4Actual sample rate of generated data does not match z(that expected. Possible causes of this:
z3The desired duration is not a multiple of delta_t. z2e.g. If using LISA with delta_t = 15 the duration z!must be a multiple of 15 seconds.z|Please provide channel names with the format ifo:channel (e.g. H1:CALIB-STRAIN) to inject simulated signals into fake strainzHighpass Filtering)Z	frequencyzApplying zpk filterzDividing strain by constantzResampling datar(   )r)   zApplying injections:)distance_scaleinjection_sample_rateinj_filter_rejectorz'Applying sine-Gaussian burst injections)rb   rZ   zConverting to float32doublezConverting to float64zUnrecognized precision {}z%Gating times contained in gating fileF)windowr)   r.   Ztaper_widthc                sL   g | ]D}|d  |d  |d   j kr|d  |d  |d   jkr|qS )r   r   r,   )r3   r\   )r4   gp)r6   r   r    r7   W  s    zfrom_cli.<locals>.<listcomp>fileauto)rQ   rR   rP   rS   c                s   g | ]}| j  jgqS r   )autogating_widthautogating_taper)r4   gt)optr   r    r7   c  s   zAutogating at %sz, c             S   s   g | ]}d | qS )z%.3fr   )r4   rl   r   r   r    r7   m  s   zLowpass Filteringwitness_frame_type)r3   r\   )group)r*   zRemove PaddingzTapering datag        )br   from_cliZframe_cacheZframe_files
frame_typeZ	hdf_storelogginginfohasattrr[   r=   frameZquery_and_read_framechannel_nameZgps_start_timeZpad_dataZgps_end_timeZ
read_frameZ
read_storeZfake_strainZfake_strain_from_fileZfake_strain_filter_durationZfake_strain_flowZfake_strain_sample_rateZfake_strain_extra_argsroundr9   r@   Zfrom_txtZfrom_stringr   r>   r   Zpycbc.noise.reproduceabler_   Zfake_strain_seedZsample_rate_close
ValueErrorZinjection_fileZsgburst_injection_fileZzpk_zZzpk_pZzpk_kr   Zstrain_high_passr:   rM   r<   r   astypeZfloat64Znormalize_strainr   applysplitZinjection_scale_factorrc   r   float32formatZgating_fileZloadtxtr?   shapeZgateZgating_methodautogating_thresholdrangeZautogating_max_iterationsrY   autogating_clusterautogating_padjoinZstrain_low_passr   rn   rG   h5pyFileZwitness_tf_filestrr3   r\   r*   Zload_frequencyseriesr8   Zwitness_filter_lengthrB   rE   rH   r   ZhanningminZ
taper_dataappend	gate_data
injectionsgating_info))rm   dyn_range_fac	precisionrd   r   ZinjectorZframe_sourcer]   rC   ZpdfZ	fake_flowZ	fake_rateZfake_extra_argsplenZ
strain_psdr_   err_msgzpklr   gate_paramsZ	gate_timeZgate_windowZ
gate_taper_glitch_timesstilder   Ztf_filekeyZwitnesstfZflenZtf_timerf   rU   startendZpd_taper_windowr   )rm   r6   r    rp      sp   










































$2



rp   c             K   s   t | |}t|fd|i|S )zK
    Get the strain for a single ifo when using the multi-detector CLI
    rd   )r   rp   )rm   iford   kwargsZsingle_det_optr   r   r    from_cli_single_ifo  s    
r   c             K   sD   i }|dkrdd |D }x$|D ]}t | ||| f|||< q W |S )zG
    Get the strain for all ifos when using the multi-detector CLI
    Nc             S   s   i | ]
}d |qS )Nr   )r4   r   r   r   r    
<dictcomp>  s    z'from_cli_multi_ifos.<locals>.<dictcomp>)r   )rm   ifosZinj_filter_rejector_dictr   r6   r   r   r   r    from_cli_multi_ifos  s    
r   Tc          	   C   s  |  dd}|r0|jddtd |jddtd |jdtd	d
 |jdtdd
 |jdddtd |jddtdd |jdtdd
 |jdtdd
 |jdtddd |jdtddd |jdtd d
 |jd!td"d
 |jd#td$d
 |jd%d&tj d'g d( |jd)dtd*i td+d, |jd-tdd.d/ |jd0d1d2 |jd3d4td5d6 |jd7d8td9d6 |jd:d;td<d6 |jd=td>d
 |jd?td@d
 |jdAtdBdCd/ |jdDtdEd
 |jdFtdGd
 |jdHtdId
 |jdJtdKd
 |jdLtdMdNdO |jdPtdMdBdQdR |jdStdTdUdVdR |jdWtdTdXdYdR |jdZtdTdXd[dR |jd\tdTd]d^dR |jd_td`dadbd`dcgdd |jdetdfd
 |jdgtddhd |jditddjd |jdktdld
 |jdmtdnd
 |jdotdpd
 |jdqtdrd
 |S )sa   Add strain-related options to the optparser object.

    Adds the options used to call the pycbc.strain.from_cli function to an
    optparser as an OptionGroup. This should be used if you
    want to use these options in your code.

    Parameters
    -----------
    parser : object
        OptionParser instance.
    gps_times : bool, optional
        Include ``--gps-start-time`` and ``--gps-end-time`` options. Default
        is True.
    zOptions for obtaining h(t)zThese options are used for generating h(t) either by reading from a file or by generating it. This is only needed if the PSD is to be estimated from the data, ie.  if the --psd-estimation option is given.z--gps-start-timez0The gps start time of the data (integer seconds))helptypez--gps-end-timez.The gps end time of the data (integer seconds)z--strain-high-passzHigh pass frequency)r   r   z--strain-low-passzLow pass frequencyz
--pad-data   zHExtra padding to remove highpass corruption (integer seconds, default 8))defaultr   r   z--taper-datazRTaper ends of data to zero using the supplied length as a window (integer seconds)r   )r   r   r   z--sample-ratez7The sample rate to use for h(t) generation (integer Hz)z--channel-namez4The channel containing the gravitational strain dataz--frame-cache+z*Cache file containing the frame locations.)r   nargsr   z--frame-fileszlist of frame filesz--hdf-storez'Store of time series data in hdf formatz--frame-typez\(optional), replaces frame-files. Use datafind to get the needed frame file(s) of this type.z--frame-sievezT(optional), Only use frame files where the URL matches the regular expression given.z--fake-strainz5Name of model PSD for generating fake gaussian noise.r^   )r   choicesz--fake-strain-extra-argszPARAM:VALUEz4(optional) Extra arguments passed to the PSD models.)r   actionmetavarr   r   r   z--fake-strain-seedz<Seed value for the generation of fake colored gaussian noise)r   r   r   z--fake-strain-from-filez6File containing ASD for generating fake noise from it.)r   z--fake-strain-flowg      ?z'Low frequency cutoff of the fake strain)r   r   r   z--fake-strain-filter-durationg      `@z4Duration in seconds of the fake data coloring filterz--fake-strain-sample-ratei @  z'Sample rate of the fake data generationz--injection-filezX(optional) Injection file containing parameters of CBC signals to be added to the strainz--sgburst-injection-filezb(optional) Injection file containing parametersof sine-Gaussian burst signals to add to the strainz--injection-scale-factorr   zADivide injections by this factor before adding to the strain dataz--injection-sample-ratezSample rate to use for injections (integer Hz). Typically similar to the strain data sample rate.If not provided, the strain sample rate will be usedz--injection-f-refzFReference frequency in Hz for creating CBC injections from an XML filez--injection-f-finalzHOverride the f_final field of a CBC XML injection file (frequency in Hz)z--gating-filez(optional) Text file of gating segments to apply. Format of each line is (all values in seconds):  gps_time zeros_half_width pad_half_widthz--autogating-thresholdSIGMAzlIf given, find and gate glitches producing a deviation larger than SIGMA in the whitened strain time series.)r   r   r   z--autogating-max-iterationsz&If given, iteratively apply autogating)r   r   r   r   z--autogating-clusterZSECONDSg      @zBLength of clustering window for detecting glitches for autogating.z--autogating-widthg      ?z Half-width of the gating window.z--autogating-taperzPTaper the strain before and after each gating window over a duration of SECONDS.z--autogating-pad   z^Ignore the given length of whitened strain at the ends of a segment, to avoid filters ringing.z--gating-methodtaperz.Choose the method for gating. Default: `taper`hardpaint)r   r   r   r   z--normalize-strainz)(optional) Divide frame data by constant.z--zpk-zzT(optional) Zero-pole-gain (zpk) filter strain. A list of zeros for transfer functionz--zpk-pzT(optional) Zero-pole-gain (zpk) filter strain. A list of poles for transfer functionz--zpk-kzE(optional) Zero-pole-gain (zpk) filter strain. Transfer function gainz--witness-frame-typezK(optional), frame type which will be use to query the witness channel data.z--witness-tf-filezNan hdf file containing the transfer functions and the associated channel namesz--witness-filter-lengthz2filter length in seconds for the transfer function)	add_argument_groupadd_argumentr8   r<   r   r=   r@   Zget_psd_model_listr	   )parser	gps_timesZdata_reading_groupr   r   r    insert_strain_option_group  s    




r   c             C   sz  |  dd}|r<|jddtdtdd |jddtdtd	d |jd
dttddd |jddttddd |jdddttddd |jddttdddd |jdtdtddd |jdtdtddd |jd tdtd!d"d |jd#tdtd$d%d |jd&tdtd'd(d |jd)tdtd*d+d |jd,tdtd-d.d |jd/tdtd0d1d2t	j
 f d |jd3dtd4i td5d6 |jd7tddtd8d9d: |jd;dtd<d=d> |jd?d@tdtdAdB |jdCdDtdtdEdB |jdFdGtdtdHdB |jdItdtd<dJd |jdKtdtd<dLd |jdMtdtdNd@dOdP |jdQtdtdNdRd |jdSttdTdUdV |jdWttdTdXdV |jdYdtd<dZd> |jd[tdtd\d]d |jd^td_d`dadb |jdctdtdddedfdP |jdgtdtdddhdidP |jdjtdtdddhdkdP |jdltdtdddmdndP |jdotdtdpdqdrdpdsgdt |jdutdtdTdvd |jdwtdtdTdxd |jdytdtdTdzd |jd{tdtdTd|d |S )}a  
    Adds the options used to call the pycbc.strain.from_cli function to an
    optparser as an OptionGroup. This should be used if you
    want to use these options in your code.

    Parameters
    -----------
    parser : object
        OptionParser instance.
    gps_times : bool, optional
        Include ``--gps-start-time`` and ``--gps-end-time`` options. Default
        is True.
    zOptions for obtaining h(t)a
  These options are used for generating h(t) either by reading from a file or by generating it. This is only needed if the PSD is to be estimated from the data, ie. if the --psd-estimation option is given. This group supports reading from multiple ifos simultaneously.z--gps-start-timer   zIFO:TIMEz0The gps start time of the data (integer seconds))r   r   r   r   r   z--gps-end-timez.The gps end time of the data (integer seconds)z--strain-high-passzIFO:FREQUENCYzHigh pass frequency)r   r   r   r   r   z--strain-low-passzLow pass frequencyz
--pad-datar   z
IFO:LENGTHzHExtra padding to remove highpass corruption (integer seconds, default 8))r   r   r   r   r   r   z--taper-datar   zRTaper ends of data to zero using the supplied length as a window (integer seconds))r   r   r   r   r   r   z--sample-ratezIFO:RATEz9The sample rate to use for h(t) generation  (integer Hz).)r   r   r   r   r   z--channel-namezIFO:CHANNELz4The channel containing the gravitational strain dataz--frame-cachezIFO:FRAME_CACHEz*Cache file containing the frame locations.z--frame-fileszIFO:FRAME_FILESzlist of frame filesz--hdf-storezIFO:HDF_STORE_FILEz'Store of time series data in hdf formatz--frame-typezIFO:FRAME_TYPEz[(optional) Replaces frame-files. Use datafind to get the needed frame file(s) of this type.z--frame-sievezIFO:FRAME_SIEVEzT(optional), Only use frame files where the URL matches the regular expression given.z--fake-strainz
IFO:CHOICEzQName of model PSD for generating fake gaussian noise. Choose from %s or zeroNoisez, z--fake-strain-extra-argszDETECTOR:PARAM:VALUEz4(optional) Extra arguments passed to the PSD models.)r   r   r   r   r   r   z--fake-strain-seedzIFO:SEEDz<Seed value for the generation of fake colored gaussian noise)r   r   r   r   r   r   z--fake-strain-from-filezIFO:FILEz6File containing ASD for generating fake noise from it.)r   r   r   r   z--fake-strain-flowg      ?z'Low frequency cutoff of the fake strain)r   r   r   r   r   z--fake-strain-filter-durationg      `@z4Duration in seconds of the fake data coloring filterz--fake-strain-sample-ratei @  z'Sample rate of the fake data generationz--injection-filezW(optional) Injection file containing parametersof CBC signals to be added to the strainz--sgburst-injection-filezb(optional) Injection file containing parametersof sine-Gaussian burst signals to add to the strainz--injection-scale-factorzIFO:VALzADivide injections by this factor before adding to the strain data)r   r   r   r   r   r   z--injection-sample-ratezSample rate to use for injections (integer Hz). Typically similar to the strain data sample rate.If not provided, the strain sample rate will be usedz--injection-f-refz	IFO:VALUEzFReference frequency in Hz for creating CBC injections from an XML file)r   r   r   r   z--injection-f-finalzHOverride the f_final field of a CBC XML injection file (frequency in Hz)z--gating-filezz(optional) Text file of gating segments to apply. Format of each line (units s) : gps_time zeros_half_width pad_half_widthz--autogating-thresholdz	IFO:SIGMAzkIf given, find and gate glitches producing a deviation larger than SIGMA in the whitened strain time seriesz--autogating-max-iterationsr   r   z&If given, iteratively apply autogating)r   r   r   r   z--autogating-clusterzIFO:SECONDSg      @zBLength of clustering window for detecting glitches for autogating.z--autogating-widthg      ?z Half-width of the gating window.z--autogating-taperzPTaper the strain before and after each gating window over a duration of SECONDS.z--autogating-padr   z^Ignore the given length of whitened strain at the ends of a segment, to avoid filters ringing.z--gating-methodr   z.Choose the method for gating. Default: `taper`r   r   )r   r   r   r   r   r   z--normalize-strainz)(optional) Divide frame data by constant.z--zpk-zzT(optional) Zero-pole-gain (zpk) filter strain. A list of zeros for transfer functionz--zpk-pzT(optional) Zero-pole-gain (zpk) filter strain. A list of poles for transfer functionz--zpk-kzE(optional) Zero-pole-gain (zpk) filter strain. Transfer function gain)r   r   r   r8   r<   r   r   r   r   r=   r@   Zget_lalsim_psd_listr
   )r   r   Zdata_reading_group_multir   r   r    $insert_strain_option_group_multi_ifos  s2   








r   z--frame-cachez--fake-strainz--fake-strain-from-filez--frame-filesz--frame-typez--hdf-storez--gps-start-timez--gps-end-timez
--pad-dataz--sample-ratez--channel-namec             C   s*   xt D ]}t| || qW t| |t dS )a  Sanity check provided strain arguments.

    Parses the strain data CLI options and verifies that they are consistent
    and reasonable.

    Parameters
    ----------
    opt : object
        Result of parsing the CLI with OptionParser, or any object with the
        required attributes (gps-start-time, gps-end-time, strain-high-pass,
        pad-data, sample-rate, frame-cache, channel-name, fake-strain,
        fake-strain-seed).
    parser : object
        OptionParser instance.
    N)ensure_one_opt_groupsr   r   required_opts_list)optsr   	opt_groupr   r   r    verify_strain_options`  s    
r   c             C   s<   x6|D ].}xt D ]}t| ||| qW t| ||t qW dS )a<  Sanity check provided strain arguments.

    Parses the strain data CLI options and verifies that they are consistent
    and reasonable.

    Parameters
    ----------
    opt : object
        Result of parsing the CLI with OptionParser, or any object with the
        required attributes (gps-start-time, gps-end-time, strain-high-pass,
        pad-data, sample-rate, frame-cache, channel-name, fake-strain,
        fake-strain-seed).
    parser : object
        OptionParser instance.
    ifos : list of strings
        List of ifos for which to verify options for
    N)r   r   r   r   )r   r   r   r   r   r   r   r    verify_strain_options_multi_ifou  s    

r   c             C   s   dd }d| j  }| j}x|D ]\}}}|| | | j }|| | | j }	|| jks|	dk r`qtd| ||  }
t|| }||
|}t|| }td| }tt|t| | }||| ||   ||| 9  < qW | S )a  Apply a set of gating windows to a time series.

    Each gating window is
    defined by a central time, a given duration (centered on the given
    time) to zero out, and a given duration of smooth tapering on each side of
    the window. The window function used for tapering is a Tukey window.

    Parameters
    ----------
    data : TimeSeries
        The time series to be gated.
    gate_params : list
        List of parameters for the gating windows. Each element should be a
        list or tuple with 3 elements: the central time of the gating window,
        the half-duration of the portion to zero out, and the duration of the
        Tukey tapering on each side. All times in seconds. The total duration
        of the data affected by one gating window is thus twice the second
        parameter plus twice the third parameter.

    Returns
    -------
    data: TimeSeries
        The gated time series.
    c             S   s^   | d|  }|dk rt dddttjt| |   }t|t||d d d fS )Nr,   r   z%No zeros left after applying padding.g      ?g      ?r+   )rx   r:   cospir;   Zconcatenater   )MZn_padZmidlenZpadarrr   r   r    inverted_tukey  s
    "z!gate_data.<locals>.inverted_tukeyg      ?g        r,   r   )r-   datar3   rC   r8   maxr   r?   )r   r   r   r9   tempZglitch_timeZglitch_widthZ	pad_widthZt_startZt_endZwin_samplesZpad_samplesrf   offsetZidx1Zidx2r   r   r    r     s     

(r   c               @   s   e Zd ZdZdddZdd Zed	d
 Zedd Zedd Z	edd Z
edd ZdddgZedd Zedd ZdS )StrainSegmentsz Class for managing manipulation of strain data for the purpose of
        matched filtering. This includes methods for segmenting and
        conditioning.
    Nr   Fc
       /         s2  d| _  | _ j| _ j| _|r&|}
n j}
d|
 | _t|
| j | _| jd d | _|}|}srt j	| nJ|	st j	| }n
t j	}|k rd}|d 7 }|d| 7 }t
|st j| nL|	st j| }n
t j}|krd}|d	 7 }|d
| 7 }t
||| }|
| } }| t j	 }| t j	 }|| }| j }| j }ttt|t| }tt|t| }g | _g | _xt|d D ]z}t|||  j  }t||
 j  }t||}| j| t| j }t|| j  }t||}| j| qW t|}t||
 j  }t||}| j| ||d | |  }t|
|  j }t|
|  j }t||}| j| t| j| _g } g }!t j	  j }"t j	  j }#|r:t dr: j }$fdd|$D }$ fdd|$D }%xt| j| jD ]\}&}'|'j}(|'j})|(|&j }*|)|&j }+|"|*kr|(|"|* 7 }(|#|+k r|)|+|# 8 })|rt drd}, jd }-x.|%D ]&}.|.|+|- k r|.|*|- krd},qW |,sqJ|(|)k rJ| |& |!t|(|) qJW | | _|!| _dS )zb Determine how to chop up the strain data into smaller segments
            for analysis.
        Ng      ?r,   r   z-Trigger start time must be within analysable zwindow. Asked to start from %d zbut can only analyse from %d.z+Trigger end time must be within analysable zwindow. Asked to end at %d zbut can only analyse to %d.r   c                s(   g | ] }t | k rt |kr|qS r   )r<   )r4   time)trigger_endtrigger_startr   r    r7   2  s    z+StrainSegments.__init__.<locals>.<listcomp>c                s$   g | ]}t |t  j  j qS r   )r<   r3   r9   )r4   r   )r6   r   r    r7   3  s    Fr   T)_fourier_segmentsr6   r-   r9   rC   rE   r8   Ztime_lenZfreq_lenr3   rx   r\   r:   ceilr<   segment_slicesanalyze_slicesr   slicer   r.   deepcopyZfull_segment_slicesrt   r   	end_timeszipr   stop)/selfr6   segment_lengthsegment_start_padsegment_end_padr   r   filter_inj_onlyinjection_windowallow_zero_paddingr0   Zseg_end_padZseg_start_padZmin_start_timer   Zmax_end_timeZthrowaway_sizeZ	seg_widthZ
analyzableZ
data_startZdata_endZdata_durZnum_segsZ
seg_offsetZnsegZ	seg_startZseg_end	seg_sliceZ	ana_startZana_endZ	ana_slice	remainingZsegment_slices_redZanalyze_slices_redZtrig_start_idxZtrig_end_idxr   Zinj_idxseganar   r   Z	cum_startZcum_endZanalyze_thisZ
inj_windowZinj_idr   )r6   r   r   r    __init__  s    



















zStrainSegments.__init__c             C   s   | j sg | _ xt| j| jD ]\}}|jdkrN|jt| jkrNt| j| }np|jdk r| jd|j }|	|j  t|}n>|jt| jkr| j|jd }|
|jt| j  t|}||_|j|j |_||_| j | qW | j S )a   Return a list of the FFT'd segments.
        Return the list of FrequencySeries. Additional properties are
        added that describe the strain segment. The property 'analyze'
        is a slice corresponding to the portion of the time domain equivalent
        of the segment to analyze for triggers. The value 'cumulative_index'
        indexes from the beginning of the original strain series.
        r   N)r   r   r   r   r   r   r?   r6   r   Zprepend_zerosZappend_zerosZanalyzeZcumulative_indexr   r   )r   r   r   Zfreq_segZstrain_chunkr   r   r    fourier_segmentsU  s$    

zStrainSegments.fourier_segmentsc             C   s*   | ||j |j|j|j|j|j|j|jd	S )zjCalculate the segmentation of the strain data for analysis from
        the command line options.
        )r   r   r   r   r   r   r   r   )r   r   r   trig_start_timetrig_end_timer   r   r   )clsrm   r6   r   r   r    rp   s  s    zStrainSegments.from_clic             C   s   | dd}|jdtddd |jdtddd |jd	td
d |jdtdd |jdtdd |jdddd |jdddd |jdd tdd d S )Nz!Options for segmenting the strainzThese options are used to determine how to segment the strain into smaller chunks, and for determining the portion of each to analyze for triggers. z--trig-start-timer   z3(optional) The gps time to start recording triggers)r   r   r   z--trig-end-timez2(optional) The gps time to stop recording triggersz--segment-lengthz-The length of each strain segment in seconds.)r   r   z--segment-start-padzKThe time in seconds to ignore of the beginning of each segment in seconds. z--segment-end-padzDThe time in seconds to ignore at the end of each segment in seconds.z--allow-zero-padding
store_truezEAllow for zero padding of data to analyze requested times, if needed.)r   r   z--filter-inj-onlyz0Analyze only segments that contain an injection.z--injection-windowa  If using --filter-inj-only then
                          only search for injections within +/- injection
                          window of the injections's end time. This is useful
                          to speed up a coherent search or a search where we
                          initially filter at lower sample rate, and then
                          filter at full rate where needed. NOTE: Reverts to
                          full analysis if two injections are in the same
                          segment.)r   r   r   )r   r   r8   r<   )r   r   segment_groupr   r   r    insert_segment_option_group  s(    

z*StrainSegments.insert_segment_option_groupc          
   C   s:   | ||j | |j| |j| |j| |j| |j|jdS )zjCalculate the segmentation of the strain data for analysis from
        the command line options.
        )r   r   r   r   r   r   r   )r   r   r   r   r   r   r   )r   rm   r6   r   r   r   r    r     s    z"StrainSegments.from_cli_single_ifoc             C   s,   i }x"|D ]}|  ||| |||< q
W |S )zjCalculate the segmentation of the strain data for analysis from
        the command line options.
        )r   )r   rm   Zstrain_dictr   Zstrain_segmentsr   r   r   r    r     s
    
z"StrainSegments.from_cli_multi_ifosc          	   C   s   | dd}|jdtddtddd |jd	tddtdd
d |jdtdtddd |jdtdtddd |jdtdtddd |jdddd |jdddd d S )Nz!Options for segmenting the strainzThese options are used to determine how to segment the strain into smaller chunks, and for determining the portion of each to analyze for triggers. z--trig-start-timer   r   zIFO:TIMEz3(optional) The gps time to start recording triggers)r   r   r   r   r   r   z--trig-end-timez2(optional) The gps time to stop recording triggersz--segment-lengthz
IFO:LENGTHz-The length of each strain segment in seconds.)r   r   r   r   r   z--segment-start-padzKThe time in seconds to ignore of the beginning of each segment in seconds. z--segment-end-padzDThe time in seconds to ignore at the end of each segment in seconds.z--allow-zero-paddingr   zEAllow for zero padding of data to analyze requested times, if needed.)r   r   z--filter-inj-onlyz0Analyze only segments that contain an injection.)r   r   r8   r   )r   r   r   r   r   r    %insert_segment_option_group_multi_ifo  s.    

z4StrainSegments.insert_segment_option_group_multi_ifoz--segment-lengthz--segment-start-padz--segment-end-padc             C   s   t ||| j d S )N)r   r   )r   rm   r   r   r   r    verify_segment_options  s    z%StrainSegments.verify_segment_optionsc             C   s"   x|D ]}t |||| j qW d S )N)r   r   )r   rm   r   r   r   r   r   r     verify_segment_options_multi_ifo  s    
z/StrainSegments.verify_segment_options_multi_ifo)Nr   r   NNFNF)__name__
__module____qualname____doc__r   r   classmethodrp   r   r   r   r   r   r   r   r   r   r   r    r     s"      
 %!r   i  )maxsizec             C   s|   | d d }d| |  }t t| |d|dd}tt|t|d|dd}|r`t||}	|}
|}nt||}	|}
|}|
||	fS )a   Create memory and engine for class-based FFT/IFFT

    Currently only supports R2C FFT / C2R IFFTs, but this could be expanded
    if use-cases arise.

    Parameters
    ----------
    npoints_time : int
        Number of time samples of the real input vector (or real output vector
        if doing an IFFT).
    dtype : np.dtype
        The dtype for the real input vector (or real output vector if doing an
        IFFT). np.float32 or np.float64 I think in all cases.
    delta_t : float (default: 1)
        delta_t of the real vector. If not given this will be set to 1, and we
        will assume it is not needed in the returned TimeSeries/FrequencySeries
    ifft : boolean (default: False)
        By default will use the FFT class, set to true to use IFFT.
    uid : int (default: 0)
        Provide a unique identifier. This is used to provide a separate set
        of memory in the cache, for instance if calling this from different
        codes.
    r,   r   g      ?)r*   F)r-   r.   )rE   r.   )r   r   r   r   r   r   )npoints_timer*   r-   ifftuidZnpoints_freqZdelta_f_tmpZvecZvectilde	fft_classinvecoutvecr   r   r    ,create_memory_and_engine_for_class_based_fft  s,    


r   c             C   s   ddl m} |r"t| d d }nt| }y
| j}W n  tk
rT   |sNd}n Y nX || }t|||||d\}	}
}| dk	r| jdd |	jdd< |  |r|r|
 j|	j9  _n|
 j|	j	9  _|r|

 }
|
S )a   Executes a cached FFT

    Parameters
    -----------
    invec_data : Array
        Array which will be used as input when fft_class is executed.
    normalize_by_rate : boolean (optional, default:False)
        If True, then normalize by delta_t (for an FFT) or delta_f (for an
        IFFT).
    ifft : boolean (optional, default:False)
        If true assume this is an IFFT and multiply by delta_f not delta_t.
        Will do nothing if normalize_by_rate is False.
    copy_output : boolean (optional, default:True)
        If True we will copy the output into a new array. This avoids the issue
        that calling this function again might overwrite output. However, if
        you know that the output array will not be used before this function
        might be called again with the same length, then setting this to False
        will provide some increase in efficiency. The uid can also be used to
        help ensure that data doesn't get unintentionally overwritten!
    uid : int (default: 0)
        Provide a unique identifier. This is used to provide a separate set
        of memory in the cache, for instance if calling this from different
        codes.
    r   )real_same_precision_asr   r,   )r-   r   r   N)pycbc.typesr   r?   r-   AttributeErrorr   _dataexecute_delta_fZ_delta_tr.   )Z
invec_dataZnormalize_by_rater   copy_outputr   r   r   r-   r*   r   r   r   r   r   r    execute_cached_fft+  s6    
r   c              O   s   t | |ddiS )a   Executes a cached IFFT

    Parameters
    -----------
    invec_data : Array
        Array which will be used as input when fft_class is executed.
    normalize_by_rate : boolean (optional, default:False)
        If True, then normalize by delta_t (for an FFT) or delta_f (for an
        IFFT).
    copy_output : boolean (optional, default:True)
        If True we will copy the output into a new array. This avoids the issue
        that calling this function again might overwrite output. However, if
        you know that the output array will not be used before this function
        might be called again with the same length, then setting this to False
        will provide some increase in efficiency. The uid can also be used to
        help ensure that data doesn't get unintentionally overwritten!
    uid : int (default: 0)
        Provide a unique identifier. This is used to provide a separate set
        of memory in the cache, for instance if calling this from different
        codes.
    r   T)r   )argsr   r   r   r    execute_cached_ifftk  s    r   ikim.i['c                   s   e Zd Zddddddddd	d
ddddddddddejdddddddf fdd	Zedd Zedd Zdd Z	dd Z
dd Zdd Zdd Zdd Zd% fd!d"	Zed#d$ Z  ZS )&StrainBufferi   i      g      .@g      i@g      @      g      @g      ?NTr   c        %   
      s  t t| j|||d||d || _|| _|| _d| _d| _d| _|| _	|dk	rt
j| j} td|t|  t
jj||||| ||d| _|dk	rt|||d}!t| jdkr| jd dkrd	|!d
< td| n$t
j| j|!d< td|t|  t
jj|||f|!| _|dk	rZ|dkr*td|dkr<tdt
jj||||||||d| _|| _|| _|	| _|| _|| _|| _|| _|| _g | _|| _|| _|| _ || _!|| _"|
| _#|| _$d| _%i | _&t'|| j }"t(t)|"t*j+dd| j || d| _,t-| j| j| j.j d t*j/ \}#| _0t'|#d | _1d}$t2d| j.j3 | j | _4| j1| j4 |$ | _5| j$| j | _6| j5| j6 | _7t'|| j | _8| j8| j7kr| j7| _8|
d d | | _9t'| j7| j8 | _:i | _;| <  d	| _=dS )a   Class to produce overwhitened strain incrementally

        Parameters
        ----------
        frame_src: str of list of strings
            Strings that indicate where to read from files from. This can be a
            list of frame files, a glob, etc.
        channel_name: str
            Name of the channel to read from the frame files
        start_time:
            Time to start reading from.
        max_buffer: {int, 512}, Optional
            Length of the buffer in seconds
        sample_rate: {int, 2048}, Optional
            Rate in Hz to sample the data.
        low_frequency_cutoff: {float, 20}, Optional
            The low frequency cutoff to use for inverse spectrum truncation
        highpass_frequency: {float, 15}, Optional
            The frequency to apply a highpass filter at before downsampling.
        highpass_reduction: {float, 200}, Optional
            The amount of reduction to apply to the low frequencies.
        highpass_bandwidth: {float, 5}, Optional
            The width of the transition region for the highpass filter.
        psd_samples: {int, 30}, Optional
            The number of sample to use for psd estimation
        psd_segment_length: {float, 4}, Optional
            The number of seconds in each psd sample.
        psd_inverse_length: {float, 3.5}, Optional
            The length in seconds for fourier transform of the inverse of the
            PSD to be truncated to.
        trim_padding: {float, 0.25}, Optional
            Amount of padding in seconds to give for truncated the overwhitened
            data stream.
        autogating_threshold: float, Optional
            Sigma deviation required to cause autogating of data.
            If None, no autogating is performed.
        autogating_cluster: float, Optional
            Seconds to cluster possible gating locations.
        autogating_pad: float, Optional
            Seconds of corrupted whitened strain to ignore when generating a gate.
        autogating_width: float, Optional
            Half-duration of the zeroed-out portion of autogates.
        autogating_taper: float, Optional
            Duration of taper on either side of the gating window in seconds.
        state_channel: {str, None}, Optional
            Channel to use for state information about the strain
        data_quality_channel: {str, None}, Optional
            Channel to use for data quality information about the strain
        idq_channel: {str, None}, Optional
            Channel to use for idq timeseries
        idq_state_channel : {str, None}, Optional
            Channel containing information about usability of idq
        idq_threshold : float, Optional
            Threshold which triggers a veto if iDQ channel falls below this threshold
        dyn_range_fac: {float, pycbc.DYN_RANGE_FAC}, Optional
            Scale factor to apply to strain
        psd_abort_difference: {float, None}, Optional
            The relative change in the inspiral range from the previous PSD
            estimate to trigger the data to be considered invalid.
        psd_recalculate_difference: {float, None}, Optional
            the relative change in the inspiral range from the previous PSD
            to trigger a re-estimatoin of the PSD.
        force_update_cache: {boolean, True}, Optional
            Re-check the filesystem for frame files on every attempt to
            read more data.
        analyze_flags: list of strs
            The flags that must be on to mark the current data as valid for
            *any* use.
        data_quality_flags: list of strs
            The flags used to determine if to keep triggers.
        dq_padding: {float, 0}, optional
            Extra seconds to consider invalid before/after times with bad DQ.
        increment_update_cache: {str, None}, Optional
            Pattern to look for frame files in a GPS dependent directory. This
            is an alternate to the forced updated of the frame cache, and
            apptempts to predict the next frame file name without probing the
            filesystem.
            )
max_bufferforce_update_cacheincrement_update_cacheNz1State channel %s interpreted as bitmask %s = good)r  
valid_maskr  r  r   r   Zveto_nonzeroTZvalid_on_zeroz(DQ channel %s interpreted as zero = goodr  z.DQ channel %s interpreted as bitmask %s = goodzGEach detector with an iDQ channel requires an iDQ state channel as wellzEIf an iDQ channel is provided, a veto threshold must also be provided)r*   g      ?)r-   r/   r,   
   )>superr   r   r2   analyze_flagsdata_quality_flagsstatedqidq
dq_paddingr=   ru   Zflag_names_to_bitmaskrr   rs   binZStatusBufferdictr?   rx   Z	iDQBufferhighpass_frequencyhighpass_reductionhighpass_bandwidthr   r   r   rj   rk   r   r9   r   psd_abort_differencepsd_recalculate_differencepsd_segment_lengthpsd_samplespsd_inverse_lengthr@   psdsr8   r   r   r:   r|   r6   r   
raw_bufferr   betahighpass_samplesrw   r-   factor
corruptionZpsd_corruptiontotal_corruptiontrim_paddingrN   reduced_padsegmentsadd_hard_counttaper_immediate_strain)%r   	frame_srcrv   r3   r  r9   r2   r  r  r  r  r  r  r   r   r   r   rj   rk   state_channeldata_quality_channelidq_channelidq_state_channelidq_thresholdr   r  r  r  r  r	  r
  r  r  Z	sb_kwargsZ
strain_lenr  Zresample_corruption)	__class__r   r    r     s    k






 zStrainBuffer.__init__c             C   s   | j | j S )z< Return the start time of the current valid segment of data )r\   	blocksize)r   r   r   r    r3   k  s    zStrainBuffer.start_timec             C   s"   t | jjt| j| j | j  S )z: Return the end time of the current valid segment of data )r<   r6   r3   r?   r  r9   )r   r   r   r    r\   p  s    zStrainBuffer.end_timec             C   s*   t t| j| j | j | _|   dS )zm Reset the countdown timer, so that we don't analyze data long enough
        to generate a new PSD.
        N)r8   r:   r   r  r9   rN   wait_durationinvalidate_psd)r   r   r   r    r#  u  s    zStrainBuffer.add_hard_countc             C   s   d| _ i | _dS )z\ Make the current PSD invalid. A new one will be generated when
        it is next required N)r@   r  )r   r   r   r    r.  |  s    zStrainBuffer.invalidate_psdc             C   s,  t | j| j }t| j}|| jd | d  }tjj| j|| ||d d}t	|dd| j
tj |_| jr| jrt| jj|j | jj | jk rtd| j| jj|j dS | jr
| jr
t| jj|j | jj | jkr
td| j| jj|j || _i | _dS || _i | _td	| j|j dS )
z Recalculate the psd
        r   r,   )r0   r1   gffffff?z'Skipping recalculation of %s PSD, %s-%sTz$%s PSD is CRAZY, aborting!!!!, %s-%sFzRecalculating %s PSD, %s)r8   r9   r  r?   r6   r  r=   r@   rA   r   r2   DYN_RANGE_FACdistr  rI   rr   rs   detectorr  r  )r   r0   esr@   r   r   r    recalculate_psd  s*    
  "zStrainBuffer.recalculate_psdc             C   s  || j krtd| }t| j}t||| j  | jd  }t| j|| dtd}| jj|| jj	  |_|| j
krtj| j|j}tjj|t| j| j | jd}|j|_tj| j|}tjj|t| j| j | jd}||_|| j
|< | j
| }||j }| jdkrt|dtd}|| jt|| j  }	| jd |j }
|	jd|
f|	jd|
fg}t|	| t|	d	td}|j| j| jj	  |_n|}||_|| j |< | j | }|S )
a   Return overwhitened data

        Parameters
        ----------
        delta_f: float
            The sample step to generate overwhitened frequency domain data for

        Returns
        -------
        htilde: FrequencySeries
            Overwhited strain data
        g      ?r,   F)r   r   )r2   r   g       @g        T)r"  r8   r?   r6   r9   r!  r   STRAINBUFFER_UNIQUE_ID_1_epochr-   r  r=   r@   rB   rE   rD   r  r2   r   psdtr   STRAINBUFFER_UNIQUE_ID_2r   r3   r\   r   STRAINBUFFER_UNIQUE_ID_3)r   rE   Zbuffer_lengthr2  r3  Zfseriesr7  r@   Z	overwhiteZ
overwhite2Ztaper_windowr   Zfseries_trimmedr   r   r   r    overwhitened_data  sR    










zStrainBuffer.overwhitened_datac             C   s*   | j s
dS | j | j| jtjjs&dS dS )zdCheck that the current set of triggers could be influenced by
        a hardware injection.
        FT)r  Zis_extent_validr3   r,  r=   ru   ZNO_HWINJ)r   r   r   r    
near_hwinj  s
    zStrainBuffer.near_hwinjc             C   sb   t || j }|| jd  }| j|  d| jt| j| | j d< | j j|7  _d| _dS )z Advance and insert zeros

        Parameters
        ----------
        blocksize: int
            The number of seconds to attempt to read from the channel
        r,   r   NT)r8   r9   r  r6   rollr?   r3   r$  )r   r,  sample_stepcsizer   r   r    null_advance_strain  s    z StrainBuffer.null_advance_strainr  c       	   	      s  t t j||d}| _g  _|dkrztd j  |  j	rR j	
|  jrd j
|  jrv j
| dS   j|8  _ j	r j	|dkr    |  jr j
|  jrԈ j
| td j dS  jr j|  jr j| i  _t| j }| jd  }t j| j  } j|d }tjj| j j jd}| j tj }tjj!|d j d	d
}| jd } j"rtd j t#||j$d j%fg}d _" j&'|  |dd  j&t j&|  j d<  j& j$|7  _$ j(dk	rt)|d j  dd j( j* j j+d}t|dkrtd jd,dd |D   fdd|D  _t# j& j _& j-dkr jdkr .   jdkS )a  Advanced buffer blocksize seconds.

        Add blocksize seconds more to the buffer, push blocksize seconds
        from the beginning.

        Parameters
        ----------
        blocksize: int
            The number of seconds to attempt to read from the channel

        Returns
        -------
        status: boolean
            Returns True if this block is analyzable.
        )timeoutNz%s frame is late, giving upFz*%s time has invalid data, resetting bufferr,   )r  g      ?r(   )r)   z!Tapering start of %s strain blockg        g       @)rN   rO   rQ   rR   rP   rS   r   zAutogating %s at %sz, c             S   s   g | ]}d | qS )z%.3fr   )r4   rl   r   r   r    r7   o  s    z(StrainBuffer.advance.<locals>.<listcomp>c                s   g | ]}| j  jfqS r   )rj   rk   )r4   rl   )r   r   r    r7   q  s   )/r  r   Zattempt_advancer,  r   rr   rs   r1  r?  r  Znull_advancer  r  r-  advancer#  r"  r8   r9   r  r?   r  r  r=   filterZhighpass_firr  r  r  r   ry   r:   r|   r   r$  r   r3   rk   r6   r<  r   rY   r   r   r   r@   r4  )	r   r,  r@  tsr=  r>  r   r6   r   )r+  )r   r    rA    s    


&



zStrainBuffer.advancec              C   s  d }}|j rL||j krL|jrL||jkrLd||j | g}|j| d}d }}|jr||jkr|jr||jkrd||j| g}|j| d}d}|jr||jkrd||j| g}d}	|jr||jkrd||j| g}	|jrt	j
|j| |j|j}
n|j| g}
d||j| g}| |
||j|d ||||	|j|j|j|j|j|j|j|j|j|j|j|j|j|j|j|j|j |j!|j"| |||j#dS )zZInitialize a StrainBuffer object (data reader) for a particular
        detector.
        Nra   ,r,   )r  r&  r'  r(  r)  r*  r9   r2   r  r  r  r  r   r  r  r   r   r   rj   rk   r  r  r  r  r	  r
  r  )$r&  r	  r   r{   r'  r
  r(  r)  rq   r=   ru   Zframe_pathsr3   r\   r%  rv   r*  r9   r2   r  r  r  r  r   r  r  r   r   r   rj   rk   r  r  r  r  Zdata_quality_padding)r   r   r   maxlenr&  r	  Z
dq_channelZdq_flagsr(  r)  r%  Zstrain_channelr   r   r    rp   z  sd    

zStrainBuffer.from_cli)r  )r   r   r   r=   r/  r   propertyr3   r\   r#  r.  r4  r:  r;  r?  rA  r   rp   __classcell__r   r   )r+  r    r     sN    D!Jor   )	r"   r#   r$   r%   r&   r'   r"   NF)r   rZ   N)N)N)T)T)r   Fr   )TFTr   )Cr   r.   rr   r:   	functoolsr   r=   r   r   r   r   r   r   r   r	   r
   r   r   r   r   r   r   Zpycbc.injectr   r   Zpycbc.filterr   r   r   r   Zpycbc.filter.zpkr   Zpycbc.waveform.spa_tmpltr   Z	pycbc.psdZ	pycbc.fftr   r   Zpycbc.eventsZpycbc.frameZscipy.signalr   r!   rY   rp   r   r   r   r   r   r   r   r   r   r   objectr   	lru_cacher   r   r   r5  r8  r9  ru   Z
DataBufferr   r   r   r   r    <module>   sz      
s 
 {


 5
 c3  0
  7 
?