3
ub"                 @   s  d dl mZ 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	Z	d dl
Z
d dlmZ d dlmZmZmZmZmZ yd dlmZ d dlZW n"   d dlmZ d dljZY nX d dlmZmZmZ d dlmZ eejZd	Z d
Z!ej"jej#dZ$da%dd Z&dd Z'dddZ(dd Z)dd Z*dd Z+dd Z,dd Z-dd Z.dd  Z/dd"d#Z0d$d% Z1d&d' Z2d(d) Z3d*d+ Z4d,d- Z5d.d/ Z6d0d1 Z7dd2d3Z8d4d5 Z9d6efd7d8Z:dd9d:Z;d;d< Z<e fd=d>Z=e fd?d@Z>dAdB Z?dCdD Z@dEdF ZAdGdH ZBefdIdJZCdKdL ZDdMdN ZEdOdP ZFdddd6dQdefdRdSZGdTdU ZHddVdWZId dXlJmKZKmLZLmMZMmZmNZNmOZO eKfdYdZZPdd[d\ZQd]d^ ZRdd_d`ZSdadb ZTdcdd ZUdedf ZVdgdh ZWdidj ZXdkdl ZYdefdmdnZZdodp Z[ddqdrZ\dsdt Z]dudv Z^deddddfdwdxZ_ddzd{Z`d|d} Zadefd~dZbdd ZcdddZddd Zedd Zfdd ZgeddfddZhdddZiefddZjdddZkdddZldd Zmdd ZndddZodd Zpdd ZqdS )    )with_statement)divisionN)defaultdict)basenameisfileisdirexistsjoin)urlopen)fastaparserqconfigplotter_data)
get_loggeri  i*  Zexternal_toolsc       	      C   sD  d}| r>t | rtt| tjd s8tt| tjd rd}nXtjjtjjtj	tj
} t | r|rd}| }x(t | rt|d t| } |d7 }qnW t | stj|  |rtj }tjtj	 d}tjj|rtj| tjt| | tj| |r:|rt |s:tj| n$tjj| tj}t |s:tj| | ||fS )NFz.logT   __   Zlatest)r   r   r	   r   LOGGER_DEFAULT_NAMELOGGER_META_NAMEospathabspathdefault_results_root_dirnameoutput_dirnamestrmakedirsgetcwdchdirislinkremovesymlinkr   default_json_dirname)	output_dirpathZjson_outputpathmake_latest_symlink	save_jsonZexisting_quast_diriZbase_dirpathZprev_dirpathZlatest_symlink r%   ;/home/psgendb/BIRCHDEV/pkg/quast-5.2.0/quast_libs/qutils.pyset_up_output_dir'   s@    






r'   c                s   | j  }ddddddddddd
 ddjttj j  }tj| fdd|}tjdj|r|t	j
d| d	 d
d d S |S )NN)
MKRYWSVBHDz(%s)|c                s    | j   S )N)group)m)dicr%   r&   <lambda>_   s    zcorrect_seq.<locals>.<lambda>z[^ACGTN]z	Skipping z* because it contains non-ACGTN characters.z    )indent)upperr	   mapreescapekeyssubcompilesearchloggererror)seqoriginal_fpathcorr_seqpatr%   )r6   r&   correct_seqX   s    rG   Fc             C   s  g }t t}xtj| D ]\}}|sJtjd|  d|d d   dd dS t||ksZ|rt|}t||}	||  d7  < t	j
st|| }
|
sdS n0tjdj|rtjd	|  d
 ddd dS |}
|j|	|
f qW |stjd|  d dd dS |rtj|| dS )Nz	Skipping zH because >sequence_name field is empty for the entry starting with "%s".   z    )r8   Fr   z[^ACGTN]zFile zG contains non-ACGTN characters. Please re-run QUAST without --no-check.)r8   exit_with_codez because file is empty.T)r   intr   
read_fastarA   rB   lencorrect_nameget_uniq_namer   no_checkrG   r;   r?   r@   appendwarningwrite_fasta)rD   
min_contigZcorrected_fpathis_referenceZmodified_fasta_entriesZused_seq_namesZ
first_linerC   Z	corr_nameZ	uniq_namerE   r%   r%   r&   correct_fastah   s6    


