U
    H$xeFA                     @   s4  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mZmZmZ d dlZddlmZmZmZ ddlmZ ddlmZmZmZmZ dd	lmZmZmZm Z m!Z!m"Z"m#Z#m$Z$m%Z% dd
l&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2 e3 Z4G dd deZ5G dd de5Z6G dd de5Z7dS )    N)ABCabstractmethod)Path)ListOptionalAnyTupleDictUnionTextIOBinaryIO   )
InputFilesOutputFilesopen_raise_limit)Progress)SingleEndModifierPairedEndModifierPairedEndModifierWrapperModificationInfo)	DiscardUntrimmed	PredicateTooShortTooLongTooManyNTooManyExpectedErrorsTooHighAverageErrorRateCasavaFilteredDiscardTrimmed)SingleEndSinkPairedEndSinkSingleEndFilterPairedEndFilterDemultiplexerPairedDemultiplexerCombinatorialDemultiplexerSingleEndStepPairedSingleEndStepRestFileWriterInfoFileWriterWildcardFileWriterc                
   @   s(  e Zd ZdZdZdZddddZddee ee	 d	d
dZ
eddddZddddZddddZddddZddddZee	dddZed)eeee eeeee f dddZeee ee dddZedd  Zeed!d"d#Zeed!d$d%Zeed&d'd(ZdS )*PipelinezU
    Processing pipeline that loops over reads and applies modifiers and filters
    r   FN)returnc                 C   sX   d | _ g | _d | _d | _d | _g | _d | _d | _d | _d | _	d | _
d| _d| _d| _d S NF)_reader_steps_infiles	_outfiles_demultiplexer_textiowrappers_minimum_length_maximum_lengthmax_nmax_expected_errorsmax_average_error_ratediscard_casavadiscard_trimmeddiscard_untrimmedself r>   0lib/python3.8/site-packages/cutadapt/pipeline.py__init__?   s    zPipeline.__init__force_fasta)filesrB   c                G   sr   |D ]}t |tttfrtqt|dkrH|d d krH|d d }d}nd}ttjf|d| j	|rfdnd |dS )N   r   TFwZfasta)modeZ	qualitiesZ
fileformatinterleaved)

isinstancestrbytesr   AssertionErrorlenr   dnaioopenuses_qualities)r=   rB   rC   frG   r>   r>   r?   _open_writerQ   s     
zPipeline._open_writeroutfilesr,   c                 C   s0  g | _ g | _|| _t|jft|jft|jffD ]8\}}|r.t	
|}| j| | j | || q.| j|j|jtf| j|j|jtffD ]\}}}}|d krq| jr||gn|g}	|r| j|	 nd }
|d d k	r||d nd }t|dkr|d d k	r||d }nd }| j | j|||
d q| jd k	r\t| j }}| j | ||d  | jd k	r| jjs~td n$t | j }}| j | ||d  | j!d k	r| jjstd n$t"| j! }}| j | ||d  | j#rt$  }}| j | ||d  t%| j&t%| j' t%|j(d k	 dkr@t)d|j*d k	sX|j+d k	rt| ,|| _-| j | j- n| j&r| j | t. t. d  n\| j'r| j | /d  n@|j(r|j(g}	| jr|	|j0g7 }	| j|	 }| j | /| | j | 1| t2| j dD ]\}}t3d|| qd S )	Nr   rD   r   )
predicate1
predicate2writerzFIgnoring option --max-ee because input does not contain quality valueszFIgnoring option --max-er because input does not contain quality valueszXdiscard_trimmed, discard_untrimmed and outfiles.untrimmed must not be set simultaneouslyzPipeline step %d: %s)4r/   r3   r1   r(   restr)   infor*   ZwildcardioTextIOWrapperappend_wrap_single_end_stepr4   Z	too_shortZ
too_short2r   r5   Ztoo_longZ	too_long2r   pairedrQ   rL   _make_filterr6   r   r7   r.   delivers_qualitiesloggerZwarningr   r8   r   r9   r   intr:   r;   	untrimmed
ValueErrordemultiplex_outcombinatorial_out_create_demultiplexerr2   r   _make_untrimmed_filter
untrimmed2_final_filter	enumeratedebug)r=   rS   Z
step_classZoutfileZtextiowrapperZlengthsZfile1file2Zpredicate_classrC   rV   f1f2Zuntrimmed_writeristepr>   r>   r?   _set_outputh   s    




zPipeline._set_outputc                 C   s:   | j D ]}|  q| jd k	s"t| jD ]}|  q(d S N)r3   flushr1   rK   r=   rP   r>   r>   r?   rs      s
    


