o
    Nrfkc                     @  s  d dl mZ d dlZd dlZd dlmZmZ d dlmZ d dl	m
Z
mZmZmZm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 dddZdddZdddZdddZdddZ	ddd"d#Ze d$ej!fdd&d'Z"dd+d,Z#dd/d0Z$	1	2ddd:d;Z%dd=d>Z&ddBdCZ'ddFdGZ(e(Z)ddJdKZ*ddNdOZ+ddPdQZ,ddTdUZ-ddYdZZ.	ddd]d^Z/dd`daZ0dddddeZ1e	fdddkdlZ2G dmdn dnej3Z4ddrdsZ5ddtduZ6dddej7fdvdwZ8ddxdyZ9	ddddZ:G dd{ d{Z;	ddddZ<dS )    )annotationsN)OrderedDictdefaultdict)contextmanager)IOAnyContextManagerIterableIterator)
is_integer	is_scalar   )GenomicRangeSpecifierGenomicRangeTuplestartintstopstepreturnIterator[tuple[int, int]]c                   s    fddt |  D S )a  Partition an integer interval into equally-sized subintervals.
    Like builtin :py:func:`range`, but yields pairs of end points.

    Examples
    --------
    >>> for lo, hi in partition(0, 9, 2):
           print(lo, hi)
    0 2
    2 4
    4 6
    6 8
    8 9

    c                 3  s"    | ]}|t |  fV  qd S N)min.0ir   r    T/var/www/html/software/conda/envs/catlas/lib/python3.10/site-packages/cooler/util.py	<genexpr>    s     zpartition.<locals>.<genexpr>)range)r   r   r   r   r   r   	partition   s   r    sstrtuple[str, str]c                 C  sb   |  d}t|dkr|d d}}||fS t|dkr-|\}}|ds)d| }||fS td)zW
    Parse a Cooler URI string

    e.g. /path/to/mycoolers.cool::/path/to/cooler

    z::r   r   /   zInvalid Cooler URI string)splitlen
startswith
ValueError)r!   parts	file_pathZ
group_pathr   r   r   parse_cooler_uri#   s   

r,   c                 C  s   t | ddS )N, )r   replace)r!   r   r   r   atoi6   s   r0   c                 C  s   t d}|| dd\}}}t|st|S t|}|  }|dv r/|d9 }t|S |dv r;|d9 }t|S |dv rG|d	9 }t|S t	d
| d)Nz
([0-9,.]+)r-   r.   )KZKBi  )MMBi@B )GGBi ʚ;zUnknown unit '')
recompiler&   r/   r'   r   floatupperstripr)   )r!   Z_NUMERIC_RE_valueunitr   r   r   parse_humanized:   s    
r?   "tuple[str, int | None, int | None]c                   sv   dd }dd   fdd}|  d}|d  }t|s!td	t|d
k r,|ddfS |||d \}}|||fS )ac  
    Parse a UCSC-style genomic region string into a triple.

    Parameters
    ----------
    s : str
        UCSC-style string, e.g. "chr5:10,100,000-30,000,000". Ensembl and FASTA
        style sequence names are allowed. End coordinate must be greater than
        or equal to start.

    Returns
    -------
    (str, int or None, int or None)

    c                 s  s\    g d}d dd |D }td| tj}|| D ]}|j}|||fV  qd S )N))HYPHEN-)COORDz[0-9,]+(\.[0-9]*)?(?:[a-z]+)?)OTHERz.+z|\s*c                 S  s&   g | ]}d |d  d|d  dqS )z(?P<r   >r   )r   )r   pairr   r   r   
<listcomp>d   s   & z:parse_region_string.<locals>._tokenize.<locals>.<listcomp>z\s*)joinr7   r8   
IGNORECASEfinditer	lastgroupgroup)r!   Z
token_specpatternZ	tok_regexmatchtypr   r   r   	_tokenize^   s   z&parse_region_string.<locals>._tokenizec                 S  s8   | d u rt dd|| |vrt d| dd S )NzExpected {} token missingz or zUnexpected token "")r)   formatrI   )rP   tokenexpectedr   r   r   _check_tokenj   s
   z)parse_region_string.<locals>._check_tokenc                   s   t | d\}} ||dg t|}t | d\}} ||dg t | d\}}|d u r/|d fS  ||dg t|}||k rBtd||fS )N)NNrC   rA   zEnd coordinate less than start)nextr?   r)   )tokensrP   rT   r   endrV   r   r   _expectq   s   z$parse_region_string.<locals>._expect:r   zChromosome name cannot be emptyr%   Nr   )r&   r;   r'   r)   )r!   rQ   r[   r*   chromr   rY   r   rZ   r   parse_region_stringM   s   