rU   c             C   s@   t j| j }tdd |D s8tjd|tjf  d S t|S )Nc             s   s   | ]}|t jkr|V  qd S )N)r   rS   ).0lr%   r%   r&   	<genexpr>   s    z)get_lengths_from_fasta.<locals>.<genexpr>z8Skipping %s because it doesn't contain contigs >= %d bp.)	r   get_chr_lengths_from_fastafilevaluessumrA   rQ   r   rS   list)contigs_fpathlabellengthsr%   r%   r&   get_lengths_from_fasta   s    r`   c                s   |r|j |}d}tjr:|tjks6tj|d tjkr:d}|sBdntj|j|j	j
 fddtjD  |j|j	j fddtjD  d S )NFr   Tr   c                s.   g | ]&  kr&t  fd dD ndqS )c             3   s   | ]}| krd V  qdS )r   Nr%   )rV   rW   )	thresholdr%   r&   rX      s    z3add_lengths_to_report.<locals>.<listcomp>.<genexpr>N)r[   )rV   )r_   min_threshold)ra   r&   
<listcomp>   s   z)add_lengths_to_report.<locals>.<listcomp>c                s.   g | ]&  kr&t  fd dD ndqS )c             3   s   | ]}| kr|V  qd S )Nr%   )rV   rW   )ra   r%   r&   rX      s    z3add_lengths_to_report.<locals>.<listcomp>.<genexpr>N)r[   )rV   )r_   rb   )ra   r&   rc      s   )getr   split_scaffoldsdict_of_broken_scaffoldsr   Zget_color_and_lsZsecondary_line_stylerS   	add_fieldFieldsZCONTIGS__FOR_THRESHOLDScontig_thresholdsZTOTALLENS__FOR_THRESHOLDS)r_   	reportingr]   reportZ	is_brokenr%   )r_   rb   r&   add_lengths_to_report   s    



rl   c                sn  t jd krdt _tt| t j}tjd  fddt| D }tt||\}}}}	}
g }g }t	|
rpt
d xtt|D ]}| }tjdj|	|  x$|| D ]}|j| |t j|< qW x4|| D ](\}}|j| |t j|< t||| qW xD|| D ]8\}}|j| |j| |d t j|< t||| qW q~W t jsTt jrftjsftj| ||fS )Nr   z  Pre-processing...c                s   g | ]\}}|| fqS r%   r%   )rV   r$   r]   )corrected_dirpathlabelsr%   r&   rc      s    z#correct_contigs.<locals>.<listcomp>   
_broken)r   max_threadsminrL   rA   	main_info	enumeraterun_parallelparallel_correct_contigsanyexitranger	   rP   assembly_labels_by_fpathrl   
draw_plotshtml_reportr   dict_color_and_lsZsave_colors_and_ls)contigs_fpathsrm   rn   rj   n_jobsZparallel_run_argsZ
old_fpathscorr_fpathsbroken_scaffold_fpathslogsis_fatal_errorZcorrected_contigs_fpathsold_contigs_fpathsZ
contig_idxr^   Z	old_fpath
corr_fpathr_   Zbroken_fpathr%   )rm   rn   r&   correct_contigs   s:    







r   c             C   s   t  rt| S t| S d S )N)
is_python2Zunicoder   )valuer%   r%   r&   convert_to_unicode   s    r   c             C   sV   ddl }|jdt| jddjd} ttjdd| j } ttjd	d| } t| S )
z
    Prepare string to use in file names: normalizes string,
    removes non-alpha characters, and converts spaces to hyphens.
    r   NZNFKDasciiignorezutf-8z[^\w\s-]-z[-\s]+)	unicodedata	normalizer   encodedecoder;   r>   stripr   )r   r   r%   r%   r&   slugify   s
    r   c             C   s`  t jj|}t|\}}||  }g }g }	g }
g }d}tt jj|t|| }t||}|sbd }n8tj	rt
|tjs~d }d}q|}nt
|tj|sd }d}|r|	j||f |
j| |jdt| t|dkd d||f   tjotj o|rRt| ||||\}}|rRt||d }|rRtj	s:t
|tj|rR|j||f |tj|< |
|	|||fS )NFTz  r   )forcez	%s ==> %srq   )r   r   r   splitext_for_fasta_fileunique_corrected_fpathr	   r   r`   r   no_check_metarU   rS   rP   index_to_strrL   re   is_combined_refbroke_scaffoldsrf   )file_counterr]   rm   rn   contigs_fnamefname	fasta_extr^   r   r   r   r   r   r   r_   Zbroken_scaffold_fpathr%   r%   r&   rw      s@    

