3
d7                 @   s  d Z ddlZddlmZ ddlZddlZddlm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 dZy ddlZddlZddlmZ W n ek
r   d	ZY nX 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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%G d"d# d#eZ&G d$d% d%eZ'G d&d' d'eZ(d2d(d)Z)G d*d+ d+eZ*G d,d- d-eZ+G d.d/ d/eZ,G d0d1 d1eZ-dS )3zSdcmstack allows series of DICOM images to be stacked into multi-dimensional arrays.    N)path)glob   )	TraitedSpecDynamicTraitedSpecInputMultiPathFile	DirectorytraitsBaseInterface	isdefined	UndefinedT)NiftiWrapperFc             C   sF   g }x6| D ].}|t jt j d kr.|jd q
|j| q
W dj|S )Nz-_._ )stringlettersdigitsappendjoin)Z	path_compresultchar r   </tmp/pip-build-7vycvbft/nipype/nipype/interfaces/dcmstack.pysanitize_path_comp"   s    
r   c               @   s2   e Zd ZejddZejddddZeddZdS )	NiftiGeneratorBaseInputSpeczMString which can be formatted with meta data to create the output filename(s))descz.nii.gzTzDetermines output file type)
usedefaultr   z1output path, current working directory if not setN)	__name__
__module____qualname__r
   Str
out_formatout_extr	   out_pathr   r   r   r   r   ,   s   r   c               @   s   e Zd ZdZdddZdS )NiftiGeneratorBasez\Base class for interfaces that produce Nifti files, potentially with
    embedded meta data.Nc             C   s  | j jr| j j}nhg }|dk	r,|jd|  d|kr>|jd d|krR|jd nd|krf|jd n
|jd	 d
j|}|| | j j }t|}tj }t| j j	rt
j| j j	}ytj| W n> tk
r } z |jtjkrt
j|rn W Y dd}~X nX t
j||S )z0Return the output path for the gernerated Nifti.Nz%03dZSeriesNumberz%(SeriesNumber)03dZProtocolNamez%(ProtocolName)sZSeriesDescriptionz%(SeriesDescription)ssequence-)inputsr"   r   r   r#   r   osgetcwdr   r$   opabspathmakedirsOSErrorerrnoEEXISTisdir)selfmetaidxZout_fmtZout_fnr$   excr   r   r   _get_out_path9   s2    



z NiftiGeneratorBase._get_out_path)N)r   r   r    __doc__r6   r   r   r   r   r%   5   s   r%   c               @   sf   e Zd Zejeeddeddej ddZ	ej
ddZejddZejddZej
dddd	Zd
S )DcmStackInputSpecT)exists)	mandatoryz!Embed DICOM meta data into result)r   z>Meta data to exclude, suplementing any default exclude filtersz4Meta data to include, overriding any exclude filtersz'Force reading files without DICM marker)r   r   N)r   r   r    r
   Eitherr   r   r	   r!   dicom_filesZBool
embed_metaListexclude_regexesinclude_regexes
force_readr   r   r   r   r8   _   s   r8   c               @   s   e Zd ZeddZdS )DcmStackOutputSpecT)r9   N)r   r   r    r   out_filer   r   r   r   rB   r   s   rB   c               @   s0   e Zd ZdZeZeZdd Zdd Z	dd Z
dS )	DcmStackaz  Create one Nifti file from a set of DICOM files. Can optionally embed
    meta data.

    Example
    -------

    >>> from nipype.interfaces.dcmstack import DcmStack
    >>> stacker = DcmStack()
    >>> stacker.inputs.dicom_files = 'path/to/series/'
    >>> stacker.run() # doctest: +SKIP
    >>> result.outputs.out_file # doctest: +SKIP
    '/path/to/cwd/sequence.nii.gz'
    c             C   s4   t |ttfr0tj|r(ttj|dS t|S |S )Nz*.dcm)
isinstancestrbytesr+   r1   r   r   )r2   Ztrait_inputr   r   r   _get_filelist   s
    
zDcmStack._get_filelistc             C   s   | j | jj}tj}t| jjr,|| jj7 }tj}t| jjrJ|| jj7 }tj	||}tj
|d}x6|D ].}tj|dkshtj|| jjd}|j| qhW |jdd}	t|	}
| j|
jjd| _| jjs|
j  tj|	| j |S )	N)meta_filterZgif)forceT)r=   globalconst)rK   rL   )rH   r(   r<   dcmstackZdefault_key_incl_resr   r@   Zdefault_key_excl_resr?   Zmake_key_regex_filterZ
DicomStackimghdrwhatdicom	read_filerA   Zadd_dcmto_niftir   r6   meta_extget_class_dictr$   r=   remove_extensionnbsave)r2   runtime	src_pathsr@   r?   rI   stackZsrc_pathZsrc_dcmniinwr   r   r   _run_interface   s*    
zDcmStack._run_interfacec             C   s   | j  j }| j|d< |S )NrC   )_outputsgetr$   )r2   outputsr   r   r   _list_outputs   s    
zDcmStack._list_outputsN)r   r   r    r7   r8   
input_specrB   output_specrH   r]   ra   r   r   r   r   rD   v   s   	rD   c               @   s   e Zd ZejddZdS )GroupAndStackOutputSpeczList of output nifti files)r   N)r   r   r    r
   r>   out_listr   r   r   r   rd      s   rd   c               @   s(   e Zd ZdZeZeZdd Zdd Z	dS )GroupAndStackzCCreate (potentially) multiple Nifti files for a set of DICOM files.c       	      C   s   | j | jj}tj|}g | _xht|j D ]X\}}t|j	dd}|j