r^   regr   
chromsizesdict | pd.Series | Noner   c              
   C  s  t | trt| \}}}n| \}}}|durt|n|}|dur$t|n|}z|dur/|| nd}W n tyF } ztd| |d}~ww |du rMdn|}|du r]|du r[td|}||k retd|dk sq|dur|||kr|td| d| d|||fS )	aU  
    Genomic regions are represented as half-open intervals (0-based starts,
    1-based ends) along the length coordinate of a contig/scaffold/chromosome.

    Parameters
    ----------
    reg : str or tuple
        UCSC-style genomic region string, or
        Triple (chrom, start, end), where ``start`` or ``end`` may be ``None``.
    chromsizes : mapping, optional
        Lookup table of scaffold lengths to check against ``chrom`` and the
        ``end`` coordinate. Required if ``end`` is not supplied.

    Returns
    -------
    A well-formed genomic region triple (str, int, int)

    NzUnknown sequence label: r   z Cannot determine end coordinate.zEnd cannot be less than startzGenomic region out of bounds: [z, rF   )
isinstancer"   r^   r   KeyErrorr)   )r_   r`   r]   r   rY   clener   r   r   parse_region   s*   


rf   z(\d+)tuplec                 C  s   t dd || D S )Nc                 S  s$   g | ]}|r|  rt|n|qS r   )isdigitr   r   xr   r   r   rH      s   $ znatsort_key.<locals>.<listcomp>)rg   r&   )r!   Z	_NS_REGEXr   r   r   natsort_key   s   rk   iterableIterable[str]	list[str]c                 C  s   t | tdS )N)key)sortedrk   )rl   r   r   r   	natsorted   s   rq   array
np.ndarrayc                 C  sJ   t | } t| st jg tdS ttdd | D  }t |d d d S )Ndtypec                 s  s    | ]}t |V  qd S r   )rk   ri   r   r   r   r      s    zargnatsort.<locals>.<genexpr>)npasarrayr'   rr   r   rg   zipZlexsort)rr   colsr   r   r   
argnatsort   s
   
r{   z^chr[0-9]+$z	^chr[XY]$z^chrM$Ffilepath_orstr | IO[str]name_patternstuple[str, ...]	all_namesbool	pd.Seriesc                 K  s   t | tr| dr|dd tj| fdddgddgdtid	|}|sLg }|D ]}||d j| }|jt|d  }|	| q*tj
|dd
}|d j|_|d S )at  
    Parse a ``<db>.chrom.sizes`` or ``<db>.chromInfo.txt`` file from the UCSC
    database, where ``db`` is a genome assembly name.

    Parameters
    ----------
    filepath_or : str or file-like
        Path or url to text file, or buffer.
    name_patterns : sequence, optional
        Sequence of regular expressions to capture desired sequence names.
        Each corresponding set of records will be sorted in natural order.
    all_names : bool, optional
        Whether to return all contigs listed in the file. Default is
        ``False``.

    Returns
    -------
    :py:class:`pandas.Series`
        Series of integer bp lengths indexed by sequence name.

    References
    ----------
    * `UCSC assembly terminology <http://genome.ucsc.edu/FAQ/FAQdownloads.html#download9>`_
    * `GRC assembly terminology <https://www.ncbi.nlm.nih.gov/grc/help/definitions>`_

    z.gzcompressiongzip	r   r   namelength)sepZusecolsnamesru   axis)rb   r"   endswith
setdefaultpdZread_csvcontainsilocr{   appendconcatvaluesindex)r}   r   r   kwargs
chromtabler*   rN   partr   r   r   read_chromsizes   s*    r   dbc                 K  s   t d|  dfi |S )zo
    Download chromosome sizes from UCSC as a :py:class:`pandas.Series`, indexed
    by chromosome label.

    z*http://hgdownload.soe.ucsc.edu/goldenPath/z/database/chromInfo.txt.gz)r   )r   r   r   r   r   fetch_chromsizes  s
   