*
rw   c             C   s\  |j dt| t|dkd d  tjj|}t|\}}||  }ttjj|t	|| }	tjj|t
|	}
|
d | }g }d}d}xNttj|D ]<\}\}}|d dkr|dkrt|||tjtj}||7 }qW ||d kr.tj|| |j dt| t|dkd d	|d |||d f   ||fS |j dt| t|dkd d
|   d |fS )Nz  r   )r   z"  breaking scaffolds into contigs:rq   r   d   i  z6    %d scaffolds (%s) were broken into %d contigs (%s)zK    WARNING: nothing was broken, skipping '%s broken' from further analysis)rP   r   rL   r   r   r   r   r   r	   r   name_from_fpathru   r   rK   split_by_nsr   Ns_break_thresholdrS   rR   )r   rn   r]   rm   r   r   r   r   r^   r   Zcorr_fpath_wo_extZbroken_scaffolds_fpathZbroken_scaffolds_fastaZcontigs_counterZscaffold_counternamerC   Ztotal_contigs_for_the_scafr%   r%   r&   r     s6    "r   r   c       
      C   s   d}d}x|t | k r| jd|dkr| jd|}|d }	x$|	t | kr^| |	 dkr^|	d7 }	q<W |	d }|	| |kr
|j|j d d t|d  | || f |d7 }|	}q
W t | | |kr|j|j d d t|d  | |d  f |d7 }|S )Nr   r(   r   _)rL   findrP   splitr   )
rC   r   Zsplitted_fastar   rS   Ztotal_contigsZcur_contig_startcumul_contig_lengthstartendr%   r%   r&   r   /  s,    r   c             C   s   t jr
dS d}t| }xl||k r| jd|dkr| jd|}|d }x ||krd| | dkrd|d7 }qFW |d }|| t jkrdS qW dS )NFr   r(   r   Tr   )r   rO   rL   r   r   )rC   r   Zseq_lenr   r   r%   r%   r&   is_scaffoldI  s    r   c             C   s   t jj| }t|\}}tt jj||| }tj rhtj rht	| tj
|ddsltjd|  d dd n| }tjd| t|f  |} | S )NT)rT   zReference file zU is empty or contains incorrect sequences (header-only or with non-ACGTN characters)!r   )rI   z  %s ==> %s)r   r   r   r   r   r	   r   r   r   rU   rS   rA   rB   rt   r   )	ref_fpathrm   Z	ref_fnamer   r   r   r%   r%   r&   correct_referenceZ  s    

