3
dG5                 @   sr  d Z ddljZddlZddlZddl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 ejd
Zere	e e	dkrddlmZ eeZx,eD ]$\ZZejddZeeee  e< qW [n
ej!d 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*dS )"z6
Interfaces to the reconstruction algorithms in dipy

    N)LooseVersion   )logging   )TraitedSpecFiletraits	isdefined   )DipyDiffusionInterfaceDipyBaseInterfaceInputSpec	HAVE_DIPYdipy_versiondipy_to_nipype_interfaceget_dipy_workflowsznipype.interfacez0.15)reconstZFlow zSWe advise you to upgrade DIPY version. This upgrade will open access to more modelsc               @   s$   e Zd ZedddZedddZdS )RESTOREInputSpecTz#input mask in which compute tensors)existsdescz*input mask in which compute noise varianceN)__name__
__module____qualname__r   in_mask
noise_mask r   r   G/tmp/pip-build-7vycvbft/nipype/nipype/interfaces/dipy/reconstruction.pyr   *   s   r   c               @   sR   e Zd ZeddZeddZeddZeddZeddZeddZ	eddZ
d	S )
RESTOREOutputSpeczBoutput fractional anisotropy (FA) map computed from the fitted DTI)r   z=output mean diffusivity (MD) map computed from the fitted DTIz?output radial diffusivity (RD) map computed from the fitted DTIz1output mode (MO) map computed from the fitted DTIz8output the tensor trace map computed from the fitted DTIz(output the eigenvalues of the fitted DTIz)output the eigenvectors of the fitted DTIN)r   r   r   r   faZmdrdmodetraceevalsZevecsr   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 )RESTOREa  
    Uses RESTORE [Chang2005]_ to perform DTI fitting with outlier detection.
    The interface uses :py:mod:`dipy`, as explained in `dipy's documentation`_.

    .. [Chang2005] Chang, LC, Jones, DK and Pierpaoli, C. RESTORE: robust     estimation of tensors by outlier rejection. MRM, 53:1088-95, (2005).

    .. _dipy's documentation:     http://nipy.org/dipy/examples_built/restore_dti.html


    Example
    -------

    >>> from nipype.interfaces import dipy as ndp
    >>> dti = ndp.RESTORE()
    >>> dti.inputs.in_file = '4d_dwi.nii'
    >>> dti.inputs.in_bval = 'bvals'
    >>> dti.inputs.in_bvec = 'bvecs'
    >>> res = dti.run() # doctest: +SKIP


    c             C   s6  ddl m} ddlm} dd l}tj| jj}|j	j
 }|j}|j }| j }	t| jjrztjtj| jjjjtj}
