Esempio n. 1
0
def define_good_voxels(input_fMRI_4D, ribbon_vol, goodvoxels_vol, tmpdir,
          NeighborhoodSmoothing = "5", CI_limit = "0.5"):
    '''
    does diagnostics on input_fMRI_4D volume, within the ribbon_out mask,
    produces a goodvoxels_vol volume mask
    '''

    ## calculate Coefficient of Variation (cov) of the fMRI
    tmean_vol = os.path.join(tmpdir, 'Mean.nii.gz')
    TstdVol = os.path.join(tmpdir, 'SD.nii.gz')
    cov_vol = os.path.join(tmpdir, 'cov.nii.gz')
    run(['fslmaths', input_fMRI_4D, '-Tmean', tmean_vol, '-odt', 'float'])
    run(['fslmaths', input_fMRI_4D, '-Tstd', TstdVol, '-odt', 'float'])
    run(['fslmaths', TstdVol, '-div', tmean_vol, cov_vol])

    ## calculate a cov ribbon - modulated by the NeighborhoodSmoothing factor
    cov_ribbon = os.path.join(tmpdir, 'cov_ribbon.nii.gz')
    cov_ribbon_norm = os.path.join(tmpdir, 'cov_ribbon_norm.nii.gz')
    SmoothNorm = os.path.join(tmpdir, 'SmoothNorm.nii.gz')
    cov_ribbon_norm_smooth = os.path.join(tmpdir, 'cov_ribbon_norm_smooth.nii.gz')
    cov_norm_modulate = os.path.join(tmpdir, 'cov_norm_modulate.nii.gz')
    cov_norm_modulate_ribbon = os.path.join(tmpdir, 'cov_norm_modulate_ribbon.nii.gz')
    run(['fslmaths', cov_vol,'-mas', ribbon_vol, cov_ribbon])
    cov_ribbonMean = first_word(get_stdout(['fslstats', cov_ribbon, '-M']))
    cov_ribbonMean = cov_ribbonMean.rstrip(os.linesep) ## remove return
    run(['fslmaths', cov_ribbon, '-div', cov_ribbonMean, cov_ribbon_norm])
    run(['fslmaths', cov_ribbon_norm, '-bin', '-s', NeighborhoodSmoothing,
        SmoothNorm])
    run(['fslmaths', cov_ribbon_norm, '-s', NeighborhoodSmoothing,
    '-div', SmoothNorm, '-dilD', cov_ribbon_norm_smooth])
    run(['fslmaths', cov_vol, '-div', cov_ribbonMean,
    '-div', cov_ribbon_norm_smooth, cov_norm_modulate])
    run(['fslmaths', cov_norm_modulate,
    '-mas', ribbon_vol, cov_norm_modulate_ribbon])

    ## get stats from the modulated cov ribbon file and log them
    ribbonMean = first_word(get_stdout(['fslstats', cov_norm_modulate_ribbon, '-M']))
    logger.info('Ribbon Mean: {}'.format(ribbonMean))
    ribbonSTD = first_word(get_stdout(['fslstats', cov_norm_modulate_ribbon, '-S']))
    logger.info('Ribbon STD: {}'.format(ribbonSTD))
    ribbonLower = float(ribbonMean) - (float(ribbonSTD)*float(CI_limit))
    logger.info('Ribbon Lower: {}'.format(ribbonLower))
    ribbonUpper = float(ribbonMean) + (float(ribbonSTD)*float(CI_limit))
    logger.info('Ribbon Upper: {}'.format(ribbonUpper))

    ## get a basic brain mask from the mean img
    bmaskVol = os.path.join(tmpdir, 'mask.nii.gz')
    run(['fslmaths', tmean_vol, '-bin', bmaskVol])

    ## make a goodvoxels_vol mask img
    run(['fslmaths', cov_norm_modulate,
    '-thr', str(ribbonUpper), '-bin', '-sub', bmaskVol, '-mul', '-1',
    goodvoxels_vol])

    return(tmean_vol, cov_vol)