r   c             C   sv   dd }|| j d}dd |D }t|t|krHtjdddd	 g S x$t|D ]\}}||j ||< qRW |S d S )
Nc             S   s<   | r8| d dkr| dd  } | d dkr4| d d } | S d S )Nr   "r   r   r   r%   )liner%   r%   r&   remove_quotesn  s    z#parse_labels.<locals>.remove_quotes,c             S   s   g | ]}|j  qS r%   )r   )rV   r^   r%   r%   r&   rc   {  s    z parse_labels.<locals>.<listcomp>z@Number of labels does not match the number of files with contigs   T)	to_stderr)r   rL   rA   rB   ru   r   )r   r   r   rn   r$   r^   r%   r%   r&   parse_labelsm  s    	r   c             C   s    t jjt jjt jj| }|S )N)r   r   r   dirnamer   )r]   r^   r%   r%   r&   get_label_from_par_dir  s    r   c             C   s<   t jj| }tt jj| }t jjt jj|d | }|S )Nr   )r   r   r   rm_extentions_for_fasta_filer   r   )r]   r   r   r^   r%   r%   r&    get_label_from_par_dir_and_fname  s    r   c                s$   dd | D   fdd| D }|S )Nc             S   s   g | ]}|j  qS r%   )lower)rV   r^   r%   r%   r&   rc     s    z"get_duplicated.<locals>.<listcomp>c                s"   g | ]} j |j d kr|qS )r   )countr   )rV   r^   )lowercase_labelsr%   r&   rc     s    r%   )rn   Z
dup_labelsr%   )r   r&   get_duplicated  s    r   c             C   sj   g }x| D ]}|j t| q
W xDt|D ]8}x2tt|| D ] \}\}}||kr>t|||< q>W q*W |S )N)rP   r   r   ru   zipr   )r   rn   fpathduplicated_labelr$   r^   r%   r%   r&   get_labels_from_par_dirs  s    
r   c       	      C   s   |r0xt |D ]\}}|st| | ||< qW n`|r>t| }nRdd | D }tt|}x6t t|| D ]$\}\}}||krht| | ||< qhW xjt|D ]^}d}xTt t|| D ]B\}\}}||kr|dkr|||< n|d t| ||< |d7 }qW qW |S )Nc             S   s   g | ]}t tjj|qS r%   )r   r   r   r   )rV   r   r%   r%   r&   rc     s    z"process_labels.<locals>.<listcomp>r    r   )ru   r   r   setr   r   r   )	r   rn   all_labels_from_dirsr$   r^   Zduplicated_labelsr   r   jr%   r%   r&   process_labels  s(    

r   c             C   s   t j rt j rtj|  d S )N)r   debugr   shutilrmtree)rm   r%   r%   r&   cleanup  s    r    c             C   s(   t jj| s$|jd|| f ddd | S )NzFile not found (%s): %sr   T)r   )r   r   r   rB   )r   messagerA   r%   r%   r&   assert_file_exists  s    r   c             C   s8   t jdkr| rdS d| d dkr&dnd | d  S d S )Nr   r   z%d 
   r   )r   assemblies_num)r$   r   r%   r%   r&   r     s    r   c             C   sv   t jj| tj}t jj|r&t j| t jj| tjd }t jj|rPt j| t jj| tj}t	|rrt
j| d S )Nz.html)r   r   r	   r   plots_fnamer   r   report_prefixhtml_aux_dirr   r   r   )r!   Zplots_fpathZ
html_fpathZhtml_report_aux_dirr%   r%   r&   remove_reports  s    

r   c             C   s   t jdd| j d | S )Nz
[^\w\._\-]r   )r;   r>   r   )r   max_name_lenr%   r%   r&   rM     s    rM   c             C   s   | j  d | S )N)r   )r   r   r%   r%   r&   correct_asm_label  s    r   c             C   s    | |kr| dt ||   7 } | S )Nr   )r   )r   Z
used_namesr%   r%   r&   rN     s    rN   c             C   s   t jj| }t jj| }t|}t jjt jj||rzd}|}x:t jjt jj||rxt|}t|d | }|d7 }q@W t jj||S )Nr   r   )r   r   r   r   rM   r   r	   r   )r   dirpathr   Z
corr_fnamer$   Zbase_corr_fnameZstr_ir%   r%   r&   r   !  s    r   c             C   s   t t| d S )Nr   )r   r   )r   r%   r%   r&   r   2  s    r   c             C   sL   t jj| \}}|dkr"| d }}t jj|\}}|dkrD|d }}||fS )N.zip.gz.gzip.bz2.bzip2r   .fa.fasta.fas.seq.fna.contig)r   r   r   r   r   )r   r   r   r   r   r   )r   r   splitext)r   basename_plus_innerext	outer_extr   r   r%   r%   r&   r   6  s    

r   c             C   s   d| ksd| ks| dkrdS t jj| \}}t jj|\}}|dkrN|| }}|dkrZdS |dkrt|jd|   dS |dkr|jd|   dS dS )Nz	blast.reszblast.checkz	blast.errFr   .fa.fasta.fas.seq.fnaT.zip.gz.gzip.bz2.bzip2z2Skipping %s because it is not a supported archive.z5Skipping %s because it has not a supported extension.)r   r   r   r   r   )r   r   r   r   r   r   )r   r   r   r   r   )r   r   r   rQ   )r   rA   r   r   r   r   r%   r%   r&   check_is_fasta_fileE  s    
r   c             C   s   t jjt jj| d S )Nr   )r   r   r   r   )r   r%   r%   r&   r   [  s    r   c             C   s
   t j|  S )N)r   r{   )r   r%   r%   r&   label_from_fpath_  s    r   c             C   s   t tj|  S )N)r   r   r{   )r   r%   r%   r&   label_from_fpath_for_fnamec  s    r   Tc             C   s   | d d  }|r|d|j g7 }|r>||jdkr2dnd|j g7 }|r^||jdkrRdnd|j g7 }x.t|D ]"\}	}
|
jtj rht|
||	< qhW |j|||d tj	| ||||d}|d	kr|j
d
t| d |rdt|j  d nd  |S )N<az>>>z2>>z2>)only_if_debug)stdinstdoutstderrenvr   r   zThe tool returned non-zero.z See z for stderr.r   )r   moderu   
startswithr   r   relpathZprint_command_line
subprocesscallr   rL   )argsr   r   r   r8   r   r   rA   Zprinted_argsr$   argreturn_coder%   r%   r&   call_subprocessg  s     r  c              C   s   d\} }t jdkrtddd}x\|D ]T}|j }t|d dkrTt|d d d } t|d d	kr$t|d d d }q$W W d Q R X t| d
 |d S )Nr   linux_64z/proc/meminforr   z	MemTotal:r   i   zMemFree:ro   )r   r   )r   platform_nameopenr   r   rJ   rs   )Z	total_memZfree_memZmemr   r%   r%   r&   get_free_memory  s    

"r  c             C   s   | d }|r"t dd |j D nd }t|stj| }t|dF}x>|j D ]2\}}|rb|| n|}|j|d t| d  qNW W d Q R X |S )Nz.faic             s   s   | ]\}}||fV  qd S )Nr%   )rV   rM   Zraw_namer%   r%   r&   rX     s    z$get_chr_len_fpath.<locals>.<genexpr>w	rp   )dictitemsis_non_empty_filer   rY   r  writer   )r   Zcorrect_chr_namesZchr_len_fpathZraw_chr_namesZchr_lengthsZout_fZchr_nameZchr_lenr%   r%   r&   get_chr_len_fpath  s    
(r  )curdirseppardirr	   r   commonprefixc             C   sf   | st dt|jt}t| jt}tt||g}tgt||  ||d  }|s^tS t| S )z#Return a relative version of a pathzNo path specifiedN)	
ValueErrorr   r   r  rL   r  r  r  r	   )r   r   
start_list	path_listr$   rel_listr%   r%   r&   r     s    r   c                s   dd dfdd}d
 fdd	|rTt jj|}||rT|S x4t jd	 jt jD ]}t jj|}||rh|S qhW dS )zH
    returns the path to an executable or None if it can't be found
    r   r   r   c                sR   t jj| rNt j| t jrN| }| krN|krJtjdf  dS dS )NzVersion of installed %s differs from its version in the QUAST package (%s). Please make sure that you use an actual version of software.TF)r   r   r   accessX_OKrA   rQ   )r   Zversion_check)INCOMPATIBLE_VERSIONNOT_RECOMMENDED_VERSIONcheck_versionmax_allowed_versionmin_versionprogramrecommend_versionr%   r&   is_exe  s    z#get_path_to_program.<locals>.is_exeNc                sL  |s S t j| dgt jt jd}|j \}}tjd}|jt|}|j	d s\|j	d r`S t
