
    чoe?                        d dl Z d dlZd dlmZ d dl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mZ d dlZd dlmZ d dlmZ d dlZ	  ej        e          Z ej        e          Zn# e$ r dZdZY nw xY wd d	lmZmZmZmZ d
ZdZ g dZ!dZ"dZ#d
Z$dZ%dZ&dZ'd)dZ(d*dZ)d Z*d Z+d Z,d Z-d Z.d Z/d Z0d Z1d Z2d Z3d  Z4d+d!Z5d,d#Z6d$ Z7ed-d&            Z8d' Z9d( Z:dS ).    N)contextmanager)defaultdict)getenv)abspathdirnameexists)md5)open)vlen)meanmedianminmaxDaniel McDonaldz5Copyright 2011-2020, The BIOM Format Development Team)r   zJai Ram RideoutzGreg CaporasozJose ClementezJustin Kuczynskiu   Jorge Cañardo AlastueyBSDzhttp://biom-format.orgzdaniel.mcdonald@colorado.edu)      z2.1.15sampleFc              #   <   K   	 |                      |||          V  )a  Indefinitely generate random subsamples

    Parameters
    ----------
    table : Table
        The table to subsample from
    n : int
        The size of the subsample
    axis : {'sample', 'observation'}, optional
        The axis to operate on, defaults to 'sample'.
    by_id : bool, optional
        If `True`, operate on IDs, if `False`, operate on values. Defaults to
        `False`.

    Returns
    -------
    GeneratorType
        Each subsequent call to .next() will yield a new randomly subsampled
        table

    Examples
    --------

    Randomly subsample the samples in the example_table 10 times:

    >>> from biom import example_table
    >>> gen = generate_subsamples(example_table, 2, by_id=True)
    >>> observed_ids = []
    >>> for _, table in zip(range(100), gen):
    ...     observed_ids.append(tuple(table.ids()))
    >>> print(sorted(set(observed_ids)))
    [('S1', 'S2'), ('S1', 'S3'), ('S2', 'S3')]

    )	subsample)tablenaxisby_ids       ^/mounts/lovelace/software/anaconda3/envs/kraken-biom/lib/python3.11/site-packages/biom/util.pygenerate_subsamplesr   /   s-      F.ooau-----.    c                 4    | dS d| d          d| d          dS )zReturns the current Biom file format version.

    Parameters
    ----------
    version : tuple
        a tuple containing the version number of the biom table
    Nz#Biological Observation Matrix 1.0.0zBiological Observation Matrix r   .r   z.0 )versions    r   get_biom_format_version_stringr"   V   s0     44K
