3
d6                 @   sh  d Z ddlZddlZddlZddlmZmZmZ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 ddlmZmZmZ G dd	 d	eZG d
d deeZG dd deZdd ZG dd deZG dd deZG dd deZG dd deeZ G dd deZ!G dd deZ"G dd deZ#G dd deZ$G d d! d!eZ%G d"d# d#eZ&G d$d% d%eZ'dS )&zf
    # changing to temporary directories
    >>> tmp = getfixture('tmpdir')
    >>> old = tmp.chdir()
    N   )traitsTraitedSpecDynamicTraitedSpecFile	Undefined	isdefinedOutputMultiPathInputMultiPathBaseInterfaceBaseInterfaceInputSpecStrSimpleInterface)IOBase
add_traits   )ensure_listcopyfilesplit_filenamec                   s:   e Zd ZdZeZeZd
 fdd	Zdd Zdd	 Z	  Z
S )IdentityInterfacea  Basic interface class generates identity mappings

    Examples
    --------

    >>> from nipype.interfaces.utility import IdentityInterface
    >>> ii = IdentityInterface(fields=['a', 'b'], mandatory_inputs=False)
    >>> ii.inputs.a
    <undefined>

    >>> ii.inputs.a = 'foo'
    >>> out = ii._outputs()
    >>> out.a
    <undefined>

    >>> out = ii.run()
    >>> out.outputs.a
    'foo'

    >>> ii2 = IdentityInterface(fields=['a', 'b'], mandatory_inputs=True)
    >>> ii2.inputs.a = 'foo'
    >>> out = ii2.run() # doctest: +SKIP
    ValueError: IdentityInterface requires a value for input 'b' because it was listed in 'fields' Interface IdentityInterface failed to run.
    NTc                st   t t| jf | |d ks | r(tdx |D ]}||kr.td| q.W || _|| _t| j| | jjf | d S )Nz2Identity Interface fields must be a non-empty listz1Identity Interface input is not in the fields: %s)	superr   __init__
ValueError_fields_mandatory_inputsr   inputs	trait_set)selffieldsZmandatory_inputsr   Zin_field)	__class__ @/tmp/pip-build-7vycvbft/nipype/nipype/interfaces/utility/base.pyr   <   s    
zIdentityInterface.__init__c             C   s   t || jS )N)r   r   )r   baser    r    r!   _add_output_traitsN   s    z$IdentityInterface._add_output_traitsc             C   s   | j rH| jrHx:| j D ]0}t| j|}t|sd| jj|f }t|qW | j j	 }x*| j D ] }t| j|}t|r\|||< q\W |S )Nz%s requires a value for input '%s' because it was listed in 'fields'.                     You can turn off mandatory inputs checking by passing mandatory_inputs = False to the constructor.)
r   r   getattrr   r   r   __name__r   _outputsget)r   keyvaluemsgoutputsvalr    r    r!   _list_outputsQ   s    zIdentityInterface._list_outputs)NT)r%   
__module____qualname____doc__r   
input_specoutput_specr   r#   r-   __classcell__r    r    )r   r!   r      s   r   c               @   s>   e Zd ZejdddddZejddddZejddddZd	S )
MergeInputSpecvstackZhstackTzRdirection in which to merge, hstack requires same number of elements in each input)
usedefaultdescFz5append to outlist instead of extending in vstack modez%ravel inputs when no_flatten is FalseN)	r%   r.   r/   r   EnumaxisBool
no_flattenravel_inputsr    r    r    r!   r4   f   s   r4   c               @   s   e Zd ZejddZdS )MergeOutputSpeczMerged output)r7   N)r%   r.   r/   r   Listoutr    r    r    r!   r=   w   s   r=   c             C   sL   t | ts| S g }x4| D ],}t|}t |tr:|j| q|j| qW |S )N)
isinstancelist_ravelextendappend)Zin_valZ	flat_listr,   Zraveled_valr    r    r!   rB   {   s    


rB   c                   s2   e Zd ZdZeZeZd fdd	Zdd Z	  Z
S )MergeaN  Basic interface class to merge inputs into a single list

    ``Merge(1)`` will merge a list of lists

    Examples
    --------

    >>> from nipype.interfaces.utility import Merge
    >>> mi = Merge(3)
    >>> mi.inputs.in1 = 1
    >>> mi.inputs.in2 = [2, 5]
    >>> mi.inputs.in3 = 3
    >>> out = mi.run()
    >>> out.outputs.out
    [1, 2, 5, 3]

    >>> merge = Merge(1)
    >>> merge.inputs.in1 = [1, [2, 5], 3]
    >>> out = merge.run()
    >>> out.outputs.out
    [1, [2, 5], 3]

    >>> merge = Merge(1)
    >>> merge.inputs.in1 = [1, [2, 5], 3]
    >>> merge.inputs.ravel_inputs = True
    >>> out = merge.run()
    >>> out.outputs.out
    [1, 2, 5, 3]

    >>> merge = Merge(1)
    >>> merge.inputs.in1 = [1, [2, 5], 3]
    >>> merge.inputs.no_flatten = True
    >>> out = merge.run()
    >>> out.outputs.out
    [[1, [2, 5], 3]]
    r   c                sH   t t| jf | || _|dkr4dd t|D }ng }t| j| d S )N   c             S   s   g | ]}d |d  qS )zin%drF   r    ).0ir    r    r!   
