
    DUf@                         d dl Zd dlZddlmZ ddlmZmZ g dZ		 	 	 dd	Z
ddZd ZddZddZddZd Z	 	 	 	 	 	 	 ddZdS )    N   )ops)_get_default_colnames_verify_columns)make_chromarmsbinnifydigestfrac_mappedfrac_gcseq_gcfrac_gene_coveragepair_by_distancechromlengthr   mid_p_qc           	      2   ddg}t          |          dk    r|\  }}nt          |          dk    r|\  }}}t          | t          j        t          f          rft	          |           } t          j        |t          |                                           dt          |                                           i          }	n>t          | t          j                  r| 	                                }	nt          d          t          |          dk    r3t          |	||g           ||gz  }|	|         j        |	d<   d|	d	<   d
\  }}nkt          |          dk    rI|\  }}}t          |	|||gd           t          |	|         j        dk              rt          d          nt          d          |\  }
}t          |t          j        t          f          rbt	          |          }t          j                            |d|g          }|                    d           |                    d|
id           n>t          |t          j                  r|	                                }nt          d          t          ||
|g           ||         |d	<   ||         |d<   t!          j        |	||||f|
d	dfd          }|d                                         dk    rt          d          ||         fd|d         j        D             z   |d<   ||||dg         S )a9  
    Split chromosomes into chromosome arms.

    Parameters
    ----------
    chromsizes : pandas.Dataframe or dict-like
        If dict or pandas.Series, a map from chromosomes to lengths in bp.
        If pandas.Dataframe, a dataframe with columns defined by cols_chroms.
        If cols_chroms is a triplet (e.g. 'chrom','start','end'), then
        values in chromsizes[cols_chroms[1]].values must all be zero.

    midpoints : pandas.Dataframe or dict-like
        Mapping of chromosomes to midpoint (aka centromere) locations.
        If dict or pandas.Series, a map from chromosomes to midpoints in bp.
        If pandas.Dataframe, a dataframe with columns defined by cols_mids.

    cols_chroms : (str, str) or (str, str, str)
        Two columns

    suffixes : tuple, optional
        Suffixes to name chromosome arms. Defaults to p and q.

    Returns
    -------
    df_chromarms
        4-column BED-like DataFrame (chrom, start, end, name).
        Arm names are chromosome names + suffix.
        Any chromosome not included in ``mids`` will be not be split.

    index
