o
    UݢgpO                     @  s  U d dl mZ d dl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
mZ d dlmZmZ d dlmZmZmZ d dlZd dlZd dlmZ dZded< d	Zded
< dZded< dZdtddZduddZG dd de Z!dvddZ"dwdd Z#dud!d"Z$dxd$d%Z%dyd'd(Z&ej'fdzd*d+Z(ej'fd{d-d.Z)d|d/d0Z*d|d1d2Z+d}d~d5d6Z,dd8d9Z-	:ddd?d@Z.G dAdB dBeZ/G dCdD dDeZ0ddIdJZ1ddKdLZ2ddNdOZ3G dPdQ dQeZ4ddSdTZ5ddWdXZ6e4dYe5dYdZgd[e4d\e5d\dZgd[e4d]e5d]dZgd[e4d^e5g d_d[e4d`e5g dad[e4dbe5g dcd[e4dde5g ded[e4dfe5g dgd[e4dhe5g did[e4dje6djgdkd[e4dle5dldZgd[e4dme6dmdngdod[gZ7dpedq< ddrdsZ8dS )    )annotationsN)CallableIterableMapping)c_intcdll)Literal
NamedTuple	TypedDicti   intMIN_PROCESS_NOFILEi   MIN_GLOBAL_NOFILEz/proc/sys/fs/file-maxstrGLOBAL_NOFILE_PATHz*https://support.10xgenomics.com/os-supportfilename9os.PathLike[str] | os.PathLike[bytes] | bytes | int | strregexreturn
str | Nonec                 C  sX   t j| r*t|}zt| D ]}||r|  W S qW dS  ty)   Y dS w dS )zHelper function for warn_deprecated_os - searches a file for a regex pattern.

    returns the line if pattern is found otherwise None
    returns None if an I/O error occurs as we expect to probe non-existent files
    N)ospathexistsrecompileopensearchOSError)r   r   Zsearcherline r   _/oak/stanford/groups/akundaje/marinovg/programs/cellranger-9.0.1/lib/python/tenkit/preflight.py_search_file_for_re    s   


r    Nonec               
   C  s   dD ]\} }t || }|rtd| dt d  dS qz#tt  ztd}W n t	y6   Y W dS w t