<listcomp>   s    z"Merge.__init__.<locals>.<listcomp>)r   rE   r   
_numinputsranger   r   )r   Z	numinputsr   Zinput_names)r   r    r!   r      s    zMerge.__init__c                s   j  j }g }jdk r|S fdd  fddtjD }jjdkrxt|D ]>}t|trjj r|j	jj
rt|n| qT|j| qTW n,dd |D fddttd	 D }||d
< |S )NrF   c                s   t  jd| d  S )Nzin%drF   )r$   r   )idx)r   r    r!   <lambda>   s    z%Merge._list_outputs.<locals>.<lambda>c                s    g | ]}t  |r |qS r    )r   )rG   rL   )getvalr    r!   rI      s    z'Merge._list_outputs.<locals>.<listcomp>r5   c             S   s   g | ]}t |qS r    )r   )rG   r,   r    r    r!   rI      s    c                s   g | ]  fd dD qS )c                s   g | ]}|  qS r    r    )rG   r,   )rH   r    r!   rI      s    z2Merge._list_outputs.<locals>.<listcomp>.<listcomp>r    )rG   )lists)rH   r!   rI      s    r   r?   )r&   r'   rJ   rK   r   r9   r@   rA   r;   rC   r<   rB   rD   len)r   r+   r?   valuesr)   r    )rN   rO   r   r!   r-      s    

zMerge._list_outputs)r   )r%   r.   r/   r0   r4   r1   r=   r2   r   r-   r3   r    r    )r   r!   rE      s
   $	rE   c               @   sL   e Zd ZeddddZejddZedddZ	eddZ
ejd	dd
dZdS )RenameInputSpecTzfile to rename)exists	mandatoryr7   z?Keep in_file extension, replace non-extension component of name)r7   z,Python formatting string for output template)rT   r7   z7Python regexp parse string to define replacement inputsFz&Use full path as input to regex parser)r6   r7   N)r%   r.   r/   r   in_filer   r:   keep_extr   format_stringparse_stringuse_fullpathr    r    r    r!   rR      s   
rR   c               @   s   e Zd ZedddZdS )RenameOutputSpecTz'softlink to original file with new name)rS   r7   N)r%   r.   r/   r   out_filer    r    r    r!   rZ      s   rZ   c                   s:   e Zd ZdZeZeZd	 fdd	Zdd Z	dd Z
  ZS )
Renameay  Change the name of a file based on a mapped format string.

    To use additional inputs that will be defined at run-time, the class
    constructor must be called with the format template, and the fields
    identified will become inputs to the interface.

    Additionally, you may set the parse_string input, which will be run
    over the input filename with a regular expressions search, and will
    fill in additional input fields from matched groups. Fields set with
    inputs have precedence over fields filled in with the regexp match.

    Examples
    --------

    >>> from nipype.interfaces.utility import Rename
    >>> rename1 = Rename()
    >>> rename1.inputs.in_file = os.path.join(datadir, "zstat1.nii.gz") # datadir is a directory with exemplary files, defined in conftest.py
    >>> rename1.inputs.format_string = "Faces-Scenes.nii.gz"
    >>> res = rename1.run()          # doctest: +SKIP
    >>> res.outputs.out_file         # doctest: +SKIP
    'Faces-Scenes.nii.gz"            # doctest: +SKIP

    >>> rename2 = Rename(format_string="%(subject_id)s_func_run%(run)02d")
    >>> rename2.inputs.in_file = os.path.join(datadir, "functional.nii")
    >>> rename2.inputs.keep_ext = True
    >>> rename2.inputs.subject_id = "subj_201"
    >>> rename2.inputs.run = 2
    >>> res = rename2.run()          # doctest: +SKIP
    >>> res.outputs.out_file         # doctest: +SKIP
    'subj_201_func_run02.nii'        # doctest: +SKIP

    >>> rename3 = Rename(format_string="%(subject_id)s_%(seq)s_run%(run)02d.nii")
    >>> rename3.inputs.in_file = os.path.join(datadir, "func_epi_1_1.nii")
    >>> rename3.inputs.parse_string = r"func_(?P<seq>\w*)_.*"
    >>> rename3.inputs.subject_id = "subj_201"
    >>> rename3.inputs.run = 2
    >>> res = rename3.run()          # doctest: +SKIP
    >>> res.outputs.out_file         # doctest: +SKIP
    'subj_201_epi_run02.nii'         # doctest: +SKIP

    Nc                sJ   t t| jf | |d k	r@|| j_tjd|| _t| j| j ng | _d S )Nz