zPipeline.flushc                 C   s   |    |   d S rr   )_close_input_close_outputr<   r>   r>   r?   close   s    zPipeline.closec                 C   s,   | j d k	r| j   | jd k	r(| j  d S rr   )r.   rw   r0   r<   r>   r>   r?   ru      s    


zPipeline._close_inputc                 C   s,   | j D ]}|  q| jd k	r(| j  d S rr   )r3   rw   r1   rt   r>   r>   r?   rv      s    


zPipeline._close_outputc                 C   s   | j d k	st| j jS rr   )r.   rK   r_   r<   r>   r>   r?   rO      s    zPipeline.uses_qualitiesinfilesrS   progressr,   c                 C   s   d S rr   r>   )r=   ry   rS   rz   r>   r>   r?   process_reads   s    zPipeline.process_readsrT   rU   c                 C   s   d S rr   r>   )r=   rT   rU   rV   r>   r>   r?   r^      s    zPipeline._make_filterc                 C   s   d S rr   r>   r=   rV   r>   r>   r?   rg      s    zPipeline._make_untrimmed_filterrS   c                 C   s   d S rr   r>   r=   rS   r>   r>   r?   ri     s    zPipeline._final_filterc                 C   s   d S rr   r>   r   r>   r>   r?   rf     s    zPipeline._create_demultiplexerrp   c                 C   s   d S rr   r>   r=   rp   r>   r>   r?   r\     s    zPipeline._wrap_single_end_step)N) __name__
__module____qualname____doc__Z
n_adaptersr]   r@   r   r   boolrQ   r   rq   rs   rw   ru   rv   propertyrO   r   r   r   r   ra   r{   r   r^   rg   ri   rf   r&   r\   r>   r>   r>   r?   r+   7   sH   h  
r+   c                	       s   e Zd ZdZee d fddZdeee	e
 eeee	e f dddZe	e e	e d	d
dZdd ZedddZeedddZedddZedd Zejdd Zedd Zejdd Z  ZS )SingleEndPipelinez2
    Processing pipeline for single-end reads
    )	modifiersc                    s   t    || _d S rr   )superr@   
_modifiers)r=   r   	__class__r>   r?   r@     s    
zSingleEndPipeline.__init__Nrx   c           
      C   s   || _ | | _| | d}d}| jD ]v}|d7 }|d dkrR|dk	rR|d |t|7 }t|}| jD ]}|||}ql| jD ]}	|	||}|dkr q(qq(|dk	r||d  ||dfS )z#Run the pipeline. Return statisticsr   r   '  N)	r0   rN   r.   rq   updaterL   r   r   r/   )
r=   ry   rS   rz   nZtotal_bpreadrX   modifierfilter_r>   r>   r?   r{     s(    






zSingleEndPipeline.process_readsr|   c                 C   s   |}|d k	st t||S rr   )rK   r!   )r=   rT   rU   rV   _r>   r>   r?   r^   6  s    zSingleEndPipeline._make_filterc                 C   s   t t |S rr   )r!   r   r}   r>   r>   r?   rg   =  s    z(SingleEndPipeline._make_untrimmed_filterr~   c                 C   s2   |j d kr|jd k	st| j|j|jd}t|S NrA   )out2outrK   rQ   rB   r   r=   rS   rV   r>   r>   r?   ri   @  s    zSingleEndPipeline._final_filterrR   c                 C   sd   t  }|jd k	r&| j|j|jd|d < |jd k	s4t|j D ]\}}| j||jd||< q>t|S r   )dictrb   rQ   rB   rd   rK   itemsr#   )r=   rS   writersnamefiler>   r>   r?   rf   E  s    
 