t|jdd d \}	}
t|j	d|	kot|j	d|
krD|d k	rt
t|jdd d \}}t|j	d|kst|j	d|krS |d k	r@t
t|jdd d \}}t|j	d|ks<t|j	d|kr@S  S S d S )Nz	--version)r   r   z.(?P<major_version>\d+)\.(?P<minor_version>\d+)Zmajor_versionminor_version.r   )r   PopenPIPESTDOUTcommunicater;   r?   r@   r   r4   r:   rJ   r   )r   r  r  r  pr   r   version_patternvversionr   Zmax_versionZmax_minor_versionZrec_versionZrec_minor_version)CORRECT_VERSIONr  r  r%   r&   r    s(    
&$
(z*get_path_to_program.<locals>.check_versionPATH)NN)r   r   r	   environr   pathsep)r  r   r  r  r  r  Zexe_filer   r%   )r*  r  r  r  r  r  r  r  r&   get_path_to_program  s    
r.  c             C   s   dd }yft jddgt jt jd}|j \}}tjd}t|jt	|dk rRdS ||jt	|d	 }|| kS  t
k
r   dS X d S )
Nc             S   s0   | j drt| dd  S dd l}|jt| S )Nz1.r   r   )r   floatmathfloor)verr0  r%   r%   r&   __get_java_major_version  s    
z4check_java_version.<locals>.__get_java_major_versionjavaz-version)r   r   zversion "(\d+\.\d+)r   Fr   )r   r"  r#  r$  r%  r;   r?   rL   findallr   r  )r  r3  r&  r   r   r'  r)  r%   r%   r&   check_java_version  s    
r6  c             C   s    | ot jj| ot jj| |kS )N)r   r   r   getsize)r   Zmin_sizer%   r%   r&   r    s    r  c             C   sp   t | ts| g} t|dL}xD| D ]<}tjj|r"t|}x|D ]}|j| qBW W d Q R X q"W W d Q R X d S )Nr  )
isinstancer\   r  r   r   r   r  )Z	in_fnamesZ	out_fnameZoutfiler   Zinfiler   r%   r%   r&   	cat_files   s    