| t  W dS  tyZ } ztt| W Y d}~dS d}~ww )zCheck and warn the user about a deprecated OS being used.

    Direct port of the hints here:
    https://github.com/10XDev/cellranger/blob/b8df29dde96ba65e53a8fa0e9756ee06cac753d6/bin/tenkit/common/_deprecation
    )) [56]\.z/etc/redhat-release)r"   z/etc/rocks-release)r"   /etc/os-release)r"   z/etc/system-release)z	 1[0-3]\./etc/lsb-release)z [1-9]\.r$   )zSUSE.* 1[01]\bz/etc/SuSE-release)zPRETTY_NAME="Debian.*\b[1-7]\.r#   zWWARNING: This operating system version is unsupported or will soon be unsupported:
    z`
Future releases of this pipeline will require a more current system.
For more information, see .NCS_GNU_LIBC_VERSION)r    martianalarmOS_SUPPORT_URLcheck_kernel_versionplatformreleaser   confstr
ValueErrorcheck_libc_versioncheck_cpu_featuresOsVersionErrorr   )patnamer   libc_verexr   r   r   warn_deprecated_os4   s2   
	r6   c                   @  s   e Zd ZdZdS )r1   z@An exception notifying that the operating system is out of date.N)__name__
__module____qualname____doc__r   r   r   r   r1   ^   s    r1   r,   c              	   C  st   | sdS t d| }|sdS zt|d t|d f}W n ttfy(   Y dS w |dk r8td|  dt ddS )	zCheck that the kernel version is sufficiently new.

    Args:
        release (str): The kernel release, as returned by platform.release().

    Raises:
        OsVersionError: The kernel version is not sufficiently new.
    N\D*(\d+)\.(\d+)      )   
   zO
WARNING: The kernel used by this operating system version is unsupported:
    zR
This release requires kernel version 3.10.0 or higher.
For more information, see r%   )r   matchr   r.   	TypeErrorr1   r)   )r,   versionr   r   r   r*   b   s&   	r*   r4   c                 C  sp   | sdS t d| }|sdS zt|d t|d f}W n
 ty&   Y dS w |dk r6td|  dt ddS )	a
  Check that the libc version is sufficiently new.

    Args:
        libc_ver (str): The libc version string as returned by
                        os.confstr("CS_GNU_LIBC_VERSION")

    Raises:
        OsVersionError: The kernel version is not sufficiently new.
    Nr;   r<   r=   )r=      zY
    WARNING: The glibc version of this operating system version is unsupported:
        zV
    This release requires libc version 2.17 or higher.
    For more information, see r%   )r   r@   r   r.   r1   r)   )r4   Zlibc_versionr   r   r   r/      s&   
r/   c               
   C  s   t jt jtd} zt| }W n ty# } ztd|d }~ww |j	}t
|_| s5tdt d|j}t
|_| sFtdt d|j}t
|_| sWtdt dd S )Nzcpu_support.sozError loading cpu_support.soz[
WARNING: The current CPU does not support sse4.2 instructions.

For more information, see
r%   z
WARNING: The current CPU does not support avx instructions.

Future versions of 10X Genomics software will not support CPUs older than
Intel Xeon E3 (Sandy Bridge) or AMD Opteron FX (circa 2011).

For more information, see
)r   r   joindirname__file__r   LoadLibraryr   ImportErrorcpu_supports_sse4_2r   restyper1   r)   cpu_supports_popcntcpu_supports_avx)Zso_file_nameliberrrI   rK   rL   r   r   r   r0      s@   
r0   boolc                 C  s$   zt |  W dS  ty   Y dS w )NFT)r   r.   )sr   r   r   is_int   s   
rQ   	file_pathc                 C  s   | dstd|  d|  tj|s$td| d|  d|  tj|r8td| d|  d|  t|tjsOtd| d|  d|  d S d S )	N/
Specified z  file must be an absolute path: On machine: , specified z file does not exist: z file is a folder: z file is not readable: )	
startswithr'   exitr   r   r   isdiraccessR_OK)Z	file_typerR   hostnamer   r   r   
check_file   s   
r]   folder_pathc                 C  s   | dstd|  d|  tj|s$td| d|  d|  tj|s8td| d|  d|  t||sNtd| d|  d	|  d S d S )
NrS   rT   " folder must be an absolute path: rU   rV   z folder does not exist:  path is not a folder: , insufficient permissions on 	 folder: )rW   r'   rX   r   r   r   rY   rZ   Zfolder_typer^   r\   
permissionr   r   r   check_folder   s   
re   rd   c                 C  s   | dstd|  d|  tj|rBtj|s*td| d|  d|  t||s@td| d|  d|  d S d S zt| W d S  t	yb   td| d	|  d|  Y d S w )
NrS   rT   r_   rU   rV   r`   ra   rb   z, could not create )
rW   r'   rX   r   r   r   rY   rZ   makedirsr   rc   r   r   r   check_folder_or_create   s&   

rg   c                 C  sD   t  }td| | tj| d}tj|s td| d |S )zCheck that the RTAComplete.txt file is present.

    :return: path to valid RTAComplete.txt in folder_path
    :rtype: string
    sequencing runzRTAComplete.txtrU   zE, run does not appear to be complete yet.  RTAComplete.txt not found.)	socketgethostnamere   r   r   rD   r   r'   rX   )r^   r\   Zrta_completer   r   r   check_rta_complete
  s   
rk   c                 C  sd   t  }td| | tj| d}tj|s td| d t	|tj
s0td| d |S )zChecks that the RunInfo.xml file is present and readable.

    :return: path to valid RunInfo.xml in folder_path
    :rtype: string
    rh   zRunInfo.xmlrU   z;, RunInfo.xml not found. Cannot verify run was 10X-prepped.z., insufficient permission to open RunInfo.xml.)ri   rj   re   r   r   rD   r   r'   rX   rZ   r[   )r^   r\   Zruninfor   r   r   check_runinfo_xml  s   