Esempio n. 2
0
 def __set_func_4D(self, func_4D):
     '''
     parse the input func file and test it's validity
     '''
     if not os.path.isfile(func_4D):
       logger.error("fMRI input {} does not exist :(..Exiting".format(func_4D))
       sys.exit(1)
         ## read the number of TR's and the TR from the header
     num_TR = first_word(get_stdout(['fslval', func_4D, 'dim4']))
     #self.middle_TR = int(self.num_TR)//2
     TR_in_ms = first_word(get_stdout(['fslval', func_4D, 'pixdim4']))
     return func_4D, num_TR, TR_in_ms
Esempio n. 3
0
def dilate_out_low_intensity_voxels(settings, hemisphere, mesh_settings):
    '''
    looks for voxels of low intensity and marks dilates to try to correct for them
    Hopefully this is an unnessary step with volume to surface mapping is done well
    '''
    intput_func_gii = func_gii_file(settings.subject.id, settings.fmri_label,
                                    hemisphere, mesh_settings)
    lowvoxels_gii = func_gii_file(settings.subject.id, 'lowvoxels', hemisphere,
                                  mesh_settings)
    middle_TR = int(settings.num_TR) // 2
    low_intensity_thres = get_stdout([
        'wb_command', '-metric-stats', input_func_gii, '-percentile',
        str(settings.dilate_percent_below), '-column',
        str(middle_TR), '-roi',
        medial_wall_roi_file(settings.subject.id, hemisphere, mesh_settings)
    ])
    run([
        'wb_command', '-metric-math', '"(x < {})"'.format(low_intensity_thres),
        lowvoxels_gii, '-var', 'x', input_func_gii, '-column',
        str(middle_TR)
    ])
    run([
        'wb_command', '-metric-dilate', input_func_gii,
        medial_wall_roi_file(settings.subject.id, hemisphere, mesh_settings),
        str(settings.dilate_factor), input_func_gii, '-bad-vertex-roi',
        lowvoxels_gii, '-nearest'
    ])
Esempio n. 4
0
def log_build_environment():
    '''print the running environment info to the logs (info)'''
    logger.info("{}---### Environment Settings ###---".format(os.linesep))
    logger.info("Username: {}".format(get_stdout(['whoami'], echo = False).replace(os.linesep,'')))
    logger.info(ciftify.config.system_info())
    logger.info(ciftify.config.ciftify_version(os.path.basename(__file__)))
    logger.info(ciftify.config.wb_command_version())
    logger.info(ciftify.config.freesurfer_version())
    logger.info(ciftify.config.fsl_version())
    logger.info("---### End of Environment Settings ###---{}".format(os.linesep))
Esempio n. 5
0
def cifti_info(filename):
    '''runs wb_command -file-information" to try to figure out what the file is made off'''
    c_info = get_stdout(
        ['wb_command', '-file-information', filename, '-no-map-info'])
    cinfo = {}
    for line in c_info.split(os.linesep):
        if 'Structure' in line:
            cinfo['has_LSurf'] = True if 'CortexLeft' in line else False
            cinfo['has_RSurf'] = True if 'CortexRight' in line else False
        if 'Maps to Surface' in line:
            cinfo['maps_to_surf'] = True if "true" in line else False
        if 'Maps to Volume' in line:
            cinfo['maps_to_volume'] = True if "true" in line else False
    return cinfo
