def test_class_srm_inverse_transform(input_format, low_ram, tempdir, atlas, n_jobs, n_timeframes, aggregate): with tempfile.TemporaryDirectory() as datadir: X, W, S = generate_data(n_voxels, n_timeframes, n_subjects, n_components, datadir, 0, input_format) if tempdir: temp_dir = datadir else: temp_dir = None srm = FastSRM(atlas=atlas, n_components=n_components, n_iter=10, temp_dir=temp_dir, low_ram=low_ram, verbose=True, n_jobs=n_jobs, aggregate=aggregate, seed=0) # Check that there is no difference between fit_transform # and fit then transform srm.fit(X) shared_response_raw = srm.transform(X) # Check inverse transform if input_format == "list_of_array": reconstructed_data = srm.inverse_transform(shared_response_raw, subjects_indexes=[0, 2]) for i, ii in enumerate([0, 2]): assert_array_almost_equal(reconstructed_data[i], X[ii]) reconstructed_data = srm.inverse_transform(shared_response_raw, subjects_indexes=None) for i in range(len(X)): assert_array_almost_equal(reconstructed_data[i], X[i]) else: reconstructed_data = srm.inverse_transform(shared_response_raw, sessions_indexes=[1], subjects_indexes=[0, 2]) for i, ii in enumerate([0, 2]): for j, jj in enumerate([1]): assert_array_almost_equal(reconstructed_data[i][j], safe_load(X[ii][jj])) reconstructed_data = srm.inverse_transform(shared_response_raw, subjects_indexes=None, sessions_indexes=None) for i in range(len(X)): for j in range(len(X[i])): assert_array_almost_equal(reconstructed_data[i][j], safe_load(X[i][j]))
def test_fastsrm_identity(): # In this function we test whether fastsrm and DetSRM have # identical behavior when atlas=None # We authorize different timeframes for different sessions # but they should be the same across subject n_voxels = 8 n_timeframes = [4, 5, 6] n_subjects = 2 n_components = 3 # number of components used for SRM model np.random.seed(0) paths, W, S = generate_data(n_voxels, n_timeframes, n_subjects, n_components, None, input_format="list_of_array") # Test if generated data has the good shape for subject in range(n_subjects): assert paths[subject].shape == (n_voxels, np.sum([n_timeframes])) srm = DetSRM(n_iter=11, features=3, rand_seed=0) srm.fit(paths) shared = srm.transform(paths) fastsrm = FastSRM(atlas=None, n_components=3, verbose=True, seed=0, n_jobs=1, n_iter=10) fastsrm.fit(paths) shared_fast = fastsrm.transform(paths) assert_array_almost_equal(shared_fast, np.mean(shared, axis=0)) for i in range(n_subjects): assert_array_almost_equal(safe_load(fastsrm.basis_list[i]), srm.w_[i].T)
def test_consistency_paths_data(): with tempfile.TemporaryDirectory() as datadir: # In this function we test that input format # does not change the results n_voxels = 8 n_timeframes = [4, 5, 6] n_subjects = 2 n_components = 3 # number of components used for SRM model np.random.seed(0) paths, W, S = generate_data(n_voxels, n_timeframes, n_subjects, n_components, datadir, input_format="array") print() print("shape", paths.shape) fastsrm = FastSRM( n_components=3, atlas=None, verbose=True, seed=0, n_jobs=1, n_iter=10, ) fastsrm.fit(paths) b0 = fastsrm.basis_list[0] fastsrm.fit(load_and_concat(paths)) b1 = fastsrm.basis_list[0] assert_array_almost_equal(b0, b1)
def test_fastsrm_class_correctness(input_format, low_ram, tempdir, atlas, n_jobs, n_timeframes, aggregate): with tempfile.TemporaryDirectory() as datadir: np.random.seed(0) X, W, S = generate_data(n_voxels, n_timeframes, n_subjects, n_components, datadir, 0, input_format) XX, n_sessions = apply_input_format(X, input_format) if tempdir: temp_dir = datadir else: temp_dir = None srm = FastSRM(atlas=atlas, n_components=n_components, n_iter=10, temp_dir=temp_dir, low_ram=low_ram, verbose=True, n_jobs=n_jobs, aggregate=aggregate, seed=0) # Check that there is no difference between fit_transform # and fit then transform srm.fit(X) basis = [safe_load(b) for b in srm.basis_list] shared_response_raw = srm.transform(X) shared_response = apply_aggregate(shared_response_raw, aggregate, input_format) shared_response_fittransform = apply_aggregate(srm.fit_transform(X), aggregate, input_format) for j in range(n_sessions): assert_array_almost_equal(shared_response_fittransform[j], shared_response[j]) # Check that the decomposition works for i in range(n_subjects): for j in range(n_sessions): assert_array_almost_equal(shared_response[j].T.dot(basis[i]), XX[i][j].T) # Check that if we use all subjects but one if gives almost the # same shared response shared_response_partial_raw = srm.transform(X[1:5], subjects_indexes=list( range(1, 5))) shared_response_partial = apply_aggregate(shared_response_partial_raw, aggregate, input_format) for j in range(n_sessions): assert_array_almost_equal(shared_response_partial[j], shared_response[j]) # Check that if we perform add 2 times the same subject we # obtain the same decomposition srm.add_subjects(X[:1], shared_response_raw) assert_array_almost_equal(safe_load(srm.basis_list[0]), safe_load(srm.basis_list[-1]))
def test_fastsrm_class(): n_jobs = 1 with tempfile.TemporaryDirectory() as datadir: np.random.seed(0) # We authorize different timeframes for different sessions # but they should be the same across subject n_voxels = 10 n_timeframes = [25, 24] n_subjects = 5 n_components = 3 # number of components used for SRM model np.random.seed(0) paths, W, S = generate_data(n_voxels, n_timeframes, n_subjects, n_components, datadir, 0) atlas = np.arange(1, n_voxels + 1) srm = FastSRM(atlas=atlas, n_components=n_components, n_iter=10, temp_dir=datadir, low_ram=True, verbose=True, n_jobs=n_jobs) # Raises an error because model is not fitted yet with pytest.raises(NotFittedError): srm.transform(paths) srm.fit(paths) # An error can occur if temporary directory already exists with pytest.raises(ValueError, match=("Path %s already exists. When a model " "is used, filesystem should be " r"cleaned by using the .clean\(\) " "method" % srm.temp_dir)): # Error can occur if the filesystem is uncleaned create_temp_dir(srm.temp_dir) create_temp_dir(srm.temp_dir) shared_response = srm.transform(paths) # Raise error when wrong index with pytest.raises(ValueError, match=("subjects_indexes should be either " "a list, an array or None but " "received type <class 'int'>")): srm.transform(paths, subjects_indexes=1000) with pytest.raises(ValueError, match=("subjects_indexes should be either " "a list, an array or None but " "received type <class 'int'>")): srm.inverse_transform(shared_response, subjects_indexes=1000) with pytest.raises(ValueError, match=("sessions_indexes should be either " "a list, an array or None but " "received type <class 'int'>")): srm.inverse_transform(shared_response, sessions_indexes=1000) with pytest.raises(ValueError, match=("Input data imgs has len 5 whereas " "subject_indexes has len 1. " "The number of basis used to compute " "the shared response should be equal to " "the number of subjects in imgs")): srm.transform(paths, subjects_indexes=[0]) with pytest.raises(ValueError, match=("Index 1 of subjects_indexes has value 8 " "whereas value should be between 0 and 4")): srm.transform(paths[:2], subjects_indexes=[0, 8]) with pytest.raises(ValueError, match=("Index 1 of sessions_indexes has value 8 " "whereas value should be between 0 and 1")): srm.inverse_transform(shared_response, sessions_indexes=[0, 8]) # Check behavior of .clean assert os.path.exists(srm.temp_dir) srm.clean() assert not os.path.exists(srm.temp_dir)
def test_bad_aggregate(): with pytest.raises(ValueError, match="aggregate can have only value mean or None"): FastSRM(aggregate="invalid")