KKWQZKKKKr   c                      t           S )z5Returns the current Biom file format description URL.)__url__r    r   r   get_biom_format_url_stringr%   d   s    Nr   c           
      v    | r6t          t          t           t          t          |                                S g S )aA  Performs the reverse of zip, i.e. produces separate lists from tuples.

    items should be list of k-element tuples. Will raise exception if any
    tuples contain more items than the first one.

    Conceptually equivalent to transposing the matrix of tuples.

    Returns list of lists in which the ith list contains the ith element of
    each tuple.

    Note: zip expects *items rather than items, such that unzip(zip(*items))
    returns something that compares equal to items.

    Always returns lists: does not check original data type, but will accept
    any sequence.

    This function is ported from PyCogent (http://www.pycogent.org). PyCogent
    is a GPL project, but we obtained permission from the authors of this
    function to port it to the BIOM Format project (and keep it under BIOM's
    BSD license).
    )listmapzip)itemss    r   unzipr+   i   s4    ,  Cc4;;/00111	r   c                 x    g }| D ]4}	 |                     |           #  |                    |           Y 2xY w|S )ah  Removes one level of nesting from items.

    items can be any sequence, but flatten always returns a list.

    This function is ported from PyCogent (http://www.pycogent.org). PyCogent
    is a GPL project, but we obtained permission from the authors of this
    function to port it to the BIOM Format project (and keep it under BIOM's
    BSD license).
    )extendappend)r*   resultis      r   flattenr1      sX     F  	MM!	MM!Ms   7c                    t          |           } 	 t          j        d|           }n+# t          $ r t          j        d| d                   }Y nw xY wt	          t          |                    D ]W}||         r@||         d         dv r0d||         v rt          }nt          }d |||                   f||<   Jd||         f||<   X|| fS )a  Provides normalized version of item for sorting with digits.

    This function is ported from QIIME (http://www.qiime.org) and is based on:
    http://lists.canonical.org/pipermail/kragen-hacks/2005-October/000419.html
    QIIME is a GPL project, but we obtained permission from the authors of this
    function to port it to the BIOM Format project (and keep it under BIOM's
    BSD license).
    z(\d+(?:\.\d+)?)r   
0123456789r   r   )strresplit	TypeErrorrangelenfloatint)itemchunksiinumtypes       r   _natsort_keyr@      s     t99D7,d33 7 7 7 ,d1g667 CKK   	) 	)": 	)&*Q-<77fRj  WWVBZ001F2JJVBZF2JJD>s   ' %AAc                 Z    t          |           }|                    t                     |S )a  Sort a sequence of text strings in a reasonable order.

    This function is ported from QIIME (http://www.qiime.org) and is based on:
    http://lists.canonical.org/pipermail/kragen-hacks/2005-October/000419.html
    QIIME is a GPL project, but we obtained permission from the authors of this
    function to port it to the BIOM Format project (and keep it under BIOM's
    BSD license).
    )key)r'   sortr@   )seqalists     r   natsortrF      s(     IIE	JJ<J   Lr   c                     | | n|S )z+Merge metadata method, return X if X else Yr    )xys     r   prefer_selfrJ      s    111$r   c                 4    d t          |           D             S )z%Takes a list and returns {l[idx]:idx}c                     i | ]\  }}||	S r    r    ).0idxid_s      r   
<dictcomp>zindex_list.<locals>.<dictcomp>   s    555cC555r   )	enumerate)r<   s    r   
index_listrR      s    55Yt__5555r   c                     g } t                      }|                     |dz              t          d          }|r|                     |           t          d          }|r|dz   }|                     |           g }| D ]3}t          |          r"|                    t	          |                     4t          |          S )aL  Returns biom-format configuration read in from file.

    This function is ported from QIIME (http://www.qiime.org), previously named
    load_qiime_config. QIIME is a GPL project, but we obtained permission from
    the authors of this function to port it to the BIOM Format project (and
    keep it under BIOM's BSD license).
    z/support_files/biom_configBIOM_CONFIG_FPHOMEz/.biom_config)get_biom_project_dirr.   r   r   r
   parse_biom_config_files)biom_config_fpsbiom_project_dirbiom_config_env_fphome_dirbiom_config_home_fpbiom_config_filesbiom_config_fps          r   load_biom_configr_      s     O+--+.JJKKK 011 31222f~~H 4&82333) ; ;.!! 	;$$T.%9%9:::"#4555r   c                      t          t                    } t          |           }t          |          }t          |          S )aH  Returns the top-level biom-format directory.

    This function is ported from QIIME (http://www.qiime.org), previously named
    get_qiime_project_dir. QIIME is a GPL project, but we obtained permission
    from the authors of this function to port it to the BIOM Format project
    (and keep it under BIOM's BSD license).
    )r   __file__r   )
