def test_hdf5(): """Test HDF5 IO """ test_file = op.join(tempdir, 'test.hdf5') x = dict(a=dict(b=np.zeros(3)), c=np.zeros(2, np.complex128), d=[dict(e=(1, -2., 'hello'))]) write_hdf5(test_file, 1) assert_equal(read_hdf5(test_file), 1) assert_raises(IOError, write_hdf5, test_file, x) # file exists write_hdf5(test_file, x, overwrite=True) assert_raises(IOError, read_hdf5, test_file + 'FOO') # not found xx = read_hdf5(test_file) print(object_diff(x, xx)) assert_true(object_diff(x, xx) == '') # no assert_equal, ugly output
def generate_stimuli(num_trials=10, num_freqs=4, stim_dur=0.5, min_freq=500.0, max_freq=4000.0, fs=24414.0625, rms=0.01, output_dir='.', save_as='hdf5', rand_seed=0): """Make some sine waves and save in various formats. Optimized for saving as MAT files, but can also save directly as WAV files, or can return a python dictionary with sinewave data as values. Parameters ---------- num_trials : int Number of trials you want in your experiment. Ignored if save_as is not 'mat'. num_freqs : int Number of frequencies (equally-spaced on a log2-scale) at which to generate tones. stim_dur : float Duration of the tones in seconds. min_freq : float Frequency of the lowest tone in Hertz. max_freq : float Frequency of the highest tone in Hertz. fs : float | None Sampling frequency of resulting sinewaves. Defaults to 24414.0625 (a standard rate for TDTs). rms : float RMS amplitude to which all sinwaves will be scaled. output_dir : str Directory to output the files into. save_as : str Format in which to return the sinewaves. 'dict' returns sinewave arrays as values in a python dictionary; 'wav' saves them as WAV files at sampling frequency 'fs'; 'mat' saves them as a MAT file along with related variables 'fs', 'freqs', 'trial_order', and 'rms'. rand_seed : int | None Seed for the random number generator. Returns ------- wavs : dict | None The stimulus dictionary. """ if rand_seed is None: rng = np.random.RandomState() else: rng = np.random.RandomState(rand_seed) # check input arguments if save_as not in ['dict', 'wav', 'hdf5']: raise ValueError('"save_as" must be "dict", "wav", or "hdf5"') fs = float(fs) t = np.arange(np.round(stim_dur * fs)) / fs # frequencies equally spaced on a log-2 scale freqs = min_freq * np.logspace(0, np.log2(max_freq / float(min_freq)), num_freqs, endpoint=True, base=2) # strings for the filenames / dictionary keys freq_names = [str(int(f)) for f in freqs] names = ['stim_%s_%s' % (n, f) for n, f in enumerate(freq_names)] # generate sinewaves & RMS normalize wavs = [np.sin(2 * np.pi * f * t) for f in freqs] wavs = [rms / np.sqrt(np.mean(w**2)) * w for w in wavs] # collect into dictionary & save wav_dict = {n: w for (n, w) in zip(names, wavs)} if save_as == 'hdf5': num_reps = num_trials // num_freqs + 1 trials = np.tile(range(num_freqs), num_reps) trial_order = rng.permutation(trials[0:num_trials]) wav_dict.update({ 'trial_order': trial_order, 'freqs': freqs, 'fs': fs, 'rms': rms }) write_hdf5(op.join(output_dir, 'equally_spaced_sinewaves.hdf5'), wav_dict, overwrite=True) elif save_as == 'wav': for n in names: write_wav(op.join(output_dir, n + '.wav'), wav_dict[n], int(fs)) return wav_dict
plt.figure() for p in percent_correct[i]: per_mean = p.mean(-1) plt.plot(snrs, per_mean*100) plt.xlabel('SNR (db)') plt.ylabel('Percent Correct') plt.title(sub) plt.legend(('0', '90', '180', 'Static')) percent_condition_subject = percent_correct.mean(-1) mean_across_subjects = percent_condition_subject.mean(0) sem = percent_condition_subject.std(axis=0)/np.sqrt(len(subjects)) write_hdf5('matrix1.hdf5', dict(data=percent_condition_subject), overwrite=True) percent_across_snrs = percent_condition_subject.mean(2) mean_across_subjects2 = percent_across_snrs.mean(0) sem2 = percent_across_snrs.std(axis=0)/np.sqrt(len(subjects)) #plt.plot(snrs, mean_sub*100, 'o') width = 8 height = 5 fname = 'Average Percent Correct Across SNR' plt.figure(figsize=(width, height)) plt.errorbar(x=[0, 1, 2, 3], y=mean_across_subjects2*100, yerr=sem2*100, fmt='o') plt.xticks([0, 1, 2, 3], [0, 1, 2, 3]) plt.gca().set_xticklabels(['0', '90', '180', 'Static']) plt.xlabel('Angle (deg)')
for n in np.arange(10000): sub_ind = np.random.choice(np.arange(23), (n_sub, )) disagree_tvm_resamp = disagree_tvm.mean(1)[sub_ind] t, p_tvm = scipy.stats.ttest_1samp(disagree_tvm_resamp, 0, axis=0) disagree_inv_resamp = disagree_up_vs_inv[sub_ind] t, p_inv = scipy.stats.ttest_1samp(disagree_inv_resamp, 0, axis=0) pval_tvm.append(p_tvm) pval_inv.append(p_inv) percent_sig_tvm.append(100 * sum(np.array(pval_tvm) < 0.05) / len(pval_tvm)) percent_sig_inv.append(100 * sum(np.array(pval_inv) < 0.05) / len(pval_inv)) from expyfun.io import write_hdf5 write_hdf5( 'power_analysis_sim.hdf5', dict(percent_sig_inv=percent_sig_inv, percent_sig_tvm=percent_sig_tvm)) plt.figure() plt.plot(np.arange(2, 1000), percent_sig_tvm) plt.plot(np.arange(2, 1000), percent_sig_inv) plt.plot([2, 1000], [80, 80], 'k') plt.legend(('Target vs. Masker', 'Upright vs. Inverted')) plt.xlabel('Number of simulated subjects') plt.ylabel('% of 1000 observations significant') import scipy.stats import statsmodels.stats.power as smp import matplotlib.pyplot as plt power_analysis = smp.TTestIndPower() sample_size = power_analysis.solve_power(effect_size=0.064,
(ti + 1, attns[ai], spatials[si], idents[ii], int(1e3 * gap_durs[gi]), ''.join(t), ''.join(m))) write_wav(op.join(stim_dir, fname), stim, fs, verbose=False) print(' Writing %s (%s/%s)' % (fname, ti + 1, n_trials)) stim_names.append(fname) ############################################################################## # Write out result params = dict(gap_durs=gap_durs, spatials=spatials, idents=idents, attns=attns, inter_trial_dur=inter_trial_dur, targ_pos=targ_pos, cond_mat=cond_mat, cond_readme=cond_readme, blocks=blocks, block_trials=block_trials, stim_names=stim_names, stim_dir=stim_dir_end, n_targ_let=n_targ_let, n_cue_let=n_cue_let, trial_durs=trial_durs, stim_times=ts, n_blocks=n_blocks, letter_mat=letter_mat, letters=letters, gap_after=gap_after) write_hdf5(op.join(work_dir, 'params.hdf5'), params, overwrite=True)
if w: print(':\'(') thresholds = np.array([np.power(10, m / 20) for m in [params[0][0], params[1][0]]]) thresholds = np.array([-1. / ok[1] * np.log((ok[2] - .5) / (.75 - .5) - 1) + p[0] for p in params]) thresholds = np.power(10, thresholds / 20) perform_imp = (sigmoid(20 * np.log10(thresholds[0]), lower=.5, upper=ok[2], midpt=params[1][0], slope=ok[1]) - .75) * 100 # %% save the data data = dict(responses=responses[-1], thresholds=thresholds, ok = ok, params=params, percent=percent, perform_imp = perform_imp) write_hdf5((path + 'percent_' + subject), data, overwrite=True) # %% plot an example if subject=='016': from collections import OrderedDict from matplotlib.transforms import blended_transform_factory from matplotlib import rc from matplotlib import rcParams rcParams['font.sans-serif'] = "Arial" linestyles = OrderedDict( [('densely dotted', (0, (1, 1))), ('densely dashed', (0, (5, 1))), ('loosely dashdotted', (0, (3, 10, 1, 10))),
def generate_stimuli(num_trials=10, num_freqs=4, stim_dur=0.5, min_freq=500.0, max_freq=4000.0, fs=24414.0625, rms=0.01, output_dir='.', save_as='hdf5', rand_seed=0): """Make some sine waves and save in various formats. Optimized for saving as MAT files, but can also save directly as WAV files, or can return a python dictionary with sinewave data as values. Parameters ---------- num_trials : int Number of trials you want in your experiment. Ignored if save_as is not 'mat'. num_freqs : int Number of frequencies (equally-spaced on a log2-scale) at which to generate tones. stim_dur : float Duration of the tones in seconds. min_freq : float Frequency of the lowest tone in Hertz. max_freq : float Frequency of the highest tone in Hertz. fs : float | None Sampling frequency of resulting sinewaves. Defaults to 24414.0625 (a standard rate for TDTs). rms : float RMS amplitude to which all sinwaves will be scaled. output_dir : str Directory to output the files into. save_as : str | None Format in which to return the sinewaves. 'dict' returns sinewave arrays as values in a python dictionary; 'wav' saves them as WAV files at sampling frequency 'fs'; 'mat' saves them as a MAT file along with related variables 'fs', 'freqs', 'trial_order', and 'rms'. None will not save any data. rand_seed : int | None Seed for the random number generator. Returns ------- wavs : dict | None The stimulus dictionary. """ if rand_seed is None: rng = np.random.RandomState() else: rng = np.random.RandomState(rand_seed) # check input arguments if save_as is not None and save_as not in ['dict', 'wav', 'hdf5']: raise ValueError('"save_as" must be "dict", "wav", or "hdf5"') fs = float(fs) t = np.arange(np.round(stim_dur * fs)) / fs # frequencies equally spaced on a log-2 scale freqs = min_freq * np.logspace(0, np.log2(max_freq / float(min_freq)), num_freqs, endpoint=True, base=2) # strings for the filenames / dictionary keys freq_names = [str(int(f)) for f in freqs] names = ['stim_%s_%s' % (n, f) for n, f in enumerate(freq_names)] # generate sinewaves & RMS normalize wavs = [np.sin(2 * np.pi * f * t) for f in freqs] wavs = [rms / np.sqrt(np.mean(w ** 2)) * w for w in wavs] # collect into dictionary & save wav_dict = {n: w for (n, w) in zip(names, wavs)} if save_as == 'hdf5': num_reps = num_trials // num_freqs + 1 trials = np.tile(range(num_freqs), num_reps) trial_order = rng.permutation(trials[0:num_trials]) wav_dict.update({'trial_order': trial_order, 'freqs': freqs, 'fs': fs, 'rms': rms}) write_hdf5(op.join(output_dir, 'equally_spaced_sinewaves.hdf5'), wav_dict, overwrite=True) elif save_as == 'wav': for n in names: write_wav(op.join(output_dir, n + '.wav'), wav_dict[n], int(fs)) return wav_dict
c_flash_locs = np.tile(c_flash_locations, 5) condition_stamp_controls = np.array((range(1, 49))) c_stamp_controls = np.tile(condition_stamp, 5) cc = np.vstack(([control_stim], [cflashes], [c_flash_locs], [control_C], [c_stamp_controls])).T ############################################################################ # create and store the blocks (should be 15) blocks = {} bn = ['Block1', 'Block2', 'Block3', 'Block4', 'Block5', 'Block6', 'Block7', 'Block8', 'Block9', 'Block10', 'Block11', 'Block12', 'Block13', 'Block14', 'Block15'] blocks.fromkeys(bn) n_blocks = total_trials / trials_per_block for bi in range(1, 16): d = c[0:96] # iter over this to stack into blocks stack = cc[:12] dd = np.append(d, stack, 0) blocks["Block{0}".format(bi)] = rng.permutation(dd) np.delete(c, np.s_[:96], 0) np.delete(cc, np.s_[:12], 0) # write out result: print('Saving stimuli variables') Stim_vars = dict(space_conditions=space_conditions, nocomp_stim_name=nocomp_stim_name, taud_stim=taud_stim, blocks=blocks, flashes=flashes) np.savez('stim', **Stim_vars) write_hdf5(op.join(work_dir, 'Stim_vars.hdf5'), Stim_vars, overwrite=True)
plt.gca().spines['right'].set_visible(False) plt.xlim([0,21.25]) plt.xlabel(u'Central threshold (°)') plt.ylabel('Performance improvement \n (% correct)') plt.subplots_adjust(left=0.4, right=.97, top=0.95, bottom=0.2) plt.savefig(path + 'stem_correct.pdf', dpi=600) improvements = -np.diff(thresholds, 1, -1) # %% some stats ax = plt.figure(figsize=(4.2, 2.8)) dist = np.mean(np.diff(per_cor, 1, -2), -1).squeeze() inds = np.argsort(dist) write_hdf5('effectsize.hdf5', dist, overwrite=True) plt.plot(np.arange(20) + 1, dist[inds], '^', c='C2', ms=7) plt.plot(np.arange(20) + 1, perform_imp[inds], 'd', mec='C2', mfc='w', ms=7) plt.errorbar(23.6, dist.mean(), dist.std() / np.sqrt(20), fmt='^', color='C2', ms=10, lw=1.5, capsize=3) plt.errorbar(24.4, perform_imp.mean(), perform_imp.std() / np.sqrt(20), fmt='d', mec='C2', mfc='w', color='C2', ms=10, lw=1.5, capsize=3) plt.plot([0, 28], [0,0], 'k--', zorder=-5) plt.xlim([0, 25]) plt.xlabel('Subjects') plt.ylabel('Improvement \n (percent correct)')