Пример #1
0
def get_teams_to_rectify(narps):
    map_metadata_file = os.path.join(narps.dirs.dirs['orig'],
                                     'narps_neurovault_images_details.csv')
    map_metadata = get_map_metadata(map_metadata_file)
    rectify_status = {}
    # manual fix for one
    rectify_status['R7D1'] = [5, 6]
    for teamID in narps.teams:
        for hyp in [5, 6]:
            mdstring = map_metadata.query(
                'teamID == "%s"' % teamID)['hyp%d_direction' % hyp].iloc[0]
            rectify = mdstring.split()[0] == 'Negative'
            if rectify:
                if teamID not in rectify_status:
                    rectify_status[teamID] = []
                rectify_status[teamID].append(hyp)
    return (rectify_status)
Пример #2
0
    def convert_to_zscores(self, map_metadata_file=None, overwrite=None):
        """
        convert rectified images to z scores
        - unthresholded images could be either t or z images
        - if they are already z then just copy
        - use metadata supplied by teams to determine image type
        """
        log_to_file(self.dirs.logfile,
                    '\n\n%s' % sys._getframe().f_code.co_name)
        func_args = inspect.getargvalues(inspect.currentframe()).locals
        log_to_file(self.dirs.logfile, stringify_dict(func_args))

        if overwrite is None:
            overwrite = self.overwrite
        if map_metadata_file is None:
            map_metadata_file = os.path.join(
                self.dirs.dirs['orig'], 'narps_neurovault_images_details.csv')
        unthresh_stat_type = get_map_metadata(map_metadata_file)
        metadata = get_metadata(self.metadata_file)

        n_participants = metadata[['n_participants', 'NV_collection_string']]

        n_participants.index = metadata.teamID

        unthresh_stat_type = unthresh_stat_type.merge(n_participants,
                                                      left_index=True,
                                                      right_index=True)

        for teamID in self.complete_image_sets:
            if teamID not in unthresh_stat_type.index:
                print('no map metadata for', teamID)
                continue
            # this is a bit of a kludge
            # since some contrasts include all subjects
            # but others only include some
            # we don't have the number of participants in each
            # group so we just use the entire number
            n = unthresh_stat_type.loc[teamID, 'n_participants']

            for hyp in range(1, 10):
                infile = self.teams[teamID].images['unthresh']['rectified'][
                    hyp]
                if not os.path.exists(infile):
                    print('skipping', infile)
                    continue
                self.teams[teamID].images['unthresh']['zstat'][
                    hyp] = os.path.join(self.dirs.dirs['zstat'],
                                        self.teams[teamID].datadir_label,
                                        'hypo%d_unthresh.nii.gz' % hyp)
                if not overwrite and os.path.exists(
                        self.teams[teamID].images['unthresh']['zstat'][hyp]):
                    continue

                if unthresh_stat_type.loc[teamID,
                                          'unthresh_type'].lower() == 't':
                    if not os.path.exists(
                            os.path.dirname(self.teams[teamID].
                                            images['unthresh']['zstat'][hyp])):
                        os.mkdir(
                            os.path.dirname(
                                self.teams[teamID].images['unthresh']['zstat']
                                [hyp]))
                    print("converting %s (hyp %d) to z - %d participants" %
                          (teamID, hyp, n))
                    TtoZ(infile,
                         self.teams[teamID].images['unthresh']['zstat'][hyp],
                         n - 1)
                elif unthresh_stat_type.loc[teamID, 'unthresh_type'] == 'z':
                    if not os.path.exists(
                            os.path.dirname(self.teams[teamID].
                                            images['unthresh']['zstat'][hyp])):
                        os.mkdir(
                            os.path.dirname(
                                self.teams[teamID].images['unthresh']['zstat']
                                [hyp]))
                    if not os.path.exists(self.teams[teamID].images['unthresh']
                                          ['zstat'][hyp]):
                        print('copying', teamID)
                        shutil.copy(
                            infile,
                            os.path.dirname(
                                self.teams[teamID].images['unthresh']['zstat']
                                [hyp]))
                else:
                    # if it's not T or Z then we skip it as it's not usable
                    print('skipping %s - other data type' % teamID)
