Beispiel #1
0
def test_process_second_level_input_as_firstlevelmodels():
    """Unit tests for function
    _process_second_level_input_as_firstlevelmodels().
    """
    from nilearn.glm.second_level.second_level import _process_second_level_input_as_firstlevelmodels  # noqa
    shapes, rk = [(7, 8, 9, 15)], 3
    mask, fmri_data, design_matrices = \
        generate_fake_fmri_data_and_design(shapes, rk)
    list_of_flm = [
        FirstLevelModel(mask_img=mask, subject_label=f"sub-{i}").fit(
            fmri_data[0], design_matrices=design_matrices[0]) for i in range(3)
    ]
    sample_map, subjects_label =\
        _process_second_level_input_as_firstlevelmodels(list_of_flm)
    assert subjects_label == [f"sub-{i}" for i in range(3)]
    assert isinstance(sample_map, Nifti1Image)
    assert sample_map.shape == (7, 8, 9)
Beispiel #2
0
def test_compute_contrast_num_contrasts():
    shapes, rk = ((7, 8, 7, 15), (7, 8, 7, 19), (7, 8, 7, 13)), 3
    mask, fmri_data, design_matrices =\
        generate_fake_fmri_data_and_design(shapes, rk)

    # Fit a glm with 3 sessions and design matrices
    multi_session_model = FirstLevelModel(mask_img=mask).fit(
        fmri_data, design_matrices=design_matrices)

    # raise when n_contrast != n_runs | 1
    with pytest.raises(ValueError):
        multi_session_model.compute_contrast([np.eye(rk)[1]] * 2)

    multi_session_model.compute_contrast([np.eye(rk)[1]] * 3)
    with pytest.warns(UserWarning,
                      match='One contrast given, '
                      'assuming it for all 3 runs'):
        multi_session_model.compute_contrast([np.eye(rk)[1]])
Beispiel #3
0
def test_high_level_glm_one_session():
    shapes, rk = [(7, 8, 9, 15)], 3
    mask, fmri_data, design_matrices = generate_fake_fmri_data_and_design(shapes, rk)

    # Give an unfitted NiftiMasker as mask_img and check that we get an error
    masker = NiftiMasker(mask)
    with pytest.raises(ValueError,
                       match="It seems that NiftiMasker has not been fitted."):
        single_session_model = FirstLevelModel(mask_img=masker).fit(
                fmri_data[0], design_matrices=design_matrices[0])

    # Give a fitted NiftiMasker with a None mask_img_ attribute
    # and check that the masker parameters are overriden by the
    # FirstLevelModel parameters
    masker.fit()
    masker.mask_img_ = None
    with pytest.warns(UserWarning,
                      match="Parameter memory of the masker overriden"):
        single_session_model = FirstLevelModel(mask_img=masker).fit(
                fmri_data[0], design_matrices=design_matrices[0])

    # Give a fitted NiftiMasker
    masker = NiftiMasker(mask)
    masker.fit()
    single_session_model = FirstLevelModel(mask_img=masker).fit(
                    fmri_data[0], design_matrices=design_matrices[0])
    assert single_session_model.masker_ == masker

    # Call with verbose (improve coverage)
    single_session_model = FirstLevelModel(mask_img=None,
                                           verbose=1).fit(
        fmri_data[0], design_matrices=design_matrices[0])

    single_session_model = FirstLevelModel(mask_img=None).fit(
        fmri_data[0], design_matrices=design_matrices[0])
    assert isinstance(single_session_model.masker_.mask_img_,
                      Nifti1Image)

    single_session_model = FirstLevelModel(mask_img=mask).fit(
        fmri_data[0], design_matrices=design_matrices[0])
    z1 = single_session_model.compute_contrast(np.eye(rk)[:1])
    assert isinstance(z1, Nifti1Image)
