def test_transform_data(): """Test applying linear (time) transform to data""" # make up some data n_sensors, n_vertices, n_times = 10, 20, 4 kernel = rng.randn(n_vertices, n_sensors) sens_data = rng.randn(n_sensors, n_times) vertices = np.arange(n_vertices) data = np.dot(kernel, sens_data) for idx, tmin_idx, tmax_idx in\ zip([None, np.arange(n_vertices // 2, n_vertices)], [None, 1], [None, 3]): if idx is None: idx_use = slice(None, None) else: idx_use = idx data_f, _ = _my_trans(data[idx_use, tmin_idx:tmax_idx]) for stc_data in (data, (kernel, sens_data)): stc = VolSourceEstimate(stc_data, vertices=vertices, tmin=0., tstep=1.) stc_data_t = stc.transform_data(_my_trans, idx=idx, tmin_idx=tmin_idx, tmax_idx=tmax_idx) assert_allclose(data_f, stc_data_t)
def test_plot_volume_source_estimates(): """Test interactive plotting of volume source estimates.""" forward = read_forward_solution(fwd_fname) sample_src = forward['src'] vertices = [s['vertno'] for s in sample_src] n_verts = sum(len(v) for v in vertices) n_time = 2 data = np.random.RandomState(0).rand(n_verts, n_time) vol_stc = VolSourceEstimate(data, vertices, 1, 1) vol_vec_stc = VolVectorSourceEstimate( np.tile(vol_stc.data[:, np.newaxis], (1, 3, 1)), vol_stc.vertices, 0, 1) for mode, stc in zip(['glass_brain', 'stat_map'], (vol_stc, vol_vec_stc)): with pytest.warns(None): # sometimes get scalars/index warning fig = stc.plot(sample_src, subject='sample', subjects_dir=subjects_dir, mode=mode) # [ax_time, ax_y, ax_x, ax_z] for ax_idx in [0, 2, 3, 4]: _fake_click(fig, fig.axes[ax_idx], (0.3, 0.5)) fig.canvas.key_press_event('left') fig.canvas.key_press_event('shift+right') with pytest.raises(ValueError, match='must be one of'): vol_stc.plot(sample_src, 'sample', subjects_dir, mode='abcd') vertices.append([]) surface_stc = SourceEstimate(data, vertices, 1, 1) with pytest.raises(ValueError, match='Only Vol'): plot_volume_source_estimates(surface_stc, sample_src, 'sample', subjects_dir) with pytest.raises(ValueError, match='Negative colormap limits'): vol_stc.plot(sample_src, 'sample', subjects_dir, clim=dict(lims=[-1, 2, 3], kind='value'))
def test_transform_data(): """Test applying linear (time) transform to data.""" # make up some data n_sensors, n_vertices, n_times = 10, 20, 4 kernel = rng.randn(n_vertices, n_sensors) sens_data = rng.randn(n_sensors, n_times) vertices = np.arange(n_vertices) data = np.dot(kernel, sens_data) for idx, tmin_idx, tmax_idx in\ zip([None, np.arange(n_vertices // 2, n_vertices)], [None, 1], [None, 3]): if idx is None: idx_use = slice(None, None) else: idx_use = idx data_f, _ = _my_trans(data[idx_use, tmin_idx:tmax_idx]) for stc_data in (data, (kernel, sens_data)): stc = VolSourceEstimate(stc_data, vertices=vertices, tmin=0., tstep=1.) stc_data_t = stc.transform_data(_my_trans, idx=idx, tmin_idx=tmin_idx, tmax_idx=tmax_idx) assert_allclose(data_f, stc_data_t) # bad sens_data sens_data = sens_data[..., np.newaxis] with pytest.raises(ValueError, match='sensor data must have 2'): VolSourceEstimate((kernel, sens_data), vertices)
def test_transform_data(): """Test applying linear (time) transform to data""" # make up some data n_sensors, n_vertices, n_times = 10, 20, 4 kernel = np.random.randn(n_vertices, n_sensors) sens_data = np.random.randn(n_sensors, n_times) vertices = np.arange(n_vertices) data = np.dot(kernel, sens_data) for idx, tmin_idx, tmax_idx in\ zip([None, np.arange(n_vertices // 2, n_vertices)], [None, 1], [None, 3]): if idx is None: idx_use = slice(None, None) else: idx_use = idx data_f, _ = _my_trans(data[idx_use, tmin_idx:tmax_idx]) for stc_data in (data, (kernel, sens_data)): stc = VolSourceEstimate(stc_data, vertices=vertices, tmin=0., tstep=1.) stc_data_t = stc.transform_data(_my_trans, idx=idx, tmin_idx=tmin_idx, tmax_idx=tmax_idx) assert_allclose(data_f, stc_data_t)
def test_get_peak(): """Test peak getter.""" n_vert, n_times = 10, 5 vertices = [np.arange(n_vert, dtype=np.int), np.empty(0, dtype=np.int)] data = rng.randn(n_vert, n_times) stc_surf = SourceEstimate(data, vertices=vertices, tmin=0, tstep=1, subject='sample') stc_vol = VolSourceEstimate(data, vertices=vertices[0], tmin=0, tstep=1, subject='sample') # Versions with only one time point stc_surf_1 = SourceEstimate(data[:, :1], vertices=vertices, tmin=0, tstep=1, subject='sample') stc_vol_1 = VolSourceEstimate(data[:, :1], vertices=vertices[0], tmin=0, tstep=1, subject='sample') for ii, stc in enumerate([stc_surf, stc_vol, stc_surf_1, stc_vol_1]): pytest.raises(ValueError, stc.get_peak, tmin=-100) pytest.raises(ValueError, stc.get_peak, tmax=90) pytest.raises(ValueError, stc.get_peak, tmin=0.002, tmax=0.001) vert_idx, time_idx = stc.get_peak() vertno = np.concatenate(stc.vertices) if ii in [0, 2] else stc.vertices assert (vert_idx in vertno) assert (time_idx in stc.times) data_idx, time_idx = stc.get_peak(vert_as_index=True, time_as_index=True) assert_equal(data_idx, np.argmax(np.abs(stc.data[:, time_idx]))) assert_equal(time_idx, np.argmax(np.abs(stc.data[data_idx, :])))
def test_plot_volume_source_estimates_morph(): """Test interactive plotting of volume source estimates with morph.""" forward = read_forward_solution(fwd_fname) sample_src = forward['src'] vertices = [s['vertno'] for s in sample_src] n_verts = sum(len(v) for v in vertices) n_time = 2 data = np.random.RandomState(0).rand(n_verts, n_time) stc = VolSourceEstimate(data, vertices, 1, 1) sample_src[0]['subject_his_id'] = 'sample' # old src morph = compute_source_morph(sample_src, 'sample', 'fsaverage', zooms=5, subjects_dir=subjects_dir) initial_pos = (-0.05, -0.01, -0.006) with pytest.warns(None): # sometimes get scalars/index warning with catch_logging() as log: stc.plot(morph, subjects_dir=subjects_dir, mode='glass_brain', initial_pos=initial_pos, verbose=True) log = log.getvalue() assert 't = 1.000 s' in log assert '(-52.0, -8.0, -7.0) mm' in log with pytest.raises(ValueError, match='Allowed values are'): stc.plot(sample_src, 'sample', subjects_dir, mode='abcd') vertices.append([]) surface_stc = SourceEstimate(data, vertices, 1, 1) with pytest.raises(TypeError, match='an instance of VolSourceEstimate'): plot_volume_source_estimates(surface_stc, sample_src, 'sample', subjects_dir) with pytest.raises(ValueError, match='Negative colormap limits'): stc.plot(sample_src, 'sample', subjects_dir, clim=dict(lims=[-1, 2, 3], kind='value'))
def _export_to_vol_stc(inv_op, subject=None): if not hasattr(inv_op, 'pmap'): raise AttributeError('Run the inversion algorithm first!!') pmaps = inv_op.pmap est_n_dips = inv_op.est_n_dips if len(inv_op.forward['src']) == 2: vertno = [ inv_op.forward['src'][0]['vertno'], inv_op.forward['src'][1]['vertno'] ] elif len(inv_op.forward['src']) == 1: vertno = inv_op.forward['src'][0]['vertno'] else: raise ValueError nv_tot = inv_op.forward['nsource'] pmap_tot = np.zeros([len(pmaps), nv_tot]) for it, bl in enumerate(pmaps): if est_n_dips[it] > 0: pmap_tot[it] = np.sum(bl, axis=0) vol_stc = VolSourceEstimate(data=pmap_tot.T, vertices=vertno, tmin=1, tstep=1, subject=subject) return vol_stc
def test_vol_mask(): """Test extraction of volume mask.""" src = read_source_spaces(fname_vsrc) mask = _get_vol_mask(src) # Let's use an alternative way that should be equivalent vertices = src[0]['vertno'] n_vertices = len(vertices) data = (1 + np.arange(n_vertices))[:, np.newaxis] stc_tmp = VolSourceEstimate(data, vertices, tmin=0., tstep=1.) img = stc_tmp.as_volume(src, mri_resolution=False) img_data = img.get_data()[:, :, :, 0].T mask_nib = (img_data != 0) assert_array_equal(img_data[mask_nib], data[:, 0]) assert_array_equal(np.where(mask_nib.ravel())[0], src[0]['vertno']) assert_array_equal(mask, mask_nib) assert_array_equal(img_data.shape, mask.shape)
def plot_max_amplitude_data(fwdmag, stcdata, tmin, tstep, subject, method='mft'): print "##### Attempting to plot max. amplitude data:" fig = plt.figure() iblck = -1 offsets = np.append([0], [s['nuse'] for s in fwdmag['src']]) for s in fwdmag['src']: iblck = iblck + 1 stc = VolSourceEstimate(stcdata[offsets[iblck]:offsets[iblck] + offsets[iblck + 1], :], vertices=s['vertno'], tmin=tmin, tstep=tstep, subject=subject) # View activation time-series plt.xlim((1e3 * np.min(stc.times), 1e3 * np.max(stc.times))) plt.ylim((0, np.max(stcdata))) plt.plot(1e3 * stc.times, np.max(stc.data, axis=0), label=(('lh', 'rh'))[iblck]) plt.xlabel('time (ms)') plt.ylabel('%s value' % method) plt.savefig('testfig' + "{0:0=2d}".format(iblck) + '.png') plt.close()
def test_notify_array_source_estimate(): """Test that modifying the stc data removes the kernel and sensor data""" # make up some data n_sensors, n_vertices, n_times = 10, 20, 4 kernel = np.random.randn(n_vertices, n_sensors) sens_data = np.random.randn(n_sensors, n_times) vertices = np.arange(n_vertices) stc = VolSourceEstimate((kernel, sens_data), vertices=vertices, tmin=0., tstep=1.) assert_true(stc._data is None) assert_true(stc._kernel is not None) assert_true(stc._sens_data is not None) # now modify the data in some way data_half = stc.data[:, n_times / 2:] data_half[0] = 1.0 data_half.fill(1.0) # the kernel and sensor data can no longer be used: they have been removed assert_true(stc._kernel is None) assert_true(stc._sens_data is None)
def test_get_peak(): """Test peak getter """ n_vert, n_times = 10, 5 vertices = [np.arange(n_vert, dtype=np.int), np.empty(0, dtype=np.int)] data = np.random.randn(n_vert, n_times) stc_surf = SourceEstimate(data, vertices=vertices, tmin=0, tstep=1, subject='sample') stc_vol = VolSourceEstimate(data, vertices=vertices[0], tmin=0, tstep=1, subject='sample') for ii, stc in enumerate([stc_surf, stc_vol]): assert_raises(ValueError, stc.get_peak, tmin=-100) assert_raises(ValueError, stc.get_peak, tmax=90) assert_raises(ValueError, stc.get_peak, tmin=0.002, tmax=0.001) vert_idx, time_idx = stc.get_peak() vertno = np.concatenate(stc.vertices) if ii == 0 else stc.vertices assert_true(vert_idx in vertno) assert_true(time_idx in stc.times) ch_idx, time_idx = stc.get_peak(vert_as_index=True, time_as_index=True) assert_true(vert_idx < stc.data.shape[0]) assert_true(time_idx < len(stc.times))
def test_as_data_frame(): """Test stc Pandas exporter""" n_vert, n_times = 10, 5 vertices = [np.arange(n_vert, dtype=np.int), np.empty(0, dtype=np.int)] data = np.random.randn(n_vert, n_times) stc_surf = SourceEstimate(data, vertices=vertices, tmin=0, tstep=1, subject='sample') stc_vol = VolSourceEstimate(data, vertices=vertices[0], tmin=0, tstep=1, subject='sample') for stc in [stc_surf, stc_vol]: assert_raises(ValueError, stc.as_data_frame, index=['foo', 'bar']) for ncat, ind in zip([1, 0], ['time', ['subject', 'time']]): df = stc.as_data_frame(index=ind) assert_true(df.index.names == ind if isinstance(ind, list) else [ind]) assert_array_equal(df.values.T[ncat:], stc.data) # test that non-indexed data were present as categorial variables assert_true( all([ c in ['time', 'subject'] for c in df.reset_index().columns ][:2]))
def test_volume_stc(): """Test volume STCs.""" tempdir = _TempDir() N = 100 data = np.arange(N)[:, np.newaxis] datas = [data, data, np.arange(2)[:, np.newaxis]] vertno = np.arange(N) vertnos = [vertno, vertno[:, np.newaxis], np.arange(2)[:, np.newaxis]] vertno_reads = [vertno, vertno, np.arange(2)] for data, vertno, vertno_read in zip(datas, vertnos, vertno_reads): stc = VolSourceEstimate(data, vertno, 0, 1) fname_temp = op.join(tempdir, 'temp-vl.stc') stc_new = stc for _ in range(2): stc_new.save(fname_temp) stc_new = read_source_estimate(fname_temp) assert (isinstance(stc_new, VolSourceEstimate)) assert_array_equal(vertno_read, stc_new.vertices) assert_array_almost_equal(stc.data, stc_new.data) # now let's actually read a MNE-C processed file stc = read_source_estimate(fname_vol, 'sample') assert (isinstance(stc, VolSourceEstimate)) assert ('sample' in repr(stc)) stc_new = stc pytest.raises(ValueError, stc.save, fname_vol, ftype='whatever') for ftype in ['w', 'h5']: for _ in range(2): fname_temp = op.join(tempdir, 'temp-vol.%s' % ftype) stc_new.save(fname_temp, ftype=ftype) stc_new = read_source_estimate(fname_temp) assert (isinstance(stc_new, VolSourceEstimate)) assert_array_equal(stc.vertices, stc_new.vertices) assert_array_almost_equal(stc.data, stc_new.data)
def test_plot_volume_source_estimates(mode, stype, init_t, want_t, init_p, want_p): """Test interactive plotting of volume source estimates.""" forward = read_forward_solution(fwd_fname) sample_src = forward['src'] if init_p is not None: init_p = np.array(init_p) / 1000. vertices = [s['vertno'] for s in sample_src] n_verts = sum(len(v) for v in vertices) n_time = 2 data = np.random.RandomState(0).rand(n_verts, n_time) if stype == 'vec': stc = VolVectorSourceEstimate( np.tile(data[:, np.newaxis], (1, 3, 1)), vertices, 1, 1) else: assert stype == 's' stc = VolSourceEstimate(data, vertices, 1, 1) with pytest.warns(None): # sometimes get scalars/index warning with catch_logging() as log: fig = stc.plot( sample_src, subject='sample', subjects_dir=subjects_dir, mode=mode, initial_time=init_t, initial_pos=init_p, verbose=True) log = log.getvalue() want_str = 't = %0.3f s' % want_t assert want_str in log, (want_str, init_t) want_str = '(%0.1f, %0.1f, %0.1f) mm' % want_p assert want_str in log, (want_str, init_p) for ax_idx in [0, 2, 3, 4]: _fake_click(fig, fig.axes[ax_idx], (0.3, 0.5)) fig.canvas.key_press_event('left') fig.canvas.key_press_event('shift+right')
def test_plot_volume_source_estimates(): """Test interactive plotting of volume source estimates.""" forward = read_forward_solution(fwd_fname) sample_src = forward['src'] vertices = [s['vertno'] for s in sample_src] n_verts = sum(len(v) for v in vertices) n_time = 2 data = np.random.RandomState(0).rand(n_verts, n_time) vol_stc = VolSourceEstimate(data, vertices, 1, 1) for mode in ['glass_brain', 'stat_map']: with pytest.warns(None): # sometimes get scalars/index warning fig = vol_stc.plot(sample_src, subject='sample', subjects_dir=subjects_dir, mode=mode) # [ax_time, ax_y, ax_x, ax_z] for ax_idx in [0, 2, 3, 4]: _fake_click(fig, fig.axes[ax_idx], (0.3, 0.5)) with pytest.raises(ValueError, match='must be one of'): vol_stc.plot(sample_src, 'sample', subjects_dir, mode='abcd') vertices.append([]) surface_stc = SourceEstimate(data, vertices, 1, 1) with pytest.raises(ValueError, match='Only Vol'): plot_volume_source_estimates(surface_stc, sample_src, 'sample', subjects_dir) with pytest.raises(ValueError, match='Negative colormap limits'): vol_stc.plot(sample_src, 'sample', subjects_dir, clim=dict(lims=[-1, 2, 3], kind='value'))
def test_plot_volume_source_estimates(mode, stype, init_t, want_t, init_p, want_p, bg_img): """Test interactive plotting of volume source estimates.""" forward = read_forward_solution(fwd_fname) sample_src = forward['src'] if init_p is not None: init_p = np.array(init_p) / 1000. vertices = [s['vertno'] for s in sample_src] n_verts = sum(len(v) for v in vertices) n_time = 2 data = np.random.RandomState(0).rand(n_verts, n_time) if stype == 'vec': stc = VolVectorSourceEstimate(np.tile(data[:, np.newaxis], (1, 3, 1)), vertices, 1, 1) else: assert stype == 's' stc = VolSourceEstimate(data, vertices, 1, 1) # sometimes get scalars/index warning with _record_warnings(): with catch_logging() as log: fig = stc.plot(sample_src, subject='sample', subjects_dir=subjects_dir, mode=mode, initial_time=init_t, initial_pos=init_p, bg_img=bg_img, verbose=True) log = log.getvalue() want_str = 't = %0.3f s' % want_t assert want_str in log, (want_str, init_t) want_str = '(%0.1f, %0.1f, %0.1f) mm' % want_p assert want_str in log, (want_str, init_p) for ax_idx in [0, 2, 3, 4]: _fake_click(fig, fig.axes[ax_idx], (0.3, 0.5)) fig.canvas.key_press_event('left') fig.canvas.key_press_event('shift+right') if bg_img is not None: with pytest.raises(FileNotFoundError, match='MRI file .* not found'): stc.plot(sample_src, subject='sample', subjects_dir=subjects_dir, mode='stat_map', bg_img='junk.mgz') use_ax = None for ax in fig.axes: if ax.get_xlabel().startswith('Time'): use_ax = ax break assert use_ax is not None label = use_ax.get_legend().get_texts()[0].get_text() assert re.match('[0-9]*', label) is not None, label
def test_save_vol_stc_as_nifti(): """Save the stc as a nifti file and export.""" import nibabel as nib tempdir = _TempDir() with warnings.catch_warnings(record=True): warnings.simplefilter('always') src = read_source_spaces(fname_vsrc) vol_fname = op.join(tempdir, 'stc.nii.gz') # now let's actually read a MNE-C processed file stc = read_source_estimate(fname_vol, 'sample') assert_true(isinstance(stc, VolSourceEstimate)) stc.save_as_volume(vol_fname, src, dest='surf', mri_resolution=False) with warnings.catch_warnings(record=True): # nib<->numpy img = nib.load(vol_fname) assert_true(img.shape == src[0]['shape'] + (len(stc.times), )) with warnings.catch_warnings(record=True): # nib<->numpy t1_img = nib.load(fname_t1) stc.save_as_volume(op.join(tempdir, 'stc.nii.gz'), src, dest='mri', mri_resolution=True) with warnings.catch_warnings(record=True): # nib<->numpy img = nib.load(vol_fname) assert_true(img.shape == t1_img.shape + (len(stc.times), )) assert_allclose(img.affine, t1_img.affine, atol=1e-5) # export without saving img = stc.as_volume(src, dest='mri', mri_resolution=True) assert_true(img.shape == t1_img.shape + (len(stc.times), )) assert_allclose(img.affine, t1_img.affine, atol=1e-5) src = SourceSpaces([src[0], src[0]]) stc = VolSourceEstimate(np.r_[stc.data, stc.data], [stc.vertices, stc.vertices], tmin=stc.tmin, tstep=stc.tstep) img = stc.as_volume(src, dest='mri', mri_resolution=False) assert_true(img.shape == src[0]['shape'] + (len(stc.times), ))
def test_volume_stc(): """Test volume STCs """ N = 100 data = np.arange(N)[:, np.newaxis] datas = [data, data, np.arange(2)[:, np.newaxis]] vertno = np.arange(N) vertnos = [vertno, vertno[:, np.newaxis], np.arange(2)[:, np.newaxis]] vertno_reads = [vertno, vertno, np.arange(2)] for data, vertno, vertno_read in zip(datas, vertnos, vertno_reads): stc = VolSourceEstimate(data, vertno, 0, 1) fname_temp = op.join(tempdir, 'temp-vl.stc') stc_new = stc for _ in xrange(2): stc_new.save(fname_temp) stc_new = read_source_estimate(fname_temp) assert_true(isinstance(stc_new, VolSourceEstimate)) assert_array_equal(vertno_read, stc_new.vertno) assert_array_almost_equal(stc.data, stc_new.data) # now let's actually read a MNE-C processed file stc = read_source_estimate(fname_vol, 'sample') assert_true(isinstance(stc, VolSourceEstimate)) assert_true('sample' in repr(stc)) stc_new = stc assert_raises(ValueError, stc.save, fname_vol, ftype='whatever') for _ in xrange(2): fname_temp = op.join(tempdir, 'temp-vol.w') stc_new.save(fname_temp, ftype='w') stc_new = read_source_estimate(fname_temp) assert_true(isinstance(stc_new, VolSourceEstimate)) assert_array_equal(stc.vertno, stc_new.vertno) assert_array_almost_equal(stc.data, stc_new.data) # save the stc as a nifti file and export try: import nibabel as nib src = read_source_spaces(fname_vsrc) vol_fname = op.join(tempdir, 'stc.nii.gz') stc.save_as_volume(vol_fname, src, dest='surf', mri_resolution=False) img = nib.load(vol_fname) assert_true(img.shape == src[0]['shape'] + (len(stc.times),)) t1_img = nib.load(fname_t1) stc.save_as_volume(op.join(tempdir, 'stc.nii.gz'), src, dest='mri', mri_resolution=True) img = nib.load(vol_fname) assert_true(img.shape == t1_img.shape + (len(stc.times),)) assert_array_almost_equal(img.get_affine(), t1_img.get_affine(), decimal=5) # export without saving img = stc.as_volume(src, dest='mri', mri_resolution=True) assert_true(img.shape == t1_img.shape + (len(stc.times),)) assert_array_almost_equal(img.get_affine(), t1_img.get_affine(), decimal=5) except ImportError: print 'Save as nifti test skipped, needs NiBabel'
def test_save_vol_stc_as_nifti(tmpdir): """Save the stc as a nifti file and export.""" import nibabel as nib src = read_source_spaces(fname_vsrc) vol_fname = tmpdir.join('stc.nii.gz') # now let's actually read a MNE-C processed file stc = read_source_estimate(fname_vol, 'sample') assert (isinstance(stc, VolSourceEstimate)) stc.save_as_volume(vol_fname, src, dest='surf', mri_resolution=False) with pytest.warns(None): # nib<->numpy img = nib.load(str(vol_fname)) assert (img.shape == src[0]['shape'] + (len(stc.times), )) with pytest.warns(None): # nib<->numpy t1_img = nib.load(fname_t1) stc.save_as_volume(tmpdir.join('stc.nii.gz'), src, dest='mri', mri_resolution=True) with pytest.warns(None): # nib<->numpy img = nib.load(str(vol_fname)) assert (img.shape == t1_img.shape + (len(stc.times), )) assert_allclose(img.affine, t1_img.affine, atol=1e-5) # export without saving img = stc.as_volume(src, dest='mri', mri_resolution=True) assert (img.shape == t1_img.shape + (len(stc.times), )) assert_allclose(img.affine, t1_img.affine, atol=1e-5) src = SourceSpaces([src[0], src[0]]) stc = VolSourceEstimate(np.r_[stc.data, stc.data], [stc.vertices, stc.vertices], tmin=stc.tmin, tstep=stc.tstep, subject='sample') img = stc.as_volume(src, dest='mri', mri_resolution=False) assert (img.shape == src[0]['shape'] + (len(stc.times), ))
def test_volume_stc(tmpdir): """Test volume STCs.""" N = 100 data = np.arange(N)[:, np.newaxis] datas = [ data, data, np.arange(2)[:, np.newaxis], np.arange(6).reshape(2, 3, 1) ] vertno = np.arange(N) vertnos = [ vertno, vertno[:, np.newaxis], np.arange(2)[:, np.newaxis], np.arange(2) ] vertno_reads = [vertno, vertno, np.arange(2), np.arange(2)] for data, vertno, vertno_read in zip(datas, vertnos, vertno_reads): if data.ndim in (1, 2): stc = VolSourceEstimate(data, vertno, 0, 1) ext = 'stc' klass = VolSourceEstimate else: assert data.ndim == 3 stc = VolVectorSourceEstimate(data, vertno, 0, 1) ext = 'h5' klass = VolVectorSourceEstimate fname_temp = tmpdir.join('temp-vl.' + ext) stc_new = stc for _ in range(2): stc_new.save(fname_temp) stc_new = read_source_estimate(fname_temp) assert isinstance(stc_new, klass) assert_array_equal(vertno_read, stc_new.vertices) assert_array_almost_equal(stc.data, stc_new.data) # now let's actually read a MNE-C processed file stc = read_source_estimate(fname_vol, 'sample') assert (isinstance(stc, VolSourceEstimate)) assert ('sample' in repr(stc)) stc_new = stc pytest.raises(ValueError, stc.save, fname_vol, ftype='whatever') for ftype in ['w', 'h5']: for _ in range(2): fname_temp = tmpdir.join('temp-vol.%s' % ftype) stc_new.save(fname_temp, ftype=ftype) stc_new = read_source_estimate(fname_temp) assert (isinstance(stc_new, VolSourceEstimate)) assert_array_equal(stc.vertices, stc_new.vertices) assert_array_almost_equal(stc.data, stc_new.data)
def test_save_vol_stc_as_nifti(): """Save the stc as a nifti file and export.""" import nibabel as nib tempdir = _TempDir() src = read_source_spaces(fname_vsrc) vol_fname = op.join(tempdir, 'stc.nii.gz') # now let's actually read a MNE-C processed file stc = read_source_estimate(fname_vol, 'sample') assert (isinstance(stc, VolSourceEstimate)) stc.save_as_volume(vol_fname, src, dest='surf', mri_resolution=False) with pytest.warns(None): # nib<->numpy img = nib.load(vol_fname) assert (img.shape == src[0]['shape'] + (len(stc.times),)) with pytest.warns(None): # nib<->numpy t1_img = nib.load(fname_t1) stc.save_as_volume(op.join(tempdir, 'stc.nii.gz'), src, dest='mri', mri_resolution=True) with pytest.warns(None): # nib<->numpy img = nib.load(vol_fname) assert (img.shape == t1_img.shape + (len(stc.times),)) assert_allclose(img.affine, t1_img.affine, atol=1e-5) # export without saving img = stc.as_volume(src, dest='mri', mri_resolution=True) assert (img.shape == t1_img.shape + (len(stc.times),)) assert_allclose(img.affine, t1_img.affine, atol=1e-5) src = SourceSpaces([src[0], src[0]]) stc = VolSourceEstimate(np.r_[stc.data, stc.data], [stc.vertices, stc.vertices], tmin=stc.tmin, tstep=stc.tstep) img = stc.as_volume(src, dest='mri', mri_resolution=False) assert (img.shape == src[0]['shape'] + (len(stc.times),))
def test_to_data_frame(): """Test stc Pandas exporter.""" n_vert, n_times = 10, 5 vertices = [np.arange(n_vert, dtype=np.int), np.empty(0, dtype=np.int)] data = rng.randn(n_vert, n_times) stc_surf = SourceEstimate(data, vertices=vertices, tmin=0, tstep=1, subject='sample') stc_vol = VolSourceEstimate(data, vertices=vertices[0], tmin=0, tstep=1, subject='sample') for stc in [stc_surf, stc_vol]: df = stc.to_data_frame() # test data preservation (first 2 dataframe elements are subj & time) assert_array_equal(df.values.T[2:], stc.data) # test long format df_long = stc.to_data_frame(long_format=True) assert(len(df_long) == stc.data.size) expected = ('subject', 'time', 'source', 'value') assert set(expected) == set(df_long.columns)
def plot_max_amplitude_data(fwdmag, stcdata, tmin, tstep, subject, method='mft'): """ Plot max(|cdv(src)|) vs. time and src-space(s) Parameters ---------- fwdmag: forward solution stcdata: stc with ||cdv|| (point sequence as in fwdmag['source_rr']) tmin, tstep, subject: passed to mne.VolSourceEstimate() method: used as y-axis label """ print("##### Attempting to plot max. amplitude data:") fig = plt.figure() offsets = [0] for s in fwdmag['src']: offsets = np.append(offsets, [offsets[-1] + s['nuse']]) for isrc, s in enumerate(fwdmag['src']): stc = VolSourceEstimate(stcdata[offsets[isrc]:offsets[isrc + 1], :], vertices=s['vertno'], tmin=tmin, tstep=tstep, subject=subject) # View activation time-series plt.xlim((1e3 * np.min(stc.times), 1e3 * np.max(stc.times))) plt.ylim((0, np.max(stcdata))) plt.plot(1e3 * stc.times, np.max(stc.data, axis=0)) # label=(('lh', 'rh'))[isrc]) plt.xlabel('time (ms)') plt.ylabel('%s value' % method) # plt.savefig('testfig'+"{0:0=2d}".format(isrc)+'.png') plt.title('max(|cdv(src)|) vs. time and src-space(s)', loc='center') plt.savefig('testfig_cdvmaxsrc.png') plt.close()
def test_volume_source_morph_round_trip(tmpdir, subject_from, subject_to, lower, upper): """Test volume source estimate morph round-trips well.""" import nibabel as nib from nibabel.processing import resample_from_to src = dict() if 'sample' in (subject_from, subject_to): src['sample'] = mne.read_source_spaces(fname_vol) src['sample'][0]['subject_his_id'] = 'sample' assert src['sample'][0]['nuse'] == 4157 if 'fsaverage' in (subject_from, subject_to): # Created to save space with: # # bem = op.join(op.dirname(mne.__file__), 'data', 'fsaverage', # 'fsaverage-inner_skull-bem.fif') # src_fsaverage = mne.setup_volume_source_space( # 'fsaverage', pos=7., bem=bem, mindist=0, # subjects_dir=subjects_dir, add_interpolator=False) # mne.write_source_spaces(fname_fs_vol, src_fsaverage, overwrite=True) # # For speed we do it without the interpolator because it's huge. src['fsaverage'] = mne.read_source_spaces(fname_fs_vol) src['fsaverage'][0].update(vol_dims=np.array([23, 29, 25]), seg_name='brain') _add_interpolator(src['fsaverage'], True) assert src['fsaverage'][0]['nuse'] == 6379 src_to, src_from = src[subject_to], src[subject_from] del src # No SDR just for speed once everything works kwargs = dict(niter_sdr=(), niter_affine=(1, ), subjects_dir=subjects_dir, verbose=True) morph_from_to = compute_source_morph(src=src_from, src_to=src_to, subject_to=subject_to, **kwargs) morph_to_from = compute_source_morph(src=src_to, src_to=src_from, subject_to=subject_from, **kwargs) use = np.linspace(0, src_from[0]['nuse'] - 1, 10).round().astype(int) stc_from = VolSourceEstimate( np.eye(src_from[0]['nuse'])[:, use], [src_from[0]['vertno']], 0, 1) stc_from_rt = morph_to_from.apply(morph_from_to.apply(stc_from)) maxs = np.argmax(stc_from_rt.data, axis=0) src_rr = src_from[0]['rr'][src_from[0]['vertno']] dists = 1000 * np.linalg.norm(src_rr[use] - src_rr[maxs], axis=1) mu = np.mean(dists) assert lower <= mu < upper # fsaverage=7.97; 25.4 without src_ras_t fix # check that pre_affine is close to identity when subject_to==subject_from if subject_to == subject_from: for morph in (morph_to_from, morph_from_to): assert_allclose(morph.pre_affine.affine, np.eye(4), atol=1e-2) # check that power is more or less preserved ratio = stc_from.data.size / stc_from_rt.data.size limits = ratio * np.array([1, 1.2]) stc_from.crop(0, 0)._data.fill(1.) stc_from_rt = morph_to_from.apply(morph_from_to.apply(stc_from)) assert_power_preserved(stc_from, stc_from_rt, limits=limits) # before and after morph, check the proportion of vertices # that are inside and outside the brainmask.mgz brain = nib.load(op.join(subjects_dir, subject_from, 'mri', 'brain.mgz')) mask = _get_img_fdata(brain) > 0 if subject_from == subject_to == 'sample': for stc in [stc_from, stc_from_rt]: img = stc.as_volume(src_from, mri_resolution=True) img = nib.Nifti1Image(_get_img_fdata(img)[:, :, :, 0], img.affine) img = _get_img_fdata(resample_from_to(img, brain, order=1)) assert img.shape == mask.shape in_ = img[mask].astype(bool).mean() out = img[~mask].astype(bool).mean() assert 0.97 < in_ < 0.98 assert out < 0.02
def test_volume_source_morph(tmpdir): """Test volume source estimate morph, special cases and exceptions.""" import nibabel as nib inverse_operator_vol = read_inverse_operator(fname_inv_vol) stc_vol = read_source_estimate(fname_vol_w, 'sample') # check for invalid input type with pytest.raises(TypeError, match='src must be'): compute_source_morph(src=42) # check for raising an error if neither # inverse_operator_vol['src'][0]['subject_his_id'] nor subject_from is set, # but attempting to perform a volume morph src = inverse_operator_vol['src'] assert src._subject is None # already None on disk (old!) with pytest.raises(ValueError, match='subject_from could not be inferred'): with pytest.warns(RuntimeWarning, match='recommend regenerating'): compute_source_morph(src=src, subjects_dir=subjects_dir) # check infer subject_from from src[0]['subject_his_id'] src[0]['subject_his_id'] = 'sample' with pytest.raises(ValueError, match='Inter-hemispheric morphing'): compute_source_morph(src=src, subjects_dir=subjects_dir, xhemi=True) with pytest.raises(ValueError, match='Only surface.*sparse morph'): compute_source_morph(src=src, sparse=True, subjects_dir=subjects_dir) # terrible quality but fast zooms = 20 kwargs = dict(zooms=zooms, niter_sdr=(1,), niter_affine=(1,)) source_morph_vol = compute_source_morph( subjects_dir=subjects_dir, src=fname_inv_vol, subject_from='sample', **kwargs) shape = (13,) * 3 # for the given zooms assert source_morph_vol.subject_from == 'sample' # the brain used in sample data has shape (255, 255, 255) assert tuple(source_morph_vol.sdr_morph.domain_shape) == shape assert tuple(source_morph_vol.pre_affine.domain_shape) == shape # proofs the above assert_array_equal(source_morph_vol.zooms, (zooms,) * 3) # assure proper src shape mri_size = (src[0]['mri_height'], src[0]['mri_depth'], src[0]['mri_width']) assert source_morph_vol.src_data['src_shape_full'] == mri_size fwd = read_forward_solution(fname_fwd_vol) fwd['src'][0]['subject_his_id'] = 'sample' # avoid further warnings source_morph_vol = compute_source_morph( fwd['src'], 'sample', 'sample', subjects_dir=subjects_dir, **kwargs) # check wrong subject_to with pytest.raises(IOError, match='cannot read file'): compute_source_morph(fwd['src'], 'sample', '42', subjects_dir=subjects_dir) # two different ways of saving source_morph_vol.save(tmpdir.join('vol')) # check loading source_morph_vol_r = read_source_morph(tmpdir.join('vol-morph.h5')) # check for invalid file name handling () with pytest.raises(IOError, match='not found'): read_source_morph(tmpdir.join('42')) # check morph stc_vol_morphed = source_morph_vol.apply(stc_vol) # old way, verts do not match assert not np.array_equal(stc_vol_morphed.vertices[0], stc_vol.vertices[0]) # vector stc_vol_vec = VolVectorSourceEstimate( np.tile(stc_vol.data[:, np.newaxis], (1, 3, 1)), stc_vol.vertices, 0, 1) stc_vol_vec_morphed = source_morph_vol.apply(stc_vol_vec) assert isinstance(stc_vol_vec_morphed, VolVectorSourceEstimate) for ii in range(3): assert_allclose(stc_vol_vec_morphed.data[:, ii], stc_vol_morphed.data) # check output as NIfTI assert isinstance(source_morph_vol.apply(stc_vol_vec, output='nifti2'), nib.Nifti2Image) # check for subject_from mismatch source_morph_vol_r.subject_from = '42' with pytest.raises(ValueError, match='subject_from must match'): source_morph_vol_r.apply(stc_vol_morphed) # check if nifti is in grid morph space with voxel_size == spacing img_morph_res = source_morph_vol.apply(stc_vol, output='nifti1') # assure morph spacing assert isinstance(img_morph_res, nib.Nifti1Image) assert img_morph_res.header.get_zooms()[:3] == (zooms,) * 3 # assure src shape img_mri_res = source_morph_vol.apply(stc_vol, output='nifti1', mri_resolution=True) assert isinstance(img_mri_res, nib.Nifti1Image) assert (img_mri_res.shape == (src[0]['mri_height'], src[0]['mri_depth'], src[0]['mri_width']) + (img_mri_res.shape[3],)) # check if nifti is defined resolution with voxel_size == (5., 5., 5.) img_any_res = source_morph_vol.apply(stc_vol, output='nifti1', mri_resolution=(5., 5., 5.)) assert isinstance(img_any_res, nib.Nifti1Image) assert img_any_res.header.get_zooms()[:3] == (5., 5., 5.) # check if morph outputs correct data assert isinstance(stc_vol_morphed, VolSourceEstimate) # check if loaded and saved objects contain the same assert (all([read == saved for read, saved in zip(sorted(source_morph_vol_r.__dict__), sorted(source_morph_vol.__dict__))])) # check __repr__ assert 'volume' in repr(source_morph_vol) # check Nifti2Image assert isinstance( source_morph_vol.apply(stc_vol, mri_resolution=True, mri_space=True, output='nifti2'), nib.Nifti2Image) # Degenerate conditions with pytest.raises(TypeError, match='output must be'): source_morph_vol.apply(stc_vol, output=1) with pytest.raises(ValueError, match='subject_from does not match'): compute_source_morph(src=src, subject_from='42') with pytest.raises(ValueError, match='output'): source_morph_vol.apply(stc_vol, output='42') with pytest.raises(ValueError, match='subject_to cannot be None'): compute_source_morph(src, 'sample', None, subjects_dir=subjects_dir) # Check if not morphed, but voxel size not boolean, raise ValueError. # Note that this check requires dipy to not raise the dipy ImportError # before checking if the actual voxel size error will raise. with pytest.raises(ValueError, match='Cannot infer original voxel size'): stc_vol.as_volume(inverse_operator_vol['src'], mri_resolution=4) stc_surf = read_source_estimate(fname_stc, 'sample') with pytest.raises(TypeError, match='stc_from must be an instance'): source_morph_vol.apply(stc_surf) # src_to source_morph_vol = compute_source_morph( fwd['src'], subject_from='sample', src_to=fwd['src'], subject_to='sample', subjects_dir=subjects_dir, **kwargs) stc_vol_2 = source_morph_vol.apply(stc_vol) # new way, verts match assert_array_equal(stc_vol.vertices[0], stc_vol_2.vertices[0]) stc_vol_bad = VolSourceEstimate( stc_vol.data[:-1], [stc_vol.vertices[0][:-1]], stc_vol.tmin, stc_vol.tstep) match = ( 'vertices do not match between morph \\(4157\\) and stc \\(4156\\).*' '\n.*\n.*\n.*Vertices were likely excluded during forward computatio.*' ) with pytest.raises(ValueError, match=match): source_morph_vol.apply(stc_vol_bad)
def test_volume_stc(): """Test volume STCs """ tempdir = _TempDir() N = 100 data = np.arange(N)[:, np.newaxis] datas = [data, data, np.arange(2)[:, np.newaxis]] vertno = np.arange(N) vertnos = [vertno, vertno[:, np.newaxis], np.arange(2)[:, np.newaxis]] vertno_reads = [vertno, vertno, np.arange(2)] for data, vertno, vertno_read in zip(datas, vertnos, vertno_reads): stc = VolSourceEstimate(data, vertno, 0, 1) fname_temp = op.join(tempdir, 'temp-vl.stc') stc_new = stc for _ in range(2): stc_new.save(fname_temp) stc_new = read_source_estimate(fname_temp) assert_true(isinstance(stc_new, VolSourceEstimate)) assert_array_equal(vertno_read, stc_new.vertices) assert_array_almost_equal(stc.data, stc_new.data) # now let's actually read a MNE-C processed file stc = read_source_estimate(fname_vol, 'sample') assert_true(isinstance(stc, VolSourceEstimate)) assert_true('sample' in repr(stc)) stc_new = stc assert_raises(ValueError, stc.save, fname_vol, ftype='whatever') for _ in range(2): fname_temp = op.join(tempdir, 'temp-vol.w') stc_new.save(fname_temp, ftype='w') stc_new = read_source_estimate(fname_temp) assert_true(isinstance(stc_new, VolSourceEstimate)) assert_array_equal(stc.vertices, stc_new.vertices) assert_array_almost_equal(stc.data, stc_new.data) # save the stc as a nifti file and export try: import nibabel as nib with warnings.catch_warnings(record=True): warnings.simplefilter('always') src = read_source_spaces(fname_vsrc) vol_fname = op.join(tempdir, 'stc.nii.gz') stc.save_as_volume(vol_fname, src, dest='surf', mri_resolution=False) with warnings.catch_warnings(record=True): # nib<->numpy img = nib.load(vol_fname) assert_true(img.shape == src[0]['shape'] + (len(stc.times), )) with warnings.catch_warnings(record=True): # nib<->numpy t1_img = nib.load(fname_t1) stc.save_as_volume(op.join(tempdir, 'stc.nii.gz'), src, dest='mri', mri_resolution=True) with warnings.catch_warnings(record=True): # nib<->numpy img = nib.load(vol_fname) assert_true(img.shape == t1_img.shape + (len(stc.times), )) assert_array_almost_equal(img.get_affine(), t1_img.get_affine(), decimal=5) # export without saving img = stc.as_volume(src, dest='mri', mri_resolution=True) assert_true(img.shape == t1_img.shape + (len(stc.times), )) assert_array_almost_equal(img.get_affine(), t1_img.get_affine(), decimal=5) except ImportError: print('Save as nifti test skipped, needs NiBabel')
def test_volume_source_morph_round_trip( tmpdir, subject_from, subject_to, lower, upper, dtype, morph_mat, monkeypatch): """Test volume source estimate morph round-trips well.""" import nibabel as nib from nibabel.processing import resample_from_to src = dict() if morph_mat: # ~1.5 minutes with pos=7. (4157 morphs!) for sample, so only test # morph_mat computation mode with a few labels label_names = sorted(get_volume_labels_from_aseg(fname_aseg))[1:2] if 'sample' in (subject_from, subject_to): src['sample'] = setup_volume_source_space( 'sample', subjects_dir=subjects_dir, volume_label=label_names, mri=fname_aseg) assert sum(s['nuse'] for s in src['sample']) == 12 if 'fsaverage' in (subject_from, subject_to): src['fsaverage'] = setup_volume_source_space( 'fsaverage', subjects_dir=subjects_dir, volume_label=label_names[:3], mri=fname_aseg_fs) assert sum(s['nuse'] for s in src['fsaverage']) == 16 else: assert not morph_mat if 'sample' in (subject_from, subject_to): src['sample'] = mne.read_source_spaces(fname_vol) src['sample'][0]['subject_his_id'] = 'sample' assert src['sample'][0]['nuse'] == 4157 if 'fsaverage' in (subject_from, subject_to): # Created to save space with: # # bem = op.join(op.dirname(mne.__file__), 'data', 'fsaverage', # 'fsaverage-inner_skull-bem.fif') # src_fsaverage = mne.setup_volume_source_space( # 'fsaverage', pos=7., bem=bem, mindist=0, # subjects_dir=subjects_dir, add_interpolator=False) # mne.write_source_spaces(fname_fs_vol, src_fsaverage, # overwrite=True) # # For speed we do it without the interpolator because it's huge. src['fsaverage'] = mne.read_source_spaces(fname_fs_vol) src['fsaverage'][0].update( vol_dims=np.array([23, 29, 25]), seg_name='brain') _add_interpolator(src['fsaverage']) assert src['fsaverage'][0]['nuse'] == 6379 src_to, src_from = src[subject_to], src[subject_from] del src # No SDR just for speed once everything works kwargs = dict(niter_sdr=(), niter_affine=(1,), subjects_dir=subjects_dir, verbose=True) morph_from_to = compute_source_morph( src=src_from, src_to=src_to, subject_to=subject_to, **kwargs) morph_to_from = compute_source_morph( src=src_to, src_to=src_from, subject_to=subject_from, **kwargs) nuse = sum(s['nuse'] for s in src_from) assert nuse > 10 use = np.linspace(0, nuse - 1, 10).round().astype(int) data = np.eye(nuse)[:, use] if dtype is complex: data = data * 1j vertices = [s['vertno'] for s in src_from] stc_from = VolSourceEstimate(data, vertices, 0, 1) with catch_logging() as log: stc_from_rt = morph_to_from.apply( morph_from_to.apply(stc_from, verbose='debug')) log = log.getvalue() assert 'individual volume morph' in log maxs = np.argmax(stc_from_rt.data, axis=0) src_rr = np.concatenate([s['rr'][s['vertno']] for s in src_from]) dists = 1000 * np.linalg.norm(src_rr[use] - src_rr[maxs], axis=1) mu = np.mean(dists) # fsaverage=5.99; 7.97 without additional src_ras_t fix # fsaverage=7.97; 25.4 without src_ras_t fix assert lower <= mu < upper, f'round-trip distance {mu}' # check that pre_affine is close to identity when subject_to==subject_from if subject_to == subject_from: for morph in (morph_to_from, morph_from_to): assert_allclose( morph.pre_affine.affine, np.eye(4), atol=1e-2) # check that power is more or less preserved (labelizing messes with this) if morph_mat: if subject_to == 'fsaverage': limits = (18, 18.5) else: limits = (7, 7.5) else: limits = (1, 1.2) stc_from_unit = stc_from.copy().crop(0, 0) stc_from_unit._data.fill(1.) stc_from_unit_rt = morph_to_from.apply(morph_from_to.apply(stc_from_unit)) assert_power_preserved(stc_from_unit, stc_from_unit_rt, limits=limits) if morph_mat: fname = tmpdir.join('temp-morph.h5') morph_to_from.save(fname) morph_to_from = read_source_morph(fname) assert morph_to_from.vol_morph_mat is None morph_to_from.compute_vol_morph_mat(verbose=True) morph_to_from.save(fname, overwrite=True) morph_to_from = read_source_morph(fname) assert isinstance(morph_to_from.vol_morph_mat, csr_matrix), 'csr' # equivalence (plus automatic calling) assert morph_from_to.vol_morph_mat is None monkeypatch.setattr(mne.morph, '_VOL_MAT_CHECK_RATIO', 0.) with catch_logging() as log: with pytest.warns(RuntimeWarning, match=r'calling morph\.compute'): stc_from_rt_lin = morph_to_from.apply( morph_from_to.apply(stc_from, verbose='debug')) assert isinstance(morph_from_to.vol_morph_mat, csr_matrix), 'csr' log = log.getvalue() assert 'sparse volume morph matrix' in log assert_allclose(stc_from_rt.data, stc_from_rt_lin.data) del stc_from_rt_lin stc_from_unit_rt_lin = morph_to_from.apply( morph_from_to.apply(stc_from_unit)) assert_allclose(stc_from_unit_rt.data, stc_from_unit_rt_lin.data) del stc_from_unit_rt_lin del stc_from, stc_from_rt # before and after morph, check the proportion of vertices # that are inside and outside the brainmask.mgz brain = nib.load(op.join(subjects_dir, subject_from, 'mri', 'brain.mgz')) mask = _get_img_fdata(brain) > 0 if subject_from == subject_to == 'sample': for stc in [stc_from_unit, stc_from_unit_rt]: img = stc.as_volume(src_from, mri_resolution=True) img = nib.Nifti1Image( # abs to convert complex np.abs(_get_img_fdata(img)[:, :, :, 0]), img.affine) img = _get_img_fdata(resample_from_to(img, brain, order=1)) assert img.shape == mask.shape in_ = img[mask].astype(bool).mean() out = img[~mask].astype(bool).mean() if morph_mat: out_max = 0.001 in_min, in_max = 0.005, 0.007 else: out_max = 0.02 in_min, in_max = 0.97, 0.98 assert out < out_max, f'proportion out of volume {out}' assert in_min < in_ < in_max, f'proportion inside volume {in_}'
def test_iterable(): """Test iterable support for simulate_raw.""" raw = read_raw_fif(raw_fname_short).load_data() raw.pick_channels(raw.ch_names[:10] + ['STI 014']) src = setup_volume_source_space( pos=dict(rr=[[-0.05, 0, 0], [0.1, 0, 0]], nn=[[0, 1., 0], [0, 1., 0]])) assert src.kind == 'discrete' trans = None sphere = make_sphere_model(head_radius=None, info=raw.info) tstep = 1. / raw.info['sfreq'] rng = np.random.RandomState(0) vertices = np.array([1]) data = rng.randn(1, 2) stc = VolSourceEstimate(data, vertices, 0, tstep) assert isinstance(stc.vertices, np.ndarray) with pytest.raises(ValueError, match='at least three time points'): simulate_raw(raw.info, stc, trans, src, sphere, None) data = rng.randn(1, 1000) n_events = (len(raw.times) - 1) // 1000 + 1 stc = VolSourceEstimate(data, vertices, 0, tstep) assert isinstance(stc.vertices, np.ndarray) with catch_logging() as log: with pytest.deprecated_call(): raw_sim = simulate_raw(raw, stc, trans, src, sphere, None, verbose=True) log = log.getvalue() assert 'Making 15 copies of STC' in log assert_allclose(raw.times, raw_sim.times) events = find_events(raw_sim, initial_event=True) assert len(events) == n_events assert_array_equal(events[:, 2], 1) # Degenerate STCs with pytest.raises(RuntimeError, match=r'Iterable did not provide stc\[0\]'): simulate_raw(raw.info, [], trans, src, sphere, None) with pytest.raises(RuntimeError, match=r'Iterable did not provide stc\[2\].*duration'): with pytest.deprecated_call(): simulate_raw(raw, [stc, stc], trans, src, sphere, None) # tuple with ndarray event_data = np.zeros(len(stc.times), int) event_data[0] = 3 raw_new = simulate_raw(raw.info, [(stc, event_data)] * 15, trans, src, sphere, None, first_samp=raw.first_samp) assert raw_new.n_times == 15000 raw_new.crop(0, raw_sim.times[-1]) _assert_iter_sim(raw_sim, raw_new, 3) with pytest.raises(ValueError, match='event data had shape .* but need'): simulate_raw(raw.info, [(stc, event_data[:-1])], trans, src, sphere, None) with pytest.raises(ValueError, match='stim_data in a stc tuple .* int'): simulate_raw(raw.info, [(stc, event_data * 1.)], trans, src, sphere, None) # iterable def stc_iter(): stim_data = np.zeros(len(stc.times), int) stim_data[0] = 4 ii = 0 while ii < 100: ii += 1 yield (stc, stim_data) with pytest.deprecated_call(): raw_new = simulate_raw(raw, stc_iter(), trans, src, sphere, None) _assert_iter_sim(raw_sim, raw_new, 4) def stc_iter_bad(): ii = 0 while ii < 100: ii += 1 yield (stc, 4, 3) with pytest.raises(ValueError, match='stc, if tuple, must be length'): simulate_raw(raw.info, stc_iter_bad(), trans, src, sphere, None) _assert_iter_sim(raw_sim, raw_new, 4) def stc_iter_bad(): ii = 0 while ii < 100: ii += 1 stc_new = stc.copy() stc_new.vertices = np.array([ii % 2]) yield stc_new with pytest.raises(RuntimeError, match=r'Vertex mismatch for stc\[1\]'): simulate_raw(raw.info, stc_iter_bad(), trans, src, sphere, None) # Forward omission vertices = np.array([0, 1]) data = rng.randn(2, 1000) stc = VolSourceEstimate(data, vertices, 0, tstep) assert isinstance(stc.vertices, np.ndarray) # XXX eventually we should support filtering based on sphere radius, too, # by refactoring the code in source_space.py that does it! surf = _get_ico_surface(3) surf['rr'] *= 60 # mm model = _surfaces_to_bem([surf], [FIFF.FIFFV_BEM_SURF_ID_BRAIN], [0.3]) bem = make_bem_solution(model) with pytest.warns(RuntimeWarning, match='1 of 2 SourceEstimate vertices'): simulate_raw(raw, stc, trans, src, bem, None)