r   r   	filepathsOrderedDict[str, Any]c                   sz   ddl }t|dkrtdt|dkr|j|d dd ni  |D ]} |j|ddj q"t fdd| D }|S )	az  
    Load lazy FASTA records from one or multiple files without reading them
    into memory.

    Parameters
    ----------
    names : sequence of str
        Names of sequence records in FASTA file or files.
    filepaths : str
        Paths to one or more FASTA files to gather records from.

    Returns
    -------
    OrderedDict of sequence name -> sequence record

    r   NzNeed at least one filer   T)Zas_rawc                 3  s    | ]	}| | fV  qd S r   r   )r   r]   far   r   r   .  s    zload_fasta.<locals>.<genexpr>)pyfaidxr'   r)   ZFastaupdaterecordsr   )r   r   r   filepathr   r   r   r   
load_fasta  s   r   binsizepd.DataFramec                   sJ    fdd}t jt| ddd}t j|d tjdd|d< |S )af  
    Divide a genome into evenly sized bins.

    Parameters
    ----------
    chromsizes : Series
        pandas Series indexed by chromosome name with chromosome lengths in bp.
    binsize : int
        size of bins in bp

    Returns
    -------
    bins : :py:class:`pandas.DataFrame`
        Dataframe with columns: ``chrom``, ``start``, ``end``.

    c                   sf   |  }t t|  }td|d   }||d< tj| g| |d d |dd  dg ddS Nr   r   rv   )r]   r   rY   columns)r   rw   ceilZaranger   	DataFrame)r]   rd   Zn_binsZbinedgesr   r`   r   r   _eachD  s    zbinnify.<locals>._eachr   Tr   Zignore_indexr]   
categoriesZordered)r   r   mapkeysCategoricallistr   )r`   r   r   Zbintabler   r   r   binnify2  s   

r   fasta_recordsenzymec              
     s   zddl m} ddlm  W n ty   tddw  }zt||jW n ty; } zt	d| |d}~ww  fdd}t
jt||dddS )	av  
    Divide a genome into restriction fragments.

    Parameters
    ----------
    fasta_records : OrderedDict
        Dictionary of chromosome names to sequence records.
    enzyme: str
        Name of restriction enzyme (e.g., 'DpnII').

    Returns
    -------
    frags : :py:class:`pandas.DataFrame`
        Dataframe with columns: ``chrom``, ``start``, ``end``.

    r   Nz4Biopython is required to find restriction fragments.zUnknown enzyme name: c                   s     t|  d d  }tjdt|d t|f tj}t|d }tj	| g| |d d |dd  dg dd}|S r   )
Seqr"   rw   r_rr   r'   astypeZint64r   r   )r]   seqcutsZn_fragsZfragsZbioseqZ
cut_finderr   r   r   r   z  s   * zdigest.<locals>._eachTr   )ZBio.RestrictionZRestrictionZBio.Seqr   ImportErrorr   getattrsearchAttributeErrorr)   r   r   r   )r   r   Zbiorstchromsre   r   r   r   r   digestZ  s&   r   bins
int | Nonec                 C  sp   t  }| jdddD ]\}}||d |d  jdd   t|dkr) dS q
t|dkr6tt|S dS )	z
    Infer bin size from a bin DataFrame. Assumes that the last bin of each
    contig is allowed to differ in size from the rest.

    Returns
    -------
    int or None if bins are non-uniform

    r]   T)observedrY   r   Nrv   r   )setgroupbyr   r   uniquer'   rW   iter)r   sizesZ_chromrM   r   r   r   get_binsize  s   
$r   c                 C  sV   | j dgddddg jddjddd	d
}t|d t|d }}tj||dS )z
    Infer chromsizes Series from a bin DataFrame. Assumes that the last bin of
    each contig is allowed to differ in size from the rest.

    Returns
    -------
    int or None if bins are non-uniform

    r]   last)ZkeeprY   T)Zdropr   r   )r]   rY   r   r   data)Zdrop_duplicatesZreset_indexrenamer   r   Series)r   r   r   lengthsr   r   r   get_chromsizes  s   