Beispiel #4
0
def test_first_level_hrf_model(hrf_model, spaces):
    """
    Ensure that FirstLevelModel runs without raising errors
    for different values of hrf_model. In particular, one checks that it runs
    without raising errors when given a custom response function.
    Also ensure that it computes contrasts without raising errors,
    even when event (ie condition) names have spaces.
    """
    shapes, rk = [(10, 10, 10, 25)], 3
    mask, fmri_data, _ =\
        generate_fake_fmri_data_and_design(shapes, rk)

    events = basic_paradigm(condition_names_have_spaces=spaces)

    model = FirstLevelModel(t_r=2.0, mask_img=mask, hrf_model=hrf_model)

    model.fit(fmri_data, events)

    columns = model.design_matrices_[0].columns
    model.compute_contrast(f"{columns[0]}-{columns[1]}")
def test_high_level_glm_different_design_matrices_formulas():
    # test that one can estimate a contrast when design matrices are different
    shapes, rk = ((7, 8, 7, 15), (7, 8, 7, 19)), 3
    mask, fmri_data, design_matrices = generate_fake_fmri_data_and_design(shapes, rk)

    # make column names identical
    design_matrices[1].columns = design_matrices[0].columns
    # add a column to the second design matrix
    design_matrices[1]['new'] = np.ones((19, 1))

    # Fit a glm with two sessions and design matrices
    multi_session_model = FirstLevelModel(mask_img=mask).fit(
        fmri_data, design_matrices=design_matrices)

    # Compute contrast with formulas
    cols_formula = tuple(design_matrices[0].columns[:2])
    formula = "%s-%s" % cols_formula
    with pytest.warns(UserWarning, match='One contrast given, assuming it for all 2 runs'):
        z_joint_formula = multi_session_model.compute_contrast(
            formula, output_type='effect_size')
Beispiel #6
0
def test_second_level_voxelwise_attribute_errors(attribute):
    """Tests that an error is raised when trying to access
    voxelwise attributes before fitting the model, before
    computing a contrast, and when not setting
    ``minimize_memory`` to ``True``.
    """
    shapes = ((7, 8, 9, 1), )
    mask, fmri_data, _ = generate_fake_fmri_data_and_design(shapes)
    model = SecondLevelModel(mask_img=mask, minimize_memory=False)
    with pytest.raises(ValueError, match="The model has no results."):
        getattr(model, attribute)
    Y = fmri_data * 4
    X = pd.DataFrame([[1]] * 4, columns=['intercept'])
    model.fit(Y, design_matrix=X)
    with pytest.raises(ValueError, match="The model has no results."):
        getattr(model, attribute)
    with pytest.raises(ValueError, match="attribute must be one of"):
        model._get_voxelwise_model_attribute("foo", True)
    model = SecondLevelModel(mask_img=mask, minimize_memory=True)
    model.fit(Y, design_matrix=X)
    model.compute_contrast()
    with pytest.raises(ValueError, match="To access voxelwise attributes"):
        getattr(model, attribute)
def test_high_level_glm_different_design_matrices():
    # test that one can estimate a contrast when design matrices are different
    shapes, rk = ((7, 8, 7, 15), (7, 8, 7, 19)), 3
    mask, fmri_data, design_matrices = generate_fake_fmri_data_and_design(
        shapes, rk)

    # add a column to the second design matrix
    design_matrices[1]['new'] = np.ones((19, 1))

    # Fit a glm with two sessions and design matrices
    multi_session_model = FirstLevelModel(mask_img=mask).fit(
        fmri_data, design_matrices=design_matrices)
    z_joint = multi_session_model.compute_contrast(
        [np.eye(rk)[:1], np.eye(rk + 1)[:1]], output_type='effect_size')
    assert z_joint.shape == (7, 8, 7)

    # compare the estimated effects to seprarately-fitted models
    model1 = FirstLevelModel(mask_img=mask).fit(
        fmri_data[0], design_matrices=design_matrices[0])
    z1 = model1.compute_contrast(np.eye(rk)[:1], output_type='effect_size')
    model2 = FirstLevelModel(mask_img=mask).fit(
        fmri_data[1], design_matrices=design_matrices[1])
    z2 = model2.compute_contrast(np.eye(rk + 1)[:1], output_type='effect_size')
    assert_almost_equal(z1.get_data() + z2.get_data(), 2 * z_joint.get_data())
