Ejemplo n.º 1
0
def test_first_level_design_creation():
    # Test processing of FMRI inputs
    with InTemporaryDirectory():
        shapes = ((7, 8, 9, 10), )
        mask, FUNCFILE, _ = write_fake_fmri_data_and_design(shapes)
        FUNCFILE = FUNCFILE[0]
        func_img = load(FUNCFILE)
        # basic test based on basic_paradigm and glover hrf
        t_r = 10.0
        slice_time_ref = 0.
        events = basic_paradigm()
        model = FirstLevelModel(t_r,
                                slice_time_ref,
                                mask_img=mask,
                                drift_model='polynomial',
                                drift_order=3)
        model = model.fit(func_img, events)
        frame1, X1, names1 = check_design_matrix(model.design_matrices_[0])
        # check design computation is identical
        n_scans = get_data(func_img).shape[3]
        start_time = slice_time_ref * t_r
        end_time = (n_scans - 1 + slice_time_ref) * t_r
        frame_times = np.linspace(start_time, end_time, n_scans)
        design = make_first_level_design_matrix(frame_times,
                                                events,
                                                drift_model='polynomial',
                                                drift_order=3)
        frame2, X2, names2 = check_design_matrix(design)
        assert_array_equal(frame1, frame2)
        assert_array_equal(X1, X2)
        assert_array_equal(names1, names2)
        # Delete objects attached to files to avoid WindowsError when deleting
        # temporary directory (in Windows)
        del FUNCFILE, mask, model, func_img
Ejemplo n.º 2
0
def test_design_matrix0c():
    # test design matrix creation when regressors are provided manually
    rng = np.random.RandomState(42)
    tr = 1.0
    frame_times = np.linspace(0, 127 * tr, 128)
    ax = rng.standard_normal(size=(128, 4))
    _, X, names = check_design_matrix(
        make_first_level_design_matrix(frame_times,
                                       drift_model='polynomial',
                                       drift_order=3,
                                       add_regs=ax))
    assert_almost_equal(X[:, 0], ax[:, 0])
    ax = rng.standard_normal(size=(127, 4))
    with pytest.raises(
            AssertionError,
            match="Incorrect specification of additional regressors:."):
        make_first_level_design_matrix(frame_times, add_regs=ax)
    ax = rng.standard_normal(size=(128, 4))
    with pytest.raises(
            ValueError,
            match="Incorrect number of additional regressor names."):
        make_first_level_design_matrix(frame_times,
                                       add_regs=ax,
                                       add_reg_names='')
    # with pandas Dataframe
    axdf = pd.DataFrame(ax)
    _, X1, names = check_design_matrix(
        make_first_level_design_matrix(frame_times,
                                       drift_model='polynomial',
                                       drift_order=3,
                                       add_regs=axdf))
    assert_almost_equal(X1[:, 0], ax[:, 0])
    assert_array_equal(names[:4], np.arange(4))
Ejemplo n.º 3
0
def test_design_matrix0():
    # Test design matrix creation when no experimental paradigm is provided
    tr = 1.0
    frame_times = np.linspace(0, 127 * tr, 128)
    _, X, names = check_design_matrix(
        make_first_level_design_matrix(frame_times,
                                       drift_model='polynomial',
                                       drift_order=3))
    assert len(names) == 4
    x = np.linspace(-0.5, .5, 128)
    assert_almost_equal(X[:, 0], x)
Ejemplo n.º 4
0
def test_csv_io():
    # test the csv io on design matrices
    tr = 1.0
    frame_times = np.linspace(0, 127 * tr, 128)
    events = modulated_event_paradigm()
    DM = make_first_level_design_matrix(
        frame_times,
        events,
        hrf_model='glover',
        drift_model='polynomial',
        drift_order=3,
    )
    path = 'design_matrix.csv'
    with InTemporaryDirectory():
        DM.to_csv(path)
        DM2 = pd.read_csv(path, index_col=0)

    _, matrix, names = check_design_matrix(DM)
    _, matrix_, names_ = check_design_matrix(DM2)
    assert_almost_equal(matrix, matrix_)
    assert names == names_
Ejemplo n.º 5
0
def test_design_matrix0d():
    # test design matrix creation when regressors are provided manually
    tr = 1.0
    frame_times = np.linspace(0, 127 * tr, 128)
    ax = np.random.randn(128, 4)
    _, X, names = check_design_matrix(
        make_first_level_design_matrix(frame_times,
                                       drift_model='polynomial',
                                       drift_order=3,
                                       add_regs=ax))
    assert len(names) == 8
    assert X.shape[1] == 8