Esempio n. 6
0
def run_ciftify_subject_fmri(arguments, tmpdir):
    input_fMRI = arguments["<func.nii.gz>"]
    if arguments['--ciftify-work-dir']:
        WorkDir = arguments['--ciftify-work-dir']
    else:
        WorkDir = arguments["--hcp-data-dir"]
    Subject = arguments["<Subject>"]
    NameOffMRI = arguments["<NameOffMRI>"]
    SmoothingFWHM = arguments["--SmoothingFWHM"]
    DilateBelowPct = arguments["--DilateBelowPct"]
    OutputSurfDiagnostics = arguments['--OutputSurfDiagnostics']
    noMNItransform = arguments['--already-in-MNI']
    RegTemplate = arguments['--FLIRT-template']
    FLIRT_dof = arguments['--FLIRT-dof']
    FLIRT_cost = arguments['--FLIRT-cost']
    reg_name = arguments['--reg-name']

    if WorkDir == None: WorkDir = ciftify.config.find_work_dir()

    ## write a bunch of info about the environment to the logs
    log_build_environment()

    logger.info('Arguments:')
    logger.info("\tinput_fMRI: {}".format(input_fMRI))
    if not os.path.isfile(input_fMRI):
        logger.error("input_fMRI does not exist :(..Exiting")
        sys.exit(1)
    logger.info("\tHCP_DATA: {}".format(WorkDir))
    logger.info("\tSubject: {}".format(Subject))
    logger.info("\tNameOffMRI: {}".format(NameOffMRI))
    logger.info("\tSurface Registration: {}".format(reg_name))

    if reg_name == "MSMSulc":
        RegName = "MSMSulc"
    elif reg_name == "FS":
        RegName = "reg.reg_LR"
    else:
        logger.critical('--reg-name argument must be "FS" or "MSMSulc"')
        sys.exit(1)

    if SmoothingFWHM:
        logger.info("\tSmoothingFWHM: {}".format(SmoothingFWHM))
    if DilateBelowPct:
        logger.info(
            "\tWill fill holes defined as data with intensity below {} percentile"
            .format(DilateBelowPct))

    # Setup PATHS
    GrayordinatesResolution = "2"
    LowResMesh = "32"
    DilateFactor = "10"

    #Templates and settings
    AtlasSpaceFolder = os.path.join(WorkDir, Subject, "MNINonLinear")
    DownSampleFolder = os.path.join(AtlasSpaceFolder, "fsaverage_LR32k")
    ResultsFolder = os.path.join(AtlasSpaceFolder, "Results", NameOffMRI)
    AtlasSpaceNativeFolder = os.path.join(AtlasSpaceFolder, "Native")

    logger.info("The following settings are set by default:")
    logger.info(
        "\nGrayordinatesResolution: {}".format(GrayordinatesResolution))
    logger.info('\nLowResMesh: {}k'.format(LowResMesh))
    logger.info(
        'Native space surfaces are in: {}'.format(AtlasSpaceNativeFolder))

    L_sphere = os.path.join(
        AtlasSpaceNativeFolder,
        '{}.L.sphere.{}.native.surf.gii'.format(Subject, RegName))
    if not os.path.exists(L_sphere):
        logger.critical("Registration Sphere {} not found".format(L_sphere))
        sys.exit(1)

    logger.info(
        'The resampled surfaces (those matching the final result are in: {})'.
        format(DownSampleFolder))

    # PipelineScripts=${HCPPIPEDIR_fMRISurf}
    input_fMRI_4D = os.path.join(ResultsFolder, '{}.nii.gz'.format(NameOffMRI))
    input_fMRI_3D = os.path.join(tmpdir, '{}_Mean.nii.gz'.format(NameOffMRI))

    # output files
    if OutputSurfDiagnostics:
        DiagnosticsFolder = os.path.join(ResultsFolder,
                                         'RibbonVolumeToSurfaceMapping')
        logger.info("Diagnostic Files will be written to: {}".format(
            DiagnosticsFolder))
        run(['mkdir', '-p', DiagnosticsFolder])
    else:
        DiagnosticsFolder = tmpdir

    ###### from end of volume mapping pipeline

    ## copy inputs into the ResultsFolder
    run(['mkdir', '-p', ResultsFolder])

    ## read the number of TR's and the TR from the header
    TR_num = first_word(get_stdout(['fslval', input_fMRI, 'dim4']))
    logger.info('Number of TRs: {}'.format(TR_num))
    MiddleTR = int(TR_num) // 2
    logger.info('Middle TR: {}'.format(MiddleTR))
    TR_vol = first_word(get_stdout(['fslval', input_fMRI, 'pixdim4']))
    logger.info('TR(ms): {}'.format(TR_vol))

    ## either transform or copy the input_fMRI
    if noMNItransform:
        run(['cp', input_fMRI, input_fMRI_4D])
    else:
        logger.info(section_header('MNI Transform'))
        logger.info(
            'Running transform to MNIspace with costfunction {} and dof {}'.
            format(FLIRT_cost, FLIRT_dof))
        transform_to_MNI(input_fMRI, input_fMRI_4D, FLIRT_cost, FLIRT_dof,
                         WorkDir, Subject, RegTemplate, tmpdir)

    #Make fMRI Ribbon
    #Noisy Voxel Outlier Exclusion
    #Ribbon-based Volume to Surface mapping and resampling to standard surface
    logger.info(section_header('Making fMRI Ribbon'))

    run(['fslmaths', input_fMRI_4D, '-Tmean', input_fMRI_3D])

    ribbon_vol = os.path.join(DiagnosticsFolder, 'ribbon_only.nii.gz')
    make_cortical_ribbon(Subject, AtlasSpaceNativeFolder, input_fMRI_3D,
                         ribbon_vol)

    goodvoxels_vol = os.path.join(DiagnosticsFolder, 'goodvoxels.nii.gz')
    tmean_vol, cov_vol = define_good_voxels(input_fMRI_4D, ribbon_vol,
                                            goodvoxels_vol, tmpdir)

    logger.info(section_header('Mapping fMRI to 32k Surface'))

    for Hemisphere in ["L", "R"]:

        ## the input surfaces for this section in the AtlasSpaceNativeFolder
        mid_surf_native = os.path.join(
            AtlasSpaceNativeFolder,
            '{}.{}.midthickness.native.surf.gii'.format(Subject, Hemisphere))
        pial_surf = os.path.join(
            AtlasSpaceNativeFolder,
            '{}.{}.pial.native.surf.gii'.format(Subject, Hemisphere))
        white_surf = os.path.join(
            AtlasSpaceNativeFolder,
            '{}.{}.white.native.surf.gii'.format(Subject, Hemisphere))
        roi_native_gii = os.path.join(
            AtlasSpaceNativeFolder,
            '{}.{}.roi.native.shape.gii'.format(Subject, Hemisphere))
        sphere_reg_native = os.path.join(
            AtlasSpaceNativeFolder,
            '{}.{}.sphere.{}.native.surf.gii'.format(Subject, Hemisphere,
                                                     RegName))

        ## the inputs for this section from the DownSampleFolder
        mid_surf_32k = os.path.join(
            DownSampleFolder, '{}.{}.midthickness.{}k_fs_LR.surf.gii'.format(
                Subject, Hemisphere, LowResMesh))
        roi_32k_gii = os.path.join(
            DownSampleFolder, '{}.{}.atlasroi.{}k_fs_LR.shape.gii'.format(
                Subject, Hemisphere, LowResMesh))
        sphere_reg_32k = os.path.join(
            DownSampleFolder,
            '{}.{}.sphere.{}k_fs_LR.surf.gii'.format(Subject, Hemisphere,
                                                     LowResMesh))

        ## now finally, actually project the fMRI input
        input_func_native = os.path.join(
            tmpdir, '{}.{}.native.func.gii'.format(NameOffMRI, Hemisphere))
        run([
            'wb_command', '-volume-to-surface-mapping', input_fMRI_4D,
            mid_surf_native, input_func_native, '-ribbon-constrained',
            white_surf, pial_surf, '-volume-roi', goodvoxels_vol
        ])

        ## dilate to get rid of wholes caused by the goodvoxels_vol mask
        run([
            'wb_command', '-metric-dilate', input_func_native, mid_surf_native,
            DilateFactor, input_func_native, '-nearest'
        ])

        ## Erin's new addition - find what is below a certain percentile and dilate..
        ## Erin's new addition - find what is below a certain percentile and dilate..
        if DilateBelowPct:
            DilThres = get_stdout([
                'wb_command', '-metric-stats', input_func_native,
                '-percentile',
                str(DilateBelowPct), '-column',
                str(MiddleTR), '-roi', roi_native_gii
            ])
            lowvoxels_gii = os.path.join(
                tmpdir, '{}.lowvoxels.native.func.gii'.format(Hemisphere))
            run([
                'wb_command', '-metric-math', '"(x < {})"'.format(DilThres),
                lowvoxels_gii, '-var', 'x', input_func_native, '-column',
                str(MiddleTR)
            ])
            run([
                'wb_command', '-metric-dilate', input_func_native,
                mid_surf_native,
                str(DilateFactor), input_func_native, '-bad-vertex-roi',
                lowvoxels_gii, '-nearest'
            ])
    ## back to the HCP program - do the mask and resample

    ## mask resample than mask combo
        input_func_32k = os.path.join(
            tmpdir,
            '{}.{}.atlasroi.{}k_fs_LR.func.gii'.format(NameOffMRI, Hemisphere,
                                                       LowResMesh))
        mask_and_resample(input_func_native, input_func_32k, roi_native_gii,
                          roi_32k_gii, mid_surf_native, mid_surf_32k,
                          sphere_reg_native, sphere_reg_32k)

        if OutputSurfDiagnostics:
            logger.info(
                section_header('Writing Surface Mapping Diagnotic Files'))

            for mapname in ["mean", "cov"]:

                if mapname == "mean": map_vol = tmean_vol
                if mapname == "cov": map_vol = cov_vol

                ## the output directories for this section
                map_native_gii = os.path.join(
                    tmpdir,
                    '{}.{}.native.func.gii'.format(mapname, Hemisphere))
                map_32k_gii = os.path.join(
                    tmpdir,
                    "{}.{}.{}k_fs_LR.func.gii".format(Hemisphere, mapname,
                                                      LowResMesh))
                run([
                    'wb_command', '-volume-to-surface-mapping', map_vol,
                    mid_surf_native, map_native_gii, '-ribbon-constrained',
                    white_surf, pial_surf, '-volume-roi', goodvoxels_vol
                ])
                run([
                    'wb_command', '-metric-dilate', map_native_gii,
                    mid_surf_native, DilateFactor, map_native_gii, '-nearest'
                ])
                mask_and_resample(map_native_gii, map_32k_gii, roi_native_gii,
                                  roi_32k_gii, mid_surf_native, mid_surf_32k,
                                  sphere_reg_native, sphere_reg_32k)

                mapall_native_gii = os.path.join(
                    tmpdir,
                    '{}_all.{}.native.func.gii'.format(mapname, Hemisphere))
                mapall_32k_gii = os.path.join(
                    tmpdir, "{}.{}_all.{}k_fs_LR.func.gii".format(
                        Hemisphere, mapname, LowResMesh))
                run([
                    'wb_command', '-volume-to-surface-mapping', map_vol,
                    mid_surf_native, mapall_native_gii, '-ribbon-constrained',
                    white_surf, pial_surf
                ])
                mask_and_resample(mapall_native_gii, mapall_32k_gii,
                                  roi_native_gii, roi_32k_gii, mid_surf_native,
                                  mid_surf_32k, sphere_reg_native,
                                  sphere_reg_32k)

            ## now project the goodvoxels to the surface
            goodvoxels_native_gii = os.path.join(
                tmpdir, '{}.goodvoxels.native.func.gii'.format(Hemisphere))
            goodvoxels_32k_gii = os.path.join(
                tmpdir, '{}.goodvoxels.{}k_fs_LR.func.gii'.format(
                    Hemisphere, LowResMesh))
            run([
                'wb_command', '-volume-to-surface-mapping', goodvoxels_vol,
                mid_surf_native, goodvoxels_native_gii, '-ribbon-constrained',
                white_surf, pial_surf
            ])
            mask_and_resample(goodvoxels_native_gii, goodvoxels_32k_gii,
                              roi_native_gii, roi_32k_gii, mid_surf_native,
                              mid_surf_32k, sphere_reg_native, sphere_reg_32k)

            ## Also ouput the resampled low voxels
            if DilateBelowPct:
                lowvoxels_32k_gii = os.path.join(
                    tmpdir, '{}.lowvoxels.{}k_fs_LR.func.gii'.format(
                        Hemisphere, LowResMesh))
                mask_and_resample(lowvoxels_gii, lowvoxels_32k_gii,
                                  roi_native_gii, roi_32k_gii, mid_surf_native,
                                  mid_surf_32k, sphere_reg_native,
                                  sphere_reg_32k)

    if OutputSurfDiagnostics:
        Maps = ['goodvoxels', 'mean', 'mean_all', 'cov', 'cov_all']
        if DilateBelowPct: Maps.append('lowvoxels')
        #   import pbd; pdb.set_trace()
        for Map in Maps:
            run([
                'wb_command', '-cifti-create-dense-scalar',
                os.path.join(
                    DiagnosticsFolder,
                    '{}.atlasroi.{}k_fs_LR.dscalar.nii'.format(
                        Map, LowResMesh)), '-left-metric',
                os.path.join(tmpdir,
                             'L.{}.{}k_fs_LR.func.gii'.format(Map,
                                                              LowResMesh)),
                '-roi-left',
                os.path.join(
                    DownSampleFolder,
                    '{}.L.atlasroi.{}k_fs_LR.shape.gii'.format(
                        Subject, LowResMesh)), '-right-metric',
                os.path.join(tmpdir,
                             'R.{}.{}k_fs_LR.func.gii'.format(Map,
                                                              LowResMesh)),
                '-roi-right',
                os.path.join(
                    DownSampleFolder,
                    '{}.R.atlasroi.{}k_fs_LR.shape.gii'.format(
                        Subject, LowResMesh))
            ])

    ############ The subcortical resampling step...
    logger.info(section_header("Subcortical Processing"))
    logger.info("VolumefMRI: {}".format(input_fMRI_4D))

    Atlas_Subcortical = os.path.join(
        tmpdir, '{}_AtlasSubcortical_s0.nii.gz'.format(NameOffMRI))
    AtlasROIvols = os.path.join(
        AtlasSpaceFolder, "ROIs",
        'Atlas_ROIs.{}.nii.gz'.format(GrayordinatesResolution))

    atlas_roi_vol = subcortical_atlas(input_fMRI_4D, AtlasSpaceFolder,
                                      ResultsFolder, GrayordinatesResolution,
                                      tmpdir)
    resample_subcortical(input_fMRI_4D, atlas_roi_vol, AtlasROIvols,
                         Atlas_Subcortical, tmpdir)

    #Generation of Dense Timeseries
    logger.info(section_header("Generation of Dense Timeseries"))
    cifti_output_s0 = os.path.join(
        ResultsFolder, '{}_Atlas_s0.dtseries.nii'.format(NameOffMRI))
    run([
        'wb_command', '-cifti-create-dense-timeseries', cifti_output_s0,
        '-volume', Atlas_Subcortical, AtlasROIvols, '-left-metric',
        os.path.join(
            tmpdir,
            '{}.L.atlasroi.{}k_fs_LR.func.gii'.format(NameOffMRI, LowResMesh)),
        '-roi-left',
        os.path.join(
            DownSampleFolder,
            '{}.L.atlasroi.{}k_fs_LR.shape.gii'.format(Subject, LowResMesh)),
        '-right-metric',
        os.path.join(
            tmpdir,
            '{}.R.atlasroi.{}k_fs_LR.func.gii'.format(NameOffMRI, LowResMesh)),
        '-roi-right',
        os.path.join(
            DownSampleFolder,
            '{}.R.atlasroi.{}k_fs_LR.shape.gii'.format(Subject, LowResMesh)),
        '-timestep', TR_vol
    ])

    #########cifti smoothing ################
    if SmoothingFWHM:
        logger.info(section_header("Smoothing Output"))
        Sigma = FWHM2Sigma(SmoothingFWHM)
        logger.info("FWHM: {}".format(SmoothingFWHM))
        logger.info("Sigma: {}".format(Sigma))

        run([
            'wb_command', '-cifti-smoothing', cifti_output_s0,
            str(Sigma),
            str(Sigma), 'COLUMN',
            os.path.join(
                ResultsFolder,
                '{}_Atlas_s{}.dtseries.nii'.format(NameOffMRI, SmoothingFWHM)),
            '-left-surface',
            os.path.join(
                DownSampleFolder,
                '{}.L.midthickness.{}k_fs_LR.surf.gii'.format(
                    Subject, LowResMesh)), '-right-surface',
            os.path.join(
                DownSampleFolder,
                '{}.R.midthickness.{}k_fs_LR.surf.gii'.format(
                    Subject, LowResMesh))
        ])