r9  c             C   s8   yt |  dS  tk
r    dS  tk
r2   dS X d S )NTF)r/  r  	TypeError)r   r%   r%   r&   is_float  s    r;  c             C   s&   yt | S  tk
r    t| S X d S )N)rJ   r  r/  )sr%   r%   r&   parse_str_to_num  s    r=  c             C   s   | d krdS t | S d S )Nr   )r   )valr%   r%   r&   
val_to_str  s    r?  c             C   sH   t jj| \}}|dkr0t jj|\}}|| }||r>d| nd | S )N.gz.bz2.zipr!  r   )r@  rA  rB  )r   r   r   )r   suffixbaseextZext2r%   r%   r&   
add_suffix#  s
    rF  c             C   s$   x|D ]}t t| |sdS qW dS )NFT)r   r	   )Zaligner_dirpathZrequired_binariesrequired_binaryr%   r%   r&   all_required_binaries_exist+  s    
rH  c             C   sB   t |r>d|  d d | d }|r0|j| n
|j| dS dS )NzPrevious try of z compilation was unsuccessful! z#For forced retrying, please remove z and restart QUAST. TF)r   noticerQ   )r   failed_compilation_flagjust_noticerA   msgr%   r%   r&   check_prev_compilation_failed2  s    
rM  c             C   s`   t | r,ytj|  W n tk
r*   Y nX t| r\ytj| dd W n tk
rZ   Y nX d S )NT)ignore_errors)r   r   r   OSErrorr   r   r   )r   r%   r%   r&   safe_rm>  s    rP  c             C   sN   yt | dj  W n6 tk
rH   | d }|r:|j| n
|j| Y nX d S )Nr  z( cannot be created. Did you forget sudo?)r  closeIOErrorrB   rI  )r   rA   Zis_requiredrL  r%   r%   r&   safe_createK  s    rS  c               C   s   t jd dk S )Nr      )sysversion_infor%   r%   r%   r&   r   V  s    r   c          
   C   s^   yLt jt| dd  t jt| dd  t jt| dd  t jt| dd  W n   Y nX d S )Nz
aclocal.m4zMakefile.inzconfig.h.inZ	configure)r   utimer	   )r   r%   r%   r&   fix_configure_timestampsZ  s    rX  c	             C   s  t |d}	|	|rt|nd d }
|rNx|D ]}tt || q,W t|
 dS t||st| |
||drndS |jd|  d |	 d	  t|	d
 dj  t|	d dj  |rtj	 }tj
| tdg| t|	d
 dt|	d dd tj
| y@t|rd|gndgd|g t|	d
 dt|	d d|d}W n> tk
rr   d| d }|rd|j| n
|j| dS X |dkst|| rt| ||
||d dS dS )NZmaker   z.failedT)rA   Fz
Compiling z (details are in z.log and make.err)z.logr  z.errz./configurer   )r   r   z-C)r   r   rA   zPermission denied accessing z. Did you forget sudo?r   )rK  rA   )r	   r   rP  rH  rM  rt   r  rQ  r   r   r   r  rR  rI  rQ   write_failed_compilation_flag)r   r   ZrequirementsrK  rA   
only_cleanZflag_suffixZmake_cmdZconfigure_argsZmake_logs_basepathrJ  rG  Zprev_dirr   rL  r%   r%   r&   compile_toold  sD    




r[  rT  c             C   s<   t | stjd| d|d d| kr8tjd| d|d dS )Nz5QUAST does not support non-ASCII characters in path.
T)r   rI   r   z(QUAST does not support spaces in paths.
)is_ascii_stringrA   rB   )r   r   	exit_coder%   r%   r&   check_dirpath  s
    r^  c             C   s:   t | rt|  rdS t |  r6ttjj|  r6dS dS )NFT)r   check_write_permissionr   r   r   )r   r%   r%   r&   is_dir_writable  s
    r`  c             C   sJ   d|  d | d t jsdnd }|r2|j| n