jd}| j|}| jjsj|j  tj|j| | jj| q,W |S )NT)r=   rK   rL   )rK   rL   )rH   r(   r<   rM   Zparse_and_stackre   listitemsr   rR   rS   rT   r6   r=   rU   rV   rW   nii_imgr   )	r2   rX   rY   ZstackskeyrZ   r\   
const_metar$   r   r   r   r]      s    

zGroupAndStack._run_interfacec             C   s   | j  j }| j|d< |S )Nre   )r^   r_   re   )r2   r`   r   r   r   ra      s    
zGroupAndStack._list_outputsN)
r   r   r    r7   r8   rb   rd   rc   r]   ra   r   r   r   r   rf      s
   rf   c               @   s4   e Zd ZeddddZejej ej dddZ	dS )LookupMetaInputSpecTzThe input Nifti file)r:   r9   r   zList of meta data keys to lookup, or a dict where keys specify the meta data keys to lookup and the values specify the output names)r:   r   N)
r   r   r    r   in_filer
   r;   r>   Dict	meta_keysr   r   r   r   rl      s   rl   c                   s@   e Zd ZdZeZeZdd Z fddZ	dd Z
dd	 Z  ZS )

LookupMetaa  Lookup meta data values from a Nifti with embedded meta data.

    Example
    -------

    >>> from nipype.interfaces import dcmstack
    >>> lookup = dcmstack.LookupMeta()
    >>> lookup.inputs.in_file = 'functional.nii'
    >>> lookup.inputs.meta_keys = {'RepetitionTime' : 'TR',                                    'EchoTime' : 'TE'}
    >>> result = lookup.run() # doctest: +SKIP
    >>> result.outputs.TR # doctest: +SKIP
    9500.0
    >>> result.outputs.TE # doctest: +SKIP
    95.0
    c             C   s@   t | jjtr2i | _x&| jjD ]}|| j|< qW n
| jj| _d S )N)rE   r(   ro   rg   
_meta_keys)r2   rj   r   r   r   _make_name_map   s
    zLookupMeta._make_name_mapc                s   | j   tt| j }i }x,t| jj D ]}|j|tj	 t
||< q*W |jf ddi| x t| jj D ]}t||}qlW |S )NZtrait_change_notifyF)rr   superrp   r^   rg   rq   valuesZ	add_traitr
   ZAnyr   Z	trait_setgetattr)r2   r`   Zundefined_traitsout_namer   )	__class__r   r   r^      s    zLookupMeta._outputsc             C   sN   | j   tj| jj}i | _x,t| jj D ]\}}|j	j
|| j|< q,W |S )N)rr   r   from_filenamer(   rm   r   rg   rq   rh   rS   Z
get_values)r2   rX   r\   Zmeta_keyrv   r   r   r   r]     s    zLookupMeta._run_interfacec             C   s   | j  j }|j| j |S )N)r^   r_   updater   )r2   r`   r   r   r   ra     s    zLookupMeta._list_outputs)r   r   r    r7   rl   rb   r   rc   rr   r^   r]   ra   __classcell__r   r   )rw   r   rp      s   
rp   c               @   s<   e Zd ZedddZedddZejddZejddZ	dS )CopyMetaInputSpecT)r:   r9   z[List of specific meta data classifications to include. If not specified include everything.)r   z,List of meta data classifications to excludeN)
r   r   r    r   src_file	dest_filer
   r>   include_classesexclude_classesr   r   r   r   r{     s   r{   c               @   s   e Zd ZeddZdS )CopyMetaOutputSpecT)r9   N)r   r   r    r   r}   r   r   r   r   r   %  s   r   c               @   s(   e Zd ZdZeZeZdd Zdd Z	dS )CopyMetazoCopy meta data from one Nifti file to another. Useful for preserving
    meta data after some processing steps.c       
         s   t j jj}t|dd}t j jj}t|dd}|jj } jjrX fdd|D } jj	rr fdd|D }x.|D ]&}|jj
|}|jj
|}	|	j| qxW |jj|j_|jj|j_tjtj tj jj _|j j |S )NT)
make_emptyc                s   g | ]}| j jkr|qS r   )r(   r~   ).0cls)r2   r   r   
<listcomp>7  s    z+CopyMeta._run_interface.<locals>.<listcomp>c                s   g | ]}| j jkr|qS r   )r(   r   )r   r   )r2   r   r   r   9  s    )rV   loadr(   r|   r   r}   rS   Zget_valid_classesr~   r   rT   ry   Z	slice_dimshaper+   r   r)   r*   basenamer$   to_filename)
r2   rX   src_niisrcZdest_niidestclassesr   Zsrc_dictZ	dest_dictr   )r2   r   r]   0  s$    

zCopyMeta._run_interfacec             C   s   | j  j }| j|d< |S )Nr}   )r^   r_   r$   )r2   r`   r   r   r   ra   I  s    
zCopyMeta._list_outputsN)
r   r   r    r7   r{   rb   r   rc   r]   ra   r   r   r   r   r   )  s
   r   c               @   s>   e Zd ZejdddZejej ej ddZej	ddZ