%\((.+?)\))	r   r\   r   r   rW   refindall
fmt_fieldsr   )r   rW   r   )r   r    r!   r     s    zRename.__init__c             C   s   t  }t| jjrnt| jjr<| jjr<tj| jj| jj}n tj| jjtj	j
| jjd }|rn|j|j  x2| jD ](}t| j|}t|rvt| j|||< qvW | jjrdj| jjt| jjd g}n| jj}|| S )NrF    r   )dictr   r   rX   rY   r]   searchrU   ospathsplitupdate	groupdictr_   r$   rV   joinrW   r   )r   Zfmt_dictmfieldr,   Z
fmt_stringr    r    r!   _rename  s"    zRename._renamec             C   s6   d|_ tjj|j| j }t| jj|}|| j	d< |S )Nr   r[   )

returncoderc   rd   rh   cwdrk   r   r   rU   Z_results)r   runtimer[   _r    r    r!   _run_interface5  s
    
zRename._run_interface)N)r%   r.   r/   r0   rR   r1   rZ   r2   r   rk   rp   r3   r    r    )r   r!   r\      s   )	r\   c               @   s@   e Zd ZejejdddZejejdddZej	ddddZ
dS )	SplitInputSpecTzlist of values to split)rT   r7   z@Number of outputs in each split - should add to number of inputsFz+unfold one-element splits removing the list)r6   r7   N)r%   r.   r/   r   r>   AnyinlistIntsplitsr:   squeezer    r    r    r!   rq   =  s   rq   c               @   s(   e Zd ZdZeZeZdd Zdd Z	dS )Splita!  Basic interface class to split lists into multiple outputs

    Examples
    --------

    >>> from nipype.interfaces.utility import Split
    >>> sp = Split()
    >>> _ = sp.inputs.trait_set(inlist=[1, 2, 3], splits=[2, 1])
    >>> out = sp.run()
    >>> out.outputs.out1
    [1, 2]

    c             C   sX   i }x:t t| jjD ]&}d|d  }|j|tj t||< qW |jf ddi| |S )Nzout%drF   Ztrait_change_notifyF)	rK   rP   r   ru   Z	add_traitr   rr   r   r   )r   r"   Zundefined_traitsrH   r(   r    r    r!   r#   [  s    zSplit._add_output_traitsc             C   s   | j  j }t| jjrt| jjt| jjkr8tddg}|j	| jj t
j|}xntt|d D ]Z}t
j| jjtd|| ||d   j }| jjrt|dkr|d }||d|d  < qhW |S )Nz%sum of splits != num of list elementsr   rF   )dtypezout%d)r&   r'   r   r   ru   sumrP   rs   RuntimeErrorrC   npZcumsumrK   arrayobjecttolistrv   )r   r+   ru   rH   r,   r    r    r!   r-   d  s    
zSplit._list_outputsN)
r%   r.   r/   r0   rq   r1   r   r2   r#   r-   r    r    r    r!   rw   I  s
   	rw   c               @   s,   e Zd ZeejdddZeejdddZdS )SelectInputSpecTzlist of values to choose from)rT   r7   z#0-based indices of values to chooseN)	r%   r.   r/   r
   r   rr   rs   rt   indexr    r    r    r!   r   v  s   r   c               @   s   e Zd ZeejddZdS )SelectOutputSpeczlist of selected values)r7   N)r%   r.   r/   r	   r   rr   r?   r    r    r    r!   r     s   r   c               @   s    e Zd ZdZeZeZdd ZdS )Selecta  Basic interface class to select specific elements from a list

    Examples
    --------

    >>> from nipype.interfaces.utility import Select
    >>> sl = Select()
    >>> _ = sl.inputs.trait_set(inlist=[1, 2, 3, 4, 5], index=[3])
    >>> out = sl.run()
    >>> out.outputs.out
    4

    >>> _ = sl.inputs.trait_set(inlist=[1, 2, 3, 4, 5], index=[3, 4])
    >>> out = sl.run()
    >>> out.outputs.out
    [4, 5]

    c             C   s<   | j  j }tj| jjtdtj| jj j }||d< |S )N)rx   r?   )	r&   r'   r{   r|   r   rs   r}   r   r~   )r   r+   r?   r    r    r!   r-     s
    zSelect._list_outputsN)	r%   r.   r/   r0   r   r1   r   r2   r-   r    r    r    r!   r     s   r   c               @   s$   e Zd ZedddZedddZdS )AssertEqualInputSpecT)rS   rT   N)r%   r.   r/   r   volume1volume2r    r    r    r!   r     s   r   c               @   s   e Zd ZeZdd ZdS )AssertEqualc             C   sH   dd l }tj|j| jj}tj|j| jj}tj||sDtd|S )Nr   z"Input images are not exactly equal)	Znibabelr{   Z
asanyarrayloadr   r   r   Zarray_equalrz   )r   rn   nbZdata1Zdata2r    r    r!   rp     s    zAssertEqual._run_interfaceN)r%   r.   r/   r   r1   rp   r    r    r    r!   r     s   r   )(r0   rc   r]   numpyr{   r"   r   r   r   r   r   r   r	   r
   r   r   r   r   ior   r   Zutils.filemanipr   r   r   r   r4   r=   rB   rE   rR   rZ   r\   rq   rw   r   r   r   r   r   r    r    r    r!   <module>   s*   8GKV-	 