r   pd.Series | dictregionc           	      C  st   t ||\}}}| |}|dks||| k r8|d jj|dd}||d j|d j|dd }|j|| }|S )zN
    Range query on a BED-like dataframe with non-overlapping intervals.

    r   rY   rightZsider   Nleft)rf   	get_groupr   searchsortedr   )	groupedr`   r   r]   r   rY   resultlohir   r   r   bedslice  s   	
 r   rj   r   np.ndarray | h5py.Datasetc                 C  s   t | tjr| S t| S r   )rb   h5pyZDatasetrw   rx   )rj   r   r   r   asarray_or_dataset  s   r   	chunksize)tuple[np.ndarray, np.ndarray, np.ndarray]c                 C  s  t j}t| } t| }|dkr$t jg tdt jg tdt jg | jdfS |du r*|}g g }}t j}td||D ]9}| |||  }||dd |dd kd }	|d |kr_t j	d|	f }	|
||	  |
||	  |d }q8t |}t t j	||f }
t |}||
|fS )aS  
    Run length encoding.
    Based on http://stackoverflow.com/a/32681075, which is based on the rle
    function from R.

    Parameters
    ----------
    x : 1D array_like
        Input array to encode
    dropna: bool, optional
        Drop all runs of NaNs.

    Returns
    -------
    start positions, run lengths, run values

    r   rt   Nr   rv   )rw   Zflatnonzeror   r'   rr   r   ru   nanr   r   r   Zconcatenatediff)rr   r   wherenZstartsr   Zlast_valr   rj   locsr   r   r   r   rlencode  s0   
 



r   cmdc                   s$   t  fddtjd tjD S )Nc                 3  s(    | ]}t t j| t jV  qd S r   )osaccesspathrI   X_OK)r   r   r   r   r   r     s
    
zcmd_exists.<locals>.<genexpr>PATH)anyr   environr&   pathsepr   r   r   r   
cmd_exists  s   r   r   r   c              	   C  s   t t | t | | |S r   )rw   Zmedianabs)r   r   r   r   r   mad   s   r   rfpstr | h5py.GroupmodeContextManager[h5py.Group]c                 o  s    t | trd}tj| |g|R i |}n-d}|dkr#| jjdkr#n|dv r1| jjdkr1td|dkr9td|d	v rAtd
| }z|V  W |rP|  dS dS |rY|  w w )a  
    Context manager like ``h5py.File`` but accepts already open HDF5 file
    handles which do not get closed on teardown.

    Parameters
    ----------
    fp : str or ``h5py.File`` object
        If an open file object is provided, it passes through unchanged,
        provided that the requested mode is compatible.
        If a filepath is passed, the context manager will close the file on
        tear down.

    mode : str
        * r        Readonly, file must exist
        * r+       Read/write, file must exist
        * a        Read/write if exists, create otherwise
        * w        Truncate if exists, create otherwise
        * w- or x  Fail if exists, create otherwise

    TFr   r+)r   az%File object provided is not writeablewzCannot truncate open file)zw-rj   zFile existsN)rb   r"   r   Filefiler   r)   close)r   r   argsr   Zown_fhfhr   r   r   	open_hdf5  s*   

r  c                      s<   e Zd Zd fddZdddZdd	d
ZdddZ  ZS )closing_hdf5grp
h5py.Groupc                   s   t  |j d S r   )super__init__id)selfr  	__class__r   r   r
  6  s   zclosing_hdf5.__init__r   c                 C  s   | S r   r   r  r   r   r   	__enter__9  s   zclosing_hdf5.__enter__Nonec                 G  s
   | j  S r   r  r  )r  exc_infor   r   r   __exit__<  s   
zclosing_hdf5.__exit__c                 C  s   | j   d S r   r  r  r   r   r   r  ?  s   zclosing_hdf5.close)r  r  )r   r  )r   r  )__name__
__module____qualname__r
  r  r  r  __classcell__r   r   r  r   r  5  s
    

r  attrsh5py.AttributeManagerdictc              	   C  sd   t | }|  D ]'\}}z| ||< W q ty#   | ||< Y q ty/   |||< Y qw |S r   )r  itemsitemr)   tolistr   )r  outkvr   r   r   attrs_to_jsonableC  s   r"  c              	     s  t dt dt dt dt dt dt dddd fdd	fd
d}d fdd	t| dr=| jS t	| t
jt
jfrM| jdd S t	| t
jrY| dd S du r_ndd t	| tr{t
jfdd|  D dS t	| trt| dkr| d | d dS t	| ttfrtdd | D std|  t
jfdd| D dd | D dS t| ds| durz
t | }|W S    Y t| r|| S td|  )a  
    Extracted and modified from dask/dataframe/utils.py :
        make_meta (BSD licensed)

    Create an empty pandas object containing the desired metadata.

    Parameters
    ----------
    x : dict, tuple, list, pd.Series, pd.DataFrame, pd.Index, dtype, scalar
        To create a DataFrame, provide a `dict` mapping of `{name: dtype}`, or
        an iterable of `(name, dtype)` tuples. To create a `Series`, provide a
        tuple of `(name, dtype)`. If a pandas object, names, dtypes, and index
        should match the desired output. If a dtype or scalar, a scalar of the
        same dtype is returned.
    index :  pd.Index, optional
        Any pandas index to use in the metadata. If none provided, a
        `RangeIndex` will be used.

    Examples
    --------
    >>> make_meta([('a', 'i8'), ('b', 'O')])
    Empty DataFrame
    Columns: [a, b]
    Index: []
    >>> make_meta(('a', 'f8'))
    Series([], Name: a, dtype: float64)
    >>> make_meta('i8')
    1

    T    z
1970-01-01r   Zfoo)bVr2   mSr   UOZ__UNKNOWN_CATEGORIES__c                   sh   | j dv r
| dS | j dkr| tddS | j  v r- | j  }| j dv r+|| S |S td|  )N)r   fur   cr   )r&  r2   zCan't handle dtype: )kindtypecomplexr   	TypeError)ru   o)_simple_fake_mappingr   r   _scalar_from_dtype|  s   




z&infer_meta.<locals>._scalar_from_dtypec                   s`   t | tjtjtjfr| S t| r%t| dr| jntt	| } |S t
dt	| j d)Nru   zCan't handle meta of type 'r6   )rb   r   	TimestampZ	TimedeltaZPeriodrw   Zisscalarhasattrru   r.  r0  r  )rj   ru   )r3  r   r   _nonempty_scalar  s   
z$infer_meta.<locals>._nonempty_scalarNc                   sF   t |tr|dkrtjt g| |djd d S tjg || |dS )Ncategory)r   r   r   )ru   r   r   )rb   r"   r   r   r   r   )r   ru   r   )UNKNOWN_CATEGORIESr   r   _empty_series  s   z!infer_meta.<locals>._empty_series_metar   c                       i | ]\}}| ||d qS r   r   r   r,  dr9  r   r   r   
<dictcomp>       zinfer_meta.<locals>.<dictcomp>r=  r%   c                 s  s&    | ]}t |tot|d kV  qdS )r%   N)rb   rg   r'   r   r   r   r   r     s   $ zinfer_meta.<locals>.<genexpr>z2Expected iterable of tuples of (name, dtype), got c                   r;  r<  r   r>  r@  r   r   rA    rB  c                 S  s   g | ]\}}|qS r   r   r>  r   r   r   rH     s    zinfer_meta.<locals>.<listcomp>r   r   ru   z'Don't know how to create metadata from r   )rw   Zbool_voidZ
datetime64Ztimedelta64Zstr_Zunicode_r5  r:  rb   r   r   r   r   Indexr  r  rg   r'   r   allr)   ru   r   r0  )rj   r   r6  ru   r   )r8  r9  r3  r2  r   r   
infer_metaO  sZ   !	