sub_index_      r   z!unknown input type for chromsizesendr   start)r   r   T)unique_colsz(all values in starts column must be zerozinvalid number of cols_chroms)orientcolumnsinplace)r    r"   z unknown input type for midpoints)cols1cols2return_indexr   z@chromosome split into more than two arms, double-check midpointsc                      g | ]
}|         S  r'   ).0isuffixess     L/var/www/html/software/conda/lib/python3.11/site-packages/bioframe/extras.py
<listcomp>z"make_chromarms.<locals>.<listcomp>r   s*     0 0 00 0 0    name)len
isinstancepdSeriesdict	DataFramelistkeysvaluescopy
ValueErrorr   any	from_dictreset_indexrenamer   subtractmax)
chromsizes	midpointscols_chroms	cols_midsr*   columns_to_dropck1sk1ek1	df_chromsck2sk2df_midsdf_chromarmss       `         r+   r   r      sf   J -O
;1SS	[		Q		#S#*ry$/00 >*%%
LT*//++,,$z002233
 
		 
J	-	- >OO%%		<===
;1	C:...C5 $S>0	%	'!SS	[		Q		#S#	Cc?EEEEy~$)** 	IGHHH	I 8999HC)bi.// =OO	,((7SE(RRD)))~t<<<<	Ir|	,	, =.."";<<<Gc3Z(((s|GGS\GEN<CoGU#  L L!%%''!++N
 
 	
 (, 0 0 0 0),7>0 0 0 L c3/00r-   Fc                 $    t          t                    st          d           fd}t          j        t          |                                           dd          }|r*|                    d                                          |d<   |S )aG  
    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
    -------
    bintable : pandas.DataFrame with columns: 'chrom', 'start', 'end'.

    zbinsize must be intc                     |          }t          t          j        |z                      }t          j        d|dz             z  }||d<   t	          j        | g|z  |d d         |dd          dg d          S Nr   r   )r   r   r   r    )intnpceilaranger1   r4   )r   clenn_binsbinedgesbinsizer@   s       r+   _eachzbinnify.<locals>._each   s    % RWTG^,,--9Q!--7|g&#2#xPQPRPR|TT---
 
 
 	
r-   r   Taxisignore_indexr   rel_id)	r0   rR   r9   r1   concatmapr6   groupbycumcount)r@   rY   rel_idsrZ   bintables   ``   r+   r   r   y   s    $ gs## 0.///
 
 
 
 
 
 yUJOO$5$566QTRRRH B%--g66??AA Or-   c                     	 ddl m} ddlm n# t          $ r t	          d          w xY wt           t                    st          d                                           }	 t          ||          j
        n # t          $ r t          d|           w xY w fd}t          j        t          ||          dd          S )	aq  
    Divide a genome into restriction fragments.

    Parameters
    ----------
    fasta_records : OrderedDict
        Dictionary of chromosome names to sequence records.
        Created by: bioframe.load_fasta('/path/to/fasta.fa')

    enzyme: str
        Name of restriction enzyme.

    Returns
    -------
    Dataframe with columns: 'chrom', 'start', 'end'.

    r   Nz#Biopython is required to use digestWfasta records must be provided as an OrderedDict, can be created by bioframe.load_fastazUnknown enzyme name: c                                         t          |          d d                              }t          j        dt          j         |                    dz   t          |          f                             t          j                  }t          |          dz
  }t          j	        | g|z  |d d         |dd          dg d          }|S rO   )
SeqstrrS   r_arrayr/   astypeint64r1   r4   )r   seqcutsn_fragsfragsbioseq
cut_finderfasta_recordss        r+   rZ   zdigest.<locals>._each   s    jj]51!!!45566uQC11A5s3xx?@GGQQd))a-g'$ss)DHMM---
 
 
 r-   Tr[   )Bio.RestrictionRestrictionBio.Seqrh   ImportErrorr0   r3   r9   r6   getattrsearchAttributeErrorr1   r_   r`   )rt   enzymebiorstchromsrZ   rr   rs   s   `    @@r+   r	   r	      s/   $A((((((        A A A?@@@A mT** 
%
 
 	
 !!F;VV,,3

 ; ; ;999:::;	 	 	 	 	 	 	 9S''adCCCCs    ,(A> >BTc                    t          | d         j                                      t                                                              st	          d          t          t                    st	          d          fd}|rBt          j        | | 	                    |d          
                    dd	          gd
          S | 	                    |d          
                    dd	          S )a/  
    Calculate the fraction of mapped base-pairs for each interval in a dataframe.

    Parameters
    ----------
    df : pandas.DataFrame
        A sets of genomic intervals stored as a DataFrame.

    fasta_records : OrderedDict
        Dictionary of chromosome names to sequence records.
        Created by: bioframe.load_fasta('/path/to/fasta.fa')

    return_input: bool
        if False, only return Series named frac_mapped.

    Returns
    -------
    df_mapped : pd.DataFrame
        Original dataframe with new column 'frac_mapped' appended.

    r   Hchrom from intervals not in fasta_records: double-check genome agreementrf   c                     t          | j                 | j        | j                           }t	          |          }|                    d          }||                    d          z  }|dk    r||z
  |z  ndS )NNnr   )ri   r   r   r   r/   count)binsnbasesr   rt   s       r+   rZ   zfrac_mapped.<locals>._each   so    ci(SW)<=>>QGGCLL	QWWS\\(.


f$$9r-   r   r\   r
   Tr!   r    )setr7   issubsetr6   r9   r0   r3   r1   r_   applyr=   )dfrt   return_inputrZ   s    `  r+   r
   r
      s   . r'{!""++C0B0B0D0D,E,EFF 
,
 
 	
 mT** 
%
 
 	