Ejemplo n.º 6
0
def test_spm_2():
    # Check that the nistats design matrix is close enough to the SPM one
    # (it cannot be identical, because the hrf shape is different)
    frame_times = np.linspace(0, 99, 100)
    conditions = ['c0', 'c0', 'c0', 'c1', 'c1', 'c1', 'c2', 'c2', 'c2']
    onsets = [30, 50, 70, 10, 30, 80, 30, 40, 60]
    durations = 10 * np.ones(9)
    events = pd.DataFrame({
        'trial_type': conditions,
        'onset': onsets,
        'duration': durations
    })
    X1 = make_first_level_design_matrix(frame_times, events, drift_model=None)
    spm_design_matrix = DESIGN_MATRIX['arr_1']
    _, matrix, _ = check_design_matrix(X1)
    assert (((spm_design_matrix - matrix)**2).sum() /
            (spm_design_matrix**2).sum() < .1)
Ejemplo n.º 7
0
def design_matrix_light(frame_times,
                        events=None,
                        hrf_model='glover',
                        drift_model='cosine',
                        high_pass=.01,
                        drift_order=1,
                        fir_delays=None,
                        add_regs=None,
                        add_reg_names=None,
                        min_onset=-24,
                        path=None):
    """ Same as make_first_level_design_matrix,
    but only returns the computed matrix and associated name.
    """
    fir_delays = fir_delays if fir_delays else [0]
    dmtx = make_first_level_design_matrix(frame_times, events, hrf_model,
                                          drift_model, high_pass, drift_order,
                                          fir_delays, add_regs, add_reg_names,
                                          min_onset)
    _, matrix, names = check_design_matrix(dmtx)
    return matrix, names
Ejemplo n.º 8
0
def test_design_matrix0c():
    # test design matrix creation when regressors are provided manually
    tr = 1.0
    frame_times = np.linspace(0, 127 * tr, 128)
    ax = np.random.randn(128, 4)
    _, X, names = check_design_matrix(
        make_first_level_design_matrix(frame_times,
                                       drift_model='polynomial',
                                       drift_order=3,
                                       add_regs=ax))
    assert_almost_equal(X[:, 0], ax[:, 0])
    ax = np.random.randn(127, 4)
    with pytest.raises(
            AssertionError,
            match="Incorrect specification of additional regressors:."):
        make_first_level_design_matrix(frame_times, add_regs=ax)
    ax = np.random.randn(128, 4)
    with pytest.raises(
            ValueError,
            match="Incorrect number of additional regressor names."):
        make_first_level_design_matrix(frame_times,
                                       add_regs=ax,
                                       add_reg_names='')