rG  c                   s  t | } ttst fddn# }t fdd| D ]\}}t|r/| | n|}||< q#|du s>|du rDtg }	n7fdd|D }
t	|
dkr_tj|
d	 |d	 d
}	ntj
j|
|d}	|  t|D ]\}}| ||  qofdd| D }tj|| |	dS )ze
    Extracted and modified from pandas/io/parsers.py :
        _get_empty_meta (BSD licensed).

    c                     s   p S r   r   r   default_dtyperu   r   r   <lambda>  s    zget_meta.<locals>.<lambda>c                     s    S r   r   r   )rI  r   r   rJ    s    NFc                   s   g | ]}t jg  | d qS rt   r   r   )r   r   rt   r   r   rH     s    zget_meta.<locals>.<listcomp>r   r   )r   )r   c                   s    i | ]}|t jg  | d qS rK  rL  )r   Zcol_namert   r   r   rA    rB  zget_meta.<locals>.<dictcomp>rC  )r   rb   r  r   copyr  r   r   rE  r'   Z
MultiIndexZfrom_arrayssort	enumeratepopr   )r   ru   Zindex_columnsZindex_namesrI  Z_dtyper   r!  colr   r   r   r   Zcol_dictr   rH  r   get_meta  s&   

rR  c                 C  s\   t | d jtj}|  } |stj| jt|jdd| d< | S | d j	j
|jk s,J | S )Nr]   Tr   )rb   ru   r   ZCategoricalDtyperM  r   r]   r   r   catr   rF  )r   r`   Zis_catr   r   r   
check_bins  s   
rT  gsGenomeSegmentationn_chunk_maxfile_contigsloadingslist[int | float] | Nonelist[GenomicRangeTuple]c              	     s   | j }| }|d u r|}| }||j|  }|j| | }g }|D ]G\ }	 |vr,q#| j  }
tt||j   }|	jj	d d | }|d |
krStj
||
f }| fddt|d d |dd  D  q#|S )Nrv   c                 3  s    | ]
\}} ||fV  qd S r   r   )r   r   rY   r]   r   r   r     s    
z%balanced_partition.<locals>.<genexpr>r   )_bins_groupedsizeZidxmaxlocr`   r   rw   r   r   r   r   extendry   )rU  rW  rX  rY  r   Zchrom_nbinsZchrmaxconstZgrangesrM   rd   r   anchorsr   r\  r   balanced_partition  s(   

rc  c                   @  s    e Zd ZdddZdd
dZdS )rV  r`   r   r   r   c                 C  s   t ||}|jdddd| _| j j}|| _t|| _t|	 | _
|| _tj|	 tt|d| _tjdt|f | _tjdt|jf | _| j|d jj |d j | _d S )Nr]   TF)r   rN  r   r   r   )rT  r   r]  r^  r   r`   r   r   r   r   Zcontigsr   r   r   r   r'   Zidmaprw   r   ZcumsumZchrom_binoffsetZchrom_absposrS  codesZstart_abspos)r  r`   r   Znbins_per_chromr   r   r   r
    s   