Пример #3
0
    def create_rectified_images(self, map_metadata_file=None, overwrite=None):
        """
        create rectified images
        - contrasts 5 and 6 were negative contrasts
        some teams uploaded images where negative values
        provided evidence in favor of the contrast
        using metadata provided by teams, we identify these
        images and flip their valence so that all maps
        present positive evidence for each contrast
        """
        log_to_file(self.dirs.logfile,
                    '\n\n%s' % sys._getframe().f_code.co_name)
        func_args = inspect.getargvalues(inspect.currentframe()).locals
        log_to_file(self.dirs.logfile, stringify_dict(func_args))
        if map_metadata_file is None:
            map_metadata_file = os.path.join(
                self.dirs.dirs['orig'], 'narps_neurovault_images_details.csv')
        map_metadata = get_map_metadata(map_metadata_file)
        if overwrite is None:
            overwrite = self.overwrite
        for teamID in self.complete_image_sets:
            for hyp in range(1, 10):
                if hyp in [5, 6]:
                    mdstring = map_metadata.query('teamID == "%s"' %
                                                  teamID)['hyp%d_direction' %
                                                          hyp].iloc[0]
                    rectify = mdstring.split()[0] == 'Negative'
                elif hyp == 9:
                    # manual fix for one team with reversed maps
                    if teamID in ['R7D1']:
                        mdstring = map_metadata.query(
                            'teamID == "%s"' % teamID)['hyp%d_direction' %
                                                       hyp].iloc[0]
                        rectify = True
                else:  # just copy the other hypotheses directly
                    rectify = False

                # load data from unthresh map within
                # positive voxels of thresholded mask
                unthresh_file = self.teams[teamID].images['unthresh'][
                    'resampled'][hyp]

                self.teams[teamID].images['unthresh']['rectified'][
                    hyp] = os.path.join(self.dirs.dirs['rectified'],
                                        self.teams[teamID].datadir_label,
                                        'hypo%d_unthresh.nii.gz' % hyp)

                if not os.path.exists(
                        os.path.dirname(self.teams[teamID].images['unthresh']
                                        ['rectified'][hyp])):
                    os.mkdir(
                        os.path.dirname(self.teams[teamID].images['unthresh']
                                        ['rectified'][hyp]))

                if overwrite or not os.path.exists(
                        self.teams[teamID].images['unthresh']['rectified']
                    [hyp]):
                    # if values were flipped for negative contrasts
                    if rectify:
                        print('rectifying hyp', hyp, 'for', teamID)
                        print(mdstring)
                        print('')
                        img = nibabel.load(unthresh_file)
                        img_rectified = nilearn.image.math_img('img*-1',
                                                               img=img)
                        img_rectified.to_filename(
                            self.teams[teamID].images['unthresh']['rectified']
                            [hyp])
                        self.rectified_list.append((teamID, hyp))
                    else:  # just copy original
                        shutil.copy(
                            unthresh_file,
                            self.teams[teamID].images['unthresh']['rectified']
                            [hyp])
        # write list of rectified teams to disk
        if len(self.rectified_list) > 0:
            with open(
                    os.path.join(self.dirs.dirs['metadata'],
                                 'rectified_images_list.txt'), 'w') as f:
                for l in self.rectified_list:
                    f.write('%s\t%s\n' % (l[0], l[1]))