ntj|jd d tjd}
d}t| jjrtj| jjjtjdjd}d||dk< d||d	k < |jtj}d
}nPtj||
dkdf dkr&tjd |
jdjtj}nd|
 jdjtj}tj|	j}|jd|jd }|r|dkr|jtj |	jdd|dkdf }|}n`tj |	j }|d j! }t"|dkrdnt"|}tj#j$||d
d}|j|dd|dkdf }tj%|j&d}y6d	tj'd|d  ||d ||d d    }W n   d}Y nX |d|  }|dkrttj(d ||	}ntjd| ||	d|d}y|j)||
}W n* t*k
r   ||	}|j)||
}Y nX |j+tj d|d< xR| j, j- D ]B}t.||}|j/tj| tj0|jtj||j1| j2| qW |S ) Nr   )gamma)TensorModelr   )dtypeTr
   g      ?g      ?FzInput data are masked.)axis.   )sizereplaceg       @g        zNoise std is 0.0, looks like data was masked and noise cannot be estimated correctly. Using default tensor model instead of RESTORE.z'Performing RESTORE with noise std=%.4f.r#   )Z
fit_methodsigma   Z	data_typer-   r-   r-   r-   r-   r-   r-   )3Zscipy.specialr$   dipy.reconst.dtir%   gcnbloadinputsin_fileheadercopyaffine	get_fdata_get_gradient_tabler	   r   np
asanyarraydataobjastypeuint8onesshaper   float32ZreshapeallIFLOGGERinfosumb0s_maskZtakewheretolistlenrandomchoiceZmedianZstdsqrtwarningfit	TypeErrorZset_data_dtype_outputsgetgetattrZset_data_shapeNifti1Imageto_filename_gen_filename)selfruntimer$   r%   r/   imghdrr6   datagtabmskZtry_b0Z	noise_mskZnb0ZdsampleZ
noise_datanZnodiffZ	nodiffidxZidxsZmean_stdZbiasr+   ZdtiZfit_restorekZscalarr   r   r   _run_interfaceW   sx    
 
$


zRESTORE._run_interfacec             C   s4   | j  j }x"t|j D ]}| j|||< qW |S )N)rO   rP   listkeysrT   )rU   outputsr]   r   r   r   _list_outputs   s    zRESTORE._list_outputsN)
r   r   r   __doc__r   
input_specr   output_specr^   rb   r   r   r   r   r#   ;   s
   Wr#   c               @   s   e Zd ZeddddZedddZejddddZej	d	dd
dZ
ejdgddZejdgddZeddddZeddddZdS )EstimateResponseSHInputSpecTzinput eigenvalues file)r   	mandatoryr   z)input mask in which we find single fibers)r   r   gffffff?zFA threshold)
usedefaultr   
   z&ROI radius to be used in auto_response	recursivez)use the auto_response estimator from dipy)xorr   autoz.use the recursive response estimator from dipyzresponse.txtzthe output response filezwm_mask.nii.gzzcomputed wm maskN)r   r   r   r   in_evalsr   r   ZFloat	fa_threshInt
roi_radiusBoolrl   rj   responseout_maskr   r   r   r   rf      s   rf   c               @   s$   e Zd ZedddZedddZdS )EstimateResponseSHOutputSpecTzthe response file)r   r   zoutput wm maskN)r   r   r   r   rr   rs   r   r   r   r   rt      s   rt   c               @   s(   e Zd ZdZeZeZdd Zdd Z	dS )EstimateResponseSHa  
    Uses dipy to compute the single fiber response to be used in spherical
    deconvolution methods, in a similar way to MRTrix's command
    ``estimate_response``.


    Example
    -------

    >>> from nipype.interfaces import dipy as ndp
    >>> dti = ndp.EstimateResponseSH()
    >>> dti.inputs.in_file = '4d_dwi.nii'
    >>> dti.inputs.in_bval = 'bvals'
    >>> dti.inputs.in_bvec = 'bvecs'
    >>> dti.inputs.in_evals = 'dwi_evals.nii'
    >>> res = dti.run() # doctest: +SKIP


    c             C   s  ddl m} ddlm}m} ddlm}m} tj	| j
j}tj|d }|j}	t| j
jrtjtj	| j
jj}
d|
|
dk< d|
|
dk < ntj|j}
|jtjd}| j }tjtj	| j
jj}tj|||
 }tj|| j
jk}|| d d tj|jd f }tj|}| j
jrJ|||| j
j | j
jd\}}|d j! |g }n| j
j"rtj|||
 }tj#|dktj$|d	k|d
k}tjtj	| j
jj}||||dddddddd
}t%|d |d  }nN|| }tj&tj|dd}tj'|d |d |d |g}t%|d |d  }|dkr4t(j)d| nR|dk sPtj*tj+|rntj'ddd|g}t(j)d nt(j,dt-|d d  tj.t/j0| j
j1| tj2|}d||< tj3|j4tj5|	d j6t/j0| j
j7 |S )Nr   )GradientTable)fractional_anisotropymean_diffusivity)recursive_responseauto_responser
   )r&   )rp   Zfa_thrg?g333333?g/nR?   g{Gz?g{Gz?gJ4a?gMbP?T)masksh_orderZpeak_thrZinit_faZ
init_traceiterZconvergenceparallel)r'   r   g      ?z6Estimated response is not prolate enough. Ratio=%0.3f.gh㈵>gH}]?g9̗7?z4Estimated response is not valid, using a default onezEstimated response: %sr   r-   r   )8Zdipy.core.gradientsrv   r.   rw   rx   dipy.reconst.csdeconvry   rz   r0   r1   r2   r3   four_to_threer6   r	   r   r9   r:   r;   r>   r?   r7   r@   r8   Z
nan_to_numrm   rF   rn   ZnonzerorE   Zmeanrl   rp   rG   rj   
logical_orlogical_andabssortarrayrB   rL   anyisnanrC   strZsavetxtopabspathrr   Z
zeros_likerR   r<   r=   rS   rs   )rU   rV   rv   rw   rx   ry   rz   rW   imrefr6   r[   rY   rZ   r"   ZFAindicesZS0sZS0rr   ratioZMDZlambdasZl01Zwm_maskr   r   r   r^      sv     





z!EstimateResponseSH._run_interfacec             C   s4   | j  j }tj| jj|d< tj| jj|d< |S )Nrr   rs   )rO   rP   r   r   r2   rr   rs   )rU   ra   r   r   r   rb   1  s    z EstimateResponseSH._list_outputsN)
r   r   r   rc   rf   rd   rt   re   r^   rb   r   r   r   r   ru      s
   Nru   c               @   sN   e Zd ZedddZedddZejddddZej	ddddZ
ed	d
ZdS )CSDInputSpecTz#input mask in which compute tensors)r   r   zsingle fiber estimated responser{   z!maximal shperical harmonics order)rh   r   zsave fODFs in filezfODFs output file name)r   N)r   r   r   r   r   rr   r   ro   r}   rq   	save_fodsout_fodsr   r   r   r   r   8  s   r   c               @   s    e Zd ZeddZeddZdS )CSDOutputSpecz.Python pickled object of the CSD model fitted.)r   zfODFs output file nameN)r   r   r   r   modelr   r   r   r   r   r   B  s   
r   c               @   s(   e Zd ZdZeZeZdd Zdd Z	dS )CSDa  
    Uses CSD [Tournier2007]_ to generate the fODF of DWIs. The interface uses
    :py:mod:`dipy`, as explained in `dipy's CSD example
    <http://nipy.org/dipy/examples_built/reconst_csd.html>`_.

    .. [Tournier2007] Tournier, J.D., et al. NeuroImage 2007.
      Robust determination of the fibre orientation distribution in diffusion
      MRI: Non-negativity constrained super-resolved spherical deconvolution


    Example
    -------

    >>> from nipype.interfaces import dipy as ndp
    >>> csd = ndp.CSD()
    >>> csd.inputs.in_file = '4d_dwi.nii'
    >>> csd.inputs.in_bval = 'bvals'
    >>> csd.inputs.in_bvec = 'bvecs'
    >>> res = csd.run() # doctest: +SKIP
    c             C   s~  ddl m} ddlm} dd l}dd l}tj| jj	}tj