Ejemplo n.º 9
0
def first_level(subject_dic,
                additional_regressors=None,
                compcorr=False,
                smooth=None,
                mesh=False,
                mask_img=None):
    """ Run the first-level analysis (GLM fitting + statistical maps)
    in a given subject

    Parameters
    ----------
    subject_dic: dict,
                 exhaustive description of an individual acquisition
    additional_regressors: dict or None,
                 additional regressors provided as an already sampled
                 design_matrix
                 dictionary keys are session_ids
    compcorr: Bool, optional,
              whether confound estimation and removal should be done or not
    smooth: float or None, optional,
            how much the data should spatially smoothed during masking
    """
    start_time = time.ctime()
    # experimental paradigm meta-params
    motion_names = ['tx', 'ty', 'tz', 'rx', 'ry', 'rz']
    hrf_model = subject_dic['hrf_model']
    high_pass = subject_dic['high_pass']
    drift_model = subject_dic['drift_model']
    tr = subject_dic['TR']
    slice_time_ref = 1.

    if not mesh and (mask_img is None):
        mask_img = masking(subject_dic['func'], subject_dic['output_dir'])

    if additional_regressors is None:
        additional_regressors = dict([
            (session_id, None) for session_id in subject_dic['session_id']
        ])

    for session_id, fmri_path, onset, motion_path in zip(
            subject_dic['session_id'], subject_dic['func'],
            subject_dic['onset'], subject_dic['realignment_parameters']):

        task_id = _session_id_to_task_id([session_id])[0]

        if mesh is not False:
            from nibabel.gifti import read
            n_scans = np.array(
                [darrays.data for darrays in read(fmri_path).darrays]).shape[0]
        else:
            n_scans = nib.load(fmri_path).shape[3]

        # motion parameters
        motion = np.loadtxt(motion_path)
        # define the time stamps for different images
        frametimes = np.linspace(slice_time_ref,
                                 (n_scans - 1 + slice_time_ref) * tr, n_scans)
        if task_id == 'audio':
            mask = np.array([1, 0, 1, 1, 0, 1, 1, 0, 1, 1])
            n_cycles = 28
            cycle_duration = 20
            t_r = 2
            cycle = np.arange(0, cycle_duration, t_r)[mask > 0]
            frametimes = np.tile(cycle, n_cycles) +\
                np.repeat(np.arange(n_cycles) * cycle_duration, mask.sum())
            frametimes = frametimes[:-2]  # for some reason...

        if mesh is not False:
            compcorr = False  # XXX Fixme

        if compcorr:
            confounds = high_variance_confounds(fmri_path, mask_img=mask_img)
            confounds = np.hstack((confounds, motion))
            confound_names = ['conf_%d' % i for i in range(5)] + motion_names
        else:
            confounds = motion
            confound_names = motion_names

        if onset is None:
            warnings.warn('Onset file not provided. Trying to guess it')
            task = os.path.basename(fmri_path).split('task')[-1][4:]
            onset = os.path.join(
                os.path.split(os.path.dirname(fmri_path))[0], 'model001',
                'onsets', 'task' + task + '_run001', 'task%s.csv' % task)

        if not os.path.exists(onset):
            warnings.warn('non-existant onset file. proceeding without it')
            paradigm = None
        else:
            paradigm = make_paradigm(onset, task_id)

        # handle manually supplied regressors
        add_reg_names = []
        if additional_regressors[session_id] is None:
            add_regs = confounds
        else:
            df = read_csv(additional_regressors[session_id])
            add_regs = []
            for regressor in df:
                add_reg_names.append(regressor)
                add_regs.append(df[regressor])
            add_regs = np.array(add_regs).T
            add_regs = np.hstack((add_regs, confounds))

        add_reg_names += confound_names

        # create the design matrix
        design_matrix = make_first_level_design_matrix(
            frametimes,
            paradigm,
            hrf_model=hrf_model,
            drift_model=drift_model,
            high_pass=high_pass,
            add_regs=add_regs,
            add_reg_names=add_reg_names)
        _, dmtx, names = check_design_matrix(design_matrix)

        # create the relevant contrasts
        contrasts = make_contrasts(task_id, names)

        if mesh == 'fsaverage5':
            # this is low-resolution data
            subject_session_output_dir = os.path.join(
                subject_dic['output_dir'], 'res_fsaverage5_%s' % session_id)
        elif mesh == 'fsaverage7':
            subject_session_output_dir = os.path.join(
                subject_dic['output_dir'], 'res_fsaverage7_%s' % session_id)
        elif mesh == 'individual':
            subject_session_output_dir = os.path.join(
                subject_dic['output_dir'], 'res_individual_%s' % session_id)
        else:
            subject_session_output_dir = os.path.join(
                subject_dic['output_dir'], 'res_stats_%s' % session_id)

        if not os.path.exists(subject_session_output_dir):
            os.makedirs(subject_session_output_dir)
        np.savez(os.path.join(subject_session_output_dir, 'design_matrix.npz'),
                 design_matrix=design_matrix)

        if mesh is not False:
            run_surface_glm(design_matrix, contrasts, fmri_path,
                            subject_session_output_dir)
        else:
            z_maps, fmri_glm = run_glm(design_matrix,
                                       contrasts,
                                       fmri_path,
                                       mask_img,
                                       subject_dic,
                                       subject_session_output_dir,
                                       tr=tr,
                                       slice_time_ref=slice_time_ref,
                                       smoothing_fwhm=smooth)

            # do stats report
            anat_img = nib.load(subject_dic['anat'])
            stats_report_filename = os.path.join(subject_session_output_dir,
                                                 'report_stats.html')

            report = make_glm_report(
                fmri_glm,
                contrasts,
                threshold=3.0,
                bg_img=anat_img,
                cluster_threshold=15,
                title="GLM for subject %s" % session_id,
            )
            report.save_as_html(stats_report_filename)
design_matrix = make_first_level_design_matrix(frametimes,
                                               paradigm,
                                               hrf_model=hrf_model,
                                               drift_model=drift_model,
                                               high_pass=hfcut)

# plot and save design matrix
ax = plot_design_matrix(design_matrix)
ax.set_position([.05, .25, .9, .65])
ax.set_title('Design matrix')
dmat_outfile = os.path.join(subject_data.output_dir, 'design_matrix.png')
plt.savefig(dmat_outfile, bbox_inches="tight", dpi=200)

# specify contrasts
contrasts = {}
_, matrix, names = check_design_matrix(design_matrix)
contrast_matrix = np.eye(len(names))
for i in range(len(names)):
    contrasts[names[i]] = contrast_matrix[i]

# more interesting contrasts"""
contrasts = {'active-rest': contrasts['active'] - contrasts['rest']}

# fit GLM
print('\r\nFitting a GLM (this takes time) ..')
fmri_glm = FirstLevelModel(noise_model='ar1', standardize=False, t_r=tr).fit(
    [nibabel.concat_images(subject_data.func[0])],
    design_matrices=design_matrix)

# save computed mask
mask_path = os.path.join(subject_data.output_dir, "mask.nii.gz")