|j| t|| d S )NzFailed to compile z (z)! Try to compile it manually. zKYou can restart Quast with the --debug flag to see the compilation command.r   )r   r   rI  rQ   rS  )tooltool_dirpathrJ  rK  rA   rL  r%   r%   r&   rY    s    
rY  c             C   s   t j| t jS )N)r   r  W_OK)r   r%   r%   r&   r_    s    r_  c                s   t tj|  t tjjdd}t || t fdd|D rB S tfdd|D r\S t s|s|jd  d | d |  t|s|s|j	d	| d | d
  d S  t
 stj   S )N~z.quastc             3   s    | ]}t jjt |V  qd S )N)r   r   r   r	   )rV   r   )rb  r%   r&   rX     s    z'get_dir_for_download.<locals>.<genexpr>c             3   s    | ]}t jjt |V  qd S )N)r   r   r   r	   )rV   r   )tool_home_dirpathr%   r&   rX     s    zPermission denied accessing z. z& will be downloaded to home directory z+Permission denied accessing home directory z cannot be downloaded.)r	   r   LIBS_LOCATIONr   r   
expanduserallr`  rI  rQ   r   r   )r   ra  required_filesrA   rZ  Zquast_home_dirpathr%   )rb  re  r&   get_dir_for_download  s$    

rj  c          	   C   s   t jt jt jt jt jt jt jt jt j	g	}dd |D t _
t j
sBd S dd tt jt jD t _t jjt j dd tt jt jD t _t jjt j d S )Nc             S   s   g | ]}|D ]}|r|qqS r%   r%   )rV   libr   r%   r%   r&   rc     s    z&check_reads_fpaths.<locals>.<listcomp>c             S   s   g | ]\}}||fqS r%   r%   )rV   read1read2r%   r%   r&   rc     s    c             S   s   g | ]\}}||fqS r%   r%   )rV   rl  rm  r%   r%   r&   rc     s    )r   forward_readsreverse_readsinterlaced_readsunpaired_readsmp_forward_readsmp_reverse_readsmp_interlaced_readspacbio_readsnanopore_readsreads_fpathsr   paired_readsextend
mate_pairs)rA   Zreads_librariesr%   r%   r&   check_reads_fpaths  s    r{  c             C   s   t | t}|S )N)r.  blast_dirpath)r   Z
blast_pathr%   r%   r&   get_blast_fpath  s    
r}  c             C   sn   | dkrjt ||d  dkrj| t ||d   dkrjtdtdt t| | | d |f f tjj  d S )Nr   r   z% 3.1f%% of %d bytes)rJ   printrs   r/  rU  r   flush)r   bcr%   r%   r&   show_progress  s    4,r  c             C   s   dddg}|p|}dd |D }| r0| r0dS t dd|| |d	atsJd
S dd |D }|rztjjtrvtjtdd dS xVt|D ]J\}}t|| d}| j	  |sd
S tj
|tj|jtjB tjB tjB  qW dS )NZmakeblastdbZblastnZtblastnc             S   s   g | ]}t |s|qS r%   )r}  )rV   cmdr%   r%   r&   rc     s    z+download_blast_binaries.<locals>.<listcomp>TblastZBLAST)rZ  Fc             S   s   g | ]}t |s|qS r%   )r}  )rV   r  r%   r%   r&   rc     s    )rN  )rA   )rj  r|  r   r   r   r   r   ru   download_blast_binaryinfochmodstatst_modeS_IXUSRS_IXGRPS_IXOTH)rA   	filenamesrZ  Zall_binariesri  r$   r  Zblast_fpathr%   r%   r&   download_blast_binaries  s(    
*r  c             C   s   t jj|stjd|t jj|f  ytj j| |d t	 W n8 t
k
rx   tj \}}}tjd|| ||f  d S X |rtj|d | tjd|  |S )NzDownloading %s (file: %s)...z	.downloadzFailed downloading %s (url: %s), QUAST functionality will be limited! Exception caught: %s
You can try to download the file manually, place it in %s and restart QUASTz%s successfully downloaded!)r   r   r   rA   r  r   urllibZ	URLopenerZretriever  	ExceptionrU  exc_inforB   r   move)urlr   Z	tool_nameZ	move_filer   	exc_valuer%   r%   r&   download_file  s    r  c             C   s(   t jjtst jt t| tddddS )Nr  T)platform_specificis_executable)r   r   r   r|  r   download_external_tool)Zblast_filenamerA   r%   r%   r&   r    s    
r  c       	      C   s   t || }tjj|r|S t t|}|r4t |tj}tjj || }t tjt|tj	 | }t|sltj
| t|rtjd|  d |  tj|| nt|||}|r|rtj|tj|jtjB tjB tjB  n
tjd |S )NzCopying z from zePlease try to install the tool manually, add it to your PATH environment variable, and restart QUAST.)r	   r   r   r   external_tools_dirpathr   r  GIT_ROOT_URLr   
QUAST_HOMEr   r   rA   r  r   copyr  r  r  r  r  r  r  rB   )	r   r   ra  r  r  Zdownloaded_fpathZexternal_dirpathZexternal_fpathr  r%   r%   r&   r    s&    


(
r  c       
         sZ  t jr fdd|D n|p"t j}d|i}yRdd l}ddlm}m y ddi}|f | |j| W n tk
rz   Y nX W n< tk
r   t	 rddl
m}m nddlm}m Y nX |f | fdd	|D g }rVtd tptd trDtd }	r,fd
dt|	D }nfddt|	D }nfddD }|S )Nc                s   g | ]} | qS r%   r%   )rV   r   )_fnr%   r&   rc   -  s    z run_parallel.<locals>.<listcomp>r   r   )ParalleldelayedZbackendmultiprocessingc             3   s   | ]} | V  qd S )Nr%   )rV   r   )r  r  r%   r&   rX   B  s    zrun_parallel.<locals>.<genexpr>c                s   g | ]  fd dD qS )c                s   g | ]}|  r|  qS r%   r%   )rV   result_list)r$   r%   r&   rc   H  s    z+run_parallel.<locals>.<listcomp>.<listcomp>r%   )rV   )results_tuples)r$   r&   rc   H  s    c                s   g | ]  fd dD qS )c                s   g | ]}|  qS r%   r%   )rV   r  )r$   r%   r&   rc   J  s    z+run_parallel.<locals>.<listcomp>.<listcomp>r%   )rV   )r  )r$   r&   rc   J  s    c                s   g | ]}|s  r|qS r%   r%   )rV   result)filter_resultsr%   r&   rc   L  s    )r   memory_efficientrr   joblibr  r  updater:  ImportErrorr   Zjoblib2Zjoblib3r8  r\   tuplerL   rz   )
r  Zfn_argsr   r  Zparallel_argsr  r  Znew_style_parallel_argsresultsZresults_cntr%   )r  r  r  r  r&   rv   +  s6    


rv   c             C   s>   y| j d W n& tk
r"   dS  tk
r4   dS X dS d S )Nr   FT)r   UnicodeDecodeErrorUnicodeEncodeError)r   r%   r%   r&   r\  Q  s    r\  c          	   C   sF   t j }t| d&}x|jd}|s&P |j| qW W d Q R X |j S )Nrbi    )hashlibmd5r  readr  Z	hexdigest)r   Zhash_md5fbufr%   r%   r&   r  \  s    
r  c             C   s   |d kr| d }t | rxt |rxt|}|j j j d }W d Q R X tt| }||krttjd| ||f  dS dS tjd| |f  dS )Nz.md5r   zFFailure of md5 check for %s! Expected md5 is %s, calculated md5 is %s.FTzVFailed to check md5 for %s! Either this file or its md5 file (%s) is missing or empty.)	r  r  readliner   r   r   r  rA   rQ   )r   Z	md5_fpathr  Zexpected_md5Zcalculated_md5r%   r%   r&   
verify_md5g  s    
r  c             C   s4   dd l }t|jt| | d d }| td| S )Nr   r   r   )r0  rJ   ceilrL   max)rZ   percentr0  Zpercentile_idxr%   r%   r&   
percentiley  s    r  c             C   sR   t | d dkr&| t | d d  }n(| t | d  | t | d d   d }|S )Nr   r   )rL   )rZ   Zmedianr%   r%   r&   calc_median  s    (r  )NF)r   r   r   )NF)F)N)NNNN)r   )F)r   rT  )F)T)FF)NF)N)rZ
__future__r   r   Zglobr  r   r   r   r  rU  r;   collectionsr   Zos.pathr   r   r   r   r	   Zurllib2r
   r  Zurllib.requestZrequest
quast_libsr   r   r   quast_libs.logr   r   rA   ZMAX_CONTIG_NAMEZMAX_CONTIG_NAME_GLIMMERr   r  r  r|  r'   rG   rU   r`   rl   r   r   r   rw   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rM   r   rN   r   r   r   r   r   r   r   r  r  r  	posixpathr  r  r  r   r  r   r.  r6  r  r9  r;  r=  r?  rF  rH  rM  rP  rS  r   rX  r[  r^  r`  rY  r_  rj  r{  r}  r  r  r  r  r  rv   r\  r  r  r  r  r%   r%   r%   r&   <module>   s   
1
#')"

$
.
 
5



+





&
