def do_subject_preproc(subject_id, output_dir, func, anat, do_bet=True, do_mc=True, do_coreg=True, do_normalize=True, cmd_prefix="fsl5.0-", **kwargs ): """ Preprocesses subject data using FSL. Parameters ---------- """ output = {'func': func, 'anat': anat } # output dir subject_output_dir = os.path.join(output_dir, subject_id) if not os.path.exists(subject_output_dir): os.makedirs(subject_output_dir) # prepare for smart-caching cache_dir = os.path.join(output_dir, "cache_dir") if not os.path.exists(cache_dir): os.makedirs(cache_dir) nipype_mem = NipypeMemory(base_dir=cache_dir) joblib_mem = JoblibMemory(cache_dir, verbose=100) # sanitize input files if not isinstance(output['func'], basestring): output['func'] = joblib_mem.cache(do_fsl_merge)( func, subject_output_dir, output_prefix='Merged', cmd_prefix=cmd_prefix) ###################### # Brain Extraction ###################### if do_bet: if not fsl.BET._cmd.startswith("fsl"): fsl.BET._cmd = cmd_prefix + fsl.BET._cmd bet = nipype_mem.cache(fsl.BET) bet_results = bet(in_file=output['anat'], ) output['anat'] = bet_results.outputs.out_file ####################### # Motion correction ####################### if do_mc: if not fsl.MCFLIRT._cmd.startswith("fsl"): fsl.MCFLIRT._cmd = cmd_prefix + fsl.MCFLIRT._cmd mcflirt = nipype_mem.cache(fsl.MCFLIRT) mcflirt_results = mcflirt(in_file=output['func'], cost='mutualinfo', save_mats=True, # save mc matrices save_plots=True # save mc params ) output['motion_parameters'] = mcflirt_results.outputs.par_file output['motion_matrices'] = mcflirt_results.outputs.mat_file output['func'] = mcflirt_results.outputs.out_file ################### # Coregistration ################### if do_coreg: if not fsl.FLIRT._cmd.startswith("fsl"): fsl.FLIRT._cmd = cmd_prefix + fsl.FLIRT._cmd flirt1 = nipype_mem.cache(fsl.FLIRT) flirt1_results = flirt1(in_file=output['func'], reference=output['anat'] ) if not do_normalize: output['func'] = flirt1_results.outputs.out_file ########################## # Spatial normalization ########################## if do_normalize: if not fsl.FLIRT._cmd.startswith("fsl"): fsl.FLIRT._cmd = cmd_prefix + fsl.FLIRT._cmd # T1 normalization flirt2 = nipype_mem.cache(fsl.FLIRT) flirt2_results = flirt2(in_file=output['anat'], reference=FSL_T1_TEMPLATE) output['anat'] = flirt2_results.outputs.out_file # concatenate 'func -> anat' and 'anat -> standard space' # transformation matrices to obtaun 'func -> standard space' # transformation matrix if do_coreg: if not fsl.ConvertXFM._cmd.startswith("fsl"): fsl.ConvertXFM._cmd = cmd_prefix + fsl.ConvertXFM._cmd convertxfm = nipype_mem.cache(fsl.ConvertXFM) convertxfm_results = convertxfm( in_file=flirt1_results.outputs.out_matrix_file, in_file2=flirt2_results.outputs.out_matrix_file, concat_xfm=True ) # warp func data into standard space by applying # 'func -> standard space' transformation matrix if not fsl.ApplyXfm._cmd.startswith("fsl"): fsl.ApplyXfm._cmd = cmd_prefix + fsl.ApplyXfm._cmd applyxfm = nipype_mem.cache(fsl.ApplyXfm) applyxfm_results = applyxfm( in_file=output['func'], in_matrix_file=convertxfm_results.outputs.out_file, reference=FSL_T1_TEMPLATE ) output['func'] = applyxfm_results.outputs.out_file return output
def run_suject_level1_glm( subject_data, readout_time=.01392, # seconds tr=.72, dc=True, hrf_model="Canonical with Derivative", drift_model="Cosine", hfcut=100, regress_motion=True, slicer='ortho', cut_coords=None, threshold=3., cluster_th=15, normalize=True, fwhm=0., protocol="MOTOR", func_write_voxel_sizes=None, anat_write_voxel_sizes=None, **other_preproc_kwargs): """ Function to do preproc + analysis for a single HCP subject (task fMRI) """ add_regs_files = None n_motion_regressions = 6 subject_data.n_sessions = 2 subject_data.tmp_output_dir = os.path.join(subject_data.output_dir, "tmp") if not os.path.exists(subject_data.tmp_output_dir): os.makedirs(subject_data.tmp_output_dir) if not os.path.exists(subject_data.output_dir): os.makedirs(subject_data.output_dir) mem = Memory(os.path.join(subject_data.output_dir, "cache_dir"), verbose=100) # glob design files (.fsf) subject_data.design_files = [ os.path.join(subject_data.data_dir, ("MNINonLinear/Results/tfMRI_%s_%s/" "tfMRI_%s_%s_hp200_s4_level1.fsf") % (protocol, direction, protocol, direction)) for direction in ['LR', 'RL'] ] assert len(subject_data.design_files) == 2 for df in subject_data.design_files: if not os.path.isfile(df): return if 0x0: subject_data = _do_fmri_distortion_correction( subject_data, dc=dc, fwhm=fwhm, readout_time=readout_time, **other_preproc_kwargs) # chronometry stats_start_time = pretty_time() # merged lists paradigms = [] frametimes_list = [] design_matrices = [] # fmri_files = [] n_scans = [] # for direction, direction_index in zip(['LR', 'RL'], xrange(2)): for sess in xrange(subject_data.n_sessions): direction = ['LR', 'RL'][sess] # glob the design file # design_file = os.path.join(# _subject_data_dir, "tfMRI_%s_%s" % ( # protocol, direction), design_file = subject_data.design_files[sess] # "tfMRI_%s_%s_hp200_s4_level1.fsf" % ( # protocol, direction)) if not os.path.isfile(design_file): print "Can't find design file %s; skipping subject %s" % ( design_file, subject_data.subject_id) return # read the experimental setup print "Reading experimental setup from %s ..." % design_file fsl_condition_ids, timing_files, fsl_contrast_ids, contrast_values = \ read_fsl_design_file(design_file) print "... done.\r\n" # fix timing filenames timing_files = [ tf.replace("EVs", "tfMRI_%s_%s/EVs" % (protocol, direction)) for tf in timing_files ] # make design matrix print "Constructing design matrix for direction %s ..." % direction _n_scans = nibabel.load(subject_data.func[sess]).shape[-1] n_scans.append(_n_scans) add_regs_file = add_regs_files[ sess] if not add_regs_files is None else None design_matrix, paradigm, frametimes = make_dmtx_from_timing_files( timing_files, fsl_condition_ids, n_scans=_n_scans, tr=tr, hrf_model=hrf_model, drift_model=drift_model, hfcut=hfcut, add_regs_file=add_regs_file, add_reg_names=[ 'Translation along x axis', 'Translation along yaxis', 'Translation along z axis', 'Rotation along x axis', 'Rotation along y axis', 'Rotation along z axis', 'Differential Translation along x axis', 'Differential Translation along yaxis', 'Differential Translation along z axis', 'Differential Rotation along x axis', 'Differential Rotation along y axis', 'Differential Rotation along z axis' ][:n_motion_regressions] if not add_regs_files is None else None, ) print "... done." paradigms.append(paradigm) frametimes_list.append(frametimes) design_matrices.append(design_matrix) # convert contrasts to dict contrasts = dict(( contrast_id, # append zeros to end of contrast to match design np.hstack(( contrast_value, np.zeros(len(design_matrix.names) - len(contrast_value))))) for contrast_id, contrast_value in zip( fsl_contrast_ids, contrast_values)) # more interesting contrasts if protocol == 'MOTOR': contrasts['RH-LH'] = contrasts['RH'] - contrasts['LH'] contrasts['LH-RH'] = -contrasts['RH-LH'] contrasts['RF-LF'] = contrasts['RF'] - contrasts['LF'] contrasts['LF-RF'] = -contrasts['RF-LF'] contrasts['H'] = contrasts['RH'] + contrasts['LH'] contrasts['F'] = contrasts['RF'] + contrasts['LF'] contrasts['H-F'] = contrasts['RH'] + contrasts['LH'] - ( contrasts['RF'] - contrasts['LF']) contrasts['F-H'] = -contrasts['H-F'] contrasts = dict((k, v) for k, v in contrasts.iteritems() if "-" in k) # replicate contrasts across sessions contrasts = dict((cid, [cval] * 2) for cid, cval in contrasts.iteritems()) cache_dir = cache_dir = os.path.join(subject_data.output_dir, 'cache_dir') if not os.path.exists(cache_dir): os.makedirs(cache_dir) nipype_mem = NipypeMemory(base_dir=cache_dir) if 0x0: if np.sum(fwhm) > 0.: subject_data.func = nipype_mem.cache(spm.Smooth)( in_files=subject_data.func, fwhm=fwhm, ignore_exception=False, ).outputs.smoothed_files # fit GLM def tortoise(*args): print args print( 'Fitting a "Fixed Effect" GLM for merging LR and RL ' 'phase-encoding directions for subject %s ...' % (subject_data.subject_id)) fmri_glm = FMRILinearModel( subject_data.func, [design_matrix.matrix for design_matrix in design_matrices], mask='compute') fmri_glm.fit(do_scaling=True, model='ar1') print "... done.\r\n" # save computed mask mask_path = os.path.join(subject_data.output_dir, "mask.nii") print "Saving mask image to %s ..." % mask_path nibabel.save(fmri_glm.mask, mask_path) print "... done.\r\n" z_maps = {} effects_maps = {} map_dirs = {} try: for contrast_id, contrast_val in contrasts.iteritems(): print "\tcontrast id: %s" % contrast_id z_map, eff_map = fmri_glm.contrast(contrast_val, con_id=contrast_id, output_z=True, output_effects=True) # store stat maps to disk for map_type, out_map in zip(['z', 'effects'], [z_map, eff_map]): map_dir = os.path.join(subject_data.output_dir, '%s_maps' % map_type) map_dirs[map_type] = map_dir if not os.path.exists(map_dir): os.makedirs(map_dir) map_path = os.path.join( map_dir, '%s_%s.nii' % (map_type, contrast_id)) print "\t\tWriting %s ..." % map_path nibabel.save(out_map, map_path) # collect zmaps for contrasts we're interested in if map_type == 'z': z_maps[contrast_id] = map_path if map_type == 'effects': effects_maps[contrast_id] = map_path return effects_maps, z_maps, mask_path, map_dirs except: return None # compute native-space maps and mask stuff = mem.cache(tortoise)(subject_data.func, subject_data.anat) if stuff is None: return None effects_maps, z_maps, mask_path, map_dirs = stuff # remove repeated contrasts contrasts = dict((cid, cval[0]) for cid, cval in contrasts.iteritems()) import json json.dump( dict((k, list(v)) for k, v in contrasts.iteritems()), open(os.path.join(subject_data.tmp_output_dir, "contrasts.json"), "w")) subject_data.contrasts = contrasts if normalize: assert hasattr(subject_data, "parameter_file") subject_data.native_effects_maps = effects_maps subject_data.native_z_maps = z_maps subject_data.native_mask_path = mask_path # warp effects maps and mask from native to standard space (MNI) apply_to_files = [ v for _, v in subject_data.native_effects_maps.iteritems() ] + [subject_data.native_mask_path] tmp = nipype_mem.cache(spm.Normalize)( parameter_file=getattr(subject_data, "parameter_file"), apply_to_files=apply_to_files, write_bounding_box=[[-78, -112, -50], [78, 76, 85]], write_voxel_sizes=func_write_voxel_sizes, write_wrap=[0, 0, 0], write_interp=1, jobtype='write', ignore_exception=False, ).outputs.normalized_files subject_data.mask = hard_link(tmp[-1], subject_data.output_dir) subject_data.effects_maps = dict( zip(effects_maps.keys(), hard_link(tmp[:-1], map_dirs["effects"]))) # warp anat image subject_data.anat = hard_link( nipype_mem.cache(spm.Normalize)( parameter_file=getattr(subject_data, "parameter_file"), apply_to_files=subject_data.anat, write_bounding_box=[[-78, -112, -50], [78, 76, 85]], write_voxel_sizes=anat_write_voxel_sizes, write_wrap=[0, 0, 0], write_interp=1, jobtype='write', ignore_exception=False, ).outputs.normalized_files, subject_data.anat_output_dir) else: subject_data.mask = mask_path subject_data.effects_maps = effects_maps subject_data.z_maps = z_maps return subject_data
def preproc(funcfile, anatfile, sid, outdir, repetitiontime, template, jipdir, erase, resample, interleaved, sliceorder, realign_dof, realign_to_vol, warp, warp_njobs, warp_index, warp_file, warp_restrict, delta_te, dwell_time, manufacturer, blip_files, blip_enc_dirs, unwarp_direction, phase_file, magnitude_file, anatorient, funcorient, kernel_size, fslconfig, normalization_trf, coregistration_trf, recon1, recon2, auto, verbose): """ fMRI preprocessings using FSL, SPM, JIP, and ANTS. """ # TODO: remove when all controls available in pypipe if not isinstance(erase, bool): erase = eval(erase) resample = eval(resample) interleaved = eval(interleaved) realign_to_vol = eval(realign_to_vol) warp = eval(warp) recon1 = eval(recon1) recon2 = eval(recon2) auto = eval(auto) warp_restrict = eval(warp_restrict) blip_files = None if blip_files == "" else eval(blip_files) blip_enc_dirs = eval(blip_enc_dirs) # Read input parameters funcfile = os.path.abspath(funcfile) anatfile = os.path.abspath(anatfile) template = os.path.abspath(template) jipdir = os.path.abspath(jipdir) realign_to_mean = not realign_to_vol subjdir = os.path.join(os.path.abspath(outdir), sid) cachedir = os.path.join(subjdir, "cachedir") outputs = {} if erase and os.path.isdir(subjdir): shutil.rmtree(subjdir) if not os.path.isdir(cachedir): os.makedirs(cachedir) nipype_memory = NipypeMemory(cachedir) joblib_memory = JoblibMemory(cachedir, verbose=verbose) def display_outputs(outputs, verbose, **kwargs): """ Simple function to display/store step outputs. """ if verbose > 0: print("-" * 50) for key, val in kwargs.items(): print("{0}: {1}".format(key, val)) print("-" * 50) outputs.update(kwargs) # Check input parameters template_axes = guess_orientation(template) if template_axes != "RAS": raise ValueError("The template orientation must be 'RAS', '{0}' " "found.".format(template_axes)) check_jip_install(jipdir) if sliceorder not in ("ascending", "descending"): raise ValueError("Supported slice order are: ascending & descending.") # Slice timing fslenv = environment(fslconfig) if (fslenv["FSLDIR"] != os.environ.get("FSLDIR", "")): os.environ = concat_environment(os.environ, fslenv) st_dir = os.path.join(subjdir, STEPS["slice_timing"]) if not os.path.isdir(st_dir): os.mkdir(st_dir) fsl.FSLCommand.set_default_output_type('NIFTI_GZ') interface = nipype_memory.cache(fsl.SliceTimer) returncode = interface( in_file=funcfile, interleaved=interleaved, slice_direction=3, time_repetition=repetitiontime, index_dir=False if sliceorder == "ascending" else True, out_file=os.path.join( st_dir, os.path.basename(funcfile).split(".")[0] + ".nii.gz")) st_outputs = returncode.outputs.get() slice_time_corrected_file = st_outputs["slice_time_corrected_file"] display_outputs(outputs, verbose, slice_time_corrected_file=slice_time_corrected_file) # B0 inhomogeneities: topup or fugue or None + motion induced if warp: warp_dir = os.path.join(subjdir, STEPS["warp"]) if not os.path.isdir(warp_dir): os.mkdir(warp_dir) if blip_files is not None: interface = joblib_memory.cache(topup) fieldmap_hz_file, unwarped_epi_file = interface( blip_up_file=blip_files[0], blip_down_file=blip_files[1], blip_up_phase_enc_dir=blip_enc_dirs[0], blip_down_phase_enc_dir=blip_enc_dirs[1], apply_to=slice_time_corrected_file, unwarp_direction=unwarp_direction, dwell_time=dwell_time, outdir=warp_dir, fsl_sh=fslconfig) elif phase_file is not None: interface = joblib_memory.cache(fugue) magnitude_brain_mask_file, vsm_file, unwarped_epi_file = interface( epi_file=slice_time_corrected_file, phase_file=phase_file, magnitude_file=magnitude_file, delta_te=delta_te, dwell_time=dwell_time, unwarp_direction=unwarp_direction, manufacturer=manufacturer, outdir=warp_dir, fsl_sh=fslconfig, verbose=verbose) else: unwarped_epi_file = slice_time_corrected_file interface = joblib_memory.cache(timeserie_to_reference) b0_corrected_file = interface(tfile=unwarped_epi_file, rindex=warp_index, restrict_deformation=warp_restrict, rfile=warp_file, outdir=warp_dir, njobs=warp_njobs, clean_tmp=True) else: b0_corrected_file = slice_time_corrected_file display_outputs(outputs, verbose, b0_corrected_file=b0_corrected_file) # Reorient images not in RAS coordinate system and # reorient images to match the orientation of the standard MNI152 template. reorient_dir = os.path.join(subjdir, STEPS["reorient"]) if not os.path.isdir(reorient_dir): os.mkdir(reorient_dir) reoriented_funcfile = b0_corrected_file reoriented_anatfile = anatfile interface = joblib_memory.cache(reorient_image) if funcorient != "RAS": reoriented_funcfile = interface(b0_corrected_file, axes=funcorient, prefix="o", output_directory=reorient_dir) if anatorient != "RAS": reoriented_anatfile = interface(anatfile, axes=anatorient, prefix="o", output_directory=reorient_dir) standard_funcfile = os.path.join( reorient_dir, "d" + os.path.basename(reoriented_funcfile).split(".")[0]) standard_anatfile = os.path.join( reorient_dir, "d" + os.path.basename(reoriented_anatfile).split(".")[0]) interface = joblib_memory.cache(fslreorient2std) standard_funcfile = interface(reoriented_funcfile, standard_funcfile, fslconfig=fslconfig) standard_anatfile = interface(reoriented_anatfile, standard_anatfile, fslconfig=fslconfig) display_outputs(outputs, verbose, standard_funcfile=standard_funcfile, standard_anatfile=standard_anatfile) # Downsample template if resample: template = resample_image(source_file=template, target_file=standard_anatfile, out_file=os.path.join( subjdir, "template.nii.gz"), fslconfig=fslconfig) # Realign realign_dir = os.path.join(subjdir, STEPS["realign"]) if not os.path.isdir(realign_dir): os.mkdir(realign_dir) realign_func_rootfile = os.path.join( realign_dir, "r" + os.path.basename(standard_funcfile).split(".")[0]) interface = joblib_memory.cache(mcflirt) realign_funcfile, realign_func_meanfile, realign_func_parfile = interface( in_file=standard_funcfile, out_fileroot=realign_func_rootfile, cost="normcorr", bins=256, dof=realign_dof, refvol=warp_index, reffile=warp_file, reg_to_mean=realign_to_mean, mats=True, plots=True, verbose=verbose, shfile=fslconfig) display_outputs(outputs, verbose, realign_funcfile=realign_funcfile, realign_func_meanfile=realign_func_meanfile) # Early stop detected if recon1: print( "[warn] User requested a processing early stop. Remove the 'recon1' " "option to resume.") return outputs # Normalization. normalization_dir = os.path.join(subjdir, STEPS["normalization"]) if not os.path.isdir(normalization_dir): os.mkdir(normalization_dir) if normalization_trf is not None: shutil.copyfile(normalization_trf, os.path.join(normalization_dir, "align.com")) interface = joblib_memory.cache(jip_align) (register_anatfile, register_anat_maskfile, native_anat_maskfile, align_normfile) = interface(source_file=standard_anatfile, target_file=template, outdir=normalization_dir, jipdir=jipdir, prefix="w", auto=auto, non_linear=True, fslconfig=fslconfig) display_outputs(outputs, verbose, register_anatfile=register_anatfile, register_anat_maskfile=register_anat_maskfile, native_anat_maskfile=native_anat_maskfile, align_normfile=align_normfile) # Tissues segmentation and spatial intensity variations correction. inhomogeneities_dir = os.path.join(subjdir, STEPS["inhomogeneities"]) if not os.path.isdir(inhomogeneities_dir): os.mkdir(inhomogeneities_dir) biascorrected_anatfile = os.path.join( inhomogeneities_dir, "n4_" + os.path.basename(native_anat_maskfile)) bias_anatfile = os.path.join( inhomogeneities_dir, "n4field_" + os.path.basename(native_anat_maskfile)) n4 = ants.N4BiasFieldCorrection() interface = nipype_memory.cache(ants.N4BiasFieldCorrection) returncode = interface(dimension=3, input_image=native_anat_maskfile, bspline_fitting_distance=200, shrink_factor=2, n_iterations=[50, 50, 40, 30], convergence_threshold=1e-6, output_image=biascorrected_anatfile, bias_image=bias_anatfile) n4_outputs = returncode.outputs.get() display_outputs(outputs, verbose, bias_anatfile=bias_anatfile, biascorrected_anatfile=biascorrected_anatfile) # Coregistration. coregistration_dir = os.path.join(subjdir, STEPS["coregistration"]) if not os.path.isdir(coregistration_dir): os.mkdir(coregistration_dir) if coregistration_trf is not None: shutil.copy(coregistration_trf, coregistration_dir) interface = joblib_memory.cache(jip_align) (register_func_meanfile, register_func_mean_maskfile, native_func_mean_maskfile, align_coregfile) = interface(source_file=realign_func_meanfile, target_file=biascorrected_anatfile, outdir=coregistration_dir, jipdir=jipdir, prefix="w", auto=auto, non_linear=False, fslconfig=fslconfig) display_outputs(outputs, verbose, register_func_meanfile=register_func_meanfile, register_func_mean_maskfile=register_func_mean_maskfile, native_func_mean_maskfile=native_func_mean_maskfile, align_coregfile=align_coregfile) # Early stop detected if recon2: print( "[warn] User requested a processing early stop. Remove the 'recon2' " "option to resume.") return outputs # Wrap functional: resample the functional serie and mask the registered serie. wrap_dir = os.path.join(subjdir, STEPS["wrap"]) if not os.path.isdir(wrap_dir): os.mkdir(wrap_dir) interface = joblib_memory.cache(apply_jip_align) deformed_files = interface(apply_to_files=[realign_funcfile], align_with=[align_coregfile, align_normfile], outdir=wrap_dir, jipdir=jipdir, prefix="w", apply_inv=False) register_funcfile = deformed_files[0] register_func_mask_fileroot = os.path.join( wrap_dir, "m" + os.path.basename(register_funcfile).split(".")[0]) interface = joblib_memory.cache(apply_mask) register_func_maskfile = interface( input_file=register_funcfile, output_fileroot=register_func_mask_fileroot, mask_file=template, fslconfig=fslconfig) display_outputs(outputs, verbose, register_funcfile=register_funcfile, register_func_maskfile=register_func_maskfile) # Smooth the functional serie. smooth_dir = os.path.join(subjdir, STEPS["smooth"]) if not os.path.isdir(smooth_dir): os.mkdir(smooth_dir) interface = nipype_memory.cache(fsl.Smooth) returncode = interface( in_file=register_func_maskfile, fwhm=kernel_size, output_type="NIFTI", smoothed_file=os.path.join( smooth_dir, "smooth_" + os.path.basename(register_func_maskfile).split(".")[0] + ".nii")) smooth_outputs = returncode.outputs.get() smoothed_file = smooth_outputs["smoothed_file"] display_outputs(outputs, verbose, smoothed_file=smoothed_file) # Copy the results to the root directory: use Nifti format. nibabel.load(smoothed_file).to_filename(os.path.join(subjdir, "sMNI.nii")) nibabel.load(register_func_maskfile).to_filename( os.path.join(subjdir, "MNI.nii")) nibabel.load(register_anat_maskfile).to_filename( os.path.join(subjdir, "anat.nii")) # Compute some snaps assessing the different processing steps. snapdir = os.path.join(subjdir, STEPS["snaps"]) if not os.path.isdir(snapdir): os.mkdir(snapdir) interface = joblib_memory.cache(triplanar) # > generate coregistration plot coregister_fileroot = os.path.join(snapdir, "coregister") coregister_file = interface(input_file=register_func_meanfile, output_fileroot=coregister_fileroot, overlays=[standard_anatfile], overlays_colors=None, contours=True, edges=False, overlay_opacities=[0.7], resolution=300) # > generate normalization plot normalize_fileroot = os.path.join(snapdir, "normalization") normalize_file = interface(input_file=register_anatfile, output_fileroot=normalize_fileroot, overlays=[template], overlays_colors=None, contours=True, edges=False, overlay_opacities=[0.7], resolution=300) # > generate a motion parameter plot interface = joblib_memory.cache(plot_fsl_motion_parameters) realign_motion_file = os.path.join(snapdir, "realign_motion_parameters.png") interface(realign_func_parfile, realign_motion_file) display_outputs(outputs, verbose, normalize_file=normalize_file, realign_motion_file=realign_motion_file, coregister_file=coregister_file) # Generate a QC reporting reportdir = os.path.join(subjdir, STEPS["report"]) reportfile = os.path.join(reportdir, "QC_preproc_{0}.pdf".format(sid)) if not os.path.isdir(reportdir): os.mkdir(reportdir) interface = joblib_memory.cache(generate_pdf) tic = datetime.now() date = "{0}-{1}-{2}".format(tic.year, tic.month, tic.day) interface(datapath=snapdir, struct_file=os.path.join( os.path.abspath(os.path.dirname(pypreclin.__file__)), "utils", "resources", "pypreclin_qcpreproc.json"), author="NeuroSpin", client="-", poweredby="FSL-SPM-Nipype-JIP", project="-", timepoint="-", subject=sid, date=date, title="fMRI Preprocessing QC Reporting", filename=reportfile, pagesize=None, left_margin=10, right_margin=10, top_margin=20, bottom_margin=20, show_boundary=False, verbose=0) display_outputs(outputs, verbose, reportfile=reportfile) return outputs