コード例 #1
0
ファイル: second_level_model.py プロジェクト: nistats/nistats
def _infer_effect_maps(second_level_input, contrast_def):
    """Deals with the different possibilities of second_level_input"""
    # Build the design matrix X and list of imgs Y for GLM fit
    if isinstance(second_level_input, pd.DataFrame):
        # If a Dataframe was given, we expect contrast_def to be in map_name
        def _is_contrast_def(x):
            return x['map_name'] == contrast_def
        is_con = second_level_input.apply(_is_contrast_def, axis=1)
        effect_maps = second_level_input[is_con]['effects_map_path'].tolist()

    elif isinstance(second_level_input[0], FirstLevelModel):
        # Get the first level model maps
        effect_maps = []
        for model in second_level_input:
            effect_map = model.compute_contrast(contrast_def,
                                                output_type='effect_size')
            effect_maps.append(effect_map)

    else:
        effect_maps = second_level_input

    # check niimgs
    for niimg in effect_maps:
        check_niimg(niimg, ensure_ndim=3)

    return effect_maps
コード例 #2
0
ファイル: second_level_model.py プロジェクト: m9h/nistats
def _infer_effect_maps(second_level_input, contrast_def):
    """Deals with the different possibilities of second_level_input"""
    # Build the design matrix X and list of imgs Y for GLM fit
    if isinstance(second_level_input, pd.DataFrame):
        # If a Dataframe was given, we expect contrast_def to be in map_name
        def _is_contrast_def(x):
            return x['map_name'] == contrast_def

        is_con = second_level_input.apply(_is_contrast_def, axis=1)
        effect_maps = second_level_input[is_con]['effects_map_path'].tolist()

    elif isinstance(second_level_input[0], FirstLevelModel):
        # Get the first level model maps
        effect_maps = []
        for model in second_level_input:
            effect_map = model.compute_contrast(contrast_def,
                                                output_type='effect_size')
            effect_maps.append(effect_map)

    else:
        effect_maps = second_level_input

    # check niimgs
    for niimg in effect_maps:
        check_niimg(niimg, ensure_ndim=3)

    return effect_maps
コード例 #3
0
ファイル: test_atlas.py プロジェクト: salma1601/sammba-mri
def test_fetch_atlas_waxholm_rat_2014():
    datadir = os.path.join(tst.tmpdir, 'waxholm_rat_2014')
    os.mkdir(datadir)
    # Create dummy json labels file
    json_filename = os.path.join(datadir, 'WHS_SD_rat_labels.json')
    with open(json_filename, 'w') as json_content:
        json.dump({"216": "Spinal cord"}, json_content)

    # default resolution
    bunch = atlas.fetch_atlas_waxholm_rat_2014(
        data_dir=tst.tmpdir, verbose=0)
    assert_equal(
        bunch['t2star'],
        os.path.join(datadir, 'WHS_SD_rat_T2star_v1_01_downsample3.nii.gz'))
    assert_equal(
        bunch['maps'],
        os.path.join(datadir, 'WHS_SD_rat_atlas_v1_01_downsample3.nii.gz'))
    assert_equal(len(tst.mock_url_request.urls), 2)

    assert_not_equal(bunch.description, '')

    # Downsampled 2 times
    bunch = atlas.fetch_atlas_waxholm_rat_2014(
        data_dir=tst.tmpdir, verbose=0, downsample='78')
    assert_equal(
        bunch['t2star'],
        os.path.join(datadir, 'WHS_SD_rat_T2star_v1_01_downsample2.nii.gz'))
    assert_equal(
        bunch['maps'],
        os.path.join(datadir, 'WHS_SD_rat_atlas_v1_01_downsample2.nii.gz'))
    assert_equal(len(tst.mock_url_request.urls), 4)

    # test resampling
    anat_file = os.path.join(os.path.dirname(testing_data.__file__),
                             'anat.nii.gz')
    anat_img = check_niimg(anat_file)
    anat_img.to_filename(bunch['t2star'])
    anat_img = check_niimg(anat_file, dtype=int)
    anat_img.to_filename(bunch['maps'])
    bunch = atlas.fetch_atlas_waxholm_rat_2014(
        data_dir=tst.tmpdir, verbose=0, downsample='200')
    assert_equal(len(tst.mock_url_request.urls), 4)
    assert_equal(
        bunch['t2star'],
        os.path.join(datadir, 'WHS_SD_rat_T2star_v1_01_200um.nii.gz'))
    assert_equal(
        bunch['maps'],
        os.path.join(datadir, 'WHS_SD_rat_atlas_v1_01_200um.nii.gz'))
    assert_array_almost_equal(nibabel.load(bunch['t2star']).header.get_zooms(),
                              (.2, .2, .2))
    assert_array_almost_equal(nibabel.load(bunch['maps']).header.get_zooms(),
                              (.2, .2, .2))
コード例 #4
0
ファイル: test_atlas.py プロジェクト: sammba-mri/sammba-mri
def test_fetch_atlas_dorr_2008():
    datadir = os.path.join(tst.tmpdir, 'dorr_2008')
    os.mkdir(datadir)
    dummy = open(os.path.join(datadir, 'c57_brain_atlas_labels.csv'), 'w')
    dummy.write("\n1,amygdala,51,151\n27,fourth ventricle,118,118")
    dummy.close()

    # Default resolution
    bunch = atlas.fetch_atlas_dorr_2008(data_dir=tst.tmpdir, verbose=0)
    assert_equal(len(tst.mock_url_request.urls), 2)
    assert_equal(bunch['t2'], os.path.join(datadir,
                                           'Dorr_2008_average.nii.gz'))
    assert_equal(bunch['maps'], os.path.join(datadir,
                                             'Dorr_2008_labels.nii.gz'))

    # test resampling
    anat_file = os.path.join(os.path.dirname(testing_data.__file__),
                             'anat.nii.gz')
    anat_img = check_niimg(anat_file)
    anat_img.to_filename(bunch['t2'])
    anat_img = check_niimg(anat_file, dtype=int)
    anat_img.to_filename(bunch['maps'])

    bunch = atlas.fetch_atlas_dorr_2008(data_dir=tst.tmpdir,
                                        verbose=0,
                                        downsample='100')
    assert_equal(bunch['t2'],
                 os.path.join(datadir, 'Dorr_2008_average_100um.nii.gz'))
    assert_equal(bunch['maps'],
                 os.path.join(datadir, 'Dorr_2008_labels_100um.nii.gz'))
    assert_array_almost_equal(
        nibabel.load(bunch['t2']).header.get_zooms(), (.1, .1, .1))
    assert_array_almost_equal(
        nibabel.load(bunch['maps']).header.get_zooms(), (.1, .1, .1))
    assert_equal(nibabel.load(bunch['maps']).get_data().dtype, np.dtype(int))
    assert_equal(len(tst.mock_url_request.urls), 2)
    assert_equal(len(bunch['names']), 3)
    assert_equal(len(bunch['labels']), 3)

    # test with 'minc' format
    bunch = atlas.fetch_atlas_dorr_2008(data_dir=tst.tmpdir,
                                        verbose=0,
                                        image_format='minc')
    assert_equal(len(tst.mock_url_request.urls), 4)
    assert_equal(bunch['t2'],
                 os.path.join(datadir, 'male-female-mouse-atlas.mnc'))
    assert_equal(bunch['maps'],
                 os.path.join(datadir, 'c57_fixed_labels_resized.mnc'))
    assert_equal(len(bunch['names']), 3)
    assert_equal(len(bunch['labels']), 3)
    assert_not_equal(bunch.description, '')
コード例 #5
0
def dices(labels_file1, labels_file2):
    data1 = check_niimg(labels_file1).get_data().astype(int)
    data2 = check_niimg(labels_file2).get_data().astype(int)
    labels1 = np.unique(data1).tolist()
    labels2 = np.unique(data2).tolist()
    dice_coefs = []
    labels = np.unique(labels1 + labels2).tolist()
    labels.remove(0)
    for label in labels:
        if label in labels1 and label in labels2:
            mask_data1 = data1 == label
            mask_data2 = data2 == label
            dice_coefs.append(mask_arrays_to_dice(mask_data1, mask_data2))
        else:
            dice_coefs.append(0.)

    return labels, dice_coefs
コード例 #6
0
ファイル: average_images.py プロジェクト: qmac/merlinalysis
def average_images(files):
    all_data = []
    for f in files:
        data = check_niimg(f).get_data()
        all_data.append(data)

    std = np.std(all_data, axis=0)
    avg = np.mean(all_data, axis=0)

    # I don't think this is right
    t_scores = avg / ((1e-10 + std) / np.sqrt(float(len(files))))

    return avg, t_scores
コード例 #7
0
ファイル: model_fitting.py プロジェクト: qmac/merlinalysis
def run_analysis(image_file, event_file, output_file, mask_file=None):
    # Load functional data
    img = check_niimg(image_file, ensure_ndim=4)
    img_data = img.get_data()
    print('Data matrix shape: ' + str(img_data.shape))

    # Apply mask if provided
    if mask_file:
        mask = check_niimg(mask_file, ensure_ndim=3).get_data().astype(bool)
        img_data = img_data[mask]
        print('Masked data matrix shape: ' + str(img_data.shape))
    else:
        img_data = np.reshape(img_data, (245245, img_data.shape[3]))

    # Get design matrix from nistats
    dm = get_design_matrix(event_file, img_data.shape[1])
    print('Design matrix shape: ' + str(dm.shape))

    # Normalize design matrix (data normalized in preprocessing)
    X = zscore(dm.as_matrix().T).T
    if PLOT:
        plt.plot(X)
        plt.show()

    # Fit and compute R squareds
    weights, r_squared = compute_rsquared(X, img_data.T)
    print('R squared matrix shape: ' + str(r_squared.shape))

    # Output results
    if mask_file:
        output = np.zeros((65, 77, 49))
        output[mask] = r_squared
    else:
        output = np.reshape(r_squared, (65, 77, 49))
        output[output == 1.0] = 0.0
    r_squared_img = Nifti1Image(output, affine=img.affine)
    r_squared_img.to_filename(output_file)
コード例 #8
0
def compute_mask_contour(mask_file, write_dir=None, out_file=None):
    mask_img = check_niimg(mask_file)
    vertices, _ = measure.marching_cubes(mask_img.get_data(),
                                         0)  #marching_cubes_lewiner
    vertices_minus = np.floor(vertices).astype(int)
    vertices_plus = np.ceil(vertices).astype(int)
    contour_data = np.zeros(mask_img.shape)
    contour_data[vertices_minus.T[0], vertices_minus.T[1],
                 vertices_minus.T[2]] = 1
    contour_data[vertices_plus.T[0], vertices_plus.T[1],
                 vertices_plus.T[2]] = 1
    contour_img = image.new_img_like(mask_img, contour_data)
    if write_dir is None:
        write_dir = os.getcwd()

    if out_file is None:
        out_file = fname_presuffix(mask_file,
                                   suffix='_countour',
                                   newpath=write_dir)
    contour_img.to_filename(out_file)
    return out_file
コード例 #9
0
ファイル: trim_and_detrend.py プロジェクト: qmac/merlinalysis
def run_preprocessing(image_file, output_file):
    # Load and crop
    img = check_niimg(image_file, ensure_ndim=4)
    img_data = img.get_data()
    img_data = img_data[:, :, :, 17:]  # Initial scanner setup
    img_data = img_data[:, :, :, 27:]  # Starting cartoon
    img_data = img_data[:, :, :, :975]
    print('Data matrix shape: ' + str(img_data.shape))

    img_data = np.reshape(img_data, (245245, img_data.shape[3]))

    # Normalize data
    Y = zscore(img_data).T

    # Detrend data
    Y = detrend_data(Y)
    print('Detrended data matrix: ' + str(Y.shape))

    Y = np.reshape(Y.T, (65, 77, 49, 975))

    r_squared_img = Nifti1Image(Y, affine=img.affine)
    r_squared_img.to_filename(output_file)