: : : : :  Ky%a((//t/LLM
 
 
 	

 xxAx&&--mT-JJJr-   c                 6   t          | d         j                                      t                                                              st	          d          t          t                    st	          d          fd}|                     dd          ddg                             |          }t          j
        t          j        |j                  | j        	                              d
          }|rt          j        | |gd          S |S )a  
    Calculate the fraction of GC basepairs for each interval in a dataframe.

    Parameters
    ----------
    df : pandas.DataFrame
        A sets of genomic intervals stored as a DataFrame.

    fasta_records : OrderedDict
        Dictionary of chromosome names to sequence records.
        Created by: bioframe.load_fasta('/path/to/fasta.fa')

    mapped_only: bool
        if True, ignore 'N' in the fasta_records for calculation.
        if True and there are no mapped base-pairs in an interval, return np.nan.

    return_input: bool
        if False, only return Series named frac_mapped.

    Returns
    -------
    df_mapped : pd.DataFrame
        Original dataframe with new column 'GC' appended.

    r   r   rf   c                     | j         }|         }t          |d d                    }g }|                                 D ]?\  }}||d         |d                  }|                    t	          |                     @|S )Nr   r   )mapped_only)r.   ri   iterrowsappendr   )	chrom_groupr   rn   gc_r   r   rt   r   s	          r+   rZ   zfrac_gc.<locals>._each.  s     E"#aaa&kk!**,, 	: 	:FAsCL3u:-.AIIfQK8889999	r-   F)sortr   r   )datar   GCr    r   )r   r7   r   r6   r9   r0   r3   ra   r   r1   r2   rS   concatenater   r=   r_   )r   rt   r   r   rZ   aggout_cols    ``    r+   r   r   
  s#   4 r'{!""++C0B0B0D0D,E,EFF 
V
 
 	
 mT** 
%
 
 	

      **W5*
)
)7E*:
;
A
A%
H
HCiR^CJ77rxHHHOOPTUUG y"gY7777r-   c                    t          | t                    st          d          |                     d          }||                     d          z  }|                     d          }||                     d          z  }t	          |           }|r2|                     d          }||                     d          z  }||z  }|dk    r||z   |z  nt
          j        S )	ap  
    Calculate the fraction of GC basepairs for a string of nucleotides.

    Parameters
    ----------
    seq : str
        Basepair input

    mapped_only: bool
        if True, ignore 'N' in the sequence for calculation.
        if True and there are no mapped base-pairs, return np.nan.

    Returns
    -------
    gc : float
        calculated gc content.

    z reformat input sequence as a strGgCcr   r   r   )r0   ri   r9   r   r/   rS   nan)rn   r   r   r   r   r   s         r+   r   r   A  s    & c3 =;<<<		#A3A		#A3AXXF IIcNN	SYYs^^!%zzAEVrv5r-   c                    t          |t                    r$ddlm}  ||                                          }n|}|                    dddd          }t          j        | |          }t          j        ||          }|S )a  
    Calculate number and fraction of overlaps by predicted and verified
    RNA isoforms for a set of intervals stored in a dataframe.

    Parameters
    ----------
    df : pd.DataFrame
        Set of genomic intervals stored as a dataframe.

    ucsc_mrna: str or DataFrame
        Name of UCSC genome or all_mrna.txt dataframe from UCSC or similar.

    Returns
    -------
    df_gene_coverage : pd.DataFrame

    r   )
UCSCClientr   r   r   )tNametStarttEndrQ   )	r0   ri   io.resourcesr   
fetch_mrnar=   r   coveragecount_overlaps)r   	ucsc_mrnar   mrnadf_gene_coverages        r+   r   r   b  s    $ )S!! ,,,,,,z)$$//11;;GUSS;TTD|B--)*:DAAr-   rA   _1_2c
                 (  	 |                                  } t          |t                    r|nd}
|
	d         z   }|
	d         z   }|s|r|
| j        _        |t                      n|\  }}}|                     |||g                              d          } ||k    rt          d          |dk     rt          d          |d}|| j        	                                }||k    rt          d	          |dk     rt          d
          | |         | |         z   dz  }|dk    rt          d           | |         }n|dk    r|}nt          d          |s|r| ||