Пример #4
0
def compare_thresh_unthresh_values(
        dirs, collectionID, logfile,
        unthresh_dataset='orig',
        thresh_dataset='orig',
        verbose=True,
        error_thresh=.05,
        create_histogram=False,
        map_metadata_file=None):
    """examine unthresh values within thresholded map voxels
    to check direction of maps
    if more than error_thresh percent of voxels are
    in opposite direction, then flag a problem
    - we allow a few to bleed over due to interpolation"""
    verbose = True
    hyps = [i for i in range(1, 10)]
    teamID = collectionID.split('_')[1]
    diagnostic_data = pandas.DataFrame({
        'collectionID': collectionID,
        'teamID': teamID,
        'hyp': hyps,
        'autorectify': False,
        'problem': numpy.nan,
        'reverse_contrast': False,
        'n_thresh_vox': numpy.nan,
        'min_unthresh': numpy.nan,
        'max_unthresh': numpy.nan,
        'p_pos_unthresh': numpy.nan,
        'p_neg_unthresh': numpy.nan})

    teamdir_unthresh = os.path.join(
        dirs.dirs[unthresh_dataset],
        collectionID
    )
    teamdir_thresh = os.path.join(
        dirs.dirs[thresh_dataset],
        collectionID
    )
    print('using %s for thresh and %s for unthresh' %
          (thresh_dataset, unthresh_dataset))
    if not os.path.exists(teamdir_unthresh):
        print('no unthresh %s for %s' % (unthresh_dataset, collectionID))
        print(teamdir_unthresh)
        return(None)
    if not os.path.exists(teamdir_thresh):
        print('no thresh %s for %s' % (thresh_dataset, collectionID))
        print(teamdir_unthresh)
        return(None)

    for hyp in hyps:
        autorectify = False
        threshfile = os.path.join(
            teamdir_thresh, 'hypo%d_thresh.nii.gz' % hyp)
        if not os.path.exists(threshfile):
            print('no thresh hyp %d for %s' % (hyp, collectionID))
            continue
        threshdata = nibabel.load(threshfile).get_data().flatten()
        threshdata = numpy.nan_to_num(threshdata)
        n_thresh_vox = numpy.sum(threshdata > 0)
        diagnostic_data.loc[
            diagnostic_data.hyp == hyp,
            'n_thresh_vox'] = n_thresh_vox

        if n_thresh_vox == 0:
            log_to_file(
                logfile,
                'WARN: %s %d - empty mask' % (
                    collectionID, hyp
                ))

        unthreshfile = os.path.join(
            teamdir_thresh, 'hypo%d_unthresh.nii.gz' % hyp)
        if not os.path.exists(unthreshfile):
            print('no unthresh hyp %d for %s' % (hyp, collectionID))
            continue
        unthreshdata = nibabel.load(unthreshfile).get_data().flatten()
        unthreshdata = numpy.nan_to_num(unthreshdata)
        if not unthreshdata.shape == threshdata.shape:
            log_to_file(
                logfile,
                'ERROR: thresh/unthresh size mismatch for %s hyp%d' %
                (collectionID, hyp))
            continue
        if numpy.sum(threshdata > 0) > 0:
            inmask_unthreshdata = unthreshdata[threshdata > 0]
            min_val = numpy.min(inmask_unthreshdata)
            max_val = numpy.max(inmask_unthreshdata)
            p_pos_unthresh = numpy.mean(inmask_unthreshdata > 0)
            p_neg_unthresh = numpy.mean(inmask_unthreshdata < 0)
        else:
            min_val = 0
            max_val = 0
            p_pos_unthresh = 0
            p_neg_unthresh = 0

        if max_val < 0:  # need to rectify
            autorectify = True
            if verbose:
                print('autorectify:', teamID, hyp)
            diagnostic_data.loc[
                diagnostic_data.hyp == hyp,
                'autorectify'] = True
        diagnostic_data.loc[
            diagnostic_data.hyp == hyp,
            'min_unthresh'] = min_val
        diagnostic_data.loc[
            diagnostic_data.hyp == hyp,
            'max_unthresh'] = max_val
        diagnostic_data.loc[
            diagnostic_data.hyp == hyp,
            'p_pos_unthresh'] = p_pos_unthresh
        diagnostic_data.loc[
            diagnostic_data.hyp == hyp,
            'p_neg_unthresh'] = p_neg_unthresh
        min_p_direction = numpy.min([p_pos_unthresh, p_neg_unthresh])
        if min_p_direction > error_thresh:
            log_to_file(
                logfile,
                'WARN: %s hyp%d invalid in-mask values (%f, %f)' % (
                    collectionID, hyp, p_neg_unthresh, p_pos_unthresh
                ))
            diagnostic_data.loc[
                diagnostic_data.hyp == hyp,
                'problem'] = True
            if create_histogram:
                # also load their orig thresh map and create a histogram
                orig_threshfile = os.path.join(
                    dirs.dirs['orig'],
                    collectionID,
                    'hypo%d_thresh.nii.gz' % hyp)
                threshdata = nibabel.load(orig_threshfile).get_data()
                threshdata = threshdata[numpy.abs(threshdata) > 1e-6]
                plt.hist(threshdata, bins=50)
                plt.savefig(
                    os.path.join(
                        dirs.dirs['diagnostics'],
                        'thresh_hist_%s_%d.pdf' % (
                            collectionID, hyp
                        )
                    )
                )
                plt.close()

        # also get info from metadata file about direction
        # of contrasts
        if map_metadata_file is None:
            map_metadata_file = os.path.join(
                dirs.dirs['orig'],
                'narps_neurovault_images_details_responses_corrected.csv')
        map_metadata = get_map_metadata(map_metadata_file)

        reverse_contrast = False

        if hyp in [5, 6]:
            mdstring = map_metadata.query(
                'teamID == "%s"' % teamID
                )['hyp%d_direction' % hyp].iloc[0]
            reverse_contrast = mdstring.split()[0] == 'Negative'
            if verbose:
                print('manual rectify:', teamID, hyp)
        elif hyp == 9 and teamID in ['R7D1']:
            # manual fix for one team with reversed maps
            reverse_contrast = True
        diagnostic_data.loc[
            diagnostic_data.hyp == hyp,
            'reverse_contrast'] = reverse_contrast
        if reverse_contrast != autorectify:
            log_to_file(
                logfile,
                'WARN: %s %d rectification mismatch' %
                (collectionID, hyp))

    return(diagnostic_data)