dS )MergeNiftiInputSpecTzList of Nifti files to merge)r:   r   z,One or more meta data keys to sort files by.)r   z`Dimension to merge along. If not specified, the last singular or non-existant dimension is used.N)r   r   r    r
   r>   in_filesr;   r!   
sort_orderInt	merge_dimr   r   r   r   r   O  s   r   c               @   s   e Zd ZedddZdS )MergeNiftiOutputSpecTzMerged Nifti file)r9   r   N)r   r   r    r   rC   r   r   r   r   r   ]  s   r   c                s    fdd}|S )Nc                s    fddD }|S )Nc                s   g | ]}j | qS r   )Zget_meta)r   rj   )indexr   r   r   r   c  s    z3make_key_func.<locals>.key_func.<locals>.<listcomp>r   )r   r   )r   ro   )r   r   key_funcb  s    zmake_key_func.<locals>.key_funcr   )ro   r   r   r   )r   ro   r   make_key_funca  s    r   c               @   s(   e Zd ZdZeZeZdd Zdd Z	dS )
MergeNiftizVMerge multiple Nifti files into one. Merges together meta data
    extensions as well.c             C   s   dd | j jD }dd |D }| j jrT| j j}t|ttfrD|g}|jt|d | j jt	j
krhd }n| j j}tj||}|jjd}| j|| _tj|j| j |S )Nc             S   s   g | ]}t j|qS r   )rV   r   )r   fnr   r   r   r   q  s    z-MergeNifti._run_interface.<locals>.<listcomp>c             S   s   g | ]}t |d dqS )T)r   )r   )r   r[   r   r   r   r   r  s    )rj   rK   rL   )rK   rL   )r(   r   r   rE   rF   rG   sortr   r   r
   r   r   Zfrom_sequencerS   rT   r6   r$   rV   rW   ri   )r2   rX   ZniisZnwsr   r   Zmergedrk   r   r   r   r]   p  s    zMergeNifti._run_interfacec             C   s   | j  j }| j|d< |S )NrC   )r^   r_   r$   )r2   r`   r   r   r   ra     s    
zMergeNifti._list_outputsN)
r   r   r    r7   r   rb   r   rc   r]   ra   r   r   r   r   r   i  s
   r   c               @   s&   e Zd ZeddddZejddZdS )SplitNiftiInputSpecTzNifti file to split)r9   r:   r   zGDimension to split along. If not specified, the last dimension is used.)r   N)r   r   r    r   rm   r
   r   	split_dimr   r   r   r   r     s   r   c               @   s    e Zd ZejeddddZdS )SplitNiftiOutputSpecT)r9   zSplit Nifti files)r   N)r   r   r    r
   r>   r   re   r   r   r   r   r     s   r   c               @   s(   e Zd ZdZeZeZdd Zdd Z	dS )
SplitNiftiz
    Split one Nifti file into many along the specified dimension. Each
    result has an updated meta data extension as well.
    c       	      C   s   g | _ tj| jj}t|dd}d }| jjtjkr8d }n| jj}xNt	|j
|D ]<\}}|jjd}| j||d}tj|j| | j j| qPW |S )NT)r   rK   rL   )r4   )rK   rL   )re   rV   r   r(   rm   r   r   r
   r   	enumeratesplitrS   rT   r6   rW   ri   r   )	r2   rX   r[   r\   r   Z	split_idxZsplit_nwrk   r$   r   r   r   r]     s    zSplitNifti._run_interfacec             C   s   | j  j }| j|d< |S )Nre   )r^   r_   re   )r2   r`   r   r   r   ra     s    
zSplitNifti._list_outputsN)
r   r   r    r7   r   rb   r   rc   r]   ra   r   r   r   r   r     s
   r   )N).r7   r)   r   r+   r   r/   r   ZnibabelrV   rN   baser   r   r   r   r	   r
   r   r   r   Zhave_dcmstackrP   rM   Zdcmstack.dcmmetar   ImportErrorr   r   r%   r8   rB   rD   rd   rf   rl   rp   r{   r   r   r   r   r   r   r   r   r   r   r   r   r   <module>   sF   ,

	*9:&