g                                          n| |g                                          }||dz  z   ||<   ||dz   dz  z   ||<   |dk    r	| |         }n|dk    r|}nt          d          |s|r| ||
g                                          n| |g                                          }||dz  z
  ||<   ||dz   dz  z
  ||<   t          j        ||	ddd          }t          j        |d	d                   |d	d                   z
            dz
  |d<   ||d         |k    |d         |k    z           }| j        |d	d                   j                                     	fd                              d          }| j        |d	d                   j                                     	fd                              d          }t%          j        ||gd          }|r|                    ||g          }|s|                    ||gd          }|                    dd           |S )aV  
    From a dataframe of genomic intervals, find all unique pairs of intervals
    that are between ``min_sep`` and ``max_sep`` bp separated from each other.

    Parameters
    ----------
    df : pandas.DataFrame
        A BED-like dataframe.
    min_sep, max_sep : int
        Minimum and maximum separation between intervals in bp.
        Min > 0 and Max >= Min.
    min_intervening, max_intervening : int
        Minimum and maximum number of intervening intervals separating pairs.
        Min > 0 and Max >= Min.
    relative_to : str,
        Whether to calculate distances between interval "midpoints" or "endpoints".
        Default "midpoints".
    cols : (str, str, str) or None
        The names of columns containing the chromosome, start and end of the
        genomic intervals, provided separately for each set. The default
        values are 'chrom', 'start', 'end'.
    return_index : bool
        If True, return indicies of pairs as two new columns
        ('index'+suffixes[0] and 'index'+suffixes[1]). Default False.
    keep_order : bool, optional
        If True, sort the output dataframe to preserve the order
        of the intervals in df1. Default False.
        Note that it relies on sorting of index in the original dataframes,
        and will reorder the output by index.
    suffixes : (str, str), optional
        The column name suffixes for the two interval sets in the output.
        The first interval of each output pair is always upstream of the
        second.

    Returns
    -------
    pandas.DataFrame
        A BEDPE-like dataframe of paired intervals from ``df``.

    r   r   r   NF)dropz!min_sep must be less than max_sepzmin_sep must be >=0z8min_intervening must be less or equal to max_interveningzmin_intervening must be >=0r   	endpointsendpointrA   z;relative_to must either specify 'midpoints' or 'endpoints' innerT)r*   howr%   r   interveningc                     | d         z   S )Nr   r'   xr*   s    r+   <lambda>z"pair_by_distance.<locals>.<lambda>	      !hqk/ r-   rQ   c                     | d         z   S )Nr   r'   r   s    r+   r   z"pair_by_distance.<locals>.<lambda>  r   r-   r   )r   r"   )r8   r0   ri   r   r.   r   sort_valuesr<   r9   r?   printr   overlaprS   absilocr7   r=   r1   r_   r   )r   min_sepmax_sepmin_interveningmax_interveningrelative_tocolsr%   
keep_orderr*   	index_colindex_col_1index_col_2ckskekmidsrefright_probe
left_probeidxs
left_ivalsright_ivalsout_dfs            `              r+   r   r     sC   l 
B !+< = =J7Ihqk)Khqk)K "z "! -1L&(((dJBB 
R	%	%	1	1u	1	=	=B'<==={{.///(,,..((STTT6777rFRVO!D k!!jf		#	#VWWW'3WzWB	?  """B4  GqL(KOWq[Q..KO k!!f		#	#VWWW'3WzWB	?  """B4  7a<'JrNGaKA--JrN ;  D 	t)HQK))*T2G(1+2G2G-HHIIAM 	 	m		//1	3D 	*Xa[**+23	1111	2	2	$		  	*Xa[**+23	1111	2	2	$		  Y
K0q999F @##[+$>?? Ak;7a@@
D$///Mr-   )r   r   r   )F)T)TT)NNrA   NFFr   )numpyrS   pandasr1    r   
core.specsr   r   __all__r   r   r	   r
   r   r   r   r   r'   r-   r+   <module>r      s2                 > > > > > > > >	 	 	 $c1 c1 c1 c1L* * * *Z/D /D /Dd/K /K /K /Kd4 4 4 4n6 6 6 6B  H 	Z Z Z Z Z Zr-   