|d }t| jjrhtjtj| jjj}ntj|j}|jtjd}	| j }
tj| jj}tj|dd |d f}|d d |d d  }t|d dkrtjd	| ||
|| jjd
}tjd |j|	|}|j| jdddd}|j ||d |j!  | jj"rz|d}|j#|}tj$|j%tj|j&d j'| jd |S )Nr   )ConstrainedSphericalDeconvModel)
get_sphere)r&   r   r
   g?g?z6Estimated response is not prolate enough. Ratio=%0.3f.)r}   zFitting CSD modelcsdmodelz.pklz)extwbZsymmetric724fodsr-   r-   )(r   r   Z	dipy.datar   picklegzipr0   r1   r2   r3   r   r	   r   r9   r:   r;   r>   r?   r7   r@   r8   Zloadtxtrr   r   r   rB   rL   r}   rC   rM   openrT   dumpcloser   ZodfrR   r<   r6   rS   )rU   rV   r   r   r   r   rW   r   r[   rY   rZ   Z	resp_filerr   r   Z	csd_modelZcsd_fitfZspherer   r   r   r   r^   `  s<    


zCSD._run_interfacec             C   s8   | j  j }| jddd|d< | jjr4| jd|d< |S )Nr   z.pklz)r   r   r   r   )rO   rP   rT   r2   r   )rU   ra   r   r   r   rb     s
    zCSD._list_outputsN)
r   r   r   rc   r   rd   r   re   r^   rb   r   r   r   r   r   G  s
   1r   )+rc   os.pathpathr   numpyr9   Znibabelr0   distutils.versionr   r   r   baser   r   r   r	   r   r   r   r   r   r   	getLoggerrB   Zdipy.workflowsr   Zl_wkflwnameobjr*   new_nameglobalsrC   r   r   r#   rf   rt   ru   r   r   r   r   r   r   r   <module>   s4   
 

zm
