def test_isc_output(): logger.info("Testing ISC outputs") data = correlated_timeseries(20, 60, noise=0, random_state=42) iscs = isc(data, pairwise=False) assert np.allclose(iscs[:, :2], 1., rtol=1e-05) assert np.all(iscs[:, -1] < 1.) iscs = isc(data, pairwise=True) assert np.allclose(iscs[:, :2], 1., rtol=1e-05) assert np.all(iscs[:, -1] < 1.) logger.info("Finished testing ISC outputs")
def test_isfc_options(): # Set parameters for toy time series data n_subjects = 20 n_TRs = 60 n_voxels = 30 logger.info("Testing ISFC options") data = simulated_timeseries(n_subjects, n_TRs, n_voxels=n_voxels, data_type='array') isfcs = isfc(data, pairwise=False, summary_statistic=None) # Just two subjects isfcs = isfc(data[..., :2], pairwise=False, summary_statistic=None) # ISFC with pairwise approach isfcs = isfc(data, pairwise=True, summary_statistic=None) # ISFC with summary statistics isfcs = isfc(data, pairwise=True, summary_statistic='mean') isfcs = isfc(data, pairwise=True, summary_statistic='median') # Check output p-values data = correlated_timeseries(20, 60, noise=.5, random_state=42) isfcs = isfc(data, pairwise=False) assert np.all(isfcs[0, 1, :] > .5) and np.all(isfcs[1, 0, :] > .5) assert np.all(isfcs[:2, 2, :] < .5) and np.all(isfcs[2, :2, :] < .5) isfcs = isfc(data, pairwise=True) assert np.all(isfcs[0, 1, :] > .5) and np.all(isfcs[1, 0, :] > .5) assert np.all(isfcs[:2, 2, :] < .5) and np.all(isfcs[2, :2, :] < .5) # Check that ISC and ISFC diagonal are identical iscs = isc(data, pairwise=False) isfcs = isfc(data, pairwise=False) for s in np.arange(len(iscs)): assert np.allclose(isfcs[..., s].diagonal(), iscs[s, :], rtol=1e-03) # Check that ISC and ISFC diagonal are identical iscs = isc(data, pairwise=True) isfcs = isfc(data, pairwise=True) for s in np.arange(len(iscs)): assert np.allclose(isfcs[..., s].diagonal(), iscs[s, :], rtol=1e-03) logger.info("Finished testing ISFC options")
def test_isc_input(): # Set parameters for toy time series data n_subjects = 20 n_TRs = 60 n_voxels = 30 random_state = 42 logger.info("Testing ISC inputs") data = simulated_timeseries(n_subjects, n_TRs, n_voxels=None, data_type='list', random_state=random_state) iscs_list = isc(data, pairwise=False, summary_statistic=None) # Array of subjects with one voxel/ROI data = simulated_timeseries(n_subjects, n_TRs, n_voxels=None, data_type='array', random_state=random_state) iscs_array = isc(data, pairwise=False, summary_statistic=None) # Check they're the same assert np.array_equal(iscs_list, iscs_array) # List of subjects with multiple voxels/ROIs data = simulated_timeseries(n_subjects, n_TRs, n_voxels=n_voxels, data_type='list', random_state=random_state) iscs_list = isc(data, pairwise=False, summary_statistic=None) # Array of subjects with multiple voxels/ROIs data = simulated_timeseries(n_subjects, n_TRs, n_voxels=n_voxels, data_type='array', random_state=random_state) iscs_array = isc(data, pairwise=False, summary_statistic=None) # Check they're the same assert np.array_equal(iscs_list, iscs_array) logger.info("Finished testing ISC inputs")
def test_isc_options(): # Set parameters for toy time series data n_subjects = 20 n_TRs = 60 n_voxels = 30 random_state = 42 logger.info("Testing ISC options") data = simulated_timeseries(n_subjects, n_TRs, n_voxels=n_voxels, data_type='array', random_state=random_state) iscs_loo = isc(data, pairwise=False, summary_statistic=None) assert iscs_loo.shape == (n_subjects, n_voxels) # Just two subjects iscs_loo = isc(data[..., :2], pairwise=False, summary_statistic=None) assert iscs_loo.shape == (n_voxels,) iscs_pw = isc(data, pairwise=True, summary_statistic=None) assert iscs_pw.shape == (n_subjects*(n_subjects-1)/2, n_voxels) # Check summary statistics isc_mean = isc(data, pairwise=False, summary_statistic='mean') assert isc_mean.shape == (n_voxels,) isc_median = isc(data, pairwise=False, summary_statistic='median') assert isc_median.shape == (n_voxels,) with pytest.raises(ValueError): isc(data, pairwise=False, summary_statistic='min') logger.info("Finished testing ISC options")
def test_isc_options(): # Set parameters for toy time series data n_subjects = 20 n_TRs = 60 n_voxels = 30 random_state = 42 logger.info("Testing ISC options") data = simulated_timeseries(n_subjects, n_TRs, n_voxels=n_voxels, data_type='array', random_state=random_state) iscs_loo = isc(data, pairwise=False, summary_statistic=None) assert iscs_loo.shape == (n_subjects, n_voxels) iscs_pw = isc(data, pairwise=True, summary_statistic=None) assert iscs_pw.shape == (n_subjects * (n_subjects - 1) / 2, n_voxels) # Check summary statistics isc_mean = isc(data, pairwise=False, summary_statistic='mean') assert isc_mean.shape == (1, n_voxels) isc_median = isc(data, pairwise=False, summary_statistic='median') assert isc_median.shape == (1, n_voxels) try: isc(data, pairwise=False, summary_statistic='min') except ValueError: logger.info("Correctly caught unexpected summary statistic") logger.info("Finished testing ISC options")
def test_isc_options(): # Set parameters for toy time series data n_subjects = 20 n_TRs = 60 n_voxels = 30 random_state = 42 logger.info("Testing ISC options") data = simulated_timeseries(n_subjects, n_TRs, n_voxels=n_voxels, data_type='array', random_state=random_state) iscs_loo = isc(data, pairwise=False, summary_statistic=None) assert iscs_loo.shape == (n_subjects, n_voxels) iscs_pw = isc(data, pairwise=True, summary_statistic=None) assert iscs_pw.shape == (n_subjects*(n_subjects-1)/2, n_voxels) # Check summary statistics isc_mean = isc(data, pairwise=False, summary_statistic='mean') assert isc_mean.shape == (1, n_voxels) isc_median = isc(data, pairwise=False, summary_statistic='median') assert isc_median.shape == (1, n_voxels) try: isc(data, pairwise=False, summary_statistic='min') except ValueError: logger.info("Correctly caught unexpected summary statistic") logger.info("Finished testing ISC options")
def lagged_isc(data, n_lags=150, circular=True): # If lag is integer, get positive and negative range around zero if type(n_lags) is int: lags = np.arange(-n_lags, n_lags + 1) # Get number of pairs n_players = data.shape[-1] # Iterate through lags to populate lagged ISCs lagged_iscs = [] for lag in lags: pairwise_iscs = [] for pair in combinations(np.arange(n_players), 2): lagged_player1 = data[..., pair[0]] lagged_player2 = data[..., pair[1]] # If circular, loop excess elements to beginning if circular: if lag != 0: lagged_player1 = np.concatenate( (lagged_player1[-lag:], lagged_player1[:-lag])) # If not circular, trim non-overlapping elements # Shifts y with respect to x else: print('second') if lag < 0: lagged_player1 = lagged_player1[:lag] lagged_player2 = lagged_player2[-lag:] elif lag > 0: lagged_player1 = lagged_player1[lag:] lagged_player2 = lagged_player2[:-lag] pairwise_isc = isc( np.stack((lagged_player1, lagged_player2), axis=-1)) pairwise_iscs.append(pairwise_isc) pairwise_iscs = np.array(pairwise_iscs) lagged_iscs.append(pairwise_iscs) lagged_iscs = np.stack(lagged_iscs, axis=-1) if lagged_iscs.shape[1] == 1: lagged_iscs = np.squeeze(lagged_iscs) return lagged_iscs, lags
def test_phaseshift_isc(): # Set parameters for toy time series data n_subjects = 20 n_TRs = 60 n_voxels = 30 logger.info("Testing phase randomization") data = simulated_timeseries(n_subjects, n_TRs, n_voxels=n_voxels, data_type='array') observed, p, distribution = phaseshift_isc(data, pairwise=True, summary_statistic='median', n_shifts=200) # Phase randomization one-sample test, leave-one-out data = simulated_timeseries(n_subjects, n_TRs, n_voxels=n_voxels, data_type='array') observed, p, distribution = phaseshift_isc(data, pairwise=False, summary_statistic='mean', n_shifts=200) # Check output p-values data = correlated_timeseries(20, 60, noise=.5, random_state=42) iscs = isc(data, pairwise=False) observed, p, distribution = phaseshift_isc(data, pairwise=False) assert np.all(iscs[:, :2] > .5) assert np.all(iscs[:, -1] < .5) assert p[0] < .05 and p[1] < .05 assert p[2] > .01 iscs = isc(data, pairwise=True) observed, p, distribution = phaseshift_isc(data, pairwise=True) assert np.all(iscs[:, :2] > .5) assert np.all(iscs[:, -1] < .5) assert p[0] < .05 and p[1] < .05 assert p[2] > .01 # Check that ISC computation and permutation observed are same iscs = isc(data, pairwise=False) observed, p, distribution = phaseshift_isc(data, pairwise=False, summary_statistic='median') assert np.allclose(observed, isc(data, pairwise=False, summary_statistic='median'), rtol=1e-03) # Check that ISC computation and permuation observed are same iscs = isc(data, pairwise=True) observed, p, distribution = phaseshift_isc(data, pairwise=True, summary_statistic='mean') assert np.allclose(observed, isc(data, pairwise=True, summary_statistic='mean'), rtol=1e-03) logger.info("Finished testing phase randomization")
def test_squareform_isfc(): # Set parameters for toy time series data n_subjects = 20 n_TRs = 60 n_voxels = 30 random_state = 42 logger.info("Testing ISC options") data = simulated_timeseries(n_subjects, n_TRs, n_voxels=n_voxels, data_type='array', random_state=random_state) # Generate square redundant ISFCs isfcs_r = isfc(data, vectorize_isfcs=False) assert isfcs_r.shape == (n_subjects, n_voxels, n_voxels) # Squareform these into condensed ISFCs and ISCs isfcs_c, iscs_c = squareform_isfc(isfcs_r) assert isfcs_c.shape == (n_subjects, n_voxels * (n_voxels - 1) / 2) assert iscs_c.shape == (n_subjects, n_voxels) # Go back the other way and check it's the same isfcs_new = squareform_isfc(isfcs_c, iscs_c) assert np.array_equal(isfcs_r, isfcs_new) # Check against ISC function assert np.allclose(isc(data), iscs_c, rtol=1e-03) # Check for two subjects isfcs_r = isfc(data[..., :2], vectorize_isfcs=False) assert isfcs_r.shape == (n_voxels, n_voxels) isfcs_c, iscs_c = squareform_isfc(isfcs_r) assert isfcs_c.shape == (n_voxels * (n_voxels - 1) / 2, ) assert iscs_c.shape == (n_voxels, ) assert np.array_equal(isfcs_r, squareform_isfc(isfcs_c, iscs_c))
def window_isc(data, width=150, pairwise=True): # We expect time (i.e. samples) in the first dimension if data.ndim == 2: data = data[:, np.newaxis, :] n_samples = data.shape[0] n_units = data.shape[1] n_pairs = data.shape[2] * (data.shape[2] - 1) // 2 onsets = np.arange(n_samples - width) n_windows = len(onsets) win_iscs = np.zeros((n_windows, n_pairs, n_units)) for onset in onsets: win_data = data[onset:onset + width, ...] win_iscs[onset, ...] = isc(win_data, pairwise=True) if onset > 0 and onset % 500 == 0: print(f"Finished computing ISC for {onset} windows") if n_units == 1: win_iscs = win_iscs[..., 0] return win_iscs
def test_squareform_isfc(): # Set parameters for toy time series data n_subjects = 20 n_TRs = 60 n_voxels = 30 random_state = 42 logger.info("Testing ISC options") data = simulated_timeseries(n_subjects, n_TRs, n_voxels=n_voxels, data_type='array', random_state=random_state) # Generate square redundant ISFCs isfcs_r = isfc(data, vectorize_isfcs=False) assert isfcs_r.shape == (n_subjects, n_voxels, n_voxels) # Squareform these into condensed ISFCs and ISCs isfcs_c, iscs_c = squareform_isfc(isfcs_r) assert isfcs_c.shape == (n_subjects, n_voxels * (n_voxels - 1) / 2) assert iscs_c.shape == (n_subjects, n_voxels) # Go back the other way and check it's the same isfcs_new = squareform_isfc(isfcs_c, iscs_c) assert np.array_equal(isfcs_r, isfcs_new) # Check against ISC function assert np.allclose(isc(data), iscs_c, rtol=1e-03) # Check for two subjects isfcs_r = isfc(data[..., :2], vectorize_isfcs=False) assert isfcs_r.shape == (n_voxels, n_voxels) isfcs_c, iscs_c = squareform_isfc(isfcs_r) assert isfcs_c.shape == (n_voxels * (n_voxels - 1) / 2,) assert iscs_c.shape == (n_voxels,) assert np.array_equal(isfcs_r, squareform_isfc(isfcs_c, iscs_c))
def test_isc_options(): # Set parameters for toy time series data n_subjects = 20 n_TRs = 60 n_voxels = 30 random_state = 42 logger.info("Testing ISC options") data = simulated_timeseries(n_subjects, n_TRs, n_voxels=n_voxels, data_type='array', random_state=random_state) iscs_loo = isc(data, pairwise=False, summary_statistic=None) assert iscs_loo.shape == (n_subjects, n_voxels) # Just two subjects iscs_loo = isc(data[..., :2], pairwise=False, summary_statistic=None) assert iscs_loo.shape == (n_voxels, ) iscs_pw = isc(data, pairwise=True, summary_statistic=None) assert iscs_pw.shape == (n_subjects * (n_subjects - 1) / 2, n_voxels) # Check summary statistics isc_mean = isc(data, pairwise=False, summary_statistic='mean') assert isc_mean.shape == (n_voxels, ) isc_median = isc(data, pairwise=False, summary_statistic='median') assert isc_median.shape == (n_voxels, ) with pytest.raises(ValueError): isc(data, pairwise=False, summary_statistic='min') logger.info("Finished testing ISC options")
# Strip comments and load in data as numpy array subj_data = load_1D(roi_fn) # Trim data based on event onset and duration subj_data = subj_data[onset:offset] subj_data = subj_data[initial_trim:] # Z-score input time series subj_data = zscore(subj_data) multi_runs[subject][roi_fn] = subj_data # Get a clean average pieman template time series for comparison one_runs = np.column_stack(one_runs) one_clean = one_runs[:, isc(one_runs).flatten() >= threshold] one_avg = np.mean(one_clean, axis=1) # Check correlation of each run against average pieman_exclude = {task: {}} for subject in multi_runs: for run in multi_runs[subject]: r = pearsonr(one_avg, multi_runs[subject][run])[0] if r < threshold: if subject not in pieman_exclude: pieman_exclude[task][subject] = [ basename(run).split('_space')[0] ] else: pieman_exclude[task][subject].append(
mask_fn = join(curr_dir, 'avg152T1_gray_3mm.nii.gz') func_fns = [ join(curr_dir, 'sub-{0:03d}-task-intact1.nii.gz'.format(sub)) for sub in np.arange(1, 6) ] print('Loading data from {0} subjects...'.format(len(func_fns))) mask_image = io.load_boolean_mask(mask_fn, lambda x: x > 50) masked_images = image.mask_images(io.load_images(func_fns), mask_image) coords = np.where(mask_image) data = image.MaskedMultiSubjectData.from_masked_images(masked_images, len(func_fns)) print('Calculating mean ISC on {0} voxels'.format(data.shape[1])) iscs = isc(data, pairwise=False, summary_statistic='mean') iscs = np.nan_to_num(iscs) print('Writing ISC map to file...') nii_template = nib.load(mask_fn) isc_vol = np.zeros(nii_template.shape) isc_vol[coords] = iscs isc_image = nib.Nifti1Image(isc_vol, nii_template.affine, nii_template.header) nib.save(isc_image, 'example_isc.nii.gz') isc_mask = (iscs > 0.2)[0, :] print('Calculating mean ISFC on {0} voxels...'.format(np.sum(isc_mask))) data_masked = data[:, isc_mask, :] isfcs = isfc(data_masked, pairwise=False, summary_statistic='mean') print('Clustering ISFC...')
def lagged_isc(data, lags=20, circular=True, subjects=None, summary_statistic=None): # Check response time series input format data, n_TRs, n_voxels, n_subjects = _check_timeseries_input(data) # If lag is integer, get positive and negative range around zero if type(lags) is int: lags = np.arange(-lags, lags + 1) # Iterate through lags to populate lagged ISCs lagged_iscs = [] for lag in lags: lagged_isc = [] for s in np.arange(n_subjects): lagged_subject = data[..., s] lagged_mean = np.mean(np.delete(data, s, 2), axis=2) # If circular, loop excess elements to beginning if circular: if lag != 0: lagged_subject = np.concatenate( (lagged_subject[-lag:, :], lagged_subject[:-lag, :])) # If not circular, trim non-overlapping elements # Shifts y with respect to x else: if lag < 0: lagged_subject = lagged_subject[:lag, :] lagged_mean = lagged_mean[-lag:, :] elif lag > 0: lagged_subject = lagged_subject[lag:, :] lagged_mean = lagged_mean[:-lag, :] loo_isc = isc(np.dstack((lagged_subject, lagged_mean))) lagged_isc.append(loo_isc) lagged_iscs.append(np.dstack(lagged_isc)) lagged_iscs = np.vstack(lagged_iscs) # Compute lag for maximum ISC per subject peak_lags = [] for lagged_subject in np.moveaxis(lagged_iscs, 2, 0): np.argmax(lagged_subject) peak_lags.append(int(lags[np.argmax(lagged_subject)])) if subjects: peak_lags = { subject: peak_lag for subject, peak_lag in zip(subjects, peak_lags) } # Optionally summarize across subjects if summary_statistic: lagged_iscs = compute_summary_statistic( lagged_isc, summary_statistic=summary_statistic, axis=2) return lagged_iscs, peak_lags
subject_list.append(subject) run_list.append(basename(bold_fn)) data.append(subj_data) print(f"Loaded {subtask} {subject} " f"({hemi}) for ISC analysis") data = np.dstack(data) # Print group-specific ISC notification if group: print(f"Computing within-group ISCs for {task} " f"({hemi}): {group}") # Compute ISCs print(f"Started ISC analysis for {subtask} ({hemi})") iscs = isc(data) print(f"Finished ISC analysis for {subtask} ({hemi})") # Split ISCs into subject-/run-specific GIfTI files assert len(subject_list) == len(run_list) == len(iscs) for s, fn, r in zip(subject_list, run_list, iscs): isc_fn = join( afni_dir, s, 'func', fn.replace('_desc-clean.func.gii', '_isc.gii').replace(f'task-{task}', f'task-{subtask}')) template_fn = join(afni_dir, s, 'func', fn) write_gifti(r, isc_fn, template_fn) print(f"Saved {subtask} {s} ({hemi}) ISC")
def vertex_isc(data, threshold=.2, stories=None, subjects=None, half=1, save_iscs=False): # By default grab all stories stories = check_keys(data, keys=stories) vertex_iscs = {} for story in stories: # By default just grab all subjects subject_list = check_keys(data[story], keys=subjects, subkey=story) # Get for specified hemisphere(s) hemi_stack = [] for hemi in ['lh', 'rh']: # Grab ROI data and targets data_stack = np.dstack( ([data[story][subject][hemi] for subject in subject_list])) # Compute mean ISCs for this story and hemisphere iscs = isc(data_stack, summary_statistic='mean') # Optionally save ISCs if save_iscs: save_fn = (f'data/{story}_half-{half}_vertex-iscs_' f'thresh-{threshold}_{hemi}.npy') np.save(save_fn, iscs) hemi_stack.append(iscs) # Stack left and right hemispheres vertex_iscs[story] = np.hstack(hemi_stack) print(f"Finished computing vertex-wise ISCs for '{story}'") # Find the average ISCs across all stories (with Fisher Z) mean_iscs = np.tanh( np.mean([np.arctanh(vertex_iscs[story]) for story in stories], axis=0)) # Optionally save ISCs if save_iscs: save_fn = (f'data/mean_half-{half}_vertex-iscs_' f'thresh-{threshold}_{hemi}.npy') np.save(save_fn, iscs) # Get vertices with mean ISC exceeding threshold isc_mask = mean_iscs >= threshold n_mask = np.sum(isc_mask) mask_lh = isc_mask[:len(isc_mask) // 2] mask_rh = isc_mask[len(isc_mask) // 2:] # Grab vertex time-series in ISC mask masked_data = {} for story in stories: masked_data[story] = {} for subject in subject_list: # Mask and recombine hemispheres masked = np.hstack((data[story][subject]['lh'][:, mask_lh], data[story][subject]['rh'][:, mask_rh])) assert masked.shape[1] == n_mask masked_data[story][subject] = masked print("Finished computing ISC-based targets " f"({n_mask} vertices at threshold r = {threshold})") return masked_data
# Load in PCA-reduced LSTMS k = 100 lstms_pca = np.load(f'results/lstms_tanh-z_pca-k{k}.npy') # Compute simple ISC and save n_matchups = 4 n_repeats = 8 n_players = 4 n_pairs = n_players * (n_players - 1) // 2 iscs = np.full((n_matchups, n_repeats, n_pairs, k), np.nan) for matchup in np.arange(n_matchups): for repeat in np.arange(n_repeats): lstms_rep = np.moveaxis(lstms_pca[matchup, repeat], 0, 2) iscs[matchup, repeat] = isc(lstms_rep, pairwise=True) print("Finished computing ISC for" f"matchup {matchup} repeat {repeat}") np.save(f'results/iscs_tanh-z_pca-k{k}.npy', iscs) # Plot cooperative/competitive ISC for top 10 PCs matchup = 0 n_repeats = 8 pcs = np.arange(10) sns.set_context('notebook', font_scale=1.2) fig, axs = plt.subplots(2, 5, figsize=(25, 8)) for pc, ax in zip(pcs, axs.ravel()): corr = fisher_mean([np.corrcoef(lstms_pca[matchup, r, ..., pc]) for r in np.arange(n_repeats)], axis=0) sns.heatmap(corr, square=True, annot=True, vmin=-1, vmax=1,
def test_bootstrap_isc(): # Set parameters for toy time series data n_subjects = 20 n_TRs = 60 n_voxels = 30 random_state = 42 n_bootstraps = 10 logger.info("Testing bootstrap hypothesis test") data = simulated_timeseries(n_subjects, n_TRs, n_voxels=n_voxels, data_type='array', random_state=random_state) iscs = isc(data, pairwise=False, summary_statistic=None) observed, ci, p, distribution = bootstrap_isc(iscs, pairwise=False, summary_statistic='median', n_bootstraps=n_bootstraps, ci_percentile=95) assert distribution.shape == (n_bootstraps, n_voxels) # Test one-sample bootstrap test with pairwise approach n_bootstraps = 10 iscs = isc(data, pairwise=True, summary_statistic=None) observed, ci, p, distribution = bootstrap_isc(iscs, pairwise=True, summary_statistic='median', n_bootstraps=n_bootstraps, ci_percentile=95) assert distribution.shape == (n_bootstraps, n_voxels) # Check random seeds iscs = isc(data, pairwise=False, summary_statistic=None) distributions = [] for random_state in [42, 42, None]: observed, ci, p, distribution = bootstrap_isc( iscs, pairwise=False, summary_statistic='median', n_bootstraps=n_bootstraps, ci_percentile=95, random_state=random_state) distributions.append(distribution) assert np.array_equal(distributions[0], distributions[1]) assert not np.array_equal(distributions[1], distributions[2]) # Check output p-values data = correlated_timeseries(20, 60, noise=.5, random_state=42) iscs = isc(data, pairwise=False) observed, ci, p, distribution = bootstrap_isc(iscs, pairwise=False) assert np.all(iscs[:, :2] > .5) assert np.all(iscs[:, -1] < .5) assert p[0] < .05 and p[1] < .05 assert p[2] > .01 iscs = isc(data, pairwise=True) observed, ci, p, distribution = bootstrap_isc(iscs, pairwise=True) assert np.all(iscs[:, :2] > .5) assert np.all(iscs[:, -1] < .5) assert p[0] < .05 and p[1] < .05 assert p[2] > .01 # Check that ISC computation and bootstrap observed are same iscs = isc(data, pairwise=False) observed, ci, p, distribution = bootstrap_isc(iscs, pairwise=False, summary_statistic='median') assert np.array_equal(observed, isc(data, pairwise=False, summary_statistic='median')) # Check that ISC computation and bootstrap observed are same iscs = isc(data, pairwise=True) observed, ci, p, distribution = bootstrap_isc(iscs, pairwise=True, summary_statistic='median') assert np.array_equal(observed, isc(data, pairwise=True, summary_statistic='median')) logger.info("Finished testing bootstrap hypothesis test")
def test_permutation_isc(): # Set parameters for toy time series data n_subjects = 20 n_TRs = 60 n_voxels = 30 random_state = 42 group_assignment = [1] * 10 + [2] * 10 logger.info("Testing permutation test") # Create dataset with two groups in pairwise approach data = np.dstack((simulated_timeseries(10, n_TRs, n_voxels=n_voxels, noise=1, data_type='array', random_state=3), simulated_timeseries(10, n_TRs, n_voxels=n_voxels, noise=5, data_type='array', random_state=4))) iscs = isc(data, pairwise=True, summary_statistic=None) observed, p, distribution = permutation_isc( iscs, group_assignment=group_assignment, pairwise=True, summary_statistic='mean', n_permutations=200) # Create data with two groups in leave-one-out approach data_1 = simulated_timeseries(10, n_TRs, n_voxels=n_voxels, noise=1, data_type='array', random_state=3) data_2 = simulated_timeseries(10, n_TRs, n_voxels=n_voxels, noise=10, data_type='array', random_state=4) iscs = np.vstack((isc(data_1, pairwise=False, summary_statistic=None), isc(data_2, pairwise=False, summary_statistic=None))) observed, p, distribution = permutation_isc( iscs, group_assignment=group_assignment, pairwise=False, summary_statistic='mean', n_permutations=200) # One-sample leave-one-out permutation test data = simulated_timeseries(n_subjects, n_TRs, n_voxels=n_voxels, data_type='array', random_state=random_state) iscs = isc(data, pairwise=False, summary_statistic=None) observed, p, distribution = permutation_isc(iscs, pairwise=False, summary_statistic='median', n_permutations=200) # One-sample pairwise permutation test iscs = isc(data, pairwise=True, summary_statistic=None) observed, p, distribution = permutation_isc(iscs, pairwise=True, summary_statistic='median', n_permutations=200) # Small one-sample pairwise exact test data = simulated_timeseries(12, n_TRs, n_voxels=n_voxels, data_type='array', random_state=random_state) iscs = isc(data, pairwise=False, summary_statistic=None) observed, p, distribution = permutation_isc(iscs, pairwise=False, summary_statistic='median', n_permutations=10000) # Small two-sample pairwise exact test (and unequal groups) data = np.dstack((simulated_timeseries(3, n_TRs, n_voxels=n_voxels, noise=1, data_type='array', random_state=3), simulated_timeseries(4, n_TRs, n_voxels=n_voxels, noise=50, data_type='array', random_state=4))) iscs = isc(data, pairwise=True, summary_statistic=None) group_assignment = [1, 1, 1, 2, 2, 2, 2] observed, p, distribution = permutation_isc( iscs, group_assignment=group_assignment, pairwise=True, summary_statistic='mean', n_permutations=10000) # Small two-sample leave-one-out exact test (and unequal groups) data_1 = simulated_timeseries(3, n_TRs, n_voxels=n_voxels, noise=1, data_type='array', random_state=3) data_2 = simulated_timeseries(4, n_TRs, n_voxels=n_voxels, noise=50, data_type='array', random_state=4) iscs = np.vstack((isc(data_1, pairwise=False, summary_statistic=None), isc(data_2, pairwise=False, summary_statistic=None))) group_assignment = [1, 1, 1, 2, 2, 2, 2] observed, p, distribution = permutation_isc( iscs, group_assignment=group_assignment, pairwise=False, summary_statistic='mean', n_permutations=10000) # Check output p-values data = correlated_timeseries(20, 60, noise=.5, random_state=42) iscs = isc(data, pairwise=False) observed, p, distribution = permutation_isc(iscs, pairwise=False) assert np.all(iscs[:, :2] > .5) assert np.all(iscs[:, -1] < .5) assert p[0] < .05 and p[1] < .05 assert p[2] > .01 iscs = isc(data, pairwise=True) observed, p, distribution = permutation_isc(iscs, pairwise=True) assert np.all(iscs[:, :2] > .5) assert np.all(iscs[:, -1] < .5) assert p[0] < .05 and p[1] < .05 assert p[2] > .01 # Check that ISC computation and permutation observed are same iscs = isc(data, pairwise=False) observed, p, distribution = permutation_isc(iscs, pairwise=False, summary_statistic='median') assert np.allclose(observed, isc(data, pairwise=False, summary_statistic='median'), rtol=1e-03) # Check that ISC computation and permuation observed are same iscs = isc(data, pairwise=True) observed, p, distribution = permutation_isc(iscs, pairwise=True, summary_statistic='mean') assert np.allclose(observed, isc(data, pairwise=True, summary_statistic='mean'), rtol=1e-03) logger.info("Finished testing permutaton test")
if subject in task_exclude[task]: continue # Get framewise displacement subj_fd = fds[task][subject] # Trim ragged-end if task == 'slumlordreach': subj_fd = subj_fd[:1205] task_fd.append(subj_fd) task_fd = np.column_stack(task_fd) # Compute ISCs iscs = isc(task_fd[1:, :])[:, 0] fd_iscs[task] = iscs # Plot FD ISCs task_dfs = [] for task in task_meta: task_df = pd.DataFrame(fd_iscs[task]) task_df.rename(columns={0: 'FD ISC'}, inplace=True) task_df['task'] = task task_dfs.append(task_df) fd_df = pd.concat(task_dfs) task_order = [ 'pieman', 'prettymouth', 'milkyway', 'slumlordreach', 'notthefallintact', 'black', 'forgot'
# Trim data based on event onset and duration subj_data = subj_data[onset:offset] subj_data = subj_data[initial_trim:] # Z-score input time series subj_data = zscore(subj_data) subject_list.append(subject) run_list.append(basename(roi_fn)) data.append(subj_data) data = np.column_stack(data) # Compute ISCs iscs = isc(data).flatten() # Print group-specific ISC notification if group: print(f"Within-group ISC computed for {task} " f"({hemi}): {group}") # Print mean and SD print(f"Mean {hemi} {roi} ISC for {subtask} = " f"{np.mean(iscs):.3f} (SD = {np.std(iscs):.3f})") # Convert ISCs into subject-keyed dictionary assert len(subject_list) == len(run_list) == len(iscs) isc_dict = {} for s, fn, r in zip(subject_list, run_list, iscs): if s not in isc_dict:
# Load in either raw data with mask or SRM ROI data data = load_split_data(metadata, stories=story, subjects=None, hemisphere=hemi, half=2, prefix=f'{roi}_' + prefix[1]) # Depth-stack subjects subject_stack = stack_subjects(data[story], subjects=None, hemisphere=hemi) # Get the regional average as well if prefix[0] == 'no SRM (average)': subject_stack = np.expand_dims( np.mean(subject_stack, axis=1), 1) # Compute paired time-segment correlations if isc_type == 'temporal': iscs = isc(subject_stack) elif isc_type == 'spatial': iscs = isc(np.moveaxis(subject_stack, 1, 0)) results[story][roi][prefix[0]][hemi] = iscs print(f"Finished computing {isc_type} ISCs for {story}, " f"{roi}, {prefix[0]}, {hemi}") np.save(results_fn, results)
def test_isc_nans(): # Set parameters for toy time series data n_subjects = 20 n_TRs = 60 n_voxels = 30 random_state = 42 logger.info("Testing ISC options") data = simulated_timeseries(n_subjects, n_TRs, n_voxels=n_voxels, data_type='array', random_state=random_state) # Inject NaNs into data data[0, 0, 0] = np.nan # Don't tolerate NaNs, should lose zeroeth voxel iscs_loo = isc(data, pairwise=False, tolerate_nans=False) assert np.sum(np.isnan(iscs_loo)) == n_subjects # Tolerate all NaNs, only subject with NaNs yields NaN iscs_loo = isc(data, pairwise=False, tolerate_nans=True) assert np.sum(np.isnan(iscs_loo)) == 1 # Pairwise approach shouldn't care iscs_pw_T = isc(data, pairwise=True, tolerate_nans=True) iscs_pw_F = isc(data, pairwise=True, tolerate_nans=False) assert np.allclose(iscs_pw_T, iscs_pw_F, equal_nan=True) assert (np.sum(np.isnan(iscs_pw_T)) == np.sum(np.isnan(iscs_pw_F)) == n_subjects - 1) # Set proportion of nans to reject (70% and 90% non-NaN) data[0, 0, :] = np.nan data[0, 1, :n_subjects - int(n_subjects * .7)] = np.nan data[0, 2, :n_subjects - int(n_subjects * .9)] = np.nan iscs_loo_T = isc(data, pairwise=False, tolerate_nans=True) iscs_loo_F = isc(data, pairwise=False, tolerate_nans=False) iscs_loo_95 = isc(data, pairwise=False, tolerate_nans=.95) iscs_loo_90 = isc(data, pairwise=False, tolerate_nans=.90) iscs_loo_80 = isc(data, pairwise=False, tolerate_nans=.8) iscs_loo_70 = isc(data, pairwise=False, tolerate_nans=.7) iscs_loo_60 = isc(data, pairwise=False, tolerate_nans=.6) assert (np.sum(np.isnan(iscs_loo_F)) == np.sum(np.isnan(iscs_loo_95)) == 60) assert (np.sum(np.isnan(iscs_loo_80)) == np.sum(np.isnan(iscs_loo_90)) == 42) assert (np.sum(np.isnan(iscs_loo_T)) == np.sum(np.isnan(iscs_loo_60)) == np.sum(np.isnan(iscs_loo_70)) == 28) assert np.array_equal(np.sum(np.isnan(iscs_loo_F), axis=0), np.sum(np.isnan(iscs_loo_95), axis=0)) assert np.array_equal(np.sum(np.isnan(iscs_loo_80), axis=0), np.sum(np.isnan(iscs_loo_90), axis=0)) assert np.all((np.array_equal(np.sum(np.isnan(iscs_loo_T), axis=0), np.sum(np.isnan(iscs_loo_60), axis=0)), np.array_equal(np.sum(np.isnan(iscs_loo_T), axis=0), np.sum(np.isnan(iscs_loo_70), axis=0)), np.array_equal(np.sum(np.isnan(iscs_loo_60), axis=0), np.sum(np.isnan(iscs_loo_70), axis=0)))) data = simulated_timeseries(n_subjects, n_TRs, n_voxels=n_voxels, data_type='array', random_state=random_state) # Make sure voxel with NaNs across all subjects is always removed data[0, 0, :] = np.nan iscs_loo_T = isc(data, pairwise=False, tolerate_nans=True) iscs_loo_F = isc(data, pairwise=False, tolerate_nans=False) assert np.allclose(iscs_loo_T, iscs_loo_F, equal_nan=True) assert (np.sum(np.isnan(iscs_loo_T)) == np.sum(np.isnan(iscs_loo_F)) == n_subjects) iscs_pw_T = isc(data, pairwise=True, tolerate_nans=True) iscs_pw_F = isc(data, pairwise=True, tolerate_nans=False) assert np.allclose(iscs_pw_T, iscs_pw_F, equal_nan=True) assert (np.sum(np.isnan(iscs_pw_T)) == np.sum(np.isnan(iscs_pw_F)) == n_subjects * (n_subjects - 1) / 2)
def get_iscs_across_levels(levels_betas, T, num_subjects=8): ''' Parameters ---------- levels_betas: the betas from the levels. Shape is [54, voxels, subjects] num_subjects: the number of participants. T: the top voxel Returns ------- ''' print(f'Getting the intersubject corelations for voxel {T}') # === 1. Separate levels_betas for isc analyses === betas_level_one = [] betas_level_two = [] betas_level_three = [] betas_level_four = [] betas_level_five = [] betas_level_six = [] betas_level_seven = [] betas_level_eight = [] betas_level_nine = [] num_subjects = 8 for s in range(num_subjects): #print(s) # take the array for that subject levels_betas_sub = levels_betas[:, :, s] # level 1 lvl_one_betas_sub = levels_betas_sub[0::9] betas_level_one.append(lvl_one_betas_sub) # level 2 lvl_two_betas_sub = levels_betas_sub[1::9] betas_level_two.append(lvl_two_betas_sub) # level 3 lvl_three_betas_sub = levels_betas_sub[2::9] betas_level_three.append(lvl_three_betas_sub) # level 4 lvl_four_betas_sub = levels_betas_sub[3::9] betas_level_four.append(lvl_four_betas_sub) # level 5 lvl_five_betas_sub = levels_betas_sub[4::9] betas_level_five.append(lvl_five_betas_sub) # level 6 lvl_six_betas_sub = levels_betas_sub[5::9] betas_level_six.append(lvl_six_betas_sub) # level 7 lvl_seven_betas_sub = levels_betas_sub[6::9] betas_level_seven.append(lvl_seven_betas_sub) # level 8 lvl_eight_betas_sub = levels_betas_sub[7::9] betas_level_eight.append(lvl_eight_betas_sub) # level 9 lvl_nine_betas_sub = levels_betas_sub[8::9] betas_level_nine.append(lvl_nine_betas_sub) # convert lists to np arrays betas_level_one = np.array(betas_level_one) betas_level_two = np.array(betas_level_two) betas_level_three = np.array(betas_level_three) betas_level_four = np.array(betas_level_four) betas_level_five = np.array(betas_level_five) betas_level_six = np.array(betas_level_six) betas_level_seven = np.array(betas_level_seven) betas_level_eight = np.array(betas_level_eight) betas_level_nine = np.array(betas_level_nine) # sanity check #print(betas_level_one.shape) # [subjects, games, voxels] # === 2. Swap axes to get data in right shape === # do isc for each level # compute the isc correlations using the leave one out approach betas_level_one = np.swapaxes(betas_level_one, 0, 1) # need to get [TRs, voxels, subjects] betas_level_one = np.swapaxes(betas_level_one, 1, 2) betas_level_two = np.swapaxes(betas_level_two, 0, 1) # need to get [TRs, voxels, subjects] betas_level_two = np.swapaxes(betas_level_two, 1, 2) betas_level_three = np.swapaxes(betas_level_three, 0, 1) # need to get [TRs, voxels, subjects] betas_level_three = np.swapaxes(betas_level_three, 1, 2) betas_level_four = np.swapaxes(betas_level_four, 0, 1) # need to get [TRs, voxels, subjects] betas_level_four = np.swapaxes(betas_level_four, 1, 2) betas_level_five = np.swapaxes(betas_level_five, 0, 1) # need to get [TRs, voxels, subjects] betas_level_five = np.swapaxes(betas_level_five, 1, 2) betas_level_six = np.swapaxes(betas_level_six, 0, 1) # need to get [TRs, voxels, subjects] betas_level_six = np.swapaxes(betas_level_six, 1, 2) betas_level_seven = np.swapaxes(betas_level_seven, 0, 1) # need to get [TRs, voxels, subjects] betas_level_seven = np.swapaxes(betas_level_seven, 1, 2) betas_level_eight = np.swapaxes(betas_level_eight, 0, 1) # need to get [TRs, voxels, subjects] betas_level_eight = np.swapaxes(betas_level_eight, 1, 2) betas_level_nine = np.swapaxes(betas_level_nine, 0, 1) # need to get [TRs, voxels, subjects] betas_level_nine = np.swapaxes(betas_level_nine, 1, 2) # 3. === Pick a voxel (this voxel should be the most intense voxel from some ROI) === # IMPORTANT: Momchils affine's matrix is the same so if the code says its voxel 5, # I should get the 5th voxel in Python (which is actually #6 then bc of zero-indexing) topVox_betas_lvl_one = betas_level_one[:, T:T + 1, :] topVox_betas_lvl_two = betas_level_two[:, T:T + 1, :] topVox_betas_lvl_three = betas_level_three[:, T:T + 1, :] topVox_betas_lvl_four = betas_level_four[:, T:T + 1, :] topVox_betas_lvl_five = betas_level_five[:, T:T + 1, :] topVox_betas_lvl_six = betas_level_six[:, T:T + 1, :] topVox_betas_lvl_seven = betas_level_seven[:, T:T + 1, :] topVox_betas_lvl_eight = betas_level_eight[:, T:T + 1, :] topVox_betas_lvl_nine = betas_level_nine[:, T:T + 1, :] # 4. === Get standard deviations and SE for error bars === # (std of betas from voxel) / sqrt(num_subjects) SEm_one = round((np.std(topVox_betas_lvl_one)) / math.sqrt(num_subjects), 2) SEm_two = round((np.std(topVox_betas_lvl_two)) / math.sqrt(num_subjects), 2) SEm_three = round( (np.std(topVox_betas_lvl_three)) / math.sqrt(num_subjects), 2) SEm_four = round((np.std(topVox_betas_lvl_four)) / math.sqrt(num_subjects), 2) SEm_five = round((np.std(topVox_betas_lvl_five)) / math.sqrt(num_subjects), 2) SEm_six = round((np.std(topVox_betas_lvl_six)) / math.sqrt(num_subjects), 2) SEm_seven = round( (np.std(topVox_betas_lvl_seven)) / math.sqrt(num_subjects), 2) SEm_eight = round( (np.std(topVox_betas_lvl_eight)) / math.sqrt(num_subjects), 2) SEm_nine = round((np.std(topVox_betas_lvl_nine)) / math.sqrt(num_subjects), 2) # put them into a list for plotting errors = [ SEm_one, SEm_two, SEm_three, SEm_four, SEm_five, SEm_six, SEm_seven, SEm_eight, SEm_nine ] # === 5. Do the ISC for the chosen voxel === # We obtain a scalar value for each level, because we collapse the vector of r coefficients (using Fischer Z first) isc_r_topVox_one = float( isc(topVox_betas_lvl_one, pairwise=False, tolerate_nans=True, summary_statistic='mean')) isc_r_topVox_two = float( isc(topVox_betas_lvl_two, pairwise=False, tolerate_nans=True, summary_statistic='mean')) isc_r_topVox_three = float( isc(topVox_betas_lvl_three, pairwise=False, tolerate_nans=True, summary_statistic='mean')) isc_r_topVox_four = float( isc(topVox_betas_lvl_four, pairwise=False, tolerate_nans=True, summary_statistic='mean')) isc_r_topVox_five = float( isc(topVox_betas_lvl_five, pairwise=False, tolerate_nans=True, summary_statistic='mean')) isc_r_topVox_six = float( isc(topVox_betas_lvl_six, pairwise=False, tolerate_nans=True, summary_statistic='mean')) isc_r_topVox_seven = float( isc(topVox_betas_lvl_seven, pairwise=False, tolerate_nans=True, summary_statistic='mean')) isc_r_topVox_eight = float( isc(topVox_betas_lvl_eight, pairwise=False, tolerate_nans=True, summary_statistic='mean')) isc_r_topVox_nine = float( isc(topVox_betas_lvl_nine, pairwise=False, tolerate_nans=True, summary_statistic='mean')) # === 6. Collect the correlation coefficients === isc_r_values_levels = [ isc_r_topVox_one, isc_r_topVox_two, isc_r_topVox_three, isc_r_topVox_four, isc_r_topVox_five, isc_r_topVox_six, isc_r_topVox_seven, isc_r_topVox_eight, isc_r_topVox_nine ] isc_r_values_levels = [round(i, 2) for i in isc_r_values_levels] return isc_r_values_levels, errors
def test_bootstrap_isc(): # Set parameters for toy time series data n_subjects = 20 n_TRs = 60 n_voxels = 30 random_state = 42 n_bootstraps = 10 logger.info("Testing bootstrap hypothesis test") data = simulated_timeseries(n_subjects, n_TRs, n_voxels=n_voxels, data_type='array', random_state=random_state) iscs = isc(data, pairwise=False, summary_statistic=None) observed, ci, p, distribution = bootstrap_isc(iscs, pairwise=False, summary_statistic='median', n_bootstraps=n_bootstraps, ci_percentile=95) assert distribution.shape == (n_bootstraps, n_voxels) # Test one-sample bootstrap test with pairwise approach n_bootstraps = 10 iscs = isc(data, pairwise=True, summary_statistic=None) observed, ci, p, distribution = bootstrap_isc(iscs, pairwise=True, summary_statistic='median', n_bootstraps=n_bootstraps, ci_percentile=95) assert distribution.shape == (n_bootstraps, n_voxels) # Check random seeds iscs = isc(data, pairwise=False, summary_statistic=None) distributions = [] for random_state in [42, 42, None]: observed, ci, p, distribution = bootstrap_isc( iscs, pairwise=False, summary_statistic='median', n_bootstraps=n_bootstraps, ci_percentile=95, random_state=random_state) distributions.append(distribution) assert np.array_equal(distributions[0], distributions[1]) assert not np.array_equal(distributions[1], distributions[2]) # Check output p-values data = correlated_timeseries(20, 60, noise=.5, random_state=42) iscs = isc(data, pairwise=False) observed, ci, p, distribution = bootstrap_isc(iscs, pairwise=False) assert np.all(iscs[:, :2] > .5) assert np.all(iscs[:, -1] < .5) assert p[0] < .05 and p[1] < .05 assert p[2] > .01 print(p) iscs = isc(data, pairwise=True) observed, ci, p, distribution = bootstrap_isc(iscs, pairwise=True) assert np.all(iscs[:, :2] > .5) assert np.all(iscs[:, -1] < .5) assert p[0] < .05 and p[1] < .05 assert p[2] > .01 # Check that ISC computation and bootstrap observed are same iscs = isc(data, pairwise=False) observed, ci, p, distribution = bootstrap_isc(iscs, pairwise=False, summary_statistic='median') assert np.array_equal( observed, isc(data, pairwise=False, summary_statistic='median')) # Check that ISC computation and bootstrap observed are same iscs = isc(data, pairwise=True) observed, ci, p, distribution = bootstrap_isc(iscs, pairwise=True, summary_statistic='median') assert np.array_equal(observed, isc(data, pairwise=True, summary_statistic='median')) logger.info("Finished testing bootstrap hypothesis test")
def test_isc_nans(): # Set parameters for toy time series data n_subjects = 20 n_TRs = 60 n_voxels = 30 random_state = 42 logger.info("Testing ISC options") data = simulated_timeseries(n_subjects, n_TRs, n_voxels=n_voxels, data_type='array', random_state=random_state) # Inject NaNs into data data[0, 0, 0] = np.nan # Don't tolerate NaNs, should lose zeroeth voxel iscs_loo = isc(data, pairwise=False, tolerate_nans=False) assert np.sum(np.isnan(iscs_loo)) == n_subjects # Tolerate all NaNs, only subject with NaNs yields NaN iscs_loo = isc(data, pairwise=False, tolerate_nans=True) assert np.sum(np.isnan(iscs_loo)) == 1 # Pairwise approach shouldn't care iscs_pw_T = isc(data, pairwise=True, tolerate_nans=True) iscs_pw_F = isc(data, pairwise=True, tolerate_nans=False) assert np.allclose(iscs_pw_T, iscs_pw_F, equal_nan=True) assert (np.sum(np.isnan(iscs_pw_T)) == np.sum(np.isnan(iscs_pw_F)) == n_subjects - 1) # Set proportion of nans to reject (70% and 90% non-NaN) data[0, 0, :] = np.nan data[0, 1, :n_subjects - int(n_subjects * .7)] = np.nan data[0, 2, :n_subjects - int(n_subjects * .9)] = np.nan iscs_loo_T = isc(data, pairwise=False, tolerate_nans=True) iscs_loo_F = isc(data, pairwise=False, tolerate_nans=False) iscs_loo_95 = isc(data, pairwise=False, tolerate_nans=.95) iscs_loo_90 = isc(data, pairwise=False, tolerate_nans=.90) iscs_loo_80 = isc(data, pairwise=False, tolerate_nans=.8) iscs_loo_70 = isc(data, pairwise=False, tolerate_nans=.7) iscs_loo_60 = isc(data, pairwise=False, tolerate_nans=.6) assert (np.sum(np.isnan(iscs_loo_F)) == np.sum(np.isnan(iscs_loo_95)) == 60) assert (np.sum(np.isnan(iscs_loo_80)) == np.sum(np.isnan(iscs_loo_90)) == 42) assert (np.sum(np.isnan(iscs_loo_T)) == np.sum(np.isnan(iscs_loo_60)) == np.sum(np.isnan(iscs_loo_70)) == 28) assert np.array_equal(np.sum(np.isnan(iscs_loo_F), axis=0), np.sum(np.isnan(iscs_loo_95), axis=0)) assert np.array_equal(np.sum(np.isnan(iscs_loo_80), axis=0), np.sum(np.isnan(iscs_loo_90), axis=0)) assert np.all((np.array_equal( np.sum(np.isnan(iscs_loo_T), axis=0), np.sum(np.isnan(iscs_loo_60), axis=0)), np.array_equal( np.sum(np.isnan(iscs_loo_T), axis=0), np.sum(np.isnan(iscs_loo_70), axis=0)), np.array_equal( np.sum(np.isnan(iscs_loo_60), axis=0), np.sum(np.isnan(iscs_loo_70), axis=0)))) data = simulated_timeseries(n_subjects, n_TRs, n_voxels=n_voxels, data_type='array', random_state=random_state) # Make sure voxel with NaNs across all subjects is always removed data[0, 0, :] = np.nan iscs_loo_T = isc(data, pairwise=False, tolerate_nans=True) iscs_loo_F = isc(data, pairwise=False, tolerate_nans=False) assert np.allclose(iscs_loo_T, iscs_loo_F, equal_nan=True) assert (np.sum(np.isnan(iscs_loo_T)) == np.sum(np.isnan(iscs_loo_F)) == n_subjects) iscs_pw_T = isc(data, pairwise=True, tolerate_nans=True) iscs_pw_F = isc(data, pairwise=True, tolerate_nans=False) assert np.allclose(iscs_pw_T, iscs_pw_F, equal_nan=True) assert (np.sum(np.isnan(iscs_pw_T)) == np.sum(np.isnan(iscs_pw_F)) == n_subjects * (n_subjects - 1) / 2)
dpi=300, bbox_inches='tight') # Examine time-resolved intersubject synchrony of PCs from brainiak.isc import isc from detectors import get_following matchup = 0 pops = {0: 'A', 1: 'B', 2: 'C', 3: 'D'} repeat = 1 pc = 10 - 1 following = get_following(wrap_f, matchup_id=matchup, repeat_id=repeat) lstm_pc = lstm_pca_reduce[matchup, repeat, ..., pc] lstm_pc_isc = isc(lstm_pc.T, pairwise=True)[:, 0] fig, axs = plt.subplots(10, 1, figsize=(12, 14)) axs[0].plot(lstm_pc[0], c='darkred', alpha=.7) axs[0].plot(lstm_pc[1], c='coral', alpha=.7) axs[0].set_xticks([]) axs[0].set_ylabel('activation') axs[0].set_title(f'PC{pc + 1} (population {pops[matchup]}, ' f'repeat {repeat})') axs[0].annotate(f'ISC: {lstm_pc_isc[0]:.3f}', (.95, .95), ha='right', xycoords='axes fraction') axs[1].plot(lstm_pc[2], c='darkblue', alpha=.7) axs[1].plot(lstm_pc[3], c='lightseagreen', alpha=.7) axs[1].set_xticks([]) axs[1].set_ylabel('activation')
def test_isfc_options(): # Set parameters for toy time series data n_subjects = 20 n_TRs = 60 n_voxels = 30 logger.info("Testing ISFC options") data = simulated_timeseries(n_subjects, n_TRs, n_voxels=n_voxels, data_type='array') isfcs, iscs = isfc(data, pairwise=False, summary_statistic=None) assert isfcs.shape == (n_subjects, n_voxels * (n_voxels - 1) / 2) assert iscs.shape == (n_subjects, n_voxels) # Without vectorized upper triangle isfcs = isfc(data, pairwise=False, summary_statistic=None, vectorize_isfcs=False) assert isfcs.shape == (n_subjects, n_voxels, n_voxels) # Just two subjects isfcs, iscs = isfc(data[..., :2], pairwise=False, summary_statistic=None) assert isfcs.shape == (n_voxels * (n_voxels - 1) / 2, ) assert iscs.shape == (n_voxels, ) isfcs = isfc(data[..., :2], pairwise=False, summary_statistic=None, vectorize_isfcs=False) assert isfcs.shape == (n_voxels, n_voxels) # ISFC with pairwise approach isfcs, iscs = isfc(data, pairwise=True, summary_statistic=None) assert isfcs.shape == (n_subjects * (n_subjects - 1) / 2, n_voxels * (n_voxels - 1) / 2) assert iscs.shape == (n_subjects * (n_subjects - 1) / 2, n_voxels) isfcs = isfc(data, pairwise=True, summary_statistic=None, vectorize_isfcs=False) assert isfcs.shape == (n_subjects * (n_subjects - 1) / 2, n_voxels, n_voxels) # ISFC with summary statistics isfcs, iscs = isfc(data, pairwise=True, summary_statistic='mean') isfcs, iscs = isfc(data, pairwise=True, summary_statistic='median') # Check output p-values data = correlated_timeseries(20, 60, noise=.5, random_state=42) isfcs = isfc(data, pairwise=False, vectorize_isfcs=False) assert np.all(isfcs[:, 0, 1] > .5) and np.all(isfcs[:, 1, 0] > .5) assert np.all(isfcs[:, :2, 2] < .5) and np.all(isfcs[:, 2, :2] < .5) isfcs = isfc(data, pairwise=True, vectorize_isfcs=False) assert np.all(isfcs[:, 0, 1] > .5) and np.all(isfcs[:, 1, 0] > .5) assert np.all(isfcs[:, :2, 2] < .5) and np.all(isfcs[:, 2, :2] < .5) # Check that ISC and ISFC diagonal are identical iscs = isc(data, pairwise=False) isfcs = isfc(data, pairwise=False, vectorize_isfcs=False) for s in np.arange(len(iscs)): assert np.allclose(isfcs[s, ...].diagonal(), iscs[s, :], rtol=1e-03) isfcs, iscs_v = isfc(data, pairwise=False) assert np.allclose(iscs, iscs_v, rtol=1e-03) # Check that ISC and ISFC diagonal are identical (pairwise) iscs = isc(data, pairwise=True) isfcs = isfc(data, pairwise=True, vectorize_isfcs=False) for s in np.arange(len(iscs)): assert np.allclose(isfcs[s, ...].diagonal(), iscs[s, :], rtol=1e-03) isfcs, iscs_v = isfc(data, pairwise=True) assert np.allclose(iscs, iscs_v, rtol=1e-03) # Generate 'targets' data and use for ISFC data = simulated_timeseries(n_subjects, n_TRs, n_voxels=n_voxels, data_type='array') n_targets = 15 targets_data = simulated_timeseries(n_subjects, n_TRs, n_voxels=n_targets, data_type='array') isfcs = isfc(data, targets=targets_data, pairwise=False, vectorize_isfcs=False) assert isfcs.shape == (n_subjects, n_voxels, n_targets) # Ensure 'square' output enforced isfcs = isfc(data, targets=targets_data, pairwise=False, vectorize_isfcs=True) assert isfcs.shape == (n_subjects, n_voxels, n_targets) # Check list input for targets targets_data = simulated_timeseries(n_subjects, n_TRs, n_voxels=n_targets, data_type='list') isfcs = isfc(data, targets=targets_data, pairwise=False, vectorize_isfcs=False) assert isfcs.shape == (n_subjects, n_voxels, n_targets) # Check that mismatching subjects / TRs breaks targets targets_data = simulated_timeseries(n_subjects, n_TRs, n_voxels=n_targets, data_type='array') with pytest.raises(ValueError): isfcs = isfc(data, targets=targets_data[..., :-1], pairwise=False, vectorize_isfcs=False) assert isfcs.shape == (n_subjects, n_voxels, n_targets) with pytest.raises(ValueError): isfcs = isfc(data, targets=targets_data[:-1, ...], pairwise=False, vectorize_isfcs=False) # Check targets for only 2 subjects isfcs = isfc(data[..., :2], targets=targets_data[..., :2], pairwise=False, summary_statistic=None) assert isfcs.shape == (2, n_voxels, n_targets) isfcs = isfc(data[..., :2], targets=targets_data[..., :2], pairwise=True, summary_statistic=None) assert isfcs.shape == (2, n_voxels, n_targets) # Check that supplying targets enforces leave-one-out isfcs_pw = isfc(data, targets=targets_data, pairwise=True, vectorize_isfcs=False, tolerate_nans=False) assert isfcs_pw.shape == (n_subjects, n_voxels, n_targets) logger.info("Finished testing ISFC options")
def timeflip_isc(data, pairwise=False, summary_statistic='median', n_flips=1000, tolerate_nans=True, random_state=None): """Time-series flipping randomization for one-sample ISC For each voxel or ROI, compute the actual ISC and p-values from a null distribution of ISCs where response time series are first randomly flipped around zero (i.e. multiplied by 1 or -1). Input time-series are mean-centered prior to computing ISC and test. If pairwise, apply random time-series flipping to each subject and compute pairwise ISCs. If leave-one-out approach is used (pairwise=False), apply the random time-series flipping to only the left-out subject in each iteration of the leave-one-out procedure. Input data should be a list where each item is a time-points by voxels ndarray for a given subject. Multiple input ndarrays must be the same shape. If a single ndarray is supplied, the last dimension is assumed to correspond to subjects. When using leave-one-out approach, NaNs are ignored when computing mean time series of N-1 subjects (default: tolerate_nans=True). Alternatively, you may supply a float between 0 and 1 indicating a threshold proportion of N subjects with non-NaN values required when computing the average time series for a given voxel. For example, if tolerate_nans=.8, ISCs will be computed for any voxel where >= 80% of subjects have non-NaN values, while voxels with < 80% non-NaN values will be assigned NaNs. If set to False, NaNs are not tolerated and voxels with one or more NaNs among the N-1 subjects will be assigned NaN. Setting tolerate_nans to True or False will not affect the pairwise approach; however, if a threshold float is provided, voxels that do not reach this threshold will be excluded. Note that accommodating NaNs may be notably slower than setting tolerate_nans to False. Returns the observed ISC and p-values (two-tailed test), as well as the null distribution of ISCs computed on randomly flipped time-series data. Parameters ---------- data : list or ndarray (n_TRs x n_voxels x n_subjects) fMRI data for which to compute ISFC pairwise : bool, default: False Whether to use pairwise (True) or leave-one-out (False) approach summary_statistic : str, default: 'median' Summary statistic, either 'median' (default) or 'mean' n_flips : int, default: 1000 Number of randomly flipped samples tolerate_nans : bool or float, default: True Accommodate NaNs (when averaging in leave-one-out approach) random_state = int, None, or np.random.RandomState, default: None Initial random seed Returns ------- observed : float, observed ISC (without time-series flipping) Actual ISCs p : float, p-value p-value based on randomized time-series flipping distribution : ndarray, n_flips by voxels Time-series flipped null distribution """ # Check response time series input format data, n_TRs, n_voxels, n_subjects = _check_timeseries_input(data) # Mean-center time series for flipping around zero data -= np.mean(data, axis=0) # Get actual observed ISC observed = isc(data, pairwise=pairwise, summary_statistic=summary_statistic, tolerate_nans=tolerate_nans) # Roll axis to get subjects in first dimension for loop if pairwise: data = np.rollaxis(data, 2, 0) # Iterate through randomized flips to create null distribution distribution = [] for i in np.arange(n_flips): # Random seed to be deterministically re-randomized at each iteration if isinstance(random_state, np.random.RandomState): prng = random_state else: prng = np.random.RandomState(random_state) # Get a random set of flips based on number of subjects flips = prng.choice([-1, 1], size=n_subjects, replace=True) # In pairwise approach, apply all flips then compute pairwise ISCs if pairwise: # Apply flips to each subject's time series flipped_data = data * flips # Compute null ISC on shifted data for pairwise approach flipped_isc = isc(flipped_data, pairwise=pairwise, summary_statistic=summary_statistic, tolerate_nans=tolerate_nans) # In leave-one-out, apply flips only to each left-out participant elif not pairwise: flipped_isc = [] for s, flip in enumerate(flips): flipped_subject = data[..., s] * flip nonflipped_mean = np.mean(np.delete(data, s, 2), axis=2) loo_isc = isc(np.dstack((flipped_subject, nonflipped_mean)), pairwise=False, summary_statistic=None, tolerate_nans=tolerate_nans) flipped_isc.append(loo_isc) # Get summary statistics across left-out subjects flipped_isc = compute_summary_statistic( np.dstack(flipped_isc), summary_statistic=summary_statistic, axis=2) distribution.append(flipped_isc) # Update random state for next iteration random_state = np.random.RandomState(prng.randint(0, MAX_RANDOM_SEED)) # Convert distribution to numpy array distribution = np.vstack(distribution) # Get p-value for actual median from shifted distribution p = p_from_null(observed, distribution, side='two-sided', exact=False, axis=0) return observed, p, distribution
sub = str(sub) DFR_onsets = np.squeeze(onsets[sub]) DFR_average_trials, trial_type_order = create_trial_type_averages( full_data[:, :, suj_count], DFR_onsets) # add into single array: TR, regions, subjs high_correct[:, :, suj_count] = DFR_average_trials[2, :, :] low_correct[:, :, suj_count] = DFR_average_trials[0, :, :] high_incorrect[:, :, suj_count] = DFR_average_trials[3, :, :] low_incorrect[:, :, suj_count] = DFR_average_trials[1, :, :] suj_count += 1 print("finished averaging trials") # Compute isc for each ROI iscs_roi_high["matlab"] = isc(np.transpose(high_correct, [1, 0, 2]), tolerate_nans=True) iscs_pairwise_high["matlab"] = isc(np.transpose(high_correct, [1, 0, 2]), pairwise=True) print("finished high load ISCs") iscs_roi_low["matlab"] = isc(np.transpose(low_correct, [1, 0, 2])) iscs_pairwise_low["matlab"] = isc(np.transpose(low_correct, [1, 0, 2]), pairwise=True) print("finished low load ISCs") f = open("spatial_ISC_matlab_test.pckl", 'wb') pickle.dump( [iscs_pairwise_high, iscs_roi_high, iscs_pairwise_low, iscs_roi_low], f) f.close()
high_incorrect[:, :, suj_count] = DFR_average_trials[3, :, :] low_incorrect[:, :, suj_count] = DFR_average_trials[1, :, :] suj_count += 1 print("All subjects loaded") f = open("Yeo_masked_DFR.pckl", "wb") pickle.dump( [high_correct, low_correct, high_incorrect, low_incorrect, reduced_labels], f) f.close() print("Raw data saved") isc_pairwise = {} isc_LOO = {} isc_pairwise["high_correct"] = isc(high_correct, pairwise=True) isc_pairwise["low_correct"] = isc(low_correct, pairwise=True) print("Finished pairwise ISC") isc_LOO["high_correct"] = isc(high_correct, pairwise=False) isc_LOO["low_correct"] = isc(low_correct, pairwise=False) print("finished leave one out ISC") f = open('ISC.pckl', 'wb') pickle.dump([isc_pairwise, isc_LOO, reduced_labels], f) f.close()
mask_fn = join(curr_dir,'avg152T1_gray_3mm.nii.gz') func_fns = [join(curr_dir, 'sub-{0:03d}-task-intact1.nii.gz'.format(sub)) for sub in np.arange(1, 6)] print('Loading data from {0} subjects...'.format(len(func_fns))) mask_image = io.load_boolean_mask(mask_fn, lambda x: x > 50) masked_images = image.mask_images(io.load_images(func_fns), mask_image) coords = np.where(mask_image) data = image.MaskedMultiSubjectData.from_masked_images(masked_images, len(func_fns)) print('Calculating mean ISC on {0} voxels'.format(data.shape[1])) iscs = isc(data, pairwise=False, summary_statistic='mean') iscs = np.nan_to_num(iscs) print('Writing ISC map to file...') nii_template = nib.load(mask_fn) isc_vol = np.zeros(nii_template.shape) isc_vol[coords] = iscs isc_image = nib.Nifti1Image(isc_vol, nii_template.affine, nii_template.header) nib.save(isc_image, 'example_isc.nii.gz') isc_mask = (iscs > 0.2)[0, :] print('Calculating mean ISFC on {0} voxels...'.format(np.sum(isc_mask))) data_masked = data[:, isc_mask, :] isfcs = isfc(data_masked, pairwise=False, summary_statistic='mean')
def test_isfc_options(): # Set parameters for toy time series data n_subjects = 20 n_TRs = 60 n_voxels = 30 logger.info("Testing ISFC options") data = simulated_timeseries(n_subjects, n_TRs, n_voxels=n_voxels, data_type='array') isfcs, iscs = isfc(data, pairwise=False, summary_statistic=None) assert isfcs.shape == (n_subjects, n_voxels * (n_voxels - 1) / 2) assert iscs.shape == (n_subjects, n_voxels) # Without vectorized upper triangle isfcs = isfc(data, pairwise=False, summary_statistic=None, vectorize_isfcs=False) assert isfcs.shape == (n_subjects, n_voxels, n_voxels) # Just two subjects isfcs, iscs = isfc(data[..., :2], pairwise=False, summary_statistic=None) assert isfcs.shape == (n_voxels * (n_voxels - 1) / 2,) assert iscs.shape == (n_voxels,) isfcs = isfc(data[..., :2], pairwise=False, summary_statistic=None, vectorize_isfcs=False) assert isfcs.shape == (n_voxels, n_voxels) # ISFC with pairwise approach isfcs, iscs = isfc(data, pairwise=True, summary_statistic=None) assert isfcs.shape == (n_subjects * (n_subjects - 1) / 2, n_voxels * (n_voxels - 1) / 2) assert iscs.shape == (n_subjects * (n_subjects - 1) / 2, n_voxels) isfcs = isfc(data, pairwise=True, summary_statistic=None, vectorize_isfcs=False) assert isfcs.shape == (n_subjects * (n_subjects - 1) / 2, n_voxels, n_voxels) # ISFC with summary statistics isfcs, iscs = isfc(data, pairwise=True, summary_statistic='mean') isfcs, iscs = isfc(data, pairwise=True, summary_statistic='median') # Check output p-values data = correlated_timeseries(20, 60, noise=.5, random_state=42) isfcs = isfc(data, pairwise=False, vectorize_isfcs=False) assert np.all(isfcs[:, 0, 1] > .5) and np.all(isfcs[:, 1, 0] > .5) assert np.all(isfcs[:, :2, 2] < .5) and np.all(isfcs[:, 2, :2] < .5) isfcs = isfc(data, pairwise=True, vectorize_isfcs=False) assert np.all(isfcs[:, 0, 1] > .5) and np.all(isfcs[:, 1, 0] > .5) assert np.all(isfcs[:, :2, 2] < .5) and np.all(isfcs[:, 2, :2] < .5) # Check that ISC and ISFC diagonal are identical iscs = isc(data, pairwise=False) isfcs = isfc(data, pairwise=False, vectorize_isfcs=False) for s in np.arange(len(iscs)): assert np.allclose(isfcs[s, ...].diagonal(), iscs[s, :], rtol=1e-03) isfcs, iscs_v = isfc(data, pairwise=False) assert np.allclose(iscs, iscs_v, rtol=1e-03) # Check that ISC and ISFC diagonal are identical (pairwise) iscs = isc(data, pairwise=True) isfcs = isfc(data, pairwise=True, vectorize_isfcs=False) for s in np.arange(len(iscs)): assert np.allclose(isfcs[s, ...].diagonal(), iscs[s, :], rtol=1e-03) isfcs, iscs_v = isfc(data, pairwise=True) assert np.allclose(iscs, iscs_v, rtol=1e-03) # Generate 'targets' data and use for ISFC data = simulated_timeseries(n_subjects, n_TRs, n_voxels=n_voxels, data_type='array') n_targets = 15 targets_data = simulated_timeseries(n_subjects, n_TRs, n_voxels=n_targets, data_type='array') isfcs = isfc(data, targets=targets_data, pairwise=False, vectorize_isfcs=False) assert isfcs.shape == (n_subjects, n_voxels, n_targets) # Ensure 'square' output enforced isfcs = isfc(data, targets=targets_data, pairwise=False, vectorize_isfcs=True) assert isfcs.shape == (n_subjects, n_voxels, n_targets) # Check list input for targets targets_data = simulated_timeseries(n_subjects, n_TRs, n_voxels=n_targets, data_type='list') isfcs = isfc(data, targets=targets_data, pairwise=False, vectorize_isfcs=False) assert isfcs.shape == (n_subjects, n_voxels, n_targets) # Check that mismatching subjects / TRs breaks targets targets_data = simulated_timeseries(n_subjects, n_TRs, n_voxels=n_targets, data_type='array') with pytest.raises(ValueError): isfcs = isfc(data, targets=targets_data[..., :-1], pairwise=False, vectorize_isfcs=False) assert isfcs.shape == (n_subjects, n_voxels, n_targets) with pytest.raises(ValueError): isfcs = isfc(data, targets=targets_data[:-1, ...], pairwise=False, vectorize_isfcs=False) # Check targets for only 2 subjects isfcs = isfc(data[..., :2], targets=targets_data[..., :2], pairwise=False, summary_statistic=None) assert isfcs.shape == (2, n_voxels, n_targets) isfcs = isfc(data[..., :2], targets=targets_data[..., :2], pairwise=True, summary_statistic=None) assert isfcs.shape == (2, n_voxels, n_targets) # Check that supplying targets enforces leave-one-out isfcs_pw = isfc(data, targets=targets_data, pairwise=True, vectorize_isfcs=False, tolerate_nans=False) assert isfcs_pw.shape == (n_subjects, n_voxels, n_targets) logger.info("Finished testing ISFC options")