current_fpcurrent_dirs     r   rV   rV      s?     ""J *%%K +&&K ;r   c                     d }t          |          }| D ]5}	 |                    t          |                     &# t          $ r Y 2w xY w|S )a  Parses files in (ordered!) list of biom_config_files.

    The order of files must be least important to most important. Values
    defined in earlier files will be overwritten if the same values are defined
    in later files.

    This function is ported from QIIME (http://www.qiime.org), previously named
    parse_qiime_config_files. QIIME is a GPL project, but we obtained
    permission from the authors of this function to port it to the BIOM Format
    project (and keep it under BIOM's BSD license).
    c                      d S Nr    r    r   r   return_nonez,parse_biom_config_files.<locals>.return_none  s    tr   )r   updateparse_biom_config_fileOSError)r]   rg   resultsbiom_config_files       r   rW   rW      s{       +&&G-  	NN12BCCDDDD 	 	 	D	 Ns   ";
AAc                     i }| D ]n}|                                 }|r|                    d          r.|                                }|d         }d                    |dd                   pd}|||<   o|S )aA  Parses lines in a biom_config file.

    This function is ported from QIIME (http://www.qiime.org), previously named
    parse_qiime_config_file. QIIME is a GPL project, but we obtained permission
    from the authors of this function to port it to the BIOM Format project
    (and keep it under BIOM's BSD license).
    #r    r   N)strip
startswithr6   join)rl   r/   linefieldsparam_idparam_values         r   ri   ri     s     F  	' 	'zz||  	ts++ 	!9hhvabbz**2d&xMr   c                    i }|                                  D ]H\  }}}|r|dk                                    ||<   $t          |                                          ||<   It          |                                          }t          |          dk    rdddd|fS t          |          t          |          t          |          t          |          |fS )a@  Return summary statistics on per-sample observation counts

        table: a BIOM table object
        binary_counts: count the number of unique observations per
         sample, rather than the sum of the total counts (i.e., counts
         are qualitative rather than quantitative)

    This function is ported from QIIME (http://www.qiime.org), previously named
    compute_seqs_per_library_stats. QIIME is a GPL project, but we obtained
    permission from the authors of this function to port it to the BIOM Format
    project (and keep it under BIOM's BSD license).
    r   )
itersumr:   r'   valuesr9   r   r   r   r   )r   binary_countssample_countscount_vector	sample_idmetadatacountss          r   compute_counts_per_sample_statsr   0  s     M-2ZZ\\ A A)i 	A(4(9'>'>'@'@M)$$',\-=-=-?-?'@'@M)$$-&&(())F
6{{a1aM**FFvV	 	r      c                 n    d}t                      }t           d          r
 j        }|}n>t           t                    r
 fd}|}d}nt          dt                     z            |r7 ||          }|r(|                    |                    d                     |7|	                                S )a  Computes an md5 sum without loading the file into memory

    This method is based on the answers given in:
    http://stackoverflow.com/questions/1131220/get-md5-hash-of-a-files-without-open-it-in-python

    This function is ported from PyCogent (http://www.pycogent.org). PyCogent
    is a GPL project, but we obtained permission from the authors of this
    function to port it to the BIOM Format project (and keep it under BIOM's
    BSD license).
    Treadc                 R    	                      |           S # t          $ r Y d S w xY wrf   )pop
IndexError)r0   	open_files    r   fzsafe_md5.<locals>.fc  s<     }}Q'''   tts    
&&r   zHsafe_md5 can only handle a file handle or list of lines but recieved %r.utf-8)
r	   hasattrr   
isinstancer'   r7   typerh   encode	hexdigest)r   
block_sizedatar/   data_getterdata_getter_ir   s   `      r   safe_md5r   O  s     DUUF y&!! Dn"	It	$	$ 
D	 	 	 	 	
  137	??C D D 	D  0{=)) 	0MM$++g..///  0 r   c                     t          | d          5 }|                    d          dk    cddd           S # 1 swxY w Y   dS )a  Checks the first two bytes of the file for the gzip magic number

    If the first two bytes of the file are 1f 8b (the "magic number" of a
    gzip file), return True; otherwise, return false.

    This function is ported from QIIME (http://www.qiime.org). QIIME is a GPL
    project, but we obtained permission from the authors of this function to
    port it to the BIOM Format project (and keep it under BIOM's BSD license).
    rbr   s   Nr
   r   fpr   s     r   is_gzipr   u  s     
b$ (1vvayyK'( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (   7;;rc              #   z  K   |dvrt          d|z            t          j        t          j        d          }|}|dv r5t
          j                            |           dk    rt          d| z            |dv r+t          j
        |           rt          j        }|d	k    rd
n|}n|dk    rt          j        }|dv rt          |           rd }|dv rdn|}n)|dv r%t          |                               d          rd } || |          }	 |V  |                                 dS # |                                 w xY w)at  Wrapper to allow opening of gzipped or non-compressed files

    Read or write the contents of a file

    Parameters
    ----------
    file_fp : file path or pathlib.Path
    permission : str, {'r', 'w', 'wb', 'rb', 'U'}

    Returns
    -------
    [h5py.File, file, gzip.GzipFile]

    Notes
    -----
    If the file is binary, be sure to pass in a binary mode (append 'b' to
    the mode); opening a binary file in text mode (e.g., in default mode 'U')
    will have unpredictable results.

    If h5py is available on the system, you cannot use biom_open to create a
    writable ASCII file handle. You can use it to create writable GZIP handles
    and HDF5 handles, however.

    This function is ported from QIIME (http://www.qiime.org), previously named
    qiime_open. QIIME is a GPL project, but we obtained permission from the
    authors of this function to port it to the BIOM Format project (and keep it
    under BIOM's BSD license).

    Raises
    ------
    RuntimeError
        If the user tries to parse an HDF5 file without having h5py installed.
    ValueError
        If the user tries to read an empty file.

    )r   wUr   wbzUnknown mode: %sr   )encoding>   r   r   r   r   z*The file '%s' is empty and can't be parsed)r   r   r   r   r   r   c                 X     t          j        d          t          | |                    S Nr   )codecs	getreader	gzip_openr   modes     r   openerzbiom_open.<locals>.opener  s'    ,6#G,,Yr4-@-@AAAr   )r   r   r   )r   r   z.gzc                 \     t          j        d          t          | |                     d S r   )r   	getwriterr   r   s     r   r   zbiom_open.<locals>.opener  s-    %FW%%iD&9&9:::::r   N)rj   	functoolspartialior
   ospathgetsize
ValueErrorh5pyis_hdf5Filer   r4   endswithclose)r   
permissionr   r   r   s        r   	biom_openr     s|     L 444(:5666rw999FD 7??2!##IBNOOODL$4$4 C''ssZ	GBKK	B 	B 	B!Z//ttZ			R!1!1%!8!8		; 	; 	; 	r4A										s   
D$ $D:c                 "   t          j        t          j                              d         d         }t          j                            t          j                            |                    }t          j                            |d|           }|S )aT  Return path to filename ``fn`` in the data folder.

    During testing it is often necessary to load data files. This
    function returns the full path to files in the ``data`` subfolder.

    Parameters
    ----------
    fn : str
        File name.

    Returns
    -------
    str
        Inferred absolute path to the test data for the module where
        ``get_data_path(fn)`` is called.

    Notes
    -----
    The requested path may not point to an existing file, as its
    existence is not checked.

    This method was adapted from scikit-bio, specifically `skbio.util.testing`.
    r   	test_data)inspectgetouterframescurrentframer   r   r   r   rr   )fncallers_filenamer   	data_paths       r   get_data_pathr     sg    6 -g.B.D.DEEaHK7??27??+;<<==DT;33Ir   c                     t          | d          5 }|                    d          dk    cddd           S # 1 swxY w Y   dS )zGuess if file is HDF5.

    Parameters
    ----------
    fn : str
        File name

    Returns
    -------
    bool
        Whether the file is an HDF5 file
    r      s   HDF

Nr   r   s     r   is_hdf5_filer     s     
b$ 11vvayy001 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1r   )r   Frf   )F)r   )r   );r   r   
contextlibr   r   r   r   collectionsr   r   os.pathr   r   r   r5   hashlibr	   gzipr
   r   r   special_dtyper4   H5PY_VLEN_STRH5PY_VLEN_UNICODEImportErrornumpyr   r   r   r   
__author____copyright____credits____license__r$   __maintainer__	__email____format_version____version__r   r"   r%   r+   r1   r@   rF   rJ   rR   r_   rV   rW   ri   r   r   r   r   r   r   r    r   r   <module>r      s   
			  % % % % % % 				      # # # # # #       , , , , , , , , , , 				       " " " " " " &D&C000M**444   M ) ( ( ( ( ( ( ( ( ( ( (
GO O O
""*	 $. $. $. $.NL L L L  
  8  &  :  % % %
6 6 6
6 6 6:     *  6  ,   ># # # #L( ( ( C C C CL  B1 1 1 1 1s   "A) )	A54A5