zGenomeSegmentation.__init__r   r   r   c                 C  sz   t || j\}}}| j|}|dks|| j| k r;|d jj|dd}||d j|d  j|dd }|j|| }|S )Nr   rY   r   r   r   r   )rf   r`   r]  r   r   r   r   )r  r   r]   r   rY   r   r   r   r   r   r   fetch(  s    zGenomeSegmentation.fetchN)r`   r   r   r   )r   r   r   r   )r  r  r  r
  re  r   r   r   r   rV    s    
逖 chunksIterable[pd.DataFrame]r^  Iterator[pd.DataFrame]c                 c  sj    g }d}| D ]}|t |7 }|| ||kr$tj|ddV  g }d}qt |r3tj|ddV  dS dS )a  
    Take an incoming iterator of small data frame chunks and buffer them into
    an outgoing iterator of larger chunks.

    Parameters
    ----------
    chunks : iterator of :py:class:`pandas.DataFrame`
        Each chunk should have the same column names.
    size : int
        Minimum length of output chunks.

    Yields
    ------
    Larger outgoing :py:class:`pandas.DataFrame` chunks made from concatenating
    the incoming ones.

    r   r   N)r'   r   r   r   )rg  r^  bufr   chunkr   r   r   buffered2  s   
rl  )r   r   r   r   r   r   r   r   )r!   r"   r   r#   )r!   r"   r   r   )r!   r"   r   r@   r   )r_   r   r`   ra   r   r   )r!   r"   r   rg   )rl   rm   r   rn   )rr   rm   r   rs   )r|   F)r}   r~   r   r   r   r   r   r   )r   r"   r   r   )r   rn   r   r"   r   r   )r`   r   r   r   r   r   )r   r   r   r"   r   r   )r   r   r   r   )r   r   r   r   )r`   r   r   r   r   r   )rj   r   r   r   )rr   rs   r   r   r   r   )r   r"   r   r   )r   rs   r   r   r   rs   )r   )r   r   r   r"   r   r   )r  r  r   r  )r   r   r`   r   r   r   )
rU  rV  rW  r   rX  rn   rY  rZ  r   r[  )rf  )rg  rh  r^  r   r   ri  )=
__future__r   r   r7   collectionsr   r   
contextlibr   typingr   r   r   r	   r
   r   numpyrw   Zpandasr   Zpandas.api.typesr   r   Z_typingr   r   r    r,   r0   r?   r^   rf   r8   r(  rk   rq   r{   r   r   r   r   Zmake_bintabler   r   r   r   r   r   r   r   r  Groupr  r"  rG  Zobject_rR  rT  rc  rV  rl  r   r   r   r   <module>   sf    




C1



5

"%

.



30


r

+