rl   reference_pathtuple[bool, str]c              	   C  s  t  }tj| }d}|d urLtj| rLd}tj| d}tj	|s-dd| dfS tj	tj| drCtj	tj| dsKdd| dfS ntj	tj| ds_dd| dfS tj	tj| drutj	tj| d	swd
S tj
tj| dtj
tj| dk stj
tj| d	tj
tj| dk rd|rdnd|r|ndtj| dd}d|fS tj| }t|}|d ur||krdd||f fS tdd | D }	d|  d| d|d}
|
d||	f 7 }
|	dkrdS tdd |D }|r	dS d|
fS )NFTrB   ztYour reference does not contain the expected files, or they are not readable. Please check your reference folder on r%   zfasta/zgenes/zfasta/genome.fa.flatzfasta/genome.fa.gdx)FzGYour reference doesn't appear to be indexed. Please run the mkref tool.zfasta/genome.faa1  Timestamps suggest that the reference FASTA file was modified after the FASTA
index files were created. If this is the case, {}{}.
If the reference files were not deliberately modified, please run

touch {}

to fix the issue. If you do not have write permissions, please contact your
system administrator.z-please reinstall the 10X refdata
tar file on z2please reindex your reference
using the mkref tool fastazgenome.fa.*zLong Ranger supports a maximum of %d reference contigs. Your reference contains %d. Please combine small contigs into a larger contig separated by N's.c                 s  s    | ]}t |V  qd S N)len).0vr   r   r   	<genexpr>q      z check_refdata.<locals>.<genexpr>zreference path z on z contains genome: z5reference contains %d contigs. max contig length: %d.i    )FzReference contains a contig longer than 536.8Mb (2^29 bp), which is not supported due to limitations of the .bai format. Please split this contig.c                 s  s    | ]}d |v V  qdS ):Nr   )rs   Zctg_namer   r   r   ru   }  rv   )FzdReference names contain colon characters: ':'. References names containing colons are not supported.)ri   rj   tenkit	referenceZ
get_genomeZis_tenxr   r   rD   r   getmtimeformatZopen_referencerr   maxvaluesany)rm   Zmax_contigsr\   genomeZknown_genomeZversion_pathmsgrp   Znum_contigsmax_lenloggingZ
has_colonsr   r   r   check_refdata,  sx   



r   tuple[bool, str | None]c                  C  s   t t j\} }|dkr|tk rddt |ttf fS tjt	s/ddt  dt	 dfS t
t	}|  }W d    n1 sDw   Y  | s]ddt  dt	 d| dfS t|}|tk rqdd	t |ttf fS d
S )Nr   FzOn machine: %s, process open file handle hard limit (%d) is less than %d. Please run 'ulimit -n %d' before restarting the pipeline.rU   z, z does not exist.z7 contains a non-integer global open file handle limit: r%   zOn machine: %s, global open file handle limit (%d) is less than %d. Please set the global file handle limit to %d before restarting the pipeline.TN)resource	getrlimitRLIMIT_NOFILEr   ri   rj   r   r   r   r   r   readstripisdigitr   r   )_ZhardfZglob_strglobr   r   r   check_open_fh  s4   
r   sample_indicessample_itemMapping[str, list[str]]sample_index_keytuple[list | None, str | None]c                 C  s   | | }|sdS t |tsdS g }|D ]C}|dkr dgd f  S tj|r1|tj|g  qtj| }rA||d  qt	d|rM|| qd d| df  S |d fS )	N)Nz'Sample indices must be a non-empty list)Nz#Sample indices must be of type listr~   *r   z^[ACGTacgt]+$zSample index 'z{' is not valid. Must be one of: any, SI-<number>, SI-<plate>-<well coordinate>, 220<part number>, or a nucleotide sequence.)

isinstancelisttk_siZSAMPLE_INDEX_MAPgetextendZSAMPLE_DUAL_INDEX_MAPappendr   r@   )r   r   r   Znew_sample_indicessample_indexindexr   r   r   check_sample_indices  s&   

	r   c                   @     e Zd ZU ded< dS )	SampleDefz
int | None	gem_groupNr7   r8   r9   __annotations__r   r   r   r   r        
 r   c                   @  r   )_SampleDefWithGemGroupr   r   Nr   r   r   r   r   r     r   r   
sample_defIterable[SampleDef]all_null Iterable[_SampleDefWithGemGroup]c                 C  s   |r| D ]}d|d< q| S )zIf all gem_groups are set to null, then set them all to 1.

    This is broken out into a separate function in order to make type checkers
    work better.
    r<   r   r   )r   r   sdr   r   r   _make_some_gem_group  s   