def test_first_level_predictions_r_square():
    shapes, rk = [(10, 10, 10, 25)], 3
    mask, fmri_data, design_matrices = generate_fake_fmri_data_and_design(shapes, rk)

    for i in range(len(design_matrices)):
        design_matrices[i].iloc[:, 0] = 1

    model = FirstLevelModel(mask_img=mask,
                            signal_scaling=False,
                            minimize_memory=False,
                            noise_model='ols')
    model.fit(fmri_data, design_matrices=design_matrices)

    pred = model.predicted[0]
    data = fmri_data[0]
    r_square_3d = model.r_square[0]

    y_predicted = model.masker_.transform(pred)
    y_measured = model.masker_.transform(data)

    assert_almost_equal(np.mean(y_predicted - y_measured), 0)

    r_square_2d = model.masker_.transform(r_square_3d)
    assert_array_less(0., r_square_2d)
Beispiel #9
0
def test_check_second_level_input():
    from nilearn.glm.second_level.second_level import _check_second_level_input
    with pytest.raises(ValueError,
                       match="A second level model requires a list with at "
                       "least two first level models or niimgs"):
        _check_second_level_input([FirstLevelModel()], pd.DataFrame())
    with pytest.raises(ValueError,
                       match="Model sub_1 at index 0 has not been fit yet"):
        _check_second_level_input([
            FirstLevelModel(subject_label="sub_{}".format(i))
            for i in range(1, 3)
        ], pd.DataFrame())
    with InTemporaryDirectory():
        shapes, rk = [(7, 8, 9, 15)], 3
        mask, fmri_data, design_matrices = \
            generate_fake_fmri_data_and_design(shapes, rk)
        input_models = [
            FirstLevelModel(mask_img=mask).fit(
                fmri_data[0], design_matrices=design_matrices[0])
        ]
        obj = lambda: None
        obj.results_ = "foo"
        obj.labels_ = "bar"
        with pytest.raises(ValueError,
                           match=" object at idx 1 is <class 'function'> "
                           "instead of FirstLevelModel object"):
            _check_second_level_input(input_models + [obj], pd.DataFrame())
        with pytest.raises(ValueError,
                           match="In case confounds are provided, first level "
                           "objects need to provide the attribute "
                           "subject_label"):
            _check_second_level_input(input_models * 2,
                                      pd.DataFrame(),
                                      confounds=pd.DataFrame())
        with pytest.raises(ValueError,
                           match="List of niimgs as second_level_input "
                           "require a design matrix to be provided"):
            _check_second_level_input(fmri_data * 2, None)
        _check_second_level_input(fmri_data[0], pd.DataFrame())
    with pytest.raises(ValueError,
                       match=" object at idx 1 is <class 'int'> instead"):
        _check_second_level_input(["foo", 1], pd.DataFrame())
    with pytest.raises(ValueError,
                       match="second_level_input DataFrame must have columns "
                       "subject_label, map_name and effects_map_path"):
        _check_second_level_input(pd.DataFrame(columns=["foo", "bar"]),
                                  pd.DataFrame())
    with pytest.raises(ValueError,
                       match="subject_label column must contain only strings"):
        _check_second_level_input(
            pd.DataFrame({
                "subject_label": [1, 2],
                "map_name": ["a", "b"],
                "effects_map_path": ["c", "d"]
            }), pd.DataFrame())
    with pytest.raises(ValueError,
                       match="List of niimgs as second_level_input "
                       "require a design matrix to be provided"):
        _check_second_level_input("foo", None)
    with pytest.raises(ValueError,
                       match="second_level_input must be a list of"):
        _check_second_level_input(1, None)
    with pytest.raises(ValueError, match="second_level_input must be a list"):
        _check_second_level_input(1, None, flm_object=False)