B
    }d                  @   s   d Z dZddlZddlZddlmZ ddlmZ ddlm	Z	m
Z
 ddlmZmZmZ ed	Zed
Zd&ddZdd Zdd Zdd Zd'ddZe d(ddZd)ddZe d*ddZdd Zdefdd Zd+d"d#Zd,d$d%ZdS )-zGWDataFind UI for FFL cache files.

This module is used to replace the proper GWDataFind interface
on-the-fly when FFL data access is inferred.
As such this module is required to emulate those functions
from `gwdatafind` used in :mod:`gwpy.io.datafind`.
z(Duncan Macleod <duncan.macleod@ligo.org>    N)warn)	lru_cache)segmentsegmentlist   )_iter_cachecache_segmentsread_cache_entryz\A(\w+)-z^(?!lastfile|spectro|\.).*   utf-8c          	   C   s   t | d|}|| tj xV|ddkrry|| tj W q tk
rn   | |k rh|d P  Y qX qW | 	 
|S Q R X dS )z"Read the last line of a file.
    rbr      
r   N)openseekosSEEK_ENDreadSEEK_CUROSErrortellreadlinerstripdecode)pathbufsizeencodingfobj r   `/work/yifan.wang/ringdown/master-ringdown-env/lib/python3.7/site-packages/gwpy/io/ffldatafind.py_read_last_line3   s    
r   c               C   s>   dt jkrt jd S dt jkr2t jt jd dS tddS )zReturn the base directory in which to find FFL files

    Raises
    ------
    KeyError
        If neither the ``FFLPATH`` or ``VIRGODATA`` environment variables
        are set.
    ZFFLPATHZ	VIRGODATAfflzkfailed to parse FFLPATH from environment, please set FFLPATH to point to the directory containing FFL filesN)r   environr   joinKeyErrorr   r   r   r   _get_ffl_basedirL   s    	


r$   c             C   s   t | dS )zAReturn `True` if this file looks (naively) like an FFL file.
    z.ffl)strendswith)r   r   r   r   _is_ffl_file_   s    r'   c             C   sJ   t jt j| d }t|  d }tt j| d }||fS )z5Return the ``(site, tag)`` for a given FFL file.
    r   )	r   r   splitextbasenamer   split_SITE_REGEXmatchgroups)r   taglastsiter   r   r   _get_site_tage   s    r1   c             c   sH   xBt | pt D ].\}}}x"tt|D ]}t j||V  q(W qW dS )z5Find all FFL files under a given base directory.
    N)r   walkr$   filterr'   r   r"   )basedirroot_filesnamer   r   r   _find_ffl_filesr   s    r9   c          
   C   sH   i }x>t | dD ]0}y||t|< W q ttfk
r>   wY qX qW |S )z!Find all readable FFL files.
    )r4   )r9   r1   r   AttributeError)r4   fflsr   r   r   r   
_find_fflsz   s    r<   c          	   C   sB   yt |d| |f S  tk
r<   td|  d| dY nX dS )z>Return the path of the FFL file for a given site and tag.
    )r4   zno FFL file found for ('z', 'z')N)r<   r#   
ValueError)r0   r.   r4   r   r   r   	_ffl_path   s
    r>   c          	      s@   t  |d}t|d} fddt|tdD S Q R X dS )z7Read an FFL file as a list of `CacheEntry` objects
    )r4   rc                s"   g | ]}t | |j|jqS r   )typer   r   ).0entry)r0   r.   r   r   
<listcomp>   s   z_read_ffl.<locals>.<listcomp>)gpstypeN)r>   r   r   float)r0   r.   r4   r    r   r   )r0   r.   r   	_read_ffl   s    rF   c             C   s0   | dkrdS | dkr$t |dd dS t|dS )a  Handle error, warn, or ignore for the given state.

    Parameters
    ----------
    action : `str`
        The action to perform, one of
        ``'warn'`` (emit a `UserWarning`, default),
        ``'ignore'`` (do nothing),
        or anything else (raise a `RuntimeError`).

    message : `str`
        The message to emit with warnings or errors.

    Raises
    ------
    RuntimeError
        If action is not ``'warn'`` or ``'ignore'``.
    ignoreNr   r
   )
stacklevel)r   RuntimeError)actionmessager   r   r   _handle_error   s    rL   c                s>   t  } fdd|D }|dk	r:t|}tt|j|S |S )a  Return the list of known data types.

    Parameters
    ----------
    site : `str`, optional
        Observatory ID (e.g. ``'A'`)) to retrict types, if `None` (default)
        is given, all types are returned.

    match : `str`, optional
        Regular expression to use to restrict types.

    Returns
    -------
    types : `list` of `str`
        The list of data types matching the criteria.
    c                s    g | ]\}} d |fkr|qS )Nr   )rA   Zsite_r.   )r0   r   r   rC      s    zfind_types.<locals>.<listcomp>N)r<   recompilelistr3   search)r0   r,   r;   typesr   )r0   r   
find_types   s    
rR   r   c       	         sx    rt   t|| fddtD }dd |D }tgt| }|rtt|ddtt	|  |S )a  Return the list of all files of the given type in the [start, end)
    GPS interval.

    Parameters
    ----------
    site : `str`
        Observatory ID to search for.

    tag : `str`
        Data type tag to search for.

    gpsstart : `int`
        GPS start time of query.

    gpsend : `int`
        GPS end time of query.

    match : `str`, optional
        Regular expression to use to retrict returned data URLs.

    on_gaps : `str`, optional
        What to do if the full GPS interval is not covered, one of
        ``'warn'`` (emit a `UserWarning`, default),
        ``'ignore'`` (do nothing),
        anything else (raise a `RuntimeError`).

    Returns
    -------
    urls : `list` of `str`
        A list of URLs representing discovered data.
    c                sB   g | ]:}|j kr|jkr|jr r: |jrn |qS )T)Zobservatorydescriptionr   Z
intersectsrP   r   )rA   e)r,   r0   spanr.   r   r   rC     s
    

zfind_urls.<locals>.<listcomp>c             S   s   g | ]
}|j qS r   )r   )rA   rT   r   r   r   rC     s    zMissing segments: 

)
rM   rN   r   rF   r   r   rL   r"   mapr%   )	r0   r.   ZgpsstartZgpsendr,   Zon_gapscacheurlsmissingr   )r,   r0   rU   r.   r   	find_urls   s    '

r[   c             C   sL   yt | |}W n tk
r&   g }Y nX tt|tdg}|sHt|d |S )aW  Return the most recent file of a given type.

    Parameters
    ----------
    site : `str`
        Observatory ID to search for.

    tag : `str`
        Data type tag to search for.

    on_missing : `str`, optional
        What to do if a URL is not found for the given site and tag, one of
        ``'warn'`` (emit a `UserWarning`, default),
        ``'ignore'`` (do nothing),
        anything else (raise a `RuntimeError`).

    Returns
    -------
    urls : `list` of `str`
        A list (typically of one item) of URLs representing the latest data
        for a specific site and tag.
    )rD   zNo files found)r>   r=   r	   r   rE   rL   )r0   r.   Z
on_missingZfflfilerY   r   r   r   find_latest  s    

r\   )r
   r   )N)N)N)N)Nr   )r   )__doc__
__author__r   rM   warningsr   	functoolsr   Zligo.segmentsr   r   rX   r   r   r	   rN   r+   Z_DEFAULT_TYPE_MATCHr   r$   r'   r1   r9   r<   r>   rF   rL   rR   r[   r\   r   r   r   r   <module>   s0   




! 
;