r   c                 C  s   dd | D }t dd |D }t dd |D }|s|sdS tdd t| |D }t|dkr9|d d	kr9d
S d	}|D ]}|| d	krUddtt|d	 | f  S |}q=tt|d	krbdS dS )Nc                 S  s   g | ]}|d  qS )r   r   rs   r   r   r   r   
<listcomp>  s    z$check_gem_groups.<locals>.<listcomp>c                 s  s    | ]}|d u V  qd S rq   r   rs   xr   r   r   ru     rv   z#check_gem_groups.<locals>.<genexpr>c                 s  s    | ]}t |tV  qd S rq   )r   r   r   r   r   r   ru     s    )FznInconsistent gem_group tags. Please specify all gem_group tags as null, or all gem_group tags with an integer.c                 s  s    | ]}|d  V  qdS )r   Nr   r   r   r   r   ru     rv   r   r<   )Fz#gem_group numbering must start at 1Fz:gem_groups must be numbered contiguously. missing groups: )FzMulti-GEM well analysis is not enabled in `cellranger-[atac|arc] count`. Run `cellranger-[atac|arc] count` on each library and then run `cellranger-[atac|arc] aggr`.r   )allsortedr   rr   r   rangeset)r   
gem_groupsr   Zall_intZgem_groups_sortedprevgroupr   r   r   check_gem_groups  s$   r   7tuple[Literal[False], str] | tuple[Literal[True], None]c                   C  s   t jdd u r
dS dS )NZ_TENX_LD_LIBRARY_PATH)FzxEnvironment variable $_TENX_LD_LIBRARY_PATH is not set. Please enter the 10X environment before restarting the pipeline.r   )r   environr   r   r   r   r   check_ld_library_path  s   r   c                   @  s   e Zd ZU ded< ded< dS )_VersionCmdr   r3   Callable[[], bytes]cmdNr   r   r   r   r   r     s   
 r   r   c                   s    fdd}|S )Nc                     s
   t  S rq   )
subprocesscheck_outputr   r   r   r   fun  s   
z_call.<locals>.funr   )r   r   r   r   r   _call  s   r   r   bytesc                   s    t tsJ  fdd}|S )Nc                    s2   t  } | dD ]}t|r|  S q
dS )N   
	   not found)r   r   splitr   r@   )outputr   r   r   r   r   r     s   
z_grep.<locals>.fun)r   r   )r   r   r   r   r   r   _grep  s   r   mroz	--version)r3   r   mrppythonnumpy)r   -cz&import numpy; print(numpy.__version__)scipy)r   r   z&import scipy; print(scipy.__version__)pysam)r   r   z&import pysam; print(pysam.__version__)ZPyVCF)r   r   zimport vcf; print vcf.VERSIONh5py)r   r   z$import h5py; print(h5py.__version__)pandas)r   r   z(import pandas; print(pandas.__version__)Zbwas
   ^ *VersionsamtoolsZ	freebayesz-hs   ^versionzlist[_VersionCmd]_PACKAGE_VERSION_CMDSc               	   C  sV   g } t D ]!}|j}|j}d}z| }W n   Y | d||jdd qd| S )Nr   z{}: {}
replace)errorsro   )r   r3   r   r   r{   decoderD   )resultspackager3   r   rB   r   r   r   record_package_versionsA  s   

r   )r   r   r   r   r   r   )r   r!   )r,   r   r   r!   )r4   r   r   r!   )r   rO   )rR   r   r   r!   )r^   r   r   r!   )r^   r   rd   r   r   r!   )r^   r   r   r   rq   )rm   r   r   rn   )r   r   )r   )r   r   r   r   r   r   )r   r   r   rO   r   r   )r   r   r   r   )r   r   )r   r   )r   r   r   r   )r   r   )9
__future__r   r   r+   r   r   ri   r   collections.abcr   r   r   ctypesr   r   typingr   r	   r
   r'   Ztenkit.referencerx   Ztenkit.sample_indexr   r   r   r   r   r   r)   r    r6   EnvironmentErrorr1   r*   r/   r0   rQ   r]   X_OKre   rg   rk   rl   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   <module>   s   

*



-



[!!


&	

