def smoothIMG(input_file, outputPath): data = nii.load(input_file) vol = data.get_data() ImgSmooth = np.min(vol, 3) unscaledNiiData = nii.Nifti1Image(ImgSmooth, data.affine) hdrOut = unscaledNiiData.header hdrOut.set_xyzt_units('mm') output_file = os.path.join( os.path.dirname(input_file), os.path.basename(input_file).split('.')[0] + 'DN.nii.gz') # hdrOut['sform_code'] = 1 nii.save(unscaledNiiData, output_file) input_file = output_file #output_file = os.path.join(os.path.dirname(input_file),os.path.basename(input_file).split('.')[0] + 'Smooth.nii.gz') output_file = os.path.join( outputPath, os.path.basename(inputFile).split('.')[0] + 'Smooth.nii.gz') myGauss = fsl.SpatialFilter(in_file=input_file, out_file=output_file, operation='median', kernel_shape='box', kernel_size=0.1) myGauss.run() print('Smoothing DONE!') return output_file
def init_phdiff_wf(omp_nthreads, phasetype='phasediff', name='phdiff_wf'): """ Estimates the fieldmap using a phase-difference image and one or more magnitude images corresponding to two or more :abbr:`GRE (Gradient Echo sequence)` acquisitions. The `original code was taken from nipype <https://github.com/nipy/nipype/blob/master/nipype/workflows/dmri/fsl/artifacts.py#L514>`_. .. workflow :: :graph2use: orig :simple_form: yes from qsiprep.workflows.fieldmap.phdiff import init_phdiff_wf wf = init_phdiff_wf(omp_nthreads=1) Outputs:: outputnode.fmap_ref - The average magnitude image, skull-stripped outputnode.fmap_mask - The brain mask applied to the fieldmap outputnode.fmap - The estimated fieldmap in Hz """ workflow = Workflow(name=name) workflow.__desc__ = """\ A deformation field to correct for susceptibility distortions was estimated based on a field map that was co-registered to the BOLD reference, using a custom workflow of *fMRIPrep* derived from D. Greve's `epidewarp.fsl` [script](http://www.nmr.mgh.harvard.edu/~greve/fbirn/b0/epidewarp.fsl) and further improvements of HCP Pipelines [@hcppipelines]. """ inputnode = pe.Node( niu.IdentityInterface(fields=['magnitude', 'phasediff']), name='inputnode') outputnode = pe.Node( niu.IdentityInterface(fields=['fmap', 'fmap_ref', 'fmap_mask']), name='outputnode') # Merge input magnitude images magmrg = pe.Node(IntraModalMerge(), name='magmrg') # de-gradient the fields ("bias/illumination artifact") n4 = pe.Node(ants.N4BiasFieldCorrection(dimension=3, copy_header=True), name='n4', n_procs=omp_nthreads) bet = pe.Node(BETRPT(generate_report=True, frac=0.6, mask=True), name='bet') ds_report_fmap_mask = pe.Node(DerivativesDataSink(desc='brain', suffix='mask'), name='ds_report_fmap_mask', mem_gb=0.01, run_without_submitting=True) # uses mask from bet; outputs a mask # dilate = pe.Node(fsl.maths.MathsCommand( # nan2zeros=True, args='-kernel sphere 5 -dilM'), name='MskDilate') # FSL PRELUDE will perform phase-unwrapping prelude = pe.Node(fsl.PRELUDE(), name='prelude') denoise = pe.Node(fsl.SpatialFilter(operation='median', kernel_shape='sphere', kernel_size=5), name='denoise') demean = pe.Node(niu.Function(function=demean_image), name='demean') cleanup_wf = cleanup_edge_pipeline(name="cleanup_wf") compfmap = pe.Node(Phasediff2Fieldmap(), name='compfmap') # The phdiff2fmap interface is equivalent to: # rad2rsec (using rads2radsec from nipype.workflows.dmri.fsl.utils) # pre_fugue = pe.Node(fsl.FUGUE(save_fmap=True), name='ComputeFieldmapFUGUE') # rsec2hz (divide by 2pi) if phasetype == "phasediff": # Read phasediff echo times meta = pe.Node(ReadSidecarJSON(), name='meta', mem_gb=0.01) # phase diff -> radians pha2rads = pe.Node(niu.Function(function=siemens2rads), name='pha2rads') # Read phasediff echo times meta = pe.Node(ReadSidecarJSON(), name='meta', mem_gb=0.01, run_without_submitting=True) workflow.connect([ (meta, compfmap, [('out_dict', 'metadata')]), (inputnode, pha2rads, [('phasediff', 'in_file')]), (pha2rads, prelude, [('out', 'phase_file')]), (inputnode, ds_report_fmap_mask, [('phasediff', 'source_file')]), ]) elif phasetype == "phase": workflow.__desc__ += """\ The phase difference used for unwarping was calculated using two separate phase measurements [@pncprocessing]. """ # Special case for phase1, phase2 images meta = pe.MapNode(ReadSidecarJSON(), name='meta', mem_gb=0.01, run_without_submitting=True, iterfield=['in_file']) phases2fmap = pe.Node(Phases2Fieldmap(), name='phases2fmap') workflow.connect([ (meta, phases2fmap, [('out_dict', 'metadatas')]), (inputnode, phases2fmap, [('phasediff', 'phase_files')]), (phases2fmap, prelude, [('out_file', 'phase_file')]), (phases2fmap, compfmap, [('phasediff_metadata', 'metadata')]), (phases2fmap, ds_report_fmap_mask, [('out_file', 'source_file')]) ]) workflow.connect([ (inputnode, meta, [('phasediff', 'in_file')]), (inputnode, magmrg, [('magnitude', 'in_files')]), (magmrg, n4, [('out_avg', 'input_image')]), (n4, prelude, [('output_image', 'magnitude_file')]), (n4, bet, [('output_image', 'in_file')]), (bet, prelude, [('mask_file', 'mask_file')]), (prelude, denoise, [('unwrapped_phase_file', 'in_file')]), (denoise, demean, [('out_file', 'in_file')]), (demean, cleanup_wf, [('out', 'inputnode.in_file')]), (bet, cleanup_wf, [('mask_file', 'inputnode.in_mask')]), (cleanup_wf, compfmap, [('outputnode.out_file', 'in_file')]), (compfmap, outputnode, [('out_file', 'fmap')]), (bet, outputnode, [('mask_file', 'fmap_mask'), ('out_file', 'fmap_ref')]), (bet, ds_report_fmap_mask, [('out_report', 'in_file')]), ]) return workflow
def init_fmap_wf(omp_nthreads, fmap_bspline, name='fmap_wf'): """ Fieldmap workflow - when we have a sequence that directly measures the fieldmap we just need to mask it (using the corresponding magnitude image) to remove the noise in the surrounding air region, and ensure that units are Hz. .. workflow :: :graph2use: orig :simple_form: yes from fmriprep.workflows.fieldmap.fmap import init_fmap_wf wf = init_fmap_wf(omp_nthreads=6, fmap_bspline=False) """ workflow = pe.Workflow(name=name) inputnode = pe.Node( niu.IdentityInterface(fields=['magnitude', 'fieldmap']), name='inputnode') outputnode = pe.Node( niu.IdentityInterface(fields=['fmap', 'fmap_ref', 'fmap_mask']), name='outputnode') # Merge input magnitude images magmrg = pe.Node(IntraModalMerge(), name='magmrg') # Merge input fieldmap images fmapmrg = pe.Node(IntraModalMerge(zero_based_avg=False, hmc=False), name='fmapmrg') # de-gradient the fields ("bias/illumination artifact") n4_correct = pe.Node(ants.N4BiasFieldCorrection(dimension=3, copy_header=True), name='n4_correct', n_procs=omp_nthreads) bet = pe.Node(BETRPT(generate_report=True, frac=0.6, mask=True), name='bet') ds_fmap_mask = pe.Node(DerivativesDataSink(suffix='fmap_mask'), name='ds_report_fmap_mask', run_without_submitting=True) workflow.connect([ (inputnode, magmrg, [('magnitude', 'in_files')]), (inputnode, fmapmrg, [('fieldmap', 'in_files')]), (magmrg, n4_correct, [('out_file', 'input_image')]), (n4_correct, bet, [('output_image', 'in_file')]), (bet, outputnode, [('mask_file', 'fmap_mask'), ('out_file', 'fmap_ref')]), (inputnode, ds_fmap_mask, [('fieldmap', 'source_file')]), (bet, ds_fmap_mask, [('out_report', 'in_file')]), ]) if fmap_bspline: # despike_threshold=1.0, mask_erode=1), fmapenh = pe.Node(FieldEnhance(unwrap=False, despike=False), name='fmapenh', mem_gb=4, n_procs=omp_nthreads) workflow.connect([ (bet, fmapenh, [('mask_file', 'in_mask'), ('out_file', 'in_magnitude')]), (fmapmrg, fmapenh, [('out_file', 'in_file')]), (fmapenh, outputnode, [('out_file', 'fmap')]), ]) else: torads = pe.Node(FieldToRadS(), name='torads') prelude = pe.Node(fsl.PRELUDE(), name='prelude') tohz = pe.Node(FieldToHz(), name='tohz') denoise = pe.Node(fsl.SpatialFilter(operation='median', kernel_shape='sphere', kernel_size=3), name='denoise') demean = pe.Node(niu.Function(function=demean_image), name='demean') cleanup_wf = cleanup_edge_pipeline(name='cleanup_wf') applymsk = pe.Node(fsl.ApplyMask(), name='applymsk') workflow.connect([ (bet, prelude, [('mask_file', 'mask_file'), ('out_file', 'magnitude_file')]), (fmapmrg, torads, [('out_file', 'in_file')]), (torads, tohz, [('fmap_range', 'range_hz')]), (torads, prelude, [('out_file', 'phase_file')]), (prelude, tohz, [('unwrapped_phase_file', 'in_file')]), (tohz, denoise, [('out_file', 'in_file')]), (denoise, demean, [('out_file', 'in_file')]), (demean, cleanup_wf, [('out', 'inputnode.in_file')]), (bet, cleanup_wf, [('mask_file', 'inputnode.in_mask')]), (cleanup_wf, applymsk, [('outputnode.out_file', 'in_file')]), (bet, applymsk, [('mask_file', 'mask_file')]), (applymsk, outputnode, [('out_file', 'fmap')]), ]) return workflow
def init_fmap_postproc_wf(omp_nthreads, fmap_bspline, median_kernel_size=5, name='fmap_postproc_wf'): """ Postprocess a B0 map estimated elsewhere. This workflow denoises (mostly via smoothing) a B0 fieldmap. Workflow Graph .. workflow :: :graph2use: orig :simple_form: yes from sdcflows.workflows.fmap import init_fmap_postproc_wf wf = init_fmap_postproc_wf(omp_nthreads=6, fmap_bspline=False) Parameters ---------- omp_nthreads : int Maximum number of threads an individual process may use fmap_bspline : bool Whether the fieldmap should be smoothed and extrapolated to off-brain regions using B-Spline basis. median_kernel_size : int Size of the kernel when smoothing is done with a median filter. name : str Name of workflow (default: ``fmap_postproc_wf``) Inputs ------ fmap_mask : pathlike A brain binary mask corresponding to this fieldmap. fmap_ref : pathlike A preprocessed magnitude/reference image for the fieldmap. fmap : pathlike A B0-field nonuniformity map (aka fieldmap) estimated elsewhere. Outputs ------- out_fmap : pathlike Postprocessed fieldmap. """ workflow = Workflow(name=name) inputnode = pe.Node(niu.IdentityInterface( fields=['fmap_mask', 'fmap_ref', 'fmap', 'metadata']), name='inputnode') outputnode = pe.Node(niu.IdentityInterface(fields=['out_fmap', 'metadata']), name='outputnode') if fmap_bspline: from ..interfaces.fmap import FieldEnhance # despike_threshold=1.0, mask_erode=1), fmapenh = pe.Node( FieldEnhance(unwrap=False, despike=False), name='fmapenh', mem_gb=4, n_procs=omp_nthreads) workflow.connect([ (inputnode, fmapenh, [('fmap_mask', 'in_mask'), ('fmap_ref', 'in_magnitude'), ('fmap_hz', 'in_file')]), (fmapenh, outputnode, [('out_file', 'out_fmap')]), ]) else: recenter = pe.Node(niu.Function(function=_recenter), name='recenter', run_without_submitting=True) denoise = pe.Node(fsl.SpatialFilter( operation='median', kernel_shape='sphere', kernel_size=median_kernel_size), name='denoise') demean = pe.Node(niu.Function(function=_demean), name='demean') cleanup_wf = cleanup_edge_pipeline(name="cleanup_wf") workflow.connect([ (inputnode, cleanup_wf, [('fmap_mask', 'inputnode.in_mask')]), (inputnode, recenter, [(('fmap', _pop), 'in_file')]), (recenter, denoise, [('out', 'in_file')]), (denoise, demean, [('out_file', 'in_file')]), (demean, cleanup_wf, [('out', 'inputnode.in_file')]), (cleanup_wf, outputnode, [('outputnode.out_file', 'out_fmap')]), (inputnode, outputnode, [(('metadata', _pop), 'metadata')]), ]) return workflow
def init_phdiff_wf(omp_nthreads, name='phdiff_wf'): """ Distortion correction of EPI sequences using phase-difference maps. Estimates the fieldmap using a phase-difference image and one or more magnitude images corresponding to two or more :abbr:`GRE (Gradient Echo sequence)` acquisitions. The `original code was taken from nipype <https://github.com/nipy/nipype/blob/master/nipype/workflows/dmri/fsl/artifacts.py#L514>`_. .. workflow :: :graph2use: orig :simple_form: yes from sdcflows.workflows.phdiff import init_phdiff_wf wf = init_phdiff_wf(omp_nthreads=1) **Parameters**: omp_nthreads : int Maximum number of threads an individual process may use **Inputs**: magnitude : pathlike Path to the corresponding magnitude path(s). phasediff : pathlike Path to the corresponding phase-difference file. metadata : dict Metadata dictionary corresponding to the phasediff input **Outputs**: fmap_ref : pathlike The average magnitude image, skull-stripped fmap_mask : pathlike The brain mask applied to the fieldmap fmap : pathlike The estimated fieldmap in Hz """ workflow = Workflow(name=name) workflow.__desc__ = """\ A deformation field to correct for susceptibility distortions was estimated based on a field map that was co-registered to the BOLD reference, using a custom workflow of *fMRIPrep* derived from D. Greve's `epidewarp.fsl` [script](http://www.nmr.mgh.harvard.edu/~greve/fbirn/b0/epidewarp.fsl) and further improvements of HCP Pipelines [@hcppipelines]. """ inputnode = pe.Node( niu.IdentityInterface(fields=['magnitude', 'phasediff', 'metadata']), name='inputnode') outputnode = pe.Node( niu.IdentityInterface(fields=['fmap', 'fmap_ref', 'fmap_mask']), name='outputnode') # Merge input magnitude images magmrg = pe.Node(IntraModalMerge(), name='magmrg') # de-gradient the fields ("bias/illumination artifact") n4 = pe.Node(ants.N4BiasFieldCorrection(dimension=3, copy_header=True), name='n4', n_procs=omp_nthreads) bet = pe.Node(BETRPT(generate_report=True, frac=0.6, mask=True), name='bet') # uses mask from bet; outputs a mask # dilate = pe.Node(fsl.maths.MathsCommand( # nan2zeros=True, args='-kernel sphere 5 -dilM'), name='MskDilate') # phase diff -> radians pha2rads = pe.Node(niu.Function(function=siemens2rads), name='pha2rads') # FSL PRELUDE will perform phase-unwrapping prelude = pe.Node(fsl.PRELUDE(), name='prelude') denoise = pe.Node(fsl.SpatialFilter(operation='median', kernel_shape='sphere', kernel_size=3), name='denoise') demean = pe.Node(niu.Function(function=demean_image), name='demean') cleanup_wf = cleanup_edge_pipeline(name="cleanup_wf") compfmap = pe.Node(Phasediff2Fieldmap(), name='compfmap') # The phdiff2fmap interface is equivalent to: # rad2rsec (using rads2radsec from nipype.workflows.dmri.fsl.utils) # pre_fugue = pe.Node(fsl.FUGUE(save_fmap=True), name='ComputeFieldmapFUGUE') # rsec2hz (divide by 2pi) workflow.connect([ (inputnode, compfmap, [('metadata', 'metadata')]), (inputnode, magmrg, [('magnitude', 'in_files')]), (magmrg, n4, [('out_avg', 'input_image')]), (n4, prelude, [('output_image', 'magnitude_file')]), (n4, bet, [('output_image', 'in_file')]), (bet, prelude, [('mask_file', 'mask_file')]), (inputnode, pha2rads, [('phasediff', 'in_file')]), (pha2rads, prelude, [('out', 'phase_file')]), (prelude, denoise, [('unwrapped_phase_file', 'in_file')]), (denoise, demean, [('out_file', 'in_file')]), (demean, cleanup_wf, [('out', 'inputnode.in_file')]), (bet, cleanup_wf, [('mask_file', 'inputnode.in_mask')]), (cleanup_wf, compfmap, [('outputnode.out_file', 'in_file')]), (compfmap, outputnode, [('out_file', 'fmap')]), (bet, outputnode, [('mask_file', 'fmap_mask'), ('out_file', 'fmap_ref')]), ]) return workflow
def create_workflow(self, flow, inputnode, outputnode): smoothing_output = pe.Node(interface=util.IdentityInterface(fields=["smoothing_output"]),name="smoothing_output") if self.config.smoothing > 0.0: smoothing = pe.Node(interface=fsl.SpatialFilter(operation='mean',kernel_shape = 'gauss'),name="smoothing") smoothing.inputs.kernel_size = self.config.smoothing flow.connect([ (inputnode,smoothing,[("preproc_file","in_file")]), (smoothing,smoothing_output,[("out_file","smoothing_output")]) ]) else: flow.connect([ (inputnode,smoothing_output,[("preproc_file","smoothing_output")]) ]) discard_output = pe.Node(interface=util.IdentityInterface(fields=["discard_output"]),name="discard_output") if self.config.discard_n_volumes > 0: discard = pe.Node(interface=discard_tp(n_discard=self.config.discard_n_volumes),name='discard_volumes') flow.connect([ (smoothing_output,discard,[("smoothing_output","in_file")]), (discard,discard_output,[("out_file","discard_output")]) ]) else: flow.connect([ (smoothing_output,discard_output,[("smoothing_output","discard_output")]) ]) nuisance_output = pe.Node(interface=util.IdentityInterface(fields=["nuisance_output"]),name="nuisance_output") if self.config.wm or self.config.global_nuisance or self.config.csf or self.config.motion: nuisance = pe.Node(interface=nuisance_regression(),name="nuisance_regression") nuisance.inputs.global_nuisance=self.config.global_nuisance nuisance.inputs.csf_nuisance=self.config.csf nuisance.inputs.wm_nuisance=self.config.wm nuisance.inputs.motion_nuisance=self.config.motion nuisance.inputs.n_discard=self.config.discard_n_volumes flow.connect([ (discard_output,nuisance,[("discard_output","in_file")]), (inputnode,nuisance,[("eroded_brain","brainfile")]), (inputnode,nuisance,[("eroded_csf","csf_file")]), (inputnode,nuisance,[("eroded_wm","wm_file")]), (inputnode,nuisance,[("motion_par_file","motion_file")]), (inputnode,nuisance,[("registered_roi_volumes","gm_file")]), (nuisance,nuisance_output,[("out_file","nuisance_output")]) ]) else: flow.connect([ (discard_output,nuisance_output,[("discard_output","nuisance_output")]) ]) detrending_output = pe.Node(interface=util.IdentityInterface(fields=["detrending_output"]),name="detrending_output") if self.config.detrending: detrending = pe.Node(interface=Detrending(),name='detrending') flow.connect([ (nuisance_output,detrending,[("nuisance_output","in_file")]), (inputnode,detrending,[("registered_roi_volumes","gm_file")]), (detrending,detrending_output,[("out_file","detrending_output")]) ]) else: flow.connect([ (nuisance_output,detrending_output,[("nuisance_output","detrending_output")]) ]) filter_output = pe.Node(interface=util.IdentityInterface(fields=["filter_output"]),name="filter_output") if self.config.lowpass_filter > 0 or self.config.highpass_filter > 0: filtering = pe.Node(interface=fsl.TemporalFilter(),name='temporal_filter') filtering.inputs.lowpass_sigma = self.config.lowpass_filter filtering.inputs.highpass_sigma = self.config.highpass_filter flow.connect([ (detrending_output,filtering,[("detrending_output","in_file")]), (filtering,filter_output,[("out_file","filter_output")]) ]) else: flow.connect([ (detrending_output,filter_output,[("detrending_output","filter_output")]) ]) if self.config.scrubbing: scrubbing = pe.Node(interface=Scrubbing(),name='scrubbing') flow.connect([ (filter_output,scrubbing,[("filter_output","in_file")]), (inputnode,scrubbing,[("registered_wm","wm_mask")]), (inputnode,scrubbing,[("registered_roi_volumes","gm_file")]), (inputnode,scrubbing,[("motion_par_file","motion_parameters")]), (scrubbing,outputnode,[("fd_npy","FD")]), (scrubbing,outputnode,[("dvars_npy","DVARS")]) ]) flow.connect([ (filter_output,outputnode,[("filter_output","func_file")]) ])
def init_phdiff_wf(omp_nthreads, name='phdiff_wf'): """ Estimates the fieldmap using a phase-difference image and one or more magnitude images corresponding to two or more :abbr:`GRE (Gradient Echo sequence)` acquisitions. The `original code was taken from nipype <https://github.com/nipy/nipype/blob/master/nipype/workflows/dmri/fsl/artifacts.py#L514>`_. .. workflow :: :graph2use: orig :simple_form: yes from fmriprep.workflows.fieldmap.phdiff import init_phdiff_wf wf = init_phdiff_wf(omp_nthreads=1) Outputs:: outputnode.fmap_ref - The average magnitude image, skull-stripped outputnode.fmap_mask - The brain mask applied to the fieldmap outputnode.fmap - The estimated fieldmap in Hz """ inputnode = pe.Node( niu.IdentityInterface(fields=['magnitude', 'phasediff']), name='inputnode') outputnode = pe.Node( niu.IdentityInterface(fields=['fmap', 'fmap_ref', 'fmap_mask']), name='outputnode') def _pick1st(inlist): return inlist[0] # Read phasediff echo times meta = pe.Node(ReadSidecarJSON(), name='meta', mem_gb=0.01, run_without_submitting=True) # Merge input magnitude images magmrg = pe.Node(IntraModalMerge(), name='magmrg') # de-gradient the fields ("bias/illumination artifact") n4 = pe.Node(ants.N4BiasFieldCorrection(dimension=3, copy_header=True), name='n4', n_procs=omp_nthreads) bet = pe.Node(BETRPT(generate_report=True, frac=0.6, mask=True), name='bet') ds_fmap_mask = pe.Node(DerivativesDataSink(suffix='fmap_mask'), name='ds_report_fmap_mask', mem_gb=0.01, run_without_submitting=True) # uses mask from bet; outputs a mask # dilate = pe.Node(fsl.maths.MathsCommand( # nan2zeros=True, args='-kernel sphere 5 -dilM'), name='MskDilate') # phase diff -> radians pha2rads = pe.Node(niu.Function(function=siemens2rads), name='pha2rads') # FSL PRELUDE will perform phase-unwrapping prelude = pe.Node(fsl.PRELUDE(), name='prelude') denoise = pe.Node(fsl.SpatialFilter(operation='median', kernel_shape='sphere', kernel_size=3), name='denoise') demean = pe.Node(niu.Function(function=demean_image), name='demean') cleanup_wf = cleanup_edge_pipeline(name="cleanup_wf") compfmap = pe.Node(Phasediff2Fieldmap(), name='compfmap') # The phdiff2fmap interface is equivalent to: # rad2rsec (using rads2radsec from nipype.workflows.dmri.fsl.utils) # pre_fugue = pe.Node(fsl.FUGUE(save_fmap=True), name='ComputeFieldmapFUGUE') # rsec2hz (divide by 2pi) workflow = pe.Workflow(name=name) workflow.connect([ (inputnode, meta, [('phasediff', 'in_file')]), (inputnode, magmrg, [('magnitude', 'in_files')]), (magmrg, n4, [('out_avg', 'input_image')]), (n4, prelude, [('output_image', 'magnitude_file')]), (n4, bet, [('output_image', 'in_file')]), (bet, prelude, [('mask_file', 'mask_file')]), (inputnode, pha2rads, [('phasediff', 'in_file')]), (pha2rads, prelude, [('out', 'phase_file')]), (meta, compfmap, [('out_dict', 'metadata')]), (prelude, denoise, [('unwrapped_phase_file', 'in_file')]), (denoise, demean, [('out_file', 'in_file')]), (demean, cleanup_wf, [('out', 'inputnode.in_file')]), (bet, cleanup_wf, [('mask_file', 'inputnode.in_mask')]), (cleanup_wf, compfmap, [('outputnode.out_file', 'in_file')]), (compfmap, outputnode, [('out_file', 'fmap')]), (bet, outputnode, [('mask_file', 'fmap_mask'), ('out_file', 'fmap_ref')]), (inputnode, ds_fmap_mask, [('phasediff', 'source_file')]), (bet, ds_fmap_mask, [('out_report', 'in_file')]), ]) return workflow
def phase_diff_and_magnitudes(name='phase_diff_and_magnitudes'): """ Estimates the fieldmap using a phase-difference image and one or more magnitude images corresponding to two or more :abbr:`GRE (Gradient Echo sequence)` acquisitions. The `original code was taken from nipype <https://github.com/nipy/nipype/blob/master/nipype/workflows/dmri/fsl/artifacts.py#L514>`_. Outputs:: outputnode.fmap_ref - The average magnitude image, skull-stripped outputnode.fmap_mask - The brain mask applied to the fieldmap outputnode.fmap - The estimated fieldmap in Hz """ inputnode = pe.Node(niu.IdentityInterface(fields=['input_images']), name='inputnode') outputnode = pe.Node( niu.IdentityInterface(fields=['fmap_ref', 'fmap_mask', 'fmap']), name='outputnode') sortfmaps = pe.Node(niu.Function(function=_sort_fmaps, input_names=['input_images'], output_names=['magnitude', 'phasediff']), name='SortFmaps') def _pick1st(inlist): return inlist[0] # Read phasediff echo times meta = pe.Node(ReadSidecarJSON(fields=['EchoTime1', 'EchoTime2']), name='metadata') dte = pe.Node(niu.Function(input_names=['in_values'], output_names=['delta_te'], function=_delta_te), name='ComputeDeltaTE') # Merge input magnitude images magmrg = pe.Node(IntraModalMerge(), name='MagnitudeFuse') # de-gradient the fields ("bias/illumination artifact") n4 = pe.Node(ants.N4BiasFieldCorrection(dimension=3), name='MagnitudeBias') bet = pe.Node(fsl.BET(frac=0.6, mask=True), name='MagnitudeBET') # uses mask from bet; outputs a mask # dilate = pe.Node(fsl.maths.MathsCommand( # nan2zeros=True, args='-kernel sphere 5 -dilM'), name='MskDilate') # phase diff -> radians pha2rads = pe.Node(niu.Function(input_names=['in_file'], output_names=['out_file'], function=siemens2rads), name='PreparePhase') # FSL PRELUDE will perform phase-unwrapping prelude = pe.Node(fsl.PRELUDE(process3d=True), name='PhaseUnwrap') denoise = pe.Node(fsl.SpatialFilter(operation='median', kernel_shape='sphere', kernel_size=3), name='PhaseDenoise') demean = pe.Node(niu.Function(input_names=['in_file', 'in_mask'], output_names=['out_file'], function=demean_image), name='DemeanFmap') cleanup = cleanup_edge_pipeline() compfmap = pe.Node(niu.Function(input_names=['in_file', 'delta_te'], output_names=['out_file'], function=phdiff2fmap), name='ComputeFieldmap') # The phdiff2fmap interface is equivalent to: # rad2rsec (using rads2radsec from nipype.workflows.dmri.fsl.utils) # pre_fugue = pe.Node(fsl.FUGUE(save_fmap=True), name='ComputeFieldmapFUGUE') # rsec2hz (divide by 2pi) workflow = pe.Workflow(name=name) workflow.connect([ (inputnode, sortfmaps, [('input_images', 'input_images')]), (sortfmaps, meta, [(('phasediff', _pick1st), 'in_file')]), (sortfmaps, magmrg, [('magnitude', 'in_files')]), (magmrg, n4, [('out_avg', 'input_image')]), (n4, prelude, [('output_image', 'magnitude_file')]), (n4, bet, [('output_image', 'in_file')]), (bet, prelude, [('mask_file', 'mask_file')]), (sortfmaps, pha2rads, [(('phasediff', _pick1st), 'in_file')]), (pha2rads, prelude, [('out_file', 'phase_file')]), (meta, dte, [('out_dict', 'in_values')]), (dte, compfmap, [('delta_te', 'delta_te')]), (prelude, denoise, [('unwrapped_phase_file', 'in_file')]), (denoise, demean, [('out_file', 'in_file')]), (demean, cleanup, [('out_file', 'inputnode.in_file')]), (bet, cleanup, [('mask_file', 'inputnode.in_mask')]), (cleanup, compfmap, [('outputnode.out_file', 'in_file')]), (compfmap, outputnode, [('out_file', 'fmap')]), (bet, outputnode, [('mask_file', 'fmap_mask'), ('out_file', 'fmap_ref')]) ]) return workflow
maskdata(magbrain_warped, mag_mask) #unwarp withe predule unwrapped = outdir + '/unwrapped.nii.gz' prefsl = fsl.PRELUDE() prefsl.inputs.magnitude_file = magbrain_warped prefsl.inputs.phase_file = phasediff[0] prefsl.inputs.mask_file = mag_mask prefsl.inputs.unwrapped_phase_file = unwrapped prefsl.run() #denoise demean recenter the fieldmap and #recentre recentered = _recenter(unwrapped, newpath=outdir + '/') # denoise with fsl spatial filter denoised = outdir + '/unwrapped_denoise.nii.gz' denoise = fsl.SpatialFilter() denoise.inputs.in_file = recentered denoise.inputs.kernel_shape = 'sphere' denoise.inputs.kernel_size = 3 denoise.inputs.operation = 'median' denoise.inputs.out_file = denoised denoise.run() demeamed = _demean(in_file=denoised, newpath=outdir + '/') # get delta te if os.path.isfile(phasedifc[0]): with open(glob.glob(fmapdir + '/*phasediff.json')[0], 'r') as jsonfile: obj = jsonfile.read() dpdat = json.loads(obj) delta_te = np.abs(dpdat['EchoTime2'] - dpdat['EchoTime1'])