z'SingleEndPipeline._create_demultiplexerr   c                 C   s   |S rr   r>   r   r>   r>   r?   r\   P  s    z'SingleEndPipeline._wrap_single_end_stepc                 C   s   | j S rr   r4   r<   r>   r>   r?   minimum_lengthS  s    z SingleEndPipeline.minimum_lengthc                 C   s"   |d kst |dkst|| _d S Nr   rL   rK   r4   r=   valuer>   r>   r?   r   W  s    c                 C   s   | j S rr   r5   r<   r>   r>   r?   maximum_length\  s    z SingleEndPipeline.maximum_lengthc                 C   s"   |d kst |dkst|| _d S r   rL   rK   r5   r   r>   r>   r?   r   `  s    )N)r   r   r   r   r   r   r@   r   r   r   r   r   ra   r{   r   r^   rg   ri   r#   rf   r&   r\   r   r   setterr   __classcell__r>   r>   r   r?   r     s0     


r   c                	       s  e Zd ZdZdZeeeee	e
 e	e
 f f  ed fddZdd Ze	e
 e	e
 dd	d
dZeddddZd$eee	e eeee	e f dddZd%e	e e	e dddZdd Zdd Zdd ZedddZedd Zejd d Zed!d" Zejd#d" Z  Z S )&PairedEndPipelinez3
    Processing pipeline for paired-end reads.
    T)r   pair_filter_modec                    s0   t    g | _|| _d | _d| _| | d S r-   )r   r@   r   _pair_filter_moder.   override_untrimmed_pair_filter_add_modifiers)r=   r   r   r   r>   r?   r@   m  s    

zPairedEndPipeline.__init__c                 C   s.   |D ]$}t |tr| j|  q| | qd S rr   )rH   tuple_add_two_single_modifiers_add_modifier)r=   r   r   r>   r>   r?   r     s    
z PairedEndPipeline._add_modifiersN)	modifier1	modifier2r,   c                 C   s.   |dkr|dkrt d| jt|| dS )z
        Add two single-end modifiers that modify R1 and R2, respectively.
        One of them can be None, in which case the modifier
        is only applied to the respective other read.
        NzNot both modifiers can be None)rc   r   r[   r   )r=   r   r   r>   r>   r?   r     s    
z+PairedEndPipeline._add_two_single_modifiers)r   r,   c                 C   s   | j | dS )zBAdd a Modifier (without wrapping it in a PairedEndModifierWrapper)N)r   r[   )r=   r   r>   r>   r?   r     s    zPairedEndPipeline._add_modifierrx   c                 C   s   || _ | | _| | d}d}d}| jd k	s4t| jD ]}|d7 }|d dkrd|d k	rd|d |\}}	|t|7 }|t|	7 }t|}
t|	}| jD ]}|||
|f }q| j	D ] }|||
|f }|d kr q:qq:|d k	r||d  |||fS )Nr   r   r   )
r0   rN   r.   rq   rK   r   rL   r   r   r/   )r=   ry   rS   rz   r   Z	total1_bpZ	total2_bpZreadsread1Zread2Zinfo1Zinfo2r   r   r>   r>   r?   r{     s2    





zPairedEndPipeline.process_readsr|   c                 C   s   |d kr| j }t||||dS )Nr   )r   r"   )r=   rT   rU   rV   r   r>   r>   r?   r^     s       zPairedEndPipeline._make_filterc                 C   s    | j t t || jrdnddS )z
        Return a different filter wrapper when adapters were given only for R1
        or only for R2 (then override_untrimmed_pair_filter will be set)
        ZbothNr   )r^   r   r   r}   r>   r>   r?   rg     s    z(PairedEndPipeline._make_untrimmed_filterc                 C   s   | j |j|j|jd}t|S r   )rQ   r   r   rB   r    r   r>   r>   r?   ri     s    zPairedEndPipeline._final_filterc                    s    fdd} j d k	rf jd kr, jd ks0tt } j  D ]\}}|| j| ||< q@t|S t } jd k	r| j j|d <  j D ]\}}|| j	| ||< qt
|S d S )Nc                    s   j | | jdS r   )rQ   rB   )r   rl   rS   r=   r>   r?   open_writer  s    z<PairedEndPipeline._create_demultiplexer.<locals>.open_writer)re   rb   rh   rK   r   r   Zcombinatorial_out2r%   rd   Zdemultiplex_out2r$   )r=   rS   r   r   keyr   r   r   r>   r   r?   rf     s    

z'PairedEndPipeline._create_demultiplexerr   c                 C   s   t |S rr   )r'   r   r>   r>   r?   r\     s    z'PairedEndPipeline._wrap_single_end_stepc                 C   s   | j S rr   r   r<   r>   r>   r?   r     s    z PairedEndPipeline.minimum_lengthc                 C   s"   |d kst |dkst|| _d S NrD   r   r   r>   r>   r?   r     s    c                 C   s   | j S rr   r   r<   r>   r>   r?   r     s    z PairedEndPipeline.maximum_lengthc                 C   s"   |d kst |dkst|| _d S r   r   r   r>   r>   r?   r     s    )N)N)!r   r   r   r   r]   r   r
   r   r   r   r   rI   r@   r   r   r   r   r   r   ra   r{   r   r^   rg   ri   rf   r&   r\   r   r   r   r   r   r>   r>   r   r?   r   f  sR   	 % 


r   )8rY   Zloggingabcr   r   pathlibr   typingr   r   r   r   r	   r
   r   r   rM   rC   r   r   r   Zutilsr   r   r   r   r   r   Z
predicatesr   r   r   r   r   r   r   r   r   Zstepsr   r    r!   r"   r#   r$   r%   r&   r'   r(   r)   r*   Z	getLoggerr`   r+   r   r   r>   r>   r>   r?   <module>   s   (,8 [U