コード例 #10
0
                     'c{0}anat_n0_clear_hd.nii'.format(n))  # Try after N3
        for n in range(1, 4)
    ]
    rough_mask_img = image.math_img('np.max(imgs, axis=-1) > .01',
                                    imgs=spm_tissues_files)
    spm_labels_img = image.math_img('img * (np.argmax(imgs, axis=-1) + 1)',
                                    img=rough_mask_img,
                                    imgs=spm_tissues_files)
    spm_gm_wm_img = image.math_img('np.logical_or(img==1, img==2)',
                                   img=spm_labels_img)
    brain_mask_img = masking.intersect_masks(
        [sammba_brain_mask_file, spm_gm_wm_img], threshold=0)
    brain_mask_file = os.path.join(sammba_dir,
                                   'anat_n0_precise_brain_mask.nii.gz')
    brain_contour_file = compute_mask_contour(brain_mask_file)
    check_niimg(brain_contour_file).to_filename(
        os.path.join(spm_dir, 'anat_n0_precise_brain_mask_contour.nii'))

    nwarp_apply = afni.NwarpApply().run
    transforms = [
        os.path.join(sammba_dir,
                     'anat_n0_unifized_affine_general_warped_WARP.nii.gz'),
        os.path.join(sammba_dir, 'anat_n0_unifized_masked_aff.aff12.1D')
    ]
    warp = "'" + ' '.join(transforms) + "'"
    sammba_registered_contour_file = fname_presuffix(brain_contour_file,
                                                     suffix='_warped',
                                                     newpath=sammba_dir)
    out_warp_apply = nwarp_apply(in_file=brain_contour_file,
                                 master=template_brain_mask_file,
                                 warp=warp,
                                 interp='nearestneighbor',
コード例 #11
0
ファイル: atlas.py プロジェクト: nadkarni-na/sammba-mri
def fetch_masks_dorr_2008(image_format='nifti',
                          downsample='30',
                          data_dir=None,
                          resume=True,
                          verbose=1):
    """Downloads DORR 2008 atlas first, then uses its labels to produce tissue
    masks.

    Parameters
    ----------
    image_format : one of {'nifti', 'minc'}, optional
        Format to download

    downsample : one of {'30', '100'}, optional
        Downsampling resolution in microns.

    data_dir : str, optional
        Path of the data directory. Use to forec data storage in a non-
        standard location. Default: None (meaning: default)

    resume : bool, optional
        whether to resumed download of a partly-downloaded file.

    verbose : int, optional
        verbosity level (0 means no message).

    Returns
    -------
    mask_imgs: sklearn.datasets.base.Bunch
        dictionary-like object, contains:

        - 'brain' : nibabel.nifti1.Nifti1Image brain mask image.

        - 'gm' : nibabel.nifti1.Nifti1Image grey matter mask image.

        - 'cc' : nibabel.nifti1.Nifti1Image eroded corpus callosum image.

        - 'ventricles' : nibabel.nifti1.Nifti1Image eroded ventricles mask
        image.

    Notes
    -----
    This function relies on DORR 2008 atlas where we particularly pick
    ventricles and corpus callosum regions. Then, do a bit post processing
    such as binary closing operation to more compact brain and grey matter
    mask image and binary erosion to non-contaminated corpus callosum
    and ventricles mask images.
    Note: It is advised to check the mask images with your own data processing.

    See Also
    --------
    sammba.data_fetchers.fetch_atlas_dorr_2008: for details regarding
        the DORR 2008 atlas.
    """
    # Fetching DORR 2008 atlas
    dorr = fetch_atlas_dorr_2008(image_format=image_format,
                                 downsample=downsample,
                                 data_dir=data_dir,
                                 resume=resume,
                                 verbose=verbose)
    maps, names, labels = dorr['maps'], dorr['names'], dorr['labels']
    atlas_img = check_niimg(maps)
    atlas_data = niimg._safe_get_data(atlas_img).astype(int)

    brain_mask = (atlas_data > 0)
    brain_mask = ndimage.binary_closing(brain_mask, iterations=2)
    brain_mask_img = image.new_img_like(atlas_img, brain_mask)

    corpus_callosum_labels = labels[np.in1d(
        names.astype(str), ['R corpus callosum', 'L corpus callosum'])]
    print(
        np.in1d(names.astype(str), ['R corpus callosum', 'L corpus callosum']))
    print(corpus_callosum_labels)
    print(np.unique(atlas_data))
    corpus_callosum_mask = np.max(
        [atlas_data == value for value in corpus_callosum_labels], axis=0)
    eroded_corpus_callosum_mask = ndimage.binary_erosion(corpus_callosum_mask,
                                                         iterations=2)
    corpus_callosum_mask_img = image.new_img_like(atlas_img,
                                                  eroded_corpus_callosum_mask)

    ventricles_names = [
        'R lateral ventricle', 'L lateral ventricle', 'third ventricle',
        'fourth ventricle'
    ]
    ventricles_labels = labels[np.in1d(names.astype(str), ventricles_names)]
    ventricles_mask = np.max(
        [atlas_data == value for value in ventricles_labels], axis=0)
    eroded_ventricles_mask = ndimage.binary_erosion(ventricles_mask,
                                                    iterations=2)
    ventricles_mask_img = image.new_img_like(atlas_img, eroded_ventricles_mask)

    gm_mask = (atlas_data > 0)
    gm_mask[ventricles_mask] = 0
    gm_mask[corpus_callosum_mask] = 0
    gm_mask = ndimage.binary_closing(gm_mask, iterations=2)
    gm_mask_img = image.new_img_like(atlas_img, gm_mask)

    mask_imgs = {
        'brain': brain_mask_img,
        'gm': gm_mask_img,
        'cc': corpus_callosum_mask_img,
        'ventricles': ventricles_mask_img
    }

    return Bunch(**mask_imgs)
コード例 #12
0
ファイル: average_images.py プロジェクト: qmac/merlinalysis
''' Averages Nifti images. '''
import sys
import numpy as np

from nibabel import Nifti1Image
from nilearn._utils.niimg_conversions import check_niimg


def average_images(files):
    all_data = []
    for f in files:
        data = check_niimg(f).get_data()
        all_data.append(data)

    std = np.std(all_data, axis=0)
    avg = np.mean(all_data, axis=0)

    # I don't think this is right
    t_scores = avg / ((1e-10 + std) / np.sqrt(float(len(files))))

    return avg, t_scores


if __name__ == '__main__':
    output_file = sys.argv[1]
    image_files = sys.argv[2:]
    avg_data, t_scores = average_images(image_files)
    affine = check_niimg(image_files[0]).affine
    avg_nifti = Nifti1Image(avg_data, affine=affine)
    avg_nifti.to_filename(output_file)
コード例 #13
0
    def fit(self, run_imgs, events=None, confounds=None, sample_masks=None,
            design_matrices=None, bins=100):
        """Fit the GLM

        For each run:
        1. create design matrix X
        2. do a masker job: fMRI_data -> Y
        3. fit regression to (Y, X)

        Parameters
        ----------
        run_imgs : Niimg-like object or list of Niimg-like objects,
            Data on which the GLM will be fitted. If this is a list,
            the affine is considered the same for all.

        events : pandas Dataframe or string or list of pandas DataFrames \
                 or strings, optional
            fMRI events used to build design matrices. One events object
            expected per run_img. Ignored in case designs is not None.
            If string, then a path to a csv file is expected.

        confounds : pandas Dataframe, numpy array or string or
            list of pandas DataFrames, numpy arrays or strings, optional
            Each column in a DataFrame corresponds to a confound variable
            to be included in the regression model of the respective run_img.
            The number of rows must match the number of volumes in the
            respective run_img. Ignored in case designs is not None.
            If string, then a path to a csv file is expected.

        sample_masks : array_like, or list of array_like, optional
            shape of array: (number of scans - number of volumes removed, )
            Indices of retained volumes. Masks the niimgs along time/fourth
            dimension to perform scrubbing (remove volumes with high motion)
            and/or remove non-steady-state volumes.
            Default=None.

            .. versionadded:: 0.9.2.dev

        design_matrices : pandas DataFrame or \
                          list of pandas DataFrames, optional
            Design matrices that will be used to fit the GLM. If given it
            takes precedence over events and confounds.

        bins : int, optional
            Maximum number of discrete bins for the AR coef histogram.
            If an autoregressive model with order greater than one is specified
            then adaptive quantification is performed and the coefficients
            will be clustered via K-means with `bins` number of clusters.
            Default=100.

        """
        # Initialize masker_ to None such that attribute exists
        self.masker_ = None

        # Raise a warning if both design_matrices and confounds are provided
        if design_matrices is not None and \
                (confounds is not None or events is not None):
            warn(
                'If design matrices are supplied, '
                'confounds and events will be ignored.'
            )
        # Local import to prevent circular imports
        from nilearn.maskers import NiftiMasker  # noqa

        # Check arguments
        # Check imgs type
        if events is not None:
            _check_events_file_uses_tab_separators(events_files=events)
        if not isinstance(run_imgs, (list, tuple)):
            run_imgs = [run_imgs]
        if design_matrices is None:
            if events is None:
                raise ValueError('events or design matrices must be provided')
            if self.t_r is None:
                raise ValueError('t_r not given to FirstLevelModel object'
                                 ' to compute design from events')
        else:
            design_matrices = _check_run_tables(run_imgs, design_matrices,
                                                'design_matrices')
        # Check that number of events and confound files match number of runs
        # Also check that events and confound files can be loaded as DataFrame
        if events is not None:
            events = _check_run_tables(run_imgs, events, 'events')
        if confounds is not None:
            confounds = _check_run_tables(run_imgs, confounds, 'confounds')

        if sample_masks is not None:
            sample_masks = _check_run_sample_masks(len(run_imgs), sample_masks)

        # Learn the mask
        if self.mask_img is False:
            # We create a dummy mask to preserve functionality of api
            ref_img = check_niimg(run_imgs[0])
            self.mask_img = Nifti1Image(np.ones(ref_img.shape[:3]),
                                        ref_img.affine)
        if not isinstance(self.mask_img, NiftiMasker):
            self.masker_ = NiftiMasker(mask_img=self.mask_img,
                                       smoothing_fwhm=self.smoothing_fwhm,
                                       target_affine=self.target_affine,
                                       standardize=self.standardize,
                                       mask_strategy='epi',
                                       t_r=self.t_r,
                                       memory=self.memory,
                                       verbose=max(0, self.verbose - 2),
                                       target_shape=self.target_shape,
                                       memory_level=self.memory_level
                                       )
            self.masker_.fit(run_imgs[0])
        else:
            # Make sure masker has been fitted otherwise no attribute mask_img_
            self.mask_img._check_fitted()
            if self.mask_img.mask_img_ is None and self.masker_ is None:
                self.masker_ = clone(self.mask_img)
                for param_name in ['target_affine', 'target_shape',
                                   'smoothing_fwhm', 't_r', 'memory',
                                   'memory_level']:
                    our_param = getattr(self, param_name)
                    if our_param is None:
                        continue
                    if getattr(self.masker_, param_name) is not None:
                        warn('Parameter %s of the masker'
                             ' overridden' % param_name)
                    setattr(self.masker_, param_name, our_param)
                self.masker_.fit(run_imgs[0])
            else:
                self.masker_ = self.mask_img

        # For each run fit the model and keep only the regression results.
        self.labels_, self.results_, self.design_matrices_ = [], [], []
        n_runs = len(run_imgs)
        t0 = time.time()
        for run_idx, run_img in enumerate(run_imgs):
            # Report progress
            if self.verbose > 0:
                percent = float(run_idx) / n_runs
                percent = round(percent * 100, 2)
                dt = time.time() - t0
                # We use a max to avoid a division by zero
                if run_idx == 0:
                    remaining = 'go take a coffee, a big one'
                else:
                    remaining = (100. - percent) / max(0.01, percent) * dt
                    remaining = '%i seconds remaining' % remaining

                sys.stderr.write(
                    "Computing run %d out of %d runs (%s)\n"
                    % (run_idx + 1, n_runs, remaining))

            # Build the experimental design for the glm
            run_img = check_niimg(run_img, ensure_ndim=4)
            if design_matrices is None:
                n_scans = get_data(run_img).shape[3]
                if confounds is not None:
                    confounds_matrix = confounds[run_idx].values
                    if confounds_matrix.shape[0] != n_scans:
                        raise ValueError('Rows in confounds does not match'
                                         'n_scans in run_img at index %d'
                                         % (run_idx,))
                    confounds_names = confounds[run_idx].columns.tolist()
                else:
                    confounds_matrix = None
                    confounds_names = None
                start_time = self.slice_time_ref * self.t_r
                end_time = (n_scans - 1 + self.slice_time_ref) * self.t_r
                frame_times = np.linspace(start_time, end_time, n_scans)
                design = make_first_level_design_matrix(frame_times,
                                                        events[run_idx],
                                                        self.hrf_model,
                                                        self.drift_model,
                                                        self.high_pass,
                                                        self.drift_order,
                                                        self.fir_delays,
                                                        confounds_matrix,
                                                        confounds_names,
                                                        self.min_onset
                                                        )
            else:
                design = design_matrices[run_idx]

            if sample_masks is not None:
                sample_mask = sample_masks[run_idx]
                design = design.iloc[sample_mask, :]
            else:
                sample_mask = None

            self.design_matrices_.append(design)

            # Mask and prepare data for GLM
            if self.verbose > 1:
                t_masking = time.time()
                sys.stderr.write('Starting masker computation \r')

            Y = self.masker_.transform(run_img, sample_mask=sample_mask)
            del run_img  # Delete unmasked image to save memory

            if self.verbose > 1:
                t_masking = time.time() - t_masking
                sys.stderr.write('Masker took %d seconds       \n'
                                 % t_masking)

            if self.signal_scaling is not False:  # noqa
                Y, _ = mean_scaling(Y, self.signal_scaling)
            if self.memory:
                mem_glm = self.memory.cache(run_glm, ignore=['n_jobs'])
            else:
                mem_glm = run_glm

            # compute GLM
            if self.verbose > 1:
                t_glm = time.time()
                sys.stderr.write('Performing GLM computation\r')
            labels, results = mem_glm(Y, design.values,
                                      noise_model=self.noise_model,
                                      bins=bins, n_jobs=self.n_jobs)
            if self.verbose > 1:
                t_glm = time.time() - t_glm
                sys.stderr.write('GLM took %d seconds         \n' % t_glm)

            self.labels_.append(labels)
            # We save memory if inspecting model details is not necessary
            if self.minimize_memory:
                for key in results:
                    results[key] = SimpleRegressionResults(results[key])
            self.results_.append(results)
            del Y

        # Report progress
        if self.verbose > 0:
            sys.stderr.write("\nComputation of %d runs done in %i seconds\n\n"
                             % (n_runs, time.time() - t0))
        return self
コード例 #14
0
    spm_labels_files = [
        os.path.join(output_dir, prefix + 'anat_n0_clear_hd_labeled.nii.gz')
        for (prefix, output_dir) in zip(['wc', 'c'], [spm_dir, sammba_dir])
    ]
    for (prefix, spm_labels_file) in zip(['wc', 'c'], spm_labels_files):
        spm_tissues_imgs = [
            os.path.join(spm_dir, prefix +
                         '{0}anat_n0_clear_hd.nii'.format(n))  # Try after N3
            for n in range(1, 4)
        ]
        mask_img = image.math_img('np.max(imgs, axis=-1) > .01',
                                  imgs=spm_tissues_imgs)
        spm_labels_img = image.math_img('img * (np.argmax(imgs, axis=-1) + 1)',
                                        img=mask_img,
                                        imgs=spm_tissues_imgs)
        check_niimg(spm_labels_img, dtype=float).to_filename(spm_labels_file)

    nwarp_apply = afni.NwarpApply().run
    transforms = [
        os.path.join(sammba_dir,
                     'anat_n0_unifized_affine_general_warped_WARP.nii.gz'),
        os.path.join(sammba_dir, 'anat_n0_unifized_masked_aff.aff12.1D')
    ]
    warp = "'" + ' '.join(transforms) + "'"
    sammba_tissues_files = []
    for tissue_file in spm_tissues_imgs:
        sammba_tissue_file = fname_presuffix(tissue_file,
                                             suffix='_warped',
                                             newpath=sammba_dir)
        out_warp_apply = nwarp_apply(in_file=tissue_file,
                                     master=template_file,
コード例 #15
0
ファイル: second_level_model.py プロジェクト: takhs91/nistats
    def fit(self,
            second_level_input,
            first_level_conditions=None,
            confounds=None,
            design_matrix=None):
        """ Fit the second-level GLM

        1. create design matrix
        2. do a masker job: fMRI_data -> Y
        3. fit regression to (Y, X)

        Parameters
        ----------
        second_level_input: list of `FirstLevelModel` objects or pandas
                            DataFrame or list of Niimg-like objects.
            If list of `FirstLevelModel` objects, then first_level_conditions
            must be provided. If a pandas DataFrame, then they have to contain
            subject_id, map_name, effects_map_path. If list of Niimg-like
            objects then this is taken literally as Y for the model fit
            and design_matrix must be provided.

        first_level_conditions: list of (str, (str or array)) pairs
                                or list of (str, str) pairs or None
            If second_level_input is a list of `FirstLevelModel` objects then
            it is mandatory to provide a list with contrast names as first item
            (employed as column names in the design matrix) and contrast
            definitions as second item. The contrast definitions are passed
            to the compute_contrast method of `FirstLevelModel`. The contrast
            definitions can be a str or array. Check the compute_contrast
            documentation of `FirstLevelModel` for more details on the
            contrast definitions.

            If second_level_input is a pandas DataFrame then a list with
            column names as first item (employed in the design matrix) and
            their corresponding map name as second item, where the map names
            correspond to those in the second_level_input map_name column.
            If first_level_conditions is set to None then all maps are included
            and the map_name is used as the column names in the design matrix.

            If second_level_input is a list of Niimg-like objects then this
            argument is ignored.

        confounds: pandas DataFrame, optional
            Must contain a subject_id column. All other columns are
            considered as confounds and included in the model. If
            design_matrix is provided then this argument is ignored.
            The resulting second level design matrix uses the same column
            names as in the given DataFrame for confounds. At least two columns
            are expected, "subject_id" and at least one confound.

        design_matrix: pandas DataFrame, optional
            Design matrix to fit the GLM. The number of rows
            in the design matrix must agree with the number of maps derived
            from second_level_input and first_level_conditions.
            Ensure that the order of maps given by first_level_conditions
            or inferred directly from a second_level_input dataframe matches
            the order of the rows in the design matrix.
        """
        # Check parameters
        # check first level input
        if isinstance(second_level_input, list):
            if len(second_level_input) < 2:
                raise ValueError('A second level model requires a list with at'
                                 'least two first level models or niimgs')
            # Check FirstLevelModel objects case
            if isinstance(second_level_input[0], FirstLevelModel):
                if first_level_conditions is None:
                    raise ValueError('First level models input requires'
                                     'first_level_conditions to be provided')
                models_input = enumerate(second_level_input)
                for model_idx, first_level_model in models_input:
                    if not isinstance(first_level_model, FirstLevelModel):
                        raise ValueError(' object at idx %d is %s instead of'
                                         ' FirstLevelModel object' %
                                         (model_idx, type(first_level_model)))
                    if confounds is not None:
                        if first_level_model.subject_id is None:
                            raise ValueError(
                                'In case confounds are provided, first level '
                                'objects need to provide the attribute '
                                'subject_id to match rows appropriately. Model'
                                ' at idx %d do not provide it. To set it, you '
                                'can do first_level_model.subject_id = "01"' %
                                (model_idx))
            # Check niimgs case
            elif isinstance(second_level_input[0], (str, Nifti1Image)):
                if design_matrix is None:
                    raise ValueError('List of niimgs as second_level_input'
                                     ' require a design matrix to be provided')
                for model_idx, niimg in enumerate(second_level_input):
                    if not isinstance(niimg, (str, Nifti1Image)):
                        raise ValueError(' object at idx %d is %s instead of'
                                         ' Niimg-like object' %
                                         (model_idx, type(niimg)))
        # Check pandas dataframe case
        elif isinstance(second_level_input, pd.DataFrame):
            for col in ['subject_id', 'map_name', 'effects_map_path']:
                if col not in second_level_input.columns:
                    raise ValueError('second_level_input DataFrame must have'
                                     ' columns subject_id, map_name and'
                                     ' effects_map_path')
            if first_level_conditions is not None:
                for name, cond in first_level_conditions:
                    if not isinstance(cond, str) and isinstance(name, str):
                        raise ValueError('When second_level_input is a'
                                         ' DataFrame, first_level_conditions '
                                         'must be (str, str) pair')
        else:
            raise ValueError('second_level_input must be a list of'
                             ' `FirstLevelModel` objects, a pandas DataFrame'
                             ' or a list Niimg-like objects. Instead %s '
                             'was provided' % type(second_level_input))

        # check conditions if provided
        if first_level_conditions is not None:
            if isinstance(first_level_conditions, list):
                for cidx, (name, cond) in enumerate(first_level_conditions):
                    if not isinstance(name, str):
                        raise ValueError('condition name at idx %d is %s '
                                         'instead of str' % (cidx, type(name)))
                    if not isinstance(cond, (str, np.ndarray)):
                        raise ValueError('condition at idx %d is %s instead of'
                                         ' str or array' % (cidx, type(cond)))
            else:
                raise ValueError('first_level_conditions is not a list. '
                                 'It is %s instead' %
                                 type(first_level_conditions))

        # check confounds
        if confounds is not None:
            if not isinstance(confounds, pd.DataFrame):
                raise ValueError('confounds must be a pandas DataFrame')
            if 'subject_id' not in confounds.columns:
                raise ValueError('confounds DataFrame must contain column'
                                 '"subject_id"')
            if len(confounds.columns) < 2:
                raise ValueError('confounds should contain at least 2 columns'
                                 'one called "subject_id" and the other with'
                                 'a given confound')

        # check design matrix
        if design_matrix is not None:
            if not isinstance(design_matrix, pd.DataFrame):
                raise ValueError('design matrix must be a pandas DataFrame')

        # Build the design matrix X and list of imgs Y for GLM fit
        if isinstance(second_level_input, pd.DataFrame):
            maps_table = second_level_input
            # Get only first level conditions if provided
            if first_level_conditions is not None:
                for name, condition in first_level_conditions:
                    if condition not in maps_table['map_name'].tolist():
                        raise ValueError('condition %s not present in'
                                         ' second_level_input' % condition)
                condition_list = [cond[0] for cond in first_level_conditions]
                in_cond = maps_table.apply(
                    lambda x: x['map_name'] in condition_list, axis=1)
                maps_table = maps_table[in_cond]
            # Create design matrix if necessary
            if design_matrix is None:
                design_matrix = create_second_level_design(
                    maps_table, confounds)
            # get effect maps for fixed effects GLM
            effects_maps = maps_table['effects_map_path'].tolist()

        elif isinstance(second_level_input[0], FirstLevelModel):
            # Check models were fit
            for model_idx, model in enumerate(second_level_input):
                if model.labels_ is None:
                    raise ValueError('Model at idx %d has not been fit' %
                                     model_idx)
            # Get the first level model maps
            maps_table = pd.DataFrame(columns=['map_name', 'subject_id'])
            effects_maps = []
            for model in second_level_input:
                for con_name, con_def in first_level_conditions:
                    maps_table.loc[len(maps_table)] = [
                        con_name, model.subject_id
                    ]
                    eff_map = model.compute_contrast(con_def,
                                                     output_type='effect_size')
                    effects_maps.append(eff_map)
            # Get the design matrix
            if design_matrix is None:
                design_matrix = create_second_level_design(
                    maps_table, confounds)

        else:
            effects_maps = second_level_input

        # set design matrix, given or computed
        self.design_matrix_ = design_matrix

        # check design matrix X and effect maps Y agree on number of rows
        if len(effects_maps) != design_matrix.shape[0]:
            raise ValueError('design_matrix does not match the number of maps '
                             'considered. Rows in design matrix do not agree '
                             'with number of maps')
        # check niimgs
        for niimg in effects_maps:
            check_niimg(niimg, ensure_ndim=3)

        # Report progress
        t0 = time.time()
        if self.verbose > 0:
            sys.stderr.write("Computing second level model. "
                             "Go take a coffee\r")

        # Learn the mask. Assume the first level imgs have been masked.
        if not isinstance(self.mask, NiftiMasker):
            self.masker_ = NiftiMasker(mask_img=self.mask,
                                       smoothing_fwhm=self.smoothing_fwhm,
                                       memory=self.memory,
                                       verbose=max(0, self.verbose - 1),
                                       memory_level=self.memory_level)
        else:
            self.masker_ = clone(self.mask)
            for param_name in ['smoothing_fwhm', 'memory', 'memory_level']:
                our_param = getattr(self, param_name)
                if our_param is None:
                    continue
                if getattr(self.masker_, param_name) is not None:
                    warn('Parameter %s of the masker overriden' % param_name)
                setattr(self.masker_, param_name, our_param)
        self.masker_.fit(effects_maps[0])

        # Fit the model
        Y = self.masker_.transform(effects_maps)
        if self.memory is not None:
            arg_ignore = ['n_jobs', 'noise_model']
            mem_glm = self.memory.cache(run_glm, ignore=arg_ignore)
        else:
            mem_glm = run_glm
        labels, results = mem_glm(Y,
                                  design_matrix.as_matrix(),
                                  n_jobs=self.n_jobs,
                                  noise_model='ols')
        # We save memory if inspecting model details is not necessary
        if self.minimize_memory:
            for key in results:
                results[key] = SimpleRegressionResults(results[key])
        self.labels_ = labels
        self.results_ = results
        del Y

        # Report progress
        if self.verbose > 0:
            sys.stderr.write("\nComputation of second level model done in "
                             "%i seconds\n" % (time.time() - t0))

        return self
コード例 #16
0
ファイル: second_level_model.py プロジェクト: m9h/nistats
    def fit(self, second_level_input, confounds=None, design_matrix=None):
        """ Fit the second-level GLM

        1. create design matrix
        2. do a masker job: fMRI_data -> Y
        3. fit regression to (Y, X)

        Parameters
        ----------
        second_level_input: list of `FirstLevelModel` objects or pandas
                            DataFrame or list of Niimg-like objects.

            Giving FirstLevelModel objects will allow to easily compute
            the second level contast of arbitrary first level contrasts thanks
            to the first_level_contrast argument of the compute_contrast
            method. Effect size images will be computed for each model to
            contrast at the second level.

            If a pandas DataFrame, then they have to contain subject_label,
            map_name and effects_map_path. It can contain multiple maps that
            would be selected during contrast estimation with the argument
            first_level_contrast of the compute_contrast function. The
            DataFrame will be sorted based on the subject_label column to avoid
            order inconsistencies when extracting the maps. So the rows of the
            automatically computed design matrix, if not provided, will
            correspond to the sorted subject_label column.
 
            If list of Niimg-like objects then this is taken literally as Y
            for the model fit and design_matrix must be provided.

        confounds: pandas DataFrame, optional
            Must contain a subject_label column. All other columns are
            considered as confounds and included in the model. If
            design_matrix is provided then this argument is ignored.
            The resulting second level design matrix uses the same column
            names as in the given DataFrame for confounds. At least two columns
            are expected, "subject_label" and at least one confound.

        design_matrix: pandas DataFrame, optional
            Design matrix to fit the GLM. The number of rows
            in the design matrix must agree with the number of maps derived
            from second_level_input.
            Ensure that the order of maps given by a second_level_input
            list of Niimgs matches the order of the rows in the design matrix.

        """
        # Check parameters
        # check first level input
        if isinstance(second_level_input, list):
            if len(second_level_input) < 2:
                raise ValueError('A second level model requires a list with at'
                                 'least two first level models or niimgs')
            # Check FirstLevelModel objects case
            if isinstance(second_level_input[0], FirstLevelModel):
                models_input = enumerate(second_level_input)
                for model_idx, first_level_model in models_input:
                    if (first_level_model.labels_ is None
                            or first_level_model.results_ is None):
                        raise ValueError(
                            'Model %s at index %i has not been fit yet'
                            '' % (first_level_model.subject_label, model_idx))
                    if not isinstance(first_level_model, FirstLevelModel):
                        raise ValueError(' object at idx %d is %s instead of'
                                         ' FirstLevelModel object' %
                                         (model_idx, type(first_level_model)))
                    if confounds is not None:
                        if first_level_model.subject_label is None:
                            raise ValueError(
                                'In case confounds are provided, first level '
                                'objects need to provide the attribute '
                                'subject_label to match rows appropriately.'
                                'Model at idx %d does not provide it. '
                                'To set it, you can do '
                                'first_level_model.subject_label = "01"'
                                '' % (model_idx))
            # Check niimgs case
            elif isinstance(second_level_input[0], (str, Nifti1Image)):
                if design_matrix is None:
                    raise ValueError('List of niimgs as second_level_input'
                                     ' require a design matrix to be provided')
                for model_idx, niimg in enumerate(second_level_input):
                    if not isinstance(niimg, (str, Nifti1Image)):
                        raise ValueError(' object at idx %d is %s instead of'
                                         ' Niimg-like object' %
                                         (model_idx, type(niimg)))
        # Check pandas dataframe case
        elif isinstance(second_level_input, pd.DataFrame):
            for col in ['subject_label', 'map_name', 'effects_map_path']:
                if col not in second_level_input.columns:
                    raise ValueError('second_level_input DataFrame must have'
                                     ' columns subject_label, map_name and'
                                     ' effects_map_path')
            # Make sure subject_label contain strings
            second_level_columns = second_level_input.columns.tolist()
            labels_index = second_level_columns.index('subject_label')
            labels_dtype = second_level_input.dtypes[labels_index]
            if not isinstance(labels_dtype, np.object):
                raise ValueError('subject_label column must be of dtype '
                                 'object instead of dtype %s' % labels_dtype)
        elif isinstance(second_level_input, (str, Nifti1Image)):
            if design_matrix is None:
                raise ValueError('List of niimgs as second_level_input'
                                 ' require a design matrix to be provided')
            second_level_input = check_niimg(niimg=second_level_input,
                                             ensure_ndim=4)
        else:
            raise ValueError('second_level_input must be a list of'
                             ' `FirstLevelModel` objects, a pandas DataFrame'
                             ' or a list Niimg-like objects. Instead %s '
                             'was provided' % type(second_level_input))

        # check confounds
        if confounds is not None:
            if not isinstance(confounds, pd.DataFrame):
                raise ValueError('confounds must be a pandas DataFrame')
            if 'subject_label' not in confounds.columns:
                raise ValueError('confounds DataFrame must contain column'
                                 '"subject_label"')
            if len(confounds.columns) < 2:
                raise ValueError('confounds should contain at least 2 columns'
                                 'one called "subject_label" and the other'
                                 'with a given confound')
            # Make sure subject_label contain strings
            labels_index = confounds.columns.tolist().index('subject_label')
            labels_dtype = confounds.dtypes[labels_index]
            if not isinstance(labels_dtype, np.object):
                raise ValueError('subject_label column must be of dtype '
                                 'object instead of dtype %s' % labels_dtype)

        # check design matrix
        if design_matrix is not None:
            if not isinstance(design_matrix, pd.DataFrame):
                raise ValueError('design matrix must be a pandas DataFrame')

        # sort a pandas dataframe by subject_label to avoid inconsistencies
        # with the design matrix row order when automatically extracting maps
        if isinstance(second_level_input, pd.DataFrame):
            columns = second_level_input.columns.tolist()
            column_index = columns.index('subject_label')
            sorted_matrix = sorted(second_level_input.values,
                                   key=lambda x: x[column_index])
            sorted_input = pd.DataFrame(sorted_matrix, columns=columns)
            second_level_input = sorted_input

        self.second_level_input_ = second_level_input
        self.confounds_ = confounds

        # Report progress
        t0 = time.time()
        if self.verbose > 0:
            sys.stderr.write("Fitting second level model. "
                             "Take a deep breath\r")

        # Select sample map for masker fit and get subjects_label for design
        if isinstance(second_level_input, pd.DataFrame):
            sample_map = second_level_input['effects_map_path'][0]
            labels = second_level_input['subject_label']
            subjects_label = labels.values.tolist()
        elif isinstance(second_level_input, Nifti1Image):
            sample_map = mean_img(second_level_input)
        elif isinstance(second_level_input[0], FirstLevelModel):
            sample_model = second_level_input[0]
            sample_condition = sample_model.design_matrices_[0].columns[0]
            sample_map = sample_model.compute_contrast(
                sample_condition, output_type='effect_size')
            labels = [model.subject_label for model in second_level_input]
            subjects_label = labels
        else:
            # In this case design matrix had to be provided
            sample_map = mean_img(second_level_input)

        # Create and set design matrix, if not given
        if design_matrix is None:
            design_matrix = make_second_level_design_matrix(
                subjects_label, confounds)
        self.design_matrix_ = design_matrix

        # Learn the mask. Assume the first level imgs have been masked.
        if not isinstance(self.mask, NiftiMasker):
            self.masker_ = NiftiMasker(mask_img=self.mask,
                                       smoothing_fwhm=self.smoothing_fwhm,
                                       memory=self.memory,
                                       verbose=max(0, self.verbose - 1),
                                       memory_level=self.memory_level)
        else:
            self.masker_ = clone(self.mask)
            for param_name in ['smoothing_fwhm', 'memory', 'memory_level']:
                our_param = getattr(self, param_name)
                if our_param is None:
                    continue
                if getattr(self.masker_, param_name) is not None:
                    warn('Parameter %s of the masker overriden' % param_name)
                setattr(self.masker_, param_name, our_param)
        self.masker_.fit(sample_map)

        # Report progress
        if self.verbose > 0:
            sys.stderr.write("\nComputation of second level model done in "
                             "%i seconds\n" % (time.time() - t0))

        return self
コード例 #17
0
ファイル: plotting.py プロジェクト: Neurita/pypes
 def _index_img(img_file, index):
     """ Return the volume in `index` 4th dimension index of `img_file`.
     If the image is 3D and idx is zero will return the container of `img_file`.
     """
     imgs = check_niimg(img_file, ensure_ndim=4, atleast_4d=True)
     return _index_img(imgs, index)
コード例 #18
0
def dice(mask_file1, mask_file2):
    mask_data1 = check_niimg(mask_file1).get_data() > 0
    mask_data2 = check_niimg(mask_file2).get_data() > 0
    numerator = np.logical_and(mask_data1, mask_data2).sum()
    denominator = mask_data1.sum() + mask_data2.sum()
    return 2 * numerator / float(denominator)
コード例 #19
0
        sammba_registered_ventricles_file = fname_presuffix(
            ventricles_mask_file, suffix='_allineated', newpath=sammba_dir)
        allineate = afni.Allineate().run
        out_allineate = allineate(in_file=ventricles_mask_file,
                                  master=template_ventricles_mask_file,
                                  in_matrix=os.path.join(
                                      sammba_dir,
                                      'anat_n0_unifized_masked_aff.aff12.1D'),
                                  out_file=sammba_registered_ventricles_file,
                                  interpolation='nearestneighbour',
                                  environ={'AFNI_DECONFLICT': 'OVERWRITE'})

        spm_registered_ventricles_file = os.path.join(
            spm_dir, 'wmanual_ventricles_mask.nii')

        spm_registered_ventricles_data = check_niimg(
            spm_registered_ventricles_file).get_data()
        template_shape = check_niimg(template_ventricles_mask_file).shape
        if spm_registered_ventricles_data.shape != template_shape:
            uncropped_spm_registered_ventricles_data = np.vstack(
                (np.zeros((1, ) + template_shape[1:]),
                 spm_registered_ventricles_data))
            uncropped_spm_registered_ventricles_data = np.nan_to_num(
                uncropped_spm_registered_ventricles_data)
            uncropped_spm_registered_contour_file = fname_presuffix(
                spm_registered_ventricles_file, suffix='_uncropped')
            image.new_img_like(
                spm_registered_ventricles_file,
                uncropped_spm_registered_ventricles_data).to_filename(
                    uncropped_spm_registered_contour_file)

        else:
コード例 #20
0
def cluster_stats(stat_img,
                  mask_img,
                  threshold,
                  height_control='fpr',
                  cluster_th=0,
                  nulls=None):
    """
    Return a list of clusters, each cluster being represented by a
    dictionary. Clusters are sorted by descending size order. Within
    each cluster, local maxima are sorted by descending statical value

    Parameters
    ----------
    stat_img: Niimg-like object,
       statsitical image (presumably in z scale)
    mask_img: Niimg-like object,
        mask image
    threshold: float,
        cluster forming threshold (either a p-value or z-scale value)
    height_control: string
        false positive control meaning of cluster forming
        threshold: 'fpr'|'fdr'|'bonferroni'|'none'
    cluster_th: int or float,
        cluster size threshold
    nulls: dictionary,
        statistics of the null distribution

    Notes
    -----
    If there is no cluster, an empty list is returned
    """
    if nulls is None: nulls = {}

    # Masking
    mask_img, stat_img = check_niimg(mask_img), check_niimg(stat_img)
    if not _check_same_fov(mask_img, stat_img):
        raise ValueError('mask_img and stat_img do not have the same fov')
    mask = mask_img.get_data().astype(np.bool)
    affine = mask_img.get_affine()
    stat_map = stat_img.get_data() * mask
    n_voxels = mask.sum()

    # Thresholding
    if height_control == 'fpr':
        z_th = norm.isf(threshold)
    elif height_control == 'fdr':
        z_th = fdr_threshold(stat_map[mask], threshold)
    elif height_control == 'bonferroni':
        z_th = norm.isf(threshold / n_voxels)
    else:  # Brute-force thresholding
        z_th = threshold

    p_th = norm.sf(z_th)
    # General info
    info = {
        'n_voxels': n_voxels,
        'threshold_z': z_th,
        'threshold_p': p_th,
        'threshold_pcorr': np.minimum(1, p_th * n_voxels)
    }

    above_th = stat_map > z_th
    above_values = stat_map * above_th
    if (above_th == 0).all():
        return [], info

    # Extract connected components above threshold
    labels, n_labels = label(above_th)

    # Extract the local maxima anove the threshold
    maxima_mask = (above_values == np.maximum(z_th,
                                              maximum_filter(above_values, 3)))
    x, y, z = np.array(np.where(maxima_mask))
    maxima_coords = np.array(coord_transform(x, y, z, affine)).T
    maxima_labels = labels[maxima_mask]
    maxima_values = above_values[maxima_mask]

    # FDR-corrected p-values
    max_fdr_p_values = fdr_p_values(stat_map[mask])[maxima_mask[mask]]

    # Default "nulls"
    if not 'zmax' in nulls:
        nulls['zmax'] = 'bonferroni'
    if not 'smax' in nulls:
        nulls['smax'] = None
    if not 's' in nulls:
        nulls['s'] = None

    # Make list of clusters, each cluster being a dictionary
    clusters = []
    for k in range(n_labels):
        cluster_size = np.sum(labels == k + 1)
        if cluster_size >= cluster_th:

            # get the position of the maxima that belong to that cluster
            in_cluster = maxima_labels == k + 1

            # sort the maxima by decreasing statistical value
            max_vals = maxima_values[in_cluster]
            sorted_ = max_vals.argsort()[::-1]

            # Report significance levels in each cluster
            z_score = max_vals[sorted_]
            p_values = norm.sf(z_score)

            # Voxel-level corrected p-values
            fwer_p_value = None
            if nulls['zmax'] == 'bonferroni':
                fwer_p_value = np.minimum(1, p_values * n_voxels)
            elif isinstance(nulls['zmax'], np.ndarray):
                fwer_p_value = empirical_p_value(clusters['z_score'],
                                                 nulls['zmax'])

            # Cluster-level p-values (corrected)
            cluster_fwer_p_value = None
            if isinstance(nulls['smax'], np.ndarray):
                cluster_fwer_p_value = empirical_p_value(
                    cluster_size, nulls['smax'])

            # Cluster-level p-values (uncorrected)
            cluster_p_value = None
            if isinstance(nulls['s'], np.ndarray):
                cluster_p_value = empirical_p_value(cluster_size, nulls['s'])

            # write all this into the cluster structure
            clusters.append({
                'size':
                cluster_size,
                'maxima':
                maxima_coords[in_cluster][sorted_],
                'z_score':
                z_score,
                'fdr_p_value':
                max_fdr_p_values[in_cluster][sorted_],
                'p_value':
                p_values,
                'fwer_p_value':
                fwer_p_value,
                'cluster_fwer_p_value':
                cluster_fwer_p_value,
                'cluster_p_value':
                cluster_p_value
            })

    # Sort clusters by descending size order
    order = np.argsort(-np.array([cluster['size'] for cluster in clusters]))
    clusters = [clusters[i] for i in order]

    return clusters, info
コード例 #21
0
ファイル: second_level_model.py プロジェクト: alpinho/nistats
    def fit(self, second_level_input, confounds=None, design_matrix=None):
        """ Fit the second-level GLM

        1. create design matrix
        2. do a masker job: fMRI_data -> Y
        3. fit regression to (Y, X)

        Parameters
        ----------
        second_level_input: list of `FirstLevelModel` objects or pandas
                            DataFrame or list of Niimg-like objects.

            Giving FirstLevelModel objects will allow to easily compute
            the second level contast of arbitrary first level contrasts thanks
            to the first_level_contrast argument of the compute_contrast
            method. Effect size images will be computed for each model to
            contrast at the second level.

            If a pandas DataFrame, then they have to contain subject_label,
            map_name and effects_map_path. It can contain multiple maps that
            would be selected during contrast estimation with the argument
            first_level_contrast of the compute_contrast function. The
            DataFrame will be sorted based on the subject_label column to avoid
            order inconsistencies when extracting the maps. So the rows of the
            automatically computed design matrix, if not provided, will
            correspond to the sorted subject_label column.
 
            If list of Niimg-like objects then this is taken literally as Y
            for the model fit and design_matrix must be provided.

        confounds: pandas DataFrame, optional
            Must contain a subject_label column. All other columns are
            considered as confounds and included in the model. If
            design_matrix is provided then this argument is ignored.
            The resulting second level design matrix uses the same column
            names as in the given DataFrame for confounds. At least two columns
            are expected, "subject_label" and at least one confound.

        design_matrix: pandas DataFrame, optional
            Design matrix to fit the GLM. The number of rows
            in the design matrix must agree with the number of maps derived
            from second_level_input.
            Ensure that the order of maps given by a second_level_input
            list of Niimgs matches the order of the rows in the design matrix.

        """
        # Check parameters
        # check first level input
        if isinstance(second_level_input, list):
            if len(second_level_input) < 2:
                raise ValueError('A second level model requires a list with at'
                                 'least two first level models or niimgs')
            # Check FirstLevelModel objects case
            if isinstance(second_level_input[0], FirstLevelModel):
                models_input = enumerate(second_level_input)
                for model_idx, first_level_model in models_input:
                    if (first_level_model.labels_ is None or
                            first_level_model.results_ is None):
                        raise ValueError(
                            'Model %s at index %i has not been fit yet'
                            '' % (first_level_model.subject_label, model_idx))
                    if not isinstance(first_level_model, FirstLevelModel):
                        raise ValueError(' object at idx %d is %s instead of'
                                         ' FirstLevelModel object' %
                                         (model_idx, type(first_level_model)))
                    if confounds is not None:
                        if first_level_model.subject_label is None:
                            raise ValueError(
                                'In case confounds are provided, first level '
                                'objects need to provide the attribute '
                                'subject_label to match rows appropriately.'
                                'Model at idx %d does not provide it. '
                                'To set it, you can do '
                                'first_level_model.subject_label = "01"'
                                '' % (model_idx))
            # Check niimgs case
            elif isinstance(second_level_input[0], (str, Nifti1Image)):
                if design_matrix is None:
                    raise ValueError('List of niimgs as second_level_input'
                                     ' require a design matrix to be provided')
                for model_idx, niimg in enumerate(second_level_input):
                    if not isinstance(niimg, (str, Nifti1Image)):
                        raise ValueError(' object at idx %d is %s instead of'
                                         ' Niimg-like object' %
                                         (model_idx, type(niimg)))
        # Check pandas dataframe case
        elif isinstance(second_level_input, pd.DataFrame):
            for col in ['subject_label', 'map_name', 'effects_map_path']:
                if col not in second_level_input.columns:
                    raise ValueError('second_level_input DataFrame must have'
                                     ' columns subject_label, map_name and'
                                     ' effects_map_path')
            # Make sure subject_label contain strings
            second_level_columns = second_level_input.columns.tolist()
            labels_index = second_level_columns.index('subject_label')
            labels_dtype = second_level_input.dtypes[labels_index]
            if not isinstance(labels_dtype, np.object):
                raise ValueError('subject_label column must be of dtype '
                                 'object instead of dtype %s' % labels_dtype)
        elif isinstance(second_level_input, (str, Nifti1Image)):
            if design_matrix is None:
                raise ValueError('List of niimgs as second_level_input'
                                 ' require a design matrix to be provided')
            second_level_input = check_niimg(niimg=second_level_input,
                                             ensure_ndim=4) 
        else:
            raise ValueError('second_level_input must be a list of'
                             ' `FirstLevelModel` objects, a pandas DataFrame'
                             ' or a list Niimg-like objects. Instead %s '
                             'was provided' % type(second_level_input))

        # check confounds
        if confounds is not None:
            if not isinstance(confounds, pd.DataFrame):
                raise ValueError('confounds must be a pandas DataFrame')
            if 'subject_label' not in confounds.columns:
                raise ValueError('confounds DataFrame must contain column'
                                 '"subject_label"')
            if len(confounds.columns) < 2:
                raise ValueError('confounds should contain at least 2 columns'
                                 'one called "subject_label" and the other'
                                 'with a given confound')
            # Make sure subject_label contain strings
            labels_index = confounds.columns.tolist().index('subject_label')
            labels_dtype = confounds.dtypes[labels_index]
            if not isinstance(labels_dtype, np.object):
                raise ValueError('subject_label column must be of dtype '
                                 'object instead of dtype %s' % labels_dtype)

        # check design matrix
        if design_matrix is not None:
            if not isinstance(design_matrix, pd.DataFrame):
                raise ValueError('design matrix must be a pandas DataFrame')

        # sort a pandas dataframe by subject_label to avoid inconsistencies
        # with the design matrix row order when automatically extracting maps
        if isinstance(second_level_input, pd.DataFrame):
            columns = second_level_input.columns.tolist()
            column_index = columns.index('subject_label')
            sorted_matrix = sorted(
                second_level_input.values, key=lambda x: x[column_index])
            sorted_input = pd.DataFrame(sorted_matrix, columns=columns)
            second_level_input = sorted_input

        self.second_level_input_ = second_level_input
        self.confounds_ = confounds

        # Report progress
        t0 = time.time()
        if self.verbose > 0:
            sys.stderr.write("Fitting second level model. "
                             "Take a deep breath\r")

        # Select sample map for masker fit and get subjects_label for design
        if isinstance(second_level_input, pd.DataFrame):
            sample_map = second_level_input['effects_map_path'][0]
            labels = second_level_input['subject_label']
            subjects_label = labels.values.tolist()
        elif isinstance(second_level_input, Nifti1Image):
            sample_map = mean_img(second_level_input)
        elif isinstance(second_level_input[0], FirstLevelModel):
            sample_model = second_level_input[0]
            sample_condition = sample_model.design_matrices_[0].columns[0]
            sample_map = sample_model.compute_contrast(
                sample_condition, output_type='effect_size')
            labels = [model.subject_label for model in second_level_input]
            subjects_label = labels
        else:
            # In this case design matrix had to be provided
            sample_map = mean_img(second_level_input)

        # Create and set design matrix, if not given
        if design_matrix is None:
            design_matrix = make_second_level_design_matrix(subjects_label,
                                                            confounds)
        self.design_matrix_ = design_matrix

        # Learn the mask. Assume the first level imgs have been masked.
        if not isinstance(self.mask, NiftiMasker):
            self.masker_ = NiftiMasker(
                mask_img=self.mask, smoothing_fwhm=self.smoothing_fwhm,
                memory=self.memory, verbose=max(0, self.verbose - 1),
                memory_level=self.memory_level)
        else:
            self.masker_ = clone(self.mask)
            for param_name in ['smoothing_fwhm', 'memory', 'memory_level']:
                our_param = getattr(self, param_name)
                if our_param is None:
                    continue
                if getattr(self.masker_, param_name) is not None:
                    warn('Parameter %s of the masker overriden' % param_name)
                setattr(self.masker_, param_name, our_param)
        self.masker_.fit(sample_map)

        # Report progress
        if self.verbose > 0:
            sys.stderr.write("\nComputation of second level model done in "
                             "%i seconds\n" % (time.time() - t0))

        return self
コード例 #22
0
'''
import sys
import numpy as np

from nibabel import Nifti1Image
from nilearn._utils.niimg_conversions import check_niimg


def variance_partition(d1, d2, comb):
    d1 = np.maximum(d1, 0)
    d2 = np.maximum(d2, 0)
    comb = np.maximum(comb, 0)
    only_d1 = comb - d2
    only_d2 = comb - d1
    intersection = d1 - only_d1
    return only_d1, only_d2, intersection


if __name__ == '__main__':
    img = check_niimg(sys.argv[1])
    data1 = img.get_data()
    data2 = check_niimg(sys.argv[2]).get_data()
    data_combined = check_niimg(sys.argv[3]).get_data()
    ex1, ex2, intersection = variance_partition(data1, data2, data_combined)
    ex1_img = Nifti1Image(ex1, affine=img.affine)
    ex1_img.to_filename(sys.argv[4])
    ex2_img = Nifti1Image(ex2, affine=img.affine)
    ex2_img.to_filename(sys.argv[5])
    intersection_img = Nifti1Image(intersection, affine=img.affine)
    intersection_img.to_filename(sys.argv[6])
コード例 #23
0
def cluster_stats(stat_img, mask_img, threshold, height_control='fpr',
                  cluster_th=0, nulls=None):
    """
    Return a list of clusters, each cluster being represented by a
    dictionary. Clusters are sorted by descending size order. Within
    each cluster, local maxima are sorted by descending statical value

    Parameters
    ----------
    stat_img: Niimg-like object,
       statsitical image (presumably in z scale)
    mask_img: Niimg-like object,
        mask image
    threshold: float,
        cluster forming threshold (either a p-value or z-scale value)
    height_control: string
        false positive control meaning of cluster forming
        threshold: 'fpr'|'fdr'|'bonferroni'|'none'
    cluster_th: int or float,
        cluster size threshold
    nulls: dictionary,
        statistics of the null distribution

    Notes
    -----
    If there is no cluster, an empty list is returned
    """
    if nulls is None: nulls = {}

    # Masking
    mask_img, stat_img = check_niimg(mask_img), check_niimg(stat_img)
    if not _check_same_fov(mask_img, stat_img):
        raise ValueError('mask_img and stat_img do not have the same fov')
    mask = mask_img.get_data().astype(np.bool)
    affine = mask_img.get_affine()
    stat_map = stat_img.get_data() * mask
    n_voxels = mask.sum()

    # Thresholding
    if height_control == 'fpr':
        z_th = norm.isf(threshold)
    elif height_control == 'fdr':
        z_th = fdr_threshold(stat_map[mask], threshold)
    elif height_control == 'bonferroni':
        z_th = norm.isf(threshold / n_voxels)
    else:  # Brute-force thresholding
        z_th = threshold

    p_th = norm.sf(z_th)
    # General info
    info = {'n_voxels': n_voxels,
            'threshold_z': z_th,
            'threshold_p': p_th,
            'threshold_pcorr': np.minimum(1, p_th * n_voxels)}

    above_th = stat_map > z_th
    above_values = stat_map * above_th
    if (above_th == 0).all():
        return [], info

    # Extract connected components above threshold
    labels, n_labels = label(above_th)

    # Extract the local maxima anove the threshold
    maxima_mask = (above_values ==
                   np.maximum(z_th, maximum_filter(above_values, 3)))
    x, y, z = np.array(np.where(maxima_mask))
    maxima_coords = np.array(coord_transform(x, y, z, affine)).T
    maxima_labels = labels[maxima_mask]
    maxima_values = above_values[maxima_mask]

    # FDR-corrected p-values
    max_fdr_p_values = fdr_p_values(stat_map[mask])[maxima_mask[mask]]

    # Default "nulls"
    if not 'zmax' in nulls:
        nulls['zmax'] = 'bonferroni'
    if not 'smax' in nulls:
        nulls['smax'] = None
    if not 's' in nulls:
        nulls['s'] = None

    # Make list of clusters, each cluster being a dictionary
    clusters = []
    for k in range(n_labels):
        cluster_size = np.sum(labels == k + 1)
        if cluster_size >= cluster_th:

            # get the position of the maxima that belong to that cluster
            in_cluster = maxima_labels == k + 1

            # sort the maxima by decreasing statistical value
            max_vals = maxima_values[in_cluster]
            sorted_ = max_vals.argsort()[::-1]

            # Report significance levels in each cluster
            z_score = max_vals[sorted_]
            p_values = norm.sf(z_score)

            # Voxel-level corrected p-values
            fwer_p_value = None
            if nulls['zmax'] == 'bonferroni':
                fwer_p_value = np.minimum(1, p_values * n_voxels)
            elif isinstance(nulls['zmax'], np.ndarray):
                fwer_p_value = empirical_p_value(
                    clusters['z_score'], nulls['zmax'])

            # Cluster-level p-values (corrected)
            cluster_fwer_p_value = None
            if isinstance(nulls['smax'], np.ndarray):
                cluster_fwer_p_value = empirical_p_value(
                    cluster_size, nulls['smax'])

            # Cluster-level p-values (uncorrected)
            cluster_p_value = None
            if isinstance(nulls['s'], np.ndarray):
                cluster_p_value = empirical_p_value(
                    cluster_size, nulls['s'])

            # write all this into the cluster structure
            clusters.append({
                    'size': cluster_size,
                    'maxima': maxima_coords[in_cluster][sorted_],
                    'z_score': z_score,
                    'fdr_p_value': max_fdr_p_values[in_cluster][sorted_],
                    'p_value': p_values,
                    'fwer_p_value': fwer_p_value,
                    'cluster_fwer_p_value': cluster_fwer_p_value,
                    'cluster_p_value': cluster_p_value
                    })

    # Sort clusters by descending size order
    order = np.argsort(- np.array([cluster['size'] for cluster in clusters]))
    clusters = [clusters[i] for i in order]

    return clusters, info
コード例 #24
0
    def fit(self, run_imgs, events=None, confounds=None, design_matrices=None):
        """ Fit the GLM

        For each run:
        1. create design matrix X
        2. do a masker job: fMRI_data -> Y
        3. fit regression to (Y, X)

        Parameters
        ----------
        run_imgs: Niimg-like object or list of Niimg-like objects,
            See http://nilearn.github.io/manipulating_images/input_output.html#inputing-data-file-names-or-image-objects
            Data on which the GLM will be fitted. If this is a list,
            the affine is considered the same for all.

        events: pandas Dataframe or string or list of pandas DataFrames or
                   strings
                   
            fMRI events used to build design matrices. One events object
            expected per run_img. Ignored in case designs is not None.
            If string, then a path to a csv file is expected.

        confounds: pandas Dataframe or string or list of pandas DataFrames or
                   strings
                   
            Each column in a DataFrame corresponds to a confound variable
            to be included in the regression model of the respective run_img.
            The number of rows must match the number of volumes in the
            respective run_img. Ignored in case designs is not None.
            If string, then a path to a csv file is expected.

        design_matrices: pandas DataFrame or list of pandas DataFrames,
            Design matrices that will be used to fit the GLM. If given it
            takes precedence over events and confounds.

        """
        # Check arguments
        # Check imgs type
        if events is not None:
            _check_events_file_uses_tab_separators(events_files=events)
        if not isinstance(run_imgs, (list, tuple)):
            run_imgs = [run_imgs]
        if design_matrices is None:
            if events is None:
                raise ValueError('events or design matrices must be provided')
            if self.t_r is None:
                raise ValueError('t_r not given to FirstLevelModel object'
                                 ' to compute design from events')
        else:
            design_matrices = _check_run_tables(run_imgs, design_matrices,
                                                'design_matrices')
        # Check that number of events and confound files match number of runs
        # Also check that events and confound files can be loaded as DataFrame
        if events is not None:
            events = _check_run_tables(run_imgs, events, 'events')
        if confounds is not None:
            confounds = _check_run_tables(run_imgs, confounds, 'confounds')

        # Learn the mask
        if self.mask_img is False:
            # We create a dummy mask to preserve functionality of api
            ref_img = check_niimg(run_imgs[0])
            self.mask_img = Nifti1Image(np.ones(ref_img.shape[:3]),
                                        ref_img.affine)
        if not isinstance(self.mask_img, NiftiMasker):
            self.masker_ = NiftiMasker(mask_img=self.mask_img,
                                       smoothing_fwhm=self.smoothing_fwhm,
                                       target_affine=self.target_affine,
                                       standardize=self.standardize,
                                       mask_strategy='epi',
                                       t_r=self.t_r,
                                       memory=self.memory,
                                       verbose=max(0, self.verbose - 2),
                                       target_shape=self.target_shape,
                                       memory_level=self.memory_level)
            self.masker_.fit(run_imgs[0])
        else:
            if self.mask_img.mask_img_ is None and self.masker_ is None:
                self.masker_ = clone(self.mask_img)
                for param_name in [
                        'target_affine', 'target_shape', 'smoothing_fwhm',
                        't_r', 'memory', 'memory_level'
                ]:
                    our_param = getattr(self, param_name)
                    if our_param is None:
                        continue
                    if getattr(self.masker_, param_name) is not None:
                        warn('Parameter %s of the masker'
                             ' overriden' % param_name)
                    setattr(self.masker_, param_name, our_param)
                self.masker_.fit(run_imgs[0])
            else:
                self.masker_ = self.mask_img

        # For each run fit the model and keep only the regression results.
        self.labels_, self.results_, self.design_matrices_ = [], [], []
        n_runs = len(run_imgs)
        t0 = time.time()
        for run_idx, run_img in enumerate(run_imgs):
            # Report progress
            if self.verbose > 0:
                percent = float(run_idx) / n_runs
                percent = round(percent * 100, 2)
                dt = time.time() - t0
                # We use a max to avoid a division by zero
                if run_idx == 0:
                    remaining = 'go take a coffee, a big one'
                else:
                    remaining = (100. - percent) / max(0.01, percent) * dt
                    remaining = '%i seconds remaining' % remaining

                sys.stderr.write("Computing run %d out of %d runs (%s)\n" %
                                 (run_idx + 1, n_runs, remaining))

            # Build the experimental design for the glm
            run_img = check_niimg(run_img, ensure_ndim=4)
            if design_matrices is None:
                n_scans = run_img.get_data().shape[3]
                if confounds is not None:
                    confounds_matrix = confounds[run_idx].values
                    if confounds_matrix.shape[0] != n_scans:
                        raise ValueError('Rows in confounds does not match'
                                         'n_scans in run_img at index %d' %
                                         (run_idx, ))
                    confounds_names = confounds[run_idx].columns.tolist()
                else:
                    confounds_matrix = None
                    confounds_names = None
                start_time = self.slice_time_ref * self.t_r
                end_time = (n_scans - 1 + self.slice_time_ref) * self.t_r
                frame_times = np.linspace(start_time, end_time, n_scans)
                design = make_first_level_design_matrix(
                    frame_times, events[run_idx], self.hrf_model,
                    self.drift_model, self.high_pass, self.drift_order,
                    self.fir_delays, confounds_matrix, confounds_names,
                    self.min_onset)
            else:
                design = design_matrices[run_idx]
            self.design_matrices_.append(design)

            # Mask and prepare data for GLM
            if self.verbose > 1:
                t_masking = time.time()
                sys.stderr.write('Starting masker computation \r')

            Y = self.masker_.transform(run_img)

            if self.verbose > 1:
                t_masking = time.time() - t_masking
                sys.stderr.write('Masker took %d seconds       \n' % t_masking)

            if self.signal_scaling:
                Y, _ = mean_scaling(Y, self.scaling_axis)
            if self.memory:
                mem_glm = self.memory.cache(run_glm, ignore=['n_jobs'])
            else:
                mem_glm = run_glm

            # compute GLM
            if self.verbose > 1:
                t_glm = time.time()
                sys.stderr.write('Performing GLM computation\r')
            labels, results = mem_glm(Y,
                                      design.values,
                                      noise_model=self.noise_model,
                                      bins=100,
                                      n_jobs=self.n_jobs)
            if self.verbose > 1:
                t_glm = time.time() - t_glm
                sys.stderr.write('GLM took %d seconds         \n' % t_glm)

            self.labels_.append(labels)
            # We save memory if inspecting model details is not necessary
            if self.minimize_memory:
                for key in results:
                    results[key] = SimpleRegressionResults(results[key])
            self.results_.append(results)
            del Y

        # Report progress
        if self.verbose > 0:
            sys.stderr.write(
                "\nComputation of %d runs done in %i seconds\n\n" %
                (n_runs, time.time() - t0))

        return self
コード例 #25
0
def _check_second_level_input(second_level_input,
                              design_matrix,
                              confounds=None,
                              flm_object=True,
                              df_object=True):
    """Checking second_level_input type"""
    # Check parameters
    # check first level input
    if isinstance(second_level_input, list):
        if len(second_level_input) < 2:
            raise ValueError('A second level model requires a list with at'
                             ' least two first level models or niimgs')
        # Check FirstLevelModel objects case
        if flm_object and isinstance(second_level_input[0], FirstLevelModel):
            models_input = enumerate(second_level_input)
            for model_idx, first_level in models_input:
                if (first_level.labels_ is None
                        or first_level.results_ is None):
                    raise ValueError(
                        'Model %s at index %i has not been fit yet'
                        '' % (first_level.subject_label, model_idx))
                if not isinstance(first_level, FirstLevelModel):
                    raise ValueError(' object at idx %d is %s instead of'
                                     ' FirstLevelModel object' %
                                     (model_idx, type(first_level)))
                if confounds is not None:
                    if first_level.subject_label is None:
                        raise ValueError(
                            'In case confounds are provided, first level '
                            'objects need to provide the attribute '
                            'subject_label to match rows appropriately.'
                            'Model at idx %d does not provide it. '
                            'To set it, you can do '
                            'first_level.subject_label = "01"'
                            '' % (model_idx))
        # Check niimgs case
        elif isinstance(second_level_input[0], (str, Nifti1Image)):
            if design_matrix is None:
                raise ValueError('List of niimgs as second_level_input'
                                 ' require a design matrix to be provided')
            for model_idx, niimg in enumerate(second_level_input):
                if not isinstance(niimg, (str, Nifti1Image)):
                    raise ValueError(' object at idx %d is %s instead of'
                                     ' Niimg-like object' %
                                     (model_idx, type(niimg)))
    # Check pandas dataframe case
    elif df_object and isinstance(second_level_input, pd.DataFrame):
        for col in ['subject_label', 'map_name', 'effects_map_path']:
            if col not in second_level_input.columns:
                raise ValueError('second_level_input DataFrame must have'
                                 ' columns subject_label, map_name and'
                                 ' effects_map_path')
        # Make sure subject_label contain strings
        if not all([
                isinstance(_, str)
                for _ in second_level_input['subject_label'].tolist()
        ]):
            raise ValueError('subject_label column must contain only strings')
    elif isinstance(second_level_input, (str, Nifti1Image)):
        if design_matrix is None:
            raise ValueError('List of niimgs as second_level_input'
                             ' require a design matrix to be provided')
        second_level_input = check_niimg(niimg=second_level_input,
                                         ensure_ndim=4)
    else:
        if flm_object and df_object:
            raise ValueError('second_level_input must be a list of'
                             ' `FirstLevelModel` objects, a pandas DataFrame'
                             ' or a list Niimg-like objects. Instead %s '
                             'was provided' % type(second_level_input))
        else:
            raise ValueError('second_level_input must be'
                             ' a list Niimg-like objects. Instead %s '
                             'was provided' % type(second_level_input))
コード例 #26
0
ファイル: plotting.py プロジェクト: erramuzpe/pypes
 def _index_img(img_file, index):
     """ Return the volume in `index` 4th dimension index of `img_file`.
     If the image is 3D and idx is zero will return the container of `img_file`.
     """
     imgs = check_niimg(img_file, ensure_ndim=4, atleast_4d=True)
     return _index_img(imgs, index)
コード例 #27
0
ファイル: second_level_model.py プロジェクト: nistats/nistats
def _check_second_level_input(second_level_input, design_matrix,
                              confounds=None, flm_object=True, df_object=True):
    """Checking second_level_input type"""
    # Check parameters
    # check first level input
    if isinstance(second_level_input, list):
        if len(second_level_input) < 2:
            raise ValueError('A second level model requires a list with at'
                             ' least two first level models or niimgs')
        # Check FirstLevelModel objects case
        if flm_object and isinstance(second_level_input[0], FirstLevelModel):
            models_input = enumerate(second_level_input)
            for model_idx, first_level_model in models_input:
                if (first_level_model.labels_ is None or
                        first_level_model.results_ is None):
                    raise ValueError(
                        'Model %s at index %i has not been fit yet'
                        '' % (first_level_model.subject_label, model_idx))
                if not isinstance(first_level_model, FirstLevelModel):
                    raise ValueError(' object at idx %d is %s instead of'
                                     ' FirstLevelModel object' %
                                     (model_idx, type(first_level_model)))
                if confounds is not None:
                    if first_level_model.subject_label is None:
                        raise ValueError(
                            'In case confounds are provided, first level '
                            'objects need to provide the attribute '
                            'subject_label to match rows appropriately.'
                            'Model at idx %d does not provide it. '
                            'To set it, you can do '
                            'first_level_model.subject_label = "01"'
                            '' % (model_idx))
        # Check niimgs case
        elif isinstance(second_level_input[0], (str, Nifti1Image)):
            if design_matrix is None:
                raise ValueError('List of niimgs as second_level_input'
                                 ' require a design matrix to be provided')
            for model_idx, niimg in enumerate(second_level_input):
                if not isinstance(niimg, (str, Nifti1Image)):
                    raise ValueError(' object at idx %d is %s instead of'
                                     ' Niimg-like object' %
                                     (model_idx, type(niimg)))
    # Check pandas dataframe case
    elif df_object and isinstance(second_level_input, pd.DataFrame):
        for col in ['subject_label', 'map_name', 'effects_map_path']:
            if col not in second_level_input.columns:
                raise ValueError('second_level_input DataFrame must have'
                                 ' columns subject_label, map_name and'
                                 ' effects_map_path')
        # Make sure subject_label contain strings
        second_level_columns = second_level_input.columns.tolist()
        labels_index = second_level_columns.index('subject_label')
        labels_dtype = second_level_input.dtypes[labels_index]
        if not isinstance(labels_dtype, np.object):
            raise ValueError('subject_label column must be of dtype '
                             'object instead of dtype %s' % labels_dtype)
    elif isinstance(second_level_input, (str, Nifti1Image)):
        if design_matrix is None:
            raise ValueError('List of niimgs as second_level_input'
                             ' require a design matrix to be provided')
        second_level_input = check_niimg(niimg=second_level_input,
                                         ensure_ndim=4)
    else:
        if flm_object and df_object:
            raise ValueError('second_level_input must be a list of'
                             ' `FirstLevelModel` objects, a pandas DataFrame'
                             ' or a list Niimg-like objects. Instead %s '
                             'was provided' % type(second_level_input))
        else:
            raise ValueError('second_level_input must be'
                             ' a list Niimg-like objects. Instead %s '
                             'was provided' % type(second_level_input))
コード例 #28
0
def fetch_atlas_dorr_2008(image_format='nifti',
                          downsample='30',
                          data_dir=None,
                          url=None,
                          resume=True,
                          verbose=1):
    """Download and load Dorr et al. atlas and average (dated 2008)

    Parameters
    ----------
    image_format : one of {'nifti', 'minc'}, optional
        Format to download

    downsample : one of {'30', '100'}, optional
        Downsampling resolution in microns.

    data_dir : str, optional
        Path of the data directory. Use to forec data storage in a non-
        standard location. Default: None (meaning: default)

    url: string, optional
        Download URL of the dataset. Overwrite the default URL.

    resume : bool
        whether to resumed download of a partly-downloaded file.

    verbose : int
        verbosity level (0 means no message).

    Returns
    -------
    data: sklearn.datasets.base.Bunch
        dictionary-like object, contains:

        - 't2' : str, path to nifti file containing the T2 weighted average.

        - 'maps' : str, path to nifti file containing regions definition.

        - 'names' : str list containing the names of the regions.

        - 'labels' : int list containing the label value of each region.

        - 'description' : description about the atlas and the template.

    References
    ----------

    A.E. Dorr, J.P. Lerch, S. Spring, N. Kabani and R.M. Henkelman. "High
    resolution three dimensional brain atlas using an average magnetic
    resonance image of 40 adult C57Bl/6j mice", NeuroImage 42(1):60-69, 2008.

    See http://www.mouseimaging.ca/research/mouse_atlas.html for more
    information on this parcellation.

    Licence: Unknown
    """
    if image_format not in ['nifti', 'minc']:
        raise ValueError("Images format must be 'nifti' or 'minc', you "
                         "entered {0}".format(image_format))

    if downsample not in ['30', '100']:
        raise ValueError("'downsample' must be '30' or '100', you "
                         "provided {0}".format(downsample))

    if url is None:
        if image_format == 'minc':
            url = [
                'http://www.mouseimaging.ca/mnc/C57Bl6j_mouse_atlas/',
                'http://www.mouseimaging.ca/mnc/C57Bl6j_mouse_atlas/',
                'http://www.mouseimaging.ca/research/C57Bl6j_mouse_atlas/'
            ]
        else:
            url = [
                'http://repo.mouseimaging.ca/repo/Dorr_2008_nifti/',
                'http://repo.mouseimaging.ca/repo/Dorr_2008_nifti/',
                'http://www.mouseimaging.ca/research/C57Bl6j_mouse_atlas/'
            ]

    if image_format == 'minc':
        files = [
            'male-female-mouse-atlas.mnc', 'c57_fixed_labels_resized.mnc',
            'c57_brain_atlas_labels.csv'
        ]
    else:
        files = [
            'Dorr_2008_average.nii.gz', 'Dorr_2008_labels.nii.gz',
            'c57_brain_atlas_labels.csv'
        ]

    files = [(f, u + f, {}) for f, u in zip(files, url)]

    dataset_name = 'dorr_2008'
    data_dir = _get_dataset_dir(dataset_name,
                                data_dir=data_dir,
                                verbose=verbose)
    files_ = _fetch_files(data_dir, files, resume=resume, verbose=verbose)

    fdescr = _get_dataset_descr(dataset_name)
    csv_data = np.recfromcsv(files_[2],
                             skip_header=True,
                             names=('roi_id', 'roi_label', 'right_index',
                                    'left_index'))

    #TODO try dictionary with their region id as key and name as value
    left_rois = []
    right_rois = []
    lateral_rois = []
    for (idx, label, right_index, left_index) in csv_data:
        label = label.decode('UTF-8')  # for python3
        if right_index == left_index:
            lateral_rois.append((label, right_index))
        else:
            left_rois.append(('L {}'.format(label), left_index))
            right_rois.append(('R {}'.format(label), right_index))

    rois = lateral_rois + right_rois + left_rois
    labels, indices = map(list, zip(*rois))
    t2 = files_[0]
    maps = files_[1]
    if downsample == '100':
        t2_img = nibabel.load(t2)
        maps_img = check_niimg(maps, dtype=int)
        t2 = fname_presuffix(t2, suffix='_100um')
        maps = fname_presuffix(maps, suffix='_100um')
        if not os.path.isfile(t2):
            target_affine = np.eye(3) * .1
            t2_img = image.resample_img(t2_img, target_affine)
            t2_img.to_filename(t2)
        if not os.path.isfile(maps):
            maps_img = image.resample_img(maps_img,
                                          target_affine,
                                          interpolation='nearest')
            maps_img.to_filename(maps)

    params = dict(t2=t2,
                  maps=maps,
                  names=np.array(labels)[np.argsort(indices)],
                  labels=np.sort(indices),
                  description=fdescr)

    return Bunch(**params)
コード例 #29
0
def fetch_masks_dorr_2008(image_format='nifti',
                          downsample='30',
                          data_dir=None,
                          resume=True,
                          verbose=1):
    """Downloads DORR 2008 atlas first, then uses its labels to produce tissue
    masks.

    Parameters
    ----------
    image_format : one of {'nifti', 'minc'}, optional
        Format to download

    downsample : one of {'30', '100'}, optional
        Downsampling resolution in microns.

    data_dir : str, optional
        Path of the data directory. Use to forec data storage in a non-
        standard location. Default: None (meaning: default)

    resume : bool, optional
        whether to resumed download of a partly-downloaded file.

    verbose : int, optional
        verbosity level (0 means no message).

    Returns
    -------
    mask_imgs: sklearn.datasets.base.Bunch
        dictionary-like object, contains:

        - 'brain' : nibabel.nifti1.Nifti1Image brain mask image.

        - 'gm' : nibabel.nifti1.Nifti1Image grey matter mask image.

        - 'cc' : nibabel.nifti1.Nifti1Image eroded corpus callosum mask image.

        - 'ventricles' : nibabel.nifti1.Nifti1Image eroded ventricles mask
                         image.

    Notes
    -----
    This function relies on DORR 2008 atlas where we particularly pick
    ventricles and corpus callosum regions. Then, do a bit post processing
    such as binary closing operation to more compact brain and grey matter
    mask image and binary erosion to non-contaminated corpus callosum
    and ventricles mask images.
    Note: It is advised to check the mask images with your own data processing.

    See Also
    --------
    sammba.data_fetchers.fetch_atlas_dorr_2008: for details regarding
        the DORR 2008 atlas.
    """
    masks_dir = _get_dataset_dir('dorr_2008',
                                 data_dir=data_dir,
                                 verbose=verbose)
    if image_format == 'nifti':
        ext = '.nii.gz'
    elif image_format == 'minc':
        ext = '.minc'
    else:
        raise ValueError("Images format must be 'nifti' or 'minc', you "
                         "entered {0}".format(image_format))

    brain_mask_file = os.path.join(
        masks_dir, 'dorr_2008_brain_mask_{}{}'.format(downsample, ext))
    gm_mask_file = os.path.join(
        masks_dir, 'dorr_2008_gm_mask_{}{}'.format(downsample, ext))
    cc_mask_file = os.path.join(
        masks_dir, 'dorr_2008_cc_mask_{}{}'.format(downsample, ext))
    ventricles_mask_file = os.path.join(
        masks_dir, 'dorr_2008_ventricles_mask_{}{}'.format(downsample, ext))
    existing_mask_files = [
        os.path.isfile(f) for f in
        [brain_mask_file, gm_mask_file, cc_mask_file, ventricles_mask_file]
    ]
    if not np.all(existing_mask_files):
        # Fetching DORR 2008 atlas
        dorr = fetch_atlas_dorr_2008(image_format=image_format,
                                     downsample=downsample,
                                     data_dir=data_dir,
                                     resume=resume,
                                     verbose=verbose)
        atlas_img = check_niimg(dorr.maps)
        atlas_data = niimg._safe_get_data(atlas_img).astype(int)

    if not os.path.isfile(brain_mask_file):
        brain_mask = (atlas_data > 0)
        brain_mask = ndimage.binary_closing(brain_mask, iterations=2)
        brain_mask_img = image.new_img_like(atlas_img, brain_mask)
        brain_mask_img.to_filename(brain_mask_file)

    if not os.path.isfile(cc_mask_file):
        cc_labels = dorr.labels[np.in1d(
            dorr.names.astype(str),
            ['R corpus callosum', 'L corpus callosum'])]
        cc_mask = np.max([atlas_data == value for value in cc_labels], axis=0)
        eroded_cc_mask = ndimage.binary_erosion(cc_mask, iterations=2)
        cc_mask_img = image.new_img_like(atlas_img, eroded_cc_mask)
        cc_mask_img.to_filename(cc_mask_file)

    if not os.path.isfile(ventricles_mask_file):
        ventricles_names = [
            'R lateral ventricle', 'L lateral ventricle', 'third ventricle',
            'fourth ventricle'
        ]
        ventricles_labels = dorr.labels[np.in1d(dorr.names.astype(str),
                                                ventricles_names)]
        ventricles_mask = np.max(
            [atlas_data == value for value in ventricles_labels], axis=0)
        eroded_ventricles_mask = ndimage.binary_erosion(ventricles_mask,
                                                        iterations=2)
        ventricles_mask_img = image.new_img_like(atlas_img,
                                                 eroded_ventricles_mask)
        ventricles_mask_img.to_filename(ventricles_mask_file)

    if not os.path.isfile(gm_mask_file):
        gm_mask_img = image.math_img(
            'np.logical_not(np.logical_or(ventricles_mask_img, cc_mask_img))',
            ventricles_mask_img=ventricles_mask_img,
            cc_mask_img=cc_mask_img)
        gm_mask_img = image.math_img(
            'np.logical_and(brain_mask_img, gm_mask_img)',
            brain_mask_img=brain_mask_img,
            gm_mask_img=gm_mask_img)
        gm_mask_closed_data = ndimage.binary_closing(gm_mask_img.get_data(),
                                                     iterations=2)
        gm_mask_img = image.new_img_like(gm_mask_img, gm_mask_closed_data)
        gm_mask_img.to_filename(gm_mask_file)

    mask_files = {
        'brain': brain_mask_file,
        'gm': gm_mask_file,
        'cc': cc_mask_file,
        'ventricles': ventricles_mask_file
    }

    return Bunch(**mask_files)
コード例 #30
0
                                             sammba_registered_atlas_file,
                                             suffix='_warped'))
        spm_atlas_id = atlas_id.replace('_corrected', '')
        if mouse_id == '_C57_ab2_invivo_corrected.nii.gz':
            spm_atlas_id = '_Ab2_invivo.nii.gz'
        elif mouse_id == '_C57_y81_Invivo_corrected.nii.gz':
            spm_atlas_id = '_y81_invivo.nii.gz'

        spm_registered_atlas_file = fname_presuffix(
            spm_atlas_id,
            newpath=spm_dir,
            prefix='wbil2_transfo_Atlas',
            suffix='.nii',
            use_ext=False)

        spm_registered_atlas_data = check_niimg(
            spm_registered_atlas_file).get_data()
        template_shape = check_niimg(spm_template_atlas_file).shape
        if spm_registered_atlas_data.shape != template_shape:
            uncropped_spm_registered_atlas_data = np.vstack(
                (np.zeros((1, ) + template_shape[1:]),
                 spm_registered_atlas_data))
            uncropped_spm_registered_atlas_data = np.nan_to_num(
                uncropped_spm_registered_atlas_data)
            uncropped_spm_registered_atlas_file = fname_presuffix(
                spm_registered_atlas_file, suffix='_uncropped')
            image.new_img_like(
                spm_registered_atlas_file,
                uncropped_spm_registered_atlas_data).to_filename(
                    uncropped_spm_registered_atlas_file)

        else:
コード例 #31
0
ファイル: first_level_model.py プロジェクト: bthirion/nistats
    def fit(self, run_imgs, events=None, confounds=None,
            design_matrices=None):
        """ Fit the GLM

        For each run:
        1. create design matrix X
        2. do a masker job: fMRI_data -> Y
        3. fit regression to (Y, X)

        Parameters
        ----------
        run_imgs: Niimg-like object or list of Niimg-like objects,
            See http://nilearn.github.io/manipulating_images/input_output.html#inputing-data-file-names-or-image-objects
            Data on which the GLM will be fitted. If this is a list,
            the affine is considered the same for all.

        events: pandas Dataframe or string or list of pandas DataFrames or
                   strings
                   
            fMRI events used to build design matrices. One events object
            expected per run_img. Ignored in case designs is not None.
            If string, then a path to a csv file is expected.

        confounds: pandas Dataframe or string or list of pandas DataFrames or
                   strings
                   
            Each column in a DataFrame corresponds to a confound variable
            to be included in the regression model of the respective run_img.
            The number of rows must match the number of volumes in the
            respective run_img. Ignored in case designs is not None.
            If string, then a path to a csv file is expected.

        design_matrices: pandas DataFrame or list of pandas DataFrames,
            Design matrices that will be used to fit the GLM. If given it
            takes precedence over events and confounds.

        """
        # Check arguments
        # Check imgs type
        if events is not None:
            _check_events_file_uses_tab_separators(
                events_files=events)
        if not isinstance(run_imgs, (list, tuple)):
            run_imgs = [run_imgs]
        if design_matrices is None:
            if events is None:
                raise ValueError('events or design matrices must be provided')
            if self.t_r is None:
                raise ValueError('t_r not given to FirstLevelModel object'
                                 ' to compute design from events')
        else:
            design_matrices = _check_run_tables(run_imgs, design_matrices,
                                                'design_matrices')
        # Check that number of events and confound files match number of runs
        # Also check that events and confound files can be loaded as DataFrame
        if events is not None:
            events = _check_run_tables(run_imgs, events, 'events')
        if confounds is not None:
            confounds = _check_run_tables(run_imgs, confounds, 'confounds')

        # Learn the mask
        if self.mask_img is False:
            # We create a dummy mask to preserve functionality of api
            ref_img = check_niimg(run_imgs[0])
            self.mask_img = Nifti1Image(np.ones(ref_img.shape[:3]),
                                        ref_img.affine)
        if not isinstance(self.mask_img, NiftiMasker):
            self.masker_ = NiftiMasker(
                mask_img=self.mask_img, smoothing_fwhm=self.smoothing_fwhm,
                target_affine=self.target_affine,
                standardize=self.standardize, mask_strategy='epi',
                t_r=self.t_r, memory=self.memory,
                verbose=max(0, self.verbose - 2),
                target_shape=self.target_shape,
                memory_level=self.memory_level)
            self.masker_.fit(run_imgs[0])
        else:
            if self.mask_img.mask_img_ is None and self.masker_ is None:
                self.masker_ = clone(self.mask_img)
                for param_name in ['target_affine', 'target_shape',
                                   'smoothing_fwhm', 't_r', 'memory',
                                   'memory_level']:
                    our_param = getattr(self, param_name)
                    if our_param is None:
                        continue
                    if getattr(self.masker_, param_name) is not None:
                        warn('Parameter %s of the masker'
                             ' overriden' % param_name)
                    setattr(self.masker_, param_name, our_param)
                self.masker_.fit(run_imgs[0])
            else:
                self.masker_ = self.mask_img

        # For each run fit the model and keep only the regression results.
        self.labels_, self.results_, self.design_matrices_ = [], [], []
        n_runs = len(run_imgs)
        t0 = time.time()
        for run_idx, run_img in enumerate(run_imgs):
            # Report progress
            if self.verbose > 0:
                percent = float(run_idx) / n_runs
                percent = round(percent * 100, 2)
                dt = time.time() - t0
                # We use a max to avoid a division by zero
                if run_idx == 0:
                    remaining = 'go take a coffee, a big one'
                else:
                    remaining = (100. - percent) / max(0.01, percent) * dt
                    remaining = '%i seconds remaining' % remaining

                sys.stderr.write(
                    "Computing run %d out of %d runs (%s)\n"
                    % (run_idx + 1, n_runs, remaining))

            # Build the experimental design for the glm
            run_img = check_niimg(run_img, ensure_ndim=4)
            if design_matrices is None:
                n_scans = run_img.get_data().shape[3]
                if confounds is not None:
                    confounds_matrix = confounds[run_idx].values
                    if confounds_matrix.shape[0] != n_scans:
                        raise ValueError('Rows in confounds does not match'
                                         'n_scans in run_img at index %d'
                                         % (run_idx,))
                    confounds_names = confounds[run_idx].columns.tolist()
                else:
                    confounds_matrix = None
                    confounds_names = None
                start_time = self.slice_time_ref * self.t_r
                end_time = (n_scans - 1 + self.slice_time_ref) * self.t_r
                frame_times = np.linspace(start_time, end_time, n_scans)
                design = make_first_level_design_matrix(frame_times, events[run_idx],
                                                        self.hrf_model, self.drift_model,
                                                        self.period_cut, self.drift_order,
                                                        self.fir_delays, confounds_matrix,
                                                        confounds_names, self.min_onset)
            else:
                design = design_matrices[run_idx]
            self.design_matrices_.append(design)

            # Mask and prepare data for GLM
            if self.verbose > 1:
                t_masking = time.time()
                sys.stderr.write('Starting masker computation \r')

            Y = self.masker_.transform(run_img)

            if self.verbose > 1:
                t_masking = time.time() - t_masking
                sys.stderr.write('Masker took %d seconds       \n' % t_masking)

            if self.signal_scaling:
                Y, _ = mean_scaling(Y, self.scaling_axis)
            if self.memory:
                mem_glm = self.memory.cache(run_glm, ignore=['n_jobs'])
            else:
                mem_glm = run_glm

            # compute GLM
            if self.verbose > 1:
                t_glm = time.time()
                sys.stderr.write('Performing GLM computation\r')
            labels, results = mem_glm(Y, design.values,
                                      noise_model=self.noise_model,
                                      bins=100, n_jobs=self.n_jobs)
            if self.verbose > 1:
                t_glm = time.time() - t_glm
                sys.stderr.write('GLM took %d seconds         \n' % t_glm)

            self.labels_.append(labels)
            # We save memory if inspecting model details is not necessary
            if self.minimize_memory:
                for key in results:
                    results[key] = SimpleRegressionResults(results[key])
            self.results_.append(results)
            del Y

        # Report progress
        if self.verbose > 0:
            sys.stderr.write("\nComputation of %d runs done in %i seconds\n\n"
                             % (n_runs, time.time() - t0))

        return self
コード例 #32
0
    def fit(self, run_imgs, paradigms=None, confounds=None,
            design_matrices=None):
        """ Fit the GLM

        For each run:
        1. create design matrix X
        2. do a masker job: fMRI_data -> Y
        3. fit regression to (Y, X)

        Parameters
        ----------
        run_imgs: Niimg-like object or list of Niimg-like objects,
            See http://nilearn.github.io/building_blocks/manipulating_mr_images.html#niimg.
            Data on which the GLM will be fitted. If this is a list,
            the affine is considered the same for all.

        paradigms: pandas Dataframe or string or list of pandas DataFrames or
                   strings,
            fMRI paradigms used to build design matrices. One paradigm expected
            per run_img. Ignored in case designs is not None.

        confounds: pandas Dataframe or string or list of pandas DataFrames or
                   strings,
            Each column in a DataFrame corresponds to a confound variable
            to be included in the regression model of the respective run_img.
            The number of rows must match the number of volumes in the
            respective run_img. Ignored in case designs is not None.

        design_matrices: pandas DataFrame or list of pandas DataFrames,
            Design matrices that will be used to fit the GLM.
        """
        # Check arguments
        # Check imgs type
        if not isinstance(run_imgs, (list, tuple)):
            run_imgs = [run_imgs]
        for rimg in run_imgs:
            if not isinstance(rimg, (_basestring, Nifti1Image)):
                raise ValueError('run_imgs must be Niimg-like object or list'
                                 ' of Niimg-like objects')
        # check all information necessary to build design matrices is available
        if design_matrices is None:
            if paradigms is None:
                raise ValueError('paradigms or design matrices must be provided')
            if self.t_r is None:
                raise ValueError('t_r not given to FirstLevelModel object'
                                 ' to compute design from paradigm')
        else:
            design_matrices = _check_run_tables(run_imgs, design_matrices,
                                                'design_matrices')
        # check the number of paradigm and confound files match number of runs
        # Also check paradigm and confound files can be loaded as DataFrame
        if paradigms is not None:
            paradigms = _check_run_tables(run_imgs, paradigms, 'paradigms')

        if confounds is not None:
            confounds = _check_run_tables(run_imgs, confounds, 'confounds')

        # Learn the mask
        if not isinstance(self.mask, NiftiMasker):
            self.masker_ = NiftiMasker(
                mask_img=self.mask, smoothing_fwhm=self.smoothing_fwhm,
                target_affine=self.target_affine,
                standardize=self.standardize, mask_strategy='epi',
                t_r=self.t_r, memory=self.memory,
                verbose=max(0, self.verbose - 1),
                target_shape=self.target_shape,
                memory_level=self.memory_level)
        else:
            self.masker_ = clone(self.mask)
            for param_name in ['target_affine', 'target_shape',
                               'smoothing_fwhm', 'low_pass', 'high_pass',
                               't_r', 'memory', 'memory_level']:
                our_param = getattr(self, param_name)
                if our_param is None:
                    continue
                if getattr(self.masker_, param_name) is not None:
                    warn('Parameter %s of the masker overriden' % param_name)
                setattr(self.masker_, param_name, our_param)
        self.masker_.fit(run_imgs[0])

        # For each run fit the model and keep only the regression results.
        self.labels_, self.results_, self.design_matrices_ = [], [], []
        n_runs = len(run_imgs)
        t0 = time.time()
        for run_idx, run_img in enumerate(run_imgs):
            # Report progress
            if self.verbose > 0:
                percent = float(run_idx) / n_runs
                percent = round(percent * 100, 2)
                dt = time.time() - t0
                # We use a max to avoid a division by zero
                if run_idx == 0:
                    remaining = 'go take a coffee, a big one'
                else:
                    remaining = (100. - percent) / max(0.01, percent) * dt
                    remaining = '%i seconds remaining' % remaining
                sys.stderr.write(" " * 100 + "\r")
                sys.stderr.write(
                    "Computing run %d out of %d runs (%s)\r"
                    % (run_idx, n_runs, remaining))

            # Build the experimental design for the glm
            run_img = check_niimg(run_img, ensure_ndim=4)
            if design_matrices is None:
                n_scans = run_img.get_data().shape[3]
                if confounds is not None:
                    confounds_matrix = confounds[run_idx].values
                    if confounds_matrix.shape[0] != n_scans:
                        raise ValueError('Rows in confounds does not match'
                                         'n_scans in run_img at index %d'
                                         % (run_idx,))
                    confounds_names = confounds[run_idx].columns
                else:
                    confounds_matrix = None
                    confounds_names = None
                start_time = self.slice_time_ref * self.t_r
                end_time = (n_scans - 1 + self.slice_time_ref) * self.t_r
                frame_times = np.linspace(start_time, end_time, n_scans)
                design = make_design_matrix(frame_times, paradigms[run_idx],
                                            self.hrf_model, self.drift_model,
                                            self.period_cut, self.drift_order,
                                            self.fir_delays, confounds_matrix,
                                            confounds_names, self.min_onset)
            else:
                design = design_matrices[run_idx]
            self.design_matrices_.append(design)

            # Compute GLM
            Y = self.masker_.transform(run_img)
            if self.signal_scaling:
                Y, _ = mean_scaling(Y, self.scaling_axis)
            if self.memory is not None:
                mem_glm = self.memory.cache(run_glm)
            else:
                mem_glm = run_glm
            labels, results = mem_glm(Y, design,
                                      noise_model=self.noise_model,
                                      bins=100, n_jobs=self.n_jobs)
            self.labels_.append(labels)
            # We save memory if inspecting model details is not necessary
            if self.minimize_memory:
                for key in results:
                    results[key] = SimpleRegressionResults(results[key])
            self.results_.append(results)
            del Y

        # Report progress
        if self.verbose > 0:
            sys.stderr.write("\nComputation of %d runs done in %i seconds\n"
                             % (n_runs, time.time() - t0))

        return self
コード例 #33
0
    def fit(self,
            run_imgs,
            paradigms=None,
            confounds=None,
            design_matrices=None):
        """ Fit the GLM

        For each run:
        1. create design matrix X
        2. do a masker job: fMRI_data -> Y
        3. fit regression to (Y, X)

        Parameters
        ----------
        run_imgs: Niimg-like object or list of Niimg-like objects,
            See http://nilearn.github.io/building_blocks/manipulating_mr_images.html#niimg.
            Data on which the GLM will be fitted. If this is a list,
            the affine is considered the same for all.

        paradigms: pandas Dataframe or string or list of pandas DataFrames or
                   strings,
            fMRI paradigms used to build design matrices. One paradigm expected
            per run_img. Ignored in case designs is not None.

        confounds: pandas Dataframe or string or list of pandas DataFrames or
                   strings,
            Each column in a DataFrame corresponds to a confound variable
            to be included in the regression model of the respective run_img.
            The number of rows must match the number of volumes in the
            respective run_img. Ignored in case designs is not None.

        design_matrices: pandas DataFrame or list of pandas DataFrames,
            Design matrices that will be used to fit the GLM.
        """
        # Check arguments
        # Check imgs type
        if not isinstance(run_imgs, (list, tuple)):
            run_imgs = [run_imgs]
        for rimg in run_imgs:
            if not isinstance(rimg, (_basestring, Nifti1Image)):
                raise ValueError('run_imgs must be Niimg-like object or list'
                                 ' of Niimg-like objects')
        # check all information necessary to build design matrices is available
        if design_matrices is None:
            if paradigms is None:
                raise ValueError(
                    'paradigms or design matrices must be provided')
            if self.t_r is None:
                raise ValueError('t_r not given to FirstLevelModel object'
                                 ' to compute design from paradigm')
        else:
            design_matrices = _check_run_tables(run_imgs, design_matrices,
                                                'design_matrices')
        # check the number of paradigm and confound files match number of runs
        # Also check paradigm and confound files can be loaded as DataFrame
        if paradigms is not None:
            paradigms = _check_run_tables(run_imgs, paradigms, 'paradigms')

        if confounds is not None:
            confounds = _check_run_tables(run_imgs, confounds, 'confounds')

        # Learn the mask
        if not isinstance(self.mask, NiftiMasker):
            self.masker_ = NiftiMasker(mask_img=self.mask,
                                       smoothing_fwhm=self.smoothing_fwhm,
                                       target_affine=self.target_affine,
                                       standardize=self.standardize,
                                       mask_strategy='epi',
                                       t_r=self.t_r,
                                       memory=self.memory,
                                       verbose=max(0, self.verbose - 1),
                                       target_shape=self.target_shape,
                                       memory_level=self.memory_level)
        else:
            self.masker_ = clone(self.mask)
            for param_name in [
                    'target_affine', 'target_shape', 'smoothing_fwhm',
                    'low_pass', 'high_pass', 't_r', 'memory', 'memory_level'
            ]:
                our_param = getattr(self, param_name)
                if our_param is None:
                    continue
                if getattr(self.masker_, param_name) is not None:
                    warn('Parameter %s of the masker overriden' % param_name)
                setattr(self.masker_, param_name, our_param)
        self.masker_.fit(run_imgs[0])

        # For each run fit the model and keep only the regression results.
        self.labels_, self.results_, self.design_matrices_ = [], [], []
        n_runs = len(run_imgs)
        t0 = time.time()
        for run_idx, run_img in enumerate(run_imgs):
            # Report progress
            if self.verbose > 0:
                percent = float(run_idx) / n_runs
                percent = round(percent * 100, 2)
                dt = time.time() - t0
                # We use a max to avoid a division by zero
                if run_idx == 0:
                    remaining = 'go take a coffee, a big one'
                else:
                    remaining = (100. - percent) / max(0.01, percent) * dt
                    remaining = '%i seconds remaining' % remaining
                sys.stderr.write(" " * 100 + "\r")
                sys.stderr.write("Computing run %d out of %d runs (%s)\r" %
                                 (run_idx, n_runs, remaining))

            # Build the experimental design for the glm
            run_img = check_niimg(run_img, ensure_ndim=4)
            if design_matrices is None:
                n_scans = run_img.get_data().shape[3]
                if confounds is not None:
                    confounds_matrix = confounds[run_idx].values
                    if confounds_matrix.shape[0] != n_scans:
                        raise ValueError('Rows in confounds does not match'
                                         'n_scans in run_img at index %d' %
                                         (run_idx, ))
                    confounds_names = confounds[run_idx].columns
                else:
                    confounds_matrix = None
                    confounds_names = None
                start_time = self.slice_time_ref * self.t_r
                end_time = (n_scans - 1 + self.slice_time_ref) * self.t_r
                frame_times = np.linspace(start_time, end_time, n_scans)
                design = make_design_matrix(frame_times, paradigms[run_idx],
                                            self.hrf_model, self.drift_model,
                                            self.period_cut, self.drift_order,
                                            self.fir_delays, confounds_matrix,
                                            confounds_names, self.min_onset)
            else:
                design = design_matrices[run_idx]
            self.design_matrices_.append(design)

            # Compute GLM
            Y = self.masker_.transform(run_img)
            if self.signal_scaling:
                Y, _ = mean_scaling(Y, self.scaling_axis)
            if self.memory is not None:
                mem_glm = self.memory.cache(run_glm)
            else:
                mem_glm = run_glm
            labels, results = mem_glm(Y,
                                      design,
                                      noise_model=self.noise_model,
                                      bins=100,
                                      n_jobs=self.n_jobs)
            self.labels_.append(labels)
            # We save memory if inspecting model details is not necessary
            if self.minimize_memory:
                for key in results:
                    results[key] = SimpleRegressionResults(results[key])
            self.results_.append(results)
            del Y

        # Report progress
        if self.verbose > 0:
            sys.stderr.write("\nComputation of %d runs done in %i seconds\n" %
                             (n_runs, time.time() - t0))

        return self